Skip to content

Commit 155db0a

Browse files
committed
Let Character literals, which fit into 64 bits, be folded into a single integer constant.
This is done by ensuring that the corresponding Character constructor is inlined. llvm will do the constant folding. Also add a test which checks this. It makes character literals much faster (3x improvement for the CharacterLiteralsSmall benchmark) And it removes _a lot_ of redundant code (~80% for the CharacterLiteralsSmall benchmark)
1 parent 3c4fd12 commit 155db0a

File tree

3 files changed

+38
-0
lines changed

3 files changed

+38
-0
lines changed

stdlib/public/core/CTypes.swift

Lines changed: 2 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -206,6 +206,8 @@ extension CVaListPointer : CustomDebugStringConvertible {
206206
}
207207
}
208208

209+
@_versioned
210+
@_inlineable
209211
func _memcpy(
210212
dest destination: UnsafeMutableRawPointer,
211213
src: UnsafeMutableRawPointer,

stdlib/public/core/Character.swift

Lines changed: 4 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -104,6 +104,9 @@ public struct Character :
104104
UTF32.self, input: CollectionOfOne(UInt32(value))))
105105
}
106106

107+
// Inlining ensures that the whole constructor can be folded away to a single
108+
// integer constant in case of small character literals.
109+
@inline(__always)
107110
@effects(readonly)
108111
public init(
109112
_builtinExtendedGraphemeClusterLiteral start: Builtin.RawPointer,
@@ -195,6 +198,7 @@ public struct Character :
195198

196199
/// Creates a Character from a String that is already known to require the
197200
/// large representation.
201+
@_versioned
198202
internal init(_largeRepresentationString s: String) {
199203
if let native = s._core.nativeBuffer,
200204
native.start == s._core._baseAddress! {
Lines changed: 32 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -0,0 +1,32 @@
1+
// RUN: %target-swift-frontend -parse-as-library -O -emit-ir %s | %FileCheck %s
2+
// REQUIRES: swift_stdlib_no_asserts,optimized_stdlib,CPU=x86_64
3+
4+
// This is an end-to-end test to ensure that the optimizer generates
5+
// a simple literal for character literals.
6+
7+
// CHECK-LABEL: define {{.*}}charArray
8+
// CHECK-NOT: {{^}}[^ ]
9+
// CHECK: store i64 9223372036854775649, i64*
10+
// CHECK-NOT: {{^}}[^ ]
11+
// CHECK: store i64 9223372036854775650, i64*
12+
// CHECK-NOT: {{^}}[^ ]
13+
// CHECK: store i64 9223372036854775651, i64*
14+
// CHECK-NOT: {{^}}[^ ]
15+
// CHECK: store i64 9223372036854775652, i64*
16+
// CHECK-NOT: {{^}}[^ ]
17+
// CHECK: ret
18+
public func charArray(_ i: Int) -> [Character] {
19+
return [ "a", "b", "c", "d" ]
20+
}
21+
22+
// CHECK-LABEL: define {{.*}}singleChar
23+
// CHECK: ret {{.*}} 9223372036854775649
24+
public func singleChar() -> Character {
25+
return "a"
26+
}
27+
28+
// CHECK-LABEL: define {{.*}}singleNonAsciiChar
29+
// CHECK: ret {{.*}} 9223372036848850918
30+
public func singleNonAsciiChar() -> Character {
31+
return ""
32+
}

0 commit comments

Comments
 (0)