summaryrefslogtreecommitdiff
path: root/llvm/lib/Transforms/IPO/AttributorAttributes.cpp
diff options
context:
space:
mode:
Diffstat (limited to 'llvm/lib/Transforms/IPO/AttributorAttributes.cpp')
-rw-r--r--llvm/lib/Transforms/IPO/AttributorAttributes.cpp34
1 files changed, 24 insertions, 10 deletions
diff --git a/llvm/lib/Transforms/IPO/AttributorAttributes.cpp b/llvm/lib/Transforms/IPO/AttributorAttributes.cpp
index 9f033028347f..5052a40efe60 100644
--- a/llvm/lib/Transforms/IPO/AttributorAttributes.cpp
+++ b/llvm/lib/Transforms/IPO/AttributorAttributes.cpp
@@ -11904,9 +11904,9 @@ struct AAUnderlyingObjectsImpl
ChangeStatus updateImpl(Attributor &A) override {
auto &Ptr = getAssociatedValue();
+ bool UsedAssumedInformation = false;
auto DoUpdate = [&](SmallSetVector<Value *, 8> &UnderlyingObjects,
AA::ValueScope Scope) {
- bool UsedAssumedInformation = false;
SmallPtrSet<Value *, 8> SeenObjects;
SmallVector<AA::ValueAndContext> Values;
@@ -11920,31 +11920,43 @@ struct AAUnderlyingObjectsImpl
auto &VAC = Values[I];
auto *Obj = VAC.getValue();
Value *UO = getUnderlyingObject(Obj);
- if (UO && UO != VAC.getValue() && SeenObjects.insert(UO).second) {
+ if (!SeenObjects.insert(UO ? UO : Obj).second)
+ continue;
+ if (UO && UO != Obj) {
+ if (isa<AllocaInst>(UO) || isa<GlobalValue>(UO)) {
+ Changed |= UnderlyingObjects.insert(UO);
+ continue;
+ }
+
const auto *OtherAA = A.getAAFor<AAUnderlyingObjects>(
*this, IRPosition::value(*UO), DepClassTy::OPTIONAL);
- auto Pred = [&Values](Value &V) {
- Values.emplace_back(V, nullptr);
+ auto Pred = [&](Value &V) {
+ if (&V == UO)
+ Changed |= UnderlyingObjects.insert(UO);
+ else
+ Values.emplace_back(V, nullptr);
return true;
};
if (!OtherAA || !OtherAA->forallUnderlyingObjects(Pred, Scope))
llvm_unreachable(
"The forall call should not return false at this position");
-
+ UsedAssumedInformation |= !OtherAA->getState().isAtFixpoint();
continue;
}
if (isa<SelectInst>(Obj)) {
- Changed |= handleIndirect(A, *Obj, UnderlyingObjects, Scope);
+ Changed |= handleIndirect(A, *Obj, UnderlyingObjects, Scope,
+ UsedAssumedInformation);
continue;
}
if (auto *PHI = dyn_cast<PHINode>(Obj)) {
// Explicitly look through PHIs as we do not care about dynamically
// uniqueness.
for (unsigned u = 0, e = PHI->getNumIncomingValues(); u < e; u++) {
- Changed |= handleIndirect(A, *PHI->getIncomingValue(u),
- UnderlyingObjects, Scope);
+ Changed |=
+ handleIndirect(A, *PHI->getIncomingValue(u), UnderlyingObjects,
+ Scope, UsedAssumedInformation);
}
continue;
}
@@ -11958,7 +11970,8 @@ struct AAUnderlyingObjectsImpl
bool Changed = false;
Changed |= DoUpdate(IntraAssumedUnderlyingObjects, AA::Intraprocedural);
Changed |= DoUpdate(InterAssumedUnderlyingObjects, AA::Interprocedural);
-
+ if (!UsedAssumedInformation)
+ indicateOptimisticFixpoint();
return Changed ? ChangeStatus::CHANGED : ChangeStatus::UNCHANGED;
}
@@ -11983,7 +11996,7 @@ private:
/// as a phi node or a select instruction.
bool handleIndirect(Attributor &A, Value &V,
SmallSetVector<Value *, 8> &UnderlyingObjects,
- AA::ValueScope Scope) {
+ AA::ValueScope Scope, bool &UsedAssumedInformation) {
bool Changed = false;
const auto *AA = A.getAAFor<AAUnderlyingObjects>(
*this, IRPosition::value(V), DepClassTy::OPTIONAL);
@@ -11994,6 +12007,7 @@ private:
if (!AA || !AA->forallUnderlyingObjects(Pred, Scope))
llvm_unreachable(
"The forall call should not return false at this position");
+ UsedAssumedInformation |= !AA->getState().isAtFixpoint();
return Changed;
}