Skip to content
New issue

Have a question about this project? Sign up for a free GitHub account to open an issue and contact its maintainers and the community.

By clicking “Sign up for GitHub”, you agree to our terms of service and privacy statement. We’ll occasionally send you account related emails.

Already on GitHub? Sign in to your account

Try MIR inlining leaf functions by default #81079

Closed
wants to merge 10 commits into from

Conversation

tmiasko
Copy link
Contributor

@tmiasko tmiasko commented Jan 16, 2021

Based on #77307 and #68828.

@rust-highfive
Copy link
Collaborator

r? @petrochenkov

(rust-highfive has picked a reviewer for you, use r? to override)

@rust-highfive rust-highfive added the S-waiting-on-review Status: Awaiting review from the assignee but also interested parties. label Jan 16, 2021
@rust-log-analyzer
Copy link
Collaborator

The job x86_64-gnu-llvm-9 failed! Check out the build log: (web) (plain)

Click to see the possible cause of the failure (guessed by this bot)
failures:

---- [ui] ui/array-slice-vec/bounds-check-no-overflow.rs stdout ----

error: test compilation failed although it shouldn't!
status: exit code: 1
command: "/checkout/obj/build/x86_64-unknown-linux-gnu/stage2/bin/rustc" "/checkout/src/test/ui/array-slice-vec/bounds-check-no-overflow.rs" "-Zthreads=1" "--target=x86_64-unknown-linux-gnu" "--error-format" "json" "-Zui-testing" "-Zdeduplicate-diagnostics=no" "-Zemit-future-incompat-report" "-C" "prefer-dynamic" "-o" "/checkout/obj/build/x86_64-unknown-linux-gnu/test/ui/array-slice-vec/bounds-check-no-overflow/a" "-A" "unused" "-Crpath" "-O" "-Cdebuginfo=0" "-Zunstable-options" "-Lnative=/checkout/obj/build/x86_64-unknown-linux-gnu/native/rust-test-helpers" "-L" "/checkout/obj/build/x86_64-unknown-linux-gnu/test/ui/array-slice-vec/bounds-check-no-overflow/auxiliary"
------------------------------------------

------------------------------------------
stderr:
stderr:
------------------------------------------
error: this operation will panic at runtime
  --> /checkout/src/test/ui/array-slice-vec/bounds-check-no-overflow.rs:9:5
   |
LL |     xs[usize::MAX / size_of::<isize>() + 1];
   |     ^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^ index out of bounds: the length is 3 but the index is 2305843009213693952
   |
   = note: `#[deny(unconditional_panic)]` on by default
error: aborting due to previous error


------------------------------------------
---
15 error: erroneous constant encountered
-   --> $DIR/index-out-of-bounds-never-type.rs:16:13
+   --> $DIR/index-out-of-bounds-never-type.rs:21:5
17    |
18 LL |     let _ = PrintName::<T>::VOID;
+    |             -------------------- in the inlined copy of this code
+ ...
+ ...
+ LL |     f::<()>();
20 
21 error: aborting due to previous error; 1 warning emitted
22 



The actual stderr differed from the expected stderr.
Actual stderr saved to /checkout/obj/build/x86_64-unknown-linux-gnu/test/ui/consts/const-eval/index-out-of-bounds-never-type/index-out-of-bounds-never-type.stderr
To update references, rerun the tests and pass the `--bless` flag
To only update this specific test, also pass `--test-args consts/const-eval/index-out-of-bounds-never-type.rs`
error: 1 errors occurred comparing output.
status: exit code: 1
status: exit code: 1
command: "/checkout/obj/build/x86_64-unknown-linux-gnu/stage2/bin/rustc" "/checkout/src/test/ui/consts/const-eval/index-out-of-bounds-never-type.rs" "-Zthreads=1" "--target=x86_64-unknown-linux-gnu" "--error-format" "json" "-Zui-testing" "-Zdeduplicate-diagnostics=no" "-Zemit-future-incompat-report" "-C" "prefer-dynamic" "--out-dir" "/checkout/obj/build/x86_64-unknown-linux-gnu/test/ui/consts/const-eval/index-out-of-bounds-never-type" "-A" "unused" "-Crpath" "-O" "-Cdebuginfo=0" "-Zunstable-options" "-Lnative=/checkout/obj/build/x86_64-unknown-linux-gnu/native/rust-test-helpers" "-L" "/checkout/obj/build/x86_64-unknown-linux-gnu/test/ui/consts/const-eval/index-out-of-bounds-never-type/auxiliary"
------------------------------------------

