[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