Skip to content

Commit aed8c33

Browse files
authored
Merge pull request #12237 from slavapestov/kill-stdlib-binary-only
SIL: Remove special meaning for @_semantics("stdlib_binary_only")
2 parents 31c1d8d + 0fad13e commit aed8c33

19 files changed

+39
-135
lines changed

docs/HighLevelSILOptimizations.rst

Lines changed: 7 additions & 9 deletions
Original file line numberDiff line numberDiff line change
@@ -117,15 +117,13 @@ Cloning code from the standard library
117117
~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~
118118

119119
The Swift compiler can copy code from the standard library into the
120-
application. This allows the optimizer to inline calls from stdlib and improve
121-
the performance of code that uses common operators such as '++' or basic
122-
containers such as Array. However, importing code from the standard library can
123-
increase the binary size. Marking functions with @_semantics("stdlib_binary_only")
124-
will prevent the copying of the marked function from the standard library into the
125-
user program.
126-
127-
Notice that this annotation is similar to the resilient annotation that will
128-
disallow the cloning of code into the user application.
120+
application for functions marked @_inlineable. This allows the optimizer to
121+
inline calls from the stdlib and improve the performance of code that uses
122+
common operators such as '+=' or basic containers such as Array. However,
123+
importing code from the standard library can increase the binary size.
124+
125+
To prevent copying of functions from the standard library into the user
126+
program, make sure the function in question is not marked @_inlineable.
129127

130128
Array
131129
~~~~~

lib/SIL/Linker.cpp

Lines changed: 0 additions & 29 deletions
Original file line numberDiff line numberDiff line change
@@ -26,26 +26,6 @@ using namespace Lowering;
2626

2727
STATISTIC(NumFuncLinked, "Number of SIL functions linked");
2828

