Skip to content

Commit 17a2106

Browse files
committed
Merge pull request #1429 from swiftix/wip-prespecializations-module
Move pre-specializations of popular types away from the stdlib. This saves 4%-5% of code size in libswiftCore.dylib.
2 parents 13203bf + 8dff92a commit 17a2106

File tree

9 files changed

+121
-9
lines changed

9 files changed

+121
-9
lines changed

cmake/modules/AddSwift.cmake

Lines changed: 22 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -1355,6 +1355,28 @@ function(add_swift_library name)
13551355
Core)
13561356
endif()
13571357

1358+
is_build_type_optimized("${SWIFT_STDLIB_BUILD_TYPE}" optimized)
1359+
if(NOT optimized)
1360+
# All Swift code depends on the SwiftOnoneSupport in non-optmized mode,
1361+
# except for the standard library itself.
1362+
if(SWIFTLIB_TARGET_LIBRARY AND NOT SWIFTLIB_IS_STDLIB_CORE)
1363+
list(APPEND SWIFTLIB_SWIFT_MODULE_DEPENDS SwiftOnoneSupport)
1364+
endif()
1365+
endif()
1366+
1367+
if((NOT "${SWIFT_BUILD_STDLIB}") AND
1368+
(NOT "${SWIFTLIB_SWIFT_MODULE_DEPENDS}" STREQUAL ""))
1369+
list(REMOVE_ITEM SWIFTLIB_SWIFT_MODULE_DEPENDS
1370+
SwiftOnoneSupport)
1371+
endif()
1372+
1373+
# swiftSwiftOnoneSupport does not depend on itself,
1374+
# obviously.
1375+
if("${name}" STREQUAL "swiftSwiftOnoneSupport")
1376+
list(REMOVE_ITEM SWIFTLIB_SWIFT_MODULE_DEPENDS
1377+
SwiftOnoneSupport)
1378+
endif()
1379+
13581380
translate_flags(SWIFTLIB "${SWIFTLIB_options}")
13591381

13601382
if("${SWIFTLIB_INSTALL_IN_COMPONENT}" STREQUAL "")

include/swift/Strings.h

Lines changed: 2 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -27,6 +27,8 @@ namespace swift {
2727
static const char LLVM_IR_EXTENSION[] = "ll";
2828
/// The name of the standard library, which is a reserved module name.
2929
static const char STDLIB_NAME[] = "Swift";
30+
/// The name of the Onone support library, which is a reserved module name.
31+
static const char SWIFT_ONONE_SUPPORT[] = "SwiftOnoneSupport";
3032
/// The name of the SwiftShims module, which contains private stdlib decls.
3133
static const char SWIFT_SHIMS_NAME[] = "SwiftShims";
3234
/// The prefix of module names used by LLDB to capture Swift expressions

lib/Frontend/Frontend.cpp

Lines changed: 14 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -273,6 +273,20 @@ void CompilerInstance::performSema() {
273273
return;
274274
}
275275

276+
const auto &silOptions = Invocation.getSILOptions();
277+
if ((silOptions.Optimization <= SILOptions::SILOptMode::None &&
278+
(options.RequestedAction == FrontendOptions::EmitObject ||
279+
options.RequestedAction == FrontendOptions::Immediate ||
280+
options.RequestedAction == FrontendOptions::EmitSIL)) ||
281+
(silOptions.Optimization == SILOptions::SILOptMode::None &&
282+
options.RequestedAction >= FrontendOptions::EmitSILGen)) {
283+
// Implicitly import the SwiftOnoneSupport module in non-optimized
284+
// builds. This allows for use of popular specialized functions
285+
// from the standard library, which makes the non-optimized builds
286+
// execute much faster.
287+
Invocation.getFrontendOptions()
288+
.ImplicitImportModuleNames.push_back(SWIFT_ONONE_SUPPORT);
289+
}
276290
break;
277291
}
278292
}

lib/SILOptimizer/Utils/Generics.cpp

