@@ -49,6 +49,59 @@ llvm::cl::opt<bool> EnableVerifyAfterInlining(
4949 llvm::cl::desc(" Run sil verification after inlining all found callee apply "
5050 " sites into a caller." ));
5151
52+ llvm::cl::opt<bool > SILPrintInliningCallee (
53+ " sil-print-inlining-callee" , llvm::cl::init(false ),
54+ llvm::cl::desc(" Print functions that are inlined into other functions." ));
55+
56+ llvm::cl::opt<bool > SILPrintInliningCallerBefore (
57+ " sil-print-inlining-caller-before" , llvm::cl::init(false ),
58+ llvm::cl::desc(
59+ " Print functions into which another function is about to be inlined." ));
60+
61+ llvm::cl::opt<bool > SILPrintInliningCallerAfter (
62+ " sil-print-inlining-caller-after" , llvm::cl::init(false ),
63+ llvm::cl::desc(
64+ " Print functions into which another function has been inlined." ));
65+
66+ // ===----------------------------------------------------------------------===//
67+ // Printing Helpers
68+ // ===----------------------------------------------------------------------===//
69+
70+ extern bool isFunctionSelectedForPrinting (SILFunction *F);
71+
72+ static void printInliningDetails (StringRef passName, SILFunction *caller,
73+ SILFunction *callee, bool isCaller,
74+ bool alreadyInlined) {
75+ if (!isFunctionSelectedForPrinting (caller))
76+ return ;
77+ llvm::dbgs () << " " << passName
78+ << (alreadyInlined ? " has inlined " : " will inline " )
79+ << callee->getName () << " into " << caller->getName () << " .\n " ;
80+ auto *printee = isCaller ? caller : callee;
81+ printee->dump (caller->getModule ().getOptions ().EmitVerboseSIL );
82+ llvm::dbgs () << ' \n ' ;
83+ }
84+
85+ static void printInliningDetailsCallee (StringRef passName, SILFunction *caller,
86+ SILFunction *callee) {
87+ printInliningDetails (passName, caller, callee, /* isCaller=*/ false ,
88+ /* alreadyInlined=*/ false );
89+ }
90+
91+ static void printInliningDetailsCallerBefore (StringRef passName,
92+ SILFunction *caller,
93+ SILFunction *callee) {
94+ printInliningDetails (passName, caller, callee, /* isCaller=*/ true ,
95+ /* alreadyInlined=*/ false );
96+ }
97+
98+ static void printInliningDetailsCallerAfter (StringRef passName,
99+ SILFunction *caller,
100+ SILFunction *callee) {
101+ printInliningDetails (passName, caller, callee, /* isCaller=*/ true ,
102+ /* alreadyInlined=*/ true );
103+ }
104+
52105// ===----------------------------------------------------------------------===//
53106// Performance Inliner
54107// ===----------------------------------------------------------------------===//
@@ -58,6 +111,7 @@ namespace {
58111using Weight = ShortestPathAnalysis::Weight;
59112
60113class SILPerformanceInliner {
114+ StringRef PassName;
61115 SILOptFunctionBuilder &FuncBuilder;
62116
63117 // / Specifies which functions not to inline, based on @_semantics and
@@ -190,12 +244,13 @@ class SILPerformanceInliner {
190244 SmallVectorImpl<FullApplySite> &Applies);
191245
192246public:
193- SILPerformanceInliner (SILOptFunctionBuilder &FuncBuilder,
194- InlineSelection WhatToInline, DominanceAnalysis *DA,
247+ SILPerformanceInliner (StringRef PassName, SILOptFunctionBuilder &FuncBuilder,
248+ InlineSelection WhatToInline, DominanceAnalysis *DA,
195249 SILLoopAnalysis *LA, SideEffectAnalysis *SEA,
196250 OptimizationMode OptMode, OptRemark::Emitter &ORE)
197- : FuncBuilder(FuncBuilder), WhatToInline(WhatToInline), DA(DA), LA(LA),
198- SEA (SEA), CBI(DA), ORE(ORE), OptMode(OptMode) {}
251+ : PassName(PassName), FuncBuilder(FuncBuilder),
252+ WhatToInline (WhatToInline), DA(DA), LA(LA), SEA(SEA), CBI(DA), ORE(ORE),
253+ OptMode(OptMode) {}
199254
200255 bool inlineCallsIntoFunction (SILFunction *F);
201256};
@@ -975,6 +1030,12 @@ bool SILPerformanceInliner::inlineCallsIntoFunction(SILFunction *Caller) {
9751030 // will be deleted after inlining.
9761031 invalidatedStackNesting |= SILInliner::invalidatesStackNesting (AI);
9771032
1033+ if (SILPrintInliningCallee) {
1034+ printInliningDetailsCallee (PassName, Caller, Callee);
1035+ }
1036+ if (SILPrintInliningCallerBefore) {
1037+ printInliningDetailsCallerBefore (PassName, Caller, Callee);
1038+ }
9781039 // We've already determined we should be able to inline this, so
9791040 // unconditionally inline the function.
9801041 //
@@ -983,6 +1044,9 @@ bool SILPerformanceInliner::inlineCallsIntoFunction(SILFunction *Caller) {
9831044 SILInliner::inlineFullApply (AI, SILInliner::InlineKind::PerformanceInline,
9841045 FuncBuilder, deleter);
9851046 ++NumFunctionsInlined;
1047+ if (SILPrintInliningCallerAfter) {
1048+ printInliningDetailsCallerAfter (PassName, Caller, Callee);
1049+ }
9861050 }
9871051 deleter.cleanupDeadInstructions ();
9881052
@@ -1056,8 +1120,9 @@ class SILPerformanceInlinerPass : public SILFunctionTransform {
10561120 auto OptMode = getFunction ()->getEffectiveOptimizationMode ();
10571121
10581122 SILOptFunctionBuilder FuncBuilder (*this );
1059- SILPerformanceInliner Inliner (FuncBuilder, WhatToInline, DA, LA, SEA,
1060- OptMode, ORE);
1123+
1124+ SILPerformanceInliner Inliner (getID (), FuncBuilder, WhatToInline, DA, LA,
1125+ SEA, OptMode, ORE);
10611126
10621127 assert (getFunction ()->isDefinition () &&
10631128 " Expected only functions with bodies!" );
0 commit comments