@@ -75,19 +75,15 @@ InlinedArrayAllocasTy;
75
75
// / available from other functions inlined into the caller. If we are able to
76
76
// / inline this call site we attempt to reuse already available allocas or add
77
77
// / any new allocas to the set if not possible.
78
- static bool InlineCallIfPossible (Pass &P, CallSite CS, InlineFunctionInfo &IFI,
79
- InlinedArrayAllocasTy &InlinedArrayAllocas,
80
- int InlineHistory, bool InsertLifetime) {
78
+ static bool
79
+ InlineCallIfPossible (CallSite CS, InlineFunctionInfo &IFI,
80
+ InlinedArrayAllocasTy &InlinedArrayAllocas,
81
+ int InlineHistory, bool InsertLifetime,
82
+ std::function<AAResults &(Function &)> &AARGetter) {
81
83
Function *Callee = CS.getCalledFunction ();
82
84
Function *Caller = CS.getCaller ();
83
85
84
- // We need to manually construct BasicAA directly in order to disable
85
- // its use of other function analyses.
86
- BasicAAResult BAR (createLegacyPMBasicAAResult (P, *Callee));
87
-
88
- // Construct our own AA results for this function. We do this manually to
89
- // work around the limitations of the legacy pass manager.
90
- AAResults AAR (createLegacyPMAAResults (P, *Callee, BAR));
86
+ AAResults &AAR = AARGetter (*Callee);
91
87
92
88
// Try to inline the function. Get the list of static allocas that were
93
89
// inlined.
@@ -229,8 +225,15 @@ static void emitAnalysis(CallSite CS, const Twine &Msg) {
229
225
emitOptimizationRemarkAnalysis (Ctx, DEBUG_TYPE, *Caller, DLoc, Msg);
230
226
}
231
227
232
- bool Inliner::shouldBeDeferred (Function *Caller, CallSite CS, InlineCost IC,
233
- int &TotalSecondaryCost) {
228
+ // / Return true if inlining of CS can block the caller from being
229
+ // / inlined which is proved to be more beneficial. \p IC is the
230
+ // / estimated inline cost associated with callsite \p CS.
231
+ // / \p TotalAltCost will be set to the estimated cost of inlining the caller
232
+ // / if \p CS is suppressed for inlining.
233
+ static bool
234
+ shouldBeDeferred (Function *Caller, CallSite CS, InlineCost IC,
235
+ int &TotalSecondaryCost,
236
+ std::function<InlineCost(CallSite CS)> &GetInlineCost) {
234
237
235
238
// For now we only handle local or inline functions.
236
239
if (!Caller->hasLocalLinkage () && !Caller->hasLinkOnceODRLinkage ())
@@ -269,7 +272,7 @@ bool Inliner::shouldBeDeferred(Function *Caller, CallSite CS, InlineCost IC,
269
272
continue ;
270
273
}
271
274
272
- InlineCost IC2 = getInlineCost (CS2);
275
+ InlineCost IC2 = GetInlineCost (CS2);
273
276
++NumCallerCallersAnalyzed;
274
277
if (!IC2) {
275
278
callerWillBeRemoved = false ;
@@ -300,8 +303,9 @@ bool Inliner::shouldBeDeferred(Function *Caller, CallSite CS, InlineCost IC,
300
303
}
301
304
302
305
// / Return true if the inliner should attempt to inline at the given CallSite.
303
- bool Inliner::shouldInline (CallSite CS) {
304
- InlineCost IC = getInlineCost (CS);
306
+ static bool shouldInline (CallSite CS,
307
+ std::function<InlineCost(CallSite CS)> GetInlineCost) {
308
+ InlineCost IC = GetInlineCost (CS);
305
309
306
310
if (IC.isAlways ()) {
307
311
DEBUG (dbgs () << " Inlining: cost=always"
@@ -332,7 +336,7 @@ bool Inliner::shouldInline(CallSite CS) {
332
336
}
333
337
334
338
int TotalSecondaryCost = 0 ;
335
- if (shouldBeDeferred (Caller, CS, IC, TotalSecondaryCost)) {
339
+ if (shouldBeDeferred (Caller, CS, IC, TotalSecondaryCost, GetInlineCost )) {
336
340
DEBUG (dbgs () << " NOT Inlining: " << *CS.getInstruction ()
337
341
<< " Cost = " << IC.getCost ()
338
342
<< " , outer Cost = " << TotalSecondaryCost << ' \n ' );
@@ -370,15 +374,17 @@ static bool InlineHistoryIncludes(Function *F, int InlineHistoryID,
370
374
bool Inliner::runOnSCC (CallGraphSCC &SCC) {
371
375
if (skipSCC (SCC))
372
376
return false ;
377
+
373
378
return inlineCalls (SCC);
374
379
}
375
380
376
- bool Inliner::inlineCalls (CallGraphSCC &SCC) {
377
- CallGraph &CG = getAnalysis<CallGraphWrapperPass>().getCallGraph ();
378
- ACT = &getAnalysis<AssumptionCacheTracker>();
379
- PSI = getAnalysis<ProfileSummaryInfoWrapperPass>().getPSI (CG.getModule ());
380
- auto &TLI = getAnalysis<TargetLibraryInfoWrapperPass>().getTLI ();
381
-
381
+ static bool
382
+ inlineCallsImpl (CallGraphSCC &SCC, CallGraph &CG,
383
+ std::function<AssumptionCache &(Function &)> GetAssumptionCache,
384
+ ProfileSummaryInfo *PSI, TargetLibraryInfo &TLI,
385
+ bool InsertLifetime,
386
+ std::function<InlineCost(CallSite CS)> GetInlineCost,
387
+ std::function<AAResults &(Function &)> AARGetter) {
382
388
SmallPtrSet<Function*, 8 > SCCFunctions;
383
389
DEBUG (dbgs () << " Inliner visiting SCC:" );
384
390
for (CallGraphNode *Node : SCC) {
@@ -437,7 +443,7 @@ bool Inliner::inlineCalls(CallGraphSCC &SCC) {
437
443
438
444
439
445
InlinedArrayAllocasTy InlinedArrayAllocas;
440
- InlineFunctionInfo InlineInfo (&CG, ACT );
446
+ InlineFunctionInfo InlineInfo (&CG, &GetAssumptionCache );
441
447
442
448
// Now that we have all of the call sites, loop over them and inline them if
443
449
// it looks profitable to do so.
@@ -486,7 +492,7 @@ bool Inliner::inlineCalls(CallGraphSCC &SCC) {
486
492
487
493
// If the policy determines that we should inline this function,
488
494
// try to do so.
489
- if (!shouldInline (CS)) {
495
+ if (!shouldInline (CS, GetInlineCost )) {
490
496
emitOptimizationRemarkMissed (CallerCtx, DEBUG_TYPE, *Caller, DLoc,
491
497
Twine (Callee->getName () +
492
498
" will not be inlined into " +
@@ -495,8 +501,8 @@ bool Inliner::inlineCalls(CallGraphSCC &SCC) {
495
501
}
496
502
497
503
// Attempt to inline the function.
498
- if (!InlineCallIfPossible (* this , CS, InlineInfo, InlinedArrayAllocas,
499
- InlineHistoryID, InsertLifetime)) {
504
+ if (!InlineCallIfPossible (CS, InlineInfo, InlinedArrayAllocas,
505
+ InlineHistoryID, InsertLifetime, AARGetter )) {
500
506
emitOptimizationRemarkMissed (CallerCtx, DEBUG_TYPE, *Caller, DLoc,
501
507
Twine (Callee->getName () +
502
508
" will not be inlined into " +
@@ -565,6 +571,29 @@ bool Inliner::inlineCalls(CallGraphSCC &SCC) {
565
571
return Changed;
566
572
}
567
573
574
+ bool Inliner::inlineCalls (CallGraphSCC &SCC) {
575
+ CallGraph &CG = getAnalysis<CallGraphWrapperPass>().getCallGraph ();
576
+ ACT = &getAnalysis<AssumptionCacheTracker>();
577
+ PSI = getAnalysis<ProfileSummaryInfoWrapperPass>().getPSI (CG.getModule ());
578
+ auto &TLI = getAnalysis<TargetLibraryInfoWrapperPass>().getTLI ();
579
+ // We compute dedicated AA results for each function in the SCC as needed. We
580
+ // use a lambda referencing external objects so that they live long enough to
581
+ // be queried, but we re-use them each time.
582
+ Optional<BasicAAResult> BAR;
583
+ Optional<AAResults> AAR;
584
+ auto AARGetter = [&](Function &F) -> AAResults & {
585
+ BAR.emplace (createLegacyPMBasicAAResult (*this , F));
586
+ AAR.emplace (createLegacyPMAAResults (*this , F, *BAR));
587
+ return *AAR;
588
+ };
589
+ auto GetAssumptionCache = [&](Function &F) -> AssumptionCache & {
590
+ return ACT->getAssumptionCache (F);
591
+ };
592
+ return inlineCallsImpl (SCC, CG, GetAssumptionCache, PSI, TLI, InsertLifetime,
593
+ [this ](CallSite CS) { return getInlineCost (CS); },
594
+ AARGetter);
595
+ }
596
+
568
597
// / Remove now-dead linkonce functions at the end of
569
598
// / processing to avoid breaking the SCC traversal.
570
599
bool Inliner::doFinalization (CallGraph &CG) {
0 commit comments