aboutsummaryrefslogtreecommitdiff
path: root/llvm/lib/Analysis/AliasSetTracker.cpp
diff options
context:
space:
mode:
authorDavid Majnemer <david.majnemer@gmail.com>2014-11-19 09:41:05 +0000
committerDavid Majnemer <david.majnemer@gmail.com>2014-11-19 09:41:05 +0000
commitb7adf34ee064057d21de889445502ae01106f797 (patch)
treee164d8dc0c26655cb08bf0c253aba064cf46459a /llvm/lib/Analysis/AliasSetTracker.cpp
parentec66d00933cd406463266d9cc240f7ed00038606 (diff)
downloadllvm-b7adf34ee064057d21de889445502ae01106f797.zip
llvm-b7adf34ee064057d21de889445502ae01106f797.tar.gz
llvm-b7adf34ee064057d21de889445502ae01106f797.tar.bz2
AliasSetTracker: UnknownInsts should contribute to the refcount
AliasSetTracker::addUnknown may create an AliasSet devoid of pointers just to contain an instruction if no suitable AliasSet already exists. It will then AliasSet::addUnknownInst and we will be done. However, it's possible for addUnknown to choose an existing AliasSet to addUnknownInst. If this were to occur, we are in a bit of a pickle: removing pointers from the AliasSet can cause the entire AliasSet to become destroyed, taking our unknown instructions out with them. Instead, keep track whether or not our AliasSet has any unknown instructions. This fixes PR21582. llvm-svn: 222338
Diffstat (limited to 'llvm/lib/Analysis/AliasSetTracker.cpp')
-rw-r--r--llvm/lib/Analysis/AliasSetTracker.cpp41
1 files changed, 26 insertions, 15 deletions
diff --git a/llvm/lib/Analysis/AliasSetTracker.cpp b/llvm/lib/Analysis/AliasSetTracker.cpp
index 9d941e5..5b85f65 100644
--- a/llvm/lib/Analysis/AliasSetTracker.cpp
+++ b/llvm/lib/Analysis/AliasSetTracker.cpp
@@ -55,12 +55,16 @@ void AliasSet::mergeSetIn(AliasSet &AS, AliasSetTracker &AST) {
AliasTy = MayAlias;
}
+ bool ASHadUnknownInsts = false;
if (UnknownInsts.empty()) { // Merge call sites...
- if (!AS.UnknownInsts.empty())
+ if (!AS.UnknownInsts.empty()) {
std::swap(UnknownInsts, AS.UnknownInsts);
+ addRef();
+ }
} else if (!AS.UnknownInsts.empty()) {
UnknownInsts.insert(UnknownInsts.end(), AS.UnknownInsts.begin(), AS.UnknownInsts.end());
AS.UnknownInsts.clear();
+ ASHadUnknownInsts = true;
}
AS.Forward = this; // Forward across AS now...
@@ -76,6 +80,8 @@ void AliasSet::mergeSetIn(AliasSet &AS, AliasSetTracker &AST) {
AS.PtrListEnd = &AS.PtrList;
assert(*AS.PtrListEnd == nullptr && "End of list is not null?");
}
+ if (ASHadUnknownInsts)
+ AS.dropRef(AST);
}
void AliasSetTracker::removeAliasSet(AliasSet *AS) {
@@ -123,6 +129,8 @@ void AliasSet::addPointer(AliasSetTracker &AST, PointerRec &Entry,
}
void AliasSet::addUnknownInst(Instruction *I, AliasAnalysis &AA) {
+ if (UnknownInsts.empty())
+ addRef();
UnknownInsts.push_back(I);
if (!I->mayWriteToMemory()) {
@@ -218,13 +226,14 @@ AliasSet *AliasSetTracker::findAliasSetForPointer(const Value *Ptr,
uint64_t Size,
const AAMDNodes &AAInfo) {
AliasSet *FoundSet = nullptr;
- for (iterator I = begin(), E = end(); I != E; ++I) {
- if (I->Forward || !I->aliasesPointer(Ptr, Size, AAInfo, AA)) continue;
+ for (iterator I = begin(), E = end(); I != E;) {
+ iterator Cur = I++;
+ if (Cur->Forward || !Cur->aliasesPointer(Ptr, Size, AAInfo, AA)) continue;
if (!FoundSet) { // If this is the first alias set ptr can go into.
- FoundSet = I; // Remember it.
+ FoundSet = Cur; // Remember it.
} else { // Otherwise, we must merge the sets.
- FoundSet->mergeSetIn(*I, *this); // Merge in contents.
+ FoundSet->mergeSetIn(*Cur, *this); // Merge in contents.
}
}
@@ -251,14 +260,14 @@ bool AliasSetTracker::containsUnknown(Instruction *Inst) const {
AliasSet *AliasSetTracker::findAliasSetForUnknownInst(Instruction *Inst) {
AliasSet *FoundSet = nullptr;
- for (iterator I = begin(), E = end(); I != E; ++I) {
- if (I->Forward || !I->aliasesUnknownInst(Inst, AA))
+ for (iterator I = begin(), E = end(); I != E;) {
+ 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 = I; // Remember it.
- else if (!I->Forward) // Otherwise, we must merge the sets.
- FoundSet->mergeSetIn(*I, *this); // Merge in contents.
+ FoundSet = Cur; // Remember it.
+ else if (!Cur->Forward) // Otherwise, we must merge the sets.
+ FoundSet->mergeSetIn(*Cur, *this); // Merge in contents.
}
return FoundSet;
}
@@ -406,6 +415,8 @@ void AliasSetTracker::add(const AliasSetTracker &AST) {
/// tracker.
void AliasSetTracker::remove(AliasSet &AS) {
// Drop all call sites.
+ if (!AS.UnknownInsts.empty())
+ AS.dropRef(*this);
AS.UnknownInsts.clear();
// Clear the alias set.
@@ -510,10 +521,10 @@ void AliasSetTracker::deleteValue(Value *PtrVal) {
if (Instruction *Inst = dyn_cast<Instruction>(PtrVal)) {
if (Inst->mayReadOrWriteMemory()) {
// Scan all the alias sets to see if this call site is contained.
- for (iterator I = begin(), E = end(); I != E; ++I) {
- if (I->Forward) continue;
-
- I->removeUnknownInst(Inst);
+ for (iterator I = begin(), E = end(); I != E;) {
+ iterator Cur = I++;
+ if (!Cur->Forward)
+ Cur->removeUnknownInst(*this, Inst);
}
}
}