Skip to content

Commit 8557e23

Browse files
authored
Merge branch 'main' into cal--fix-nested-weak-self-issue
2 parents e6a2230 + 1d6f8ef commit 8557e23

File tree

476 files changed

+13978
-4160
lines changed

Some content is hidden

Large Commits have some content hidden by default. Use the searchbox below for content that may be hidden.

476 files changed

+13978
-4160
lines changed

Runtimes/Core/CMakeLists.txt

Lines changed: 2 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -152,6 +152,8 @@ add_compile_options(
152152
"$<$<COMPILE_LANGUAGE:Swift>:SHELL:-enable-experimental-feature FreestandingMacros>"
153153
"$<$<COMPILE_LANGUAGE:Swift>:SHELL:-enable-experimental-feature BitwiseCopyable>"
154154
"$<$<COMPILE_LANGUAGE:Swift>:SHELL:-enable-experimental-feature Extern>"
155+
"$<$<COMPILE_LANGUAGE:Swift>:SHELL:-enable-experimental-feature ValueGenerics>"
156+
"$<$<COMPILE_LANGUAGE:Swift>:SHELL:-enable-experimental-feature AddressableParameters>"
155157
"$<$<COMPILE_LANGUAGE:Swift>:SHELL:-Xfrontend -enable-experimental-concise-pound-file>"
156158
"$<$<COMPILE_LANGUAGE:Swift>:SHELL:-Xfrontend -enable-lexical-lifetimes=false>"
157159
"$<$<COMPILE_LANGUAGE:Swift>:SHELL:-Xfrontend -disable-implicit-concurrency-module-import>"

Runtimes/Core/cmake/caches/Vendors/Apple/apple-common.cmake

Lines changed: 3 additions & 3 deletions
Original file line numberDiff line numberDiff line change
@@ -13,6 +13,6 @@ set(SwiftCore_ENABLE_RUNTIME_FUNCTION_COUNTERS ON CACHE BOOL "")
1313
set(SwiftCore_ENABLE_BACKDEPLOYMENT_SUPPORT ON CACHE BOOL "")
1414
set(SwiftCore_ENABLE_FILESYSTEM_SUPPORT ON CACHE BOOL "")
1515

16-
set(CMAKE_CXX_FLAGS_RELWITHDEBINFO "-O3 -gline-tables-only -DNDEBUG" CACHE STRING "")
17-
set(CMAKE_C_FLAGS_RELWITHDEBINFO "-O3 -gline-tables-only -DNDEBUG" CACHE STRING "")
18-
set(CMAKE_Swift_FLAGS_RELWITHDEBINFO "-O -gline-tables-only" CACHE STRING "")
16+
set(CMAKE_CXX_FLAGS_MINSIZEREL "-Os -g -DNDEBUG" CACHE STRING "")
17+
set(CMAKE_C_FLAGS_MINSIZEREL "-Os -g -DNDEBUG" CACHE STRING "")
18+
set(CMAKE_Swift_FLAGS_MINSIZEREL "-Osize -g" CACHE STRING "")

Runtimes/Core/cmake/caches/Vendors/Apple/arm64-BridgeOS.cmake

Lines changed: 1 addition & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -8,5 +8,6 @@ set(CMAKE_Swift_COMPILER_TARGET "arm64-apple-bridgeos${CMAKE_OSX_DEPLOYMENT_TARG
88

99
set(SwiftCore_ARCH_SUBDIR arm64)
1010
set(SwiftCore_PLATFORM_SUBDIR freestanding)
11+
set(CMAKE_BUILD_TYPE MinSizeRel CACHE STRING "")
1112

1213
include("${CMAKE_CURRENT_LIST_DIR}/apple-common.cmake")

Runtimes/Core/core/CMakeLists.txt

Lines changed: 9 additions & 3 deletions
Original file line numberDiff line numberDiff line change
@@ -145,6 +145,7 @@ add_library(swiftCore
145145
SetVariant.swift
146146
ShadowProtocols.swift
147147
Shims.swift
148+
Slab.swift
148149
Slice.swift
149150
SmallString.swift
150151
Sort.swift
@@ -282,9 +283,14 @@ target_compile_options(swiftCore PRIVATE
282283
"$<$<COMPILE_LANGUAGE:Swift>:SHELL:-Xfrontend -disable-autolinking-runtime-compatibility-concurrency>"
283284
"$<$<COMPILE_LANGUAGE:Swift>:SHELL:-Xfrontend -disable-objc-attr-requires-foundation-module>"
284285
"$<$<COMPILE_LANGUAGE:Swift>:SHELL:-Xfrontend -require-explicit-availability=ignore>"
285-
"$<$<COMPILE_LANGUAGE:Swift>:SHELL:-Xfrontend -prespecialize-generic-metadata>"
286-
"$<$<COMPILE_LANGUAGE:Swift>:SHELL:-Xllvm -sil-inline-generics>"
287-
"$<$<COMPILE_LANGUAGE:Swift>:SHELL:-Xllvm -sil-partial-specialization>")
286+
"$<$<COMPILE_LANGUAGE:Swift>:SHELL:-Xfrontend -prespecialize-generic-metadata>")
287+
288+
if(NOT "${CMAKE_BUILD_TYPE}" STREQUAL "MinSizeRel")
289+
# Using these in MinSizeRel would result in a 15% increase in the binary size
290+
target_compile_options(swiftCore PRIVATE
291+
"$<$<COMPILE_LANGUAGE:Swift>:SHELL:-Xllvm -sil-inline-generics>"
292+
"$<$<COMPILE_LANGUAGE:Swift>:SHELL:-Xllvm -sil-partial-specialization>")
293+
endif()
288294

289295
target_compile_definitions(swiftCore PRIVATE
290296
$<$<BOOL:${SwiftCore_ENABLE_REFLECTION}>:-DSWIFT_ENABLE_REFLECTION>

SwiftCompilerSources/Sources/Optimizer/Analysis/AliasAnalysis.swift

Lines changed: 4 additions & 1 deletion
Original file line numberDiff line numberDiff line change
@@ -603,7 +603,7 @@ private enum ImmutableScope {
603603

604604
init?(for basedAddress: Value, _ context: FunctionPassContext) {
605605
switch basedAddress.enclosingAccessScope {
606-
case .scope(let beginAccess):
606+
case .access(let beginAccess):
607607
if beginAccess.isUnsafe {
608608
return nil
609609
}
@@ -652,6 +652,9 @@ private enum ImmutableScope {
652652
return nil
653653
}
654654
}
655+
case .dependence(let markDep):
656+
// ignore mark_dependence for the purpose of alias analysis.
657+
self.init(for: markDep.value, context)
655658
}
656659
}
657660

SwiftCompilerSources/Sources/Optimizer/FunctionPasses/LifetimeDependenceDiagnostics.swift

Lines changed: 0 additions & 15 deletions
Original file line numberDiff line numberDiff line change
@@ -199,21 +199,6 @@ private struct DiagnoseDependence {
199199
if function.hasUnsafeNonEscapableResult {
200200
return .continueWalk
201201
}
202-
// FIXME: remove this condition once we have a Builtin.dependence,
203-
// which developers should use to model the unsafe
204-
// dependence. Builtin.lifetime_dependence will be lowered to
205-
// mark_dependence [unresolved], which will be checked
206-
// independently. Instead, of this function result check, allow
207-
// isUnsafeApplyResult to be used be mark_dependence [unresolved]
208-
// without checking its dependents.
209-
//
210-
// Allow returning an apply result (@_unsafeNonescapableResult) if
211-
// the calling function has a dependence. This implicitly makes
212-
// the unsafe nonescapable result dependent on the calling
213-
// function's lifetime dependence arguments.
214-
if dependence.isUnsafeApplyResult, function.hasResultDependence {
215-
return .continueWalk
216-
}
217202
// Check that the parameter dependence for this result is the same
218203
// as the current dependence scope.
219204
if let arg = dependence.scope.parentValue as? FunctionArgument,

SwiftCompilerSources/Sources/Optimizer/FunctionPasses/LifetimeDependenceScopeFixup.swift

Lines changed: 13 additions & 7 deletions
Original file line numberDiff line numberDiff line change
@@ -274,7 +274,8 @@ private extension LifetimeDependence.Scope {
274274
case let .access(beginAccess):
275275
// Finding the access base also finds all intermediate nested scopes; there is no need to recursively call
276276
// gatherExtensions().
277-
let (accessBase, nestedAccesses) = beginAccess.accessBaseWithScopes
277+
let accessBaseAndScopes = beginAccess.accessBaseWithScopes
278+
let accessBase = accessBaseAndScopes.base
278279
let ownerAddress: Value
279280
var dependsOnArg: FunctionArgument? = nil
280281
switch accessBase {
@@ -287,13 +288,18 @@ private extension LifetimeDependence.Scope {
287288
.pointer, .index:
288289
ownerAddress = accessBase.address!
289290
}
290-
assert(!nestedAccesses.isEmpty)
291-
for nestedAccess in nestedAccesses {
292-
innerScopes.push(.access(nestedAccess))
291+
assert(!accessBaseAndScopes.scopes.isEmpty)
292+
for nestedScope in accessBaseAndScopes.scopes {
293+
switch nestedScope {
294+
case let .access(beginAccess):
295+
innerScopes.push(.access(beginAccess))
296+
case .dependence, .base:
297+
// ignore recursive mark_dependence base for the purpose of extending scopes. This pass will extend the base
298+
// of that mark_dependence (if it is unresolved) later as a separate LifetimeDependence.Scope.
299+
break
300+
}
293301
}
294-
// This is the outermost scope. We only see nested access scopes after inlining.
295-
//
296-
// TODO: could we have a nested access within an yielded inout address?
302+
// TODO: could we have a nested access within an yielded inout address prior to inlining?
297303
return SingleInlineArray(element: ScopeExtension(owner: ownerAddress, nestedScopes: innerScopes,
298304
dependsOnArg: dependsOnArg))
299305
case let .borrowed(beginBorrow):

SwiftCompilerSources/Sources/Optimizer/Utilities/AddressUtils.swift

Lines changed: 5 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -215,6 +215,11 @@ extension AccessBase {
215215
return nil
216216
}
217217
baseAddr = arg
218+
case let .storeBorrow(sbi):
219+
guard case let .stack(allocStack) = sbi.destinationOperand.value.accessBase else {
220+
return nil
221+
}
222+
return (initialAddress: allocStack, initializingStore: sbi)
218223
default:
219224
return nil
220225
}

SwiftCompilerSources/Sources/Optimizer/Utilities/LifetimeDependenceUtils.swift

Lines changed: 41 additions & 15 deletions
Original file line numberDiff line numberDiff line change
@@ -117,7 +117,7 @@ struct LifetimeDependence : CustomStringConvertible {
117117
case yield(Value)
118118
/// An owned value whose OSSA lifetime encloses nonescapable values, or a trivial variable introduced by move_value.
119119
case owned(Value)
120-
/// An borrowed value whose OSSA lifetime encloses nonescapable values, or a trivial variable introduced by
120+
/// A borrowed value whose OSSA lifetime encloses nonescapable values, or a trivial variable introduced by
121121
/// begin_borrow.
122122
case borrowed(BeginBorrowValue)
123123
/// Singly-initialized addressable storage (likely for an
@@ -225,16 +225,6 @@ extension LifetimeDependence {
225225
self.dependentValue = value
226226
}
227227

228-
var isUnsafeApplyResult: Bool {
229-
if case let .owned(value) = scope {
230-
if let apply = value.definingInstruction as? FullApplySite {
231-
assert(!apply.hasResultDependence)
232-
return true
233-
}
234-
}
235-
return false
236-
}
237-
238228
/// Construct LifetimeDependence from mark_dependence [unresolved] or mark_dependence [nonescaping].
239229
///
240230
/// For any LifetimeDependence constructed from a mark_dependence, its `dependentValue` will be the result of the
@@ -313,10 +303,15 @@ extension LifetimeDependence.Scope {
313303

314304
private init(address: Value, _ context: some Context) {
315305
switch address.enclosingAccessScope {
316-
case let .scope(access):
306+
case let .access(access):
317307
self = .access(access)
318308
case let .base(accessBase):
319309
self = Self(accessBase: accessBase, address: address, context)
310+
case let .dependence(markDep):
311+
// The current dependence only represents the forwarded address. If the mark_dependence instruction encoutered
312+
// here is [unresolved], then a separate LifetimeDependence.Scope will be created for it, and if it is [escaping],
313+
// then it is ignored for the purpose of lifetime dependence.
314+
self.init(address: markDep.value, context)
320315
}
321316
}
322317

@@ -334,7 +329,11 @@ extension LifetimeDependence.Scope {
334329
self = Self(guaranteed: refElt.operand.value, context)
335330
case let .argument(arg):
336331
if arg.convention.isIndirectIn {
337-
self = .initialized(initialAddress: arg, initializingStore: nil)
332+
if arg.convention.isGuaranteed {
333+
self = .caller(arg)
334+
} else {
335+
self = .initialized(initialAddress: arg, initializingStore: nil)
336+
}
338337
} else if arg.convention.isIndirectOut || arg.convention.isInout {
339338
// TODO: verify that @out values are never reassigned.
340339
self = .caller(arg)
@@ -482,7 +481,12 @@ extension LifetimeDependence.Scope {
482481
}
483482
}
484483

485-
// !!! - handle allocations of trivial values: no destroy. Use the dealloc in that case?
484+
// Note: an initialized range should always have a destroy_addr. For trivial 'var' variables, we have a alloc_box,
485+
// which has a destroy_value. For concrete trivial 'let' variables, we load the trivial value:
486+
// %l = load [trivial] %0
487+
// %m = move_value [var_decl] %2
488+
//
489+
// For generic trivial (BitwiseCopyable) 'let' variables, we emit a destroy_addr for the alloc_stack.
486490
private static func computeInitializedRange(initialAddress: Value, initializingStore: Instruction?,
487491
_ context: Context)
488492
-> InstructionRange {
@@ -633,12 +637,34 @@ struct VariableIntroducerUseDefWalker : LifetimeDependenceUseDefWalker {
633637

634638
mutating func walkUp(address: Value) -> WalkResult {
635639
if let beginAccess = address.definingInstruction as? BeginAccessInst {
640+
// Treat calls to unsafe[Mutable]Address like a projection of 'self' rather than a separate variable access.
641+
if let addressorSelf = beginAccess.unsafeAddressorSelf {
642+
return walkUp(valueOrAddress: addressorSelf)
643+
}
636644
return introducer(beginAccess, nil)
637645
}
638646
return walkUpDefault(address: address)
639647
}
640648
}
641649

650+
private extension BeginAccessInst {
651+
// Recognize an access scope for a unsafe addressor:
652+
// %adr = pointer_to_address
653+
// %md = mark_dependence %adr
654+
// begin_access [unsafe] %md
655+
var unsafeAddressorSelf: Value? {
656+
guard isUnsafe else {
657+
return nil
658+
}
659+
let accessBaseAndScopes = address.accessBaseWithScopes
660+
guard case .pointer = accessBaseAndScopes.base,
661+
case let .dependence(markDep) = accessBaseAndScopes.scopes.first else {
662+
return nil
663+
}
664+
return markDep.base
665+
}
666+
}
667+
642668
/// Walk up the lifetime dependence chain.
643669
///
644670
/// This finds the introducers of a dependence chain. which represent the value's "inherited" dependencies. This stops
@@ -1151,7 +1177,7 @@ extension LifetimeDependenceDefUseWalker {
11511177

11521178
// Get the local variable access that encloses this store.
11531179
var storeAccess = storedOperand.instruction
1154-
if case let .scope(beginAccess) = storeAddress.enclosingAccessScope {
1180+
if case let .access(beginAccess) = storeAddress.enclosingAccessScope {
11551181
storeAccess = beginAccess
11561182
}
11571183
if !localReachability.gatherAllReachableUses(of: storeAccess, in: &accessStack) {

SwiftCompilerSources/Sources/SIL/Utilities/AccessUtils.swift

Lines changed: 38 additions & 14 deletions
Original file line numberDiff line numberDiff line change
@@ -477,7 +477,7 @@ private extension PointerToAddressInst {
477477
}
478478
}
479479

480-
/// The `EnclosingScope` of an access is the innermost `begin_access`
480+
/// The `EnclosingAccessScope` of an access is the innermost `begin_access`
481481
/// instruction that checks for exclusivity of the access.
482482
/// If there is no `begin_access` instruction found, then the scope is
483483
/// the base itself.
@@ -497,13 +497,29 @@ private extension PointerToAddressInst {
497497
/// %l3 = load %a3 : $*Int64
498498
/// end_access %a3 : $*Int64
499499
/// ```
500-
public enum EnclosingScope {
501-
case scope(BeginAccessInst)
500+
public enum EnclosingAccessScope {
501+
case access(BeginAccessInst)
502502
case base(AccessBase)
503+
case dependence(MarkDependenceInst)
504+
}
505+
506+
// An AccessBase with the nested enclosing scopes that contain the original address in bottom-up order.
507+
public struct AccessBaseAndScopes {
508+
public let base: AccessBase
509+
public let scopes: SingleInlineArray<EnclosingAccessScope>
510+
511+
public var innermostAccess: BeginAccessInst? {
512+
for scope in scopes {
513+
if case let .access(beginAccess) = scope {
514+
return beginAccess
515+
}
516+
}
517+
return nil
518+
}
503519
}
504520

505521
private struct EnclosingAccessWalker : AddressUseDefWalker {
506-
var enclosingScope: EnclosingScope?
522+
var enclosingScope: EnclosingAccessScope?
507523

508524
mutating func walk(startAt address: Value, initialPath: UnusedWalkingPath = UnusedWalkingPath()) {
509525
if walkUp(address: address, path: UnusedWalkingPath()) == .abortWalk {
@@ -522,19 +538,24 @@ private struct EnclosingAccessWalker : AddressUseDefWalker {
522538
}
523539

524540
mutating func walkUp(address: Value, path: UnusedWalkingPath) -> WalkResult {
525-
if let ba = address as? BeginAccessInst {
526-
enclosingScope = .scope(ba)
541+
switch address {
542+
case let ba as BeginAccessInst:
543+
enclosingScope = .access(ba)
527544
return .continueWalk
545+
case let md as MarkDependenceInst:
546+
enclosingScope = .dependence(md)
547+
return .continueWalk
548+
default:
549+
return walkUpDefault(address: address, path: path)
528550
}
529-
return walkUpDefault(address: address, path: path)
530551
}
531552
}
532553

533554
private struct AccessPathWalker : AddressUseDefWalker {
534555
var result = AccessPath.unidentified()
535556

536-
// List of nested BeginAccessInst: inside-out order.
537-
var foundBeginAccesses = SingleInlineArray<BeginAccessInst>()
557+
// List of nested BeginAccessInst & MarkDependenceInst: inside-out order.
558+
var foundEnclosingScopes = SingleInlineArray<EnclosingAccessScope>()
538559

539560
let enforceConstantProjectionPath: Bool
540561

@@ -602,7 +623,9 @@ private struct AccessPathWalker : AddressUseDefWalker {
602623
// projection. Bail out
603624
return .abortWalk
604625
} else if let ba = address as? BeginAccessInst {
605-
foundBeginAccesses.push(ba)
626+
foundEnclosingScopes.push(.access(ba))
627+
} else if let md = address as? MarkDependenceInst {
628+
foundEnclosingScopes.push(.dependence(md))
606629
}
607630
return walkUpDefault(address: address, path: path.with(indexAddr: false))
608631
}
@@ -655,20 +678,21 @@ extension Value {
655678
public var accessPathWithScope: (AccessPath, scope: BeginAccessInst?) {
656679
var walker = AccessPathWalker()
657680
walker.walk(startAt: self)
658-
return (walker.result, walker.foundBeginAccesses.first)
681+
let baseAndScopes = AccessBaseAndScopes(base: walker.result.base, scopes: walker.foundEnclosingScopes)
682+
return (walker.result, baseAndScopes.innermostAccess)
659683
}
660684

661685
/// Computes the enclosing access scope of this address value.
662-
public var enclosingAccessScope: EnclosingScope {
686+
public var enclosingAccessScope: EnclosingAccessScope {
663687
var walker = EnclosingAccessWalker()
664688
walker.walk(startAt: self)
665689
return walker.enclosingScope ?? .base(.unidentified)
666690
}
667691

668-
public var accessBaseWithScopes: (AccessBase, SingleInlineArray<BeginAccessInst>) {
692+
public var accessBaseWithScopes: AccessBaseAndScopes {
669693
var walker = AccessPathWalker()
670694
walker.walk(startAt: self)
671-
return (walker.result.base, walker.foundBeginAccesses)
695+
return AccessBaseAndScopes(base: walker.result.base, scopes: walker.foundEnclosingScopes)
672696
}
673697

674698
/// The root definition of a reference, obtained by skipping ownership forwarding and ownership transition.

0 commit comments

Comments
 (0)