summaryrefslogtreecommitdiffstats
path: root/compiler/rustc_mir_transform/src/dead_store_elimination.rs
diff options
context:
space:
mode:
authorDaniel Baumann <daniel.baumann@progress-linux.org>2024-05-30 03:59:35 +0000
committerDaniel Baumann <daniel.baumann@progress-linux.org>2024-05-30 03:59:35 +0000
commitd1b2d29528b7794b41e66fc2136e395a02f8529b (patch)
treea4a17504b260206dec3cf55b2dca82929a348ac2 /compiler/rustc_mir_transform/src/dead_store_elimination.rs
parentReleasing progress-linux version 1.72.1+dfsg1-1~progress7.99u1. (diff)
downloadrustc-d1b2d29528b7794b41e66fc2136e395a02f8529b.tar.xz
rustc-d1b2d29528b7794b41e66fc2136e395a02f8529b.zip
Merging upstream version 1.73.0+dfsg1.
Signed-off-by: Daniel Baumann <daniel.baumann@progress-linux.org>
Diffstat (limited to 'compiler/rustc_mir_transform/src/dead_store_elimination.rs')
-rw-r--r--compiler/rustc_mir_transform/src/dead_store_elimination.rs40
1 files changed, 38 insertions, 2 deletions
diff --git a/compiler/rustc_mir_transform/src/dead_store_elimination.rs b/compiler/rustc_mir_transform/src/dead_store_elimination.rs
index 7bc5183a0..3f988930b 100644
--- a/compiler/rustc_mir_transform/src/dead_store_elimination.rs
+++ b/compiler/rustc_mir_transform/src/dead_store_elimination.rs
@@ -13,9 +13,12 @@
//!
use rustc_index::bit_set::BitSet;
+use rustc_middle::mir::visit::Visitor;
use rustc_middle::mir::*;
use rustc_middle::ty::TyCtxt;
-use rustc_mir_dataflow::impls::{borrowed_locals, MaybeTransitiveLiveLocals};
+use rustc_mir_dataflow::impls::{
+ borrowed_locals, LivenessTransferFunction, MaybeTransitiveLiveLocals,
+};
use rustc_mir_dataflow::Analysis;
/// Performs the optimization on the body
@@ -28,8 +31,33 @@ pub fn eliminate<'tcx>(tcx: TyCtxt<'tcx>, body: &mut Body<'tcx>, borrowed: &BitS
.iterate_to_fixpoint()
.into_results_cursor(body);
+ // For blocks with a call terminator, if an argument copy can be turned into a move,
+ // record it as (block, argument index).
+ let mut call_operands_to_move = Vec::new();
let mut patch = Vec::new();
+
for (bb, bb_data) in traversal::preorder(body) {
+ if let TerminatorKind::Call { ref args, .. } = bb_data.terminator().kind {
+ let loc = Location { block: bb, statement_index: bb_data.statements.len() };
+
+ // Position ourselves between the evaluation of `args` and the write to `destination`.
+ live.seek_to_block_end(bb);
+ let mut state = live.get().clone();
+
+ for (index, arg) in args.iter().enumerate().rev() {
+ if let Operand::Copy(place) = *arg
+ && !place.is_indirect()
+ && !borrowed.contains(place.local)
+ && !state.contains(place.local)
+ {
+ call_operands_to_move.push((bb, index));
+ }
+
+ // Account that `arg` is read from, so we don't promote another argument to a move.
+ LivenessTransferFunction(&mut state).visit_operand(arg, loc);
+ }
+ }
+
for (statement_index, statement) in bb_data.statements.iter().enumerate().rev() {
let loc = Location { block: bb, statement_index };
if let StatementKind::Assign(assign) = &statement.kind {
@@ -64,7 +92,7 @@ pub fn eliminate<'tcx>(tcx: TyCtxt<'tcx>, body: &mut Body<'tcx>, borrowed: &BitS
}
}
- if patch.is_empty() {
+ if patch.is_empty() && call_operands_to_move.is_empty() {
return;
}
@@ -72,6 +100,14 @@ pub fn eliminate<'tcx>(tcx: TyCtxt<'tcx>, body: &mut Body<'tcx>, borrowed: &BitS
for Location { block, statement_index } in patch {
bbs[block].statements[statement_index].make_nop();
}
+ for (block, argument_index) in call_operands_to_move {
+ let TerminatorKind::Call { ref mut args, .. } = bbs[block].terminator_mut().kind else {
+ bug!()
+ };
+ let arg = &mut args[argument_index];
+ let Operand::Copy(place) = *arg else { bug!() };
+ *arg = Operand::Move(place);
+ }
crate::simplify::simplify_locals(body, tcx)
}