Introduce MIR optimizations for simplifying x? on Results.
This optimization depends on inlining for the identity conversions introduced by the lowering of the `?`. To take advantage of `SimplifyArmIdentity`, `-Z mir-opt-level=2` is required because that triggers the inlining MIR optimization.
This commit is contained in:
parent
35ef33a89d
commit
2f00e86cb5
11 changed files with 432 additions and 12 deletions
|
|
@ -9,19 +9,21 @@ pub enum E {
|
|||
|
||||
// CHECK-LABEL: @exhaustive_match
|
||||
#[no_mangle]
|
||||
pub fn exhaustive_match(e: E, unit: ()) {
|
||||
pub fn exhaustive_match(e: E) -> u8 {
|
||||
// CHECK: switch{{.*}}, label %[[OTHERWISE:[a-zA-Z0-9_]+]] [
|
||||
// CHECK-NEXT: i[[TY:[0-9]+]] [[DISCR:[0-9]+]], label %[[A:[a-zA-Z0-9_]+]]
|
||||
// CHECK-NEXT: i[[TY:[0-9]+]] [[DISCR:[0-9]+]], label %[[B:[a-zA-Z0-9_]+]]
|
||||
// CHECK-NEXT: ]
|
||||
// CHECK: [[B]]:
|
||||
// CHECK-NEXT: store i8 1, i8* %1, align 1
|
||||
// CHECK-NEXT: br label %[[EXIT:[a-zA-Z0-9_]+]]
|
||||
// CHECK: [[OTHERWISE]]:
|
||||
// CHECK-NEXT: unreachable
|
||||
// CHECK: [[A]]:
|
||||
// CHECK-NEXT: store i8 0, i8* %1, align 1
|
||||
// CHECK-NEXT: br label %[[EXIT:[a-zA-Z0-9_]+]]
|
||||
match e {
|
||||
E::A => unit,
|
||||
E::B => unit,
|
||||
E::A => 0,
|
||||
E::B => 1,
|
||||
}
|
||||
}
|
||||
|
|
|
|||
17
src/test/codegen/try_identity.rs
Normal file
17
src/test/codegen/try_identity.rs
Normal file
|
|
@ -0,0 +1,17 @@
|
|||
// compile-flags: -C no-prepopulate-passes -Z mir-opt-level=2
|
||||
|
||||
// Ensure that `x?` has no overhead on `Result<T, E>` due to identity `match`es in lowering.
|
||||
// This requires inlining to trigger the MIR optimizations in `SimplifyArmIdentity`.
|
||||
|
||||
#![crate_type = "lib"]
|
||||
|
||||
type R = Result<u64, i32>;
|
||||
|
||||
#[no_mangle]
|
||||
fn try_identity(x: R) -> R {
|
||||
// CHECK: start:
|
||||
// CHECK-NOT: br {{.*}}
|
||||
// CHECK ret void
|
||||
let y = x?;
|
||||
Ok(y)
|
||||
}
|
||||
193
src/test/mir-opt/simplify_try.rs
Normal file
193
src/test/mir-opt/simplify_try.rs
Normal file
|
|
@ -0,0 +1,193 @@
|
|||
fn try_identity(x: Result<u32, i32>) -> Result<u32, i32> {
|
||||
let y = x?;
|
||||
Ok(y)
|
||||
}
|
||||
|
||||
fn main() {
|
||||
let _ = try_identity(Ok(0));
|
||||
}
|
||||
|
||||
// END RUST SOURCE
|
||||
// START rustc.try_identity.SimplifyArmIdentity.before.mir
|
||||
// fn try_identity(_1: std::result::Result<u32, i32>) -> std::result::Result<u32, i32> {
|
||||
// let mut _0: std::result::Result<u32, i32>;
|
||||
// let _2: u32;
|
||||
// let mut _3: std::result::Result<u32, i32>;
|
||||
// let mut _4: std::result::Result<u32, i32>;
|
||||
// let mut _5: isize;
|
||||
// let _6: i32;
|
||||
// let mut _7: !;
|
||||
// let mut _8: i32;
|
||||
// let mut _9: i32;
|
||||
// let _10: u32;
|
||||
// let mut _11: u32;
|
||||
// scope 1 {
|
||||
// }
|
||||
// scope 2 {
|
||||
// scope 3 {
|
||||
// scope 7 {
|
||||
// }
|
||||
// scope 8 {
|
||||
// let mut _12: i32;
|
||||
// }
|
||||
// }
|
||||
// }
|
||||
// scope 4 {
|
||||
// scope 5 {
|
||||
// }
|
||||
// }
|
||||
// scope 6 {
|
||||
// }
|
||||
// bb0: {
|
||||
// _5 = discriminant(_1);
|
||||
// switchInt(move _5) -> [0isize: bb4, 1isize: bb2, otherwise: bb1];
|
||||
// }
|
||||
// bb1: {
|
||||
// unreachable;
|
||||
// }
|
||||
// bb2: {
|
||||
// _6 = ((_1 as Err).0: i32);
|
||||
// ((_0 as Err).0: i32) = move _6;
|
||||
// discriminant(_0) = 1;
|
||||
// goto -> bb3;
|
||||
// }
|
||||
// bb3: {
|
||||
// return;
|
||||
// }
|
||||
// bb4: {
|
||||
// _10 = ((_1 as Ok).0: u32);
|
||||
// ((_0 as Ok).0: u32) = move _10;
|
||||
// discriminant(_0) = 0;
|
||||
// goto -> bb3;
|
||||
// }
|
||||
// }
|
||||
// END rustc.try_identity.SimplifyArmIdentity.before.mir
|
||||
|
||||
// START rustc.try_identity.SimplifyArmIdentity.after.mir
|
||||
// fn try_identity(_1: std::result::Result<u32, i32>) -> std::result::Result<u32, i32> {
|
||||
// let mut _0: std::result::Result<u32, i32>;
|
||||
// let _2: u32;
|
||||
// let mut _3: std::result::Result<u32, i32>;
|
||||
// let mut _4: std::result::Result<u32, i32>;
|
||||
// let mut _5: isize;
|
||||
// let _6: i32;
|
||||
// let mut _7: !;
|
||||
// let mut _8: i32;
|
||||
// let mut _9: i32;
|
||||
// let _10: u32;
|
||||
// let mut _11: u32;
|
||||
// scope 1 {
|
||||
// }
|
||||
// scope 2 {
|
||||
// scope 3 {
|
||||
// scope 7 {
|
||||
// }
|
||||
// scope 8 {
|
||||
// let mut _12: i32;
|
||||
// }
|
||||
// }
|
||||
// }
|
||||
// scope 4 {
|
||||
// scope 5 {
|
||||
// }
|
||||
// }
|
||||
// scope 6 {
|
||||
// }
|
||||
// bb0: {
|
||||
// _5 = discriminant(_1);
|
||||
// switchInt(move _5) -> [0isize: bb4, 1isize: bb2, otherwise: bb1];
|
||||
// }
|
||||
// bb1: {
|
||||
// unreachable;
|
||||
// }
|
||||
// bb2: {
|
||||
// _0 = move _1;
|
||||
// nop;
|
||||
// nop;
|
||||
// goto -> bb3;
|
||||
// }
|
||||
// bb3: {
|
||||
// return;
|
||||
// }
|
||||
// bb4: {
|
||||
// _0 = move _1;
|
||||
// nop;
|
||||
// nop;
|
||||
// goto -> bb3;
|
||||
// }
|
||||
// }
|
||||
// END rustc.try_identity.SimplifyArmIdentity.after.mir
|
||||
|
||||
// START rustc.try_identity.SimplifyBranchSame.after.mir
|
||||
// fn try_identity(_1: std::result::Result<u32, i32>) -> std::result::Result<u32, i32> {
|
||||
// let mut _0: std::result::Result<u32, i32>;
|
||||
// let _2: u32;
|
||||
// let mut _3: std::result::Result<u32, i32>;
|
||||
// let mut _4: std::result::Result<u32, i32>;
|
||||
// let mut _5: isize;
|
||||
// let _6: i32;
|
||||
// let mut _7: !;
|
||||
// let mut _8: i32;
|
||||
// let mut _9: i32;
|
||||
// let _10: u32;
|
||||
// let mut _11: u32;
|
||||
// scope 1 {
|
||||
// }
|
||||
// scope 2 {
|
||||
// scope 3 {
|
||||
// scope 7 {
|
||||
// }
|
||||
// scope 8 {
|
||||
// let mut _12: i32;
|
||||
// }
|
||||
// }
|
||||
// }
|
||||
// scope 4 {
|
||||
// scope 5 {
|
||||
// }
|
||||
// }
|
||||
// scope 6 {
|
||||
// }
|
||||
// bb0: {
|
||||
// _5 = discriminant(_1);
|
||||
// goto -> bb2;
|
||||
// }
|
||||
// bb1: {
|
||||
// return;
|
||||
// }
|
||||
// bb2: {
|
||||
// _0 = move _1;
|
||||
// nop;
|
||||
// nop;
|
||||
// goto -> bb1;
|
||||
// }
|
||||
// }
|
||||
// END rustc.try_identity.SimplifyBranchSame.after.mir
|
||||
|
||||
// START rustc.try_identity.SimplifyLocals.after.mir
|
||||
// fn try_identity(_1: std::result::Result<u32, i32>) -> std::result::Result<u32, i32> {
|
||||
// let mut _0: std::result::Result<u32, i32>;
|
||||
// let mut _2: isize;
|
||||
// scope 1 {
|
||||
// }
|
||||
// scope 2 {
|
||||
// scope 3 {
|
||||
// scope 7 {
|
||||
// }
|
||||
// scope 8 {
|
||||
// }
|
||||
// }
|
||||
// }
|
||||
// scope 4 {
|
||||
// scope 5 {
|
||||
// }
|
||||
// }
|
||||
// scope 6 {
|
||||
// }
|
||||
// bb0: {
|
||||
// _2 = discriminant(_1);
|
||||
// _0 = move _1;
|
||||
// return;
|
||||
// }
|
||||
// }
|
||||
// END rustc.try_identity.SimplifyLocals.after.mir
|
||||
Loading…
Add table
Add a link
Reference in a new issue