Index: llvm/trunk/include/llvm/Transforms/IPO/Attributor.h =================================================================== --- llvm/trunk/include/llvm/Transforms/IPO/Attributor.h +++ llvm/trunk/include/llvm/Transforms/IPO/Attributor.h @@ -176,8 +176,6 @@ 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 @@ // 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 @@ /// 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 @@ // 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 @@ /// 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 @@ ///} /// 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 @@ 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 @@ 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 @@ 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 @@ 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 @@ /// 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 @@ /// 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 @@ 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 @@ 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 @@ 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 @@ return false; } + + /// Unique ID (due to the unique address) + static const char ID; }; /// An abstract interface for all dereferenceable attribute. @@ -912,10 +922,12 @@ 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 @@ : 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 @@ /// 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 Index: llvm/trunk/lib/Transforms/IPO/Attributor.cpp =================================================================== --- llvm/trunk/lib/Transforms/IPO/Attributor.cpp +++ llvm/trunk/lib/Transforms/IPO/Attributor.cpp @@ -1074,7 +1074,7 @@ 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 @@ /// 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 @@ 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 @@ 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 @@ 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 @@ 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 @@ 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 @@ 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",