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 "Support/hash_set"
28 // FIXME: move this stuff to a private header
29 namespace DataStructureAnalysis {
30 // isPointerType - Return true if this first class type is big enough to hold
33 bool isPointerType(const Type *Ty);
37 // LocalDataStructures - The analysis that computes the local data structure
38 // graphs for all of the functions in the program.
40 // FIXME: This should be a Function pass that can be USED by a Pass, and would
41 // be automatically preserved. Until we can do that, this is a Pass.
43 class LocalDataStructures : public Pass {
44 // DSInfo, one graph for each function
45 hash_map<Function*, DSGraph*> DSInfo;
46 DSGraph *GlobalsGraph;
48 ~LocalDataStructures() { releaseMemory(); }
50 virtual bool run(Module &M);
52 bool hasGraph(const Function &F) const {
53 return DSInfo.find(const_cast<Function*>(&F)) != DSInfo.end();
56 // getDSGraph - Return the data structure graph for the specified function.
57 DSGraph &getDSGraph(const Function &F) const {
58 hash_map<Function*, DSGraph*>::const_iterator I =
59 DSInfo.find(const_cast<Function*>(&F));
60 assert(I != DSInfo.end() && "Function not in module!");
64 DSGraph &getGlobalsGraph() const { return *GlobalsGraph; }
66 // print - Print out the analysis results...
67 void print(std::ostream &O, const Module *M) const;
69 // If the pass pipeline is done with this pass, we can release our memory...
70 virtual void releaseMemory();
72 // getAnalysisUsage - This obviously provides a data structure graph.
73 virtual void getAnalysisUsage(AnalysisUsage &AU) const {
75 AU.addRequired<TargetData>();
80 // BUDataStructures - The analysis that computes the interprocedurally closed
81 // data structure graphs for all of the functions in the program. This pass
82 // only performs a "Bottom Up" propagation (hence the name).
84 class BUDataStructures : public Pass {
85 // DSInfo, one graph for each function
86 hash_map<Function*, DSGraph*> DSInfo;
87 DSGraph *GlobalsGraph;
88 hash_multimap<Instruction*, Function*> ActualCallees;
90 ~BUDataStructures() { releaseMemory(); }
92 virtual bool run(Module &M);
94 bool hasGraph(const Function &F) const {
95 return DSInfo.find(const_cast<Function*>(&F)) != DSInfo.end();
98 // getDSGraph - Return the data structure graph for the specified function.
99 DSGraph &getDSGraph(const Function &F) const {
100 hash_map<Function*, DSGraph*>::const_iterator I =
101 DSInfo.find(const_cast<Function*>(&F));
102 assert(I != DSInfo.end() && "Function not in module!");
106 DSGraph &getGlobalsGraph() const { return *GlobalsGraph; }
108 // print - Print out the analysis results...
109 void print(std::ostream &O, const Module *M) const;
111 // If the pass pipeline is done with this pass, we can release our memory...
112 virtual void releaseMemory();
114 virtual void getAnalysisUsage(AnalysisUsage &AU) const {
115 AU.setPreservesAll();
116 AU.addRequired<LocalDataStructures>();
119 typedef hash_multimap<Instruction*, Function*> ActualCalleesTy;
120 const ActualCalleesTy &getActualCallees() const {
121 return ActualCallees;
125 void calculateGraph(DSGraph &G);
127 void calculateReachableGraphs(Function *F);
130 DSGraph &getOrCreateGraph(Function *F);
132 unsigned calculateGraphs(Function *F, std::vector<Function*> &Stack,
134 hash_map<Function*, unsigned> &ValMap);
138 // TDDataStructures - Analysis that computes new data structure graphs
139 // for each function using the closed graphs for the callers computed
140 // by the bottom-up pass.
142 class TDDataStructures : public Pass {
143 // DSInfo, one graph for each function
144 hash_map<Function*, DSGraph*> DSInfo;
145 hash_set<Function*> ArgsRemainIncomplete;
146 DSGraph *GlobalsGraph;
148 ~TDDataStructures() { releaseMyMemory(); }
150 virtual bool run(Module &M);
152 bool hasGraph(const Function &F) const {
153 return DSInfo.find(const_cast<Function*>(&F)) != DSInfo.end();
156 // getDSGraph - Return the data structure graph for the specified function.
157 DSGraph &getDSGraph(const Function &F) const {
158 hash_map<Function*, DSGraph*>::const_iterator I =
159 DSInfo.find(const_cast<Function*>(&F));
160 assert(I != DSInfo.end() && "Function not in module!");
164 DSGraph &getGlobalsGraph() const { return *GlobalsGraph; }
166 // print - Print out the analysis results...
167 void print(std::ostream &O, const Module *M) const;
169 // If the pass pipeline is done with this pass, we can release our memory...
170 virtual void releaseMyMemory();
172 // getAnalysisUsage - This obviously provides a data structure graph.
173 virtual void getAnalysisUsage(AnalysisUsage &AU) const {
174 AU.setPreservesAll();
175 AU.addRequired<BUDataStructures>();
179 void markReachableFunctionsExternallyAccessible(DSNode *N,
180 hash_set<DSNode*> &Visited);
182 void inlineGraphIntoCallees(DSGraph &G);
183 DSGraph &getOrCreateDSGraph(Function &F);
184 void ComputePostOrder(Function &F, hash_set<DSGraph*> &Visited,
185 std::vector<DSGraph*> &PostOrder,
186 const BUDataStructures::ActualCalleesTy &ActualCallees);
189 } // End llvm namespace