[llvm-commits] PATCH: Fix very slow algorithm in RescheduleMIBelowKill

Jakob Stoklund Olesen stoklund at 2pi.dk
Thu Jul 12 21:21:43 PDT 2012


On Jul 12, 2012, at 6:16 PM, Chandler Carruth <chandlerc at gmail.com> wrote:

> Hello,
> 
> This patch removes an badly scaling code path from RescheduleMIBelowKill in the twoaddr pass.
> 
> The problem is essentially that we walk the instructions of the basic blocks of a function, and call RescheduleMIBelowKill for a large number of them. It in turn calls findLocalKill, which then walks *the entire* use/def chain for the register for the function. For functions with a very large number of register uses, this starts to scale very poorly. =]
> 
> There is a better algorithm to use here. Right after we do findLocalKill, we walk the instructions linearly from the original instruction to the kill, checking if dependencies have been violated. This already has a cap to prevent n^2 complexity on very large basic blocks.
> 
> If we fuse the search for the kill with the checking for dependencies we can share the single linear walk and the single cap to prevent n^2 behavior.

When reading your code, it struck me that LiveVariables already did all this. It has a list of kill instructions for each virtual register. If LiveVariables is not available, you are running under -O0, and shouldn't be trying to reschedule instructions anyway.

You can simply go LV->getVarInfo(Reg).findKill(MBB), and avoid scanning instructions at all.

If the LV list of kill instructions also is large, that is easily fixable in findKill():

  if (Kills.size() > 10) {
    if (getVRegDef(Reg)->getParent() == MBB)
      return 0; // live-out of defining block.
    if (AliveBlocks.test(MBB->getNumber())
      return 0; // live-through MBB.
  }

/jakob





More information about the llvm-commits mailing list