1
Fork 0

Explicitly don't inline user-written rust-call fns

This commit is contained in:
Michael Goulet 2023-06-30 21:40:47 +00:00
parent 0391af0e1f
commit 3c9549b349
13 changed files with 102 additions and 201 deletions

View file

@ -222,7 +222,14 @@ impl<'tcx> Inliner<'tcx> {
trace!(?output_type, ?destination_ty); trace!(?output_type, ?destination_ty);
return Err("failed to normalize return type"); return Err("failed to normalize return type");
} }
if callsite.fn_sig.abi() == Abi::RustCall && callee_body.spread_arg.is_none() { if callsite.fn_sig.abi() == Abi::RustCall {
// FIXME: Don't inline user-written `extern "rust-call"` functions,
// since this is generally perf-negative on rustc, and we hope that
// LLVM will inline these functions instead.
if callee_body.spread_arg.is_some() {
return Err("do not inline user-written rust-call functions");
}
let (self_arg, arg_tuple) = match &args[..] { let (self_arg, arg_tuple) = match &args[..] {
[arg_tuple] => (None, arg_tuple), [arg_tuple] => (None, arg_tuple),
[self_arg, arg_tuple] => (Some(self_arg), arg_tuple), [self_arg, arg_tuple] => (Some(self_arg), arg_tuple),

View file

@ -5,13 +5,10 @@
let mut _0: (); let mut _0: ();
let _1: (); let _1: ();
+ let mut _2: fn() {main}; + let mut _2: fn() {main};
+ let mut _5: ();
+ scope 1 (inlined f::<fn() {main}>) { + scope 1 (inlined f::<fn() {main}>) {
+ debug g => _2; + debug g => _2;
+ let mut _3: &fn() {main}; + let mut _3: &fn() {main};
+ let _4: (); + let _4: ();
+ scope 2 (inlined <fn() {main} as Fn<()>>::call - shim(fn() {main})) {
+ }
+ } + }
bb0: { bb0: {
@ -22,9 +19,7 @@
+ StorageLive(_4); + StorageLive(_4);
+ StorageLive(_3); + StorageLive(_3);
+ _3 = &_2; + _3 = &_2;
+ StorageLive(_5); + _4 = <fn() {main} as Fn<()>>::call(move _3, const ()) -> [return: bb2, unwind unreachable];
+ _5 = const ();
+ _4 = move (*_3)() -> [return: bb2, unwind unreachable];
} }
bb1: { bb1: {
@ -36,7 +31,6 @@
+ } + }
+ +
+ bb2: { + bb2: {
+ StorageDead(_5);
+ StorageDead(_3); + StorageDead(_3);
+ drop(_2) -> [return: bb1, unwind unreachable]; + drop(_2) -> [return: bb1, unwind unreachable];
} }

View file

@ -5,13 +5,10 @@
let mut _0: (); let mut _0: ();
let _1: (); let _1: ();
+ let mut _2: fn() {main}; + let mut _2: fn() {main};
+ let mut _5: ();
+ scope 1 (inlined f::<fn() {main}>) { + scope 1 (inlined f::<fn() {main}>) {
+ debug g => _2; + debug g => _2;
+ let mut _3: &fn() {main}; + let mut _3: &fn() {main};
+ let _4: (); + let _4: ();
+ scope 2 (inlined <fn() {main} as Fn<()>>::call - shim(fn() {main})) {
+ }
+ } + }
bb0: { bb0: {
@ -22,9 +19,7 @@
+ StorageLive(_4); + StorageLive(_4);
+ StorageLive(_3); + StorageLive(_3);
+ _3 = &_2; + _3 = &_2;
+ StorageLive(_5); + _4 = <fn() {main} as Fn<()>>::call(move _3, const ()) -> [return: bb2, unwind: bb3];
+ _5 = const ();
+ _4 = move (*_3)() -> [return: bb4, unwind: bb2];
} }
bb1: { bb1: {
@ -35,18 +30,17 @@
return; return;
+ } + }
+ +
+ bb2 (cleanup): { + bb2: {
+ drop(_2) -> [return: bb3, unwind terminate]; + StorageDead(_3);
+ drop(_2) -> [return: bb1, unwind continue];
+ } + }
+ +
+ bb3 (cleanup): { + bb3 (cleanup): {
+ resume; + drop(_2) -> [return: bb4, unwind terminate];
+ } + }
+ +
+ bb4: { + bb4 (cleanup): {
+ StorageDead(_5); + resume;
+ StorageDead(_3);
+ drop(_2) -> [return: bb1, unwind continue];
} }
} }

View file

@ -5,21 +5,10 @@
let mut _0: (); let mut _0: ();
let _1: (); let _1: ();
+ let mut _2: fn() {g}; + let mut _2: fn() {g};
+ let mut _5: ();
+ scope 1 (inlined f::<fn() {g}>) { + scope 1 (inlined f::<fn() {g}>) {
+ debug g => _2; + debug g => _2;
+ let mut _3: &fn() {g}; + let mut _3: &fn() {g};
+ let _4: (); + let _4: ();
+ scope 2 (inlined <fn() {g} as Fn<()>>::call - shim(fn() {g})) {
+ scope 3 (inlined g) {
+ scope 4 (inlined f::<fn() {main}>) {
+ debug g => main;
+ let _6: ();
+ scope 5 (inlined <fn() {main} as Fn<()>>::call - shim(fn() {main})) {
+ }
+ }
+ }
+ }
+ } + }
bb0: { bb0: {
@ -30,10 +19,7 @@
+ StorageLive(_4); + StorageLive(_4);
+ StorageLive(_3); + StorageLive(_3);
+ _3 = &_2; + _3 = &_2;
+ StorageLive(_5); + _4 = <fn() {g} as Fn<()>>::call(move _3, const ()) -> [return: bb2, unwind unreachable];
+ _5 = const ();
+ StorageLive(_6);
+ _6 = main() -> [return: bb2, unwind unreachable];
} }
bb1: { bb1: {
@ -45,8 +31,6 @@
+ } + }
+ +
+ bb2: { + bb2: {
+ StorageDead(_6);
+ StorageDead(_5);
+ StorageDead(_3); + StorageDead(_3);
+ drop(_2) -> [return: bb1, unwind unreachable]; + drop(_2) -> [return: bb1, unwind unreachable];
} }

View file

@ -5,21 +5,10 @@
let mut _0: (); let mut _0: ();
let _1: (); let _1: ();
+ let mut _2: fn() {g}; + let mut _2: fn() {g};
+ let mut _5: ();
+ scope 1 (inlined f::<fn() {g}>) { + scope 1 (inlined f::<fn() {g}>) {
+ debug g => _2; + debug g => _2;
+ let mut _3: &fn() {g}; + let mut _3: &fn() {g};
+ let _4: (); + let _4: ();
+ scope 2 (inlined <fn() {g} as Fn<()>>::call - shim(fn() {g})) {
+ scope 3 (inlined g) {
+ scope 4 (inlined f::<fn() {main}>) {
+ debug g => main;
+ let _6: ();
+ scope 5 (inlined <fn() {main} as Fn<()>>::call - shim(fn() {main})) {
+ }
+ }
+ }
+ }
+ } + }
bb0: { bb0: {
@ -30,10 +19,7 @@
+ StorageLive(_4); + StorageLive(_4);
+ StorageLive(_3); + StorageLive(_3);
+ _3 = &_2; + _3 = &_2;
+ StorageLive(_5); + _4 = <fn() {g} as Fn<()>>::call(move _3, const ()) -> [return: bb2, unwind: bb3];
+ _5 = const ();
+ StorageLive(_6);
+ _6 = main() -> [return: bb4, unwind: bb2];
} }
bb1: { bb1: {
@ -44,19 +30,17 @@
return; return;
+ } + }
+ +
+ bb2 (cleanup): { + bb2: {
+ drop(_2) -> [return: bb3, unwind terminate]; + StorageDead(_3);
+ drop(_2) -> [return: bb1, unwind continue];
+ } + }
+ +
+ bb3 (cleanup): { + bb3 (cleanup): {
+ resume; + drop(_2) -> [return: bb4, unwind terminate];
+ } + }
+ +
+ bb4: { + bb4 (cleanup): {
+ StorageDead(_6); + resume;
+ StorageDead(_5);
+ StorageDead(_3);
+ drop(_2) -> [return: bb1, unwind continue];
} }
} }

