Skip to content

Commit 8552044

Browse files
authored
Merge pull request #40828 from glessard/sort-optimization
[nfc] document legacy ABI in the implementation of sort
2 parents 59f29f0 + b9eed4f commit 8552044

File tree

2 files changed

+97
-5
lines changed

2 files changed

+97
-5
lines changed

stdlib/public/core/Sort.swift

Lines changed: 21 additions & 5 deletions
Original file line numberDiff line numberDiff line change
@@ -329,9 +329,13 @@ extension MutableCollection where Self: BidirectionalCollection {
329329
}
330330
}
331331

332+
// FIXME(ABI): unused return value
332333
/// Merges the elements in the ranges `lo..<mid` and `mid..<hi` using `buffer`
333334
/// as out-of-place storage. Stable.
334335
///
336+
/// The unused return value is legacy ABI. It was originally added as a
337+
/// workaround for a compiler bug (now fixed). See SR-14750 (rdar://45044610).
338+
///
335339
/// - Precondition: `lo..<mid` and `mid..<hi` must already be sorted according
336340
/// to `areInIncreasingOrder`.
337341
/// - Precondition: `buffer` must point to a region of memory at least as large
@@ -506,15 +510,19 @@ internal func _findNextRun<C: RandomAccessCollection>(
506510
}
507511

