00001
00002
00003
00004
00005
00006
00007
00008
00009
00010
00011
00012
00013
00014 #ifndef LLVM_ANALYSIS_MEMORY_DEPENDENCE_H
00015 #define LLVM_ANALYSIS_MEMORY_DEPENDENCE_H
00016
00017 #include "llvm/BasicBlock.h"
00018 #include "llvm/Pass.h"
00019 #include "llvm/Support/ValueHandle.h"
00020 #include "llvm/ADT/DenseMap.h"
00021 #include "llvm/ADT/SmallPtrSet.h"
00022 #include "llvm/ADT/OwningPtr.h"
00023 #include "llvm/ADT/PointerIntPair.h"
00024
00025 namespace llvm {
00026 class Function;
00027 class FunctionPass;
00028 class Instruction;
00029 class CallSite;
00030 class AliasAnalysis;
00031 class TargetData;
00032 class MemoryDependenceAnalysis;
00033 class PredIteratorCache;
00034 class DominatorTree;
00035 class PHITransAddr;
00036
00039 class MemDepResult {
00040 enum DepType {
00042 Invalid = 0,
00043
00049 Clobber,
00050
00068 Def,
00069
00073 NonLocal
00074 };
00075 typedef PointerIntPair<Instruction*, 2, DepType> PairTy;
00076 PairTy Value;
00077 explicit MemDepResult(PairTy V) : Value(V) {}
00078 public:
00079 MemDepResult() : Value(0, Invalid) {}
00080
00083 static MemDepResult getDef(Instruction *Inst) {
00084 return MemDepResult(PairTy(Inst, Def));
00085 }
00086 static MemDepResult getClobber(Instruction *Inst) {
00087 return MemDepResult(PairTy(Inst, Clobber));
00088 }
00089 static MemDepResult getNonLocal() {
00090 return MemDepResult(PairTy(0, NonLocal));
00091 }
00092
00095 bool isClobber() const { return Value.getInt() == Clobber; }
00096
00099 bool isDef() const { return Value.getInt() == Def; }
00100
00104 bool isNonLocal() const { return Value.getInt() == NonLocal; }
00105
00108 Instruction *getInst() const { return Value.getPointer(); }
00109
00110 bool operator==(const MemDepResult &M) const { return Value == M.Value; }
00111 bool operator!=(const MemDepResult &M) const { return Value != M.Value; }
00112 bool operator<(const MemDepResult &M) const { return Value < M.Value; }
00113 bool operator>(const MemDepResult &M) const { return Value > M.Value; }
00114 private:
00115 friend class MemoryDependenceAnalysis;
00125
00128 bool isDirty() const { return Value.getInt() == Invalid; }
00129
00130 static MemDepResult getDirty(Instruction *Inst) {
00131 return MemDepResult(PairTy(Inst, Invalid));
00132 }
00133 };
00134
00138 class NonLocalDepResult {
00139 BasicBlock *BB;
00140 MemDepResult Result;
00141 Value *Address;
00142 public:
00143 NonLocalDepResult(BasicBlock *bb, MemDepResult result, Value *address)
00144 : BB(bb), Result(result), Address(address) {}
00145
00146
00147 BasicBlock *getBB() const { return BB; }
00148
00149 void setResult(const MemDepResult &R, Value *Addr) {
00150 Result = R;
00151 Address = Addr;
00152 }
00153
00154 const MemDepResult &getResult() const { return Result; }
00155
00163 Value *getAddress() const { return Address; }
00164 };
00165
00168 class NonLocalDepEntry {
00169 BasicBlock *BB;
00170 MemDepResult Result;
00171 public:
00172 NonLocalDepEntry(BasicBlock *bb, MemDepResult result)
00173 : BB(bb), Result(result) {}
00174
00175
00176 NonLocalDepEntry(BasicBlock *bb) : BB(bb) {}
00177
00178
00179 BasicBlock *getBB() const { return BB; }
00180
00181 void setResult(const MemDepResult &R) { Result = R; }
00182
00183 const MemDepResult &getResult() const { return Result; }
00184
00185 bool operator<(const NonLocalDepEntry &RHS) const {
00186 return BB < RHS.BB;
00187 }
00188 };
00189
00205 class MemoryDependenceAnalysis : public FunctionPass {
00206
00207 typedef DenseMap<Instruction*, MemDepResult> LocalDepMapType;
00208 LocalDepMapType LocalDeps;
00209
00210 public:
00211 typedef std::vector<NonLocalDepEntry> NonLocalDepInfo;
00212 private:
00215 typedef PointerIntPair<Value*, 1, bool> ValueIsLoadPair;
00216
00221 typedef PointerIntPair<BasicBlock*, 1, bool> BBSkipFirstBlockPair;
00222
00226 typedef DenseMap<ValueIsLoadPair, std::pair<BBSkipFirstBlockPair,
00227 NonLocalDepInfo> > CachedNonLocalPointerInfo;
00228 CachedNonLocalPointerInfo NonLocalPointerDeps;
00229
00230
00231 typedef DenseMap<Instruction*,
00232 SmallPtrSet<ValueIsLoadPair, 4> > ReverseNonLocalPtrDepTy;
00233 ReverseNonLocalPtrDepTy ReverseNonLocalPtrDeps;
00234
00235
00239 typedef std::pair<NonLocalDepInfo, bool> PerInstNLInfo;
00240
00241
00242 typedef DenseMap<Instruction*, PerInstNLInfo> NonLocalDepMapType;
00243
00244 NonLocalDepMapType NonLocalDeps;
00245
00246
00247
00248 typedef DenseMap<Instruction*,
00249 SmallPtrSet<Instruction*, 4> > ReverseDepMapType;
00250 ReverseDepMapType ReverseLocalDeps;
00251
00252
00253 ReverseDepMapType ReverseNonLocalDeps;
00254
00256 AliasAnalysis *AA;
00257 TargetData *TD;
00258 OwningPtr<PredIteratorCache> PredCache;
00259 public:
00260 MemoryDependenceAnalysis();
00261 ~MemoryDependenceAnalysis();
00262 static char ID;
00263
00265 bool runOnFunction(Function &);
00266
00268 void releaseMemory();
00269
00273 virtual void getAnalysisUsage(AnalysisUsage &AU) const;
00274
00278 MemDepResult getDependency(Instruction *QueryInst);
00279
00292 const NonLocalDepInfo &getNonLocalCallDependency(CallSite QueryCS);
00293
00294
00300 void getNonLocalPointerDependency(Value *Pointer, bool isLoad,
00301 BasicBlock *BB,
00302 SmallVectorImpl<NonLocalDepResult> &Result);
00303
00306 void removeInstruction(Instruction *InstToRemove);
00307
00314 void invalidateCachedPointerInfo(Value *Ptr);
00315
00319 void invalidateCachedPredecessors();
00320
00321 private:
00322 MemDepResult getPointerDependencyFrom(Value *Pointer, uint64_t MemSize,
00323 bool isLoad,
00324 BasicBlock::iterator ScanIt,
00325 BasicBlock *BB);
00326 MemDepResult getCallSiteDependencyFrom(CallSite C, bool isReadOnlyCall,
00327 BasicBlock::iterator ScanIt,
00328 BasicBlock *BB);
00329 bool getNonLocalPointerDepFromBB(const PHITransAddr &Pointer, uint64_t Size,
00330 bool isLoad, BasicBlock *BB,
00331 SmallVectorImpl<NonLocalDepResult> &Result,
00332 DenseMap<BasicBlock*, Value*> &Visited,
00333 bool SkipFirstBlock = false);
00334 MemDepResult GetNonLocalInfoForBlock(Value *Pointer, uint64_t PointeeSize,
00335 bool isLoad, BasicBlock *BB,
00336 NonLocalDepInfo *Cache,
00337 unsigned NumSortedEntries);
00338
00339 void RemoveCachedNonLocalPointerDependencies(ValueIsLoadPair P);
00340
00343 void verifyRemoved(Instruction *Inst) const;
00344
00345 };
00346
00347 }
00348
00349 #endif