[llvm-commits] [llvm] r70661 - in /llvm/trunk: include/llvm/Analysis/ScalarEvolution.h include/llvm/Transforms/Utils/BasicBlockUtils.h include/llvm/Transforms/Utils/Local.h lib/Analysis/ScalarEvolution.cpp lib/Transforms/Scalar/IndVarSimplify.cpp lib/Transforms/Scalar/LoopDeletion.cpp lib/Transforms/Scalar/LoopStrengthReduce.cpp lib/Transforms/Utils/BasicBlockUtils.cpp lib/Transforms/Utils/Local.cpp

Dan Gohman gohman at apple.com
Sat May 2 22:46:21 PDT 2009


Author: djg
Date: Sun May  3 00:46:20 2009
New Revision: 70661

URL: http://llvm.org/viewvc/llvm-project?rev=70661&view=rev
Log:
Revert r70645 for now; it's causing a variety of regressions.

Modified:
    llvm/trunk/include/llvm/Analysis/ScalarEvolution.h
    llvm/trunk/include/llvm/Transforms/Utils/BasicBlockUtils.h
    llvm/trunk/include/llvm/Transforms/Utils/Local.h
    llvm/trunk/lib/Analysis/ScalarEvolution.cpp
    llvm/trunk/lib/Transforms/Scalar/IndVarSimplify.cpp
    llvm/trunk/lib/Transforms/Scalar/LoopDeletion.cpp
    llvm/trunk/lib/Transforms/Scalar/LoopStrengthReduce.cpp
    llvm/trunk/lib/Transforms/Utils/BasicBlockUtils.cpp
    llvm/trunk/lib/Transforms/Utils/Local.cpp

Modified: llvm/trunk/include/llvm/Analysis/ScalarEvolution.h
URL: http://llvm.org/viewvc/llvm-project/llvm/trunk/include/llvm/Analysis/ScalarEvolution.h?rev=70661&r1=70660&r2=70661&view=diff

==============================================================================
--- llvm/trunk/include/llvm/Analysis/ScalarEvolution.h (original)
+++ llvm/trunk/include/llvm/Analysis/ScalarEvolution.h Sun May  3 00:46:20 2009
@@ -24,7 +24,6 @@
 #include "llvm/Pass.h"
 #include "llvm/Analysis/LoopInfo.h"
 #include "llvm/Support/DataTypes.h"