------------------------------------------
stderr:
stderr:
------------------------------------------
warning: any use of this value will cause an error
   |
   |
LL |     const VOID: ! = { let x = 0 * std::mem::size_of::<T>(); [][x] };
   |                                                             |
   |                                                             |
   |                                                             index out of bounds: the length is 0 but the index is 0
note: the lint level is defined here
  --> /checkout/src/test/ui/consts/const-eval/index-out-of-bounds-never-type.rs:4:9
   |
   |
LL | #![warn(const_err, unconditional_panic)]

error: erroneous constant encountered
  --> /checkout/src/test/ui/consts/const-eval/index-out-of-bounds-never-type.rs:21:5
   |
   |
LL |     let _ = PrintName::<T>::VOID;
   |             -------------------- in the inlined copy of this code
...
LL |     f::<()>();

error: aborting due to previous error; 1 warning emitted



------------------------------------------


---- [ui] ui/issues/issue-74614.rs stdout ----

error: test compilation failed although it shouldn't!
status: exit code: 101
command: "/checkout/obj/build/x86_64-unknown-linux-gnu/stage2/bin/rustc" "/checkout/src/test/ui/issues/issue-74614.rs" "-Zthreads=1" "--target=x86_64-unknown-linux-gnu" "--error-format" "json" "-Zui-testing" "-Zdeduplicate-diagnostics=no" "-Zemit-future-incompat-report" "-C" "prefer-dynamic" "--out-dir" "/checkout/obj/build/x86_64-unknown-linux-gnu/test/ui/issues/issue-74614" "-A" "unused" "-Crpath" "-O" "-Cdebuginfo=0" "-Zunstable-options" "-Lnative=/checkout/obj/build/x86_64-unknown-linux-gnu/native/rust-test-helpers" "-Zpolymorphize=on" "-L" "/checkout/obj/build/x86_64-unknown-linux-gnu/test/ui/issues/issue-74614/auxiliary"
------------------------------------------

------------------------------------------
stderr:
stderr:
------------------------------------------
thread 'rustc' panicked at 'assertion failed: matches!(ty . kind(), ty :: Param(_))', compiler/rustc_mir/src/interpret/util.rs:61:37

error: internal compiler error: unexpected panic

note: the compiler unexpectedly panicked. this is a bug.
note: the compiler unexpectedly panicked. this is a bug.

note: we would appreciate a bug report: https://github.com/rust-lang/rust/issues/new?labels=C-bug%2C+I-ICE%2C+T-compiler&template=ice.md

note: rustc 1.51.0-nightly (1bbcc5fa1 2021-01-16) running on x86_64-unknown-linux-gnu

note: compiler flags: -Z threads=1 -Z ui-testing -Z deduplicate-diagnostics=no -Z emit-future-incompat-report -Z unstable-options -Z polymorphize=on -C prefer-dynamic -C rpath -C debuginfo=0
query stack during panic:
query stack during panic:
#0 [eval_to_allocation_raw] const-evaluating + checking `foo::promoted[0]`
#1 [eval_to_const_value_raw] simplifying constant for the type system `foo::promoted[0]`
end of query stack
------------------------------------------


---- [ui] ui/type_length_limit.rs stdout ----
---- [ui] ui/type_length_limit.rs stdout ----
diff of stderr:

- error: reached the type-length limit while instantiating `std::mem::drop::<Option<((((...,....., ...), ..., ...), ..., ...)>>`
-   --> $SRC_DIR/core/src/mem/mod.rs:LL:COL
+ error: reached the type-length limit while instantiating `std::rt::lang_start::<()>::{closure#0}`
+   --> $SRC_DIR/std/src/rt.rs:LL:COL
3    |
- LL | pub fn drop<T>(_x: T) {}
-    | ^^^^^^^^^^^^^^^^^^^^^
+ LL |         &move || crate::sys_common::backtrace::__rust_begin_short_backtrace(main).report(),
6    |
6    |
-    = note: the full type name has been written to '$TEST_BUILD_DIR/type_length_limit/type_length_limit.long-type.txt'
8    = help: consider adding a `#![type_length_limit="8"]` attribute to your crate
10 error: aborting due to previous error


