@@ -40,9 +40,6 @@ import SIL
40
40
/// destruct this data structure, e.g. in a `defer {}` block.
41
41
struct InstructionRange : CustomStringConvertible , NoReflectionChildren {
42
42
43
- /// The dominating begin instruction.
44
- let begin : Instruction
45
-
46
43
/// The underlying block range.
47
44
private( set) var blockRange : BasicBlockRange
48
45
@@ -52,36 +49,37 @@ struct InstructionRange : CustomStringConvertible, NoReflectionChildren {
52
49
private var inExclusiveRange : InstructionSet
53
50
54
51
init ( begin beginInst: Instruction , _ context: some Context ) {
55
- self . begin = beginInst
56
- self . blockRange = BasicBlockRange ( begin: beginInst. parentBlock, context)
57
- self . insertedInsts = InstructionSet ( context)
58
- self . inExclusiveRange = InstructionSet ( context)
52
+ self = InstructionRange ( beginBlock: beginInst. parentBlock, context)
59
53
self . inExclusiveRange. insert ( beginInst)
60
54
}
61
55
62
56
init ( for value: Value , _ context: some Context ) {
63
- self = InstructionRange ( begin: InstructionRange . beginningInstruction ( for: value) , context)
57
+ if let inst = value. definingInstruction {
58
+ self = InstructionRange ( begin: inst, context)
59
+ } else if let arg = value as? Argument {
60
+ self = InstructionRange ( beginBlock: arg. parentBlock, context)
61
+ } else {
62
+ fatalError ( " cannot build an instruction range for \( value) " )
63
+ }
64
64
}
65
65
66
- static func beginningInstruction( for value: Value ) -> Instruction {
67
- if let def = value. definingInstructionOrTerminator {
68
- return def
69
- }
70
- assert ( Phi ( value) != nil || value is FunctionArgument )
71
- return value. parentBlock. instructions. first!
66
+ private init ( beginBlock: BasicBlock , _ context: some Context ) {
67
+ self . blockRange = BasicBlockRange ( begin: beginBlock, context)
68
+ self . insertedInsts = InstructionSet ( context)
69
+ self . inExclusiveRange = InstructionSet ( context)
72
70
}
73
71
74
72
/// Insert a potential end instruction.
75
73
mutating func insert( _ inst: Instruction ) {
76
74
insertedInsts. insert ( inst)
77
75
insertIntoRange ( instructions: ReverseInstructionList ( first: inst. previous) )
78
76
blockRange. insert ( inst. parentBlock)
79
- if inst. parentBlock != begin . parentBlock {
77
+ if inst. parentBlock != blockRange . begin {
80
78
// The first time an instruction is inserted in another block than the begin-block we need to insert
81
79
// instructions from the begin instruction to the end of the begin block.
82
80
// For subsequent insertions this is a no-op: `insertIntoRange` will return immediately because those
83
81
// instruction are already inserted.
84
- insertIntoRange ( instructions: begin . parentBlock . instructions. reversed ( ) )
82
+ insertIntoRange ( instructions: blockRange . begin . instructions. reversed ( ) )
85
83
}
86
84
}
87
85
@@ -98,22 +96,14 @@ struct InstructionRange : CustomStringConvertible, NoReflectionChildren {
98
96
return true
99
97
}
100
98
let block = inst. parentBlock
101
- return block != begin . parentBlock && blockRange. contains ( block)
99
+ return block != blockRange . begin && blockRange. contains ( block)
102
100
}
103
101
104
102
/// Returns true if the inclusive range contains `inst`.
105
103
func inclusiveRangeContains ( _ inst: Instruction ) -> Bool {
106
104
contains ( inst) || insertedInsts. contains ( inst)
107
105
}
108
106
109
- /// Returns true if the range is valid and that's iff the begin instruction
110
- /// dominates all instructions of the range.
111
- var isValid : Bool {
112
- blockRange. isValid &&
113
- // Check if there are any inserted instructions before the begin instruction in its block.
114
- !ReverseInstructionList( first: begin) . dropFirst ( ) . contains { insertedInsts. contains ( $0) }
115
- }
116
-
117
107
/// Returns the end instructions.
118
108
///
119
109
/// Warning: this returns `begin` if no instructions were inserted.
@@ -155,6 +145,10 @@ struct InstructionRange : CustomStringConvertible, NoReflectionChildren {
155
145
}
156
146
}
157
147
148
+ var begin : Instruction ? {
149
+ blockRange. begin. instructions. first ( where: inExclusiveRange. contains)
150
+ }
151
+
158
152
private mutating func insertIntoRange( instructions: ReverseInstructionList ) {
159
153
for inst in instructions {
160
154
if !inExclusiveRange. insert ( inst) {
@@ -164,9 +158,9 @@ struct InstructionRange : CustomStringConvertible, NoReflectionChildren {
164
158
}
165
159
166
160
var description : String {
167
- return ( isValid ? " " : " <invalid> \n " ) +
161
+ return ( blockRange . isValid ? " " : " <invalid> \n " ) +
168
162
"""
169
- begin: \( begin)
163
+ begin: \( begin? . description ?? blockRange . begin . name )
170
164
ends: \( ends. map { $0. description } . joined ( separator: " \n " ) )
171
165
exits: \( exits. map { $0. description } . joined ( separator: " \n " ) )
172
166
interiors: \( interiors. map { $0. description } . joined ( separator: " \n " ) )
0 commit comments