Skip to content

Commit f8fb33c

Browse files
Merge pull request #4806 from swiftwasm/katei/merge-main-2022-08-19
Merge main 2022-08-19
2 parents e36b8ea + 1de6a0d commit f8fb33c

File tree

1,158 files changed

+26996
-11884
lines changed

Some content is hidden

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

1,158 files changed

+26996
-11884
lines changed

.flake8

Lines changed: 0 additions & 3 deletions
Original file line numberDiff line numberDiff line change
@@ -51,9 +51,6 @@ ignore =
5151
# compliant (https://github.com/psf/black#slices).
5252
E203,
5353

54-
# FIXME: We should not have trailing whitespace.
55-
W291,
56-
5754
# Line breaks before binary operators are not explicitly disallowed in
5855
# PEP8, rather it should be consistent throughout the project. The black
5956
# tool puts them on new lines which is to be considered a best practice

.github/workflows/build-toolchain.yml

Lines changed: 1 addition & 1 deletion
Original file line numberDiff line numberDiff line change
@@ -191,7 +191,7 @@ jobs:
191191
build-toolchain:
192192
env:
193193
TOOLCHAIN_CHANNEL: DEVELOPMENT
194-
DEVELOPER_DIR: /Applications/Xcode_13.0.app/Contents/Developer/
194+
DEVELOPER_DIR: /Applications/Xcode_13.2.1.app/Contents/Developer/
195195
needs: [build-matrix]
196196
if: ${{ always() }}
197197
strategy:

SwiftCompilerSources/Sources/Optimizer/CMakeLists.txt

Lines changed: 1 addition & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -16,4 +16,5 @@ add_subdirectory(DataStructures)
1616
add_subdirectory(InstructionPasses)
1717
add_subdirectory(PassManager)
1818
add_subdirectory(FunctionPasses)
19+
add_subdirectory(TestPasses)
1920
add_subdirectory(Utilities)

SwiftCompilerSources/Sources/Optimizer/DataStructures/BasicBlockRange.swift