View file

@ -7,40 +7,23 @@
let mut _0: (); let mut _0: ();
let mut _3: &mut std::boxed::Box<dyn std::ops::FnMut<I, Output = ()>>; let mut _3: &mut std::boxed::Box<dyn std::ops::FnMut<I, Output = ()>>;
let mut _4: I; let mut _4: I;
+ scope 1 (inlined <Box<dyn FnMut<I, Output = ()>> as FnMut<I>>::call_mut) {
+ debug self => _3;
+ debug args => _4;
+ let mut _5: &mut dyn std::ops::FnMut<I, Output = ()>;
+ let mut _6: std::boxed::Box<dyn std::ops::FnMut<I, Output = ()>>;
+ let mut _7: *const dyn std::ops::FnMut<I, Output = ()>;
+ }
bb0: { bb0: {
StorageLive(_3); StorageLive(_3);
_3 = &mut _1; _3 = &mut _1;
StorageLive(_4); StorageLive(_4);
_4 = move _2; _4 = move _2;
- _0 = <Box<dyn FnMut<I, Output = ()>> as FnMut<I>>::call_mut(move _3, move _4) -> [return: bb1, unwind unreachable]; _0 = <Box<dyn FnMut<I, Output = ()>> as FnMut<I>>::call_mut(move _3, move _4) -> [return: bb1, unwind unreachable];
+ StorageLive(_5);
+ _6 = deref_copy (*_3);
+ _7 = (((_6.0: std::ptr::Unique<dyn std::ops::FnMut<I, Output = ()>>).0: std::ptr::NonNull<dyn std::ops::FnMut<I, Output = ()>>).0: *const dyn std::ops::FnMut<I, Output = ()>);
+ _5 = &mut (*_7);
+ _0 = <dyn FnMut<I, Output = ()> as FnMut<I>>::call_mut(move _5, move _4) -> [return: bb2, unwind unreachable];
} }
bb1: { bb1: {
- StorageDead(_4); StorageDead(_4);
- StorageDead(_3); StorageDead(_3);
- drop(_1) -> [return: bb2, unwind unreachable]; drop(_1) -> [return: bb2, unwind unreachable];
+ return;
} }
bb2: { bb2: {
- return; return;
+ StorageDead(_5);
+ StorageDead(_4);
+ StorageDead(_3);
+ drop(_1) -> [return: bb1, unwind unreachable];
} }
} }

