Turn copy into moves during DSE.
This commit is contained in:
parent
b657dc555b
commit
f5feb3e3ca
32 changed files with 129 additions and 31 deletions
|
@ -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)
|
||||
}
|
||||
|
|
Loading…
Add table
Add a link
Reference in a new issue