Convert analyses over to new Pass framework

git-svn-id: https://llvm.org/svn/llvm-project/llvm/trunk@1595 91177308-0d34-0410-b5e6-96231b3b80d8
This commit is contained in:
Chris Lattner 2002-01-30 23:27:55 +00:00
parent 05ad462d1b
commit facd752d3a
6 changed files with 206 additions and 72 deletions

View File

@ -17,8 +17,7 @@
#define LLVM_ANALYSIS_CALLGRAPH_H #define LLVM_ANALYSIS_CALLGRAPH_H
#include "Support/GraphTraits.h" #include "Support/GraphTraits.h"
#include <map> #include "llvm/Pass.h"
#include <vector>
class Method; class Method;
class Module; class Module;
@ -62,7 +61,7 @@ private: // Stuff to construct the node, used by CallGraph
}; };
class CallGraph { class CallGraph : public Pass {
Module *Mod; // The module this call graph represents Module *Mod; // The module this call graph represents
typedef std::map<const Method *, CallGraphNode *> MethodMapTy; typedef std::map<const Method *, CallGraphNode *> MethodMapTy;
@ -70,8 +69,10 @@ class CallGraph {
CallGraphNode *Root; CallGraphNode *Root;
public: public:
CallGraph(Module *TheModule); static AnalysisID ID; // We are an analysis, we must have an ID
~CallGraph();
CallGraph(AnalysisID AID) : Root(0) { assert(AID == ID); }
~CallGraph() { destroy(); }
typedef MethodMapTy::iterator iterator; typedef MethodMapTy::iterator iterator;
typedef MethodMapTy::const_iterator const_iterator; typedef MethodMapTy::const_iterator const_iterator;
@ -111,7 +112,18 @@ public:
return removeMethodFromModule((*this)[Meth]); return removeMethodFromModule((*this)[Meth]);
} }
// run - Compute the call graph for the specified module.
virtual bool run(Module *TheModule);
// getAnalysisUsageInfo - This obviously provides a call graph
virtual void getAnalysisUsageInfo(AnalysisSet &Required,
AnalysisSet &Destroyed,
AnalysisSet &Provided) {
Provided.push_back(ID);
}
private: // Implementation of CallGraph construction private: // Implementation of CallGraph construction
void destroy();
// getNodeFor - Return the node for the specified method or create one if it // getNodeFor - Return the node for the specified method or create one if it
// does not already exist. // does not already exist.

View File

@ -1,4 +1,4 @@
//===- llvm/Analysis/DominatorSet.h - Dominator Set Calculation --*- C++ -*--=// //===- llvm/Analysis/Dominators.h - Dominator Info Calculation ---*- C++ -*--=//
// //
// This file defines the following classes: // This file defines the following classes:
// 1. DominatorSet: Calculates the [reverse] dominator set for a method // 1. DominatorSet: Calculates the [reverse] dominator set for a method
@ -18,11 +18,8 @@
#ifndef LLVM_DOMINATORS_H #ifndef LLVM_DOMINATORS_H
#define LLVM_DOMINATORS_H #define LLVM_DOMINATORS_H
#include "llvm/Pass.h"
#include <set> #include <set>
#include <map>
#include <vector>
class Method;
class BasicBlock;
namespace cfg { namespace cfg {
@ -31,13 +28,18 @@ namespace cfg {
// DominatorBase - Base class that other, more interesting dominator analyses // DominatorBase - Base class that other, more interesting dominator analyses
// inherit from. // inherit from.
// //
class DominatorBase { class DominatorBase : public MethodPass {
protected: protected:
const BasicBlock *Root; BasicBlock *Root;
inline DominatorBase(const BasicBlock *root = 0) : Root(root) {} const bool IsPostDominators;
inline DominatorBase(bool isPostDom) : Root(0), IsPostDominators(isPostDom) {}
public: public:
inline const BasicBlock *getRoot() const { return Root; } inline const BasicBlock *getRoot() const { return Root; }
bool isPostDominator() const; // Returns true if analysis based of postdoms inline BasicBlock *getRoot() { return Root; }
// Returns true if analysis based of postdoms
bool isPostDominator() const { return IsPostDominators; }
}; };
//===----------------------------------------------------------------------===// //===----------------------------------------------------------------------===//
@ -53,21 +55,28 @@ public:
private: private:
DomSetMapType Doms; DomSetMapType Doms;
void calcForwardDominatorSet(const Method *M); void calcForwardDominatorSet(Method *M);
void calcPostDominatorSet(Method *M);
public: public:
// DominatorSet ctor - Build either the dominator set or the post-dominator // DominatorSet ctor - Build either the dominator set or the post-dominator
// set for a method... Building the postdominator set may require the analysis // set for a method...
// routine to modify the method so that there is only a single return in the
// method.
// //
DominatorSet(const Method *M); static AnalysisID ID; // Build dominator set
DominatorSet( Method *M, bool PostDomSet); static AnalysisID PostDomID; // Build postdominator set
DominatorSet(AnalysisID id) : DominatorBase(id == PostDomID) {}
virtual bool runOnMethod(Method *M);
// Accessor interface: // Accessor interface:
typedef DomSetMapType::const_iterator const_iterator; typedef DomSetMapType::const_iterator const_iterator;
typedef DomSetMapType::iterator iterator;
inline const_iterator begin() const { return Doms.begin(); } inline const_iterator begin() const { return Doms.begin(); }
inline iterator begin() { return Doms.begin(); }
inline const_iterator end() const { return Doms.end(); } inline const_iterator end() const { return Doms.end(); }
inline iterator end() { return Doms.end(); }
inline const_iterator find(const BasicBlock* B) const { return Doms.find(B); } inline const_iterator find(const BasicBlock* B) const { return Doms.find(B); }
inline iterator find( BasicBlock* B) { return Doms.find(B); }
// getDominators - Return the set of basic blocks that dominate the specified // getDominators - Return the set of basic blocks that dominate the specified
// block. // block.
@ -83,6 +92,13 @@ public:
inline bool dominates(const BasicBlock *A, const BasicBlock *B) const { inline bool dominates(const BasicBlock *A, const BasicBlock *B) const {
return getDominators(B).count(A) != 0; return getDominators(B).count(A) != 0;
} }
// getAnalysisUsageInfo - This obviously provides a dominator set, but it also
// uses the UnifyMethodExitNode pass if building post-dominators
//
virtual void getAnalysisUsageInfo(Pass::AnalysisSet &Requires,
Pass::AnalysisSet &Destroyed,
Pass::AnalysisSet &Provided);
}; };
@ -96,12 +112,25 @@ class ImmediateDominators : public DominatorBase {
void calcIDoms(const DominatorSet &DS); void calcIDoms(const DominatorSet &DS);
public: public:
// ImmediateDominators ctor - Calculate the idom mapping, for a method, or // ImmediateDominators ctor - Calculate the idom or post-idom mapping,
// from a dominator set calculated for something else... // for a method...
// //
inline ImmediateDominators(const DominatorSet &DS) static AnalysisID ID; // Build immediate dominators
: DominatorBase(DS.getRoot()) { static AnalysisID PostDomID; // Build immediate postdominators
calcIDoms(DS); // Can be used to make rev-idoms
ImmediateDominators(AnalysisID id) : DominatorBase(id == PostDomID) {}
virtual bool runOnMethod(Method *M) {
IDoms.clear(); // Reset from the last time we were run...
DominatorSet *DS;
if (isPostDominator())
DS = &getAnalysis<DominatorSet>(DominatorSet::PostDomID);
else
DS = &getAnalysis<DominatorSet>();
Root = DS->getRoot();
calcIDoms(*DS); // Can be used to make rev-idoms
return false;
} }
// Accessor interface: // Accessor interface:
@ -119,6 +148,21 @@ public:
IDoms.find(BB); IDoms.find(BB);
return I != IDoms.end() ? I->second : 0; return I != IDoms.end() ? I->second : 0;
} }
// getAnalysisUsageInfo - This obviously provides a dominator tree, but it
// can only do so with the input of dominator sets
//
virtual void getAnalysisUsageInfo(Pass::AnalysisSet &Requires,
Pass::AnalysisSet &Destroyed,
Pass::AnalysisSet &Provided) {
if (isPostDominator()) {
Requires.push_back(DominatorSet::PostDomID);
Provided.push_back(PostDomID);
} else {
Requires.push_back(DominatorSet::ID);
Provided.push_back(ID);
}
}
}; };
@ -133,6 +177,7 @@ public:
private: private:
std::map<const BasicBlock*, Node*> Nodes; std::map<const BasicBlock*, Node*> Nodes;
void calculate(const DominatorSet &DS); void calculate(const DominatorSet &DS);
void reset();
typedef std::map<const BasicBlock*, Node*> NodeMapType; typedef std::map<const BasicBlock*, Node*> NodeMapType;
public: public:
class Node2 : public std::vector<Node*> { class Node2 : public std::vector<Node*> {
@ -160,19 +205,45 @@ public:
}; };
public: public:
// DominatorTree ctors - Compute a dominator tree, given various amounts of // DominatorTree ctor - Compute a dominator tree, given various amounts of
// previous knowledge... // previous knowledge...
inline DominatorTree(const DominatorSet &DS) : DominatorBase(DS.getRoot()) { static AnalysisID ID; // Build dominator tree
calculate(DS); static AnalysisID PostDomID; // Build postdominator tree
}
DominatorTree(const ImmediateDominators &IDoms); DominatorTree(AnalysisID id) : DominatorBase(id == PostDomID) {}
~DominatorTree(); ~DominatorTree() { reset(); }
virtual bool runOnMethod(Method *M) {
reset();
DominatorSet *DS;
if (isPostDominator())
DS = &getAnalysis<DominatorSet>(DominatorSet::PostDomID);
else
DS = &getAnalysis<DominatorSet>();
Root = DS->getRoot();
calculate(*DS); // Can be used to make rev-idoms
return false;
}
inline const Node *operator[](const BasicBlock *BB) const { inline const Node *operator[](const BasicBlock *BB) const {
NodeMapType::const_iterator i = Nodes.find(BB); NodeMapType::const_iterator i = Nodes.find(BB);
return (i != Nodes.end()) ? i->second : 0; return (i != Nodes.end()) ? i->second : 0;
} }
// getAnalysisUsageInfo - This obviously provides a dominator tree, but it
// uses dominator sets
//
virtual void getAnalysisUsageInfo(Pass::AnalysisSet &Requires,
Pass::AnalysisSet &Destroyed,
Pass::AnalysisSet &Provided) {
if (isPostDominator()) {
Requires.push_back(DominatorSet::PostDomID);
Provided.push_back(PostDomID);
} else {
Requires.push_back(DominatorSet::ID);
Provided.push_back(ID);
}
}
}; };
@ -191,33 +262,50 @@ private:
const DomSetType &calcPostDomFrontier(const DominatorTree &DT, const DomSetType &calcPostDomFrontier(const DominatorTree &DT,
const DominatorTree::Node *Node); const DominatorTree::Node *Node);
public: public:
DominanceFrontier(const DominatorSet &DS) : DominatorBase(DS.getRoot()) {
const DominatorTree DT(DS); // DominatorFrontier ctor - Compute dominator frontiers for a method
//
static AnalysisID ID; // Build dominator frontier
static AnalysisID PostDomID; // Build postdominator frontier
DominanceFrontier(AnalysisID id) : DominatorBase(id == PostDomID) {}
virtual bool runOnMethod(Method *M) {
Frontiers.clear();
DominatorTree *DT;
if (isPostDominator()) if (isPostDominator())
calcPostDomFrontier(DT, DT[Root]); DT = &getAnalysis<DominatorTree>(DominatorTree::PostDomID);
else else
calcDomFrontier(DT, DT[Root]); DT = &getAnalysis<DominatorTree>();
} Root = DT->getRoot();
DominanceFrontier(const ImmediateDominators &ID)
: DominatorBase(ID.getRoot()) {
const DominatorTree DT(ID);
if (isPostDominator()) if (isPostDominator())
calcPostDomFrontier(DT, DT[Root]); calcPostDomFrontier(*DT, (*DT)[Root]);
else else
calcDomFrontier(DT, DT[Root]); calcDomFrontier(*DT, (*DT)[Root]);
} return false;
DominanceFrontier(const DominatorTree &DT) : DominatorBase(DT.getRoot()) {
if (isPostDominator())
calcPostDomFrontier(DT, DT[Root]);
else
calcDomFrontier(DT, DT[Root]);
} }
// Accessor interface: // Accessor interface:
typedef DomSetMapType::const_iterator const_iterator; typedef DomSetMapType::const_iterator const_iterator;
inline const_iterator begin() const { return Frontiers.begin(); } inline const_iterator begin() const { return Frontiers.begin(); }
inline const_iterator end() const { return Frontiers.end(); } inline const_iterator end() const { return Frontiers.end(); }
inline const_iterator find(const BasicBlock* B) const { return Frontiers.find(B);} inline const_iterator find(const BasicBlock* B) const { return Frontiers.find(B); }
// getAnalysisUsageInfo - This obviously provides a dominator tree, but it
// uses dominator sets
//
virtual void getAnalysisUsageInfo(Pass::AnalysisSet &Requires,
Pass::AnalysisSet &Destroyed,
Pass::AnalysisSet &Provided) {
if (isPostDominator()) {
Requires.push_back(DominatorTree::PostDomID);
Provided.push_back(PostDomID);
} else {
Requires.push_back(DominatorTree::ID);
Provided.push_back(ID);
}
}
}; };
} // End namespace cfg } // End namespace cfg

