Auto merge of #133929 - saethlin:remove-inline-in-all-cgus, r= · rust-lang/rust@75620fd (original) (raw)
34 files changed
lines changed
Original file line number | Diff line number | Diff line change |
---|---|---|
@@ -797,7 +797,6 @@ fn test_unstable_options_tracking_hash() { | ||
797 | 797 | tracked!(function_sections, Some(false)); |
798 | 798 | tracked!(human_readable_cgu_names, true); |
799 | 799 | tracked!(incremental_ignore_spans, true); |
800 | -tracked!(inline_in_all_cgus, Some(true)); | |
801 | 800 | tracked!(inline_mir, Some(true)); |
802 | 801 | tracked!(inline_mir_hint_threshold, Some(123)); |
803 | 802 | tracked!(inline_mir_threshold, Some(123)); |
Original file line number | Diff line number | Diff line change |
---|---|---|
@@ -91,13 +91,8 @@ impl<'tcx> MonoItem<'tcx> { | ||
91 | 91 | } |
92 | 92 | |
93 | 93 | pub fn instantiation_mode(&self, tcx: TyCtxt<'tcx>) -> InstantiationMode { |
94 | -let generate_cgu_internal_copies = tcx | |
95 | -.sess | |
96 | -.opts | |
97 | -.unstable_opts | |
98 | -.inline_in_all_cgus | |
99 | -.unwrap_or_else(| | |
100 | - && !tcx.sess.link_dead_code(); | |
94 | +let generate_cgu_internal_copies = | |
95 | +(tcx.sess.opts.optimize != OptLevel::No) && !tcx.sess.link_dead_code(); | |
101 | 96 | |
102 | 97 | match *self { |
103 | 98 | MonoItem::Fn(ref instance) => { |
@@ -121,8 +116,8 @@ impl<'tcx> MonoItem<'tcx> { | ||
121 | 116 | } |
122 | 117 | |
123 | 118 | // At this point we don't have explicit linkage and we're an |
124 | -// inlined function. If we're inlining into all CGUs then we'll | |
125 | -// be creating a local copy per CGU. | |
119 | +// inlined function. If this crate's build settings permit, | |
120 | +// we'll be creating a local copy per CGU. | |
126 | 121 | if generate_cgu_internal_copies { |
127 | 122 | return InstantiationMode::LocalCopy; |
128 | 123 | } |
Original file line number | Diff line number | Diff line change |
---|---|---|
@@ -1870,8 +1870,6 @@ options! { | ||
1870 | 1870 | "verify extended properties for incr. comp. (default: no): |
1871 | 1871 | - hashes of green query instances |
1872 | 1872 | - hash collisions of query keys"), |
1873 | - inline_in_all_cgus: Option<bool> = (None, parse_opt_bool, [TRACKED], | |
1874 | -"control whether `#[inline]` functions are in all CGUs"), | |
1875 | 1873 | inline_llvm: bool = (true, parse_bool, [TRACKED], |
1876 | 1874 | "enable LLVM inlining (default: yes)"), |
1877 | 1875 | inline_mir: Option<bool> = (None, parse_opt_bool, [TRACKED], |
Original file line number | Diff line number | Diff line change |
---|---|---|
@@ -1,7 +1,6 @@ | ||
1 | -// | |
2 | 1 | //@ compile-flags:-Zprint-mono-items=eager |
3 | -//@ compile-flags:-Zinline-in-all-cgus | |
4 | 2 | //@ compile-flags:-Zinline-mir=no |
3 | +//@ compile-flags: -O | |
5 | 4 | |
6 | 5 | #![crate_type = "lib"] |
7 | 6 |
Original file line number | Diff line number | Diff line change |
---|---|---|
@@ -1,6 +1,5 @@ | ||
1 | -// | |
2 | 1 | //@ compile-flags:-Zprint-mono-items=eager |
3 | -//@ compile-flags:-Zinline-in-all-cgus | |
2 | +//@ compile-flags: -O | |
4 | 3 | |
5 | 4 | #![deny(dead_code)] |
6 | 5 | #![crate_type = "lib"] |
Original file line number | Diff line number | Diff line change |
---|---|---|
@@ -1,5 +1,4 @@ | ||
1 | -// | |
2 | -//@ compile-flags:-Zprint-mono-items=eager -Zinline-in-all-cgus -Zmir-opt-level=0 | |
1 | +//@ compile-flags:-Zprint-mono-items=eager -Zmir-opt-level=0 | |
3 | 2 | |
4 | 3 | #![deny(dead_code)] |
5 | 4 | #![crate_type = "lib"] |
Original file line number | Diff line number | Diff line change |
---|---|---|
@@ -1,6 +1,5 @@ | ||
1 | -// | |
2 | 1 | //@ compile-flags:-Zprint-mono-items=eager |
3 | -//@ compile-flags:-Zinline-in-all-cgus | |
2 | +//@ compile-flags: -O | |
4 | 3 | |
5 | 4 | #![deny(dead_code)] |
6 | 5 | #![crate_type = "lib"] |
Original file line number | Diff line number | Diff line change |
---|---|---|
@@ -1,6 +1,5 @@ | ||
1 | -// | |
2 | 1 | //@ compile-flags:-Zprint-mono-items=eager |
3 | -//@ compile-flags:-Zinline-in-all-cgus | |
2 | +//@ compile-flags: -O | |
4 | 3 | |
5 | 4 | #![deny(dead_code)] |
6 | 5 | #![crate_type = "lib"] |
Original file line number | Diff line number | Diff line change |
---|---|---|
@@ -1,6 +1,5 @@ | ||
1 | -// | |
2 | 1 | //@ compile-flags:-Zprint-mono-items=eager |
3 | -//@ compile-flags:-Zinline-in-all-cgus | |
2 | +//@ compile-flags: -O | |
4 | 3 | |
5 | 4 | #![deny(dead_code)] |
6 | 5 | #![crate_type = "lib"] |
Original file line number | Diff line number | Diff line change |
---|---|---|
@@ -1,5 +1,4 @@ | ||
1 | 1 | //@ compile-flags:-Zprint-mono-items=eager |
2 | -//@ compile-flags:-Zinline-in-all-cgus | |
3 | 2 | //@ compile-flags:-Zmir-opt-level=0 |
4 | 3 | |
5 | 4 | #![deny(dead_code)] |
Original file line number | Diff line number | Diff line change |
---|---|---|
@@ -0,0 +1,14 @@ | ||
1 | +# codegen-units/partitioning tests | |
2 | + | |
3 | +This test suite is designed to test that codegen unit partitioning works as intended. | |
4 | +Note that it does not evaluate whether CGU partitioning is *good*. That is the job of the compiler benchmark suite. | |
5 | + | |
6 | +All tests in this suite use the flag `-Zprint-mono-items=lazy`, which makes the compiler print a machine-readable summary of all MonoItems that were collected, which CGUs they were assigned to, and the linkage in each CGU. The output looks like: | |
7 | +``` | |
8 | +MONO_ITEM @@ [] [] | |
9 | +``` | |
10 | +DO NOT add tests to this suite that use `-Zprint-mono-items=eager`. That flag changes the way that MonoItem collection works in rather fundamental ways that are otherwise only used by `-Clink-dead-code`, and thus the MonoItems collected and their linkage under `-Zprint-mono-items=eager` does not correlate very well with normal compilation behavior. | |
11 | + | |
12 | +The current CGU partitioning algorithm essentially groups MonoItems by which module they are defined in, then merges small CGUs. There are a lot of inline modules in this test suite because that's the only way to observe the partitioning. | |
13 | + | |
14 | +Currently, the test suite is very heavily biased towards incremental builds with -Copt-level=0. This is mostly an accident of history; the entire test suite was added as part of supporting incremental compilation in #32779. But also CGU partitioning is *mostly* valuable because the CGU is the unit of incrementality to the codegen backend (cached queries are the unit of incrementality for the rest of the compiler). |
Original file line number | Diff line number | Diff line change |
---|---|---|
@@ -1,7 +1,6 @@ | ||
1 | 1 | // NOTE: We always compile this test with -Copt-level=0 because higher opt-levels |
2 | 2 | // prevent drop-glue from participating in share-generics. |
3 | -//@ compile-flags:-Zshare-generics=yes -Copt-level=0 | |
4 | -//@ no-prefer-dynamic | |
3 | +//@ compile-flags: -Zshare-generics=yes -Copt-level=0 | |
5 | 4 | |
6 | 5 | #![crate_type = "rlib"] |
7 | 6 |
Original file line number | Diff line number | Diff line change |
---|---|---|
@@ -1,15 +1,14 @@ | ||
1 | -// We specify incremental here because we want to test the partitioning for incremental compilation | |
2 | -// We specify opt-level=0 because `drop_in_place` is `Internal` when optimizing | |
3 | 1 | //@ incremental |
4 | -//@ compile-flags:-Zprint-mono-items=lazy | |
5 | -//@ compile-flags:-Zinline-in-all-cgus -Copt-level=0 | |
2 | +//@ compile-flags: -Zprint-mono-items=lazy -Copt-level=0 | |
6 | 3 | |
7 | -#![allow(dead_code)] | |
8 | 4 | #![crate_type = "rlib"] |
9 | 5 | |
10 | 6 | //@ aux-build:cgu_extern_drop_glue.rs |
11 | 7 | extern crate cgu_extern_drop_glue; |
12 | 8 | |
9 | +// This test checks that drop glue is generated, even for types not defined in this crate, and all | |
10 | +// drop glue is put in the fallback CGU. | |
11 | + | |
13 | 12 | //~ MONO_ITEM fn std::ptr::drop_in_place::<cgu_extern_drop_glue::Struct> - shim(Some(cgu_extern_drop_glue::Struct)) @@ extern_drop_glue-fallback.cgu[External] |
14 | 13 | |
15 | 14 | struct LocalStruct(cgu_extern_drop_glue::Struct); |
Original file line number | Diff line number | Diff line change |
---|---|---|
@@ -1,51 +1,36 @@ | ||
1 | -// We specify incremental here because we want to test the partitioning for incremental compilation | |
2 | 1 | //@ incremental |
3 | -//@ compile-flags:-Zprint-mono-items=eager -Zshare-generics=y | |
2 | +//@ compile-flags: -Zprint-mono-items=lazy -Copt-level=0 | |
4 | 3 | |
5 | -#![allow(dead_code)] | |
6 | 4 | #![crate_type = "lib"] |
7 | 5 | |
8 | 6 | //@ aux-build:cgu_generic_function.rs |
9 | 7 | extern crate cgu_generic_function; |
10 | 8 | |
11 | -//~ MONO_ITEM fn user @@ extern_generic[Internal] | |
12 | -fn user() { | |
9 | +// This test checks that, in an unoptimized build, a generic function and its callees are only | |
10 | +// instantiated once in this crate. | |
11 | + | |
12 | +//~ MONO_ITEM fn user @@ extern_generic[External] | |
13 | +pub fn user() { | |
13 | 14 | let _ = cgu_generic_function::foo("abc"); |
14 | 15 | } |
15 | 16 | |
16 | -mod mod1 { | |
17 | +pub mod mod1 { | |
17 | 18 | use cgu_generic_function; |
18 | 19 | |
19 | -//~ MONO_ITEM fn mod1::user @@ extern_generic-mod1[Internal] | |
20 | -fn user() { | |
20 | +//~ MONO_ITEM fn mod1::user @@ extern_generic-mod1[External] | |
21 | +pub fn user() { | |
21 | 22 | let _ = cgu_generic_function::foo("abc"); |
22 | 23 | } |
23 | 24 | |
24 | -mod mod1 { | |
25 | +pub mod mod1 { | |
25 | 26 | use cgu_generic_function; |
26 | 27 | |
27 | -//~ MONO_ITEM fn mod1::mod1::user @@ extern_generic-mod1-mod1[Internal] | |
28 | -fn user() { | |
28 | +//~ MONO_ITEM fn mod1::mod1::user @@ extern_generic-mod1-mod1[External] | |
29 | +pub fn user() { | |
29 | 30 | let _ = cgu_generic_function::foo("abc"); |
30 | 31 | } |
31 | 32 | } |
32 | 33 | } |
33 | 34 | |
34 | -mod mod2 { | |
35 | -use cgu_generic_function; | |
36 | - | |
37 | -//~ MONO_ITEM fn mod2::user @@ extern_generic-mod2[Internal] | |
38 | -fn user() { | |
39 | -let _ = cgu_generic_function::foo("abc"); | |
40 | -} | |
41 | -} | |
42 | - | |
43 | -mod mod3 { | |
44 | -//~ MONO_ITEM fn mod3::non_user @@ extern_generic-mod3[Internal] | |
45 | -fn non_user() {} | |
46 | -} | |
47 | - | |
48 | -// Make sure the two generic functions from the extern crate get instantiated | |
49 | -// once for the current crate | |
50 | 35 | //~ MONO_ITEM fn cgu_generic_function::foo::<&str> @@ cgu_generic_function-in-extern_generic.volatile[External] |
51 | 36 | //~ MONO_ITEM fn cgu_generic_function::bar::<&str> @@ cgu_generic_function-in-extern_generic.volatile[External] |
Original file line number | Diff line number | Diff line change |
---|---|---|
@@ -1,16 +1,15 @@ | ||
1 | -// We specify incremental here because we want to test the partitioning for incremental compilation | |
2 | 1 | //@ incremental |
3 | -//@ compile-flags:-Zprint-mono-items=lazy | |
4 | -//@ compile-flags:-Ccodegen-units=3 | |
2 | +//@ compile-flags: -Zprint-mono-items=lazy -Copt-level=0 -Ccodegen-units=3 | |
5 | 3 | |
6 | 4 | #![crate_type = "rlib"] |
7 | 5 | |
8 | 6 | // This test makes sure that merging of CGUs works together with incremental |
9 | 7 | // compilation but at the same time does not modify names of CGUs that were not |
10 | 8 | // affected by merging. |
11 | 9 | // |
12 | -// We expect CGUs `aaa` and `bbb` to be merged (because they are the smallest), | |
13 | -// while `ccc` and `ddd` are supposed to stay untouched. | |
10 | +// CGU partitioning creates one CGU per module, so with 4 modules and codegen-units=3, | |
11 | +// two of the modules should be merged. We expect CGUs `aaa` and `bbb` to be merged | |
12 | +// (because they are the smallest), while `ccc` and `ddd` should stay untouched. | |
14 | 13 | |
15 | 14 | pub mod aaa { |
16 | 15 | //~ MONO_ITEM fn aaa::foo @@ incremental_merging-aaa--incremental_merging-bbb[External] |
Original file line number | Diff line number | Diff line change |
---|---|---|
@@ -0,0 +1,38 @@ | ||
1 | +//@ incremental | |
2 | +//@ compile-flags: -Zprint-mono-items=lazy -Copt-level=0 | |
3 | + | |
4 | +#![crate_type = "lib"] | |
5 | + | |
6 | +// This test checks that a monomorphic inline(always) function is instantiated in every CGU that | |
7 | +// references it, even though this is an unoptimized incremental build. | |
8 | +// It also checks that an inline(always) function is only placed in CGUs that reference it. | |
9 | + | |
10 | +mod inline { | |
11 | +//~ MONO_ITEM fn inline::inlined_function @@ inline_always-user1[Internal] inline_always-user2[Internal] | |
12 | +#[inline(always)] | |
13 | +pub fn inlined_function() {} | |
14 | +} | |
15 | + | |
16 | +pub mod user1 { | |
17 | +use super::inline; | |
18 | + | |
19 | +//~ MONO_ITEM fn user1::foo @@ inline_always-user1[External] | |
20 | +pub fn foo() { | |
21 | + inline::inlined_function(); | |
22 | +} | |
23 | +} | |
24 | + | |
25 | +pub mod user2 { | |
26 | +use super::inline; | |
27 | + | |
28 | +//~ MONO_ITEM fn user2::bar @@ inline_always-user2[External] | |
29 | +pub fn bar() { | |
30 | + inline::inlined_function(); | |
31 | +} | |
32 | +} | |
33 | + | |
34 | +pub mod non_user { | |
35 | + | |
36 | +//~ MONO_ITEM fn non_user::baz @@ inline_always-non_user[External] | |
37 | +pub fn baz() {} | |
38 | +} |
Original file line number | Diff line number | Diff line change |
---|---|---|
@@ -1,7 +1,5 @@ | ||
1 | -// We specify incremental here because we want to test the partitioning for incremental compilation | |
2 | 1 | //@ incremental |
3 | -//@ compile-flags:-Zprint-mono-items=lazy | |
4 | -//@ compile-flags:-Zinline-in-all-cgus | |
2 | +//@ compile-flags: -Zprint-mono-items=lazy -Copt-level=1 | |
5 | 3 | |
6 | 4 | #![crate_type = "lib"] |
7 | 5 |
Original file line number | Diff line number | Diff line change |
---|---|---|
@@ -1,14 +1,14 @@ | ||
1 | -// We specify incremental here because we want to test the partitioning for incremental compilation | |
2 | -// We specify opt-level=0 because `drop_in_place` is `Internal` when optimizing | |
3 | 1 | //@ incremental |
4 | -//@ compile-flags:-Zprint-mono-items=lazy | |
5 | -//@ compile-flags:-Zinline-in-all-cgus -Copt-level=0 | |
2 | +//@ compile-flags: -Zprint-mono-items=lazy -Copt-level=0 | |
6 | 3 | |
7 | -#![allow(dead_code)] | |
8 | 4 | #![crate_type = "rlib"] |
9 | 5 | |
6 | +// This test checks that drop glue is generated for types defined in this crate, and that all drop | |
7 | +// glue is put in the fallback CGU. | |
8 | +// This is rather similar to extern-drop-glue.rs. | |
9 | + | |
10 | 10 | //~ MONO_ITEM fn std::ptr::drop_in_place:: - shim(Some(Struct)) @@ local_drop_glue-fallback.cgu[External] |
11 | -struct Struct { | |
11 | +pub struct Struct { | |
12 | 12 | _a: u32, |
13 | 13 | } |
14 | 14 | |
@@ -18,7 +18,7 @@ impl Drop for Struct { | ||
18 | 18 | } |
19 | 19 | |
20 | 20 | //~ MONO_ITEM fn std::ptr::drop_in_place:: - shim(Some(Outer)) @@ local_drop_glue-fallback.cgu[External] |
21 | -struct Outer { | |
21 | +pub struct Outer { | |
22 | 22 | _a: Struct, |
23 | 23 | } |
24 | 24 | |
@@ -33,7 +33,7 @@ pub mod mod1 { | ||
33 | 33 | //~ MONO_ITEM fn std::ptr::drop_in_place::mod1::Struct2 - shim(Some(mod1::Struct2)) @@ local_drop_glue-fallback.cgu[External] |
34 | 34 | struct Struct2 { |
35 | 35 | _a: Struct, |
36 | -//~ MONO_ITEM fn std::ptr::drop_in_place::<(u32, Struct)> - shim(Some((u32, Struct))) @@ local_drop_glue-fallback.cgu[Internal] | |
36 | +//~ MONO_ITEM fn std::ptr::drop_in_place::<(u32, Struct)> - shim(Some((u32, Struct))) @@ local_drop_glue-fallback.cgu[External] | |
37 | 37 | _b: (u32, Struct), |
38 | 38 | } |
39 | 39 |
Original file line number | Diff line number | Diff line change |
---|---|---|
@@ -1,10 +1,11 @@ | ||
1 | -// We specify incremental here because we want to test the partitioning for incremental compilation | |
2 | 1 | //@ incremental |
3 | -//@ compile-flags:-Zprint-mono-items=eager | |
2 | +//@ compile-flags: -Zprint-mono-items=lazy -Copt-level=0 | |
4 | 3 | |
5 | -#![allow(dead_code)] | |
6 | 4 | #![crate_type = "lib"] |
7 | 5 | |
6 | +// This test checks that all the instantiations of a local generic fn are placed in the same CGU, | |
7 | +// regardless of where it is called. | |
8 | + | |
8 | 9 | //~ MONO_ITEM fn generic:: @@ local_generic.volatile[External] |
9 | 10 | //~ MONO_ITEM fn generic:: @@ local_generic.volatile[External] |
10 | 11 | //~ MONO_ITEM fn generic:: @@ local_generic.volatile[External] |
@@ -13,34 +14,34 @@ pub fn generic(x: T) -> T { | ||
13 | 14 | x |
14 | 15 | } |
15 | 16 | |
16 | -//~ MONO_ITEM fn user @@ local_generic[Internal] | |
17 | -fn user() { | |
17 | +//~ MONO_ITEM fn user @@ local_generic[External] | |
18 | +pub fn user() { | |
18 | 19 | let _ = generic(0u32); |
19 | 20 | } |
20 | 21 | |
21 | -mod mod1 { | |
22 | +pub mod mod1 { | |
22 | 23 | pub use super::generic; |
23 | 24 | |
24 | -//~ MONO_ITEM fn mod1::user @@ local_generic-mod1[Internal] | |
25 | -fn user() { | |
25 | +//~ MONO_ITEM fn mod1::user @@ local_generic-mod1[External] | |
26 | +pub fn user() { | |
26 | 27 | let _ = generic(0u64); |
27 | 28 | } |
28 | 29 | |
29 | -mod mod1 { | |
30 | +pub mod mod1 { | |
30 | 31 | use super::generic; |
31 | 32 | |
32 | -//~ MONO_ITEM fn mod1::mod1::user @@ local_generic-mod1-mod1[Internal] | |
33 | -fn user() { | |
33 | +//~ MONO_ITEM fn mod1::mod1::user @@ local_generic-mod1-mod1[External] | |
34 | +pub fn user() { | |
34 | 35 | let _ = generic('c'); |
35 | 36 | } |
36 | 37 | } |
37 | 38 | } |
38 | 39 | |
39 | -mod mod2 { | |
40 | +pub mod mod2 { | |
40 | 41 | use super::generic; |
41 | 42 | |
42 | -//~ MONO_ITEM fn mod2::user @@ local_generic-mod2[Internal] | |
43 | -fn user() { | |
43 | +//~ MONO_ITEM fn mod2::user @@ local_generic-mod2[External] | |
44 | +pub fn user() { | |
44 | 45 | let _ = generic("abc"); |
45 | 46 | } |
46 | 47 | } |