Skip to content

Commit

Permalink
Implement a few basic InstCombine optimizations
Browse files Browse the repository at this point in the history
  • Loading branch information
saethlin committed Jun 16, 2023
1 parent 6bba061 commit 9949d31
Show file tree
Hide file tree
Showing 31 changed files with 1,211 additions and 458 deletions.
424 changes: 424 additions & 0 deletions compiler/rustc_mir_transform/src/instcombine.rs

Large diffs are not rendered by default.

2 changes: 2 additions & 0 deletions compiler/rustc_mir_transform/src/lib.rs
Original file line number Diff line number Diff line change
Expand Up @@ -76,6 +76,7 @@ mod ffi_unwind_calls;
mod function_item_references;
mod generator;
mod inline;
mod instcombine;
mod instsimplify;
mod large_enums;
mod lower_intrinsics;
Expand Down Expand Up @@ -575,6 +576,7 @@ fn run_optimization_passes<'tcx>(tcx: TyCtxt<'tcx>, body: &mut Body<'tcx>) {
&simplify_comparison_integral::SimplifyComparisonIntegral,
&dead_store_elimination::DeadStoreElimination,
&dest_prop::DestinationPropagation,
&instcombine::InstCombine,
&o1(simplify_branches::SimplifyConstCondition::Final),
&o1(remove_noop_landing_pads::RemoveNoopLandingPads),
&o1(simplify::SimplifyCfg::Final),
Expand Down
6 changes: 1 addition & 5 deletions tests/mir-opt/casts.roundtrip.PreCodegen.after.mir
Original file line number Diff line number Diff line change
Expand Up @@ -3,13 +3,9 @@
fn roundtrip(_1: *const u8) -> *const u8 {
debug x => _1;
let mut _0: *const u8;
let mut _2: *mut u8;

bb0: {
StorageLive(_2);
_2 = _1 as *mut u8 (PtrToPtr);
_0 = move _2 as *const u8 (Pointer(MutToConstPointer));
StorageDead(_2);
_0 = _1 as *const u8 (PtrToPtr);
return;
}
}
Original file line number Diff line number Diff line change
Expand Up @@ -158,13 +158,11 @@
+ StorageLive(_17);
+ StorageLive(_18);
+ _18 = (_11.0: *const [u8]);
+ _17 = move _18 as *mut [u8] (PtrToPtr);
+ StorageDead(_18);
+ _16 = _17 as *mut u8 (PtrToPtr);
+ StorageDead(_17);
+ StorageLive(_19);
+ _19 = move _18 as *const u8 (PtrToPtr);
+ StorageDead(_18);
+ StorageLive(_20);
+ _19 = _16 as *const u8 (Pointer(MutToConstPointer));
+ StorageDead(_17);
+ _15 = NonNull::<u8> { pointer: _19 };
+ StorageDead(_20);
+ StorageDead(_19);
Expand Down
Original file line number Diff line number Diff line change
Expand Up @@ -175,13 +175,11 @@
+ StorageLive(_17);
+ StorageLive(_18);
+ _18 = (_11.0: *const [u8]);
+ _17 = move _18 as *mut [u8] (PtrToPtr);
+ StorageDead(_18);
+ _16 = _17 as *mut u8 (PtrToPtr);
+ StorageDead(_17);
+ StorageLive(_19);
+ _19 = move _18 as *const u8 (PtrToPtr);
+ StorageDead(_18);
+ StorageLive(_20);
+ _19 = _16 as *const u8 (Pointer(MutToConstPointer));
+ StorageDead(_17);
+ _15 = NonNull::<u8> { pointer: _19 };
+ StorageDead(_20);
+ StorageDead(_19);
Expand Down
Original file line number Diff line number Diff line change
@@ -0,0 +1,22 @@
- // MIR for `place_projection` before InstCombine
+ // MIR for `place_projection` after InstCombine

fn place_projection(_1: Outer) -> u8 {
debug o => _1;
let mut _0: u8;
let _2: Inner;
scope 1 {
debug temp => _2;
}

bb0: {
StorageLive(_2);
- _2 = move (_1.0: Inner);
- _0 = (_2.0: u8);
+ _0 = ((_1.0: Inner).0: u8);
+ nop;
StorageDead(_2);
return;
}
}

16 changes: 16 additions & 0 deletions tests/mir-opt/instcombine/place_projection.rs
Original file line number Diff line number Diff line change
@@ -0,0 +1,16 @@
// unit-test: InstCombine
#![crate_type = "lib"]

pub struct Outer {
inner: Inner,
}

struct Inner {
field: u8,
}

