Skip to content

Commit 0bb04ac

Browse files
Merge pull request #5174 from swiftwasm/main
[pull] swiftwasm from main
2 parents 4873245 + ffac122 commit 0bb04ac

File tree

380 files changed

+10082
-3059
lines changed

Some content is hidden

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

380 files changed

+10082
-3059
lines changed

.github/CODEOWNERS

Lines changed: 6 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -62,6 +62,12 @@ cmake/**/*Windows* @compnerd
6262
lib/Basic/Windows @compnerd
6363
utils/*windows* @compnerd
6464

65+
# Repository checkout utils
66+
67+
/utils/update_checkout/ @shahmishal
68+
/utils/update-checkout* @shahmishal
69+
70+
6571
# AST
6672
/include/swift/AST/ @hborla @slavapestov @xedin
6773
/include/swift/AST/*Conformance* @slavapestov

CMakeLists.txt

Lines changed: 6 additions & 1 deletion
Original file line numberDiff line numberDiff line change
@@ -268,7 +268,7 @@ set(SWIFT_ANALYZE_CODE_COVERAGE FALSE CACHE STRING
268268
# SWIFT_VERSION is deliberately /not/ cached so that an existing build directory
269269
# can be reused when a new version of Swift comes out (assuming the user hasn't
270270
# manually set it as part of their own CMake configuration).
271-
set(SWIFT_VERSION "5.8")
271+
set(SWIFT_VERSION "5.9")
272272

273273
set(SWIFT_VENDOR "" CACHE STRING
274274
"The vendor name of the Swift compiler")
@@ -570,6 +570,10 @@ option(SWIFT_ENABLE_EXPERIMENTAL_STRING_PROCESSING
570570
"Enable experimental string processing"
571571
FALSE)
572572

573+
option(SWIFT_ENABLE_EXPERIMENTAL_REFLECTION
574+
"Enable build of the Swift reflection module"
575+
FALSE)
576+
573577
option(SWIFT_ENABLE_DISPATCH
574578
"Enable use of libdispatch"
575579
TRUE)
@@ -1115,6 +1119,7 @@ if(SWIFT_BUILD_STDLIB OR SWIFT_BUILD_SDK_OVERLAY)
11151119
message(STATUS "Distributed Support: ${SWIFT_ENABLE_EXPERIMENTAL_DISTRIBUTED}")
11161120
message(STATUS "String Processing Support: ${SWIFT_ENABLE_EXPERIMENTAL_STRING_PROCESSING}")
11171121
message(STATUS "Unicode Support: ${SWIFT_STDLIB_ENABLE_UNICODE_DATA}")
1122+
message(STATUS "Reflection Support: ${SWIFT_ENABLE_EXPERIMENTAL_REFLECTION}")
11181123
message(STATUS "")
11191124
else()
11201125
message(STATUS "Not building Swift standard library, SDK overlays, and runtime")

SwiftCompilerSources/README.md

Lines changed: 2 additions & 2 deletions
Original file line numberDiff line numberDiff line change
@@ -156,9 +156,9 @@ With instruction passes it's possible to implement small peephole optimizations
156156

157157
To add a new instruction pass:
158158

159-
* add a `SWIFT_INSTRUCTION_PASS` entry in `Passes.def`
159+
* add a `SWIFT_SILCOMBINE_PASS` entry in `Passes.def`
160160
* create a new Swift file in `SwiftCompilerSources/Optimizer/InstructionPasses`
161-
* add an `InstructionPass` global
161+
* implement the `simplify` function in conformance to `SILCombineSimplifyable`
162162
* register the pass in `registerSwiftPasses()`
163163
* if this pass replaces an existing `SILCombiner` visit function, remove the old visit function
164164

SwiftCompilerSources/Sources/Optimizer/Analysis/AliasAnalysis.swift

Lines changed: 36 additions & 11 deletions
Original file line numberDiff line numberDiff line change
@@ -65,7 +65,7 @@ struct AliasAnalysis {
6565
AliasAnalysis_register(
6666
// getMemEffectsFn
6767
{ (bridgedCtxt: BridgedPassContext, bridgedVal: BridgedValue, bridgedInst: BridgedInstruction) -> BridgedMemoryBehavior in
68-
let context = PassContext(_bridged: bridgedCtxt)
68+
let context = FunctionPassContext(_bridged: bridgedCtxt)
6969
let inst = bridgedInst.instruction
7070
let val = bridgedVal.value
7171
let path = AliasAnalysis.getPtrOrAddressPath(for: val)
@@ -78,28 +78,28 @@ struct AliasAnalysis {
7878
case (true, true): return MayReadWriteBehavior
7979
}
8080
}
81-
if val.at(path).isAddressEscaping(using: EscapesToInstructionVisitor(target: inst), context) {
81+
if val.at(path).isEscaping(using: EscapesToInstructionVisitor(target: inst, isAddress: true), context) {
8282
return MayReadWriteBehavior
8383
}
8484
return NoneBehavior
8585
},
8686

8787
// isObjReleasedFn
8888
{ (bridgedCtxt: BridgedPassContext, bridgedObj: BridgedValue, bridgedInst: BridgedInstruction) -> Bool in
89-
let context = PassContext(_bridged: bridgedCtxt)
89+
let context = FunctionPassContext(_bridged: bridgedCtxt)
9090
let inst = bridgedInst.instruction
9191
let obj = bridgedObj.value
9292
let path = SmallProjectionPath(.anyValueFields)
9393
if let apply = inst as? ApplySite {
9494
let effect = getOwnershipEffect(of: apply, for: obj, path: path, context)
9595
return effect.destroy
9696
}
97-
return obj.at(path).isEscaping(using: EscapesToInstructionVisitor(target: inst), context)
97+
return obj.at(path).isEscaping(using: EscapesToInstructionVisitor(target: inst, isAddress: false), context)
9898
},
9999

100100
// isAddrVisibleFromObj
101101
{ (bridgedCtxt: BridgedPassContext, bridgedAddr: BridgedValue, bridgedObj: BridgedValue) -> Bool in
102-
let context = PassContext(_bridged: bridgedCtxt)
102+
let context = FunctionPassContext(_bridged: bridgedCtxt)
103103
let addr = bridgedAddr.value.at(AliasAnalysis.getPtrOrAddressPath(for: bridgedAddr.value))
104104

105105
// This is similar to `canReferenceSameFieldFn`, except that all addresses of all objects are
@@ -110,7 +110,7 @@ struct AliasAnalysis {
110110

111111
// canReferenceSameFieldFn
112112
{ (bridgedCtxt: BridgedPassContext, bridgedLhs: BridgedValue, bridgedRhs: BridgedValue) -> Bool in
113-
let context = PassContext(_bridged: bridgedCtxt)
113+
let context = FunctionPassContext(_bridged: bridgedCtxt)
114114

115115
// If `lhs` or `rhs` is not an address, but an object, it means: check for alias of any class
116116
// field address of the object.
@@ -122,13 +122,13 @@ struct AliasAnalysis {
122122
}
123123
}
124124

125-
private func getMemoryEffect(of apply: ApplySite, for address: Value, path: SmallProjectionPath, _ context: PassContext) -> SideEffects.Memory {
125+
private func getMemoryEffect(of apply: ApplySite, for address: Value, path: SmallProjectionPath, _ context: FunctionPassContext) -> SideEffects.Memory {
126126
let calleeAnalysis = context.calleeAnalysis
127-
let visitor = SideEffectsVisitor(apply: apply, calleeAnalysis: calleeAnalysis)
127+
let visitor = SideEffectsVisitor(apply: apply, calleeAnalysis: calleeAnalysis, isAddress: true)
128128
let memoryEffects: SideEffects.Memory
129129

130130
// First try to figure out to which argument(s) the address "escapes" to.
131-
if let result = address.at(path).visitAddress(using: visitor, context) {
131+
if let result = address.at(path).visit(using: visitor, context) {
132132
// The resulting effects are the argument effects to which `address` escapes to.
133133
memoryEffects = result.memory
134134
} else {
@@ -145,8 +145,8 @@ private func getMemoryEffect(of apply: ApplySite, for address: Value, path: Smal
145145
return memoryEffects
146146
}
147147

148-
private func getOwnershipEffect(of apply: ApplySite, for value: Value, path: SmallProjectionPath, _ context: PassContext) -> SideEffects.Ownership {
149-
let visitor = SideEffectsVisitor(apply: apply, calleeAnalysis: context.calleeAnalysis)
148+
private func getOwnershipEffect(of apply: ApplySite, for value: Value, path: SmallProjectionPath, _ context: FunctionPassContext) -> SideEffects.Ownership {
149+
let visitor = SideEffectsVisitor(apply: apply, calleeAnalysis: context.calleeAnalysis, isAddress: false)
150150
if let result = value.at(path).visit(using: visitor, context) {
151151
// The resulting effects are the argument effects to which `value` escapes to.
152152
return result.ownership
@@ -159,6 +159,7 @@ private func getOwnershipEffect(of apply: ApplySite, for value: Value, path: Sma
159159
private struct SideEffectsVisitor : EscapeVisitorWithResult {
160160
let apply: ApplySite
161161
let calleeAnalysis: CalleeAnalysis
162+
let isAddress: Bool
162163
var result = SideEffects.GlobalEffects()
163164

164165
mutating func visitUse(operand: Operand, path: EscapePath) -> UseResult {
@@ -175,6 +176,30 @@ private struct SideEffectsVisitor : EscapeVisitorWithResult {
175176
}
176177
return .continueWalk
177178
}
179+
180+
var followTrivialTypes: Bool { isAddress }
181+
var followLoads: Bool { !isAddress }
182+
}
183+
184+
/// Lets `ProjectedValue.isEscaping` return true if the value is "escaping" to the `target` instruction.
185+
private struct EscapesToInstructionVisitor : EscapeVisitor {
186+
let target: Instruction
187+
let isAddress: Bool
188+
189+
mutating func visitUse(operand: Operand, path: EscapePath) -> UseResult {
190+
let user = operand.instruction
191+
if user == target {
192+
return .abort
193+
}
194+
if user is ReturnInst {
195+
// Anything which is returned cannot escape to an instruction inside the function.
196+
return .ignore
197+
}
198+
return .continueWalk
199+
}
200+
201+
var followTrivialTypes: Bool { isAddress }
202+
var followLoads: Bool { !isAddress }
178203
}
179204

180205
private extension Value {

SwiftCompilerSources/Sources/Optimizer/Analysis/CalleeAnalysis.swift

Lines changed: 1 addition & 1 deletion
Original file line numberDiff line numberDiff line change
@@ -24,7 +24,7 @@ public struct CalleeAnalysis {
2424
},
2525
// getMemBehaviorFn
2626
{ (bridgedCtxt: BridgedPassContext, bridgedApply: BridgedInstruction, observeRetains: Bool) -> BridgedMemoryBehavior in
27-
let context = PassContext(_bridged: bridgedCtxt)
27+
let context = FunctionPassContext(_bridged: bridgedCtxt)
2828
let apply = bridgedApply.instruction as! ApplySite
2929
let e = context.calleeAnalysis.getSideEffects(of: apply)
3030
return e.getMemBehavior(observeRetains: observeRetains)

SwiftCompilerSources/Sources/Optimizer/CMakeLists.txt

Lines changed: 1 addition & 1 deletion
Original file line numberDiff line numberDiff line change
@@ -13,7 +13,7 @@ add_swift_compiler_module(Optimizer DEPENDS ${dependencies})
1313

1414
add_subdirectory(Analysis)
1515
add_subdirectory(DataStructures)
16-
add_subdirectory(InstructionPasses)
16+
add_subdirectory(InstructionSimplification)
1717
add_subdirectory(PassManager)
1818
add_subdirectory(ModulePasses)
1919
add_subdirectory(FunctionPasses)

SwiftCompilerSources/Sources/Optimizer/DataStructures/BasicBlockRange.swift

Lines changed: 2 additions & 2 deletions
Original file line numberDiff line numberDiff line change
@@ -66,7 +66,7 @@ struct BasicBlockRange : CustomStringConvertible, NoReflectionChildren {
6666
private var inExclusiveRange: BasicBlockSet
6767
private var worklist: BasicBlockWorklist
6868

69-
init(begin: BasicBlock, _ context: PassContext) {
69+
init(begin: BasicBlock, _ context: some Context) {
7070
self.begin = begin
7171
self.inclusiveRange = Stack(context)
7272
self.inserted = Stack(context)
@@ -110,7 +110,7 @@ struct BasicBlockRange : CustomStringConvertible, NoReflectionChildren {
110110

111111
/// Returns true if the range is valid and that's iff the begin block dominates all blocks of the range.
112112
var isValid: Bool {
113-
let entry = begin.function.entryBlock
113+
let entry = begin.parentFunction.entryBlock
114114
return begin == entry ||
115115
// If any block in the range is not dominated by `begin`, the range propagates back to the entry block.
116116
!inclusiveRangeContains(entry)

SwiftCompilerSources/Sources/Optimizer/DataStructures/BasicBlockWorklist.swift

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

SwiftCompilerSources/Sources/Optimizer/DataStructures/CMakeLists.txt

Lines changed: 3 additions & 2 deletions
Original file line numberDiff line numberDiff line change
@@ -8,9 +8,10 @@
88

99
swift_compiler_sources(Optimizer
1010
BasicBlockRange.swift
11-
BasicBlockWorklist.swift
1211
DeadEndBlocks.swift
1312
FunctionUses.swift
1413
InstructionRange.swift
14+
ReachableBlocks.swift
1515
Set.swift
16-
Stack.swift)
16+
Stack.swift
17+
Worklist.swift)

SwiftCompilerSources/Sources/Optimizer/DataStructures/DeadEndBlocks.swift

Lines changed: 4 additions & 2 deletions
Original file line numberDiff line numberDiff line change
@@ -19,8 +19,10 @@ import SIL
1919
/// instruction and blocks from which all paths end in "unreachable" blocks.
2020
struct DeadEndBlocks : CustomStringConvertible, NoReflectionChildren {
2121
private var worklist: BasicBlockWorklist
22+
private var function: Function
2223

23-
init(function: Function, _ context: PassContext) {
24+
init(function: Function, _ context: FunctionPassContext) {
25+
self.function = function
2426
self.worklist = BasicBlockWorklist(context)
2527

2628
// Initialize the worklist with all function-exiting blocks.
@@ -40,7 +42,7 @@ struct DeadEndBlocks : CustomStringConvertible, NoReflectionChildren {
4042
}
4143

4244
var description: String {
43-
let blockNames = worklist.function.blocks.filter(isDeadEnd).map(\.name)
45+
let blockNames = function.blocks.filter(isDeadEnd).map(\.name)
4446
return "[" + blockNames.joined(separator: ",") + "]"
4547
}
4648

SwiftCompilerSources/Sources/Optimizer/DataStructures/FunctionUses.swift

Lines changed: 1 addition & 1 deletion
Original file line numberDiff line numberDiff line change
@@ -93,7 +93,7 @@ struct FunctionUses {
9393
result += "<unknown uses>\n"
9494
}
9595
for inst in self {
96-
result += "@\(inst.function.name): \(inst)\n"
96+
result += "@\(inst.parentFunction.name): \(inst)\n"
9797

9898
}
9999
result += "]"

SwiftCompilerSources/Sources/Optimizer/DataStructures/InstructionRange.swift

Lines changed: 4 additions & 4 deletions
Original file line numberDiff line numberDiff line change
@@ -48,16 +48,16 @@ struct InstructionRange : CustomStringConvertible, NoReflectionChildren {
4848

4949
private var insertedInsts: InstructionSet
5050

51-
init(begin beginInst: Instruction, _ context: PassContext) {
51+
init(begin beginInst: Instruction, _ context: some Context) {
5252
self.begin = beginInst
53-
self.blockRange = BasicBlockRange(begin: beginInst.block, context)
53+
self.blockRange = BasicBlockRange(begin: beginInst.parentBlock, context)
5454
self.insertedInsts = InstructionSet(context)
5555
}
5656

5757
/// Insert a potential end instruction.
5858
mutating func insert(_ inst: Instruction) {
5959
insertedInsts.insert(inst)
60-
blockRange.insert(inst.block)
60+
blockRange.insert(inst.parentBlock)
6161
}
6262

6363
/// Insert a sequence of potential end instructions.
@@ -69,7 +69,7 @@ struct InstructionRange : CustomStringConvertible, NoReflectionChildren {
6969

7070
/// Returns true if the exclusive range contains `inst`.
7171
func contains(_ inst: Instruction) -> Bool {
72-
let block = inst.block
72+
let block = inst.parentBlock
7373
if !blockRange.inclusiveRangeContains(block) { return false }
7474
var inRange = false
7575
if blockRange.contains(block) {
Lines changed: 48 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -0,0 +1,48 @@
1+
//===--- ReachableBlocks.swift --------------------------------------------===//
2+
//
3+
// This source file is part of the Swift.org open source project
4+
//
5+
// Copyright (c) 2014 - 2023 Apple Inc. and the Swift project authors
6+
// Licensed under Apache License v2.0 with Runtime Library Exception
7+
//
8+
// See https://swift.org/LICENSE.txt for license information
9+
// See https://swift.org/CONTRIBUTORS.txt for the list of Swift project authors
10+
//
11+
//===----------------------------------------------------------------------===//
12+
13+
import SIL
14+
15+
/// A utility for finding reachable and unreachable blocks.
16+
///
17+
/// Reachable blocks are all blocks which are reachable from the entry block of
18+
/// the function. All other blocks are dead blocks.
19+
struct ReachableBlocks : CustomStringConvertible, NoReflectionChildren {
20+
private var worklist: BasicBlockWorklist
21+
private var function: Function
22+
23+
init(function: Function, _ context: FunctionPassContext) {
24+
self.function = function
25+
self.worklist = BasicBlockWorklist(context)
26+
27+
worklist.pushIfNotVisited(function.entryBlock)
28+
29+
// Propagate lifeness down the control flow.
30+
while let block = worklist.pop() {
31+
worklist.pushIfNotVisited(contentsOf: block.successors)
32+
}
33+
}
34+
35+
func isReachable(block: BasicBlock) -> Bool {
36+
return worklist.hasBeenPushed(block)
37+
}
38+
39+
var description: String {
40+
let blockNames = function.blocks.filter(isReachable).map(\.name)
41+
return "[" + blockNames.joined(separator: ",") + "]"
42+
}
43+
44+
/// TODO: once we have move-only types, make this a real deinit.
45+
mutating func deinitialize() {
46+
worklist.deinitialize()
47+
}
48+
}

0 commit comments

Comments
 (0)