Skip to content

Commit 84d00d7

Browse files
authored
Merge branch 'main' into es-sil-pkg
2 parents b9add53 + ee10a4e commit 84d00d7

File tree

235 files changed

+5837
-1367
lines changed

Some content is hidden

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

235 files changed

+5837
-1367
lines changed

CMakeLists.txt

Lines changed: 5 additions & 1 deletion
Original file line numberDiff line numberDiff line change
@@ -655,6 +655,10 @@ option(SWIFT_ENABLE_EXPERIMENTAL_OBSERVATION
655655
"Enable build of the Swift observation module"
656656
FALSE)
657657

658+
option(SWIFT_STDLIB_ENABLE_STRICT_CONCURRENCY_COMPLETE
659+
"Build the stdlib with -strict-concurrency=complete"
660+
FALSE)
661+
658662
option(SWIFT_ENABLE_SYNCHRONIZATION
659663
"Enable build of the Swift Synchronization module"
660664
FALSE)
@@ -802,7 +806,7 @@ if(SWIFT_PATH_TO_CMARK_BUILD)
802806
OUTPUT_STRIP_TRAILING_WHITESPACE)
803807
message(STATUS "CMark Version: ${_CMARK_VERSION}")
804808
elseif(SWIFT_INCLUDE_TOOLS)
805-
find_package(cmark-gfm REQUIRED)
809+
find_package(cmark-gfm CONFIG REQUIRED)
806810
endif()
807811
message(STATUS "")
808812

SwiftCompilerSources/Sources/Optimizer/FunctionPasses/LifetimeDependenceDiagnostics.swift

Lines changed: 1 addition & 1 deletion
Original file line numberDiff line numberDiff line change
@@ -12,7 +12,7 @@
1212

1313
import SIL
1414

15-
private let verbose = true
15+
private let verbose = false
1616

