Index: llvm/trunk/include/llvm/Transforms/Instrumentation.h =================================================================== --- llvm/trunk/include/llvm/Transforms/Instrumentation.h +++ llvm/trunk/include/llvm/Transforms/Instrumentation.h @@ -40,6 +40,7 @@ class FunctionPass; class ModulePass; +class OptimizationRemarkEmitter; /// Instrumentation passes often insert conditional checks into entry blocks. /// Call this function before splitting the entry block to move instructions @@ -109,7 +110,8 @@ // Returns the promoted direct call instruction. Instruction *promoteIndirectCall(Instruction *Inst, Function *F, uint64_t Count, uint64_t TotalCount, - bool AttachProfToDirectCall); + bool AttachProfToDirectCall, + OptimizationRemarkEmitter *ORE = nullptr); /// Options for the frontend instrumentation based profiling pass. struct InstrProfOptions { Index: llvm/trunk/lib/Transforms/Instrumentation/IndirectCallPromotion.cpp =================================================================== --- llvm/trunk/lib/Transforms/Instrumentation/IndirectCallPromotion.cpp +++ llvm/trunk/lib/Transforms/Instrumentation/IndirectCallPromotion.cpp @@ -21,6 +21,7 @@ #include "llvm/Analysis/GlobalsModRef.h" #include "llvm/Analysis/IndirectCallPromotionAnalysis.h" #include "llvm/Analysis/IndirectCallSiteVisitor.h" +#include "llvm/Analysis/OptimizationDiagnosticInfo.h" #include "llvm/IR/BasicBlock.h" #include "llvm/IR/CallSite.h" #include "llvm/IR/DerivedTypes.h" @@ -160,9 +161,7 @@ bool SamplePGO; - // Test if we can legally promote this direct-call of Target. - bool isPromotionLegal(Instruction *Inst, uint64_t Target, Function *&F, - const char **Reason = nullptr); + OptimizationRemarkEmitter &ORE; // A struct that records the direct target and it's call count. struct PromotionCandidate { @@ -192,8 +191,8 @@ public: ICallPromotionFunc(Function &Func, Module *Modu, InstrProfSymtab *Symtab, - bool SamplePGO) - : F(Func), M(Modu), Symtab(Symtab), SamplePGO(SamplePGO) {} + bool SamplePGO, OptimizationRemarkEmitter &ORE) + : F(Func), M(Modu), Symtab(Symtab), SamplePGO(SamplePGO), ORE(ORE) {} bool processFunction(); }; @@ -242,17 +241,6 @@ return true; } -bool ICallPromotionFunc::isPromotionLegal(Instruction *Inst, uint64_t Target, - Function *&TargetFunction, - const char **Reason) { - TargetFunction = Symtab->getFunction(Target); - if (TargetFunction == nullptr) { - *Reason = "Cannot find the target"; - return false; - } - return isLegalToPromote(Inst, TargetFunction, Reason); -} - // Indirect-call promotion heuristic. The direct targets are sorted based on // the count. Stop at the first target that is not promoted. std::vector @@ -279,28 +267,41 @@ if (ICPInvokeOnly && dyn_cast(Inst)) { DEBUG(dbgs() << " Not promote: User options.\n"); + ORE.emit(OptimizationRemarkMissed(DEBUG_TYPE, "UserOptions", Inst) + << " Not promote: User options"); break; } if (ICPCallOnly && dyn_cast(Inst)) { DEBUG(dbgs() << " Not promote: User option.\n"); + ORE.emit(OptimizationRemarkMissed(DEBUG_TYPE, "UserOptions", Inst) + << " Not promote: User options"); break; } if (ICPCutOff != 0 && NumOfPGOICallPromotion >= ICPCutOff) { DEBUG(dbgs() << " Not promote: Cutoff reached.\n"); + ORE.emit(OptimizationRemarkMissed(DEBUG_TYPE, "CutOffReached", Inst) + << " Not promote: Cutoff reached"); + break; + } + + Function *TargetFunction = Symtab->getFunction(Target); + if (TargetFunction == nullptr) { + DEBUG(dbgs() << " Not promote: Cannot find the target\n"); + ORE.emit(OptimizationRemarkMissed(DEBUG_TYPE, "UnableToFindTarget", Inst) + << "Cannot promote indirect call: target not found"); break; } - Function *TargetFunction = nullptr; + const char *Reason = nullptr; - if (!isPromotionLegal(Inst, Target, TargetFunction, &Reason)) { - StringRef TargetFuncName = Symtab->getFuncName(Target); - DEBUG(dbgs() << " Not promote: " << Reason << "\n"); - emitOptimizationRemarkMissed( - F.getContext(), "pgo-icall-prom", F, Inst->getDebugLoc(), - Twine("Cannot promote indirect call to ") + - (TargetFuncName.empty() ? Twine(Target) : Twine(TargetFuncName)) + - Twine(" with count of ") + Twine(Count) + ": " + Reason); + if (!isLegalToPromote(Inst, TargetFunction, &Reason)) { + using namespace ore; + ORE.emit(OptimizationRemarkMissed(DEBUG_TYPE, "UnableToPromote", Inst) + << "Cannot promote indirect call to " + << NV("TargetFunction", TargetFunction) << " with count of " + << NV("Count", Count) << ": " << Reason); break; } + Ret.push_back(PromotionCandidate(TargetFunction, Count)); TotalCount -= Count; } @@ -532,7 +533,8 @@ Instruction *llvm::promoteIndirectCall(Instruction *Inst, Function *DirectCallee, uint64_t Count, uint64_t TotalCount, - bool AttachProfToDirectCall) { + bool AttachProfToDirectCall, + OptimizationRemarkEmitter *ORE) { assert(DirectCallee != nullptr); BasicBlock *BB = Inst->getParent(); // Just to suppress the non-debug build warning. @@ -582,10 +584,12 @@ DEBUG(dbgs() << "\n== Basic Blocks After ==\n"); DEBUG(dbgs() << *BB << *DirectCallBB << *IndirectCallBB << *MergeBB << "\n"); - emitOptimizationRemark( - BB->getContext(), "pgo-icall-prom", *BB->getParent(), Inst->getDebugLoc(), - Twine("Promote indirect call to ") + DirectCallee->getName() + - " with count " + Twine(Count) + " out of " + Twine(TotalCount)); + using namespace ore; + if (ORE) + ORE->emit(OptimizationRemark(DEBUG_TYPE, "Promoted", Inst) + << "Promote indirect call to " << NV("DirectCallee", DirectCallee) + << " with count " << NV("Count", Count) << " out of " + << NV("TotalCount", TotalCount)); return NewInst; } @@ -597,7 +601,8 @@ for (auto &C : Candidates) { uint64_t Count = C.Count; - promoteIndirectCall(Inst, C.TargetFunction, Count, TotalCount, SamplePGO); + promoteIndirectCall(Inst, C.TargetFunction, Count, TotalCount, SamplePGO, + &ORE); assert(TotalCount >= Count); TotalCount -= Count; NumOfPGOICallPromotion++; @@ -638,7 +643,8 @@ } // A wrapper function that does the actual work. -static bool promoteIndirectCalls(Module &M, bool InLTO, bool SamplePGO) { +static bool promoteIndirectCalls(Module &M, bool InLTO, bool SamplePGO, + ModuleAnalysisManager *AM = nullptr) { if (DisableICP) return false; InstrProfSymtab Symtab; @@ -654,7 +660,19 @@ continue; if (F.hasFnAttribute(Attribute::OptimizeNone)) continue; - ICallPromotionFunc ICallPromotion(F, &M, &Symtab, SamplePGO); + + std::unique_ptr OwnedORE; + OptimizationRemarkEmitter *ORE; + if (AM) { + auto &FAM = + AM->getResult(M).getManager(); + ORE = &FAM.getResult(F); + } else { + OwnedORE = make_unique(&F); + ORE = OwnedORE.get(); + } + + ICallPromotionFunc ICallPromotion(F, &M, &Symtab, SamplePGO, *ORE); bool FuncChanged = ICallPromotion.processFunction(); if (ICPDUMPAFTER && FuncChanged) { DEBUG(dbgs() << "\n== IR Dump After =="; F.print(dbgs())); @@ -677,8 +695,8 @@ PreservedAnalyses PGOIndirectCallPromotion::run(Module &M, ModuleAnalysisManager &AM) { - if (!promoteIndirectCalls(M, InLTO | ICPLTOMode, - SamplePGO | ICPSamplePGOMode)) + if (!promoteIndirectCalls(M, InLTO | ICPLTOMode, SamplePGO | ICPSamplePGOMode, + &AM)) return PreservedAnalyses::all(); return PreservedAnalyses::none(); Index: llvm/trunk/test/Other/new-pm-lto-defaults.ll =================================================================== --- llvm/trunk/test/Other/new-pm-lto-defaults.ll +++ llvm/trunk/test/Other/new-pm-lto-defaults.ll @@ -4,7 +4,7 @@ ; RUN: opt -disable-verify -debug-pass-manager \ ; RUN: -passes='lto' -S %s 2>&1 \ -; RUN: | FileCheck %s --check-prefix=CHECK-O +; RUN: | FileCheck %s --check-prefix=CHECK-O --check-prefix=CHECK-O1 ; RUN: opt -disable-verify -debug-pass-manager \ ; RUN: -passes='lto' -S %s 2>&1 \ ; RUN: | FileCheck %s --check-prefix=CHECK-O --check-prefix=CHECK-O2 @@ -30,10 +30,12 @@ ; CHECK-O-NEXT: Running pass: InferFunctionAttrsPass ; CHECK-O-NEXT: Running analysis: TargetLibraryAnalysis ; CHECK-O2-NEXT: PGOIndirectCallPromotion +; CHECK-O2-NEXT: Running analysis: InnerAnalysisManagerProxy -; CHECK-O-NEXT: Running analysis: InnerAnalysisManagerProxy -; CHECK-O-NEXT: Running analysis: InnerAnalysisManagerProxy +; CHECK-O-NEXT: Running analysis: InnerAnalysisManagerProxy @@ -52,7 +54,6 @@ ; CHECK-O2-NEXT: Running pass: ModuleToFunctionPassAdaptor<{{.*}}PassManager{{.*}}> ; CHECK-O2-NEXT: Starting llvm::Function pass manager run. ; CHECK-O2-NEXT: Running pass: InstCombinePass -; CHECK-O2-NEXT: Running analysis: OptimizationRemarkEmitterAnalysis ; CHECK-EP-Peephole-NEXT: Running pass: NoOpFunctionPass ; CHECK-O2-NEXT: Finished llvm::Function pass manager run. ; CHECK-O2-NEXT: Running pass: ModuleToPostOrderCGSCCPassAdaptor<{{.*}}InlinerPass> Index: llvm/trunk/test/Other/new-pm-thinlto-defaults.ll =================================================================== --- llvm/trunk/test/Other/new-pm-thinlto-defaults.ll +++ llvm/trunk/test/Other/new-pm-thinlto-defaults.ll @@ -46,12 +46,14 @@ ; CHECK-O-NEXT: Starting llvm::Module pass manager run. ; CHECK-O-NEXT: Running pass: ForceFunctionAttrsPass ; CHECK-POSTLINK-O-NEXT: Running pass: PGOIndirectCallPromotion +; CHECK-POSTLINK-O-NEXT: Running analysis: InnerAnalysisManagerProxy ; CHECK-O-NEXT: Starting llvm::Module pass manager run. ; CHECK-O-NEXT: Running pass: InferFunctionAttrsPass ; CHECK-O-NEXT: Running analysis: TargetLibraryAnalysis ; CHECK-O-NEXT: Running pass: ModuleToFunctionPassAdaptor<{{.*}}PassManager{{.*}}> -; CHECK-O-NEXT: Running analysis: InnerAnalysisManagerProxy +; CHECK-PRELINK-O-NEXT: Running analysis: InnerAnalysisManagerProxy ; CHECK-O-NEXT: Starting llvm::Function pass manager run. ; CHECK-O-NEXT: Running pass: SimplifyCFGPass ; CHECK-O-NEXT: Running analysis: TargetIRAnalysis @@ -69,7 +71,7 @@ ; CHECK-O-NEXT: Running pass: ModuleToFunctionPassAdaptor<{{.*}}PassManager{{.*}}> ; CHECK-O-NEXT: Starting llvm::Function pass manager run. ; CHECK-O-NEXT: Running pass: InstCombinePass -; CHECK-O-NEXT: Running analysis: OptimizationRemarkEmitterAnalysis +; CHECK-PRELINK-O-NEXT: Running analysis: OptimizationRemarkEmitterAnalysis ; CHECK-O-NEXT: Running pass: SimplifyCFGPass ; CHECK-O-NEXT: Finished llvm::Function pass manager run. ; CHECK-O-NEXT: Running pass: RequireAnalysisPass<{{.*}}GlobalsAA Index: llvm/trunk/test/Transforms/PGOProfile/icp_mismatch_msg.ll =================================================================== --- llvm/trunk/test/Transforms/PGOProfile/icp_mismatch_msg.ll +++ llvm/trunk/test/Transforms/PGOProfile/icp_mismatch_msg.ll @@ -2,7 +2,7 @@ ; RUN: opt < %s -passes=pgo-icall-prom -pass-remarks-missed=pgo-icall-prom -S 2>& 1 | FileCheck %s ; CHECK: remark: :0:0: Cannot promote indirect call to func4 with count of 1234: The number of arguments mismatch -; CHECK: remark: :0:0: Cannot promote indirect call to 11517462787082255043 with count of 2345: Cannot find the target +; CHECK: remark: :0:0: Cannot promote indirect call: target not found ; CHECK: remark: :0:0: Cannot promote indirect call to func2 with count of 7890: Return type mismatch target datalayout = "e-m:e-i64:64-f80:128-n8:16:32:64-S128"