The actual stderr differed from the expected stderr.
The actual stderr differed from the expected stderr.
Actual stderr saved to /checkout/obj/build/x86_64-unknown-linux-gnu/test/ui/type_length_limit/type_length_limit.stderr
To update references, rerun the tests and pass the `--bless` flag
To only update this specific test, also pass `--test-args type_length_limit.rs`
error: 1 errors occurred comparing output.
status: exit code: 1
status: exit code: 1
command: "/checkout/obj/build/x86_64-unknown-linux-gnu/stage2/bin/rustc" "/checkout/src/test/ui/type_length_limit.rs" "-Zthreads=1" "--target=x86_64-unknown-linux-gnu" "--error-format" "json" "-Zui-testing" "-Zdeduplicate-diagnostics=no" "-Zemit-future-incompat-report" "-C" "prefer-dynamic" "--out-dir" "/checkout/obj/build/x86_64-unknown-linux-gnu/test/ui/type_length_limit" "-A" "unused" "-Crpath" "-O" "-Cdebuginfo=0" "-Zunstable-options" "-Lnative=/checkout/obj/build/x86_64-unknown-linux-gnu/native/rust-test-helpers" "-L" "/checkout/obj/build/x86_64-unknown-linux-gnu/test/ui/type_length_limit/auxiliary"
------------------------------------------

------------------------------------------
stderr:
stderr:
------------------------------------------
error: reached the type-length limit while instantiating `std::rt::lang_start::<()>::{closure#0}`
   |
   |
LL |         &move || crate::sys_common::backtrace::__rust_begin_short_backtrace(main).report(),
   |
   |
   = help: consider adding a `#![type_length_limit="8"]` attribute to your crate
error: aborting due to previous error


------------------------------------------
---

Some tests failed in compiletest suite=ui mode=ui host=x86_64-unknown-linux-gnu target=x86_64-unknown-linux-gnu


command did not execute successfully: "/checkout/obj/build/x86_64-unknown-linux-gnu/stage0-tools-bin/compiletest" "--compile-lib-path" "/checkout/obj/build/x86_64-unknown-linux-gnu/stage2/lib" "--run-lib-path" "/checkout/obj/build/x86_64-unknown-linux-gnu/stage2/lib/rustlib/x86_64-unknown-linux-gnu/lib" "--rustc-path" "/checkout/obj/build/x86_64-unknown-linux-gnu/stage2/bin/rustc" "--src-base" "/checkout/src/test/ui" "--build-base" "/checkout/obj/build/x86_64-unknown-linux-gnu/test/ui" "--stage-id" "stage2-x86_64-unknown-linux-gnu" "--suite" "ui" "--mode" "ui" "--target" "x86_64-unknown-linux-gnu" "--host" "x86_64-unknown-linux-gnu" "--llvm-filecheck" "/usr/lib/llvm-9/bin/FileCheck" "--nodejs" "/usr/bin/node" "--host-rustcflags" "-Crpath -O -Cdebuginfo=0 -Zunstable-options  -Lnative=/checkout/obj/build/x86_64-unknown-linux-gnu/native/rust-test-helpers" "--target-rustcflags" "-Crpath -O -Cdebuginfo=0 -Zunstable-options  -Lnative=/checkout/obj/build/x86_64-unknown-linux-gnu/native/rust-test-helpers" "--docck-python" "/usr/bin/python3" "--lldb-python" "/usr/bin/python3" "--gdb" "/usr/bin/gdb" "--quiet" "--llvm-version" "9.0.0" "--llvm-components" "aarch64 aarch64asmparser aarch64codegen aarch64desc aarch64disassembler aarch64info aarch64utils aggressiveinstcombine all all-targets amdgpu amdgpuasmparser amdgpucodegen amdgpudesc amdgpudisassembler amdgpuinfo amdgpuutils analysis arm armasmparser armcodegen armdesc armdisassembler arminfo armutils asmparser asmprinter avr avrasmparser avrcodegen avrdesc avrdisassembler avrinfo binaryformat bitreader bitstreamreader bitwriter bpf bpfasmparser bpfcodegen bpfdesc bpfdisassembler bpfinfo codegen core coroutines coverage debuginfocodeview debuginfodwarf debuginfogsym debuginfomsf debuginfopdb demangle dlltooldriver engine executionengine fuzzmutate globalisel hexagon hexagonasmparser hexagoncodegen hexagondesc hexagondisassembler hexagoninfo instcombine instrumentation interpreter ipo irreader jitlink lanai lanaiasmparser lanaicodegen lanaidesc lanaidisassembler lanaiinfo libdriver lineeditor linker lto mc mca mcdisassembler mcjit mcparser mips mipsasmparser mipscodegen mipsdesc mipsdisassembler mipsinfo mirparser msp430 msp430asmparser msp430codegen msp430desc msp430disassembler msp430info native nativecodegen nvptx nvptxcodegen nvptxdesc nvptxinfo objcarcopts object objectyaml option orcjit passes perfjitevents powerpc powerpcasmparser powerpccodegen powerpcdesc powerpcdisassembler powerpcinfo profiledata remarks riscv riscvasmparser riscvcodegen riscvdesc riscvdisassembler riscvinfo riscvutils runtimedyld scalaropts selectiondag sparc sparcasmparser sparccodegen sparcdesc sparcdisassembler sparcinfo support symbolize systemz systemzasmparser systemzcodegen systemzdesc systemzdisassembler systemzinfo tablegen target textapi transformutils vectorize webassembly webassemblyasmparser webassemblycodegen webassemblydesc webassemblydisassembler webassemblyinfo windowsmanifest x86 x86asmparser x86codegen x86desc x86disassembler x86info x86utils xcore xcorecodegen xcoredesc xcoredisassembler xcoreinfo xray" "--system-llvm" "--cc" "" "--cxx" "" "--cflags" "" "--adb-path" "adb" "--adb-test-dir" "/data/tmp/work" "--android-cross-path" "" "--color" "always"


