Skip to content

Commit 03bb5e0

Browse files
committed
Do less work in codegen now that the MIR is simplified
1 parent 0d804b9 commit 03bb5e0

File tree

2 files changed

+20
-20
lines changed

2 files changed

+20
-20
lines changed

compiler/rustc_codegen_ssa/src/mir/block.rs

+14-5
Original file line numberDiff line numberDiff line change
@@ -363,15 +363,24 @@ impl<'a, 'tcx, Bx: BuilderMethods<'a, 'tcx>> FunctionCx<'a, 'tcx, Bx> {
363363
discr: &mir::Operand<'tcx>,
364364
targets: &SwitchTargets,
365365
) {
366-
let discr = self.codegen_operand(bx, discr);
367-
let discr_value = discr.immediate();
368-
let switch_ty = discr.layout.ty;
369366
// If our discriminant is a constant we can branch directly
370-
if let Some(const_discr) = bx.const_to_opt_u128(discr_value, false) {
367+
if let Some(const_op) = discr.constant() {
368+
let const_value = self.eval_mir_constant(const_op);
369+
let Some(const_discr) = const_value.try_to_bits_for_ty(
370+
self.cx.tcx(),
371+
ty::ParamEnv::reveal_all(),
372+
const_op.ty(),
373+
) else {
374+
bug!("Failed to evaluate constant {discr:?} for SwitchInt terminator")
375+
};
371376
let target = targets.target_for_value(const_discr);
372377
bx.br(helper.llbb_with_cleanup(self, target));
373378
return;
374-
};
379+
}
380+
381+
let discr = self.codegen_operand(bx, discr);
382+
let discr_value = discr.immediate();
383+
let switch_ty = discr.layout.ty;
375384

376385
let mut target_iter = targets.iter();
377386
if target_iter.len() == 1 {

compiler/rustc_middle/src/mir/mod.rs

+6-15
Original file line numberDiff line numberDiff line change
@@ -711,6 +711,7 @@ impl<'tcx> Body<'tcx> {
711711
};
712712

713713
// If this is a SwitchInt(const _), then we can just evaluate the constant and return.
714+
// (The `SwitchConst` transform pass tries to ensure this.)
714715
let discr = match discr {
715716
Operand::Constant(constant) => {
716717
let bits = eval_mono_const(constant)?;
@@ -719,24 +720,18 @@ impl<'tcx> Body<'tcx> {
719720
Operand::Move(place) | Operand::Copy(place) => place,
720721
};
721722

722-
// MIR for `if false` actually looks like this:
723-
// _1 = const _
724-
// SwitchInt(_1)
725-
//
726723
// And MIR for if intrinsics::ub_checks() looks like this:
727724
// _1 = UbChecks()
728725
// SwitchInt(_1)
729726
//
730727
// So we're going to try to recognize this pattern.
731728
//
732-
// If we have a SwitchInt on a non-const place, we find the most recent statement that
733-
// isn't a storage marker. If that statement is an assignment of a const to our
734-
// discriminant place, we evaluate and return the const, as if we've const-propagated it
735-
// into the SwitchInt.
729+
// If we have a SwitchInt on a non-const place, we look at the last statement
730+
// in the block. If that statement is an assignment of UbChecks to our
731+
// discriminant place, we evaluate its value, as if we've
732+
// const-propagated it into the SwitchInt.
736733

737-
let last_stmt = block.statements.iter().rev().find(|stmt| {
738-
!matches!(stmt.kind, StatementKind::StorageDead(_) | StatementKind::StorageLive(_))
739-
})?;
734+
let last_stmt = block.statements.last()?;
740735

741736
let (place, rvalue) = last_stmt.kind.as_assign()?;
742737

@@ -746,10 +741,6 @@ impl<'tcx> Body<'tcx> {
746741

747742
match rvalue {
748743
Rvalue::NullaryOp(NullOp::UbChecks, _) => Some((tcx.sess.ub_checks() as u128, targets)),
749-
Rvalue::Use(Operand::Constant(constant)) => {
750-
let bits = eval_mono_const(constant)?;
751-
Some((bits, targets))
752-
}
753744
_ => None,
754745
}
755746
}

0 commit comments

Comments
 (0)