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 @@ -111,6 +111,7 @@ #include "llvm/Analysis/MustExecute.h" #include "llvm/Analysis/PostDominators.h" #include "llvm/Analysis/TargetLibraryInfo.h" +#include "llvm/Analysis/OptimizationRemarkEmitter.h" #include "llvm/IR/AbstractCallSite.h" #include "llvm/IR/ConstantRange.h" #include "llvm/IR/PassManager.h" @@ -1066,6 +1067,10 @@ /// NOTE: The mechanics of adding a new "concrete" abstract attribute are /// described in the file comment. struct Attributor { + + using OptimizationRemarkGetter = + function_ref; + /// Constructor /// /// \param Functions The set of functions we are deriving attributes for. @@ -1079,7 +1084,28 @@ DenseSet *Allowed = nullptr, bool DeleteFns = true) : Allocator(InfoCache.Allocator), Functions(Functions), InfoCache(InfoCache), CGUpdater(CGUpdater), Allowed(Allowed), - DeleteFns(DeleteFns) {} + DeleteFns(DeleteFns), OREGetter(None), PassName("") {} + + /// Constructor + /// + /// \param Functions The set of functions we are deriving attributes for. + /// \param InfoCache Cache to hold various information accessible for + /// the abstract attributes. + /// \param CGUpdater Helper to update an underlying call graph. + /// \param Allowed If not null, a set limiting the attribute opportunities. + /// \param DeleteFns Whether to delete functions + /// \param OREGetter A callback function that returns an ORE object from a + /// Function pointer. + /// \param PassName The name of the pass emitting remarks. + Attributor(SetVector &Functions, InformationCache &InfoCache, + CallGraphUpdater &CGUpdater, + DenseSet *Allowed, bool DeleteFns, + OptimizationRemarkGetter OREGetter, const char *PassName) + : Allocator(InfoCache.Allocator), Functions(Functions), + InfoCache(InfoCache), CGUpdater(CGUpdater), Allowed(Allowed), + DeleteFns(DeleteFns), + OREGetter(Optional(OREGetter)), + PassName(PassName) {} ~Attributor(); @@ -1440,6 +1466,30 @@ const AbstractAttribute &QueryingAA, const Value &V, DepClassTy LivenessDepClass = DepClassTy::OPTIONAL); + /// Emit a remark generically. + /// + /// This template function can be used to generically emit a remark. The + /// RemarkKind should be one of the following: + /// - OptimizationRemark to indicate a successful optimization attempt + /// - OptimizationRemarkMissed to report a failed optimization attempt + /// - OptimizationRemarkAnalysis to provide additional information about an + /// optimization attempt + /// + /// The remark is built using a callback function provided by the caller that + /// takes a RemarkKind as input and returns a RemarkKind. + template + void emitRemark(Instruction *Inst, StringRef RemarkName, + RemarkCallBack &&RemarkCB) const { + if (!OREGetter) + return; + auto &Getter = OREGetter.getValue(); + Function *F = Inst->getParent()->getParent(); + auto &ORE = Getter(F); + + ORE.emit( + [&]() { return RemarkCB(RemarkKind(PassName, RemarkName, Inst)); }); + } + /// Helper struct used in the communication between an abstract attribute (AA) /// that wants to change the signature of a function and the Attributor which /// applies the changes. The struct is partially initialized with the @@ -1758,6 +1808,10 @@ SmallDenseSet ToBeDeletedInsts; ///} + Optional OREGetter; + + const char *PassName; + friend AADepGraph; }; diff --git a/llvm/lib/Transforms/IPO/AttributorAttributes.cpp b/llvm/lib/Transforms/IPO/AttributorAttributes.cpp --- a/llvm/lib/Transforms/IPO/AttributorAttributes.cpp +++ b/llvm/lib/Transforms/IPO/AttributorAttributes.cpp @@ -5035,6 +5035,11 @@ LLVM_DEBUG(dbgs() << "H2S: Removing malloc call: " << *MallocCall << "\n"); + auto Remark = [&](OptimizationRemark OR) { + return OR << "Moving memory allocation to the stack."; + }; + A.emitRemark(MallocCall, "HeapToStack", Remark); + Align Alignment; Value *Size; if (isCallocLikeFn(MallocCall, TLI)) { diff --git a/llvm/lib/Transforms/IPO/OpenMPOpt.cpp b/llvm/lib/Transforms/IPO/OpenMPOpt.cpp --- a/llvm/lib/Transforms/IPO/OpenMPOpt.cpp +++ b/llvm/lib/Transforms/IPO/OpenMPOpt.cpp @@ -2494,7 +2494,7 @@ OMPInformationCache InfoCache(M, AG, Allocator, /*CGSCC*/ Functions, OMPInModule.getKernels()); - Attributor A(Functions, InfoCache, CGUpdater); + Attributor A(Functions, InfoCache, CGUpdater, nullptr, true, OREGetter, DEBUG_TYPE); OpenMPOpt OMPOpt(SCC, CGUpdater, OREGetter, InfoCache, A); bool Changed = OMPOpt.run(true); @@ -2549,7 +2549,7 @@ OMPInformationCache InfoCache(*(Functions.back()->getParent()), AG, Allocator, /*CGSCC*/ Functions, OMPInModule.getKernels()); - Attributor A(Functions, InfoCache, CGUpdater); + Attributor A(Functions, InfoCache, CGUpdater, nullptr, false, OREGetter, DEBUG_TYPE); OpenMPOpt OMPOpt(SCC, CGUpdater, OREGetter, InfoCache, A); bool Changed = OMPOpt.run(false); @@ -2624,7 +2624,7 @@ *(Functions.back()->getParent()), AG, Allocator, /*CGSCC*/ Functions, OMPInModule.getKernels()); - Attributor A(Functions, InfoCache, CGUpdater); + Attributor A(Functions, InfoCache, CGUpdater, nullptr, false, OREGetter, DEBUG_TYPE); OpenMPOpt OMPOpt(SCC, CGUpdater, OREGetter, InfoCache, A); return OMPOpt.run(false);