1717
private func log(_ message: @autoclosure () -> String) {
1818
if verbose {

SwiftCompilerSources/Sources/Optimizer/FunctionPasses/ObjectOutliner.swift

Lines changed: 12 additions & 4 deletions
Original file line numberDiff line numberDiff line change
@@ -76,7 +76,14 @@ private func optimizeObjectAllocation(allocRef: AllocRefInstBase, _ context: Fun
7676
return nil
7777
}
7878

79-
guard let endOfInitInst = findEndOfInitialization(of: allocRef) else {
79+
guard let endOfInitInst = findEndOfInitialization(
80+
of: allocRef,
81+
// An object with tail allocated elements is in risk of being passed to malloc_size, which does
82+
// not work for non-heap allocated objects. Conservatively, disable objects with tail allocations.
83+
// Note, that this does not affect Array because Array always has an end_cow_mutation at the end of
84+
// initialization.
85+
canStoreToGlobal: allocRef.tailAllocatedCounts.count == 0)
86+
else {
8087
return nil
8188
}
8289

@@ -98,15 +105,15 @@ private func optimizeObjectAllocation(allocRef: AllocRefInstBase, _ context: Fun
98105
// The end-of-initialization is either an end_cow_mutation, because it guarantees that the originally initialized
99106
// object is not mutated (it must be copied before mutation).
100107
// Or it is the store to a global let variable in the global's initializer function.
101-
private func findEndOfInitialization(of object: Value) -> Instruction? {
108+
private func findEndOfInitialization(of object: Value, canStoreToGlobal: Bool) -> Instruction? {
102109
for use in object.uses {
103110
let user = use.instruction
104111
switch user {
105112
case is UpcastInst,
106113
is UncheckedRefCastInst,
107114
is MoveValueInst,
108115
is EndInitLetRefInst:
109-
if let ecm = findEndOfInitialization(of: user as! SingleValueInstruction) {
116+
if let ecm = findEndOfInitialization(of: user as! SingleValueInstruction, canStoreToGlobal: canStoreToGlobal) {
110117
return ecm
111118
}
112119
case let ecm as EndCOWMutationInst:
@@ -115,7 +122,8 @@ private func findEndOfInitialization(of object: Value) -> Instruction? {
115122
}
116123
return ecm
117124
case let store as StoreInst:
118-
if let ga = store.destination as? GlobalAddrInst,
125+
if canStoreToGlobal,
126+
let ga = store.destination as? GlobalAddrInst,
119127
ga.global.isLet,
120128
ga.parentFunction.initializedGlobal == ga.global
121129
{

SwiftCompilerSources/Sources/Optimizer/FunctionPasses/ReleaseDevirtualizer.swift

Lines changed: 1 addition & 1 deletion
Original file line numberDiff line numberDiff line change
@@ -108,7 +108,7 @@ private func tryDevirtualizeRelease(
108108
let functionRef = builder.createFunctionRef(dealloc)
109109

110110
let substitutionMap: SubstitutionMap
111-
if dealloc.isGenericFunction {
111+
if dealloc.isGeneric {
112112
substitutionMap = context.getContextSubstitutionMap(for: type)
113113
} else {
114114
// In embedded Swift, dealloc might be a specialized deinit, so the substitution map on the old apply isn't valid for the new apply

SwiftCompilerSources/Sources/Optimizer/ModulePasses/MandatoryPerformanceOptimizations.swift

Lines changed: 23 additions & 5 deletions
Original file line numberDiff line numberDiff line change
@@ -52,6 +52,13 @@ private func optimizeFunctionsTopDown(using worklist: inout FunctionWorklist,
5252

5353
optimize(function: f, context, &worklist)
5454
}
55+
56+
// Generic specialization takes care of removing metatype arguments of generic functions.
57+
// But sometimes non-generic functions have metatype arguments which must be removed.
58+
// We need handle this case with a function signature optimization.
59+
removeMetatypeArgumentsInCallees(of: f, moduleContext)
60+
61+
worklist.addCallees(of: f)
5562
}
5663
}
5764

@@ -100,6 +107,11 @@ private func optimize(function: Function, _ context: FunctionPassContext, _ work
100107
context.diagnosticEngine.diagnose(destroyAddr.location.sourceLoc, .deinit_not_visible)
101108
}
102109

110+
case let iem as InitExistentialMetatypeInst:
111+
if iem.uses.ignoreDebugUses.isEmpty {
112+
context.erase(instructionIncludingDebugUses: iem)
113+
}
114+
103115
default:
104116
break
105117
}
@@ -111,10 +123,8 @@ private func optimize(function: Function, _ context: FunctionPassContext, _ work
111123

112124
// If this is a just specialized function, try to optimize copy_addr, etc.
113125
changed = context.optimizeMemoryAccesses(in: function) || changed
114-
_ = context.eliminateDeadAllocations(in: function)
126+
changed = context.eliminateDeadAllocations(in: function) || changed
115127
}
116-
117-
worklist.add(calleesOf: function)
118128
}
119129

120130
private func specializeVTableAndAddEntriesToWorklist(for type: Type, in function: Function, _ context: FunctionPassContext, _ worklist: inout FunctionWorklist) {
@@ -153,6 +163,14 @@ private func inlineAndDevirtualize(apply: FullApplySite, alreadyInlinedFunctions
153163
}
154164
}
155165

166+
private func removeMetatypeArgumentsInCallees(of function: Function, _ context: ModulePassContext) {
167+
for inst in function.instructions {
168+
if let apply = inst as? FullApplySite {
169+
specializeByRemovingMetatypeArguments(apply: apply, context)
170+
}
171+
}
172+
}
173+
156174
private func removeUnusedMetatypeInstructions(in function: Function, _ context: FunctionPassContext) {
157175
for inst in function.instructions {
158176
if let mt = inst as? MetatypeInst,
@@ -351,7 +369,7 @@ fileprivate struct FunctionWorklist {
351369
}
352370

353371
mutating func addAllNonGenericFunctions(of moduleContext: ModulePassContext) {
354-
for f in moduleContext.functions where !f.isGenericFunction {
372+
for f in moduleContext.functions where !f.isGeneric {
355373
pushIfNotVisited(f)
356374
}
357375
return
@@ -366,7 +384,7 @@ fileprivate struct FunctionWorklist {
366384
}
367385
}
368386

369-
mutating func add(calleesOf function: Function) {
387+
mutating func addCallees(of function: Function) {
370388
for inst in function.instructions {
371389
switch inst {
372390
case let apply as ApplySite:

SwiftCompilerSources/Sources/Optimizer/PassManager/Context.swift

Lines changed: 40 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -50,6 +50,12 @@ extension Context {
5050
}
5151

5252
func getBuiltinIntegerType(bitWidth: Int) -> Type { _bridged.getBuiltinIntegerType(bitWidth).type }
53+
54+
func lookupFunction(name: String) -> Function? {
55+
name._withBridgedStringRef {
56+
_bridged.lookupFunction($0).function
57+
}
58+
}
5359
}
5460

5561
/// A context which allows mutation of a function's SIL.
@@ -62,6 +68,10 @@ extension MutatingContext {
6268
func notifyInvalidatedStackNesting() { _bridged.notifyInvalidatedStackNesting() }
6369
var needFixStackNesting: Bool { _bridged.getNeedFixStackNesting() }
6470

71+
func verifyIsTransforming(function: Function) {
72+
precondition(_bridged.isTransforming(function.bridged), "pass modifies wrong function")
73+
}
74+
6575
/// Splits the basic block, which contains `inst`, before `inst` and returns the
6676
/// new block.
6777
///
@@ -88,6 +98,9 @@ extension MutatingContext {
8898
}
8999

90100
func erase(instruction: Instruction) {
101+
if !instruction.isInStaticInitializer {
102+
verifyIsTransforming(function: instruction.parentFunction)
103+
}
91104
if instruction is FullApplySite {
92105
notifyCallsChanged()
93106
}
@@ -374,18 +387,21 @@ extension Type {
374387
extension Builder {
375388
/// Creates a builder which inserts _before_ `insPnt`, using a custom `location`.
376389
init(before insPnt: Instruction, location: Location, _ context: some MutatingContext) {
390+
context.verifyIsTransforming(function: insPnt.parentFunction)
377391
self.init(insertAt: .before(insPnt), location: location,
378392
context.notifyInstructionChanged, context._bridged.asNotificationHandler())
379393
}
380394

381395
/// Creates a builder which inserts _before_ `insPnt`, using the location of `insPnt`.
382396
init(before insPnt: Instruction, _ context: some MutatingContext) {
397+
context.verifyIsTransforming(function: insPnt.parentFunction)
383398
self.init(insertAt: .before(insPnt), location: insPnt.location,
384399
context.notifyInstructionChanged, context._bridged.asNotificationHandler())
385400
}
386401

387402
/// Creates a builder which inserts _after_ `insPnt`, using a custom `location`.
388403
init(after insPnt: Instruction, location: Location, _ context: some MutatingContext) {
404+
context.verifyIsTransforming(function: insPnt.parentFunction)
389405
if let nextInst = insPnt.next {
390406
self.init(insertAt: .before(nextInst), location: location,
391407
context.notifyInstructionChanged, context._bridged.asNotificationHandler())
@@ -397,17 +413,20 @@ extension Builder {
397413

398414
/// Creates a builder which inserts _after_ `insPnt`, using the location of `insPnt`.
399415
init(after insPnt: Instruction, _ context: some MutatingContext) {
416+
context.verifyIsTransforming(function: insPnt.parentFunction)
400417
self.init(after: insPnt, location: insPnt.location, context)
401418
}
402419

403420
/// Creates a builder which inserts at the end of `block`, using a custom `location`.
404421
init(atEndOf block: BasicBlock, location: Location, _ context: some MutatingContext) {
422+
context.verifyIsTransforming(function: block.parentFunction)
405423
self.init(insertAt: .atEndOf(block), location: location,
406424
context.notifyInstructionChanged, context._bridged.asNotificationHandler())
407425
}
408426

409427
/// Creates a builder which inserts at the begin of `block`, using a custom `location`.
410428
init(atBeginOf block: BasicBlock, location: Location, _ context: some MutatingContext) {
429+
context.verifyIsTransforming(function: block.parentFunction)
411430
let firstInst = block.instructions.first!
412431
self.init(insertAt: .before(firstInst), location: location,
413432
context.notifyInstructionChanged, context._bridged.asNotificationHandler())
@@ -416,6 +435,7 @@ extension Builder {
416435
/// Creates a builder which inserts at the begin of `block`, using the location of the first
417436
/// instruction of `block`.
418437
init(atBeginOf block: BasicBlock, _ context: some MutatingContext) {
438+
context.verifyIsTransforming(function: block.parentFunction)
419439
let firstInst = block.instructions.first!
420440
self.init(insertAt: .before(firstInst), location: firstInst.location,
421441
context.notifyInstructionChanged, context._bridged.asNotificationHandler())
@@ -444,6 +464,11 @@ extension BasicBlock {
444464
return bridged.addBlockArgument(type.bridged, ownership._bridged).argument
445465
}
446466

467+
func addFunctionArgument(type: Type, _ context: some MutatingContext) -> FunctionArgument {
468+
context.notifyInstructionsChanged()
469+
return bridged.addFunctionArgument(type.bridged).argument as! FunctionArgument
470+
}
471+
447472
func eraseArgument(at index: Int, _ context: some MutatingContext) {
448473
context.notifyInstructionsChanged()
449474
bridged.eraseArgument(index)
@@ -585,7 +610,22 @@ extension Function {
585610
bridged.setNeedStackProtection(needStackProtection)
586611
}
587612

613+
func set(thunkKind: ThunkKind, _ context: FunctionPassContext) {
614+
context.notifyEffectsChanged()
615+
switch thunkKind {
616+
case .noThunk: bridged.setThunk(.IsNotThunk)
617+
case .thunk: bridged.setThunk(.IsThunk)
618+
case .reabstractionThunk: bridged.setThunk(.IsReabstractionThunk)
619+
case .signatureOptimizedThunk: bridged.setThunk(.IsSignatureOptimizedThunk)
620+
}
621+
}
622+
588623
func fixStackNesting(_ context: FunctionPassContext) {
589624
context._bridged.fixStackNesting(bridged)
590625
}
626+
627+
func appendNewBlock(_ context: FunctionPassContext) -> BasicBlock {
628+
context.notifyBranchesChanged()
629+
return context._bridged.appendBlock(bridged).block
630+
}
591631
}

SwiftCompilerSources/Sources/Optimizer/PassManager/ModulePassContext.swift

Lines changed: 38 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -123,9 +123,47 @@ struct ModulePassContext : Context, CustomStringConvertible {
123123
_bridged.endTransformFunction();
124124
}
125125

126+
func loadFunction(function: Function, loadCalleesRecursively: Bool) -> Bool {
127+
if function.isDefinition {
128+
return true
129+
}
130+
_bridged.loadFunction(function.bridged, loadCalleesRecursively)
131+
return function.isDefinition
132+
}
133+
134+
func createSpecializedFunctionDeclaration(
135+
name: String,
136+
parameters: [ParameterInfo],
137+
hasSelfParameter: Bool,
138+
fromOriginal originalFunction: Function
139+
) -> Function {
140+
return name._withBridgedStringRef { nameRef in
141+
let bridgedParamInfos = parameters.map { $0._bridged }
142+
return bridgedParamInfos.withUnsafeBufferPointer { paramBuf in
143+
_bridged.createSpecializedFunction(nameRef, paramBuf.baseAddress, paramBuf.count,
144+
hasSelfParameter, originalFunction.bridged).function
145+
}
146+
}
147+
}
148+
149+
func moveFunctionBody(from sourceFunc: Function, to destFunc: Function) {
150+
precondition(!destFunc.isDefinition, "cannot move body to non-empty function")
151+
_bridged.moveFunctionBody(sourceFunc.bridged, destFunc.bridged)
152+
}
153+
126154
func mangleAsyncRemoved(from function: Function) -> String {
127155
return String(taking: _bridged.mangleAsyncRemoved(function.bridged))
128156
}
157+
158+
func mangle(withDeadArguments: [Int], from function: Function) -> String {
159+
withDeadArguments.withUnsafeBufferPointer { bufPtr in
160+
bufPtr.withMemoryRebound(to: Int.self) { valPtr in
161+
String(taking: _bridged.mangleWithDeadArgs(valPtr.baseAddress,
162+
withDeadArguments.count,
163+
function.bridged))
164+
}
165+
}
166+
}
129167
}
130168

131169
extension GlobalVariable {

SwiftCompilerSources/Sources/Optimizer/Utilities/CMakeLists.txt

Lines changed: 1 addition & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -13,6 +13,7 @@ swift_compiler_sources(Optimizer
1313
Devirtualization.swift
1414
EscapeUtils.swift
1515
ForwardingUtils.swift
16+
FunctionSignatureTransforms.swift
1617
LifetimeDependenceUtils.swift
1718
OptUtils.swift
1819
OwnershipLiveness.swift

0 commit comments

Comments
 (0)