Skip to content

Commit 5bf15f8

Browse files
authored
Add a -ignore-always-inline frontend flag which ignores @inline(__always) attributes. (swiftlang#33466)
1 parent 9f2db6c commit 5bf15f8

File tree

6 files changed

+99
-7
lines changed

6 files changed

+99
-7
lines changed

include/swift/AST/SILOptions.h

Lines changed: 5 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -128,6 +128,11 @@ class SILOptions {
128128
/// Assume that code will be executed in a single-threaded environment.
129129
bool AssumeSingleThreaded = false;
130130

131+
/// Turn @inline(__always) attributes into no-ops.
132+
///
133+
/// For experimentation around code size reduction.
134+
bool IgnoreAlwaysInline = false;
135+
131136
/// Indicates which sanitizer is turned on.
132137
OptionSet<SanitizerKind> Sanitizers;
133138

include/swift/Option/FrontendOptions.td

Lines changed: 3 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -601,6 +601,9 @@ def disable_incremental_llvm_codegeneration :
601601
Flag<["-"], "disable-incremental-llvm-codegen">,
602602
HelpText<"Disable incremental llvm code generation.">;
603603

604+
def ignore_always_inline : Flag<["-"], "ignore-always-inline">,
605+
HelpText<"Ignore @inline(__always) attributes.">;
606+
604607
def emit_sorted_sil : Flag<["-"], "emit-sorted-sil">,
605608
HelpText<"When printing SIL, print out all sil entities sorted by name to "
606609
"ease diffing">;

lib/Frontend/CompilerInvocation.cpp

Lines changed: 2 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -1128,6 +1128,8 @@ static bool ParseSILArgs(SILOptions &Opts, ArgList &Args,
11281128
Opts.AssumeSingleThreaded = true;
11291129
}
11301130

1131+
Opts.IgnoreAlwaysInline |= Args.hasArg(OPT_ignore_always_inline);
1132+
11311133
// Parse the assert configuration identifier.
11321134
if (const Arg *A = Args.getLastArg(OPT_AssertConfig)) {
11331135
StringRef Configuration = A->getValue();

lib/SILOptimizer/Transforms/PerformanceInliner.cpp

Lines changed: 12 additions & 7 deletions
Original file line numberDiff line numberDiff line change
@@ -559,6 +559,15 @@ static bool returnsClosure(SILFunction *F) {
559559
return false;
560560
}
561561

562+
static bool isInlineAlwaysCallSite(SILFunction *Callee) {
563+
if (Callee->isTransparent())
564+
return true;
565+
if (Callee->getInlineStrategy() == AlwaysInline)
566+
if (!Callee->getModule().getOptions().IgnoreAlwaysInline)
567+
return true;
568+
return false;
569+
}
570+
562571
/// Checks if a given generic apply should be inlined unconditionally, i.e.
563572
/// without any complex analysis using e.g. a cost model.
564573
/// It returns true if a function should be inlined.
@@ -585,7 +594,7 @@ static Optional<bool> shouldInlineGeneric(FullApplySite AI) {
585594

586595
// Always inline generic functions which are marked as
587596
// AlwaysInline or transparent.
588-
if (Callee->getInlineStrategy() == AlwaysInline || Callee->isTransparent())
597+
if (isInlineAlwaysCallSite(Callee))
589598
return true;
590599

591600
// If all substitutions are concrete, then there is no need to perform the
@@ -632,7 +641,7 @@ bool SILPerformanceInliner::decideInWarmBlock(
632641

633642
SILFunction *Callee = AI.getReferencedFunctionOrNull();
634643

635-
if (Callee->getInlineStrategy() == AlwaysInline || Callee->isTransparent()) {
644+
if (isInlineAlwaysCallSite(Callee)) {
636645
LLVM_DEBUG(dumpCaller(AI.getFunction());
637646
llvm::dbgs() << " always-inline decision "
638647
<< Callee->getName() << '\n');
@@ -655,7 +664,7 @@ bool SILPerformanceInliner::decideInColdBlock(FullApplySite AI,
655664
return false;
656665
}
657666

658-
if (Callee->getInlineStrategy() == AlwaysInline || Callee->isTransparent()) {
667+
if (isInlineAlwaysCallSite(Callee)) {
659668
LLVM_DEBUG(dumpCaller(AI.getFunction());
660669
llvm::dbgs() << " always-inline decision "
661670
<< Callee->getName() << '\n');
@@ -717,10 +726,6 @@ addToBBCounts(llvm::DenseMap<SILBasicBlock *, uint64_t> &BBToWeightMap,
717726
}
718727
}
719728

720-
static bool isInlineAlwaysCallSite(SILFunction *Callee) {
721-
return Callee->getInlineStrategy() == AlwaysInline || Callee->isTransparent();
722-
}
723-
724729
static void
725730
calculateBBWeights(SILFunction *Caller, DominanceInfo *DT,
726731
llvm::DenseMap<SILBasicBlock *, uint64_t> &BBToWeightMap) {
Lines changed: 71 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -0,0 +1,71 @@
1+
// RUN: %target-sil-opt -enable-sil-verify-all %s -inline -dce | %FileCheck %s -check-prefix=REGULAR
2+
// RUN: %target-sil-opt -enable-sil-verify-all %s -inline -dce -ignore-always-inline | %FileCheck %s -check-prefix=IGNORED
3+
4+
sil_stage canonical
5+
6+
// REGULAR: sil [Osize] @caller
7+
// IGNORED: sil [Osize] @caller
8+
sil [Osize] @caller : $@convention(thin) () -> () {
9+
bb0:
10+
// REGULAR-NOT: function_ref @callee
11+
// REGULAR: function_ref @foobar
12+
// IGNORED: function_ref @callee
13+
%d1 = function_ref @callee : $@convention(thin) () -> ()
14+
apply %d1() : $@convention(thin) () -> ()
15+
16+
%9999 = tuple()
17+
return %9999 : $()
18+
}
19+
20+
sil @foobar : $@convention(thin) () -> ()
21+
22+
// callee is "expensive" enough to not get inlined unless [always_inline] is used
23+
// REGULAR: sil [always_inline] [Osize] @callee
24+
// IGNORED: sil [always_inline] [Osize] @callee
25+
sil [always_inline] [Osize] @callee : $@convention(thin) () -> () {
26+
bb0:
27+
%d1 = function_ref @foobar : $@convention(thin) () -> ()
28+
apply %d1() : $@convention(thin) () -> ()
29+
apply %d1() : $@convention(thin) () -> ()
30+
apply %d1() : $@convention(thin) () -> ()
31+
apply %d1() : $@convention(thin) () -> ()
32+
apply %d1() : $@convention(thin) () -> ()
33+
apply %d1() : $@convention(thin) () -> ()
34+
apply %d1() : $@convention(thin) () -> ()
35+
apply %d1() : $@convention(thin) () -> ()
36+
apply %d1() : $@convention(thin) () -> ()
37+
apply %d1() : $@convention(thin) () -> ()
38+
apply %d1() : $@convention(thin) () -> ()
39+
apply %d1() : $@convention(thin) () -> ()
40+
apply %d1() : $@convention(thin) () -> ()
41+
apply %d1() : $@convention(thin) () -> ()
42+
apply %d1() : $@convention(thin) () -> ()
43+
apply %d1() : $@convention(thin) () -> ()
44+
apply %d1() : $@convention(thin) () -> ()
45+
apply %d1() : $@convention(thin) () -> ()
46+
apply %d1() : $@convention(thin) () -> ()
47+
apply %d1() : $@convention(thin) () -> ()
48+
apply %d1() : $@convention(thin) () -> ()
49+
apply %d1() : $@convention(thin) () -> ()
50+
apply %d1() : $@convention(thin) () -> ()
51+
apply %d1() : $@convention(thin) () -> ()
52+
apply %d1() : $@convention(thin) () -> ()
53+
apply %d1() : $@convention(thin) () -> ()
54+
apply %d1() : $@convention(thin) () -> ()
55+
apply %d1() : $@convention(thin) () -> ()
56+
apply %d1() : $@convention(thin) () -> ()
57+
apply %d1() : $@convention(thin) () -> ()
58+
apply %d1() : $@convention(thin) () -> ()
59+
apply %d1() : $@convention(thin) () -> ()
60+
apply %d1() : $@convention(thin) () -> ()
61+
apply %d1() : $@convention(thin) () -> ()
62+
apply %d1() : $@convention(thin) () -> ()
63+
apply %d1() : $@convention(thin) () -> ()
64+
apply %d1() : $@convention(thin) () -> ()
65+
apply %d1() : $@convention(thin) () -> ()
66+
apply %d1() : $@convention(thin) () -> ()
67+
apply %d1() : $@convention(thin) () -> ()
68+
69+
%9999 = tuple()
70+
return %9999 : $()
71+
}

tools/sil-opt/SILOpt.cpp

Lines changed: 6 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -274,6 +274,11 @@ static llvm::cl::opt<bool>
274274
llvm::cl::desc("Enable C++ interop."),
275275
llvm::cl::init(false));
276276

277+
static llvm::cl::opt<bool>
278+
IgnoreAlwaysInline("ignore-always-inline",
279+
llvm::cl::desc("Ignore [always_inline] attribute."),
280+
llvm::cl::init(false));
281+
277282
static void runCommandLineSelectedPasses(SILModule *Module,
278283
irgen::IRGenModule *IRGenMod) {
279284
auto &opts = Module->getOptions();
@@ -398,6 +403,7 @@ int main(int argc, char **argv) {
398403
}
399404

400405
SILOpts.EnableSpeculativeDevirtualization = EnableSpeculativeDevirtualization;
406+
SILOpts.IgnoreAlwaysInline = IgnoreAlwaysInline;
401407

402408
serialization::ExtendedValidationInfo extendedInfo;
403409
llvm::ErrorOr<std::unique_ptr<llvm::MemoryBuffer>> FileBufOrErr =

0 commit comments

Comments
 (0)