Skip to content

Commit

Permalink
Auto merge of rust-lang#128265 - DianQK:instsimplify-before-inline, r…
Browse files Browse the repository at this point in the history
…=saethlin

 Perform instsimplify before inline to eliminate some trivial calls

I am currently working on rust-lang#128081. In the current pipeline, we can get the following clone statements ([godbolt](https://rust.godbolt.org/z/931316fhP)):

```
    bb0: {
        StorageLive(_2);
        _2 = ((*_1).0: i32);
        StorageLive(_3);
        _3 = ((*_1).1: u64);
        _0 = Foo { a: move _2, b: move _3 };
        StorageDead(_3);
        StorageDead(_2);
        return;
    }
```

Analyzing such statements will be simple and fast. We don't need to consider branches or some interfering statements. However, this requires us to run `InstSimplify`, `ReferencePropagation`, and `SimplifyCFG` at least once. I can introduce a new pass, but I think the best place for it would be within `InstSimplify`.

I put `InstSimplify` before `Inline`, which takes some of the burden away from `Inline`.

r? `@saethlin`
  • Loading branch information
bors committed Jul 29, 2024
2 parents 56c698c + ae681c9 commit 4db3d12
Show file tree
Hide file tree
Showing 83 changed files with 226 additions and 182 deletions.
18 changes: 17 additions & 1 deletion compiler/rustc_mir_transform/src/instsimplify.rs
Original file line number Diff line number Diff line change
Expand Up @@ -13,9 +13,25 @@ use rustc_target::spec::abi::Abi;
use crate::simplify::simplify_duplicate_switch_targets;
use crate::take_array;

pub struct InstSimplify;
pub enum InstSimplify {
BeforeInline,
AfterSimplifyCfg,
}

impl InstSimplify {
pub fn name(&self) -> &'static str {
match self {
InstSimplify::BeforeInline => "InstSimplify-before-inline",
InstSimplify::AfterSimplifyCfg => "InstSimplify-after-simplifycfg",
}
}
}

impl<'tcx> MirPass<'tcx> for InstSimplify {
fn name(&self) -> &'static str {
self.name()
}

fn is_enabled(&self, sess: &rustc_session::Session) -> bool {
sess.mir_opt_level() > 0
}
Expand Down
5 changes: 4 additions & 1 deletion compiler/rustc_mir_transform/src/lib.rs
Original file line number Diff line number Diff line change
Expand Up @@ -571,6 +571,8 @@ fn run_optimization_passes<'tcx>(tcx: TyCtxt<'tcx>, body: &mut Body<'tcx>) {
// Has to be done before inlining, otherwise actual call will be almost always inlined.
// Also simple, so can just do first
&lower_slice_len::LowerSliceLenCalls,
// Perform instsimplify before inline to eliminate some trivial calls (like clone shims).
&instsimplify::InstSimplify::BeforeInline,
// Perform inlining, which may add a lot of code.
&inline::Inline,
// Code from other crates may have storage markers, so this needs to happen after inlining.
Expand All @@ -590,7 +592,8 @@ fn run_optimization_passes<'tcx>(tcx: TyCtxt<'tcx>, body: &mut Body<'tcx>) {
&match_branches::MatchBranchSimplification,
// inst combine is after MatchBranchSimplification to clean up Ne(_1, false)
&multiple_return_terminators::MultipleReturnTerminators,
&instsimplify::InstSimplify,
// After simplifycfg, it allows us to discover new opportunities for peephole optimizations.
&instsimplify::InstSimplify::AfterSimplifyCfg,
&simplify::SimplifyLocals::BeforeConstProp,
&dead_store_elimination::DeadStoreElimination::Initial,
&gvn::GVN,
Expand Down
2 changes: 1 addition & 1 deletion compiler/rustc_mir_transform/src/shim.rs
Original file line number Diff line number Diff line change
Expand Up @@ -155,7 +155,7 @@ fn make_shim<'tcx>(tcx: TyCtxt<'tcx>, instance: ty::InstanceKind<'tcx>) -> Body<
&deref_separator::Derefer,
&remove_noop_landing_pads::RemoveNoopLandingPads,
&simplify::SimplifyCfg::MakeShim,
&instsimplify::InstSimplify,
&instsimplify::InstSimplify::BeforeInline,
&abort_unwinding_calls::AbortUnwindingCalls,
&add_call_guards::CriticalCallEdges,
],
Expand Down
2 changes: 1 addition & 1 deletion tests/incremental/hashes/call_expressions.rs
Original file line number Diff line number Diff line change
Expand Up @@ -162,7 +162,7 @@ pub fn change_to_ufcs() {
}

