Skip to content

Commit 0e126a7

Browse files
Auto merge of #147131 - cjgillot:patch-branches, r=<try>
Use MirPatch in simplify_branches.
2 parents c8905ea + 599e8db commit 0e126a7

File tree

2 files changed

+37
-12
lines changed

2 files changed

+37
-12
lines changed

compiler/rustc_mir_transform/src/patch.rs

Lines changed: 25 additions & 5 deletions
Original file line numberDiff line numberDiff line change
@@ -11,6 +11,8 @@ use tracing::debug;
1111
/// once with `apply`. This is useful for MIR transformation passes.
1212
pub(crate) struct MirPatch<'tcx> {
1313
term_patch_map: FxHashMap<BasicBlock, TerminatorKind<'tcx>>,
14+
/// Set of statements that should be replaced by `Nop`.
15+
nop_statements: Vec<Location>,
1416
new_blocks: Vec<BasicBlockData<'tcx>>,
1517
new_statements: Vec<(Location, StatementKind<'tcx>)>,
1618
new_locals: Vec<LocalDecl<'tcx>>,
@@ -33,6 +35,7 @@ impl<'tcx> MirPatch<'tcx> {
3335
pub(crate) fn new(body: &Body<'tcx>) -> Self {
3436
let mut result = MirPatch {
3537
term_patch_map: Default::default(),
38+
nop_statements: vec![],
3639
new_blocks: vec![],
3740
new_statements: vec![],
3841
new_locals: vec![],
@@ -212,6 +215,15 @@ impl<'tcx> MirPatch<'tcx> {
212215
self.term_patch_map.insert(block, new);
213216
}
214217

218+
/// Mark given statement to be replaced by a `Nop`.
219+
///
220+
/// This method only works on statements from the initial body, and cannot be used to remove
221+
/// statements from `add_statement` or `add_assign`.
222+
#[tracing::instrument(level = "debug", skip(self))]
223+
pub(crate) fn nop_statement(&mut self, loc: Location) {
224+
self.nop_statements.push(loc);
225+
}
226+
215227
/// Queues the insertion of a statement at a given location. The statement
216228
/// currently at that location, and all statements that follow, are shifted
217229
/// down. If multiple statements are queued for addition at the same
@@ -257,11 +269,8 @@ impl<'tcx> MirPatch<'tcx> {
257269
bbs.extend(self.new_blocks);
258270
body.local_decls.extend(self.new_locals);
259271

260-
// The order in which we patch terminators does not change the result.
261-
#[allow(rustc::potential_query_instability)]
262-
for (src, patch) in self.term_patch_map {
263-
debug!("MirPatch: patching block {:?}", src);
264-
bbs[src].terminator_mut().kind = patch;
272+
for loc in self.nop_statements {
273+
bbs[loc.block].statements[loc.statement_index].make_nop();
265274
}
266275

267276
let mut new_statements = self.new_statements;
@@ -285,6 +294,17 @@ impl<'tcx> MirPatch<'tcx> {
285294
.insert(loc.statement_index, Statement::new(source_info, stmt));
286295
delta += 1;
287296
}
297+
298+
// The order in which we patch terminators does not change the result.
299+
#[allow(rustc::potential_query_instability)]
300+
for (src, patch) in self.term_patch_map {
301+
debug!("MirPatch: patching block {:?}", src);
302+
let bb = &mut bbs[src];
303+
if let TerminatorKind::Unreachable = patch {
304+
bb.statements.clear();
305+
}
306+
bb.terminator_mut().kind = patch;
307+
}
288308
}
289309

290310
fn source_info_for_index(data: &BasicBlockData<'_>, loc: Location) -> SourceInfo {

compiler/rustc_mir_transform/src/simplify_branches.rs

Lines changed: 12 additions & 7 deletions
Original file line numberDiff line numberDiff line change
@@ -2,6 +2,8 @@ use rustc_middle::mir::*;
22
use rustc_middle::ty::TyCtxt;
33
use tracing::trace;
44

5+
use crate::patch::MirPatch;
6+
57
pub(super) enum SimplifyConstCondition {
68
AfterConstProp,
79
Final,
@@ -19,26 +21,27 @@ impl<'tcx> crate::MirPass<'tcx> for SimplifyConstCondition {
1921
fn run_pass(&self, tcx: TyCtxt<'tcx>, body: &mut Body<'tcx>) {
2022
trace!("Running SimplifyConstCondition on {:?}", body.source);
2123
let typing_env = body.typing_env(tcx);
22-
'blocks: for block in body.basic_blocks_mut() {
23-
for stmt in block.statements.iter_mut() {
24+
let mut patch = MirPatch::new(body);
25+
26+
'blocks: for (bb, block) in body.basic_blocks.iter_enumerated() {
27+
for (statement_index, stmt) in block.statements.iter().enumerate() {
2428
// Simplify `assume` of a known value: either a NOP or unreachable.
2529
if let StatementKind::Intrinsic(box ref intrinsic) = stmt.kind
2630
&& let NonDivergingIntrinsic::Assume(discr) = intrinsic
2731
&& let Operand::Constant(c) = discr
2832
&& let Some(constant) = c.const_.try_eval_bool(tcx, typing_env)
2933
{
3034
if constant {
31-
stmt.make_nop();
35+
patch.nop_statement(Location { block: bb, statement_index });
3236
} else {
33-
block.statements.clear();
34-
block.terminator_mut().kind = TerminatorKind::Unreachable;
37+
patch.patch_terminator(bb, TerminatorKind::Unreachable);
3538
continue 'blocks;
3639
}
3740
}
3841
}
3942

40-
let terminator = block.terminator_mut();
41-
terminator.kind = match terminator.kind {
43+
let terminator = block.terminator();
44+
let terminator = match terminator.kind {
4245
TerminatorKind::SwitchInt {
4346
discr: Operand::Constant(ref c), ref targets, ..
4447
} => {
@@ -58,7 +61,9 @@ impl<'tcx> crate::MirPass<'tcx> for SimplifyConstCondition {
5861
},
5962
_ => continue,
6063
};
64+
patch.patch_terminator(bb, terminator);
6165
}
66+
patch.apply(body);
6267
}
6368

6469
fn is_required(&self) -> bool {

0 commit comments

Comments
 (0)