@@ -268,71 +268,13 @@ pub enum Terminator<'tcx> {
268268 func : Operand < ' tcx > ,
269269 /// Arguments the function is called with
270270 args : Vec < Operand < ' tcx > > ,
271- /// The kind of call with associated information
272- kind : CallKind < ' tcx > ,
271+ /// Destination for the return value. If some, the call is converging.
272+ destination : Option < ( Lvalue < ' tcx > , BasicBlock ) > ,
273+ /// Cleanups to be done if the call unwinds.
274+ cleanup : Option < BasicBlock >
273275 } ,
274276}
275277
276- #[ derive( Clone , RustcEncodable , RustcDecodable ) ]
277- pub enum CallKind < ' tcx > {
278- /// Diverging function without associated cleanup
279- Diverging ,
280- /// Diverging function with associated cleanup
281- DivergingCleanup ( BasicBlock ) ,
282- /// Converging function without associated cleanup
283- Converging {
284- /// Destination where the call result is written
285- destination : Lvalue < ' tcx > ,
286- /// Block to branch into on successful return
287- target : BasicBlock ,
288- } ,
289- ConvergingCleanup {
290- /// Destination where the call result is written
291- destination : Lvalue < ' tcx > ,
292- /// First target is branched to on successful return.
293- /// Second block contains the cleanups to do on unwind.
294- targets : ( BasicBlock , BasicBlock )
295- }
296- }
297-
298- impl < ' tcx > CallKind < ' tcx > {
299- pub fn successors ( & self ) -> & [ BasicBlock ] {
300- match * self {
301- CallKind :: Diverging => & [ ] ,
302- CallKind :: DivergingCleanup ( ref b) |
303- CallKind :: Converging { target : ref b, .. } => slice:: ref_slice ( b) ,
304- CallKind :: ConvergingCleanup { ref targets, .. } => targets. as_slice ( ) ,
305- }
306- }
307-
308- pub fn successors_mut ( & mut self ) -> & mut [ BasicBlock ] {
309- match * self {
310- CallKind :: Diverging => & mut [ ] ,
311- CallKind :: DivergingCleanup ( ref mut b) |
312- CallKind :: Converging { target : ref mut b, .. } => slice:: mut_ref_slice ( b) ,
313- CallKind :: ConvergingCleanup { ref mut targets, .. } => targets. as_mut_slice ( ) ,
314- }
315- }
316-
317- pub fn destination ( & self ) -> Option < & Lvalue < ' tcx > > {
318- match * self {
319- CallKind :: Converging { ref destination, .. } |
320- CallKind :: ConvergingCleanup { ref destination, .. } => Some ( destination) ,
321- CallKind :: Diverging |
322- CallKind :: DivergingCleanup ( _) => None
323- }
324- }
325-
326- pub fn destination_mut ( & mut self ) -> Option < & mut Lvalue < ' tcx > > {
327- match * self {
328- CallKind :: Converging { ref mut destination, .. } |
329- CallKind :: ConvergingCleanup { ref mut destination, .. } => Some ( destination) ,
330- CallKind :: Diverging |
331- CallKind :: DivergingCleanup ( _) => None
332- }
333- }
334- }
335-
336278impl < ' tcx > Terminator < ' tcx > {
337279 pub fn successors ( & self ) -> Cow < [ BasicBlock ] > {
338280 use self :: Terminator :: * ;
@@ -343,7 +285,11 @@ impl<'tcx> Terminator<'tcx> {
343285 SwitchInt { targets : ref b, .. } => b[ ..] . into_cow ( ) ,
344286 Resume => ( & [ ] ) . into_cow ( ) ,
345287 Return => ( & [ ] ) . into_cow ( ) ,
346- Call { ref kind, .. } => kind. successors ( ) [ ..] . into_cow ( ) ,
288+ Call { destination : Some ( ( _, t) ) , cleanup : Some ( c) , .. } => vec ! [ t, c] . into_cow ( ) ,
289+ Call { destination : Some ( ( _, ref t) ) , cleanup : None , .. } =>
290+ slice:: ref_slice ( t) . into_cow ( ) ,
291+ Call { destination : None , cleanup : Some ( ref c) , .. } => slice:: ref_slice ( c) . into_cow ( ) ,
292+ Call { destination : None , cleanup : None , .. } => ( & [ ] ) . into_cow ( ) ,
347293 }
348294 }
349295
@@ -358,7 +304,10 @@ impl<'tcx> Terminator<'tcx> {
358304 SwitchInt { targets : ref mut b, .. } => b. iter_mut ( ) . collect ( ) ,
359305 Resume => Vec :: new ( ) ,
360306 Return => Vec :: new ( ) ,
361- Call { ref mut kind, .. } => kind. successors_mut ( ) . iter_mut ( ) . collect ( ) ,
307+ Call { destination : Some ( ( _, ref mut t) ) , cleanup : Some ( ref mut c) , .. } => vec ! [ t, c] ,
308+ Call { destination : Some ( ( _, ref mut t) ) , cleanup : None , .. } => vec ! [ t] ,
309+ Call { destination : None , cleanup : Some ( ref mut c) , .. } => vec ! [ c] ,
310+ Call { destination : None , cleanup : None , .. } => vec ! [ ] ,
362311 }
363312 }
364313}
@@ -425,8 +374,8 @@ impl<'tcx> Terminator<'tcx> {
425374 SwitchInt { discr : ref lv, .. } => write ! ( fmt, "switchInt({:?})" , lv) ,
426375 Return => write ! ( fmt, "return" ) ,
427376 Resume => write ! ( fmt, "resume" ) ,
428- Call { ref kind , ref func , ref args } => {
429- if let Some ( destination) = kind . destination ( ) {
377+ Call { ref func , ref args , ref destination , .. } => {
378+ if let Some ( ( ref destination, _ ) ) = * destination {
430379 try!( write ! ( fmt, "{:?} = " , destination) ) ;
431380 }
432381 try!( write ! ( fmt, "{:?}(" , func) ) ;
@@ -464,16 +413,11 @@ impl<'tcx> Terminator<'tcx> {
464413 . chain ( iter:: once ( String :: from ( "otherwise" ) . into ( ) ) )
465414 . collect ( )
466415 }
467- Call { ref kind, .. } => match * kind {
468- CallKind :: Diverging =>
469- vec ! [ ] ,
470- CallKind :: DivergingCleanup ( ..) =>
471- vec ! [ "unwind" . into_cow( ) ] ,
472- CallKind :: Converging { .. } =>
473- vec ! [ "return" . into_cow( ) ] ,
474- CallKind :: ConvergingCleanup { .. } =>
475- vec ! [ "return" . into_cow( ) , "unwind" . into_cow( ) ] ,
476- } ,
416+ Call { destination : Some ( _) , cleanup : Some ( _) , .. } =>
417+ vec ! [ "return" . into_cow( ) , "unwind" . into_cow( ) ] ,
418+ Call { destination : Some ( _) , cleanup : None , .. } => vec ! [ "return" . into_cow( ) ] ,
419+ Call { destination : None , cleanup : Some ( _) , .. } => vec ! [ "unwind" . into_cow( ) ] ,
420+ Call { destination : None , cleanup : None , .. } => vec ! [ ] ,
477421 }
478422 }
479423}
0 commit comments