Skip to content

Commit 570c22c

Browse files
authored
Merge pull request #2334 from swiftwasm/main
[pull] swiftwasm from main
2 parents 97e10e4 + 8082b58 commit 570c22c

19 files changed

+158
-63
lines changed

lib/Driver/Compilation.cpp

Lines changed: 5 additions & 2 deletions
Original file line numberDiff line numberDiff line change
@@ -1802,8 +1802,11 @@ namespace driver {
18021802

18031803
fine_grained_dependencies::ModuleDepGraph &&
18041804
takeFineGrainedDepGraph(const bool forRanges) && {
1805-
return forRanges ? std::move(FineGrainedDepGraphForRanges)
1806-
: std::move(FineGrainedDepGraph);
1805+
if (forRanges) {
1806+
return std::move(FineGrainedDepGraphForRanges);
1807+
} else {
1808+
return std::move(FineGrainedDepGraph);
1809+
}
18071810
}
18081811
};
18091812
} // namespace driver

lib/Frontend/ArgsToFrontendOutputsConverter.cpp

Lines changed: 9 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -354,6 +354,15 @@ SupplementaryOutputPathsComputer::getSupplementaryFilenamesFromArguments(
354354

355355
if (paths.size() == N)
356356
return paths;
357+
else if (pathID == options::OPT_emit_loaded_module_trace_path &&
358+
paths.size() < N) {
359+
// We only need one file to output the module trace file because they
360+
// are all equivalent. Add additional empty output paths for module trace to
361+
// make sure the compiler won't panic for diag::error_wrong_number_of_arguments.
362+
for(unsigned I = paths.size(); I != N; I ++)
363+
paths.emplace_back();
364+
return paths;
365+
}
357366

358367
if (paths.empty())
359368
return std::vector<std::string>(N, std::string());

stdlib/public/Concurrency/Task.cpp

Lines changed: 1 addition & 20 deletions
Original file line numberDiff line numberDiff line change
@@ -22,11 +22,6 @@
2222
#include "TaskPrivate.h"
2323
#include "AsyncCall.h"
2424

25-
#if defined(__APPLE__)
26-
// TODO: We shouldn't need this
27-
#include <dispatch/dispatch.h>
28-
#endif
29-
3025
using namespace swift;
3126
using FutureFragment = AsyncTask::FutureFragment;
3227

@@ -509,23 +504,9 @@ struct AsyncContinuationContext {
509504

510505
static void resumeTaskAfterContinuation(AsyncTask *task,
511506
AsyncContinuationContext *context) {
512-
#if __APPLE__
513-
// TODO: Enqueue the task on the specific executor in the continuation
514-
// context.
515-
//
516-
// For now, just enqueue the task resumption on the global concurrent queue
517-
// so that we're able to return back to the caller of resume.
518-
519-
dispatch_async(dispatch_get_global_queue(DISPATCH_QUEUE_PRIORITY_DEFAULT, 0),
520-
^{
521-
task->run(context->ResumeExecutor);
522-
});
523-
#else
524-
swift_unreachable("not implemented");
525-
#endif
507+
swift_task_enqueue(task, context->ResumeExecutor);
526508
}
527509

528-
529510
}
530511

531512
SWIFT_CC(swift)

stdlib/public/Concurrency/Task.swift

Lines changed: 3 additions & 3 deletions
Original file line numberDiff line numberDiff line change
@@ -412,11 +412,11 @@ public func _runChildTask<T>(operation: @escaping () async throws -> T) async
412412
@_alwaysEmitIntoClient
413413
@usableFromInline
414414
internal func _runTaskForBridgedAsyncMethod(_ body: @escaping () async -> Void) {
415-
// TODO: As a start, we should invoke Task.runDetached here, but we
416-
// can probably do better if we're already running on behalf of a task,
415+
// TODO: We can probably do better than Task.runDetached
416+
// if we're already running on behalf of a task,
417417
// if the receiver of the method invocation is itself an Actor, or in other
418418
// situations.
419-
fatalError("not implemented")
419+
_ = Task.runDetached { await body() }
420420
}
421421

422422
#endif

stdlib/public/SwiftShims/LibcShims.h

Lines changed: 5 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -129,7 +129,12 @@ float _stdlib_remainderf(float _self, float _other) {
129129

130130
static inline SWIFT_ALWAYS_INLINE
131131
float _stdlib_squareRootf(float _self) {
132+
#if defined(_WIN32) && (defined(_M_IX86) || defined(__i386__))
133+
typedef float __m128 __attribute__((__vector_size__(16), __aligned__(16)));
134+
return __builtin_ia32_sqrtss(__extension__ (__m128){ _self, 0, 0, 0 })[0];
135+
#else
132136
return __builtin_sqrtf(_self);
137+
#endif
133138
}
134139

135140
static inline SWIFT_ALWAYS_INLINE

stdlib/public/core/ClosedRange.swift

Lines changed: 18 additions & 8 deletions
Original file line numberDiff line numberDiff line change
@@ -68,6 +68,14 @@ public struct ClosedRange<Bound: Comparable> {
6868
/// The range's upper bound.
6969
public let upperBound: Bound
7070

71+
// This works around _debugPrecondition() impacting the performance of
72+
// optimized code. (rdar://72246338)
73+
@_alwaysEmitIntoClient @inline(__always)
74+
internal init(_uncheckedBounds bounds: (lower: Bound, upper: Bound)) {
75+
self.lowerBound = bounds.lower
76+
self.upperBound = bounds.upper
77+
}
78+
7179
/// Creates an instance with the given bounds.
7280
///
7381
/// Because this initializer does not perform any checks, it should be used
@@ -78,8 +86,9 @@ public struct ClosedRange<Bound: Comparable> {
7886
/// - Parameter bounds: A tuple of the lower and upper bounds of the range.
7987
@inlinable
8088
public init(uncheckedBounds bounds: (lower: Bound, upper: Bound)) {
81-
self.lowerBound = bounds.lower
82-
self.upperBound = bounds.upper
89+
_debugPrecondition(bounds.lower <= bounds.upper,
90+
"ClosedRange requires lowerBound <= upperBound")
91+
self.init(_uncheckedBounds: (lower: bounds.lower, upper: bounds.upper))
8392
}
8493
}
8594

@@ -100,8 +109,9 @@ extension ClosedRange: RangeExpression {
100109
public func relative<C: Collection>(to collection: C) -> Range<Bound>
101110
where C.Index == Bound {
102111
return Range(
103-
uncheckedBounds: (
104-
lower: lowerBound, upper: collection.index(after: self.upperBound)))
112+
_uncheckedBounds: (
113+
lower: lowerBound,
114+
upper: collection.index(after: self.upperBound)))
105115
}
106116

107117
/// Returns a Boolean value indicating whether the given element is contained
@@ -336,7 +346,7 @@ extension Comparable {
336346
public static func ... (minimum: Self, maximum: Self) -> ClosedRange<Self> {
337347
_precondition(
338348
minimum <= maximum, "Range requires lowerBound <= upperBound")
339-
return ClosedRange(uncheckedBounds: (lower: minimum, upper: maximum))
349+
return ClosedRange(_uncheckedBounds: (lower: minimum, upper: maximum))
340350
}
341351
}
342352

@@ -423,7 +433,7 @@ extension ClosedRange {
423433
limits.upperBound < self.upperBound ? limits.upperBound
424434
: limits.lowerBound > self.upperBound ? limits.lowerBound
425435
: self.upperBound
426-
return ClosedRange(uncheckedBounds: (lower: lower, upper: upper))
436+
return ClosedRange(_uncheckedBounds: (lower: lower, upper: upper))
427437
}
428438
}
429439

@@ -439,7 +449,7 @@ extension ClosedRange where Bound: Strideable, Bound.Stride: SignedInteger {
439449
public init(_ other: Range<Bound>) {
440450
_precondition(!other.isEmpty, "Can't form an empty closed range")
441451
let upperBound = other.upperBound.advanced(by: -1)
442-
self.init(uncheckedBounds: (lower: other.lowerBound, upper: upperBound))
452+
self.init(_uncheckedBounds: (lower: other.lowerBound, upper: upperBound))
443453
}
444454
}
445455

@@ -476,7 +486,7 @@ extension ClosedRange: Decodable where Bound: Decodable {
476486
codingPath: decoder.codingPath,
477487
debugDescription: "Cannot initialize \(ClosedRange.self) with a lowerBound (\(lowerBound)) greater than upperBound (\(upperBound))"))
478488
}
479-
self.init(uncheckedBounds: (lower: lowerBound, upper: upperBound))
489+
self.init(_uncheckedBounds: (lower: lowerBound, upper: upperBound))
480490
}
481491
}
482492

