Skip to content

Commit

Permalink
Auto merge of #113684 - nnethercote:streamline-size-estimates, r=<try>
Browse files Browse the repository at this point in the history
Streamline size estimates

Makes things nicer and a tiny bit faster.

r? `@wesleywiser`
  • Loading branch information
bors committed Jul 14, 2023
2 parents ad96323 + f4c4602 commit bef6ff6
Show file tree
Hide file tree
Showing 8 changed files with 85 additions and 97 deletions.
10 changes: 5 additions & 5 deletions compiler/rustc_codegen_cranelift/src/driver/mod.rs
Original file line number Diff line number Diff line change
Expand Up @@ -5,7 +5,7 @@
//! [`codegen_static`]: crate::constant::codegen_static

use rustc_data_structures::profiling::SelfProfilerRef;
use rustc_middle::mir::mono::{Linkage as RLinkage, MonoItem, Visibility};
use rustc_middle::mir::mono::{MonoItem, MonoItemData};

use crate::prelude::*;

Expand All @@ -16,11 +16,11 @@ pub(crate) mod jit;
fn predefine_mono_items<'tcx>(
tcx: TyCtxt<'tcx>,
module: &mut dyn Module,
mono_items: &[(MonoItem<'tcx>, (RLinkage, Visibility))],
mono_items: &[(MonoItem<'tcx>, MonoItemData)],
) {
tcx.prof.generic_activity("predefine functions").run(|| {
let is_compiler_builtins = tcx.is_compiler_builtins(LOCAL_CRATE);
for &(mono_item, (linkage, visibility)) in mono_items {
for &(mono_item, data) in mono_items {
match mono_item {
MonoItem::Fn(instance) => {
let name = tcx.symbol_name(instance).name;
Expand All @@ -29,8 +29,8 @@ fn predefine_mono_items<'tcx>(
get_function_sig(tcx, module.target_config().default_call_conv, instance);
let linkage = crate::linkage::get_clif_linkage(
mono_item,
linkage,
visibility,
data.linkage,
data.visibility,
is_compiler_builtins,
);
module.declare_function(name, linkage, &sig).unwrap();
Expand Down
4 changes: 2 additions & 2 deletions compiler/rustc_codegen_gcc/src/base.rs
Original file line number Diff line number Diff line change
Expand Up @@ -159,8 +159,8 @@ pub fn compile_codegen_unit(tcx: TyCtxt<'_>, cgu_name: Symbol, supports_128bit_i
let cx = CodegenCx::new(&context, cgu, tcx, supports_128bit_integers);

let mono_items = cgu.items_in_deterministic_order(tcx);
for &(mono_item, (linkage, visibility)) in &mono_items {
mono_item.predefine::<Builder<'_, '_, '_>>(&cx, linkage, visibility);
for &(mono_item, data) in &mono_items {
mono_item.predefine::<Builder<'_, '_, '_>>(&cx, data.linkage, data.visibility);
}

// ... and now that we have everything pre-defined, fill out those definitions.
Expand Down
4 changes: 2 additions & 2 deletions compiler/rustc_codegen_llvm/src/base.rs
Original file line number Diff line number Diff line change
Expand Up @@ -86,8 +86,8 @@ pub fn compile_codegen_unit(tcx: TyCtxt<'_>, cgu_name: Symbol) -> (ModuleCodegen
{
let cx = CodegenCx::new(tcx, cgu, &llvm_module);
let mono_items = cx.codegen_unit.items_in_deterministic_order(cx.tcx);
for &(mono_item, (linkage, visibility)) in &mono_items {
mono_item.predefine::<Builder<'_, '_, '_>>(&cx, linkage, visibility);
for &(mono_item, data) in &mono_items {
mono_item.predefine::<Builder<'_, '_, '_>>(&cx, data.linkage, data.visibility);
}

// ... and now that we have everything pre-defined, fill out those definitions.
Expand Down
6 changes: 3 additions & 3 deletions compiler/rustc_codegen_ssa/src/back/symbol_export.rs
Original file line number Diff line number Diff line change
Expand Up @@ -328,14 +328,14 @@ fn exported_symbols_provider_local(

let (_, cgus) = tcx.collect_and_partition_mono_items(());

for (mono_item, &(linkage, visibility)) in cgus.iter().flat_map(|cgu| cgu.items().iter()) {
if linkage != Linkage::External {
for (mono_item, data) in cgus.iter().flat_map(|cgu| cgu.items().iter()) {
if data.linkage != Linkage::External {
// We can only re-use things with external linkage, otherwise
// we'll get a linker error
continue;
}

if need_visibility && visibility == Visibility::Hidden {
if need_visibility && data.visibility == Visibility::Hidden {
// If we potentially share things from Rust dylibs, they must
// not be hidden
continue;
Expand Down
45 changes: 30 additions & 15 deletions compiler/rustc_middle/src/mir/mono.rs
Original file line number Diff line number Diff line change
Expand Up @@ -59,12 +59,19 @@ impl<'tcx> MonoItem<'tcx> {
pub fn size_estimate(&self, tcx: TyCtxt<'tcx>) -> usize {
match *self {
MonoItem::Fn(instance) => {
// Estimate the size of a function based on how many statements
// it contains.
tcx.instance_def_size_estimate(instance.def)
match instance.def {
// "Normal" functions size estimate: the number of
// statements, plus one for the terminator.
InstanceDef::Item(..) | InstanceDef::DropGlue(..) => {
let mir = tcx.instance_mir(instance.def);
mir.basic_blocks.iter().map(|bb| bb.statements.len() + 1).sum()
}
// Other compiler-generated shims size estimate: 1
_ => 1,
}
}
// Conservatively estimate the size of a static declaration
// or assembly to be 1.
// Conservatively estimate the size of a static declaration or
// assembly item to be 1.
MonoItem::Static(_) | MonoItem::GlobalAsm(_) => 1,
}
}
Expand Down Expand Up @@ -230,14 +237,22 @@ pub struct CodegenUnit<'tcx> {
/// contain something unique to this crate (e.g., a module path)
/// as well as the crate name and disambiguator.
name: Symbol,
items: FxHashMap<MonoItem<'tcx>, (Linkage, Visibility)>,
items: FxHashMap<MonoItem<'tcx>, MonoItemData>,
size_estimate: usize,
primary: bool,
/// True if this is CGU is used to hold code coverage information for dead code,
/// false otherwise.
is_code_coverage_dead_code_cgu: bool,
}

/// Auxiliary info about a `MonoItem`.
#[derive(Copy, Clone, PartialEq, Debug, HashStable)]
pub struct MonoItemData {
pub linkage: Linkage,
pub visibility: Visibility,
pub size_estimate: usize,
}

/// Specifies the linkage type for a `MonoItem`.
///
/// See <https://llvm.org/docs/LangRef.html#linkage-types> for more details about these variants.
Expand Down Expand Up @@ -292,12 +307,12 @@ impl<'tcx> CodegenUnit<'tcx> {
}

/// The order of these items is non-determinstic.
pub fn items(&self) -> &FxHashMap<MonoItem<'tcx>, (Linkage, Visibility)> {
pub fn items(&self) -> &FxHashMap<MonoItem<'tcx>, MonoItemData> {
&self.items
}

/// The order of these items is non-determinstic.
pub fn items_mut(&mut self) -> &mut FxHashMap<MonoItem<'tcx>, (Linkage, Visibility)> {
pub fn items_mut(&mut self) -> &mut FxHashMap<MonoItem<'tcx>, MonoItemData> {
&mut self.items
}

Expand All @@ -320,16 +335,16 @@ impl<'tcx> CodegenUnit<'tcx> {
base_n::encode(hash, base_n::CASE_INSENSITIVE)
}

pub fn compute_size_estimate(&mut self, tcx: TyCtxt<'tcx>) {
// Estimate the size of a codegen unit as (approximately) the number of MIR
// statements it corresponds to.
self.size_estimate = self.items.keys().map(|mi| mi.size_estimate(tcx)).sum();
pub fn compute_size_estimate(&mut self) {
// The size of a codegen unit as the sum of the sizes of the items
// within it.
self.size_estimate = self.items.values().map(|data| data.size_estimate).sum();
}

#[inline]
/// Should only be called if [`compute_size_estimate`] has previously been called.
///
/// [`compute_size_estimate`]: Self::compute_size_estimate
#[inline]
pub fn size_estimate(&self) -> usize {
// Items are never zero-sized, so if we have items the estimate must be
// non-zero, unless we forgot to call `compute_size_estimate` first.
Expand All @@ -355,7 +370,7 @@ impl<'tcx> CodegenUnit<'tcx> {
pub fn items_in_deterministic_order(
&self,
tcx: TyCtxt<'tcx>,
) -> Vec<(MonoItem<'tcx>, (Linkage, Visibility))> {
) -> Vec<(MonoItem<'tcx>, MonoItemData)> {
// The codegen tests rely on items being process in the same order as
// they appear in the file, so for local items, we sort by node_id first
#[derive(PartialEq, Eq, PartialOrd, Ord)]
Expand Down Expand Up @@ -390,7 +405,7 @@ impl<'tcx> CodegenUnit<'tcx> {
)
}

let mut items: Vec<_> = self.items().iter().map(|(&i, &l)| (i, l)).collect();
let mut items: Vec<_> = self.items().iter().map(|(&i, &data)| (i, data)).collect();
items.sort_by_cached_key(|&(i, _)| item_sort_key(tcx, i));
items
}
Expand Down
6 changes: 0 additions & 6 deletions compiler/rustc_middle/src/query/mod.rs
Original file line number Diff line number Diff line change
Expand Up @@ -2080,12 +2080,6 @@ rustc_queries! {
desc { "looking up supported target features" }
}

/// Get an estimate of the size of an InstanceDef based on its MIR for CGU partitioning.
query instance_def_size_estimate(def: ty::InstanceDef<'tcx>)
-> usize {
desc { |tcx| "estimating size for `{}`", tcx.def_path_str(def.def_id()) }
}

query features_query(_: ()) -> &'tcx rustc_feature::Features {
feedable
desc { "looking up enabled feature gates" }
Expand Down
Loading

0 comments on commit bef6ff6

Please sign in to comment.