From: Johannes Doerfert Date: Wed, 14 Aug 2019 21:31:32 +0000 (+0000) Subject: [Attributor] Use the AANoNull attribute directly in AADereferenceable X-Git-Url: https://granicus.if.org/sourcecode?a=commitdiff_plain;h=8e521dae89ed0672f965d7c148d4ecc529616734;p=llvm [Attributor] Use the AANoNull attribute directly in AADereferenceable Summary: Instead of constantly keeping track of the nonnull status with the dereferenceable information we can simply query the nonnull attribute whenever we need the information (debug + manifest). Reviewers: sstefan1, uenoku Subscribers: hiraditya, bollu, jfb, llvm-commits Tags: #llvm Differential Revision: https://reviews.llvm.org/D66113 git-svn-id: https://llvm.org/svn/llvm-project/llvm/trunk@368924 91177308-0d34-0410-b5e6-96231b3b80d8 --- diff --git a/include/llvm/Transforms/IPO/Attributor.h b/include/llvm/Transforms/IPO/Attributor.h index a7985642509..ed3e572d953 100644 --- a/include/llvm/Transforms/IPO/Attributor.h +++ b/include/llvm/Transforms/IPO/Attributor.h @@ -1297,9 +1297,6 @@ struct AADereferenceable /// 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/lib/Transforms/IPO/Attributor.cpp b/lib/Transforms/IPO/Attributor.cpp index 32bc88efe1e..b5d80dc99b2 100644 --- a/lib/Transforms/IPO/Attributor.cpp +++ b/lib/Transforms/IPO/Attributor.cpp @@ -1609,35 +1609,29 @@ struct DerefState : AbstractState { /// 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; } @@ -1651,18 +1645,10 @@ struct DerefState : AbstractState { 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; } }; @@ -1670,6 +1656,16 @@ struct AADereferenceableImpl : AADereferenceable, DerefState { 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; } @@ -1686,38 +1682,14 @@ struct AADereferenceableImpl : AADereferenceable, DerefState { 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, @@ -1731,15 +1703,7 @@ struct AADereferenceableImpl : AADereferenceable, DerefState { 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 { @@ -1751,6 +1715,9 @@ struct AADereferenceableImpl : AADereferenceable, DerefState { std::to_string(getKnownDereferenceableBytes()) + "-" + std::to_string(getAssumedDereferenceableBytes()) + ">"; } + +private: + const AANonNull *NonNullAA = nullptr; }; struct AADereferenceableReturned final : AADereferenceableImpl { @@ -1774,15 +1741,15 @@ static uint64_t calcDifferenceIfBaseIsNonNull(int64_t DerefBytes, 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(); } @@ -1795,7 +1762,6 @@ uint64_t AADereferenceableImpl::computeAssumedDerefenceableBytes( if (auto *BaseDerefAA = A.getAAFor(*this, IRPosition::value(*Base))) { - IsNonNull &= Offset != 0; return calcDifferenceIfBaseIsNonNull( BaseDerefAA->getAssumedDereferenceableBytes(), Offset.getSExtValue(), Offset != 0 || BaseDerefAA->isAssumedNonNull()); @@ -1810,26 +1776,22 @@ uint64_t AADereferenceableImpl::computeAssumedDerefenceableBytes( !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.intersectAssumedBits(IsGlobal); return BeforeState == static_cast(*this) ? ChangeStatus::UNCHANGED : ChangeStatus::CHANGED; @@ -1857,9 +1819,6 @@ ChangeStatus AADereferenceableArgument::updateImpl(Attributor &A) { unsigned ArgNo = Arg.getArgNo(); - syncNonNull(A.getAAFor(*this, getIRPosition())); - - bool IsNonNull = isAssumedNonNull(); bool IsGlobal = isAssumedGlobal(); // Callback function @@ -1874,14 +1833,13 @@ ChangeStatus AADereferenceableArgument::updateImpl(Attributor &A) { 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(); }; @@ -1889,7 +1847,7 @@ ChangeStatus AADereferenceableArgument::updateImpl(Attributor &A) { if (!A.checkForAllCallSites(CallSiteCheck, *this, true)) return indicatePessimisticFixpoint(); - updateAssumedNonNullGlobalState(IsNonNull, IsGlobal); + GlobalState.intersectAssumedBits(IsGlobal); return BeforeState == static_cast(*this) ? ChangeStatus::UNCHANGED : ChangeStatus::CHANGED; @@ -1918,13 +1876,11 @@ ChangeStatus AADereferenceableCallSiteArgument::updateImpl(Attributor &A) { 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.intersectAssumedBits(IsGlobal); return BeforeState == static_cast(*this) ? ChangeStatus::UNCHANGED : ChangeStatus::CHANGED;