Skip to content

Commit e89fdb5

Browse files
committed
SwiftCompilerSources: move SIL-related datastructures from the Optimizer to the SIL module
1 parent e2129b5 commit e89fdb5

File tree

10 files changed

+174
-164
lines changed

10 files changed

+174
-164
lines changed

SwiftCompilerSources/Sources/Optimizer/DataStructures/CMakeLists.txt

Lines changed: 1 addition & 6 deletions
Original file line numberDiff line numberDiff line change
@@ -7,11 +7,6 @@
77
# See http://swift.org/CONTRIBUTORS.txt for Swift project authors
88

99
swift_compiler_sources(Optimizer
10-
BasicBlockRange.swift
1110
DeadEndBlocks.swift
1211
FunctionUses.swift
13-
InstructionRange.swift
14-
ReachableBlocks.swift
15-
Set.swift
16-
Stack.swift
17-
Worklist.swift)
12+
ReachableBlocks.swift)

SwiftCompilerSources/Sources/Optimizer/Utilities/AccessUtilsTest.swift

Lines changed: 2 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -14,6 +14,8 @@
1414
//
1515
//===----------------------------------------------------------------------===//
1616

17+
import SIL
18+
1719
let getAccessBaseTest = FunctionTest("swift_get_access_base") {
1820
function, arguments, context in
1921
let address = arguments.takeValue()

SwiftCompilerSources/Sources/Optimizer/Utilities/OwnershipLiveness.swift

Lines changed: 26 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -904,3 +904,29 @@ let interiorLivenessTest = FunctionTest("interior_liveness_swift") {
904904
defer { boundary.deinitialize() }
905905
print(boundary)
906906
}
907+
908+
//
909+
// TODO: Move this to InstructionRange.swift when computeLinearLiveness is in the SIL module.
910+
//
911+
let rangeOverlapsPathTest = FunctionTest("range_overlaps_path") {
912+
function, arguments, context in
913+
let rangeValue = arguments.takeValue()
914+
print("Range of: \(rangeValue)")
915+
var range = computeLinearLiveness(for: rangeValue, context)
916+
defer { range.deinitialize() }
917+
let pathInst = arguments.takeInstruction()
918+
print("Path begin: \(pathInst)")
919+
if let pathBegin = pathInst as? ScopedInstruction {
920+
for end in pathBegin.endInstructions {
921+
print("Overlap kind:", range.overlaps(pathBegin: pathInst, pathEnd: end, context))
922+
}
923+
return
924+
}
925+
if let pathValue = pathInst as? SingleValueInstruction, pathValue.ownership == .owned {
926+
for end in pathValue.uses.endingLifetime {
927+
print("Overlap kind:", range.overlaps(pathBegin: pathInst, pathEnd: end.instruction, context))
928+
}
929+
return
930+
}
931+
print("Test specification error: not a scoped or owned instruction: \(pathInst)")
932+
}

SwiftCompilerSources/Sources/SIL/CMakeLists.txt

Lines changed: 1 addition & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -35,5 +35,6 @@ add_swift_compiler_module(SIL
3535
VTable.swift
3636
WitnessTable.swift)
3737

38+
add_subdirectory(DataStructures)
3839
add_subdirectory(Utilities)
3940

SwiftCompilerSources/Sources/Optimizer/DataStructures/BasicBlockRange.swift renamed to SwiftCompilerSources/Sources/SIL/DataStructures/BasicBlockRange.swift

Lines changed: 17 additions & 19 deletions
Original file line numberDiff line numberDiff line change
@@ -10,8 +10,6 @@
1010
//
1111
//===----------------------------------------------------------------------===//
1212

13-
import SIL
14-
1513
/// A range of basic blocks.
1614
///
1715
/// The `BasicBlockRange` defines a range from a dominating "begin" block to one or more "end" blocks.
@@ -46,16 +44,16 @@ import SIL
4644
/// This type should be a move-only type, but unfortunately we don't have move-only
4745
/// types yet. Therefore it's needed to call `deinitialize()` explicitly to
4846
/// destruct this data structure, e.g. in a `defer {}` block.
49-
struct BasicBlockRange : CustomStringConvertible, NoReflectionChildren {
47+
public struct BasicBlockRange : CustomStringConvertible, NoReflectionChildren {
5048

5149
/// The dominating begin block.
52-
let begin: BasicBlock
50+
public let begin: BasicBlock
5351

5452
/// The inclusive range, i.e. the exclusive range plus the end blocks.
55-
private(set) var inclusiveRange: Stack<BasicBlock>
56-
53+
public private(set) var inclusiveRange: Stack<BasicBlock>
54+
5755
/// The exclusive range, i.e. not containing the end blocks.
58-
var range: LazyFilterSequence<Stack<BasicBlock>> {
56+
public var range: LazyFilterSequence<Stack<BasicBlock>> {
5957
inclusiveRange.lazy.filter { contains($0) }
6058
}
6159

@@ -66,7 +64,7 @@ struct BasicBlockRange : CustomStringConvertible, NoReflectionChildren {
6664
private var inExclusiveRange: BasicBlockSet
6765
private var worklist: BasicBlockWorklist
6866

69-
init(begin: BasicBlock, _ context: some Context) {
67+
public init(begin: BasicBlock, _ context: some Context) {
7068
self.begin = begin
7169
self.inclusiveRange = Stack(context)
7270
self.inserted = Stack(context)
@@ -81,7 +79,7 @@ struct BasicBlockRange : CustomStringConvertible, NoReflectionChildren {
8179
/// Returns true if the begin-block is reached during backward propagation.
8280
/// Usually this is not relevant, but InstructionRange needs this information.
8381
@discardableResult
84-
mutating func insert(_ block: BasicBlock) -> Bool {
82+
public mutating func insert(_ block: BasicBlock) -> Bool {
8583
if wasInserted.insert(block) {
8684
inserted.append(block)
8785
}
@@ -103,35 +101,35 @@ struct BasicBlockRange : CustomStringConvertible, NoReflectionChildren {
103101
}
104102

105103
/// Insert a sequence of potential end blocks.
106-
mutating func insert<S: Sequence>(contentsOf other: S) where S.Element == BasicBlock {
104+
public mutating func insert<S: Sequence>(contentsOf other: S) where S.Element == BasicBlock {
107105
for block in other {
108106
insert(block)
109107
}
110108
}
111109

112110
/// Returns true if the exclusive range contains `block`.
113-
func contains(_ block: BasicBlock) -> Bool { inExclusiveRange.contains(block) }
114-
111+
public func contains(_ block: BasicBlock) -> Bool { inExclusiveRange.contains(block) }
112+
115113
/// Returns true if the inclusive range contains `block`.
116-
func inclusiveRangeContains (_ block: BasicBlock) -> Bool {
114+
public func inclusiveRangeContains (_ block: BasicBlock) -> Bool {
117115
worklist.hasBeenPushed(block)
118116
}
119117

120118
/// Returns true if the range is valid and that's iff the begin block dominates all blocks of the range.
121-
var isValid: Bool {
119+
public var isValid: Bool {
122120
let entry = begin.parentFunction.entryBlock
123121
return begin == entry ||
124122
// If any block in the range is not dominated by `begin`, the range propagates back to the entry block.
125123
!inclusiveRangeContains(entry)
126124
}
127125

128126
/// Returns the end blocks.
129-
var ends: LazyFilterSequence<Stack<BasicBlock>> {
127+
public var ends: LazyFilterSequence<Stack<BasicBlock>> {
130128
inserted.lazy.filter { !contains($0) }
131129
}
132130

133131
/// Returns the exit blocks.
134-
var exits: LazySequence<FlattenSequence<
132+
public var exits: LazySequence<FlattenSequence<
135133
LazyMapSequence<LazyFilterSequence<Stack<BasicBlock>>,
136134
LazyFilterSequence<SuccessorArray>>>> {
137135
range.flatMap {
@@ -142,11 +140,11 @@ struct BasicBlockRange : CustomStringConvertible, NoReflectionChildren {
142140
}
143141

144142
/// Returns the interior blocks.
145-
var interiors: LazyFilterSequence<Stack<BasicBlock>> {
143+
public var interiors: LazyFilterSequence<Stack<BasicBlock>> {
146144
inserted.lazy.filter { contains($0) && $0 != begin }
147145
}
148146

149-
var description: String {
147+
public var description: String {
150148
return (isValid ? "" : "<invalid>\n") +
151149
"""
152150
begin: \(begin.name)
@@ -159,7 +157,7 @@ struct BasicBlockRange : CustomStringConvertible, NoReflectionChildren {
159157
}
160158

161159
/// TODO: once we have move-only types, make this a real deinit.
162-
mutating func deinitialize() {
160+
public mutating func deinitialize() {
163161
worklist.deinitialize()
164162
inExclusiveRange.deinitialize()
165163
wasInserted.deinitialize()
Lines changed: 14 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -0,0 +1,14 @@
1+
# This source file is part of the Swift.org open source project
2+
#
3+
# Copyright (c) 2014 - 2021 Apple Inc. and the Swift project authors
4+
# Licensed under Apache License v2.0 with Runtime Library Exception
5+
#
6+
# See http://swift.org/LICENSE.txt for license information
7+
# See http://swift.org/CONTRIBUTORS.txt for Swift project authors
8+
9+
swift_compiler_sources(SIL
10+
BasicBlockRange.swift
11+
InstructionRange.swift
12+
Set.swift
13+
Stack.swift
14+
Worklist.swift)

SwiftCompilerSources/Sources/Optimizer/DataStructures/InstructionRange.swift renamed to SwiftCompilerSources/Sources/SIL/DataStructures/InstructionRange.swift

Lines changed: 22 additions & 46 deletions
Original file line numberDiff line numberDiff line change
@@ -10,8 +10,6 @@
1010
//
1111
//===----------------------------------------------------------------------===//
1212

13-
import SIL
14-
1513
/// A range of instructions.
1614
///
1715
/// The `InstructionRange` defines a range from a dominating "begin" instruction to one or more "end" instructions.
@@ -38,29 +36,29 @@ import SIL
3836
/// This type should be a move-only type, but unfortunately we don't have move-only
3937
/// types yet. Therefore it's needed to call `deinitialize()` explicitly to
4038
/// destruct this data structure, e.g. in a `defer {}` block.
41-
struct InstructionRange : CustomStringConvertible, NoReflectionChildren {
42-
39+
public struct InstructionRange : CustomStringConvertible, NoReflectionChildren {
40+
4341
/// The underlying block range.
44-
private(set) var blockRange: BasicBlockRange
42+
public private(set) var blockRange: BasicBlockRange
4543

4644
private var insertedInsts: InstructionSet
4745

4846
// For efficiency, this set does not include instructions in blocks which are not the begin or any end block.
4947
private var inExclusiveRange: InstructionSet
5048

51-
init(begin beginInst: Instruction, _ context: some Context) {
49+
public init(begin beginInst: Instruction, _ context: some Context) {
5250
self = InstructionRange(beginBlock: beginInst.parentBlock, context)
5351
self.inExclusiveRange.insert(beginInst)
5452
}
5553

5654
// Note: 'ends' are simply the instructions to insert in the range. 'self.ends' might not return the same sequence
5755
// as this 'ends' argument because 'self.ends' will not include block exits.
58-
init<S: Sequence>(begin beginInst: Instruction, ends: S, _ context: some Context) where S.Element: Instruction {
56+
public init<S: Sequence>(begin beginInst: Instruction, ends: S, _ context: some Context) where S.Element: Instruction {
5957
self = InstructionRange(begin: beginInst, context)
6058
insert(contentsOf: ends)
6159
}
6260

63-
init(for value: Value, _ context: some Context) {
61+
public init(for value: Value, _ context: some Context) {
6462
if let inst = value.definingInstruction {
6563
self = InstructionRange(begin: inst, context)
6664
} else if let arg = value as? Argument {
@@ -77,7 +75,7 @@ struct InstructionRange : CustomStringConvertible, NoReflectionChildren {
7775
}
7876

7977
/// Insert a potential end instruction.
80-
mutating func insert(_ inst: Instruction) {
78+
public mutating func insert(_ inst: Instruction) {
8179
insertedInsts.insert(inst)
8280
insertIntoRange(instructions: ReverseInstructionList(first: inst.previous))
8381
if blockRange.insert(inst.parentBlock) {
@@ -90,14 +88,14 @@ struct InstructionRange : CustomStringConvertible, NoReflectionChildren {
9088
}
9189

9290
/// Insert a sequence of potential end instructions.
93-
mutating func insert<S: Sequence>(contentsOf other: S) where S.Element: Instruction {
91+
public mutating func insert<S: Sequence>(contentsOf other: S) where S.Element: Instruction {
9492
for inst in other {
9593
insert(inst)
9694
}
9795
}
9896

9997
/// Returns true if the exclusive range contains `inst`.
100-
func contains(_ inst: Instruction) -> Bool {
98+
public func contains(_ inst: Instruction) -> Bool {
10199
if inExclusiveRange.contains(inst) {
102100
return true
103101
}
@@ -106,37 +104,37 @@ struct InstructionRange : CustomStringConvertible, NoReflectionChildren {
106104
}
107105

108106
/// Returns true if the inclusive range contains `inst`.
109-
func inclusiveRangeContains (_ inst: Instruction) -> Bool {
107+
public func inclusiveRangeContains (_ inst: Instruction) -> Bool {
110108
contains(inst) || insertedInsts.contains(inst)
111109
}
112110

113111
/// Returns the end instructions.
114112
///
115113
/// Warning: this returns `begin` if no instructions were inserted.
116-
var ends: LazyMapSequence<LazyFilterSequence<Stack<BasicBlock>>, Instruction> {
114+
public var ends: LazyMapSequence<LazyFilterSequence<Stack<BasicBlock>>, Instruction> {
117115
blockRange.ends.map {
118116
$0.instructions.reversed().first(where: { insertedInsts.contains($0)})!
119117
}
120118
}
121119

122120
// Returns the exit blocks.
123-
var exitBlocks: LazySequence<FlattenSequence<
124-
LazyMapSequence<LazyFilterSequence<Stack<BasicBlock>>,
121+
public var exitBlocks: LazySequence<FlattenSequence<
122+
LazyMapSequence<LazyFilterSequence<Stack<BasicBlock>>,
125123
LazyFilterSequence<SuccessorArray>>>> {
126124
blockRange.exits
127125
}
128126

129127
/// Returns the exit instructions.
130-
var exits: LazyMapSequence<LazySequence<FlattenSequence<
131-
LazyMapSequence<LazyFilterSequence<Stack<BasicBlock>>,
128+
public var exits: LazyMapSequence<LazySequence<FlattenSequence<
129+
LazyMapSequence<LazyFilterSequence<Stack<BasicBlock>>,
132130
LazyFilterSequence<SuccessorArray>>>>,
133131
Instruction> {
134132
blockRange.exits.lazy.map { $0.instructions.first! }
135133
}
136134

137135
/// Returns the interior instructions.
138-
var interiors: LazySequence<FlattenSequence<
139-
LazyMapSequence<Stack<BasicBlock>,
136+
public var interiors: LazySequence<FlattenSequence<
137+
LazyMapSequence<Stack<BasicBlock>,
140138
LazyFilterSequence<ReverseInstructionList>>>> {
141139
blockRange.inserted.lazy.flatMap {
142140
var include = blockRange.contains($0)
@@ -151,7 +149,7 @@ struct InstructionRange : CustomStringConvertible, NoReflectionChildren {
151149
}
152150
}
153151

154-
var begin: Instruction? {
152+
public var begin: Instruction? {
155153
blockRange.begin.instructions.first(where: inExclusiveRange.contains)
156154
}
157155

@@ -163,7 +161,7 @@ struct InstructionRange : CustomStringConvertible, NoReflectionChildren {
163161
}
164162
}
165163

166-
var description: String {
164+
public var description: String {
167165
return (blockRange.isValid ? "" : "<invalid>\n") +
168166
"""
169167
begin: \(begin?.description ?? blockRange.begin.name)
@@ -174,15 +172,15 @@ struct InstructionRange : CustomStringConvertible, NoReflectionChildren {
174172
}
175173

176174
/// TODO: once we have move-only types, make this a real deinit.
177-
mutating func deinitialize() {
175+
public mutating func deinitialize() {
178176
inExclusiveRange.deinitialize()
179177
insertedInsts.deinitialize()
180178
blockRange.deinitialize()
181179
}
182180
}
183181

184182
extension InstructionRange {
185-
enum PathOverlap {
183+
public enum PathOverlap {
186184
// range: ---
187185
// | pathBegin
188186
// | |
@@ -226,7 +224,7 @@ extension InstructionRange {
226224
/// Returns .containsBegin, if this range has the same begin and end as the path.
227225
///
228226
/// Precondition: `begin` dominates `end`.
229-
func overlaps(pathBegin: Instruction, pathEnd: Instruction, _ context: some Context) -> PathOverlap {
227+
public func overlaps(pathBegin: Instruction, pathEnd: Instruction, _ context: some Context) -> PathOverlap {
230228
assert(pathBegin != pathEnd, "expect an exclusive path")
231229
if contains(pathBegin) {
232230
// Note: pathEnd != self.begin here since self.contains(pathBegin)
@@ -277,25 +275,3 @@ extension InstructionRange {
277275
}
278276
}
279277

280-
let rangeOverlapsPathTest = FunctionTest("range_overlaps_path") {
281-
function, arguments, context in
282-
let rangeValue = arguments.takeValue()
283-
print("Range of: \(rangeValue)")
284-
var range = computeLinearLiveness(for: rangeValue, context)
285-
defer { range.deinitialize() }
286-
let pathInst = arguments.takeInstruction()
287-
print("Path begin: \(pathInst)")
288-
if let pathBegin = pathInst as? ScopedInstruction {
289-
for end in pathBegin.endInstructions {
290-
print("Overlap kind:", range.overlaps(pathBegin: pathInst, pathEnd: end, context))
291-
}
292-
return
293-
}
294-
if let pathValue = pathInst as? SingleValueInstruction, pathValue.ownership == .owned {
295-
for end in pathValue.uses.endingLifetime {
296-
print("Overlap kind:", range.overlaps(pathBegin: pathInst, pathEnd: end.instruction, context))
297-
}
298-
return
299-
}
300-
print("Test specification error: not a scoped or owned instruction: \(pathInst)")
301-
}

0 commit comments

Comments
 (0)