View file

@ -7,13 +7,6 @@
let _2: (); let _2: ();
let mut _3: &std::boxed::Box<dyn std::ops::Fn(i32)>; let mut _3: &std::boxed::Box<dyn std::ops::Fn(i32)>;
let mut _4: (i32,); let mut _4: (i32,);
+ scope 1 (inlined <Box<dyn Fn(i32)> as Fn<(i32,)>>::call) {
+ debug self => _3;
+ debug args => _4;
+ let mut _5: &dyn std::ops::Fn(i32);
+ let mut _6: std::boxed::Box<dyn std::ops::Fn(i32)>;
+ let mut _7: *const dyn std::ops::Fn(i32);
+ }
bb0: { bb0: {
StorageLive(_2); StorageLive(_2);
@ -21,30 +14,19 @@
_3 = &_1; _3 = &_1;
StorageLive(_4); StorageLive(_4);
_4 = (const 1_i32,); _4 = (const 1_i32,);
- _2 = <Box<dyn Fn(i32)> as Fn<(i32,)>>::call(move _3, move _4) -> [return: bb1, unwind unreachable]; _2 = <Box<dyn Fn(i32)> as Fn<(i32,)>>::call(move _3, move _4) -> [return: bb1, unwind unreachable];
+ StorageLive(_5);
+ _6 = deref_copy (*_3);
+ _7 = (((_6.0: std::ptr::Unique<dyn std::ops::Fn(i32)>).0: std::ptr::NonNull<dyn std::ops::Fn(i32)>).0: *const dyn std::ops::Fn(i32));
+ _5 = &(*_7);
+ _2 = <dyn Fn(i32) as Fn<(i32,)>>::call(move _5, move _4) -> [return: bb2, unwind unreachable];
} }
bb1: { bb1: {
+ return;
+ }
+
+ bb2: {
+ StorageDead(_5);
StorageDead(_4); StorageDead(_4);
StorageDead(_3); StorageDead(_3);
StorageDead(_2); StorageDead(_2);
_0 = const (); _0 = const ();
- drop(_1) -> [return: bb2, unwind unreachable]; drop(_1) -> [return: bb2, unwind unreachable];
- } }
-
- bb2: { bb2: {
- return; return;
+ drop(_1) -> [return: bb1, unwind unreachable];
} }
} }

