Skip to content

Commit

Permalink
Replace NormalizeArrayLen with GVN
Browse files Browse the repository at this point in the history
GVN is actually on in release, and covers all the same things (or more), with `LowerSliceLen` changed to produce `PtrMetadata`.
  • Loading branch information
scottmcm committed Jun 16, 2024
1 parent 637d384 commit 7323f2a
Show file tree
Hide file tree
Showing 30 changed files with 138 additions and 218 deletions.
4 changes: 0 additions & 4 deletions compiler/rustc_mir_transform/src/lib.rs
Original file line number Diff line number Diff line change
Expand Up @@ -88,7 +88,6 @@ mod lower_slice_len;
mod match_branches;
mod mentioned_items;
mod multiple_return_terminators;
mod normalize_array_len;
mod nrvo;
mod prettify;
mod promote_consts;
Expand Down Expand Up @@ -581,9 +580,6 @@ fn run_optimization_passes<'tcx>(tcx: TyCtxt<'tcx>, body: &mut Body<'tcx>) {
&o1(simplify::SimplifyCfg::AfterUnreachableEnumBranching),
// Inlining may have introduced a lot of redundant code and a large move pattern.
// Now, we need to shrink the generated MIR.

// Has to run after `slice::len` lowering
&normalize_array_len::NormalizeArrayLen,
&ref_prop::ReferencePropagation,
&sroa::ScalarReplacementOfAggregates,
&match_branches::MatchBranchSimplification,
Expand Down
24 changes: 8 additions & 16 deletions compiler/rustc_mir_transform/src/lower_slice_len.rs
Original file line number Diff line number Diff line change
@@ -1,10 +1,9 @@
//! This pass lowers calls to core::slice::len to just Len op.
//! This pass lowers calls to core::slice::len to just PtrMetadata op.
//! It should run before inlining!

use rustc_hir::def_id::DefId;
use rustc_index::IndexSlice;
use rustc_middle::mir::*;
use rustc_middle::ty::{self, TyCtxt};
use rustc_middle::ty::TyCtxt;

pub struct LowerSliceLenCalls;

Expand All @@ -29,16 +28,11 @@ pub fn lower_slice_len_calls<'tcx>(tcx: TyCtxt<'tcx>, body: &mut Body<'tcx>) {
let basic_blocks = body.basic_blocks.as_mut_preserves_cfg();
for block in basic_blocks {
// lower `<[_]>::len` calls
lower_slice_len_call(tcx, block, &body.local_decls, slice_len_fn_item_def_id);
lower_slice_len_call(block, slice_len_fn_item_def_id);
}
}