-#include "llvm/Support/ValueHandle.h"
 #include <iosfwd>
 
 namespace llvm {
@@ -193,23 +192,11 @@
   template<> struct simplify_type<SCEVHandle>
     : public simplify_type<const SCEVHandle> {};
 
-  /// SCEVCallbackVH - A CallbackVH to arrange for ScalarEvolution to be
-  /// notified whenever a Value is deleted.
-  class SCEVCallbackVH : public CallbackVH {
-    ScalarEvolution *SE;
-    virtual void deleted();
-    virtual void allUsesReplacedWith(Value *V);
-  public:
-    SCEVCallbackVH(Value *V, ScalarEvolution *SE = 0);
-  };
-
   /// ScalarEvolution - This class is the main scalar evolution driver.  Because
   /// client code (intentionally) can't do much with the SCEV objects directly,
   /// they must ask this class for services.
   ///
   class ScalarEvolution : public FunctionPass {
-    friend class SCEVCallbackVH;
-
     /// F - The function we are analyzing.
     ///
     Function *F;
@@ -228,7 +215,7 @@
 
     /// Scalars - This is a cache of the scalars we have analyzed so far.
     ///
-    std::map<SCEVCallbackVH, SCEVHandle> Scalars;
+    std::map<Value*, SCEVHandle> Scalars;
 
     /// BackedgeTakenInfo - Information about the backedge-taken count
     /// of a loop. This currently inclues an exact count and a maximum count.
@@ -500,6 +487,11 @@
     /// is deleted.
     void forgetLoopBackedgeTakenCount(const Loop *L);
 
+    /// deleteValueFromRecords - This method should be called by the
+    /// client before it removes a Value from the program, to make sure
+    /// that no dangling references are left around.
+    void deleteValueFromRecords(Value *V);
+
     virtual bool runOnFunction(Function &F);
     virtual void releaseMemory();
     virtual void getAnalysisUsage(AnalysisUsage &AU) const;

Modified: llvm/trunk/include/llvm/Transforms/Utils/BasicBlockUtils.h
URL: http://llvm.org/viewvc/llvm-project/llvm/trunk/include/llvm/Transforms/Utils/BasicBlockUtils.h?rev=70661&r1=70660&r2=70661&view=diff

==============================================================================
--- llvm/trunk/include/llvm/Transforms/Utils/BasicBlockUtils.h (original)
+++ llvm/trunk/include/llvm/Transforms/Utils/BasicBlockUtils.h Sun May  3 00:46:20 2009
@@ -25,6 +25,7 @@
 class Instruction;
 class Pass;
 class AliasAnalysis;
+class ValueDeletionListener;
 
 /// DeleteDeadBlock - Delete the specified block, which must have no
 /// predecessors.
@@ -40,8 +41,9 @@
 /// DeleteDeadPHIs - Examine each PHI in the given block and delete it if it
 /// is dead. Also recursively delete any operands that become dead as
 /// a result. This includes tracing the def-use list from the PHI to see if
-/// it is ultimately unused or if it reaches an unused cycle.
-void DeleteDeadPHIs(BasicBlock *BB);
+/// it is ultimately unused or if it reaches an unused cycle.  If a
+/// ValueDeletionListener is specified, it is notified of the deletions.
+void DeleteDeadPHIs(BasicBlock *BB, ValueDeletionListener *VDL = 0);
 
 /// MergeBlockIntoPredecessor - Attempts to merge a block into its predecessor,
 /// if possible.  The return value indicates success or failure.

Modified: llvm/trunk/include/llvm/Transforms/Utils/Local.h
URL: http://llvm.org/viewvc/llvm-project/llvm/trunk/include/llvm/Transforms/Utils/Local.h?rev=70661&r1=70660&r2=70661&view=diff

==============================================================================
--- llvm/trunk/include/llvm/Transforms/Utils/Local.h (original)
+++ llvm/trunk/include/llvm/Transforms/Utils/Local.h Sun May  3 00:46:20 2009
@@ -50,17 +50,40 @@
 ///
 bool isInstructionTriviallyDead(Instruction *I);
 
+/// ValueDeletionListener - A simple abstract interface for delivering
+/// notifications when Values are deleted.
+///
+/// @todo Consider whether ValueDeletionListener can be made obsolete by
+///       requiring clients to use CallbackVH instead.
+class ValueDeletionListener {
+public:
+  /// ValueWillBeDeleted - This method is called shortly before the specified
+  /// value will be deleted.
+  virtual void ValueWillBeDeleted(Value *V) = 0;
+
+protected:
+  virtual ~ValueDeletionListener();
+};
+
 /// RecursivelyDeleteTriviallyDeadInstructions - If the specified value is a
 /// trivially dead instruction, delete it.  If that makes any of its operands
 /// trivially dead, delete them too, recursively.
-void RecursivelyDeleteTriviallyDeadInstructions(Value *V);
+///
+/// If a ValueDeletionListener is specified, it is notified of instructions that
+/// are actually deleted (before they are actually deleted).
+void RecursivelyDeleteTriviallyDeadInstructions(Value *V,
+                                                ValueDeletionListener *VDL = 0);
 
 /// RecursivelyDeleteDeadPHINode - If the specified value is an effectively
 /// dead PHI node, due to being a def-use chain of single-use nodes that
 /// either forms a cycle or is terminated by a trivially dead instruction,
 /// delete it.  If that makes any of its operands trivially dead, delete them
 /// too, recursively.
-void RecursivelyDeleteDeadPHINode(PHINode *PN);
+///
+/// If a ValueDeletionListener is specified, it is notified of instructions that
+/// are actually deleted (before they are actually deleted).
+void RecursivelyDeleteDeadPHINode(PHINode *PN,
+                                  ValueDeletionListener *VDL = 0);
 
 //===----------------------------------------------------------------------===//
 //  Control Flow Graph Restructuring.

Modified: llvm/trunk/lib/Analysis/ScalarEvolution.cpp
URL: http://llvm.org/viewvc/llvm-project/llvm/trunk/lib/Analysis/ScalarEvolution.cpp?rev=70661&r1=70660&r2=70661&view=diff

==============================================================================
--- llvm/trunk/lib/Analysis/ScalarEvolution.cpp (original)
+++ llvm/trunk/lib/Analysis/ScalarEvolution.cpp Sun May  3 00:46:20 2009
@@ -1466,6 +1466,34 @@
 //            Basic SCEV Analysis and PHI Idiom Recognition Code
 //
 
+/// deleteValueFromRecords - This method should be called by the
+/// client before it removes an instruction from the program, to make sure
+/// that no dangling references are left around.
+void ScalarEvolution::deleteValueFromRecords(Value *V) {
+  SmallVector<Value *, 16> Worklist;
+
+  if (Scalars.erase(V)) {
+    if (PHINode *PN = dyn_cast<PHINode>(V))
+      ConstantEvolutionLoopExitValue.erase(PN);
+    Worklist.push_back(V);
+  }
+
+  while (!Worklist.empty()) {
+    Value *VV = Worklist.back();
+    Worklist.pop_back();
+
+    for (Instruction::use_iterator UI = VV->use_begin(), UE = VV->use_end();
+         UI != UE; ++UI) {
+      Instruction *Inst = cast<Instruction>(*UI);
+      if (Scalars.erase(Inst)) {
+        if (PHINode *PN = dyn_cast<PHINode>(VV))
+          ConstantEvolutionLoopExitValue.erase(PN);
+        Worklist.push_back(Inst);
+      }
+    }
+  }
+}
+
 /// isSCEVable - Test if values of the given type are analyzable within
 /// the SCEV framework. This primarily includes integer types, and it
 /// can optionally include pointer types if the ScalarEvolution class
@@ -1527,10 +1555,10 @@
 SCEVHandle ScalarEvolution::getSCEV(Value *V) {
   assert(isSCEVable(V->getType()) && "Value is not SCEVable!");
 
-  std::map<SCEVCallbackVH, SCEVHandle>::iterator I = Scalars.find(V);
+  std::map<Value*, SCEVHandle>::iterator I = Scalars.find(V);
   if (I != Scalars.end()) return I->second;
   SCEVHandle S = createSCEV(V);
-  Scalars.insert(std::make_pair(SCEVCallbackVH(V, this), S));
+  Scalars.insert(std::make_pair(V, S));
   return S;
 }
 
@@ -1619,8 +1647,7 @@
 void ScalarEvolution::
 ReplaceSymbolicValueWithConcrete(Instruction *I, const SCEVHandle &SymName,
                                  const SCEVHandle &NewVal) {
-  std::map<SCEVCallbackVH, SCEVHandle>::iterator SI =
-    Scalars.find(SCEVCallbackVH(I, this));
+  std::map<Value*, SCEVHandle>::iterator SI = Scalars.find(I);
   if (SI == Scalars.end()) return;
 
   SCEVHandle NV =
@@ -1652,7 +1679,7 @@
         SCEVHandle SymbolicName = getUnknown(PN);
         assert(Scalars.find(PN) == Scalars.end() &&
                "PHI node already processed?");
-        Scalars.insert(std::make_pair(SCEVCallbackVH(PN, this), SymbolicName));
+        Scalars.insert(std::make_pair(PN, SymbolicName));
 
         // Using this symbolic name for the PHI, analyze the value coming around
         // the back-edge.
@@ -2104,7 +2131,7 @@
 void ScalarEvolution::forgetLoopPHIs(const Loop *L) {
   for (BasicBlock::iterator I = L->getHeader()->begin();
        PHINode *PN = dyn_cast<PHINode>(I); ++I)
-    Scalars.erase(PN);
+    deleteValueFromRecords(PN);
 }
 
 /// ComputeBackedgeTakenCount - Compute the number of times the backedge
@@ -3317,25 +3344,6 @@
 
 
 //===----------------------------------------------------------------------===//
-//                   SCEVCallbackVH Class Implementation
-//===----------------------------------------------------------------------===//
-
-void SCEVCallbackVH::deleted() {
-  assert(SE && "SCEVCallbackVH called with a non-null ScalarEvolution!");
-  SE->Scalars.erase(getValPtr());
-  // this now dangles!
-}
-
-void SCEVCallbackVH::allUsesReplacedWith(Value *V) {
-  assert(SE && "SCEVCallbackVH called with a non-null ScalarEvolution!");
-  SE->Scalars.erase(getValPtr());
-  // this now dangles!
-}
-
-SCEVCallbackVH::SCEVCallbackVH(Value *V, ScalarEvolution *se)
-  : CallbackVH(V), SE(se) {}
-
-//===----------------------------------------------------------------------===//
 //                   ScalarEvolution Class Implementation
 //===----------------------------------------------------------------------===//
 

Modified: llvm/trunk/lib/Transforms/Scalar/IndVarSimplify.cpp
URL: http://llvm.org/viewvc/llvm-project/llvm/trunk/lib/Transforms/Scalar/IndVarSimplify.cpp?rev=70661&r1=70660&r2=70661&view=diff

==============================================================================
--- llvm/trunk/lib/Transforms/Scalar/IndVarSimplify.cpp (original)
+++ llvm/trunk/lib/Transforms/Scalar/IndVarSimplify.cpp Sun May  3 00:46:20 2009
@@ -124,6 +124,7 @@
       for (unsigned i = 0, e = I->getNumOperands(); i != e; ++i)
         if (Instruction *U = dyn_cast<Instruction>(I->getOperand(i)))
           Insts.insert(U);
+      SE->deleteValueFromRecords(I);
       DOUT << "INDVARS: Deleting: " << *I;
       I->eraseFromParent();
       Changed = true;
@@ -307,6 +308,7 @@
         // the PHI entirely.  This is safe, because the NewVal won't be variant
         // in the loop, so we don't need an LCSSA phi node anymore.
         if (NumPreds == 1) {
+          SE->deleteValueFromRecords(PN);
           PN->replaceAllUsesWith(ExitVal);
           PN->eraseFromParent();
           break;

Modified: llvm/trunk/lib/Transforms/Scalar/LoopDeletion.cpp
URL: http://llvm.org/viewvc/llvm-project/llvm/trunk/lib/Transforms/Scalar/LoopDeletion.cpp?rev=70661&r1=70660&r2=70661&view=diff

==============================================================================
--- llvm/trunk/lib/Transforms/Scalar/LoopDeletion.cpp (original)
+++ llvm/trunk/lib/Transforms/Scalar/LoopDeletion.cpp Sun May  3 00:46:20 2009
@@ -246,6 +246,13 @@
     DT.eraseNode(*LI);
     if (DF) DF->removeBlock(*LI);
 
+    // Remove instructions that we're deleting from ScalarEvolution.
+    for (BasicBlock::iterator BI = (*LI)->begin(), BE = (*LI)->end();
+         BI != BE; ++BI)
+      SE.deleteValueFromRecords(BI);
+    
+    SE.deleteValueFromRecords(*LI);
+    
     // Remove the block from the reference counting scheme, so that we can
     // delete it freely later.
     (*LI)->dropAllReferences();

Modified: llvm/trunk/lib/Transforms/Scalar/LoopStrengthReduce.cpp
URL: http://llvm.org/viewvc/llvm-project/llvm/trunk/lib/Transforms/Scalar/LoopStrengthReduce.cpp?rev=70661&r1=70660&r2=70661&view=diff

==============================================================================
--- llvm/trunk/lib/Transforms/Scalar/LoopStrengthReduce.cpp (original)
+++ llvm/trunk/lib/Transforms/Scalar/LoopStrengthReduce.cpp Sun May  3 00:46:20 2009
@@ -253,6 +253,8 @@
     if (I == 0 || !isInstructionTriviallyDead(I))
       continue;
 
+    SE->deleteValueFromRecords(I);
+
     for (User::op_iterator OI = I->op_begin(), E = I->op_end(); OI != E; ++OI) {
       if (Instruction *U = dyn_cast<Instruction>(*OI)) {
         *OI = 0;
@@ -2128,6 +2130,7 @@
 
     // Remove the old compare instruction. The old indvar is probably dead too.
     DeadInsts.push_back(cast<Instruction>(CondUse->OperandValToReplace));
+    SE->deleteValueFromRecords(OldCond);
     OldCond->replaceAllUsesWith(Cond);
     OldCond->eraseFromParent();
 
@@ -2248,12 +2251,16 @@
                  Cond->getOperand(0), NewRHS, "scmp", Cond);
 
   // Delete the max calculation instructions.
+  SE->deleteValueFromRecords(Cond);
   Cond->replaceAllUsesWith(NewCond);
   Cond->eraseFromParent();
   Instruction *Cmp = cast<Instruction>(Sel->getOperand(0));
+  SE->deleteValueFromRecords(Sel);
   Sel->eraseFromParent();
-  if (Cmp->use_empty())
+  if (Cmp->use_empty()) {
+    SE->deleteValueFromRecords(Cmp);
     Cmp->eraseFromParent();
+  }
   CondUse->User = NewCond;
   return NewCond;
 }
@@ -2360,6 +2367,7 @@
       NewPH->addIncoming(NewIncr, PH->getIncomingBlock(Latch));
 
       /* Remove cast operation */
+      SE->deleteValueFromRecords(ShadowUse);
       ShadowUse->replaceAllUsesWith(NewPH);
       ShadowUse->eraseFromParent();
       SI->second.Users.erase(CandidateUI);
@@ -2499,8 +2507,17 @@
     DeleteTriviallyDeadInstructions();
 
   // At this point, it is worth checking to see if any recurrence PHIs are also
-  // dead, so that we can remove them as well.
-  DeleteDeadPHIs(L->getHeader());
+  // dead, so that we can remove them as well. To keep ScalarEvolution
+  // current, use a ValueDeletionListener class.
+  struct LSRListener : public ValueDeletionListener {
+    ScalarEvolution &SE;
+    explicit LSRListener(ScalarEvolution &se) : SE(se) {}
+
+    virtual void ValueWillBeDeleted(Value *V) {
+      SE.deleteValueFromRecords(V);
+    }
+  } VDL(*SE);
+  DeleteDeadPHIs(L->getHeader(), &VDL);
 
   return Changed;
 }

Modified: llvm/trunk/lib/Transforms/Utils/BasicBlockUtils.cpp
URL: http://llvm.org/viewvc/llvm-project/llvm/trunk/lib/Transforms/Utils/BasicBlockUtils.cpp?rev=70661&r1=70660&r2=70661&view=diff

==============================================================================
--- llvm/trunk/lib/Transforms/Utils/BasicBlockUtils.cpp (original)
+++ llvm/trunk/lib/Transforms/Utils/BasicBlockUtils.cpp Sun May  3 00:46:20 2009
@@ -78,8 +78,9 @@
 /// DeleteDeadPHIs - Examine each PHI in the given block and delete it if it
 /// is dead. Also recursively delete any operands that become dead as
 /// a result. This includes tracing the def-use list from the PHI to see if
-/// it is ultimately unused or if it reaches an unused cycle.
-void llvm::DeleteDeadPHIs(BasicBlock *BB) {
+/// it is ultimately unused or if it reaches an unused cycle.  If a
+/// ValueDeletionListener is specified, it is notified of the deletions.
+void llvm::DeleteDeadPHIs(BasicBlock *BB, ValueDeletionListener *VDL) {
   // Recursively deleting a PHI may cause multiple PHIs to be deleted
   // or RAUW'd undef, so use an array of WeakVH for the PHIs to delete.
   SmallVector<WeakVH, 8> PHIs;
@@ -89,7 +90,7 @@
 
   for (unsigned i = 0, e = PHIs.size(); i != e; ++i)
     if (PHINode *PN = dyn_cast_or_null<PHINode>(PHIs[i].operator Value*()))
-      RecursivelyDeleteDeadPHINode(PN);
+      RecursivelyDeleteDeadPHINode(PN, VDL);
 }
 
 /// MergeBlockIntoPredecessor - Attempts to merge a block into its predecessor,

Modified: llvm/trunk/lib/Transforms/Utils/Local.cpp
URL: http://llvm.org/viewvc/llvm-project/llvm/trunk/lib/Transforms/Utils/Local.cpp?rev=70661&r1=70660&r2=70661&view=diff

==============================================================================
--- llvm/trunk/lib/Transforms/Utils/Local.cpp (original)
+++ llvm/trunk/lib/Transforms/Utils/Local.cpp Sun May  3 00:46:20 2009
@@ -178,10 +178,18 @@
   return false;
 }
 
+/// ~ValueDeletionListener - A trivial dtor, defined out of line to give the
+/// class a home.
+llvm::ValueDeletionListener::~ValueDeletionListener() {}
+
 /// RecursivelyDeleteTriviallyDeadInstructions - If the specified value is a
 /// trivially dead instruction, delete it.  If that makes any of its operands
 /// trivially dead, delete them too, recursively.
-void llvm::RecursivelyDeleteTriviallyDeadInstructions(Value *V) {
+///
+/// If a ValueDeletionListener is specified, it is notified of instructions that
+/// are actually deleted (before they are actually deleted).
+void llvm::RecursivelyDeleteTriviallyDeadInstructions(Value *V,
+                                                   ValueDeletionListener *VDL) {
   Instruction *I = dyn_cast<Instruction>(V);
   if (!I || !I->use_empty() || !isInstructionTriviallyDead(I))
     return;
@@ -193,6 +201,10 @@
     I = DeadInsts.back();
     DeadInsts.pop_back();
 
+    // If the client wanted to know, tell it about deleted instructions.
+    if (VDL)
+      VDL->ValueWillBeDeleted(I);
+    
     // Null out all of the instruction's operands to see if any operand becomes
     // dead as we go.
     for (unsigned i = 0, e = I->getNumOperands(); i != e; ++i) {
@@ -218,8 +230,11 @@
 /// either forms a cycle or is terminated by a trivially dead instruction,
 /// delete it.  If that makes any of its operands trivially dead, delete them
 /// too, recursively.
+///
+/// If a ValueDeletionListener is specified, it is notified of instructions that
+/// are actually deleted (before they are actually deleted).
 void
-llvm::RecursivelyDeleteDeadPHINode(PHINode *PN) {
+llvm::RecursivelyDeleteDeadPHINode(PHINode *PN, ValueDeletionListener *VDL) {
 
   // We can remove a PHI if it is on a cycle in the def-use graph
   // where each node in the cycle has degree one, i.e. only one use,
@@ -238,7 +253,7 @@
       if (!PHIs.insert(cast<PHINode>(JP))) {
         // Break the cycle and delete the PHI and its operands.
         JP->replaceAllUsesWith(UndefValue::get(JP->getType()));
-        RecursivelyDeleteTriviallyDeadInstructions(JP);
+        RecursivelyDeleteTriviallyDeadInstructions(JP, VDL);
         break;
       }
 }





More information about the llvm-commits mailing list