]> git.lizzy.rs Git - rust.git/blob - compiler/rustc_mir_transform/src/simplify_branches.rs
Auto merge of #107241 - clubby789:bootstrap-lto-off, r=simulacrum
[rust.git] / compiler / rustc_mir_transform / src / simplify_branches.rs
1 use crate::MirPass;
2 use rustc_middle::mir::*;
3 use rustc_middle::ty::TyCtxt;
4
5 /// A pass that replaces a branch with a goto when its condition is known.
6 pub struct SimplifyConstCondition {
7     label: String,
8 }
9
10 impl SimplifyConstCondition {
11     pub fn new(label: &str) -> Self {
12         SimplifyConstCondition { label: format!("SimplifyConstCondition-{}", label) }
13     }
14 }
15
16 impl<'tcx> MirPass<'tcx> for SimplifyConstCondition {
17     fn name(&self) -> &str {
18         &self.label
19     }
20
21     fn run_pass(&self, tcx: TyCtxt<'tcx>, body: &mut Body<'tcx>) {
22         let param_env = tcx.param_env(body.source.def_id());
23         for block in body.basic_blocks_mut() {
24             let terminator = block.terminator_mut();
25             terminator.kind = match terminator.kind {
26                 TerminatorKind::SwitchInt {
27                     discr: Operand::Constant(ref c), ref targets, ..
28                 } => {
29                     let constant = c.literal.try_eval_bits(tcx, param_env, c.ty());
30                     if let Some(constant) = constant {
31                         let target = targets.target_for_value(constant);
32                         TerminatorKind::Goto { target }
33                     } else {
34                         continue;
35                     }
36                 }
37                 TerminatorKind::Assert {
38                     target, cond: Operand::Constant(ref c), expected, ..
39                 } => match c.literal.try_eval_bool(tcx, param_env) {
40                     Some(v) if v == expected => TerminatorKind::Goto { target },
41                     _ => continue,
42                 },
43                 _ => continue,
44             };
45         }
46     }
47 }