diff --git a/bolt/lib/Passes/IndirectCallPromotion.cpp b/bolt/lib/Passes/IndirectCallPromotion.cpp --- a/bolt/lib/Passes/IndirectCallPromotion.cpp +++ b/bolt/lib/Passes/IndirectCallPromotion.cpp @@ -203,7 +203,7 @@ IndirectCallPromotion::getCallTargets(BinaryBasicBlock &BB, const MCInst &Inst) const { BinaryFunction &BF = *BB.getFunction(); - BinaryContext &BC = BF.getBinaryContext(); + const BinaryContext &BC = BF.getBinaryContext(); std::vector Targets; if (const JumpTable *JT = BF.getJumpTable(Inst)) { @@ -509,6 +509,7 @@ return SymTargets; } + // Use memory profile to select hot targets. JumpTableInfoType HotTargets = maybeGetHotJumpTableTargets(BB, CallInst, TargetFetchInst, JT); @@ -914,25 +915,28 @@ size_t IndirectCallPromotion::canPromoteCallsite( const BinaryBasicBlock &BB, const MCInst &Inst, const std::vector &Targets, uint64_t NumCalls) { + BinaryFunction *BF = BB.getFunction(); + const BinaryContext &BC = BF->getBinaryContext(); + if (BB.getKnownExecutionCount() < opts::ExecutionCountThreshold) return 0; - const bool IsJumpTable = BB.getFunction()->getJumpTable(Inst); + const bool IsJumpTable = BF->getJumpTable(Inst); auto computeStats = [&](size_t N) { for (size_t I = 0; I < N; ++I) - if (!IsJumpTable) - TotalNumFrequentCalls += Targets[I].Branches; - else + if (IsJumpTable) TotalNumFrequentJmps += Targets[I].Branches; + else + TotalNumFrequentCalls += Targets[I].Branches; }; // If we have no targets (or no calls), skip this callsite. if (Targets.empty() || !NumCalls) { if (opts::Verbosity >= 1) { const ptrdiff_t InstIdx = &Inst - &(*BB.begin()); - outs() << "BOLT-INFO: ICP failed in " << *BB.getFunction() << " @ " - << InstIdx << " in " << BB.getName() << ", calls = " << NumCalls + outs() << "BOLT-INFO: ICP failed in " << *BF << " @ " << InstIdx << " in " + << BB.getName() << ", calls = " << NumCalls << ", targets empty or NumCalls == 0.\n"; } return 0; @@ -947,7 +951,6 @@ const size_t TrialN = TopN ? std::min(TopN, Targets.size()) : Targets.size(); if (opts::ICPTopCallsites > 0) { - BinaryContext &BC = BB.getFunction()->getBinaryContext(); if (!BC.MIB->hasAnnotation(Inst, "DoICP")) return 0; } @@ -975,8 +978,8 @@ if (TopNFrequency == 0 || TopNFrequency < opts::ICPMispredictThreshold) { if (opts::Verbosity >= 1) { const ptrdiff_t InstIdx = &Inst - &(*BB.begin()); - outs() << "BOLT-INFO: ICP failed in " << *BB.getFunction() << " @ " - << InstIdx << " in " << BB.getName() << ", calls = " << NumCalls + outs() << "BOLT-INFO: ICP failed in " << *BF << " @ " << InstIdx + << " in " << BB.getName() << ", calls = " << NumCalls << ", top N mis. frequency " << format("%.1f", TopNFrequency) << "% < " << opts::ICPMispredictThreshold << "%\n"; } @@ -1021,9 +1024,9 @@ if (TopNMispredictFrequency < opts::ICPMispredictThreshold) { if (opts::Verbosity >= 1) { const ptrdiff_t InstIdx = &Inst - &(*BB.begin()); - outs() << "BOLT-INFO: ICP failed in " << *BB.getFunction() << " @ " - << InstIdx << " in " << BB.getName() - << ", calls = " << NumCalls << ", top N mispredict frequency " + outs() << "BOLT-INFO: ICP failed in " << *BF << " @ " << InstIdx + << " in " << BB.getName() << ", calls = " << NumCalls + << ", top N mispredict frequency " << format("%.1f", TopNMispredictFrequency) << "% < " << opts::ICPMispredictThreshold << "%\n"; } @@ -1035,7 +1038,7 @@ // Filter functions that can have ICP applied (for debugging) if (!opts::ICPFuncsList.empty()) { for (std::string &Name : opts::ICPFuncsList) - if (BB.getFunction()->hasName(Name)) + if (BF->hasName(Name)) return N; return 0; }