Convert analyses to new pass structure
authorChris Lattner <sabre@nondot.org>
Thu, 31 Jan 2002 00:42:27 +0000 (00:42 +0000)
committerChris Lattner <sabre@nondot.org>
Thu, 31 Jan 2002 00:42:27 +0000 (00:42 +0000)
git-svn-id: https://llvm.org/svn/llvm-project/llvm/trunk@1603 91177308-0d34-0410-b5e6-96231b3b80d8

lib/Analysis/IPA/CallGraph.cpp
lib/Analysis/IPA/FindUnsafePointerTypes.cpp
lib/Analysis/IPA/FindUsedTypes.cpp
lib/Analysis/IntervalPartition.cpp
lib/Analysis/LoopInfo.cpp
lib/Analysis/PostDominators.cpp
lib/Transforms/Utils/UnifyFunctionExitNodes.cpp
lib/VMCore/Dominators.cpp
lib/VMCore/Verifier.cpp

index e48cf7fa386aa6cb8d5a4f090bc455e94d7f4789..244c35ea46ec037db0a29cdef5a55ec2af689edf 100644 (file)
@@ -19,6 +19,9 @@
 #include "Support/STLExtras.h"
 #include <algorithm>
 
+AnalysisID cfg::CallGraph::ID(AnalysisID::create<cfg::CallGraph>());
+//AnalysisID cfg::CallGraph::ID(AnalysisID::template AnalysisID<cfg::CallGraph>());
+
 // getNodeFor - Return the node for the specified method or create one if it
 // does not already exist.
 //
@@ -53,7 +56,9 @@ void cfg::CallGraph::addToCallGraph(Method *M) {
   }
 }
 