// EMIT_MIR place_projection.place_projection.InstCombine.diff
pub fn place_projection(o: Outer) -> u8 {
let temp = o.inner;
temp.field
}
23 changes: 23 additions & 0 deletions tests/mir-opt/instcombine/ptr_cast.ptr_cast.InstCombine.diff
Original file line number Diff line number Diff line change
@@ -0,0 +1,23 @@
- // MIR for `ptr_cast` before InstCombine
+ // MIR for `ptr_cast` after InstCombine

fn ptr_cast(_1: *const u8) -> *mut () {
debug p => _1;
let mut _0: *mut ();
let mut _2: *mut u8;
let mut _3: *const u8;

bb0: {
StorageLive(_2);
StorageLive(_3);
_3 = _1;
- _2 = move _3 as *mut u8 (PtrToPtr);
+ _0 = move _3 as *mut () (PtrToPtr);
+ nop;
StorageDead(_3);
- _0 = move _2 as *mut () (PtrToPtr);
StorageDead(_2);
return;
}
}

7 changes: 7 additions & 0 deletions tests/mir-opt/instcombine/ptr_cast.rs
Original file line number Diff line number Diff line change
@@ -0,0 +1,7 @@
// unit-test: InstCombine
#![crate_type = "lib"]

// EMIT_MIR ptr_cast.ptr_cast.InstCombine.diff
pub fn ptr_cast(p: *const u8) -> *mut () {
p as *mut u8 as *mut ()
}
Original file line number Diff line number Diff line change
@@ -0,0 +1,44 @@
- // MIR for `ref_addressof` before InstCombine
+ // MIR for `ref_addressof` after InstCombine

fn ref_addressof(_1: T) -> () {
debug t => _1;
let mut _0: ();
let _2: &T;
let _4: ();
let mut _5: *const T;
scope 1 {
debug r => _2;
let _3: *const T;
scope 2 {
debug ptr => _3;
}
}

bb0: {
StorageLive(_2);
- _2 = &_1;
StorageLive(_3);
- _3 = &raw const (*_2);
+ _3 = &raw const _1;
+ nop;
StorageLive(_4);
StorageLive(_5);
_5 = _3;
_4 = std::mem::drop::<*const T>(move _5) -> [return: bb1, unwind unreachable];
}

bb1: {
StorageDead(_5);
StorageDead(_4);
_0 = const ();
StorageDead(_3);
StorageDead(_2);
drop(_1) -> [return: bb2, unwind unreachable];
}

bb2: {
return;
}
}

9 changes: 9 additions & 0 deletions tests/mir-opt/instcombine/ref_addressof.rs
Original file line number Diff line number Diff line change
@@ -0,0 +1,9 @@
// unit-test: InstCombine
#![crate_type = "lib"]

// EMIT_MIR ref_addressof.ref_addressof.InstCombine.diff
pub fn ref_addressof<T>(t: T) {
let r = &t;
let ptr = std::ptr::addr_of!(*r);
drop(ptr);
}
22 changes: 22 additions & 0 deletions tests/mir-opt/instcombine/ref_deref.ref_deref.InstCombine.diff
Original file line number Diff line number Diff line change
@@ -0,0 +1,22 @@
- // MIR for `ref_deref` before InstCombine
+ // MIR for `ref_deref` after InstCombine

fn ref_deref(_1: T) -> T {
debug t => _1;
let mut _0: T;
let _2: &T;
scope 1 {
debug r => _2;
}

bb0: {
StorageLive(_2);
- _2 = &_1;
- _0 = (*_2);
+ _0 = _1;
+ nop;
StorageDead(_2);
return;
}
}

8 changes: 8 additions & 0 deletions tests/mir-opt/instcombine/ref_deref.rs
Original file line number Diff line number Diff line change
@@ -0,0 +1,8 @@
// unit-test: InstCombine
#![crate_type = "lib"]

// EMIT_MIR ref_deref.ref_deref.InstCombine.diff
pub fn ref_deref<T: Copy>(t: T) -> T {
let r = &t;
*r
}
18 changes: 18 additions & 0 deletions tests/mir-opt/nested_getter.outer_get.InstCombine.diff
Original file line number Diff line number Diff line change
@@ -0,0 +1,18 @@
- // MIR for `outer_get` before InstCombine
+ // MIR for `outer_get` after InstCombine

fn outer_get(_1: &Outer) -> u8 {
debug this => _1;
let mut _0: u8;
let mut _2: &Inner;
let _3: &Inner;
scope 1 (inlined inner_get) {
debug this => &((*_1).0: Inner);
}

bb0: {
_0 = (((*_1).0: Inner).0: u8);
return;
}
}

