See issue #34151 for more information.
println!("n_null_glues: {}", stats.n_null_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_monos: {}", stats.n_monos.get());
println!("n_inlines: {}", stats.n_inlines.get());
assert!(scx.tcx().sess.opts.cg.codegen_units == codegen_units.len() ||
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() {
let mut item_to_cgus = HashMap::new();
for item in item_keys {
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)
pub n_glues_created: Cell<usize>,
pub n_null_glues: Cell<usize>,
pub n_real_glues: Cell<usize>,
+ pub n_fallback_instantiations: Cell<usize>,
pub n_fns: Cell<usize>,
pub n_monos: Cell<usize>,
pub n_inlines: Cell<usize>,
n_glues_created: Cell::new(0),
n_null_glues: Cell::new(0),
n_real_glues: Cell::new(0),
+ n_fallback_instantiations: Cell::new(0),
n_fns: Cell::new(0),
n_monos: Cell::new(0),
n_inlines: Cell::new(0),
g: DropGlueKind<'tcx>) -> ValueRef {
let g = g.map_ty(|t| get_drop_glue_type(ccx.tcx(), t));
match ccx.drop_glues().borrow().get(&g) {
- Some(&(glue, _)) => glue,
- None => { bug!("Could not find drop glue for {:?} -- {} -- {}. \
- It should have be instantiated during the pre-definition phase",
- g,
- TransItem::DropGlue(g).to_raw_string(),
- ccx.codegen_unit().name) }
+ Some(&(glue, _)) => return glue,
+ None => {
+ debug!("Could not find drop glue for {:?} -- {} -- {}. \
+ Falling back to on-demand instantiation.",
+ g,
+ 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>,
ref attrs, node: hir::MethodTraitItem(
hir::MethodSig { .. }, Some(_)), ..
}) => {
- attributes::from_fn_attrs(ccx, attrs, lldecl);
- llvm::SetLinkage(lldecl, llvm::ExternalLinkage);
+ let trans_item = TransItem::Fn(instance);
+
+ 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(_) => {
if reachable.contains(&node_id) {
llvm::ExternalLinkage
} else {
- llvm::InternalLinkage
+ llvm::PrivateLinkage
}
}
TransItem::DropGlue(_) => {
- llvm::InternalLinkage
+ llvm::PrivateLinkage
}
TransItem::Fn(instance) => {
if trans_item.is_generic_fn() ||
ccx.codegen_unit().name);
let symbol_name = ccx.symbol_map()
- .get(*self)
- .expect("Name not present in SymbolMap?");
- debug!("symbol {}", symbol_name);
+ .get_or_compute(ccx.shared(), *self);
+
+ debug!("symbol {}", &symbol_name);
match *self {
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::predefine_fn(ccx, instance, linkage, symbol_name);
+ TransItem::predefine_fn(ccx, instance, linkage, &symbol_name);
}
TransItem::DropGlue(dg) => {
- TransItem::predefine_drop_glue(ccx, dg, linkage, symbol_name);
+ TransItem::predefine_drop_glue(ccx, dg, linkage, &symbol_name);
}
}