stdlib/public/core/Range.swift

Lines changed: 16 additions & 7 deletions
Original file line numberDiff line numberDiff line change
@@ -157,6 +157,14 @@ public struct Range<Bound: Comparable> {
157157
/// instance does not contain its upper bound.
158158
public let upperBound: Bound
159159

160+
// This works around _debugPrecondition() impacting the performance of
161+
// optimized code. (rdar://72246338)
162+
@_alwaysEmitIntoClient @inline(__always)
163+
internal init(_uncheckedBounds bounds: (lower: Bound, upper: Bound)) {
164+
self.lowerBound = bounds.lower
165+
self.upperBound = bounds.upper
166+
}
167+
160168
/// Creates an instance with the given bounds.
161169
///
162170
/// Because this initializer does not perform any checks, it should be used
@@ -167,8 +175,9 @@ public struct Range<Bound: Comparable> {
167175
/// - Parameter bounds: A tuple of the lower and upper bounds of the range.
168176
@inlinable
169177
public init(uncheckedBounds bounds: (lower: Bound, upper: Bound)) {
170-
self.lowerBound = bounds.lower
171-
self.upperBound = bounds.upper
178+
_debugPrecondition(bounds.lower <= bounds.upper,
179+
"Range requires lowerBound <= upperBound")
180+
self.init(_uncheckedBounds: (lower: bounds.lower, upper: bounds.upper))
172181
}
173182

174183
/// Returns a Boolean value indicating whether the given element is contained
@@ -308,7 +317,7 @@ extension Range where Bound: Strideable, Bound.Stride: SignedInteger {
308317
/// require an upper bound of `Int.max + 1`, which is not representable as
309318
public init(_ other: ClosedRange<Bound>) {
310319
let upperBound = other.upperBound.advanced(by: 1)
311-
self.init(uncheckedBounds: (lower: other.lowerBound, upper: upperBound))
320+
self.init(_uncheckedBounds: (lower: other.lowerBound, upper: upperBound))
312321
}
313322
}
314323

@@ -325,7 +334,7 @@ extension Range: RangeExpression {
325334
@inlinable // trivial-implementation
326335
public func relative<C: Collection>(to collection: C) -> Range<Bound>
327336
where C.Index == Bound {
328-
return Range(uncheckedBounds: (lower: lowerBound, upper: upperBound))
337+
self
329338
}
330339
}
331340

@@ -359,7 +368,7 @@ extension Range {
359368
limits.upperBound < self.upperBound ? limits.upperBound
360369
: limits.lowerBound > self.upperBound ? limits.lowerBound
361370
: self.upperBound
362-
return Range(uncheckedBounds: (lower: lower, upper: upper))
371+
return Range(_uncheckedBounds: (lower: lower, upper: upper))
363372
}
364373
}
365374

@@ -435,7 +444,7 @@ extension Range: Decodable where Bound: Decodable {
435444
codingPath: decoder.codingPath,
436445
debugDescription: "Cannot initialize \(Range.self) with a lowerBound (\(lowerBound)) greater than upperBound (\(upperBound))"))
437446
}
438-
self.init(uncheckedBounds: (lower: lowerBound, upper: upperBound))
447+
self.init(_uncheckedBounds: (lower: lowerBound, upper: upperBound))
439448
}
440449
}
441450

