944f532407ab06801a4d52923d3adadbbdf7a694
[oota-llvm.git] / lib / Analysis / MemoryDependenceAnalysis.cpp
1 //===- MemoryDependenceAnalysis.cpp - Mem Deps Implementation  --*- C++ -*-===//
2 //
3 //                     The LLVM Compiler Infrastructure
4 //
5 // This file was developed by the Owen Anderson and is distributed under
6 // the University of Illinois Open Source License. See LICENSE.TXT for details.
7 //
8 //===----------------------------------------------------------------------===//
9 //
10 // This file implements an analysis that determines, for a given memory
11 // operation, what preceding memory operations it depends on.  It builds on 
12 // alias analysis information, and tries to provide a lazy, caching interface to 
13 // a common kind of alias information query.
14 //
15 //===----------------------------------------------------------------------===//
16
17 #include "llvm/Analysis/MemoryDependenceAnalysis.h"
18 #include "llvm/Constants.h"
19 #include "llvm/Instructions.h"
20 #include "llvm/Function.h"
21 #include "llvm/Analysis/AliasAnalysis.h"
22 #include "llvm/Target/TargetData.h"
23
24 using namespace llvm;
25
26 char MemoryDependenceAnalysis::ID = 0;
27   
28 Instruction* MemoryDependenceAnalysis::NonLocal = (Instruction*)0;
29 Instruction* MemoryDependenceAnalysis::None = (Instruction*)~0;
30   
31 // Register this pass...
32 RegisterPass<MemoryDependenceAnalysis> X("memdep",
33                                            "Memory Dependence Analysis");
34
35 /// getAnalysisUsage - Does not modify anything.  It uses Alias Analysis.
36 ///
37 void MemoryDependenceAnalysis::getAnalysisUsage(AnalysisUsage &AU) const {
38   AU.setPreservesAll();
39   AU.addRequiredTransitive<AliasAnalysis>();
40   AU.addRequiredTransitive<TargetData>();
41 }
42
43 // Find the dependency of a CallSite
44 Instruction* MemoryDependenceAnalysis::getCallSiteDependency(CallSite C, bool local) {
45   assert(local && "Non-local memory dependence analysis not yet implemented");
46   
47   AliasAnalysis& AA = getAnalysis<AliasAnalysis>();
48   TargetData& TD = getAnalysis<TargetData>();
49   BasicBlock::iterator blockBegin = C.getInstruction()->getParent()->begin();
50   BasicBlock::iterator QI = C.getInstruction();
51   
52   while (QI != blockBegin) {
53     --QI;
54     
55     // If this inst is a memory op, get the pointer it accessed
56     Value* pointer = 0;
57     uint64_t pointerSize = 0;
58     if (StoreInst* S = dyn_cast<StoreInst>(QI)) {
59       pointer = S->getPointerOperand();
60       pointerSize = TD.getTypeSize(S->getOperand(0)->getType());
61     } else if (LoadInst* L = dyn_cast<LoadInst>(QI)) {
62       pointer = L->getPointerOperand();
63       pointerSize = TD.getTypeSize(L->getType());
64     } else if (AllocationInst* AI = dyn_cast<AllocationInst>(QI)) {
65       pointer = AI;
66       if (ConstantInt* C = dyn_cast<ConstantInt>(AI->getArraySize()))
67         pointerSize = C->getZExtValue();
68       else
69         pointerSize = ~0UL;
70     } else if (FreeInst* F = dyn_cast<FreeInst>(QI)) {
71       pointer = F->getPointerOperand();
72       
73       // FreeInsts erase the entire structure
74       pointerSize = ~0UL;
75     } else if (CallSite::get(QI).getInstruction() != 0) {
76       if (AA.getModRefInfo(C, CallSite::get(QI)) != AliasAnalysis::NoModRef) {
77         depGraphLocal.insert(std::make_pair(C.getInstruction(), std::make_pair(QI, true)));
78         reverseDep.insert(std::make_pair(QI, C.getInstruction()));
79         return QI;
80       } else {
81         continue;
82       }
83     }
84     
85     if (AA.getModRefInfo(C, pointer, pointerSize) != AliasAnalysis::NoModRef) {
86       depGraphLocal.insert(std::make_pair(C.getInstruction(), std::make_pair(QI, true)));
87       reverseDep.insert(std::make_pair(QI, C.getInstruction()));
88       return QI;
89     }
90   }
91   
92   // No dependence found
93   depGraphLocal.insert(std::make_pair(C.getInstruction(), std::make_pair(NonLocal, true)));
94   reverseDep.insert(std::make_pair(NonLocal, C.getInstruction()));
95   return NonLocal;
96 }
97
98 /// getDependency - Return the instruction on which a memory operation
99 /// depends.  The local paramter indicates if the query should only
100 /// evaluate dependencies within the same basic block.
101 Instruction* MemoryDependenceAnalysis::getDependency(Instruction* query,
102                                                      bool local) {
103   if (!local)
104     assert(0 && "Non-local memory dependence is not yet supported.");
105   
106   // Start looking for dependencies with the queried inst
107   BasicBlock::iterator QI = query;
108   
109   // Check for a cached result
110   std::pair<Instruction*, bool> cachedResult = depGraphLocal[query];
111   // If we have a _confirmed_ cached entry, return it
112   if (cachedResult.second)
113     return cachedResult.first;
114   else if (cachedResult.first != NonLocal)
115   // If we have an unconfirmed cached entry, we can start our search from there
116     QI = cachedResult.first;
117   
118   AliasAnalysis& AA = getAnalysis<AliasAnalysis>();
119   TargetData& TD = getAnalysis<TargetData>();
120   
121   // Get the pointer value for which dependence will be determined
122   Value* dependee = 0;
123   uint64_t dependeeSize = 0;
124   bool queryIsVolatile = false;
125   if (StoreInst* S = dyn_cast<StoreInst>(QI)) {
126     dependee = S->getPointerOperand();
127     dependeeSize = TD.getTypeSize(S->getOperand(0)->getType());
128     queryIsVolatile = S->isVolatile();
129   } else if (LoadInst* L = dyn_cast<LoadInst>(QI)) {
130     dependee = L->getPointerOperand();
131     dependeeSize = TD.getTypeSize(L->getType());
132     queryIsVolatile = L->isVolatile();
133   } else if (FreeInst* F = dyn_cast<FreeInst>(QI)) {
134     dependee = F->getPointerOperand();
135     
136     // FreeInsts erase the entire structure, not just a field
137     dependeeSize = ~0UL;
138   } else if (CallSite::get(QI).getInstruction() != 0)
139     return getCallSiteDependency(CallSite::get(QI));
140   else if (isa<AllocationInst>(query))
141     return None;
142   else
143     return None;
144   
145   BasicBlock::iterator blockBegin = query->getParent()->begin();
146   
147   while (QI != blockBegin) {
148     --QI;
149     
150     // If this inst is a memory op, get the pointer it accessed
151     Value* pointer = 0;
152     uint64_t pointerSize = 0;
153     if (StoreInst* S = dyn_cast<StoreInst>(QI)) {
154       // All volatile loads/stores depend on each other
155       if (queryIsVolatile && S->isVolatile()) {
156         depGraphLocal.insert(std::make_pair(query, std::make_pair(S, true)));
157         reverseDep.insert(std::make_pair(S, query));
158         return S;
159       }
160       
161       pointer = S->getPointerOperand();
162       pointerSize = TD.getTypeSize(S->getOperand(0)->getType());
163     } else if (LoadInst* L = dyn_cast<LoadInst>(QI)) {
164       // All volatile loads/stores depend on each other
165       if (queryIsVolatile && L->isVolatile()) {
166         depGraphLocal.insert(std::make_pair(query, std::make_pair(L, true)));
167         reverseDep.insert(std::make_pair(L, query));
168         return L;
169       }
170       
171       pointer = L->getPointerOperand();
172       pointerSize = TD.getTypeSize(L->getType());
173     } else if (AllocationInst* AI = dyn_cast<AllocationInst>(QI)) {
174       pointer = AI;
175       if (ConstantInt* C = dyn_cast<ConstantInt>(AI->getArraySize()))
176         pointerSize = C->getZExtValue();
177       else
178         pointerSize = ~0UL;
179     } else if (FreeInst* F = dyn_cast<FreeInst>(QI)) {
180       pointer = F->getPointerOperand();
181       
182       // FreeInsts erase the entire structure
183       pointerSize = ~0UL;
184     } else if (CallSite::get(QI).getInstruction() != 0) {
185       // Call insts need special handling.  Check is they can modify our pointer
186       if (AA.getModRefInfo(CallSite::get(QI), dependee, dependeeSize) !=
187           AliasAnalysis::NoModRef) {
188         depGraphLocal.insert(std::make_pair(query, std::make_pair(QI, true)));
189         reverseDep.insert(std::make_pair(QI, query));
190         return QI;
191       } else {
192         continue;
193       }
194     }
195     
196     // If we found a pointer, check if it could be the same as our pointer
197     if (pointer) {
198       AliasAnalysis::AliasResult R = AA.alias(pointer, pointerSize,
199                                               dependee, dependeeSize);
200       
201       if (R != AliasAnalysis::NoAlias) {
202         depGraphLocal.insert(std::make_pair(query, std::make_pair(QI, true)));
203         reverseDep.insert(std::make_pair(QI, query));
204         return QI;
205       }
206     }
207   }
208   
209   // If we found nothing, return the non-local flag
210   depGraphLocal.insert(std::make_pair(query,
211                                       std::make_pair(NonLocal, true)));
212   reverseDep.insert(std::make_pair(NonLocal, query));
213   
214   return NonLocal;
215 }
216
217 /// removeInstruction - Remove an instruction from the dependence analysis,
218 /// updating the dependence of instructions that previously depended on it.
219 void MemoryDependenceAnalysis::removeInstruction(Instruction* rem) {
220   // Figure out the new dep for things that currently depend on rem
221   Instruction* newDep = NonLocal;
222   if (depGraphLocal[rem].first != NonLocal) {
223     // If we have dep info for rem, set them to it
224     BasicBlock::iterator RI = depGraphLocal[rem].first;
225     RI++;
226     newDep = RI;
227   } else if (depGraphLocal[rem].first == NonLocal &&
228              depGraphLocal[rem].second ) {
229     // If we have a confirmed non-local flag, use it
230     newDep = NonLocal;
231   } else {
232     // Otherwise, use the immediate successor of rem
233     // NOTE: This is because, when getDependence is called, it will first check
234     // the immediate predecessor of what is in the cache.
235     BasicBlock::iterator RI = rem;
236     RI++;
237     newDep = RI;
238   }
239
240   std::multimap<Instruction*, Instruction*>::iterator I = reverseDep.find(rem);
241   while (I->first == rem) {
242     // Insert the new dependencies
243     // Mark it as unconfirmed as long as it is not the non-local flag
244     depGraphLocal[I->second] = std::make_pair(newDep, !newDep);
245     reverseDep.erase(I);
246     I = reverseDep.find(rem);
247   }
248 }