#[cfg(not(any(cfail1,cfail4)))]
#[rustc_clean(cfg="cfail2", except="opt_hir_owner_nodes,typeck")]
#[rustc_clean(cfg="cfail2", except="opt_hir_owner_nodes,optimized_mir,typeck")]
#[rustc_clean(cfg="cfail3")]
#[rustc_clean(cfg="cfail5", except="opt_hir_owner_nodes,optimized_mir,typeck")]
#[rustc_clean(cfg="cfail6")]
Expand Down
2 changes: 1 addition & 1 deletion tests/mir-opt/const_prop/slice_len.rs
Original file line number Diff line number Diff line change
@@ -1,5 +1,5 @@
//@ test-mir-pass: GVN
//@ compile-flags: -Zmir-enable-passes=+InstSimplify -Zdump-mir-exclude-alloc-bytes
//@ compile-flags: -Zmir-enable-passes=+InstSimplify-after-simplifycfg -Zdump-mir-exclude-alloc-bytes
// EMIT_MIR_FOR_EACH_PANIC_STRATEGY
// EMIT_MIR_FOR_EACH_BIT_WIDTH

Expand Down
2 changes: 1 addition & 1 deletion tests/mir-opt/dataflow-const-prop/slice_len.rs
Original file line number Diff line number Diff line change
@@ -1,6 +1,6 @@
// EMIT_MIR_FOR_EACH_PANIC_STRATEGY
//@ test-mir-pass: DataflowConstProp
//@ compile-flags: -Zmir-enable-passes=+InstSimplify
//@ compile-flags: -Zmir-enable-passes=+InstSimplify-after-simplifycfg
// EMIT_MIR_FOR_EACH_BIT_WIDTH

// EMIT_MIR slice_len.main.DataflowConstProp.diff
Expand Down
Original file line number Diff line number Diff line change
Expand Up @@ -21,14 +21,14 @@
bb0: {
StorageLive(_2);
StorageLive(_3);
_3 = &(*_1);
_3 = _1;
_2 = <Q as Query>::cache::<T>(move _3) -> [return: bb1, unwind unreachable];
}

