From 9f49baf4d57411e38ce868c48fcc349ebfdd6292 Mon Sep 17 00:00:00 2001 From: Johannes Doerfert Date: Mon, 5 Aug 2019 23:30:01 +0000 Subject: [PATCH] [Attributor] Use proper ID for attribute lookup Summary: The new scheme is similar to the pass manager and dyn_cast scheme where we identify classes by the address of a static member. This is better than the old scheme in which we had to "invent" new Attributor enums if there was no corresponding one. Reviewers: sstefan1, uenoku Subscribers: hiraditya, bollu, llvm-commits Tags: #llvm Differential Revision: https://reviews.llvm.org/D65710 git-svn-id: https://llvm.org/svn/llvm-project/llvm/trunk@367951 91177308-0d34-0410-b5e6-96231b3b80d8 --- include/llvm/Transforms/IPO/Attributor.h | 98 ++++++++++++++---------- lib/Transforms/IPO/Attributor.cpp | 49 ++++++++---- 2 files changed, 88 insertions(+), 59 deletions(-) diff --git a/include/llvm/Transforms/IPO/Attributor.h b/include/llvm/Transforms/IPO/Attributor.h index df26a50f324..fe99b30f6d3 100644 --- a/include/llvm/Transforms/IPO/Attributor.h +++ b/include/llvm/Transforms/IPO/Attributor.h @@ -176,8 +176,6 @@ struct Attributor { static_assert(std::is_base_of::value, "Cannot query an attribute with a type not derived from " "'AbstractAttribute'!"); - assert(AAType::ID != Attribute::None && - "Cannot lookup generic abstract attributes!"); // Determine the argument number automatically for llvm::Arguments if none // is set. Do not override a given one as it could be a use of the argument @@ -198,7 +196,7 @@ struct Attributor { // registering a dependence of QueryingAA on the one returned attribute. const auto &KindToAbstractAttributeMap = AAMap.lookup({&V, ArgNo}); if (AAType *AA = static_cast( - KindToAbstractAttributeMap.lookup(AAType::ID))) { + KindToAbstractAttributeMap.lookup(&AAType::ID))) { // Do not return an attribute with an invalid state. This minimizes checks // at the calls sites and allows the fallback below to kick in. if (AA->getState().isValidState()) { @@ -225,7 +223,7 @@ struct Attributor { /// Attributes are identified by /// (1) their anchored value (see AA.getAnchoredValue()), /// (2) their argument number (\p ArgNo, or Argument::getArgNo()), and - /// (3) their default attribute kind (see AAType::ID). + /// (3) the address of their static member (see AAType::ID). template AAType ®isterAA(AAType &AA, int ArgNo = -1) { static_assert(std::is_base_of::value, "Cannot register an attribute with a type not derived from " @@ -242,7 +240,7 @@ struct Attributor { // Put the attribute in the lookup map structure and the container we use to // keep track of all attributes. - AAMap[{&AnchoredVal, ArgNo}][AAType::ID] = &AA; + AAMap[{&AnchoredVal, ArgNo}][&AAType::ID] = &AA; AllAbstractAttributes.push_back(&AA); return AA; } @@ -261,7 +259,7 @@ struct Attributor { /// various places. void identifyDefaultAbstractAttributes( Function &F, InformationCache &InfoCache, - DenseSet *Whitelist = nullptr); + DenseSet *Whitelist = nullptr); /// Check \p Pred on all function call sites. /// @@ -279,10 +277,11 @@ private: ///} /// A nested map to lookup abstract attributes based on the anchored value and - /// an argument positions (or -1) on the outer level, and attribute kinds - /// (Attribute::AttrKind) on the inner level. + /// an argument positions (or -1) on the outer level, and the addresses of the + /// static member (AAType::ID) on the inner level. ///{ - using KindToAbstractAttributeMap = DenseMap; + using KindToAbstractAttributeMap = + DenseMap; DenseMap, KindToAbstractAttributeMap> AAMap; ///} @@ -700,10 +699,12 @@ struct AAReturnedValues : public AbstractAttribute { const = 0; /// See AbstractAttribute::getAttrKind() - Attribute::AttrKind getAttrKind() const override { return ID; } + Attribute::AttrKind getAttrKind() const override { + return Attribute::Returned; + } - /// The identifier used by the Attributor for this class of attributes. - static constexpr Attribute::AttrKind ID = Attribute::Returned; + /// Unique ID (due to the unique address) + static const char ID; }; struct AANoUnwind : public AbstractAttribute { @@ -711,15 +712,18 @@ struct AANoUnwind : public AbstractAttribute { AANoUnwind(Value &V) : AbstractAttribute(V) {} /// See AbstractAttribute::getAttrKind()/ - Attribute::AttrKind getAttrKind() const override { return ID; } - - static constexpr Attribute::AttrKind ID = Attribute::NoUnwind; + Attribute::AttrKind getAttrKind() const override { + return Attribute::NoUnwind; + } /// Returns true if nounwind is assumed. virtual bool isAssumedNoUnwind() const = 0; /// Returns true if nounwind is known. virtual bool isKnownNoUnwind() const = 0; + + /// Unique ID (due to the unique address) + static const char ID; }; struct AANoSync : public AbstractAttribute { @@ -727,16 +731,16 @@ struct AANoSync : public AbstractAttribute { AANoSync(Value &V) : AbstractAttribute(V) {} /// See AbstractAttribute::getAttrKind(). - Attribute::AttrKind getAttrKind() const override { return ID; } - - static constexpr Attribute::AttrKind ID = - Attribute::AttrKind(Attribute::NoSync); + Attribute::AttrKind getAttrKind() const override { return Attribute::NoSync; } /// Returns true if "nosync" is assumed. virtual bool isAssumedNoSync() const = 0; /// Returns true if "nosync" is known. virtual bool isKnownNoSync() const = 0; + + /// Unique ID (due to the unique address) + static const char ID; }; /// An abstract interface for all nonnull attributes. @@ -756,10 +760,12 @@ struct AANonNull : public AbstractAttribute { virtual bool isKnownNonNull() const = 0; /// See AbastractState::getAttrKind(). - Attribute::AttrKind getAttrKind() const override { return ID; } + Attribute::AttrKind getAttrKind() const override { + return Attribute::NonNull; + } - /// The identifier used by the Attributor for this class of attributes. - static constexpr Attribute::AttrKind ID = Attribute::NonNull; + /// Unique ID (due to the unique address) + static const char ID; }; /// An abstract attribute for norecurse. @@ -779,8 +785,8 @@ struct AANoRecurse : public AbstractAttribute { /// Return true if "norecurse" is assumed. virtual bool isAssumedNoRecurse() const = 0; - /// The identifier used by the Attributor for this class of attributes. - static constexpr Attribute::AttrKind ID = Attribute::NoRecurse; + /// Unique ID (due to the unique address) + static const char ID; }; /// An abstract attribute for willreturn. @@ -800,8 +806,8 @@ struct AAWillReturn : public AbstractAttribute { /// Return true if "willreturn" is assumed. virtual bool isAssumedWillReturn() const = 0; - /// The identifier used by the Attributor for this class of attributes. - static constexpr Attribute::AttrKind ID = Attribute::WillReturn; + /// Unique ID (due to the unique address) + static const char ID; }; /// An abstract interface for all noalias attributes. @@ -817,10 +823,12 @@ struct AANoAlias : public AbstractAttribute { virtual bool isKnownNoAlias() const = 0; /// See AbastractState::getAttrKind(). - Attribute::AttrKind getAttrKind() const override { return ID; } + Attribute::AttrKind getAttrKind() const override { + return Attribute::NoAlias; + } - /// The identifier used by the Attributor for this class of attributes. - static constexpr Attribute::AttrKind ID = Attribute::NoAlias; + /// Unique ID (due to the unique address) + static const char ID; }; /// An AbstractAttribute for noreturn. @@ -836,10 +844,12 @@ struct AANoReturn : public AbstractAttribute { virtual bool isAssumedNoReturn() const = 0; /// See AbstractAttribute::getAttrKind() - Attribute::AttrKind getAttrKind() const override { return ID; } + Attribute::AttrKind getAttrKind() const override { + return Attribute::NoReturn; + } - /// The identifier used by the Attributor for this class of attributes. - static constexpr Attribute::AttrKind ID = Attribute::NoReturn; + /// Unique ID (due to the unique address) + static const char ID; }; /// An abstract interface for liveness abstract attribute. @@ -849,10 +859,7 @@ struct AAIsDead : public AbstractAttribute { AAIsDead(Value &V) : AbstractAttribute(V) {} /// See AbstractAttribute::getAttrKind() - Attribute::AttrKind getAttrKind() const override { return ID; } - - static constexpr Attribute::AttrKind ID = - Attribute::AttrKind(Attribute::EndAttrKinds + 1); + Attribute::AttrKind getAttrKind() const override { return Attribute::None; } /// Returns true if \p BB is assumed dead. virtual bool isAssumedDead(const BasicBlock *BB) const = 0; @@ -879,6 +886,9 @@ struct AAIsDead : public AbstractAttribute { return false; } + + /// Unique ID (due to the unique address) + static const char ID; }; /// An abstract interface for all dereferenceable attribute. @@ -912,10 +922,12 @@ struct AADereferenceable : public AbstractAttribute { virtual uint32_t getKnownDereferenceableBytes() const = 0; /// See AbastractState::getAttrKind(). - Attribute::AttrKind getAttrKind() const override { return ID; } + Attribute::AttrKind getAttrKind() const override { + return Attribute::Dereferenceable; + } - /// The identifier used by the Attributor for this class of attributes. - static constexpr Attribute::AttrKind ID = Attribute::Dereferenceable; + /// Unique ID (due to the unique address) + static const char ID; }; /// An abstract interface for all align attributes. @@ -929,7 +941,9 @@ struct AAAlign : public AbstractAttribute { : AbstractAttribute(AssociatedVal, AnchoredValue) {} /// See AbastractState::getAttrKind(). - Attribute::AttrKind getAttrKind() const override { return ID; } + Attribute::AttrKind getAttrKind() const override { + return Attribute::Alignment; + } /// Return assumed alignment. virtual unsigned getAssumedAlign() const = 0; @@ -937,8 +951,8 @@ struct AAAlign : public AbstractAttribute { /// Return known alignemnt. virtual unsigned getKnownAlign() const = 0; - /// The identifier used by the Attributor for this class of attributes. - static constexpr Attribute::AttrKind ID = Attribute::Alignment; + /// Unique ID (due to the unique address) + static const char ID; }; } // end namespace llvm diff --git a/lib/Transforms/IPO/Attributor.cpp b/lib/Transforms/IPO/Attributor.cpp index e55751b5e5b..aea1de6febc 100644 --- a/lib/Transforms/IPO/Attributor.cpp +++ b/lib/Transforms/IPO/Attributor.cpp @@ -1074,7 +1074,7 @@ struct AANoFreeFunction : AbstractAttribute, BooleanState { ChangeStatus updateImpl(Attributor &A, InformationCache &InfoCache) override; /// See AbstractAttribute::getAttrKind(). - Attribute::AttrKind getAttrKind() const override { return ID; } + Attribute::AttrKind getAttrKind() const override { return Attribute::NoFree; } /// Return true if "nofree" is assumed. bool isAssumedNoFree() const { return getAssumed(); } @@ -1082,8 +1082,8 @@ struct AANoFreeFunction : AbstractAttribute, BooleanState { /// Return true if "nofree" is known. bool isKnownNoFree() const { return getKnown(); } - /// The identifier used by the Attributor for this class of attributes. - static constexpr Attribute::AttrKind ID = Attribute::NoFree; + /// Unique ID (due to the unique address) + static const char ID; }; ChangeStatus AANoFreeFunction::updateImpl(Attributor &A, @@ -2177,8 +2177,9 @@ struct AAAlignImpl : AAAlign, IntegerState { getAttrIndex(getManifestPosition(), getArgNo(getAnchoredValue())); // Already the function has align attribute on return value or argument. - if (F.getAttributes().hasAttribute(AttrIdx, ID)) - addKnownBits(F.getAttribute(AttrIdx, ID).getAlignment()); + if (F.getAttributes().hasAttribute(AttrIdx, Attribute::Alignment)) + addKnownBits( + F.getAttribute(AttrIdx, Attribute::Alignment).getAlignment()); } /// See AbstractAttribute::getDeducedAttributes @@ -2580,7 +2581,7 @@ ChangeStatus Attributor::run(InformationCache &InfoCache) { void Attributor::identifyDefaultAbstractAttributes( Function &F, InformationCache &InfoCache, - DenseSet *Whitelist) { + DenseSet *Whitelist) { // Check for dead BasicBlocks in every function. registerAA(*new AAIsDeadFunction(F)); @@ -2605,26 +2606,26 @@ void Attributor::identifyDefaultAbstractAttributes( if (!ReturnType->isVoidTy()) { // Argument attribute "returned" --- Create only one per function even // though it is an argument attribute. - if (!Whitelist || Whitelist->count(AAReturnedValues::ID)) + if (!Whitelist || Whitelist->count(&AAReturnedValues::ID)) registerAA(*new AAReturnedValuesImpl(F)); if (ReturnType->isPointerTy()) { // Every function with pointer return type might be marked align. - if (!Whitelist || Whitelist->count(AAAlignReturned::ID)) + if (!Whitelist || Whitelist->count(&AAAlignReturned::ID)) registerAA(*new AAAlignReturned(F)); // Every function with pointer return type might be marked nonnull. - if (!Whitelist || Whitelist->count(AANonNullReturned::ID)) + if (!Whitelist || Whitelist->count(&AANonNullReturned::ID)) registerAA(*new AANonNullReturned(F)); // Every function with pointer return type might be marked noalias. - if (!Whitelist || Whitelist->count(AANoAliasReturned::ID)) + if (!Whitelist || Whitelist->count(&AANoAliasReturned::ID)) registerAA(*new AANoAliasReturned(F)); // Every function with pointer return type might be marked // dereferenceable. if (ReturnType->isPointerTy() && - (!Whitelist || Whitelist->count(AADereferenceableReturned::ID))) + (!Whitelist || Whitelist->count(&AADereferenceableReturned::ID))) registerAA(*new AADereferenceableReturned(F)); } } @@ -2632,15 +2633,15 @@ void Attributor::identifyDefaultAbstractAttributes( for (Argument &Arg : F.args()) { if (Arg.getType()->isPointerTy()) { // Every argument with pointer type might be marked nonnull. - if (!Whitelist || Whitelist->count(AANonNullArgument::ID)) + if (!Whitelist || Whitelist->count(&AANonNullArgument::ID)) registerAA(*new AANonNullArgument(Arg)); // Every argument with pointer type might be marked dereferenceable. - if (!Whitelist || Whitelist->count(AADereferenceableArgument::ID)) + if (!Whitelist || Whitelist->count(&AADereferenceableArgument::ID)) registerAA(*new AADereferenceableArgument(Arg)); // Every argument with pointer type might be marked align. - if (!Whitelist || Whitelist->count(AAAlignArgument::ID)) + if (!Whitelist || Whitelist->count(&AAAlignArgument::ID)) registerAA(*new AAAlignArgument(Arg)); } } @@ -2686,16 +2687,16 @@ void Attributor::identifyDefaultAbstractAttributes( continue; // Call site argument attribute "non-null". - if (!Whitelist || Whitelist->count(AANonNullCallSiteArgument::ID)) + if (!Whitelist || Whitelist->count(&AANonNullCallSiteArgument::ID)) registerAA(*new AANonNullCallSiteArgument(CS, i), i); // Call site argument attribute "dereferenceable". if (!Whitelist || - Whitelist->count(AADereferenceableCallSiteArgument::ID)) + Whitelist->count(&AADereferenceableCallSiteArgument::ID)) registerAA(*new AADereferenceableCallSiteArgument(CS, i), i); // Call site argument attribute "align". - if (!Whitelist || Whitelist->count(AAAlignCallSiteArgument::ID)) + if (!Whitelist || Whitelist->count(&AAAlignCallSiteArgument::ID)) registerAA(*new AAAlignCallSiteArgument(CS, i), i); } } @@ -2817,6 +2818,20 @@ struct AttributorLegacyPass : public ModulePass { Pass *llvm::createAttributorLegacyPass() { return new AttributorLegacyPass(); } char AttributorLegacyPass::ID = 0; + +const char AAReturnedValues::ID = 0; +const char AANoUnwind::ID = 0; +const char AANoSync::ID = 0; +const char AANoFreeFunction::ID = 0; +const char AANonNull::ID = 0; +const char AANoRecurse::ID = 0; +const char AAWillReturn::ID = 0; +const char AANoAlias::ID = 0; +const char AANoReturn::ID = 0; +const char AAIsDead::ID = 0; +const char AADereferenceable::ID = 0; +const char AAAlign::ID = 0; + INITIALIZE_PASS_BEGIN(AttributorLegacyPass, "attributor", "Deduce and propagate attributes", false, false) INITIALIZE_PASS_END(AttributorLegacyPass, "attributor", -- 2.50.1