blob: 68366f6d912dcaf17ef11c18f5482aa6bd224e3e [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"
Owen Andersond6c7fea2007-09-09 21:43:49 +000024#include "llvm/ADT/Statistic.h"
25
26#define DEBUG_TYPE "memdep"
Dan Gohmanf17a25c2007-07-18 16:29:46 +000027
28using namespace llvm;
29
Owen Andersond6c7fea2007-09-09 21:43:49 +000030STATISTIC(NumCacheNonlocal, "Number of cached non-local responses");
31STATISTIC(NumUncacheNonlocal, "Number of uncached non-local responses");
32
Dan Gohmanf17a25c2007-07-18 16:29:46 +000033char MemoryDependenceAnalysis::ID = 0;
34
Owen Anderson935e39b2007-08-09 04:42:44 +000035Instruction* const MemoryDependenceAnalysis::NonLocal = (Instruction*)-3;
36Instruction* const MemoryDependenceAnalysis::None = (Instruction*)-4;
Owen Anderson7e447562007-09-19 16:13:57 +000037Instruction* const MemoryDependenceAnalysis::Dirty = (Instruction*)-5;
Dan Gohmanf17a25c2007-07-18 16:29:46 +000038
39// Register this pass...
40static RegisterPass<MemoryDependenceAnalysis> X("memdep",
41 "Memory Dependence Analysis");
42
43/// getAnalysisUsage - Does not modify anything. It uses Alias Analysis.
44///
45void MemoryDependenceAnalysis::getAnalysisUsage(AnalysisUsage &AU) const {
46 AU.setPreservesAll();
47 AU.addRequiredTransitive<AliasAnalysis>();
48 AU.addRequiredTransitive<TargetData>();
49}
50
Owen Anderson3de3c532007-08-08 22:26:03 +000051/// getCallSiteDependency - Private helper for finding the local dependencies
52/// of a call site.
Owen Anderson935e39b2007-08-09 04:42:44 +000053Instruction* MemoryDependenceAnalysis::getCallSiteDependency(CallSite C,
Owen Andersonafe840e2007-08-08 22:01:54 +000054 Instruction* start,
55 BasicBlock* block) {
Dan Gohmanf17a25c2007-07-18 16:29:46 +000056
57 AliasAnalysis& AA = getAnalysis<AliasAnalysis>();
58 TargetData& TD = getAnalysis<TargetData>();
59 BasicBlock::iterator blockBegin = C.getInstruction()->getParent()->begin();
60 BasicBlock::iterator QI = C.getInstruction();
61
Owen Anderson3de3c532007-08-08 22:26:03 +000062 // If the starting point was specifiy, use it
Owen Andersone84f4bc2007-08-07 00:33:45 +000063 if (start) {
64 QI = start;
65 blockBegin = start->getParent()->end();
Owen Anderson3de3c532007-08-08 22:26:03 +000066 // If the starting point wasn't specified, but the block was, use it
Owen Andersone84f4bc2007-08-07 00:33:45 +000067 } else if (!start && block) {
68 QI = block->end();
69 blockBegin = block->end();
70 }
71
Owen Anderson3de3c532007-08-08 22:26:03 +000072 // Walk backwards through the block, looking for dependencies
Dan Gohmanf17a25c2007-07-18 16:29:46 +000073 while (QI != blockBegin) {
74 --QI;
75
76 // If this inst is a memory op, get the pointer it accessed
77 Value* pointer = 0;
78 uint64_t pointerSize = 0;
79 if (StoreInst* S = dyn_cast<StoreInst>(QI)) {
80 pointer = S->getPointerOperand();
Duncan Sandsf99fdc62007-11-01 20:53:16 +000081 pointerSize = TD.getTypeStoreSize(S->getOperand(0)->getType());
Dan Gohmanf17a25c2007-07-18 16:29:46 +000082 } else if (AllocationInst* AI = dyn_cast<AllocationInst>(QI)) {
83 pointer = AI;
84 if (ConstantInt* C = dyn_cast<ConstantInt>(AI->getArraySize()))
Owen Andersonafe840e2007-08-08 22:01:54 +000085 pointerSize = C->getZExtValue() * \
Duncan Sandsf99fdc62007-11-01 20:53:16 +000086 TD.getABITypeSize(AI->getAllocatedType());
Dan Gohmanf17a25c2007-07-18 16:29:46 +000087 else
88 pointerSize = ~0UL;
89 } else if (VAArgInst* V = dyn_cast<VAArgInst>(QI)) {
90 pointer = V->getOperand(0);
Duncan Sandsf99fdc62007-11-01 20:53:16 +000091 pointerSize = TD.getTypeStoreSize(V->getType());
Dan Gohmanf17a25c2007-07-18 16:29:46 +000092 } else if (FreeInst* F = dyn_cast<FreeInst>(QI)) {
93 pointer = F->getPointerOperand();
94
95 // FreeInsts erase the entire structure
96 pointerSize = ~0UL;
97 } else if (CallSite::get(QI).getInstruction() != 0) {
Owen Anderson8b6f04e2007-11-26 02:26:36 +000098 AliasAnalysis::ModRefBehavior result =
99 AA.getModRefBehavior(cast<CallInst>(QI)->getCalledFunction(),
100 CallSite::get(QI));
101 if (result != AliasAnalysis::DoesNotAccessMemory &&
102 result != AliasAnalysis::OnlyReadsMemory) {
Owen Andersone84f4bc2007-08-07 00:33:45 +0000103 if (!start && !block) {
104 depGraphLocal.insert(std::make_pair(C.getInstruction(),
105 std::make_pair(QI, true)));
106 reverseDep[QI].insert(C.getInstruction());
107 }
Dan Gohmanf17a25c2007-07-18 16:29:46 +0000108 return QI;
109 } else {
110 continue;
111 }
112 } else
113 continue;
114
115 if (AA.getModRefInfo(C, pointer, pointerSize) != AliasAnalysis::NoModRef) {
Owen Andersone84f4bc2007-08-07 00:33:45 +0000116 if (!start && !block) {
117 depGraphLocal.insert(std::make_pair(C.getInstruction(),
118 std::make_pair(QI, true)));
119 reverseDep[QI].insert(C.getInstruction());
120 }
Dan Gohmanf17a25c2007-07-18 16:29:46 +0000121 return QI;
122 }
123 }
124
125 // No dependence found
Owen Andersonafe840e2007-08-08 22:01:54 +0000126 depGraphLocal.insert(std::make_pair(C.getInstruction(),
127 std::make_pair(NonLocal, true)));
Owen Andersone84f4bc2007-08-07 00:33:45 +0000128 reverseDep[NonLocal].insert(C.getInstruction());
Dan Gohmanf17a25c2007-07-18 16:29:46 +0000129 return NonLocal;
130}
131
Owen Anderson3de3c532007-08-08 22:26:03 +0000132/// nonLocalHelper - Private helper used to calculate non-local dependencies
133/// by doing DFS on the predecessors of a block to find its dependencies
Owen Anderson3f75d122007-08-01 22:01:54 +0000134void MemoryDependenceAnalysis::nonLocalHelper(Instruction* query,
Owen Anderson5d72a422007-07-25 19:57:03 +0000135 BasicBlock* block,
Owen Andersonafe840e2007-08-08 22:01:54 +0000136 DenseMap<BasicBlock*, Value*>& resp) {
Owen Anderson3de3c532007-08-08 22:26:03 +0000137 // Set of blocks that we've already visited in our DFS
Owen Anderson3f75d122007-08-01 22:01:54 +0000138 SmallPtrSet<BasicBlock*, 4> visited;
Owen Anderson05749072007-09-21 03:53:52 +0000139 // If we're updating a dirtied cache entry, we don't need to reprocess
140 // already computed entries.
141 for (DenseMap<BasicBlock*, Value*>::iterator I = resp.begin(),
142 E = resp.end(); I != E; ++I)
143 if (I->second != Dirty)
144 visited.insert(I->first);
145
Owen Anderson3de3c532007-08-08 22:26:03 +0000146 // Current stack of the DFS
Owen Anderson3f75d122007-08-01 22:01:54 +0000147 SmallVector<BasicBlock*, 4> stack;
148 stack.push_back(block);
Owen Anderson4c295472007-07-24 21:52:37 +0000149
Owen Anderson3de3c532007-08-08 22:26:03 +0000150 // Do a basic DFS
Owen Anderson3f75d122007-08-01 22:01:54 +0000151 while (!stack.empty()) {
152 BasicBlock* BB = stack.back();
153
Owen Anderson3de3c532007-08-08 22:26:03 +0000154 // If we've already visited this block, no need to revist
Owen Andersonc6a31b92007-08-02 17:56:05 +0000155 if (visited.count(BB)) {
Owen Anderson3f75d122007-08-01 22:01:54 +0000156 stack.pop_back();
157 continue;
158 }
159
Owen Anderson3de3c532007-08-08 22:26:03 +0000160 // If we find a new block with a local dependency for query,
161 // then we insert the new dependency and backtrack.
Owen Anderson3f75d122007-08-01 22:01:54 +0000162 if (BB != block) {
Owen Andersonc6a31b92007-08-02 17:56:05 +0000163 visited.insert(BB);
164
Owen Anderson935e39b2007-08-09 04:42:44 +0000165 Instruction* localDep = getDependency(query, 0, BB);
Owen Anderson3f75d122007-08-01 22:01:54 +0000166 if (localDep != NonLocal) {
Owen Anderson935e39b2007-08-09 04:42:44 +0000167 resp.insert(std::make_pair(BB, localDep));
Owen Andersonc6a31b92007-08-02 17:56:05 +0000168 stack.pop_back();
169
Owen Anderson3f75d122007-08-01 22:01:54 +0000170 continue;
171 }
Owen Anderson3de3c532007-08-08 22:26:03 +0000172 // If we re-encounter the starting block, we still need to search it
173 // because there might be a dependency in the starting block AFTER
174 // the position of the query. This is necessary to get loops right.
Owen Andersonc6a31b92007-08-02 17:56:05 +0000175 } else if (BB == block && stack.size() > 1) {
176 visited.insert(BB);
177
Owen Anderson935e39b2007-08-09 04:42:44 +0000178 Instruction* localDep = getDependency(query, 0, BB);
Owen Andersonc6a31b92007-08-02 17:56:05 +0000179 if (localDep != query)
Owen Anderson935e39b2007-08-09 04:42:44 +0000180 resp.insert(std::make_pair(BB, localDep));
Owen Andersonc6a31b92007-08-02 17:56:05 +0000181
182 stack.pop_back();
183
184 continue;
Owen Anderson3f75d122007-08-01 22:01:54 +0000185 }
186
Owen Anderson3de3c532007-08-08 22:26:03 +0000187 // If we didn't find anything, recurse on the precessors of this block
Owen Anderson3f75d122007-08-01 22:01:54 +0000188 bool predOnStack = false;
189 bool inserted = false;
190 for (pred_iterator PI = pred_begin(BB), PE = pred_end(BB);
191 PI != PE; ++PI)
192 if (!visited.count(*PI)) {
193 stack.push_back(*PI);
194 inserted = true;
195 } else
196 predOnStack = true;
197
Owen Anderson3de3c532007-08-08 22:26:03 +0000198 // If we inserted a new predecessor, then we'll come back to this block
Owen Anderson3f75d122007-08-01 22:01:54 +0000199 if (inserted)
200 continue;
Owen Anderson3de3c532007-08-08 22:26:03 +0000201 // If we didn't insert because we have no predecessors, then this
202 // query has no dependency at all.
Owen Anderson3f75d122007-08-01 22:01:54 +0000203 else if (!inserted && !predOnStack) {
Owen Anderson935e39b2007-08-09 04:42:44 +0000204 resp.insert(std::make_pair(BB, None));
Owen Anderson3de3c532007-08-08 22:26:03 +0000205 // If we didn't insert because our predecessors are already on the stack,
206 // then we might still have a dependency, but it will be discovered during
207 // backtracking.
Owen Anderson3f75d122007-08-01 22:01:54 +0000208 } else if (!inserted && predOnStack){
Owen Anderson935e39b2007-08-09 04:42:44 +0000209 resp.insert(std::make_pair(BB, NonLocal));
Owen Anderson3f75d122007-08-01 22:01:54 +0000210 }
211
212 stack.pop_back();
Owen Anderson4c295472007-07-24 21:52:37 +0000213 }
Owen Anderson4c295472007-07-24 21:52:37 +0000214}
215
Owen Andersonafe840e2007-08-08 22:01:54 +0000216/// getNonLocalDependency - Fills the passed-in map with the non-local
217/// dependencies of the queries. The map will contain NonLocal for
218/// blocks between the query and its dependencies.
Owen Anderson3f75d122007-08-01 22:01:54 +0000219void MemoryDependenceAnalysis::getNonLocalDependency(Instruction* query,
Owen Andersonafe840e2007-08-08 22:01:54 +0000220 DenseMap<BasicBlock*, Value*>& resp) {
Owen Anderson2bd46a52007-08-16 21:27:05 +0000221 if (depGraphNonLocal.count(query)) {
Owen Anderson05749072007-09-21 03:53:52 +0000222 DenseMap<BasicBlock*, Value*>& cached = depGraphNonLocal[query];
Owen Andersond6c7fea2007-09-09 21:43:49 +0000223 NumCacheNonlocal++;
Owen Anderson05749072007-09-21 03:53:52 +0000224
225 SmallVector<BasicBlock*, 4> dirtied;
226 for (DenseMap<BasicBlock*, Value*>::iterator I = cached.begin(),
227 E = cached.end(); I != E; ++I)
228 if (I->second == Dirty)
229 dirtied.push_back(I->first);
230
231 for (SmallVector<BasicBlock*, 4>::iterator I = dirtied.begin(),
232 E = dirtied.end(); I != E; ++I) {
233 Instruction* localDep = getDependency(query, 0, *I);
234 if (localDep != NonLocal)
235 cached[*I] = localDep;
236 else {
237 cached.erase(*I);
238 nonLocalHelper(query, *I, cached);
239 }
240 }
241
242 resp = cached;
243
Owen Anderson2bd46a52007-08-16 21:27:05 +0000244 return;
Owen Andersond6c7fea2007-09-09 21:43:49 +0000245 } else
246 NumUncacheNonlocal++;
Owen Anderson2bd46a52007-08-16 21:27:05 +0000247
Owen Andersond6c7fea2007-09-09 21:43:49 +0000248 // If not, go ahead and search for non-local deps.
Owen Anderson3f75d122007-08-01 22:01:54 +0000249 nonLocalHelper(query, query->getParent(), resp);
Owen Anderson2bd46a52007-08-16 21:27:05 +0000250
251 // Update the non-local dependency cache
252 for (DenseMap<BasicBlock*, Value*>::iterator I = resp.begin(), E = resp.end();
253 I != E; ++I) {
254 depGraphNonLocal[query].insert(*I);
255 reverseDepNonLocal[I->second].insert(query);
256 }
Owen Anderson4c295472007-07-24 21:52:37 +0000257}
258
Dan Gohmanf17a25c2007-07-18 16:29:46 +0000259/// getDependency - Return the instruction on which a memory operation
260/// depends. The local paramter indicates if the query should only
261/// evaluate dependencies within the same basic block.
Owen Anderson935e39b2007-08-09 04:42:44 +0000262Instruction* MemoryDependenceAnalysis::getDependency(Instruction* query,
Dan Gohmanf17a25c2007-07-18 16:29:46 +0000263 Instruction* start,
Owen Anderson4c295472007-07-24 21:52:37 +0000264 BasicBlock* block) {
Dan Gohmanf17a25c2007-07-18 16:29:46 +0000265 // Start looking for dependencies with the queried inst
266 BasicBlock::iterator QI = query;
267
268 // Check for a cached result
Owen Anderson935e39b2007-08-09 04:42:44 +0000269 std::pair<Instruction*, bool> cachedResult = depGraphLocal[query];
Dan Gohmanf17a25c2007-07-18 16:29:46 +0000270 // If we have a _confirmed_ cached entry, return it
271 if (cachedResult.second)
272 return cachedResult.first;
Owen Anderson5d72a422007-07-25 19:57:03 +0000273 else if (cachedResult.first && cachedResult.first != NonLocal)
Dan Gohmanf17a25c2007-07-18 16:29:46 +0000274 // If we have an unconfirmed cached entry, we can start our search from there
Owen Anderson935e39b2007-08-09 04:42:44 +0000275 QI = cachedResult.first;
Dan Gohmanf17a25c2007-07-18 16:29:46 +0000276
277 if (start)
278 QI = start;
Owen Anderson5d72a422007-07-25 19:57:03 +0000279 else if (!start && block)
280 QI = block->end();
Dan Gohmanf17a25c2007-07-18 16:29:46 +0000281
282 AliasAnalysis& AA = getAnalysis<AliasAnalysis>();
283 TargetData& TD = getAnalysis<TargetData>();
284
285 // Get the pointer value for which dependence will be determined
286 Value* dependee = 0;
287 uint64_t dependeeSize = 0;
288 bool queryIsVolatile = false;
289 if (StoreInst* S = dyn_cast<StoreInst>(query)) {
290 dependee = S->getPointerOperand();
Duncan Sandsf99fdc62007-11-01 20:53:16 +0000291 dependeeSize = TD.getTypeStoreSize(S->getOperand(0)->getType());
Dan Gohmanf17a25c2007-07-18 16:29:46 +0000292 queryIsVolatile = S->isVolatile();
293 } else if (LoadInst* L = dyn_cast<LoadInst>(query)) {
294 dependee = L->getPointerOperand();
Duncan Sandsf99fdc62007-11-01 20:53:16 +0000295 dependeeSize = TD.getTypeStoreSize(L->getType());
Dan Gohmanf17a25c2007-07-18 16:29:46 +0000296 queryIsVolatile = L->isVolatile();
297 } else if (VAArgInst* V = dyn_cast<VAArgInst>(query)) {
298 dependee = V->getOperand(0);
Duncan Sandsf99fdc62007-11-01 20:53:16 +0000299 dependeeSize = TD.getTypeStoreSize(V->getType());
Dan Gohmanf17a25c2007-07-18 16:29:46 +0000300 } else if (FreeInst* F = dyn_cast<FreeInst>(query)) {
301 dependee = F->getPointerOperand();
302
303 // FreeInsts erase the entire structure, not just a field
304 dependeeSize = ~0UL;
305 } else if (CallSite::get(query).getInstruction() != 0)
Owen Andersone84f4bc2007-08-07 00:33:45 +0000306 return getCallSiteDependency(CallSite::get(query), start, block);
Dan Gohmanf17a25c2007-07-18 16:29:46 +0000307 else if (isa<AllocationInst>(query))
308 return None;
309 else
310 return None;
311
Owen Anderson4c295472007-07-24 21:52:37 +0000312 BasicBlock::iterator blockBegin = block ? block->begin()
313 : query->getParent()->begin();
Dan Gohmanf17a25c2007-07-18 16:29:46 +0000314
Owen Anderson3de3c532007-08-08 22:26:03 +0000315 // Walk backwards through the basic block, looking for dependencies
Dan Gohmanf17a25c2007-07-18 16:29:46 +0000316 while (QI != blockBegin) {
317 --QI;
318
319 // If this inst is a memory op, get the pointer it accessed
320 Value* pointer = 0;
321 uint64_t pointerSize = 0;
322 if (StoreInst* S = dyn_cast<StoreInst>(QI)) {
323 // All volatile loads/stores depend on each other
324 if (queryIsVolatile && S->isVolatile()) {
Owen Andersone84f4bc2007-08-07 00:33:45 +0000325 if (!start && !block) {
Dan Gohmanf17a25c2007-07-18 16:29:46 +0000326 depGraphLocal.insert(std::make_pair(query, std::make_pair(S, true)));
Owen Andersone84f4bc2007-08-07 00:33:45 +0000327 reverseDep[S].insert(query);
Dan Gohmanf17a25c2007-07-18 16:29:46 +0000328 }
329
330 return S;
331 }
332
333 pointer = S->getPointerOperand();
Duncan Sandsf99fdc62007-11-01 20:53:16 +0000334 pointerSize = TD.getTypeStoreSize(S->getOperand(0)->getType());
Dan Gohmanf17a25c2007-07-18 16:29:46 +0000335 } else if (LoadInst* L = dyn_cast<LoadInst>(QI)) {
336 // All volatile loads/stores depend on each other
337 if (queryIsVolatile && L->isVolatile()) {
Owen Andersone84f4bc2007-08-07 00:33:45 +0000338 if (!start && !block) {
Dan Gohmanf17a25c2007-07-18 16:29:46 +0000339 depGraphLocal.insert(std::make_pair(query, std::make_pair(L, true)));
Owen Andersone84f4bc2007-08-07 00:33:45 +0000340 reverseDep[L].insert(query);
Dan Gohmanf17a25c2007-07-18 16:29:46 +0000341 }
342
343 return L;
344 }
345
346 pointer = L->getPointerOperand();
Duncan Sandsf99fdc62007-11-01 20:53:16 +0000347 pointerSize = TD.getTypeStoreSize(L->getType());
Dan Gohmanf17a25c2007-07-18 16:29:46 +0000348 } else if (AllocationInst* AI = dyn_cast<AllocationInst>(QI)) {
349 pointer = AI;
350 if (ConstantInt* C = dyn_cast<ConstantInt>(AI->getArraySize()))
Owen Andersonafe840e2007-08-08 22:01:54 +0000351 pointerSize = C->getZExtValue() * \
Duncan Sandsf99fdc62007-11-01 20:53:16 +0000352 TD.getABITypeSize(AI->getAllocatedType());
Dan Gohmanf17a25c2007-07-18 16:29:46 +0000353 else
354 pointerSize = ~0UL;
355 } else if (VAArgInst* V = dyn_cast<VAArgInst>(QI)) {
356 pointer = V->getOperand(0);
Duncan Sandsf99fdc62007-11-01 20:53:16 +0000357 pointerSize = TD.getTypeStoreSize(V->getType());
Dan Gohmanf17a25c2007-07-18 16:29:46 +0000358 } else if (FreeInst* F = dyn_cast<FreeInst>(QI)) {
359 pointer = F->getPointerOperand();
360
361 // FreeInsts erase the entire structure
362 pointerSize = ~0UL;
363 } else if (CallSite::get(QI).getInstruction() != 0) {
Owen Andersonafe840e2007-08-08 22:01:54 +0000364 // Call insts need special handling. Check if they can modify our pointer
Owen Anderson151f7692007-08-06 23:26:03 +0000365 AliasAnalysis::ModRefResult MR = AA.getModRefInfo(CallSite::get(QI),
366 dependee, dependeeSize);
367
368 if (MR != AliasAnalysis::NoModRef) {
369 // Loads don't depend on read-only calls
370 if (isa<LoadInst>(query) && MR == AliasAnalysis::Ref)
371 continue;
372
Owen Andersone84f4bc2007-08-07 00:33:45 +0000373 if (!start && !block) {
Owen Andersonafe840e2007-08-08 22:01:54 +0000374 depGraphLocal.insert(std::make_pair(query,
375 std::make_pair(QI, true)));
Owen Andersone84f4bc2007-08-07 00:33:45 +0000376 reverseDep[QI].insert(query);
Dan Gohmanf17a25c2007-07-18 16:29:46 +0000377 }
378
379 return QI;
380 } else {
381 continue;
382 }
383 }
384
385 // If we found a pointer, check if it could be the same as our pointer
386 if (pointer) {
387 AliasAnalysis::AliasResult R = AA.alias(pointer, pointerSize,
388 dependee, dependeeSize);
389
390 if (R != AliasAnalysis::NoAlias) {
Owen Anderson151f7692007-08-06 23:26:03 +0000391 // May-alias loads don't depend on each other
392 if (isa<LoadInst>(query) && isa<LoadInst>(QI) &&
393 R == AliasAnalysis::MayAlias)
394 continue;
395
Owen Andersone84f4bc2007-08-07 00:33:45 +0000396 if (!start && !block) {
Owen Andersonafe840e2007-08-08 22:01:54 +0000397 depGraphLocal.insert(std::make_pair(query,
398 std::make_pair(QI, true)));
Owen Andersone84f4bc2007-08-07 00:33:45 +0000399 reverseDep[QI].insert(query);
Dan Gohmanf17a25c2007-07-18 16:29:46 +0000400 }
401
402 return QI;
403 }
404 }
405 }
406
407 // If we found nothing, return the non-local flag
Owen Andersone84f4bc2007-08-07 00:33:45 +0000408 if (!start && !block) {
Dan Gohmanf17a25c2007-07-18 16:29:46 +0000409 depGraphLocal.insert(std::make_pair(query,
410 std::make_pair(NonLocal, true)));
Owen Andersone84f4bc2007-08-07 00:33:45 +0000411 reverseDep[NonLocal].insert(query);
Dan Gohmanf17a25c2007-07-18 16:29:46 +0000412 }
413
414 return NonLocal;
415}
416
417/// removeInstruction - Remove an instruction from the dependence analysis,
418/// updating the dependence of instructions that previously depended on it.
Owen Anderson3de3c532007-08-08 22:26:03 +0000419/// This method attempts to keep the cache coherent using the reverse map.
Dan Gohmanf17a25c2007-07-18 16:29:46 +0000420void MemoryDependenceAnalysis::removeInstruction(Instruction* rem) {
421 // Figure out the new dep for things that currently depend on rem
Owen Anderson935e39b2007-08-09 04:42:44 +0000422 Instruction* newDep = NonLocal;
David Greene701171c2007-07-31 20:01:27 +0000423
424 depMapType::iterator depGraphEntry = depGraphLocal.find(rem);
David Greene701171c2007-07-31 20:01:27 +0000425
426 if (depGraphEntry != depGraphLocal.end()) {
427 if (depGraphEntry->second.first != NonLocal &&
428 depGraphEntry->second.second) {
429 // If we have dep info for rem, set them to it
Owen Anderson935e39b2007-08-09 04:42:44 +0000430 BasicBlock::iterator RI = depGraphEntry->second.first;
David Greene701171c2007-07-31 20:01:27 +0000431 RI++;
432 newDep = RI;
433 } else if (depGraphEntry->second.first == NonLocal &&
434 depGraphEntry->second.second ) {
435 // If we have a confirmed non-local flag, use it
436 newDep = NonLocal;
437 } else {
438 // Otherwise, use the immediate successor of rem
Owen Andersonafe840e2007-08-08 22:01:54 +0000439 // NOTE: This is because, when getDependence is called, it will first
440 // check the immediate predecessor of what is in the cache.
David Greene701171c2007-07-31 20:01:27 +0000441 BasicBlock::iterator RI = rem;
442 RI++;
443 newDep = RI;
444 }
445
Owen Andersone84f4bc2007-08-07 00:33:45 +0000446 SmallPtrSet<Instruction*, 4>& set = reverseDep[rem];
447 for (SmallPtrSet<Instruction*, 4>::iterator I = set.begin(), E = set.end();
448 I != E; ++I) {
David Greene701171c2007-07-31 20:01:27 +0000449 // Insert the new dependencies
450 // Mark it as unconfirmed as long as it is not the non-local flag
Owen Andersone84f4bc2007-08-07 00:33:45 +0000451 depGraphLocal[*I] = std::make_pair(newDep, !newDep);
David Greene701171c2007-07-31 20:01:27 +0000452 }
Owen Anderson2bd46a52007-08-16 21:27:05 +0000453
Owen Andersone84f4bc2007-08-07 00:33:45 +0000454 reverseDep.erase(rem);
Dan Gohmanf17a25c2007-07-18 16:29:46 +0000455 }
Owen Anderson2bd46a52007-08-16 21:27:05 +0000456
Owen Anderson0ceeca52007-09-11 04:31:00 +0000457 if (reverseDepNonLocal.count(rem)) {
Owen Anderson2bd46a52007-08-16 21:27:05 +0000458 SmallPtrSet<Instruction*, 4>& set = reverseDepNonLocal[rem];
459 for (SmallPtrSet<Instruction*, 4>::iterator I = set.begin(), E = set.end();
460 I != E; ++I)
Owen Anderson05749072007-09-21 03:53:52 +0000461 for (DenseMap<BasicBlock*, Value*>::iterator DI =
462 depGraphNonLocal[*I].begin(), DE = depGraphNonLocal[*I].end();
463 DI != DE; ++DI)
464 if (DI->second == rem)
465 DI->second = Dirty;
Owen Anderson2bd46a52007-08-16 21:27:05 +0000466
467 reverseDepNonLocal.erase(rem);
468 }
Dan Gohmanf17a25c2007-07-18 16:29:46 +0000469
Dan Gohmanf17a25c2007-07-18 16:29:46 +0000470 getAnalysis<AliasAnalysis>().deleteValue(rem);
471}