Remove -Zinline-in-all-cgus and clean up CGU partitioning tests
This commit is contained in:
parent
ed43cbcb88
commit
bf9df97660
34 changed files with 187 additions and 367 deletions
|
@ -795,7 +795,6 @@ fn test_unstable_options_tracking_hash() {
|
|||
tracked!(function_sections, Some(false));
|
||||
tracked!(human_readable_cgu_names, true);
|
||||
tracked!(incremental_ignore_spans, true);
|
||||
tracked!(inline_in_all_cgus, Some(true));
|
||||
tracked!(inline_mir, Some(true));
|
||||
tracked!(inline_mir_hint_threshold, Some(123));
|
||||
tracked!(inline_mir_threshold, Some(123));
|
||||
|
|
|
@ -91,13 +91,8 @@ impl<'tcx> MonoItem<'tcx> {
|
|||
}
|
||||
|
||||
pub fn instantiation_mode(&self, tcx: TyCtxt<'tcx>) -> InstantiationMode {
|
||||
let generate_cgu_internal_copies = tcx
|
||||
.sess
|
||||
.opts
|
||||
.unstable_opts
|
||||
.inline_in_all_cgus
|
||||
.unwrap_or_else(|| tcx.sess.opts.optimize != OptLevel::No)
|
||||
&& !tcx.sess.link_dead_code();
|
||||
let generate_cgu_internal_copies =
|
||||
(tcx.sess.opts.optimize != OptLevel::No) && !tcx.sess.link_dead_code();
|
||||
|
||||
match *self {
|
||||
MonoItem::Fn(ref instance) => {
|
||||
|
@ -121,8 +116,8 @@ impl<'tcx> MonoItem<'tcx> {
|
|||
}
|
||||
|
||||
// At this point we don't have explicit linkage and we're an
|
||||
// inlined function. If we're inlining into all CGUs then we'll
|
||||
// be creating a local copy per CGU.
|
||||
// inlined function. If this crate's build settings permit,
|
||||
// we'll be creating a local copy per CGU.
|
||||
if generate_cgu_internal_copies {
|
||||
return InstantiationMode::LocalCopy;
|
||||
}
|
||||
|
|
|
@ -1870,8 +1870,6 @@ options! {
|
|||
"verify extended properties for incr. comp. (default: no):
|
||||
- hashes of green query instances
|
||||
- hash collisions of query keys"),
|
||||
inline_in_all_cgus: Option<bool> = (None, parse_opt_bool, [TRACKED],
|
||||
"control whether `#[inline]` functions are in all CGUs"),
|
||||
inline_llvm: bool = (true, parse_bool, [TRACKED],
|
||||
"enable LLVM inlining (default: yes)"),
|
||||
inline_mir: Option<bool> = (None, parse_opt_bool, [TRACKED],
|
||||
|
|
|
@ -1,7 +1,6 @@
|
|||
//
|
||||
//@ compile-flags:-Zprint-mono-items=eager
|
||||
//@ compile-flags:-Zinline-in-all-cgus
|
||||
//@ compile-flags:-Zinline-mir=no
|
||||
//@ compile-flags: -O
|
||||
|
||||
#![crate_type = "lib"]
|
||||
|
||||
|
|
|
@ -1,6 +1,5 @@
|
|||
//
|
||||
//@ compile-flags:-Zprint-mono-items=eager
|
||||
//@ compile-flags:-Zinline-in-all-cgus
|
||||
//@ compile-flags: -O
|
||||
|
||||
#![deny(dead_code)]
|
||||
#![crate_type = "lib"]
|
||||
|
|
|
@ -1,5 +1,4 @@
|
|||
//
|
||||
//@ compile-flags:-Zprint-mono-items=eager -Zinline-in-all-cgus -Zmir-opt-level=0
|
||||
//@ compile-flags:-Zprint-mono-items=eager -Zmir-opt-level=0
|
||||
|
||||
#![deny(dead_code)]
|
||||
#![crate_type = "lib"]
|
||||
|
|
|
@ -1,6 +1,5 @@
|
|||
//
|
||||
//@ compile-flags:-Zprint-mono-items=eager
|
||||
//@ compile-flags:-Zinline-in-all-cgus
|
||||
//@ compile-flags: -O
|
||||
|
||||
#![deny(dead_code)]
|
||||
#![crate_type = "lib"]
|
||||
|
|
|
@ -1,6 +1,5 @@
|
|||
//
|
||||
//@ compile-flags:-Zprint-mono-items=eager
|
||||
//@ compile-flags:-Zinline-in-all-cgus
|
||||
//@ compile-flags: -O
|
||||
|
||||
#![deny(dead_code)]
|
||||
#![crate_type = "lib"]
|
||||
|
|
|
@ -1,6 +1,5 @@
|
|||
//
|
||||
//@ compile-flags:-Zprint-mono-items=eager
|
||||
//@ compile-flags:-Zinline-in-all-cgus
|
||||
//@ compile-flags: -O
|
||||
|
||||
#![deny(dead_code)]
|
||||
#![crate_type = "lib"]
|
||||
|
|
|
@ -1,5 +1,4 @@
|
|||
//@ compile-flags:-Zprint-mono-items=eager
|
||||
//@ compile-flags:-Zinline-in-all-cgus
|
||||
//@ compile-flags:-Zmir-opt-level=0
|
||||
|
||||
#![deny(dead_code)]
|
||||
|
|
14
tests/codegen-units/partitioning/README.md
Normal file
14
tests/codegen-units/partitioning/README.md
Normal file
|
@ -0,0 +1,14 @@
|
|||
# codegen-units/partitioning tests
|
||||
|
||||
This test suite is designed to test that codegen unit partitioning works as intended.
|
||||
Note that it does not evaluate whether CGU partitioning is *good*. That is the job of the compiler benchmark suite.
|
||||
|
||||
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:
|
||||
```
|
||||
MONO_ITEM <item> @@ <cgu name>[<linkage>] <other cgu name>[<linkage in other cgu>]
|
||||
```
|
||||
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.
|
||||
|
||||
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.
|
||||
|
||||
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).
|
|
@ -1,7 +1,6 @@
|
|||
// NOTE: We always compile this test with -Copt-level=0 because higher opt-levels
|
||||
// prevent drop-glue from participating in share-generics.
|
||||
//@ compile-flags:-Zshare-generics=yes -Copt-level=0
|
||||
//@ no-prefer-dynamic
|
||||
//@ compile-flags: -Zshare-generics=yes -Copt-level=0
|
||||
|
||||
#![crate_type = "rlib"]
|
||||
|
||||
|
|
|
@ -1,15 +1,14 @@
|
|||
// We specify incremental here because we want to test the partitioning for incremental compilation
|
||||
// We specify opt-level=0 because `drop_in_place` is `Internal` when optimizing
|
||||
//@ incremental
|
||||
//@ compile-flags:-Zprint-mono-items=lazy
|
||||
//@ compile-flags:-Zinline-in-all-cgus -Copt-level=0
|
||||
//@ compile-flags: -Zprint-mono-items=lazy -Copt-level=0
|
||||
|
||||
#![allow(dead_code)]
|
||||
#![crate_type = "rlib"]
|
||||
|
||||
//@ aux-build:cgu_extern_drop_glue.rs
|
||||
extern crate cgu_extern_drop_glue;
|
||||
|
||||
// This test checks that drop glue is generated, even for types not defined in this crate, and all
|
||||
// drop glue is put in the fallback CGU.
|
||||
|
||||
//~ 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]
|
||||
|
||||
struct LocalStruct(cgu_extern_drop_glue::Struct);
|
||||
|
|
|
@ -1,51 +1,36 @@
|
|||
// We specify incremental here because we want to test the partitioning for incremental compilation
|
||||
//@ incremental
|
||||
//@ compile-flags:-Zprint-mono-items=eager -Zshare-generics=y
|
||||
//@ compile-flags: -Zprint-mono-items=lazy -Copt-level=0
|
||||
|
||||
#![allow(dead_code)]
|
||||
#![crate_type = "lib"]
|
||||
|
||||
//@ aux-build:cgu_generic_function.rs
|
||||
extern crate cgu_generic_function;
|
||||
|
||||
//~ MONO_ITEM fn user @@ extern_generic[Internal]
|
||||
fn user() {
|
||||
// This test checks that, in an unoptimized build, a generic function and its callees are only
|
||||
// instantiated once in this crate.
|
||||
|
||||
//~ MONO_ITEM fn user @@ extern_generic[External]
|
||||
pub fn user() {
|
||||
let _ = cgu_generic_function::foo("abc");
|
||||
}
|
||||
|
||||
mod mod1 {
|
||||
pub mod mod1 {
|
||||
use cgu_generic_function;
|
||||
|
||||
//~ MONO_ITEM fn mod1::user @@ extern_generic-mod1[Internal]
|
||||
fn user() {
|
||||
//~ MONO_ITEM fn mod1::user @@ extern_generic-mod1[External]
|
||||
pub fn user() {
|
||||
let _ = cgu_generic_function::foo("abc");
|
||||
}
|
||||
|
||||
mod mod1 {
|
||||
pub mod mod1 {
|
||||
use cgu_generic_function;
|
||||
|
||||
//~ MONO_ITEM fn mod1::mod1::user @@ extern_generic-mod1-mod1[Internal]
|
||||
fn user() {
|
||||
//~ MONO_ITEM fn mod1::mod1::user @@ extern_generic-mod1-mod1[External]
|
||||
pub fn user() {
|
||||
let _ = cgu_generic_function::foo("abc");
|
||||
}
|
||||
}
|
||||
}
|
||||
|
||||
mod mod2 {
|
||||
use cgu_generic_function;
|
||||
|
||||
//~ MONO_ITEM fn mod2::user @@ extern_generic-mod2[Internal]
|
||||
fn user() {
|
||||
let _ = cgu_generic_function::foo("abc");
|
||||
}
|
||||
}
|
||||
|
||||
mod mod3 {
|
||||
//~ MONO_ITEM fn mod3::non_user @@ extern_generic-mod3[Internal]
|
||||
fn non_user() {}
|
||||
}
|
||||
|
||||
// Make sure the two generic functions from the extern crate get instantiated
|
||||
// once for the current crate
|
||||
//~ MONO_ITEM fn cgu_generic_function::foo::<&str> @@ cgu_generic_function-in-extern_generic.volatile[External]
|
||||
//~ MONO_ITEM fn cgu_generic_function::bar::<&str> @@ cgu_generic_function-in-extern_generic.volatile[External]
|
||||
|
|
|
@ -1,7 +1,5 @@
|
|||
// We specify incremental here because we want to test the partitioning for incremental compilation
|
||||
//@ incremental
|
||||
//@ compile-flags:-Zprint-mono-items=lazy
|
||||
//@ compile-flags:-Ccodegen-units=3
|
||||
//@ compile-flags: -Zprint-mono-items=lazy -Copt-level=0 -Ccodegen-units=3
|
||||
|
||||
#![crate_type = "rlib"]
|
||||
|
||||
|
@ -9,8 +7,9 @@
|
|||
// compilation but at the same time does not modify names of CGUs that were not
|
||||
// affected by merging.
|
||||
//
|
||||
// We expect CGUs `aaa` and `bbb` to be merged (because they are the smallest),
|
||||
// while `ccc` and `ddd` are supposed to stay untouched.
|
||||
// CGU partitioning creates one CGU per module, so with 4 modules and codegen-units=3,
|
||||
// two of the modules should be merged. We expect CGUs `aaa` and `bbb` to be merged
|
||||
// (because they are the smallest), while `ccc` and `ddd` should stay untouched.
|
||||
|
||||
pub mod aaa {
|
||||
//~ MONO_ITEM fn aaa::foo @@ incremental_merging-aaa--incremental_merging-bbb[External]
|
||||
|
|
38
tests/codegen-units/partitioning/inline-always.rs
Normal file
38
tests/codegen-units/partitioning/inline-always.rs
Normal file
|
@ -0,0 +1,38 @@
|
|||
//@ incremental
|
||||
//@ compile-flags: -Zprint-mono-items=lazy -Copt-level=0
|
||||
|
||||
#![crate_type = "lib"]
|
||||
|
||||
// This test checks that a monomorphic inline(always) function is instantiated in every CGU that
|
||||
// references it, even though this is an unoptimized incremental build.
|
||||
// It also checks that an inline(always) function is only placed in CGUs that reference it.
|
||||
|
||||
mod inline {
|
||||
//~ MONO_ITEM fn inline::inlined_function @@ inline_always-user1[Internal] inline_always-user2[Internal]
|
||||
#[inline(always)]
|
||||
pub fn inlined_function() {}
|
||||
}
|
||||
|
||||
pub mod user1 {
|
||||
use super::inline;
|
||||
|
||||
//~ MONO_ITEM fn user1::foo @@ inline_always-user1[External]
|
||||
pub fn foo() {
|
||||
inline::inlined_function();
|
||||
}
|
||||
}
|
||||
|
||||
pub mod user2 {
|
||||
use super::inline;
|
||||
|
||||
//~ MONO_ITEM fn user2::bar @@ inline_always-user2[External]
|
||||
pub fn bar() {
|
||||
inline::inlined_function();
|
||||
}
|
||||
}
|
||||
|
||||
pub mod non_user {
|
||||
|
||||
//~ MONO_ITEM fn non_user::baz @@ inline_always-non_user[External]
|
||||
pub fn baz() {}
|
||||
}
|
|
@ -1,7 +1,5 @@
|
|||
// We specify incremental here because we want to test the partitioning for incremental compilation
|
||||
//@ incremental
|
||||
//@ compile-flags:-Zprint-mono-items=lazy
|
||||
//@ compile-flags:-Zinline-in-all-cgus
|
||||
//@ compile-flags: -Zprint-mono-items=lazy -Copt-level=1
|
||||
|
||||
#![crate_type = "lib"]
|
||||
|
||||
|
|
|
@ -1,14 +1,14 @@
|
|||
// We specify incremental here because we want to test the partitioning for incremental compilation
|
||||
// We specify opt-level=0 because `drop_in_place` is `Internal` when optimizing
|
||||
//@ incremental
|
||||
//@ compile-flags:-Zprint-mono-items=lazy
|
||||
//@ compile-flags:-Zinline-in-all-cgus -Copt-level=0
|
||||
//@ compile-flags: -Zprint-mono-items=lazy -Copt-level=0
|
||||
|
||||
#![allow(dead_code)]
|
||||
#![crate_type = "rlib"]
|
||||
|
||||
// This test checks that drop glue is generated for types defined in this crate, and that all drop
|
||||
// glue is put in the fallback CGU.
|
||||
// This is rather similar to extern-drop-glue.rs.
|
||||
|
||||
//~ MONO_ITEM fn std::ptr::drop_in_place::<Struct> - shim(Some(Struct)) @@ local_drop_glue-fallback.cgu[External]
|
||||
struct Struct {
|
||||
pub struct Struct {
|
||||
_a: u32,
|
||||
}
|
||||
|
||||
|
@ -18,7 +18,7 @@ impl Drop for Struct {
|
|||
}
|
||||
|
||||
//~ MONO_ITEM fn std::ptr::drop_in_place::<Outer> - shim(Some(Outer)) @@ local_drop_glue-fallback.cgu[External]
|
||||
struct Outer {
|
||||
pub struct Outer {
|
||||
_a: Struct,
|
||||
}
|
||||
|
||||
|
@ -33,7 +33,7 @@ pub mod mod1 {
|
|||
//~ MONO_ITEM fn std::ptr::drop_in_place::<mod1::Struct2> - shim(Some(mod1::Struct2)) @@ local_drop_glue-fallback.cgu[External]
|
||||
struct Struct2 {
|
||||
_a: Struct,
|
||||
//~ MONO_ITEM fn std::ptr::drop_in_place::<(u32, Struct)> - shim(Some((u32, Struct))) @@ local_drop_glue-fallback.cgu[Internal]
|
||||
//~ MONO_ITEM fn std::ptr::drop_in_place::<(u32, Struct)> - shim(Some((u32, Struct))) @@ local_drop_glue-fallback.cgu[External]
|
||||
_b: (u32, Struct),
|
||||
}
|
||||
|
||||
|
|
|
@ -1,10 +1,11 @@
|
|||
// We specify incremental here because we want to test the partitioning for incremental compilation
|
||||
//@ incremental
|
||||
//@ compile-flags:-Zprint-mono-items=eager
|
||||
//@ compile-flags: -Zprint-mono-items=lazy -Copt-level=0
|
||||
|
||||
#![allow(dead_code)]
|
||||
#![crate_type = "lib"]
|
||||
|
||||
// This test checks that all the instantiations of a local generic fn are placed in the same CGU,
|
||||
// regardless of where it is called.
|
||||
|
||||
//~ MONO_ITEM fn generic::<u32> @@ local_generic.volatile[External]
|
||||
//~ MONO_ITEM fn generic::<u64> @@ local_generic.volatile[External]
|
||||
//~ MONO_ITEM fn generic::<char> @@ local_generic.volatile[External]
|
||||
|
@ -13,34 +14,34 @@ pub fn generic<T>(x: T) -> T {
|
|||
x
|
||||
}
|
||||
|
||||
//~ MONO_ITEM fn user @@ local_generic[Internal]
|
||||
fn user() {
|
||||
//~ MONO_ITEM fn user @@ local_generic[External]
|
||||
pub fn user() {
|
||||
let _ = generic(0u32);
|
||||
}
|
||||
|
||||
mod mod1 {
|
||||
pub mod mod1 {
|
||||
pub use super::generic;
|
||||
|
||||
//~ MONO_ITEM fn mod1::user @@ local_generic-mod1[Internal]
|
||||
fn user() {
|
||||
//~ MONO_ITEM fn mod1::user @@ local_generic-mod1[External]
|
||||
pub fn user() {
|
||||
let _ = generic(0u64);
|
||||
}
|
||||
|
||||
mod mod1 {
|
||||
pub mod mod1 {
|
||||
use super::generic;
|
||||
|
||||
//~ MONO_ITEM fn mod1::mod1::user @@ local_generic-mod1-mod1[Internal]
|
||||
fn user() {
|
||||
//~ MONO_ITEM fn mod1::mod1::user @@ local_generic-mod1-mod1[External]
|
||||
pub fn user() {
|
||||
let _ = generic('c');
|
||||
}
|
||||
}
|
||||
}
|
||||
|
||||
mod mod2 {
|
||||
pub mod mod2 {
|
||||
use super::generic;
|
||||
|
||||
//~ MONO_ITEM fn mod2::user @@ local_generic-mod2[Internal]
|
||||
fn user() {
|
||||
//~ MONO_ITEM fn mod2::user @@ local_generic-mod2[External]
|
||||
pub fn user() {
|
||||
let _ = generic("abc");
|
||||
}
|
||||
}
|
||||
|
|
|
@ -1,38 +0,0 @@
|
|||
// We specify incremental here because we want to test the partitioning for incremental compilation
|
||||
//@ incremental
|
||||
//@ compile-flags:-Zprint-mono-items=lazy
|
||||
//@ compile-flags:-Zinline-in-all-cgus=no
|
||||
|
||||
#![allow(dead_code)]
|
||||
#![crate_type = "lib"]
|
||||
|
||||
mod inline {
|
||||
|
||||
//~ MONO_ITEM fn inline::inlined_function @@ local_inlining_but_not_all-inline[External]
|
||||
#[inline]
|
||||
pub fn inlined_function() {}
|
||||
}
|
||||
|
||||
pub mod user1 {
|
||||
use super::inline;
|
||||
|
||||
//~ MONO_ITEM fn user1::foo @@ local_inlining_but_not_all-user1[External]
|
||||
pub fn foo() {
|
||||
inline::inlined_function();
|
||||
}
|
||||
}
|
||||
|
||||
pub mod user2 {
|
||||
use super::inline;
|
||||
|
||||
//~ MONO_ITEM fn user2::bar @@ local_inlining_but_not_all-user2[External]
|
||||
pub fn bar() {
|
||||
inline::inlined_function();
|
||||
}
|
||||
}
|
||||
|
||||
pub mod non_user {
|
||||
|
||||
//~ MONO_ITEM fn non_user::baz @@ local_inlining_but_not_all-non_user[External]
|
||||
pub fn baz() {}
|
||||
}
|
|
@ -1,39 +0,0 @@
|
|||
// We specify incremental here because we want to test the partitioning for incremental compilation
|
||||
//@ incremental
|
||||
//@ compile-flags:-Zprint-mono-items=lazy
|
||||
//@ compile-flags:-Zinline-in-all-cgus
|
||||
|
||||
#![allow(dead_code)]
|
||||
#![crate_type = "lib"]
|
||||
|
||||
mod inline {
|
||||
|
||||
// Important: This function should show up in all codegen units where it is inlined
|
||||
//~ MONO_ITEM fn inline::inlined_function @@ local_inlining-user1[Internal] local_inlining-user2[Internal]
|
||||
#[inline(always)]
|
||||
pub fn inlined_function() {}
|
||||
}
|
||||
|
||||
pub mod user1 {
|
||||
use super::inline;
|
||||
|
||||
//~ MONO_ITEM fn user1::foo @@ local_inlining-user1[External]
|
||||
pub fn foo() {
|
||||
inline::inlined_function();
|
||||
}
|
||||
}
|
||||
|
||||
pub mod user2 {
|
||||
use super::inline;
|
||||
|
||||
//~ MONO_ITEM fn user2::bar @@ local_inlining-user2[External]
|
||||
pub fn bar() {
|
||||
inline::inlined_function();
|
||||
}
|
||||
}
|
||||
|
||||
pub mod non_user {
|
||||
|
||||
//~ MONO_ITEM fn non_user::baz @@ local_inlining-non_user[External]
|
||||
pub fn baz() {}
|
||||
}
|
|
@ -1,11 +1,13 @@
|
|||
// We specify incremental here because we want to test the partitioning for incremental compilation
|
||||
//@ incremental
|
||||
//@ compile-flags:-Zprint-mono-items=lazy
|
||||
//@ compile-flags:-Zinline-in-all-cgus
|
||||
//@ compile-flags: -Zprint-mono-items=lazy -Copt-level=0
|
||||
|
||||
#![allow(dead_code)]
|
||||
#![crate_type = "rlib"]
|
||||
|
||||
// This test checks that a monomorphic inline(always) function is instantiated in every CGU that
|
||||
// references it, even if it is only referenced via another module.
|
||||
// The modules `inline` and `direct_user` do not get CGUs because they only define inline(always)
|
||||
// functions, which always get lazy codegen.
|
||||
|
||||
mod inline {
|
||||
|
||||
//~ MONO_ITEM fn inline::inlined_function @@ local_transitive_inlining-indirect_user[Internal]
|
||||
|
@ -13,7 +15,7 @@ mod inline {
|
|||
pub fn inlined_function() {}
|
||||
}
|
||||
|
||||
mod direct_user {
|
||||
pub mod direct_user {
|
||||
use super::inline;
|
||||
|
||||
//~ MONO_ITEM fn direct_user::foo @@ local_transitive_inlining-indirect_user[Internal]
|
||||
|
|
|
@ -1,9 +1,11 @@
|
|||
// We specify incremental here because we want to test the partitioning for incremental compilation
|
||||
//@ incremental
|
||||
//@ compile-flags:-Zprint-mono-items=lazy
|
||||
//@ compile-flags: -Zprint-mono-items=lazy -Copt-level=0
|
||||
|
||||
#![crate_type = "lib"]
|
||||
|
||||
// This test ensures that methods are assigned to the module where their self-type is defined, not
|
||||
// where the method is defined.
|
||||
|
||||
pub struct SomeType;
|
||||
|
||||
struct SomeGenericType<T1, T2>(T1, T2);
|
||||
|
|
|
@ -1,71 +1,71 @@
|
|||
// We specify incremental here because we want to test the partitioning for incremental compilation
|
||||
//@ incremental
|
||||
//@ compile-flags:-Zprint-mono-items=eager
|
||||
//@ compile-flags: -Zprint-mono-items=lazy -Copt-level=0
|
||||
|
||||
#![allow(dead_code)]
|
||||
#![crate_type = "lib"]
|
||||
|
||||
//~ MONO_ITEM fn foo @@ regular_modules[Internal]
|
||||
fn foo() {}
|
||||
// This test ensures that regular fn items and statics are assigned to the CGU of their module.
|
||||
|
||||
//~ MONO_ITEM fn bar @@ regular_modules[Internal]
|
||||
fn bar() {}
|
||||
//~ MONO_ITEM fn foo @@ regular_modules[External]
|
||||
pub fn foo() {}
|
||||
|
||||
//~ MONO_ITEM static BAZ @@ regular_modules[Internal]
|
||||
static BAZ: u64 = 0;
|
||||
//~ MONO_ITEM fn bar @@ regular_modules[External]
|
||||
pub fn bar() {}
|
||||
|
||||
mod mod1 {
|
||||
//~ MONO_ITEM static BAZ @@ regular_modules[External]
|
||||
pub static BAZ: u64 = 0;
|
||||
|
||||
//~ MONO_ITEM fn mod1::foo @@ regular_modules-mod1[Internal]
|
||||
fn foo() {}
|
||||
//~ MONO_ITEM fn mod1::bar @@ regular_modules-mod1[Internal]
|
||||
fn bar() {}
|
||||
//~ MONO_ITEM static mod1::BAZ @@ regular_modules-mod1[Internal]
|
||||
static BAZ: u64 = 0;
|
||||
pub mod mod1 {
|
||||
|
||||
mod mod1 {
|
||||
//~ MONO_ITEM fn mod1::mod1::foo @@ regular_modules-mod1-mod1[Internal]
|
||||
fn foo() {}
|
||||
//~ MONO_ITEM fn mod1::mod1::bar @@ regular_modules-mod1-mod1[Internal]
|
||||
fn bar() {}
|
||||
//~ MONO_ITEM static mod1::mod1::BAZ @@ regular_modules-mod1-mod1[Internal]
|
||||
static BAZ: u64 = 0;
|
||||
//~ MONO_ITEM fn mod1::foo @@ regular_modules-mod1[External]
|
||||
pub fn foo() {}
|
||||
//~ MONO_ITEM fn mod1::bar @@ regular_modules-mod1[External]
|
||||
pub fn bar() {}
|
||||
//~ MONO_ITEM static mod1::BAZ @@ regular_modules-mod1[External]
|
||||
pub static BAZ: u64 = 0;
|
||||
|
||||
pub mod mod1 {
|
||||
//~ MONO_ITEM fn mod1::mod1::foo @@ regular_modules-mod1-mod1[External]
|
||||
pub fn foo() {}
|
||||
//~ MONO_ITEM fn mod1::mod1::bar @@ regular_modules-mod1-mod1[External]
|
||||
pub fn bar() {}
|
||||
//~ MONO_ITEM static mod1::mod1::BAZ @@ regular_modules-mod1-mod1[External]
|
||||
pub static BAZ: u64 = 0;
|
||||
}
|
||||
|
||||
mod mod2 {
|
||||
//~ MONO_ITEM fn mod1::mod2::foo @@ regular_modules-mod1-mod2[Internal]
|
||||
fn foo() {}
|
||||
//~ MONO_ITEM fn mod1::mod2::bar @@ regular_modules-mod1-mod2[Internal]
|
||||
fn bar() {}
|
||||
//~ MONO_ITEM static mod1::mod2::BAZ @@ regular_modules-mod1-mod2[Internal]
|
||||
static BAZ: u64 = 0;
|
||||
pub mod mod2 {
|
||||
//~ MONO_ITEM fn mod1::mod2::foo @@ regular_modules-mod1-mod2[External]
|
||||
pub fn foo() {}
|
||||
//~ MONO_ITEM fn mod1::mod2::bar @@ regular_modules-mod1-mod2[External]
|
||||
pub fn bar() {}
|
||||
//~ MONO_ITEM static mod1::mod2::BAZ @@ regular_modules-mod1-mod2[External]
|
||||
pub static BAZ: u64 = 0;
|
||||
}
|
||||
}
|
||||
|
||||
mod mod2 {
|
||||
pub mod mod2 {
|
||||
|
||||
//~ MONO_ITEM fn mod2::foo @@ regular_modules-mod2[Internal]
|
||||
fn foo() {}
|
||||
//~ MONO_ITEM fn mod2::bar @@ regular_modules-mod2[Internal]
|
||||
fn bar() {}
|
||||
//~ MONO_ITEM static mod2::BAZ @@ regular_modules-mod2[Internal]
|
||||
static BAZ: u64 = 0;
|
||||
//~ MONO_ITEM fn mod2::foo @@ regular_modules-mod2[External]
|
||||
pub fn foo() {}
|
||||
//~ MONO_ITEM fn mod2::bar @@ regular_modules-mod2[External]
|
||||
pub fn bar() {}
|
||||
//~ MONO_ITEM static mod2::BAZ @@ regular_modules-mod2[External]
|
||||
pub static BAZ: u64 = 0;
|
||||
|
||||
mod mod1 {
|
||||
//~ MONO_ITEM fn mod2::mod1::foo @@ regular_modules-mod2-mod1[Internal]
|
||||
fn foo() {}
|
||||
//~ MONO_ITEM fn mod2::mod1::bar @@ regular_modules-mod2-mod1[Internal]
|
||||
fn bar() {}
|
||||
//~ MONO_ITEM static mod2::mod1::BAZ @@ regular_modules-mod2-mod1[Internal]
|
||||
static BAZ: u64 = 0;
|
||||
pub mod mod1 {
|
||||
//~ MONO_ITEM fn mod2::mod1::foo @@ regular_modules-mod2-mod1[External]
|
||||
pub fn foo() {}
|
||||
//~ MONO_ITEM fn mod2::mod1::bar @@ regular_modules-mod2-mod1[External]
|
||||
pub fn bar() {}
|
||||
//~ MONO_ITEM static mod2::mod1::BAZ @@ regular_modules-mod2-mod1[External]
|
||||
pub static BAZ: u64 = 0;
|
||||
}
|
||||
|
||||
mod mod2 {
|
||||
//~ MONO_ITEM fn mod2::mod2::foo @@ regular_modules-mod2-mod2[Internal]
|
||||
fn foo() {}
|
||||
//~ MONO_ITEM fn mod2::mod2::bar @@ regular_modules-mod2-mod2[Internal]
|
||||
fn bar() {}
|
||||
//~ MONO_ITEM static mod2::mod2::BAZ @@ regular_modules-mod2-mod2[Internal]
|
||||
static BAZ: u64 = 0;
|
||||
pub mod mod2 {
|
||||
//~ MONO_ITEM fn mod2::mod2::foo @@ regular_modules-mod2-mod2[External]
|
||||
pub fn foo() {}
|
||||
//~ MONO_ITEM fn mod2::mod2::bar @@ regular_modules-mod2-mod2[External]
|
||||
pub fn bar() {}
|
||||
//~ MONO_ITEM static mod2::mod2::BAZ @@ regular_modules-mod2-mod2[External]
|
||||
pub static BAZ: u64 = 0;
|
||||
}
|
||||
}
|
||||
|
|
|
@ -2,13 +2,19 @@
|
|||
// NOTE: We always compile this test with -Copt-level=0 because higher opt-levels
|
||||
// prevent drop-glue from participating in share-generics.
|
||||
//@ incremental
|
||||
//@ compile-flags:-Zprint-mono-items=eager -Zshare-generics=yes -Copt-level=0
|
||||
//@ compile-flags: -Zprint-mono-items=lazy -Zshare-generics=yes -Copt-level=0
|
||||
|
||||
#![crate_type = "rlib"]
|
||||
|
||||
//@ aux-build:shared_generics_aux.rs
|
||||
extern crate shared_generics_aux;
|
||||
|
||||
// This test ensures that when a crate and a dependency are compiled with -Zshare-generics, the
|
||||
// downstream crate reuses generic instantiations from the dependency, but will still instantiate
|
||||
// its own copy when instantiating with arguments that the dependency did not.
|
||||
// Drop glue has a lot of special handling in the compiler, so we check that drop glue is also
|
||||
// shared.
|
||||
|
||||
//~ MONO_ITEM fn foo
|
||||
pub fn foo() {
|
||||
//~ MONO_ITEM fn shared_generics_aux::generic_fn::<u16> @@ shared_generics_aux-in-shared_generics.volatile[External]
|
||||
|
|
|
@ -1,9 +1,11 @@
|
|||
// We specify incremental here because we want to test the partitioning for incremental compilation
|
||||
//@ incremental
|
||||
//@ compile-flags:-Zprint-mono-items=lazy
|
||||
//@ compile-flags: -Zprint-mono-items=lazy -Copt-level=0
|
||||
|
||||
#![crate_type = "rlib"]
|
||||
|
||||
// This test ensures that statics are assigned to the correct module when they are defined inside
|
||||
// of a function.
|
||||
|
||||
//~ MONO_ITEM static FOO @@ statics[Internal]
|
||||
static FOO: u32 = 0;
|
||||
|
||||
|
|
|
@ -1,14 +1,11 @@
|
|||
// We specify incremental here because we want to test the partitioning for incremental compilation
|
||||
//@ incremental
|
||||
//@ compile-flags:-Zprint-mono-items=lazy
|
||||
//@ compile-flags:-Zinline-in-all-cgus
|
||||
// Need to disable optimizations to ensure consistent output across all CI runners.
|
||||
//@ compile-flags:-Copt-level=0
|
||||
//@ compile-flags: -Zprint-mono-items=lazy -Copt-level=0
|
||||
|
||||
// This test case makes sure, that references made through constants are
|
||||
// recorded properly in the InliningMap.
|
||||
#![crate_type = "rlib"]
|
||||
|
||||
#![crate_type = "lib"]
|
||||
// This test case makes sure that references made through constants cause trait associated methods
|
||||
// to be monomorphized when required.
|
||||
|
||||
mod mod1 {
|
||||
struct NeedsDrop;
|
||||
|
@ -43,7 +40,7 @@ mod mod1 {
|
|||
x
|
||||
}
|
||||
|
||||
// These are referenced, so they produce mono-items (see start())
|
||||
// These are referenced, so they produce mono-items (see main)
|
||||
pub const TRAIT1_REF: &'static Trait1 = &NeedsDrop as &Trait1;
|
||||
pub const TRAIT1_GEN_REF: &'static Trait1Gen<u8> = &NeedsDrop as &Trait1Gen<u8>;
|
||||
pub const ID_CHAR: fn(char) -> char = id::<char>;
|
||||
|
@ -77,9 +74,8 @@ mod mod1 {
|
|||
pub const ID_I64: fn(i64) -> i64 = id::<i64>;
|
||||
}
|
||||
|
||||
//~ MONO_ITEM fn start
|
||||
#[no_mangle]
|
||||
pub fn start(_: isize, _: *const *const u8) -> isize {
|
||||
//~ MONO_ITEM fn main @@ vtable_through_const[External]
|
||||
pub fn main() {
|
||||
//~ MONO_ITEM fn <mod1::NeedsDrop as std::ops::Drop>::drop @@ vtable_through_const-fallback.cgu[External]
|
||||
//~ MONO_ITEM fn std::ptr::drop_in_place::<mod1::NeedsDrop> - shim(Some(mod1::NeedsDrop)) @@ vtable_through_const-fallback.cgu[External]
|
||||
|
||||
|
@ -103,6 +99,4 @@ pub fn start(_: isize, _: *const *const u8) -> isize {
|
|||
|
||||
//~ MONO_ITEM fn mod1::id::<char> @@ vtable_through_const-mod1.volatile[External]
|
||||
mod1::ID_CHAR('x');
|
||||
|
||||
0
|
||||
}
|
||||
|
|
|
@ -1,6 +0,0 @@
|
|||
#![crate_type = "rlib"]
|
||||
|
||||
#[inline]
|
||||
pub fn cci_fn() -> usize {
|
||||
1234
|
||||
}
|
|
@ -1,25 +0,0 @@
|
|||
extern crate cci_lib;
|
||||
use cci_lib::cci_fn;
|
||||
|
||||
fn call1() -> usize {
|
||||
cci_fn()
|
||||
}
|
||||
|
||||
mod a {
|
||||
use cci_lib::cci_fn;
|
||||
pub fn call2() -> usize {
|
||||
cci_fn()
|
||||
}
|
||||
}
|
||||
|
||||
mod b {
|
||||
pub fn call3() -> usize {
|
||||
0
|
||||
}
|
||||
}
|
||||
|
||||
fn main() {
|
||||
call1();
|
||||
a::call2();
|
||||
b::call3();
|
||||
}
|
|
@ -1,14 +0,0 @@
|
|||
// Check that cross-crate inlined items are inlined in all compilation units
|
||||
// that refer to them, and not in any other compilation units.
|
||||
// Note that we have to pass `-C codegen-units=6` because up to two CGUs may be
|
||||
// created for each source module (see `rustc_const_eval::monomorphize::partitioning`).
|
||||
// See https://github.com/rust-lang/rust/pull/16367
|
||||
|
||||
use run_make_support::{count_regex_matches_in_files_with_extension, regex, rustc};
|
||||
|
||||
fn main() {
|
||||
rustc().input("cci_lib.rs").run();
|
||||
rustc().input("foo.rs").emit("llvm-ir").codegen_units(6).arg("-Zinline-in-all-cgus").run();
|
||||
let re = regex::Regex::new(r#"define\ .*cci_fn"#).unwrap();
|
||||
assert_eq!(count_regex_matches_in_files_with_extension(&re, "ll"), 2);
|
||||
}
|
|
@ -1,29 +0,0 @@
|
|||
#![crate_type = "lib"]
|
||||
|
||||
#[inline]
|
||||
fn inlined() -> u32 {
|
||||
1234
|
||||
}
|
||||
|
||||
fn normal() -> u32 {
|
||||
2345
|
||||
}
|
||||
|
||||
mod a {
|
||||
pub fn f() -> u32 {
|
||||
::inlined() + ::normal()
|
||||
}
|
||||
}
|
||||
|
||||
mod b {
|
||||
pub fn f() -> u32 {
|
||||
::inlined() + ::normal()
|
||||
}
|
||||
}
|
||||
|
||||
pub fn start(_: isize, _: *const *const u8) -> isize {
|
||||
a::f();
|
||||
b::f();
|
||||
|
||||
0
|
||||
}
|
|
@ -1,20 +0,0 @@
|
|||
// Test that #[inline] functions still get inlined across compilation unit
|
||||
// boundaries. Compilation should produce three IR files, but only the two
|
||||
// compilation units that have a usage of the #[inline] function should
|
||||
// contain a definition. Also, the non-#[inline] function should be defined
|
||||
// in only one compilation unit.
|
||||
// See https://github.com/rust-lang/rust/pull/16367
|
||||
|
||||
use run_make_support::{count_regex_matches_in_files_with_extension, regex, rustc};
|
||||
|
||||
fn main() {
|
||||
rustc().input("foo.rs").emit("llvm-ir").codegen_units(3).arg("-Zinline-in-all-cgus").run();
|
||||
let re = regex::Regex::new(r#"define\ i32\ .*inlined"#).unwrap();
|
||||
assert_eq!(count_regex_matches_in_files_with_extension(&re, "ll"), 0);
|
||||
let re = regex::Regex::new(r#"define\ internal\ .*inlined"#).unwrap();
|
||||
assert_eq!(count_regex_matches_in_files_with_extension(&re, "ll"), 2);
|
||||
let re = regex::Regex::new(r#"define\ hidden\ i32\ .*normal"#).unwrap();
|
||||
assert_eq!(count_regex_matches_in_files_with_extension(&re, "ll"), 1);
|
||||
let re = regex::Regex::new(r#"declare\ hidden\ i32\ .*normal"#).unwrap();
|
||||
assert_eq!(count_regex_matches_in_files_with_extension(&re, "ll"), 2);
|
||||
}
|
|
@ -1,21 +0,0 @@
|
|||
fn magic_fn() -> usize {
|
||||
1234
|
||||
}
|
||||
|
||||
mod a {
|
||||
pub fn magic_fn() -> usize {
|
||||
2345
|
||||
}
|
||||
}
|
||||
|
||||
mod b {
|
||||
pub fn magic_fn() -> usize {
|
||||
3456
|
||||
}
|
||||
}
|
||||
|
||||
fn main() {
|
||||
magic_fn();
|
||||
a::magic_fn();
|
||||
b::magic_fn();
|
||||
}
|
|
@ -1,12 +0,0 @@
|
|||
// Test that separate compilation actually puts code into separate compilation
|
||||
// units. `foo.rs` defines `magic_fn` in three different modules, which should
|
||||
// wind up in three different compilation units.
|
||||
// See https://github.com/rust-lang/rust/pull/16367
|
||||
|
||||
use run_make_support::{count_regex_matches_in_files_with_extension, regex, rustc};
|
||||
|
||||
fn main() {
|
||||
rustc().input("foo.rs").emit("llvm-ir").codegen_units(3).run();
|
||||
let re = regex::Regex::new(r#"define\ .*magic_fn"#).unwrap();
|
||||
assert_eq!(count_regex_matches_in_files_with_extension(&re, "ll"), 3);
|
||||
}
|
Loading…
Add table
Add a link
Reference in a new issue