456eb2f3335e4ee620480efcec584f86aecced0c
[oota-llvm.git] / lib / Analysis / DataStructure / Local.cpp
1 //===- Local.cpp - Compute a local data structure graph for a function ----===//
2 //
3 // Compute the local version of the data structure graph for a function.  The
4 // external interface to this file is the DSGraph constructor.
5 //
6 //===----------------------------------------------------------------------===//
7
8 #include "llvm/Analysis/DSGraph.h"
9 #include "llvm/Analysis/DataStructure.h"
10 #include "llvm/iMemory.h"
11 #include "llvm/iTerminators.h"
12 #include "llvm/iPHINode.h"
13 #include "llvm/iOther.h"
14 #include "llvm/Constants.h"
15 #include "llvm/DerivedTypes.h"
16 #include "llvm/Function.h"
17 #include "llvm/GlobalVariable.h"
18 #include "llvm/Support/InstVisitor.h"
19 #include "llvm/Target/TargetData.h"
20 #include "Support/Statistic.h"
21
22 // FIXME: This should eventually be a FunctionPass that is automatically
23 // aggregated into a Pass.
24 //
25 #include "llvm/Module.h"
26
27 using std::map;
28 using std::vector;
29
30 static RegisterAnalysis<LocalDataStructures>
31 X("datastructure", "Local Data Structure Analysis");
32
33 using namespace DataStructureAnalysis;
34
35 namespace DataStructureAnalysis {
36   // FIXME: Do something smarter with target data!
37   TargetData TD("temp-td");
38   unsigned PointerSize(TD.getPointerSize());
39
40   // isPointerType - Return true if this type is big enough to hold a pointer.
41   bool isPointerType(const Type *Ty) {
42     if (isa<PointerType>(Ty))
43       return true;
44     else if (Ty->isPrimitiveType() && Ty->isInteger())
45       return Ty->getPrimitiveSize() >= PointerSize;
46     return false;
47   }
48 }
49
50
51 namespace {
52   //===--------------------------------------------------------------------===//
53   //  GraphBuilder Class
54   //===--------------------------------------------------------------------===//
55   //
56   /// This class is the builder class that constructs the local data structure
57   /// graph by performing a single pass over the function in question.
58   ///
59   class GraphBuilder : InstVisitor<GraphBuilder> {
60     DSGraph &G;
61     vector<DSNode*> &Nodes;
62     DSNodeHandle &RetNode;               // Node that gets returned...
63     map<Value*, DSNodeHandle> &ValueMap;
64     vector<DSCallSite> &FunctionCalls;
65
66   public:
67     GraphBuilder(DSGraph &g, vector<DSNode*> &nodes, DSNodeHandle &retNode,
68                  map<Value*, DSNodeHandle> &vm,
69                  vector<DSCallSite> &fc)
70       : G(g), Nodes(nodes), RetNode(retNode), ValueMap(vm), FunctionCalls(fc) {
71
72       // Create scalar nodes for all pointer arguments...
73       for (Function::aiterator I = G.getFunction().abegin(),
74              E = G.getFunction().aend(); I != E; ++I)
75         if (isPointerType(I->getType()))
76           getValueDest(*I);
77
78       visit(G.getFunction());  // Single pass over the function
79
80       // Not inlining, only eliminate trivially dead nodes.
81       G.removeTriviallyDeadNodes();
82     }
83
84   private:
85     // Visitor functions, used to handle each instruction type we encounter...
86     friend class InstVisitor<GraphBuilder>;
87     void visitMallocInst(MallocInst &MI) { handleAlloc(MI, DSNode::NewNode); }
88     void visitAllocaInst(AllocaInst &AI) { handleAlloc(AI, DSNode::AllocaNode);}
89     void handleAlloc(AllocationInst &AI, DSNode::NodeTy NT);
90
91     void visitPHINode(PHINode &PN);
92
93     void visitGetElementPtrInst(GetElementPtrInst &GEP);
94     void visitReturnInst(ReturnInst &RI);
95     void visitLoadInst(LoadInst &LI);
96     void visitStoreInst(StoreInst &SI);
97     void visitCallInst(CallInst &CI);
98     void visitSetCondInst(SetCondInst &SCI) {}  // SetEQ & friends are ignored
99     void visitFreeInst(FreeInst &FI) {}         // Ignore free instructions
100     void visitCastInst(CastInst &CI);
101     void visitInstruction(Instruction &I) {}
102
103   private:
104     // Helper functions used to implement the visitation functions...
105
106     /// createNode - Create a new DSNode, ensuring that it is properly added to
107     /// the graph.
108     ///
109     DSNode *createNode(DSNode::NodeTy NodeType, const Type *Ty = 0) {
110       DSNode *N = new DSNode(NodeType, Ty);   // Create the node
111       Nodes.push_back(N);                     // Add node to nodes list
112       return N;
113     }
114
115     /// setDestTo - Set the ValueMap entry for the specified value to point to
116     /// the specified destination.  If the Value already points to a node, make
117     /// sure to merge the two destinations together.
118     ///
119     void setDestTo(Value &V, const DSNodeHandle &NH);
120
121     /// getValueDest - Return the DSNode that the actual value points to. 
122     ///
123     DSNodeHandle getValueDest(Value &V);
124
125     /// getLink - This method is used to return the specified link in the
126     /// specified node if one exists.  If a link does not already exist (it's
127     /// null), then we create a new node, link it, then return it.
128     ///
129     DSNodeHandle &getLink(const DSNodeHandle &Node, unsigned Link = 0);
130   };
131 }
132
133 //===----------------------------------------------------------------------===//
134 // DSGraph constructor - Simply use the GraphBuilder to construct the local
135 // graph.
136 DSGraph::DSGraph(Function &F) : Func(&F) {
137   // Use the graph builder to construct the local version of the graph
138   GraphBuilder B(*this, Nodes, RetNode, ValueMap, FunctionCalls);
139   markIncompleteNodes();
140 }
141
142
143 //===----------------------------------------------------------------------===//
144 // Helper method implementations...
145 //
146
147
148 /// getValueDest - Return the DSNode that the actual value points to.
149 ///
150 DSNodeHandle GraphBuilder::getValueDest(Value &V) {
151   if (Constant *C = dyn_cast<Constant>(&V)) {
152     // FIXME: Return null NH for constants like 10 or null
153     // FIXME: Handle constant exprs here.
154
155     return 0;   // Constant doesn't point to anything.
156   }
157
158   DSNodeHandle &NH = ValueMap[&V];
159   if (NH.getNode())
160     return NH;     // Already have a node?  Just return it...
161
162   // Otherwise we need to create a new node to point to...
163   DSNode *N;
164   if (GlobalValue *GV = dyn_cast<GlobalValue>(&V)) {
165     // Create a new global node for this global variable...
166     N = createNode(DSNode::GlobalNode, GV->getType()->getElementType());
167     N->addGlobal(GV);
168   } else {
169     // Otherwise just create a shadow node
170     N = createNode(DSNode::ShadowNode);
171   }
172
173   NH.setNode(N);      // Remember that we are pointing to it...
174   NH.setOffset(0);
175   return NH;
176 }
177
178
179 /// getLink - This method is used to return the specified link in the
180 /// specified node if one exists.  If a link does not already exist (it's
181 /// null), then we create a new node, link it, then return it.  We must
182 /// specify the type of the Node field we are accessing so that we know what
183 /// type should be linked to if we need to create a new node.
184 ///
185 DSNodeHandle &GraphBuilder::getLink(const DSNodeHandle &node, unsigned LinkNo) {
186   DSNodeHandle &Node = const_cast<DSNodeHandle&>(node);
187   DSNodeHandle *Link = Node.getLink(LinkNo);
188   if (Link) return *Link;
189
190   // If the link hasn't been created yet, make and return a new shadow node
191   DSNode *N = createNode(DSNode::ShadowNode);
192   Node.setLink(LinkNo, N);
193   return *Node.getLink(LinkNo);
194 }
195
196
197 /// setDestTo - Set the ValueMap entry for the specified value to point to the
198 /// specified destination.  If the Value already points to a node, make sure to
199 /// merge the two destinations together.
200 ///
201 void GraphBuilder::setDestTo(Value &V, const DSNodeHandle &NH) {
202   DSNodeHandle &AINH = ValueMap[&V];
203   if (AINH.getNode() == 0)   // Not pointing to anything yet?
204     AINH = NH;               // Just point directly to NH
205   else
206     AINH.mergeWith(NH);
207 }
208
209
210 //===----------------------------------------------------------------------===//
211 // Specific instruction type handler implementations...
212 //
213
214 /// Alloca & Malloc instruction implementation - Simply create a new memory
215 /// object, pointing the scalar to it.
216 ///
217 void GraphBuilder::handleAlloc(AllocationInst &AI, DSNode::NodeTy NodeType) {
218   setDestTo(AI, createNode(NodeType));
219 }
220
221 // PHINode - Make the scalar for the PHI node point to all of the things the
222 // incoming values point to... which effectively causes them to be merged.
223 //
224 void GraphBuilder::visitPHINode(PHINode &PN) {
225   if (!isPointerType(PN.getType())) return; // Only pointer PHIs
226
227   DSNodeHandle &PNDest = ValueMap[&PN];
228   for (unsigned i = 0, e = PN.getNumIncomingValues(); i != e; ++i)
229     PNDest.mergeWith(getValueDest(*PN.getIncomingValue(i)));
230 }
231
232 void GraphBuilder::visitGetElementPtrInst(GetElementPtrInst &GEP) {
233   DSNodeHandle Value = getValueDest(*GEP.getOperand(0));
234   if (Value.getNode() == 0) return;
235
236   unsigned Offset = 0;
237   const PointerType *PTy = cast<PointerType>(GEP.getOperand(0)->getType());
238   const Type *CurTy = PTy->getElementType();
239   DSTypeRec &TopTypeRec =
240     Value.getNode()->getTypeRec(PTy->getElementType(), Value.getOffset());
241
242   // If the node had to be folded... exit quickly
243   if (TopTypeRec.Ty == Type::VoidTy) {
244     setDestTo(GEP, Value);  // GEP result points to folded node
245     return;
246   }
247
248   // Handle the pointer index specially...
249   if (GEP.getNumOperands() > 1 &&
250       GEP.getOperand(1) != ConstantSInt::getNullValue(Type::LongTy)) {
251
252     // If we already know this is an array being accessed, don't do anything...
253     if (!TopTypeRec.isArray) {
254       TopTypeRec.isArray = true;
255
256       // If we are treating some inner field pointer as an array, fold the node
257       // up because we cannot handle it right.  This can come because of
258       // something like this:  &((&Pt->X)[1]) == &Pt->Y
259       //
260       if (Value.getOffset()) {
261         // Value is now the pointer we want to GEP to be...
262         Value.getNode()->foldNodeCompletely();
263         setDestTo(GEP, Value);  // GEP result points to folded node
264         return;
265       } else {
266         // This is a pointer to the first byte of the node.  Make sure that we
267         // are pointing to the outter most type in the node.
268         // FIXME: We need to check one more case here...
269       }
270     }
271   }
272
273   // All of these subscripts are indexing INTO the elements we have...
274   for (unsigned i = 2, e = GEP.getNumOperands(); i < e; ++i)
275     if (GEP.getOperand(i)->getType() == Type::LongTy) {
276       // Get the type indexing into...
277       const SequentialType *STy = cast<SequentialType>(CurTy);
278       CurTy = STy->getElementType();
279       if (ConstantSInt *CS = dyn_cast<ConstantSInt>(GEP.getOperand(i))) {
280         Offset += CS->getValue()*TD.getTypeSize(CurTy);
281       } else {
282         // Variable index into a node.  We must merge all of the elements of the
283         // sequential type here.
284         if (isa<PointerType>(STy))
285           std::cerr << "Pointer indexing not handled yet!\n";
286         else {
287           const ArrayType *ATy = cast<ArrayType>(STy);
288           unsigned ElSize = TD.getTypeSize(CurTy);
289           DSNode *N = Value.getNode();
290           assert(N && "Value must have a node!");
291           unsigned RawOffset = Offset+Value.getOffset();
292
293           // Loop over all of the elements of the array, merging them into the
294           // zero'th element.
295           for (unsigned i = 1, e = ATy->getNumElements(); i != e; ++i)
296             // Merge all of the byte components of this array element
297             for (unsigned j = 0; j != ElSize; ++j)
298               N->mergeIndexes(RawOffset+j, RawOffset+i*ElSize+j);
299         }
300       }
301     } else if (GEP.getOperand(i)->getType() == Type::UByteTy) {
302       unsigned FieldNo = cast<ConstantUInt>(GEP.getOperand(i))->getValue();
303       const StructType *STy = cast<StructType>(CurTy);
304       Offset += TD.getStructLayout(STy)->MemberOffsets[FieldNo];
305       CurTy = STy->getContainedType(FieldNo);
306     }
307
308   // Add in the offset calculated...
309   Value.setOffset(Value.getOffset()+Offset);
310
311   // Value is now the pointer we want to GEP to be...
312   setDestTo(GEP, Value);
313 }
314
315 void GraphBuilder::visitLoadInst(LoadInst &LI) {
316   DSNodeHandle Ptr = getValueDest(*LI.getOperand(0));
317   if (Ptr.getNode() == 0) return;
318
319   // Make that the node is read from...
320   Ptr.getNode()->NodeType |= DSNode::Read;
321
322   // Ensure a typerecord exists...
323   Ptr.getNode()->getTypeRec(LI.getType(), Ptr.getOffset());
324
325   if (isPointerType(LI.getType()))
326     setDestTo(LI, getLink(Ptr));
327 }
328
329 void GraphBuilder::visitStoreInst(StoreInst &SI) {
330   const Type *StoredTy = SI.getOperand(0)->getType();
331   DSNodeHandle Dest = getValueDest(*SI.getOperand(1));
332   if (Dest.getNode() == 0) return;
333
334   // Make that the node is written to...
335   Dest.getNode()->NodeType |= DSNode::Modified;
336
337   // Ensure a typerecord exists...
338   Dest.getNode()->getTypeRec(StoredTy, Dest.getOffset());
339
340   // Avoid adding edges from null, or processing non-"pointer" stores
341   if (isPointerType(StoredTy))
342     Dest.addEdgeTo(getValueDest(*SI.getOperand(0)));
343 }
344
345 void GraphBuilder::visitReturnInst(ReturnInst &RI) {
346   if (RI.getNumOperands() && isPointerType(RI.getOperand(0)->getType()))
347     RetNode.mergeWith(getValueDest(*RI.getOperand(0)));
348 }
349
350 void GraphBuilder::visitCallInst(CallInst &CI) {
351   // Set up the return value...
352   DSNodeHandle RetVal;
353   if (isPointerType(CI.getType()))
354     RetVal = getValueDest(CI);
355
356   DSNodeHandle Callee = getValueDest(*CI.getOperand(0));
357
358   std::vector<DSNodeHandle> Args;
359   Args.reserve(CI.getNumOperands()-1);
360
361   // Calculate the arguments vector...
362   for (unsigned i = 1, e = CI.getNumOperands(); i != e; ++i)
363     if (isPointerType(CI.getOperand(i)->getType()))
364       Args.push_back(getValueDest(*CI.getOperand(i)));
365
366   // Add a new function call entry...
367   FunctionCalls.push_back(DSCallSite(CI, RetVal, Callee, Args));
368 }
369
370 /// Handle casts...
371 void GraphBuilder::visitCastInst(CastInst &CI) {
372   if (isPointerType(CI.getType())) {
373     if (isPointerType(CI.getOperand(0)->getType()))
374       setDestTo(CI, getValueDest(*CI.getOperand(0)));
375     else
376       ; // FIXME: "Other" node
377   }
378 }
379
380
381
382
383 //===----------------------------------------------------------------------===//
384 // LocalDataStructures Implementation
385 //===----------------------------------------------------------------------===//
386
387 // releaseMemory - If the pass pipeline is done with this pass, we can release
388 // our memory... here...
389 //
390 void LocalDataStructures::releaseMemory() {
391   for (std::map<const Function*, DSGraph*>::iterator I = DSInfo.begin(),
392          E = DSInfo.end(); I != E; ++I)
393     delete I->second;
394
395   // Empty map so next time memory is released, data structures are not
396   // re-deleted.
397   DSInfo.clear();
398 }
399
400 bool LocalDataStructures::run(Module &M) {
401   // Calculate all of the graphs...
402   for (Module::iterator I = M.begin(), E = M.end(); I != E; ++I)
403     if (!I->isExternal())
404       DSInfo.insert(std::make_pair(I, new DSGraph(*I)));
405   return false;
406 }