14
14
#include " swift/SILOptimizer/PassManager/Passes.h"
15
15
#include " swift/SILOptimizer/PassManager/Transforms.h"
16
16
#include " swift/SILOptimizer/Utils/PerformanceInlinerUtils.h"
17
+ #include " swift/Strings.h"
17
18
#include " llvm/ADT/Statistic.h"
18
19
#include " llvm/Support/Debug.h"
19
20
#include " llvm/Support/CommandLine.h"
@@ -26,6 +27,10 @@ llvm::cl::opt<bool> PrintShortestPathInfo(
26
27
" print-shortest-path-info" , llvm::cl::init(false ),
27
28
llvm::cl::desc(" Print shortest-path information for inlining" ));
28
29
30
+ llvm::cl::opt<bool > EnableSILInliningOfGenerics (
31
+ " sil-inline-generics" , llvm::cl::init(false ),
32
+ llvm::cl::desc(" Enable inlining of generics" ));
33
+
29
34
// ===----------------------------------------------------------------------===//
30
35
// Performance Inliner
31
36
// ===----------------------------------------------------------------------===//
@@ -122,6 +127,11 @@ class SILPerformanceInliner {
122
127
ConstantTracker &constTracker,
123
128
int &NumCallerBlocks);
124
129
130
+ bool isProfitableToInlineGeneric (FullApplySite AI,
131
+ Weight CallerWeight,
132
+ ConstantTracker &constTracker,
133
+ int &NumCallerBlocks);
134
+
125
135
bool isProfitableInColdBlock (FullApplySite AI, SILFunction *Callee);
126
136
127
137
void visitColdBlocks (SmallVectorImpl<FullApplySite> &AppliesToInline,
@@ -191,10 +201,6 @@ SILFunction *SILPerformanceInliner::getEligibleFunction(FullApplySite AI) {
191
201
return nullptr ;
192
202
}
193
203
194
- // We don't support this yet.
195
- if (AI.hasSubstitutions ())
196
- return nullptr ;
197
-
198
204
SILFunction *Caller = AI.getFunction ();
199
205
200
206
// We don't support inlining a function that binds dynamic self because we
@@ -369,6 +375,37 @@ bool SILPerformanceInliner::isProfitableToInlineNonGeneric(FullApplySite AI,
369
375
return true ;
370
376
}
371
377
378
+ // / Return true if inlining this call site is profitable.
379
+ bool SILPerformanceInliner::isProfitableToInlineGeneric (FullApplySite AI,
380
+ Weight CallerWeight,
381
+ ConstantTracker &callerTracker,
382
+ int &NumCallerBlocks) {
383
+ assert (!AI.getSubstitutions ().empty () &&
384
+ " Expected a generic apply" );
385
+
386
+ SILFunction *Callee = AI.getReferencedFunction ();
387
+
388
+ // Do not inline @_semantics functions when compiling the stdlib,
389
+ // because they need to be preserved, so that the optimizer
390
+ // can properly optimize a user code later.
391
+ auto ModuleName = Callee->getModule ().getSwiftModule ()->getName ().str ();
392
+ if (Callee->hasSemanticsAttrThatStartsWith (" array." ) &&
393
+ (ModuleName == STDLIB_NAME || ModuleName == SWIFT_ONONE_SUPPORT))
394
+ return false ;
395
+
396
+ // Always inline generic functions which are marked as
397
+ // AlwaysInline or transparent.
398
+ bool ShouldInline = Callee->getInlineStrategy () == AlwaysInline ||
399
+ Callee->isTransparent ();
400
+
401
+ // Only inline if we decided to inline or we are asked to inline all
402
+ // generic functions.
403
+ if (ShouldInline || EnableSILInliningOfGenerics)
404
+ return true ;
405
+
406
+ return false ;
407
+ }
408
+
372
409
// / Return true if inlining this call site into a cold block is profitable.
373
410
bool SILPerformanceInliner::isProfitableInColdBlock (FullApplySite AI,
374
411
SILFunction *Callee) {
@@ -482,8 +519,13 @@ void SILPerformanceInliner::collectAppliesToInline(
482
519
// The actual weight including a possible weight correction.
483
520
Weight W (BlockWeight, WeightCorrections.lookup (AI));
484
521
485
- bool IsProfitableToInline = isProfitableToInlineNonGeneric (
486
- AI, W, constTracker, NumCallerBlocks);
522
+ bool IsGenericApply = !AI.getSubstitutions ().empty ();
523
+ bool IsProfitableToInline =
524
+ IsGenericApply ? isProfitableToInlineGeneric (AI, W, constTracker,
525
+ NumCallerBlocks)
526
+ : isProfitableToInlineNonGeneric (AI, W, constTracker,
527
+ NumCallerBlocks);
528
+
487
529
if (IsProfitableToInline)
488
530
InitialCandidates.push_back (AI);
489
531
}
0 commit comments