blob: dd567aac95dc35c854963a226940f30b96158b74 [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;
Owen Anderson4746c622007-11-26 03:27:38 +000097 } else if (CallSite::get(QI).getInstruction() != 0 &&
98 cast<CallInst>(QI)->getCalledFunction()) {
Owen Anderson8b6f04e2007-11-26 02:26:36 +000099 AliasAnalysis::ModRefBehavior result =
100 AA.getModRefBehavior(cast<CallInst>(QI)->getCalledFunction(),
101 CallSite::get(QI));
102 if (result != AliasAnalysis::DoesNotAccessMemory &&
103 result != AliasAnalysis::OnlyReadsMemory) {
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 } else {
111 continue;
112 }
113 } else
114 continue;
115
116 if (AA.getModRefInfo(C, pointer, pointerSize) != AliasAnalysis::NoModRef) {
Owen Andersone84f4bc2007-08-07 00:33:45 +0000117 if (!start && !block) {
118 depGraphLocal.insert(std::make_pair(C.getInstruction(),
119 std::make_pair(QI, true)));
120 reverseDep[QI].insert(C.getInstruction());
121 }
Dan Gohmanf17a25c2007-07-18 16:29:46 +0000122 return QI;
123 }
124 }
125
126 // No dependence found
Owen Andersonafe840e2007-08-08 22:01:54 +0000127 depGraphLocal.insert(std::make_pair(C.getInstruction(),
128 std::make_pair(NonLocal, true)));
Owen Andersone84f4bc2007-08-07 00:33:45 +0000129 reverseDep[NonLocal].insert(C.getInstruction());
Dan Gohmanf17a25c2007-07-18 16:29:46 +0000130 return NonLocal;
131}
132
Owen Anderson3de3c532007-08-08 22:26:03 +0000133/// nonLocalHelper - Private helper used to calculate non-local dependencies
134/// by doing DFS on the predecessors of a block to find its dependencies
Owen Anderson3f75d122007-08-01 22:01:54 +0000135void MemoryDependenceAnalysis::nonLocalHelper(Instruction* query,
Owen Anderson5d72a422007-07-25 19:57:03 +0000136 BasicBlock* block,
Owen Andersonafe840e2007-08-08 22:01:54 +0000137 DenseMap<BasicBlock*, Value*>& resp) {
Owen Anderson3de3c532007-08-08 22:26:03 +0000138 // Set of blocks that we've already visited in our DFS
Owen Anderson3f75d122007-08-01 22:01:54 +0000139 SmallPtrSet<BasicBlock*, 4> visited;
Owen Anderson05749072007-09-21 03:53:52 +0000140 // If we're updating a dirtied cache entry, we don't need to reprocess
141 // already computed entries.
142 for (DenseMap<BasicBlock*, Value*>::iterator I = resp.begin(),
143 E = resp.end(); I != E; ++I)
144 if (I->second != Dirty)
145 visited.insert(I->first);
146
Owen Anderson3de3c532007-08-08 22:26:03 +0000147 // Current stack of the DFS
Owen Anderson3f75d122007-08-01 22:01:54 +0000148 SmallVector<BasicBlock*, 4> stack;
149 stack.push_back(block);
Owen Anderson4c295472007-07-24 21:52:37 +0000150
Owen Anderson3de3c532007-08-08 22:26:03 +0000151 // Do a basic DFS
Owen Anderson3f75d122007-08-01 22:01:54 +0000152 while (!stack.empty()) {
153 BasicBlock* BB = stack.back();
154
Owen Anderson3de3c532007-08-08 22:26:03 +0000155 // If we've already visited this block, no need to revist
Owen Andersonc6a31b92007-08-02 17:56:05 +0000156 if (visited.count(BB)) {
Owen Anderson3f75d122007-08-01 22:01:54 +0000157 stack.pop_back();
158 continue;
159 }
160
Owen Anderson3de3c532007-08-08 22:26:03 +0000161 // If we find a new block with a local dependency for query,
162 // then we insert the new dependency and backtrack.
Owen Anderson3f75d122007-08-01 22:01:54 +0000163 if (BB != block) {
Owen Andersonc6a31b92007-08-02 17:56:05 +0000164 visited.insert(BB);
165
Owen Anderson935e39b2007-08-09 04:42:44 +0000166 Instruction* localDep = getDependency(query, 0, BB);
Owen Anderson3f75d122007-08-01 22:01:54 +0000167 if (localDep != NonLocal) {
Owen Anderson935e39b2007-08-09 04:42:44 +0000168 resp.insert(std::make_pair(BB, localDep));
Owen Andersonc6a31b92007-08-02 17:56:05 +0000169 stack.pop_back();
170
Owen Anderson3f75d122007-08-01 22:01:54 +0000171 continue;
172 }
Owen Anderson3de3c532007-08-08 22:26:03 +0000173 // If we re-encounter the starting block, we still need to search it
174 // because there might be a dependency in the starting block AFTER
175 // the position of the query. This is necessary to get loops right.
Owen Andersonc6a31b92007-08-02 17:56:05 +0000176 } else if (BB == block && stack.size() > 1) {
177 visited.insert(BB);
178
Owen Anderson935e39b2007-08-09 04:42:44 +0000179 Instruction* localDep = getDependency(query, 0, BB);
Owen Andersonc6a31b92007-08-02 17:56:05 +0000180 if (localDep != query)
Owen Anderson935e39b2007-08-09 04:42:44 +0000181 resp.insert(std::make_pair(BB, localDep));
Owen Andersonc6a31b92007-08-02 17:56:05 +0000182
183 stack.pop_back();
184
185 continue;
Owen Anderson3f75d122007-08-01 22:01:54 +0000186 }
187
Owen Anderson3de3c532007-08-08 22:26:03 +0000188 // If we didn't find anything, recurse on the precessors of this block
Owen Anderson3f75d122007-08-01 22:01:54 +0000189 bool predOnStack = false;
190 bool inserted = false;
191 for (pred_iterator PI = pred_begin(BB), PE = pred_end(BB);
192 PI != PE; ++PI)
193 if (!visited.count(*PI)) {
194 stack.push_back(*PI);
195 inserted = true;
196 } else
197 predOnStack = true;
198
Owen Anderson3de3c532007-08-08 22:26:03 +0000199 // If we inserted a new predecessor, then we'll come back to this block
Owen Anderson3f75d122007-08-01 22:01:54 +0000200 if (inserted)
201 continue;
Owen Anderson3de3c532007-08-08 22:26:03 +0000202 // If we didn't insert because we have no predecessors, then this
203 // query has no dependency at all.
Owen Anderson3f75d122007-08-01 22:01:54 +0000204 else if (!inserted && !predOnStack) {
Owen Anderson935e39b2007-08-09 04:42:44 +0000205 resp.insert(std::make_pair(BB, None));
Owen Anderson3de3c532007-08-08 22:26:03 +0000206 // If we didn't insert because our predecessors are already on the stack,
207 // then we might still have a dependency, but it will be discovered during
208 // backtracking.
Owen Anderson3f75d122007-08-01 22:01:54 +0000209 } else if (!inserted && predOnStack){
Owen Anderson935e39b2007-08-09 04:42:44 +0000210 resp.insert(std::make_pair(BB, NonLocal));
Owen Anderson3f75d122007-08-01 22:01:54 +0000211 }
212
213 stack.pop_back();
Owen Anderson4c295472007-07-24 21:52:37 +0000214 }
Owen Anderson4c295472007-07-24 21:52:37 +0000215}
216
Owen Andersonafe840e2007-08-08 22:01:54 +0000217/// getNonLocalDependency - Fills the passed-in map with the non-local
218/// dependencies of the queries. The map will contain NonLocal for
219/// blocks between the query and its dependencies.
Owen Anderson3f75d122007-08-01 22:01:54 +0000220void MemoryDependenceAnalysis::getNonLocalDependency(Instruction* query,
Owen Andersonafe840e2007-08-08 22:01:54 +0000221 DenseMap<BasicBlock*, Value*>& resp) {
Owen Anderson2bd46a52007-08-16 21:27:05 +0000222 if (depGraphNonLocal.count(query)) {
Owen Anderson05749072007-09-21 03:53:52 +0000223 DenseMap<BasicBlock*, Value*>& cached = depGraphNonLocal[query];
Owen Andersond6c7fea2007-09-09 21:43:49 +0000224 NumCacheNonlocal++;
Owen Anderson05749072007-09-21 03:53:52 +0000225
226 SmallVector<BasicBlock*, 4> dirtied;
227 for (DenseMap<BasicBlock*, Value*>::iterator I = cached.begin(),
228 E = cached.end(); I != E; ++I)
229 if (I->second == Dirty)
230 dirtied.push_back(I->first);
231
232 for (SmallVector<BasicBlock*, 4>::iterator I = dirtied.begin(),
233 E = dirtied.end(); I != E; ++I) {
234 Instruction* localDep = getDependency(query, 0, *I);
235 if (localDep != NonLocal)
236 cached[*I] = localDep;
237 else {
238 cached.erase(*I);
239 nonLocalHelper(query, *I, cached);
240 }
241 }
242
243 resp = cached;
244
Owen Anderson2bd46a52007-08-16 21:27:05 +0000245 return;
Owen Andersond6c7fea2007-09-09 21:43:49 +0000246 } else
247 NumUncacheNonlocal++;
Owen Anderson2bd46a52007-08-16 21:27:05 +0000248
Owen Andersond6c7fea2007-09-09 21:43:49 +0000249 // If not, go ahead and search for non-local deps.
Owen Anderson3f75d122007-08-01 22:01:54 +0000250 nonLocalHelper(query, query->getParent(), resp);
Owen Anderson2bd46a52007-08-16 21:27:05 +0000251
252 // Update the non-local dependency cache
253 for (DenseMap<BasicBlock*, Value*>::iterator I = resp.begin(), E = resp.end();
254 I != E; ++I) {
255 depGraphNonLocal[query].insert(*I);
256 reverseDepNonLocal[I->second].insert(query);
257 }
Owen Anderson4c295472007-07-24 21:52:37 +0000258}
259
Dan Gohmanf17a25c2007-07-18 16:29:46 +0000260/// getDependency - Return the instruction on which a memory operation
261/// depends. The local paramter indicates if the query should only
262/// evaluate dependencies within the same basic block.
Owen Anderson935e39b2007-08-09 04:42:44 +0000263Instruction* MemoryDependenceAnalysis::getDependency(Instruction* query,
Dan Gohmanf17a25c2007-07-18 16:29:46 +0000264 Instruction* start,
Owen Anderson4c295472007-07-24 21:52:37 +0000265 BasicBlock* block) {
Dan Gohmanf17a25c2007-07-18 16:29:46 +0000266 // Start looking for dependencies with the queried inst
267 BasicBlock::iterator QI = query;
268
269 // Check for a cached result
Owen Anderson935e39b2007-08-09 04:42:44 +0000270 std::pair<Instruction*, bool> cachedResult = depGraphLocal[query];
Dan Gohmanf17a25c2007-07-18 16:29:46 +0000271 // If we have a _confirmed_ cached entry, return it
272 if (cachedResult.second)
273 return cachedResult.first;
Owen Anderson5d72a422007-07-25 19:57:03 +0000274 else if (cachedResult.first && cachedResult.first != NonLocal)
Dan Gohmanf17a25c2007-07-18 16:29:46 +0000275 // If we have an unconfirmed cached entry, we can start our search from there
Owen Anderson935e39b2007-08-09 04:42:44 +0000276 QI = cachedResult.first;
Dan Gohmanf17a25c2007-07-18 16:29:46 +0000277
278 if (start)
279 QI = start;
Owen Anderson5d72a422007-07-25 19:57:03 +0000280 else if (!start && block)
281 QI = block->end();
Dan Gohmanf17a25c2007-07-18 16:29:46 +0000282
283 AliasAnalysis& AA = getAnalysis<AliasAnalysis>();
284 TargetData& TD = getAnalysis<TargetData>();
285
286 // Get the pointer value for which dependence will be determined
287 Value* dependee = 0;
288 uint64_t dependeeSize = 0;
289 bool queryIsVolatile = false;
290 if (StoreInst* S = dyn_cast<StoreInst>(query)) {
291 dependee = S->getPointerOperand();
Duncan Sandsf99fdc62007-11-01 20:53:16 +0000292 dependeeSize = TD.getTypeStoreSize(S->getOperand(0)->getType());
Dan Gohmanf17a25c2007-07-18 16:29:46 +0000293 queryIsVolatile = S->isVolatile();
294 } else if (LoadInst* L = dyn_cast<LoadInst>(query)) {
295 dependee = L->getPointerOperand();
Duncan Sandsf99fdc62007-11-01 20:53:16 +0000296 dependeeSize = TD.getTypeStoreSize(L->getType());
Dan Gohmanf17a25c2007-07-18 16:29:46 +0000297 queryIsVolatile = L->isVolatile();
298 } else if (VAArgInst* V = dyn_cast<VAArgInst>(query)) {
299 dependee = V->getOperand(0);
Duncan Sandsf99fdc62007-11-01 20:53:16 +0000300 dependeeSize = TD.getTypeStoreSize(V->getType());
Dan Gohmanf17a25c2007-07-18 16:29:46 +0000301 } else if (FreeInst* F = dyn_cast<FreeInst>(query)) {
302 dependee = F->getPointerOperand();
303
304 // FreeInsts erase the entire structure, not just a field
305 dependeeSize = ~0UL;
306 } else if (CallSite::get(query).getInstruction() != 0)
Owen Andersone84f4bc2007-08-07 00:33:45 +0000307 return getCallSiteDependency(CallSite::get(query), start, block);
Dan Gohmanf17a25c2007-07-18 16:29:46 +0000308 else if (isa<AllocationInst>(query))
309 return None;
310 else
311 return None;
312
Owen Anderson4c295472007-07-24 21:52:37 +0000313 BasicBlock::iterator blockBegin = block ? block->begin()
314 : query->getParent()->begin();
Dan Gohmanf17a25c2007-07-18 16:29:46 +0000315
Owen Anderson3de3c532007-08-08 22:26:03 +0000316 // Walk backwards through the basic block, looking for dependencies
Dan Gohmanf17a25c2007-07-18 16:29:46 +0000317 while (QI != blockBegin) {
318 --QI;
319
320 // If this inst is a memory op, get the pointer it accessed
321 Value* pointer = 0;
322 uint64_t pointerSize = 0;
323 if (StoreInst* S = dyn_cast<StoreInst>(QI)) {
324 // All volatile loads/stores depend on each other
325 if (queryIsVolatile && S->isVolatile()) {
Owen Andersone84f4bc2007-08-07 00:33:45 +0000326 if (!start && !block) {
Dan Gohmanf17a25c2007-07-18 16:29:46 +0000327 depGraphLocal.insert(std::make_pair(query, std::make_pair(S, true)));
Owen Andersone84f4bc2007-08-07 00:33:45 +0000328 reverseDep[S].insert(query);
Dan Gohmanf17a25c2007-07-18 16:29:46 +0000329 }
330
331 return S;
332 }
333
334 pointer = S->getPointerOperand();
Duncan Sandsf99fdc62007-11-01 20:53:16 +0000335 pointerSize = TD.getTypeStoreSize(S->getOperand(0)->getType());
Dan Gohmanf17a25c2007-07-18 16:29:46 +0000336 } else if (LoadInst* L = dyn_cast<LoadInst>(QI)) {
337 // All volatile loads/stores depend on each other
338 if (queryIsVolatile && L->isVolatile()) {
Owen Andersone84f4bc2007-08-07 00:33:45 +0000339 if (!start && !block) {
Dan Gohmanf17a25c2007-07-18 16:29:46 +0000340 depGraphLocal.insert(std::make_pair(query, std::make_pair(L, true)));
Owen Andersone84f4bc2007-08-07 00:33:45 +0000341 reverseDep[L].insert(query);
Dan Gohmanf17a25c2007-07-18 16:29:46 +0000342 }
343
344 return L;
345 }
346
347 pointer = L->getPointerOperand();
Duncan Sandsf99fdc62007-11-01 20:53:16 +0000348 pointerSize = TD.getTypeStoreSize(L->getType());
Dan Gohmanf17a25c2007-07-18 16:29:46 +0000349 } else if (AllocationInst* AI = dyn_cast<AllocationInst>(QI)) {
350 pointer = AI;
351 if (ConstantInt* C = dyn_cast<ConstantInt>(AI->getArraySize()))
Owen Andersonafe840e2007-08-08 22:01:54 +0000352 pointerSize = C->getZExtValue() * \
Duncan Sandsf99fdc62007-11-01 20:53:16 +0000353 TD.getABITypeSize(AI->getAllocatedType());
Dan Gohmanf17a25c2007-07-18 16:29:46 +0000354 else
355 pointerSize = ~0UL;
356 } else if (VAArgInst* V = dyn_cast<VAArgInst>(QI)) {
357 pointer = V->getOperand(0);
Duncan Sandsf99fdc62007-11-01 20:53:16 +0000358 pointerSize = TD.getTypeStoreSize(V->getType());
Dan Gohmanf17a25c2007-07-18 16:29:46 +0000359 } else if (FreeInst* F = dyn_cast<FreeInst>(QI)) {
360 pointer = F->getPointerOperand();
361
362 // FreeInsts erase the entire structure
363 pointerSize = ~0UL;
364 } else if (CallSite::get(QI).getInstruction() != 0) {
Owen Andersonafe840e2007-08-08 22:01:54 +0000365 // Call insts need special handling. Check if they can modify our pointer
Owen Anderson151f7692007-08-06 23:26:03 +0000366 AliasAnalysis::ModRefResult MR = AA.getModRefInfo(CallSite::get(QI),
367 dependee, dependeeSize);
368
369 if (MR != AliasAnalysis::NoModRef) {
370 // Loads don't depend on read-only calls
371 if (isa<LoadInst>(query) && MR == AliasAnalysis::Ref)
372 continue;
373
Owen Andersone84f4bc2007-08-07 00:33:45 +0000374 if (!start && !block) {
Owen Andersonafe840e2007-08-08 22:01:54 +0000375 depGraphLocal.insert(std::make_pair(query,
376 std::make_pair(QI, true)));
Owen Andersone84f4bc2007-08-07 00:33:45 +0000377 reverseDep[QI].insert(query);
Dan Gohmanf17a25c2007-07-18 16:29:46 +0000378 }
379
380 return QI;
381 } else {
382 continue;
383 }
384 }
385
386 // If we found a pointer, check if it could be the same as our pointer
387 if (pointer) {
388 AliasAnalysis::AliasResult R = AA.alias(pointer, pointerSize,
389 dependee, dependeeSize);
390
391 if (R != AliasAnalysis::NoAlias) {
Owen Anderson151f7692007-08-06 23:26:03 +0000392 // May-alias loads don't depend on each other
393 if (isa<LoadInst>(query) && isa<LoadInst>(QI) &&
394 R == AliasAnalysis::MayAlias)
395 continue;
396
Owen Andersone84f4bc2007-08-07 00:33:45 +0000397 if (!start && !block) {
Owen Andersonafe840e2007-08-08 22:01:54 +0000398 depGraphLocal.insert(std::make_pair(query,
399 std::make_pair(QI, true)));
Owen Andersone84f4bc2007-08-07 00:33:45 +0000400 reverseDep[QI].insert(query);
Dan Gohmanf17a25c2007-07-18 16:29:46 +0000401 }
402
403 return QI;
404 }
405 }
406 }
407
408 // If we found nothing, return the non-local flag
Owen Andersone84f4bc2007-08-07 00:33:45 +0000409 if (!start && !block) {
Dan Gohmanf17a25c2007-07-18 16:29:46 +0000410 depGraphLocal.insert(std::make_pair(query,
411 std::make_pair(NonLocal, true)));
Owen Andersone84f4bc2007-08-07 00:33:45 +0000412 reverseDep[NonLocal].insert(query);
Dan Gohmanf17a25c2007-07-18 16:29:46 +0000413 }
414
415 return NonLocal;
416}
417
418/// removeInstruction - Remove an instruction from the dependence analysis,
419/// updating the dependence of instructions that previously depended on it.
Owen Anderson3de3c532007-08-08 22:26:03 +0000420/// This method attempts to keep the cache coherent using the reverse map.
Dan Gohmanf17a25c2007-07-18 16:29:46 +0000421void MemoryDependenceAnalysis::removeInstruction(Instruction* rem) {
422 // Figure out the new dep for things that currently depend on rem
Owen Anderson935e39b2007-08-09 04:42:44 +0000423 Instruction* newDep = NonLocal;
David Greene701171c2007-07-31 20:01:27 +0000424
425 depMapType::iterator depGraphEntry = depGraphLocal.find(rem);
David Greene701171c2007-07-31 20:01:27 +0000426
427 if (depGraphEntry != depGraphLocal.end()) {
428 if (depGraphEntry->second.first != NonLocal &&
429 depGraphEntry->second.second) {
430 // If we have dep info for rem, set them to it
Owen Anderson935e39b2007-08-09 04:42:44 +0000431 BasicBlock::iterator RI = depGraphEntry->second.first;
David Greene701171c2007-07-31 20:01:27 +0000432 RI++;
433 newDep = RI;
434 } else if (depGraphEntry->second.first == NonLocal &&
435 depGraphEntry->second.second ) {
436 // If we have a confirmed non-local flag, use it
437 newDep = NonLocal;
438 } else {
439 // Otherwise, use the immediate successor of rem
Owen Andersonafe840e2007-08-08 22:01:54 +0000440 // NOTE: This is because, when getDependence is called, it will first
441 // check the immediate predecessor of what is in the cache.
David Greene701171c2007-07-31 20:01:27 +0000442 BasicBlock::iterator RI = rem;
443 RI++;
444 newDep = RI;
445 }
446
Owen Andersone84f4bc2007-08-07 00:33:45 +0000447 SmallPtrSet<Instruction*, 4>& set = reverseDep[rem];
448 for (SmallPtrSet<Instruction*, 4>::iterator I = set.begin(), E = set.end();
449 I != E; ++I) {
David Greene701171c2007-07-31 20:01:27 +0000450 // Insert the new dependencies
451 // Mark it as unconfirmed as long as it is not the non-local flag
Owen Andersone84f4bc2007-08-07 00:33:45 +0000452 depGraphLocal[*I] = std::make_pair(newDep, !newDep);
David Greene701171c2007-07-31 20:01:27 +0000453 }
Owen Anderson2bd46a52007-08-16 21:27:05 +0000454
Owen Andersone84f4bc2007-08-07 00:33:45 +0000455 reverseDep.erase(rem);
Dan Gohmanf17a25c2007-07-18 16:29:46 +0000456 }
Owen Anderson2bd46a52007-08-16 21:27:05 +0000457
Owen Anderson0ceeca52007-09-11 04:31:00 +0000458 if (reverseDepNonLocal.count(rem)) {
Owen Anderson2bd46a52007-08-16 21:27:05 +0000459 SmallPtrSet<Instruction*, 4>& set = reverseDepNonLocal[rem];
460 for (SmallPtrSet<Instruction*, 4>::iterator I = set.begin(), E = set.end();
461 I != E; ++I)
Owen Anderson05749072007-09-21 03:53:52 +0000462 for (DenseMap<BasicBlock*, Value*>::iterator DI =
463 depGraphNonLocal[*I].begin(), DE = depGraphNonLocal[*I].end();
464 DI != DE; ++DI)
465 if (DI->second == rem)
466 DI->second = Dirty;
Owen Anderson2bd46a52007-08-16 21:27:05 +0000467
468 reverseDepNonLocal.erase(rem);
469 }
Dan Gohmanf17a25c2007-07-18 16:29:46 +0000470
Dan Gohmanf17a25c2007-07-18 16:29:46 +0000471 getAnalysis<AliasAnalysis>().deleteValue(rem);
472}