fn lower_slice_len_call<'tcx>(
tcx: TyCtxt<'tcx>,
block: &mut BasicBlockData<'tcx>,
local_decls: &IndexSlice<Local, LocalDecl<'tcx>>,
slice_len_fn_item_def_id: DefId,
) {
fn lower_slice_len_call<'tcx>(block: &mut BasicBlockData<'tcx>, slice_len_fn_item_def_id: DefId) {
let terminator = block.terminator();
if let TerminatorKind::Call {
func,
Expand All @@ -50,19 +44,17 @@ fn lower_slice_len_call<'tcx>(
} = &terminator.kind
// some heuristics for fast rejection
&& let [arg] = &args[..]
&& let Some(arg) = arg.node.place()
&& let ty::FnDef(fn_def_id, _) = func.ty(local_decls, tcx).kind()
&& *fn_def_id == slice_len_fn_item_def_id
&& let Some((fn_def_id, _)) = func.const_fn_def()
&& fn_def_id == slice_len_fn_item_def_id
{
// perform modifications from something like:
// _5 = core::slice::<impl [u8]>::len(move _6) -> bb1
// into:
// _5 = Len(*_6)
// _5 = PtrMetadata(move _6)
// goto bb1

// make new RValue for Len
let deref_arg = tcx.mk_place_deref(arg);
let r_value = Rvalue::Len(deref_arg);
let r_value = Rvalue::UnaryOp(UnOp::PtrMetadata, arg.node.clone());
let len_statement_kind = StatementKind::Assign(Box::new((*destination, r_value)));
let add_statement =
Statement { kind: len_statement_kind, source_info: terminator.source_info };
Expand Down
103 changes: 0 additions & 103 deletions compiler/rustc_mir_transform/src/normalize_array_len.rs

This file was deleted.

1 change: 0 additions & 1 deletion tests/mir-opt/issue_76432.rs
Original file line number Diff line number Diff line change
@@ -1,6 +1,5 @@
// skip-filecheck
// EMIT_MIR_FOR_EACH_PANIC_STRATEGY
//@ compile-flags: -Zmir-enable-passes=-NormalizeArrayLen
// Check that we do not insert StorageDead at each target if StorageDead was never seen

// EMIT_MIR issue_76432.test.SimplifyComparisonIntegral.diff
Expand Down
Original file line number Diff line number Diff line change
@@ -1,5 +1,5 @@
- // MIR for `array_bound` before NormalizeArrayLen
+ // MIR for `array_bound` after NormalizeArrayLen
- // MIR for `array_bound` before GVN
+ // MIR for `array_bound` after GVN

fn array_bound(_1: usize, _2: &[u8; N]) -> u8 {
debug index => _1;
Expand All @@ -24,14 +24,15 @@
_7 = &(*_2);
_6 = move _7 as &[u8] (PointerCoercion(Unsize));
StorageDead(_7);
- _5 = Len((*_6));
- _5 = PtrMetadata(move _6);
+ _5 = const N;
goto -> bb1;
}

bb1: {
StorageDead(_6);
_3 = Lt(move _4, move _5);
- _3 = Lt(move _4, move _5);
+ _3 = Lt(_1, move _5);
switchInt(move _3) -> [0: bb4, otherwise: bb2];
}

Expand All @@ -40,13 +41,17 @@
StorageDead(_4);
StorageLive(_8);
_8 = _1;
_9 = Len((*_2));
_10 = Lt(_8, _9);
assert(move _10, "index out of bounds: the length is {} but the index is {}", move _9, _8) -> [success: bb3, unwind unreachable];
- _9 = Len((*_2));
- _10 = Lt(_8, _9);
- assert(move _10, "index out of bounds: the length is {} but the index is {}", move _9, _8) -> [success: bb3, unwind unreachable];
+ _9 = const N;
+ _10 = Lt(_1, const N);
+ assert(move _10, "index out of bounds: the length is {} but the index is {}", const N, _1) -> [success: bb3, unwind unreachable];
}

bb3: {
_0 = (*_2)[_8];
- _0 = (*_2)[_8];
+ _0 = (*_2)[_1];
StorageDead(_8);
goto -> bb5;
}
Expand Down
Original file line number Diff line number Diff line change
@@ -1,5 +1,5 @@
- // MIR for `array_bound` before NormalizeArrayLen
+ // MIR for `array_bound` after NormalizeArrayLen
- // MIR for `array_bound` before GVN
+ // MIR for `array_bound` after GVN

fn array_bound(_1: usize, _2: &[u8; N]) -> u8 {
debug index => _1;
Expand All @@ -24,14 +24,15 @@
_7 = &(*_2);
_6 = move _7 as &[u8] (PointerCoercion(Unsize));
StorageDead(_7);
- _5 = Len((*_6));
- _5 = PtrMetadata(move _6);
+ _5 = const N;
goto -> bb1;
}

bb1: {
StorageDead(_6);
_3 = Lt(move _4, move _5);
- _3 = Lt(move _4, move _5);
+ _3 = Lt(_1, move _5);
switchInt(move _3) -> [0: bb4, otherwise: bb2];
}

Expand All @@ -40,13 +41,17 @@
StorageDead(_4);
StorageLive(_8);
_8 = _1;
_9 = Len((*_2));
_10 = Lt(_8, _9);
assert(move _10, "index out of bounds: the length is {} but the index is {}", move _9, _8) -> [success: bb3, unwind continue];
- _9 = Len((*_2));
- _10 = Lt(_8, _9);
- assert(move _10, "index out of bounds: the length is {} but the index is {}", move _9, _8) -> [success: bb3, unwind continue];
+ _9 = const N;
+ _10 = Lt(_1, const N);
+ assert(move _10, "index out of bounds: the length is {} but the index is {}", const N, _1) -> [success: bb3, unwind continue];
}

