From 0d9924a87b862529591c3039959fef5bc7c95359 Mon Sep 17 00:00:00 2001 From: David Wood Date: Fri, 7 Aug 2020 17:11:16 +0100 Subject: instance: always polymorphize substs By always polymorphizing substitutions, functions which take closures as arguments (e.g. `impl Fn()`) can have fewer mono items when some of the argument closures can be polymorphized. Signed-off-by: David Wood --- .../codegen-units/polymorphization/pr-75255.rs | 37 ++++++++++++++++++++++ 1 file changed, 37 insertions(+) create mode 100644 src/test/codegen-units/polymorphization/pr-75255.rs (limited to 'src/test/codegen-units/polymorphization') diff --git a/src/test/codegen-units/polymorphization/pr-75255.rs b/src/test/codegen-units/polymorphization/pr-75255.rs new file mode 100644 index 00000000000..ea9a6e8b181 --- /dev/null +++ b/src/test/codegen-units/polymorphization/pr-75255.rs @@ -0,0 +1,37 @@ +// compile-flags:-Zpolymorphize=on -Zprint-mono-items=lazy -Copt-level=1 +// ignore-tidy-linelength + +#![crate_type = "rlib"] + +// Test that only one copy of `Iter::map` is generated. + +fn foo() { + let x = [1, 2, 3, std::mem::size_of::()]; + x.iter().map(|_| ()); +} + +pub fn dispatch() { + foo::(); + foo::>(); +} + +//~ MONO_ITEM fn core::iter[0]::adapters[0]::{{impl}}[29]::new[0], pr_75255::foo[0]::{{closure}}[0]> @@ pr_75255-cgu.0[External] +//~ MONO_ITEM fn core::iter[0]::traits[0]::iterator[0]::Iterator[0]::map[0], (), pr_75255::foo[0]::{{closure}}[0]> @@ pr_75255-cgu.1[Internal] + +// These are all the items that aren't relevant to the test. +//~ MONO_ITEM fn core::mem[0]::size_of[0] @@ pr_75255-cgu.1[Internal] +//~ MONO_ITEM fn core::mem[0]::size_of[0]> @@ pr_75255-cgu.1[Internal] +//~ MONO_ITEM fn core::mem[0]::size_of[0] @@ pr_75255-cgu.1[Internal] +//~ MONO_ITEM fn core::ptr[0]::const_ptr[0]::{{impl}}[0]::add[0] @@ pr_75255-cgu.1[Internal] +//~ MONO_ITEM fn core::ptr[0]::const_ptr[0]::{{impl}}[0]::is_null[0] @@ pr_75255-cgu.1[Internal] +//~ MONO_ITEM fn core::ptr[0]::const_ptr[0]::{{impl}}[0]::offset[0] @@ pr_75255-cgu.1[Internal] +//~ MONO_ITEM fn core::ptr[0]::const_ptr[0]::{{impl}}[0]::wrapping_add[0] @@ pr_75255-cgu.1[Internal] +//~ MONO_ITEM fn core::ptr[0]::const_ptr[0]::{{impl}}[0]::wrapping_offset[0] @@ pr_75255-cgu.1[Internal] +//~ MONO_ITEM fn core::ptr[0]::non_null[0]::{{impl}}[3]::new_unchecked[0] @@ pr_75255-cgu.1[Internal] +//~ MONO_ITEM fn core::ptr[0]::null[0] @@ pr_75255-cgu.1[Internal] +//~ MONO_ITEM fn core::slice[0]::{{impl}}[0]::as_ptr[0] @@ pr_75255-cgu.1[Internal] +//~ MONO_ITEM fn core::slice[0]::{{impl}}[0]::iter[0] @@ pr_75255-cgu.1[Internal] +//~ MONO_ITEM fn core::slice[0]::{{impl}}[0]::len[0] @@ pr_75255-cgu.1[Internal] +//~ MONO_ITEM fn pr_75255::dispatch[0] @@ pr_75255-cgu.1[External] +//~ MONO_ITEM fn pr_75255::foo[0] @@ pr_75255-cgu.1[Internal] +//~ MONO_ITEM fn pr_75255::foo[0]> @@ pr_75255-cgu.1[Internal] -- cgit 1.4.1-3-g733a5 From ac50d61785ae5112b9b4e30a58cfcffe096b31ec Mon Sep 17 00:00:00 2001 From: David Wood Date: Fri, 7 Aug 2020 17:57:21 +0100 Subject: instance: polymorphize `FnDef` substs This commit extends previous polymorphization of substs to polymorphize `FnDef`. Signed-off-by: David Wood --- src/librustc_middle/ty/flags.rs | 2 ++ src/librustc_middle/ty/fold.rs | 2 +- src/librustc_middle/ty/instance.rs | 8 ++++++++ src/librustc_middle/ty/mod.rs | 2 +- .../codegen-units/polymorphization/pr-75255.rs | 23 ++++++++++++++++++---- 5 files changed, 31 insertions(+), 6 deletions(-) (limited to 'src/test/codegen-units/polymorphization') diff --git a/src/librustc_middle/ty/flags.rs b/src/librustc_middle/ty/flags.rs index 1782c38f573..81f7474962c 100644 --- a/src/librustc_middle/ty/flags.rs +++ b/src/librustc_middle/ty/flags.rs @@ -196,6 +196,8 @@ impl FlagComputation { } &ty::FnDef(_, substs) => { + self.add_flags(TypeFlags::MAY_POLYMORPHIZE); + self.add_substs(substs); } diff --git a/src/librustc_middle/ty/fold.rs b/src/librustc_middle/ty/fold.rs index c7dbd79e033..87434f3f267 100644 --- a/src/librustc_middle/ty/fold.rs +++ b/src/librustc_middle/ty/fold.rs @@ -150,7 +150,7 @@ pub trait TypeFoldable<'tcx>: fmt::Debug + Clone { self.has_type_flags(TypeFlags::STILL_FURTHER_SPECIALIZABLE) } - /// Does this value contain closures or generators such that it may require + /// Does this value contain closures, generators or functions such that it may require /// polymorphization? fn may_polymorphize(&self) -> bool { self.has_type_flags(TypeFlags::MAY_POLYMORPHIZE) diff --git a/src/librustc_middle/ty/instance.rs b/src/librustc_middle/ty/instance.rs index 0eea10513d1..cf876db26bc 100644 --- a/src/librustc_middle/ty/instance.rs +++ b/src/librustc_middle/ty/instance.rs @@ -512,6 +512,14 @@ fn polymorphize<'tcx>( self.tcx.mk_closure(def_id, polymorphized_substs) } } + ty::FnDef(def_id, substs) => { + let polymorphized_substs = polymorphize(self.tcx, def_id, substs); + if substs == polymorphized_substs { + ty + } else { + self.tcx.mk_fn_def(def_id, polymorphized_substs) + } + } ty::Generator(def_id, substs, movability) => { let polymorphized_substs = polymorphize(self.tcx, def_id, substs); if substs == polymorphized_substs { diff --git a/src/librustc_middle/ty/mod.rs b/src/librustc_middle/ty/mod.rs index 349add46fb2..c82fb2712c2 100644 --- a/src/librustc_middle/ty/mod.rs +++ b/src/librustc_middle/ty/mod.rs @@ -576,7 +576,7 @@ bitflags! { /// replaced later, in a way that would change the results of `impl` specialization? const STILL_FURTHER_SPECIALIZABLE = 1 << 17; - /// Does this value contain closures or generators such that it may require + /// Does this value contain closures, generators or functions such that it may require /// polymorphization? const MAY_POLYMORPHIZE = 1 << 18; } diff --git a/src/test/codegen-units/polymorphization/pr-75255.rs b/src/test/codegen-units/polymorphization/pr-75255.rs index ea9a6e8b181..af47b440640 100644 --- a/src/test/codegen-units/polymorphization/pr-75255.rs +++ b/src/test/codegen-units/polymorphization/pr-75255.rs @@ -3,20 +3,33 @@ #![crate_type = "rlib"] -// Test that only one copy of `Iter::map` is generated. +// Test that only one copy of `Iter::map` and `iter::repeat` are generated. + +fn unused() -> u64 { + 42 +} fn foo() { let x = [1, 2, 3, std::mem::size_of::()]; x.iter().map(|_| ()); } +//~ MONO_ITEM fn core::iter[0]::adapters[0]::{{impl}}[29]::new[0], pr_75255::foo[0]::{{closure}}[0]> @@ pr_75255-cgu.0[External] +//~ MONO_ITEM fn core::iter[0]::traits[0]::iterator[0]::Iterator[0]::map[0], (), pr_75255::foo[0]::{{closure}}[0]> @@ pr_75255-cgu.1[Internal] + +fn bar() { + std::iter::repeat(unused::); +} + +//~ MONO_ITEM fn core::iter[0]::sources[0]::repeat[0] u64> @@ pr_75255-cgu.1[Internal] + pub fn dispatch() { foo::(); foo::>(); -} -//~ MONO_ITEM fn core::iter[0]::adapters[0]::{{impl}}[29]::new[0], pr_75255::foo[0]::{{closure}}[0]> @@ pr_75255-cgu.0[External] -//~ MONO_ITEM fn core::iter[0]::traits[0]::iterator[0]::Iterator[0]::map[0], (), pr_75255::foo[0]::{{closure}}[0]> @@ pr_75255-cgu.1[Internal] + bar::(); + bar::>(); +} // These are all the items that aren't relevant to the test. //~ MONO_ITEM fn core::mem[0]::size_of[0] @@ pr_75255-cgu.1[Internal] @@ -35,3 +48,5 @@ pub fn dispatch() { //~ MONO_ITEM fn pr_75255::dispatch[0] @@ pr_75255-cgu.1[External] //~ MONO_ITEM fn pr_75255::foo[0] @@ pr_75255-cgu.1[Internal] //~ MONO_ITEM fn pr_75255::foo[0]> @@ pr_75255-cgu.1[Internal] +//~ MONO_ITEM fn pr_75255::bar[0] @@ pr_75255-cgu.1[Internal] +//~ MONO_ITEM fn pr_75255::bar[0]> @@ pr_75255-cgu.1[Internal] -- cgit 1.4.1-3-g733a5