[llvm] d70ab63 - [Attributor][NFCI] Filter uninteresting accesses early
Johannes Doerfert via llvm-commits
llvm-commits at lists.llvm.org
Fri Aug 4 11:37:17 PDT 2023
Author: Johannes Doerfert
Date: 2023-08-04T11:36:58-07:00
New Revision: d70ab63bc2762ffb4757676f1cd73fd0bdd2bcce
URL: https://github.com/llvm/llvm-project/commit/d70ab63bc2762ffb4757676f1cd73fd0bdd2bcce
DIFF: https://github.com/llvm/llvm-project/commit/d70ab63bc2762ffb4757676f1cd73fd0bdd2bcce.diff
LOG: [Attributor][NFCI] Filter uninteresting accesses early
We can prevent the costly interference check if an access is not
interesting in the first place. Let the user decide via a callback.
Added:
Modified:
llvm/include/llvm/Transforms/IPO/Attributor.h
llvm/lib/Transforms/IPO/Attributor.cpp
llvm/lib/Transforms/IPO/AttributorAttributes.cpp
Removed:
################################################################################
diff --git a/llvm/include/llvm/Transforms/IPO/Attributor.h b/llvm/include/llvm/Transforms/IPO/Attributor.h
index 2ea223482c6015..675221576fb680 100644
--- a/llvm/include/llvm/Transforms/IPO/Attributor.h
+++ b/llvm/include/llvm/Transforms/IPO/Attributor.h
@@ -5952,12 +5952,15 @@ struct AAPointerInfo : public AbstractAttribute {
/// this function will perform reasoning to exclude write accesses that cannot
/// affect the load even if they on the surface look as if they would. The
/// flag \p HasBeenWrittenTo will be set to true if we know that \p I does not
- /// read the intial value of the underlying memory.
+ /// read the initial value of the underlying memory. If \p SkipCB is given and
+ /// returns false for a potentially interfering access, that access is not
+ /// checked for actual interference.
virtual bool forallInterferingAccesses(
Attributor &A, const AbstractAttribute &QueryingAA, Instruction &I,
bool FindInterferingWrites, bool FindInterferingReads,
function_ref<bool(const Access &, bool)> CB, bool &HasBeenWrittenTo,
- AA::RangeTy &Range) const = 0;
+ AA::RangeTy &Range,
+ function_ref<bool(const Access &)> SkipCB = nullptr) const = 0;
/// This function should return true if the type of the \p AA is AAPointerInfo
static bool classof(const AbstractAttribute *AA) {
diff --git a/llvm/lib/Transforms/IPO/Attributor.cpp b/llvm/lib/Transforms/IPO/Attributor.cpp
index fe82506d0e4a42..3b6ca60f0f9970 100644
--- a/llvm/lib/Transforms/IPO/Attributor.cpp
+++ b/llvm/lib/Transforms/IPO/Attributor.cpp
@@ -350,7 +350,7 @@ AA::combineOptionalValuesInAAValueLatice(const std::optional<Value *> &A,
template <bool IsLoad, typename Ty>
static bool getPotentialCopiesOfMemoryValue(
Attributor &A, Ty &I, SmallSetVector<Value *, 4> &PotentialCopies,
- SmallSetVector<Instruction *, 4> &PotentialValueOrigins,
+ SmallSetVector<Instruction *, 4> *PotentialValueOrigins,
const AbstractAttribute &QueryingAA, bool &UsedAssumedInformation,
bool OnlyExact) {
LLVM_DEBUG(dbgs() << "Trying to determine the potential copies of " << I
@@ -361,8 +361,8 @@ static bool getPotentialCopiesOfMemoryValue(
// sure that we can find all of them. If we abort we want to avoid spurious
// dependences and potential copies in the provided container.
SmallVector<const AAPointerInfo *> PIs;
- SmallVector<Value *> NewCopies;
- SmallVector<Instruction *> NewCopyOrigins;
+ SmallSetVector<Value *, 8> NewCopies;
+ SmallSetVector<Instruction *, 8> NewCopyOrigins;
const auto *TLI =
A.getInfoCache().getTargetLibraryInfoForFunction(*I.getFunction());
@@ -425,6 +425,30 @@ static bool getPotentialCopiesOfMemoryValue(
return AdjV;
};
+ auto SkipCB = [&](const AAPointerInfo::Access &Acc) {
+ if ((IsLoad && !Acc.isWriteOrAssumption()) || (!IsLoad && !Acc.isRead()))
+ return true;
+ if (IsLoad) {
+ if (Acc.isWrittenValueYetUndetermined())
+ return true;
+ if (PotentialValueOrigins && !isa<AssumeInst>(Acc.getRemoteInst()))
+ return false;
+ if (!Acc.isWrittenValueUnknown())
+ if (Value *V = AdjustWrittenValueType(Acc, *Acc.getWrittenValue()))
+ if (NewCopies.count(V)) {
+ NewCopyOrigins.insert(Acc.getRemoteInst());
+ return true;
+ }
+ if (auto *SI = dyn_cast<StoreInst>(Acc.getRemoteInst()))
+ if (Value *V = AdjustWrittenValueType(Acc, *SI->getValueOperand()))
+ if (NewCopies.count(V)) {
+ NewCopyOrigins.insert(Acc.getRemoteInst());
+ return true;
+ }
+ }
+ return false;
+ };
+
auto CheckAccess = [&](const AAPointerInfo::Access &Acc, bool IsExact) {
if ((IsLoad && !Acc.isWriteOrAssumption()) || (!IsLoad && !Acc.isRead()))
return true;
@@ -449,8 +473,9 @@ static bool getPotentialCopiesOfMemoryValue(
Value *V = AdjustWrittenValueType(Acc, *Acc.getWrittenValue());
if (!V)
return false;
- NewCopies.push_back(V);
- NewCopyOrigins.push_back(Acc.getRemoteInst());
+ NewCopies.insert(V);
+ if (PotentialValueOrigins)
+ NewCopyOrigins.insert(Acc.getRemoteInst());
return true;
}
auto *SI = dyn_cast<StoreInst>(Acc.getRemoteInst());
@@ -463,8 +488,9 @@ static bool getPotentialCopiesOfMemoryValue(
Value *V = AdjustWrittenValueType(Acc, *SI->getValueOperand());
if (!V)
return false;
- NewCopies.push_back(V);
- NewCopyOrigins.push_back(SI);
+ NewCopies.insert(V);
+ if (PotentialValueOrigins)
+ NewCopyOrigins.insert(SI);
} else {
assert(isa<StoreInst>(I) && "Expected load or store instruction only!");
auto *LI = dyn_cast<LoadInst>(Acc.getRemoteInst());
@@ -474,7 +500,7 @@ static bool getPotentialCopiesOfMemoryValue(
<< *Acc.getRemoteInst() << "\n";);
return false;
}
- NewCopies.push_back(Acc.getRemoteInst());
+ NewCopies.insert(Acc.getRemoteInst());
}
return true;
};
@@ -486,11 +512,11 @@ static bool getPotentialCopiesOfMemoryValue(
AA::RangeTy Range;
auto *PI = A.getAAFor<AAPointerInfo>(QueryingAA, IRPosition::value(Obj),
DepClassTy::NONE);
- if (!PI ||
- !PI->forallInterferingAccesses(A, QueryingAA, I,
- /* FindInterferingWrites */ IsLoad,
- /* FindInterferingReads */ !IsLoad,
- CheckAccess, HasBeenWrittenTo, Range)) {
+ if (!PI || !PI->forallInterferingAccesses(
+ A, QueryingAA, I,
+ /* FindInterferingWrites */ IsLoad,
+ /* FindInterferingReads */ !IsLoad, CheckAccess,
+ HasBeenWrittenTo, Range, SkipCB)) {
LLVM_DEBUG(
dbgs()
<< "Failed to verify all interfering accesses for underlying object: "
@@ -514,8 +540,9 @@ static bool getPotentialCopiesOfMemoryValue(
return false;
}
- NewCopies.push_back(InitialValue);
- NewCopyOrigins.push_back(nullptr);
+ NewCopies.insert(InitialValue);
+ if (PotentialValueOrigins)
+ NewCopyOrigins.insert(nullptr);
}
PIs.push_back(PI);
@@ -540,7 +567,8 @@ static bool getPotentialCopiesOfMemoryValue(
A.recordDependence(*PI, QueryingAA, DepClassTy::OPTIONAL);
}
PotentialCopies.insert(NewCopies.begin(), NewCopies.end());
- PotentialValueOrigins.insert(NewCopyOrigins.begin(), NewCopyOrigins.end());
+ if (PotentialValueOrigins)
+ PotentialValueOrigins->insert(NewCopyOrigins.begin(), NewCopyOrigins.end());
return true;
}
@@ -551,7 +579,7 @@ bool AA::getPotentiallyLoadedValues(
const AbstractAttribute &QueryingAA, bool &UsedAssumedInformation,
bool OnlyExact) {
return getPotentialCopiesOfMemoryValue</* IsLoad */ true>(
- A, LI, PotentialValues, PotentialValueOrigins, QueryingAA,
+ A, LI, PotentialValues, &PotentialValueOrigins, QueryingAA,
UsedAssumedInformation, OnlyExact);
}
@@ -559,10 +587,9 @@ bool AA::getPotentialCopiesOfStoredValue(
Attributor &A, StoreInst &SI, SmallSetVector<Value *, 4> &PotentialCopies,
const AbstractAttribute &QueryingAA, bool &UsedAssumedInformation,
bool OnlyExact) {
- SmallSetVector<Instruction *, 4> PotentialValueOrigins;
return getPotentialCopiesOfMemoryValue</* IsLoad */ false>(
- A, SI, PotentialCopies, PotentialValueOrigins, QueryingAA,
- UsedAssumedInformation, OnlyExact);
+ A, SI, PotentialCopies, nullptr, QueryingAA, UsedAssumedInformation,
+ OnlyExact);
}
static bool isAssumedReadOnlyOrReadNone(Attributor &A, const IRPosition &IRP,
diff --git a/llvm/lib/Transforms/IPO/AttributorAttributes.cpp b/llvm/lib/Transforms/IPO/AttributorAttributes.cpp
index 15dada6f854bde..c5259c1e312ae0 100644
--- a/llvm/lib/Transforms/IPO/AttributorAttributes.cpp
+++ b/llvm/lib/Transforms/IPO/AttributorAttributes.cpp
@@ -1103,7 +1103,8 @@ struct AAPointerInfoImpl
Attributor &A, const AbstractAttribute &QueryingAA, Instruction &I,
bool FindInterferingWrites, bool FindInterferingReads,
function_ref<bool(const Access &, bool)> UserCB, bool &HasBeenWrittenTo,
- AA::RangeTy &Range) const override {
+ AA::RangeTy &Range,
+ function_ref<bool(const Access &)> SkipCB) const override {
HasBeenWrittenTo = false;
SmallPtrSet<const Access *, 8> DominatingWrites;
@@ -1275,6 +1276,8 @@ struct AAPointerInfoImpl
// Helper to determine if we can skip a specific write access.
auto CanSkipAccess = [&](const Access &Acc, bool Exact) {
+ if (SkipCB && SkipCB(Acc))
+ return true;
if (!CanIgnoreThreading(Acc))
return false;
More information about the llvm-commits
mailing list