Skip to content

Commit

Permalink
Default-enable share-generics, with available_externally to still all…
Browse files Browse the repository at this point in the history
…ow inlining

WIP, just experimenting, not clear whether this works for other codegen
backends, or how practical of a tradeoff it is.
  • Loading branch information
Mark-Simulacrum committed Apr 7, 2024
1 parent aa1c459 commit 7f69532
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 7f69532

Please sign in to comment.