View File

@ -22,26 +22,35 @@
class PointerType; class PointerType;
struct FindUnsafePointerTypes : public MethodPass { struct FindUnsafePointerTypes : public Pass {
// UnsafeTypes - Set of types that are not safe to transform. // UnsafeTypes - Set of types that are not safe to transform.
std::set<PointerType*> UnsafeTypes; std::set<PointerType*> UnsafeTypes;
public: public:
static AnalysisID ID; // We are an analysis, we must have an ID
FindUnsafePointerTypes(AnalysisID id) { assert(ID == id); }
// Accessor for underlying type set... // Accessor for underlying type set...
inline const std::set<PointerType*> &getUnsafeTypes() const { inline const std::set<PointerType*> &getUnsafeTypes() const {
return UnsafeTypes; return UnsafeTypes;
} }
// runOnMethod - Inspect the operations that the specified method does on // run - Inspect the operations that the specified module does on
// values of various types. If they are deemed to be 'unsafe' note that the // values of various types. If they are deemed to be 'unsafe' note that the
// type is not safe to transform. // type is not safe to transform.
// //
virtual bool runOnMethod(Method *M); virtual bool run(Module *M);
// printResults - Loop over the results of the analysis, printing out unsafe // printResults - Loop over the results of the analysis, printing out unsafe
// types. // types.
// //
void printResults(const Module *Mod, std::ostream &o); void printResults(const Module *Mod, std::ostream &o) const;
// getAnalysisUsageInfo - This function needs FindUsedTypes to do its job...
//
virtual void getAnalysisUsageInfo(Pass::AnalysisSet &Required,
Pass::AnalysisSet &Destroyed,
Pass::AnalysisSet &Provided);
}; };
#endif #endif

