diff --git a/llvm/include/llvm/Transforms/IPO/Attributor.h b/llvm/include/llvm/Transforms/IPO/Attributor.h --- a/llvm/include/llvm/Transforms/IPO/Attributor.h +++ b/llvm/include/llvm/Transforms/IPO/Attributor.h @@ -1294,9 +1294,6 @@ /// Return true if we assume that the underlying value is nonnull. virtual bool isAssumedNonNull() const = 0; - /// Return true if we know that underlying value is nonnull. - virtual bool isKnownNonNull() const = 0; - /// Return true if we assume that underlying value is /// dereferenceable(_or_null) globally. virtual bool isAssumedGlobal() const = 0; diff --git a/llvm/lib/Transforms/IPO/Attributor.cpp b/llvm/lib/Transforms/IPO/Attributor.cpp --- a/llvm/lib/Transforms/IPO/Attributor.cpp +++ b/llvm/lib/Transforms/IPO/Attributor.cpp @@ -1584,35 +1584,29 @@ /// State representing for dereferenceable bytes. IntegerState DerefBytesState; - /// State representing that whether the value is nonnull or global. - IntegerState NonNullGlobalState; - - /// Bits encoding for NonNullGlobalState. - enum { - DEREF_NONNULL = 1 << 0, - DEREF_GLOBAL = 1 << 1, - }; + /// State representing that whether the value is globaly dereferenceable. + BooleanState GlobalState; /// See AbstractState::isValidState() bool isValidState() const override { return DerefBytesState.isValidState(); } /// See AbstractState::isAtFixpoint() bool isAtFixpoint() const override { - return !isValidState() || (DerefBytesState.isAtFixpoint() && - NonNullGlobalState.isAtFixpoint()); + return !isValidState() || + (DerefBytesState.isAtFixpoint() && GlobalState.isAtFixpoint()); } /// See AbstractState::indicateOptimisticFixpoint(...) ChangeStatus indicateOptimisticFixpoint() override { DerefBytesState.indicateOptimisticFixpoint(); - NonNullGlobalState.indicateOptimisticFixpoint(); + GlobalState.indicateOptimisticFixpoint(); return ChangeStatus::UNCHANGED; } /// See AbstractState::indicatePessimisticFixpoint(...) ChangeStatus indicatePessimisticFixpoint() override { DerefBytesState.indicatePessimisticFixpoint(); - NonNullGlobalState.indicatePessimisticFixpoint(); + GlobalState.indicatePessimisticFixpoint(); return ChangeStatus::CHANGED; } @@ -1626,18 +1620,10 @@ DerefBytesState.takeAssumedMinimum(Bytes); } - /// Update assumed NonNullGlobalState - void updateAssumedNonNullGlobalState(bool IsNonNull, bool IsGlobal) { - if (!IsNonNull) - NonNullGlobalState.removeAssumedBits(DEREF_NONNULL); - if (!IsGlobal) - NonNullGlobalState.removeAssumedBits(DEREF_GLOBAL); - } - /// Equality for DerefState. bool operator==(const DerefState &R) { return this->DerefBytesState == R.DerefBytesState && - this->NonNullGlobalState == R.NonNullGlobalState; + this->GlobalState == R.GlobalState; } }; @@ -1645,6 +1631,16 @@ AADereferenceableImpl(const IRPosition &IRP) : AADereferenceable(IRP) {} using StateType = DerefState; + void initialize(Attributor &A) override { + SmallVector Attrs; + getAttrs({Attribute::Dereferenceable, Attribute::DereferenceableOrNull}, + Attrs); + for (const Attribute &Attr : Attrs) + takeKnownDerefBytesMaximum(Attr.getValueAsInt()); + + NonNullAA = A.getAAFor(*this, getIRPosition()); + } + /// See AbstractAttribute::getState() /// { StateType &getState() override { return *this; } @@ -1661,38 +1657,14 @@ return DerefBytesState.getKnown(); } - // Helper function for syncing nonnull state. - void syncNonNull(const AANonNull *NonNullAA) { - if (!NonNullAA) { - NonNullGlobalState.removeAssumedBits(DEREF_NONNULL); - return; - } - - if (NonNullAA->isKnownNonNull()) - NonNullGlobalState.addKnownBits(DEREF_NONNULL); - - if (!NonNullAA->isAssumedNonNull()) - NonNullGlobalState.removeAssumedBits(DEREF_NONNULL); - } - /// See AADereferenceable::isAssumedGlobal(). - bool isAssumedGlobal() const override { - return NonNullGlobalState.isAssumed(DEREF_GLOBAL); - } + bool isAssumedGlobal() const override { return GlobalState.getAssumed(); } /// See AADereferenceable::isKnownGlobal(). - bool isKnownGlobal() const override { - return NonNullGlobalState.isKnown(DEREF_GLOBAL); - } + bool isKnownGlobal() const override { return GlobalState.getKnown(); } - /// See AADereferenceable::isAssumedNonNull(). bool isAssumedNonNull() const override { - return NonNullGlobalState.isAssumed(DEREF_NONNULL); - } - - /// See AADereferenceable::isKnownNonNull(). - bool isKnownNonNull() const override { - return NonNullGlobalState.isKnown(DEREF_NONNULL); + return NonNullAA && NonNullAA->isAssumedNonNull(); } void getDeducedAttributes(LLVMContext &Ctx, @@ -1706,15 +1678,7 @@ Ctx, getAssumedDereferenceableBytes())); } uint64_t computeAssumedDerefenceableBytes(Attributor &A, Value &V, - bool &IsNonNull, bool &IsGlobal); - - void initialize(Attributor &A) override { - SmallVector Attrs; - getAttrs({Attribute::Dereferenceable, Attribute::DereferenceableOrNull}, - Attrs); - for (const Attribute &Attr : Attrs) - takeKnownDerefBytesMaximum(Attr.getValueAsInt()); - } + bool &IsGlobal); /// See AbstractAttribute::getAsStr(). const std::string getAsStr() const override { @@ -1726,6 +1690,9 @@ std::to_string(getKnownDereferenceableBytes()) + "-" + std::to_string(getAssumedDereferenceableBytes()) + ">"; } + +private: + const AANonNull *NonNullAA = nullptr; }; struct AADereferenceableReturned final : AADereferenceableImpl { @@ -1749,15 +1716,15 @@ return std::max((int64_t)0, DerefBytes - Offset); } -uint64_t AADereferenceableImpl::computeAssumedDerefenceableBytes( - Attributor &A, Value &V, bool &IsNonNull, bool &IsGlobal) { +uint64_t +AADereferenceableImpl::computeAssumedDerefenceableBytes(Attributor &A, Value &V, + bool &IsGlobal) { // TODO: Tracking the globally flag. IsGlobal = false; // First, we try to get information about V from Attributor. if (auto *DerefAA = A.getAAFor(*this, IRPosition::value(V))) { - IsNonNull &= DerefAA->isAssumedNonNull(); return DerefAA->getAssumedDereferenceableBytes(); } @@ -1770,7 +1737,6 @@ if (auto *BaseDerefAA = A.getAAFor(*this, IRPosition::value(*Base))) { - IsNonNull &= Offset != 0; return calcDifferenceIfBaseIsNonNull( BaseDerefAA->getAssumedDereferenceableBytes(), Offset.getSExtValue(), Offset != 0 || BaseDerefAA->isAssumedNonNull()); @@ -1785,26 +1751,22 @@ !NullPointerIsDefined(getAnchorScope(), V.getType()->getPointerAddressSpace())); - IsNonNull = false; return 0; } ChangeStatus AADereferenceableReturned::updateImpl(Attributor &A) { auto BeforeState = static_cast(*this); - syncNonNull(A.getAAFor(*this, getIRPosition())); - - bool IsNonNull = isAssumedNonNull(); bool IsGlobal = isAssumedGlobal(); auto CheckReturnValue = [&](Value &RV) -> bool { takeAssumedDerefBytesMinimum( - computeAssumedDerefenceableBytes(A, RV, IsNonNull, IsGlobal)); + computeAssumedDerefenceableBytes(A, RV, IsGlobal)); return isValidState(); }; if (A.checkForAllReturnedValues(CheckReturnValue, *this)) { - updateAssumedNonNullGlobalState(IsNonNull, IsGlobal); + GlobalState.takeAssumedMinimum(IsGlobal); return BeforeState == static_cast(*this) ? ChangeStatus::UNCHANGED : ChangeStatus::CHANGED; @@ -1832,9 +1794,6 @@ unsigned ArgNo = Arg.getArgNo(); - syncNonNull(A.getAAFor(*this, getIRPosition())); - - bool IsNonNull = isAssumedNonNull(); bool IsGlobal = isAssumedGlobal(); // Callback function @@ -1849,14 +1808,13 @@ if (ICS && CS.getInstruction() == ICS.getInstruction()) { takeAssumedDerefBytesMinimum( DereferenceableAA->getAssumedDereferenceableBytes()); - IsNonNull &= DereferenceableAA->isAssumedNonNull(); IsGlobal &= DereferenceableAA->isAssumedGlobal(); return isValidState(); } } takeAssumedDerefBytesMinimum(computeAssumedDerefenceableBytes( - A, *CS.getArgOperand(ArgNo), IsNonNull, IsGlobal)); + A, *CS.getArgOperand(ArgNo), IsGlobal)); return isValidState(); }; @@ -1864,7 +1822,7 @@ if (!A.checkForAllCallSites(CallSiteCheck, *this, true)) return indicatePessimisticFixpoint(); - updateAssumedNonNullGlobalState(IsNonNull, IsGlobal); + GlobalState.takeAssumedMinimum(IsGlobal); return BeforeState == static_cast(*this) ? ChangeStatus::UNCHANGED : ChangeStatus::CHANGED; @@ -1893,13 +1851,11 @@ auto BeforeState = static_cast(*this); - syncNonNull(A.getAAFor(*this, getIRPosition())); - bool IsNonNull = isAssumedNonNull(); - bool IsGlobal = isKnownGlobal(); + bool IsGlobal = isAssumedGlobal(); takeAssumedDerefBytesMinimum( - computeAssumedDerefenceableBytes(A, V, IsNonNull, IsGlobal)); - updateAssumedNonNullGlobalState(IsNonNull, IsGlobal); + computeAssumedDerefenceableBytes(A, V, IsGlobal)); + GlobalState.takeAssumedMinimum(IsGlobal); return BeforeState == static_cast(*this) ? ChangeStatus::UNCHANGED : ChangeStatus::CHANGED;