blob: 8ed2be35fc545f1cdad86cd9e0839b6a148e33c2 [file] [log] [blame]
Owen Andersonc0daf5f2007-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"
18#include "llvm/Instructions.h"
19#include "llvm/Function.h"
20#include "llvm/Analysis/AliasAnalysis.h"
21#include "llvm/Target/TargetData.h"
22
23using namespace llvm;
24
25char MemoryDependenceAnalysis::ID = 0;
26
27Instruction* MemoryDependenceAnalysis::NonLocal = (Instruction*)0;
28Instruction* MemoryDependenceAnalysis::None = (Instruction*)~0;
29
30// Register this pass...
31RegisterPass<MemoryDependenceAnalysis> X("memdep",
32 "Memory Dependence Analysis");
33
34/// getAnalysisUsage - Does not modify anything. It uses Alias Analysis.
35///
36void MemoryDependenceAnalysis::getAnalysisUsage(AnalysisUsage &AU) const {
37 AU.setPreservesAll();
38 AU.addRequiredTransitive<AliasAnalysis>();
39 AU.addRequiredTransitive<TargetData>();
40}
41
42/// getDependency - Return the instruction on which a memory operation
Owen Anderson47352db2007-07-10 17:08:11 +000043/// depends. The local paramter indicates if the query should only
44/// evaluate dependencies within the same basic block.
Owen Andersonc0daf5f2007-07-06 23:14:35 +000045Instruction* MemoryDependenceAnalysis::getDependency(Instruction* query,
46 bool local) {
47 if (!local)
48 assert(0 && "Non-local memory dependence is not yet supported.");
49
50 // Start looking for dependencies with the queried inst
51 BasicBlock::iterator QI = query;
52
53 // Check for a cached result
54 std::pair<Instruction*, bool> cachedResult = depGraphLocal[query];
55 // If we have a _confirmed_ cached entry, return it
56 if (cachedResult.second)
57 return cachedResult.first;
58 else if (cachedResult.first != NonLocal)
59 // If we have an unconfirmed cached entry, we can start our search from there
60 QI = cachedResult.first;
61
62 AliasAnalysis& AA = getAnalysis<AliasAnalysis>();
Owen Anderson47352db2007-07-10 17:08:11 +000063 TargetData& TD = getAnalysis<TargetData>();
Owen Andersonc0daf5f2007-07-06 23:14:35 +000064
65 // Get the pointer value for which dependence will be determined
66 Value* dependee = 0;
Owen Anderson47352db2007-07-10 17:08:11 +000067 uint64_t dependeeSize = 0;
68 if (StoreInst* S = dyn_cast<StoreInst>(QI)) {
Owen Andersonc0daf5f2007-07-06 23:14:35 +000069 dependee = S->getPointerOperand();
Owen Anderson47352db2007-07-10 17:08:11 +000070 dependeeSize = TD.getTypeSize(dependee->getType());
71 } else if (LoadInst* L = dyn_cast<LoadInst>(QI)) {
Owen Andersonc0daf5f2007-07-06 23:14:35 +000072 dependee = L->getPointerOperand();
Owen Anderson47352db2007-07-10 17:08:11 +000073 dependeeSize = TD.getTypeSize(dependee->getType());
74 } else if (FreeInst* F = dyn_cast<FreeInst>(QI)) {
Owen Andersonc0daf5f2007-07-06 23:14:35 +000075 dependee = F->getPointerOperand();
Owen Anderson47352db2007-07-10 17:08:11 +000076
77 // FreeInsts erase the entire structure, not just a field
78 dependeeSize = ~0UL;
79 } else if (isa<AllocationInst>(query)) {
Owen Andersonc0daf5f2007-07-06 23:14:35 +000080 // Allocations don't depend on anything
81 depGraphLocal.insert(std::make_pair(query, std::make_pair(None,
82 true)));
83 reverseDep.insert(std::make_pair(None, query));
84 return None;
Owen Anderson47352db2007-07-10 17:08:11 +000085 } else
86 // FIXME: Call/InvokeInsts need proper handling
87 return None;
Owen Andersonc0daf5f2007-07-06 23:14:35 +000088
Owen Andersonc0daf5f2007-07-06 23:14:35 +000089
Owen Anderson47352db2007-07-10 17:08:11 +000090 BasicBlock::iterator blockBegin = query->getParent()->begin();
Owen Andersonc0daf5f2007-07-06 23:14:35 +000091
92 while (QI != blockBegin) {
Owen Anderson47352db2007-07-10 17:08:11 +000093 --QI;
94
95 // If we've reached the pointer's definition...
96 if (QI == dependee) {
97 depGraphLocal.insert(std::make_pair(query, std::make_pair(QI, true)));
98 reverseDep.insert(std::make_pair(QI, query));
99 return QI;
100 }
101
Owen Andersonc0daf5f2007-07-06 23:14:35 +0000102 // If this inst is a memory op, get the pointer it accessed
103 Value* pointer = 0;
Owen Anderson47352db2007-07-10 17:08:11 +0000104 uint64_t pointerSize = 0;
105 if (StoreInst* S = dyn_cast<StoreInst>(QI)) {
Owen Andersonc0daf5f2007-07-06 23:14:35 +0000106 pointer = S->getPointerOperand();
Owen Anderson47352db2007-07-10 17:08:11 +0000107 pointerSize = TD.getTypeSize(pointer->getType());
108 } else if (LoadInst* L = dyn_cast<LoadInst>(QI)) {
Owen Andersonc0daf5f2007-07-06 23:14:35 +0000109 pointer = L->getPointerOperand();
Owen Anderson47352db2007-07-10 17:08:11 +0000110 pointerSize = TD.getTypeSize(pointer->getType());
111 } else if (AllocationInst* AI = dyn_cast<AllocationInst>(QI)) {
112 pointer = AI;
113 if (isa<ConstantInt>(AI->getArraySize()))
114 pointerSize = AI->getZExtValue();
115 else
116 pointerSize = ~0UL;
117 } else if (FreeInst* F = dyn_cast<FreeInst>(QI)) {
Owen Andersonc0daf5f2007-07-06 23:14:35 +0000118 pointer = F->getPointerOperand();
Owen Anderson47352db2007-07-10 17:08:11 +0000119
120 // FreeInsts erase the entire structure
121 pointerSize = ~0UL;
122 } else if (CallSite* C = dyn_cast<CallSite>(QI)) {
Owen Andersonc0daf5f2007-07-06 23:14:35 +0000123 // Call insts need special handling. Check is they can modify our pointer
Owen Anderson47352db2007-07-10 17:08:11 +0000124 if (AA.getModRefInfo(C, dependee, dependeeSize) != AliasAnalysis::NoModRef) {
Owen Andersonc0daf5f2007-07-06 23:14:35 +0000125 depGraphLocal.insert(std::make_pair(query, std::make_pair(C, true)));
126 reverseDep.insert(std::make_pair(C, query));
127 return C;
128 } else {
129 continue;
130 }
131 }
132
133 // If we found a pointer, check if it could be the same as our pointer
134 if (pointer) {
Owen Anderson47352db2007-07-10 17:08:11 +0000135 AliasAnalysis::AliasResult R = AA.alias(pointer, pointerSize,
136 dependee, dependeeSize);
Owen Andersonc0daf5f2007-07-06 23:14:35 +0000137
138 if (R != AliasAnalysis::NoAlias) {
139 depGraphLocal.insert(std::make_pair(query, std::make_pair(QI, true)));
140 reverseDep.insert(std::make_pair(QI, query));
141 return QI;
142 }
143 }
Owen Andersonc0daf5f2007-07-06 23:14:35 +0000144 }
145
146 // If we found nothing, return the non-local flag
147 depGraphLocal.insert(std::make_pair(query,
148 std::make_pair(NonLocal, true)));
149 reverseDep.insert(std::make_pair(NonLocal, query));
150
151 return NonLocal;
152}
153
154/// removeInstruction - Remove an instruction from the dependence analysis,
155/// updating the dependence of instructions that previously depended on it.
156void MemoryDependenceAnalysis::removeInstruction(Instruction* rem) {
157 // Figure out the new dep for things that currently depend on rem
158 Instruction* newDep = NonLocal;
159 if (depGraphLocal[rem].first != NonLocal) {
160 // If we have dep info for rem, set them to it
161 BasicBlock::iterator RI = depGraphLocal[rem].first;
162 RI++;
163 newDep = RI;
164 } else if (depGraphLocal[rem].first == NonLocal &&
165 depGraphLocal[rem].second ) {
166 // If we have a confirmed non-local flag, use it
167 newDep = NonLocal;
168 } else {
169 // Otherwise, use the immediate successor of rem
170 // NOTE: This is because, when getDependence is called, it will first check
171 // the immediate predecessor of what is in the cache.
172 BasicBlock::iterator RI = rem;
173 RI++;
174 newDep = RI;
175 }
176
177 std::multimap<Instruction*, Instruction*>::iterator I = reverseDep.find(rem);
178 while (I->first == rem) {
179 // Insert the new dependencies
180 // Mark it as unconfirmed as long as it is not the non-local flag
181 depGraphLocal[I->second] = std::make_pair(newDep, !newDep);
182 reverseDep.erase(I);
183 I = reverseDep.find(rem);
184 }
185}