use rustc_middle::mir::*;
use rustc_middle::ty::TyCtxt;
+use super::simplify::simplify_cfg;
+
pub struct MatchBranchSimplification;
/// If a source block is found that switches between two blocks that are exactly
impl<'tcx> MirPass<'tcx> for MatchBranchSimplification {
fn run_pass(&self, tcx: TyCtxt<'tcx>, body: &mut Body<'tcx>) {
- if tcx.sess.opts.debugging_opts.mir_opt_level <= 1 {
+ if tcx.sess.mir_opt_level() < 3 {
return;
}
- let param_env = tcx.param_env(body.source.def_id());
let def_id = body.source.def_id();
+ let param_env = tcx.param_env(def_id);
+
let (bbs, local_decls) = body.basic_blocks_and_local_decls_mut();
+ let mut should_cleanup = false;
'outer: for bb_idx in bbs.indices() {
if !tcx.consider_optimizing(|| format!("MatchBranchSimplification {:?} ", def_id)) {
continue;
StatementKind::Assign(box (lhs_f, Rvalue::Use(Operand::Constant(f_c)))),
StatementKind::Assign(box (lhs_s, Rvalue::Use(Operand::Constant(s_c)))),
) if lhs_f == lhs_s
- && f_c.literal.ty.is_bool()
- && s_c.literal.ty.is_bool()
+ && f_c.literal.ty().is_bool()
+ && s_c.literal.ty().is_bool()
&& f_c.literal.try_eval_bool(tcx, param_env).is_some()
&& s_c.literal.try_eval_bool(tcx, param_env).is_some() => {}
let op = if f_b { BinOp::Eq } else { BinOp::Ne };
let rhs = Rvalue::BinaryOp(
op,
- Operand::Copy(Place::from(discr_local)),
- const_cmp,
+ box (Operand::Copy(Place::from(discr_local)), const_cmp),
);
Statement {
source_info: f.source_info,
from.statements
.push(Statement { source_info, kind: StatementKind::StorageDead(discr_local) });
from.terminator_mut().kind = first.terminator().kind.clone();
+ should_cleanup = true;
+ }
+
+ if should_cleanup {
+ simplify_cfg(body);
}
}
}