Skip to content

Commit b1769df

Browse files
authored
Merge pull request #9225 from eeckstein/char-literals
Let Character literals, which fit into 64 bits, be folded into a single integer constant.
2 parents 0ffe048 + 155db0a commit b1769df

File tree

5 files changed

+57
-8
lines changed

5 files changed

+57
-8
lines changed

benchmark/single-source/CharacterLiteralsSmall.swift

Lines changed: 13 additions & 8 deletions
Original file line numberDiff line numberDiff line change
@@ -55,15 +55,20 @@ func makeCharacter_UTF8Length8() -> Character {
5555
return "\u{00a9}\u{0300}\u{0301}\u{0302}"
5656
}
5757

58+
@inline(never)
59+
func makeLiterals() {
60+
blackHole(makeCharacter_UTF8Length1())
61+
blackHole(makeCharacter_UTF8Length2())
62+
blackHole(makeCharacter_UTF8Length3())
63+
blackHole(makeCharacter_UTF8Length4())
64+
blackHole(makeCharacter_UTF8Length5())
65+
blackHole(makeCharacter_UTF8Length6())
66+
blackHole(makeCharacter_UTF8Length7())
67+
blackHole(makeCharacter_UTF8Length8())
68+
}
69+
5870
public func run_CharacterLiteralsSmall(_ N: Int) {
5971
for _ in 0...10000 * N {
60-
_ = makeCharacter_UTF8Length1()
61-
_ = makeCharacter_UTF8Length2()
62-
_ = makeCharacter_UTF8Length3()
63-
_ = makeCharacter_UTF8Length4()
64-
_ = makeCharacter_UTF8Length5()
65-
_ = makeCharacter_UTF8Length6()
66-
_ = makeCharacter_UTF8Length7()
67-
_ = makeCharacter_UTF8Length8()
72+
makeLiterals()
6873
}
6974
}

benchmark/utils/TestsUtils.swift

Lines changed: 6 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -66,3 +66,9 @@ struct MyStruct : SomeProtocol {
6666
}
6767
public func someProtocolFactory() -> SomeProtocol { return MyStruct() }
6868

69+
// Just consume the argument.
70+
// It's important that this function is in a another module than the tests
71+
// which are using it.
72+
public func blackHole<T>(_ x: T) {
73+
}
74+

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)