diff options
Diffstat (limited to 'lib/Analysis/AliasSetTracker.cpp')
-rw-r--r-- | lib/Analysis/AliasSetTracker.cpp | 131 |
1 files changed, 79 insertions, 52 deletions
diff --git a/lib/Analysis/AliasSetTracker.cpp b/lib/Analysis/AliasSetTracker.cpp index f6ad704cc914..a6e5b9fab558 100644 --- a/lib/Analysis/AliasSetTracker.cpp +++ b/lib/Analysis/AliasSetTracker.cpp @@ -1,9 +1,8 @@ //===- AliasSetTracker.cpp - Alias Sets Tracker implementation-------------===// // -// The LLVM Compiler Infrastructure -// -// This file is distributed under the University of Illinois Open Source -// License. See LICENSE.TXT for details. +// Part of the LLVM Project, under the Apache License v2.0 with LLVM Exceptions. +// See https://llvm.org/LICENSE.txt for license information. +// SPDX-License-Identifier: Apache-2.0 WITH LLVM-exception // //===----------------------------------------------------------------------===// // @@ -14,7 +13,9 @@ #include "llvm/Analysis/AliasSetTracker.h" #include "llvm/Analysis/AliasAnalysis.h" #include "llvm/Analysis/GuardUtils.h" +#include "llvm/Analysis/LoopInfo.h" #include "llvm/Analysis/MemoryLocation.h" +#include "llvm/Analysis/MemorySSA.h" #include "llvm/Config/llvm-config.h" #include "llvm/IR/Constants.h" #include "llvm/IR/DataLayout.h" @@ -127,24 +128,24 @@ void AliasSet::removeFromTracker(AliasSetTracker &AST) { void AliasSet::addPointer(AliasSetTracker &AST, PointerRec &Entry, LocationSize Size, const AAMDNodes &AAInfo, - bool KnownMustAlias) { + bool KnownMustAlias, bool SkipSizeUpdate) { assert(!Entry.hasAliasSet() && "Entry already in set!"); // Check to see if we have to downgrade to _may_ alias. - if (isMustAlias() && !KnownMustAlias) + if (isMustAlias()) if (PointerRec *P = getSomePointer()) { - AliasAnalysis &AA = AST.getAliasAnalysis(); - AliasResult Result = - AA.alias(MemoryLocation(P->getValue(), P->getSize(), P->getAAInfo()), - MemoryLocation(Entry.getValue(), Size, AAInfo)); - if (Result != MustAlias) { - Alias = SetMayAlias; - AST.TotalMayAliasSetSize += size(); - } else { - // First entry of must alias must have maximum size! + if (!KnownMustAlias) { + AliasAnalysis &AA = AST.getAliasAnalysis(); + AliasResult Result = AA.alias( + MemoryLocation(P->getValue(), P->getSize(), P->getAAInfo()), + MemoryLocation(Entry.getValue(), Size, AAInfo)); + if (Result != MustAlias) { + Alias = SetMayAlias; + AST.TotalMayAliasSetSize += size(); + } + assert(Result != NoAlias && "Cannot be part of must set!"); + } else if (!SkipSizeUpdate) P->updateSizeAndAAInfo(Size, AAInfo); - } - assert(Result != NoAlias && "Cannot be part of must set!"); } Entry.setAliasSet(this); @@ -184,14 +185,15 @@ void AliasSet::addUnknownInst(Instruction *I, AliasAnalysis &AA) { Access = ModRefAccess; } -/// aliasesPointer - Return true if the specified pointer "may" (or must) -/// alias one of the members in the set. +/// aliasesPointer - If the specified pointer "may" (or must) alias one of the +/// members in the set return the appropriate AliasResult. Otherwise return +/// NoAlias. /// -bool AliasSet::aliasesPointer(const Value *Ptr, LocationSize Size, - const AAMDNodes &AAInfo, - AliasAnalysis &AA) const { +AliasResult AliasSet::aliasesPointer(const Value *Ptr, LocationSize Size, + const AAMDNodes &AAInfo, + AliasAnalysis &AA) const { if (AliasAny) - return true; + return MayAlias; if (Alias == SetMustAlias) { assert(UnknownInsts.empty() && "Illegal must alias set!"); @@ -208,9 +210,10 @@ bool AliasSet::aliasesPointer(const Value *Ptr, LocationSize 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(MemoryLocation(Ptr, Size, AAInfo), - MemoryLocation(I.getPointer(), I.getSize(), I.getAAInfo()))) - return true; + if (AliasResult AR = AA.alias( + MemoryLocation(Ptr, Size, AAInfo), + MemoryLocation(I.getPointer(), I.getSize(), I.getAAInfo()))) + return AR; // Check the unknown instructions... if (!UnknownInsts.empty()) { @@ -218,10 +221,10 @@ bool AliasSet::aliasesPointer(const Value *Ptr, LocationSize Size, if (auto *Inst = getUnknownInst(i)) if (isModOrRefSet( AA.getModRefInfo(Inst, MemoryLocation(Ptr, Size, AAInfo)))) - return true; + return MayAlias; } - return false; + return NoAlias; } bool AliasSet::aliasesUnknownInst(const Instruction *Inst, @@ -288,25 +291,38 @@ void AliasSetTracker::clear() { AliasSets.clear(); } - /// mergeAliasSetsForPointer - Given a pointer, merge all alias sets that may /// alias the pointer. Return the unified set, or nullptr if no set that aliases -/// the pointer was found. +/// the pointer was found. MustAliasAll is updated to true/false if the pointer +/// is found to MustAlias all the sets it merged. AliasSet *AliasSetTracker::mergeAliasSetsForPointer(const Value *Ptr, LocationSize Size, - const AAMDNodes &AAInfo) { + const AAMDNodes &AAInfo, + bool &MustAliasAll) { AliasSet *FoundSet = nullptr; + AliasResult AllAR = MustAlias; for (iterator I = begin(), E = end(); I != E;) { iterator Cur = I++; - if (Cur->Forward || !Cur->aliasesPointer(Ptr, Size, AAInfo, AA)) continue; + if (Cur->Forward) + continue; + + AliasResult AR = Cur->aliasesPointer(Ptr, Size, AAInfo, AA); + if (AR == NoAlias) + continue; + + AllAR = + AliasResult(AllAR & AR); // Possible downgrade to May/Partial, even No - if (!FoundSet) { // If this is the first alias set ptr can go into. - FoundSet = &*Cur; // Remember it. - } else { // Otherwise, we must merge the sets. - FoundSet->mergeSetIn(*Cur, *this); // Merge in contents. + if (!FoundSet) { + // If this is the first alias set ptr can go into, remember it. + FoundSet = &*Cur; + } else { + // Otherwise, we must merge the sets. + FoundSet->mergeSetIn(*Cur, *this); } } + MustAliasAll = (AllAR == MustAlias); return FoundSet; } @@ -316,10 +332,13 @@ AliasSet *AliasSetTracker::findAliasSetForUnknownInst(Instruction *Inst) { iterator Cur = I++; if (Cur->Forward || !Cur->aliasesUnknownInst(Inst, AA)) continue; - if (!FoundSet) // If this is the first alias set ptr can go into. - FoundSet = &*Cur; // Remember it. - else // Otherwise, we must merge the sets. - FoundSet->mergeSetIn(*Cur, *this); // Merge in contents. + if (!FoundSet) { + // If this is the first alias set ptr can go into, remember it. + FoundSet = &*Cur; + } else { + // Otherwise, we must merge the sets. + FoundSet->mergeSetIn(*Cur, *this); + } } return FoundSet; } @@ -329,7 +348,7 @@ AliasSet &AliasSetTracker::getAliasSetFor(const MemoryLocation &MemLoc) { Value * const Pointer = const_cast<Value*>(MemLoc.Ptr); const LocationSize Size = MemLoc.Size; const AAMDNodes &AAInfo = MemLoc.AATags; - + AliasSet::PointerRec &Entry = getEntryFor(Pointer); if (AliasAnyAS) { @@ -348,6 +367,7 @@ AliasSet &AliasSetTracker::getAliasSetFor(const MemoryLocation &MemLoc) { return *AliasAnyAS; } + bool MustAliasAll = false; // Check to see if the pointer is already known. if (Entry.hasAliasSet()) { // If the size changed, we may need to merge several alias sets. @@ -356,20 +376,21 @@ AliasSet &AliasSetTracker::getAliasSetFor(const MemoryLocation &MemLoc) { // is NoAlias, mergeAliasSetsForPointer(undef, ...) will not find the // the right set for undef, even if it exists. if (Entry.updateSizeAndAAInfo(Size, AAInfo)) - mergeAliasSetsForPointer(Pointer, Size, AAInfo); + mergeAliasSetsForPointer(Pointer, Size, AAInfo, MustAliasAll); // Return the set! return *Entry.getAliasSet(*this)->getForwardedTarget(*this); } - if (AliasSet *AS = mergeAliasSetsForPointer(Pointer, Size, AAInfo)) { + if (AliasSet *AS = + mergeAliasSetsForPointer(Pointer, Size, AAInfo, MustAliasAll)) { // Add it to the alias set it aliases. - AS->addPointer(*this, Entry, Size, AAInfo); + AS->addPointer(*this, Entry, Size, AAInfo, MustAliasAll); return *AS; } // Otherwise create a new alias set to hold the loaded pointer. AliasSets.push_back(new AliasSet()); - AliasSets.back().addPointer(*this, Entry, Size, AAInfo); + AliasSets.back().addPointer(*this, Entry, Size, AAInfo, true); return AliasSets.back(); } @@ -422,14 +443,12 @@ void AliasSetTracker::addUnknown(Instruction *Inst) { if (!Inst->mayReadOrWriteMemory()) return; // doesn't alias anything - AliasSet *AS = findAliasSetForUnknownInst(Inst); - if (AS) { + if (AliasSet *AS = findAliasSetForUnknownInst(Inst)) { AS->addUnknownInst(Inst, AA); return; } AliasSets.push_back(new AliasSet()); - AS = &AliasSets.back(); - AS->addUnknownInst(Inst, AA); + AliasSets.back().addUnknownInst(Inst, AA); } void AliasSetTracker::add(Instruction *I) { @@ -516,6 +535,15 @@ void AliasSetTracker::add(const AliasSetTracker &AST) { } } +void AliasSetTracker::addAllInstructionsInLoopUsingMSSA() { + assert(MSSA && L && "MSSA and L must be available"); + for (const BasicBlock *BB : L->blocks()) + if (auto *Accesses = MSSA->getBlockAccesses(BB)) + for (auto &Access : *Accesses) + if (auto *MUD = dyn_cast<MemoryUseOrDef>(&Access)) + add(MUD->getMemoryInst()); +} + // deleteValue method - This method is used to remove a pointer value from the // AliasSetTracker entirely. It should be used when an instruction is deleted // from the program to update the AST. If you don't use this, you would have @@ -563,9 +591,8 @@ void AliasSetTracker::copyValue(Value *From, Value *To) { I = PointerMap.find_as(From); // Add it to the alias set it aliases... AliasSet *AS = I->second->getAliasSet(*this); - AS->addPointer(*this, Entry, I->second->getSize(), - I->second->getAAInfo(), - true); + AS->addPointer(*this, Entry, I->second->getSize(), I->second->getAAInfo(), + true, true); } AliasSet &AliasSetTracker::mergeAllAliasSets() { |