MemoryDependenceAnalysis.cpp revision 1cb960a4bb97336be1339fd5bc2eb28f125f099a
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
24using namespace llvm;
25
26char MemoryDependenceAnalysis::ID = 0;
27
28Instruction* MemoryDependenceAnalysis::NonLocal = (Instruction*)0;
29Instruction* MemoryDependenceAnalysis::None = (Instruction*)~0;
30
31// Register this pass...
32static RegisterPass<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
43// 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() * TD.getTypeSize(AI->getAllocatedType());
68      else
69        pointerSize = ~0UL;
70    } else if (VAArgInst* V = dyn_cast<VAArgInst>(QI)) {
71      pointer = V->getOperand(0);
72      pointerSize = TD.getTypeSize(V->getType());
73    } else if (FreeInst* F = dyn_cast<FreeInst>(QI)) {
74      pointer = F->getPointerOperand();
75
76      // FreeInsts erase the entire structure
77      pointerSize = ~0UL;
78    } else if (CallSite::get(QI).getInstruction() != 0) {
79      if (AA.getModRefInfo(C, CallSite::get(QI)) != AliasAnalysis::NoModRef) {
80        depGraphLocal.insert(std::make_pair(C.getInstruction(), std::make_pair(QI, true)));
81        reverseDep.insert(std::make_pair(QI, C.getInstruction()));
82        return QI;
83      } else {
84        continue;
85      }
86    } else
87      continue;
88
89    if (AA.getModRefInfo(C, pointer, pointerSize) != AliasAnalysis::NoModRef) {
90      depGraphLocal.insert(std::make_pair(C.getInstruction(), std::make_pair(QI, true)));
91      reverseDep.insert(std::make_pair(QI, C.getInstruction()));
92      return QI;
93    }
94  }
95
96  // No dependence found
97  depGraphLocal.insert(std::make_pair(C.getInstruction(), std::make_pair(NonLocal, true)));
98  reverseDep.insert(std::make_pair(NonLocal, C.getInstruction()));
99  return NonLocal;
100}
101
102/// getDependency - Return the instruction on which a memory operation
103/// depends.  The local paramter indicates if the query should only
104/// evaluate dependencies within the same basic block.
105Instruction* MemoryDependenceAnalysis::getDependency(Instruction* query,
106                                                     bool local) {
107  if (!local)
108    assert(0 && "Non-local memory dependence is not yet supported.");
109
110  // Start looking for dependencies with the queried inst
111  BasicBlock::iterator QI = query;
112
113  // Check for a cached result
114  std::pair<Instruction*, bool> cachedResult = depGraphLocal[query];
115  // If we have a _confirmed_ cached entry, return it
116  if (cachedResult.second)
117    return cachedResult.first;
118  else if (cachedResult.first != NonLocal)
119  // If we have an unconfirmed cached entry, we can start our search from there
120    QI = cachedResult.first;
121
122  AliasAnalysis& AA = getAnalysis<AliasAnalysis>();
123  TargetData& TD = getAnalysis<TargetData>();
124
125  // Get the pointer value for which dependence will be determined
126  Value* dependee = 0;
127  uint64_t dependeeSize = 0;
128  bool queryIsVolatile = false;
129  if (StoreInst* S = dyn_cast<StoreInst>(QI)) {
130    dependee = S->getPointerOperand();
131    dependeeSize = TD.getTypeSize(S->getOperand(0)->getType());
132    queryIsVolatile = S->isVolatile();
133  } else if (LoadInst* L = dyn_cast<LoadInst>(QI)) {
134    dependee = L->getPointerOperand();
135    dependeeSize = TD.getTypeSize(L->getType());
136    queryIsVolatile = L->isVolatile();
137  } else if (VAArgInst* V = dyn_cast<VAArgInst>(QI)) {
138    dependee = V->getOperand(0);
139    dependeeSize = TD.getTypeSize(V->getType());
140  } else if (FreeInst* F = dyn_cast<FreeInst>(QI)) {
141    dependee = F->getPointerOperand();
142
143    // FreeInsts erase the entire structure, not just a field
144    dependeeSize = ~0UL;
145  } else if (CallSite::get(QI).getInstruction() != 0)
146    return getCallSiteDependency(CallSite::get(QI));
147  else if (isa<AllocationInst>(query))
148    return None;
149  else
150    return None;
151
152  BasicBlock::iterator blockBegin = query->getParent()->begin();
153
154  while (QI != blockBegin) {
155    --QI;
156
157    // If this inst is a memory op, get the pointer it accessed
158    Value* pointer = 0;
159    uint64_t pointerSize = 0;
160    if (StoreInst* S = dyn_cast<StoreInst>(QI)) {
161      // All volatile loads/stores depend on each other
162      if (queryIsVolatile && S->isVolatile()) {
163        depGraphLocal.insert(std::make_pair(query, std::make_pair(S, true)));
164        reverseDep.insert(std::make_pair(S, query));
165        return S;
166      }
167
168      pointer = S->getPointerOperand();
169      pointerSize = TD.getTypeSize(S->getOperand(0)->getType());
170    } else if (LoadInst* L = dyn_cast<LoadInst>(QI)) {
171      // All volatile loads/stores depend on each other
172      if (queryIsVolatile && L->isVolatile()) {
173        depGraphLocal.insert(std::make_pair(query, std::make_pair(L, true)));
174        reverseDep.insert(std::make_pair(L, query));
175        return L;
176      }
177
178      pointer = L->getPointerOperand();
179      pointerSize = TD.getTypeSize(L->getType());
180    } else if (AllocationInst* AI = dyn_cast<AllocationInst>(QI)) {
181      pointer = AI;
182      if (ConstantInt* C = dyn_cast<ConstantInt>(AI->getArraySize()))
183        pointerSize = C->getZExtValue() * TD.getTypeSize(AI->getAllocatedType());
184      else
185        pointerSize = ~0UL;
186    } else if (VAArgInst* V = dyn_cast<VAArgInst>(QI)) {
187      pointer = V->getOperand(0);
188      pointerSize = TD.getTypeSize(V->getType());
189    } else if (FreeInst* F = dyn_cast<FreeInst>(QI)) {
190      pointer = F->getPointerOperand();
191
192      // FreeInsts erase the entire structure
193      pointerSize = ~0UL;
194    } else if (CallSite::get(QI).getInstruction() != 0) {
195      // Call insts need special handling.  Check is they can modify our pointer
196      if (AA.getModRefInfo(CallSite::get(QI), dependee, dependeeSize) !=
197          AliasAnalysis::NoModRef) {
198        depGraphLocal.insert(std::make_pair(query, std::make_pair(QI, true)));
199        reverseDep.insert(std::make_pair(QI, query));
200        return QI;
201      } else {
202        continue;
203      }
204    }
205
206    // If we found a pointer, check if it could be the same as our pointer
207    if (pointer) {
208      AliasAnalysis::AliasResult R = AA.alias(pointer, pointerSize,
209                                              dependee, dependeeSize);
210
211      if (R != AliasAnalysis::NoAlias) {
212        depGraphLocal.insert(std::make_pair(query, std::make_pair(QI, true)));
213        reverseDep.insert(std::make_pair(QI, query));
214        return QI;
215      }
216    }
217  }
218
219  // If we found nothing, return the non-local flag
220  depGraphLocal.insert(std::make_pair(query,
221                                      std::make_pair(NonLocal, true)));
222  reverseDep.insert(std::make_pair(NonLocal, query));
223
224  return NonLocal;
225}
226
227/// removeInstruction - Remove an instruction from the dependence analysis,
228/// updating the dependence of instructions that previously depended on it.
229void MemoryDependenceAnalysis::removeInstruction(Instruction* rem) {
230  // Figure out the new dep for things that currently depend on rem
231  Instruction* newDep = NonLocal;
232  if (depGraphLocal[rem].first != NonLocal) {
233    // If we have dep info for rem, set them to it
234    BasicBlock::iterator RI = depGraphLocal[rem].first;
235    RI++;
236    newDep = RI;
237  } else if (depGraphLocal[rem].first == NonLocal &&
238             depGraphLocal[rem].second ) {
239    // If we have a confirmed non-local flag, use it
240    newDep = NonLocal;
241  } else {
242    // Otherwise, use the immediate successor of rem
243    // NOTE: This is because, when getDependence is called, it will first check
244    // the immediate predecessor of what is in the cache.
245    BasicBlock::iterator RI = rem;
246    RI++;
247    newDep = RI;
248  }
249
250  std::multimap<Instruction*, Instruction*>::iterator I = reverseDep.find(rem);
251  while (I->first == rem) {
252    // Insert the new dependencies
253    // Mark it as unconfirmed as long as it is not the non-local flag
254    depGraphLocal[I->second] = std::make_pair(newDep, !newDep);
255    reverseDep.erase(I);
256    I = reverseDep.find(rem);
257  }
258
259  getAnalysis<AliasAnalysis>().deleteValue(rem);
260}
261