Add GlobalDSGraph -- a common graph that holds externally visible nodes.

git-svn-id: https://llvm.org/svn/llvm-project/llvm/trunk@3169 91177308-0d34-0410-b5e6-96231b3b80d8
This commit is contained in:
Vikram S. Adve
2002-07-30 22:02:04 +00:00
parent d4c7f2766b
commit 3b43b772e6
2 changed files with 180 additions and 68 deletions

View File

@@ -8,12 +8,17 @@
#define LLVM_ANALYSIS_DATA_STRUCTURE_H #define LLVM_ANALYSIS_DATA_STRUCTURE_H
#include "llvm/Pass.h" #include "llvm/Pass.h"
#include "llvm/GlobalValue.h"
#include "Support/HashExtras.h"
#include <set>
#include <hash_set>
#include <string> #include <string>
class Type; class Type;
class GlobalValue; class GlobalValue;
class DSNode; // Each node in the graph class DSNode; // Each node in the graph
class DSGraph; // A graph for a function class DSGraph; // A graph for a function
class GlobalDSGraph; // A common graph for globals in a program
class DSNodeIterator; // Data structure graph traversal iterator class DSNodeIterator; // Data structure graph traversal iterator
class LocalDataStructures; // A collection of local graphs for a program class LocalDataStructures; // A collection of local graphs for a program
class BUDataStructures; // A collection of bu graphs for a program class BUDataStructures; // A collection of bu graphs for a program
@@ -37,10 +42,11 @@ public:
inline DSNodeHandle &operator=(DSNode *n); inline DSNodeHandle &operator=(DSNode *n);
// Allow automatic, implicit, conversion to DSNode* // Allow automatic, implicit, conversion to DSNode*
operator DSNode*() { return N; } operator DSNode*() { return N; }
operator const DSNode*() const { return N; } operator const DSNode*() const { return N; }
operator bool() const { return N != 0; } operator const DSNode*() { return N; }
operator bool() { return N != 0; } operator bool() const { return N != 0; }
operator bool() { return N != 0; }
bool operator<(const DSNodeHandle &H) const { // Allow sorting bool operator<(const DSNodeHandle &H) const { // Allow sorting
return N < H.N; return N < H.N;
@@ -87,7 +93,7 @@ class DSNode {
void operator=(const DSNode &); // DO NOT IMPLEMENT void operator=(const DSNode &); // DO NOT IMPLEMENT
public: public:
enum NodeTy { enum NodeTy {
ShadowNode = 0 << 0, // Nothing is known about this node... ShadowNode = 0, // Nothing is known about this node...
ScalarNode = 1 << 0, // Scalar of the current function contains this value ScalarNode = 1 << 0, // Scalar of the current function contains this value
AllocaNode = 1 << 1, // This node was allocated with alloca AllocaNode = 1 << 1, // This node was allocated with alloca
NewNode = 1 << 2, // This node was allocated with malloc NewNode = 1 << 2, // This node was allocated with malloc
@@ -187,11 +193,18 @@ inline DSNodeHandle &DSNodeHandle::operator=(DSNode *n) {
// DSGraph - The graph that represents a function. // DSGraph - The graph that represents a function.
// //
class DSGraph { class DSGraph {
friend class GlobalDSGraph;
protected:
Function &Func; Function &Func;
std::vector<DSNode*> Nodes; std::vector<DSNode*> Nodes;
DSNodeHandle RetNode; // Node that gets returned... DSNodeHandle RetNode; // Node that gets returned...
std::map<Value*, DSNodeHandle> ValueMap; std::map<Value*, DSNodeHandle> ValueMap;
// GlobalsGraph -- Reference to the common graph of globally visible objects.
// This includes GlobalValues, New nodes, Cast nodes, and Calls.
//
GlobalDSGraph* GlobalsGraph;
// FunctionCalls - This vector maintains a single entry for each call // FunctionCalls - This vector maintains a single entry for each call
// instruction in the current graph. Each call entry contains DSNodeHandles // instruction in the current graph. Each call entry contains DSNodeHandles
// that refer to the arguments that are passed into the function call. The // that refer to the arguments that are passed into the function call. The
@@ -213,16 +226,16 @@ class DSGraph {
// for formal arguments in the current graph cannot be eliminated, and // for formal arguments in the current graph cannot be eliminated, and
// nodes in the graph reachable from the formal argument nodes or // nodes in the graph reachable from the formal argument nodes or
// global variable nodes must be considered incomplete. // global variable nodes must be considered incomplete.
std::vector<Function*> PendingCallers; std::set<Function*> PendingCallers;
private: protected:
// Define the interface only accessable to DataStructure // Define the interface only accessable to DataStructure
friend class LocalDataStructures; friend class LocalDataStructures;
friend class BUDataStructures; friend class BUDataStructures;
friend class TDDataStructures; friend class TDDataStructures;
DSGraph(Function &F); // Compute the local DSGraph DSGraph(Function &F, GlobalDSGraph* GlobalsG); // Compute the local DSGraph
DSGraph(const DSGraph &DSG); // Copy ctor DSGraph(const DSGraph &DSG); // Copy ctor
~DSGraph(); virtual ~DSGraph();
// clone all the call nodes and save the copies in OrigFunctionCalls // clone all the call nodes and save the copies in OrigFunctionCalls
void saveOrigFunctionCalls() { void saveOrigFunctionCalls() {
@@ -240,6 +253,11 @@ public:
Function &getFunction() const { return Func; } Function &getFunction() const { return Func; }
// getNodes - Get a vector of all the nodes in the graph
//
const std::vector<DSNode*>& getNodes() const { return Nodes; }
std::vector<DSNode*>& getNodes() { return Nodes; }
// getValueMap - Get a map that describes what the nodes the scalars in this // getValueMap - Get a map that describes what the nodes the scalars in this
// function point to... // function point to...
// //
@@ -249,8 +267,12 @@ public:
std::vector<std::vector<DSNodeHandle> > &getFunctionCalls() { std::vector<std::vector<DSNodeHandle> > &getFunctionCalls() {
return FunctionCalls; return FunctionCalls;
} }
const std::vector<std::vector<DSNodeHandle> > &getFunctionCalls() const {
return FunctionCalls;
}
const DSNode *getRetNode() const { return RetNode; } const DSNode *getRetNode() const { return RetNode; }
DSNode *getRetNode() { return RetNode; }
unsigned getGraphSize() const { unsigned getGraphSize() const {
return Nodes.size(); return Nodes.size();
@@ -274,13 +296,13 @@ public:
// the scope of current analysis may have modified it), the 'Incomplete' flag // the scope of current analysis may have modified it), the 'Incomplete' flag
// is added to the NodeType. // is added to the NodeType.
// //
void markIncompleteNodes(); void markIncompleteNodes(bool markFormalArgs = true);
// removeTriviallyDeadNodes - After the graph has been constructed, this // removeTriviallyDeadNodes - After the graph has been constructed, this
// method removes all unreachable nodes that are created because they got // method removes all unreachable nodes that are created because they got
// merged with other nodes in the graph. // merged with other nodes in the graph.
// //
void removeTriviallyDeadNodes(); void removeTriviallyDeadNodes(bool KeepAllGlobals = false);
// removeDeadNodes - Use a more powerful reachability analysis to eliminate // removeDeadNodes - Use a more powerful reachability analysis to eliminate
// subgraphs that are unreachable. This often occurs because the data // subgraphs that are unreachable. This often occurs because the data
@@ -288,8 +310,7 @@ public:
// from the caller's graph entirely. This is only appropriate to use when // from the caller's graph entirely. This is only appropriate to use when
// inlining graphs. // inlining graphs.
// //
void removeDeadNodes(); void removeDeadNodes(bool KeepAllGlobals = false, bool KeepCalls = true);
// AddCaller - add a known caller node into the graph and mark it pending. // AddCaller - add a known caller node into the graph and mark it pending.
// getCallers - get a vector of the functions that call this one // getCallers - get a vector of the functions that call this one
@@ -297,26 +318,65 @@ public:
// caller's DSGraph has been resolved into this one. // caller's DSGraph has been resolved into this one.
// //
void addCaller(Function& caller) { void addCaller(Function& caller) {
PendingCallers.push_back(&caller); PendingCallers.insert(&caller);
} }
std::vector<Function*>& getPendingCallers() { std::set<Function*>& getPendingCallers() {
return PendingCallers; return PendingCallers;
} }
// cloneInto - Clone the specified DSGraph into the current graph, returning // cloneInto - Clone the specified DSGraph into the current graph, returning
// the Return node of the graph. The translated ValueMap for the old function // the Return node of the graph. The translated ValueMap for the old function
// is filled into the OldValMap member. If StripLocals is set to true, Scalar // is filled into the OldValMap member.
// and Alloca markers are removed from the graph, as the graph is being cloned // If StripScalars (StripAllocas) is set to true, Scalar (Alloca) markers
// into a calling function's graph. // are removed from the graph as the graph is being cloned.
// If CopyCallers is set to true, the PendingCallers list is copied.
// If CopyOrigCalls is set to true, the OrigFunctionCalls list is copied.
// //
DSNode *cloneInto(const DSGraph &G, std::map<Value*, DSNodeHandle> &OldValMap, DSNode *cloneInto(const DSGraph &G, std::map<Value*, DSNodeHandle> &OldValMap,
std::map<const DSNode*, DSNode*>& OldNodeMap, std::map<const DSNode*, DSNode*>& OldNodeMap,
bool StripLocals = true); bool StripScalars = false, bool StripAllocas = false,
bool CopyCallers = true, bool CopyOrigCalls = true);
// cloneGlobalInto - Clone the given global node (or the node for the given
// GlobalValue) from the GlobalsGraph and all its target links (recursively).
//
DSNode* cloneGlobalInto(const DSNode* GNode);
DSNode* cloneGlobalInto(GlobalValue* GV) {
assert(!GV || (((DSGraph*) GlobalsGraph)->ValueMap[GV] != 0));
return GV? cloneGlobalInto(((DSGraph*) GlobalsGraph)->ValueMap[GV]) : 0;
}
private: private:
bool isNodeDead(DSNode *N); bool isNodeDead(DSNode *N);
}; };
// GlobalDSGraph - A common graph for all the globals and their outgoing links
// to externally visible nodes. This includes GlobalValues, New nodes,
// Cast nodes, and Calls. This graph can only be used by one of the
// individual function graphs, and it goes away when they all go away.
//
class GlobalDSGraph: public DSGraph {
hash_set<const DSGraph*, hash<const DSGraph*> > Referrers;
void addReference(const DSGraph* referrer);
void removeReference(const DSGraph* referrer);
friend class DSGraph; // give access to Referrers
GlobalDSGraph(const GlobalDSGraph &GlobalDSG); // Do not implement
// Helper function for cloneGlobals and cloneCalls
DSNode* cloneNodeInto(DSNode *OldNode,
std::map<const DSNode*, DSNode*> &NodeCache,
bool GlobalsAreFinal = false);
public:
GlobalDSGraph(); // Create an empty DSGraph
virtual ~GlobalDSGraph();
void cloneGlobals(DSGraph& Graph, bool CloneCalls = false);
void cloneCalls (DSGraph& Graph);
};
// LocalDataStructures - The analysis that computes the local data structure // LocalDataStructures - The analysis that computes the local data structure
// graphs for all of the functions in the program. // graphs for all of the functions in the program.
@@ -326,7 +386,7 @@ private:
// //
class LocalDataStructures : public Pass { class LocalDataStructures : public Pass {
// DSInfo, one graph for each function // DSInfo, one graph for each function
std::map<Function*, DSGraph*> DSInfo; std::map<const Function*, DSGraph*> DSInfo;
public: public:
static AnalysisID ID; // DataStructure Analysis ID static AnalysisID ID; // DataStructure Analysis ID
@@ -335,8 +395,8 @@ public:
virtual bool run(Module &M); virtual bool run(Module &M);
// getDSGraph - Return the data structure graph for the specified function. // getDSGraph - Return the data structure graph for the specified function.
DSGraph &getDSGraph(Function &F) const { DSGraph &getDSGraph(const Function &F) const {
std::map<Function*, DSGraph*>::const_iterator I = DSInfo.find(&F); std::map<const Function*, DSGraph*>::const_iterator I = DSInfo.find(&F);
assert(I != DSInfo.end() && "Function not in module!"); assert(I != DSInfo.end() && "Function not in module!");
return *I->second; return *I->second;
} }
@@ -360,7 +420,7 @@ public:
// //
class BUDataStructures : public Pass { class BUDataStructures : public Pass {
// DSInfo, one graph for each function // DSInfo, one graph for each function
std::map<Function*, DSGraph*> DSInfo; std::map<const Function*, DSGraph*> DSInfo;
public: public:
static AnalysisID ID; // BUDataStructure Analysis ID static AnalysisID ID; // BUDataStructure Analysis ID
@@ -369,12 +429,12 @@ public:
virtual bool run(Module &M); virtual bool run(Module &M);
// getDSGraph - Return the data structure graph for the specified function. // getDSGraph - Return the data structure graph for the specified function.
DSGraph &getDSGraph(Function &F) const { DSGraph &getDSGraph(const Function &F) const {
std::map<Function*, DSGraph*>::const_iterator I = DSInfo.find(&F); std::map<const Function*, DSGraph*>::const_iterator I = DSInfo.find(&F);
assert(I != DSInfo.end() && "Function not in module!"); assert(I != DSInfo.end() && "Function not in module!");
return *I->second; return *I->second;
} }
// print - Print out the analysis results... // print - Print out the analysis results...
void print(std::ostream &O, const Module *M) const; void print(std::ostream &O, const Module *M) const;
@@ -397,21 +457,17 @@ private:
// //
class TDDataStructures : public Pass { class TDDataStructures : public Pass {
// DSInfo, one graph for each function // DSInfo, one graph for each function
std::map<Function*, DSGraph*> DSInfo; std::map<const Function*, DSGraph*> DSInfo;
public: public:
static AnalysisID ID; // TDDataStructure Analysis ID static AnalysisID ID; // TDDataStructure Analysis ID
~TDDataStructures() { releaseMemory(); } ~TDDataStructures() { releaseMemory(); }
virtual const char *getPassName() const {
return "Top-down Data Structure Analysis Closure";
}
virtual bool run(Module &M); virtual bool run(Module &M);
// getDSGraph - Return the data structure graph for the specified function. // getDSGraph - Return the data structure graph for the specified function.
DSGraph &getDSGraph(Function &F) const { DSGraph &getDSGraph(const Function &F) const {
std::map<Function*, DSGraph*>::const_iterator I = DSInfo.find(&F); std::map<const Function*, DSGraph*>::const_iterator I = DSInfo.find(&F);
assert(I != DSInfo.end() && "Function not in module!"); assert(I != DSInfo.end() && "Function not in module!");
return *I->second; return *I->second;
} }

View File

@@ -8,12 +8,17 @@
#define LLVM_ANALYSIS_DATA_STRUCTURE_H #define LLVM_ANALYSIS_DATA_STRUCTURE_H
#include "llvm/Pass.h" #include "llvm/Pass.h"
#include "llvm/GlobalValue.h"
#include "Support/HashExtras.h"
#include <set>
#include <hash_set>
#include <string> #include <string>
class Type; class Type;
class GlobalValue; class GlobalValue;
class DSNode; // Each node in the graph class DSNode; // Each node in the graph
class DSGraph; // A graph for a function class DSGraph; // A graph for a function
class GlobalDSGraph; // A common graph for globals in a program
class DSNodeIterator; // Data structure graph traversal iterator class DSNodeIterator; // Data structure graph traversal iterator
class LocalDataStructures; // A collection of local graphs for a program class LocalDataStructures; // A collection of local graphs for a program
class BUDataStructures; // A collection of bu graphs for a program class BUDataStructures; // A collection of bu graphs for a program
@@ -37,10 +42,11 @@ public:
inline DSNodeHandle &operator=(DSNode *n); inline DSNodeHandle &operator=(DSNode *n);
// Allow automatic, implicit, conversion to DSNode* // Allow automatic, implicit, conversion to DSNode*
operator DSNode*() { return N; } operator DSNode*() { return N; }
operator const DSNode*() const { return N; } operator const DSNode*() const { return N; }
operator bool() const { return N != 0; } operator const DSNode*() { return N; }
operator bool() { return N != 0; } operator bool() const { return N != 0; }
operator bool() { return N != 0; }
bool operator<(const DSNodeHandle &H) const { // Allow sorting bool operator<(const DSNodeHandle &H) const { // Allow sorting
return N < H.N; return N < H.N;
@@ -87,7 +93,7 @@ class DSNode {
void operator=(const DSNode &); // DO NOT IMPLEMENT void operator=(const DSNode &); // DO NOT IMPLEMENT
public: public:
enum NodeTy { enum NodeTy {
ShadowNode = 0 << 0, // Nothing is known about this node... ShadowNode = 0, // Nothing is known about this node...
ScalarNode = 1 << 0, // Scalar of the current function contains this value ScalarNode = 1 << 0, // Scalar of the current function contains this value
AllocaNode = 1 << 1, // This node was allocated with alloca AllocaNode = 1 << 1, // This node was allocated with alloca
NewNode = 1 << 2, // This node was allocated with malloc NewNode = 1 << 2, // This node was allocated with malloc
@@ -187,11 +193,18 @@ inline DSNodeHandle &DSNodeHandle::operator=(DSNode *n) {
// DSGraph - The graph that represents a function. // DSGraph - The graph that represents a function.
// //
class DSGraph { class DSGraph {
friend class GlobalDSGraph;
protected:
Function &Func; Function &Func;
std::vector<DSNode*> Nodes; std::vector<DSNode*> Nodes;
DSNodeHandle RetNode; // Node that gets returned... DSNodeHandle RetNode; // Node that gets returned...
std::map<Value*, DSNodeHandle> ValueMap; std::map<Value*, DSNodeHandle> ValueMap;
// GlobalsGraph -- Reference to the common graph of globally visible objects.
// This includes GlobalValues, New nodes, Cast nodes, and Calls.
//
GlobalDSGraph* GlobalsGraph;
// FunctionCalls - This vector maintains a single entry for each call // FunctionCalls - This vector maintains a single entry for each call
// instruction in the current graph. Each call entry contains DSNodeHandles // instruction in the current graph. Each call entry contains DSNodeHandles
// that refer to the arguments that are passed into the function call. The // that refer to the arguments that are passed into the function call. The
@@ -213,16 +226,16 @@ class DSGraph {
// for formal arguments in the current graph cannot be eliminated, and // for formal arguments in the current graph cannot be eliminated, and
// nodes in the graph reachable from the formal argument nodes or // nodes in the graph reachable from the formal argument nodes or
// global variable nodes must be considered incomplete. // global variable nodes must be considered incomplete.
std::vector<Function*> PendingCallers; std::set<Function*> PendingCallers;
private: protected:
// Define the interface only accessable to DataStructure // Define the interface only accessable to DataStructure
friend class LocalDataStructures; friend class LocalDataStructures;
friend class BUDataStructures; friend class BUDataStructures;
friend class TDDataStructures; friend class TDDataStructures;
DSGraph(Function &F); // Compute the local DSGraph DSGraph(Function &F, GlobalDSGraph* GlobalsG); // Compute the local DSGraph
DSGraph(const DSGraph &DSG); // Copy ctor DSGraph(const DSGraph &DSG); // Copy ctor
~DSGraph(); virtual ~DSGraph();
// clone all the call nodes and save the copies in OrigFunctionCalls // clone all the call nodes and save the copies in OrigFunctionCalls
void saveOrigFunctionCalls() { void saveOrigFunctionCalls() {
@@ -240,6 +253,11 @@ public:
Function &getFunction() const { return Func; } Function &getFunction() const { return Func; }
// getNodes - Get a vector of all the nodes in the graph
//
const std::vector<DSNode*>& getNodes() const { return Nodes; }
std::vector<DSNode*>& getNodes() { return Nodes; }
// getValueMap - Get a map that describes what the nodes the scalars in this // getValueMap - Get a map that describes what the nodes the scalars in this
// function point to... // function point to...
// //
@@ -249,8 +267,12 @@ public:
std::vector<std::vector<DSNodeHandle> > &getFunctionCalls() { std::vector<std::vector<DSNodeHandle> > &getFunctionCalls() {
return FunctionCalls; return FunctionCalls;
} }
const std::vector<std::vector<DSNodeHandle> > &getFunctionCalls() const {
return FunctionCalls;
}
const DSNode *getRetNode() const { return RetNode; } const DSNode *getRetNode() const { return RetNode; }
DSNode *getRetNode() { return RetNode; }
unsigned getGraphSize() const { unsigned getGraphSize() const {
return Nodes.size(); return Nodes.size();
@@ -274,13 +296,13 @@ public:
// the scope of current analysis may have modified it), the 'Incomplete' flag // the scope of current analysis may have modified it), the 'Incomplete' flag
// is added to the NodeType. // is added to the NodeType.
// //
void markIncompleteNodes(); void markIncompleteNodes(bool markFormalArgs = true);
// removeTriviallyDeadNodes - After the graph has been constructed, this // removeTriviallyDeadNodes - After the graph has been constructed, this
// method removes all unreachable nodes that are created because they got // method removes all unreachable nodes that are created because they got
// merged with other nodes in the graph. // merged with other nodes in the graph.
// //
void removeTriviallyDeadNodes(); void removeTriviallyDeadNodes(bool KeepAllGlobals = false);
// removeDeadNodes - Use a more powerful reachability analysis to eliminate // removeDeadNodes - Use a more powerful reachability analysis to eliminate
// subgraphs that are unreachable. This often occurs because the data // subgraphs that are unreachable. This often occurs because the data
@@ -288,8 +310,7 @@ public:
// from the caller's graph entirely. This is only appropriate to use when // from the caller's graph entirely. This is only appropriate to use when
// inlining graphs. // inlining graphs.
// //
void removeDeadNodes(); void removeDeadNodes(bool KeepAllGlobals = false, bool KeepCalls = true);
// AddCaller - add a known caller node into the graph and mark it pending. // AddCaller - add a known caller node into the graph and mark it pending.
// getCallers - get a vector of the functions that call this one // getCallers - get a vector of the functions that call this one
@@ -297,26 +318,65 @@ public:
// caller's DSGraph has been resolved into this one. // caller's DSGraph has been resolved into this one.
// //
void addCaller(Function& caller) { void addCaller(Function& caller) {
PendingCallers.push_back(&caller); PendingCallers.insert(&caller);
} }
std::vector<Function*>& getPendingCallers() { std::set<Function*>& getPendingCallers() {
return PendingCallers; return PendingCallers;
} }
// cloneInto - Clone the specified DSGraph into the current graph, returning // cloneInto - Clone the specified DSGraph into the current graph, returning
// the Return node of the graph. The translated ValueMap for the old function // the Return node of the graph. The translated ValueMap for the old function
// is filled into the OldValMap member. If StripLocals is set to true, Scalar // is filled into the OldValMap member.
// and Alloca markers are removed from the graph, as the graph is being cloned // If StripScalars (StripAllocas) is set to true, Scalar (Alloca) markers
// into a calling function's graph. // are removed from the graph as the graph is being cloned.
// If CopyCallers is set to true, the PendingCallers list is copied.
// If CopyOrigCalls is set to true, the OrigFunctionCalls list is copied.
// //
DSNode *cloneInto(const DSGraph &G, std::map<Value*, DSNodeHandle> &OldValMap, DSNode *cloneInto(const DSGraph &G, std::map<Value*, DSNodeHandle> &OldValMap,
std::map<const DSNode*, DSNode*>& OldNodeMap, std::map<const DSNode*, DSNode*>& OldNodeMap,
bool StripLocals = true); bool StripScalars = false, bool StripAllocas = false,
bool CopyCallers = true, bool CopyOrigCalls = true);
// cloneGlobalInto - Clone the given global node (or the node for the given
// GlobalValue) from the GlobalsGraph and all its target links (recursively).
//
DSNode* cloneGlobalInto(const DSNode* GNode);
DSNode* cloneGlobalInto(GlobalValue* GV) {
assert(!GV || (((DSGraph*) GlobalsGraph)->ValueMap[GV] != 0));
return GV? cloneGlobalInto(((DSGraph*) GlobalsGraph)->ValueMap[GV]) : 0;
}
private: private:
bool isNodeDead(DSNode *N); bool isNodeDead(DSNode *N);
}; };
// GlobalDSGraph - A common graph for all the globals and their outgoing links
// to externally visible nodes. This includes GlobalValues, New nodes,
// Cast nodes, and Calls. This graph can only be used by one of the
// individual function graphs, and it goes away when they all go away.
//
class GlobalDSGraph: public DSGraph {
hash_set<const DSGraph*, hash<const DSGraph*> > Referrers;
void addReference(const DSGraph* referrer);
void removeReference(const DSGraph* referrer);
friend class DSGraph; // give access to Referrers
GlobalDSGraph(const GlobalDSGraph &GlobalDSG); // Do not implement
// Helper function for cloneGlobals and cloneCalls
DSNode* cloneNodeInto(DSNode *OldNode,
std::map<const DSNode*, DSNode*> &NodeCache,
bool GlobalsAreFinal = false);
public:
GlobalDSGraph(); // Create an empty DSGraph
virtual ~GlobalDSGraph();
void cloneGlobals(DSGraph& Graph, bool CloneCalls = false);
void cloneCalls (DSGraph& Graph);
};
// LocalDataStructures - The analysis that computes the local data structure // LocalDataStructures - The analysis that computes the local data structure
// graphs for all of the functions in the program. // graphs for all of the functions in the program.
@@ -326,7 +386,7 @@ private:
// //
class LocalDataStructures : public Pass { class LocalDataStructures : public Pass {
// DSInfo, one graph for each function // DSInfo, one graph for each function
std::map<Function*, DSGraph*> DSInfo; std::map<const Function*, DSGraph*> DSInfo;
public: public:
static AnalysisID ID; // DataStructure Analysis ID static AnalysisID ID; // DataStructure Analysis ID
@@ -335,8 +395,8 @@ public:
virtual bool run(Module &M); virtual bool run(Module &M);
// getDSGraph - Return the data structure graph for the specified function. // getDSGraph - Return the data structure graph for the specified function.
DSGraph &getDSGraph(Function &F) const { DSGraph &getDSGraph(const Function &F) const {
std::map<Function*, DSGraph*>::const_iterator I = DSInfo.find(&F); std::map<const Function*, DSGraph*>::const_iterator I = DSInfo.find(&F);
assert(I != DSInfo.end() && "Function not in module!"); assert(I != DSInfo.end() && "Function not in module!");
return *I->second; return *I->second;
} }
@@ -360,7 +420,7 @@ public:
// //
class BUDataStructures : public Pass { class BUDataStructures : public Pass {
// DSInfo, one graph for each function // DSInfo, one graph for each function
std::map<Function*, DSGraph*> DSInfo; std::map<const Function*, DSGraph*> DSInfo;
public: public:
static AnalysisID ID; // BUDataStructure Analysis ID static AnalysisID ID; // BUDataStructure Analysis ID
@@ -369,12 +429,12 @@ public:
virtual bool run(Module &M); virtual bool run(Module &M);
// getDSGraph - Return the data structure graph for the specified function. // getDSGraph - Return the data structure graph for the specified function.
DSGraph &getDSGraph(Function &F) const { DSGraph &getDSGraph(const Function &F) const {
std::map<Function*, DSGraph*>::const_iterator I = DSInfo.find(&F); std::map<const Function*, DSGraph*>::const_iterator I = DSInfo.find(&F);
assert(I != DSInfo.end() && "Function not in module!"); assert(I != DSInfo.end() && "Function not in module!");
return *I->second; return *I->second;
} }
// print - Print out the analysis results... // print - Print out the analysis results...
void print(std::ostream &O, const Module *M) const; void print(std::ostream &O, const Module *M) const;
@@ -397,21 +457,17 @@ private:
// //
class TDDataStructures : public Pass { class TDDataStructures : public Pass {
// DSInfo, one graph for each function // DSInfo, one graph for each function
std::map<Function*, DSGraph*> DSInfo; std::map<const Function*, DSGraph*> DSInfo;
public: public:
static AnalysisID ID; // TDDataStructure Analysis ID static AnalysisID ID; // TDDataStructure Analysis ID
~TDDataStructures() { releaseMemory(); } ~TDDataStructures() { releaseMemory(); }
virtual const char *getPassName() const {
return "Top-down Data Structure Analysis Closure";
}
virtual bool run(Module &M); virtual bool run(Module &M);
// getDSGraph - Return the data structure graph for the specified function. // getDSGraph - Return the data structure graph for the specified function.
DSGraph &getDSGraph(Function &F) const { DSGraph &getDSGraph(const Function &F) const {
std::map<Function*, DSGraph*>::const_iterator I = DSInfo.find(&F); std::map<const Function*, DSGraph*>::const_iterator I = DSInfo.find(&F);
assert(I != DSInfo.end() && "Function not in module!"); assert(I != DSInfo.end() && "Function not in module!");
return *I->second; return *I->second;
} }