@@ -3,7 +3,7 @@ use crate::ty::{
33 AdtDef , ClosureDef , Const , CoroutineDef , GenericArgs , Movability , Region , RigidTy , Ty , TyKind ,
44} ;
55use crate :: { Error , Opaque , Span , Symbol } ;
6- use std:: { io , slice } ;
6+ use std:: io ;
77/// The SMIR representation of a single function.
88#[ derive( Clone , Debug ) ]
99pub struct Body {
@@ -23,6 +23,8 @@ pub struct Body {
2323 pub ( super ) var_debug_info : Vec < VarDebugInfo > ,
2424}
2525
26+ pub type BasicBlockIdx = usize ;
27+
2628impl Body {
2729 /// Constructs a `Body`.
2830 ///
@@ -114,66 +116,64 @@ pub struct Terminator {
114116}
115117
116118impl Terminator {
117- pub fn successors ( & self ) -> Successors < ' _ > {
119+ pub fn successors ( & self ) -> Successors {
118120 self . kind . successors ( )
119121 }
120122}
121123
122- pub type Successors < ' a > = impl Iterator < Item = usize > + ' a ;
124+ pub type Successors = Vec < BasicBlockIdx > ;
123125
124126#[ derive( Clone , Debug , Eq , PartialEq ) ]
125127pub enum TerminatorKind {
126128 Goto {
127- target : usize ,
129+ target : BasicBlockIdx ,
128130 } ,
129131 SwitchInt {
130132 discr : Operand ,
131133 targets : SwitchTargets ,
132- otherwise : usize ,
133134 } ,
134135 Resume ,
135136 Abort ,
136137 Return ,
137138 Unreachable ,
138139 Drop {
139140 place : Place ,
140- target : usize ,
141+ target : BasicBlockIdx ,
141142 unwind : UnwindAction ,
142143 } ,
143144 Call {
144145 func : Operand ,
145146 args : Vec < Operand > ,
146147 destination : Place ,
147- target : Option < usize > ,
148+ target : Option < BasicBlockIdx > ,
148149 unwind : UnwindAction ,
149150 } ,
150151 Assert {
151152 cond : Operand ,
152153 expected : bool ,
153154 msg : AssertMessage ,
154- target : usize ,
155+ target : BasicBlockIdx ,
155156 unwind : UnwindAction ,
156157 } ,
157- CoroutineDrop ,
158158 InlineAsm {
159159 template : String ,
160160 operands : Vec < InlineAsmOperand > ,
161161 options : String ,
162162 line_spans : String ,
163- destination : Option < usize > ,
163+ destination : Option < BasicBlockIdx > ,
164164 unwind : UnwindAction ,
165165 } ,
166166}
167167
168168impl TerminatorKind {
169- pub fn successors ( & self ) -> Successors < ' _ > {
169+ pub fn successors ( & self ) -> Successors {
170170 use self :: TerminatorKind :: * ;
171171 match * self {
172- Call { target : Some ( t) , unwind : UnwindAction :: Cleanup ( ref u) , .. }
173- | Drop { target : t, unwind : UnwindAction :: Cleanup ( ref u) , .. }
174- | Assert { target : t, unwind : UnwindAction :: Cleanup ( ref u) , .. }
175- | InlineAsm { destination : Some ( t) , unwind : UnwindAction :: Cleanup ( ref u) , .. } => {
176- Some ( t ) . into_iter ( ) . chain ( slice :: from_ref ( u ) . into_iter ( ) . copied ( ) )
172+ Call { target : Some ( t) , unwind : UnwindAction :: Cleanup ( u) , .. }
173+ | Drop { target : t, unwind : UnwindAction :: Cleanup ( u) , .. }
174+ | Assert { target : t, unwind : UnwindAction :: Cleanup ( u) , .. }
175+ | InlineAsm { destination : Some ( t) , unwind : UnwindAction :: Cleanup ( u) , .. } => {
176+ vec ! [ t , u ]
177177 }
178178 Goto { target : t }
179179 | Call { target : None , unwind : UnwindAction :: Cleanup ( t) , .. }
@@ -182,21 +182,18 @@ impl TerminatorKind {
182182 | Assert { target : t, unwind : _, .. }
183183 | InlineAsm { destination : None , unwind : UnwindAction :: Cleanup ( t) , .. }
184184 | InlineAsm { destination : Some ( t) , unwind : _, .. } => {
185- Some ( t ) . into_iter ( ) . chain ( ( & [ ] ) . into_iter ( ) . copied ( ) )
185+ vec ! [ t ]
186186 }
187187
188- CoroutineDrop
189- | Return
188+ Return
190189 | Resume
191190 | Abort
192191 | Unreachable
193192 | Call { target : None , unwind : _, .. }
194193 | InlineAsm { destination : None , unwind : _, .. } => {
195- None . into_iter ( ) . chain ( ( & [ ] ) . into_iter ( ) . copied ( ) )
196- }
197- SwitchInt { ref targets, .. } => {
198- None . into_iter ( ) . chain ( targets. targets . iter ( ) . copied ( ) )
194+ vec ! [ ]
199195 }
196+ SwitchInt { ref targets, .. } => targets. all_targets ( ) ,
200197 }
201198 }
202199
@@ -205,7 +202,6 @@ impl TerminatorKind {
205202 TerminatorKind :: Goto { .. }
206203 | TerminatorKind :: Return
207204 | TerminatorKind :: Unreachable
208- | TerminatorKind :: CoroutineDrop
209205 | TerminatorKind :: Resume
210206 | TerminatorKind :: Abort
211207 | TerminatorKind :: SwitchInt { .. } => None ,
@@ -231,7 +227,7 @@ pub enum UnwindAction {
231227 Continue ,
232228 Unreachable ,
233229 Terminate ,
234- Cleanup ( usize ) ,
230+ Cleanup ( BasicBlockIdx ) ,
235231}
236232
237233#[ derive( Clone , Debug , Eq , PartialEq ) ]
@@ -662,10 +658,45 @@ pub struct Constant {
662658 pub literal : Const ,
663659}
664660
661+ /// The possible branch sites of a [TerminatorKind::SwitchInt].
665662#[ derive( Clone , Debug , Eq , PartialEq ) ]
666663pub struct SwitchTargets {
667- pub value : Vec < u128 > ,
668- pub targets : Vec < usize > ,
664+ /// The conditional branches where the first element represents the value that guards this
665+ /// branch, and the second element is the branch target.
666+ branches : Vec < ( u128 , BasicBlockIdx ) > ,
667+ /// The `otherwise` branch which will be taken in case none of the conditional branches are
668+ /// satisfied.
669+ otherwise : BasicBlockIdx ,
670+ }
671+
672+ impl SwitchTargets {
673+ /// All possible targets including the `otherwise` target.
674+ pub fn all_targets ( & self ) -> Successors {
675+ Some ( self . otherwise )
676+ . into_iter ( )
677+ . chain ( self . branches . iter ( ) . map ( |( _, target) | * target) )
678+ . collect ( )
679+ }
680+
681+ /// The `otherwise` branch target.
682+ pub fn otherwise ( & self ) -> BasicBlockIdx {
683+ self . otherwise
684+ }
685+
686+ /// The conditional targets which are only taken if the pattern matches the given value.
687+ pub fn branches ( & self ) -> impl Iterator < Item = ( u128 , BasicBlockIdx ) > + ' _ {
688+ self . branches . iter ( ) . copied ( )
689+ }
690+
691+ /// The number of targets including `otherwise`.
692+ pub fn len ( & self ) -> usize {
693+ self . branches . len ( ) + 1
694+ }
695+
696+ /// Create a new SwitchTargets from the given branches and `otherwise` target.
697+ pub fn new ( branches : Vec < ( u128 , BasicBlockIdx ) > , otherwise : BasicBlockIdx ) -> SwitchTargets {
698+ SwitchTargets { branches, otherwise }
699+ }
669700}
670701
671702#[ derive( Copy , Clone , Debug , Eq , PartialEq ) ]
0 commit comments