1 //! A pass that simplifies branches when their condition is known.
3 use crate::transform
::MirPass
;
4 use rustc_middle
::mir
::*;
5 use rustc_middle
::ty
::TyCtxt
;
9 pub struct SimplifyBranches
{
13 impl SimplifyBranches
{
14 pub fn new(label
: &str) -> Self {
15 SimplifyBranches { label: format!("SimplifyBranches-{}
", label) }
19 impl<'tcx> MirPass<'tcx> for SimplifyBranches {
20 fn name(&self) -> Cow<'_, str> {
21 Cow::Borrowed(&self.label)
24 fn run_pass(&self, tcx: TyCtxt<'tcx>, body: &mut Body<'tcx>) {
25 let param_env = tcx.param_env(body.source.def_id());
26 for block in body.basic_blocks_mut() {
27 let terminator = block.terminator_mut();
28 terminator.kind = match terminator.kind {
29 TerminatorKind::SwitchInt {
30 discr: Operand::Constant(ref c),
35 let constant = c.literal.try_eval_bits(tcx, param_env, switch_ty);
36 if let Some(constant) = constant {
37 let otherwise = targets.otherwise();
38 let mut ret = TerminatorKind::Goto { target: otherwise };
39 for (v, t) in targets.iter() {
41 ret = TerminatorKind::Goto { target: t };
50 TerminatorKind::Assert {
51 target, cond: Operand::Constant(ref c), expected, ..
52 } => match c.literal.try_eval_bool(tcx, param_env) {
53 Some(v) if v == expected => TerminatorKind::Goto { target },
56 TerminatorKind::FalseEdge { real_target, .. } => {
57 TerminatorKind::Goto { target: real_target }
59 TerminatorKind::FalseUnwind { real_target, .. } => {
60 TerminatorKind::Goto { target: real_target }