[llvm-commits] [llvm] r101819 - in /llvm/trunk: include/llvm/Analysis/IVUsers.h lib/Analysis/IVUsers.cpp lib/Transforms/Scalar/LoopStrengthReduce.cpp test/Transforms/IndVarSimplify/eliminate-comparison.ll

Dan Gohman gohman at apple.com
Mon Apr 19 14:48:58 PDT 2010


Author: djg
Date: Mon Apr 19 16:48:58 2010
New Revision: 101819

URL: http://llvm.org/viewvc/llvm-project?rev=101819&view=rev
Log:
Remove the Expr member from IVUsers. Instead of remembering the expression,
just ask ScalarEvolution for it on demand. This helps IVUsers be more robust
in the case of expressions changing underneath it. This fixes PR6862.

Modified:
    llvm/trunk/include/llvm/Analysis/IVUsers.h
    llvm/trunk/lib/Analysis/IVUsers.cpp
    llvm/trunk/lib/Transforms/Scalar/LoopStrengthReduce.cpp
    llvm/trunk/test/Transforms/IndVarSimplify/eliminate-comparison.ll

Modified: llvm/trunk/include/llvm/Analysis/IVUsers.h
URL: http://llvm.org/viewvc/llvm-project/llvm/trunk/include/llvm/Analysis/IVUsers.h?rev=101819&r1=101818&r2=101819&view=diff
==============================================================================
--- llvm/trunk/include/llvm/Analysis/IVUsers.h (original)
+++ llvm/trunk/include/llvm/Analysis/IVUsers.h Mon Apr 19 16:48:58 2010
@@ -36,9 +36,8 @@
 class IVStrideUse : public CallbackVH, public ilist_node<IVStrideUse> {
   friend class IVUsers;
 public:
-  IVStrideUse(IVUsers *P, const SCEV *E,
-              Instruction* U, Value *O)
-    : CallbackVH(U), Parent(P), Expr(E), OperandValToReplace(O) {
+  IVStrideUse(IVUsers *P, Instruction* U, Value *O)
+    : CallbackVH(U), Parent(P), OperandValToReplace(O) {
   }
 
   /// getUser - Return the user instruction for this use.
@@ -51,20 +50,6 @@
     setValPtr(NewUser);
   }
 
-  /// getParent - Return a pointer to the IVUsers that owns
-  /// this IVStrideUse.
-  IVUsers *getParent() const { return Parent; }
-
-  /// getExpr - Return the expression for the use.
-  const SCEV *getExpr() const { return Expr; }
-
-  /// setExpr - Assign a new expression to this use.
-  void setExpr(const SCEV *Val) {
-    Expr = Val;
-  }
-
-  const SCEV *getStride(const Loop *L) const;
-
   /// getOperandValToReplace - Return the Value of the operand in the user
   /// instruction that this IVStrideUse is representing.
   Value *getOperandValToReplace() const {
@@ -91,9 +76,6 @@
   /// Parent - a pointer to the IVUsers that owns this IVStrideUse.
   IVUsers *Parent;
 
-  /// Expr - The expression for this use.
-  const SCEV *Expr;
-
   /// OperandValToReplace - The Value of the operand in the user instruction
   /// that this IVStrideUse is representing.
   WeakVH OperandValToReplace;
@@ -161,12 +143,16 @@
   /// return true.  Otherwise, return false.
   bool AddUsersIfInteresting(Instruction *I);
 
-  IVStrideUse &AddUser(const SCEV *Expr,
-                       Instruction *User, Value *Operand);
+  IVStrideUse &AddUser(Instruction *User, Value *Operand);
 
   /// getReplacementExpr - Return a SCEV expression which computes the
   /// value of the OperandValToReplace of the given IVStrideUse.
-  const SCEV *getReplacementExpr(const IVStrideUse &U) const;
+  const SCEV *getReplacementExpr(const IVStrideUse &IU) const;
+
+  /// getExpr - Return the expression for the use.
+  const SCEV *getExpr(const IVStrideUse &IU) const;
+
+  const SCEV *getStride(const IVStrideUse &IU, const Loop *L) const;
 
   typedef ilist<IVStrideUse>::iterator iterator;
   typedef ilist<IVStrideUse>::const_iterator const_iterator;

Modified: llvm/trunk/lib/Analysis/IVUsers.cpp
URL: http://llvm.org/viewvc/llvm-project/llvm/trunk/lib/Analysis/IVUsers.cpp?rev=101819&r1=101818&r2=101819&view=diff
==============================================================================
--- llvm/trunk/lib/Analysis/IVUsers.cpp (original)
+++ llvm/trunk/lib/Analysis/IVUsers.cpp Mon Apr 19 16:48:58 2010
@@ -122,23 +122,21 @@
 
     if (AddUserToIVUsers) {
       // Okay, we found a user that we cannot reduce.
-      IVUses.push_back(new IVStrideUse(this, ISE, User, I));
+      IVUses.push_back(new IVStrideUse(this, User, I));
       IVStrideUse &NewUse = IVUses.back();
       // Transform the expression into a normalized form.
-      NewUse.Expr =
-        TransformForPostIncUse(NormalizeAutodetect, NewUse.Expr,
-                               User, I,
-                               NewUse.PostIncLoops,
-                               *SE, *DT);
-      DEBUG(dbgs() << "   NORMALIZED TO: " << *NewUse.Expr << '\n');
+      ISE = TransformForPostIncUse(NormalizeAutodetect,
+                                   ISE, User, I,
+                                   NewUse.PostIncLoops,
+                                   *SE, *DT);
+      DEBUG(dbgs() << "   NORMALIZED TO: " << *ISE << '\n');
     }
   }
   return true;
 }
 
