Skip to content

Commit

Permalink
Auto merge of #123610 - Mark-Simulacrum:share-generics-available-exte…
Browse files Browse the repository at this point in the history
…rnally, 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 #14527

r? `@Mark-Simulacrum` for now
  • Loading branch information
bors committed Apr 7, 2024
2 parents 9d5cdf7 + 7f69532 commit 0962dae
Show file tree
Hide file tree
Showing 4 changed files with 37 additions and 9 deletions.
5 changes: 4 additions & 1 deletion compiler/rustc_monomorphize/src/collector.rs
Original file line number Diff line number Diff line change
Expand Up @@ -1127,7 +1127,10 @@ pub(crate) fn should_codegen_locally<'tcx>(tcx: TyCtxt<'tcx>, instance: Instance
|| instance.polymorphize(tcx).upstream_monomorphization(tcx).is_some()
{
// We can link to the item in question, no instance needed in this crate.
return false;
// However, we will still codegen this item locally *if* we have the MIR to do so.
// This codegen will happen in LLVM with available_externally linkage, which lets us benefit
// from inlining etc. while saving on binary size.
return tcx.is_mir_available(def_id);
}

if let DefKind::Static { .. } = tcx.def_kind(def_id) {
Expand Down
31 changes: 31 additions & 0 deletions compiler/rustc_monomorphize/src/partitioning.rs
Original file line number Diff line number Diff line change
Expand Up @@ -174,6 +174,37 @@ where
debug_dump(tcx, "INTERNALIZE", &codegen_units);
}

// Mark items we're importing from upstream
for cgu in codegen_units.iter_mut() {
for (item, data) in cgu.items_mut() {
if let MonoItem::Fn(instance) = item {
let Some(def_id) = instance.def.def_id_if_not_guaranteed_local_codegen() else {
continue;
};

if tcx.is_foreign_item(def_id) {
continue;
}

if def_id.is_local() {
continue;
}

if tcx.is_reachable_non_generic(instance.def_id())
|| instance.polymorphize(tcx).upstream_monomorphization(tcx).is_some()
{
// We can link to the item in question, no instance needed in this crate.
// However, we will still codegen this item locally *if* we have the MIR to do so.
// This codegen will happen in LLVM with available_externally linkage, which lets us benefit
// from inlining etc. while saving on binary size.
if tcx.is_mir_available(instance.def_id()) {
data.linkage = Linkage::AvailableExternally;
}
}
}
}
}

// Mark one CGU for dead code, if necessary.
if tcx.sess.instrument_coverage() {
mark_code_coverage_dead_code_cgu(&mut codegen_units);
Expand Down
8 changes: 1 addition & 7 deletions compiler/rustc_session/src/config.rs
Original file line number Diff line number Diff line change
Expand Up @@ -1095,13 +1095,7 @@ impl Options {

#[inline]
pub fn share_generics(&self) -> bool {
match self.unstable_opts.share_generics {
Some(setting) => setting,
None => match self.optimize {
OptLevel::No | OptLevel::Less | OptLevel::Size | OptLevel::SizeMin => true,
OptLevel::Default | OptLevel::Aggressive => false,
},
}
true
}

pub fn get_symbol_mangling_version(&self) -> SymbolManglingVersion {
Expand Down
2 changes: 1 addition & 1 deletion compiler/rustc_symbol_mangling/src/lib.rs
Original file line number Diff line number Diff line change
Expand Up @@ -141,7 +141,7 @@ fn symbol_name_provider<'tcx>(tcx: TyCtxt<'tcx>, instance: Instance<'tcx>) -> ty
// to differentiate between local copies.
if is_generic(instance, tcx) {
// For generics we might find re-usable upstream instances. If there
// is one, we rely on the symbol being instantiated locally.
// is not one, we rely on the symbol being instantiated locally.
instance.upstream_monomorphization(tcx).unwrap_or(LOCAL_CRATE)
} else {
// For non-generic things that need to avoid naming conflicts, we
Expand Down

0 comments on commit 0962dae

Please sign in to comment.