From 8447f4fc0fe4e497b9e914f8dc81b3134efaf6a4 Mon Sep 17 00:00:00 2001 From: varkor Date: Sat, 13 Jan 2018 15:55:38 +0000 Subject: [PATCH 1/5] Add CGU size heuristic for partitioning This addresses the concern of #47316 by estimating CGU size based on the size of its MIR. Looking at the size estimate differences for a small selection of crates, this heuristic produces different orderings, which should more accurately reflect optimisation time. Fixes #47316. --- src/librustc_mir/monomorphize/partitioning.rs | 46 +++++++++++++++++-- 1 file changed, 42 insertions(+), 4 deletions(-) diff --git a/src/librustc_mir/monomorphize/partitioning.rs b/src/librustc_mir/monomorphize/partitioning.rs index e899cc072e072..d8ec074b8a464 100644 --- a/src/librustc_mir/monomorphize/partitioning.rs +++ b/src/librustc_mir/monomorphize/partitioning.rs @@ -110,11 +110,12 @@ use rustc::mir::mono::{Linkage, Visibility}; use rustc::ty::{self, TyCtxt, InstanceDef}; use rustc::ty::item_path::characteristic_def_id_of_type; use rustc::util::nodemap::{FxHashMap, FxHashSet}; -use std::collections::hash_map::Entry; +use std::collections::hash_map::{HashMap, Entry}; use syntax::ast::NodeId; use syntax::symbol::{Symbol, InternedString}; use rustc::mir::mono::MonoItem; use monomorphize::item::{MonoItemExt, InstantiationMode}; +use core::usize; pub use rustc::mir::mono::CodegenUnit; @@ -229,7 +230,7 @@ pub fn partition<'a, 'tcx, I>(tcx: TyCtxt<'a, 'tcx, 'tcx>, // If the partitioning should produce a fixed count of codegen units, merge // until that count is reached. if let PartitioningStrategy::FixedUnitCount(count) = strategy { - merge_codegen_units(&mut initial_partitioning, count, &tcx.crate_name.as_str()); + merge_codegen_units(tcx, &mut initial_partitioning, count, &tcx.crate_name.as_str()); debug_dump(tcx, "POST MERGING:", initial_partitioning.codegen_units.iter()); } @@ -404,7 +405,8 @@ fn place_root_translation_items<'a, 'tcx, I>(tcx: TyCtxt<'a, 'tcx, 'tcx>, } } -fn merge_codegen_units<'tcx>(initial_partitioning: &mut PreInliningPartitioning<'tcx>, +fn merge_codegen_units<'a, 'tcx>(tcx: TyCtxt<'a, 'tcx, 'tcx>, + initial_partitioning: &mut PreInliningPartitioning<'tcx>, target_cgu_count: usize, crate_name: &str) { assert!(target_cgu_count >= 1); @@ -421,12 +423,48 @@ fn merge_codegen_units<'tcx>(initial_partitioning: &mut PreInliningPartitioning< // the stable sort below will keep everything nice and deterministic. codegen_units.sort_by_key(|cgu| cgu.name().clone()); + // Estimate the size of a codegen unit as (approximately) the number of MIR + // statements it corresponds to. + fn codegen_unit_size_estimate<'a, 'tcx>(cgu: &CodegenUnit<'tcx>, + mono_item_sizes: &HashMap) + -> usize { + cgu.items().keys().map(|mi| mono_item_sizes.get(mi).unwrap()).sum() + } + + fn mono_item_size_estimate<'a, 'tcx>(tcx: TyCtxt<'a, 'tcx, 'tcx>, + item: &MonoItem<'tcx>) + -> usize { + match item { + MonoItem::Fn(instance) => { + // Estimate the size of a function based on how many statements + // it contains. + let mir = tcx.instance_mir(instance.def); + mir.basic_blocks().iter().map(|bb| bb.statements.len()).sum() + }, + // Conservatively estimate the size of a static declaration + // or assembly to be 1. + MonoItem::Static(_) | MonoItem::GlobalAsm(_) => 1, + } + } + + // Since `sort_by_key` currently recomputes the keys for each comparison, + // we can save unnecessary recomputations by storing size estimates for + // each `MonoItem`. Storing estimates for `CodegenUnit` might be preferable, + // but its structure makes it awkward to use as a key and additionally their + // sizes change as the merging occurs, requiring the map to be updated. + let mut sizes: HashMap = HashMap::new(); + for mis in codegen_units.iter().map(|cgu| cgu.items().keys()) { + mis.for_each(|mi| { + sizes.entry(*mi).or_insert_with(|| mono_item_size_estimate(tcx, mi)); + }); + } + // Merge the two smallest codegen units until the target size is reached. // Note that "size" is estimated here rather inaccurately as the number of // translation items in a given unit. This could be improved on. while codegen_units.len() > target_cgu_count { // Sort small cgus to the back - codegen_units.sort_by_key(|cgu| -(cgu.items().len() as i64)); + codegen_units.sort_by_key(|cgu| usize::MAX - codegen_unit_size_estimate(cgu, &sizes)); let mut smallest = codegen_units.pop().unwrap(); let second_smallest = codegen_units.last_mut().unwrap(); From e60b0f802b438d350ccd1ec1b42f515994b1a4c0 Mon Sep 17 00:00:00 2001 From: varkor Date: Mon, 15 Jan 2018 18:28:34 +0000 Subject: [PATCH 2/5] Refactor CodegenUnit size estimates --- src/librustc/mir/mono.rs | 40 ++++++++++++++- src/librustc_mir/monomorphize/partitioning.rs | 50 ++++--------------- src/librustc_trans/base.rs | 4 +- 3 files changed, 50 insertions(+), 44 deletions(-) diff --git a/src/librustc/mir/mono.rs b/src/librustc/mir/mono.rs index efdf4066815f4..bbef045a305a5 100644 --- a/src/librustc/mir/mono.rs +++ b/src/librustc/mir/mono.rs @@ -10,7 +10,7 @@ use syntax::ast::NodeId; use syntax::symbol::InternedString; -use ty::Instance; +use ty::{Instance, TyCtxt}; use util::nodemap::FxHashMap; use rustc_data_structures::base_n; use rustc_data_structures::stable_hasher::{HashStable, StableHasherResult, @@ -25,6 +25,22 @@ pub enum MonoItem<'tcx> { GlobalAsm(NodeId), } +impl<'tcx> MonoItem<'tcx> { + pub fn size_estimate<'a>(&self, tcx: &TyCtxt<'a, 'tcx, 'tcx>) -> usize { + match *self { + MonoItem::Fn(instance) => { + // Estimate the size of a function based on how many statements + // it contains. + let mir = tcx.instance_mir(instance.def); + mir.basic_blocks().iter().map(|bb| bb.statements.len()).sum() + }, + // Conservatively estimate the size of a static declaration + // or assembly to be 1. + MonoItem::Static(_) | MonoItem::GlobalAsm(_) => 1, + } + } +} + impl<'tcx> HashStable> for MonoItem<'tcx> { fn hash_stable(&self, hcx: &mut StableHashingContext<'tcx>, @@ -52,6 +68,7 @@ pub struct CodegenUnit<'tcx> { /// as well as the crate name and disambiguator. name: InternedString, items: FxHashMap, (Linkage, Visibility)>, + size_estimate: Option, } #[derive(Copy, Clone, PartialEq, Eq, Hash, Debug)] @@ -101,6 +118,7 @@ impl<'tcx> CodegenUnit<'tcx> { CodegenUnit { name: name, items: FxHashMap(), + size_estimate: None, } } @@ -131,6 +149,25 @@ impl<'tcx> CodegenUnit<'tcx> { let hash = hash & ((1u128 << 80) - 1); base_n::encode(hash, base_n::CASE_INSENSITIVE) } + + pub fn estimate_size<'a>(&mut self, tcx: &TyCtxt<'a, 'tcx, 'tcx>) { + // Estimate the size of a codegen unit as (approximately) the number of MIR + // statements it corresponds to. + self.size_estimate = Some(self.items.keys().map(|mi| mi.size_estimate(tcx)).sum()); + } + + pub fn size_estimate(&self) -> usize { + // Should only be called if `estimate_size` has previously been called. + assert!(self.size_estimate.is_some()); + self.size_estimate.unwrap() + } + + pub fn modify_size_estimate(&mut self, delta: usize) { + assert!(self.size_estimate.is_some()); + if let Some(size_estimate) = self.size_estimate { + self.size_estimate = Some(size_estimate + delta); + } + } } impl<'tcx> HashStable> for CodegenUnit<'tcx> { @@ -140,6 +177,7 @@ impl<'tcx> HashStable> for CodegenUnit<'tcx> { let CodegenUnit { ref items, name, + .. } = *self; name.hash_stable(hcx, hasher); diff --git a/src/librustc_mir/monomorphize/partitioning.rs b/src/librustc_mir/monomorphize/partitioning.rs index d8ec074b8a464..4150f9f95485b 100644 --- a/src/librustc_mir/monomorphize/partitioning.rs +++ b/src/librustc_mir/monomorphize/partitioning.rs @@ -110,7 +110,7 @@ use rustc::mir::mono::{Linkage, Visibility}; use rustc::ty::{self, TyCtxt, InstanceDef}; use rustc::ty::item_path::characteristic_def_id_of_type; use rustc::util::nodemap::{FxHashMap, FxHashSet}; -use std::collections::hash_map::{HashMap, Entry}; +use std::collections::hash_map::Entry; use syntax::ast::NodeId; use syntax::symbol::{Symbol, InternedString}; use rustc::mir::mono::MonoItem; @@ -225,12 +225,14 @@ pub fn partition<'a, 'tcx, I>(tcx: TyCtxt<'a, 'tcx, 'tcx>, let mut initial_partitioning = place_root_translation_items(tcx, trans_items); + initial_partitioning.codegen_units.iter_mut().for_each(|cgu| cgu.estimate_size(&tcx)); + debug_dump(tcx, "INITIAL PARTITIONING:", initial_partitioning.codegen_units.iter()); // If the partitioning should produce a fixed count of codegen units, merge // until that count is reached. if let PartitioningStrategy::FixedUnitCount(count) = strategy { - merge_codegen_units(tcx, &mut initial_partitioning, count, &tcx.crate_name.as_str()); + merge_codegen_units(&mut initial_partitioning, count, &tcx.crate_name.as_str()); debug_dump(tcx, "POST MERGING:", initial_partitioning.codegen_units.iter()); } @@ -242,6 +244,8 @@ pub fn partition<'a, 'tcx, I>(tcx: TyCtxt<'a, 'tcx, 'tcx>, let mut post_inlining = place_inlined_translation_items(initial_partitioning, inlining_map); + post_inlining.codegen_units.iter_mut().for_each(|cgu| cgu.estimate_size(&tcx)); + debug_dump(tcx, "POST INLINING:", post_inlining.codegen_units.iter()); // Next we try to make as many symbols "internal" as possible, so LLVM has @@ -405,8 +409,7 @@ fn place_root_translation_items<'a, 'tcx, I>(tcx: TyCtxt<'a, 'tcx, 'tcx>, } } -fn merge_codegen_units<'a, 'tcx>(tcx: TyCtxt<'a, 'tcx, 'tcx>, - initial_partitioning: &mut PreInliningPartitioning<'tcx>, +fn merge_codegen_units<'tcx>(initial_partitioning: &mut PreInliningPartitioning<'tcx>, target_cgu_count: usize, crate_name: &str) { assert!(target_cgu_count >= 1); @@ -423,51 +426,16 @@ fn merge_codegen_units<'a, 'tcx>(tcx: TyCtxt<'a, 'tcx, 'tcx>, // the stable sort below will keep everything nice and deterministic. codegen_units.sort_by_key(|cgu| cgu.name().clone()); - // Estimate the size of a codegen unit as (approximately) the number of MIR - // statements it corresponds to. - fn codegen_unit_size_estimate<'a, 'tcx>(cgu: &CodegenUnit<'tcx>, - mono_item_sizes: &HashMap) - -> usize { - cgu.items().keys().map(|mi| mono_item_sizes.get(mi).unwrap()).sum() - } - - fn mono_item_size_estimate<'a, 'tcx>(tcx: TyCtxt<'a, 'tcx, 'tcx>, - item: &MonoItem<'tcx>) - -> usize { - match item { - MonoItem::Fn(instance) => { - // Estimate the size of a function based on how many statements - // it contains. - let mir = tcx.instance_mir(instance.def); - mir.basic_blocks().iter().map(|bb| bb.statements.len()).sum() - }, - // Conservatively estimate the size of a static declaration - // or assembly to be 1. - MonoItem::Static(_) | MonoItem::GlobalAsm(_) => 1, - } - } - - // Since `sort_by_key` currently recomputes the keys for each comparison, - // we can save unnecessary recomputations by storing size estimates for - // each `MonoItem`. Storing estimates for `CodegenUnit` might be preferable, - // but its structure makes it awkward to use as a key and additionally their - // sizes change as the merging occurs, requiring the map to be updated. - let mut sizes: HashMap = HashMap::new(); - for mis in codegen_units.iter().map(|cgu| cgu.items().keys()) { - mis.for_each(|mi| { - sizes.entry(*mi).or_insert_with(|| mono_item_size_estimate(tcx, mi)); - }); - } - // Merge the two smallest codegen units until the target size is reached. // Note that "size" is estimated here rather inaccurately as the number of // translation items in a given unit. This could be improved on. while codegen_units.len() > target_cgu_count { // Sort small cgus to the back - codegen_units.sort_by_key(|cgu| usize::MAX - codegen_unit_size_estimate(cgu, &sizes)); + codegen_units.sort_by_key(|cgu| usize::MAX - cgu.size_estimate()); let mut smallest = codegen_units.pop().unwrap(); let second_smallest = codegen_units.last_mut().unwrap(); + second_smallest.modify_size_estimate(smallest.size_estimate()); for (k, v) in smallest.items_mut().drain() { second_smallest.items_mut().insert(k, v); } diff --git a/src/librustc_trans/base.rs b/src/librustc_trans/base.rs index 633ed9b32cd1e..e03b6ee794d67 100644 --- a/src/librustc_trans/base.rs +++ b/src/librustc_trans/base.rs @@ -79,7 +79,7 @@ use std::ffi::CString; use std::str; use std::sync::Arc; use std::time::{Instant, Duration}; -use std::i32; +use std::{i32, usize}; use std::iter; use std::sync::mpsc; use syntax_pos::Span; @@ -829,7 +829,7 @@ pub fn trans_crate<'a, 'tcx>(tcx: TyCtxt<'a, 'tcx, 'tcx>, // account the size of each TransItem. let codegen_units = { let mut codegen_units = codegen_units; - codegen_units.sort_by_key(|cgu| -(cgu.items().len() as isize)); + codegen_units.sort_by_key(|cgu| usize::MAX - cgu.size_estimate()); codegen_units }; From c8e9da44a9e361b43548cb60a46cf3c2138968c7 Mon Sep 17 00:00:00 2001 From: varkor Date: Mon, 15 Jan 2018 18:52:42 +0000 Subject: [PATCH 3/5] Update comments about the partitioning inefficiency --- src/librustc_mir/monomorphize/partitioning.rs | 2 -- src/librustc_trans/base.rs | 4 +--- 2 files changed, 1 insertion(+), 5 deletions(-) diff --git a/src/librustc_mir/monomorphize/partitioning.rs b/src/librustc_mir/monomorphize/partitioning.rs index 4150f9f95485b..806d787c84522 100644 --- a/src/librustc_mir/monomorphize/partitioning.rs +++ b/src/librustc_mir/monomorphize/partitioning.rs @@ -427,8 +427,6 @@ fn merge_codegen_units<'tcx>(initial_partitioning: &mut PreInliningPartitioning< codegen_units.sort_by_key(|cgu| cgu.name().clone()); // Merge the two smallest codegen units until the target size is reached. - // Note that "size" is estimated here rather inaccurately as the number of - // translation items in a given unit. This could be improved on. while codegen_units.len() > target_cgu_count { // Sort small cgus to the back codegen_units.sort_by_key(|cgu| usize::MAX - cgu.size_estimate()); diff --git a/src/librustc_trans/base.rs b/src/librustc_trans/base.rs index e03b6ee794d67..1126c9d2c8cdb 100644 --- a/src/librustc_trans/base.rs +++ b/src/librustc_trans/base.rs @@ -824,9 +824,7 @@ pub fn trans_crate<'a, 'tcx>(tcx: TyCtxt<'a, 'tcx, 'tcx>, ongoing_translation.submit_pre_translated_module_to_llvm(tcx, metadata_module); // We sort the codegen units by size. This way we can schedule work for LLVM - // a bit more efficiently. Note that "size" is defined rather crudely at the - // moment as it is just the number of TransItems in the CGU, not taking into - // account the size of each TransItem. + // a bit more efficiently. let codegen_units = { let mut codegen_units = codegen_units; codegen_units.sort_by_key(|cgu| usize::MAX - cgu.size_estimate()); From 5c9a8b504146cc9f755c4e7d73b3693cb781021f Mon Sep 17 00:00:00 2001 From: varkor Date: Fri, 19 Jan 2018 00:32:58 +0000 Subject: [PATCH 4/5] Add instance_def_size_estimate query --- src/librustc/dep_graph/dep_node.rs | 1 + src/librustc/mir/mono.rs | 3 +-- src/librustc/ty/maps/config.rs | 6 ++++++ src/librustc/ty/maps/mod.rs | 10 ++++++++++ src/librustc/ty/maps/plumbing.rs | 1 + src/librustc/ty/mod.rs | 14 ++++++++++++++ 6 files changed, 33 insertions(+), 2 deletions(-) diff --git a/src/librustc/dep_graph/dep_node.rs b/src/librustc/dep_graph/dep_node.rs index 14f54fbffac2e..1de9091b5df7d 100644 --- a/src/librustc/dep_graph/dep_node.rs +++ b/src/librustc/dep_graph/dep_node.rs @@ -638,6 +638,7 @@ define_dep_nodes!( <'tcx> [input] TargetFeaturesWhitelist, [] TargetFeaturesEnabled(DefId), + [] InstanceDefSizeEstimate { instance_def: InstanceDef<'tcx> }, ); trait DepNodeParams<'a, 'gcx: 'tcx + 'a, 'tcx: 'a> : fmt::Debug { diff --git a/src/librustc/mir/mono.rs b/src/librustc/mir/mono.rs index bbef045a305a5..2af2219d26785 100644 --- a/src/librustc/mir/mono.rs +++ b/src/librustc/mir/mono.rs @@ -31,8 +31,7 @@ impl<'tcx> MonoItem<'tcx> { MonoItem::Fn(instance) => { // Estimate the size of a function based on how many statements // it contains. - let mir = tcx.instance_mir(instance.def); - mir.basic_blocks().iter().map(|bb| bb.statements.len()).sum() + tcx.instance_def_size_estimate(instance.def) }, // Conservatively estimate the size of a static declaration // or assembly to be 1. diff --git a/src/librustc/ty/maps/config.rs b/src/librustc/ty/maps/config.rs index 8dedcb24c2fb6..b0adfe2087966 100644 --- a/src/librustc/ty/maps/config.rs +++ b/src/librustc/ty/maps/config.rs @@ -637,6 +637,12 @@ impl<'tcx> QueryDescription<'tcx> for queries::target_features_whitelist<'tcx> { } } +impl<'tcx> QueryDescription<'tcx> for queries::instance_def_size_estimate<'tcx> { + fn describe(tcx: TyCtxt, def: ty::InstanceDef<'tcx>) -> String { + format!("estimating size for `{}`", tcx.item_path_str(def.def_id())) + } +} + macro_rules! impl_disk_cacheable_query( ($query_name:ident, |$key:tt| $cond:expr) => { impl<'tcx> QueryDescription<'tcx> for queries::$query_name<'tcx> { diff --git a/src/librustc/ty/maps/mod.rs b/src/librustc/ty/maps/mod.rs index e7e92b8a4288f..6c79f6a62fa0b 100644 --- a/src/librustc/ty/maps/mod.rs +++ b/src/librustc/ty/maps/mod.rs @@ -365,6 +365,9 @@ define_maps! { <'tcx> target_features_whitelist_node(CrateNum) -> Rc>, [] fn target_features_enabled: TargetFeaturesEnabled(DefId) -> Rc>, + // Get an estimate of the size of an InstanceDef based on its MIR for CGU partitioning. + [] fn instance_def_size_estimate: instance_def_size_estimate_dep_node(ty::InstanceDef<'tcx>) + -> usize, } ////////////////////////////////////////////////////////////////////// @@ -514,3 +517,10 @@ fn substitute_normalize_and_test_predicates_node<'tcx>(key: (DefId, &'tcx Substs fn target_features_whitelist_node<'tcx>(_: CrateNum) -> DepConstructor<'tcx> { DepConstructor::TargetFeaturesWhitelist } + +fn instance_def_size_estimate_dep_node<'tcx>(instance_def: ty::InstanceDef<'tcx>) + -> DepConstructor<'tcx> { + DepConstructor::InstanceDefSizeEstimate { + instance_def + } +} diff --git a/src/librustc/ty/maps/plumbing.rs b/src/librustc/ty/maps/plumbing.rs index d670ecc2691ae..f35693c702b32 100644 --- a/src/librustc/ty/maps/plumbing.rs +++ b/src/librustc/ty/maps/plumbing.rs @@ -761,6 +761,7 @@ pub fn force_from_dep_node<'a, 'gcx, 'lcx>(tcx: TyCtxt<'a, 'gcx, 'lcx>, DepKind::EraseRegionsTy | DepKind::NormalizeTy | DepKind::SubstituteNormalizeAndTestPredicates | + DepKind::InstanceDefSizeEstimate | // This one should never occur in this context DepKind::Null => { diff --git a/src/librustc/ty/mod.rs b/src/librustc/ty/mod.rs index 2b4d2c80c6f9e..1d64e7bae913c 100644 --- a/src/librustc/ty/mod.rs +++ b/src/librustc/ty/mod.rs @@ -2669,6 +2669,19 @@ fn crate_hash<'a, 'tcx>(tcx: TyCtxt<'a, 'tcx, 'tcx>, tcx.hir.crate_hash } +fn instance_def_size_estimate<'a, 'tcx>(tcx: TyCtxt<'a, 'tcx, 'tcx>, + instance_def: InstanceDef<'tcx>) + -> usize { + match instance_def { + InstanceDef::Item(def_id) => { + let mir = tcx.optimized_mir(def_id); + mir.basic_blocks().iter().map(|bb| bb.statements.len()).sum() + }, + // Estimate the size of compiler-generated shims to be 1. + _ => 1 + } +} + pub fn provide(providers: &mut ty::maps::Providers) { context::provide(providers); erase_regions::provide(providers); @@ -2686,6 +2699,7 @@ pub fn provide(providers: &mut ty::maps::Providers) { original_crate_name, crate_hash, trait_impls_of: trait_def::trait_impls_of_provider, + instance_def_size_estimate, ..*providers }; } From 62703cfd26592be8ea641912aa61ecf5d1cbe64f Mon Sep 17 00:00:00 2001 From: varkor Date: Fri, 19 Jan 2018 11:51:48 +0000 Subject: [PATCH 5/5] Estimate size of InstanceDef::DropGlue more accurately Also a little bit of clean up. --- src/librustc/mir/mono.rs | 6 +++--- src/librustc/ty/mod.rs | 7 ++++--- 2 files changed, 7 insertions(+), 6 deletions(-) diff --git a/src/librustc/mir/mono.rs b/src/librustc/mir/mono.rs index 2af2219d26785..49e5c0dc21f9e 100644 --- a/src/librustc/mir/mono.rs +++ b/src/librustc/mir/mono.rs @@ -157,8 +157,7 @@ impl<'tcx> CodegenUnit<'tcx> { pub fn size_estimate(&self) -> usize { // Should only be called if `estimate_size` has previously been called. - assert!(self.size_estimate.is_some()); - self.size_estimate.unwrap() + self.size_estimate.expect("estimate_size must be called before getting a size_estimate") } pub fn modify_size_estimate(&mut self, delta: usize) { @@ -176,7 +175,8 @@ impl<'tcx> HashStable> for CodegenUnit<'tcx> { let CodegenUnit { ref items, name, - .. + // The size estimate is not relevant to the hash + size_estimate: _, } = *self; name.hash_stable(hcx, hasher); diff --git a/src/librustc/ty/mod.rs b/src/librustc/ty/mod.rs index 1d64e7bae913c..332afe36010bd 100644 --- a/src/librustc/ty/mod.rs +++ b/src/librustc/ty/mod.rs @@ -2673,11 +2673,12 @@ fn instance_def_size_estimate<'a, 'tcx>(tcx: TyCtxt<'a, 'tcx, 'tcx>, instance_def: InstanceDef<'tcx>) -> usize { match instance_def { - InstanceDef::Item(def_id) => { - let mir = tcx.optimized_mir(def_id); + InstanceDef::Item(..) | + InstanceDef::DropGlue(..) => { + let mir = tcx.instance_mir(instance_def); mir.basic_blocks().iter().map(|bb| bb.statements.len()).sum() }, - // Estimate the size of compiler-generated shims to be 1. + // Estimate the size of other compiler-generated shims to be 1. _ => 1 } }