bb3: {
_0 = (*_2)[_8];
- _0 = (*_2)[_8];
+ _0 = (*_2)[_1];
StorageDead(_8);
goto -> bb5;
}
Expand Down
Original file line number Diff line number Diff line change
@@ -1,5 +1,5 @@
- // MIR for `array_bound_mut` before NormalizeArrayLen
+ // MIR for `array_bound_mut` after NormalizeArrayLen
- // MIR for `array_bound_mut` before GVN
+ // MIR for `array_bound_mut` after GVN

fn array_bound_mut(_1: usize, _2: &mut [u8; N]) -> u8 {
debug index => _1;
Expand Down Expand Up @@ -27,14 +27,15 @@
_7 = &(*_2);
_6 = move _7 as &[u8] (PointerCoercion(Unsize));
StorageDead(_7);
- _5 = Len((*_6));
- _5 = PtrMetadata(move _6);
+ _5 = const N;
goto -> bb1;
}

bb1: {
StorageDead(_6);
_3 = Lt(move _4, move _5);
- _3 = Lt(move _4, move _5);
+ _3 = Lt(_1, move _5);
switchInt(move _3) -> [0: bb4, otherwise: bb2];
}

Expand All @@ -43,13 +44,17 @@
StorageDead(_4);
StorageLive(_8);
_8 = _1;
_9 = Len((*_2));
_10 = Lt(_8, _9);
assert(move _10, "index out of bounds: the length is {} but the index is {}", move _9, _8) -> [success: bb3, unwind unreachable];
- _9 = Len((*_2));
- _10 = Lt(_8, _9);
- assert(move _10, "index out of bounds: the length is {} but the index is {}", move _9, _8) -> [success: bb3, unwind unreachable];
+ _9 = const N;
+ _10 = Lt(_1, const N);
+ assert(move _10, "index out of bounds: the length is {} but the index is {}", const N, _1) -> [success: bb3, unwind unreachable];
}

bb3: {
_0 = (*_2)[_8];
- _0 = (*_2)[_8];
+ _0 = (*_2)[_1];
StorageDead(_8);
goto -> bb6;
}
Expand All @@ -59,13 +64,17 @@
StorageDead(_4);
StorageLive(_11);
_11 = const 0_usize;
_12 = Len((*_2));
_13 = Lt(_11, _12);
assert(move _13, "index out of bounds: the length is {} but the index is {}", move _12, _11) -> [success: bb5, unwind unreachable];
- _12 = Len((*_2));
- _13 = Lt(_11, _12);
- assert(move _13, "index out of bounds: the length is {} but the index is {}", move _12, _11) -> [success: bb5, unwind unreachable];
+ _12 = const N;
+ _13 = Lt(const 0_usize, const N);
+ assert(move _13, "index out of bounds: the length is {} but the index is {}", const N, const 0_usize) -> [success: bb5, unwind unreachable];
}

bb5: {
(*_2)[_11] = const 42_u8;
- (*_2)[_11] = const 42_u8;
+ (*_2)[0 of 1] = const 42_u8;
StorageDead(_11);
_0 = const 42_u8;
goto -> bb6;
Expand Down
Loading

0 comments on commit 7323f2a

Please sign in to comment.