@@ -3,7 +3,7 @@ use crate::ty::{
3
3
AdtDef , ClosureDef , Const , CoroutineDef , GenericArgs , Movability , Region , RigidTy , Ty , TyKind ,
4
4
} ;
5
5
use crate :: { Error , Opaque , Span , Symbol } ;
6
- use std:: { io , slice } ;
6
+ use std:: io ;
7
7
/// The SMIR representation of a single function.
8
8
#[ derive( Clone , Debug ) ]
9
9
pub struct Body {
@@ -23,6 +23,8 @@ pub struct Body {
23
23
pub ( super ) var_debug_info : Vec < VarDebugInfo > ,
24
24
}
25
25
26
+ pub type BasicBlockIdx = usize ;
27
+
26
28
impl Body {
27
29
/// Constructs a `Body`.
28
30
///
@@ -114,66 +116,64 @@ pub struct Terminator {
114
116
}
115
117
116
118
impl Terminator {
117
- pub fn successors ( & self ) -> Successors < ' _ > {
119
+ pub fn successors ( & self ) -> Successors {
118
120
self . kind . successors ( )
119
121
}
120
122
}
121
123
122
- pub type Successors < ' a > = impl Iterator < Item = usize > + ' a ;
124
+ pub type Successors = Vec < BasicBlockIdx > ;
123
125
124
126
#[ derive( Clone , Debug , Eq , PartialEq ) ]
125
127
pub enum TerminatorKind {
126
128
Goto {
127
- target : usize ,
129
+ target : BasicBlockIdx ,
128
130
} ,
129
131
SwitchInt {
130
132
discr : Operand ,
131
133
targets : SwitchTargets ,
132
- otherwise : usize ,
133
134
} ,
134
135
Resume ,
135
136
Abort ,
136
137
Return ,
137
138
Unreachable ,
138
139
Drop {
139
140
place : Place ,
140
- target : usize ,
141
+ target : BasicBlockIdx ,
141
142
unwind : UnwindAction ,
142
143
} ,
143
144
Call {
144
145
func : Operand ,
145
146
args : Vec < Operand > ,
146
147
destination : Place ,
147
- target : Option < usize > ,
148
+ target : Option < BasicBlockIdx > ,
148
149
unwind : UnwindAction ,
149
150
} ,
150
151
Assert {
151
152
cond : Operand ,
152
153
expected : bool ,
153
154
msg : AssertMessage ,
154
- target : usize ,
155
+ target : BasicBlockIdx ,
155
156
unwind : UnwindAction ,
156
157
} ,
157
- CoroutineDrop ,
158
158
InlineAsm {
159
159
template : String ,
160
160
operands : Vec < InlineAsmOperand > ,
161
161
options : String ,
162
162
line_spans : String ,
163
- destination : Option < usize > ,
163
+ destination : Option < BasicBlockIdx > ,
164
164
unwind : UnwindAction ,
165
165
} ,
166
166
}
167
167
168
168
impl TerminatorKind {
169
- pub fn successors ( & self ) -> Successors < ' _ > {
169
+ pub fn successors ( & self ) -> Successors {
170
170
use self :: TerminatorKind :: * ;
171
171
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 ]
177
177
}
178
178
Goto { target : t }
179
179
| Call { target : None , unwind : UnwindAction :: Cleanup ( t) , .. }
@@ -182,21 +182,18 @@ impl TerminatorKind {
182
182
| Assert { target : t, unwind : _, .. }
183
183
| InlineAsm { destination : None , unwind : UnwindAction :: Cleanup ( t) , .. }
184
184
| InlineAsm { destination : Some ( t) , unwind : _, .. } => {
185
- Some ( t ) . into_iter ( ) . chain ( ( & [ ] ) . into_iter ( ) . copied ( ) )
185
+ vec ! [ t ]
186
186
}
187
187
188
- CoroutineDrop
189
- | Return
188
+ Return
190
189
| Resume
191
190
| Abort
192
191
| Unreachable
193
192
| Call { target : None , unwind : _, .. }
194
193
| 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 ! [ ]
199
195
}
196
+ SwitchInt { ref targets, .. } => targets. all_targets ( ) ,
200
197
}
201
198
}
202
199
@@ -205,7 +202,6 @@ impl TerminatorKind {
205
202
TerminatorKind :: Goto { .. }
206
203
| TerminatorKind :: Return
207
204
| TerminatorKind :: Unreachable
208
- | TerminatorKind :: CoroutineDrop
209
205
| TerminatorKind :: Resume
210
206
| TerminatorKind :: Abort
211
207
| TerminatorKind :: SwitchInt { .. } => None ,
@@ -231,7 +227,7 @@ pub enum UnwindAction {
231
227
Continue ,
232
228
Unreachable ,
233
229
Terminate ,
234
- Cleanup ( usize ) ,
230
+ Cleanup ( BasicBlockIdx ) ,
235
231
}
236
232
237
233
#[ derive( Clone , Debug , Eq , PartialEq ) ]
@@ -662,10 +658,42 @@ pub struct Constant {
662
658
pub literal : Const ,
663
659
}
664
660
661
+ /// The possible branch sites of a [TerminatorKind::SwitchInt].
665
662
#[ derive( Clone , Debug , Eq , PartialEq ) ]
666
663
pub 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
+ self . branches . iter ( ) . map ( |( _, target) | * target) . chain ( Some ( self . otherwise ) ) . collect ( )
676
+ }
677
+
678
+ /// The `otherwise` branch target.
679
+ pub fn otherwise ( & self ) -> BasicBlockIdx {
680
+ self . otherwise
681
+ }
682
+
683
+ /// The conditional targets which are only taken if the pattern matches the given value.
684
+ pub fn branches ( & self ) -> impl Iterator < Item = ( u128 , BasicBlockIdx ) > + ' _ {
685
+ self . branches . iter ( ) . copied ( )
686
+ }
687
+
688
+ /// The number of targets including `otherwise`.
689
+ pub fn len ( & self ) -> usize {
690
+ self . branches . len ( ) + 1
691
+ }
692
+
693
+ /// Create a new SwitchTargets from the given branches and `otherwise` target.
694
+ pub fn new ( branches : Vec < ( u128 , BasicBlockIdx ) > , otherwise : BasicBlockIdx ) -> SwitchTargets {
695
+ SwitchTargets { branches, otherwise }
696
+ }
669
697
}
670
698
671
699
#[ derive( Copy , Clone , Debug , Eq , PartialEq ) ]
0 commit comments