Skip to content

Commit 0962dae

Browse files
committed
Auto merge of rust-lang#123610 - Mark-Simulacrum:share-generics-available-externally, r=<try>
Default-enable share-generics, with available_externally to still allow inlining. WIP, just experimenting, not clear whether this works for other codegen backends, or how practical of a tradeoff it is. cc rust-lang#14527 r? `@Mark-Simulacrum` for now
2 parents 9d5cdf7 + 7f69532 commit 0962dae

File tree

4 files changed

+37
-9
lines changed

4 files changed

+37
-9
lines changed

compiler/rustc_monomorphize/src/collector.rs

+4-1
Original file line numberDiff line numberDiff line change
@@ -1127,7 +1127,10 @@ pub(crate) fn should_codegen_locally<'tcx>(tcx: TyCtxt<'tcx>, instance: Instance
11271127
|| instance.polymorphize(tcx).upstream_monomorphization(tcx).is_some()
11281128
{
11291129
// We can link to the item in question, no instance needed in this crate.
1130-
return false;
1130+
// However, we will still codegen this item locally *if* we have the MIR to do so.
1131+
// This codegen will happen in LLVM with available_externally linkage, which lets us benefit
1132+
// from inlining etc. while saving on binary size.
1133+
return tcx.is_mir_available(def_id);
11311134
}
11321135

11331136
if let DefKind::Static { .. } = tcx.def_kind(def_id) {

compiler/rustc_monomorphize/src/partitioning.rs

+31
Original file line numberDiff line numberDiff line change
@@ -174,6 +174,37 @@ where
174174
debug_dump(tcx, "INTERNALIZE", &codegen_units);
175175
}
176176

177+
// Mark items we're importing from upstream
178+
for cgu in codegen_units.iter_mut() {
179+
for (item, data) in cgu.items_mut() {
180+
if let MonoItem::Fn(instance) = item {
181+
let Some(def_id) = instance.def.def_id_if_not_guaranteed_local_codegen() else {
182+
continue;
183+
};
184+
185+
if tcx.is_foreign_item(def_id) {
186+
continue;
187+
}
188+
189+
if def_id.is_local() {
190+
continue;
191+
}
192+
193+
if tcx.is_reachable_non_generic(instance.def_id())
194+
|| instance.polymorphize(tcx).upstream_monomorphization(tcx).is_some()
195+
{
196+
// We can link to the item in question, no instance needed in this crate.
197+
// However, we will still codegen this item locally *if* we have the MIR to do so.
198+
// This codegen will happen in LLVM with available_externally linkage, which lets us benefit
199+
// from inlining etc. while saving on binary size.
200+
if tcx.is_mir_available(instance.def_id()) {
201+
data.linkage = Linkage::AvailableExternally;
202+
}
203+
}
204+
}
205+
}
206+
}
207+
177208
// Mark one CGU for dead code, if necessary.
178209
if tcx.sess.instrument_coverage() {
179210
mark_code_coverage_dead_code_cgu(&mut codegen_units);

compiler/rustc_session/src/config.rs

+1-7
Original file line numberDiff line numberDiff line change
@@ -1095,13 +1095,7 @@ impl Options {
10951095

10961096
#[inline]
10971097
pub fn share_generics(&self) -> bool {
1098-
match self.unstable_opts.share_generics {
1099-
Some(setting) => setting,
1100-
None => match self.optimize {
1101-
OptLevel::No | OptLevel::Less | OptLevel::Size | OptLevel::SizeMin => true,
1102-
OptLevel::Default | OptLevel::Aggressive => false,
1103-
},
1104-
}
1098+
true
11051099
}
11061100

11071101
pub fn get_symbol_mangling_version(&self) -> SymbolManglingVersion {

compiler/rustc_symbol_mangling/src/lib.rs

+1-1
Original file line numberDiff line numberDiff line change
@@ -141,7 +141,7 @@ fn symbol_name_provider<'tcx>(tcx: TyCtxt<'tcx>, instance: Instance<'tcx>) -> ty
141141
// to differentiate between local copies.
142142
if is_generic(instance, tcx) {
143143
// For generics we might find re-usable upstream instances. If there
144-
// is one, we rely on the symbol being instantiated locally.
144+
// is not one, we rely on the symbol being instantiated locally.
145145
instance.upstream_monomorphization(tcx).unwrap_or(LOCAL_CRATE)
146146
} else {
147147
// For non-generic things that need to avoid naming conflicts, we

0 commit comments

Comments
 (0)