View file

@ -5,20 +5,9 @@
let mut _0: (); let mut _0: ();
let _1: (); let _1: ();
+ let mut _2: fn() {f}; + let mut _2: fn() {f};
+ let mut _4: ();
+ scope 1 (inlined call::<fn() {f}>) { + scope 1 (inlined call::<fn() {f}>) {
+ debug f => _2; + debug f => _2;
+ let _3: (); + let _3: ();
+ scope 2 (inlined <fn() {f} as FnOnce<()>>::call_once - shim(fn() {f})) {
+ scope 3 (inlined f) {
+ scope 4 (inlined call::<fn() {f}>) {
+ debug f => f;
+ let _5: ();
+ scope 5 (inlined <fn() {f} as FnOnce<()>>::call_once - shim(fn() {f})) {
+ }
+ }
+ }
+ }
+ } + }
bb0: { bb0: {
@ -27,15 +16,10 @@
+ StorageLive(_2); + StorageLive(_2);
+ _2 = f; + _2 = f;
+ StorageLive(_3); + StorageLive(_3);
+ StorageLive(_4); + _3 = <fn() {f} as FnOnce<()>>::call_once(move _2, const ()) -> [return: bb1, unwind unreachable];
+ _4 = const ();
+ StorageLive(_5);
+ _5 = f() -> [return: bb1, unwind unreachable];
} }
bb1: { bb1: {
+ StorageDead(_5);
+ StorageDead(_4);
+ StorageDead(_3); + StorageDead(_3);
+ StorageDead(_2); + StorageDead(_2);
StorageDead(_1); StorageDead(_1);

View file

@ -5,20 +5,9 @@
let mut _0: (); let mut _0: ();
let _1: (); let _1: ();
+ let mut _2: fn() {f}; + let mut _2: fn() {f};
+ let mut _4: ();
+ scope 1 (inlined call::<fn() {f}>) { + scope 1 (inlined call::<fn() {f}>) {
+ debug f => _2; + debug f => _2;
+ let _3: (); + let _3: ();
+ scope 2 (inlined <fn() {f} as FnOnce<()>>::call_once - shim(fn() {f})) {
+ scope 3 (inlined f) {
+ scope 4 (inlined call::<fn() {f}>) {
+ debug f => f;
+ let _5: ();
+ scope 5 (inlined <fn() {f} as FnOnce<()>>::call_once - shim(fn() {f})) {
+ }
+ }
+ }
+ }
+ } + }
bb0: { bb0: {
@ -27,15 +16,10 @@
+ StorageLive(_2); + StorageLive(_2);
+ _2 = f; + _2 = f;
+ StorageLive(_3); + StorageLive(_3);
+ StorageLive(_4); + _3 = <fn() {f} as FnOnce<()>>::call_once(move _2, const ()) -> [return: bb1, unwind continue];
+ _4 = const ();
+ StorageLive(_5);
+ _5 = f() -> [return: bb1, unwind continue];
} }
bb1: { bb1: {
+ StorageDead(_5);
+ StorageDead(_4);
+ StorageDead(_3); + StorageDead(_3);
+ StorageDead(_2); + StorageDead(_2);
StorageDead(_1); StorageDead(_1);

View file

@ -5,7 +5,6 @@
let mut _0: (); let mut _0: ();
let _1: (!, !); let _1: (!, !);
+ let mut _2: fn() -> ! {sleep}; + let mut _2: fn() -> ! {sleep};
+ let mut _7: ();
+ scope 1 (inlined call_twice::<!, fn() -> ! {sleep}>) { + scope 1 (inlined call_twice::<!, fn() -> ! {sleep}>) {
+ debug f => _2; + debug f => _2;
+ let mut _3: &fn() -> ! {sleep}; + let mut _3: &fn() -> ! {sleep};
@ -18,10 +17,6 @@
+ debug b => _6; + debug b => _6;
+ } + }
+ } + }
+ scope 4 (inlined <fn() -> ! {sleep} as Fn<()>>::call - shim(fn() -> ! {sleep})) {
+ scope 5 (inlined sleep) {
+ }
+ }
+ } + }
bb0: { bb0: {
@ -33,13 +28,24 @@
+ StorageLive(_6); + StorageLive(_6);
+ StorageLive(_3); + StorageLive(_3);
+ _3 = &_2; + _3 = &_2;
+ StorageLive(_7); + _4 = <fn() -> ! {sleep} as Fn<()>>::call(move _3, const ()) -> [return: bb1, unwind unreachable];
+ _7 = const ();
+ goto -> bb1;
+ } + }
+ +
+ bb1: { + bb1: {
+ goto -> bb1; + StorageDead(_3);
+ StorageLive(_5);
+ _5 = &_2;
+ _6 = <fn() -> ! {sleep} as Fn<()>>::call(move _5, const ()) -> [return: bb2, unwind unreachable];
+ }
+
+ bb2: {
+ StorageDead(_5);
+ _1 = (move _4, move _6);
+ drop(_2) -> [return: bb3, unwind unreachable];
+ }
+
+ bb3: {
+ unreachable;
} }
} }