View File

@ -10,17 +10,20 @@
#include "llvm/Pass.h" #include "llvm/Pass.h"
#include <set> #include <set>
class SymbolTable; class SymbolTable;
class Type;
class FindUsedTypes : public MethodPass { class FindUsedTypes : public Pass {
std::set<const Type *> UsedTypes; std::set<const Type *> UsedTypes;
bool IncludeSymbolTables; bool IncludeSymbolTables;
public: public:
// FindUsedTypes ctor - This pass can optionally include types that are // FindUsedTypes ctor - This pass can optionally include types that are
// referenced only in symbol tables, but the default is not to. // referenced only in symbol tables, but the default is not to.
// //
FindUsedTypes(bool IST = false) : IncludeSymbolTables(IST) {} static AnalysisID ID;
static AnalysisID IncludeSymbolTableID;
FindUsedTypes(AnalysisID id) : IncludeSymbolTables(id != ID) {}
// getTypes - After the pass has been run, return the set containing all of // getTypes - After the pass has been run, return the set containing all of
// the types used in the module. // the types used in the module.
@ -45,14 +48,15 @@ private:
void IncorporateSymbolTable(const SymbolTable *ST); void IncorporateSymbolTable(const SymbolTable *ST);
public: public:
// doInitialization - This loops over global constants defined in the // run - This incorporates all types used by the specified module
// module, converting them to their new type.
// //
bool doInitialization(Module *M); bool run(Module *M);
// runOnMethod - This incorporates all types used by the specified method // getAnalysisUsageInfo - This function needs FindUsedTypes to do its job...
// //
bool runOnMethod(Method *M); virtual void getAnalysisUsageInfo(Pass::AnalysisSet &Required,
Pass::AnalysisSet &Destroyed,
Pass::AnalysisSet &Provided);
}; };
#endif #endif

