1 //===- DataStructure.h - Build data structure graphs ------------*- C++ -*-===//
3 // The LLVM Compiler Infrastructure
5 // This file was developed by the LLVM research group and is distributed under
6 // the University of Illinois Open Source License. See LICENSE.TXT for details.
8 //===----------------------------------------------------------------------===//
10 // Implement the LLVM data structure analysis library.
12 //===----------------------------------------------------------------------===//
14 #ifndef LLVM_ANALYSIS_DATA_STRUCTURE_H
15 #define LLVM_ANALYSIS_DATA_STRUCTURE_H
17 #include "llvm/Pass.h"
18 #include "llvm/Target/TargetData.h"
19 #include "llvm/ADT/hash_map"
20 #include "llvm/ADT/hash_set"
21 #include "llvm/ADT/EquivalenceClasses.h"
32 // FIXME: move this stuff to a private header
33 namespace DataStructureAnalysis {
34 /// isPointerType - Return true if this first class type is big enough to hold
37 bool isPointerType(const Type *Ty);
41 // LocalDataStructures - The analysis that computes the local data structure
42 // graphs for all of the functions in the program.
44 // FIXME: This should be a Function pass that can be USED by a Pass, and would
45 // be automatically preserved. Until we can do that, this is a Pass.
47 class LocalDataStructures : public ModulePass {
48 // DSInfo, one graph for each function
49 hash_map<Function*, DSGraph*> DSInfo;
50 DSGraph *GlobalsGraph;
52 /// GlobalECs - The equivalence classes for each global value that is merged
53 /// with other global values in the DSGraphs.
54 EquivalenceClasses<GlobalValue*> GlobalECs;
56 ~LocalDataStructures() { releaseMemory(); }
58 virtual bool runOnModule(Module &M);
60 bool hasGraph(const Function &F) const {
61 return DSInfo.find(const_cast<Function*>(&F)) != DSInfo.end();
64 /// getDSGraph - Return the data structure graph for the specified function.
66 DSGraph &getDSGraph(const Function &F) const {
67 hash_map<Function*, DSGraph*>::const_iterator I =
68 DSInfo.find(const_cast<Function*>(&F));
69 assert(I != DSInfo.end() && "Function not in module!");
73 DSGraph &getGlobalsGraph() const { return *GlobalsGraph; }
75 EquivalenceClasses<GlobalValue*> &getGlobalECs() { return GlobalECs; }
77 /// print - Print out the analysis results...
79 void print(std::ostream &O, const Module *M) const;
81 /// releaseMemory - if the pass pipeline is done with this pass, we can
82 /// release our memory...
84 virtual void releaseMemory();
86 /// getAnalysisUsage - This obviously provides a data structure graph.
88 virtual void getAnalysisUsage(AnalysisUsage &AU) const {
90 AU.addRequired<TargetData>();
95 /// BUDataStructures - The analysis that computes the interprocedurally closed
96 /// data structure graphs for all of the functions in the program. This pass
97 /// only performs a "Bottom Up" propagation (hence the name).
99 class BUDataStructures : public ModulePass {
101 // DSInfo, one graph for each function
102 hash_map<Function*, DSGraph*> DSInfo;
103 DSGraph *GlobalsGraph;
104 hash_multimap<Instruction*, Function*> ActualCallees;
106 // This map is only maintained during construction of BU Graphs
107 std::map<std::vector<Function*>,
108 std::pair<DSGraph*, std::vector<DSNodeHandle> > > *IndCallGraphMap;
110 /// GlobalECs - The equivalence classes for each global value that is merged
111 /// with other global values in the DSGraphs.
112 EquivalenceClasses<GlobalValue*> GlobalECs;
114 ~BUDataStructures() { releaseMemory(); }
116 virtual bool runOnModule(Module &M);
118 bool hasGraph(const Function &F) const {
119 return DSInfo.find(const_cast<Function*>(&F)) != DSInfo.end();
122 /// getDSGraph - Return the data structure graph for the specified function.
124 DSGraph &getDSGraph(const Function &F) const {
125 hash_map<Function*, DSGraph*>::const_iterator I =
126 DSInfo.find(const_cast<Function*>(&F));
127 assert(I != DSInfo.end() && "Function not in module!");
131 DSGraph &getGlobalsGraph() const { return *GlobalsGraph; }
133 EquivalenceClasses<GlobalValue*> &getGlobalECs() { return GlobalECs; }
136 /// deleteValue/copyValue - Interfaces to update the DSGraphs in the program.
137 /// These correspond to the interfaces defined in the AliasAnalysis class.
138 void deleteValue(Value *V);
139 void copyValue(Value *From, Value *To);
141 /// print - Print out the analysis results...
143 void print(std::ostream &O, const Module *M) const;
145 /// releaseMemory - if the pass pipeline is done with this pass, we can
146 /// release our memory...
148 virtual void releaseMemory();
150 virtual void getAnalysisUsage(AnalysisUsage &AU) const {
151 AU.setPreservesAll();
152 AU.addRequired<LocalDataStructures>();
155 typedef hash_multimap<Instruction*, Function*> ActualCalleesTy;
156 const ActualCalleesTy &getActualCallees() const {
157 return ActualCallees;
161 void calculateGraph(DSGraph &G);
163 DSGraph &getOrCreateGraph(Function *F);
165 unsigned calculateGraphs(Function *F, std::vector<Function*> &Stack,
167 hash_map<Function*, unsigned> &ValMap);
171 /// TDDataStructures - Analysis that computes new data structure graphs
172 /// for each function using the closed graphs for the callers computed
173 /// by the bottom-up pass.
175 class TDDataStructures : public ModulePass {
176 // DSInfo, one graph for each function
177 hash_map<Function*, DSGraph*> DSInfo;
178 hash_set<Function*> ArgsRemainIncomplete;
179 DSGraph *GlobalsGraph;
181 /// GlobalECs - The equivalence classes for each global value that is merged
182 /// with other global values in the DSGraphs.
183 EquivalenceClasses<GlobalValue*> GlobalECs;
185 ~TDDataStructures() { releaseMyMemory(); }
187 virtual bool runOnModule(Module &M);
189 bool hasGraph(const Function &F) const {
190 return DSInfo.find(const_cast<Function*>(&F)) != DSInfo.end();
193 /// getDSGraph - Return the data structure graph for the specified function.
195 DSGraph &getDSGraph(const Function &F) const {
196 hash_map<Function*, DSGraph*>::const_iterator I =
197 DSInfo.find(const_cast<Function*>(&F));
198 assert(I != DSInfo.end() && "Function not in module!");
202 DSGraph &getGlobalsGraph() const { return *GlobalsGraph; }
203 EquivalenceClasses<GlobalValue*> &getGlobalECs() { return GlobalECs; }
206 /// deleteValue/copyValue - Interfaces to update the DSGraphs in the program.
207 /// These correspond to the interfaces defined in the AliasAnalysis class.
208 void deleteValue(Value *V);
209 void copyValue(Value *From, Value *To);
211 /// print - Print out the analysis results...
213 void print(std::ostream &O, const Module *M) const;
215 /// If the pass pipeline is done with this pass, we can release our memory...
217 virtual void releaseMyMemory();
219 /// getAnalysisUsage - This obviously provides a data structure graph.
221 virtual void getAnalysisUsage(AnalysisUsage &AU) const {
222 AU.setPreservesAll();
223 AU.addRequired<BUDataStructures>();
227 void markReachableFunctionsExternallyAccessible(DSNode *N,
228 hash_set<DSNode*> &Visited);
230 void inlineGraphIntoCallees(DSGraph &G);
231 DSGraph &getOrCreateDSGraph(Function &F);
232 void ComputePostOrder(Function &F, hash_set<DSGraph*> &Visited,
233 std::vector<DSGraph*> &PostOrder,
234 const BUDataStructures::ActualCalleesTy &ActualCallees);
238 /// CompleteBUDataStructures - This is the exact same as the bottom-up graphs,
239 /// but we use take a completed call graph and inline all indirect callees into
240 /// their callers graphs, making the result more useful for things like pool
243 struct CompleteBUDataStructures : public BUDataStructures {
244 virtual bool runOnModule(Module &M);
246 bool hasGraph(const Function &F) const {
247 return DSInfo.find(const_cast<Function*>(&F)) != DSInfo.end();
250 /// getDSGraph - Return the data structure graph for the specified function.
252 DSGraph &getDSGraph(const Function &F) const {
253 hash_map<Function*, DSGraph*>::const_iterator I =
254 DSInfo.find(const_cast<Function*>(&F));
255 assert(I != DSInfo.end() && "Function not in module!");
259 virtual void getAnalysisUsage(AnalysisUsage &AU) const {
260 AU.setPreservesAll();
261 AU.addRequired<BUDataStructures>();
263 // FIXME: TEMPORARY (remove once finalization of indirect call sites in the
264 // globals graph has been implemented in the BU pass)
265 AU.addRequired<TDDataStructures>();
268 /// print - Print out the analysis results...
270 void print(std::ostream &O, const Module *M) const;
273 unsigned calculateSCCGraphs(DSGraph &FG, std::vector<DSGraph*> &Stack,
275 hash_map<DSGraph*, unsigned> &ValMap);
276 DSGraph &getOrCreateGraph(Function &F);
277 void processGraph(DSGraph &G);
280 } // End llvm namespace