View file

@ -5,7 +5,6 @@
let mut _0: (); let mut _0: ();
let _1: (!, !); let _1: (!, !);
+ let mut _2: fn() -> ! {sleep}; + let mut _2: fn() -> ! {sleep};
+ let mut _8: ();
+ scope 1 (inlined call_twice::<!, fn() -> ! {sleep}>) { + scope 1 (inlined call_twice::<!, fn() -> ! {sleep}>) {
+ debug f => _2; + debug f => _2;
+ let mut _3: &fn() -> ! {sleep}; + let mut _3: &fn() -> ! {sleep};
@ -19,10 +18,6 @@
+ debug b => _6; + debug b => _6;
+ } + }
+ } + }
+ scope 4 (inlined <fn() -> ! {sleep} as Fn<()>>::call - shim(fn() -> ! {sleep})) {
+ scope 5 (inlined sleep) {
+ }
+ }
+ } + }
bb0: { bb0: {
@ -34,13 +29,40 @@
+ StorageLive(_4); + StorageLive(_4);
+ StorageLive(_3); + StorageLive(_3);
+ _3 = &_2; + _3 = &_2;
+ StorageLive(_8); + _4 = <fn() -> ! {sleep} as Fn<()>>::call(move _3, const ()) -> [return: bb1, unwind: bb5];
+ _8 = const ();
+ goto -> bb1;
+ } + }
+ +
+ bb1: { + bb1: {
+ goto -> bb1; + StorageDead(_3);
+ StorageLive(_5);
+ _5 = &_2;
+ _6 = <fn() -> ! {sleep} as Fn<()>>::call(move _5, const ()) -> [return: bb2, unwind: bb4];
+ }
+
+ bb2: {
+ StorageDead(_5);
+ StorageLive(_7);
+ _7 = move _4;
+ _1 = (move _7, move _6);
+ StorageDead(_7);
+ StorageDead(_4);
+ drop(_2) -> [return: bb3, unwind continue];
+ }
+
+ bb3: {
+ unreachable;
+ }
+
+ bb4 (cleanup): {
+ drop(_4) -> [return: bb5, unwind terminate];
+ }
+
+ bb5 (cleanup): {
+ drop(_2) -> [return: bb6, unwind terminate];
+ }
+
+ bb6 (cleanup): {
+ resume;
} }
} }

