[llvm] [IPO] Added attributor for identifying invariant loads (PR #141800)
Shilei Tian via llvm-commits
llvm-commits at lists.llvm.org
Wed May 28 10:07:18 PDT 2025
================
@@ -12534,6 +12535,248 @@ struct AAIndirectCallInfoCallSite : public AAIndirectCallInfo {
};
} // namespace
+/// --------------------- Invariant Load Pointer -------------------------------
+namespace {
+
+struct AAInvariantLoadPointerImpl
+ : public StateWrapper<BitIntegerState<uint8_t, 7>, AAInvariantLoadPointer,
+ uint8_t> {
+ // load invariance is implied by, but not equivalent to IS_NOALIAS |
+ // IS_READONLY, as load invariance is also implied by all underlying objects
+ // being load invariant.
+ //
+ // IS_INVARIANT is set to indicate that the contents of the pointer are
+ // *known* to be invariant.
+ enum {
+ IS_INVARIANT = 1 << 0,
+ IS_NOALIAS = 1 << 1,
+ IS_READONLY = 1 << 2,
+ };
+ static_assert(getBestState() == (IS_INVARIANT | IS_NOALIAS | IS_READONLY),
+ "Unexpected best state!");
+
+ using Base = StateWrapper<BitIntegerState<uint8_t, 7>, AAInvariantLoadPointer,
+ uint8_t>;
+
+ // the BitIntegerState is optimistic about noalias and readonly, but
+ // pessimistic about invariance
+ AAInvariantLoadPointerImpl(const IRPosition &IRP, Attributor &A)
+ : Base(IRP, IS_NOALIAS | IS_READONLY) {}
+
+ void initialize(Attributor &A) final {
+ // conservatively assume that the pointer's contents are not invariant,
+ // until proven otherwise.
+ removeAssumedBits(IS_INVARIANT);
+ }
+
+ bool isKnownInvariant() const final {
+ return isKnown(IS_INVARIANT) || isKnown(IS_NOALIAS | IS_READONLY);
+ }
+
+ bool isAssumedInvariant() const final {
+ return isAssumed(IS_INVARIANT) || isAssumed(IS_NOALIAS | IS_READONLY);
+ }
+
+ ChangeStatus updateImpl(Attributor &A) override {
+ if (isKnownInvariant())
+ return ChangeStatus::UNCHANGED;
+
+ ChangeStatus Changed = ChangeStatus::UNCHANGED;
+
+ Changed |= updateNoAlias(A);
+ Changed |= updateReadOnly(A);
+
+ bool UsedAssumedInformation = false;
+ const auto IsInvariantLoadIfPointer = [&](const Value &V) {
+ if (!V.getType()->isPointerTy())
+ return true;
+ const auto *IsInvariantLoadPointer =
+ A.getOrCreateAAFor<AAInvariantLoadPointer>(IRPosition::value(V), this,
+ DepClassTy::REQUIRED);
+ if (IsInvariantLoadPointer->isKnownInvariant())
+ return true;
+ if (!IsInvariantLoadPointer->isAssumedInvariant())
+ return false;
+
+ UsedAssumedInformation = true;
+ return true;
+ };
+
+ const auto *AUO = A.getOrCreateAAFor<AAUnderlyingObjects>(
+ getIRPosition(), this, DepClassTy::REQUIRED);
+
+ if (!AUO->forallUnderlyingObjects(IsInvariantLoadIfPointer)) {
+ removeAssumedBits(IS_INVARIANT);
+ return ChangeStatus::CHANGED;
----------------
shiltian wrote:
directly indicate pessimistic state here
https://github.com/llvm/llvm-project/pull/141800
More information about the llvm-commits
mailing list