blob: 8736ad4c28ed378ce5fd64d536f39ce6858cadfe [file] [log] [blame]
Dan Gohmanf17a25c2007-07-18 16:29:46 +00001//===- 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
Owen Andersonafe840e2007-08-08 22:01:54 +000012// alias analysis information, and tries to provide a lazy, caching interface to
Dan Gohmanf17a25c2007-07-18 16:29:46 +000013// 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"
Owen Anderson4c295472007-07-24 21:52:37 +000022#include "llvm/Support/CFG.h"
Dan Gohmanf17a25c2007-07-18 16:29:46 +000023#include "llvm/Target/TargetData.h"
24
25using namespace llvm;
26
27char MemoryDependenceAnalysis::ID = 0;
28
Owen Anderson77eea8d2007-08-08 21:39:39 +000029const Instruction* MemoryDependenceAnalysis::NonLocal = (Instruction*)-3;
30const Instruction* MemoryDependenceAnalysis::None = (Instruction*)-4;
Dan Gohmanf17a25c2007-07-18 16:29:46 +000031
32// Register this pass...
33static RegisterPass<MemoryDependenceAnalysis> X("memdep",
34 "Memory Dependence Analysis");
35
36/// getAnalysisUsage - Does not modify anything. It uses Alias Analysis.
37///
38void MemoryDependenceAnalysis::getAnalysisUsage(AnalysisUsage &AU) const {
39 AU.setPreservesAll();
40 AU.addRequiredTransitive<AliasAnalysis>();
41 AU.addRequiredTransitive<TargetData>();
42}
43
44// Find the dependency of a CallSite
Owen Andersonafe840e2007-08-08 22:01:54 +000045const Instruction* MemoryDependenceAnalysis::getCallSiteDependency(CallSite C,
46 Instruction* start,
47 BasicBlock* block) {
Dan Gohmanf17a25c2007-07-18 16:29:46 +000048
49 AliasAnalysis& AA = getAnalysis<AliasAnalysis>();
50 TargetData& TD = getAnalysis<TargetData>();
51 BasicBlock::iterator blockBegin = C.getInstruction()->getParent()->begin();
52 BasicBlock::iterator QI = C.getInstruction();
53
Owen Andersone84f4bc2007-08-07 00:33:45 +000054 if (start) {
55 QI = start;
56 blockBegin = start->getParent()->end();
57 } else if (!start && block) {
58 QI = block->end();
59 blockBegin = block->end();
60 }
61
Dan Gohmanf17a25c2007-07-18 16:29:46 +000062 while (QI != blockBegin) {
63 --QI;
64
65 // If this inst is a memory op, get the pointer it accessed
66 Value* pointer = 0;
67 uint64_t pointerSize = 0;
68 if (StoreInst* S = dyn_cast<StoreInst>(QI)) {
69 pointer = S->getPointerOperand();
70 pointerSize = TD.getTypeSize(S->getOperand(0)->getType());
71 } else if (LoadInst* L = dyn_cast<LoadInst>(QI)) {
72 pointer = L->getPointerOperand();
73 pointerSize = TD.getTypeSize(L->getType());
74 } else if (AllocationInst* AI = dyn_cast<AllocationInst>(QI)) {
75 pointer = AI;
76 if (ConstantInt* C = dyn_cast<ConstantInt>(AI->getArraySize()))
Owen Andersonafe840e2007-08-08 22:01:54 +000077 pointerSize = C->getZExtValue() * \
78 TD.getTypeSize(AI->getAllocatedType());
Dan Gohmanf17a25c2007-07-18 16:29:46 +000079 else
80 pointerSize = ~0UL;
81 } else if (VAArgInst* V = dyn_cast<VAArgInst>(QI)) {
82 pointer = V->getOperand(0);
83 pointerSize = TD.getTypeSize(V->getType());
84 } else if (FreeInst* F = dyn_cast<FreeInst>(QI)) {
85 pointer = F->getPointerOperand();
86
87 // FreeInsts erase the entire structure
88 pointerSize = ~0UL;
89 } else if (CallSite::get(QI).getInstruction() != 0) {
90 if (AA.getModRefInfo(C, CallSite::get(QI)) != AliasAnalysis::NoModRef) {
Owen Andersone84f4bc2007-08-07 00:33:45 +000091 if (!start && !block) {
92 depGraphLocal.insert(std::make_pair(C.getInstruction(),
93 std::make_pair(QI, true)));
94 reverseDep[QI].insert(C.getInstruction());
95 }
Dan Gohmanf17a25c2007-07-18 16:29:46 +000096 return QI;
97 } else {
98 continue;
99 }
100 } else
101 continue;
102
103 if (AA.getModRefInfo(C, pointer, pointerSize) != AliasAnalysis::NoModRef) {
Owen Andersone84f4bc2007-08-07 00:33:45 +0000104 if (!start && !block) {
105 depGraphLocal.insert(std::make_pair(C.getInstruction(),
106 std::make_pair(QI, true)));
107 reverseDep[QI].insert(C.getInstruction());
108 }
Dan Gohmanf17a25c2007-07-18 16:29:46 +0000109 return QI;
110 }
111 }
112
113 // No dependence found
Owen Andersonafe840e2007-08-08 22:01:54 +0000114 depGraphLocal.insert(std::make_pair(C.getInstruction(),
115 std::make_pair(NonLocal, true)));
Owen Andersone84f4bc2007-08-07 00:33:45 +0000116 reverseDep[NonLocal].insert(C.getInstruction());
Dan Gohmanf17a25c2007-07-18 16:29:46 +0000117 return NonLocal;
118}
119
Owen Anderson3f75d122007-08-01 22:01:54 +0000120void MemoryDependenceAnalysis::nonLocalHelper(Instruction* query,
Owen Anderson5d72a422007-07-25 19:57:03 +0000121 BasicBlock* block,
Owen Andersonafe840e2007-08-08 22:01:54 +0000122 DenseMap<BasicBlock*, Value*>& resp) {
Owen Anderson3f75d122007-08-01 22:01:54 +0000123 SmallPtrSet<BasicBlock*, 4> visited;
124 SmallVector<BasicBlock*, 4> stack;
125 stack.push_back(block);
Owen Anderson4c295472007-07-24 21:52:37 +0000126
Owen Anderson3f75d122007-08-01 22:01:54 +0000127 while (!stack.empty()) {
128 BasicBlock* BB = stack.back();
129
Owen Andersonc6a31b92007-08-02 17:56:05 +0000130 if (visited.count(BB)) {
Owen Anderson3f75d122007-08-01 22:01:54 +0000131 stack.pop_back();
132 continue;
133 }
134
135 if (BB != block) {
Owen Andersonc6a31b92007-08-02 17:56:05 +0000136 visited.insert(BB);
137
Owen Anderson77eea8d2007-08-08 21:39:39 +0000138 const Instruction* localDep = getDependency(query, 0, BB);
Owen Anderson3f75d122007-08-01 22:01:54 +0000139 if (localDep != NonLocal) {
Owen Anderson77eea8d2007-08-08 21:39:39 +0000140 resp.insert(std::make_pair(BB, const_cast<Instruction*>(localDep)));
Owen Andersonc6a31b92007-08-02 17:56:05 +0000141 stack.pop_back();
142
Owen Anderson3f75d122007-08-01 22:01:54 +0000143 continue;
144 }
Owen Andersonc6a31b92007-08-02 17:56:05 +0000145 } else if (BB == block && stack.size() > 1) {
146 visited.insert(BB);
147
Owen Anderson77eea8d2007-08-08 21:39:39 +0000148 const Instruction* localDep = getDependency(query, 0, BB);
Owen Andersonc6a31b92007-08-02 17:56:05 +0000149 if (localDep != query)
Owen Anderson77eea8d2007-08-08 21:39:39 +0000150 resp.insert(std::make_pair(BB, const_cast<Instruction*>(localDep)));
Owen Andersonc6a31b92007-08-02 17:56:05 +0000151
152 stack.pop_back();
153
154 continue;
Owen Anderson3f75d122007-08-01 22:01:54 +0000155 }
156
157 bool predOnStack = false;
158 bool inserted = false;
159 for (pred_iterator PI = pred_begin(BB), PE = pred_end(BB);
160 PI != PE; ++PI)
161 if (!visited.count(*PI)) {
162 stack.push_back(*PI);
163 inserted = true;
164 } else
165 predOnStack = true;
166
167 if (inserted)
168 continue;
169 else if (!inserted && !predOnStack) {
Owen Anderson77eea8d2007-08-08 21:39:39 +0000170 resp.insert(std::make_pair(BB, const_cast<Instruction*>(None)));
Owen Anderson3f75d122007-08-01 22:01:54 +0000171 } else if (!inserted && predOnStack){
Owen Anderson77eea8d2007-08-08 21:39:39 +0000172 resp.insert(std::make_pair(BB, const_cast<Instruction*>(NonLocal)));
Owen Anderson3f75d122007-08-01 22:01:54 +0000173 }
174
175 stack.pop_back();
Owen Anderson4c295472007-07-24 21:52:37 +0000176 }
Owen Anderson4c295472007-07-24 21:52:37 +0000177}
178
Owen Andersonafe840e2007-08-08 22:01:54 +0000179/// getNonLocalDependency - Fills the passed-in map with the non-local
180/// dependencies of the queries. The map will contain NonLocal for
181/// blocks between the query and its dependencies.
Owen Anderson3f75d122007-08-01 22:01:54 +0000182void MemoryDependenceAnalysis::getNonLocalDependency(Instruction* query,
Owen Andersonafe840e2007-08-08 22:01:54 +0000183 DenseMap<BasicBlock*, Value*>& resp) {
Owen Anderson77eea8d2007-08-08 21:39:39 +0000184 const Instruction* localDep = getDependency(query);
Owen Anderson4c295472007-07-24 21:52:37 +0000185 if (localDep != NonLocal) {
Owen Andersonafe840e2007-08-08 22:01:54 +0000186 resp.insert(std::make_pair(query->getParent(),
187 const_cast<Instruction*>(localDep)));
Owen Anderson3f75d122007-08-01 22:01:54 +0000188 return;
Owen Anderson4c295472007-07-24 21:52:37 +0000189 }
190
Owen Anderson3f75d122007-08-01 22:01:54 +0000191 nonLocalHelper(query, query->getParent(), resp);
Owen Anderson4c295472007-07-24 21:52:37 +0000192}
193
Dan Gohmanf17a25c2007-07-18 16:29:46 +0000194/// getDependency - Return the instruction on which a memory operation
195/// depends. The local paramter indicates if the query should only
196/// evaluate dependencies within the same basic block.
Owen Anderson77eea8d2007-08-08 21:39:39 +0000197const Instruction* MemoryDependenceAnalysis::getDependency(Instruction* query,
Dan Gohmanf17a25c2007-07-18 16:29:46 +0000198 Instruction* start,
Owen Anderson4c295472007-07-24 21:52:37 +0000199 BasicBlock* block) {
Dan Gohmanf17a25c2007-07-18 16:29:46 +0000200 // Start looking for dependencies with the queried inst
201 BasicBlock::iterator QI = query;
202
203 // Check for a cached result
Owen Anderson77eea8d2007-08-08 21:39:39 +0000204 std::pair<const Instruction*, bool> cachedResult = depGraphLocal[query];
Dan Gohmanf17a25c2007-07-18 16:29:46 +0000205 // If we have a _confirmed_ cached entry, return it
206 if (cachedResult.second)
207 return cachedResult.first;
Owen Anderson5d72a422007-07-25 19:57:03 +0000208 else if (cachedResult.first && cachedResult.first != NonLocal)
Dan Gohmanf17a25c2007-07-18 16:29:46 +0000209 // If we have an unconfirmed cached entry, we can start our search from there
Owen Anderson77eea8d2007-08-08 21:39:39 +0000210 QI = const_cast<Instruction*>(cachedResult.first);
Dan Gohmanf17a25c2007-07-18 16:29:46 +0000211
212 if (start)
213 QI = start;
Owen Anderson5d72a422007-07-25 19:57:03 +0000214 else if (!start && block)
215 QI = block->end();
Dan Gohmanf17a25c2007-07-18 16:29:46 +0000216
217 AliasAnalysis& AA = getAnalysis<AliasAnalysis>();
218 TargetData& TD = getAnalysis<TargetData>();
219
220 // Get the pointer value for which dependence will be determined
221 Value* dependee = 0;
222 uint64_t dependeeSize = 0;
223 bool queryIsVolatile = false;
224 if (StoreInst* S = dyn_cast<StoreInst>(query)) {
225 dependee = S->getPointerOperand();
226 dependeeSize = TD.getTypeSize(S->getOperand(0)->getType());
227 queryIsVolatile = S->isVolatile();
228 } else if (LoadInst* L = dyn_cast<LoadInst>(query)) {
229 dependee = L->getPointerOperand();
230 dependeeSize = TD.getTypeSize(L->getType());
231 queryIsVolatile = L->isVolatile();
232 } else if (VAArgInst* V = dyn_cast<VAArgInst>(query)) {
233 dependee = V->getOperand(0);
234 dependeeSize = TD.getTypeSize(V->getType());
235 } else if (FreeInst* F = dyn_cast<FreeInst>(query)) {
236 dependee = F->getPointerOperand();
237
238 // FreeInsts erase the entire structure, not just a field
239 dependeeSize = ~0UL;
240 } else if (CallSite::get(query).getInstruction() != 0)
Owen Andersone84f4bc2007-08-07 00:33:45 +0000241 return getCallSiteDependency(CallSite::get(query), start, block);
Dan Gohmanf17a25c2007-07-18 16:29:46 +0000242 else if (isa<AllocationInst>(query))
243 return None;
244 else
245 return None;
246
Owen Anderson4c295472007-07-24 21:52:37 +0000247 BasicBlock::iterator blockBegin = block ? block->begin()
248 : query->getParent()->begin();
Dan Gohmanf17a25c2007-07-18 16:29:46 +0000249
250 while (QI != blockBegin) {
251 --QI;
252
253 // If this inst is a memory op, get the pointer it accessed
254 Value* pointer = 0;
255 uint64_t pointerSize = 0;
256 if (StoreInst* S = dyn_cast<StoreInst>(QI)) {
257 // All volatile loads/stores depend on each other
258 if (queryIsVolatile && S->isVolatile()) {
Owen Andersone84f4bc2007-08-07 00:33:45 +0000259 if (!start && !block) {
Dan Gohmanf17a25c2007-07-18 16:29:46 +0000260 depGraphLocal.insert(std::make_pair(query, std::make_pair(S, true)));
Owen Andersone84f4bc2007-08-07 00:33:45 +0000261 reverseDep[S].insert(query);
Dan Gohmanf17a25c2007-07-18 16:29:46 +0000262 }
263
264 return S;
265 }
266
267 pointer = S->getPointerOperand();
268 pointerSize = TD.getTypeSize(S->getOperand(0)->getType());
269 } else if (LoadInst* L = dyn_cast<LoadInst>(QI)) {
270 // All volatile loads/stores depend on each other
271 if (queryIsVolatile && L->isVolatile()) {
Owen Andersone84f4bc2007-08-07 00:33:45 +0000272 if (!start && !block) {
Dan Gohmanf17a25c2007-07-18 16:29:46 +0000273 depGraphLocal.insert(std::make_pair(query, std::make_pair(L, true)));
Owen Andersone84f4bc2007-08-07 00:33:45 +0000274 reverseDep[L].insert(query);
Dan Gohmanf17a25c2007-07-18 16:29:46 +0000275 }
276
277 return L;
278 }
279
280 pointer = L->getPointerOperand();
281 pointerSize = TD.getTypeSize(L->getType());
282 } else if (AllocationInst* AI = dyn_cast<AllocationInst>(QI)) {
283 pointer = AI;
284 if (ConstantInt* C = dyn_cast<ConstantInt>(AI->getArraySize()))
Owen Andersonafe840e2007-08-08 22:01:54 +0000285 pointerSize = C->getZExtValue() * \
286 TD.getTypeSize(AI->getAllocatedType());
Dan Gohmanf17a25c2007-07-18 16:29:46 +0000287 else
288 pointerSize = ~0UL;
289 } else if (VAArgInst* V = dyn_cast<VAArgInst>(QI)) {
290 pointer = V->getOperand(0);
291 pointerSize = TD.getTypeSize(V->getType());
292 } else if (FreeInst* F = dyn_cast<FreeInst>(QI)) {
293 pointer = F->getPointerOperand();
294
295 // FreeInsts erase the entire structure
296 pointerSize = ~0UL;
297 } else if (CallSite::get(QI).getInstruction() != 0) {
Owen Andersonafe840e2007-08-08 22:01:54 +0000298 // Call insts need special handling. Check if they can modify our pointer
Owen Anderson151f7692007-08-06 23:26:03 +0000299 AliasAnalysis::ModRefResult MR = AA.getModRefInfo(CallSite::get(QI),
300 dependee, dependeeSize);
301
302 if (MR != AliasAnalysis::NoModRef) {
303 // Loads don't depend on read-only calls
304 if (isa<LoadInst>(query) && MR == AliasAnalysis::Ref)
305 continue;
306
Owen Andersone84f4bc2007-08-07 00:33:45 +0000307 if (!start && !block) {
Owen Andersonafe840e2007-08-08 22:01:54 +0000308 depGraphLocal.insert(std::make_pair(query,
309 std::make_pair(QI, true)));
Owen Andersone84f4bc2007-08-07 00:33:45 +0000310 reverseDep[QI].insert(query);
Dan Gohmanf17a25c2007-07-18 16:29:46 +0000311 }
312
313 return QI;
314 } else {
315 continue;
316 }
317 }
318
319 // If we found a pointer, check if it could be the same as our pointer
320 if (pointer) {
321 AliasAnalysis::AliasResult R = AA.alias(pointer, pointerSize,
322 dependee, dependeeSize);
323
324 if (R != AliasAnalysis::NoAlias) {
Owen Anderson151f7692007-08-06 23:26:03 +0000325 // May-alias loads don't depend on each other
326 if (isa<LoadInst>(query) && isa<LoadInst>(QI) &&
327 R == AliasAnalysis::MayAlias)
328 continue;
329
Owen Andersone84f4bc2007-08-07 00:33:45 +0000330 if (!start && !block) {
Owen Andersonafe840e2007-08-08 22:01:54 +0000331 depGraphLocal.insert(std::make_pair(query,
332 std::make_pair(QI, true)));
Owen Andersone84f4bc2007-08-07 00:33:45 +0000333 reverseDep[QI].insert(query);
Dan Gohmanf17a25c2007-07-18 16:29:46 +0000334 }
335
336 return QI;
337 }
338 }
339 }
340
341 // If we found nothing, return the non-local flag
Owen Andersone84f4bc2007-08-07 00:33:45 +0000342 if (!start && !block) {
Dan Gohmanf17a25c2007-07-18 16:29:46 +0000343 depGraphLocal.insert(std::make_pair(query,
344 std::make_pair(NonLocal, true)));
Owen Andersone84f4bc2007-08-07 00:33:45 +0000345 reverseDep[NonLocal].insert(query);
Dan Gohmanf17a25c2007-07-18 16:29:46 +0000346 }
347
348 return NonLocal;
349}
350
351/// removeInstruction - Remove an instruction from the dependence analysis,
352/// updating the dependence of instructions that previously depended on it.
353void MemoryDependenceAnalysis::removeInstruction(Instruction* rem) {
354 // Figure out the new dep for things that currently depend on rem
Owen Anderson77eea8d2007-08-08 21:39:39 +0000355 const Instruction* newDep = NonLocal;
David Greene701171c2007-07-31 20:01:27 +0000356
357 depMapType::iterator depGraphEntry = depGraphLocal.find(rem);
358 // We assume here that it's not in the reverse map if it's not in
359 // the dep map. Checking it could be expensive, so don't do it.
360
361 if (depGraphEntry != depGraphLocal.end()) {
362 if (depGraphEntry->second.first != NonLocal &&
363 depGraphEntry->second.second) {
364 // If we have dep info for rem, set them to it
Owen Andersonafe840e2007-08-08 22:01:54 +0000365 BasicBlock::iterator RI =
366 const_cast<Instruction*>(depGraphEntry->second.first);
David Greene701171c2007-07-31 20:01:27 +0000367 RI++;
368 newDep = RI;
369 } else if (depGraphEntry->second.first == NonLocal &&
370 depGraphEntry->second.second ) {
371 // If we have a confirmed non-local flag, use it
372 newDep = NonLocal;
373 } else {
374 // Otherwise, use the immediate successor of rem
Owen Andersonafe840e2007-08-08 22:01:54 +0000375 // NOTE: This is because, when getDependence is called, it will first
376 // check the immediate predecessor of what is in the cache.
David Greene701171c2007-07-31 20:01:27 +0000377 BasicBlock::iterator RI = rem;
378 RI++;
379 newDep = RI;
380 }
381
Owen Andersone84f4bc2007-08-07 00:33:45 +0000382 SmallPtrSet<Instruction*, 4>& set = reverseDep[rem];
383 for (SmallPtrSet<Instruction*, 4>::iterator I = set.begin(), E = set.end();
384 I != E; ++I) {
David Greene701171c2007-07-31 20:01:27 +0000385 // Insert the new dependencies
386 // Mark it as unconfirmed as long as it is not the non-local flag
Owen Andersone84f4bc2007-08-07 00:33:45 +0000387 depGraphLocal[*I] = std::make_pair(newDep, !newDep);
David Greene701171c2007-07-31 20:01:27 +0000388 }
Owen Andersone84f4bc2007-08-07 00:33:45 +0000389 reverseDep.erase(rem);
Dan Gohmanf17a25c2007-07-18 16:29:46 +0000390 }
391
Dan Gohmanf17a25c2007-07-18 16:29:46 +0000392 getAnalysis<AliasAnalysis>().deleteValue(rem);
393}