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 @@ -13,6 +13,7 @@ #include "bolt/Passes/IndirectCallPromotion.h" #include "bolt/Passes/BinaryFunctionCallGraph.h" #include "bolt/Passes/DataflowInfoManager.h" +#include "bolt/Passes/Inliner.h" #include "llvm/Support/CommandLine.h" #define DEBUG_TYPE "ICP" @@ -120,6 +121,10 @@ "for jump tables, optimize indirect jmp targets instead of indices"), cl::init(false), cl::ZeroOrMore, cl::Hidden, cl::cat(BoltOptCategory)); +static cl::opt ICPPeelForInline( + "icp-inline", cl::desc("only promote call targets eligible for inlining"), + cl::init(false), cl::ZeroOrMore, cl::Hidden, cl::cat(BoltOptCategory)); + } // namespace opts namespace llvm { @@ -1038,6 +1043,20 @@ } } + // Filter by inline-ability of target functions, stop at first target that + // can't be inlined. + if (opts::ICPPeelForInline) { + for (size_t I = 0; I < N; ++I) { + const MCSymbol *TargetSym = Targets[I].To.Sym; + const BinaryFunction *TargetBF = BC.getFunctionForSymbol(TargetSym); + if (!BinaryFunctionPass::shouldOptimize(*TargetBF) || + getInliningInfo(*TargetBF).Type == InliningType::INL_NONE) { + N = I; + break; + } + } + } + // Filter functions that can have ICP applied (for debugging) if (!opts::ICPFuncsList.empty()) { for (std::string &Name : opts::ICPFuncsList)