diff --git a/llvm/include/llvm/Transforms/IPO/Attributor.h b/llvm/include/llvm/Transforms/IPO/Attributor.h index fa4b3d23cc8c..c17ff5d2f2a7 100644 --- a/llvm/include/llvm/Transforms/IPO/Attributor.h +++ b/llvm/include/llvm/Transforms/IPO/Attributor.h @@ -96,9 +96,9 @@ #ifndef LLVM_TRANSFORMS_IPO_ATTRIBUTOR_H #define LLVM_TRANSFORMS_IPO_ATTRIBUTOR_H +#include "llvm/ADT/SetVector.h" #include "llvm/IR/CallSite.h" #include "llvm/IR/PassManager.h" -#include "llvm/ADT/SetVector.h" namespace llvm { @@ -147,6 +147,7 @@ ChangeStatus operator&(ChangeStatus l, ChangeStatus r); /// NOTE: The mechanics of adding a new "concrete" abstract attribute are /// described in the file comment. struct Attributor { + Attributor(InformationCache &InfoCache) : InfoCache(InfoCache) {} ~Attributor() { DeleteContainerPointers(AllAbstractAttributes); } /// Run the analyses until a fixpoint is reached or enforced (timeout). @@ -155,7 +156,7 @@ struct Attributor { /// as the Attributor is not destroyed (it owns the attributes now). /// /// \Returns CHANGED if the IR was changed, otherwise UNCHANGED. - ChangeStatus run(InformationCache &InfoCache); + ChangeStatus run(); /// Lookup an abstract attribute of type \p AAType anchored at value \p V and /// argument number \p ArgNo. If no attribute is found and \p V is a call base @@ -244,11 +245,13 @@ struct Attributor { return AA; } + /// Return the internal information cache. + InformationCache &getInfoCache() { return InfoCache; } + /// Determine opportunities to derive 'default' attributes in \p F and create /// abstract attribute objects for them. /// /// \param F The function that is checked for attribute opportunities. - /// \param InfoCache A cache for information queryable by the new attributes. /// \param Whitelist If not null, a set limiting the attribute opportunities. /// /// Note that abstract attribute instances are generally created even if the @@ -257,8 +260,7 @@ struct Attributor { /// instance, which can be queried without the need to look at the IR in /// various places. void identifyDefaultAbstractAttributes( - Function &F, InformationCache &InfoCache, - DenseSet *Whitelist = nullptr); + Function &F, DenseSet *Whitelist = nullptr); /// Check \p Pred on all function call sites. /// @@ -294,16 +296,16 @@ struct Attributor { bool checkForAllInstructions(const Function &F, const function_ref &Pred, const AbstractAttribute &QueryingAA, - InformationCache &InfoCache, const ArrayRef &Opcodes); /// Check \p Pred on all call-like instructions (=CallBased derived). /// /// See checkForAllCallLikeInstructions(...) for more information. - bool checkForAllCallLikeInstructions( - const Function &F, const function_ref &Pred, - const AbstractAttribute &QueryingAA, InformationCache &InfoCache) { - return checkForAllInstructions(F, Pred, QueryingAA, InfoCache, + bool + checkForAllCallLikeInstructions(const Function &F, + const function_ref &Pred, + const AbstractAttribute &QueryingAA) { + return checkForAllInstructions(F, Pred, QueryingAA, {(unsigned)Instruction::Invoke, (unsigned)Instruction::CallBr, (unsigned)Instruction::Call}); @@ -312,11 +314,11 @@ struct Attributor { /// Check \p Pred on all Read/Write instructions. /// /// This method will evaluate \p Pred on all instructions that read or write - /// to memory present in \p InfoCache and return true if \p Pred holds on all - /// of them. + /// to memory present in the information cache and return true if \p Pred + /// holds on all of them. bool checkForAllReadWriteInstructions( const Function &F, const llvm::function_ref &Pred, - AbstractAttribute &QueryingAA, InformationCache &InfoCache); + AbstractAttribute &QueryingAA); private: /// The set of all abstract attributes. @@ -341,6 +343,9 @@ private: DenseMap>; QueryMapTy QueryMap; ///} + + /// The information cache that holds pre-processed (LLVM-IR) information. + InformationCache &InfoCache; }; /// Data structure to hold cached (LLVM-IR) information. @@ -356,6 +361,8 @@ private: /// reusable, it is advised to inherit from the InformationCache and cast the /// instance down in the abstract attributes. struct InformationCache { + InformationCache(const DataLayout &DL) : DL(DL) {} + /// A map type from opcodes to instructions with this opcode. using OpcodeInstMapTy = DenseMap>; @@ -387,6 +394,9 @@ private: /// A map from functions to their instructions that may read or write memory. FuncRWInstsMapTy FuncRWInstsMap; + /// The datalayout used in the module. + const DataLayout &DL; + /// Give the Attributor access to the members so /// Attributor::identifyDefaultAbstractAttributes(...) can initialize them. friend struct Attributor; @@ -705,8 +715,7 @@ struct StateWrapper : public StateTy, public Base { /// Helper class that provides common functionality to manifest IR attributes. template -struct IRAttribute : public IRPosition, - public Base { +struct IRAttribute : public IRPosition, public Base { ~IRAttribute() {} /// Constructors for the IRPosition. @@ -796,7 +805,7 @@ struct AbstractAttribute { /// - perform any work that is not going to change over time, e.g., determine /// a subset of the IR, or attributes in-flight, that have to be looked at /// in the `updateImpl` method. - virtual void initialize(Attributor &A, InformationCache &InfoCache) {} + virtual void initialize(Attributor &A) {} /// Return the internal abstract state for inspection. virtual StateType &getState() = 0; @@ -824,7 +833,7 @@ protected: /// otherwise it delegates to `AbstractAttribute::updateImpl`. /// /// \Return CHANGED if the internal state changed, otherwise UNCHANGED. - ChangeStatus update(Attributor &A, InformationCache &InfoCache); + ChangeStatus update(Attributor &A); /// Hook for the Attributor to trigger the manifestation of the information /// represented by the abstract attribute in the LLVM-IR. @@ -851,8 +860,7 @@ protected: /// the current information is still valid or adjust it otherwise. /// /// \Return CHANGED if the internal state changed, otherwise UNCHANGED. - virtual ChangeStatus updateImpl(Attributor &A, - InformationCache &InfoCache) = 0; + virtual ChangeStatus updateImpl(Attributor &A) = 0; }; /// Forward declarations of output streams for debug purposes. diff --git a/llvm/lib/Transforms/IPO/Attributor.cpp b/llvm/lib/Transforms/IPO/Attributor.cpp index d5b158bf8850..ad27b81945a7 100644 --- a/llvm/lib/Transforms/IPO/Attributor.cpp +++ b/llvm/lib/Transforms/IPO/Attributor.cpp @@ -247,15 +247,14 @@ static bool addIfNotExistent(LLVMContext &Ctx, const Attribute &Attr, llvm_unreachable("Expected enum or string attribute!"); } -ChangeStatus AbstractAttribute::update(Attributor &A, - InformationCache &InfoCache) { +ChangeStatus AbstractAttribute::update(Attributor &A) { ChangeStatus HasChanged = ChangeStatus::UNCHANGED; if (getState().isAtFixpoint()) return HasChanged; LLVM_DEBUG(dbgs() << "[Attributor] Update: " << *this << "\n"); - HasChanged = updateImpl(A, InfoCache); + HasChanged = updateImpl(A); LLVM_DEBUG(dbgs() << "[Attributor] Update " << HasChanged << " " << *this << "\n"); @@ -324,7 +323,7 @@ struct AANoUnwindImpl : AANoUnwind { } /// See AbstractAttribute::updateImpl(...). - ChangeStatus updateImpl(Attributor &A, InformationCache &InfoCache) override; + ChangeStatus updateImpl(Attributor &A) override; }; struct AANoUnwindFunction final : public AANoUnwindImpl { @@ -336,8 +335,7 @@ struct AANoUnwindFunction final : public AANoUnwindImpl { } }; -ChangeStatus AANoUnwindImpl::updateImpl(Attributor &A, - InformationCache &InfoCache) { +ChangeStatus AANoUnwindImpl::updateImpl(Attributor &A) { Function &F = getAnchorScope(); // The map from instruction opcodes to those instructions in the function. @@ -354,8 +352,7 @@ ChangeStatus AANoUnwindImpl::updateImpl(Attributor &A, return NoUnwindAA && NoUnwindAA->isAssumedNoUnwind(); }; - if (!A.checkForAllInstructions(F, CheckForNoUnwind, *this, InfoCache, - Opcodes)) + if (!A.checkForAllInstructions(F, CheckForNoUnwind, *this, Opcodes)) return indicatePessimisticFixpoint(); return ChangeStatus::UNCHANGED; @@ -411,7 +408,7 @@ public: IRPositionConstructorForward(AAReturnedValuesImpl, AAReturnedValues); /// See AbstractAttribute::initialize(...). - void initialize(Attributor &A, InformationCache &InfoCache) override { + void initialize(Attributor &A) override { // Reset the state. setAssociatedValue(nullptr); IsFixed = false; @@ -422,7 +419,7 @@ public: Function &F = getAnchorScope(); // The map from instruction opcodes to those instructions in the function. - auto &OpcodeInstMap = InfoCache.getOpcodeInstMapForFunction(F); + auto &OpcodeInstMap = A.getInfoCache().getOpcodeInstMapForFunction(F); // Look through all arguments, if one is marked as returned we are done. for (Argument &Arg : F.args()) { @@ -456,7 +453,7 @@ public: const AbstractState &getState() const override { return *this; } /// See AbstractAttribute::updateImpl(Attributor &A). - ChangeStatus updateImpl(Attributor &A, InformationCache &InfoCache) override; + ChangeStatus updateImpl(Attributor &A) override; /// Return the number of potential return values, -1 if unknown. size_t getNumReturnValues() const { @@ -595,8 +592,7 @@ bool AAReturnedValuesImpl::checkForAllReturnedValuesAndReturnInsts( return true; } -ChangeStatus AAReturnedValuesImpl::updateImpl(Attributor &A, - InformationCache &InfoCache) { +ChangeStatus AAReturnedValuesImpl::updateImpl(Attributor &A) { // Check if we know of any values returned by the associated function, // if not, we are done. @@ -726,7 +722,7 @@ struct AANoSyncImpl : AANoSync { } /// See AbstractAttribute::updateImpl(...). - ChangeStatus updateImpl(Attributor &A, InformationCache &InfoCache) override; + ChangeStatus updateImpl(Attributor &A) override; /// Helper function used to determine whether an instruction is non-relaxed /// atomic. In other words, if an atomic instruction does not have unordered @@ -837,8 +833,7 @@ bool AANoSyncImpl::isVolatile(Instruction *I) { } } -ChangeStatus AANoSyncImpl::updateImpl(Attributor &A, - InformationCache &InfoCache) { +ChangeStatus AANoSyncImpl::updateImpl(Attributor &A) { Function &F = getAnchorScope(); auto CheckRWInstForNoSync = [&](Instruction &I) { @@ -874,9 +869,8 @@ ChangeStatus AANoSyncImpl::updateImpl(Attributor &A, return !ImmutableCallSite(&I).isConvergent(); }; - if (!A.checkForAllReadWriteInstructions(F, CheckRWInstForNoSync, *this, - InfoCache) || - !A.checkForAllCallLikeInstructions(F, CheckForNoSync, *this, InfoCache)) + if (!A.checkForAllReadWriteInstructions(F, CheckRWInstForNoSync, *this) || + !A.checkForAllCallLikeInstructions(F, CheckForNoSync, *this)) return indicatePessimisticFixpoint(); return ChangeStatus::UNCHANGED; @@ -893,7 +887,7 @@ struct AANoFreeImpl : public AANoFree { } /// See AbstractAttribute::updateImpl(...). - ChangeStatus updateImpl(Attributor &A, InformationCache &InfoCache) override; + ChangeStatus updateImpl(Attributor &A) override; }; struct AANoFreeFunction final : public AANoFreeImpl { @@ -903,8 +897,7 @@ struct AANoFreeFunction final : public AANoFreeImpl { void trackStatistics() const override { STATS_DECL_AND_TRACK_FN_ATTR(nofree) } }; -ChangeStatus AANoFreeImpl::updateImpl(Attributor &A, - InformationCache &InfoCache) { +ChangeStatus AANoFreeImpl::updateImpl(Attributor &A) { Function &F = getAnchorScope(); auto CheckForNoFree = [&](Instruction &I) { @@ -915,7 +908,7 @@ ChangeStatus AANoFreeImpl::updateImpl(Attributor &A, return NoFreeAA && NoFreeAA->isAssumedNoFree(); }; - if (!A.checkForAllCallLikeInstructions(F, CheckForNoFree, *this, InfoCache)) + if (!A.checkForAllCallLikeInstructions(F, CheckForNoFree, *this)) return indicatePessimisticFixpoint(); return ChangeStatus::UNCHANGED; } @@ -972,7 +965,7 @@ struct AANonNullReturned final : AANonNullImpl { AANonNullReturned(Function &F) : AANonNullImpl(F, IRP_RETURNED) {} /// See AbstractAttribute::initialize(...). - void initialize(Attributor &A, InformationCache &InfoCache) override { + void initialize(Attributor &A) override { Function &F = getAnchorScope(); // Already nonnull. @@ -984,7 +977,7 @@ struct AANonNullReturned final : AANonNullImpl { } /// See AbstractAttribute::updateImpl(...). - ChangeStatus updateImpl(Attributor &A, InformationCache &InfoCache) override; + ChangeStatus updateImpl(Attributor &A) override; /// See AbstractAttribute::trackStatistics() void trackStatistics() const override { @@ -992,8 +985,7 @@ struct AANonNullReturned final : AANonNullImpl { } }; -ChangeStatus AANonNullReturned::updateImpl(Attributor &A, - InformationCache &InfoCache) { +ChangeStatus AANonNullReturned::updateImpl(Attributor &A) { Function &F = getAnchorScope(); std::function &)> Pred = @@ -1009,14 +1001,14 @@ struct AANonNullArgument final : AANonNullImpl { AANonNullArgument(Argument &A) : AANonNullImpl(A) {} /// See AbstractAttriubute::initialize(...). - void initialize(Attributor &A, InformationCache &InfoCache) override { + void initialize(Attributor &A) override { Argument *Arg = cast(getAssociatedValue()); if (Arg->hasNonNullAttr()) indicateOptimisticFixpoint(); } /// See AbstractAttribute::updateImpl(...). - ChangeStatus updateImpl(Attributor &A, InformationCache &InfoCache) override; + ChangeStatus updateImpl(Attributor &A) override; /// See AbstractAttribute::trackStatistics() void trackStatistics() const override { @@ -1030,7 +1022,7 @@ struct AANonNullCallSiteArgument final : AANonNullImpl { : AANonNullImpl(CallSite(&I).getArgOperand(ArgNo), I, ArgNo) {} /// See AbstractAttribute::initialize(...). - void initialize(Attributor &A, InformationCache &InfoCache) override { + void initialize(Attributor &A) override { CallSite CS(&getAnchorValue()); if (CS.paramHasAttr(getArgNo(), getAttrKind()) || CS.paramHasAttr(getArgNo(), Attribute::Dereferenceable) || @@ -1040,7 +1032,7 @@ struct AANonNullCallSiteArgument final : AANonNullImpl { } /// See AbstractAttribute::updateImpl(Attributor &A). - ChangeStatus updateImpl(Attributor &A, InformationCache &InfoCache) override; + ChangeStatus updateImpl(Attributor &A) override; /// See AbstractAttribute::trackStatistics() void trackStatistics() const override { @@ -1048,8 +1040,7 @@ struct AANonNullCallSiteArgument final : AANonNullImpl { } }; -ChangeStatus AANonNullArgument::updateImpl(Attributor &A, - InformationCache &InfoCache) { +ChangeStatus AANonNullArgument::updateImpl(Attributor &A) { Function &F = getAnchorScope(); unsigned ArgNo = getArgNo(); @@ -1082,9 +1073,7 @@ ChangeStatus AANonNullArgument::updateImpl(Attributor &A, return ChangeStatus::UNCHANGED; } -ChangeStatus -AANonNullCallSiteArgument::updateImpl(Attributor &A, - InformationCache &InfoCache) { +ChangeStatus AANonNullCallSiteArgument::updateImpl(Attributor &A) { // NOTE: Never look at the argument of the callee in this method. // If we do this, "nonnull" is always deduced because of the assumption. @@ -1113,10 +1102,10 @@ struct AAWillReturnFunction final : AAWillReturnImpl { AAWillReturnFunction(Function &F) : AAWillReturnImpl(F, IRP_FUNCTION) {} /// See AbstractAttribute::initialize(...). - void initialize(Attributor &A, InformationCache &InfoCache) override; + void initialize(Attributor &A) override; /// See AbstractAttribute::updateImpl(...). - ChangeStatus updateImpl(Attributor &A, InformationCache &InfoCache) override; + ChangeStatus updateImpl(Attributor &A) override; /// See AbstractAttribute::trackStatistics() void trackStatistics() const override { @@ -1146,16 +1135,14 @@ bool containsCycle(Function &F) { // We have to allow some patterns. bool containsPossiblyEndlessLoop(Function &F) { return containsCycle(F); } -void AAWillReturnFunction::initialize(Attributor &A, - InformationCache &InfoCache) { +void AAWillReturnFunction::initialize(Attributor &A) { Function &F = getAnchorScope(); if (containsPossiblyEndlessLoop(F)) indicatePessimisticFixpoint(); } -ChangeStatus AAWillReturnFunction::updateImpl(Attributor &A, - InformationCache &InfoCache) { +ChangeStatus AAWillReturnFunction::updateImpl(Attributor &A) { const Function &F = getAnchorScope(); // The map from instruction opcodes to those instructions in the function. @@ -1176,8 +1163,7 @@ ChangeStatus AAWillReturnFunction::updateImpl(Attributor &A, return NoRecurseAA && NoRecurseAA->isAssumedNoRecurse(); }; - if (!A.checkForAllCallLikeInstructions(F, CheckForWillReturn, *this, - InfoCache)) + if (!A.checkForAllCallLikeInstructions(F, CheckForWillReturn, *this)) return indicatePessimisticFixpoint(); return ChangeStatus::UNCHANGED; @@ -1198,7 +1184,7 @@ struct AANoAliasReturned final : AANoAliasImpl { AANoAliasReturned(Function &F) : AANoAliasImpl(F, IRP_RETURNED) {} /// See AbstractAttriubute::initialize(...). - void initialize(Attributor &A, InformationCache &InfoCache) override { + void initialize(Attributor &A) override { Function &F = getAnchorScope(); // Already noalias. @@ -1209,8 +1195,7 @@ struct AANoAliasReturned final : AANoAliasImpl { } /// See AbstractAttribute::updateImpl(...). - virtual ChangeStatus updateImpl(Attributor &A, - InformationCache &InfoCache) override; + virtual ChangeStatus updateImpl(Attributor &A) override; /// See AbstractAttribute::trackStatistics() void trackStatistics() const override { @@ -1218,8 +1203,7 @@ struct AANoAliasReturned final : AANoAliasImpl { } }; -ChangeStatus AANoAliasReturned::updateImpl(Attributor &A, - InformationCache &InfoCache) { +ChangeStatus AANoAliasReturned::updateImpl(Attributor &A) { Function &F = getAnchorScope(); auto CheckReturnValue = [&](Value &RV) -> bool { @@ -1260,7 +1244,7 @@ ChangeStatus AANoAliasReturned::updateImpl(Attributor &A, struct AAIsDeadImpl : public AAIsDead { IRPositionConstructorForward(AAIsDeadImpl, AAIsDead); - void initialize(Attributor &A, InformationCache &InfoCache) override { + void initialize(Attributor &A) override { const Function &F = getAnchorScope(); ToBeExploredPaths.insert(&(F.getEntryBlock().front())); @@ -1351,7 +1335,7 @@ struct AAIsDeadImpl : public AAIsDead { } /// See AbstractAttribute::updateImpl(...). - ChangeStatus updateImpl(Attributor &A, InformationCache &InfoCache) override; + ChangeStatus updateImpl(Attributor &A) override; /// See AAIsDead::isAssumedDead(BasicBlock *). bool isAssumedDead(const BasicBlock *BB) const override { @@ -1484,8 +1468,7 @@ const Instruction *AAIsDeadImpl::findNextNoReturn(Attributor &A, return nullptr; } -ChangeStatus AAIsDeadImpl::updateImpl(Attributor &A, - InformationCache &InfoCache) { +ChangeStatus AAIsDeadImpl::updateImpl(Attributor &A) { // Temporary collection to iterate over existing noreturn instructions. This // will alow easier modification of NoReturnCalls collection SmallVector NoReturnChanged; @@ -1662,7 +1645,7 @@ struct AADereferenceableImpl : AADereferenceable, DerefState { uint64_t computeAssumedDerefenceableBytes(Attributor &A, Value &V, bool &IsNonNull, bool &IsGlobal); - void initialize(Attributor &A, InformationCache &InfoCache) override { + void initialize(Attributor &A) override { Function &F = getAnchorScope(); unsigned AttrIdx = getIRPosition().getAttrIdx(); @@ -1689,7 +1672,7 @@ struct AADereferenceableReturned final : AADereferenceableImpl { : AADereferenceableImpl(F, IRP_RETURNED) {} /// See AbstractAttribute::updateImpl(...). - ChangeStatus updateImpl(Attributor &A, InformationCache &InfoCache) override; + ChangeStatus updateImpl(Attributor &A) override; /// See AbstractAttribute::trackStatistics() void trackStatistics() const override { @@ -1743,9 +1726,7 @@ uint64_t AADereferenceableImpl::computeAssumedDerefenceableBytes( return 0; } -ChangeStatus -AADereferenceableReturned::updateImpl(Attributor &A, - InformationCache &InfoCache) { +ChangeStatus AADereferenceableReturned::updateImpl(Attributor &A) { Function &F = getAnchorScope(); auto BeforeState = static_cast(*this); @@ -1773,7 +1754,7 @@ struct AADereferenceableArgument final : AADereferenceableImpl { AADereferenceableArgument(Argument &A) : AADereferenceableImpl(A) {} /// See AbstractAttribute::updateImpl(...). - ChangeStatus updateImpl(Attributor &A, InformationCache &InfoCache) override; + ChangeStatus updateImpl(Attributor &A) override; /// See AbstractAttribute::trackStatistics() void trackStatistics() const override { @@ -1781,9 +1762,7 @@ struct AADereferenceableArgument final : AADereferenceableImpl { } }; -ChangeStatus -AADereferenceableArgument::updateImpl(Attributor &A, - InformationCache &InfoCache) { +ChangeStatus AADereferenceableArgument::updateImpl(Attributor &A) { Function &F = getAnchorScope(); Argument &Arg = cast(getAnchorValue()); @@ -1835,7 +1814,7 @@ struct AADereferenceableCallSiteArgument final : AADereferenceableImpl { : AADereferenceableImpl(CallSite(&I).getArgOperand(ArgNo), I, ArgNo) {} /// See AbstractAttribute::initialize(...). - void initialize(Attributor &A, InformationCache &InfoCache) override { + void initialize(Attributor &A) override { CallSite CS(&getAnchorValue()); if (CS.paramHasAttr(getArgNo(), Attribute::Dereferenceable)) takeKnownDerefBytesMaximum(CS.getDereferenceableBytes(getArgNo())); @@ -1845,7 +1824,7 @@ struct AADereferenceableCallSiteArgument final : AADereferenceableImpl { } /// See AbstractAttribute::updateImpl(Attributor &A). - ChangeStatus updateImpl(Attributor &A, InformationCache &InfoCache) override; + ChangeStatus updateImpl(Attributor &A) override; /// See AbstractAttribute::trackStatistics() void trackStatistics() const override { @@ -1853,9 +1832,7 @@ struct AADereferenceableCallSiteArgument final : AADereferenceableImpl { } }; -ChangeStatus -AADereferenceableCallSiteArgument::updateImpl(Attributor &A, - InformationCache &InfoCache) { +ChangeStatus AADereferenceableCallSiteArgument::updateImpl(Attributor &A) { // NOTE: Never look at the argument of the callee in this method. // If we do this, "dereferenceable" is always deduced because of the // assumption. @@ -1891,7 +1868,7 @@ struct AAAlignImpl : AAAlign { } /// See AbstractAttriubute::initialize(...). - void initialize(Attributor &A, InformationCache &InfoCache) override { + void initialize(Attributor &A) override { takeAssumedMinimum(MAX_ALIGN); Function &F = getAnchorScope(); @@ -1916,7 +1893,7 @@ struct AAAlignReturned final : AAAlignImpl { AAAlignReturned(Function &F) : AAAlignImpl(F, IRP_RETURNED) {} /// See AbstractAttribute::updateImpl(...). - ChangeStatus updateImpl(Attributor &A, InformationCache &InfoCache) override; + ChangeStatus updateImpl(Attributor &A) override; /// See AbstractAttribute::trackStatistics() void trackStatistics() const override { @@ -1924,8 +1901,7 @@ struct AAAlignReturned final : AAAlignImpl { } }; -ChangeStatus AAAlignReturned::updateImpl(Attributor &A, - InformationCache &InfoCache) { +ChangeStatus AAAlignReturned::updateImpl(Attributor &A) { Function &F = getAnchorScope(); // Currently, align is deduced if alignments in return values are assumed @@ -1960,15 +1936,13 @@ struct AAAlignArgument final : AAAlignImpl { AAAlignArgument(Argument &A) : AAAlignImpl(A) {} /// See AbstractAttribute::updateImpl(...). - virtual ChangeStatus updateImpl(Attributor &A, - InformationCache &InfoCache) override; + virtual ChangeStatus updateImpl(Attributor &A) override; /// See AbstractAttribute::trackStatistics() void trackStatistics() const override{STATS_DECL_AND_TRACK_ARG_ATTR(aligned)}; }; -ChangeStatus AAAlignArgument::updateImpl(Attributor &A, - InformationCache &InfoCache) { +ChangeStatus AAAlignArgument::updateImpl(Attributor &A) { Function &F = getAnchorScope(); Argument &Arg = cast(getAnchorValue()); @@ -2010,14 +1984,14 @@ struct AAAlignCallSiteArgument final : AAAlignImpl { : AAAlignImpl(CallSite(&I).getArgOperand(ArgNo), I, ArgNo) {} /// See AbstractAttribute::initialize(...). - void initialize(Attributor &A, InformationCache &InfoCache) override { + void initialize(Attributor &A) override { CallSite CS(&getAnchorValue()); takeKnownMaximum(getAssociatedValue()->getPointerAlignment( getAnchorScope().getParent()->getDataLayout())); } /// See AbstractAttribute::updateImpl(Attributor &A). - ChangeStatus updateImpl(Attributor &A, InformationCache &InfoCache) override; + ChangeStatus updateImpl(Attributor &A) override; /// See AbstractAttribute::trackStatistics() void trackStatistics() const override { @@ -2025,8 +1999,7 @@ struct AAAlignCallSiteArgument final : AAAlignImpl { } }; -ChangeStatus AAAlignCallSiteArgument::updateImpl(Attributor &A, - InformationCache &InfoCache) { +ChangeStatus AAAlignCallSiteArgument::updateImpl(Attributor &A) { // NOTE: Never look at the argument of the callee in this method. // If we do this, "align" is always deduced because of the assumption. @@ -2055,18 +2028,17 @@ struct AANoReturnImpl : public AANoReturn { } /// See AbstractAttribute::initialize(...). - void initialize(Attributor &A, InformationCache &InfoCache) override { + void initialize(Attributor &A) override { Function &F = getAnchorScope(); if (F.hasFnAttribute(getAttrKind())) indicateOptimisticFixpoint(); } /// See AbstractAttribute::updateImpl(Attributor &A). - virtual ChangeStatus updateImpl(Attributor &A, - InformationCache &InfoCache) override { + virtual ChangeStatus updateImpl(Attributor &A) override { const Function &F = getAnchorScope(); auto CheckForNoReturn = [](Instruction &) { return false; }; - if (!A.checkForAllInstructions(F, CheckForNoReturn, *this, InfoCache, + if (!A.checkForAllInstructions(F, CheckForNoReturn, *this, {(unsigned)Instruction::Ret})) return indicatePessimisticFixpoint(); return ChangeStatus::UNCHANGED; @@ -2187,8 +2159,7 @@ bool Attributor::checkForAllReturnedValues( bool Attributor::checkForAllInstructions( const Function &F, const llvm::function_ref &Pred, - const AbstractAttribute &QueryingAA, InformationCache &InfoCache, - const ArrayRef &Opcodes) { + const AbstractAttribute &QueryingAA, const ArrayRef &Opcodes) { auto *LivenessAA = getAAFor(QueryingAA, F); @@ -2209,7 +2180,7 @@ bool Attributor::checkForAllInstructions( bool Attributor::checkForAllReadWriteInstructions( const Function &F, const llvm::function_ref &Pred, - AbstractAttribute &QueryingAA, InformationCache &InfoCache) { + AbstractAttribute &QueryingAA) { auto *LivenessAA = getAAFor(QueryingAA, F); @@ -2225,10 +2196,10 @@ bool Attributor::checkForAllReadWriteInstructions( return true; } -ChangeStatus Attributor::run(InformationCache &InfoCache) { +ChangeStatus Attributor::run() { // Initialize all abstract attributes. for (AbstractAttribute *AA : AllAbstractAttributes) - AA->initialize(*this, InfoCache); + AA->initialize(*this); LLVM_DEBUG(dbgs() << "[Attributor] Identified and initialized " << AllAbstractAttributes.size() @@ -2260,7 +2231,7 @@ ChangeStatus Attributor::run(InformationCache &InfoCache) { // Update all abstract attribute in the work list and record the ones that // changed. for (AbstractAttribute *AA : Worklist) - if (AA->update(*this, InfoCache) == ChangeStatus::CHANGED) + if (AA->update(*this) == ChangeStatus::CHANGED) ChangedAAs.push_back(AA); // Reset the work list and repopulate with the changed abstract attributes. @@ -2347,7 +2318,7 @@ ChangeStatus Attributor::run(InformationCache &InfoCache) { if (VerifyAttributor && FinishedAtFixpoint && ManifestChange == ChangeStatus::CHANGED) { VerifyAttributor = false; - ChangeStatus VerifyStatus = run(InfoCache); + ChangeStatus VerifyStatus = run(); if (VerifyStatus != ChangeStatus::UNCHANGED) llvm_unreachable( "Attributor verification failed, re-run did result in an IR change " @@ -2381,8 +2352,7 @@ static AAType *checkAndRegisterAA(const Function &F, Attributor &A, } void Attributor::identifyDefaultAbstractAttributes( - Function &F, InformationCache &InfoCache, - DenseSet *Whitelist) { + Function &F, DenseSet *Whitelist) { // Check for dead BasicBlocks in every function. // We need dead instruction detection because we do not want to deal with @@ -2556,8 +2526,8 @@ static bool runAttributorOnModule(Module &M) { // Create an Attributor and initially empty information cache that is filled // while we identify default attribute opportunities. - Attributor A; - InformationCache InfoCache; + InformationCache InfoCache(M.getDataLayout()); + Attributor A(InfoCache); for (Function &F : M) { // TODO: Not all attributes require an exact definition. Find a way to @@ -2581,10 +2551,10 @@ static bool runAttributorOnModule(Module &M) { // Populate the Attributor with abstract attribute opportunities in the // function and the information cache with IR information. - A.identifyDefaultAbstractAttributes(F, InfoCache); + A.identifyDefaultAbstractAttributes(F); } - return A.run(InfoCache) == ChangeStatus::CHANGED; + return A.run() == ChangeStatus::CHANGED; } PreservedAnalyses AttributorPass::run(Module &M, ModuleAnalysisManager &AM) {