@@ -5,7 +5,8 @@ use rustc_ast as ast;
55use rustc_ast:: { InlineAsmOptions , InlineAsmTemplatePiece } ;
66use rustc_hir:: lang_items:: LangItem ;
77use rustc_middle:: mir:: {
8- self , AssertKind , BasicBlock , InlineAsmMacro , SwitchTargets , UnwindTerminateReason ,
8+ self , AssertKind , BasicBlock , InlineAsmMacro , SwitchAction , SwitchTargets ,
9+ UnwindTerminateReason ,
910} ;
1011use rustc_middle:: ty:: layout:: { HasTyCtxt , LayoutOf , ValidityRequirement } ;
1112use rustc_middle:: ty:: print:: { with_no_trimmed_paths, with_no_visible_paths} ;
@@ -96,6 +97,17 @@ impl<'a, 'tcx> TerminatorCodegenHelper<'tcx> {
9697 }
9798 }
9899
100+ fn llbb_with_cleanup_from_switch_action < Bx : BuilderMethods < ' a , ' tcx > > (
101+ & self ,
102+ fx : & mut FunctionCx < ' a , ' tcx , Bx > ,
103+ target : mir:: SwitchAction ,
104+ ) -> Bx :: BasicBlock {
105+ match target {
106+ mir:: SwitchAction :: Unreachable => fx. unreachable_block ( ) ,
107+ mir:: SwitchAction :: Goto ( bb) => self . llbb_with_cleanup ( fx, bb) ,
108+ }
109+ }
110+
99111 fn llbb_characteristics < Bx : BuilderMethods < ' a , ' tcx > > (
100112 & self ,
101113 fx : & mut FunctionCx < ' a , ' tcx , Bx > ,
@@ -368,7 +380,7 @@ impl<'a, 'tcx, Bx: BuilderMethods<'a, 'tcx>> FunctionCx<'a, 'tcx, Bx> {
368380 // If our discriminant is a constant we can branch directly
369381 if let Some ( const_discr) = bx. const_to_opt_u128 ( discr_value, false ) {
370382 let target = targets. target_for_value ( const_discr) ;
371- bx. br ( helper. llbb_with_cleanup ( self , target) ) ;
383+ bx. br ( helper. llbb_with_cleanup_from_switch_action ( self , target) ) ;
372384 return ;
373385 } ;
374386
@@ -379,9 +391,12 @@ impl<'a, 'tcx, Bx: BuilderMethods<'a, 'tcx>> FunctionCx<'a, 'tcx, Bx> {
379391 let ( test_value, target) = target_iter. next ( ) . unwrap ( ) ;
380392 let otherwise = targets. otherwise ( ) ;
381393 let lltarget = helper. llbb_with_cleanup ( self , target) ;
382- let llotherwise = helper. llbb_with_cleanup ( self , otherwise) ;
394+ let llotherwise = helper. llbb_with_cleanup_from_switch_action ( self , otherwise) ;
383395 let target_cold = self . cold_blocks [ target] ;
384- let otherwise_cold = self . cold_blocks [ otherwise] ;
396+ let otherwise_cold = match otherwise {
397+ SwitchAction :: Goto ( otherwise) => self . cold_blocks [ otherwise] ,
398+ SwitchAction :: Unreachable => true ,
399+ } ;
385400 // If `target_cold == otherwise_cold`, the branches have the same weight
386401 // so there is no expectation. If they differ, the `target` branch is expected
387402 // when the `otherwise` branch is cold.
@@ -406,7 +421,7 @@ impl<'a, 'tcx, Bx: BuilderMethods<'a, 'tcx>> FunctionCx<'a, 'tcx, Bx> {
406421 }
407422 } else if self . cx . sess ( ) . opts . optimize == OptLevel :: No
408423 && target_iter. len ( ) == 2
409- && self . mir [ targets. otherwise ( ) ] . is_empty_unreachable ( )
424+ && self . mir . basic_blocks . is_empty_unreachable ( targets. otherwise ( ) )
410425 {
411426 // In unoptimized builds, if there are two normal targets and the `otherwise` target is
412427 // an unreachable BB, emit `br` instead of `switch`. This leaves behind the unreachable
@@ -431,7 +446,7 @@ impl<'a, 'tcx, Bx: BuilderMethods<'a, 'tcx>> FunctionCx<'a, 'tcx, Bx> {
431446 } else {
432447 bx. switch (
433448 discr_value,
434- helper. llbb_with_cleanup ( self , targets. otherwise ( ) ) ,
449+ helper. llbb_with_cleanup_from_switch_action ( self , targets. otherwise ( ) ) ,
435450 target_iter. map ( |( value, target) | ( value, helper. llbb_with_cleanup ( self , target) ) ) ,
436451 ) ;
437452 }
@@ -1648,11 +1663,10 @@ impl<'a, 'tcx, Bx: BuilderMethods<'a, 'tcx>> FunctionCx<'a, 'tcx, Bx> {
16481663 }
16491664
16501665 fn unreachable_block ( & mut self ) -> Bx :: BasicBlock {
1651- self . unreachable_block . unwrap_or_else ( || {
1666+ * self . unreachable_block . get_or_insert_with ( || {
16521667 let llbb = Bx :: append_block ( self . cx , self . llfn , "unreachable" ) ;
16531668 let mut bx = Bx :: build ( self . cx , llbb) ;
16541669 bx. unreachable ( ) ;
1655- self . unreachable_block = Some ( llbb) ;
16561670 llbb
16571671 } )
16581672 }
0 commit comments