bb1: {
StorageDead(_3);
StorageLive(_4);
_4 = &(*_2);
_4 = _2;
- _0 = try_execute_query::<<Q as Query>::C>(move _4) -> [return: bb2, unwind unreachable];
+ StorageLive(_5);
+ _5 = _4 as &dyn Cache<V = <Q as Query>::V> (PointerCoercion(Unsize));
Expand Down
Original file line number Diff line number Diff line change
Expand Up @@ -21,14 +21,14 @@
bb0: {
StorageLive(_2);
StorageLive(_3);
_3 = &(*_1);
_3 = _1;
_2 = <Q as Query>::cache::<T>(move _3) -> [return: bb1, unwind continue];
}

bb1: {
StorageDead(_3);
StorageLive(_4);
_4 = &(*_2);
_4 = _2;
- _0 = try_execute_query::<<Q as Query>::C>(move _4) -> [return: bb2, unwind continue];
+ StorageLive(_5);
+ _5 = _4 as &dyn Cache<V = <Q as Query>::V> (PointerCoercion(Unsize));
Expand Down
Original file line number Diff line number Diff line change
Expand Up @@ -8,7 +8,7 @@

bb0: {
StorageLive(_2);
_2 = &(*_1);
_2 = _1;
_0 = <dyn Cache<V = V> as Cache>::store_nocache(move _2) -> [return: bb1, unwind unreachable];
}

Expand Down
Original file line number Diff line number Diff line change
Expand Up @@ -8,7 +8,7 @@

bb0: {
StorageLive(_2);
_2 = &(*_1);
_2 = _1;
_0 = <dyn Cache<V = V> as Cache>::store_nocache(move _2) -> [return: bb1, unwind continue];
}

Expand Down
Original file line number Diff line number Diff line change
Expand Up @@ -13,7 +13,7 @@
bb0: {
StorageLive(_2);
StorageLive(_3);
_3 = &(*_1);
_3 = _1;
_2 = move _3 as &dyn Cache<V = <C as Cache>::V> (PointerCoercion(Unsize));
StorageDead(_3);
- _0 = mk_cycle::<<C as Cache>::V>(move _2) -> [return: bb1, unwind unreachable];
Expand Down
Original file line number Diff line number Diff line change
Expand Up @@ -13,7 +13,7 @@
bb0: {
StorageLive(_2);
StorageLive(_3);
_3 = &(*_1);
_3 = _1;
_2 = move _3 as &dyn Cache<V = <C as Cache>::V> (PointerCoercion(Unsize));
StorageDead(_3);
- _0 = mk_cycle::<<C as Cache>::V>(move _2) -> [return: bb1, unwind continue];
Expand Down
Original file line number Diff line number Diff line change
Expand Up @@ -26,9 +26,9 @@ fn foo(_1: T, _2: &i32) -> i32 {
_4 = &_3;
StorageLive(_5);
StorageLive(_6);
_6 = &(*_2);
_6 = _2;
StorageLive(_7);
_7 = &(*_2);
_7 = _2;
_5 = (move _6, move _7);
StorageLive(_8);
_8 = move (_5.0: &i32);
Expand Down
8 changes: 4 additions & 4 deletions tests/mir-opt/inline/inline_retag.bar.Inline.after.mir
Original file line number Diff line number Diff line change
Expand Up @@ -31,14 +31,14 @@ fn bar() -> bool {
StorageLive(_4);
_10 = const bar::promoted[1];
Retag(_10);
_4 = &(*_10);
_3 = &(*_4);
_4 = _10;
_3 = _4;
StorageLive(_6);
StorageLive(_7);
_9 = const bar::promoted[0];
Retag(_9);
_7 = &(*_9);
_6 = &(*_7);
_7 = _9;
_6 = _7;
Retag(_3);
Retag(_6);
StorageLive(_11);
Expand Down
Original file line number Diff line number Diff line change
Expand Up @@ -7,7 +7,7 @@ fn test(_1: &dyn X) -> u32 {

bb0: {
StorageLive(_2);
_2 = &(*_1);
_2 = _1;
_0 = <dyn X as X>::y(move _2) -> [return: bb1, unwind unreachable];
}

Expand Down
Original file line number Diff line number Diff line change
Expand Up @@ -7,7 +7,7 @@ fn test(_1: &dyn X) -> u32 {

bb0: {
StorageLive(_2);
_2 = &(*_1);
_2 = _1;
_0 = <dyn X as X>::y(move _2) -> [return: bb1, unwind continue];
}

Expand Down
Original file line number Diff line number Diff line change
Expand Up @@ -12,8 +12,8 @@ fn test2(_1: &dyn X) -> bool {
bb0: {
StorageLive(_2);
StorageLive(_3);
_3 = &(*_1);
_2 = move _3 as &dyn X (PointerCoercion(Unsize));
_3 = _1;
_2 = move _3;
StorageDead(_3);
_0 = <dyn X as X>::y(move _2) -> [return: bb1, unwind unreachable];
}
Expand Down
Original file line number Diff line number Diff line change
Expand Up @@ -12,8 +12,8 @@ fn test2(_1: &dyn X) -> bool {
bb0: {
StorageLive(_2);
StorageLive(_3);
_3 = &(*_1);
_2 = move _3 as &dyn X (PointerCoercion(Unsize));
_3 = _1;
_2 = move _3;
StorageDead(_3);
_0 = <dyn X as X>::y(move _2) -> [return: bb1, unwind continue];
}
Expand Down
Original file line number Diff line number Diff line change
Expand Up @@ -14,11 +14,11 @@ fn a(_1: &mut [T]) -> &mut [T] {
StorageLive(_2);
StorageLive(_3);
StorageLive(_4);
_4 = &mut (*_1);
_4 = _1;
_3 = _4;
_2 = &mut (*_3);
_2 = _3;
StorageDead(_4);
_0 = &mut (*_2);
_0 = _2;
StorageDead(_3);
StorageDead(_2);
return;
Expand Down
Original file line number Diff line number Diff line change
Expand Up @@ -16,17 +16,17 @@ fn b(_1: &mut Box<T>) -> &mut T {
StorageLive(_2);
StorageLive(_3);
StorageLive(_4);
_4 = &mut (*_1);
_4 = _1;
StorageLive(_5);
StorageLive(_6);
_5 = (*_4);
_6 = (((_5.0: std::ptr::Unique<T>).0: std::ptr::NonNull<T>).0: *const T);
_3 = &mut (*_6);
StorageDead(_6);
StorageDead(_5);
_2 = &mut (*_3);
_2 = _3;
StorageDead(_4);
_0 = &mut (*_2);
_0 = _2;
StorageDead(_3);
StorageDead(_2);
return;
Expand Down
Original file line number Diff line number Diff line change
Expand Up @@ -12,9 +12,9 @@ fn c(_1: &[T]) -> &[T] {
bb0: {
StorageLive(_2);
StorageLive(_3);
_3 = &(*_1);
_3 = _1;
_2 = _3;
_0 = &(*_2);
_0 = _2;
StorageDead(_3);
StorageDead(_2);
return;
Expand Down
Original file line number Diff line number Diff line change
Expand Up @@ -14,15 +14,15 @@ fn d(_1: &Box<T>) -> &T {
bb0: {
StorageLive(_2);
StorageLive(_3);
_3 = &(*_1);
_3 = _1;
StorageLive(_4);
StorageLive(_5);
_4 = (*_3);
_5 = (((_4.0: std::ptr::Unique<T>).0: std::ptr::NonNull<T>).0: *const T);
_2 = &(*_5);
StorageDead(_5);
StorageDead(_4);
_0 = &(*_2);
_0 = _2;
StorageDead(_3);
StorageDead(_2);
return;
Expand Down
Original file line number Diff line number Diff line change
@@ -1,5 +1,5 @@
- // MIR for `eq_false` before InstSimplify
+ // MIR for `eq_false` after InstSimplify
- // MIR for `eq_false` before InstSimplify-after-simplifycfg
+ // MIR for `eq_false` after InstSimplify-after-simplifycfg

fn eq_false(_1: bool) -> u32 {
debug x => _1;
Expand Down
Original file line number Diff line number Diff line change
@@ -1,5 +1,5 @@
- // MIR for `eq_true` before InstSimplify
+ // MIR for `eq_true` after InstSimplify
- // MIR for `eq_true` before InstSimplify-after-simplifycfg
+ // MIR for `eq_true` after InstSimplify-after-simplifycfg

fn eq_true(_1: bool) -> u32 {
debug x => _1;
Expand Down
Original file line number Diff line number Diff line change
@@ -1,5 +1,5 @@
- // MIR for `false_eq` before InstSimplify
+ // MIR for `false_eq` after InstSimplify
- // MIR for `false_eq` before InstSimplify-after-simplifycfg
+ // MIR for `false_eq` after InstSimplify-after-simplifycfg

fn false_eq(_1: bool) -> u32 {
debug x => _1;
Expand Down
Original file line number Diff line number Diff line change
@@ -1,5 +1,5 @@
- // MIR for `false_ne` before InstSimplify
+ // MIR for `false_ne` after InstSimplify
- // MIR for `false_ne` before InstSimplify-after-simplifycfg
+ // MIR for `false_ne` after InstSimplify-after-simplifycfg

fn false_ne(_1: bool) -> u32 {
debug x => _1;
Expand Down
Original file line number Diff line number Diff line change
@@ -1,5 +1,5 @@
- // MIR for `ne_false` before InstSimplify
+ // MIR for `ne_false` after InstSimplify
- // MIR for `ne_false` before InstSimplify-after-simplifycfg
+ // MIR for `ne_false` after InstSimplify-after-simplifycfg

fn ne_false(_1: bool) -> u32 {
debug x => _1;
Expand Down
Original file line number Diff line number Diff line change
@@ -1,5 +1,5 @@
- // MIR for `ne_true` before InstSimplify
+ // MIR for `ne_true` after InstSimplify
- // MIR for `ne_true` before InstSimplify-after-simplifycfg
+ // MIR for `ne_true` after InstSimplify-after-simplifycfg

fn ne_true(_1: bool) -> u32 {
debug x => _1;
Expand Down
18 changes: 9 additions & 9 deletions tests/mir-opt/instsimplify/bool_compare.rs
Original file line number Diff line number Diff line change
@@ -1,55 +1,55 @@
//@ test-mir-pass: InstSimplify
//@ test-mir-pass: InstSimplify-after-simplifycfg

// EMIT_MIR bool_compare.eq_true.InstSimplify.diff
// EMIT_MIR bool_compare.eq_true.InstSimplify-after-simplifycfg.diff
fn eq_true(x: bool) -> u32 {
// CHECK-LABEL: fn eq_true(
// CHECK-NOT: Eq(
if x == true { 0 } else { 1 }
}

// EMIT_MIR bool_compare.true_eq.InstSimplify.diff
// EMIT_MIR bool_compare.true_eq.InstSimplify-after-simplifycfg.diff
fn true_eq(x: bool) -> u32 {
// CHECK-LABEL: fn true_eq(
// CHECK-NOT: Eq(
if true == x { 0 } else { 1 }
}

// EMIT_MIR bool_compare.ne_true.InstSimplify.diff
// EMIT_MIR bool_compare.ne_true.InstSimplify-after-simplifycfg.diff
fn ne_true(x: bool) -> u32 {
// CHECK-LABEL: fn ne_true(
// CHECK: Not(
if x != true { 0 } else { 1 }
}

// EMIT_MIR bool_compare.true_ne.InstSimplify.diff
// EMIT_MIR bool_compare.true_ne.InstSimplify-after-simplifycfg.diff
fn true_ne(x: bool) -> u32 {
// CHECK-LABEL: fn true_ne(
// CHECK: Not(
if true != x { 0 } else { 1 }
}

// EMIT_MIR bool_compare.eq_false.InstSimplify.diff
// EMIT_MIR bool_compare.eq_false.InstSimplify-after-simplifycfg.diff
fn eq_false(x: bool) -> u32 {
// CHECK-LABEL: fn eq_false(
// CHECK: Not(
if x == false { 0 } else { 1 }
}

// EMIT_MIR bool_compare.false_eq.InstSimplify.diff
// EMIT_MIR bool_compare.false_eq.InstSimplify-after-simplifycfg.diff
fn false_eq(x: bool) -> u32 {
// CHECK-LABEL: fn false_eq(
// CHECK: Not(
if false == x { 0 } else { 1 }
}

// EMIT_MIR bool_compare.ne_false.InstSimplify.diff
// EMIT_MIR bool_compare.ne_false.InstSimplify-after-simplifycfg.diff
fn ne_false(x: bool) -> u32 {
// CHECK-LABEL: fn ne_false(
// CHECK-NOT: Ne(
if x != false { 0 } else { 1 }
}

// EMIT_MIR bool_compare.false_ne.InstSimplify.diff
// EMIT_MIR bool_compare.false_ne.InstSimplify-after-simplifycfg.diff
fn false_ne(x: bool) -> u32 {
// CHECK-LABEL: fn false_ne(
// CHECK-NOT: Ne(
Expand Down
Loading

0 comments on commit 4db3d12

Please sign in to comment.