Index: include/llvm/Analysis/OptimizationDiagnosticInfo.h =================================================================== --- include/llvm/Analysis/OptimizationDiagnosticInfo.h +++ include/llvm/Analysis/OptimizationDiagnosticInfo.h @@ -16,6 +16,7 @@ #define LLVM_IR_OPTIMIZATIONDIAGNOSTICINFO_H #include "llvm/ADT/Optional.h" +#include "llvm/IR/PassManager.h" #include "llvm/Pass.h" namespace llvm { @@ -28,9 +29,19 @@ class Twine; class Value; -class OptimizationRemarkEmitter : public FunctionPass { +class OptimizationRemarkEmitter { public: - OptimizationRemarkEmitter(); + OptimizationRemarkEmitter(Function *F, BlockFrequencyInfo *BFI) + : F(F), BFI(BFI) {} + + OptimizationRemarkEmitter(OptimizationRemarkEmitter &&Arg) + : F(Arg.F), BFI(Arg.BFI) {} + + OptimizationRemarkEmitter &operator=(OptimizationRemarkEmitter &&RHS) { + F = RHS.F; + BFI = RHS.BFI; + return *this; + } /// Emit an optimization-missed message. /// @@ -48,19 +59,46 @@ void emitOptimizationRemarkMissed(const char *PassName, Loop *L, const Twine &Msg); +private: + Function *F; + + BlockFrequencyInfo *BFI; + + Optional computeHotness(Value *V); + + OptimizationRemarkEmitter(const OptimizationRemarkEmitter &) = delete; + void operator=(const OptimizationRemarkEmitter &) = delete; +}; + +class OptimizationRemarkEmitterWrapperPass : public FunctionPass { + std::unique_ptr ORE; + +public: + OptimizationRemarkEmitterWrapperPass(); + bool runOnFunction(Function &F) override; void getAnalysisUsage(AnalysisUsage &AU) const override; + OptimizationRemarkEmitter &getORE() { + assert(ORE && "pass not run yet"); + return *ORE; + } + static char ID; +}; -private: - Function *F; +class OptimizationRemarkEmitterAnalysis + : public AnalysisInfoMixin { + friend AnalysisInfoMixin; + static char PassID; - BlockFrequencyInfo *BFI; +public: + /// \brief Provide the result typedef for this analysis pass. + typedef OptimizationRemarkEmitter Result; - Optional computeHotness(Value *V); + /// \brief Run the analysis pass over a function and produce BFI. + Result run(Function &F, AnalysisManager &AM); }; } - #endif // LLVM_IR_OPTIMIZATIONDIAGNOSTICINFO_H Index: include/llvm/InitializePasses.h =================================================================== --- include/llvm/InitializePasses.h +++ include/llvm/InitializePasses.h @@ -243,7 +243,7 @@ void initializeObjCARCContractPass(PassRegistry&); void initializeObjCARCExpandPass(PassRegistry&); void initializeObjCARCOptPass(PassRegistry&); -void initializeOptimizationRemarkEmitterPass(PassRegistry&); +void initializeOptimizationRemarkEmitterWrapperPassPass(PassRegistry&); void initializeOptimizePHIsPass(PassRegistry&); void initializePAEvalPass(PassRegistry &); void initializePEIPass(PassRegistry&); Index: lib/Analysis/Analysis.cpp =================================================================== --- lib/Analysis/Analysis.cpp +++ lib/Analysis/Analysis.cpp @@ -64,7 +64,7 @@ initializeModuleDebugInfoPrinterPass(Registry); initializeModuleSummaryIndexWrapperPassPass(Registry); initializeObjCARCAAWrapperPassPass(Registry); - initializeOptimizationRemarkEmitterPass(Registry); + initializeOptimizationRemarkEmitterWrapperPassPass(Registry); initializePostDominatorTreeWrapperPassPass(Registry); initializeRegionInfoPassPass(Registry); initializeRegionViewerPass(Registry); Index: lib/Analysis/OptimizationDiagnosticInfo.cpp =================================================================== --- lib/Analysis/OptimizationDiagnosticInfo.cpp +++ lib/Analysis/OptimizationDiagnosticInfo.cpp @@ -20,10 +20,6 @@ using namespace llvm; -OptimizationRemarkEmitter::OptimizationRemarkEmitter() : FunctionPass(ID) { - initializeOptimizationRemarkEmitterPass(*PassRegistry::getPassRegistry()); -} - Optional OptimizationRemarkEmitter::computeHotness(Value *V) { if (!BFI) return None; @@ -43,27 +39,50 @@ emitOptimizationRemarkMissed(PassName, L->getStartLoc(), L->getHeader(), Msg); } -bool OptimizationRemarkEmitter::runOnFunction(Function &Fn) { - F = &Fn; +OptimizationRemarkEmitterWrapperPass::OptimizationRemarkEmitterWrapperPass() + : FunctionPass(ID) { + initializeOptimizationRemarkEmitterWrapperPassPass( + *PassRegistry::getPassRegistry()); +} + +bool OptimizationRemarkEmitterWrapperPass::runOnFunction(Function &Fn) { + BlockFrequencyInfo *BFI; if (Fn.getContext().getDiagnosticHotnessRequested()) BFI = &getAnalysis().getBFI(); else BFI = nullptr; + ORE = llvm::make_unique(&Fn, BFI); return false; } -void OptimizationRemarkEmitter::getAnalysisUsage(AnalysisUsage &AU) const { +void OptimizationRemarkEmitterWrapperPass::getAnalysisUsage( + AnalysisUsage &AU) const { LazyBlockFrequencyInfoPass::getLazyBFIAnalysisUsage(AU); AU.setPreservesAll(); } -char OptimizationRemarkEmitter::ID = 0; +char OptimizationRemarkEmitterAnalysis::PassID; + +OptimizationRemarkEmitter +OptimizationRemarkEmitterAnalysis::run(Function &F, AnalysisManager &AM) { + BlockFrequencyInfo *BFI; + + if (F.getContext().getDiagnosticHotnessRequested()) + BFI = &AM.getResult(F); + else + BFI = nullptr; + + return OptimizationRemarkEmitter(&F, BFI); +} + +char OptimizationRemarkEmitterWrapperPass::ID = 0; static const char ore_name[] = "Optimization Remark Emitter"; #define ORE_NAME "opt-remark-emitter" -INITIALIZE_PASS_BEGIN(OptimizationRemarkEmitter, ORE_NAME, ore_name, false, - true) +INITIALIZE_PASS_BEGIN(OptimizationRemarkEmitterWrapperPass, ORE_NAME, ore_name, + false, true) INITIALIZE_PASS_DEPENDENCY(LazyBFIPass) -INITIALIZE_PASS_END(OptimizationRemarkEmitter, ORE_NAME, ore_name, false, true) +INITIALIZE_PASS_END(OptimizationRemarkEmitterWrapperPass, ORE_NAME, ore_name, + false, true) Index: lib/Passes/PassBuilder.cpp =================================================================== --- lib/Passes/PassBuilder.cpp +++ lib/Passes/PassBuilder.cpp @@ -37,6 +37,7 @@ #include "llvm/Analysis/LoopAccessAnalysis.h" #include "llvm/Analysis/LoopInfo.h" #include "llvm/Analysis/MemoryDependenceAnalysis.h" +#include "llvm/Analysis/OptimizationDiagnosticInfo.h" #include "llvm/Analysis/PostDominators.h" #include "llvm/Analysis/ProfileSummaryInfo.h" #include "llvm/Analysis/RegionInfo.h" Index: lib/Passes/PassRegistry.def =================================================================== --- lib/Passes/PassRegistry.def +++ lib/Passes/PassRegistry.def @@ -101,6 +101,7 @@ FUNCTION_ANALYSIS("memoryssa", MemorySSAAnalysis()) FUNCTION_ANALYSIS("regions", RegionInfoAnalysis()) FUNCTION_ANALYSIS("no-op-function", NoOpFunctionAnalysis()) +FUNCTION_ANALYSIS("opt-remark-emit", OptimizationRemarkEmitterAnalysis()) FUNCTION_ANALYSIS("scalar-evolution", ScalarEvolutionAnalysis()) FUNCTION_ANALYSIS("targetlibinfo", TargetLibraryAnalysis()) FUNCTION_ANALYSIS("targetir", Index: lib/Transforms/Scalar/LoopDistribute.cpp =================================================================== --- lib/Transforms/Scalar/LoopDistribute.cpp +++ lib/Transforms/Scalar/LoopDistribute.cpp @@ -883,7 +883,7 @@ auto *LAA = &getAnalysis(); auto *DT = &getAnalysis().getDomTree(); auto *SE = &getAnalysis().getSE(); - auto *ORE = &getAnalysis(); + auto *ORE = &getAnalysis().getORE(); // Build up a worklist of inner-loops to vectorize. This is necessary as the // act of distributing a loop creates new loops and can invalidate iterators @@ -918,7 +918,7 @@ AU.addRequired(); AU.addRequired(); AU.addPreserved(); - AU.addRequired(); + AU.addRequired(); } static char ID; @@ -938,7 +938,7 @@ INITIALIZE_PASS_DEPENDENCY(LoopAccessLegacyAnalysis) INITIALIZE_PASS_DEPENDENCY(DominatorTreeWrapperPass) INITIALIZE_PASS_DEPENDENCY(ScalarEvolutionWrapperPass) -INITIALIZE_PASS_DEPENDENCY(OptimizationRemarkEmitter) +INITIALIZE_PASS_DEPENDENCY(OptimizationRemarkEmitterWrapperPass) INITIALIZE_PASS_END(LoopDistribute, LDIST_NAME, ldist_name, false, false) namespace llvm {