@@ -729,7 +738,7 @@ extension Comparable {
729738
public static func ..< (minimum: Self, maximum: Self) -> Range<Self> {
730739
_precondition(minimum <= maximum,
731740
"Range requires lowerBound <= upperBound")
732-
return Range(uncheckedBounds: (lower: minimum, upper: maximum))
741+
return Range(_uncheckedBounds: (lower: minimum, upper: maximum))
733742
}
734743

735744
/// Returns a partial range up to, but not including, its upper bound.

stdlib/public/core/SmallString.swift

Lines changed: 1 addition & 1 deletion
Original file line numberDiff line numberDiff line change
@@ -208,7 +208,7 @@ extension _SmallString {
208208
// Restore the memory type of self._storage
209209
_ = rawPtr.bindMemory(to: RawBitPattern.self, capacity: 1)
210210
}
211-
return try f(UnsafeBufferPointer(start: ptr, count: count))
211+
return try f(UnsafeBufferPointer(_uncheckedStart: ptr, count: count))
212212
}
213213
}
214214

stdlib/public/core/String.swift

Lines changed: 1 addition & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -458,6 +458,7 @@ extension String {
458458
contigBytes._providesContiguousBytesNoCopy
459459
{
460460
self = contigBytes.withUnsafeBytes { rawBufPtr in
461+
Builtin.onFastPath() // encourage SIL Optimizer to inline this closure
461462
return String._fromUTF8Repairing(
462463
UnsafeBufferPointer(
463464
start: rawBufPtr.baseAddress?.assumingMemoryBound(to: UInt8.self),

stdlib/public/core/StringObject.swift

Lines changed: 1 addition & 1 deletion
Original file line numberDiff line numberDiff line change
@@ -902,7 +902,7 @@ extension _StringObject {
902902
return sharedUTF8
903903
}
904904
return UnsafeBufferPointer(
905-
start: self.nativeUTF8Start, count: self.largeCount)
905+
_uncheckedStart: self.nativeUTF8Start, count: self.largeCount)
906906
}
907907

908908
// Whether the object stored can be bridged directly as a NSString

stdlib/public/core/StringProtocol.swift

Lines changed: 1 addition & 1 deletion
Original file line numberDiff line numberDiff line change
@@ -153,7 +153,7 @@ extension StringProtocol {
153153
let end = endIndex
154154
_internalInvariant(
155155
start.transcodedOffset == 0 && end.transcodedOffset == 0)
156-
return Range(uncheckedBounds: (start._encodedOffset, end._encodedOffset))
156+
return Range(_uncheckedBounds: (start._encodedOffset, end._encodedOffset))
157157
}
158158
}
159159

stdlib/public/core/StringStorageBridge.swift

Lines changed: 1 addition & 1 deletion
Original file line numberDiff line numberDiff line change
@@ -30,7 +30,7 @@ extension _AbstractStringStorage {
3030
"Range out of bounds")
3131

3232
let range = Range(
33-
uncheckedBounds: (aRange.location, aRange.location+aRange.length))
33+
_uncheckedBounds: (aRange.location, aRange.location+aRange.length))
3434
let str = asString
3535
str._copyUTF16CodeUnits(
3636
into: UnsafeMutableBufferPointer(start: buffer, count: range.count),

stdlib/public/core/Substring.swift

Lines changed: 6 additions & 5 deletions
Original file line numberDiff line numberDiff line change
@@ -105,7 +105,7 @@ public struct Substring {
105105

106106
self._slice = Slice(
107107
base: slice.base,
108-
bounds: Range(uncheckedBounds: (start, end)))
108+
bounds: Range(_uncheckedBounds: (start, end)))
109109
_invariantCheck()
110110
}
111111

@@ -132,7 +132,7 @@ extension Substring {
132132
@inlinable @inline(__always)
133133
internal var _offsetRange: Range<Int> {
134134
return Range(
135-
uncheckedBounds: (startIndex._encodedOffset, endIndex._encodedOffset))
135+
_uncheckedBounds: (startIndex._encodedOffset, endIndex._encodedOffset))
136136
}
137137

138138
#if !INTERNAL_CHECKS_ENABLED
@@ -322,7 +322,8 @@ extension Substring: CustomDebugStringConvertible {
322322

323323
extension Substring: LosslessStringConvertible {
324324
public init(_ content: String) {
325-
self = content[...]
325+
let range = Range(_uncheckedBounds: (content.startIndex, content.endIndex))
326+
self.init(Slice(base: content, bounds: range))
326327
}
327328
}
328329

@@ -727,14 +728,14 @@ extension Substring: RangeReplaceableCollection {
727728
public init<S: Sequence>(_ elements: S)
728729
where S.Element == Character {
729730
if let str = elements as? String {
730-
self = str[...]
731+
self.init(str)
731732
return
732733
}
733734
if let subStr = elements as? Substring {
734735
self = subStr
735736
return
736737
}
737-
self = String(elements)[...]
738+
self.init(String(elements))
738739
}
739740

740741
@inlinable // specialize

stdlib/public/core/UnsafeBufferPointer.swift.gyb

Lines changed: 33 additions & 5 deletions
Original file line numberDiff line numberDiff line change
@@ -207,7 +207,14 @@ extension Unsafe${Mutable}BufferPointer: ${Mutable}Collection, RandomAccessColle
207207
// optimizer is not capable of creating partial specializations yet.
208208
// NOTE: Range checks are not performed here, because it is done later by
209209
// the subscript function.
210-
return end - start
210+
// NOTE: We allow the subtraction to silently overflow in release builds
211+
// to eliminate a superflous check when `start` and `end` are both valid
212+
// indices. (The operation can only overflow if `start` is negative, which
213+
// implies it's an invalid index.) `Collection` does not specify what
214+
// `distance` should return when given an invalid index pair.
215+
let result = end.subtractingReportingOverflow(start)
216+
_debugPrecondition(!result.overflow)
217+
return result.partialValue
211218
}
212219

213220
@inlinable // unsafe-performance
@@ -387,6 +394,17 @@ extension Unsafe${Mutable}BufferPointer: ${Mutable}Collection, RandomAccessColle
387394
}
388395

389396
extension Unsafe${Mutable}BufferPointer {
397+
// This works around _debugPrecondition() impacting the performance of
398+
// optimized code. (rdar://72246338)
399+
@_alwaysEmitIntoClient
400+
internal init(
401+
@_nonEphemeral _uncheckedStart start: Unsafe${Mutable}Pointer<Element>?,
402+
count: Int
403+
) {
404+
_position = start
405+
self.count = count
406+
}
407+
390408
/// Creates a new buffer pointer over the specified number of contiguous
391409
/// instances beginning at the given pointer.
392410
///
@@ -401,13 +419,12 @@ extension Unsafe${Mutable}BufferPointer {
401419
public init(
402420
@_nonEphemeral start: Unsafe${Mutable}Pointer<Element>?, count: Int
403421
) {
404-
_precondition(
422+
_debugPrecondition(
405423
count >= 0, "Unsafe${Mutable}BufferPointer with negative count")
406-
_precondition(
424+
_debugPrecondition(
407425
count == 0 || start != nil,
408426
"Unsafe${Mutable}BufferPointer has a nil start and nonzero count")
409-
_position = start
410-
self.count = count
427+
self.init(_uncheckedStart: start, count: _assumeNonNegative(count))
411428
}
412429

413430
@inlinable // unsafe-performance
@@ -498,6 +515,17 @@ extension Unsafe${Mutable}BufferPointer {
498515
/// - Parameter slice: The buffer slice to rebase.
499516
@inlinable // unsafe-performance
500517
public init(rebasing slice: Slice<UnsafeBufferPointer<Element>>) {
518+
// NOTE: `Slice` does not guarantee that its start/end indices are valid
519+
// in `base` -- it merely ensures that `startIndex <= endIndex`.
520+
// We need manually check that we aren't given an invalid slice,
521+
// or the resulting collection would allow access that was
522+
// out-of-bounds with respect to the original base buffer.
523+
// We only do this in debug builds to prevent a measurable performance
524+
// degradation wrt passing around pointers not wrapped in a BufferPointer
525+
// construct.
526+
_debugPrecondition(
527+
slice.startIndex >= 0 && slice.endIndex <= slice.base.count,
528+
"Invalid slice")
501529
let base = slice.base.baseAddress?.advanced(by: slice.startIndex)
502530
let count = slice.endIndex &- slice.startIndex
503531
self.init(start: base, count: count)

0 commit comments

Comments
 (0)