mirror of
https://github.com/c64scene-ar/llvm-6502.git
synced 2025-05-24 18:38:50 +00:00
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:
parent
05ad462d1b
commit
facd752d3a
@ -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.
|
||||||
|
@ -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
|
||||||
|
@ -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
|
||||||
|
@ -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
|
||||||
|
@ -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).
|
||||||
|
@ -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);
|
||||||
};
|
};
|
||||||
|
|
||||||
|
Loading…
x
Reference in New Issue
Block a user