Skip to content

Commit 5b403ea

Browse files
committed
SILOptimizer: semantic attribute to prevent specialization of a function when compiled with -Osize
It's @_semantics("optimize.sil.specialize.generic.size.never") It is similar to "optimize.sil.specialize.generic.partial.never", but only prevents specialization if the optimization mode is Size
1 parent 81b5970 commit 5b403ea

File tree

2 files changed

+34
-6
lines changed

2 files changed

+34
-6
lines changed

lib/SILOptimizer/Utils/Generics.cpp

Lines changed: 13 additions & 6 deletions
Original file line numberDiff line numberDiff line change
@@ -364,11 +364,18 @@ static bool createsInfiniteSpecializationLoop(ApplySite Apply) {
364364
// ReabstractionInfo
365365
// =============================================================================
366366

367-
static bool shouldNotSpecializeCallee(SILFunction *Callee,
368-
SubstitutionMap Subs = {}) {
367+
static bool shouldNotSpecialize(SILFunction *Callee, SILFunction *Caller,
368+
SubstitutionMap Subs = {}) {
369369
if (Callee->hasSemanticsAttr("optimize.sil.specialize.generic.never"))
370370
return true;
371371

372+
if (Caller &&
373+
Caller->getEffectiveOptimizationMode() == OptimizationMode::ForSize &&
374+
Callee->hasSemanticsAttr("optimize.sil.specialize.generic.size.never")) {
375+
return true;
376+
}
377+
378+
372379
if (Subs.hasAnySubstitutableParams() &&
373380
Callee->hasSemanticsAttr("optimize.sil.specialize.generic.partial.never"))
374381
return true;
@@ -383,7 +390,7 @@ static bool shouldNotSpecializeCallee(SILFunction *Callee,
383390
bool ReabstractionInfo::prepareAndCheck(ApplySite Apply, SILFunction *Callee,
384391
SubstitutionMap ParamSubs,
385392
OptRemark::Emitter *ORE) {
386-
if (shouldNotSpecializeCallee(Callee))
393+
if (shouldNotSpecialize(Callee, Apply ? Apply.getFunction() : nullptr))
387394
return false;
388395

389396
SpecializedGenericEnv = nullptr;
@@ -489,7 +496,7 @@ bool ReabstractionInfo::prepareAndCheck(ApplySite Apply, SILFunction *Callee,
489496
return false;
490497

491498
// Bail if the callee should not be partially specialized.
492-
if (shouldNotSpecializeCallee(Callee, ParamSubs))
499+
if (shouldNotSpecialize(Callee, Apply.getFunction(), ParamSubs))
493500
return false;
494501
}
495502

@@ -1763,7 +1770,7 @@ checkSpecializationRequirements(ArrayRef<Requirement> Requirements) {
17631770
/// This constructor is used when processing @_specialize.
17641771
ReabstractionInfo::ReabstractionInfo(SILFunction *Callee,
17651772
ArrayRef<Requirement> Requirements) {
1766-
if (shouldNotSpecializeCallee(Callee))
1773+
if (shouldNotSpecialize(Callee, nullptr))
17671774
return;
17681775

17691776
// Perform some sanity checks for the requirements.
@@ -2281,7 +2288,7 @@ void swift::trySpecializeApplyOfGeneric(
22812288
if (F->isSerialized() && !RefF->hasValidLinkageForFragileInline())
22822289
return;
22832290

2284-
if (shouldNotSpecializeCallee(RefF))
2291+
if (shouldNotSpecialize(RefF, F))
22852292
return;
22862293

22872294
// If the caller and callee are both fragile, preserve the fragility when
Lines changed: 21 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -0,0 +1,21 @@
1+
// RUN: %target-swift-frontend %s -O -emit-sil | %FileCheck %s -check-prefix=CHECK-O
2+
// RUN: %target-swift-frontend %s -Osize -emit-sil | %FileCheck %s -check-prefix=CHECK-OSIZE
3+
4+
@_semantics("optimize.sil.specialize.generic.size.never")
5+
func foo<T>(_ t: T) -> T {
6+
return t
7+
}
8+
9+
// CHECK-O-LABEL: sil @{{.*}}test
10+
// CHECK-O: %0 = integer_literal
11+
// CHECK-O: %1 = struct $Int
12+
// CHECK-O: return %1
13+
14+
// CHECK-OSIZE-LABEL: sil {{.*}} @{{.*}}foo
15+
16+
// CHECK-OSIZE-LABEL: sil @{{.*}}test
17+
// CHECK-OSIZE: function_ref {{.*}}foo
18+
// CHECK-OSIZE: apply
19+
public func test() -> Int {
20+
return foo(27)
21+
}

0 commit comments

Comments
 (0)