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/Support/CallSite.h"
20 #include "llvm/ADT/hash_map"
21 #include "llvm/ADT/hash_set"
22 #include "llvm/ADT/EquivalenceClasses.h"
34 FunctionPass *createDataStructureStatsPass();
35 FunctionPass *createDataStructureGraphCheckerPass();
38 // FIXME: move this stuff to a private header
39 namespace DataStructureAnalysis {
40 /// isPointerType - Return true if this first class type is big enough to hold
43 bool isPointerType(const Type *Ty);
47 // LocalDataStructures - The analysis that computes the local data structure
48 // graphs for all of the functions in the program.
50 // FIXME: This should be a Function pass that can be USED by a Pass, and would
51 // be automatically preserved. Until we can do that, this is a Pass.
53 class LocalDataStructures : public ModulePass {
54 // DSInfo, one graph for each function
55 hash_map<Function*, DSGraph*> DSInfo;
56 DSGraph *GlobalsGraph;
58 /// GlobalECs - The equivalence classes for each global value that is merged
59 /// with other global values in the DSGraphs.
60 EquivalenceClasses<GlobalValue*> GlobalECs;
62 ~LocalDataStructures() { releaseMemory(); }
64 virtual bool runOnModule(Module &M);
66 bool hasGraph(const Function &F) const {
67 return DSInfo.find(const_cast<Function*>(&F)) != DSInfo.end();
70 /// getDSGraph - Return the data structure graph for the specified function.
72 DSGraph &getDSGraph(const Function &F) const {
73 hash_map<Function*, DSGraph*>::const_iterator I =
74 DSInfo.find(const_cast<Function*>(&F));
75 assert(I != DSInfo.end() && "Function not in module!");
79 DSGraph &getGlobalsGraph() const { return *GlobalsGraph; }
81 EquivalenceClasses<GlobalValue*> &getGlobalECs() { return GlobalECs; }
83 /// print - Print out the analysis results...
85 void print(std::ostream &O, const Module *M) const;
87 /// releaseMemory - if the pass pipeline is done with this pass, we can
88 /// release our memory...
90 virtual void releaseMemory();
92 /// getAnalysisUsage - This obviously provides a data structure graph.
94 virtual void getAnalysisUsage(AnalysisUsage &AU) const {
96 AU.addRequired<TargetData>();
101 /// BUDataStructures - The analysis that computes the interprocedurally closed
102 /// data structure graphs for all of the functions in the program. This pass
103 /// only performs a "Bottom Up" propagation (hence the name).
105 class BUDataStructures : public ModulePass {
107 // DSInfo, one graph for each function
108 hash_map<Function*, DSGraph*> DSInfo;
109 DSGraph *GlobalsGraph;
110 std::set<std::pair<Instruction*, Function*> > ActualCallees;
112 // This map is only maintained during construction of BU Graphs
113 std::map<std::vector<Function*>,
114 std::pair<DSGraph*, std::vector<DSNodeHandle> > > *IndCallGraphMap;
116 /// GlobalECs - The equivalence classes for each global value that is merged
117 /// with other global values in the DSGraphs.
118 EquivalenceClasses<GlobalValue*> GlobalECs;
120 std::map<CallSite, std::vector<Function*> > AlreadyInlined;
123 ~BUDataStructures() { releaseMyMemory(); }
125 virtual bool runOnModule(Module &M);
127 bool hasGraph(const Function &F) const {
128 return DSInfo.find(const_cast<Function*>(&F)) != DSInfo.end();
131 /// getDSGraph - Return the data structure graph for the specified function.
133 DSGraph &getDSGraph(const Function &F) const {
134 hash_map<Function*, DSGraph*>::const_iterator I =
135 DSInfo.find(const_cast<Function*>(&F));
136 if (I != DSInfo.end())
138 return const_cast<BUDataStructures*>(this)->
139 CreateGraphForExternalFunction(F);
142 /// DSGraphExists - Is the DSGraph computed for this function?
144 bool doneDSGraph(const Function *F) const {
145 return (DSInfo.find(const_cast<Function*>(F)) != DSInfo.end());
148 DSGraph &getGlobalsGraph() const { return *GlobalsGraph; }
150 EquivalenceClasses<GlobalValue*> &getGlobalECs() { return GlobalECs; }
152 DSGraph &CreateGraphForExternalFunction(const Function &F);
154 /// deleteValue/copyValue - Interfaces to update the DSGraphs in the program.
155 /// These correspond to the interfaces defined in the AliasAnalysis class.
156 void deleteValue(Value *V);
157 void copyValue(Value *From, Value *To);
159 /// print - Print out the analysis results...
161 void print(std::ostream &O, const Module *M) const;
163 // FIXME: Once the pass manager is straightened out, rename this to
165 void releaseMyMemory();
167 virtual void getAnalysisUsage(AnalysisUsage &AU) const {
168 AU.setPreservesAll();
169 AU.addRequired<LocalDataStructures>();
172 typedef std::set<std::pair<Instruction*, Function*> > ActualCalleesTy;
173 const ActualCalleesTy &getActualCallees() const {
174 return ActualCallees;
177 typedef ActualCalleesTy::const_iterator callee_iterator;
178 callee_iterator callee_begin(Instruction *I) const {
179 return ActualCallees.lower_bound(std::pair<Instruction*,Function*>(I, 0));
182 callee_iterator callee_end(Instruction *I) const {
183 I = (Instruction*)((char*)I + 1);
184 return ActualCallees.lower_bound(std::pair<Instruction*,Function*>(I, 0));
188 void calculateGraph(DSGraph &G);
190 DSGraph &getOrCreateGraph(Function *F);
192 unsigned calculateGraphs(Function *F, std::vector<Function*> &Stack,
194 hash_map<Function*, unsigned> &ValMap);
198 /// TDDataStructures - Analysis that computes new data structure graphs
199 /// for each function using the closed graphs for the callers computed
200 /// by the bottom-up pass.
202 class TDDataStructures : public ModulePass {
203 // DSInfo, one graph for each function
204 hash_map<Function*, DSGraph*> DSInfo;
205 hash_set<Function*> ArgsRemainIncomplete;
206 DSGraph *GlobalsGraph;
207 BUDataStructures *BUInfo;
209 /// GlobalECs - The equivalence classes for each global value that is merged
210 /// with other global values in the DSGraphs.
211 EquivalenceClasses<GlobalValue*> GlobalECs;
213 /// CallerCallEdges - For a particular graph, we keep a list of these records
214 /// which indicates which graphs call this function and from where.
215 struct CallerCallEdge {
216 DSGraph *CallerGraph; // The graph of the caller function.
217 const DSCallSite *CS; // The actual call site.
218 Function *CalledFunction; // The actual function being called.
220 CallerCallEdge(DSGraph *G, const DSCallSite *cs, Function *CF)
221 : CallerGraph(G), CS(cs), CalledFunction(CF) {}
223 bool operator<(const CallerCallEdge &RHS) const {
224 return CallerGraph < RHS.CallerGraph ||
225 (CallerGraph == RHS.CallerGraph && CS < RHS.CS);
229 std::map<DSGraph*, std::vector<CallerCallEdge> > CallerEdges;
232 // IndCallMap - We memoize the results of indirect call inlining operations
233 // that have multiple targets here to avoid N*M inlining. The key to the map
234 // is a sorted set of callee functions, the value is the DSGraph that holds
235 // all of the caller graphs merged together, and the DSCallSite to merge with
236 // the arguments for each function.
237 std::map<std::vector<Function*>, DSGraph*> IndCallMap;
240 ~TDDataStructures() { releaseMyMemory(); }
242 virtual bool runOnModule(Module &M);
244 bool hasGraph(const Function &F) const {
245 return DSInfo.find(const_cast<Function*>(&F)) != DSInfo.end();
248 /// getDSGraph - Return the data structure graph for the specified function.
250 DSGraph &getDSGraph(const Function &F) const {
251 hash_map<Function*, DSGraph*>::const_iterator I =
252 DSInfo.find(const_cast<Function*>(&F));
253 if (I != DSInfo.end()) return *I->second;
254 return const_cast<TDDataStructures*>(this)->
255 getOrCreateDSGraph(const_cast<Function&>(F));
258 DSGraph &getGlobalsGraph() const { return *GlobalsGraph; }
259 EquivalenceClasses<GlobalValue*> &getGlobalECs() { return GlobalECs; }
262 /// deleteValue/copyValue - Interfaces to update the DSGraphs in the program.
263 /// These correspond to the interfaces defined in the AliasAnalysis class.
264 void deleteValue(Value *V);
265 void copyValue(Value *From, Value *To);
267 /// print - Print out the analysis results...
269 void print(std::ostream &O, const Module *M) const;
271 /// If the pass pipeline is done with this pass, we can release our memory...
273 virtual void releaseMyMemory();
275 /// getAnalysisUsage - This obviously provides a data structure graph.
277 virtual void getAnalysisUsage(AnalysisUsage &AU) const {
278 AU.setPreservesAll();
279 AU.addRequired<BUDataStructures>();
283 void markReachableFunctionsExternallyAccessible(DSNode *N,
284 hash_set<DSNode*> &Visited);
286 void InlineCallersIntoGraph(DSGraph &G);
287 DSGraph &getOrCreateDSGraph(Function &F);
288 void ComputePostOrder(Function &F, hash_set<DSGraph*> &Visited,
289 std::vector<DSGraph*> &PostOrder);
293 /// CompleteBUDataStructures - This is the exact same as the bottom-up graphs,
294 /// but we use take a completed call graph and inline all indirect callees into
295 /// their callers graphs, making the result more useful for things like pool
298 struct CompleteBUDataStructures : public BUDataStructures {
299 virtual bool runOnModule(Module &M);
301 bool hasGraph(const Function &F) const {
302 return DSInfo.find(const_cast<Function*>(&F)) != DSInfo.end();
305 /// getDSGraph - Return the data structure graph for the specified function.
307 DSGraph &getDSGraph(const Function &F) const {
308 hash_map<Function*, DSGraph*>::const_iterator I =
309 DSInfo.find(const_cast<Function*>(&F));
310 assert(I != DSInfo.end() && "Function not in module!");
314 virtual void getAnalysisUsage(AnalysisUsage &AU) const {
315 AU.setPreservesAll();
316 AU.addRequired<BUDataStructures>();
318 // FIXME: TEMPORARY (remove once finalization of indirect call sites in the
319 // globals graph has been implemented in the BU pass)
320 AU.addRequired<TDDataStructures>();
323 /// print - Print out the analysis results...
325 void print(std::ostream &O, const Module *M) const;
328 unsigned calculateSCCGraphs(DSGraph &FG, std::vector<DSGraph*> &Stack,
330 hash_map<DSGraph*, unsigned> &ValMap);
331 DSGraph &getOrCreateGraph(Function &F);
332 void processGraph(DSGraph &G);
336 /// EquivClassGraphs - This is the same as the complete bottom-up graphs, but
337 /// with functions partitioned into equivalence classes and a single merged
338 /// DS graph for all functions in an equivalence class. After this merging,
339 /// graphs are inlined bottom-up on the SCCs of the final (CBU) call graph.
341 struct EquivClassGraphs : public ModulePass {
342 CompleteBUDataStructures *CBU;
344 DSGraph *GlobalsGraph;
346 // DSInfo - one graph for each function.
347 hash_map<const Function*, DSGraph*> DSInfo;
349 /// ActualCallees - The actual functions callable from indirect call sites.
351 std::set<std::pair<Instruction*, Function*> > ActualCallees;
353 // Equivalence class where functions that can potentially be called via the
354 // same function pointer are in the same class.
355 EquivalenceClasses<Function*> FuncECs;
357 /// OneCalledFunction - For each indirect call, we keep track of one
358 /// target of the call. This is used to find equivalence class called by
360 std::map<DSNode*, Function *> OneCalledFunction;
362 /// GlobalECs - The equivalence classes for each global value that is merged
363 /// with other global values in the DSGraphs.
364 EquivalenceClasses<GlobalValue*> GlobalECs;
367 /// EquivClassGraphs - Computes the equivalence classes and then the
368 /// folded DS graphs for each class.
370 virtual bool runOnModule(Module &M);
372 /// print - Print out the analysis results...
374 void print(std::ostream &O, const Module *M) const;
376 EquivalenceClasses<GlobalValue*> &getGlobalECs() { return GlobalECs; }
378 /// getDSGraph - Return the data structure graph for the specified function.
379 /// This returns the folded graph. The folded graph is the same as the CBU
380 /// graph iff the function is in a singleton equivalence class AND all its
381 /// callees also have the same folded graph as the CBU graph.
383 DSGraph &getDSGraph(const Function &F) const {
384 hash_map<const Function*, DSGraph*>::const_iterator I = DSInfo.find(&F);
385 assert(I != DSInfo.end() && "No graph computed for that function!");
389 bool hasGraph(const Function &F) const {
390 return DSInfo.find(&F) != DSInfo.end();
393 /// ContainsDSGraphFor - Return true if we have a graph for the specified
395 bool ContainsDSGraphFor(const Function &F) const {
396 return DSInfo.find(&F) != DSInfo.end();
399 /// getSomeCalleeForCallSite - Return any one callee function at
402 Function *getSomeCalleeForCallSite(const CallSite &CS) const;
404 DSGraph &getGlobalsGraph() const {
405 return *GlobalsGraph;
408 typedef std::set<std::pair<Instruction*, Function*> > ActualCalleesTy;
409 const ActualCalleesTy &getActualCallees() const {
410 return ActualCallees;
413 typedef ActualCalleesTy::const_iterator callee_iterator;
414 callee_iterator callee_begin(Instruction *I) const {
415 return ActualCallees.lower_bound(std::pair<Instruction*,Function*>(I, 0));
418 callee_iterator callee_end(Instruction *I) const {
419 I = (Instruction*)((char*)I + 1);
420 return ActualCallees.lower_bound(std::pair<Instruction*,Function*>(I, 0));
423 virtual void getAnalysisUsage(AnalysisUsage &AU) const {
424 AU.setPreservesAll();
425 AU.addRequired<CompleteBUDataStructures>();
429 void buildIndirectFunctionSets(Module &M);
431 unsigned processSCC(DSGraph &FG, std::vector<DSGraph*> &Stack,
433 std::map<DSGraph*, unsigned> &ValMap);
434 void processGraph(DSGraph &FG);
436 DSGraph &getOrCreateGraph(Function &F);
439 } // End llvm namespace