-cfg::CallGraph::CallGraph(Module *TheModule) {
+bool cfg::CallGraph::run(Module *TheModule) {
+  destroy();
+
   Mod = TheModule;
 
   // Create the root node of the module...
@@ -61,13 +66,16 @@ cfg::CallGraph::CallGraph(Module *TheModule) {
 
   // Add every method to the call graph...
   for_each(Mod->begin(), Mod->end(), bind_obj(this,&CallGraph::addToCallGraph));
+  
+  return false;
 }
 
-cfg::CallGraph::~CallGraph() {
+void cfg::CallGraph::destroy() {
   for (MethodMapTy::iterator I = MethodMap.begin(), E = MethodMap.end();
        I != E; ++I) {
     delete I->second;
   }
+  MethodMap.clear();
 }
 
 
index 85b5da8ce2ef936911d1d614649302156d8b9a3e..bc092920907e1ddfef89a2e907f936ff999e9e47 100644 (file)
 #include "llvm/Analysis/FindUnsafePointerTypes.h"
 #include "llvm/Assembly/CachedWriter.h"
 #include "llvm/Type.h"
+#include "llvm/Instruction.h"
+#include "llvm/Method.h"
+#include "llvm/Module.h"
 #include "Support/CommandLine.h"
 
+AnalysisID FindUnsafePointerTypes::ID(AnalysisID::create<FindUnsafePointerTypes>());
+
 // Provide a command line option to turn on printing of which instructions cause
 // a type to become invalid
 //
@@ -49,22 +54,25 @@ static inline bool isSafeInstruction(const Instruction *I) {
 // values of various types.  If they are deemed to be 'unsafe' note that the
 // type is not safe to transform.
 //
-bool FindUnsafePointerTypes::runOnMethod(Method *Meth) {
-  const Method *M = Meth;  // We don't need/want write access
-  for (Method::const_inst_iterator I = M->inst_begin(), E = M->inst_end();
-       I != E; ++I) {
-    const Instruction *Inst = *I;
-    const Type *ITy = Inst->getType();
-    if (ITy->isPointerType() && !UnsafeTypes.count((PointerType*)ITy))
-      if (!isSafeInstruction(Inst)) {
-        UnsafeTypes.insert((PointerType*)ITy);
+bool FindUnsafePointerTypes::run(Module *Mod) {
+  for (Module::iterator MI = Mod->begin(), ME = Mod->end();
+       MI != ME; ++MI) {
+    const Method *M = *MI;  // We don't need/want write access
+    for (Method::const_inst_iterator I = M->inst_begin(), E = M->inst_end();
+         I != E; ++I) {
+      const Instruction *Inst = *I;
+      const Type *ITy = Inst->getType();
+      if (ITy->isPointerType() && !UnsafeTypes.count((PointerType*)ITy))
+        if (!isSafeInstruction(Inst)) {
+          UnsafeTypes.insert((PointerType*)ITy);
 
-        if (PrintFailures) {
-          CachedWriter CW(M->getParent(), std::cerr);
-          CW << "FindUnsafePointerTypes: Type '" << ITy
-             << "' marked unsafe in '" << Meth->getName() << "' by:\n" << Inst;
+          if (PrintFailures) {
+            CachedWriter CW(M->getParent(), std::cerr);
+            CW << "FindUnsafePointerTypes: Type '" << ITy
+               << "' marked unsafe in '" << M->getName() << "' by:\n" << Inst;
+          }
         }
-      }
+    }
   }
 
   return false;
@@ -74,7 +82,8 @@ bool FindUnsafePointerTypes::runOnMethod(Method *Meth) {
 // printResults - Loop over the results of the analysis, printing out unsafe
 // types.
 //
-void FindUnsafePointerTypes::printResults(const Module *M, std::ostream &o) {
+void FindUnsafePointerTypes::printResults(const Module *M,
+                                          std::ostream &o) const {
   if (UnsafeTypes.empty()) {
     o << "SafePointerAccess Analysis: No unsafe types found!\n";
     return;
@@ -90,3 +99,11 @@ void FindUnsafePointerTypes::printResults(const Module *M, std::ostream &o) {
     CW << " #" << Counter << ". " << (Value*)*I << "\n";
   }
 }
+
+// getAnalysisUsageInfo - Of course, we provide ourself...
+//
+void FindUnsafePointerTypes::getAnalysisUsageInfo(Pass::AnalysisSet &Required,
+                                                  Pass::AnalysisSet &Destroyed,
+                                                  Pass::AnalysisSet &Provided) {
+  Provided.push_back(FindUnsafePointerTypes::ID);
+}
index c439407cb13c8d3654bd00bbc1121df082d0e8ac..b876e5e68d8d2db7dbd41cb342f1f67e939e50aa 100644 (file)
@@ -9,6 +9,11 @@
 #include "llvm/SymbolTable.h"
 #include "llvm/GlobalVariable.h"
 #include "llvm/DerivedTypes.h"
+#include "llvm/Module.h"
+#include "llvm/Method.h"
+
+AnalysisID FindUsedTypes::ID(AnalysisID::create<FindUsedTypes>());
+AnalysisID FindUsedTypes::IncludeSymbolTableID(AnalysisID::create<FindUsedTypes>());
 
 // IncorporateType - Incorporate one type and all of its subtypes into the
 // collection of used types.
@@ -34,43 +39,39 @@ void FindUsedTypes::IncorporateSymbolTable(const SymbolTable *ST) {
   assert(0 && "Unimp");
 }
 
-
-// doInitialization - This loops over global constants defined in the
-// module, converting them to their new type.
+// doPerMethodWork - This incorporates all types used by the specified method
 //
-bool FindUsedTypes::doInitialization(Module *m) {
-  const Module *M = m;
-  if (IncludeSymbolTables && M->hasSymbolTable())
-    IncorporateSymbolTable(M->getSymbolTable()); // Add symtab first...
+bool FindUsedTypes::run(Module *m) {
+  UsedTypes.clear();  // reset if run multiple times...
+
+  if (IncludeSymbolTables && m->hasSymbolTable())
+    IncorporateSymbolTable(m->getSymbolTable()); // Add symtab first...
 
   // Loop over global variables, incorporating their types
-  for (Module::const_giterator I = M->gbegin(), E = M->gend(); I != E; ++I)
+  for (Module::const_giterator I = m->gbegin(), E = m->gend(); I != E; ++I)
     IncorporateType((*I)->getType());
-  return false;
-}
 
-// doPerMethodWork - This incorporates all types used by the specified method
-//
-bool FindUsedTypes::runOnMethod(Method *m) {
-  const Method *M = m;
-  if (IncludeSymbolTables && M->hasSymbolTable())
-  IncorporateSymbolTable(M->getSymbolTable()); // Add symtab first...
+  for (Module::iterator MI = m->begin(), ME = m->end(); MI != ME; ++MI) {
+    const Method *M = *MI;
+    if (IncludeSymbolTables && M->hasSymbolTable())
+      IncorporateSymbolTable(M->getSymbolTable()); // Add symtab first...
   
-  // Loop over all of the instructions in the method, adding their return type
-  // as well as the types of their operands.
-  //
-  for (Method::const_inst_iterator II = M->inst_begin(), IE = M->inst_end();
-       II != IE; ++II) {
-    const Instruction *I = *II;
-    const Type *Ty = I->getType();
+    // Loop over all of the instructions in the method, adding their return type
+    // as well as the types of their operands.
+    //
+    for (Method::const_inst_iterator II = M->inst_begin(), IE = M->inst_end();
+         II != IE; ++II) {
+      const Instruction *I = *II;
+      const Type *Ty = I->getType();
     
-    IncorporateType(Ty);  // Incorporate the type of the instruction
-    for (User::const_op_iterator OI = I->op_begin(), OE = I->op_end();
-         OI != OE; ++OI)
-      if ((*OI)->getType() != Ty)          // Avoid set lookup in common case
-        IncorporateType((*OI)->getType()); // Insert inst operand types as well
+      IncorporateType(Ty);  // Incorporate the type of the instruction
+      for (User::const_op_iterator OI = I->op_begin(), OE = I->op_end();
+           OI != OE; ++OI)
+        if ((*OI)->getType() != Ty)         // Avoid set lookup in common case
+          IncorporateType((*OI)->getType());// Insert inst operand types as well
+    }
   }
-  
   return false;
 }
 
@@ -90,3 +91,11 @@ void FindUsedTypes::printTypes(std::ostream &o, const Module *M = 0) const {
            E = UsedTypes.end(); I != E; ++I)
       o << "  " << *I << "\n";
 }
+
+// getAnalysisUsageInfo - Of course, we provide ourself...
+//
+void FindUsedTypes::getAnalysisUsageInfo(Pass::AnalysisSet &Required,
+                                         Pass::AnalysisSet &Destroyed,
+                                         Pass::AnalysisSet &Provided) {
+  Provided.push_back(FindUsedTypes::ID);
+}
index fff8d224e21017c80d0b6787e4efda6150702efb..f524d016f16843c9f4fe3a176068d359590efd56 100644 (file)
 using namespace cfg;
 using std::make_pair;
 
+AnalysisID IntervalPartition::ID(AnalysisID::create<IntervalPartition>());
+
 //===----------------------------------------------------------------------===//
 // IntervalPartition Implementation
 //===----------------------------------------------------------------------===//
 
-// Destructor - Free memory
-IntervalPartition::~IntervalPartition() {
+// destroy - Reset state back to before method was analyzed
+void IntervalPartition::destroy() {
   for_each(begin(), end(), deleter<cfg::Interval>);
+  IntervalMap.clear();
+  RootInterval = 0;
 }
 
 // addIntervalToPartition - Add an interval to the internal list of intervals,
@@ -48,7 +52,7 @@ void IntervalPartition::updatePredecessors(cfg::Interval *Int) {
 // IntervalPartition ctor - Build the first level interval partition for the
 // specified method...
 //
-IntervalPartition::IntervalPartition(Method *M) {
+bool IntervalPartition::runOnMethod(Method *M) {
   assert(M->front() && "Cannot operate on prototypes!");
 
   // Pass false to intervals_begin because we take ownership of it's memory
@@ -67,6 +71,7 @@ IntervalPartition::IntervalPartition(Method *M) {
   // predecessors for each block...
   for_each(begin(), end(), 
           bind_obj(this, &IntervalPartition::updatePredecessors));
+  return false;
 }
 
 
index ed91ca8bd5f7982775fc99bb63835199a805a0a6..9b34095e4f2477c07d07e0d68905d8f8175896c5 100644 (file)
 #include "Support/DepthFirstIterator.h"
 #include <algorithm>
 
+AnalysisID cfg::LoopInfo::ID(AnalysisID::create<cfg::LoopInfo>());
+
+//===----------------------------------------------------------------------===//
+// cfg::Loop implementation
+//
 bool cfg::Loop::contains(const BasicBlock *BB) const {
   return find(Blocks.begin(), Blocks.end(), BB) != Blocks.end();
 }
 
-cfg::LoopInfo::LoopInfo(const DominatorSet &DS) {
+
+//===----------------------------------------------------------------------===//
+// cfg::LoopInfo implementation
+//
+bool cfg::LoopInfo::runOnMethod(Method *M) {
+  BBMap.clear();                             // Reset internal state of analysis
+  TopLevelLoops.clear();
+  Calculate(getAnalysis<DominatorSet>());    // Update
+  return false;
+}
+
+void cfg::LoopInfo::Calculate(const DominatorSet &DS) {
   const BasicBlock *RootNode = DS.getRoot();
 
   for (df_iterator<const BasicBlock*> NI = df_begin(RootNode),
@@ -29,6 +45,14 @@ cfg::LoopInfo::LoopInfo(const DominatorSet &DS) {
     TopLevelLoops[i]->setLoopDepth(1);
 }
 
+void cfg::LoopInfo::getAnalysisUsageInfo(Pass::AnalysisSet &Required,
+                                         Pass::AnalysisSet &Destroyed,
+                                         Pass::AnalysisSet &Provided) {
+  Required.push_back(DominatorSet::ID);
+  Provided.push_back(ID);
+}
+
+
 cfg::Loop *cfg::LoopInfo::ConsiderForLoop(const BasicBlock *BB,
                                          const DominatorSet &DS) {
   if (BBMap.find(BB) != BBMap.end()) return 0;   // Havn't processed this node?
index 2e4f6e4df1fff5f78396d695ef1d3fe9afc51553..f3e66137771115dcdaf01a5adcdf3ed9d5282891 100644 (file)
@@ -5,7 +5,7 @@
 //===----------------------------------------------------------------------===//
 
 #include "llvm/Analysis/Dominators.h"
-#include "llvm/Analysis/SimplifyCFG.h"   // To get cfg::UnifyAllExitNodes
+#include "llvm/Transforms/UnifyMethodExitNodes.h"
 #include "llvm/Method.h"
 #include "Support/DepthFirstIterator.h"
 #include "Support/STLExtras.h"
@@ -31,31 +31,28 @@ void set_intersect(set<Ty> &S1, const set<Ty2> &S2) {
 }
 
 //===----------------------------------------------------------------------===//
-//  DominatorBase Implementation
+//  DominatorSet Implementation
 //===----------------------------------------------------------------------===//
 
-bool cfg::DominatorBase::isPostDominator() const { 
-  // Root can be null if there is no exit node from the CFG and is postdom set
-  return Root == 0 || Root != Root->getParent()->front();
-}
-
+AnalysisID cfg::DominatorSet::ID(AnalysisID::create<cfg::DominatorSet>());
+AnalysisID cfg::DominatorSet::PostDomID(AnalysisID::create<cfg::DominatorSet>());
 
-//===----------------------------------------------------------------------===//
-//  DominatorSet Implementation
-//===----------------------------------------------------------------------===//
+bool cfg::DominatorSet::runOnMethod(Method *M) {
+  Doms.clear();   // Reset from the last time we were run...
 
-// DominatorSet ctor - Build either the dominator set or the post-dominator
-// set for a method...
-//
-cfg::DominatorSet::DominatorSet(const Method *M) : DominatorBase(M->front()) {
-  calcForwardDominatorSet(M);
+  if (isPostDominator())
+    calcPostDominatorSet(M);
+  else
+    calcForwardDominatorSet(M);
+  return false;
 }
 
+
 // calcForwardDominatorSet - This method calculates the forward dominator sets
 // for the specified method.
 //
-void cfg::DominatorSet::calcForwardDominatorSet(const Method *M) {
-  assert(Root && M && "Can't build dominator set of null method!");
+void cfg::DominatorSet::calcForwardDominatorSet(Method *M) {
+  Root = M->getEntryNode();
   assert(Root->pred_begin() == Root->pred_end() &&
         "Root node has predecessors in method!");
 
@@ -64,7 +61,7 @@ void cfg::DominatorSet::calcForwardDominatorSet(const Method *M) {
     Changed = false;
 
     DomSetType WorkingSet;
-    df_iterator<const Method*> It = df_begin(M), End = df_end(M);
+    df_iterator<Method*> It = df_begin(M), End = df_end(M);
     for ( ; It != End; ++It) {
       const BasicBlock *BB = *It;
       BasicBlock::pred_const_iterator PI = BB->pred_begin(),
@@ -99,13 +96,15 @@ void cfg::DominatorSet::calcForwardDominatorSet(const Method *M) {
 // only have a single exit node (return stmt), then calculates the post
 // dominance sets for the method.
 //
-cfg::DominatorSet::DominatorSet(Method *M, bool PostDomSet)
-  : DominatorBase(M->front()) {
-  if (!PostDomSet) { calcForwardDominatorSet(M); return; }
+void cfg::DominatorSet::calcPostDominatorSet(Method *M) {
+  // Since we require that the unify all exit nodes pass has been run, we know
+  // that there can be at most one return instruction in the method left.
+  // Get it.
+  //
+  Root = getAnalysis<UnifyMethodExitNodes>().getExitNode();
 
-  Root = cfg::UnifyAllExitNodes(M);
   if (Root == 0) {  // No exit node for the method?  Postdomsets are all empty
-    for (Method::iterator MI = M->begin(), ME = M->end(); MI != ME; ++MI)
+    for (Method::const_iterator MI = M->begin(), ME = M->end(); MI != ME; ++MI)
       Doms[*MI] = DomSetType();
     return;
   }
@@ -116,7 +115,7 @@ cfg::DominatorSet::DominatorSet(Method *M, bool PostDomSet)
 
     set<const BasicBlock*> Visited;
     DomSetType WorkingSet;
-    idf_iterator<const BasicBlock*> It = idf_begin(Root), End = idf_end(Root);
+    idf_iterator<BasicBlock*> It = idf_begin(Root), End = idf_end(Root);
     for ( ; It != End; ++It) {
       const BasicBlock *BB = *It;
       BasicBlock::succ_const_iterator PI = BB->succ_begin(),
@@ -147,11 +146,26 @@ cfg::DominatorSet::DominatorSet(Method *M, bool PostDomSet)
   } while (Changed);
 }
 
+// getAnalysisUsageInfo - This obviously provides a dominator set, but it also
+// uses the UnifyMethodExitNodes pass if building post-dominators
+//
+void cfg::DominatorSet::getAnalysisUsageInfo(Pass::AnalysisSet &Requires,
+                                             Pass::AnalysisSet &Destroyed,
+                                             Pass::AnalysisSet &Provided) {
+  if (isPostDominator())
+    Requires.push_back(UnifyMethodExitNodes::ID);
+  
+  Provided.push_back(ID);
+}
+
 
 //===----------------------------------------------------------------------===//
 //  ImmediateDominators Implementation
 //===----------------------------------------------------------------------===//
 
+AnalysisID cfg::ImmediateDominators::ID(AnalysisID::create<cfg::ImmediateDominators>());
+AnalysisID cfg::ImmediateDominators::PostDomID(AnalysisID::create<cfg::ImmediateDominators>());
+
 // calcIDoms - Calculate the immediate dominator mapping, given a set of
 // dominators for every basic block.
 void cfg::ImmediateDominators::calcIDoms(const DominatorSet &DS) {
@@ -193,14 +207,20 @@ void cfg::ImmediateDominators::calcIDoms(const DominatorSet &DS) {
 //  DominatorTree Implementation
 //===----------------------------------------------------------------------===//
 
-// DominatorTree dtor - Free all of the tree node memory.
+AnalysisID cfg::DominatorTree::ID(AnalysisID::create<cfg::DominatorTree>());
+AnalysisID cfg::DominatorTree::PostDomID(AnalysisID::create<cfg::DominatorTree>());
+
+// DominatorTree::reset - Free all of the tree node memory.
 //
-cfg::DominatorTree::~DominatorTree() { 
+void cfg::DominatorTree::reset() { 
   for (NodeMapType::iterator I = Nodes.begin(), E = Nodes.end(); I != E; ++I)
     delete I->second;
+  Nodes.clear();
 }
 
 
+#if 0
+// Given immediate dominators, we can also calculate the dominator tree
 cfg::DominatorTree::DominatorTree(const ImmediateDominators &IDoms) 
   : DominatorBase(IDoms.getRoot()) {
   const Method *M = Root->getParent();
@@ -224,13 +244,14 @@ cfg::DominatorTree::DominatorTree(const ImmediateDominators &IDoms)
     }
   }
 }
+#endif
 
 void cfg::DominatorTree::calculate(const DominatorSet &DS) {
   Nodes[Root] = new Node(Root, 0);   // Add a node for the root...
 
   if (!isPostDominator()) {
     // Iterate over all nodes in depth first order...
-    for (df_iterator<const BasicBlock*> I = df_begin(Root), E = df_end(Root);
+    for (df_iterator<BasicBlock*> I = df_begin(Root), E = df_end(Root);
          I != E; ++I) {
       const BasicBlock *BB = *I;
       const DominatorSet::DomSetType &Dominators = DS.getDominators(BB);
@@ -271,7 +292,7 @@ void cfg::DominatorTree::calculate(const DominatorSet &DS) {
     }
   } else if (Root) {
     // Iterate over all nodes in depth first order...
-    for (idf_iterator<const BasicBlock*> I = idf_begin(Root), E = idf_end(Root);
+    for (idf_iterator<BasicBlock*> I = idf_begin(Root), E = idf_end(Root);
          I != E; ++I) {
       const BasicBlock *BB = *I;
       const DominatorSet::DomSetType &Dominators = DS.getDominators(BB);
@@ -290,10 +311,11 @@ void cfg::DominatorTree::calculate(const DominatorSet &DS) {
       DominatorSet::DomSetType::const_iterator I = Dominators.begin();
       DominatorSet::DomSetType::const_iterator End = Dominators.end();
       for (; I != End; ++I) {   // Iterate over dominators...
-       // All of our dominators should form a chain, where the number of elements
-       // in the dominator set indicates what level the node is at in the chain.
-       // We want the node immediately above us, so it will have an identical 
-       // dominator set, except that BB will not dominate it... therefore it's
+       // All of our dominators should form a chain, where the number
+       // of elements in the dominator set indicates what level the
+       // node is at in the chain.  We want the node immediately
+       // above us, so it will have an identical dominator set,
+       // except that BB will not dominate it... therefore it's
        // dominator set size will be one less than BB's...
        //
        if (DS.getDominators(*I).size() == DomSetSize - 1) {
@@ -319,6 +341,9 @@ void cfg::DominatorTree::calculate(const DominatorSet &DS) {
 //  DominanceFrontier Implementation
 //===----------------------------------------------------------------------===//
 
+AnalysisID cfg::DominanceFrontier::ID(AnalysisID::create<cfg::DominanceFrontier>());
+AnalysisID cfg::DominanceFrontier::PostDomID(AnalysisID::create<cfg::DominanceFrontier>());
+
 const cfg::DominanceFrontier::DomSetType &
 cfg::DominanceFrontier::calcDomFrontier(const DominatorTree &DT, 
                                        const DominatorTree::Node *Node) {
index 56c4b204ca9f0c54b38054ccc06d41efd0389d6b..4716e7ebcd8c6376669a82fa5804c6626d6e52d0 100644 (file)
@@ -6,6 +6,7 @@
 //===----------------------------------------------------------------------===//
 
 #include "llvm/Analysis/SimplifyCFG.h"
+#include "llvm/Transforms/UnifyMethodExitNodes.h"
 #include "llvm/BasicBlock.h"
 #include "llvm/Method.h"
 #include "llvm/iTerminators.h"
@@ -13,6 +14,9 @@
 #include "llvm/Type.h"
 using std::vector;
 
+AnalysisID UnifyMethodExitNodes::ID(AnalysisID::create<UnifyMethodExitNodes>());
+
+
 // UnifyAllExitNodes - Unify all exit nodes of the CFG by creating a new
 // BasicBlock, and converting all returns to unconditional branches to this
 // new basic block.  The singular exit node is returned.
index 2e4f6e4df1fff5f78396d695ef1d3fe9afc51553..f3e66137771115dcdaf01a5adcdf3ed9d5282891 100644 (file)
@@ -5,7 +5,7 @@
 //===----------------------------------------------------------------------===//
 
 #include "llvm/Analysis/Dominators.h"
-#include "llvm/Analysis/SimplifyCFG.h"   // To get cfg::UnifyAllExitNodes
+#include "llvm/Transforms/UnifyMethodExitNodes.h"
 #include "llvm/Method.h"
 #include "Support/DepthFirstIterator.h"
 #include "Support/STLExtras.h"
@@ -31,31 +31,28 @@ void set_intersect(set<Ty> &S1, const set<Ty2> &S2) {
 }
 
 //===----------------------------------------------------------------------===//
-//  DominatorBase Implementation
+//  DominatorSet Implementation
 //===----------------------------------------------------------------------===//
 
-bool cfg::DominatorBase::isPostDominator() const { 
-  // Root can be null if there is no exit node from the CFG and is postdom set
-  return Root == 0 || Root != Root->getParent()->front();
-}
-
+AnalysisID cfg::DominatorSet::ID(AnalysisID::create<cfg::DominatorSet>());
+AnalysisID cfg::DominatorSet::PostDomID(AnalysisID::create<cfg::DominatorSet>());
 
-//===----------------------------------------------------------------------===//
-//  DominatorSet Implementation
-//===----------------------------------------------------------------------===//
+bool cfg::DominatorSet::runOnMethod(Method *M) {
+  Doms.clear();   // Reset from the last time we were run...
 
-// DominatorSet ctor - Build either the dominator set or the post-dominator
-// set for a method...
-//
-cfg::DominatorSet::DominatorSet(const Method *M) : DominatorBase(M->front()) {
-  calcForwardDominatorSet(M);
+  if (isPostDominator())
+    calcPostDominatorSet(M);
+  else
+    calcForwardDominatorSet(M);
+  return false;
 }
 
+
 // calcForwardDominatorSet - This method calculates the forward dominator sets
 // for the specified method.
 //
-void cfg::DominatorSet::calcForwardDominatorSet(const Method *M) {
-  assert(Root && M && "Can't build dominator set of null method!");
+void cfg::DominatorSet::calcForwardDominatorSet(Method *M) {
+  Root = M->getEntryNode();
   assert(Root->pred_begin() == Root->pred_end() &&
         "Root node has predecessors in method!");
 
@@ -64,7 +61,7 @@ void cfg::DominatorSet::calcForwardDominatorSet(const Method *M) {
     Changed = false;
 
     DomSetType WorkingSet;
-    df_iterator<const Method*> It = df_begin(M), End = df_end(M);
+    df_iterator<Method*> It = df_begin(M), End = df_end(M);
     for ( ; It != End; ++It) {
       const BasicBlock *BB = *It;
       BasicBlock::pred_const_iterator PI = BB->pred_begin(),
@@ -99,13 +96,15 @@ void cfg::DominatorSet::calcForwardDominatorSet(const Method *M) {
 // only have a single exit node (return stmt), then calculates the post
 // dominance sets for the method.
 //
-cfg::DominatorSet::DominatorSet(Method *M, bool PostDomSet)
-  : DominatorBase(M->front()) {
-  if (!PostDomSet) { calcForwardDominatorSet(M); return; }
+void cfg::DominatorSet::calcPostDominatorSet(Method *M) {
+  // Since we require that the unify all exit nodes pass has been run, we know
+  // that there can be at most one return instruction in the method left.
+  // Get it.
+  //
+  Root = getAnalysis<UnifyMethodExitNodes>().getExitNode();
 
-  Root = cfg::UnifyAllExitNodes(M);
   if (Root == 0) {  // No exit node for the method?  Postdomsets are all empty
-    for (Method::iterator MI = M->begin(), ME = M->end(); MI != ME; ++MI)
+    for (Method::const_iterator MI = M->begin(), ME = M->end(); MI != ME; ++MI)
       Doms[*MI] = DomSetType();
     return;
   }
@@ -116,7 +115,7 @@ cfg::DominatorSet::DominatorSet(Method *M, bool PostDomSet)
 
     set<const BasicBlock*> Visited;
     DomSetType WorkingSet;
-    idf_iterator<const BasicBlock*> It = idf_begin(Root), End = idf_end(Root);
+    idf_iterator<BasicBlock*> It = idf_begin(Root), End = idf_end(Root);
     for ( ; It != End; ++It) {
       const BasicBlock *BB = *It;
       BasicBlock::succ_const_iterator PI = BB->succ_begin(),
@@ -147,11 +146,26 @@ cfg::DominatorSet::DominatorSet(Method *M, bool PostDomSet)
   } while (Changed);
 }
 
+// getAnalysisUsageInfo - This obviously provides a dominator set, but it also
+// uses the UnifyMethodExitNodes pass if building post-dominators
+//
+void cfg::DominatorSet::getAnalysisUsageInfo(Pass::AnalysisSet &Requires,
+                                             Pass::AnalysisSet &Destroyed,
+                                             Pass::AnalysisSet &Provided) {
+  if (isPostDominator())
+    Requires.push_back(UnifyMethodExitNodes::ID);
+  
+  Provided.push_back(ID);
+}
+
 
 //===----------------------------------------------------------------------===//
 //  ImmediateDominators Implementation
 //===----------------------------------------------------------------------===//
 
+AnalysisID cfg::ImmediateDominators::ID(AnalysisID::create<cfg::ImmediateDominators>());
+AnalysisID cfg::ImmediateDominators::PostDomID(AnalysisID::create<cfg::ImmediateDominators>());
+
 // calcIDoms - Calculate the immediate dominator mapping, given a set of
 // dominators for every basic block.
 void cfg::ImmediateDominators::calcIDoms(const DominatorSet &DS) {
@@ -193,14 +207,20 @@ void cfg::ImmediateDominators::calcIDoms(const DominatorSet &DS) {
 //  DominatorTree Implementation
 //===----------------------------------------------------------------------===//
 
-// DominatorTree dtor - Free all of the tree node memory.
+AnalysisID cfg::DominatorTree::ID(AnalysisID::create<cfg::DominatorTree>());
+AnalysisID cfg::DominatorTree::PostDomID(AnalysisID::create<cfg::DominatorTree>());
+
+// DominatorTree::reset - Free all of the tree node memory.
 //
-cfg::DominatorTree::~DominatorTree() { 
+void cfg::DominatorTree::reset() { 
   for (NodeMapType::iterator I = Nodes.begin(), E = Nodes.end(); I != E; ++I)
     delete I->second;
+  Nodes.clear();
 }
 
 
+#if 0
+// Given immediate dominators, we can also calculate the dominator tree
 cfg::DominatorTree::DominatorTree(const ImmediateDominators &IDoms) 
   : DominatorBase(IDoms.getRoot()) {
   const Method *M = Root->getParent();
@@ -224,13 +244,14 @@ cfg::DominatorTree::DominatorTree(const ImmediateDominators &IDoms)
     }
   }
 }
+#endif
 
 void cfg::DominatorTree::calculate(const DominatorSet &DS) {
   Nodes[Root] = new Node(Root, 0);   // Add a node for the root...
 
   if (!isPostDominator()) {
     // Iterate over all nodes in depth first order...
-    for (df_iterator<const BasicBlock*> I = df_begin(Root), E = df_end(Root);
+    for (df_iterator<BasicBlock*> I = df_begin(Root), E = df_end(Root);
          I != E; ++I) {
       const BasicBlock *BB = *I;
       const DominatorSet::DomSetType &Dominators = DS.getDominators(BB);
@@ -271,7 +292,7 @@ void cfg::DominatorTree::calculate(const DominatorSet &DS) {
     }
   } else if (Root) {
     // Iterate over all nodes in depth first order...
-    for (idf_iterator<const BasicBlock*> I = idf_begin(Root), E = idf_end(Root);
+    for (idf_iterator<BasicBlock*> I = idf_begin(Root), E = idf_end(Root);
          I != E; ++I) {
       const BasicBlock *BB = *I;
       const DominatorSet::DomSetType &Dominators = DS.getDominators(BB);
@@ -290,10 +311,11 @@ void cfg::DominatorTree::calculate(const DominatorSet &DS) {
       DominatorSet::DomSetType::const_iterator I = Dominators.begin();
       DominatorSet::DomSetType::const_iterator End = Dominators.end();
       for (; I != End; ++I) {   // Iterate over dominators...
-       // All of our dominators should form a chain, where the number of elements
-       // in the dominator set indicates what level the node is at in the chain.
-       // We want the node immediately above us, so it will have an identical 
-       // dominator set, except that BB will not dominate it... therefore it's
+       // All of our dominators should form a chain, where the number
+       // of elements in the dominator set indicates what level the
+       // node is at in the chain.  We want the node immediately
+       // above us, so it will have an identical dominator set,
+       // except that BB will not dominate it... therefore it's
        // dominator set size will be one less than BB's...
        //
        if (DS.getDominators(*I).size() == DomSetSize - 1) {
@@ -319,6 +341,9 @@ void cfg::DominatorTree::calculate(const DominatorSet &DS) {
 //  DominanceFrontier Implementation
 //===----------------------------------------------------------------------===//
 
+AnalysisID cfg::DominanceFrontier::ID(AnalysisID::create<cfg::DominanceFrontier>());
+AnalysisID cfg::DominanceFrontier::PostDomID(AnalysisID::create<cfg::DominanceFrontier>());
+
 const cfg::DominanceFrontier::DomSetType &
 cfg::DominanceFrontier::calcDomFrontier(const DominatorTree &DT, 
                                        const DominatorTree::Node *Node) {
index 0702e85f0e0cc363cf2dad295ccd176242546fba..02c24aa799c218530e6ed5a196e2ae67f79d0dfb 100644 (file)
@@ -21,7 +21,7 @@
 //  . PHI nodes must have an entry for each predecessor, with no extras.
 //  . All other things that are tested by asserts spread about the code...
 //  . All basic blocks should only end with terminator insts, not contain them
-//  . All methods must have >= 1 basic block
+//  . The entry node to a method must not have predecessors!
 //  . Verify that none of the Value getType()'s are null.
 //  . Method's cannot take a void typed parameter
 //  . Verify that a method's argument list agrees with it's declared type.