[llvm-commits] [llvm] r70645 - 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 14:19:20 PDT 2009


Author: djg
Date: Sat May  2 16:19:20 2009
New Revision: 70645

URL: http://llvm.org/viewvc/llvm-project?rev=70645&view=rev
Log:
Convert ScalarEvolution to use CallbackVH for its internal map. This
makes ScalarEvolution::deleteValueFromRecords, and it's code that
subtly needed to be called before ReplaceAllUsesWith, unnecessary.

It also makes ValueDeletionListener unnecessary.

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=70645&r1=70644&r2=70645&view=diff

==============================================================================
--- llvm/trunk/include/llvm/Analysis/ScalarEvolution.h (original)
+++ llvm/trunk/include/llvm/Analysis/ScalarEvolution.h Sat May  2 16:19:20 2009
@@ -24,6 +24,7 @@
 #include "llvm/Pass.h"
 #include "llvm/Analysis/LoopInfo.h"
 #include "llvm/Support/DataTypes.h"
+#include "llvm/Support/ValueHandle.h"
 #include <iosfwd>
 
 namespace llvm {
@@ -192,11 +193,23 @@
   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;
@@ -215,7 +228,7 @@
 
     /// Scalars - This is a cache of the scalars we have analyzed so far.
     ///
-    std::map<Value*, SCEVHandle> Scalars;
+    std::map<SCEVCallbackVH, SCEVHandle> Scalars;
 
     /// BackedgeTakenInfo - Information about the backedge-taken count
     /// of a loop. This currently inclues an exact count and a maximum count.
@@ -487,11 +500,6 @@
     /// 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=70645&r1=70644&r2=70645&view=diff

==============================================================================
--- llvm/trunk/include/llvm/Transforms/Utils/BasicBlockUtils.h (original)
+++ llvm/trunk/include/llvm/Transforms/Utils/BasicBlockUtils.h Sat May  2 16:19:20 2009
@@ -25,7 +25,6 @@
 class Instruction;
 class Pass;
 class AliasAnalysis;
-class ValueDeletionListener;
 
 /// DeleteDeadBlock - Delete the specified block, which must have no
 /// predecessors.
@@ -41,9 +40,8 @@
 /// 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.  If a
-/// ValueDeletionListener is specified, it is notified of the deletions.
-void DeleteDeadPHIs(BasicBlock *BB, ValueDeletionListener *VDL = 0);
+/// it is ultimately unused or if it reaches an unused cycle.
+void DeleteDeadPHIs(BasicBlock *BB);
 
 /// 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=70645&r1=70644&r2=70645&view=diff

==============================================================================
--- llvm/trunk/include/llvm/Transforms/Utils/Local.h (original)
+++ llvm/trunk/include/llvm/Transforms/Utils/Local.h Sat May  2 16:19:20 2009
@@ -50,40 +50,17 @@
 ///
 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.
-///
-/// 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);
+void RecursivelyDeleteTriviallyDeadInstructions(Value *V);
 
 /// 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.
-///
-/// 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);
+void RecursivelyDeleteDeadPHINode(PHINode *PN);
 
 //===----------------------------------------------------------------------===//
 //  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=70645&r1=70644&r2=70645&view=diff

==============================================================================
--- llvm/trunk/lib/Analysis/ScalarEvolution.cpp (original)
+++ llvm/trunk/lib/Analysis/ScalarEvolution.cpp Sat May  2 16:19:20 2009
@@ -1466,34 +1466,6 @@
 //            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
@@ -1555,10 +1527,10 @@
 SCEVHandle ScalarEvolution::getSCEV(Value *V) {
   assert(isSCEVable(V->getType()) && "Value is not SCEVable!");
 
-  std::map<Value*, SCEVHandle>::iterator I = Scalars.find(V);
+  std::map<SCEVCallbackVH, SCEVHandle>::iterator I = Scalars.find(V);
   if (I != Scalars.end()) return I->second;
   SCEVHandle S = createSCEV(V);
-  Scalars.insert(std::make_pair(V, S));
+  Scalars.insert(std::make_pair(SCEVCallbackVH(V, this), S));
   return S;
 }
 
@@ -1647,7 +1619,8 @@
 void ScalarEvolution::
 ReplaceSymbolicValueWithConcrete(Instruction *I, const SCEVHandle &SymName,
                                  const SCEVHandle &NewVal) {
-  std::map<Value*, SCEVHandle>::iterator SI = Scalars.find(I);
+  std::map<SCEVCallbackVH, SCEVHandle>::iterator SI =
+    Scalars.find(SCEVCallbackVH(I, this));
   if (SI == Scalars.end()) return;
 
   SCEVHandle NV =
@@ -1679,7 +1652,7 @@
         SCEVHandle SymbolicName = getUnknown(PN);
         assert(Scalars.find(PN) == Scalars.end() &&
                "PHI node already processed?");
-        Scalars.insert(std::make_pair(PN, SymbolicName));
+        Scalars.insert(std::make_pair(SCEVCallbackVH(PN, this), SymbolicName));
 
         // Using this symbolic name for the PHI, analyze the value coming around
         // the back-edge.
@@ -2131,7 +2104,7 @@
 void ScalarEvolution::forgetLoopPHIs(const Loop *L) {
   for (BasicBlock::iterator I = L->getHeader()->begin();
        PHINode *PN = dyn_cast<PHINode>(I); ++I)
-    deleteValueFromRecords(PN);
+    Scalars.erase(PN);
 }
 
 /// ComputeBackedgeTakenCount - Compute the number of times the backedge
@@ -3344,6 +3317,25 @@
 
 
 //===----------------------------------------------------------------------===//
+//                   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=70645&r1=70644&r2=70645&view=diff

==============================================================================
--- llvm/trunk/lib/Transforms/Scalar/IndVarSimplify.cpp (original)
+++ llvm/trunk/lib/Transforms/Scalar/IndVarSimplify.cpp Sat May  2 16:19:20 2009
@@ -124,7 +124,6 @@
       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;
@@ -308,7 +307,6 @@
         // 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=70645&r1=70644&r2=70645&view=diff

==============================================================================
--- llvm/trunk/lib/Transforms/Scalar/LoopDeletion.cpp (original)
+++ llvm/trunk/lib/Transforms/Scalar/LoopDeletion.cpp Sat May  2 16:19:20 2009
@@ -246,13 +246,6 @@
     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=70645&r1=70644&r2=70645&view=diff

==============================================================================
--- llvm/trunk/lib/Transforms/Scalar/LoopStrengthReduce.cpp (original)
+++ llvm/trunk/lib/Transforms/Scalar/LoopStrengthReduce.cpp Sat May  2 16:19:20 2009
@@ -253,8 +253,6 @@
     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;
@@ -2130,7 +2128,6 @@
 
     // 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();
 
@@ -2251,16 +2248,12 @@
                  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()) {
-    SE->deleteValueFromRecords(Cmp);
+  if (Cmp->use_empty())
     Cmp->eraseFromParent();
-  }
   CondUse->User = NewCond;
   return NewCond;
 }
