trans: Enable falling back to on-demand instantiation for drop-glue and monomorphizations.

See issue #34151 for more information.
This commit is contained in:
Michael Woerister 2016-06-07 21:14:51 -04:00
parent a7bc0b920f
commit 4c27a3c6d5
6 changed files with 66 additions and 22 deletions

View File

@ -2684,6 +2684,8 @@ pub fn trans_crate<'a, 'tcx>(tcx: TyCtxt<'a, 'tcx, 'tcx>,
println!("n_null_glues: {}", stats.n_null_glues.get()); println!("n_null_glues: {}", stats.n_null_glues.get());
println!("n_real_glues: {}", stats.n_real_glues.get()); println!("n_real_glues: {}", stats.n_real_glues.get());
println!("n_fallback_instantiations: {}", stats.n_fallback_instantiations.get());
println!("n_fns: {}", stats.n_fns.get()); println!("n_fns: {}", stats.n_fns.get());
println!("n_monos: {}", stats.n_monos.get()); println!("n_monos: {}", stats.n_monos.get());
println!("n_inlines: {}", stats.n_inlines.get()); println!("n_inlines: {}", stats.n_inlines.get());
@ -2875,6 +2877,14 @@ fn collect_and_partition_translation_items<'a, 'tcx>(scx: &SharedCrateContext<'a
assert!(scx.tcx().sess.opts.cg.codegen_units == codegen_units.len() || assert!(scx.tcx().sess.opts.cg.codegen_units == codegen_units.len() ||
scx.tcx().sess.opts.debugging_opts.incremental.is_some()); scx.tcx().sess.opts.debugging_opts.incremental.is_some());
{
let mut ccx_map = scx.translation_items().borrow_mut();
for trans_item in items.iter().cloned() {
ccx_map.insert(trans_item, TransItemState::PredictedButNotGenerated);
}
}
if scx.sess().opts.debugging_opts.print_trans_items.is_some() { if scx.sess().opts.debugging_opts.print_trans_items.is_some() {
let mut item_to_cgus = HashMap::new(); let mut item_to_cgus = HashMap::new();
@ -2926,12 +2936,6 @@ fn collect_and_partition_translation_items<'a, 'tcx>(scx: &SharedCrateContext<'a
for item in item_keys { for item in item_keys {
println!("TRANS_ITEM {}", item); println!("TRANS_ITEM {}", item);
} }
let mut ccx_map = scx.translation_items().borrow_mut();
for cgi in items {
ccx_map.insert(cgi, TransItemState::PredictedButNotGenerated);
}
} }
(codegen_units, symbol_map) (codegen_units, symbol_map)

View File

@ -53,6 +53,7 @@ pub struct Stats {
pub n_glues_created: Cell<usize>, pub n_glues_created: Cell<usize>,
pub n_null_glues: Cell<usize>, pub n_null_glues: Cell<usize>,
pub n_real_glues: Cell<usize>, pub n_real_glues: Cell<usize>,
pub n_fallback_instantiations: Cell<usize>,
pub n_fns: Cell<usize>, pub n_fns: Cell<usize>,
pub n_monos: Cell<usize>, pub n_monos: Cell<usize>,
pub n_inlines: Cell<usize>, pub n_inlines: Cell<usize>,
@ -406,6 +407,7 @@ impl<'b, 'tcx> SharedCrateContext<'b, 'tcx> {
n_glues_created: Cell::new(0), n_glues_created: Cell::new(0),
n_null_glues: Cell::new(0), n_null_glues: Cell::new(0),
n_real_glues: Cell::new(0), n_real_glues: Cell::new(0),
n_fallback_instantiations: Cell::new(0),
n_fns: Cell::new(0), n_fns: Cell::new(0),
n_monos: Cell::new(0), n_monos: Cell::new(0),
n_inlines: Cell::new(0), n_inlines: Cell::new(0),

View File

@ -234,13 +234,34 @@ fn get_drop_glue_core<'a, 'tcx>(ccx: &CrateContext<'a, 'tcx>,
g: DropGlueKind<'tcx>) -> ValueRef { g: DropGlueKind<'tcx>) -> ValueRef {
let g = g.map_ty(|t| get_drop_glue_type(ccx.tcx(), t)); let g = g.map_ty(|t| get_drop_glue_type(ccx.tcx(), t));
match ccx.drop_glues().borrow().get(&g) { match ccx.drop_glues().borrow().get(&g) {
Some(&(glue, _)) => glue, Some(&(glue, _)) => return glue,
None => { bug!("Could not find drop glue for {:?} -- {} -- {}. \ None => {
It should have be instantiated during the pre-definition phase", debug!("Could not find drop glue for {:?} -- {} -- {}. \
g, Falling back to on-demand instantiation.",
TransItem::DropGlue(g).to_raw_string(), g,
ccx.codegen_unit().name) } TransItem::DropGlue(g).to_raw_string(),
ccx.codegen_unit().name);
ccx.stats().n_fallback_instantiations.set(ccx.stats()
.n_fallback_instantiations
.get() + 1);
}
} }
// FIXME: #34151
// Normally, getting here would indicate a bug in trans::collector,
// since it seems to have missed a translation item. When we are
// translating with non-MIR-based trans, however, the results of the
// collector are not entirely reliable since it bases its analysis
// on MIR. Thus, we'll instantiate the missing function on demand in
// this codegen unit, so that things keep working.
TransItem::DropGlue(g).predefine(ccx, llvm::LinkOnceODRLinkage);
TransItem::DropGlue(g).define(ccx);
// Now that we made sure that the glue function is in ccx.drop_glues,
// give it another try
get_drop_glue_core(ccx, g)
} }
pub fn implement_drop_glue<'a, 'tcx>(ccx: &CrateContext<'a, 'tcx>, pub fn implement_drop_glue<'a, 'tcx>(ccx: &CrateContext<'a, 'tcx>,

View File

@ -121,8 +121,25 @@ pub fn monomorphic_fn<'a, 'tcx>(ccx: &CrateContext<'a, 'tcx>,
ref attrs, node: hir::MethodTraitItem( ref attrs, node: hir::MethodTraitItem(
hir::MethodSig { .. }, Some(_)), .. hir::MethodSig { .. }, Some(_)), ..
}) => { }) => {
attributes::from_fn_attrs(ccx, attrs, lldecl); let trans_item = TransItem::Fn(instance);
llvm::SetLinkage(lldecl, llvm::ExternalLinkage);
if ccx.shared().translation_items().borrow().contains_key(&trans_item) {
attributes::from_fn_attrs(ccx, attrs, lldecl);
llvm::SetLinkage(lldecl, llvm::ExternalLinkage);
} else {
// FIXME: #34151
// Normally, getting here would indicate a bug in trans::collector,
// since it seems to have missed a translation item. When we are
// translating with non-MIR based trans, however, the results of
// the collector are not entirely reliable since it bases its
// analysis on MIR. Thus, we'll instantiate the missing function
// privately in this codegen unit, so that things keep working.
ccx.stats().n_fallback_instantiations.set(ccx.stats()
.n_fallback_instantiations
.get() + 1);
trans_item.predefine(ccx, llvm::PrivateLinkage);
trans_item.define(ccx);
}
} }
hir_map::NodeVariant(_) | hir_map::NodeStructCtor(_) => { hir_map::NodeVariant(_) | hir_map::NodeStructCtor(_) => {

View File

@ -517,11 +517,11 @@ fn single_codegen_unit<'a, 'tcx, I>(tcx: TyCtxt<'a, 'tcx, 'tcx>,
if reachable.contains(&node_id) { if reachable.contains(&node_id) {
llvm::ExternalLinkage llvm::ExternalLinkage
} else { } else {
llvm::InternalLinkage llvm::PrivateLinkage
} }
} }
TransItem::DropGlue(_) => { TransItem::DropGlue(_) => {
llvm::InternalLinkage llvm::PrivateLinkage
} }
TransItem::Fn(instance) => { TransItem::Fn(instance) => {
if trans_item.is_generic_fn() || if trans_item.is_generic_fn() ||

View File

@ -108,19 +108,19 @@ impl<'a, 'tcx> TransItem<'tcx> {
ccx.codegen_unit().name); ccx.codegen_unit().name);
let symbol_name = ccx.symbol_map() let symbol_name = ccx.symbol_map()
.get(*self) .get_or_compute(ccx.shared(), *self);
.expect("Name not present in SymbolMap?");
debug!("symbol {}", symbol_name); debug!("symbol {}", &symbol_name);
match *self { match *self {
TransItem::Static(node_id) => { TransItem::Static(node_id) => {
TransItem::predefine_static(ccx, node_id, linkage, symbol_name); TransItem::predefine_static(ccx, node_id, linkage, &symbol_name);
} }
TransItem::Fn(instance) => { TransItem::Fn(instance) => {
TransItem::predefine_fn(ccx, instance, linkage, symbol_name); TransItem::predefine_fn(ccx, instance, linkage, &symbol_name);
} }
TransItem::DropGlue(dg) => { TransItem::DropGlue(dg) => {
TransItem::predefine_drop_glue(ccx, dg, linkage, symbol_name); TransItem::predefine_drop_glue(ccx, dg, linkage, &symbol_name);
} }
} }