Skip to content

Commit bce5eb0

Browse files
committed
Update w/ comments from oli
This also updates a check to ensure that this is only applied to bools
1 parent 6c0f2a9 commit bce5eb0

File tree

3 files changed

+40
-57
lines changed

3 files changed

+40
-57
lines changed

src/librustc_infer/infer/error_reporting/mod.rs

Lines changed: 1 addition & 1 deletion
Original file line numberDiff line numberDiff line change
@@ -827,7 +827,7 @@ impl<'a, 'tcx> InferCtxt<'a, 'tcx> {
827827
ty::GenericParamDefKind::Type { has_default, .. } => {
828828
Some((param.def_id, has_default))
829829
}
830-
ty::GenericParamDefKind::Const { .. } => None, // FIXME(const_generics:defaults)
830+
ty::GenericParamDefKind::Const => None, // FIXME(const_generics:defaults)
831831
})
832832
.peekable();
833833
let has_default = {
Lines changed: 38 additions & 55 deletions
Original file line numberDiff line numberDiff line change
@@ -1,4 +1,4 @@
1-
use crate::transform::{simplify, MirPass, MirSource};
1+
use crate::transform::{MirPass, MirSource};
22
use rustc_middle::mir::*;
33
use rustc_middle::ty::TyCtxt;
44

@@ -12,71 +12,63 @@ pub struct MatchBranchSimplification;
1212
impl<'tcx> MirPass<'tcx> for MatchBranchSimplification {
1313
fn run_pass(&self, tcx: TyCtxt<'tcx>, src: MirSource<'tcx>, body: &mut Body<'tcx>) {
1414
let param_env = tcx.param_env(src.def_id());
15-
let mut did_remove_blocks = false;
1615
let bbs = body.basic_blocks_mut();
1716
'outer: for bb_idx in bbs.indices() {
18-
let (discr, val, switch_ty, targets) = match bbs[bb_idx].terminator().kind {
17+
let (discr, val, switch_ty, first, second) = match bbs[bb_idx].terminator().kind {
1918
TerminatorKind::SwitchInt {
2019
discr: Operand::Move(ref place),
2120
switch_ty,
2221
ref targets,
2322
ref values,
2423
..
2524
} if targets.len() == 2 && values.len() == 1 => {
26-
(place.clone(), values[0], switch_ty, targets)
25+
(place, values[0], switch_ty, targets[0], targets[1])
2726
}
27+
// Only optimize switch int statements
2828
_ => continue,
2929
};
30-
let (first, rest) = if let ([first], rest) = targets.split_at(1) {
31-
(*first, rest)
32-
} else {
33-
unreachable!();
34-
};
35-
let first_dest = bbs[first].terminator().kind.clone();
36-
let same_destinations = rest
37-
.iter()
38-
.map(|target| &bbs[*target].terminator().kind)
39-
.all(|t_kind| t_kind == &first_dest);
40-
if !same_destinations {
30+
31+
// Check that destinations are identical, and if not, then don't optimize this block
32+
if &bbs[first].terminator().kind != &bbs[second].terminator().kind {
4133
continue;
4234
}
35+
36+
// Check that blocks are assignments of consts to the same place or same statement,
37+
// and match up 1-1, if not don't optimize this block.
4338
let first_stmts = &bbs[first].statements;
44-
for s in first_stmts.iter() {
45-
match &s.kind {
46-
StatementKind::Assign(box (_, rhs)) => {
47-
if let Rvalue::Use(Operand::Constant(_)) = rhs {
48-
} else {
49-
continue 'outer;
50-
}
51-
}
52-
_ => continue 'outer,
53-
}
39+
let scnd_stmts = &bbs[second].statements;
40+
if first_stmts.len() != scnd_stmts.len() {
41+
continue;
5442
}
55-
for target in rest.iter() {
56-
for s in bbs[*target].statements.iter() {
57-
if let StatementKind::Assign(box (ref lhs, rhs)) = &s.kind {
58-
if let Rvalue::Use(Operand::Constant(_)) = rhs {
59-
let has_matching_assn = first_stmts
60-
.iter()
61-
.find(|s| {
62-
if let StatementKind::Assign(box (lhs_f, _)) = &s.kind {
63-
lhs_f == lhs
64-
} else {
65-
false
66-
}
67-
})
68-
.is_some();
69-
if has_matching_assn {
70-
continue;
43+
for (f, s) in first_stmts.iter().zip(scnd_stmts.iter()) {
44+
match (&f.kind, &s.kind) {
45+
// If two statements are exactly the same just ignore them.
46+
(f_s, s_s) if f_s == s_s => (),
47+
48+
(
49+
StatementKind::Assign(box (lhs_f, Rvalue::Use(Operand::Constant(f_c)))),
50+
StatementKind::Assign(box (lhs_s, Rvalue::Use(Operand::Constant(s_c)))),
51+
) if lhs_f == lhs_s => {
52+
if let Some(f_c) = f_c.literal.try_eval_bool(tcx, param_env) {
53+
// This should also be a bool because it's writing to the same place
54+
let s_c = s_c.literal.try_eval_bool(tcx, param_env).unwrap();
55+
// Check that only const assignments of opposite bool values are
56+
// permitted.
57+
if f_c != s_c {
58+
continue
7159
}
7260
}
61+
continue 'outer;
7362
}
74-
75-
continue 'outer;
63+
// If there are not exclusively assignments, then ignore this
64+
_ => continue 'outer,
7665
}
7766
}
78-
let (first_block, to_add) = bbs.pick2_mut(first, bb_idx);
79-
let new_stmts = first_block.statements.iter().cloned().map(|mut s| {
67+
// Take owenership of items now that we know we can optimize.
68+
let discr = discr.clone();
69+
70+
bbs[bb_idx].terminator_mut().kind = TerminatorKind::Goto { target: first };
71+
for s in bbs[first].statements.iter_mut() {
8072
if let StatementKind::Assign(box (_, ref mut rhs)) = s.kind {
8173
let size = tcx.layout_of(param_env.and(switch_ty)).unwrap().size;
8274
let const_cmp = Operand::const_from_scalar(
@@ -86,17 +78,8 @@ impl<'tcx> MirPass<'tcx> for MatchBranchSimplification {
8678
rustc_span::DUMMY_SP,
8779
);
8880
*rhs = Rvalue::BinaryOp(BinOp::Eq, Operand::Move(discr), const_cmp);
89-
} else {
90-
unreachable!()
9181
}
92-
s
93-
});
94-
to_add.statements.extend(new_stmts);
95-
to_add.terminator_mut().kind = first_dest;
96-
did_remove_blocks = true;
97-
}
98-
if did_remove_blocks {
99-
simplify::remove_dead_blocks(body);
82+
}
10083
}
10184
}
10285
}

src/librustc_mir/transform/mod.rs

Lines changed: 1 addition & 1 deletion
Original file line numberDiff line numberDiff line change
@@ -441,6 +441,7 @@ fn run_optimization_passes<'tcx>(
441441
// with async primitives.
442442
&generator::StateTransform,
443443
&instcombine::InstCombine,
444+
&match_branches::MatchBranchSimplification,
444445
&const_prop::ConstProp,
445446
&simplify_branches::SimplifyBranches::new("after-const-prop"),
446447
&simplify_try::SimplifyArmIdentity,
@@ -452,7 +453,6 @@ fn run_optimization_passes<'tcx>(
452453
&simplify::SimplifyCfg::new("final"),
453454
&nrvo::RenameReturnPlace,
454455
&simplify::SimplifyLocals,
455-
&match_branches::MatchBranchSimplification,
456456
];
457457

458458
let no_optimizations: &[&dyn MirPass<'tcx>] = &[

0 commit comments

Comments
 (0)