-IVStrideUse &IVUsers::AddUser(const SCEV *Expr,
-                              Instruction *User, Value *Operand) {
-  IVUses.push_back(new IVStrideUse(this, Expr, User, Operand));
+IVStrideUse &IVUsers::AddUser(Instruction *User, Value *Operand) {
+  IVUses.push_back(new IVStrideUse(this, User, Operand));
   return IVUses.back();
 }
 
@@ -169,15 +167,6 @@
   return false;
 }
 
-/// getReplacementExpr - Return a SCEV expression which computes the
-/// value of the OperandValToReplace of the given IVStrideUse.
-const SCEV *IVUsers::getReplacementExpr(const IVStrideUse &U) const {
-  PostIncLoopSet &Loops = const_cast<PostIncLoopSet &>(U.PostIncLoops);
-  return TransformForPostIncUse(Denormalize, U.getExpr(),
-                                U.getUser(), U.getOperandValToReplace(),
-                                Loops, *SE, *DT);
-}
-
 void IVUsers::print(raw_ostream &OS, const Module *M) const {
   OS << "IV Users for loop ";
   WriteAsOperand(OS, L->getHeader(), false);
@@ -194,8 +183,7 @@
        E = IVUses.end(); UI != E; ++UI) {
     OS << "  ";
     WriteAsOperand(OS, UI->getOperandValToReplace(), false);
-    OS << " = "
-       << *getReplacementExpr(*UI);
+    OS << " = " << *getReplacementExpr(*UI);
     for (PostIncLoopSet::const_iterator
          I = UI->PostIncLoops.begin(),
          E = UI->PostIncLoops.end(); I != E; ++I) {
@@ -218,6 +206,21 @@
   IVUses.clear();
 }
 
+/// getReplacementExpr - Return a SCEV expression which computes the
+/// value of the OperandValToReplace.
+const SCEV *IVUsers::getReplacementExpr(const IVStrideUse &IU) const {
+  return SE->getSCEV(IU.getOperandValToReplace());
+}
+
+/// getExpr - Return the expression for the use.
+const SCEV *IVUsers::getExpr(const IVStrideUse &IU) const {
+  return
+    TransformForPostIncUse(Normalize, getReplacementExpr(IU),
+                           IU.getUser(), IU.getOperandValToReplace(),
+                           const_cast<PostIncLoopSet &>(IU.getPostIncLoops()),
+                           *SE, *DT);
+}
+
 static const SCEVAddRecExpr *findAddRecForLoop(const SCEV *S, const Loop *L) {
   if (const SCEVAddRecExpr *AR = dyn_cast<SCEVAddRecExpr>(S)) {
     if (AR->getLoop() == L)
@@ -236,18 +239,13 @@
   return 0;
 }
 
-const SCEV *IVStrideUse::getStride(const Loop *L) const {
-  if (const SCEVAddRecExpr *AR = findAddRecForLoop(getExpr(), L))
-    return AR->getStepRecurrence(*Parent->SE);
+const SCEV *IVUsers::getStride(const IVStrideUse &IU, const Loop *L) const {
+  if (const SCEVAddRecExpr *AR = findAddRecForLoop(getExpr(IU), L))
+    return AR->getStepRecurrence(*SE);
   return 0;
 }
 
 void IVStrideUse::transformToPostInc(const Loop *L) {
-  PostIncLoopSet Loops;
-  Loops.insert(L);
-  Expr = TransformForPostIncUse(Normalize, Expr,
-                                getUser(), getOperandValToReplace(),
-                                Loops, *Parent->SE, *Parent->DT);
   PostIncLoops.insert(L);
 }
 

Modified: llvm/trunk/lib/Transforms/Scalar/LoopStrengthReduce.cpp
URL: http://llvm.org/viewvc/llvm-project/llvm/trunk/lib/Transforms/Scalar/LoopStrengthReduce.cpp?rev=101819&r1=101818&r2=101819&view=diff
==============================================================================
--- llvm/trunk/lib/Transforms/Scalar/LoopStrengthReduce.cpp (original)
+++ llvm/trunk/lib/Transforms/Scalar/LoopStrengthReduce.cpp Mon Apr 19 16:48:58 2010
@@ -1575,8 +1575,8 @@
             !DT.properlyDominates(UI->getUser()->getParent(), ExitingBlock)) {
           // Conservatively assume there may be reuse if the quotient of their
           // strides could be a legal scale.
-          const SCEV *A = CondUse->getStride(L);
-          const SCEV *B = UI->getStride(L);
+          const SCEV *A = IU.getStride(*CondUse, L);
+          const SCEV *B = IU.getStride(*UI, L);
           if (!A || !B) continue;
           if (SE.getTypeSizeInBits(A->getType()) !=
               SE.getTypeSizeInBits(B->getType())) {
@@ -1629,8 +1629,7 @@
         ExitingBlock->getInstList().insert(TermBr, Cond);
 
         // Clone the IVUse, as the old use still exists!
-        CondUse = &IU.AddUser(CondUse->getExpr(),
-                              Cond, CondUse->getOperandValToReplace());
+        CondUse = &IU.AddUser(Cond, CondUse->getOperandValToReplace());
         TermBr->replaceUsesOfWith(OldCond, Cond);
       }
     }
@@ -1748,7 +1747,7 @@
   // Collect interesting types and strides.
   SmallVector<const SCEV *, 4> Worklist;
   for (IVUsers::const_iterator UI = IU.begin(), E = IU.end(); UI != E; ++UI) {
-    const SCEV *Expr = UI->getExpr();
+    const SCEV *Expr = IU.getExpr(*UI);
 
     // Collect interesting types.
     Types.insert(SE.getEffectiveSCEVType(Expr->getType()));
@@ -1819,7 +1818,7 @@
       AccessTy = getAccessType(LF.UserInst);
     }
 
-    const SCEV *S = UI->getExpr();
+    const SCEV *S = IU.getExpr(*UI);
 
     // Equality (== and !=) ICmps are special. We can rewrite (i == N) as
     // (N - i == 0), and this allows (N - i) to be the expression that we work

Modified: llvm/trunk/test/Transforms/IndVarSimplify/eliminate-comparison.ll
URL: http://llvm.org/viewvc/llvm-project/llvm/trunk/test/Transforms/IndVarSimplify/eliminate-comparison.ll?rev=101819&r1=101818&r2=101819&view=diff
==============================================================================
--- llvm/trunk/test/Transforms/IndVarSimplify/eliminate-comparison.ll (original)
+++ llvm/trunk/test/Transforms/IndVarSimplify/eliminate-comparison.ll Mon Apr 19 16:48:58 2010
@@ -82,3 +82,27 @@
   %tmp.0.ph = phi i32 [ 0, %bb18 ], [ 1, %bb15 ], [ 0, %bb13 ]
   ret i32 %tmp.0.ph
 }
+
+; Indvars should eliminate the icmp here.
+
+; CHECK: @func_10
+; CHECK-NOT: icmp
+; CHECK: ret void
+
+define void @func_10() nounwind {
+entry:
+  br label %loop
+
+loop:
+  %i = phi i32 [ %i.next, %loop ], [ 0, %entry ]
+  %t0 = icmp slt i32 %i, 0
+  %t1 = zext i1 %t0 to i32
+  %t2 = add i32 %t1, %i
+  %u3 = zext i32 %t2 to i64
+  store i64 %u3, i64* null
+  %i.next = add i32 %i, 1
+  br i1 undef, label %loop, label %return
+
+return:
+  ret void
+}





More information about the llvm-commits mailing list