View file

@ -8,8 +8,6 @@
let mut _3: &fn() {foo}; let mut _3: &fn() {foo};
let _4: fn() {foo}; let _4: fn() {foo};
let mut _5: (); let mut _5: ();
+ scope 1 (inlined <fn() {foo} as Fn<()>>::call - shim(fn() {foo})) {
+ }
bb0: { bb0: {
StorageLive(_2); StorageLive(_2);
@ -22,26 +20,20 @@
_3 = &_4; _3 = &_4;
StorageLive(_5); StorageLive(_5);
_5 = (); _5 = ();
- _2 = <fn() {foo} as Fn<()>>::call(move _3, move _5) -> [return: bb2, unwind unreachable]; _2 = <fn() {foo} as Fn<()>>::call(move _3, move _5) -> [return: bb2, unwind unreachable];
+ _2 = move (*_3)() -> [return: bb3, unwind unreachable];
} }
bb2: { bb2: {
+ return;
+ }
+
+ bb3: {
StorageDead(_5); StorageDead(_5);
StorageDead(_3); StorageDead(_3);
StorageDead(_4); StorageDead(_4);
StorageDead(_2); StorageDead(_2);
_0 = const (); _0 = const ();
- drop(_1) -> [return: bb3, unwind unreachable]; drop(_1) -> [return: bb3, unwind unreachable];
- } }
-
- bb3: { bb3: {
- return; return;
+ drop(_1) -> [return: bb2, unwind unreachable];
} }
} }

View file

@ -8,55 +8,40 @@
let mut _3: &fn() {foo}; let mut _3: &fn() {foo};
let _4: fn() {foo}; let _4: fn() {foo};
let mut _5: (); let mut _5: ();
+ scope 1 (inlined <fn() {foo} as Fn<()>>::call - shim(fn() {foo})) {
+ }
bb0: { bb0: {
StorageLive(_2); StorageLive(_2);
StorageLive(_3); StorageLive(_3);
StorageLive(_4); StorageLive(_4);
- _4 = hide_foo() -> [return: bb1, unwind: bb4]; _4 = hide_foo() -> [return: bb1, unwind: bb4];
+ _4 = hide_foo() -> [return: bb1, unwind: bb3];
} }
bb1: { bb1: {
_3 = &_4; _3 = &_4;
StorageLive(_5); StorageLive(_5);
_5 = (); _5 = ();
- _2 = <fn() {foo} as Fn<()>>::call(move _3, move _5) -> [return: bb2, unwind: bb4]; _2 = <fn() {foo} as Fn<()>>::call(move _3, move _5) -> [return: bb2, unwind: bb4];
+ _2 = move (*_3)() -> [return: bb5, unwind: bb3];
} }
bb2: { bb2: {
- StorageDead(_5); StorageDead(_5);
- StorageDead(_3); StorageDead(_3);
- StorageDead(_4); StorageDead(_4);
- StorageDead(_2); StorageDead(_2);
- _0 = const (); _0 = const ();
- drop(_1) -> [return: bb3, unwind: bb5]; drop(_1) -> [return: bb3, unwind: bb5];
+ return;
} }
- bb3: { bb3: {
- return; return;
+ bb3 (cleanup): {
+ drop(_1) -> [return: bb4, unwind terminate];
} }
bb4 (cleanup): { bb4 (cleanup): {
- drop(_1) -> [return: bb5, unwind terminate]; drop(_1) -> [return: bb5, unwind terminate];
+ resume;
} }
- bb5 (cleanup): { bb5 (cleanup): {
- resume; resume;
+ bb5: {
+ StorageDead(_5);
+ StorageDead(_3);
+ StorageDead(_4);
+ StorageDead(_2);
+ _0 = const ();
+ drop(_1) -> [return: bb2, unwind: bb4];
} }
} }