failed to run: /checkout/obj/build/bootstrap/debug/bootstrap --stage 2 test --exclude src/tools/tidy
Build completed unsuccessfully in 0:16:34

@bjorn3
Copy link
Member

bjorn3 commented Jan 16, 2021

@bors try @rust-timer queue

@rust-timer
Copy link
Collaborator

Awaiting bors try build completion.

@bors
Copy link
Contributor

bors commented Jan 16, 2021

⌛ Trying commit 3d43b90 with merge 032277c8bdf5002b9a9d01a6a1c5db9ea04fc839...

@bors
Copy link
Contributor

bors commented Jan 16, 2021

☀️ Try build successful - checks-actions
Build commit: 032277c8bdf5002b9a9d01a6a1c5db9ea04fc839 (032277c8bdf5002b9a9d01a6a1c5db9ea04fc839)

@rust-timer
Copy link
Collaborator

Queued 032277c8bdf5002b9a9d01a6a1c5db9ea04fc839 with parent 410a546, future comparison URL.

@rustbot label: +S-waiting-on-perf

@rustbot rustbot added the S-waiting-on-perf Status: Waiting on a perf run to be completed. label Jan 16, 2021
@rust-timer
Copy link
Collaborator

Finished benchmarking try commit (032277c8bdf5002b9a9d01a6a1c5db9ea04fc839): comparison url.

Benchmarking this pull request likely means that it is perf-sensitive, so we're automatically marking it as not fit for rolling up. Please note that if the perf results are neutral, you should likely undo the rollup=never given below by specifying rollup- to bors.

Importantly, though, if the results of this run are non-neutral do not roll this PR up -- it will mask other regressions or improvements in the roll up.

@bors rollup=never
@rustbot label: +S-waiting-on-review -S-waiting-on-perf

@rustbot rustbot removed the S-waiting-on-perf Status: Waiting on a perf run to be completed. label Jan 16, 2021
@petrochenkov
Copy link
Contributor

r? @lcnr

Copy link
Contributor

@lcnr lcnr left a comment

Choose a reason for hiding this comment

The reason will be displayed to describe this comment to others. Learn more.

so inlining parts iter::Empty fixes the deeply-nested test, gj on figuring all of this out.

