* Standardize how analysis results/passes as printed with the print() virtual
authorChris Lattner <sabre@nondot.org>
Sat, 27 Jul 2002 01:12:17 +0000 (01:12 +0000)
committerChris Lattner <sabre@nondot.org>
Sat, 27 Jul 2002 01:12:17 +0000 (01:12 +0000)
  methods
* Eliminate AnalysisID:  Now it is just a typedef for const PassInfo*
* Simplify how AnalysisID's are initialized
* Eliminate Analysis/Writer.cpp/.h: incorporate printing functionality into
  the analyses themselves.

git-svn-id: https://llvm.org/svn/llvm-project/llvm/trunk@3116 91177308-0d34-0410-b5e6-96231b3b80d8

17 files changed:
include/llvm/Pass.h
include/llvm/PassAnalysisSupport.h
include/llvm/PassSupport.h
lib/Analysis/IPA/CallGraph.cpp
lib/Analysis/IPA/FindUnsafePointerTypes.cpp
lib/Analysis/IPA/FindUsedTypes.cpp
lib/Analysis/InductionVariable.cpp
lib/Analysis/Interval.cpp
lib/Analysis/IntervalPartition.cpp
lib/Analysis/LoopInfo.cpp
lib/Analysis/PostDominators.cpp
lib/Analysis/Writer.cpp [deleted file]
lib/Transforms/Scalar/ADCE.cpp
lib/Transforms/Scalar/IndVarSimplify.cpp
lib/VMCore/Dominators.cpp
lib/VMCore/Pass.cpp
lib/VMCore/PassManagerT.h

index 2cf85d4dc47bfd9d9870a130139c506055959644..4f027a418d115f2cdcd5248b422a5b4935e3b472 100644 (file)
 
 #include <vector>
 #include <map>
+#include <iosfwd>
 class Value;
 class BasicBlock;
 class Function;
 class Module;
 class AnalysisUsage;
-class AnalysisID;
 class PassInfo;
 template<class UnitType> class PassManagerT;
 struct AnalysisResolver;
 
+// AnalysisID - Use the PassInfo to identify a pass...
+typedef const PassInfo* AnalysisID;
+
+
 //===----------------------------------------------------------------------===//
 // Pass interface - Implemented by all 'passes'.  Subclass this if you are an
 // interprocedural optimization or you do not fit into any of the more
@@ -61,6 +65,18 @@ public:
   //
   virtual bool run(Module &M) = 0;
 
+  // print - Print out the internal state of the pass.  This is called by
+  // Analyze to print out the contents of an analysis.  Otherwise it is not
+  // neccesary to implement this method.  Beware that the module pointer MAY be
+  // null.  This automatically forwards to a virtual function that does not
+  // provide the Module* in case the analysis doesn't need it it can just be
+  // ignored.
+  //
+  virtual void print(std::ostream &O, const Module *M) const { print(O); }
+  virtual void print(std::ostream &O) const;
+  void dump() const; // dump - call print(std::cerr, 0);
+
+
   // getAnalysisUsage - This function should be overriden by passes that need
   // analysis information to do their job.  If a pass specifies that it uses a
   // particular analysis result to this function, it can then use the
@@ -117,6 +133,9 @@ private:
   virtual void addToPassManager(PassManagerT<Module> *PM, AnalysisUsage &AU);
 };
 
+inline std::ostream &operator<<(std::ostream &OS, const Pass &P) {
+  P.print(OS, 0); return OS;
+}
 
 //===----------------------------------------------------------------------===//
 // FunctionPass class - This class is used to implement most global
index c105c390c55b5b2a2aa4e8105585cbff19ac27c7..e59399d48fe73eb74486b4d530ac735f88ebcb7e 100644 (file)
 // No need to include Pass.h, we are being included by it!
 
 
-// CreatePass - Helper template to invoke the constructor for the AnalysisID
-// class. Note that this should be a template internal to AnalysisID, but
-// GCC 2.95.3 crashes if we do that, doh.
-//
-template<class AnalysisType>
-static Pass *CreatePass() { return new AnalysisType(); }
-
-//===----------------------------------------------------------------------===//
-// AnalysisID - This class is used to uniquely identify an analysis pass that
-//              is referenced by a transformation.
-//
-class AnalysisID {
-  static unsigned NextID;               // Next ID # to deal out...
-  unsigned ID;                          // Unique ID for this analysis
-  Pass *(*Constructor)();               // Constructor to return the Analysis
-
-  AnalysisID();                         // Disable default ctor
-  AnalysisID(unsigned id, Pass *(*Ct)()) : ID(id), Constructor(Ct) {}
-public:
-  // create - the only way to define a new AnalysisID.  This static method is
-  // supposed to be used to define the class static AnalysisID's that are
-  // provided by analysis passes.  In the implementation (.cpp) file for the
-  // class, there should be a line that looks like this (using CallGraph as an
-  // example):
-  //
-  //  AnalysisID CallGraph::ID(AnalysisID::create<CallGraph>());
-  //
-  template<class AnalysisType>
-  static AnalysisID create() {
-    return AnalysisID(NextID++, CreatePass<AnalysisType>);
-  }
-
-  // Special Copy Constructor - This is how analysis passes declare that they
-  // only depend on the CFG of the function they are working on, so they are not
-  // invalidated by other passes that do not modify the CFG.  This should be
-  // used like this:
-  // AnalysisID DominatorSet::ID(AnalysisID::create<DominatorSet>(), true);
-  //
-  AnalysisID(const AnalysisID &AID, bool DependsOnlyOnCFG = false);
-
-
-  inline Pass *createPass() const { return Constructor(); }
-
-  inline bool operator==(const AnalysisID &A) const {
-    return A.ID == ID;
-  }
-  inline bool operator!=(const AnalysisID &A) const {
-    return A.ID != ID;
-  }
-  inline bool operator<(const AnalysisID &A) const {
-    return ID < A.ID;
-  }
-};
 
 //===----------------------------------------------------------------------===//
 // AnalysisUsage - Represent the analysis usage information of a pass.  This
