mirror of
https://github.com/rust-lang/rust.git
synced 2026-04-26 13:01:27 +03:00
Rollup merge of #155680 - Amanieu:call-arg-move-index, r=cjgillot
Handle index projections in call destinations in DSE Since call destinations are evaluated after call arguments, we can't turn copy arguments into moves if the same local is later used as an index projection in the call destination. DSE call arg optimization: rust-lang/rust#113758 r? @cjgillot cc @RalfJung
This commit is contained in:
@@ -47,13 +47,21 @@ fn eliminate<'tcx>(tcx: TyCtxt<'tcx>, body: &mut Body<'tcx>) -> bool {
|
|||||||
let mut patch = Vec::new();
|
let mut patch = Vec::new();
|
||||||
|
|
||||||
for (bb, bb_data) in traversal::preorder(body) {
|
for (bb, bb_data) in traversal::preorder(body) {
|
||||||
if let TerminatorKind::Call { ref args, .. } = bb_data.terminator().kind {
|
if let TerminatorKind::Call { ref args, ref destination, .. } = bb_data.terminator().kind {
|
||||||
let loc = Location { block: bb, statement_index: bb_data.statements.len() };
|
let loc = Location { block: bb, statement_index: bb_data.statements.len() };
|
||||||
|
|
||||||
// Position ourselves between the evaluation of `args` and the write to `destination`.
|
// Position ourselves between the evaluation of `args` and the write to `destination`.
|
||||||
live.seek_to_block_end(bb);
|
live.seek_to_block_end(bb);
|
||||||
let mut state = live.get().clone();
|
let mut state = live.get().clone();
|
||||||
|
|
||||||
|
// Don't turn into a move if the local is used as an index
|
||||||
|
// projection for the destination place.
|
||||||
|
LivenessTransferFunction(&mut state).visit_place(
|
||||||
|
destination,
|
||||||
|
visit::PlaceContext::MutatingUse(visit::MutatingUseContext::Call),
|
||||||
|
loc,
|
||||||
|
);
|
||||||
|
|
||||||
for (index, arg) in args.iter().map(|a| &a.node).enumerate().rev() {
|
for (index, arg) in args.iter().map(|a| &a.node).enumerate().rev() {
|
||||||
if let Operand::Copy(place) = *arg
|
if let Operand::Copy(place) = *arg
|
||||||
&& !place.is_indirect()
|
&& !place.is_indirect()
|
||||||
|
|||||||
+15
@@ -0,0 +1,15 @@
|
|||||||
|
- // MIR for `move_index` before DeadStoreElimination-final
|
||||||
|
+ // MIR for `move_index` after DeadStoreElimination-final
|
||||||
|
|
||||||
|
fn move_index(_1: [usize; 10], _2: usize) -> () {
|
||||||
|
let mut _0: ();
|
||||||
|
|
||||||
|
bb0: {
|
||||||
|
_1[_2] = passthrough_usize(copy _2) -> [return: bb1, unwind unreachable];
|
||||||
|
}
|
||||||
|
|
||||||
|
bb1: {
|
||||||
|
return;
|
||||||
|
}
|
||||||
|
}
|
||||||
|
|
||||||
+15
@@ -0,0 +1,15 @@
|
|||||||
|
- // MIR for `move_index` before DeadStoreElimination-final
|
||||||
|
+ // MIR for `move_index` after DeadStoreElimination-final
|
||||||
|
|
||||||
|
fn move_index(_1: [usize; 10], _2: usize) -> () {
|
||||||
|
let mut _0: ();
|
||||||
|
|
||||||
|
bb0: {
|
||||||
|
_1[_2] = passthrough_usize(copy _2) -> [return: bb1, unwind continue];
|
||||||
|
}
|
||||||
|
|
||||||
|
bb1: {
|
||||||
|
return;
|
||||||
|
}
|
||||||
|
}
|
||||||
|
|
||||||
@@ -40,7 +40,31 @@ fn move_packed(packed: Packed) {
|
|||||||
}
|
}
|
||||||
}
|
}
|
||||||
|
|
||||||
|
#[inline(never)]
|
||||||
|
fn passthrough_usize(a: usize) -> usize {
|
||||||
|
a
|
||||||
|
}
|
||||||
|
|
||||||
|
// EMIT_MIR call_arg_copy.move_index.DeadStoreElimination-final.diff
|
||||||
|
#[custom_mir(dialect = "analysis")]
|
||||||
|
fn move_index(a: [usize; 10], b: usize) {
|
||||||
|
// CHECK-LABEL: fn move_index(
|
||||||
|
// CHECK: = passthrough_usize(copy _2)
|
||||||
|
mir! {
|
||||||
|
{
|
||||||
|
// The index is used again after the operand is evaluated to
|
||||||
|
// evaluate the destionation place, so the argument cannot be turned
|
||||||
|
// into a move.
|
||||||
|
Call(a[b] = passthrough_usize(b), ReturnTo(ret), UnwindContinue())
|
||||||
|
}
|
||||||
|
ret = {
|
||||||
|
Return()
|
||||||
|
}
|
||||||
|
}
|
||||||
|
}
|
||||||
|
|
||||||
fn main() {
|
fn main() {
|
||||||
move_simple(1);
|
move_simple(1);
|
||||||
move_packed(Packed { x: 0, y: 1 });
|
move_packed(Packed { x: 0, y: 1 });
|
||||||
|
move_index([0; _], 1);
|
||||||
}
|
}
|
||||||
|
|||||||
Reference in New Issue
Block a user