I don't know enough about about the other touched mir opts or why they are necessary as part of this PR, so
r? @oli-obk

return false;
}

if !did.is_local() {
Copy link
Contributor

Choose a reason for hiding this comment

The reason will be displayed to describe this comment to others. Learn more.

this is unreachable. In decoding we just store false in this case 😆

@the8472
Copy link
Member

the8472 commented Jan 16, 2021

Finished benchmarking try commit (032277c): comparison url.

The max-rss results look substantially different (worse) than the noise run, is this expected?

@lcnr lcnr removed their assignment Jan 16, 2021
Copy link
Contributor

@oli-obk oli-obk left a comment

Choose a reason for hiding this comment

The reason will be displayed to describe this comment to others. Learn more.

afaict everything after f0f5e19 is not actually necessary for this PR, right?

The max-rss results look substantially different (worse) than the noise run, is this expected?

I would expect inlining to cause an increase in memory usage as MIR bodies now contain duplicates of other MIR bodies.

@@ -204,7 +204,7 @@ macro_rules! step_identical_methods {
// In debug builds, trigger a panic on overflow.
// This should optimize completely out in release builds.
if Self::forward_checked(start, n).is_none() {
let _ = Add::add(Self::MAX, 1);
let _ = Add::add(usize::MAX, n);
Copy link
Contributor

Choose a reason for hiding this comment

The reason will be displayed to describe this comment to others. Learn more.

🤣 nice trick

@@ -1827,23 +1827,6 @@ pub fn build_session_options(matches: &getopts::Matches) -> Options {
}
Some(SymbolManglingVersion::V0) => {}
}

if debugging_opts.mir_opt_level > 1 {
Copy link
Contributor

Choose a reason for hiding this comment

The reason will be displayed to describe this comment to others. Learn more.

This commit just disables the warning, it doesn't actually disable mir inlining

@@ -885,3 +903,48 @@ impl<'a, 'tcx> MutVisitor<'tcx> for Integrator<'a, 'tcx> {
}
}
}

pub fn is_trivial_mir(tcx: TyCtxt<'tcx>, did: DefId) -> bool {
Copy link
Member

Choose a reason for hiding this comment

The reason will be displayed to describe this comment to others. Learn more.

This could really use a more semantic name. A "trivial" can mean many things, and what it means in this context is not really specified.

Given that its purpose is to check that the body is trivially inlineable, a name for your consideration: is_trivially_inlineable or perhaps is_leaf_mir.

let mut this = Self {
increment: true,
arg_count: body.arg_count.try_into().unwrap(),
use_count: IndexVec::from_elem(0, &body.local_decls),
preserve_var_debug_info: tcx.sess.opts.optimize != OptLevel::Aggressive,
Copy link
Member

Choose a reason for hiding this comment

The reason will be displayed to describe this comment to others. Learn more.

What criteria was used in choosing this? Other compilers generally don't try to preserve any debuginfo after -O2 which is OptLevel::Default. Futhermore, this is a MIR optimisation so it is unclear to me that deriving this from -O flag is actually what we want?

@tmiasko
Copy link
Contributor Author

tmiasko commented Jan 17, 2021

The unicode_normalization-check full is now at -0.4%, fixing the previous +16.4% regression.

The results for packed-simd-debug & packed-simd-opt show a large regression. That is one things I would like to investigate more. The first impression is that this crate has a lot of trivial inlining opportunities while at the same time doing almost not code generation, so we are paying the cost of inlining but receive no benefits.

afaict everything after f0f5e19 is not actually necessary for this PR, right?

One additional change that follows is an extended removal of dead locals. This is something I would like to do at some point (not necessarily in the form here). The current implementation of SimplifyLocals is very conservative, and retains locals from removed dead code when they are referenced by debuginfo (e.g., it retains locals from debug_assert_eq! when debug assertions are disabled).

@tmiasko tmiasko closed this Jan 19, 2021
@tmiasko tmiasko deleted the inline-🍀 branch January 19, 2021 08:51
Sign up for free to join this conversation on GitHub. Already have an account? Sign in to comment
Labels
S-waiting-on-review Status: Awaiting review from the assignee but also interested parties.
Projects
None yet
Development

Successfully merging this pull request may close these issues.