10
10
//
11
11
//===----------------------------------------------------------------------===//
12
12
13
- import SIL
14
-
15
13
/// A range of instructions.
16
14
///
17
15
/// The `InstructionRange` defines a range from a dominating "begin" instruction to one or more "end" instructions.
@@ -38,29 +36,29 @@ import SIL
38
36
/// This type should be a move-only type, but unfortunately we don't have move-only
39
37
/// types yet. Therefore it's needed to call `deinitialize()` explicitly to
40
38
/// destruct this data structure, e.g. in a `defer {}` block.
41
- struct InstructionRange : CustomStringConvertible , NoReflectionChildren {
42
-
39
+ public struct InstructionRange : CustomStringConvertible , NoReflectionChildren {
40
+
43
41
/// The underlying block range.
44
- private( set) var blockRange : BasicBlockRange
42
+ public private( set) var blockRange : BasicBlockRange
45
43
46
44
private var insertedInsts : InstructionSet
47
45
48
46
// For efficiency, this set does not include instructions in blocks which are not the begin or any end block.
49
47
private var inExclusiveRange : InstructionSet
50
48
51
- init ( begin beginInst: Instruction , _ context: some Context ) {
49
+ public init ( begin beginInst: Instruction , _ context: some Context ) {
52
50
self = InstructionRange ( beginBlock: beginInst. parentBlock, context)
53
51
self . inExclusiveRange. insert ( beginInst)
54
52
}
55
53
56
54
// Note: 'ends' are simply the instructions to insert in the range. 'self.ends' might not return the same sequence
57
55
// 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 {
59
57
self = InstructionRange ( begin: beginInst, context)
60
58
insert ( contentsOf: ends)
61
59
}
62
60
63
- init ( for value: Value , _ context: some Context ) {
61
+ public init ( for value: Value , _ context: some Context ) {
64
62
if let inst = value. definingInstruction {
65
63
self = InstructionRange ( begin: inst, context)
66
64
} else if let arg = value as? Argument {
@@ -77,7 +75,7 @@ struct InstructionRange : CustomStringConvertible, NoReflectionChildren {
77
75
}
78
76
79
77
/// Insert a potential end instruction.
80
- mutating func insert( _ inst: Instruction ) {
78
+ public mutating func insert( _ inst: Instruction ) {
81
79
insertedInsts. insert ( inst)
82
80
insertIntoRange ( instructions: ReverseInstructionList ( first: inst. previous) )
83
81
if blockRange. insert ( inst. parentBlock) {
@@ -90,14 +88,14 @@ struct InstructionRange : CustomStringConvertible, NoReflectionChildren {
90
88
}
91
89
92
90
/// 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 {
94
92
for inst in other {
95
93
insert ( inst)
96
94
}
97
95
}
98
96
99
97
/// Returns true if the exclusive range contains `inst`.
100
- func contains( _ inst: Instruction ) -> Bool {
98
+ public func contains( _ inst: Instruction ) -> Bool {
101
99
if inExclusiveRange. contains ( inst) {
102
100
return true
103
101
}
@@ -106,37 +104,37 @@ struct InstructionRange : CustomStringConvertible, NoReflectionChildren {
106
104
}
107
105
108
106
/// Returns true if the inclusive range contains `inst`.
109
- func inclusiveRangeContains ( _ inst: Instruction ) -> Bool {
107
+ public func inclusiveRangeContains ( _ inst: Instruction ) -> Bool {
110
108
contains ( inst) || insertedInsts. contains ( inst)
111
109
}
112
110
113
111
/// Returns the end instructions.
114
112
///
115
113
/// 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 > {
117
115
blockRange. ends. map {
118
116
$0. instructions. reversed ( ) . first ( where: { insertedInsts. contains ( $0) } ) !
119
117
}
120
118
}
121
119
122
120
// 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 > > ,
125
123
LazyFilterSequence < SuccessorArray > > > > {
126
124
blockRange. exits
127
125
}
128
126
129
127
/// 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 > > ,
132
130
LazyFilterSequence < SuccessorArray > > > > ,
133
131
Instruction > {
134
132
blockRange. exits. lazy. map { $0. instructions. first! }
135
133
}
136
134
137
135
/// Returns the interior instructions.
138
- var interiors : LazySequence < FlattenSequence <
139
- LazyMapSequence < Stack < BasicBlock > ,
136
+ public var interiors : LazySequence < FlattenSequence <
137
+ LazyMapSequence < Stack < BasicBlock > ,
140
138
LazyFilterSequence < ReverseInstructionList > > > > {
141
139
blockRange. inserted. lazy. flatMap {
142
140
var include = blockRange. contains ( $0)
@@ -151,7 +149,7 @@ struct InstructionRange : CustomStringConvertible, NoReflectionChildren {
151
149
}
152
150
}
153
151
154
- var begin : Instruction ? {
152
+ public var begin : Instruction ? {
155
153
blockRange. begin. instructions. first ( where: inExclusiveRange. contains)
156
154
}
157
155
@@ -163,7 +161,7 @@ struct InstructionRange : CustomStringConvertible, NoReflectionChildren {
163
161
}
164
162
}
165
163
166
- var description : String {
164
+ public var description : String {
167
165
return ( blockRange. isValid ? " " : " <invalid> \n " ) +
168
166
"""
169
167
begin: \( begin? . description ?? blockRange. begin. name)
@@ -174,15 +172,15 @@ struct InstructionRange : CustomStringConvertible, NoReflectionChildren {
174
172
}
175
173
176
174
/// TODO: once we have move-only types, make this a real deinit.
177
- mutating func deinitialize( ) {
175
+ public mutating func deinitialize( ) {
178
176
inExclusiveRange. deinitialize ( )
179
177
insertedInsts. deinitialize ( )
180
178
blockRange. deinitialize ( )
181
179
}
182
180
}
183
181
184
182
extension InstructionRange {
185
- enum PathOverlap {
183
+ public enum PathOverlap {
186
184
// range: ---
187
185
// | pathBegin
188
186
// | |
@@ -226,7 +224,7 @@ extension InstructionRange {
226
224
/// Returns .containsBegin, if this range has the same begin and end as the path.
227
225
///
228
226
/// 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 {
230
228
assert ( pathBegin != pathEnd, " expect an exclusive path " )
231
229
if contains ( pathBegin) {
232
230
// Note: pathEnd != self.begin here since self.contains(pathBegin)
@@ -277,25 +275,3 @@ extension InstructionRange {
277
275
}
278
276
}
279
277
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