@@ -49,6 +49,13 @@ using namespace llvm;
4949STATISTIC (NumInlined, " Number of functions inlined" );
5050STATISTIC (NumDeleted, " Number of functions deleted because all callers found" );
5151
52+ cl::opt<bool > CtxProfPromoteAlwaysInline (
53+ " ctx-prof-promote-alwaysinline" , cl::init(false ), cl::Hidden,
54+ cl::desc(" If using a contextual profile in this module, and an indirect "
55+ " call target is marked as alwaysinline, perform indirect call "
56+ " promotion for that target. If multiple targets for an indirect "
57+ " call site fit this description, they are all promoted." ));
58+
5259// / Return true if the specified inline history ID
5360// / indicates an inline history that includes the specified function.
5461static bool inlineHistoryIncludes (
@@ -145,10 +152,11 @@ PreservedAnalyses ModuleInlinerPass::run(Module &M,
145152 assert (Calls != nullptr && " Expected an initialized InlineOrder" );
146153
147154 // Populate the initial list of calls in this module.
155+ SetVector<std::pair<CallBase *, Function *>> ICPCandidates;
148156 for (Function &F : M) {
149157 auto &ORE = FAM.getResult <OptimizationRemarkEmitterAnalysis>(F);
150- for (Instruction &I : instructions (F))
151- if (auto *CB = dyn_cast<CallBase>(&I))
158+ for (Instruction &I : instructions (F)) {
159+ if (auto *CB = dyn_cast<CallBase>(&I)) {
152160 if (Function *Callee = CB->getCalledFunction ()) {
153161 if (!Callee->isDeclaration ())
154162 Calls->push ({CB, -1 });
@@ -163,7 +171,17 @@ PreservedAnalyses ModuleInlinerPass::run(Module &M,
163171 << setIsVerbose ();
164172 });
165173 }
174+ } else if (CtxProfPromoteAlwaysInline && CtxProf &&
175+ CB->isIndirectCall ()) {
176+ CtxProfAnalysis::collectIndirectCallPromotionList (*CB, CtxProf,
177+ ICPCandidates);
166178 }
179+ }
180+ }
181+ }
182+ for (auto &[CB, Target] : ICPCandidates) {
183+ if (auto *DirectCB = promoteCallWithIfThenElse (*CB, *Target, CtxProf))
184+ Calls->push ({DirectCB, -1 });
167185 }
168186 if (Calls->empty ())
169187 return PreservedAnalyses::all ();
@@ -242,13 +260,22 @@ PreservedAnalyses ModuleInlinerPass::run(Module &M,
242260 // iteration because the next iteration may not happen and we may
243261 // miss inlining it.
244262 // FIXME: enable for ctxprof.
245- if (!CtxProf)
246- if (tryPromoteCall (*ICB))
247- NewCallee = ICB->getCalledFunction ();
263+ if (CtxProfPromoteAlwaysInline && CtxProf) {
264+ SetVector<std::pair<CallBase *, Function *>> Candidates;
265+ CtxProfAnalysis::collectIndirectCallPromotionList (*ICB, CtxProf,
266+ Candidates);
267+ for (auto &[DC, _] : Candidates) {
268+ assert (!DC->isIndirectCall ());
269+ assert (!DC->getCalledFunction ()->isDeclaration () &&
270+ " CtxProf promotes calls to defined targets only" );
271+ Calls->push ({DC, NewHistoryID});
272+ }
273+ } else if (tryPromoteCall (*ICB)) {
274+ NewCallee = ICB->getCalledFunction ();
275+ if (NewCallee && !NewCallee->isDeclaration ())
276+ Calls->push ({ICB, NewHistoryID});
277+ }
248278 }
249- if (NewCallee)
250- if (!NewCallee->isDeclaration ())
251- Calls->push ({ICB, NewHistoryID});
252279 }
253280 }
254281
0 commit comments