[llvm-commits] [llvm] r40883 - in /llvm/trunk: include/llvm/LinkAllPasses.h include/llvm/Transforms/Scalar.h lib/Transforms/Scalar/LoopIndexSplit.cpp

Devang Patel dpatel at apple.com
Tue Aug 7 10:40:00 PDT 2007


On Aug 7, 2007, at 9:59 AM, Chris Lattner wrote:

>> URL: http://llvm.org/viewvc/llvm-project?rev=40883&view=rev
>> Log:
>> Begin loop index split pass.
>
> Nice!
>
>>
>> +//
>> ===------------------------------------------------------------------ 
>> -
>> ---===//
>> +//
>> +// LoopIndexSplit - This pass splits loop
>
> Please finish your sentence :)

ok

>
>> +//
>> +LoopPass *createLoopIndexSplitPass();
>> +
>>
>> ===================================================================== 
>> =
>> ========
>> --- llvm/trunk/lib/Transforms/Scalar/LoopIndexSplit.cpp (added)
>> +++ llvm/trunk/lib/Transforms/Scalar/LoopIndexSplit.cpp Mon Aug  6
>> 19:25:56 2007
>> @@ -0,0 +1,384 @@
> ..
>> +
>> +#define DEBUG_TYPE "loop-index-split"
>> +
>> +#include "llvm/Function.h"
>> +#include "llvm/Transforms/Scalar.h"
>
> This should include Transforms/Scalar first, because it is the
> "interface" to the .cpp file.

ok

>
>> +/// Find condition inside a loop that is suitable candidate for
>> index split.
>> +void LoopIndexSplit::findSplitCondition() {
>> +
>> + BasicBlock *Header = L->getHeader();
>> +
>> +  for (BasicBlock::iterator I = Header->begin(); isa<PHINode>(I); +
>> +I) {
>> +    PHINode *PN = cast<PHINode>(I);
>> +
>> +    if (!PN->getType()->isInteger())
>> +      continue;
>> +
>> +    SCEVHandle SCEV = SE->getSCEV(PN);
>> +    if (!isa<SCEVAddRecExpr>(SCEV))
>> +      continue;
>> +
>> +    // If this phi node is used in a compare instruction then it  
>> is a
>> +    // split condition candidate.
>> +    for (Value::use_iterator UI = PN->use_begin(), E = PN->use_end 
>> ();
>> +         UI != E; ++UI) {
>> +      if (ICmpInst *CI = dyn_cast<ICmpInst>(*UI)) {
>> +        SplitCondition = CI;
>> +        break;
>> +      }
>> +    }
>
> One problem with this is that it won't find conditions that are
> derived expressions of the induction variable.  Consider "if (iv+1 ==
> 17)".  Because the use of the IV is actually the add, this won't pick
> it up.
>
> I'd suggest scanning the terminators in the loop body, looking for
> comparisons where one side is a loop invariant, and one side is an
> addrecexpr corresponding to this loop.

ok. Only need to check header terminator here.

> Another thing to consider: in the "non-one-iteration loop" case, you
> can actually have multiple indexes to split.  The ultimate
> implementation will probably want to collect all of them for a loop
> and use a cost model to determine which is the cheapest to split
> (based on how much code would have to be duplicated).

hmm... okay

>> +  // Replace split condition in header.
>> +  // Transform
>> +  //      SplitCondition : icmp eq i32 IndVar, SplitValue
>> +  // into
>> +  //      c1 = icmp uge i32 SplitValue, StartValue
>> +  //      c2 = icmp ult i32 vSplitValue, ExitValue
>> +  //      and i32 c1, c2
>> +  bool SignedPredicate = SplitCondition->isSignedPredicate();
>
> I don't think this is right.  Doesn't the signedness of the compare
> depend on the loop exit condition, not the split condition?
>
> while (i < n)
>    if (i == 17)
>
> You want the signedness of the i < n comparison.

I was thinking both comparisons will have same sign but now I see. OK.

>
> Similarly, somewhere in the safety checks, you should verify that the
> exit condition really is an integer compare.

It does.

>
>> +  Instruction *C1 = new ICmpInst(SignedPredicate ?
>> +                                 ICmpInst::ICMP_SGE :
>> ICmpInst::ICMP_UGE,
>> +                                 SplitValue, StartValue,
>> "lisplit", Terminator);
>> +  Instruction *C2 = new ICmpInst(SignedPredicate ?
>> +                                 ICmpInst::ICMP_SLT :
>> ICmpInst::ICMP_ULT,
>> +                                 SplitValue, ExitValue, "lisplit",
>> Terminator);
>> +  Instruction *NSplitCond = BinaryOperator::create(Instruction::And,
>> +                                                   C1, C2,
>> "lisplit", Terminator);
>
> Plz use BinaryOperator::createAnd(C1, C2, "lisplit", Terminator);

OK

>
>> +  SplitCondition->replaceAllUsesWith(NSplitCond);
>> +  SplitCondition->removeFromParent();
>> +  delete SplitCondition;
>
> Instead of removeFromParent + delete, just use eraseFromParent().

good idea :)

