aboutsummaryrefslogtreecommitdiff
path: root/llvm/lib/Analysis/AliasSetTracker.cpp
diff options
context:
space:
mode:
Diffstat (limited to 'llvm/lib/Analysis/AliasSetTracker.cpp')
-rw-r--r--llvm/lib/Analysis/AliasSetTracker.cpp205
1 files changed, 48 insertions, 157 deletions
diff --git a/llvm/lib/Analysis/AliasSetTracker.cpp b/llvm/lib/Analysis/AliasSetTracker.cpp
index bb25244a88dd..1c9ebadf3649 100644
--- a/llvm/lib/Analysis/AliasSetTracker.cpp
+++ b/llvm/lib/Analysis/AliasSetTracker.cpp
@@ -40,8 +40,8 @@ static cl::opt<unsigned>
"sets may contain before degradation"));
/// mergeSetIn - Merge the specified alias set into this alias set.
-///
-void AliasSet::mergeSetIn(AliasSet &AS, AliasSetTracker &AST) {
+void AliasSet::mergeSetIn(AliasSet &AS, AliasSetTracker &AST,
+ BatchAAResults &BatchAA) {
assert(!AS.Forward && "Alias set is already forwarding!");
assert(!Forward && "This set is a forwarding set!!");
@@ -54,12 +54,11 @@ void AliasSet::mergeSetIn(AliasSet &AS, AliasSetTracker &AST) {
// Check that these two merged sets really are must aliases. Since both
// used to be must-alias sets, we can just check any pointer from each set
// for aliasing.
- AliasAnalysis &AA = AST.getAliasAnalysis();
PointerRec *L = getSomePointer();
PointerRec *R = AS.getSomePointer();
// If the pointers are not a must-alias pair, this set becomes a may alias.
- if (!AA.isMustAlias(
+ if (!BatchAA.isMustAlias(
MemoryLocation(L->getValue(), L->getSize(), L->getAAInfo()),
MemoryLocation(R->getValue(), R->getSize(), R->getAAInfo())))
Alias = SetMayAlias;
@@ -133,7 +132,7 @@ void AliasSet::addPointer(AliasSetTracker &AST, PointerRec &Entry,
if (isMustAlias())
if (PointerRec *P = getSomePointer()) {
if (!KnownMustAlias) {
- AliasAnalysis &AA = AST.getAliasAnalysis();
+ BatchAAResults &AA = AST.getAliasAnalysis();
AliasResult Result = AA.alias(
MemoryLocation(P->getValue(), P->getSize(), P->getAAInfo()),
MemoryLocation(Entry.getValue(), Size, AAInfo));
@@ -162,7 +161,7 @@ void AliasSet::addPointer(AliasSetTracker &AST, PointerRec &Entry,
AST.TotalMayAliasSetSize++;
}
-void AliasSet::addUnknownInst(Instruction *I, AliasAnalysis &AA) {
+void AliasSet::addUnknownInst(Instruction *I, BatchAAResults &AA) {
if (UnknownInsts.empty())
addRef();
UnknownInsts.emplace_back(I);
@@ -189,7 +188,7 @@ void AliasSet::addUnknownInst(Instruction *I, AliasAnalysis &AA) {
///
AliasResult AliasSet::aliasesPointer(const Value *Ptr, LocationSize Size,
const AAMDNodes &AAInfo,
- AliasAnalysis &AA) const {
+ BatchAAResults &AA) const {
if (AliasAny)
return AliasResult::MayAlias;
@@ -217,41 +216,43 @@ AliasResult AliasSet::aliasesPointer(const Value *Ptr, LocationSize Size,
// Check the unknown instructions...
if (!UnknownInsts.empty()) {
- for (unsigned i = 0, e = UnknownInsts.size(); i != e; ++i)
- if (auto *Inst = getUnknownInst(i))
- if (isModOrRefSet(
- AA.getModRefInfo(Inst, MemoryLocation(Ptr, Size, AAInfo))))
- return AliasResult::MayAlias;
+ for (Instruction *Inst : UnknownInsts)
+ if (isModOrRefSet(
+ AA.getModRefInfo(Inst, MemoryLocation(Ptr, Size, AAInfo))))
+ return AliasResult::MayAlias;
}
return AliasResult::NoAlias;
}
-bool AliasSet::aliasesUnknownInst(const Instruction *Inst,
- AliasAnalysis &AA) const {
+ModRefInfo AliasSet::aliasesUnknownInst(const Instruction *Inst,
+ BatchAAResults &AA) const {
if (AliasAny)
- return true;
+ return ModRefInfo::ModRef;
if (!Inst->mayReadOrWriteMemory())
- return false;
-
- for (unsigned i = 0, e = UnknownInsts.size(); i != e; ++i) {
- if (auto *UnknownInst = getUnknownInst(i)) {
- const auto *C1 = dyn_cast<CallBase>(UnknownInst);
- const auto *C2 = dyn_cast<CallBase>(Inst);
- if (!C1 || !C2 || isModOrRefSet(AA.getModRefInfo(C1, C2)) ||
- isModOrRefSet(AA.getModRefInfo(C2, C1)))
- return true;
+ return ModRefInfo::NoModRef;
+
+ for (Instruction *UnknownInst : UnknownInsts) {
+ const auto *C1 = dyn_cast<CallBase>(UnknownInst);
+ const auto *C2 = dyn_cast<CallBase>(Inst);
+ if (!C1 || !C2 || isModOrRefSet(AA.getModRefInfo(C1, C2)) ||
+ isModOrRefSet(AA.getModRefInfo(C2, C1))) {
+ // TODO: Could be more precise, but not really useful right now.
+ return ModRefInfo::ModRef;
}
}
- for (iterator I = begin(), E = end(); I != E; ++I)
- if (isModOrRefSet(AA.getModRefInfo(
- Inst, MemoryLocation(I.getPointer(), I.getSize(), I.getAAInfo()))))
- return true;
+ ModRefInfo MR = ModRefInfo::NoModRef;
+ for (iterator I = begin(), E = end(); I != E; ++I) {
+ MR |= AA.getModRefInfo(
+ Inst, MemoryLocation(I.getPointer(), I.getSize(), I.getAAInfo()));
+ if (isModAndRefSet(MR))
+ return MR;
+ }
- return false;
+ return MR;
}
void AliasSetTracker::clear() {
@@ -291,7 +292,7 @@ AliasSet *AliasSetTracker::mergeAliasSetsForPointer(const Value *Ptr,
FoundSet = &AS;
} else {
// Otherwise, we must merge the sets.
- FoundSet->mergeSetIn(AS, *this);
+ FoundSet->mergeSetIn(AS, *this, AA);
}
}
@@ -301,14 +302,14 @@ AliasSet *AliasSetTracker::mergeAliasSetsForPointer(const Value *Ptr,
AliasSet *AliasSetTracker::findAliasSetForUnknownInst(Instruction *Inst) {
AliasSet *FoundSet = nullptr;
for (AliasSet &AS : llvm::make_early_inc_range(*this)) {
- if (AS.Forward || !AS.aliasesUnknownInst(Inst, AA))
+ if (AS.Forward || !isModOrRefSet(AS.aliasesUnknownInst(Inst, AA)))
continue;
if (!FoundSet) {
// If this is the first alias set ptr can go into, remember it.
FoundSet = &AS;
} else {
// Otherwise, we must merge the sets.
- FoundSet->mergeSetIn(AS, *this);
+ FoundSet->mergeSetIn(AS, *this, AA);
}
}
return FoundSet;
@@ -451,7 +452,7 @@ void AliasSetTracker::add(Instruction *I) {
return AliasSet::NoAccess;
};
- ModRefInfo CallMask = createModRefInfo(AA.getModRefBehavior(Call));
+ ModRefInfo CallMask = AA.getMemoryEffects(Call).getModRef();
// Some intrinsics are marked as modifying memory for control flow
// modelling purposes, but don't actually modify any specific memory
@@ -459,7 +460,7 @@ void AliasSetTracker::add(Instruction *I) {
using namespace PatternMatch;
if (Call->use_empty() &&
match(Call, m_Intrinsic<Intrinsic::invariant_start>()))
- CallMask = clearMod(CallMask);
+ CallMask &= ModRefInfo::Ref;
for (auto IdxArgPair : enumerate(Call->args())) {
int ArgIdx = IdxArgPair.index();
@@ -469,7 +470,7 @@ void AliasSetTracker::add(Instruction *I) {
MemoryLocation ArgLoc =
MemoryLocation::getForArgument(Call, ArgIdx, nullptr);
ModRefInfo ArgMask = AA.getArgModRefInfo(Call, ArgIdx);
- ArgMask = intersectModRef(CallMask, ArgMask);
+ ArgMask &= CallMask;
if (!isNoModRef(ArgMask))
addPointer(ArgLoc, getAccessFromModRef(ArgMask));
}
@@ -496,9 +497,8 @@ void AliasSetTracker::add(const AliasSetTracker &AST) {
continue; // Ignore forwarding alias sets
// If there are any call sites in the alias set, add them to this AST.
- for (unsigned i = 0, e = AS.UnknownInsts.size(); i != e; ++i)
- if (auto *Inst = AS.getUnknownInst(i))
- add(Inst);
+ for (Instruction *Inst : AS.UnknownInsts)
+ add(Inst);
// Loop over all of the pointers in this alias set.
for (AliasSet::iterator ASI = AS.begin(), E = AS.end(); ASI != E; ++ASI)
@@ -508,57 +508,6 @@ void AliasSetTracker::add(const AliasSetTracker &AST) {
}
}
-// 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
-// dangling pointers to deleted instructions.
-//
-void AliasSetTracker::deleteValue(Value *PtrVal) {
- // First, look up the PointerRec for this pointer.
- PointerMapType::iterator I = PointerMap.find_as(PtrVal);
- if (I == PointerMap.end()) return; // Noop
-
- // If we found one, remove the pointer from the alias set it is in.
- AliasSet::PointerRec *PtrValEnt = I->second;
- AliasSet *AS = PtrValEnt->getAliasSet(*this);
-
- // Unlink and delete from the list of values.
- PtrValEnt->eraseFromList();
-
- if (AS->Alias == AliasSet::SetMayAlias) {
- AS->SetSize--;
- TotalMayAliasSetSize--;
- }
-
- // Stop using the alias set.
- AS->dropRef(*this);
-
- PointerMap.erase(I);
-}
-
-// copyValue - This method should be used whenever a preexisting value in the
-// program is copied or cloned, introducing a new value. Note that it is ok for
-// clients that use this method to introduce the same value multiple times: if
-// the tracker already knows about a value, it will ignore the request.
-//
-void AliasSetTracker::copyValue(Value *From, Value *To) {
- // First, look up the PointerRec for this pointer.
- PointerMapType::iterator I = PointerMap.find_as(From);
- if (I == PointerMap.end())
- return; // Noop
- assert(I->second->hasAliasSet() && "Dead entry?");
-
- AliasSet::PointerRec &Entry = getEntryFor(To);
- if (Entry.hasAliasSet()) return; // Already in the tracker!
-
- // getEntryFor above may invalidate iterator \c I, so reinitialize it.
- 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, true);
-}
-
AliasSet &AliasSetTracker::mergeAllAliasSets() {
assert(!AliasAnyAS && (TotalMayAliasSetSize > SaturationThreshold) &&
"Full merge should happen once, when the saturation threshold is "
@@ -590,7 +539,7 @@ AliasSet &AliasSetTracker::mergeAllAliasSets() {
}
// Otherwise, perform the actual merge.
- AliasAnyAS->mergeSetIn(*Cur, *this);
+ AliasAnyAS->mergeSetIn(*Cur, *this, AA);
}
return *AliasAnyAS;
@@ -641,15 +590,14 @@ void AliasSet::print(raw_ostream &OS) const {
}
}
if (!UnknownInsts.empty()) {
+ ListSeparator LS;
OS << "\n " << UnknownInsts.size() << " Unknown instructions: ";
- for (unsigned i = 0, e = UnknownInsts.size(); i != e; ++i) {
- if (i) OS << ", ";
- if (auto *I = getUnknownInst(i)) {
- if (I->hasName())
- I->printAsOperand(OS);
- else
- I->print(OS);
- }
+ for (Instruction *I : UnknownInsts) {
+ OS << LS;
+ if (I->hasName())
+ I->printAsOperand(OS);
+ else
+ I->print(OS);
}
}
OS << "\n";
@@ -671,73 +619,16 @@ LLVM_DUMP_METHOD void AliasSetTracker::dump() const { print(dbgs()); }
#endif
//===----------------------------------------------------------------------===//
-// ASTCallbackVH Class Implementation
-//===----------------------------------------------------------------------===//
-
-void AliasSetTracker::ASTCallbackVH::deleted() {
- assert(AST && "ASTCallbackVH called with a null AliasSetTracker!");
- AST->deleteValue(getValPtr());
- // this now dangles!
-}
-
-void AliasSetTracker::ASTCallbackVH::allUsesReplacedWith(Value *V) {
- AST->copyValue(getValPtr(), V);
-}
-
-AliasSetTracker::ASTCallbackVH::ASTCallbackVH(Value *V, AliasSetTracker *ast)
- : CallbackVH(V), AST(ast) {}
-
-AliasSetTracker::ASTCallbackVH &
-AliasSetTracker::ASTCallbackVH::operator=(Value *V) {
- return *this = ASTCallbackVH(V, AST);
-}
-
-//===----------------------------------------------------------------------===//
// AliasSetPrinter Pass
//===----------------------------------------------------------------------===//
-namespace {
-
- class AliasSetPrinter : public FunctionPass {
- public:
- static char ID; // Pass identification, replacement for typeid
-
- AliasSetPrinter() : FunctionPass(ID) {
- initializeAliasSetPrinterPass(*PassRegistry::getPassRegistry());
- }
-
- void getAnalysisUsage(AnalysisUsage &AU) const override {
- AU.setPreservesAll();
- AU.addRequired<AAResultsWrapperPass>();
- }
-
- bool runOnFunction(Function &F) override {
- auto &AAWP = getAnalysis<AAResultsWrapperPass>();
- AliasSetTracker Tracker(AAWP.getAAResults());
- errs() << "Alias sets for function '" << F.getName() << "':\n";
- for (Instruction &I : instructions(F))
- Tracker.add(&I);
- Tracker.print(errs());
- return false;
- }
- };
-
-} // end anonymous namespace
-
-char AliasSetPrinter::ID = 0;
-
-INITIALIZE_PASS_BEGIN(AliasSetPrinter, "print-alias-sets",
- "Alias Set Printer", false, true)
-INITIALIZE_PASS_DEPENDENCY(AAResultsWrapperPass)
-INITIALIZE_PASS_END(AliasSetPrinter, "print-alias-sets",
- "Alias Set Printer", false, true)
-
AliasSetsPrinterPass::AliasSetsPrinterPass(raw_ostream &OS) : OS(OS) {}
PreservedAnalyses AliasSetsPrinterPass::run(Function &F,
FunctionAnalysisManager &AM) {
auto &AA = AM.getResult<AAManager>(F);
- AliasSetTracker Tracker(AA);
+ BatchAAResults BatchAA(AA);
+ AliasSetTracker Tracker(BatchAA);
OS << "Alias sets for function '" << F.getName() << "':\n";
for (Instruction &I : instructions(F))
Tracker.add(&I);