508512
extension UnsafeMutableBufferPointer {
513+
// FIXME(ABI): unused return value
509514
/// Merges the elements at `runs[i]` and `runs[i - 1]`, using `buffer` as
510515
/// out-of-place storage.
511516
///
517+
/// The unused return value is legacy ABI. It was originally added as a
518+
/// workaround for a compiler bug (now fixed). See SR-14750 (rdar://45044610).
519+
///
512520
/// - Precondition: `runs.count > 1` and `i > 0`
513521
/// - Precondition: `buffer` must have at least
514522
/// `min(runs[i].count, runs[i - 1].count)` uninitialized elements.
515523
@discardableResult
516524
@inlinable
517-
public mutating func _mergeRuns(
525+
internal mutating func _mergeRuns(
518526
_ runs: inout [Range<Index>],
519527
at i: Int,
520528
buffer: UnsafeMutablePointer<Element>,
@@ -537,17 +545,21 @@ extension UnsafeMutableBufferPointer {
537545

538546
return true
539547
}
540-
548+
549+
// FIXME(ABI): unused return value
541550
/// Merges upper elements of `runs` until the required invariants are
542551
/// satisfied.
543552
///
553+
/// The unused return value is legacy ABI. It was originally added as a
554+
/// workaround for a compiler bug (now fixed). See SR-14750 (rdar://45044610).
555+
///
544556
/// - Precondition: `buffer` must have at least
545557
/// `min(runs[i].count, runs[i - 1].count)` uninitialized elements.
546558
/// - Precondition: The ranges in `runs` must be consecutive, such that for
547559
/// any i, `runs[i].upperBound == runs[i + 1].lowerBound`.
548560
@discardableResult
549561
@inlinable
550-
public mutating func _mergeTopRuns(
562+
internal mutating func _mergeTopRuns(
551563
_ runs: inout [Range<Index>],
552564
buffer: UnsafeMutablePointer<Element>,
553565
by areInIncreasingOrder: (Element, Element) throws -> Bool
@@ -611,16 +623,20 @@ extension UnsafeMutableBufferPointer {
611623

612624
return true
613625
}
614-
626+
627+
// FIXME(ABI): unused return value
615628
/// Merges elements of `runs` until only one run remains.
616629
///
630+
/// The unused return value is legacy ABI. It was originally added as a
631+
/// workaround for a compiler bug (now fixed). See SR-14750 (rdar://45044610).
632+
///
617633
/// - Precondition: `buffer` must have at least
618634
/// `min(runs[i].count, runs[i - 1].count)` uninitialized elements.
619635
/// - Precondition: The ranges in `runs` must be consecutive, such that for
620636
/// any i, `runs[i].upperBound == runs[i + 1].lowerBound`.
621637
@discardableResult
622638
@inlinable
623-
public mutating func _finalizeRuns(
639+
internal mutating func _finalizeRuns(
624640
_ runs: inout [Range<Index>],
625641
buffer: UnsafeMutablePointer<Element>,
626642
by areInIncreasingOrder: (Element, Element) throws -> Bool

validation-test/stdlib/Sort-ABI.swift

Lines changed: 76 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -0,0 +1,76 @@
1+
// RUN: %target-run-stdlib-swift
2+
// REQUIRES: executable_test
3+
4+
import StdlibUnittest
5+
6+
var SortABITestSuite = TestSuite("SortABI")
7+
8+
SortABITestSuite.test("_merge-ABI") {
9+
let result = withUnsafeTemporaryAllocation(of: Int.self, capacity: 10) {
10+
buffer -> Bool in
11+
_ = buffer.initialize(from: 0..<10)
12+
return withUnsafeTemporaryAllocation(of: Int.self, capacity: 10) {
13+
_merge(
14+
low: buffer.baseAddress! + 5,
15+
mid: buffer.baseAddress! + 8,
16+
high: buffer.baseAddress! + 9,
17+
buffer: $0.baseAddress!,
18+
by: <
19+
)
20+
}
21+
}
22+
// The return value is legacy ABI. It was originally added as a
23+
// workaround for a compiler bug (now fixed). See SR-14750 (rdar://45044610).
24+
// `_merge` always returns `true`
25+
expectEqual(result, true)
26+
}
27+
28+
SortABITestSuite.test("_mergeRuns-ABI") {
29+
let result = withUnsafeTemporaryAllocation(of: Int.self, capacity: 10) {
30+
temp -> Bool in
31+
_ = temp.initialize(from: 0..<10)
32+
var buffer = temp
33+
var runs = [5..<8, 8..<9]
34+
return withUnsafeTemporaryAllocation(of: Int.self, capacity: 10) {
35+
buffer._mergeRuns(&runs, at: 1, buffer: $0.baseAddress!, by: <)
36+
}
37+
}
38+
// The return value is legacy ABI. It was originally added as a
39+
// workaround for a compiler bug (now fixed). See SR-14750 (rdar://45044610).
40+
// `_mergeRuns` always returns `true`
41+
expectEqual(result, true)
42+
}
43+
44+
SortABITestSuite.test("_mergeTopRuns-ABI") {
45+
let result = withUnsafeTemporaryAllocation(of: Int.self, capacity: 10) {
46+
temp -> Bool in
47+
_ = temp.initialize(from: 0..<10)
48+
var buffer = temp
49+
var runs = [5..<8, 8..<9]
50+
return withUnsafeTemporaryAllocation(of: Int.self, capacity: 10) {
51+
buffer._mergeTopRuns(&runs, buffer: $0.baseAddress!, by: <)
52+
}
53+
}
54+
// The return value is legacy ABI. It was originally added as a
55+
// workaround for a compiler bug (now fixed). See SR-14750 (rdar://45044610).
56+
// `_mergeTopRuns` always returns `true`
57+
expectEqual(result, true)
58+
}
59+
60+
SortABITestSuite.test("_finalizeRuns-ABI") {
61+
let result = withUnsafeTemporaryAllocation(of: Int.self, capacity: 10) {
62+
temp -> Bool in
63+
_ = temp.initialize(from: 0..<10)
64+
var buffer = temp
65+
var runs = [5..<8, 8..<9]
66+
return withUnsafeTemporaryAllocation(of: Int.self, capacity: 10) {
67+
buffer._finalizeRuns(&runs, buffer: $0.baseAddress!, by: <)
68+
}
69+
}
70+
// The return value is legacy ABI. It was originally added as a
71+
// workaround for a compiler bug (now fixed). See SR-14750 (rdar://45044610).
72+
// `_finalizeRuns` always returns `true`
73+
expectEqual(result, true)
74+
}
75+
76+
runAllTests()

0 commit comments

Comments
 (0)