diff options
Diffstat (limited to 'include')
-rw-r--r-- | include/llvm/Analysis/DSGraph.h | 41 | ||||
-rw-r--r-- | include/llvm/Analysis/DSNode.h | 4 | ||||
-rw-r--r-- | include/llvm/Analysis/DataStructure.h | 35 | ||||
-rw-r--r-- | include/llvm/Analysis/DataStructure/DSGraph.h | 41 | ||||
-rw-r--r-- | include/llvm/Analysis/DataStructure/DSNode.h | 4 | ||||
-rw-r--r-- | include/llvm/Analysis/DataStructure/DataStructure.h | 35 |
6 files changed, 72 insertions, 88 deletions
diff --git a/include/llvm/Analysis/DSGraph.h b/include/llvm/Analysis/DSGraph.h index 9b283d3..50123dc 100644 --- a/include/llvm/Analysis/DSGraph.h +++ b/include/llvm/Analysis/DSGraph.h @@ -26,14 +26,19 @@ class DSGraph { #endif // FunctionCalls - This vector maintains a single entry for each call - // instruction in the current graph. Each call entry contains DSNodeHandles - // that refer to the arguments that are passed into the function call. The - // first entry in the vector is the scalar that holds the return value for the - // call, the second is the function scalar being invoked, and the rest are - // pointer arguments to the function. + // instruction in the current graph. The first entry in the vector is the + // scalar that holds the return value for the call, the second is the function + // scalar being invoked, and the rest are pointer arguments to the function. + // This vector is built by the Local graph and is never modified after that. // std::vector<DSCallSite> FunctionCalls; + // AuxFunctionCalls - This vector contains call sites that have been processed + // by some mechanism. In pratice, the BU Analysis uses this vector to hold + // the _unresolved_ call sites, because it cannot modify FunctionCalls. + // + std::vector<DSCallSite> AuxFunctionCalls; + void operator=(const DSGraph &); // DO NOT IMPLEMENT public: DSGraph() : Func(0) {} // Create a new, empty, DSGraph. @@ -64,13 +69,20 @@ public: std::map<Value*, DSNodeHandle> &getScalarMap() { return ScalarMap; } const std::map<Value*, DSNodeHandle> &getScalarMap() const {return ScalarMap;} - std::vector<DSCallSite> &getFunctionCalls() { - return FunctionCalls; - } + /// getFunctionCalls - Return the list of call sites in the original local + /// graph... + /// const std::vector<DSCallSite> &getFunctionCalls() const { return FunctionCalls; } + /// getAuxFunctionCalls - Get the call sites as modified by whatever passes + /// have been run. + /// + std::vector<DSCallSite> &getAuxFunctionCalls() { + return AuxFunctionCalls; + } + /// getNodeForValue - Given a value that is used or defined in the body of the /// current function, return the DSNode that it points to. /// @@ -125,9 +137,11 @@ public: // void removeDeadNodes(bool KeepAllGlobals = false, bool KeepCalls = true); - enum AllocaBit { - StripAllocaBit, - KeepAllocaBit + // CloneFlags enum - Bits that may be passed into the cloneInto method to + // specify how to clone the function graph. + enum CloneFlags { + StripAllocaBit = 1 << 0, KeepAllocaBit = 0 << 0, + DontCloneCallNodes = 2 << 0, CloneCallNodes = 0 << 0, }; // cloneInto - Clone the specified DSGraph into the current graph, returning @@ -139,7 +153,7 @@ public: DSNodeHandle cloneInto(const DSGraph &G, std::map<Value*, DSNodeHandle> &OldValMap, std::map<const DSNode*, DSNodeHandle> &OldNodeMap, - AllocaBit StripAllocas = KeepAllocaBit); + unsigned CloneFlags = 0); /// mergeInGraph - The method is used for merging graphs together. If the /// argument graph is not *this, it makes a clone of the specified graph, then @@ -147,8 +161,7 @@ public: /// the graph. If the StripAlloca's argument is 'StripAllocaBit' then Alloca /// markers are removed from nodes. /// - void mergeInGraph(DSCallSite &CS, const DSGraph &Graph, - AllocaBit StripAllocas); + void mergeInGraph(DSCallSite &CS, const DSGraph &Graph, unsigned CloneFlags); #if 0 // cloneGlobalInto - Clone the given global node (or the node for the given diff --git a/include/llvm/Analysis/DSNode.h b/include/llvm/Analysis/DSNode.h index 2b01ec5..43d33bc 100644 --- a/include/llvm/Analysis/DSNode.h +++ b/include/llvm/Analysis/DSNode.h @@ -98,6 +98,10 @@ public: /// const std::vector<DSNodeHandle*> &getReferrers() const { return Referrers; } + /// hasNoReferrers - Return true if nothing is pointing to this node at all. + /// + bool hasNoReferrers() const { return Referrers.empty(); } + /// isModified - Return true if this node may be modified in this context /// bool isModified() const { return (NodeType & Modified) != 0; } diff --git a/include/llvm/Analysis/DataStructure.h b/include/llvm/Analysis/DataStructure.h index 79d738b..b38431b 100644 --- a/include/llvm/Analysis/DataStructure.h +++ b/include/llvm/Analysis/DataStructure.h @@ -9,6 +9,7 @@ #include "llvm/Analysis/DSSupport.h" #include "llvm/Pass.h" +#include <set> class Type; class DSGraph; @@ -66,7 +67,6 @@ public: class BUDataStructures : public Pass { // DSInfo, one graph for each function std::map<const Function*, DSGraph*> DSInfo; - std::map<const Function*, std::vector<DSCallSite> > CallSites; public: ~BUDataStructures() { releaseMemory(); } @@ -79,21 +79,12 @@ public: return *I->second; } - /// getCallSites - Return all of the call sites for the specified function - /// - const std::vector<DSCallSite> *getCallSites(const Function &F) const { - std::map<const Function*, std::vector<DSCallSite> >::const_iterator I - = CallSites.find(&F); - return I != CallSites.end() ? &I->second : 0; - } - - // print - Print out the analysis results... + // print - Print out the analysis results... void print(std::ostream &O, const Module *M) const; // If the pass pipeline is done with this pass, we can release our memory... virtual void releaseMemory(); - // getAnalysisUsage - This obviously provides a data structure graph. virtual void getAnalysisUsage(AnalysisUsage &AU) const { AU.setPreservesAll(); AU.addRequired<LocalDataStructures>(); @@ -109,24 +100,7 @@ private: class TDDataStructures : public Pass { // DSInfo, one graph for each function std::map<const Function*, DSGraph*> DSInfo; - - // Each graph in DSInfo is based on a graph in the BUDS object. The BUMaps - // member keeps the mappings from the BU graphs to the TD graphs as they are - // calculated by calculateGraph. This information is used to properly - // implement resolving of call sites, where the call sites in the BUGraph are - // in terms of the caller function's graph in the BUGraph. - // - typedef std::map<const DSNode*, DSNodeHandle> BUNodeMapTy; - std::map<const Function*, BUNodeMapTy> BUMaps; - - // CallSitesForFunction - This is a temporary map that is only kept around - // when building the top-down closures for a program. It traverses all of the - // call sites in the BU graph and holds all of the call sites that each - // function is the "resolving caller" for. - // - std::map<const Function*, - std::vector<const DSCallSite*> > CallSitesForFunction; - + std::set<const Function*> GraphDone; public: ~TDDataStructures() { releaseMemory(); } @@ -151,7 +125,8 @@ public: AU.addRequired<BUDataStructures>(); } private: - DSGraph &calculateGraph(Function &F); + void calculateGraph(Function &F); + DSGraph &getOrCreateDSGraph(Function &F); void ResolveCallSite(DSGraph &Graph, const DSCallSite &CallSite); }; diff --git a/include/llvm/Analysis/DataStructure/DSGraph.h b/include/llvm/Analysis/DataStructure/DSGraph.h index 9b283d3..50123dc 100644 --- a/include/llvm/Analysis/DataStructure/DSGraph.h +++ b/include/llvm/Analysis/DataStructure/DSGraph.h @@ -26,14 +26,19 @@ class DSGraph { #endif // FunctionCalls - This vector maintains a single entry for each call - // instruction in the current graph. Each call entry contains DSNodeHandles - // that refer to the arguments that are passed into the function call. The - // first entry in the vector is the scalar that holds the return value for the - // call, the second is the function scalar being invoked, and the rest are - // pointer arguments to the function. + // instruction in the current graph. The first entry in the vector is the + // scalar that holds the return value for the call, the second is the function + // scalar being invoked, and the rest are pointer arguments to the function. + // This vector is built by the Local graph and is never modified after that. // std::vector<DSCallSite> FunctionCalls; + // AuxFunctionCalls - This vector contains call sites that have been processed + // by some mechanism. In pratice, the BU Analysis uses this vector to hold + // the _unresolved_ call sites, because it cannot modify FunctionCalls. + // + std::vector<DSCallSite> AuxFunctionCalls; + void operator=(const DSGraph &); // DO NOT IMPLEMENT public: DSGraph() : Func(0) {} // Create a new, empty, DSGraph. @@ -64,13 +69,20 @@ public: std::map<Value*, DSNodeHandle> &getScalarMap() { return ScalarMap; } const std::map<Value*, DSNodeHandle> &getScalarMap() const {return ScalarMap;} - std::vector<DSCallSite> &getFunctionCalls() { - return FunctionCalls; - } + /// getFunctionCalls - Return the list of call sites in the original local + /// graph... + /// const std::vector<DSCallSite> &getFunctionCalls() const { return FunctionCalls; } + /// getAuxFunctionCalls - Get the call sites as modified by whatever passes + /// have been run. + /// + std::vector<DSCallSite> &getAuxFunctionCalls() { + return AuxFunctionCalls; + } + /// getNodeForValue - Given a value that is used or defined in the body of the /// current function, return the DSNode that it points to. /// @@ -125,9 +137,11 @@ public: // void removeDeadNodes(bool KeepAllGlobals = false, bool KeepCalls = true); - enum AllocaBit { - StripAllocaBit, - KeepAllocaBit + // CloneFlags enum - Bits that may be passed into the cloneInto method to + // specify how to clone the function graph. + enum CloneFlags { + StripAllocaBit = 1 << 0, KeepAllocaBit = 0 << 0, + DontCloneCallNodes = 2 << 0, CloneCallNodes = 0 << 0, }; // cloneInto - Clone the specified DSGraph into the current graph, returning @@ -139,7 +153,7 @@ public: DSNodeHandle cloneInto(const DSGraph &G, std::map<Value*, DSNodeHandle> &OldValMap, std::map<const DSNode*, DSNodeHandle> &OldNodeMap, - AllocaBit StripAllocas = KeepAllocaBit); + unsigned CloneFlags = 0); /// mergeInGraph - The method is used for merging graphs together. If the /// argument graph is not *this, it makes a clone of the specified graph, then @@ -147,8 +161,7 @@ public: /// the graph. If the StripAlloca's argument is 'StripAllocaBit' then Alloca /// markers are removed from nodes. /// - void mergeInGraph(DSCallSite &CS, const DSGraph &Graph, - AllocaBit StripAllocas); + void mergeInGraph(DSCallSite &CS, const DSGraph &Graph, unsigned CloneFlags); #if 0 // cloneGlobalInto - Clone the given global node (or the node for the given diff --git a/include/llvm/Analysis/DataStructure/DSNode.h b/include/llvm/Analysis/DataStructure/DSNode.h index 2b01ec5..43d33bc 100644 --- a/include/llvm/Analysis/DataStructure/DSNode.h +++ b/include/llvm/Analysis/DataStructure/DSNode.h @@ -98,6 +98,10 @@ public: /// const std::vector<DSNodeHandle*> &getReferrers() const { return Referrers; } + /// hasNoReferrers - Return true if nothing is pointing to this node at all. + /// + bool hasNoReferrers() const { return Referrers.empty(); } + /// isModified - Return true if this node may be modified in this context /// bool isModified() const { return (NodeType & Modified) != 0; } diff --git a/include/llvm/Analysis/DataStructure/DataStructure.h b/include/llvm/Analysis/DataStructure/DataStructure.h index 79d738b..b38431b 100644 --- a/include/llvm/Analysis/DataStructure/DataStructure.h +++ b/include/llvm/Analysis/DataStructure/DataStructure.h @@ -9,6 +9,7 @@ #include "llvm/Analysis/DSSupport.h" #include "llvm/Pass.h" +#include <set> class Type; class DSGraph; @@ -66,7 +67,6 @@ public: class BUDataStructures : public Pass { // DSInfo, one graph for each function std::map<const Function*, DSGraph*> DSInfo; - std::map<const Function*, std::vector<DSCallSite> > CallSites; public: ~BUDataStructures() { releaseMemory(); } @@ -79,21 +79,12 @@ public: return *I->second; } - /// getCallSites - Return all of the call sites for the specified function - /// - const std::vector<DSCallSite> *getCallSites(const Function &F) const { - std::map<const Function*, std::vector<DSCallSite> >::const_iterator I - = CallSites.find(&F); - return I != CallSites.end() ? &I->second : 0; - } - - // print - Print out the analysis results... + // print - Print out the analysis results... void print(std::ostream &O, const Module *M) const; // If the pass pipeline is done with this pass, we can release our memory... virtual void releaseMemory(); - // getAnalysisUsage - This obviously provides a data structure graph. virtual void getAnalysisUsage(AnalysisUsage &AU) const { AU.setPreservesAll(); AU.addRequired<LocalDataStructures>(); @@ -109,24 +100,7 @@ private: class TDDataStructures : public Pass { // DSInfo, one graph for each function std::map<const Function*, DSGraph*> DSInfo; - - // Each graph in DSInfo is based on a graph in the BUDS object. The BUMaps - // member keeps the mappings from the BU graphs to the TD graphs as they are - // calculated by calculateGraph. This information is used to properly - // implement resolving of call sites, where the call sites in the BUGraph are - // in terms of the caller function's graph in the BUGraph. - // - typedef std::map<const DSNode*, DSNodeHandle> BUNodeMapTy; - std::map<const Function*, BUNodeMapTy> BUMaps; - - // CallSitesForFunction - This is a temporary map that is only kept around - // when building the top-down closures for a program. It traverses all of the - // call sites in the BU graph and holds all of the call sites that each - // function is the "resolving caller" for. - // - std::map<const Function*, - std::vector<const DSCallSite*> > CallSitesForFunction; - + std::set<const Function*> GraphDone; public: ~TDDataStructures() { releaseMemory(); } @@ -151,7 +125,8 @@ public: AU.addRequired<BUDataStructures>(); } private: - DSGraph &calculateGraph(Function &F); + void calculateGraph(Function &F); + DSGraph &getOrCreateDSGraph(Function &F); void ResolveCallSite(DSGraph &Graph, const DSCallSite &CallSite); }; |