@@ -234,6 +234,7 @@ namespace {
234
234
235
235
SILFunction *getEligibleFunction (FullApplySite AI);
236
236
237
+ // / Return true if inlining this call site is profitable.
237
238
bool isProfitableToInline (FullApplySite AI, unsigned loopDepthOfAI,
238
239
DominanceAnalysis *DA,
239
240
SILLoopAnalysis *LA,
@@ -724,59 +725,55 @@ static SILBasicBlock *getTakenBlock(TermInst *term,
724
725
return nullptr ;
725
726
}
726
727
727
- // / Return true if inlining this call site is profitable.
728
- bool SILPerformanceInliner::isProfitableToInline (FullApplySite AI,
729
- unsigned loopDepthOfAI,
730
- DominanceAnalysis *DA,
731
- SILLoopAnalysis *LA,
732
- ConstantTracker &callerTracker,
733
- unsigned &NumCallerBlocks) {
734
- SILFunction *Callee = AI.getCalleeFunction ();
735
-
736
- if (Callee->getInlineStrategy () == AlwaysInline)
737
- return true ;
738
-
739
- ConstantTracker constTracker (Callee, &callerTracker, AI);
740
-
728
+
729
+ // / Return a pair of cost/benefit integers for the callee.
730
+ // / The cost is the size added to the caller, and the benefit is the
731
+ // / performance gain.
732
+ static std::pair<unsigned , unsigned >
733
+ getCostBenefitInfo (FullApplySite CallSite,
734
+ unsigned loopDepthOfAI,
735
+ DominanceAnalysis *DA,
736
+ SILLoopAnalysis *LA,
737
+ ConstantTracker &callerTracker,
738
+ unsigned InlineCostThreshold) {
739
+ SILFunction *Callee = CallSite.getCalleeFunction ();
740
+ ConstantTracker constTracker (Callee, &callerTracker, CallSite);
741
741
DominanceInfo *DT = DA->get (Callee);
742
742
SILLoopInfo *LI = LA->get (Callee);
743
743
744
744
DominanceOrder domOrder (&Callee->front (), DT, Callee->size ());
745
-
745
+
746
746
// Calculate the inlining cost of the callee.
747
- unsigned CalleeCost = 0 ;
747
+ unsigned Cost = 0 ;
748
748
unsigned Benefit = InlineCostThreshold > 0 ? InlineCostThreshold :
749
749
RemovedCallBenefit;
750
750
Benefit += loopDepthOfAI * LoopBenefitFactor;
751
- int testThreshold = TestThreshold;
752
751
753
752
while (SILBasicBlock *block = domOrder.getNext ()) {
754
753
constTracker.beginBlock ();
755
754
for (SILInstruction &I : *block) {
756
755
constTracker.trackInst (&I);
757
-
756
+
758
757
auto ICost = instructionInlineCost (I);
759
-
760
- if (testThreshold >= 0 ) {
758
+
759
+ if (TestThreshold >= 0 ) {
761
760
// We are in test-mode: use a simplified cost model.
762
- CalleeCost += testCost (&I);
761
+ Cost += testCost (&I);
763
762
} else {
764
763
// Use the regular cost model.
765
- CalleeCost += unsigned (ICost);
764
+ Cost += unsigned (ICost);
766
765
}
767
-
766
+
768
767
if (ApplyInst *AI = dyn_cast<ApplyInst>(&I)) {
769
-
770
768
// Check if the callee is passed as an argument. If so, increase the
771
769
// threshold, because inlining will (probably) eliminate the closure.
772
770
SILInstruction *def = constTracker.getDefInCaller (AI->getCallee ());
773
771
if (def && (isa<FunctionRefInst>(def) || isa<PartialApplyInst>(def))) {
774
772
775
773
DEBUG (llvm::dbgs () << " Boost: apply const function at"
776
- << *AI);
774
+ << *AI);
777
775
unsigned loopDepth = LI->getLoopDepth (block);
778
776
Benefit += ConstCalleeBenefit + loopDepth * LoopBenefitFactor;
779
- testThreshold *= 2 ;
780
777
}
781
778
}
782
779
}
@@ -788,17 +785,38 @@ bool SILPerformanceInliner::isProfitableToInline(FullApplySite AI,
788
785
DEBUG (llvm::dbgs () << " Take bb" << takenBlock->getDebugID () <<
789
786
" of" << *block->getTerminator ());
790
787
domOrder.pushChildrenIf (block, [=] (SILBasicBlock *child) {
791
- return child->getSinglePredecessor () != block || child == takenBlock;
792
- });
788
+ return child->getSinglePredecessor () != block ||
789
+ child == takenBlock;
790
+ });
793
791
} else {
794
792
domOrder.pushChildren (block);
795
793
}
796
794
}
797
795
798
- unsigned Threshold = Benefit; // The default.
799
- if (testThreshold >= 0 ) {
796
+ return std::make_pair (Cost, Benefit);
797
+ }
798
+
799
+ bool SILPerformanceInliner::isProfitableToInline (FullApplySite AI,
800
+ unsigned loopDepthOfAI,
801
+ DominanceAnalysis *DA,
802
+ SILLoopAnalysis *LA,
803
+ ConstantTracker &callerTracker,
804
+ unsigned &NumCallerBlocks) {
805
+ SILFunction *Callee = AI.getCalleeFunction ();
806
+
807
+ if (Callee->getInlineStrategy () == AlwaysInline)
808
+ return true ;
809
+
810
+ unsigned Cost;
811
+ unsigned Benefit;
812
+ std::tie (Cost, Benefit) = getCostBenefitInfo (AI, loopDepthOfAI, DA, LA,
813
+ callerTracker,
814
+ InlineCostThreshold);
815
+ // The default.
816
+ unsigned Threshold = Benefit;
817
+ if (TestThreshold >= 0 ) {
800
818
// We are in testing mode.
801
- Threshold = testThreshold ;
819
+ Threshold = TestThreshold ;
802
820
} else if (AI.getFunction ()->isThunk ()) {
803
821
// Only inline trivial functions into thunks (which will not increase the
804
822
// code size).
@@ -817,13 +835,13 @@ bool SILPerformanceInliner::isProfitableToInline(FullApplySite AI,
817
835
Threshold = TrivialFunctionThreshold;
818
836
}
819
837
820
- if (CalleeCost > Threshold) {
838
+ if (Cost > Threshold) {
821
839
DEBUG (llvm::dbgs () << " NO: Function too big to inline, "
822
- " cost: " << CalleeCost << " , threshold: " << Threshold << " \n " );
840
+ " cost: " << Cost << " , threshold: " << Threshold << " \n " );
823
841
return false ;
824
842
}
825
843
DEBUG (llvm::dbgs () << " YES: ready to inline, "
826
- " cost: " << CalleeCost << " , threshold: " << Threshold << " \n " );
844
+ " cost: " << Cost << " , threshold: " << Threshold << " \n " );
827
845
NumCallerBlocks += Callee->size ();
828
846
return true ;
829
847
}
0 commit comments