@@ -33,8 +33,8 @@ use crate::mir::interpret::{AllocRange, Scalar};
33
33
use crate :: ty:: codec:: { TyDecoder , TyEncoder } ;
34
34
use crate :: ty:: print:: { FmtPrinter , Printer , pretty_print_const, with_no_trimmed_paths} ;
35
35
use crate :: ty:: {
36
- self , GenericArg , GenericArgsRef , Instance , InstanceKind , List , Ty , TyCtxt , TypeVisitableExt ,
37
- TypingEnv , UserTypeAnnotationIndex ,
36
+ self , GenericArg , GenericArgsRef , InstanceKind , List , Ty , TyCtxt , TypeVisitableExt , TypingEnv ,
37
+ UserTypeAnnotationIndex ,
38
38
} ;
39
39
40
40
mod basic_blocks;
@@ -375,6 +375,8 @@ pub struct Body<'tcx> {
375
375
#[ type_foldable( identity) ]
376
376
#[ type_visitable( ignore) ]
377
377
pub function_coverage_info : Option < Box < coverage:: FunctionCoverageInfo > > ,
378
+
379
+ pub is_codegen_mir : bool ,
378
380
}
379
381
380
382
impl < ' tcx > Body < ' tcx > {
@@ -418,6 +420,7 @@ impl<'tcx> Body<'tcx> {
418
420
tainted_by_errors,
419
421
coverage_info_hi : None ,
420
422
function_coverage_info : None ,
423
+ is_codegen_mir : false ,
421
424
} ;
422
425
body. is_polymorphic = body. has_non_region_param ( ) ;
423
426
body
@@ -449,6 +452,7 @@ impl<'tcx> Body<'tcx> {
449
452
tainted_by_errors : None ,
450
453
coverage_info_hi : None ,
451
454
function_coverage_info : None ,
455
+ is_codegen_mir : false ,
452
456
} ;
453
457
body. is_polymorphic = body. has_non_region_param ( ) ;
454
458
body
@@ -633,74 +637,6 @@ impl<'tcx> Body<'tcx> {
633
637
self . injection_phase . is_some ( )
634
638
}
635
639
636
- /// If this basic block ends with a [`TerminatorKind::SwitchInt`] for which we can evaluate the
637
- /// discriminant in monomorphization, we return the discriminant bits and the
638
- /// [`SwitchTargets`], just so the caller doesn't also have to match on the terminator.
639
- fn try_const_mono_switchint < ' a > (
640
- tcx : TyCtxt < ' tcx > ,
641
- instance : Instance < ' tcx > ,
642
- block : & ' a BasicBlockData < ' tcx > ,
643
- ) -> Option < ( u128 , & ' a SwitchTargets ) > {
644
- // There are two places here we need to evaluate a constant.
645
- let eval_mono_const = |constant : & ConstOperand < ' tcx > | {
646
- // FIXME(#132279): what is this, why are we using an empty environment here.
647
- let typing_env = ty:: TypingEnv :: fully_monomorphized ( ) ;
648
- let mono_literal = instance. instantiate_mir_and_normalize_erasing_regions (
649
- tcx,
650
- typing_env,
651
- crate :: ty:: EarlyBinder :: bind ( constant. const_ ) ,
652
- ) ;
653
- mono_literal. try_eval_bits ( tcx, typing_env)
654
- } ;
655
-
656
- let TerminatorKind :: SwitchInt { discr, targets } = & block. terminator ( ) . kind else {
657
- return None ;
658
- } ;
659
-
660
- // If this is a SwitchInt(const _), then we can just evaluate the constant and return.
661
- let discr = match discr {
662
- Operand :: Constant ( constant) => {
663
- let bits = eval_mono_const ( constant) ?;
664
- return Some ( ( bits, targets) ) ;
665
- }
666
- Operand :: Move ( place) | Operand :: Copy ( place) => place,
667
- } ;
668
-
669
- // MIR for `if false` actually looks like this:
670
- // _1 = const _
671
- // SwitchInt(_1)
672
- //
673
- // And MIR for if intrinsics::ub_checks() looks like this:
674
- // _1 = UbChecks()
675
- // SwitchInt(_1)
676
- //
677
- // So we're going to try to recognize this pattern.
678
- //
679
- // If we have a SwitchInt on a non-const place, we find the most recent statement that
680
- // isn't a storage marker. If that statement is an assignment of a const to our
681
- // discriminant place, we evaluate and return the const, as if we've const-propagated it
682
- // into the SwitchInt.
683
-
684
- let last_stmt = block. statements . iter ( ) . rev ( ) . find ( |stmt| {
685
- !matches ! ( stmt. kind, StatementKind :: StorageDead ( _) | StatementKind :: StorageLive ( _) )
686
- } ) ?;
687
-
688
- let ( place, rvalue) = last_stmt. kind . as_assign ( ) ?;
689
-
690
- if discr != place {
691
- return None ;
692
- }
693
-
694
- match rvalue {
695
- Rvalue :: NullaryOp ( NullOp :: UbChecks , _) => Some ( ( tcx. sess . ub_checks ( ) as u128 , targets) ) ,
696
- Rvalue :: Use ( Operand :: Constant ( constant) ) => {
697
- let bits = eval_mono_const ( constant) ?;
698
- Some ( ( bits, targets) )
699
- }
700
- _ => None ,
701
- }
702
- }
703
-
704
640
/// For a `Location` in this scope, determine what the "caller location" at that point is. This
705
641
/// is interesting because of inlining: the `#[track_caller]` attribute of inlined functions
706
642
/// must be honored. Falls back to the `tracked_caller` value for `#[track_caller]` functions,
@@ -1391,19 +1327,6 @@ impl<'tcx> BasicBlockData<'tcx> {
1391
1327
pub fn is_empty_unreachable ( & self ) -> bool {
1392
1328
self . statements . is_empty ( ) && matches ! ( self . terminator( ) . kind, TerminatorKind :: Unreachable )
1393
1329
}
1394
-
1395
- /// Like [`Terminator::successors`] but tries to use information available from the [`Instance`]
1396
- /// to skip successors like the `false` side of an `if const {`.
1397
- ///
1398
- /// This is used to implement [`traversal::mono_reachable`] and
1399
- /// [`traversal::mono_reachable_reverse_postorder`].
1400
- pub fn mono_successors ( & self , tcx : TyCtxt < ' tcx > , instance : Instance < ' tcx > ) -> Successors < ' _ > {
1401
- if let Some ( ( bits, targets) ) = Body :: try_const_mono_switchint ( tcx, instance, self ) {
1402
- targets. successors_for_value ( bits)
1403
- } else {
1404
- self . terminator ( ) . successors ( )
1405
- }
1406
- }
1407
1330
}
1408
1331
1409
1332
///////////////////////////////////////////////////////////////////////////
0 commit comments