29-
//===----------------------------------------------------------------------===//
30-
// Utility
31-
//===----------------------------------------------------------------------===//
32-
33-
/// \return True if the function \p F should be imported into the current
34-
/// module.
35-
static bool shouldImportFunction(SILFunction *F) {
36-
// Skip functions that are marked with the 'no import' tag. These
37-
// are functions that we don't want to copy from the module.
38-
if (F->hasSemanticsAttr("stdlib_binary_only")) {
39-
// If we are importing a function declaration mark it as external since we
40-
// are not importing the body.
41-
if (F->isExternalDeclaration())
42-
F->setLinkage(SILLinkage::PublicExternal);
43-
return false;
44-
}
45-
46-
return true;
47-
}
48-
4929
//===----------------------------------------------------------------------===//
5030
// Linker Helpers
5131
//===----------------------------------------------------------------------===//
@@ -55,9 +35,6 @@ bool SILLinkerVisitor::processFunction(SILFunction *F) {
5535
if (Mode == LinkingMode::LinkNone)
5636
return false;
5737

58-
if (!shouldImportFunction(F))
59-
return false;
60-
6138
// If F is a declaration, first deserialize it.
6239
if (F->isExternalDeclaration()) {
6340
auto *NewFn = Loader->lookupSILFunction(F);
@@ -334,9 +311,6 @@ bool SILLinkerVisitor::process() {
334311
while (!Worklist.empty()) {
335312
auto *Fn = Worklist.pop_back_val();
336313

337-
if (!shouldImportFunction(Fn))
338-
continue;
339-
340314
DEBUG(llvm::dbgs() << "Process imports in function: "
341315
<< Fn->getName() << "\n");
342316

@@ -346,9 +320,6 @@ bool SILLinkerVisitor::process() {
346320
if (visit(&I)) {
347321
for (auto *F : FunctionDeserializationWorklist) {
348322

349-
if (!shouldImportFunction(F))
350-
continue;
351-
352323
DEBUG(llvm::dbgs() << "Imported function: "
353324
<< F->getName() << "\n");
354325
F->setBare(IsBare);

lib/SILOptimizer/IPO/GlobalOpt.cpp

Lines changed: 4 additions & 5 deletions
Original file line numberDiff line numberDiff line change
@@ -1353,11 +1353,9 @@ void SILGlobalOpt::replaceFindStringCall(ApplyInst *FindStringCall) {
13531353
if (!FD)
13541354
return;
13551355

1356-
std::string Mangled = SILDeclRef(FD, SILDeclRef::Kind::Func).mangle();
1357-
SILFunction *replacementFunc = Module->findFunction(Mangled,
1358-
SILLinkage::PublicExternal);
1359-
if (!replacementFunc)
1360-
return;
1356+
SILDeclRef declRef(FD, SILDeclRef::Kind::Func);
1357+
SILFunction *replacementFunc = Module->getOrCreateFunction(
1358+
FindStringCall->getLoc(), declRef, NotForDefinition);
13611359

13621360
SILFunctionType *FTy = replacementFunc->getLoweredFunctionType();
13631361
if (FTy->getNumParameters() != 3)
@@ -1367,6 +1365,7 @@ void SILGlobalOpt::replaceFindStringCall(ApplyInst *FindStringCall) {
13671365
NominalTypeDecl *cacheDecl = cacheType.getNominalOrBoundGenericNominal();
13681366
if (!cacheDecl)
13691367
return;
1368+
13701369
SILType wordTy = cacheType.getFieldType(
13711370
cacheDecl->getStoredProperties().front(), *Module);
13721371

lib/SILOptimizer/Utils/Local.cpp

Lines changed: 1 addition & 5 deletions
Original file line numberDiff line numberDiff line change
@@ -423,11 +423,7 @@ SILLinkage swift::getSpecializedLinkage(SILFunction *F, SILLinkage L) {
423423
return SILLinkage::Private;
424424
}
425425

426-
// Treat stdlib_binary_only specially. We don't serialize the body of
427-
// stdlib_binary_only functions so we can't mark them as Shared (making
428-
// their visibility in the dylib hidden).
429-
return F->hasSemanticsAttr("stdlib_binary_only") ? SILLinkage::Public
430-
: SILLinkage::Shared;
426+
return SILLinkage::Shared;
431427
}
432428

433429
/// Remove all instructions in the body of \p BB in safe manner by using

stdlib/private/StdlibUnittest/StdlibUnittest.swift.gyb

Lines changed: 1 addition & 1 deletion
Original file line numberDiff line numberDiff line change
@@ -627,7 +627,7 @@ func _stdlib_installTrapInterceptor()
627627
#endif
628628

629629
// Avoid serializing references to objc_setUncaughtExceptionHandler in SIL.
630-
@inline(never) @_semantics("stdlib_binary_only")
630+
@inline(never)
631631
func _childProcess() {
632632
_stdlib_installTrapInterceptor()
633633

stdlib/public/core/AssertCommon.swift

Lines changed: 3 additions & 9 deletions
Original file line numberDiff line numberDiff line change
@@ -82,10 +82,8 @@ func _fatalErrorFlags() -> UInt32 {
8282
///
8383
/// This function should not be inlined because it is cold and inlining just
8484
/// bloats code.
85-
@_inlineable // FIXME(sil-serialize-all)
86-
@_versioned
85+
@_versioned // FIXME(sil-serialize-all)
8786
@inline(never)
88-
@_semantics("stdlib_binary_only")
8987
internal func _assertionFailure(
9088
_ prefix: StaticString, _ message: StaticString,
9189
file: StaticString, line: UInt,
@@ -114,10 +112,8 @@ internal func _assertionFailure(
114112
///
115113
/// This function should not be inlined because it is cold and inlining just
116114
/// bloats code.
117-
@_inlineable // FIXME(sil-serialize-all)
118-
@_versioned
115+
@_versioned // FIXME(sil-serialize-all)
119116
@inline(never)
120-
@_semantics("stdlib_binary_only")
121117
internal func _assertionFailure(
122118
_ prefix: StaticString, _ message: String,
123119
file: StaticString, line: UInt,
@@ -146,10 +142,8 @@ internal func _assertionFailure(
146142
///
147143
/// This function should not be inlined because it is cold and it inlining just
148144
/// bloats code.
149-
@_inlineable // FIXME(sil-serialize-all)
150-
@_versioned
145+
@_versioned // FIXME(sil-serialize-all)
151146
@inline(never)
152-
@_semantics("stdlib_binary_only")
153147
@_semantics("arc.programtermination_point")
154148
internal func _fatalErrorMessage(
155149
_ prefix: StaticString, _ message: StaticString,

stdlib/public/core/DebuggerSupport.swift

Lines changed: 2 additions & 4 deletions
Original file line numberDiff line numberDiff line change
@@ -305,10 +305,8 @@ public enum _DebuggerSupport {
305305
}
306306

307307
// LLDB uses this function in expressions, and if it is inlined the resulting
308-
// LLVM IR is enormous. As a result, to improve LLDB performance we have made
309-
// this stdlib_binary_only, which prevents inlining.
310-
@_inlineable // FIXME(sil-serialize-all)
311-
@_semantics("stdlib_binary_only")
308+
// LLVM IR is enormous. As a result, to improve LLDB performance we are not
309+
// making it @_inlineable.
312310
public static func stringForPrintObject(_ value: Any) -> String {
313311
var maxItemCounter = Int.max
314312
var refs = Set<ObjectIdentifier>()

stdlib/public/core/HashedCollections.swift.gyb

Lines changed: 0 additions & 2 deletions
Original file line numberDiff line numberDiff line change
@@ -2862,9 +2862,7 @@ public func _dictionaryUpCast<DerivedKey, DerivedValue, BaseKey, BaseValue>(
28622862
///
28632863
/// - Precondition: `SwiftKey` and `SwiftValue` are bridged to Objective-C,
28642864
/// and at least one of them requires non-trivial bridging.
2865-
@_inlineable // FIXME(sil-serialize-all)
28662865
@inline(never)
2867-
@_semantics("stdlib_binary_only")
28682866
public func _dictionaryBridgeToObjectiveC<
28692867
SwiftKey, SwiftValue, ObjCKey, ObjCValue
28702868
>(

stdlib/public/core/OutputStream.swift

Lines changed: 0 additions & 2 deletions
Original file line numberDiff line numberDiff line change
@@ -343,11 +343,9 @@ internal func _adHocPrint_unlocked<T, TargetStream : TextOutputStream>(
343343
}
344344
}
345345

346-
@_inlineable // FIXME(sil-serialize-all)
347346
@_versioned
348347
@inline(never)
349348
@_semantics("optimize.sil.specialize.generic.never")
350-
@_semantics("stdlib_binary_only")
351349
internal func _print_unlocked<T, TargetStream : TextOutputStream>(
352350
_ value: T, _ target: inout TargetStream
353351
) {

stdlib/public/core/Print.swift

Lines changed: 0 additions & 8 deletions
Original file line numberDiff line numberDiff line change
@@ -49,9 +49,7 @@
4949
/// space (`" "`).
5050
/// - terminator: The string to print after all items have been printed. The
5151
/// default is a newline (`"\n"`).
52-
@_inlineable // FIXME(sil-serialize-all)
5352
@inline(never)
54-
@_semantics("stdlib_binary_only")
5553
public func print(
5654
_ items: Any...,
5755
separator: String = " ",
@@ -110,9 +108,7 @@ public func print(
110108
/// space (`" "`).
111109
/// - terminator: The string to print after all items have been printed. The
112110
/// default is a newline (`"\n"`).
113-
@_inlineable // FIXME(sil-serialize-all)
114111
@inline(never)
115-
@_semantics("stdlib_binary_only")
116112
public func debugPrint(
117113
_ items: Any...,
118114
separator: String = " ",
@@ -228,10 +224,8 @@ public func debugPrint<Target : TextOutputStream>(
228224
items, separator: separator, terminator: terminator, to: &output)
229225
}
230226

231-
@_inlineable // FIXME(sil-serialize-all)
232227
@_versioned
233228
@inline(never)
234-
@_semantics("stdlib_binary_only")
235229
internal func _print<Target : TextOutputStream>(
236230
_ items: [Any],
237231
separator: String = " ",
@@ -249,10 +243,8 @@ internal func _print<Target : TextOutputStream>(
249243
output.write(terminator)
250244
}
251245

252-
@_inlineable // FIXME(sil-serialize-all)
253246
@_versioned
254247
@inline(never)
255-
@_semantics("stdlib_binary_only")
256248
internal func _debugPrint<Target : TextOutputStream>(
257249
_ items: [Any],
258250
separator: String = " ",

stdlib/public/core/REPL.swift

Lines changed: 0 additions & 2 deletions
Original file line numberDiff line numberDiff line change
@@ -18,9 +18,7 @@ func _replPrintLiteralString(_ text: String) {
1818
}
1919

2020
/// Print the debug representation of `value`, followed by a newline.
21-
@_inlineable // FIXME(sil-serialize-all)
2221
@inline(never)
23-
@_semantics("stdlib_binary_only")
2422
public // COMPILER_INTRINSIC
2523
func _replDebugPrintln<T>(_ value: T) {
2624
debugPrint(value)

stdlib/public/core/StringBridge.swift

Lines changed: 8 additions & 15 deletions
Original file line numberDiff line numberDiff line change
@@ -47,9 +47,8 @@ func _stdlib_binary_CFStringGetCharactersPtr(
4747

4848
/// Bridges `source` to `Swift.String`, assuming that `source` has non-ASCII
4949
/// characters (does not apply ASCII optimizations).
50-
@_inlineable // FIXME(sil-serialize-all)
5150
@_versioned // FIXME(sil-serialize-all)
52-
@inline(never) @_semantics("stdlib_binary_only") // Hide the CF dependency
51+
@inline(never) // Hide the CF dependency
5352
func _cocoaStringToSwiftString_NonASCII(
5453
_ source: _CocoaString
5554
) -> String {
@@ -70,9 +69,8 @@ func _cocoaStringToSwiftString_NonASCII(
7069

7170
/// Produces a `_StringBuffer` from a given subrange of a source
7271
/// `_CocoaString`, having the given minimum capacity.
73-
@_inlineable // FIXME(sil-serialize-all)
7472
@_versioned // FIXME(sil-serialize-all)
75-
@inline(never) @_semantics("stdlib_binary_only") // Hide the CF dependency
73+
@inline(never) // Hide the CF dependency
7674
internal func _cocoaStringToContiguous(
7775
source: _CocoaString, range: Range<Int>, minimumCapacity: Int
7876
) -> _StringBuffer {
@@ -94,9 +92,8 @@ internal func _cocoaStringToContiguous(
9492

9593
/// Reads the entire contents of a _CocoaString into contiguous
9694
/// storage of sufficient capacity.
97-
@_inlineable // FIXME(sil-serialize-all)
9895
@_versioned // FIXME(sil-serialize-all)
99-
@inline(never) @_semantics("stdlib_binary_only") // Hide the CF dependency
96+
@inline(never) // Hide the CF dependency
10097
internal func _cocoaStringReadAll(
10198
_ source: _CocoaString, _ destination: UnsafeMutablePointer<UTF16.CodeUnit>
10299
) {
@@ -105,9 +102,8 @@ internal func _cocoaStringReadAll(
105102
location: 0, length: _swift_stdlib_CFStringGetLength(source)), destination)
106103
}
107104

108-
@_inlineable // FIXME(sil-serialize-all)
109105
@_versioned // FIXME(sil-serialize-all)
110-
@inline(never) @_semantics("stdlib_binary_only") // Hide the CF dependency
106+
@inline(never) // Hide the CF dependency
111107
internal func _cocoaStringSlice(
112108
_ target: _StringCore, _ bounds: Range<Int>
113109
) -> _StringCore {
@@ -126,9 +122,8 @@ internal func _cocoaStringSlice(
126122
return String(_cocoaString: cfResult)._core
127123
}
128124

129-
@_inlineable // FIXME(sil-serialize-all)
130-
@_versioned
131-
@inline(never) @_semantics("stdlib_binary_only") // Hide the CF dependency
125+
@_versioned // FIXME(sil-serialize-all)
126+
@inline(never) // Hide the CF dependency
132127
internal func _cocoaStringSubscript(
133128
_ target: _StringCore, _ position: Int
134129
) -> UTF16.CodeUnit {
@@ -151,8 +146,7 @@ internal var kCFStringEncodingASCII : _swift_shims_CFStringEncoding {
151146
}
152147

153148
extension String {
154-
@_inlineable // FIXME(sil-serialize-all)
155-
@inline(never) @_semantics("stdlib_binary_only") // Hide the CF dependency
149+
@inline(never) // Hide the CF dependency
156150
public // SPI(Foundation)
157151
init(_cocoaString: AnyObject) {
158152
if let wrapped = _cocoaString as? _NSContiguousString {
@@ -374,8 +368,7 @@ extension String {
374368
return _NSContiguousString(_core)
375369
}
376370

377-
@_inlineable // FIXME(sil-serialize-all)
378-
@inline(never) @_semantics("stdlib_binary_only") // Hide the CF dependency
371+
@inline(never) // Hide the CF dependency
379372
public func _bridgeToObjectiveCImpl() -> AnyObject {
380373
return _stdlib_binary_bridgeToObjectiveCImpl()
381374
}

stdlib/public/core/StringComparable.swift

Lines changed: 1 addition & 3 deletions
Original file line numberDiff line numberDiff line change
@@ -77,9 +77,7 @@ extension String {
7777
#endif
7878

7979
/// Compares two strings with the Unicode Collation Algorithm.
80-
@_inlineable // FIXME(sil-serialize-all)
81-
@inline(never)
82-
@_semantics("stdlib_binary_only") // Hide the CF/ICU dependency
80+
@inline(never) // Hide the CF/ICU dependency
8381
public // @testable
8482
func _compareDeterministicUnicodeCollation(_ rhs: String) -> Int {
8583
// Note: this operation should be consistent with equality comparison of

stdlib/public/core/StringHashable.swift

Lines changed: 1 addition & 3 deletions
Original file line numberDiff line numberDiff line change
@@ -82,10 +82,8 @@ extension Unicode {
8282
}
8383
}
8484

85-
// FIXME: cannot be marked @_inlineable. See <rdar://problem/34438258>
86-
// @_inlineable // FIXME(sil-serialize-all)
8785
@_versioned // FIXME(sil-serialize-all)
88-
@inline(never) @_semantics("stdlib_binary_only") // Hide the CF dependency
86+
@inline(never) // Hide the CF dependency
8987
internal func _hashString(_ string: String) -> Int {
9088
let core = string._core
9189
#if _runtime(_ObjC)

stdlib/public/core/StringSwitch.swift

Lines changed: 0 additions & 4 deletions
Original file line numberDiff line numberDiff line change
@@ -16,8 +16,6 @@
1616

1717
/// The compiler intrinsic which is called to lookup a string in a table
1818
/// of static string case values.
19-
@_inlineable // FIXME(sil-serialize-all)
20-
@_semantics("stdlib_binary_only")
2119
@_semantics("findStringSwitchCase")
2220
public // COMPILER_INTRINSIC
2321
func _findStringSwitchCase(
@@ -68,8 +66,6 @@ internal struct _StringSwitchContext {
6866
/// in \p cache. Consecutive calls use the cache for faster lookup.
6967
/// The \p cases array must not change between subsequent calls with the
7068
/// same \p cache.
71-
@_inlineable // FIXME(sil-serialize-all)
72-
@_semantics("stdlib_binary_only")
7369
@_semantics("findStringSwitchCaseWithCache")
7470
public // COMPILER_INTRINSIC
7571
func _findStringSwitchCaseWithCache(

test/SILOptimizer/Inputs/linker_pass_input.swift

Lines changed: 6 additions & 3 deletions
Original file line numberDiff line numberDiff line change
@@ -2,23 +2,26 @@
22
@_silgen_name("unknown")
33
public func unknown() -> ()
44

5+
@_inlineable
56
public func doSomething() {
67
unknown()
78
}
89

9-
@_semantics("stdlib_binary_only")
1010
public func doSomething2() {
1111
unknown()
1212
}
1313

1414
@inline(never)
15-
@_semantics("stdlib_binary_only")
1615
public func doSomething3<T>(_ a:T) {
1716
unknown()
1817
}
1918

20-
struct A {}
19+
@_versioned struct A {
20+
@_versioned init() {}
21+
}
22+
2123
@inline(never)
24+
@_inlineable
2225
public func callDoSomething3() {
2326
doSomething3(A())
2427
}

0 commit comments

Comments
 (0)