blob: 283b6b7f5dff825d77f7ac2b4879cc125ef58631 [file] [log] [blame]
Owen Anderson78e02f72007-07-06 23:14:35 +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
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"
Owen Anderson7a616a12007-07-10 17:25:03 +000018#include "llvm/Constants.h"
Owen Anderson78e02f72007-07-06 23:14:35 +000019#include "llvm/Instructions.h"
20#include "llvm/Function.h"
21#include "llvm/Analysis/AliasAnalysis.h"
22#include "llvm/Target/TargetData.h"
23
24using namespace llvm;
25
26char MemoryDependenceAnalysis::ID = 0;
27
28Instruction* MemoryDependenceAnalysis::NonLocal = (Instruction*)0;
29Instruction* MemoryDependenceAnalysis::None = (Instruction*)~0;
30
31// Register this pass...
32RegisterPass<MemoryDependenceAnalysis> X("memdep",
33 "Memory Dependence Analysis");
34
35/// getAnalysisUsage - Does not modify anything. It uses Alias Analysis.
36///
37void MemoryDependenceAnalysis::getAnalysisUsage(AnalysisUsage &AU) const {
38 AU.setPreservesAll();
39 AU.addRequiredTransitive<AliasAnalysis>();
40 AU.addRequiredTransitive<TargetData>();
41}
42
Owen Anderson5f323202007-07-10 17:59:22 +000043// Find the dependency of a CallSite
44Instruction* 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
Owen Anderson78e02f72007-07-06 23:14:35 +000098/// getDependency - Return the instruction on which a memory operation
Owen Anderson6b278fc2007-07-10 17:08:11 +000099/// depends. The local paramter indicates if the query should only
100/// evaluate dependencies within the same basic block.
Owen Anderson78e02f72007-07-06 23:14:35 +0000101Instruction* 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>();
Owen Anderson6b278fc2007-07-10 17:08:11 +0000119 TargetData& TD = getAnalysis<TargetData>();
Owen Anderson78e02f72007-07-06 23:14:35 +0000120
121 // Get the pointer value for which dependence will be determined
122 Value* dependee = 0;
Owen Anderson6b278fc2007-07-10 17:08:11 +0000123 uint64_t dependeeSize = 0;
124 if (StoreInst* S = dyn_cast<StoreInst>(QI)) {
Owen Anderson78e02f72007-07-06 23:14:35 +0000125 dependee = S->getPointerOperand();
Owen Anderson7a616a12007-07-10 17:25:03 +0000126 dependeeSize = TD.getTypeSize(S->getOperand(0)->getType());
Owen Anderson6b278fc2007-07-10 17:08:11 +0000127 } else if (LoadInst* L = dyn_cast<LoadInst>(QI)) {
Owen Anderson78e02f72007-07-06 23:14:35 +0000128 dependee = L->getPointerOperand();
Owen Anderson7a616a12007-07-10 17:25:03 +0000129 dependeeSize = TD.getTypeSize(L->getType());
Owen Anderson6b278fc2007-07-10 17:08:11 +0000130 } else if (FreeInst* F = dyn_cast<FreeInst>(QI)) {
Owen Anderson78e02f72007-07-06 23:14:35 +0000131 dependee = F->getPointerOperand();
Owen Anderson6b278fc2007-07-10 17:08:11 +0000132
133 // FreeInsts erase the entire structure, not just a field
134 dependeeSize = ~0UL;
Owen Anderson5f323202007-07-10 17:59:22 +0000135 } else if (CallSite::get(QI).getInstruction() != 0)
136 return getCallSiteDependency(CallSite::get(QI));
137 else if (isa<AllocationInst>(query))
Owen Anderson78e02f72007-07-06 23:14:35 +0000138 return None;
Owen Anderson7a616a12007-07-10 17:25:03 +0000139 else
Owen Anderson6b278fc2007-07-10 17:08:11 +0000140 return None;
Owen Anderson78e02f72007-07-06 23:14:35 +0000141
Owen Anderson6b278fc2007-07-10 17:08:11 +0000142 BasicBlock::iterator blockBegin = query->getParent()->begin();
Owen Anderson78e02f72007-07-06 23:14:35 +0000143
144 while (QI != blockBegin) {
Owen Anderson6b278fc2007-07-10 17:08:11 +0000145 --QI;
146
Owen Anderson78e02f72007-07-06 23:14:35 +0000147 // If this inst is a memory op, get the pointer it accessed
148 Value* pointer = 0;
Owen Anderson6b278fc2007-07-10 17:08:11 +0000149 uint64_t pointerSize = 0;
150 if (StoreInst* S = dyn_cast<StoreInst>(QI)) {
Owen Anderson78e02f72007-07-06 23:14:35 +0000151 pointer = S->getPointerOperand();
Owen Anderson7a616a12007-07-10 17:25:03 +0000152 pointerSize = TD.getTypeSize(S->getOperand(0)->getType());
Owen Anderson6b278fc2007-07-10 17:08:11 +0000153 } else if (LoadInst* L = dyn_cast<LoadInst>(QI)) {
Owen Anderson78e02f72007-07-06 23:14:35 +0000154 pointer = L->getPointerOperand();
Owen Anderson7a616a12007-07-10 17:25:03 +0000155 pointerSize = TD.getTypeSize(L->getType());
Owen Anderson6b278fc2007-07-10 17:08:11 +0000156 } else if (AllocationInst* AI = dyn_cast<AllocationInst>(QI)) {
157 pointer = AI;
Owen Anderson7a616a12007-07-10 17:25:03 +0000158 if (ConstantInt* C = dyn_cast<ConstantInt>(AI->getArraySize()))
159 pointerSize = C->getZExtValue();
Owen Anderson6b278fc2007-07-10 17:08:11 +0000160 else
161 pointerSize = ~0UL;
162 } else if (FreeInst* F = dyn_cast<FreeInst>(QI)) {
Owen Anderson78e02f72007-07-06 23:14:35 +0000163 pointer = F->getPointerOperand();
Owen Anderson6b278fc2007-07-10 17:08:11 +0000164
165 // FreeInsts erase the entire structure
166 pointerSize = ~0UL;
Owen Anderson5f323202007-07-10 17:59:22 +0000167 } else if (CallSite::get(QI).getInstruction() != 0) {
Owen Anderson78e02f72007-07-06 23:14:35 +0000168 // Call insts need special handling. Check is they can modify our pointer
Owen Anderson5f323202007-07-10 17:59:22 +0000169 if (AA.getModRefInfo(CallSite::get(QI), dependee, dependeeSize) !=
170 AliasAnalysis::NoModRef) {
171 depGraphLocal.insert(std::make_pair(query, std::make_pair(QI, true)));
172 reverseDep.insert(std::make_pair(QI, query));
173 return QI;
Owen Anderson7a616a12007-07-10 17:25:03 +0000174 } else {
175 continue;
176 }
Owen Anderson78e02f72007-07-06 23:14:35 +0000177 }
178
179 // If we found a pointer, check if it could be the same as our pointer
180 if (pointer) {
Owen Anderson6b278fc2007-07-10 17:08:11 +0000181 AliasAnalysis::AliasResult R = AA.alias(pointer, pointerSize,
182 dependee, dependeeSize);
Owen Anderson78e02f72007-07-06 23:14:35 +0000183
184 if (R != AliasAnalysis::NoAlias) {
185 depGraphLocal.insert(std::make_pair(query, std::make_pair(QI, true)));
186 reverseDep.insert(std::make_pair(QI, query));
187 return QI;
188 }
189 }
Owen Anderson78e02f72007-07-06 23:14:35 +0000190 }
191
192 // If we found nothing, return the non-local flag
193 depGraphLocal.insert(std::make_pair(query,
194 std::make_pair(NonLocal, true)));
195 reverseDep.insert(std::make_pair(NonLocal, query));
196
197 return NonLocal;
198}
199
200/// removeInstruction - Remove an instruction from the dependence analysis,
201/// updating the dependence of instructions that previously depended on it.
202void MemoryDependenceAnalysis::removeInstruction(Instruction* rem) {
203 // Figure out the new dep for things that currently depend on rem
204 Instruction* newDep = NonLocal;
205 if (depGraphLocal[rem].first != NonLocal) {
206 // If we have dep info for rem, set them to it
207 BasicBlock::iterator RI = depGraphLocal[rem].first;
208 RI++;
209 newDep = RI;
210 } else if (depGraphLocal[rem].first == NonLocal &&
211 depGraphLocal[rem].second ) {
212 // If we have a confirmed non-local flag, use it
213 newDep = NonLocal;
214 } else {
215 // Otherwise, use the immediate successor of rem
216 // NOTE: This is because, when getDependence is called, it will first check
217 // the immediate predecessor of what is in the cache.
218 BasicBlock::iterator RI = rem;
219 RI++;
220 newDep = RI;
221 }
222
223 std::multimap<Instruction*, Instruction*>::iterator I = reverseDep.find(rem);
224 while (I->first == rem) {
225 // Insert the new dependencies
226 // Mark it as unconfirmed as long as it is not the non-local flag
227 depGraphLocal[I->second] = std::make_pair(newDep, !newDep);
228 reverseDep.erase(I);
229 I = reverseDep.find(rem);
230 }
231}