@@ -95,6 +95,17 @@ impl<'a, 'tcx> TerminatorCodegenHelper<'tcx> {
95
95
}
96
96
}
97
97
98
+ fn llbb_with_cleanup_from_switch_action < Bx : BuilderMethods < ' a , ' tcx > > (
99
+ & self ,
100
+ fx : & mut FunctionCx < ' a , ' tcx , Bx > ,
101
+ target : mir:: SwitchAction ,
102
+ ) -> Bx :: BasicBlock {
103
+ match target {
104
+ mir:: SwitchAction :: Unreachable => fx. unreachable_block ( ) ,
105
+ mir:: SwitchAction :: Goto ( bb) => self . llbb_with_cleanup ( fx, bb) ,
106
+ }
107
+ }
108
+
98
109
fn llbb_characteristics < Bx : BuilderMethods < ' a , ' tcx > > (
99
110
& self ,
100
111
fx : & mut FunctionCx < ' a , ' tcx , Bx > ,
@@ -367,7 +378,7 @@ impl<'a, 'tcx, Bx: BuilderMethods<'a, 'tcx>> FunctionCx<'a, 'tcx, Bx> {
367
378
// If our discriminant is a constant we can branch directly
368
379
if let Some ( const_discr) = bx. const_to_opt_u128 ( discr_value, false ) {
369
380
let target = targets. target_for_value ( const_discr) ;
370
- bx. br ( helper. llbb_with_cleanup ( self , target) ) ;
381
+ bx. br ( helper. llbb_with_cleanup_from_switch_action ( self , target) ) ;
371
382
return ;
372
383
} ;
373
384
@@ -377,7 +388,7 @@ impl<'a, 'tcx, Bx: BuilderMethods<'a, 'tcx>> FunctionCx<'a, 'tcx, Bx> {
377
388
// `switch`.
378
389
let ( test_value, target) = target_iter. next ( ) . unwrap ( ) ;
379
390
let lltrue = helper. llbb_with_cleanup ( self , target) ;
380
- let llfalse = helper. llbb_with_cleanup ( self , targets. otherwise ( ) ) ;
391
+ let llfalse = helper. llbb_with_cleanup_from_switch_action ( self , targets. otherwise ( ) ) ;
381
392
if switch_ty == bx. tcx ( ) . types . bool {
382
393
// Don't generate trivial icmps when switching on bool.
383
394
match test_value {
@@ -393,7 +404,7 @@ impl<'a, 'tcx, Bx: BuilderMethods<'a, 'tcx>> FunctionCx<'a, 'tcx, Bx> {
393
404
}
394
405
} else if self . cx . sess ( ) . opts . optimize == OptLevel :: No
395
406
&& target_iter. len ( ) == 2
396
- && self . mir [ targets. otherwise ( ) ] . is_empty_unreachable ( )
407
+ && self . mir . basic_blocks . is_empty_unreachable ( targets. otherwise ( ) )
397
408
{
398
409
// In unoptimized builds, if there are two normal targets and the `otherwise` target is
399
410
// an unreachable BB, emit `br` instead of `switch`. This leaves behind the unreachable
@@ -418,7 +429,7 @@ impl<'a, 'tcx, Bx: BuilderMethods<'a, 'tcx>> FunctionCx<'a, 'tcx, Bx> {
418
429
} else {
419
430
bx. switch (
420
431
discr_value,
421
- helper. llbb_with_cleanup ( self , targets. otherwise ( ) ) ,
432
+ helper. llbb_with_cleanup_from_switch_action ( self , targets. otherwise ( ) ) ,
422
433
target_iter. map ( |( value, target) | ( value, helper. llbb_with_cleanup ( self , target) ) ) ,
423
434
) ;
424
435
}
@@ -1644,11 +1655,10 @@ impl<'a, 'tcx, Bx: BuilderMethods<'a, 'tcx>> FunctionCx<'a, 'tcx, Bx> {
1644
1655
}
1645
1656
1646
1657
fn unreachable_block ( & mut self ) -> Bx :: BasicBlock {
1647
- self . unreachable_block . unwrap_or_else ( || {
1658
+ * self . unreachable_block . get_or_insert_with ( || {
1648
1659
let llbb = Bx :: append_block ( self . cx , self . llfn , "unreachable" ) ;
1649
1660
let mut bx = Bx :: build ( self . cx , llbb) ;
1650
1661
bx. unreachable ( ) ;
1651
- self . unreachable_block = Some ( llbb) ;
1652
1662
llbb
1653
1663
} )
1654
1664
}
0 commit comments