X-Git-Url: http://demsky.eecs.uci.edu/git/?a=blobdiff_plain;f=lib%2FAnalysis%2FAliasSetTracker.cpp;h=f00e5c8b311ecb7923b7b46c9e0e88e77bda4c5d;hb=c53544af06acf3fba1788613a364f1f40317869e;hp=db704b654a24978036d6e4eaffbbaac6a3c2b4ac;hpb=9971ac4a36c54488bcdf55d7e493ac0cd6dc168a;p=oota-llvm.git diff --git a/lib/Analysis/AliasSetTracker.cpp b/lib/Analysis/AliasSetTracker.cpp index db704b654a2..f00e5c8b311 100644 --- a/lib/Analysis/AliasSetTracker.cpp +++ b/lib/Analysis/AliasSetTracker.cpp @@ -10,6 +10,7 @@ #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" @@ -52,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, Entry.first) == 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) @@ -75,27 +84,29 @@ 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? + AccessTy = ModRef; } /// 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, Ptr); + 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, *I)) + if (AA.alias(Ptr, Size, I->first, I->second.getSize())) return true; // Check the call sites list and invoke list... @@ -116,10 +127,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->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... @@ -133,10 +145,10 @@ AliasSet *AliasSetTracker::findAliasSetForPointer(const Value *Ptr) { AliasSet *AliasSetTracker::findAliasSetForCallSite(CallSite CS) { AliasSet *FoundSet = 0; for (iterator I = begin(), E = end(); I != E; ++I) - if (I->aliasesCallSite(CS, AA)) { + if (!I->Forward && I->aliasesCallSite(CS, 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... + } else if (!I->Forward) { // Otherwise, we must merge the sets... FoundSet->mergeSetIn(*I); // Merge in contents... } } @@ -149,31 +161,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) { @@ -197,6 +212,34 @@ void AliasSetTracker::add(Instruction *I) { add(II); } +void AliasSetTracker::add(BasicBlock &BB) { + for (BasicBlock::iterator I = BB.begin(), E = BB.end(); I != E; ++I) + add(I); +} + +void AliasSetTracker::add(const AliasSetTracker &AST) { + assert(&AA == &AST.AA && + "Merging AliasSetTracker objects with different Alias Analyses!"); + + // Loop over all of the alias sets in AST, adding the pointers contained + // therein into the current alias sets. This can cause alias sets to be + // merged together in the current AST. + for (const_iterator I = AST.begin(), E = AST.end(); I != E; ++I) + if (!I->Forward) { // Ignore forwarding alias sets + AliasSet &AS = const_cast(*I); + + // If there are any call sites in the alias set, add them to this AST. + for (unsigned i = 0, e = AS.CallSites.size(); i != e; ++i) + add(AS.CallSites[i]); + + // Loop over all of the pointers in this alias set... + AliasSet::iterator I = AS.begin(), E = AS.end(); + for (; I != E; ++I) + addPointer(I->first, I->second.getSize(), + (AliasSet::AccessType)AS.AccessTy); + } +} + //===----------------------------------------------------------------------===// // AliasSet/AliasSetTracker Printing Support //===----------------------------------------------------------------------===// @@ -219,7 +262,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()) {