>
>> +  BranchInst *BR = dyn_cast<BranchInst>(Latch->getTerminator());
>> +  BR->setUnconditionalDest(LatchSucc);
>
> If you know the terminator is a branch, use cast<BranchInst>,
> otherwise you need to check to see if BR is null.

OK, I'll add null check.

>
>> +  // Now, clear latch block. Remove instructions that are  
>> responsible
>> +  // to increment induction variable.
>> +  Instruction *LTerminator = Latch->getTerminator();
>> +  for (BasicBlock::iterator LB = Latch->begin(), LE = Latch->end();
>> +       LB != LE; ) {
>> +    Instruction *I = LB;
>> +    ++LB;
>> +    if (isa<PHINode>(I) || I == LTerminator)
>> +      continue;
>> +
>> +    I->replaceAllUsesWith(UndefValue::get(I->getType()));
>
> This won't work if I has void type.  I don't know if that is possible
> though, do to your safety predicate.

It won't have void type.. I think. I'll add check.
>
>> +    I->removeFromParent();
>> +    delete I;
>
> These two lines can be I->eraseFromParent();
>
>> +// If loop header includes loop variant instruction operands then
>> +// this loop can not be eliminated. This is used by
>> processOneIterationLoop().
>> +bool LoopIndexSplit::safeHeader(BasicBlock *Header) {
>> +
>> +  Instruction *Terminator = Header->getTerminator();
>> +  for(BasicBlock::iterator BI = Header->begin(), BE = Header->end();
>> +      BI != BE; ++BI) {
>> +    Instruction *I = BI;
>> +
>> +    // PHI Nodes are OK.
>> +    if (isa<PHINode>(I))
>> +      continue;
>
> What if the phi node is live out of the loop?
>
>    for (i = 0, j = 0; i < n; ++i, j = i)
>      if (i == 123) ...
>
>    use(j)
>
> ?

I thought, there was FIXME to check last value use.

>
>> +
>> +    // SplitCondition itself is OK.
>> +    if (ICmpInst *CI = dyn_cast<ICmpInst>(I)) {
>> +      if (CI == SplitCondition)
>> +        continue;
>> +    }
>
> No need for the dyncast, just use:

hmm ok.
>
>> +    if (CI == SplitCondition)
>> +      continue;
>
you mean
	if ( I == SplitCondition)
>
>> +// If Exit block includes loop variant instructions then this
>> +// loop may not be eliminated. This is used by
>> processOneIterationLoop().
>> +bool LoopIndexSplit::safeExitBlock(BasicBlock *ExitBlock) {
>> +
>> +  Instruction *ExitCondition = NULL;
>> +  Instruction *IndVarIncrement = NULL;
>> +
>> +  for (BasicBlock::iterator BI = ExitBlock->begin(), BE =
>> ExitBlock->end();
>> +       BI != BE; ++BI) {
>> +    Instruction *I = BI;
>> +
>> +    // PHI Nodes are OK.
>> +    if (isa<PHINode>(I))
>> +      continue;
>
> similar to the above.
>
>> +    // Check if I is induction variable increment instruction.
>> +    if (BinaryOperator *BOp = dyn_cast<BinaryOperator>(I)) {
>> +      if (BOp->getOpcode() != Instruction::Add)
>> +        return false;
>
> No need for the dyncast:
>
>> +    if (I->getOpcode() != Instruction::Add)
>> +      return false;
>
> should work.
>
>
>> +      Value *Op0 = BOp->getOperand(0);
>> +      Value *Op1 = BOp->getOperand(1);
>> +      PHINode *PN = NULL;
>> +      ConstantInt *CI = NULL;
>> +
>> +      if ((PN = dyn_cast<PHINode>(Op0))) {
>> +        if ((CI = dyn_cast<ConstantInt>(Op1)))
>> +          IndVarIncrement = I;
>> +      } else
>> +        if ((PN = dyn_cast<PHINode>(Op1))) {
>> +          if ((CI = dyn_cast<ConstantInt>(Op0)))
>> +            IndVarIncrement = I;
>> +      }
>> +
>> +      if (IndVarIncrement && PN == IndVar && CI->isOne())
>> +        continue;
>> +    }
>
> It seems enough to check to see that the add has a single use, and
> that its use is a phinode in the loop header, no?

that'd also work.

>
> Looks like a great start Devang!

Thanks!

-
Devang



More information about the llvm-commits mailing list