Lines changed: 1 addition & 2 deletions
Original file line numberDiff line numberDiff line change
@@ -78,8 +78,7 @@ struct BasicBlockRange : CustomStringConvertible, CustomReflectable {
7878

7979
/// Insert a potential end block.
8080
mutating func insert(_ block: BasicBlock) {
81-
if !wasInserted.contains(block) {
82-
wasInserted.insert(block)
81+
if wasInserted.insert(block) {
8382
inserted.append(block)
8483
}
8584
worklist.pushIfNotVisited(block)

SwiftCompilerSources/Sources/Optimizer/DataStructures/BasicBlockWorklist.swift

Lines changed: 1 addition & 2 deletions
Original file line numberDiff line numberDiff line change
@@ -34,8 +34,7 @@ struct BasicBlockWorklist : CustomStringConvertible, CustomReflectable {
3434

3535
/// Pushes \p block onto the worklist if \p block has never been pushed before.
3636
mutating func pushIfNotVisited(_ block: BasicBlock) {
37-
if !pushedBlocks.contains(block) {
38-
pushedBlocks.insert(block);
37+
if pushedBlocks.insert(block) {
3938
worklist.append(block)
4039
}
4140
}

SwiftCompilerSources/Sources/Optimizer/DataStructures/CMakeLists.txt

Lines changed: 1 addition & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -9,6 +9,7 @@
99
swift_compiler_sources(Optimizer
1010
BasicBlockRange.swift
1111
BasicBlockWorklist.swift
12+
FunctionUses.swift
1213
InstructionRange.swift
1314
Set.swift
1415
Stack.swift)
Lines changed: 166 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -0,0 +1,166 @@
1+
//===--- FunctionUses.swift -----------------------------------------------===//
2+
//
3+
// This source file is part of the Swift.org open source project
4+
//
5+
// Copyright (c) 2014 - 2022 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+
/// Provides a list of instructions, which reference a function.
16+
///
17+
/// A function "use" is an instruction in another (or the same) function which
18+
/// references the function. In most cases those are `function_ref` instructions,
19+
/// but can also be e.g. `keypath` instructions.
20+
///
21+
/// 'FunctionUses' performs an analysis of all functions in the module and collects
22+
/// instructions which reference other functions. This utility can be used to do
23+
/// inter-procedural caller-analysis.
24+
///
25+
/// In order to use `FunctionUses`, first call `collect()` and then get use-lists of
26+
/// functions with `getUses(of:)`.
27+
struct FunctionUses {
28+
29+
// Function uses are stored in a single linked list, whereas the "next" is not a pointer
30+
// but an index into `FunctionUses.useStorage`.
31+
fileprivate struct Use {
32+
// The index of the next use in `FunctionUses.useStorage`.
33+
let next: Int?
34+
35+
// The instruction which references the function.
36+
let usingInstruction: Instruction
37+
}
38+
39+
// The head of the single-linked list of function uses.
40+
fileprivate struct FirstUse {
41+
// The head of the use-list.
42+
var first: Int?
43+
44+
// True if the function has unknown uses
45+
var hasUnknownUses: Bool
46+
47+
init(of function: Function) {
48+
self.hasUnknownUses = function.isPossiblyUsedExternally || function.isAvailableExternally
49+
}
50+
51+
mutating func insert(_ inst: Instruction, _ uses: inout [Use]) {
52+
let newFirst = uses.count
53+
uses.append(Use(next: first, usingInstruction: inst))
54+
first = newFirst
55+
}
56+
}
57+
58+
/// The list of uses of a function.
59+
struct UseList : CollectionLikeSequence, CustomStringConvertible {
60+
struct Iterator : IteratorProtocol {
61+
fileprivate let useStorage: [Use]
62+
fileprivate var currentUseIdx: Int?
63+
64+
mutating func next() -> Instruction? {
65+
if let useIdx = currentUseIdx {
66+
let use = useStorage[useIdx]
67+
currentUseIdx = use.next
68+
return use.usingInstruction
69+
}
70+
return nil
71+
}
72+
}
73+
74+
// The "storage" for all function uses.
75+
fileprivate let useStorage: [Use]
76+
77+
// The head of the single-linked use list.
78+
fileprivate let firstUse: FirstUse
79+
80+
/// True if the function has unknown uses in addition to the list of referencing instructions.
81+
///
82+
/// This is the case, e.g. if the function has public linkage or if the function
83+
/// is referenced from a vtable or witness table.
84+
var hasUnknownUses: Bool { firstUse.hasUnknownUses }
85+
86+
func makeIterator() -> Iterator {
87+
return Iterator(useStorage: useStorage, currentUseIdx: firstUse.first)
88+
}
89+
90+
var description: String {
91+
var result = "[\n"
92+
if hasUnknownUses {
93+
result += "<unknown uses>\n"
94+
}
95+
for inst in self {
96+
result += "@\(inst.function.name): \(inst)\n"
97+
98+
}
99+
result += "]"
100+
return result
101+
}
102+
103+
var customMirror: Mirror { Mirror(self, children: []) }
104+
}
105+
106+
// The "storage" for all function uses.
107+
private var useStorage: [Use] = []
108+
109+
// The use-list head for each function.
110+
private var uses: [Function: FirstUse] = [:]
111+
112+
init() {
113+
// Already start with a reasonable big capacity to reduce the number of
114+
// re-allocations when appending to the data structures.
115+
useStorage.reserveCapacity(128)
116+
uses.reserveCapacity(64)
117+
}
118+
119+
/// Returns the use-list of `function`.
120+
///
121+
/// Note that `collect` must be called before `getUses` can be used.
122+
func getUses(of function: Function) -> UseList {
123+
UseList(useStorage: useStorage, firstUse: uses[function, default: FirstUse(of: function)])
124+
}
125+
126+
/// Collects all uses of all function in the module.
127+
mutating func collect(context: ModulePassContext) {
128+
129+
// Mark all functions, which are referenced from tables, to have "unknown" uses.
130+
131+
for vTable in context.vTables {
132+
for entry in vTable.entries {
133+
markUnknown(entry.function)
134+
}
135+
}
136+
137+
for witnessTable in context.witnessTables {
138+
for entry in witnessTable.entries {
139+
if entry.kind == .method, let f = entry.methodFunction {
140+
markUnknown(f)
141+
}
142+
}
143+
}
144+
145+
for witnessTable in context.defaultWitnessTables {
146+
for entry in witnessTable.entries {
147+
if entry.kind == .method, let f = entry.methodFunction {
148+
markUnknown(f)
149+
}
150+
}
151+
}
152+
153+
// Collect all instructions, which reference functions, in the module.
154+
for function in context.functions {
155+
for inst in function.instructions {
156+
inst.visitReferencedFunctions { referencedFunc in
157+
uses[referencedFunc, default: FirstUse(of: referencedFunc)].insert(inst, &useStorage)
158+
}
159+
}
160+
}
161+
}
162+
163+
private mutating func markUnknown(_ function: Function) {
164+
uses[function, default: FirstUse(of: function)].hasUnknownUses = true
165+
}
166+
}

SwiftCompilerSources/Sources/Optimizer/DataStructures/Set.swift

Lines changed: 15 additions & 11 deletions
Original file line numberDiff line numberDiff line change
@@ -35,8 +35,10 @@ struct BasicBlockSet : CustomStringConvertible, CustomReflectable {
3535
BasicBlockSet_contains(bridged, block.bridged) != 0
3636
}
3737

38-
mutating func insert(_ block: BasicBlock) {
39-
BasicBlockSet_insert(bridged, block.bridged)
38+
/// Returns true if `block` was not contained in the set before inserting.
39+
@discardableResult
40+
mutating func insert(_ block: BasicBlock) -> Bool {
41+
BasicBlockSet_insert(bridged, block.bridged) != 0
4042
}
4143

4244
mutating func erase(_ block: BasicBlock) {
@@ -80,8 +82,10 @@ struct ValueSet : CustomStringConvertible, CustomReflectable {
8082
NodeSet_containsValue(bridged, value.bridged) != 0
8183
}
8284

83-
mutating func insert(_ value: Value) {
84-
NodeSet_insertValue(bridged, value.bridged)
85+
/// Returns true if `value` was not contained in the set before inserting.
86+
@discardableResult
87+
mutating func insert(_ value: Value) -> Bool {
88+
NodeSet_insertValue(bridged, value.bridged) != 0
8589
}
8690

8791
mutating func erase(_ value: Value) {
@@ -139,8 +143,10 @@ struct InstructionSet : CustomStringConvertible, CustomReflectable {
139143
NodeSet_containsInstruction(bridged, inst.bridged) != 0
140144
}
141145

142-
mutating func insert(_ inst: Instruction) {
143-
NodeSet_insertInstruction(bridged, inst.bridged)
146+
/// Returns true if `inst` was not contained in the set before inserting.
147+
@discardableResult
148+
mutating func insert(_ inst: Instruction) -> Bool {
149+
NodeSet_insertInstruction(bridged, inst.bridged) != 0
144150
}
145151

146152
mutating func erase(_ inst: Instruction) {
@@ -150,11 +156,9 @@ struct InstructionSet : CustomStringConvertible, CustomReflectable {
150156
var description: String {
151157
let function = NodeSet_getFunction(bridged).function
152158
var d = "{\n"
153-
for block in function.blocks {
154-
for inst in block.instructions {
155-
if contains(inst) {
156-
d += inst.description
157-
}
159+
for inst in function.instructions {
160+
if contains(inst) {
161+
d += inst.description
158162
}
159163
}
160164
d += "}\n"

SwiftCompilerSources/Sources/Optimizer/DataStructures/Stack.swift

Lines changed: 7 additions & 6 deletions
Original file line numberDiff line numberDiff line change
@@ -26,7 +26,7 @@ import SIL
2626
/// destruct this data structure, e.g. in a `defer {}` block.
2727
struct Stack<Element> : CollectionLikeSequence {
2828

29-
private let context: PassContext
29+
private let bridgedContext: BridgedPassContext
3030
private var firstSlab = BridgedSlab(data: nil)
3131
private var lastSlab = BridgedSlab(data: nil)
3232
private var endIndex: Int = 0
@@ -61,7 +61,8 @@ struct Stack<Element> : CollectionLikeSequence {
6161
}
6262
}
6363

64-
init(_ context: PassContext) { self.context = context }
64+
init(_ context: PassContext) { self.bridgedContext = context._bridged }
65+
init(_ context: ModulePassContext) { self.bridgedContext = context._bridged }
6566

6667
func makeIterator() -> Iterator {
6768
return Iterator(slab: firstSlab, index: 0, lastSlab: lastSlab, endIndex: endIndex)
@@ -77,11 +78,11 @@ struct Stack<Element> : CollectionLikeSequence {
7778

7879
mutating func push(_ element: Element) {
7980
if endIndex >= Stack.slabCapacity {
80-
lastSlab = PassContext_allocSlab(context._bridged, lastSlab)
81+
lastSlab = PassContext_allocSlab(bridgedContext, lastSlab)
8182
endIndex = 0
8283
} else if firstSlab.data == nil {
8384
assert(endIndex == 0)
84-
firstSlab = PassContext_allocSlab(context._bridged, lastSlab)
85+
firstSlab = PassContext_allocSlab(bridgedContext, lastSlab)
8586
lastSlab = firstSlab
8687
}
8788
(Stack.bind(lastSlab) + endIndex).initialize(to: element)
@@ -109,12 +110,12 @@ struct Stack<Element> : CollectionLikeSequence {
109110

110111
if endIndex == 0 {
111112
if lastSlab.data == firstSlab.data {
112-
_ = PassContext_freeSlab(context._bridged, lastSlab)
113+
_ = PassContext_freeSlab(bridgedContext, lastSlab)
113114
firstSlab.data = nil
114115
lastSlab.data = nil
115116
endIndex = 0
116117
} else {
117-
lastSlab = PassContext_freeSlab(context._bridged, lastSlab)
118+
lastSlab = PassContext_freeSlab(bridgedContext, lastSlab)
118119
endIndex = Stack.slabCapacity
119120
}
120121
}

SwiftCompilerSources/Sources/Optimizer/FunctionPasses/AssumeSingleThreaded.swift

Lines changed: 3 additions & 5 deletions
Original file line numberDiff line numberDiff line change
@@ -29,12 +29,10 @@ import SIL
2929

3030
let assumeSingleThreadedPass = FunctionPass(
3131
name: "sil-assume-single-threaded", { function, context in
32-
for block in function.blocks {
33-
for inst in block.instructions {
34-
guard let rcInst = inst as? RefCountingInst else { continue }
32+
for inst in function.instructions {
33+
guard let rcInst = inst as? RefCountingInst else { continue }
3534

36-
rcInst.setAtomicity(isAtomic: false, context)
37-
}
35+
rcInst.setAtomicity(isAtomic: false, context)
3836
}
3937
}
4038
)

SwiftCompilerSources/Sources/Optimizer/FunctionPasses/CMakeLists.txt

Lines changed: 0 additions & 5 deletions
Original file line numberDiff line numberDiff line change
@@ -8,14 +8,9 @@
88

99
swift_compiler_sources(Optimizer
1010
AssumeSingleThreaded.swift
11-
AccessDumper.swift
1211
ComputeEffects.swift
13-
EscapeInfoDumper.swift
1412
ObjCBridgingOptimization.swift
15-
SILPrinter.swift
1613
MergeCondFails.swift
17-
RangeDumper.swift
1814
ReleaseDevirtualizer.swift
19-
RunUnitTests.swift
2015
StackPromotion.swift
2116
)

SwiftCompilerSources/Sources/Optimizer/FunctionPasses/ObjCBridgingOptimization.swift

Lines changed: 4 additions & 6 deletions
Original file line numberDiff line numberDiff line change
@@ -48,12 +48,10 @@ let objCBridgingOptimization = FunctionPass(name: "objc-bridging-opt", {
4848
}
4949

5050
// Now try to optimize non-optional and optional -> non-optional bridging.
51-
for block in function.blocks {
52-
for inst in block.instructions {
53-
if let apply = inst as? ApplyInst {
54-
if !optimizeNonOptionalBridging(apply, context) {
55-
return
56-
}
51+
for inst in function.instructions {
52+
if let apply = inst as? ApplyInst {
53+
if !optimizeNonOptionalBridging(apply, context) {
54+
return
5755
}
5856
}
5957
}

0 commit comments

Comments
 (0)