aboutsummaryrefslogtreecommitdiff
path: root/lib/Analysis/AliasSetTracker.cpp
diff options
context:
space:
mode:
Diffstat (limited to 'lib/Analysis/AliasSetTracker.cpp')
-rw-r--r--lib/Analysis/AliasSetTracker.cpp131
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() {