View File

@ -17,9 +17,7 @@
#define LLVM_INTERVAL_PARTITION_H #define LLVM_INTERVAL_PARTITION_H
#include "llvm/Analysis/Interval.h" #include "llvm/Analysis/Interval.h"
#include <map> #include "llvm/Pass.h"
class Method;
namespace cfg { namespace cfg {
@ -31,7 +29,7 @@ namespace cfg {
// BasicBlock is a (possibly nonexistent) loop with a "tail" of non looping // BasicBlock is a (possibly nonexistent) loop with a "tail" of non looping
// nodes following it. // nodes following it.
// //
class IntervalPartition : public std::vector<Interval*> { class IntervalPartition : public MethodPass, public std::vector<Interval*> {
typedef std::map<BasicBlock*, Interval*> IntervalMapTy; typedef std::map<BasicBlock*, Interval*> IntervalMapTy;
IntervalMapTy IntervalMap; IntervalMapTy IntervalMap;
@ -39,8 +37,12 @@ class IntervalPartition : public std::vector<Interval*> {
Interval *RootInterval; Interval *RootInterval;
public: public:
// IntervalPartition ctor - Build the partition for the specified method static AnalysisID ID; // We are an analysis, we must have an ID
IntervalPartition(Method *M);
IntervalPartition(AnalysisID AID) : RootInterval(0) { assert(AID == ID); }
// run - Calculate the interval partition for this method
virtual bool runOnMethod(Method *M);
// IntervalPartition ctor - Build a reduced interval partition from an // IntervalPartition ctor - Build a reduced interval partition from an
// existing interval graph. This takes an additional boolean parameter to // existing interval graph. This takes an additional boolean parameter to
@ -49,7 +51,7 @@ public:
IntervalPartition(IntervalPartition &I, bool); IntervalPartition(IntervalPartition &I, bool);
// Destructor - Free memory // Destructor - Free memory
~IntervalPartition(); ~IntervalPartition() { destroy(); }
// getRootInterval() - Return the root interval that contains the starting // getRootInterval() - Return the root interval that contains the starting
// block of the method. // block of the method.
@ -67,7 +69,17 @@ public:
return I != IntervalMap.end() ? I->second : 0; return I != IntervalMap.end() ? I->second : 0;
} }
// getAnalysisUsageInfo - Implement the Pass API
virtual void getAnalysisUsageInfo(AnalysisSet &Required,
AnalysisSet &Destroyed,
AnalysisSet &Provided) {
Provided.push_back(ID);
}
private: private:
// destroy - Reset state back to before method was analyzed
void destroy();
// addIntervalToPartition - Add an interval to the internal list of intervals, // 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 // and then add mappings from all of the basic blocks in the interval to the
// interval itself (in the IntervalMap). // interval itself (in the IntervalMap).

View File

@ -10,10 +10,8 @@
#ifndef LLVM_ANALYSIS_LOOP_INFO_H #ifndef LLVM_ANALYSIS_LOOP_INFO_H
#define LLVM_ANALYSIS_LOOP_INFO_H #define LLVM_ANALYSIS_LOOP_INFO_H
#include <vector> #include "llvm/Pass.h"
#include <map>
#include <set> #include <set>
class BasicBlock;
namespace cfg { namespace cfg {
class DominatorSet; class DominatorSet;
@ -62,13 +60,15 @@ private:
// LoopInfo - This class builds and contains all of the top level loop // LoopInfo - This class builds and contains all of the top level loop
// structures in the specified method. // structures in the specified method.
// //
class LoopInfo { class LoopInfo : public MethodPass {
// BBMap - Mapping of basic blocks to the inner most loop they occur in // BBMap - Mapping of basic blocks to the inner most loop they occur in
std::map<const BasicBlock *, Loop*> BBMap; std::map<const BasicBlock *, Loop*> BBMap;
std::vector<Loop*> TopLevelLoops; std::vector<Loop*> TopLevelLoops;
public: public:
static AnalysisID ID; // cfg::LoopInfo Analysis ID
// LoopInfo ctor - Calculate the natural loop information for a CFG // LoopInfo ctor - Calculate the natural loop information for a CFG
LoopInfo(const DominatorSet &DS); LoopInfo(AnalysisID id) { assert(id == ID); }
const std::vector<Loop*> &getTopLevelLoops() const { return TopLevelLoops; } const std::vector<Loop*> &getTopLevelLoops() const { return TopLevelLoops; }
@ -100,7 +100,16 @@ public:
bool isLoopExit(const BasicBlock *BB) const; bool isLoopExit(const BasicBlock *BB) const;
#endif #endif
// runOnMethod - Pass framework implementation
virtual bool runOnMethod(Method *M);
// getAnalysisUsageInfo - Provide loop info, require dominator set
//
virtual void getAnalysisUsageInfo(Pass::AnalysisSet &Requires,
Pass::AnalysisSet &Destroyed,
Pass::AnalysisSet &Provided);
private: private:
void Calculate(const DominatorSet &DS);
Loop *ConsiderForLoop(const BasicBlock *BB, const DominatorSet &DS); Loop *ConsiderForLoop(const BasicBlock *BB, const DominatorSet &DS);
}; };