00001
00002
00003
00004
00005
00006
00007
00008
00009
00010
00011
00012
00013
00014
00015
00016
00017 #ifndef LLVM_ANALYSIS_ALIASSETTRACKER_H
00018 #define LLVM_ANALYSIS_ALIASSETTRACKER_H
00019
00020 #include "llvm/Support/CallSite.h"
00021 #include "llvm/Support/ValueHandle.h"
00022 #include "llvm/ADT/DenseMap.h"
00023 #include "llvm/ADT/ilist.h"
00024 #include "llvm/ADT/ilist_node.h"
00025 #include <vector>
00026
00027 namespace llvm {
00028
00029 class AliasAnalysis;
00030 class LoadInst;
00031 class StoreInst;
00032 class VAArgInst;
00033 class AliasSetTracker;
00034 class AliasSet;
00035
00036 class AliasSet : public ilist_node<AliasSet> {
00037 friend class AliasSetTracker;
00038
00039 class PointerRec {
00040 Value *Val;
00041 PointerRec **PrevInList, *NextInList;
00042 AliasSet *AS;
00043 unsigned Size;
00044 public:
00045 PointerRec(Value *V)
00046 : Val(V), PrevInList(0), NextInList(0), AS(0), Size(0) {}
00047
00048 Value *getValue() const { return Val; }
00049
00050 PointerRec *getNext() const { return NextInList; }
00051 bool hasAliasSet() const { return AS != 0; }
00052
00053 PointerRec** setPrevInList(PointerRec **PIL) {
00054 PrevInList = PIL;
00055 return &NextInList;
00056 }
00057
00058 void updateSize(unsigned NewSize) {
00059 if (NewSize > Size) Size = NewSize;
00060 }
00061
00062 unsigned getSize() const { return Size; }
00063
00064 AliasSet *getAliasSet(AliasSetTracker &AST) {
00065 assert(AS && "No AliasSet yet!");
00066 if (AS->Forward) {
00067 AliasSet *OldAS = AS;
00068 AS = OldAS->getForwardedTarget(AST);
00069 AS->addRef();
00070 OldAS->dropRef(AST);
00071 }
00072 return AS;
00073 }
00074
00075 void setAliasSet(AliasSet *as) {
00076 assert(AS == 0 && "Already have an alias set!");
00077 AS = as;
00078 }
00079
00080 void eraseFromList() {
00081 if (NextInList) NextInList->PrevInList = PrevInList;
00082 *PrevInList = NextInList;
00083 if (AS->PtrListEnd == &NextInList) {
00084 AS->PtrListEnd = PrevInList;
00085 assert(*AS->PtrListEnd == 0 && "List not terminated right!");
00086 }
00087 delete this;
00088 }
00089 };
00090
00091 PointerRec *PtrList, **PtrListEnd;
00092 AliasSet *Forward;
00093 AliasSet *Next, *Prev;
00094
00095 std::vector<CallSite> CallSites;
00096
00097
00098
00099 unsigned RefCount : 28;
00100
00106 enum AccessType {
00107 NoModRef = 0, Refs = 1,
00108 Mods = 2, ModRef = 3
00109 };
00110 unsigned AccessTy : 2;
00111
00115 enum AliasType {
00116 MustAlias = 0, MayAlias = 1
00117 };
00118 unsigned AliasTy : 1;
00119
00120
00121 bool Volatile : 1;
00122
00123 void addRef() { ++RefCount; }
00124 void dropRef(AliasSetTracker &AST) {
00125 assert(RefCount >= 1 && "Invalid reference count detected!");
00126 if (--RefCount == 0)
00127 removeFromTracker(AST);
00128 }
00129
00130 public:
00132 bool isRef() const { return AccessTy & Refs; }
00133 bool isMod() const { return AccessTy & Mods; }
00134 bool isMustAlias() const { return AliasTy == MustAlias; }
00135 bool isMayAlias() const { return AliasTy == MayAlias; }
00136
00137
00138
00139 bool isVolatile() const { return Volatile; }
00140
00143 bool isForwardingAliasSet() const { return Forward; }
00144
00147 void mergeSetIn(AliasSet &AS, AliasSetTracker &AST);
00148
00149
00150
00151 class iterator;
00152 iterator begin() const { return iterator(PtrList); }
00153 iterator end() const { return iterator(); }
00154 bool empty() const { return PtrList == 0; }
00155
00156 void print(raw_ostream &OS) const;
00157 void dump() const;
00158
00160 class iterator : public std::iterator<std::forward_iterator_tag,
00161 PointerRec, ptrdiff_t> {
00162 PointerRec *CurNode;
00163 public:
00164 explicit iterator(PointerRec *CN = 0) : CurNode(CN) {}
00165
00166 bool operator==(const iterator& x) const {
00167 return CurNode == x.CurNode;
00168 }
00169 bool operator!=(const iterator& x) const { return !operator==(x); }
00170
00171 const iterator &operator=(const iterator &I) {
00172 CurNode = I.CurNode;
00173 return *this;
00174 }
00175
00176 value_type &operator*() const {
00177 assert(CurNode && "Dereferencing AliasSet.end()!");
00178 return *CurNode;
00179 }
00180 value_type *operator->() const { return &operator*(); }
00181
00182 Value *getPointer() const { return CurNode->getValue(); }
00183 unsigned getSize() const { return CurNode->getSize(); }
00184
00185 iterator& operator++() {
00186 assert(CurNode && "Advancing past AliasSet.end()!");
00187 CurNode = CurNode->getNext();
00188 return *this;
00189 }
00190 iterator operator++(int) {
00191 iterator tmp = *this; ++*this; return tmp;
00192 }
00193 };
00194
00195 private:
00196
00197
00198 friend struct ilist_sentinel_traits<AliasSet>;
00199 AliasSet() : PtrList(0), PtrListEnd(&PtrList), Forward(0), RefCount(0),
00200 AccessTy(NoModRef), AliasTy(MustAlias), Volatile(false) {
00201 }
00202
00203 AliasSet(const AliasSet &AS);
00204 void operator=(const AliasSet &AS);
00205
00206 PointerRec *getSomePointer() const {
00207 return PtrList;
00208 }
00209
00213 AliasSet *getForwardedTarget(AliasSetTracker &AST) {
00214 if (!Forward) return this;
00215
00216 AliasSet *Dest = Forward->getForwardedTarget(AST);
00217 if (Dest != Forward) {
00218 Dest->addRef();
00219 Forward->dropRef(AST);
00220 Forward = Dest;
00221 }
00222 return Dest;
00223 }
00224
00225 void removeFromTracker(AliasSetTracker &AST);
00226
00227 void addPointer(AliasSetTracker &AST, PointerRec &Entry, unsigned Size,
00228 bool KnownMustAlias = false);
00229 void addCallSite(CallSite CS, AliasAnalysis &AA);
00230 void removeCallSite(CallSite CS) {
00231 for (size_t i = 0, e = CallSites.size(); i != e; ++i)
00232 if (CallSites[i].getInstruction() == CS.getInstruction()) {
00233 CallSites[i] = CallSites.back();
00234 CallSites.pop_back();
00235 }
00236 }
00237 void setVolatile() { Volatile = true; }
00238
00242 bool aliasesPointer(const Value *Ptr, unsigned Size, AliasAnalysis &AA) const;
00243 bool aliasesCallSite(CallSite CS, AliasAnalysis &AA) const;
00244 };
00245
00246 inline raw_ostream& operator<<(raw_ostream &OS, const AliasSet &AS) {
00247 AS.print(OS);
00248 return OS;
00249 }
00250
00251
00252 class AliasSetTracker {
00255 class ASTCallbackVH : public CallbackVH {
00256 AliasSetTracker *AST;
00257 virtual void deleted();
00258 public:
00259 ASTCallbackVH(Value *V, AliasSetTracker *AST = 0);
00260 ASTCallbackVH &operator=(Value *V);
00261 };
00264 struct ASTCallbackVHDenseMapInfo : public DenseMapInfo<Value *> {};
00265
00266 AliasAnalysis &AA;
00267 ilist<AliasSet> AliasSets;
00268
00269 typedef DenseMap<ASTCallbackVH, AliasSet::PointerRec*,
00270 ASTCallbackVHDenseMapInfo>
00271 PointerMapType;
00272
00273
00274 PointerMapType PointerMap;
00275
00276 public:
00280 explicit AliasSetTracker(AliasAnalysis &aa) : AA(aa) {}
00281 ~AliasSetTracker() { clear(); }
00282
00295 bool add(Value *Ptr, unsigned Size);
00296 bool add(LoadInst *LI);
00297 bool add(StoreInst *SI);
00298 bool add(VAArgInst *VAAI);
00299 bool add(CallSite CS);
00300 bool add(CallInst *CI) { return add(CallSite(CI)); }
00301 bool add(InvokeInst *II) { return add(CallSite(II)); }
00302 bool add(Instruction *I);
00303 void add(BasicBlock &BB);
00304 void add(const AliasSetTracker &AST);
00305
00309 bool remove(Value *Ptr, unsigned Size);
00310 bool remove(LoadInst *LI);
00311 bool remove(StoreInst *SI);
00312 bool remove(VAArgInst *VAAI);
00313 bool remove(CallSite CS);
00314 bool remove(CallInst *CI) { return remove(CallSite(CI)); }
00315 bool remove(InvokeInst *II) { return remove(CallSite(II)); }
00316 bool remove(Instruction *I);
00317 void remove(AliasSet &AS);
00318
00319 void clear();
00320
00323 const ilist<AliasSet> &getAliasSets() const { return AliasSets; }
00324
00329 AliasSet &getAliasSetForPointer(Value *P, unsigned Size, bool *New = 0);
00330
00333 AliasSet *getAliasSetForPointerIfExists(Value *P, unsigned Size) {
00334 return findAliasSetForPointer(P, Size);
00335 }
00336
00340 bool containsPointer(Value *P, unsigned Size) const;
00341
00344 AliasAnalysis &getAliasAnalysis() const { return AA; }
00345
00351 void deleteValue(Value *PtrVal);
00352
00359 void copyValue(Value *From, Value *To);
00360
00361
00362 typedef ilist<AliasSet>::iterator iterator;
00363 typedef ilist<AliasSet>::const_iterator const_iterator;
00364
00365 const_iterator begin() const { return AliasSets.begin(); }
00366 const_iterator end() const { return AliasSets.end(); }
00367
00368 iterator begin() { return AliasSets.begin(); }
00369 iterator end() { return AliasSets.end(); }
00370
00371 void print(raw_ostream &OS) const;
00372 void dump() const;
00373
00374 private:
00375 friend class AliasSet;
00376 void removeAliasSet(AliasSet *AS);
00377
00378
00379
00380 AliasSet::PointerRec &getEntryFor(Value *V) {
00381 AliasSet::PointerRec *&Entry = PointerMap[ASTCallbackVH(V, this)];
00382 if (Entry == 0)
00383 Entry = new AliasSet::PointerRec(V);
00384 return *Entry;
00385 }
00386
00387 AliasSet &addPointer(Value *P, unsigned Size, AliasSet::AccessType E,
00388 bool &NewSet) {
00389 NewSet = false;
00390 AliasSet &AS = getAliasSetForPointer(P, Size, &NewSet);
00391 AS.AccessTy |= E;
00392 return AS;
00393 }
00394 AliasSet *findAliasSetForPointer(const Value *Ptr, unsigned Size);
00395
00396 AliasSet *findAliasSetForCallSite(CallSite CS);
00397 };
00398
00399 inline raw_ostream& operator<<(raw_ostream &OS, const AliasSetTracker &AST) {
00400 AST.print(OS);
00401 return OS;
00402 }
00403
00404 }
00405
00406 #endif