[llvm-commits] [llvm] r97126 - in /llvm/trunk: lib/Analysis/ScalarEvolution.cpp lib/Transforms/Scalar/IndVarSimplify.cpp lib/Transforms/Utils/LoopSimplify.cpp test/CodeGen/X86/2009-09-07-CoalescerBug.ll test/Transforms/IndVarSimplify/2003-09-12-MultiplePred.ll test/Transforms/LoopDeletion/simplify-then-delete.ll

Nick Lewycky nicholas at mxc.ca
Wed Feb 24 23:12:41 PST 2010


Dan Gohman wrote:
> Author: djg
> Date: Thu Feb 25 00:57:05 2010
> New Revision: 97126
>
> URL: http://llvm.org/viewvc/llvm-project?rev=97126&view=rev
> Log:
> Make LoopSimplify change conditional branches in loop exiting blocks
> which branch on undef to branch on a boolean constant for the edge
> exiting the loop. This helps ScalarEvolution compute trip counts for
> loops.

I'm confused. 'undef' is already a constant and ought to be more useful 
for optimization than i1 0 or i1 1. Are you sure this is the right fix?

Nick

> Teach ScalarEvolution to recognize single-value PHIs, when safe, and
> ForgetSymbolicName to forget such single-value PHI nodes as apprpriate
> in ForgetSymbolicName.
>
> Added:
>      llvm/trunk/test/Transforms/LoopDeletion/simplify-then-delete.ll
> Modified:
>      llvm/trunk/lib/Analysis/ScalarEvolution.cpp
>      llvm/trunk/lib/Transforms/Scalar/IndVarSimplify.cpp
>      llvm/trunk/lib/Transforms/Utils/LoopSimplify.cpp
>      llvm/trunk/test/CodeGen/X86/2009-09-07-CoalescerBug.ll
>      llvm/trunk/test/Transforms/IndVarSimplify/2003-09-12-MultiplePred.ll
>
> Modified: llvm/trunk/lib/Analysis/ScalarEvolution.cpp
> URL: http://llvm.org/viewvc/llvm-project/llvm/trunk/lib/Analysis/ScalarEvolution.cpp?rev=97126&r1=97125&r2=97126&view=diff
> ==============================================================================
> --- llvm/trunk/lib/Analysis/ScalarEvolution.cpp (original)
> +++ llvm/trunk/lib/Analysis/ScalarEvolution.cpp Thu Feb 25 00:57:05 2010
> @@ -2549,14 +2549,14 @@
>   /// the Scalars map if they reference SymName. This is used during PHI
>   /// resolution.
>   void
> -ScalarEvolution::ForgetSymbolicName(Instruction *I, const SCEV *SymName) {
> +ScalarEvolution::ForgetSymbolicName(Instruction *PN, const SCEV *SymName) {
>     SmallVector<Instruction *, 16>  Worklist;
> -  PushDefUseChildren(I, Worklist);
> +  PushDefUseChildren(PN, Worklist);
>
>     SmallPtrSet<Instruction *, 8>  Visited;
> -  Visited.insert(I);
> +  Visited.insert(PN);
>     while (!Worklist.empty()) {
> -    I = Worklist.pop_back_val();
> +    Instruction *I = Worklist.pop_back_val();
>       if (!Visited.insert(I)) continue;
>
>       std::map<SCEVCallbackVH, const SCEV *>::iterator It =
> @@ -2568,12 +2568,15 @@
>           continue;
>
>         // SCEVUnknown for a PHI either means that it has an unrecognized
> -      // structure, or it's a PHI that's in the progress of being computed
> -      // by createNodeForPHI.  In the former case, additional loop trip
> -      // count information isn't going to change anything. In the later
> -      // case, createNodeForPHI will perform the necessary updates on its
> -      // own when it gets to that point.
> -      if (!isa<PHINode>(I) || !isa<SCEVUnknown>(It->second)) {
> +      // structure, it's a PHI that's in the progress of being computed
> +      // by createNodeForPHI, or it's a single-value PHI. In the first case,
> +      // additional loop trip count information isn't going to change anything.
> +      // In the second case, createNodeForPHI will perform the necessary
> +      // updates on its own when it gets to that point. In the third, we do
> +      // want to forget the SCEVUnknown.
> +      if (!isa<PHINode>(I) ||
> +          !isa<SCEVUnknown>(It->second) ||
> +          (I != PN&&  It->second == SymName)) {
>           ValuesAtScopes.erase(It->second);
>           Scalars.erase(It);
>         }
> @@ -2696,9 +2699,21 @@
>           return SymbolicName;
>         }
>
> -  // It's tempting to recognize PHIs with a unique incoming value, however
> -  // this leads passes like indvars to break LCSSA form. Fortunately, such
> -  // PHIs are rare, as instcombine zaps them.
> +  // If the PHI has a single incoming value, follow that value, unless the
> +  // PHI's incoming blocks are in a different loop, in which case doing so
> +  // risks breaking LCSSA form. Instcombine would normally zap these, but
> +  // it doesn't have DominatorTree information, so it may miss cases.
> +  if (Value *V = PN->hasConstantValue(DT)) {
> +    bool AllSameLoop = true;
> +    Loop *PNLoop = LI->getLoopFor(PN->getParent());
> +    for (size_t i = 0, e = PN->getNumIncomingValues(); i != e; ++i)
> +      if (LI->getLoopFor(PN->getIncomingBlock(i)) != PNLoop) {
> +        AllSameLoop = false;
> +        break;
> +      }
> +    if (AllSameLoop)
> +      return getSCEV(V);
> +  }
>
>     // If it's not a loop phi, we can't handle it yet.
>     return getUnknown(PN);
>
> Modified: llvm/trunk/lib/Transforms/Scalar/IndVarSimplify.cpp
> URL: http://llvm.org/viewvc/llvm-project/llvm/trunk/lib/Transforms/Scalar/IndVarSimplify.cpp?rev=97126&r1=97125&r2=97126&view=diff
> ==============================================================================
> --- llvm/trunk/lib/Transforms/Scalar/IndVarSimplify.cpp (original)
> +++ llvm/trunk/lib/Transforms/Scalar/IndVarSimplify.cpp Thu Feb 25 00:57:05 2010
> @@ -384,17 +384,18 @@
>     // in this loop, insert a canonical induction variable of the largest size.
>     Value *IndVar = 0;
>     if (NeedCannIV) {
> -    // Check to see if the loop already has a canonical-looking induction
> -    // variable. If one is present and it's wider than the planned canonical
> -    // induction variable, temporarily remove it, so that the Rewriter
> -    // doesn't attempt to reuse it.
> -    PHINode *OldCannIV = L->getCanonicalInductionVariable();
> -    if (OldCannIV) {
> +    // Check to see if the loop already has any canonical-looking induction
> +    // variables. If any are present and wider than the planned canonical
> +    // induction variable, temporarily remove them, so that the Rewriter
> +    // doesn't attempt to reuse them.
> +    SmallVector<PHINode *, 2>  OldCannIVs;
> +    while (PHINode *OldCannIV = L->getCanonicalInductionVariable()) {
>         if (SE->getTypeSizeInBits(OldCannIV->getType())>
>             SE->getTypeSizeInBits(LargestType))
>           OldCannIV->removeFromParent();
>         else
> -        OldCannIV = 0;
> +        break;
> +      OldCannIVs.push_back(OldCannIV);
>       }
>
>       IndVar = Rewriter.getOrInsertCanonicalInductionVariable(L, LargestType);
> @@ -404,17 +405,21 @@
>       DEBUG(dbgs()<<  "INDVARS: New CanIV: "<<  *IndVar<<  '\n');
>
>       // Now that the official induction variable is established, reinsert
> -    // the old canonical-looking variable after it so that the IR remains
> -    // consistent. It will be deleted as part of the dead-PHI deletion at
> +    // any old canonical-looking variables after it so that the IR remains
> +    // consistent. They will be deleted as part of the dead-PHI deletion at
>       // the end of the pass.
> -    if (OldCannIV)
> -      OldCannIV->insertAfter(cast<Instruction>(IndVar));
> +    while (!OldCannIVs.empty()) {
> +      PHINode *OldCannIV = OldCannIVs.pop_back_val();
> +      OldCannIV->insertBefore(L->getHeader()->getFirstNonPHI());
> +    }
>     }
>
>     // If we have a trip count expression, rewrite the loop's exit condition
>     // using it.  We can currently only handle loops with a single exit.
>     ICmpInst *NewICmp = 0;
> -  if (!isa<SCEVCouldNotCompute>(BackedgeTakenCount)&&  ExitingBlock) {
> +  if (!isa<SCEVCouldNotCompute>(BackedgeTakenCount)&&
> +      !BackedgeTakenCount->isZero()&&
> +      ExitingBlock) {
>       assert(NeedCannIV&&
>              "LinearFunctionTestReplace requires a canonical induction variable");
>       // Can't rewrite non-branch yet.
>
> Modified: llvm/trunk/lib/Transforms/Utils/LoopSimplify.cpp
> URL: http://llvm.org/viewvc/llvm-project/llvm/trunk/lib/Transforms/Utils/LoopSimplify.cpp?rev=97126&r1=97125&r2=97126&view=diff
> ==============================================================================
> --- llvm/trunk/lib/Transforms/Utils/LoopSimplify.cpp (original)
> +++ llvm/trunk/lib/Transforms/Utils/LoopSimplify.cpp Thu Feb 25 00:57:05 2010
> @@ -159,6 +159,22 @@
>       }
>     }
>
> +  // If there are exiting blocks with branches on undef, resolve the undef in
> +  // the direction which will exit the loop. This will help simplify loop
> +  // trip count computations.
> +  SmallVector<BasicBlock*, 8>  ExitingBlocks;
> +  L->getExitingBlocks(ExitingBlocks);
> +  for (SmallVectorImpl<BasicBlock *>::iterator I = ExitingBlocks.begin(),
> +       E = ExitingBlocks.end(); I != E; ++I)
> +    if (BranchInst *BI = dyn_cast<BranchInst>((*I)->getTerminator()))
> +      if (BI->isConditional()) {
> +        if (UndefValue *Cond = dyn_cast<UndefValue>(BI->getCondition())) {
> +          BI->setCondition(ConstantInt::get(Cond->getType(),
> +                                            !L->contains(BI->getSuccessor(0))));
> +          Changed = true;
> +        }
> +      }
> +
>     // Does the loop already have a preheader?  If so, don't insert one.
>     BasicBlock *Preheader = L->getLoopPreheader();
>     if (!Preheader) {
> @@ -250,8 +266,6 @@
>           break;
>         }
>     if (UniqueExit) {
> -    SmallVector<BasicBlock*, 8>  ExitingBlocks;
> -    L->getExitingBlocks(ExitingBlocks);
>       for (unsigned i = 0, e = ExitingBlocks.size(); i != e; ++i) {
>         BasicBlock *ExitingBlock = ExitingBlocks[i];
>         if (!ExitingBlock->getSinglePredecessor()) continue;
>
> Modified: llvm/trunk/test/CodeGen/X86/2009-09-07-CoalescerBug.ll
> URL: http://llvm.org/viewvc/llvm-project/llvm/trunk/test/CodeGen/X86/2009-09-07-CoalescerBug.ll?rev=97126&r1=97125&r2=97126&view=diff
> ==============================================================================
> --- llvm/trunk/test/CodeGen/X86/2009-09-07-CoalescerBug.ll (original)
> +++ llvm/trunk/test/CodeGen/X86/2009-09-07-CoalescerBug.ll Thu Feb 25 00:57:05 2010
> @@ -8,8 +8,7 @@
>   define i64 @hammer_time(i64 %modulep, i64 %physfree) nounwind ssp noredzone noimplicitfloat {
>   ; CHECK: hammer_time:
>   ; CHECK: movq $Xrsvd, %rax
> -; CHECK: movq $Xrsvd, %rsi
> -; CHECK: movq $Xrsvd, %rdi
> +; CHECK: movq $Xrsvd, %rcx
>   entry:
>     br i1 undef, label %if.then, label %if.end
>
>
> Modified: llvm/trunk/test/Transforms/IndVarSimplify/2003-09-12-MultiplePred.ll
> URL: http://llvm.org/viewvc/llvm-project/llvm/trunk/test/Transforms/IndVarSimplify/2003-09-12-MultiplePred.ll?rev=97126&r1=97125&r2=97126&view=diff
> ==============================================================================
> --- llvm/trunk/test/Transforms/IndVarSimplify/2003-09-12-MultiplePred.ll (original)
> +++ llvm/trunk/test/Transforms/IndVarSimplify/2003-09-12-MultiplePred.ll Thu Feb 25 00:57:05 2010
> @@ -7,7 +7,7 @@
>   LoopHead:               ; preds = %LoopHead, %0, %0
>           %A = phi i32 [ 7, %0 ], [ 7, %0 ], [ %B, %LoopHead ]            ;<i32>  [#uses=1]
>           %B = add i32 %A, 1              ;<i32>  [#uses=2]
> -        br i1 undef, label %LoopHead, label %Out
> +        br i1 true, label %LoopHead, label %Out
>
>   Out:            ; preds = %LoopHead
>           ret i32 %B
>
> Added: llvm/trunk/test/Transforms/LoopDeletion/simplify-then-delete.ll
> URL: http://llvm.org/viewvc/llvm-project/llvm/trunk/test/Transforms/LoopDeletion/simplify-then-delete.ll?rev=97126&view=auto
> ==============================================================================
> --- llvm/trunk/test/Transforms/LoopDeletion/simplify-then-delete.ll (added)
> +++ llvm/trunk/test/Transforms/LoopDeletion/simplify-then-delete.ll Thu Feb 25 00:57:05 2010
> @@ -0,0 +1,65 @@
> +; RUN: opt<  %s -S -indvars -loop-deletion -simplifycfg | FileCheck %s
> +; PR5794
> +
> +; Indvars and loop deletion should be able to eliminate all looping
> +; in this testcase.
> +
> +; CHECK:      define i32 @pmat(i32 %m, i32 %n, double* %y) nounwind {
> +; CHECK-NEXT: entry:
> +; CHECK-NEXT:   ret i32 0
> +; CHECK-NEXT: }
> +
> +target datalayout = "e-p:64:64:64"
> +
> +define i32 @pmat(i32 %m, i32 %n, double* %y) nounwind {
> +entry:
> +  %cmp4 = icmp sgt i32 %m, 0
> +  br i1 %cmp4, label %bb.n10, label %w.e12
> +
> +w.c:
> +  %cmp = icmp slt i32 %inc11, %m
> +  br i1 %cmp, label %w.c2.p, label %w.c.w.e12c
> +
> +w.c.w.e12c:
> +  br label %w.c.w.e12c.s
> +
> +w.c.w.e12c.s:
> +  br label %w.e12
> +
> +bb.n10:
> +  %cmp51 = icmp sgt i32 %n, 0
> +  br i1 %cmp51, label %bb.n10.w.c.w.e12c.sc, label %bb.n10.bb.n10.sc
> +
> +bb.n10.bb.n10.sc:
> +  br label %bb.n10.s
> +
> +bb.n10.w.c.w.e12c.sc:
> +  br label %w.c.w.e12c.s
> +
> +bb.n10.s:
> +  br label %w.c2.p
> +
> +w.c2.p:
> +  %i.05 = phi i32 [ 0, %bb.n10.s ], [ %inc11, %w.c ]
> +  br i1 false, label %bb.n, label %w.e
> +
> +w.c2:
> +  br i1 undef, label %w.b6, label %w.c2.w.ec
> +
> +w.c2.w.ec:
> +  br label %w.e
> +
> +bb.n:
> +  br label %w.b6
> +
> +w.b6:
> +  br label %w.c2
> +
> +w.e:
> +  %i.08 = phi i32 [ undef, %w.c2.w.ec ], [ %i.05, %w.c2.p ]
> +  %inc11 = add nsw i32 %i.08, 1
> +  br label %w.c
> +
> +w.e12:
> +  ret i32 0
> +}
>
>
> _______________________________________________
> llvm-commits mailing list
> llvm-commits at cs.uiuc.edu
> http://lists.cs.uiuc.edu/mailman/listinfo/llvm-commits
>




More information about the llvm-commits mailing list