diff --git a/llvm/include/llvm/Transforms/IPO/Attributor.h b/llvm/include/llvm/Transforms/IPO/Attributor.h --- a/llvm/include/llvm/Transforms/IPO/Attributor.h +++ b/llvm/include/llvm/Transforms/IPO/Attributor.h @@ -755,6 +755,11 @@ virtual ChangeStatus manifest(Attributor &A) { return ChangeStatus::UNCHANGED; } + + /// Hook to enable custom statistic tracking, called after manifest that + /// resulted in a change if statistics are enabled. + virtual void trackStatistics(){}; + /// Return an IR position, see struct IRPosition. virtual IRPosition &getIRPosition() = 0; diff --git a/llvm/lib/Transforms/IPO/Attributor.cpp b/llvm/lib/Transforms/IPO/Attributor.cpp --- a/llvm/lib/Transforms/IPO/Attributor.cpp +++ b/llvm/lib/Transforms/IPO/Attributor.cpp @@ -52,30 +52,36 @@ "Number of abstract attributes in a valid fixpoint state"); STATISTIC(NumAttributesManifested, "Number of abstract attributes manifested in IR"); -STATISTIC(NumFnNoUnwind, "Number of functions marked nounwind"); - -STATISTIC(NumFnUniqueReturned, "Number of function with unique return"); -STATISTIC(NumFnKnownReturns, "Number of function with known return values"); -STATISTIC(NumFnArgumentReturned, - "Number of function arguments marked returned"); -STATISTIC(NumFnNoSync, "Number of functions marked nosync"); -STATISTIC(NumFnNoFree, "Number of functions marked nofree"); -STATISTIC(NumFnReturnedNonNull, - "Number of function return values marked nonnull"); -STATISTIC(NumFnArgumentNonNull, "Number of function arguments marked nonnull"); -STATISTIC(NumCSArgumentNonNull, "Number of call site arguments marked nonnull"); -STATISTIC(NumFnWillReturn, "Number of functions marked willreturn"); -STATISTIC(NumFnArgumentNoAlias, "Number of function arguments marked noalias"); -STATISTIC(NumFnReturnedDereferenceable, - "Number of function return values marked dereferenceable"); -STATISTIC(NumFnArgumentDereferenceable, - "Number of function arguments marked dereferenceable"); -STATISTIC(NumCSArgumentDereferenceable, - "Number of call site arguments marked dereferenceable"); -STATISTIC(NumFnReturnedAlign, "Number of function return values marked align"); -STATISTIC(NumFnArgumentAlign, "Number of function arguments marked align"); -STATISTIC(NumCSArgumentAlign, "Number of call site arguments marked align"); -STATISTIC(NumFnNoReturn, "Number of functions marked noreturn"); + +// Some helper macros to deal with statistics tracking. +// +// Usage: +// For simple IR attribute tracking overload trackStatistics in the abstract +// attribute and choose the right STATS_DECL_AND_TRACK_********* macro, +// e.g.,: +// void trackStatistics() override { STATS_DECL_AND_TRACK_ARG_ATTR(returned) }; +// If there is a single "increment" side one can use the macro +// STATS_DECL_AND_TRACK with a custom message. If there are multiple increment +// sides, STATS_DECL and STATS_TRACK can also be used separatly. +// +#define BUILD_STAT_MSG_IR_ATTR(TYPE, NAME) \ + ("Number of " #TYPE " marked '" #NAME "'") +#define BUILD_STAT_NAME(NAME, TYPE) NumIR##TYPE##_##NAME +#define STATS_DECL(NAME, TYPE, MSG) STATISTIC(BUILD_STAT_NAME(NAME, TYPE), MSG); +#define STATS_TRACK(NAME, TYPE) ++(BUILD_STAT_NAME(NAME, TYPE)); +#define STATS_DECL_AND_TRACK(NAME, TYPE, MSG) \ + STATS_DECL(NAME, TYPE, MSG) \ + STATS_TRACK(NAME, TYPE) +#define STATS_DECL_AND_TRACK_ARG_ATTR(NAME) \ + STATS_DECL_AND_TRACK(NAME, Arguments, BUILD_STAT_MSG_IR_ATTR(arguments, NAME)) +#define STATS_DECL_AND_TRACK_CSARG_ATTR(NAME) \ + STATS_DECL_AND_TRACK(NAME, CSArguments, \ + BUILD_STAT_MSG_IR_ATTR(call site arguments, NAME)) +#define STATS_DECL_AND_TRACK_FN_ATTR(NAME) \ + STATS_DECL_AND_TRACK(NAME, Function, BUILD_STAT_MSG_IR_ATTR(functions, NAME)) +#define STATS_DECL_AND_TRACK_FNRET_ATTR(NAME) \ + STATS_DECL_AND_TRACK(NAME, FunctionReturn, \ + BUILD_STAT_MSG_IR_ATTR(function returns, NAME)); // TODO: Determine a good default value. // @@ -112,83 +118,6 @@ } ///} -/// Helper to adjust the statistics. -static void bookkeeping(IRPosition::Kind PK, const Attribute &Attr) { - if (!AreStatisticsEnabled()) - return; - - switch (Attr.getKindAsEnum()) { - case Attribute::Alignment: - switch (PK) { - case IRPosition::IRP_RETURNED: - NumFnReturnedAlign++; - break; - case IRPosition::IRP_ARGUMENT: - NumFnArgumentAlign++; - break; - case IRPosition::IRP_CALL_SITE_ARGUMENT: - NumCSArgumentAlign++; - break; - default: - break; - } - break; - case Attribute::Dereferenceable: - switch (PK) { - case IRPosition::IRP_RETURNED: - NumFnReturnedDereferenceable++; - break; - case IRPosition::IRP_ARGUMENT: - NumFnArgumentDereferenceable++; - break; - case IRPosition::IRP_CALL_SITE_ARGUMENT: - NumCSArgumentDereferenceable++; - break; - default: - break; - } - break; - case Attribute::NoUnwind: - NumFnNoUnwind++; - return; - case Attribute::Returned: - NumFnArgumentReturned++; - return; - case Attribute::NoSync: - NumFnNoSync++; - break; - case Attribute::NoFree: - NumFnNoFree++; - break; - case Attribute::NonNull: - switch (PK) { - case IRPosition::IRP_RETURNED: - NumFnReturnedNonNull++; - break; - case IRPosition::IRP_ARGUMENT: - NumFnArgumentNonNull++; - break; - case IRPosition::IRP_CALL_SITE_ARGUMENT: - NumCSArgumentNonNull++; - break; - default: - break; - } - break; - case Attribute::WillReturn: - NumFnWillReturn++; - break; - case Attribute::NoReturn: - NumFnNoReturn++; - return; - case Attribute::NoAlias: - NumFnArgumentNoAlias++; - return; - default: - return; - } -} - template using followValueCB_t = std::function; template @@ -368,7 +297,6 @@ continue; HasChanged = ChangeStatus::CHANGED; - bookkeeping(PK, Attr); } if (HasChanged == ChangeStatus::UNCHANGED) @@ -571,6 +499,9 @@ struct AAReturnedValuesFunction final : public AAReturnedValuesImpl { AAReturnedValuesFunction(Function &F) : AAReturnedValuesImpl(F, IRP_FUNCTION) {} + + /// See AbstractAttribute::trackStatistics() + void trackStatistics() override { STATS_DECL_AND_TRACK_ARG_ATTR(returned) } }; ChangeStatus AAReturnedValuesImpl::manifest(Attributor &A) { @@ -578,7 +509,8 @@ // Bookkeeping. assert(isValidState()); - NumFnKnownReturns++; + STATS_DECL_AND_TRACK(KnownReturnValues, FunctionReturn, + "Number of function with known return values"); auto *LivenessAA = A.getAAFor(*this, getAnchorScope()); @@ -589,7 +521,8 @@ return Changed; // Bookkeeping. - NumFnUniqueReturned++; + STATS_DECL_AND_TRACK(UniqueReturnValue, FunctionReturn, + "Number of function with unique return"); // If the assumed unique return value is an argument, annotate it. if (auto *UniqueRVArg = dyn_cast(UniqueRV.getValue())) { @@ -820,6 +753,9 @@ struct AANoSyncFunction final : public AANoSyncImpl { AANoSyncFunction(Function &F) : AANoSyncImpl(F, IRP_FUNCTION) {} + + /// See AbstractAttribute::trackStatistics() + void trackStatistics() override { STATS_DECL_AND_TRACK_FN_ATTR(nosync) } }; bool AANoSyncImpl::isNonRelaxedAtomic(Instruction *I) { @@ -986,6 +922,9 @@ struct AANoFreeFunction final : public AANoFreeImpl { AANoFreeFunction(Function &F) : AANoFreeImpl(F, IRP_FUNCTION) {} + + /// See AbstractAttribute::trackStatistics() + void trackStatistics() override { STATS_DECL_AND_TRACK_FN_ATTR(nofree) } }; ChangeStatus AANoFreeImpl::updateImpl(Attributor &A, @@ -1081,6 +1020,9 @@ /// See AbstractAttribute::updateImpl(...). ChangeStatus updateImpl(Attributor &A, InformationCache &InfoCache) override; + + /// See AbstractAttribute::trackStatistics() + void trackStatistics() override { STATS_DECL_AND_TRACK_FNRET_ATTR(nonnull) } }; ChangeStatus AANonNullReturned::updateImpl(Attributor &A, @@ -1113,6 +1055,9 @@ /// See AbstractAttribute::updateImpl(...). ChangeStatus updateImpl(Attributor &A, InformationCache &InfoCache) override; + + /// See AbstractAttribute::trackStatistics() + void trackStatistics() override { STATS_DECL_AND_TRACK_ARG_ATTR(nonnull) } }; /// NonNull attribute for a call site argument. @@ -1134,6 +1079,9 @@ /// See AbstractAttribute::updateImpl(Attributor &A). ChangeStatus updateImpl(Attributor &A, InformationCache &InfoCache) override; + + /// See AbstractAttribute::trackStatistics() + void trackStatistics() override { STATS_DECL_AND_TRACK_CSARG_ATTR(nonnull) } }; ChangeStatus AANonNullArgument::updateImpl(Attributor &A, @@ -1207,6 +1155,9 @@ /// See AbstractAttribute::updateImpl(...). ChangeStatus updateImpl(Attributor &A, InformationCache &InfoCache) override; + + /// See AbstractAttribute::trackStatistics() + void trackStatistics() override { STATS_DECL_AND_TRACK_FN_ATTR(willreturn) } }; // Helper function that checks whether a function has any cycle. @@ -1310,6 +1261,9 @@ /// See AbstractAttribute::updateImpl(...). virtual ChangeStatus updateImpl(Attributor &A, InformationCache &InfoCache) override; + + /// See AbstractAttribute::trackStatistics() + void trackStatistics() override { STATS_DECL_AND_TRACK_FNRET_ATTR(noalias) } }; ChangeStatus AANoAliasReturned::updateImpl(Attributor &A, @@ -1951,6 +1905,9 @@ /// See AbstractAttribute::updateImpl(...). ChangeStatus updateImpl(Attributor &A, InformationCache &InfoCache) override; + + /// See AbstractAttribute::trackStatistics() + void trackStatistics() override { STATS_DECL_AND_TRACK_FNRET_ATTR(aligned) } }; ChangeStatus AAAlignReturned::updateImpl(Attributor &A, @@ -1995,6 +1952,9 @@ /// See AbstractAttribute::updateImpl(...). virtual ChangeStatus updateImpl(Attributor &A, InformationCache &InfoCache) override; + + /// See AbstractAttribute::trackStatistics() + void trackStatistics() override{STATS_DECL_AND_TRACK_ARG_ATTR(aligned)}; }; ChangeStatus AAAlignArgument::updateImpl(Attributor &A, @@ -2050,6 +2010,9 @@ /// See AbstractAttribute::updateImpl(Attributor &A). ChangeStatus updateImpl(Attributor &A, InformationCache &InfoCache) override; + + /// See AbstractAttribute::trackStatistics() + void trackStatistics() override { STATS_DECL_AND_TRACK_CSARG_ATTR(aligned) } }; ChangeStatus AAAlignCallSiteArgument::updateImpl(Attributor &A, @@ -2112,6 +2075,9 @@ struct AANoReturnFunction final : AANoReturnImpl { AANoReturnFunction(Function &F) : AANoReturnImpl(F, IRP_FUNCTION) {} + + /// See AbstractAttribute::trackStatistics() + void trackStatistics() override { STATS_DECL_AND_TRACK_FN_ATTR(noreturn) } }; /// ---------------------------------------------------------------------------- @@ -2262,6 +2228,9 @@ // Manifest the state and record if we changed the IR. ChangeStatus LocalChange = AA->manifest(*this); + if (LocalChange == ChangeStatus::CHANGED && AreStatisticsEnabled()) + AA->trackStatistics(); + ManifestChange = ManifestChange | LocalChange; NumAtFixpoint++;