Lines changed: 3 additions & 2 deletions
Original file line numberDiff line numberDiff line change
@@ -145,7 +145,7 @@ static bool cacheSpecialization(SILModule &M, SILFunction *F) {
145145

146146
if (M.getOptions().Optimization >= SILOptions::SILOptMode::Optimize &&
147147
F->getLinkage() != SILLinkage::Public &&
148-
F->getModule().getSwiftModule()->getName().str() == STDLIB_NAME) {
148+
F->getModule().getSwiftModule()->getName().str() == SWIFT_ONONE_SUPPORT) {
149149
if (F->getLinkage() != SILLinkage::Public &&
150150
isWhitelistedSpecialization(F->getName())) {
151151

@@ -209,7 +209,8 @@ SILFunction *swift::getExistingSpecialization(SILModule &M,
209209
assert((Specialization->isExternalDeclaration() ||
210210
convertExternalDefinitionIntoDeclaration(Specialization)) &&
211211
"Could not remove body of the found specialization");
212-
if (!convertExternalDefinitionIntoDeclaration(Specialization)) {
212+
if (!Specialization->isExternalDeclaration() &&
213+
!convertExternalDefinitionIntoDeclaration(Specialization)) {
213214
DEBUG(
214215
llvm::dbgs() << "Could not remove body of specialization: "
215216
<< FunctionName << '\n');

stdlib/public/CMakeLists.txt

Lines changed: 1 addition & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -30,6 +30,7 @@ if(SWIFT_BUILD_STDLIB)
3030
add_subdirectory(runtime)
3131
add_subdirectory(stubs)
3232
add_subdirectory(core)
33+
add_subdirectory(SwiftOnoneSupport)
3334
endif()
3435

3536
if(CMAKE_SYSTEM_NAME STREQUAL "Darwin")
Lines changed: 6 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -0,0 +1,6 @@
1+
add_swift_library(swiftSwiftOnoneSupport SHARED IS_STDLIB
2+
# This file should be listed the first. Module name is inferred from the
3+
# filename.
4+
SwiftOnoneSupport.swift
5+
SWIFT_COMPILE_FLAGS ${STDLIB_SIL_SERIALIZE_ALL} "-parse-stdlib"
6+
INSTALL_IN_COMPONENT stdlib)

stdlib/public/core/Prespecialized.swift renamed to stdlib/public/SwiftOnoneSupport/SwiftOnoneSupport.swift

Lines changed: 69 additions & 2 deletions
Original file line numberDiff line numberDiff line change
@@ -11,8 +11,11 @@
1111
//===----------------------------------------------------------------------===//
1212
// Pre-specialization of some popular generic classes and functions.
1313
//===----------------------------------------------------------------------===//
14+
import Swift
1415

1516
struct _Prespecialize {
17+
class C {}
18+
1619
// Create specializations for the arrays of most
1720
// popular builtin integer and floating point types.
1821
static internal func _specializeArrays() {
@@ -25,8 +28,9 @@ struct _Prespecialize {
2528
let _ = a[0]
2629

2730
// Set array elements
28-
for j in 0..<a.count {
31+
for j in 1..<a.count {
2932
a[0] = a[j]
33+
a[j-1] = a[j]
3034
}
3135

3236
for i1 in 0..<a.count {
@@ -56,12 +60,61 @@ struct _Prespecialize {
5660
let _ = a.sort { (a:Element, b:Element) in a < b }
5761
a.sortInPlace { (a:Element, b:Element) in a < b }
5862

63+
// force specialization of append.
64+
a.append(a[0])
5965

6066
// force specialization of print<Element>
6167
print(sampleValue)
6268
print("Element:\(sampleValue)")
6369
}
6470

71+
func _createArrayUserWithoutSorting<Element>(sampleValue: Element) {
72+
// Initializers.
73+
let _: [Element] = [ sampleValue ]
74+
var a = [Element](count: 1, repeatedValue: sampleValue)
75+
76+
// Read array element
77+
let _ = a[0]
78+
79+
// Set array elements
80+
for j in 0..<a.count {
81+
a[0] = a[j]
82+
}
83+
84+
for i1 in 0..<a.count {
85+
for i2 in 0..<a.count {
86+
a[i1] = a[i2]
87+
}
88+
}
89+
90+
a[0] = sampleValue
91+
92+
// Get length and capacity
93+
let _ = a.count + a.capacity
94+
95+
// Iterate over array
96+
for e in a {
97+
print(e)
98+
print("Value: \(e)")
99+
}
100+
101+
print(a)
102+
103+
// Reserve capacity
104+
a.removeAll()
105+
a.reserveCapacity(100)
106+
107+
108+
// force specialization of append.
109+
a.append(a[0])
110+
111+
// force specialization of print<Element>
112+
print(sampleValue)
113+
print("Element:\(sampleValue)")
114+
}
115+
116+
// Force pre-specialization of arrays with elements of different
117+
// integer types.
65118
_createArrayUser(1 as Int)
66119
_createArrayUser(1 as Int8)
67120
_createArrayUser(1 as Int16)
@@ -72,9 +125,23 @@ struct _Prespecialize {
72125
_createArrayUser(1 as UInt16)
73126
_createArrayUser(1 as UInt32)
74127
_createArrayUser(1 as UInt64)
75-
_createArrayUser("a" as String)
128+
129+
// Force pre-specialization of arrays with elements of different
130+
// floating point types.
76131
_createArrayUser(1.5 as Float)
77132
_createArrayUser(1.5 as Double)
133+
134+
// Force pre-specialization of string arrays
135+
_createArrayUser("a" as String)
136+
137+
// Force pre-specialization of arrays with elements of different
138+
// character and unicode scalar types.
139+
_createArrayUser("a" as Character)
140+
_createArrayUser("a" as UnicodeScalar)
141+
_createArrayUserWithoutSorting("a".utf8)
142+
_createArrayUserWithoutSorting("a".utf16)
143+
_createArrayUserWithoutSorting("a".unicodeScalars)
144+
_createArrayUserWithoutSorting("a".characters)
78145
}
79146

80147
// Force pre-specialization of Range<Int>

stdlib/public/core/CMakeLists.txt

Lines changed: 0 additions & 1 deletion
Original file line numberDiff line numberDiff line change
@@ -126,7 +126,6 @@ set(SWIFTLIB_SOURCES
126126
Tuple.swift.gyb
127127
VarArgs.swift
128128
Zip.swift
129-
Prespecialized.swift
130129
)
131130
set(GROUP_INFO_JSON_FILE ${CMAKE_CURRENT_SOURCE_DIR}/GroupInfo.json)
132131
set(swift_core_link_flags)

test/Driver/emit-sib-single-file.swift

Lines changed: 4 additions & 4 deletions
Original file line numberDiff line numberDiff line change
@@ -1,16 +1,16 @@
1-
// RUN: %target-build-swift -emit-sib %s -o %t.sib
1+
// RUN: %target-build-swift -Onone -emit-sib %s -o %t.sib
22
// RUN: %target-build-swift %t.sib -o %t
33
// RUN: %target-run %t | FileCheck %s
44

5-
// RUN: %target-build-swift -c %t.sib -o %t.o
5+
// RUN: %target-build-swift -Onone -c %t.sib -o %t.o
66
// RUN: %target-build-swift %t.o -o %t
77
// RUN: %target-run %t | FileCheck %s
88

9-
// RUN: %target-build-swift -emit-sibgen %s -o %t.sib
9+
// RUN: %target-build-swift -Onone -emit-sibgen %s -o %t.sib
1010
// RUN: %target-build-swift %t.sib -o %t
1111
// RUN: %target-run %t | FileCheck %s
1212

13-
// RUN: %target-build-swift -c %t.sib -o %t.o
13+
// RUN: %target-build-swift -Onone -c %t.sib -o %t.o
1414
// RUN: %target-build-swift %t.o -o %t
1515
// RUN: %target-run %t | FileCheck %s
1616
// REQUIRES: executable_test

0 commit comments

Comments
 (0)