56 changes: 26 additions & 30 deletions tests/mir-opt/pre-codegen/loops.filter_mapped.PreCodegen.after.mir
Original file line number Diff line number Diff line change
Expand Up @@ -6,76 +6,72 @@ fn filter_mapped(_1: impl Iterator<Item = T>, _2: impl Fn(T) -> Option<U>) -> ()
let mut _0: ();
let mut _3: std::iter::FilterMap<impl Iterator<Item = T>, impl Fn(T) -> Option<U>>;
let mut _4: std::iter::FilterMap<impl Iterator<Item = T>, impl Fn(T) -> Option<U>>;
let mut _5: std::iter::FilterMap<impl Iterator<Item = T>, impl Fn(T) -> Option<U>>;
let mut _6: &mut std::iter::FilterMap<impl Iterator<Item = T>, impl Fn(T) -> Option<U>>;
let mut _9: std::option::Option<U>;
let mut _10: isize;
let _12: ();
let mut _5: &mut std::iter::FilterMap<impl Iterator<Item = T>, impl Fn(T) -> Option<U>>;
let mut _8: std::option::Option<U>;
let mut _9: isize;
let _11: ();
scope 1 {
debug iter => _5;
let _11: U;
debug iter => _4;
let _10: U;
scope 2 {
debug x => _11;
debug x => _10;
}
scope 4 (inlined <FilterMap<impl Iterator<Item = T>, impl Fn(T) -> Option<U>> as Iterator>::next) {
debug self => _6;
let mut _7: &mut impl Iterator<Item = T>;
let mut _8: &mut impl Fn(T) -> Option<U>;
debug self => _5;
let mut _6: &mut impl Iterator<Item = T>;
let mut _7: &mut impl Fn(T) -> Option<U>;
}
}
scope 3 (inlined <FilterMap<impl Iterator<Item = T>, impl Fn(T) -> Option<U>> as IntoIterator>::into_iter) {
debug self => _3;
}

bb0: {
StorageLive(_4);
StorageLive(_3);
_3 = <impl Iterator<Item = T> as Iterator>::filter_map::<U, impl Fn(T) -> Option<U>>(move _1, move _2) -> bb1;
}

bb1: {
StorageLive(_4);
_4 = move _3;
StorageDead(_3);
StorageLive(_5);
_5 = move _4;
goto -> bb2;
}

bb2: {
StorageLive(_9);
_6 = &mut _5;
StorageLive(_7);
_7 = &mut ((*_6).0: impl Iterator<Item = T>);
StorageLive(_8);
_8 = &mut ((*_6).1: impl Fn(T) -> Option<U>);
_9 = <impl Iterator<Item = T> as Iterator>::find_map::<U, &mut impl Fn(T) -> Option<U>>(move _7, move _8) -> [return: bb3, unwind: bb9];
_5 = &mut _4;
StorageLive(_6);
_6 = &mut ((*_5).0: impl Iterator<Item = T>);
StorageLive(_7);
_7 = &mut ((*_5).1: impl Fn(T) -> Option<U>);
_8 = <impl Iterator<Item = T> as Iterator>::find_map::<U, &mut impl Fn(T) -> Option<U>>(move _6, move _7) -> [return: bb3, unwind: bb9];
}

bb3: {
StorageDead(_8);
StorageDead(_7);
_10 = discriminant(_9);
switchInt(move _10) -> [0: bb4, 1: bb6, otherwise: bb8];
StorageDead(_6);
_9 = discriminant(_8);
switchInt(move _9) -> [0: bb4, 1: bb6, otherwise: bb8];
}

bb4: {
StorageDead(_9);
drop(_5) -> bb5;
StorageDead(_8);
drop(_4) -> bb5;
}

bb5: {
StorageDead(_5);
StorageDead(_4);
return;
}

bb6: {
_11 = move ((_9 as Some).0: U);
_12 = opaque::<U>(move _11) -> [return: bb7, unwind: bb9];
_10 = move ((_8 as Some).0: U);
_11 = opaque::<U>(move _10) -> [return: bb7, unwind: bb9];
}

bb7: {
StorageDead(_9);
StorageDead(_8);
goto -> bb2;
}

Expand All @@ -84,7 +80,7 @@ fn filter_mapped(_1: impl Iterator<Item = T>, _2: impl Fn(T) -> Option<U>) -> ()
}

bb9 (cleanup): {
drop(_5) -> [return: bb10, unwind terminate];
drop(_4) -> [return: bb10, unwind terminate];
}

bb10 (cleanup): {
Expand Down
Loading

0 comments on commit 9949d31

Please sign in to comment.