Skip to content

Commit 86613cd

Browse files
trans: Enable falling back to on-demand instantiation for drop-glue and monomorphizations.
See issue rust-lang#34151 for more information.
1 parent 933d723 commit 86613cd

File tree

6 files changed

+66
-22
lines changed

6 files changed

+66
-22
lines changed

src/librustc_trans/base.rs

+10-6
Original file line numberDiff line numberDiff line change
@@ -2685,6 +2685,8 @@ pub fn trans_crate<'a, 'tcx>(tcx: TyCtxt<'a, 'tcx, 'tcx>,
26852685
println!("n_null_glues: {}", stats.n_null_glues.get());
26862686
println!("n_real_glues: {}", stats.n_real_glues.get());
26872687

2688+
println!("n_fallback_instantiations: {}", stats.n_fallback_instantiations.get());
2689+
26882690
println!("n_fns: {}", stats.n_fns.get());
26892691
println!("n_monos: {}", stats.n_monos.get());
26902692
println!("n_inlines: {}", stats.n_inlines.get());
@@ -2876,6 +2878,14 @@ fn collect_and_partition_translation_items<'a, 'tcx>(scx: &SharedCrateContext<'a
28762878
assert!(scx.tcx().sess.opts.cg.codegen_units == codegen_units.len() ||
28772879
scx.tcx().sess.opts.debugging_opts.incremental.is_some());
28782880

2881+
{
2882+
let mut ccx_map = scx.translation_items().borrow_mut();
2883+
2884+
for trans_item in items.iter().cloned() {
2885+
ccx_map.insert(trans_item, TransItemState::PredictedButNotGenerated);
2886+
}
2887+
}
2888+
28792889
if scx.sess().opts.debugging_opts.print_trans_items.is_some() {
28802890
let mut item_to_cgus = HashMap::new();
28812891

@@ -2927,12 +2937,6 @@ fn collect_and_partition_translation_items<'a, 'tcx>(scx: &SharedCrateContext<'a
29272937
for item in item_keys {
29282938
println!("TRANS_ITEM {}", item);
29292939
}
2930-
2931-
let mut ccx_map = scx.translation_items().borrow_mut();
2932-
2933-
for cgi in items {
2934-
ccx_map.insert(cgi, TransItemState::PredictedButNotGenerated);
2935-
}
29362940
}
29372941

29382942
(codegen_units, symbol_map)

src/librustc_trans/context.rs

+2
Original file line numberDiff line numberDiff line change
@@ -53,6 +53,7 @@ pub struct Stats {
5353
pub n_glues_created: Cell<usize>,
5454
pub n_null_glues: Cell<usize>,
5555
pub n_real_glues: Cell<usize>,
56+
pub n_fallback_instantiations: Cell<usize>,
5657
pub n_fns: Cell<usize>,
5758
pub n_monos: Cell<usize>,
5859
pub n_inlines: Cell<usize>,
@@ -406,6 +407,7 @@ impl<'b, 'tcx> SharedCrateContext<'b, 'tcx> {
406407
n_glues_created: Cell::new(0),
407408
n_null_glues: Cell::new(0),
408409
n_real_glues: Cell::new(0),
410+
n_fallback_instantiations: Cell::new(0),
409411
n_fns: Cell::new(0),
410412
n_monos: Cell::new(0),
411413
n_inlines: Cell::new(0),

src/librustc_trans/glue.rs

+27-6
Original file line numberDiff line numberDiff line change
@@ -234,13 +234,34 @@ fn get_drop_glue_core<'a, 'tcx>(ccx: &CrateContext<'a, 'tcx>,
234234
g: DropGlueKind<'tcx>) -> ValueRef {
235235
let g = g.map_ty(|t| get_drop_glue_type(ccx.tcx(), t));
236236
match ccx.drop_glues().borrow().get(&g) {
237-
Some(&(glue, _)) => glue,
238-
None => { bug!("Could not find drop glue for {:?} -- {} -- {}. \
239-
It should have be instantiated during the pre-definition phase",
240-
g,
241-
TransItem::DropGlue(g).to_raw_string(),
242-
ccx.codegen_unit().name) }
237+
Some(&(glue, _)) => return glue,
238+
None => {
239+
debug!("Could not find drop glue for {:?} -- {} -- {}. \
240+
Falling back to on-demand instantiation.",
241+
g,
242+
TransItem::DropGlue(g).to_raw_string(),
243+
ccx.codegen_unit().name);
244+
245+
ccx.stats().n_fallback_instantiations.set(ccx.stats()
246+
.n_fallback_instantiations
247+
.get() + 1);
248+
}
243249
}
250+
251+
// FIXME: #34151
252+
// Normally, getting here would indicate a bug in trans::collector,
253+
// since it seems to have missed a translation item. When we are
254+
// translating with non-MIR-based trans, however, the results of the
255+
// collector are not entirely reliable since it bases its analysis
256+
// on MIR. Thus, we'll instantiate the missing function on demand in
257+
// this codegen unit, so that things keep working.
258+
259+
TransItem::DropGlue(g).predefine(ccx, llvm::LinkOnceODRLinkage);
260+
TransItem::DropGlue(g).define(ccx);
261+
262+
// Now that we made sure that the glue function is in ccx.drop_glues,
263+
// give it another try
264+
get_drop_glue_core(ccx, g)
244265
}
245266

246267
pub fn implement_drop_glue<'a, 'tcx>(ccx: &CrateContext<'a, 'tcx>,

src/librustc_trans/monomorphize.rs

+19-2
Original file line numberDiff line numberDiff line change
@@ -121,8 +121,25 @@ pub fn monomorphic_fn<'a, 'tcx>(ccx: &CrateContext<'a, 'tcx>,
121121
ref attrs, node: hir::MethodTraitItem(
122122
hir::MethodSig { .. }, Some(_)), ..
123123
}) => {
124-
attributes::from_fn_attrs(ccx, attrs, lldecl);
125-
llvm::SetLinkage(lldecl, llvm::ExternalLinkage);
124+
let trans_item = TransItem::Fn(instance);
125+
126+
if ccx.shared().translation_items().borrow().contains_key(&trans_item) {
127+
attributes::from_fn_attrs(ccx, attrs, lldecl);
128+
llvm::SetLinkage(lldecl, llvm::ExternalLinkage);
129+
} else {
130+
// FIXME: #34151
131+
// Normally, getting here would indicate a bug in trans::collector,
132+
// since it seems to have missed a translation item. When we are
133+
// translating with non-MIR based trans, however, the results of
134+
// the collector are not entirely reliable since it bases its
135+
// analysis on MIR. Thus, we'll instantiate the missing function
136+
// privately in this codegen unit, so that things keep working.
137+
ccx.stats().n_fallback_instantiations.set(ccx.stats()
138+
.n_fallback_instantiations
139+
.get() + 1);
140+
trans_item.predefine(ccx, llvm::PrivateLinkage);
141+
trans_item.define(ccx);
142+
}
126143
}
127144

128145
hir_map::NodeVariant(_) | hir_map::NodeStructCtor(_) => {

src/librustc_trans/partitioning.rs

+2-2
Original file line numberDiff line numberDiff line change
@@ -517,11 +517,11 @@ fn single_codegen_unit<'a, 'tcx, I>(tcx: TyCtxt<'a, 'tcx, 'tcx>,
517517
if reachable.contains(&node_id) {
518518
llvm::ExternalLinkage
519519
} else {
520-
llvm::InternalLinkage
520+
llvm::PrivateLinkage
521521
}
522522
}
523523
TransItem::DropGlue(_) => {
524-
llvm::InternalLinkage
524+
llvm::PrivateLinkage
525525
}
526526
TransItem::Fn(instance) => {
527527
if trans_item.is_generic_fn() ||

src/librustc_trans/trans_item.rs

+6-6
Original file line numberDiff line numberDiff line change
@@ -108,19 +108,19 @@ impl<'a, 'tcx> TransItem<'tcx> {
108108
ccx.codegen_unit().name);
109109

110110
let symbol_name = ccx.symbol_map()
111-
.get(*self)
112-
.expect("Name not present in SymbolMap?");
113-
debug!("symbol {}", symbol_name);
111+
.get_or_compute(ccx.shared(), *self);
112+
113+
debug!("symbol {}", &symbol_name);
114114

115115
match *self {
116116
TransItem::Static(node_id) => {
117-
TransItem::predefine_static(ccx, node_id, linkage, symbol_name);
117+
TransItem::predefine_static(ccx, node_id, linkage, &symbol_name);
118118
}
119119
TransItem::Fn(instance) => {
120-
TransItem::predefine_fn(ccx, instance, linkage, symbol_name);
120+
TransItem::predefine_fn(ccx, instance, linkage, &symbol_name);
121121
}
122122
TransItem::DropGlue(dg) => {
123-
TransItem::predefine_drop_glue(ccx, dg, linkage, symbol_name);
123+
TransItem::predefine_drop_glue(ccx, dg, linkage, &symbol_name);
124124
}
125125
}
126126

0 commit comments

Comments
 (0)