diff --git a/llvm/lib/Analysis/IndirectCallPromotionAnalysis.cpp b/llvm/lib/Analysis/IndirectCallPromotionAnalysis.cpp --- a/llvm/lib/Analysis/IndirectCallPromotionAnalysis.cpp +++ b/llvm/lib/Analysis/IndirectCallPromotionAnalysis.cpp @@ -40,7 +40,7 @@ // Set the maximum number of targets to promote for a single indirect-call // callsite. -static cl::opt +cl::opt MaxNumPromotions("icp-max-prom", cl::init(3), cl::Hidden, cl::ZeroOrMore, cl::desc("Max number of promotions for a single indirect " "call callsite")); diff --git a/llvm/lib/Transforms/Instrumentation/IndirectCallPromotion.cpp b/llvm/lib/Transforms/Instrumentation/IndirectCallPromotion.cpp --- a/llvm/lib/Transforms/Instrumentation/IndirectCallPromotion.cpp +++ b/llvm/lib/Transforms/Instrumentation/IndirectCallPromotion.cpp @@ -65,6 +65,13 @@ ICPCutOff("icp-cutoff", cl::init(0), cl::Hidden, cl::ZeroOrMore, cl::desc("Max number of promotions for this compilation")); +extern cl::opt MaxNumPromotions; + +static cl::opt ICPMissingPercentThreshold( + "icp-missing-percent-threshold", cl::init(50), cl::Hidden, cl::ZeroOrMore, + cl::desc("The percentage threshold of unpromoted indirect call counts to " + "print missed remark")); + // If ICPCSSkip is non zero, the first ICPCSSkip callsites will be skipped. // For debug use only. static cl::opt @@ -354,8 +361,56 @@ uint64_t TotalCount; auto ICallProfDataRef = ICallAnalysis.getPromotionCandidatesForInstruction( CB, NumVals, TotalCount, NumCandidates); - if (!NumCandidates || - (PSI && PSI->hasProfileSummary() && !PSI->isHotCount(TotalCount))) + if (PSI && PSI->hasProfileSummary() && !PSI->isHotCount(TotalCount)) { + if (!ICallProfDataRef.empty()) { + ORE.emit([&]() { + return OptimizationRemarkMissed(DEBUG_TYPE, "ColdCall", CB) + << " Not promoted: cold call"; + }); + } + continue; + } + uint64_t RemainingCount = TotalCount; + for (uint32_t I = 0; I < NumCandidates; I++) { + RemainingCount -= ICallProfDataRef[I].Count; + } + if (ICallProfDataRef.size() > NumCandidates && + RemainingCount * 100 > TotalCount * ICPMissingPercentThreshold) { + ORE.emit([&]() { + OptimizationRemarkMissed R(DEBUG_TYPE, "NotEnoughCoverage", CB); + if (NumCandidates == MaxNumPromotions) { + R << "icp-max-prom (=" + << ore::NV("MaxNumPromotions", MaxNumPromotions) + << ") candidates were chosen, "; + } else { + R << ore::NV("NumCandidates", NumCandidates) + << " candidates were chosen and remaining are not profitable, "; + } + R << "but hasn't reached desired coverage " + << ore::NV("ICPMissingPercentThreshold", ICPMissingPercentThreshold) + << "\% for a hot indirect call, and " + << ore::NV("Candidates", ICallProfDataRef.size() - NumCandidates) + << " candidates left with remaining count " + << ore::NV("RemainingCount", RemainingCount) << " out of total count " + << ore::NV("TotalCount", TotalCount) << " ("; + for (uint32_t I = NumCandidates; I < ICallProfDataRef.size(); I++) { + if (I != NumCandidates) { + R << ", "; + } + uint64_t Target = ICallProfDataRef[I].Value; + StringRef Name = Symtab->getFuncName(Target); + if (Name.empty()) { + R << ore::NV("Target md4sum", Target); + } else { + R << ore::NV("TargetName", Name); + } + R << ": " << ore::NV("Target count", ICallProfDataRef[I].Count); + } + R << ")"; + return R; + }); + } + if (!NumCandidates) continue; auto PromotionCandidates = getPromotionCandidatesForCallSite( *CB, ICallProfDataRef, TotalCount, NumCandidates);