mirror of
https://github.com/RPCS3/llvm.git
synced 2024-11-27 05:30:29 +00:00
* Standardize how analysis results/passes as printed with the print() virtual
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
This commit is contained in:
parent
97f51a3024
commit
a59cbb2043
@ -24,16 +24,20 @@
|
||||
|
||||
#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
|
||||
|
@ -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<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
|
||||
|
@ -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 *);
|
||||
|
@ -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.
|
||||
|
@ -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;
|
||||
|
@ -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);
|
||||
|
@ -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";
|
||||
}
|
||||
|
@ -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"));
|
||||
}
|
||||
|
@ -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).
|
||||
|
@ -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 <algorithm>
|
||||
|
||||
static RegisterAnalysis<LoopInfo>
|
||||
X("loops", "Natural Loop Construction");
|
||||
AnalysisID LoopInfo::ID(AnalysisID::create<LoopInfo>(), 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<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)
|
||||
@ -34,15 +58,6 @@ void LoopInfo::releaseMemory() {
|
||||
}
|
||||
|
||||
|
||||
//===----------------------------------------------------------------------===//
|
||||
// LoopInfo implementation
|
||||
//
|
||||
bool LoopInfo::runOnFunction(Function &) {
|
||||
releaseMemory();
|
||||
Calculate(getAnalysis<DominatorSet>()); // 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<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?
|
||||
|
@ -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";
|
||||
}
|
||||
}
|
||||
|
@ -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";
|
||||
}
|
@ -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"
|
||||
|
@ -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) {
|
||||
|
@ -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";
|
||||
}
|
||||
}
|
||||
|
@ -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
|
||||
//
|
||||
|
@ -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
|
||||
|
Loading…
Reference in New Issue
Block a user