diff --git a/include/llvm/Analysis/AliasSetTracker.h b/include/llvm/Analysis/AliasSetTracker.h index ad71d99ca27..713add5506b 100644 --- a/include/llvm/Analysis/AliasSetTracker.h +++ b/include/llvm/Analysis/AliasSetTracker.h @@ -29,12 +29,19 @@ class AliasSet { class PointerRec { HashNodePair *NextInList; AliasSet *AS; + unsigned Size; public: - PointerRec() : NextInList(0), AS(0) {} + PointerRec() : NextInList(0), AS(0), Size(0) {} HashNodePair *getNext() const { return NextInList; } bool hasAliasSet() const { return AS != 0; } + void updateSize(unsigned NewSize) { + if (NewSize > Size) Size = NewSize; + } + + unsigned getSize() const { return Size; } + AliasSet *getAliasSet(AliasSetTracker &AST) { assert(AS && "No AliasSet yet!"); if (AS->Forward) { @@ -87,7 +94,7 @@ class AliasSet { unsigned AliasTy : 1; /// Define an iterator for alias sets... this is just a forward iterator. - class iterator : public forward_iterator { + class iterator : public forward_iterator { HashNodePair *CurNode; public: iterator(HashNodePair *CN = 0) : CurNode(CN) {} @@ -102,11 +109,11 @@ class AliasSet { return *this; } - value_type operator*() const { + value_type &operator*() const { assert(CurNode && "Dereferencing AliasSet.end()!"); - return CurNode->first; + return *CurNode; } - value_type operator->() const { return operator*(); } + value_type *operator->() const { return &operator*(); } iterator& operator++() { // Preincrement assert(CurNode && "Advancing past AliasSet.end()!"); @@ -148,8 +155,8 @@ private: AliasSet() : PtrListHead(0), PtrListTail(0), Forward(0), RefCount(0), AccessTy(NoModRef), AliasTy(MustAlias) { } - Value *getSomePointer() const { - return PtrListHead ? PtrListHead->first : 0; + HashNodePair *getSomePointer() const { + return PtrListHead ? PtrListHead : 0; } /// getForwardedTarget - Return the real alias set this represents. If this @@ -170,13 +177,13 @@ private: void removeFromTracker(AliasSetTracker &AST); - void addPointer(AliasSetTracker &AST, HashNodePair &Entry); + void addPointer(AliasSetTracker &AST, HashNodePair &Entry, unsigned Size); void addCallSite(CallSite CS); /// aliasesPointer - Return true if the specified pointer "may" (or must) /// alias one of the members in the set. /// - bool aliasesPointer(const Value *Ptr, AliasAnalysis &AA) const; + bool aliasesPointer(const Value *Ptr, unsigned Size, AliasAnalysis &AA) const; bool aliasesCallSite(CallSite CS, AliasAnalysis &AA) const; }; @@ -219,7 +226,7 @@ public: /// getAliasSetForPointer - Return the alias set that the specified pointer /// lives in... - AliasSet &getAliasSetForPointer(Value *P); + AliasSet &getAliasSetForPointer(Value *P, unsigned Size); /// getAliasAnalysis - Return the underlying alias analysis object used by /// this tracker. @@ -248,11 +255,11 @@ private: AliasSet::PointerRec())).first; } - void addPointer(Value *P, AliasSet::AccessType E) { - AliasSet &AS = getAliasSetForPointer(P); + void addPointer(Value *P, unsigned Size, AliasSet::AccessType E) { + AliasSet &AS = getAliasSetForPointer(P, Size); AS.AccessTy |= E; } - AliasSet *findAliasSetForPointer(const Value *Ptr); + AliasSet *findAliasSetForPointer(const Value *Ptr, unsigned Size); AliasSet *findAliasSetForCallSite(CallSite CS); }; diff --git a/lib/Analysis/AliasSetTracker.cpp b/lib/Analysis/AliasSetTracker.cpp index acb200481aa..f58aaa3e815 100644 --- a/lib/Analysis/AliasSetTracker.cpp +++ b/lib/Analysis/AliasSetTracker.cpp @@ -10,11 +10,10 @@ #include "llvm/iOther.h" #include "llvm/iTerminators.h" #include "llvm/Pass.h" +#include "llvm/Target/TargetData.h" #include "llvm/Assembly/Writer.h" #include "llvm/Support/InstIterator.h" -// FIXME: This should keep sizes associated with pointers! - /// mergeSetIn - Merge the specified alias set into this alias set... /// void AliasSet::mergeSetIn(AliasSet &AS) { @@ -54,17 +53,25 @@ void AliasSet::removeFromTracker(AliasSetTracker &AST) { AST.removeAliasSet(this); } -void AliasSet::addPointer(AliasSetTracker &AST, HashNodePair &Entry){ +void AliasSet::addPointer(AliasSetTracker &AST, HashNodePair &Entry, + unsigned Size) { assert(!Entry.second.hasAliasSet() && "Entry already in set!"); AliasAnalysis &AA = AST.getAliasAnalysis(); if (isMustAlias()) // Check to see if we have to downgrade to _may_ alias - if (Value *V = getSomePointer()) - if (AA.alias(V, ~0, Entry.first, ~0) == AliasAnalysis::MayAlias) + if (HashNodePair *P = getSomePointer()) { + AliasAnalysis::AliasResult Result = + AA.alias(P->first, P->second.getSize(), Entry.first, Size); + if (Result == AliasAnalysis::MayAlias) AliasTy = MayAlias; + else // First entry of must alias must have maximum size! + P->second.updateSize(Size); + assert(Result != AliasAnalysis::NoAlias && "Cannot be part of must set!"); + } Entry.second.setAliasSet(this); + Entry.second.updateSize(Size); // Add it to the end of the list... if (PtrListTail) @@ -77,27 +84,28 @@ void AliasSet::addPointer(AliasSetTracker &AST, HashNodePair &Entry){ void AliasSet::addCallSite(CallSite CS) { CallSites.push_back(CS); - AliasTy = MayAlias; // FIXME: Too conservative + AliasTy = MayAlias; // FIXME: Too conservative? } /// aliasesPointer - Return true if the specified pointer "may" (or must) /// alias one of the members in the set. /// -bool AliasSet::aliasesPointer(const Value *Ptr, AliasAnalysis &AA) const { +bool AliasSet::aliasesPointer(const Value *Ptr, unsigned Size, + AliasAnalysis &AA) const { if (AliasTy == MustAlias) { assert(CallSites.empty() && "Illegal must alias set!"); // If this is a set of MustAliases, only check to see if the pointer aliases // SOME value in the set... - Value *SomePtr = getSomePointer(); + HashNodePair *SomePtr = getSomePointer(); assert(SomePtr && "Empty must-alias set??"); - return AA.alias(SomePtr, ~0, Ptr, ~0); + return AA.alias(SomePtr->first, SomePtr->second.getSize(), Ptr, Size); } // If this is a may-alias set, we have to check all of the pointers in the set // to be sure it doesn't alias the set... for (iterator I = begin(), E = end(); I != E; ++I) - if (AA.alias(Ptr, ~0, *I, ~0)) + if (AA.alias(Ptr, Size, I->first, I->second.getSize())) return true; // Check the call sites list and invoke list... @@ -118,10 +126,11 @@ bool AliasSet::aliasesCallSite(CallSite CS, AliasAnalysis &AA) const { /// instruction referring to the pointer into. If there are multiple alias sets /// that may alias the pointer, merge them together and return the unified set. /// -AliasSet *AliasSetTracker::findAliasSetForPointer(const Value *Ptr) { +AliasSet *AliasSetTracker::findAliasSetForPointer(const Value *Ptr, + unsigned Size) { AliasSet *FoundSet = 0; for (iterator I = begin(), E = end(); I != E; ++I) - if (!I->Forward && I->aliasesPointer(Ptr, AA)) { + if (!I->Forward && I->aliasesPointer(Ptr, Size, AA)) { if (FoundSet == 0) { // If this is the first alias set ptr can go into... FoundSet = I; // Remember it. } else { // Otherwise, we must merge the sets... @@ -151,31 +160,34 @@ AliasSet *AliasSetTracker::findAliasSetForCallSite(CallSite CS) { /// getAliasSetForPointer - Return the alias set that the specified pointer /// lives in... -AliasSet &AliasSetTracker::getAliasSetForPointer(Value *Pointer) { +AliasSet &AliasSetTracker::getAliasSetForPointer(Value *Pointer, unsigned Size){ AliasSet::HashNodePair &Entry = getEntryFor(Pointer); // Check to see if the pointer is already known... - if (Entry.second.hasAliasSet()) { + if (Entry.second.hasAliasSet() && Size <= Entry.second.getSize()) { // Return the set! return *Entry.second.getAliasSet(*this)->getForwardedTarget(*this); - } else if (AliasSet *AS = findAliasSetForPointer(Pointer)) { + } else if (AliasSet *AS = findAliasSetForPointer(Pointer, Size)) { // Add it to the alias set it aliases... - AS->addPointer(*this, Entry); + AS->addPointer(*this, Entry, Size); return *AS; } else { // Otherwise create a new alias set to hold the loaded pointer... AliasSets.push_back(AliasSet()); - AliasSets.back().addPointer(*this, Entry); + AliasSets.back().addPointer(*this, Entry, Size); return AliasSets.back(); } } void AliasSetTracker::add(LoadInst *LI) { - addPointer(LI->getOperand(0), AliasSet::Refs); + addPointer(LI->getOperand(0), + AA.getTargetData().getTypeSize(LI->getType()), AliasSet::Refs); } void AliasSetTracker::add(StoreInst *SI) { - addPointer(SI->getOperand(1), AliasSet::Mods); + addPointer(SI->getOperand(1), + AA.getTargetData().getTypeSize(SI->getOperand(0)->getType()), + AliasSet::Mods); } void AliasSetTracker::add(CallSite CS) { @@ -221,7 +233,8 @@ void AliasSet::print(std::ostream &OS) const { OS << "Pointers: "; for (iterator I = begin(), E = end(); I != E; ++I) { if (I != begin()) OS << ", "; - WriteAsOperand(OS, *I); + WriteAsOperand(OS << "(", I->first); + OS << ", " << I->second.getSize() << ")"; } } if (!CallSites.empty()) {