@@ -40,9 +40,6 @@ import SIL
4040/// destruct this data structure, e.g. in a `defer {}` block.
4141struct InstructionRange : CustomStringConvertible , NoReflectionChildren {
4242
43- /// The dominating begin instruction.
44- let begin : Instruction
45-
4643 /// The underlying block range.
4744 private( set) var blockRange : BasicBlockRange
4845
@@ -52,10 +49,7 @@ struct InstructionRange : CustomStringConvertible, NoReflectionChildren {
5249 private var inExclusiveRange : InstructionSet
5350
5451 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)
5953 self . inExclusiveRange. insert ( beginInst)
6054 }
6155
@@ -65,28 +59,32 @@ struct InstructionRange : CustomStringConvertible, NoReflectionChildren {
6559 }
6660
6761 init ( for value: Value , _ context: some Context ) {
68- self = InstructionRange ( begin: InstructionRange . beginningInstruction ( for: value) , context)
62+ if let inst = value. definingInstruction {
63+ self = InstructionRange ( begin: inst, context)
64+ } else if let arg = value as? Argument {
65+ self = InstructionRange ( beginBlock: arg. parentBlock, context)
66+ } else {
67+ fatalError ( " cannot build an instruction range for \( value) " )
68+ }
6969 }
7070
71- static func beginningInstruction( for value: Value ) -> Instruction {
72- if let def = value. definingInstructionOrTerminator {
73- return def
74- }
75- assert ( Phi ( value) != nil || value is FunctionArgument )
76- return value. parentBlock. instructions. first!
71+ private init ( beginBlock: BasicBlock , _ context: some Context ) {
72+ self . blockRange = BasicBlockRange ( begin: beginBlock, context)
73+ self . insertedInsts = InstructionSet ( context)
74+ self . inExclusiveRange = InstructionSet ( context)
7775 }
7876
7977 /// Insert a potential end instruction.
8078 mutating func insert( _ inst: Instruction ) {
8179 insertedInsts. insert ( inst)
8280 insertIntoRange ( instructions: ReverseInstructionList ( first: inst. previous) )
8381 blockRange. insert ( inst. parentBlock)
84- if inst. parentBlock != begin . parentBlock {
82+ if inst. parentBlock != blockRange . begin {
8583 // The first time an instruction is inserted in another block than the begin-block we need to insert
8684 // instructions from the begin instruction to the end of the begin block.
8785 // For subsequent insertions this is a no-op: `insertIntoRange` will return immediately because those
8886 // instruction are already inserted.
89- insertIntoRange ( instructions: begin . parentBlock . instructions. reversed ( ) )
87+ insertIntoRange ( instructions: blockRange . begin . instructions. reversed ( ) )
9088 }
9189 }
9290
@@ -103,22 +101,14 @@ struct InstructionRange : CustomStringConvertible, NoReflectionChildren {
103101 return true
104102 }
105103 let block = inst. parentBlock
106- return block != begin . parentBlock && blockRange. contains ( block)
104+ return block != blockRange . begin && blockRange. contains ( block)
107105 }
108106
109107 /// Returns true if the inclusive range contains `inst`.
110108 func inclusiveRangeContains ( _ inst: Instruction ) -> Bool {
111109 contains ( inst) || insertedInsts. contains ( inst)
112110 }
113111
114- /// Returns true if the range is valid and that's iff the begin instruction
115- /// dominates all instructions of the range.
116- var isValid : Bool {
117- blockRange. isValid &&
118- // Check if there are any inserted instructions before the begin instruction in its block.
119- !ReverseInstructionList( first: begin) . dropFirst ( ) . contains { insertedInsts. contains ( $0) }
120- }
121-
122112 /// Returns the end instructions.
123113 ///
124114 /// Warning: this returns `begin` if no instructions were inserted.
@@ -160,6 +150,10 @@ struct InstructionRange : CustomStringConvertible, NoReflectionChildren {
160150 }
161151 }
162152
153+ var begin : Instruction ? {
154+ blockRange. begin. instructions. first ( where: inExclusiveRange. contains)
155+ }
156+
163157 private mutating func insertIntoRange( instructions: ReverseInstructionList ) {
164158 for inst in instructions {
165159 if !inExclusiveRange. insert ( inst) {
@@ -169,9 +163,9 @@ struct InstructionRange : CustomStringConvertible, NoReflectionChildren {
169163 }
170164
171165 var description : String {
172- return ( isValid ? " " : " <invalid> \n " ) +
166+ return ( blockRange . isValid ? " " : " <invalid> \n " ) +
173167 """
174- begin: \( begin)
168+ begin: \( begin? . description ?? blockRange . begin . name )
175169 ends: \( ends. map { $0. description } . joined ( separator: " \n " ) )
176170 exits: \( exits. map { $0. description } . joined ( separator: " \n " ) )
177171 interiors: \( interiors. map { $0. description } . joined ( separator: " \n " ) )
0 commit comments