llvm.org GIT mirror llvm / 8e521da
[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 Johannes Doerfert a month ago
2 changed file(s) with 35 addition(s) and 82 deletion(s). Raw diff Collapse all Expand all
12961296 /// Return true if we assume that the underlying value is nonnull.
12971297 virtual bool isAssumedNonNull() const = 0;
12981298
1299 /// Return true if we know that underlying value is nonnull.
1300 virtual bool isKnownNonNull() const = 0;
1301
13021299 /// Return true if we assume that underlying value is
13031300 /// dereferenceable(_or_null) globally.
13041301 virtual bool isAssumedGlobal() const = 0;
16081608 /// State representing for dereferenceable bytes.
16091609 IntegerState DerefBytesState;
16101610
1611 /// State representing that whether the value is nonnull or global.
1612 IntegerState NonNullGlobalState;
1613
1614 /// Bits encoding for NonNullGlobalState.
1615 enum {
1616 DEREF_NONNULL = 1 << 0,
1617 DEREF_GLOBAL = 1 << 1,
1618 };
1611 /// State representing that whether the value is globaly dereferenceable.
1612 BooleanState GlobalState;
16191613
16201614 /// See AbstractState::isValidState()
16211615 bool isValidState() const override { return DerefBytesState.isValidState(); }
16221616
16231617 /// See AbstractState::isAtFixpoint()
16241618 bool isAtFixpoint() const override {
1625 return !isValidState() || (DerefBytesState.isAtFixpoint() &&
1626 NonNullGlobalState.isAtFixpoint());
1619 return !isValidState() ||
1620 (DerefBytesState.isAtFixpoint() && GlobalState.isAtFixpoint());
16271621 }
16281622
16291623 /// See AbstractState::indicateOptimisticFixpoint(...)
16301624 ChangeStatus indicateOptimisticFixpoint() override {
16311625 DerefBytesState.indicateOptimisticFixpoint();
1632 NonNullGlobalState.indicateOptimisticFixpoint();
1626 GlobalState.indicateOptimisticFixpoint();
16331627 return ChangeStatus::UNCHANGED;
16341628 }
16351629
16361630 /// See AbstractState::indicatePessimisticFixpoint(...)
16371631 ChangeStatus indicatePessimisticFixpoint() override {
16381632 DerefBytesState.indicatePessimisticFixpoint();
1639 NonNullGlobalState.indicatePessimisticFixpoint();
1633 GlobalState.indicatePessimisticFixpoint();
16401634 return ChangeStatus::CHANGED;
16411635 }
16421636
16501644 DerefBytesState.takeAssumedMinimum(Bytes);
16511645 }
16521646
1653 /// Update assumed NonNullGlobalState
1654 void updateAssumedNonNullGlobalState(bool IsNonNull, bool IsGlobal) {
1655 if (!IsNonNull)
1656 NonNullGlobalState.removeAssumedBits(DEREF_NONNULL);
1657 if (!IsGlobal)
1658 NonNullGlobalState.removeAssumedBits(DEREF_GLOBAL);
1659 }
1660
16611647 /// Equality for DerefState.
16621648 bool operator==(const DerefState &R) {
16631649 return this->DerefBytesState == R.DerefBytesState &&
1664 this->NonNullGlobalState == R.NonNullGlobalState;
1650 this->GlobalState == R.GlobalState;
16651651 }
16661652 };
16671653
16681654 struct AADereferenceableImpl : AADereferenceable, DerefState {
16691655 AADereferenceableImpl(const IRPosition &IRP) : AADereferenceable(IRP) {}
16701656 using StateType = DerefState;
1657
1658 void initialize(Attributor &A) override {
1659 SmallVector Attrs;
1660 getAttrs({Attribute::Dereferenceable, Attribute::DereferenceableOrNull},
1661 Attrs);
1662 for (const Attribute &Attr : Attrs)
1663 takeKnownDerefBytesMaximum(Attr.getValueAsInt());
1664
1665 NonNullAA = A.getAAFor(*this, getIRPosition());
1666 }
16711667
16721668 /// See AbstractAttribute::getState()
16731669 /// {
16851681 return DerefBytesState.getKnown();
16861682 }
16871683
1688 // Helper function for syncing nonnull state.
1689 void syncNonNull(const AANonNull *NonNullAA) {
1690 if (!NonNullAA) {
1691 NonNullGlobalState.removeAssumedBits(DEREF_NONNULL);
1692 return;
1693 }
1694
1695 if (NonNullAA->isKnownNonNull())
1696 NonNullGlobalState.addKnownBits(DEREF_NONNULL);
1697
1698 if (!NonNullAA->isAssumedNonNull())
1699 NonNullGlobalState.removeAssumedBits(DEREF_NONNULL);
1700 }
1701
17021684 /// See AADereferenceable::isAssumedGlobal().
1703 bool isAssumedGlobal() const override {
1704 return NonNullGlobalState.isAssumed(DEREF_GLOBAL);
1705 }
1685 bool isAssumedGlobal() const override { return GlobalState.getAssumed(); }
17061686
17071687 /// See AADereferenceable::isKnownGlobal().
1708 bool isKnownGlobal() const override {
1709 return NonNullGlobalState.isKnown(DEREF_GLOBAL);
1710 }
1711
1712 /// See AADereferenceable::isAssumedNonNull().
1688 bool isKnownGlobal() const override { return GlobalState.getKnown(); }
1689
17131690 bool isAssumedNonNull() const override {
1714 return NonNullGlobalState.isAssumed(DEREF_NONNULL);
1715 }
1716
1717 /// See AADereferenceable::isKnownNonNull().
1718 bool isKnownNonNull() const override {
1719 return NonNullGlobalState.isKnown(DEREF_NONNULL);
1691 return NonNullAA && NonNullAA->isAssumedNonNull();
17201692 }
17211693
17221694 void getDeducedAttributes(LLVMContext &Ctx,
17301702 Ctx, getAssumedDereferenceableBytes()));
17311703 }
17321704 uint64_t computeAssumedDerefenceableBytes(Attributor &A, Value &V,
1733 bool &IsNonNull, bool &IsGlobal);
1734
1735 void initialize(Attributor &A) override {
1736 SmallVector Attrs;
1737 getAttrs({Attribute::Dereferenceable, Attribute::DereferenceableOrNull},
1738 Attrs);
1739 for (const Attribute &Attr : Attrs)
1740 takeKnownDerefBytesMaximum(Attr.getValueAsInt());
1741 }
1705 bool &IsGlobal);
17421706
17431707 /// See AbstractAttribute::getAsStr().
17441708 const std::string getAsStr() const override {
17501714 std::to_string(getKnownDereferenceableBytes()) + "-" +
17511715 std::to_string(getAssumedDereferenceableBytes()) + ">";
17521716 }
1717
1718 private:
1719 const AANonNull *NonNullAA = nullptr;
17531720 };
17541721
17551722 struct AADereferenceableReturned final : AADereferenceableImpl {
17731740 return std::max((int64_t)0, DerefBytes - Offset);
17741741 }
17751742
1776 uint64_t AADereferenceableImpl::computeAssumedDerefenceableBytes(
1777 Attributor &A, Value &V, bool &IsNonNull, bool &IsGlobal) {
1743 uint64_t
1744 AADereferenceableImpl::computeAssumedDerefenceableBytes(Attributor &A, Value &V,
1745 bool &IsGlobal) {
17781746 // TODO: Tracking the globally flag.
17791747 IsGlobal = false;
17801748
17811749 // First, we try to get information about V from Attributor.
17821750 if (auto *DerefAA =
17831751 A.getAAFor(*this, IRPosition::value(V))) {
1784 IsNonNull &= DerefAA->isAssumedNonNull();
17851752 return DerefAA->getAssumedDereferenceableBytes();
17861753 }
17871754
17941761
17951762 if (auto *BaseDerefAA =
17961763 A.getAAFor(*this, IRPosition::value(*Base))) {
1797 IsNonNull &= Offset != 0;
17981764 return calcDifferenceIfBaseIsNonNull(
17991765 BaseDerefAA->getAssumedDereferenceableBytes(), Offset.getSExtValue(),
18001766 Offset != 0 || BaseDerefAA->isAssumedNonNull());
18091775 !NullPointerIsDefined(getAnchorScope(),
18101776 V.getType()->getPointerAddressSpace()));
18111777
1812 IsNonNull = false;
18131778 return 0;
18141779 }
18151780
18161781 ChangeStatus AADereferenceableReturned::updateImpl(Attributor &A) {
18171782 auto BeforeState = static_cast(*this);
18181783
1819 syncNonNull(A.getAAFor(*this, getIRPosition()));
1820
1821 bool IsNonNull = isAssumedNonNull();
18221784 bool IsGlobal = isAssumedGlobal();
18231785
18241786 auto CheckReturnValue = [&](Value &RV) -> bool {
18251787 takeAssumedDerefBytesMinimum(
1826 computeAssumedDerefenceableBytes(A, RV, IsNonNull, IsGlobal));
1788 computeAssumedDerefenceableBytes(A, RV, IsGlobal));
18271789 return isValidState();
18281790 };
18291791
18301792 if (A.checkForAllReturnedValues(CheckReturnValue, *this)) {
1831 updateAssumedNonNullGlobalState(IsNonNull, IsGlobal);
1793 GlobalState.intersectAssumedBits(IsGlobal);
18321794 return BeforeState == static_cast(*this)
18331795 ? ChangeStatus::UNCHANGED
18341796 : ChangeStatus::CHANGED;
18561818
18571819 unsigned ArgNo = Arg.getArgNo();
18581820
1859 syncNonNull(A.getAAFor(*this, getIRPosition()));
1860
1861 bool IsNonNull = isAssumedNonNull();
18621821 bool IsGlobal = isAssumedGlobal();
18631822
18641823 // Callback function
18731832 if (ICS && CS.getInstruction() == ICS.getInstruction()) {
18741833 takeAssumedDerefBytesMinimum(
18751834 DereferenceableAA->getAssumedDereferenceableBytes());
1876 IsNonNull &= DereferenceableAA->isAssumedNonNull();
18771835 IsGlobal &= DereferenceableAA->isAssumedGlobal();
18781836 return isValidState();
18791837 }
18801838 }
18811839
18821840 takeAssumedDerefBytesMinimum(computeAssumedDerefenceableBytes(
1883 A, *CS.getArgOperand(ArgNo), IsNonNull, IsGlobal));
1841 A, *CS.getArgOperand(ArgNo), IsGlobal));
18841842
18851843 return isValidState();
18861844 };
18881846 if (!A.checkForAllCallSites(CallSiteCheck, *this, true))
18891847 return indicatePessimisticFixpoint();
18901848
1891 updateAssumedNonNullGlobalState(IsNonNull, IsGlobal);
1849 GlobalState.intersectAssumedBits(IsGlobal);
18921850
18931851 return BeforeState == static_cast(*this) ? ChangeStatus::UNCHANGED
18941852 : ChangeStatus::CHANGED;
19171875
19181876 auto BeforeState = static_cast(*this);
19191877
1920 syncNonNull(A.getAAFor(*this, getIRPosition()));
1921 bool IsNonNull = isAssumedNonNull();
1922 bool IsGlobal = isKnownGlobal();
1878 bool IsGlobal = isAssumedGlobal();
19231879
19241880 takeAssumedDerefBytesMinimum(
1925 computeAssumedDerefenceableBytes(A, V, IsNonNull, IsGlobal));
1926 updateAssumedNonNullGlobalState(IsNonNull, IsGlobal);
1881 computeAssumedDerefenceableBytes(A, V, IsGlobal));
1882 GlobalState.intersectAssumedBits(IsGlobal);
19271883
19281884 return BeforeState == static_cast(*this) ? ChangeStatus::UNCHANGED
19291885 : ChangeStatus::CHANGED;