@@ -2367,7 +2360,6 @@
       NewPH->addIncoming(NewIncr, PH->getIncomingBlock(Latch));
 
       /* Remove cast operation */
-      SE->deleteValueFromRecords(ShadowUse);
       ShadowUse->replaceAllUsesWith(NewPH);
       ShadowUse->eraseFromParent();
       SI->second.Users.erase(CandidateUI);
@@ -2507,17 +2499,8 @@
     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. 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);
+  // dead, so that we can remove them as well.
+  DeleteDeadPHIs(L->getHeader());
 
   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=70645&r1=70644&r2=70645&view=diff

==============================================================================
--- llvm/trunk/lib/Transforms/Utils/BasicBlockUtils.cpp (original)
+++ llvm/trunk/lib/Transforms/Utils/BasicBlockUtils.cpp Sat May  2 16:19:20 2009
@@ -78,9 +78,8 @@
 /// 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.  If a
-/// ValueDeletionListener is specified, it is notified of the deletions.
-void llvm::DeleteDeadPHIs(BasicBlock *BB, ValueDeletionListener *VDL) {
+/// it is ultimately unused or if it reaches an unused cycle.
+void llvm::DeleteDeadPHIs(BasicBlock *BB) {
   // 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;
@@ -90,7 +89,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, VDL);
+      RecursivelyDeleteDeadPHINode(PN);
 }
 
 /// 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=70645&r1=70644&r2=70645&view=diff

==============================================================================
--- llvm/trunk/lib/Transforms/Utils/Local.cpp (original)
+++ llvm/trunk/lib/Transforms/Utils/Local.cpp Sat May  2 16:19:20 2009
@@ -178,18 +178,10 @@
   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.
-///
-/// 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) {
+void llvm::RecursivelyDeleteTriviallyDeadInstructions(Value *V) {
   Instruction *I = dyn_cast<Instruction>(V);
   if (!I || !I->use_empty() || !isInstructionTriviallyDead(I))
     return;
@@ -201,10 +193,6 @@
     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) {
@@ -230,11 +218,8 @@
 /// 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, ValueDeletionListener *VDL) {
+llvm::RecursivelyDeleteDeadPHINode(PHINode *PN) {
 
   // 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,
@@ -253,7 +238,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, VDL);
+        RecursivelyDeleteTriviallyDeadInstructions(JP);
         break;
       }
 }





More information about the llvm-commits mailing list