index e3c8ba75b59caf64cb0ff3ae8b34d81ae47ab042..f9360b7f089f5514fbcf7c25108e9180925c85a0 100644 (file)
@@ -77,6 +77,13 @@ public:
     return NormalCtor;
   }
 
+  // createPass() - Use this 
+  Pass *createPass() const {
+    assert(NormalCtor &&
+           "Cannot call createPass on PassInfo without default ctor!");
+    return NormalCtor();
+  }
+
   // getDataCtor - Return a pointer to a function that creates an instance of
   // the pass and returns it.  This returns a constructor for a version of the
   // pass that takes a TArgetData object as a parameter.
@@ -111,6 +118,8 @@ struct RegisterPassBase {
 
   ~RegisterPassBase();   // Intentionally non-virtual...
 
+  inline operator PassInfo* () const { return PIObj; }
+
 protected:
   PassInfo *PIObj;       // The PassInfo object for this pass
   void registerPass(PassInfo *);
index dfb5de68de0ccf0f4831895fc8349339dc56a543..709c1942f631d105df3485c92c919358992f91a8 100644 (file)
@@ -46,8 +46,7 @@
 #include <algorithm>
 
 static RegisterAnalysis<CallGraph> X("callgraph", "Call Graph Construction");
-
-AnalysisID CallGraph::ID(AnalysisID::create<CallGraph>());
+AnalysisID CallGraph::ID = X;
 
 // getNodeFor - Return the node for the specified function or create one if it
 // does not already exist.
index 2678fcf07d46e00eff339b87c5abcf1508d5c7e1..425c154ecf7514b2860866624308f38021b7367b 100644 (file)
@@ -25,7 +25,7 @@
 
 static RegisterAnalysis<FindUnsafePointerTypes>
 X("unsafepointertypes", "Find Unsafe Pointer Types");
-AnalysisID FindUnsafePointerTypes::ID(AnalysisID::create<FindUnsafePointerTypes>());
+AnalysisID FindUnsafePointerTypes::ID = X;
 
 // Provide a command line option to turn on printing of which instructions cause
 // a type to become invalid
@@ -77,8 +77,7 @@ bool FindUnsafePointerTypes::run(Module &Mod) {
 // printResults - Loop over the results of the analysis, printing out unsafe
 // types.
 //
-void FindUnsafePointerTypes::printResults(const Module *M,
-                                          std::ostream &o) const {
+void FindUnsafePointerTypes::print(std::ostream &o, const Module *M) const {
   if (UnsafeTypes.empty()) {
     o << "SafePointerAccess Analysis: No unsafe types found!\n";
     return;
index 1139cf3df8b96d644c569085e86ecc35648e3ab2..6f12612c4efe76902f1204b2647f1e770bd74832 100644 (file)
@@ -13,7 +13,7 @@
 
 static RegisterAnalysis<FindUsedTypes>
 X("printusedtypes", "Find Used Types");
-AnalysisID FindUsedTypes::ID(AnalysisID::create<FindUsedTypes>());
+AnalysisID FindUsedTypes::ID = X;
 
 // IncorporateType - Incorporate one type and all of its subtypes into the
 // collection of used types.
@@ -68,7 +68,7 @@ bool FindUsedTypes::run(Module &m) {
 // passed in, then the types are printed symbolically if possible, using the
 // symbol table from the module.
 //
-void FindUsedTypes::printTypes(std::ostream &o, const Module *M) const {
+void FindUsedTypes::print(std::ostream &o, const Module *M) const {
   o << "Types in use by this module:\n";
   if (M) {
     CachedWriter CW(M, o);
index f7b72e5b9c4614d03fe495ccd14d6682832ce3c9..485586a018cd0f66ce9f15806da0a0b2c6c6c6fb 100644 (file)
@@ -23,6 +23,7 @@
 #include "llvm/InstrTypes.h"
 #include "llvm/Type.h"
 #include "llvm/Constants.h"
+#include "llvm/Assembly/Writer.h"
 
 using analysis::ExprType;
 
@@ -154,3 +155,24 @@ InductionVariable::InductionVariable(PHINode *P, LoopInfo *LoopInfo) {
   // Classify the induction variable type now...
   InductionType = InductionVariable::Classify(Start, Step, L);
 }
+
+void InductionVariable::print(std::ostream &o) const {
+  switch (InductionType) {
+  case InductionVariable::Cannonical:   o << "Cannonical ";   break;
+  case InductionVariable::SimpleLinear: o << "SimpleLinear "; break;
+  case InductionVariable::Linear:       o << "Linear ";       break;
+  case InductionVariable::Unknown:      o << "Unrecognized "; break;
+  }
+  o << "Induction Variable";
+  if (Phi) {
+    WriteAsOperand(o, Phi);
+    o << ":\n" << Phi;
+  } else {
+    o << "\n";
+  }
+  if (InductionType == InductionVariable::Unknown) return;
+
+  o << "  Start ="; WriteAsOperand(o, Start);
+  o << "  Step =" ; WriteAsOperand(o, Step);
+  o << "\n";
+}
index a4aa88abdbc946edc1dc4872e899eb822ae78fe9..8ba8980a47ebdea427e84e0abd95ba2028daf95a 100644 (file)
@@ -8,6 +8,7 @@
 #include "llvm/Analysis/Interval.h"
 #include "llvm/BasicBlock.h"
 #include "llvm/Support/CFG.h"
+#include <algorithm>
 
 //===----------------------------------------------------------------------===//
 // Interval Implementation
@@ -26,3 +27,19 @@ bool Interval::isLoop() const {
 }
 
 
+void Interval::print(ostream &o) const {
+  o << "-------------------------------------------------------------\n"
+       << "Interval Contents:\n";
+  
+  // Print out all of the basic blocks in the interval...
+  std::copy(Nodes.begin(), Nodes.end(), 
+            std::ostream_iterator<BasicBlock*>(o, "\n"));
+
+  o << "Interval Predecessors:\n";
+  std::copy(Predecessors.begin(), Predecessors.end(), 
+            std::ostream_iterator<BasicBlock*>(o, "\n"));
+  
+  o << "Interval Successors:\n";
+  std::copy(Successors.begin(), Successors.end(), 
+            std::ostream_iterator<BasicBlock*>(o, "\n"));
+}
index 5e6bf9ca4da127bd07e4e1f07fcf8053ca855d7d..2e8668ae5d4760237c0528e185b58fccc7f9e285 100644 (file)
@@ -13,7 +13,7 @@ using std::make_pair;
 static RegisterAnalysis<IntervalPartition>
 X("intervals", "Interval Partition Construction");
 
-AnalysisID IntervalPartition::ID(AnalysisID::create<IntervalPartition>(), true);
+AnalysisID IntervalPartition::ID = X;
 
 //===----------------------------------------------------------------------===//
 // IntervalPartition Implementation
@@ -26,6 +26,11 @@ void IntervalPartition::destroy() {
   RootInterval = 0;
 }
 
+void IntervalPartition::print(ostream &O) const {
+  std::copy(begin(), end(),
+            std::ostream_iterator<const Interval *>(O, "\n"));
+}
+
 // addIntervalToPartition - Add an interval to the internal list of intervals,
 // and then add mappings from all of the basic blocks in the interval to the
 // interval itself (in the IntervalMap).
index c53cc9038c90186fa03de2b9bf7c99a50d56e54b..ff5e2fa9dc659ac51cf16473cde7c1340c9d3247 100644 (file)
 #include "llvm/Analysis/LoopInfo.h"
 #include "llvm/Analysis/Dominators.h"
 #include "llvm/Support/CFG.h"
+#include "llvm/Assembly/Writer.h"
 #include "Support/DepthFirstIterator.h"
 #include <algorithm>
 
 static RegisterAnalysis<LoopInfo>
 X("loops", "Natural Loop Construction");
-AnalysisID LoopInfo::ID(AnalysisID::create<LoopInfo>(), true);
+AnalysisID LoopInfo::ID = X;
 
 //===----------------------------------------------------------------------===//
 // Loop implementation
@@ -24,25 +25,39 @@ bool Loop::contains(const BasicBlock *BB) const {
   return find(Blocks.begin(), Blocks.end(), BB) != Blocks.end();
 }
 
-void LoopInfo::releaseMemory() {
-  for (std::vector<Loop*>::iterator I = TopLevelLoops.begin(),
-         E = TopLevelLoops.end(); I != E; ++I)
-    delete *I;   // Delete all of the loops...
+void Loop::print(std::ostream &OS) const {
+  OS << std::string(getLoopDepth()*2, ' ') << "Loop Containing: ";
 
-  BBMap.clear();                             // Reset internal state of analysis
-  TopLevelLoops.clear();
-}
+  for (unsigned i = 0; i < getBlocks().size(); ++i) {
+    if (i) OS << ",";
+    WriteAsOperand(OS, (const Value*)getBlocks()[i]);
+  }
+  OS << "\n";
 
+  std::copy(getSubLoops().begin(), getSubLoops().end(),
+            std::ostream_iterator<const Loop*>(OS, "\n"));
+}
 
 //===----------------------------------------------------------------------===//
 // LoopInfo implementation
 //
+
 bool LoopInfo::runOnFunction(Function &) {
   releaseMemory();
   Calculate(getAnalysis<DominatorSet>());    // Update
   return false;
 }
 
+void LoopInfo::releaseMemory() {
+  for (std::vector<Loop*>::iterator I = TopLevelLoops.begin(),
+         E = TopLevelLoops.end(); I != E; ++I)
+    delete *I;   // Delete all of the loops...
+
+  BBMap.clear();                             // Reset internal state of analysis
+  TopLevelLoops.clear();
+}
+
+
 void LoopInfo::Calculate(const DominatorSet &DS) {
   BasicBlock *RootNode = DS.getRoot();
 
@@ -61,6 +76,10 @@ void LoopInfo::getAnalysisUsage(AnalysisUsage &AU) const {
   AU.addProvided(ID);
 }
 
+void LoopInfo::print(std::ostream &OS) const {
+  std::copy(getTopLevelLoops().begin(), getTopLevelLoops().end(),
+            std::ostream_iterator<const Loop*>(OS, "\n"));
+}
 
 Loop *LoopInfo::ConsiderForLoop(BasicBlock *BB, const DominatorSet &DS) {
   if (BBMap.find(BB) != BBMap.end()) return 0;   // Havn't processed this node?
index 9b35d16b9047fc01938a36b23bd36992cc001fed..9c960e3b0d43ea9bb7233d75559f815c56ad905a 100644 (file)
@@ -8,6 +8,7 @@
 #include "llvm/Analysis/Dominators.h"
 #include "llvm/Transforms/Utils/UnifyFunctionExitNodes.h"
 #include "llvm/Support/CFG.h"
+#include "llvm/Assembly/Writer.h"
 #include "Support/DepthFirstIterator.h"
 #include "Support/STLExtras.h"
 #include "Support/SetOperations.h"
@@ -23,8 +24,8 @@ A("domset", "Dominator Set Construction");
 static RegisterAnalysis<PostDominatorSet>
 B("postdomset", "Post-Dominator Set Construction");
 
-AnalysisID DominatorSet::ID(AnalysisID::create<DominatorSet>(), true);
-AnalysisID PostDominatorSet::ID(AnalysisID::create<PostDominatorSet>(), true);
+AnalysisID DominatorSet::ID = A;
+AnalysisID PostDominatorSet::ID = B;
 
 // dominates - Return true if A dominates B.  This performs the special checks
 // neccesary if A and B are in the same basic block.
@@ -151,6 +152,22 @@ void PostDominatorSet::getAnalysisUsage(AnalysisUsage &AU) const {
   AU.addRequired(UnifyFunctionExitNodes::ID);
 }
 
+static ostream &operator<<(ostream &o, const set<BasicBlock*> &BBs) {
+  for (set<BasicBlock*>::const_iterator I = BBs.begin(), E = BBs.end();
+       I != E; ++I) {
+    o << "  ";
+    WriteAsOperand(o, *I, false);
+    o << "\n";
+   }
+  return o;
+}
+
+void DominatorSetBase::print(std::ostream &o) const {
+  for (const_iterator I = begin(), E = end(); I != E; ++I)
+    o << "=============================--------------------------------\n"
+      << "\nDominator Set For Basic Block\n" << I->first
+      << "-------------------------------\n" << I->second << "\n";
+}
 
 //===----------------------------------------------------------------------===//
 //  ImmediateDominators Implementation
@@ -161,8 +178,8 @@ C("idom", "Immediate Dominators Construction");
 static RegisterAnalysis<ImmediatePostDominators>
 D("postidom", "Immediate Post-Dominators Construction");
 
-AnalysisID ImmediateDominators::ID(AnalysisID::create<ImmediateDominators>(), true);
-AnalysisID ImmediatePostDominators::ID(AnalysisID::create<ImmediatePostDominators>(), true);
+AnalysisID ImmediateDominators::ID = C;
+AnalysisID ImmediatePostDominators::ID = D;
 
 // calcIDoms - Calculate the immediate dominator mapping, given a set of
 // dominators for every basic block.
@@ -200,6 +217,13 @@ void ImmediateDominatorsBase::calcIDoms(const DominatorSetBase &DS) {
   }
 }
 
+void ImmediateDominatorsBase::print(ostream &o) const {
+  for (const_iterator I = begin(), E = end(); I != E; ++I)
+    o << "=============================--------------------------------\n"
+      << "\nImmediate Dominator For Basic Block\n" << *I->first
+      << "is: \n" << *I->second << "\n";
+}
+
 
 //===----------------------------------------------------------------------===//
 //  DominatorTree Implementation
@@ -210,8 +234,8 @@ E("domtree", "Dominator Tree Construction");
 static RegisterAnalysis<PostDominatorTree>
 F("postdomtree", "Post-Dominator Tree Construction");
 
-AnalysisID DominatorTree::ID(AnalysisID::create<DominatorTree>(), true);
-AnalysisID PostDominatorTree::ID(AnalysisID::create<PostDominatorTree>(), true);
+AnalysisID DominatorTree::ID = E;
+AnalysisID PostDominatorTree::ID = F;
 
 // DominatorTreeBase::reset - Free all of the tree node memory.
 //
@@ -316,6 +340,25 @@ void PostDominatorTree::calculate(const PostDominatorSet &DS) {
   }
 }
 
+static ostream &operator<<(ostream &o, const DominatorTreeBase::Node *Node) {
+  return o << Node->getNode()
+           << "\n------------------------------------------\n";
+}
+
+static void PrintDomTree(const DominatorTreeBase::Node *N, ostream &o,
+                         unsigned Lev) {
+  o << "Level #" << Lev << ":  " << N;
+  for (DominatorTreeBase::Node::const_iterator I = N->begin(), E = N->end(); 
+       I != E; ++I) {
+    PrintDomTree(*I, o, Lev+1);
+  }
+}
+
+void DominatorTreeBase::print(std::ostream &o) const {
+  o << "=============================--------------------------------\n"
+    << "Inorder Dominator Tree:\n";
+  PrintDomTree(Nodes.find(getRoot())->second, o, 1);
+}
 
 
 //===----------------------------------------------------------------------===//
@@ -327,8 +370,8 @@ G("domfrontier", "Dominance Frontier Construction");
 static RegisterAnalysis<PostDominanceFrontier>
 H("postdomfrontier", "Post-Dominance Frontier Construction");
 
-AnalysisID DominanceFrontier::ID(AnalysisID::create<DominanceFrontier>(), true);
-AnalysisID PostDominanceFrontier::ID(AnalysisID::create<PostDominanceFrontier>(), true);
+AnalysisID DominanceFrontier::ID = G;
+AnalysisID PostDominanceFrontier::ID = H;
 
 const DominanceFrontier::DomSetType &
 DominanceFrontier::calculate(const DominatorTree &DT, 
@@ -396,3 +439,12 @@ PostDominanceFrontier::calculate(const PostDominatorTree &DT,
 
   return S;
 }
+
+void DominanceFrontierBase::print(std::ostream &o) const {
+  for (const_iterator I = begin(), E = end(); I != E; ++I) {
+    o << "=============================--------------------------------\n"
+      << "\nDominance Frontier For Basic Block\n";
+    WriteAsOperand(o, I->first, false);
+    o << " is: \n" << I->second << "\n";
+  }
+}
diff --git a/lib/Analysis/Writer.cpp b/lib/Analysis/Writer.cpp
deleted file mode 100644 (file)
index 80a8f91..0000000
+++ /dev/null
@@ -1,163 +0,0 @@
-//===-- Analysis/Writer.cpp - Printing routines for analyses -----*- C++ -*--=//
-//
-// This library file implements analysis result printing support for 
-// llvm/Analysis/Writer.h
-//
-//===----------------------------------------------------------------------===//
-
-#include "llvm/Analysis/Writer.h"
-#include "llvm/Analysis/IntervalPartition.h"
-#include "llvm/Analysis/Dominators.h"
-#include "llvm/Analysis/LoopInfo.h"
-#include "llvm/Analysis/InductionVariable.h"
-#include "llvm/Assembly/Writer.h"
-#include "llvm/Module.h"
-#include <iterator>
-#include <algorithm>
-#include <string>
-#include <iostream>
-using std::ostream;
-using std::set;
-using std::vector;
-using std::string;
-
-//===----------------------------------------------------------------------===//
-//  Interval Printing Routines
-//===----------------------------------------------------------------------===//
-
-void WriteToOutput(const Interval *I, ostream &o) {
-  o << "-------------------------------------------------------------\n"
-       << "Interval Contents:\n";
-  
-  // Print out all of the basic blocks in the interval...
-  copy(I->Nodes.begin(), I->Nodes.end(), 
-       std::ostream_iterator<BasicBlock*>(o, "\n"));
-
-  o << "Interval Predecessors:\n";
-  copy(I->Predecessors.begin(), I->Predecessors.end(), 
-       std::ostream_iterator<BasicBlock*>(o, "\n"));
-  
-  o << "Interval Successors:\n";
-  copy(I->Successors.begin(), I->Successors.end(), 
-       std::ostream_iterator<BasicBlock*>(o, "\n"));
-}
-
-void WriteToOutput(const IntervalPartition &IP, ostream &o) {
-  copy(IP.begin(), IP.end(), std::ostream_iterator<const Interval *>(o, "\n"));
-}
-
-
-
-//===----------------------------------------------------------------------===//
-//  Dominator Printing Routines
-//===----------------------------------------------------------------------===//
-
-ostream &operator<<(ostream &o, const set<BasicBlock*> &BBs) {
-  for (set<BasicBlock*>::const_iterator I = BBs.begin(), E = BBs.end();
-       I != E; ++I) {
-    o << "  ";
-    WriteAsOperand(o, (Value*)*I, false);
-    o << "\n";
-   }
-  return o;
-}
-
-void WriteToOutput(const DominatorSetBase &DS, ostream &o) {
-  for (DominatorSetBase::const_iterator I = DS.begin(), E = DS.end();
-       I != E; ++I) {
-    o << "=============================--------------------------------\n"
-      << "\nDominator Set For Basic Block\n" << I->first
-      << "-------------------------------\n" << I->second << "\n";
-  }
-}
-
-
-void WriteToOutput(const ImmediateDominatorsBase &ID, ostream &o) {
-  for (ImmediateDominatorsBase::const_iterator I = ID.begin(), E = ID.end();
-       I != E; ++I) {
-    o << "=============================--------------------------------\n"
-      << "\nImmediate Dominator For Basic Block\n" << *I->first
-      << "is: \n" << *I->second << "\n";
-  }
-}
-
-
-static ostream &operator<<(ostream &o, const DominatorTreeBase::Node *Node) {
-  return o << Node->getNode() << "\n------------------------------------------\n";
-          
-}
-
-static void PrintDomTree(const DominatorTreeBase::Node *N, ostream &o,
-                         unsigned Lev) {
-  o << "Level #" << Lev << ":  " << N;
-  for (DominatorTreeBase::Node::const_iterator I = N->begin(), E = N->end(); 
-       I != E; ++I) {
-    PrintDomTree(*I, o, Lev+1);
-  }
-}
-
-void WriteToOutput(const DominatorTreeBase &DT, ostream &o) {
-  o << "=============================--------------------------------\n"
-    << "Inorder Dominator Tree:\n";
-  PrintDomTree(DT[DT.getRoot()], o, 1);
-}
-
-void WriteToOutput(const DominanceFrontierBase &DF, ostream &o) {
-  for (DominanceFrontierBase::const_iterator I = DF.begin(), E = DF.end();
-       I != E; ++I) {
-    o << "=============================--------------------------------\n"
-      << "\nDominance Frontier For Basic Block\n";
-    WriteAsOperand(o, (Value*)I->first, false);
-    o << " is: \n" << I->second << "\n";
-  }
-}
-
-
-//===----------------------------------------------------------------------===//
-//  Loop Printing Routines
-//===----------------------------------------------------------------------===//
-
-void WriteToOutput(const Loop *L, ostream &o) {
-  o << string(L->getLoopDepth()*2, ' ') << "Loop Containing: ";
-
-  for (unsigned i = 0; i < L->getBlocks().size(); ++i) {
-    if (i) o << ",";
-    WriteAsOperand(o, (const Value*)L->getBlocks()[i]);
-  }
-  o << "\n";
-
-  copy(L->getSubLoops().begin(), L->getSubLoops().end(),
-       std::ostream_iterator<const Loop*>(o, "\n"));
-}
-
-void WriteToOutput(const LoopInfo &LI, ostream &o) {
-  copy(LI.getTopLevelLoops().begin(), LI.getTopLevelLoops().end(),
-       std::ostream_iterator<const Loop*>(o, "\n"));
-}
-
-
-
-//===----------------------------------------------------------------------===//
-//  Induction Variable Printing Routines
-//===----------------------------------------------------------------------===//
-
-void WriteToOutput(const InductionVariable &IV, ostream &o) {
-  switch (IV.InductionType) {
-  case InductionVariable::Cannonical:   o << "Cannonical ";   break;
-  case InductionVariable::SimpleLinear: o << "SimpleLinear "; break;
-  case InductionVariable::Linear:       o << "Linear ";       break;
-  case InductionVariable::Unknown:      o << "Unrecognized "; break;
-  }
-  o << "Induction Variable";
-  if (IV.Phi) {
-    WriteAsOperand(o, (const Value*)IV.Phi);
-    o << ":\n" << (const Value*)IV.Phi;
-  } else {
-    o << "\n";
-  }
-  if (IV.InductionType == InductionVariable::Unknown) return;
-
-  o << "  Start ="; WriteAsOperand(o, IV.Start);
-  o << "  Step =" ; WriteAsOperand(o, IV.Step);
-  o << "\n";
-}
index 40ae87b5bbf28006ba84eddf94f8d59410c0dfc6..06301971f73faaf618646cd6bfd1306a41fea18d 100644 (file)
@@ -10,7 +10,6 @@
 #include "llvm/Transforms/Utils/Local.h"
 #include "llvm/Type.h"
 #include "llvm/Analysis/Dominators.h"
-#include "llvm/Analysis/Writer.h"
 #include "llvm/iTerminators.h"
 #include "llvm/iPHINode.h"
 #include "llvm/Constant.h"
index 411ab11fece088c2fc009ce7faf2cd356426aea9..ceb057d34592bf0094844a71597cd40ede3f897a 100644 (file)
@@ -8,7 +8,6 @@
 #include "llvm/Transforms/Scalar.h"
 #include "llvm/Analysis/InductionVariable.h"
 #include "llvm/Analysis/LoopInfo.h"
-#include "llvm/Analysis/Writer.h"
 #include "llvm/iPHINode.h"
 #include "llvm/iOther.h"
 #include "llvm/Type.h"
@@ -127,7 +126,7 @@ static bool TransformLoop(LoopInfo *Loops, Loop *Loop) {
   for (unsigned i = 0; i < IndVars.size(); ++i) {
     InductionVariable *IV = &IndVars[i];
 
-    DEBUG(std::cerr << IV);
+    DEBUG(IV->print(std::cerr));
 
     // Don't modify the cannonical indvar or unrecognized indvars...
     if (IV != Cannonical && IV->InductionType != InductionVariable::Unknown) {
index 9b35d16b9047fc01938a36b23bd36992cc001fed..9c960e3b0d43ea9bb7233d75559f815c56ad905a 100644 (file)
@@ -8,6 +8,7 @@
 #include "llvm/Analysis/Dominators.h"
 #include "llvm/Transforms/Utils/UnifyFunctionExitNodes.h"
 #include "llvm/Support/CFG.h"
+#include "llvm/Assembly/Writer.h"
 #include "Support/DepthFirstIterator.h"
 #include "Support/STLExtras.h"
 #include "Support/SetOperations.h"
@@ -23,8 +24,8 @@ A("domset", "Dominator Set Construction");
 static RegisterAnalysis<PostDominatorSet>
 B("postdomset", "Post-Dominator Set Construction");
 
-AnalysisID DominatorSet::ID(AnalysisID::create<DominatorSet>(), true);
-AnalysisID PostDominatorSet::ID(AnalysisID::create<PostDominatorSet>(), true);
+AnalysisID DominatorSet::ID = A;
+AnalysisID PostDominatorSet::ID = B;
 
 // dominates - Return true if A dominates B.  This performs the special checks
 // neccesary if A and B are in the same basic block.
@@ -151,6 +152,22 @@ void PostDominatorSet::getAnalysisUsage(AnalysisUsage &AU) const {
   AU.addRequired(UnifyFunctionExitNodes::ID);
 }
 
+static ostream &operator<<(ostream &o, const set<BasicBlock*> &BBs) {
+  for (set<BasicBlock*>::const_iterator I = BBs.begin(), E = BBs.end();
+       I != E; ++I) {
+    o << "  ";
+    WriteAsOperand(o, *I, false);
+    o << "\n";
+   }
+  return o;
+}
+
+void DominatorSetBase::print(std::ostream &o) const {
+  for (const_iterator I = begin(), E = end(); I != E; ++I)
+    o << "=============================--------------------------------\n"
+      << "\nDominator Set For Basic Block\n" << I->first
+      << "-------------------------------\n" << I->second << "\n";
+}
 
 //===----------------------------------------------------------------------===//
 //  ImmediateDominators Implementation
@@ -161,8 +178,8 @@ C("idom", "Immediate Dominators Construction");
 static RegisterAnalysis<ImmediatePostDominators>
 D("postidom", "Immediate Post-Dominators Construction");
 
-AnalysisID ImmediateDominators::ID(AnalysisID::create<ImmediateDominators>(), true);
-AnalysisID ImmediatePostDominators::ID(AnalysisID::create<ImmediatePostDominators>(), true);
+AnalysisID ImmediateDominators::ID = C;
+AnalysisID ImmediatePostDominators::ID = D;
 
 // calcIDoms - Calculate the immediate dominator mapping, given a set of
 // dominators for every basic block.
@@ -200,6 +217,13 @@ void ImmediateDominatorsBase::calcIDoms(const DominatorSetBase &DS) {
   }
 }
 
+void ImmediateDominatorsBase::print(ostream &o) const {
+  for (const_iterator I = begin(), E = end(); I != E; ++I)
+    o << "=============================--------------------------------\n"
+      << "\nImmediate Dominator For Basic Block\n" << *I->first
+      << "is: \n" << *I->second << "\n";
+}
+
 
 //===----------------------------------------------------------------------===//
 //  DominatorTree Implementation
@@ -210,8 +234,8 @@ E("domtree", "Dominator Tree Construction");
 static RegisterAnalysis<PostDominatorTree>
 F("postdomtree", "Post-Dominator Tree Construction");
 
-AnalysisID DominatorTree::ID(AnalysisID::create<DominatorTree>(), true);
-AnalysisID PostDominatorTree::ID(AnalysisID::create<PostDominatorTree>(), true);
+AnalysisID DominatorTree::ID = E;
+AnalysisID PostDominatorTree::ID = F;
 
 // DominatorTreeBase::reset - Free all of the tree node memory.
 //
@@ -316,6 +340,25 @@ void PostDominatorTree::calculate(const PostDominatorSet &DS) {
   }
 }
 
+static ostream &operator<<(ostream &o, const DominatorTreeBase::Node *Node) {
+  return o << Node->getNode()
+           << "\n------------------------------------------\n";
+}
+
+static void PrintDomTree(const DominatorTreeBase::Node *N, ostream &o,
+                         unsigned Lev) {
+  o << "Level #" << Lev << ":  " << N;
+  for (DominatorTreeBase::Node::const_iterator I = N->begin(), E = N->end(); 
+       I != E; ++I) {
+    PrintDomTree(*I, o, Lev+1);
+  }
+}
+
+void DominatorTreeBase::print(std::ostream &o) const {
+  o << "=============================--------------------------------\n"
+    << "Inorder Dominator Tree:\n";
+  PrintDomTree(Nodes.find(getRoot())->second, o, 1);
+}
 
 
 //===----------------------------------------------------------------------===//
@@ -327,8 +370,8 @@ G("domfrontier", "Dominance Frontier Construction");
 static RegisterAnalysis<PostDominanceFrontier>
 H("postdomfrontier", "Post-Dominance Frontier Construction");
 
-AnalysisID DominanceFrontier::ID(AnalysisID::create<DominanceFrontier>(), true);
-AnalysisID PostDominanceFrontier::ID(AnalysisID::create<PostDominanceFrontier>(), true);
+AnalysisID DominanceFrontier::ID = G;
+AnalysisID PostDominanceFrontier::ID = H;
 
 const DominanceFrontier::DomSetType &
 DominanceFrontier::calculate(const DominatorTree &DT, 
@@ -396,3 +439,12 @@ PostDominanceFrontier::calculate(const PostDominatorTree &DT,
 
   return S;
 }
+
+void DominanceFrontierBase::print(std::ostream &o) const {
+  for (const_iterator I = begin(), E = end(); I != E; ++I) {
+    o << "=============================--------------------------------\n"
+      << "\nDominance Frontier For Basic Block\n";
+    WriteAsOperand(o, I->first, false);
+    o << " is: \n" << I->second << "\n";
+  }
+}
index d8315609931ea895ba5cc41436d94d7e00d4a5ae..fb751b5db05de2636231cdf98d51f7e8c5739499 100644 (file)
@@ -22,7 +22,7 @@
 //
 
 static std::vector<AnalysisID> CFGOnlyAnalyses;
-
+#if 0
 // Source of unique analysis ID #'s.
 unsigned AnalysisID::NextID = 0;
 
@@ -35,6 +35,7 @@ AnalysisID::AnalysisID(const AnalysisID &AID, bool DependsOnlyOnCFG) {
   if (DependsOnlyOnCFG)
     CFGOnlyAnalyses.push_back(AID);
 }
+#endif
 
 //===----------------------------------------------------------------------===//
 //   AnalysisResolver Class Implementation
@@ -190,7 +191,8 @@ void PMDebug::PrintAnalysisSetInfo(unsigned Depth, const char *Msg,
   if (PassDebugging >= Details && !Set.empty()) {
     std::cerr << (void*)P << std::string(Depth*2+3, ' ') << Msg << " Analyses:";
     for (unsigned i = 0; i != Set.size(); ++i) {
-      Pass *P = Set[i].createPass();   // Good thing this is just debug code...
+      // FIXME: This can use the local pass map!
+      Pass *P = Set[i]->createPass();   // Good thing this is just debug code...
       std::cerr << "  " << P->getPassName();
       delete P;
     }
@@ -217,6 +219,19 @@ void Pass::addToPassManager(PassManagerT<Module> *PM, AnalysisUsage &AU) {
 //
 const char *Pass::getPassName() const { return typeid(*this).name(); }
 
+// print - Print out the internal state of the pass.  This is called by Analyse
+// to print out the contents of an analysis.  Otherwise it is not neccesary to
+// implement this method.
+//
+void Pass::print(std::ostream &O) const {
+  O << "Pass::print not implemented for pass: '" << getPassName() << "'!\n";
+}
+
+// dump - call print(std::cerr);
+void Pass::dump() const {
+  print(std::cerr, 0);
+}
+
 //===----------------------------------------------------------------------===//
 // FunctionPass Implementation
 //
index fb8c08ea6d28d5a80ebc6a98a143ac73164eb3c9..46aefb72f557c9276fc3b7d87c0e849c19701355 100644 (file)
@@ -297,7 +297,7 @@ public:
     for (std::vector<AnalysisID>::const_iterator I = Required.begin(),
            E = Required.end(); I != E; ++I) {
       if (getAnalysisOrNullDown(*I) == 0)
-        add((PassClass*)I->createPass());
+        add((PassClass*)(*I)->createPass());
     }
 
     // Tell the pass to add itself to this PassManager... the way it does so