Skip to content

Commit 2fb9d27

Browse files
committed
Do less work in codegen now that the MIR is simplified
1 parent b57b2bb commit 2fb9d27

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
@@ -361,15 +361,24 @@ impl<'a, 'tcx, Bx: BuilderMethods<'a, 'tcx>> FunctionCx<'a, 'tcx, Bx> {
361361
discr: &mir::Operand<'tcx>,
362362
targets: &SwitchTargets,
363363
) {
364-
let discr = self.codegen_operand(bx, discr);
365-
let discr_value = discr.immediate();
366-
let switch_ty = discr.layout.ty;
367364
// If our discriminant is a constant we can branch directly
368-
if let Some(const_discr) = bx.const_to_opt_u128(discr_value, false) {
365+
if let Some(const_op) = discr.constant() {
366+
let const_value = self.eval_mir_constant(const_op);
367+
let Some(const_discr) = const_value.try_to_bits_for_ty(
368+
self.cx.tcx(),
369+
ty::ParamEnv::reveal_all(),
370+
const_op.ty(),
371+
) else {
372+
bug!("Failed to evaluate constant {discr:?} for SwitchInt terminator")
373+
};
369374
let target = targets.target_for_value(const_discr);
370375
bx.br(helper.llbb_with_cleanup(self, target));
371376
return;
372-
};
377+
}
378+
379+
let discr = self.codegen_operand(bx, discr);
380+
let discr_value = discr.immediate();
381+
let switch_ty = discr.layout.ty;
373382

374383
let mut target_iter = targets.iter();
375384
if target_iter.len() == 1 {

compiler/rustc_middle/src/mir/mod.rs

+6-15
Original file line numberDiff line numberDiff line change
@@ -765,6 +765,7 @@ impl<'tcx> Body<'tcx> {
765765
};
766766

767767
// If this is a SwitchInt(const _), then we can just evaluate the constant and return.
768+
// (The `SwitchConst` transform pass tries to ensure this.)
768769
let discr = match discr {
769770
Operand::Constant(constant) => {
770771
let bits = eval_mono_const(constant);
@@ -773,24 +774,18 @@ impl<'tcx> Body<'tcx> {
773774
Operand::Move(place) | Operand::Copy(place) => place,
774775
};
775776

776-
// MIR for `if false` actually looks like this:
777-
// _1 = const _
778-
// SwitchInt(_1)
779-
//
780777
// And MIR for if intrinsics::debug_assertions() looks like this:
781778
// _1 = cfg!(debug_assertions)
782779
// SwitchInt(_1)
783780
//
784781
// So we're going to try to recognize this pattern.
785782
//
786-
// If we have a SwitchInt on a non-const place, we find the most recent statement that
787-
// isn't a storage marker. If that statement is an assignment of a const to our
788-
// discriminant place, we evaluate and return the const, as if we've const-propagated it
789-
// into the SwitchInt.
783+
// If we have a SwitchInt on a non-const place, we look at the last statement
784+
// in the block. If that statement is an assignment of UbChecks to our
785+
// discriminant place, we evaluate its value, as if we've
786+
// const-propagated it into the SwitchInt.
790787

791-
let last_stmt = block.statements.iter().rev().find(|stmt| {
792-
!matches!(stmt.kind, StatementKind::StorageDead(_) | StatementKind::StorageLive(_))
793-
})?;
788+
let last_stmt = block.statements.last()?;
794789

795790
let (place, rvalue) = last_stmt.kind.as_assign()?;
796791

@@ -802,10 +797,6 @@ impl<'tcx> Body<'tcx> {
802797
Rvalue::NullaryOp(NullOp::UbChecks, _) => {
803798
Some((tcx.sess.opts.debug_assertions as u128, targets))
804799
}
805-
Rvalue::Use(Operand::Constant(constant)) => {
806-
let bits = eval_mono_const(constant);
807-
Some((bits, targets))
808-
}
809800
_ => None,
810801
}
811802
}

0 commit comments

Comments
 (0)