diff --git a/include/llvm/Pass.h b/include/llvm/Pass.h index 2cf85d4dc47..4f027a418d1 100644 --- a/include/llvm/Pass.h +++ b/include/llvm/Pass.h @@ -24,16 +24,20 @@ #include #include +#include class Value; class BasicBlock; class Function; class Module; class AnalysisUsage; -class AnalysisID; class PassInfo; template 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 *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 diff --git a/include/llvm/PassAnalysisSupport.h b/include/llvm/PassAnalysisSupport.h index c105c390c55..e59399d48fe 100644 --- a/include/llvm/PassAnalysisSupport.h +++ b/include/llvm/PassAnalysisSupport.h @@ -15,59 +15,6 @@ // 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 -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()); - // - template - static AnalysisID create() { - return AnalysisID(NextID++, CreatePass); - } - - // 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(), 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 diff --git a/include/llvm/PassSupport.h b/include/llvm/PassSupport.h index e3c8ba75b59..f9360b7f089 100644 --- a/include/llvm/PassSupport.h +++ b/include/llvm/PassSupport.h @@ -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 *); diff --git a/lib/Analysis/IPA/CallGraph.cpp b/lib/Analysis/IPA/CallGraph.cpp index dfb5de68de0..709c1942f63 100644 --- a/lib/Analysis/IPA/CallGraph.cpp +++ b/lib/Analysis/IPA/CallGraph.cpp @@ -46,8 +46,7 @@ #include static RegisterAnalysis X("callgraph", "Call Graph Construction"); - -AnalysisID CallGraph::ID(AnalysisID::create()); +AnalysisID CallGraph::ID = X; // getNodeFor - Return the node for the specified function or create one if it // does not already exist. diff --git a/lib/Analysis/IPA/FindUnsafePointerTypes.cpp b/lib/Analysis/IPA/FindUnsafePointerTypes.cpp index 2678fcf07d4..425c154ecf7 100644 --- a/lib/Analysis/IPA/FindUnsafePointerTypes.cpp +++ b/lib/Analysis/IPA/FindUnsafePointerTypes.cpp @@ -25,7 +25,7 @@ static RegisterAnalysis X("unsafepointertypes", "Find Unsafe Pointer Types"); -AnalysisID FindUnsafePointerTypes::ID(AnalysisID::create()); +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; diff --git a/lib/Analysis/IPA/FindUsedTypes.cpp b/lib/Analysis/IPA/FindUsedTypes.cpp index 1139cf3df8b..6f12612c4ef 100644 --- a/lib/Analysis/IPA/FindUsedTypes.cpp +++ b/lib/Analysis/IPA/FindUsedTypes.cpp @@ -13,7 +13,7 @@ static RegisterAnalysis X("printusedtypes", "Find Used Types"); -AnalysisID FindUsedTypes::ID(AnalysisID::create()); +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); diff --git a/lib/Analysis/InductionVariable.cpp b/lib/Analysis/InductionVariable.cpp index f7b72e5b9c4..485586a018c 100644 --- a/lib/Analysis/InductionVariable.cpp +++ b/lib/Analysis/InductionVariable.cpp @@ -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"; +} diff --git a/lib/Analysis/Interval.cpp b/lib/Analysis/Interval.cpp index a4aa88abdbc..8ba8980a47e 100644 --- a/lib/Analysis/Interval.cpp +++ b/lib/Analysis/Interval.cpp @@ -8,6 +8,7 @@ #include "llvm/Analysis/Interval.h" #include "llvm/BasicBlock.h" #include "llvm/Support/CFG.h" +#include //===----------------------------------------------------------------------===// // 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(o, "\n")); + + o << "Interval Predecessors:\n"; + std::copy(Predecessors.begin(), Predecessors.end(), + std::ostream_iterator(o, "\n")); + + o << "Interval Successors:\n"; + std::copy(Successors.begin(), Successors.end(), + std::ostream_iterator(o, "\n")); +} diff --git a/lib/Analysis/IntervalPartition.cpp b/lib/Analysis/IntervalPartition.cpp index 5e6bf9ca4da..2e8668ae5d4 100644 --- a/lib/Analysis/IntervalPartition.cpp +++ b/lib/Analysis/IntervalPartition.cpp @@ -13,7 +13,7 @@ using std::make_pair; static RegisterAnalysis X("intervals", "Interval Partition Construction"); -AnalysisID IntervalPartition::ID(AnalysisID::create(), 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(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). diff --git a/lib/Analysis/LoopInfo.cpp b/lib/Analysis/LoopInfo.cpp index c53cc9038c9..ff5e2fa9dc6 100644 --- a/lib/Analysis/LoopInfo.cpp +++ b/lib/Analysis/LoopInfo.cpp @@ -10,12 +10,13 @@ #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 static RegisterAnalysis X("loops", "Natural Loop Construction"); -AnalysisID LoopInfo::ID(AnalysisID::create(), true); +AnalysisID LoopInfo::ID = X; //===----------------------------------------------------------------------===// // Loop implementation @@ -24,6 +25,29 @@ bool Loop::contains(const BasicBlock *BB) const { return find(Blocks.begin(), Blocks.end(), BB) != Blocks.end(); } +void Loop::print(std::ostream &OS) const { + OS << std::string(getLoopDepth()*2, ' ') << "Loop Containing: "; + + 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(OS, "\n")); +} + +//===----------------------------------------------------------------------===// +// LoopInfo implementation +// + +bool LoopInfo::runOnFunction(Function &) { + releaseMemory(); + Calculate(getAnalysis()); // Update + return false; +} + void LoopInfo::releaseMemory() { for (std::vector::iterator I = TopLevelLoops.begin(), E = TopLevelLoops.end(); I != E; ++I) @@ -34,15 +58,6 @@ void LoopInfo::releaseMemory() { } -//===----------------------------------------------------------------------===// -// LoopInfo implementation -// -bool LoopInfo::runOnFunction(Function &) { - releaseMemory(); - Calculate(getAnalysis()); // Update - return false; -} - 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(OS, "\n")); +} Loop *LoopInfo::ConsiderForLoop(BasicBlock *BB, const DominatorSet &DS) { if (BBMap.find(BB) != BBMap.end()) return 0; // Havn't processed this node? diff --git a/lib/Analysis/PostDominators.cpp b/lib/Analysis/PostDominators.cpp index 9b35d16b904..9c960e3b0d4 100644 --- a/lib/Analysis/PostDominators.cpp +++ b/lib/Analysis/PostDominators.cpp @@ -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 B("postdomset", "Post-Dominator Set Construction"); -AnalysisID DominatorSet::ID(AnalysisID::create(), true); -AnalysisID PostDominatorSet::ID(AnalysisID::create(), 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 &BBs) { + for (set::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 D("postidom", "Immediate Post-Dominators Construction"); -AnalysisID ImmediateDominators::ID(AnalysisID::create(), true); -AnalysisID ImmediatePostDominators::ID(AnalysisID::create(), 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 F("postdomtree", "Post-Dominator Tree Construction"); -AnalysisID DominatorTree::ID(AnalysisID::create(), true); -AnalysisID PostDominatorTree::ID(AnalysisID::create(), 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 H("postdomfrontier", "Post-Dominance Frontier Construction"); -AnalysisID DominanceFrontier::ID(AnalysisID::create(), true); -AnalysisID PostDominanceFrontier::ID(AnalysisID::create(), 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 index 80a8f91e476..00000000000 --- a/lib/Analysis/Writer.cpp +++ /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 -#include -#include -#include -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(o, "\n")); - - o << "Interval Predecessors:\n"; - copy(I->Predecessors.begin(), I->Predecessors.end(), - std::ostream_iterator(o, "\n")); - - o << "Interval Successors:\n"; - copy(I->Successors.begin(), I->Successors.end(), - std::ostream_iterator(o, "\n")); -} - -void WriteToOutput(const IntervalPartition &IP, ostream &o) { - copy(IP.begin(), IP.end(), std::ostream_iterator(o, "\n")); -} - - - -//===----------------------------------------------------------------------===// -// Dominator Printing Routines -//===----------------------------------------------------------------------===// - -ostream &operator<<(ostream &o, const set &BBs) { - for (set::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(o, "\n")); -} - -void WriteToOutput(const LoopInfo &LI, ostream &o) { - copy(LI.getTopLevelLoops().begin(), LI.getTopLevelLoops().end(), - std::ostream_iterator(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"; -} diff --git a/lib/Transforms/Scalar/ADCE.cpp b/lib/Transforms/Scalar/ADCE.cpp index 40ae87b5bbf..06301971f73 100644 --- a/lib/Transforms/Scalar/ADCE.cpp +++ b/lib/Transforms/Scalar/ADCE.cpp @@ -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" diff --git a/lib/Transforms/Scalar/IndVarSimplify.cpp b/lib/Transforms/Scalar/IndVarSimplify.cpp index 411ab11fece..ceb057d3459 100644 --- a/lib/Transforms/Scalar/IndVarSimplify.cpp +++ b/lib/Transforms/Scalar/IndVarSimplify.cpp @@ -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) { diff --git a/lib/VMCore/Dominators.cpp b/lib/VMCore/Dominators.cpp index 9b35d16b904..9c960e3b0d4 100644 --- a/lib/VMCore/Dominators.cpp +++ b/lib/VMCore/Dominators.cpp @@ -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 B("postdomset", "Post-Dominator Set Construction"); -AnalysisID DominatorSet::ID(AnalysisID::create(), true); -AnalysisID PostDominatorSet::ID(AnalysisID::create(), 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 &BBs) { + for (set::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 D("postidom", "Immediate Post-Dominators Construction"); -AnalysisID ImmediateDominators::ID(AnalysisID::create(), true); -AnalysisID ImmediatePostDominators::ID(AnalysisID::create(), 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 F("postdomtree", "Post-Dominator Tree Construction"); -AnalysisID DominatorTree::ID(AnalysisID::create(), true); -AnalysisID PostDominatorTree::ID(AnalysisID::create(), 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 H("postdomfrontier", "Post-Dominance Frontier Construction"); -AnalysisID DominanceFrontier::ID(AnalysisID::create(), true); -AnalysisID PostDominanceFrontier::ID(AnalysisID::create(), 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/VMCore/Pass.cpp b/lib/VMCore/Pass.cpp index d8315609931..fb751b5db05 100644 --- a/lib/VMCore/Pass.cpp +++ b/lib/VMCore/Pass.cpp @@ -22,7 +22,7 @@ // static std::vector 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 *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 // diff --git a/lib/VMCore/PassManagerT.h b/lib/VMCore/PassManagerT.h index fb8c08ea6d2..46aefb72f55 100644 --- a/lib/VMCore/PassManagerT.h +++ b/lib/VMCore/PassManagerT.h @@ -297,7 +297,7 @@ public: for (std::vector::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