60cf964042925792200323c72840eda396f86a2c
[oota-llvm.git] / lib / Analysis / DataStructure / FunctionRepBuilder.cpp
1 //===- FunctionRepBuilder.cpp - Build the local datastructure graph -------===//
2 //
3 // Build the local datastructure graph for a single method.
4 //
5 //===----------------------------------------------------------------------===//
6
7 #include "FunctionRepBuilder.h"
8 #include "llvm/Function.h"
9 #include "llvm/iMemory.h"
10 #include "llvm/iPHINode.h"
11 #include "llvm/iOther.h"
12 #include "llvm/iTerminators.h"
13 #include "llvm/DerivedTypes.h"
14 #include "Support/STLExtras.h"
15 #include <algorithm>
16
17 // synthesizeNode - Create a new shadow node that is to be linked into this
18 // chain..
19 // FIXME: This should not take a FunctionRepBuilder as an argument!
20 //
21 ShadowDSNode *ShadowDSNode::synthesizeNode(const Type *Ty,
22                                            FunctionRepBuilder *Rep) {
23   // If we are a derived shadow node, defer to our parent to synthesize the node
24   if (ShadowParent) return ShadowParent->synthesizeNode(Ty, Rep);
25
26   // See if we have already synthesized a node of this type...
27   for (unsigned i = 0, e = SynthNodes.size(); i != e; ++i)
28     if (SynthNodes[i].first == Ty) return SynthNodes[i].second;
29
30   // No we haven't.  Do so now and add it to our list of saved nodes...
31   ShadowDSNode *SN = new ShadowDSNode(Ty, Mod, this);
32   SynthNodes.push_back(make_pair(Ty, SN));
33   Rep->addShadowNode(SN);
34   return SN;
35 }
36
37
38
39
40 // visitOperand - If the specified instruction operand is a global value, add
41 // a node for it...
42 //
43 void InitVisitor::visitOperand(Value *V) {
44   if (!Rep->ValueMap.count(V))                  // Only process it once...
45     if (GlobalValue *GV = dyn_cast<GlobalValue>(V)) {
46       GlobalDSNode *N = new GlobalDSNode(GV);
47       Rep->GlobalNodes.push_back(N);
48       Rep->ValueMap[V].add(N);
49       Rep->addAllUsesToWorkList(GV);
50
51       // FIXME: If the global variable has fields, we should add critical
52       // shadow nodes to represent them!
53     }
54 }
55
56
57 // visitCallInst - Create a call node for the callinst, and create as shadow
58 // node if the call returns a pointer value.  Check to see if the call node
59 // uses any global variables...
60 //
61 void InitVisitor::visitCallInst(CallInst *CI) {
62   CallDSNode *C = new CallDSNode(CI);
63   Rep->CallNodes.push_back(C);
64   Rep->CallMap[CI] = C;
65       
66   if (isa<PointerType>(CI->getType())) {
67     // Create a critical shadow node to represent the memory object that the
68     // return value points to...
69     ShadowDSNode *Shad = new ShadowDSNode(C, Func->getParent(), true);
70     Rep->ShadowNodes.push_back(Shad);
71     
72     // The return value of the function is a pointer to the shadow value
73     // just created...
74     //
75     C->getLink(0).add(Shad);
76
77     // The call instruction returns a pointer to the shadow block...
78     Rep->ValueMap[CI].add(Shad, CI);
79     
80     // If the call returns a value with pointer type, add all of the users
81     // of the call instruction to the work list...
82     Rep->addAllUsesToWorkList(CI);
83   }
84
85   // Loop over all of the operands of the call instruction (except the first
86   // one), to look for global variable references...
87   //
88   for_each(CI->op_begin()+1, CI->op_end(),   // Skip first arg
89            bind_obj(this, &InitVisitor::visitOperand));
90 }
91
92
93 // visitAllocationInst - Create an allocation node for the allocation.  Since
94 // allocation instructions do not take pointer arguments, they cannot refer to
95 // global vars...
96 //
97 void InitVisitor::visitAllocationInst(AllocationInst *AI) {
98   AllocDSNode *N = new AllocDSNode(AI);
99   Rep->AllocNodes.push_back(N);
100   
101   Rep->ValueMap[AI].add(N, AI);
102   
103   // Add all of the users of the malloc instruction to the work list...
104   Rep->addAllUsesToWorkList(AI);
105 }
106
107
108 // Visit all other instruction types.  Here we just scan, looking for uses of
109 // global variables...
110 //
111 void InitVisitor::visitInstruction(Instruction *I) {
112   for_each(I->op_begin(), I->op_end(),
113            bind_obj(this, &InitVisitor::visitOperand));
114 }
115
116
117 // addAllUsesToWorkList - Add all of the instructions users of the specified
118 // value to the work list for further processing...
119 //
120 void FunctionRepBuilder::addAllUsesToWorkList(Value *V) {
121   //cerr << "Adding all uses of " << V << "\n";
122   for (Value::use_iterator I = V->use_begin(), E = V->use_end(); I != E; ++I) {
123     Instruction *Inst = cast<Instruction>(*I);
124     // When processing global values, it's possible that the instructions on
125     // the use list are not all in this method.  Only add the instructions
126     // that _are_ in this method.
127     //
128     if (Inst->getParent()->getParent() == F->getFunction())
129       // Only let an instruction occur on the work list once...
130       if (std::find(WorkList.begin(), WorkList.end(), Inst) == WorkList.end())
131         WorkList.push_back(Inst);
132   }
133 }
134
135
136
137
138 void FunctionRepBuilder::initializeWorkList(Function *Func) {
139   // Add all of the arguments to the method to the graph and add all users to
140   // the worklists...
141   //
142   for (Function::ArgumentListType::iterator I = Func->getArgumentList().begin(),
143          E = Func->getArgumentList().end(); I != E; ++I)
144     // Only process arguments that are of pointer type...
145     if (isa<PointerType>((*I)->getType())) {
146       ArgDSNode *Arg = new ArgDSNode(*I);
147       ArgNodes.push_back(Arg);
148       
149       // Add a critical shadow value for it to represent what it is pointing
150       // to and add this to the value map...
151       ShadowDSNode *Shad = new ShadowDSNode(Arg, Func->getParent(), true);
152       ShadowNodes.push_back(Shad);
153       ValueMap[*I].add(PointerVal(Shad), *I);
154       
155       // The value of the argument is the shadow value...
156       Arg->getLink(0).add(Shad);
157       
158       // Make sure that all users of the argument are processed...
159       addAllUsesToWorkList(*I);
160     }
161   
162   // Iterate over the instructions in the method.  Create nodes for malloc and
163   // call instructions.  Add all uses of these to the worklist of instructions
164   // to process.
165   //
166   InitVisitor IV(this, Func);
167   IV.visit(Func);
168 }
169
170
171
172
173 PointerVal FunctionRepBuilder::getIndexedPointerDest(const PointerVal &InP,
174                                                      const MemAccessInst *MAI) {
175   unsigned Index = InP.Index;
176   const Type *SrcTy = MAI->getPointerOperand()->getType();
177
178   for (MemAccessInst::const_op_iterator I = MAI->idx_begin(),
179          E = MAI->idx_end(); I != E; ++I)
180     if ((*I)->getType() == Type::UByteTy) {     // Look for struct indices...
181       StructType *STy = cast<StructType>(SrcTy);
182       unsigned StructIdx = cast<ConstantUInt>(*I)->getValue();
183       for (unsigned i = 0; i != StructIdx; ++i)
184         Index += countPointerFields(STy->getContainedType(i));
185
186       // Advance SrcTy to be the new element type...
187       SrcTy = STy->getContainedType(StructIdx);
188     } else {
189       // Otherwise, stepping into array or initial pointer, just increment type
190       SrcTy = cast<SequentialType>(SrcTy)->getElementType();
191     }
192   
193   return PointerVal(InP.Node, Index);
194 }
195
196 static PointerValSet &getField(const PointerVal &DestPtr) {
197   assert(DestPtr.Node != 0);
198
199   return DestPtr.Node->getLink(DestPtr.Index);
200 }
201
202
203 // Reprocessing a GEP instruction is the result of the pointer operand
204 // changing.  This means that the set of possible values for the GEP
205 // needs to be expanded.
206 //
207 void FunctionRepBuilder::visitGetElementPtrInst(GetElementPtrInst *GEP) {
208   PointerValSet &GEPPVS = ValueMap[GEP];   // PointerValSet to expand
209       
210   // Get the input pointer val set...
211   const PointerValSet &SrcPVS = ValueMap[GEP->getOperand(0)];
212       
213   bool Changed = false;  // Process each input value... propogating it.
214   for (unsigned i = 0, e = SrcPVS.size(); i != e; ++i) {
215     // Calculate where the resulting pointer would point based on an
216     // input of 'Val' as the pointer type... and add it to our outgoing
217     // value set.  Keep track of whether or not we actually changed
218     // anything.
219     //
220     Changed |= GEPPVS.add(getIndexedPointerDest(SrcPVS[i], GEP));
221   }
222
223   // If our current value set changed, notify all of the users of our
224   // value.
225   //
226   if (Changed) addAllUsesToWorkList(GEP);        
227 }
228
229 void FunctionRepBuilder::visitReturnInst(ReturnInst *RI) {
230   RetNode.add(ValueMap[RI->getOperand(0)]);
231 }
232
233 void FunctionRepBuilder::visitLoadInst(LoadInst *LI) {
234   // Only loads that return pointers are interesting...
235   if (!isa<PointerType>(LI->getType())) return;
236   const PointerType *DestTy = cast<PointerType>(LI->getType());
237
238   const PointerValSet &SrcPVS = ValueMap[LI->getOperand(0)];        
239   PointerValSet &LIPVS = ValueMap[LI];
240
241   bool Changed = false;
242   for (unsigned si = 0, se = SrcPVS.size(); si != se; ++si) {
243     PointerVal Ptr = getIndexedPointerDest(SrcPVS[si], LI);
244     PointerValSet &Field = getField(Ptr);
245
246     if (Field.size()) {             // Field loaded wasn't null?
247       Changed |= LIPVS.add(Field);
248     } else if (Ptr.Node->NodeType == DSNode::ShadowNode) {
249       // If we are loading a null field out of a shadow node, we need to
250       // synthesize a new shadow node and link it in...
251       //
252       ShadowDSNode *Shad = (ShadowDSNode*)Ptr.Node;
253       ShadowDSNode *SynthNode =
254         Shad->synthesizeNode(DestTy->getElementType(), this);
255       Field.add(SynthNode);
256
257       Changed |= LIPVS.add(Field);
258     }
259   }
260
261   if (Changed) addAllUsesToWorkList(LI);
262 }
263
264 void FunctionRepBuilder::visitStoreInst(StoreInst *SI) {
265   // The only stores that are interesting are stores the store pointers
266   // into data structures...
267   //
268   if (!isa<PointerType>(SI->getOperand(0)->getType())) return;
269         
270   const PointerValSet &SrcPVS = ValueMap[SI->getOperand(0)];
271   const PointerValSet &PtrPVS = ValueMap[SI->getOperand(1)];
272
273   for (unsigned si = 0, se = SrcPVS.size(); si != se; ++si) {
274     const PointerVal &SrcPtr = SrcPVS[si];
275     for (unsigned pi = 0, pe = PtrPVS.size(); pi != pe; ++pi) {
276       PointerVal Dest = getIndexedPointerDest(PtrPVS[pi], SI);
277
278 #if 0
279       cerr << "Setting Dest:\n";
280       Dest.print(cerr);
281       cerr << "to point to Src:\n";
282       SrcPtr.print(cerr);
283 #endif
284
285       // Add SrcPtr into the Dest field...
286       if (getField(Dest).add(SrcPtr)) {
287         // If we modified the dest field, then invalidate everyone that points
288         // to Dest.
289         const std::vector<Value*> &Ptrs = Dest.Node->getPointers();
290         for (unsigned i = 0, e = Ptrs.size(); i != e; ++i)
291           addAllUsesToWorkList(Ptrs[i]);
292       }
293     }
294   }
295 }
296
297 void FunctionRepBuilder::visitCallInst(CallInst *CI) {
298   CallDSNode *DSN = CallMap[CI];
299    
300   unsigned PtrNum = 0, i = 0;
301   if (isa<Function>(CI->getOperand(0)))
302     ++i;          // Not an Indirect function call? Skip the function pointer...
303
304   for (unsigned e = CI->getNumOperands(); i != e; ++i)
305     if (isa<PointerType>(CI->getOperand(i)->getType()))
306       DSN->addArgValue(PtrNum++, ValueMap[CI->getOperand(i)]);
307 }
308
309 void FunctionRepBuilder::visitPHINode(PHINode *PN) {
310   assert(isa<PointerType>(PN->getType()) && "Should only update ptr phis");
311
312   PointerValSet &PN_PVS = ValueMap[PN];
313   bool Changed = false;
314   for (unsigned i = 0, e = PN->getNumIncomingValues(); i != e; ++i)
315     Changed |= PN_PVS.add(ValueMap[PN->getIncomingValue(i)],
316                           PN->getIncomingValue(i));
317
318   if (Changed) addAllUsesToWorkList(PN);
319 }
320
321
322
323
324 // FunctionDSGraph constructor - Perform the global analysis to determine
325 // what the data structure usage behavior or a method looks like.
326 //
327 FunctionDSGraph::FunctionDSGraph(Function *F) : Func(F) {
328   FunctionRepBuilder Builder(this);
329   ArgNodes    = Builder.getArgNodes();
330   AllocNodes  = Builder.getAllocNodes();
331   ShadowNodes = Builder.getShadowNodes();
332   GlobalNodes = Builder.getGlobalNodes();
333   CallNodes   = Builder.getCallNodes();
334   RetNode     = Builder.getRetNode();
335   ValueMap    = Builder.getValueMap();
336
337   bool Changed = true;
338   while (Changed) {
339     // Eliminate shadow nodes that are not distinguishable from some other
340     // node in the graph...
341     //
342     Changed = UnlinkUndistinguishableNodes();
343
344     // Eliminate shadow nodes that are now extraneous due to linking...
345     Changed |= RemoveUnreachableNodes();
346   }
347 }
348