Skip to content

Commit 9152e29

Browse files
authored
Merge pull request #16890 from eeckstein/stdlib-perf-changes
Some performance improvements in the stdlib, mainly for small string literals
2 parents f0b5833 + 47383e2 commit 9152e29

12 files changed

+156
-214
lines changed

lib/SILOptimizer/SILCombiner/SILCombinerMiscVisitors.cpp

Lines changed: 2 additions & 18 deletions
Original file line numberDiff line numberDiff line change
@@ -686,20 +686,6 @@ SILInstruction *SILCombiner::visitCondFailInst(CondFailInst *CFI) {
686686
return nullptr;
687687
}
688688

689-
static bool isValueToBridgeObjectremovable(ValueToBridgeObjectInst *VTBOI) {
690-
SILValue operand = VTBOI->getOperand();
691-
// If operand is a struct $UInt (% : $Builtin.), fetch the real source
692-
if (auto *SI = dyn_cast<StructInst>(operand)) {
693-
assert(SI->SILInstruction::getAllOperands().size() == 1 &&
694-
"Expected a single operand");
695-
operand = SI->getOperand(0);
696-
}
697-
if (auto *BI = dyn_cast<BuiltinInst>(operand)) {
698-
return (BI->getBuiltinInfo().ID == BuiltinValueKind::StringObjectOr);
699-
}
700-
return false;
701-
}
702-
703689
SILInstruction *SILCombiner::visitStrongRetainInst(StrongRetainInst *SRI) {
704690
// Retain of ThinToThickFunction is a no-op.
705691
SILValue funcOper = SRI->getOperand();
@@ -718,8 +704,7 @@ SILInstruction *SILCombiner::visitStrongRetainInst(StrongRetainInst *SRI) {
718704
// builtin "stringObjectOr_Int64" (or to tag the string)
719705
// value_to_bridge_object (cast the UInt to bridge object)
720706
if (auto *VTBOI = dyn_cast<ValueToBridgeObjectInst>(SRI->getOperand())) {
721-
if (isValueToBridgeObjectremovable(VTBOI))
722-
return eraseInstFromFunction(*SRI);
707+
return eraseInstFromFunction(*SRI);
723708
}
724709

725710
// Sometimes in the stdlib due to hand offs, we will see code like:
@@ -1169,8 +1154,7 @@ SILInstruction *SILCombiner::visitStrongReleaseInst(StrongReleaseInst *SRI) {
11691154
// builtin "stringObjectOr_Int64" (or to tag the string)
11701155
// value_to_bridge_object (cast the UInt to bridge object)
11711156
if (auto *VTBOI = dyn_cast<ValueToBridgeObjectInst>(SRI->getOperand())) {
1172-
if (isValueToBridgeObjectremovable(VTBOI))
1173-
return eraseInstFromFunction(*SRI);
1157+
return eraseInstFromFunction(*SRI);
11741158
}
11751159

11761160
// Release of a classbound existential converted from a class is just a

stdlib/public/core/CMakeLists.txt

Lines changed: 0 additions & 1 deletion
Original file line numberDiff line numberDiff line change
@@ -108,7 +108,6 @@ set(SWIFTLIB_ESSENTIAL
108108
Runtime.swift.gyb
109109
RuntimeFunctionCounters.swift
110110
SipHash.swift
111-
SentinelCollection.swift
112111
Sequence.swift
113112
SequenceAlgorithms.swift
114113
SequenceWrapper.swift

stdlib/public/core/ExistentialCollection.swift.gyb

Lines changed: 2 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -413,6 +413,7 @@ internal final class _${Kind}Box<S : ${Kind}> : _Any${Kind}Box<S.Iterator.Elemen
413413
{
414414
internal typealias Element = S.Element
415415

416+
@inline(__always)
416417
@inlinable
417418
internal override func _makeIterator() -> AnyIterator<Element> {
418419
return AnyIterator(_base.makeIterator())
@@ -710,6 +711,7 @@ extension Any${Kind} {
710711
% else:
711712
/// Returns an iterator over the elements of this collection.
712713
% end
714+
@inline(__always)
713715
@inlinable
714716
public func makeIterator() -> Iterator {
715717
return _box._makeIterator()

stdlib/public/core/GroupInfo.json

Lines changed: 0 additions & 1 deletion
Original file line numberDiff line numberDiff line change
@@ -63,7 +63,6 @@
6363
"Repeat.swift",
6464
"Sort.swift",
6565
"Range.swift",
66-
"SentinelCollection.swift",
6766
"ClosedRange.swift",
6867
"CollectionOfOne.swift",
6968
"HeapBuffer.swift",

stdlib/public/core/SentinelCollection.swift

Lines changed: 0 additions & 143 deletions
This file was deleted.

stdlib/public/core/SmallString.swift

Lines changed: 27 additions & 10 deletions
Original file line numberDiff line numberDiff line change
@@ -127,25 +127,30 @@ extension _SmallUTF8String {
127127
#endif
128128
}
129129

130+
@inline(__always)
130131
@inlinable
132+
@effects(readonly)
131133
public // @testable
132134
init?(_ codeUnits: UnsafeBufferPointer<UInt8>) {
133135
#if arch(i386) || arch(arm)
134136
return nil // Never form small strings on 32-bit
135137
#else
136138
let count = codeUnits.count
137139
guard count <= _SmallUTF8String.capacity else { return nil }
138-
self.init()
139-
self._withAllUnsafeMutableBytes { rawBufPtr in
140-
let rawDst = rawBufPtr.baseAddress._unsafelyUnwrappedUnchecked
141-
memcpy_(
142-
dst: rawDst.assumingMemoryBound(to: UInt8.self),
143-
src: codeUnits.baseAddress._unsafelyUnwrappedUnchecked,
144-
count: count
145-
)
140+
141+
let addr = codeUnits.baseAddress._unsafelyUnwrappedUnchecked
142+
var high: UInt
143+
let lowCount: Int
144+
if count > 8 {
145+
lowCount = 8
146+
high = _bytesToUInt(addr + 8, count &- 8)
147+
} else {
148+
lowCount = count
149+
high = 0
146150
}
147-
_sanityCheck(self.count == 0, "overwrote count early?")
148-
self.count = count
151+
high |= (UInt(count) &<< (8*15))
152+
let low = _bytesToUInt(addr, lowCount)
153+
_storage = (low, high)
149154

150155
// FIXME: support transcoding
151156
if !self.isASCII { return nil }
@@ -169,6 +174,18 @@ extension _SmallUTF8String {
169174
}
170175
}
171176

177+
@inline(__always)
178+
@inlinable
179+
func _bytesToUInt(_ input: UnsafePointer<UInt8>, _ c: Int) -> UInt {
180+
var r: UInt = 0
181+
var shift: Int = 0
182+
for idx in 0..<c {
183+
r = r | (UInt(input[idx]) &<< shift)
184+
shift = shift &+ 8
185+
}
186+
return r
187+
}
188+
172189
//
173190
// Small string read interface
174191
//

stdlib/public/core/String.swift

Lines changed: 3 additions & 5 deletions
Original file line numberDiff line numberDiff line change
@@ -231,11 +231,8 @@ extension String {
231231
decodingCString nullTerminatedCodeUnits: UnsafePointer<Encoding.CodeUnit>,
232232
as sourceEncoding: Encoding.Type) {
233233

234-
let codeUnits = _SentinelCollection(
235-
UnsafeBufferPointer(_unboundedStartingAt: nullTerminatedCodeUnits),
236-
until: _IsZero()
237-
)
238-
self.init(decoding: codeUnits, as: sourceEncoding)
234+
self = String.decodeCString(
235+
nullTerminatedCodeUnits, as: sourceEncoding)!.result
239236
}
240237

241238
/// Calls the given closure with a pointer to the contents of the string,
@@ -737,6 +734,7 @@ extension String : _ExpressibleByBuiltinUTF16StringLiteral {
737734
}
738735

739736
extension String : _ExpressibleByBuiltinStringLiteral {
737+
@inline(__always)
740738
@inlinable
741739
@effects(readonly)
742740
@_semantics("string.makeUTF8")

0 commit comments

Comments
 (0)