Skip to content

Commit 9614746

Browse files
experimental MIR-only RLIB support.
1 parent 89b3ef3 commit 9614746

File tree

11 files changed

+104
-30
lines changed

11 files changed

+104
-30
lines changed

src/bootstrap/bin/rustc.rs

+5
Original file line numberDiff line numberDiff line change
@@ -253,6 +253,11 @@ fn main() {
253253
if env::var_os("RUSTC_FORCE_UNSTABLE").is_some() {
254254
cmd.arg("-Z").arg("force-unstable-if-unmarked");
255255
}
256+
257+
// Don't use MIR only RLIBs for the compiler yet
258+
if stage != "0" {
259+
cmd.arg("-Zmir-only-rlibs=no");
260+
}
256261
} else {
257262
// Override linker if necessary.
258263
if let Ok(host_linker) = env::var("RUSTC_HOST_LINKER") {

src/librustc/dep_graph/dep_node.rs

+1
Original file line numberDiff line numberDiff line change
@@ -642,6 +642,7 @@ define_dep_nodes!( <'tcx>
642642

643643
[] GetSymbolExportLevel(DefId),
644644

645+
[input] IsMirOnlyRlib(CrateNum),
645646
);
646647

647648
trait DepNodeParams<'a, 'gcx: 'tcx + 'a, 'tcx: 'a> : fmt::Debug {

src/librustc/session/config.rs

+2
Original file line numberDiff line numberDiff line change
@@ -1322,6 +1322,8 @@ options! {DebuggingOptions, DebuggingSetter, basic_debugging_options,
13221322
epoch). Crates compiled with different epochs can be linked together."),
13231323
run_dsymutil: Option<bool> = (None, parse_opt_bool, [TRACKED],
13241324
"run `dsymutil` and delete intermediate object files"),
1325+
1326+
mir_only_rlibs: Option<bool> = (Some(true), parse_opt_bool, [TRACKED], "go!"),
13251327
}
13261328

13271329
pub fn default_lib_output() -> CrateType {

src/librustc/ty/maps/config.rs

+7
Original file line numberDiff line numberDiff line change
@@ -50,6 +50,13 @@ impl<'tcx, M: QueryConfig<Key=DefId>> QueryDescription<'tcx> for M {
5050
}
5151
}
5252

53+
54+
impl<'tcx> QueryDescription<'tcx> for queries::is_mir_only_rlib<'tcx> {
55+
fn describe(_tcx: TyCtxt, cnum: CrateNum) -> String {
56+
format!("computing whether `{}` is a MIR-only RLIB", cnum)
57+
}
58+
}
59+
5360
impl<'tcx> QueryDescription<'tcx> for queries::is_copy_raw<'tcx> {
5461
fn describe(_tcx: TyCtxt, env: ty::ParamEnvAnd<'tcx, Ty<'tcx>>) -> String {
5562
format!("computing whether `{}` is `Copy`", env.value)

src/librustc/ty/maps/mod.rs

+2
Original file line numberDiff line numberDiff line change
@@ -374,6 +374,8 @@ define_maps! { <'tcx>
374374
// Get an estimate of the size of an InstanceDef based on its MIR for CGU partitioning.
375375
[] fn instance_def_size_estimate: instance_def_size_estimate_dep_node(ty::InstanceDef<'tcx>)
376376
-> usize,
377+
378+
[] fn is_mir_only_rlib: IsMirOnlyRlib(CrateNum) -> bool,
377379
}
378380

379381
//////////////////////////////////////////////////////////////////////

src/librustc/ty/maps/plumbing.rs

+1
Original file line numberDiff line numberDiff line change
@@ -936,6 +936,7 @@ pub fn force_from_dep_node<'a, 'gcx, 'lcx>(tcx: TyCtxt<'a, 'gcx, 'lcx>,
936936
DepKind::TargetFeaturesEnabled => { force!(target_features_enabled, def_id!()); }
937937

938938
DepKind::GetSymbolExportLevel => { force!(symbol_export_level, def_id!()); }
939+
DepKind::IsMirOnlyRlib => { force!(is_mir_only_rlib, krate!()); }
939940
}
940941

941942
true

src/librustc_metadata/cstore_impl.rs

+2
Original file line numberDiff line numberDiff line change
@@ -237,6 +237,8 @@ provide! { <'tcx> tcx, def_id, other, cdata,
237237

238238
has_copy_closures => { cdata.has_copy_closures(tcx.sess) }
239239
has_clone_closures => { cdata.has_clone_closures(tcx.sess) }
240+
241+
is_mir_only_rlib => { cdata.root.is_mir_only_rlib }
240242
}
241243

242244
pub fn provide<'tcx>(providers: &mut Providers<'tcx>) {

src/librustc_metadata/encoder.rs

+15-3
Original file line numberDiff line numberDiff line change
@@ -415,6 +415,14 @@ impl<'a, 'tcx> EncodeContext<'a, 'tcx> {
415415
let has_default_lib_allocator =
416416
attr::contains_name(tcx.hir.krate_attrs(), "default_lib_allocator");
417417
let has_global_allocator = tcx.sess.has_global_allocator.get();
418+
419+
let is_mir_only_rlib = if tcx.sess.opts.debugging_opts.mir_only_rlibs != Some(false) {
420+
let crate_types = tcx.sess.crate_types.borrow();
421+
crate_types.len() == 1 && crate_types[0] == config::CrateTypeRlib
422+
} else {
423+
false
424+
};
425+
418426
let root = self.lazy(&CrateRoot {
419427
name: tcx.crate_name(LOCAL_CRATE),
420428
triple: tcx.sess.opts.target_triple.clone(),
@@ -423,6 +431,7 @@ impl<'a, 'tcx> EncodeContext<'a, 'tcx> {
423431
panic_strategy: tcx.sess.panic_strategy(),
424432
has_global_allocator: has_global_allocator,
425433
has_default_lib_allocator: has_default_lib_allocator,
434+
is_mir_only_rlib,
426435
plugin_registrar_fn: tcx.sess
427436
.plugin_registrar_fn
428437
.get()
@@ -833,7 +842,8 @@ impl<'a, 'b: 'a, 'tcx: 'b> IsolatedEncoder<'a, 'b, 'tcx> {
833842
let needs_inline = types > 0 || attr::requests_inline(&ast_item.attrs);
834843
let is_const_fn = sig.constness == hir::Constness::Const;
835844
let ast = if is_const_fn { Some(body) } else { None };
836-
let always_encode_mir = self.tcx.sess.opts.debugging_opts.always_encode_mir;
845+
let always_encode_mir = self.tcx.sess.opts.debugging_opts.always_encode_mir ||
846+
self.tcx.sess.opts.debugging_opts.mir_only_rlibs != Some(false);
837847
(ast, needs_inline || is_const_fn || always_encode_mir)
838848
} else {
839849
(None, false)
@@ -1115,14 +1125,16 @@ impl<'a, 'b: 'a, 'tcx: 'b> IsolatedEncoder<'a, 'b, 'tcx> {
11151125
_ => None,
11161126
},
11171127
mir: match item.node {
1118-
hir::ItemStatic(..) if self.tcx.sess.opts.debugging_opts.always_encode_mir => {
1128+
hir::ItemStatic(..) if self.tcx.sess.opts.debugging_opts.always_encode_mir ||
1129+
self.tcx.sess.opts.debugging_opts.mir_only_rlibs != Some(false) => {
11191130
self.encode_optimized_mir(def_id)
11201131
}
11211132
hir::ItemConst(..) => self.encode_optimized_mir(def_id),
11221133
hir::ItemFn(_, _, constness, _, ref generics, _) => {
11231134
let has_tps = generics.ty_params().next().is_some();
11241135
let needs_inline = has_tps || attr::requests_inline(&item.attrs);
1125-
let always_encode_mir = self.tcx.sess.opts.debugging_opts.always_encode_mir;
1136+
let always_encode_mir = self.tcx.sess.opts.debugging_opts.always_encode_mir ||
1137+
self.tcx.sess.opts.debugging_opts.mir_only_rlibs != Some(false);
11261138
if needs_inline || constness == hir::Constness::Const || always_encode_mir {
11271139
self.encode_optimized_mir(def_id)
11281140
} else {

src/librustc_metadata/schema.rs

+1
Original file line numberDiff line numberDiff line change
@@ -191,6 +191,7 @@ pub struct CrateRoot {
191191
pub panic_strategy: PanicStrategy,
192192
pub has_global_allocator: bool,
193193
pub has_default_lib_allocator: bool,
194+
pub is_mir_only_rlib: bool,
194195
pub plugin_registrar_fn: Option<DefIndex>,
195196
pub macro_derive_registrar: Option<DefIndex>,
196197

src/librustc_mir/monomorphize/collector.rs

+33-3
Original file line numberDiff line numberDiff line change
@@ -192,6 +192,7 @@ use rustc::hir;
192192
use rustc::hir::itemlikevisit::ItemLikeVisitor;
193193

194194
use rustc::hir::map as hir_map;
195+
use rustc::hir::def::Def;
195196
use rustc::hir::def_id::DefId;
196197
use rustc::middle::const_val::ConstVal;
197198
use rustc::middle::lang_items::{ExchangeMallocFnLangItem, StartFnLangItem};
@@ -301,6 +302,18 @@ pub fn collect_crate_mono_items<'a, 'tcx>(tcx: TyCtxt<'a, 'tcx, 'tcx>,
301302
mode: MonoItemCollectionMode)
302303
-> (FxHashSet<MonoItem<'tcx>>,
303304
InliningMap<'tcx>) {
305+
let current_crate_is_mir_only_rlib =
306+
if tcx.sess.opts.debugging_opts.mir_only_rlibs != Some(false) {
307+
let crate_types = tcx.sess.crate_types.borrow();
308+
crate_types.len() == 1 && crate_types[0] == config::CrateTypeRlib
309+
} else {
310+
false
311+
};
312+
313+
if current_crate_is_mir_only_rlib {
314+
return (FxHashSet(), InliningMap::new())
315+
}
316+
304317
let roots = collect_roots(tcx, mode);
305318

306319
debug!("Building mono item graph, beginning at roots");
@@ -342,6 +355,22 @@ fn collect_roots<'a, 'tcx>(tcx: TyCtxt<'a, 'tcx, 'tcx>,
342355
};
343356

344357
tcx.hir.krate().visit_all_item_likes(&mut visitor);
358+
359+
// Collect upstream roots
360+
for &cnum in tcx.crates().iter() {
361+
if tcx.is_mir_only_rlib(cnum) {
362+
for &def_id in tcx.exported_symbol_ids(cnum).iter() {
363+
match tcx.describe_def(def_id) {
364+
Some(Def::Static(..)) => {
365+
visitor.output.push(MonoItem::Static(def_id));
366+
}
367+
_ => {
368+
visitor.push_if_root(def_id);
369+
}
370+
}
371+
}
372+
}
373+
}
345374
}
346375

347376
// We can only translate items that are instantiable - items all of
@@ -383,7 +412,8 @@ fn collect_items_rec<'a, 'tcx: 'a>(tcx: TyCtxt<'a, 'tcx, 'tcx>,
383412
}
384413
MonoItem::Fn(instance) => {
385414
// Sanity check whether this ended up being collected accidentally
386-
debug_assert!(should_monomorphize_locally(tcx, &instance));
415+
debug_assert!(should_monomorphize_locally(tcx, &instance),
416+
"Instantiation Error: {:?}", instance);
387417

388418
// Keep track of the monomorphization recursion depth
389419
recursion_depth_reset = Some(check_recursion_limit(tcx,
@@ -736,8 +766,8 @@ fn should_monomorphize_locally<'a, 'tcx>(tcx: TyCtxt<'a, 'tcx, 'tcx>, instance:
736766
}
737767
Some(_) => true,
738768
None => {
739-
if tcx.is_exported_symbol(def_id) ||
740-
tcx.is_foreign_item(def_id)
769+
if tcx.is_foreign_item(def_id) ||
770+
(!tcx.is_mir_only_rlib(def_id.krate) && tcx.is_exported_symbol(def_id))
741771
{
742772
// We can link to the item in question, no instance needed
743773
// in this crate

src/librustc_mir/monomorphize/mod.rs

+35-24
Original file line numberDiff line numberDiff line change
@@ -42,30 +42,41 @@ pub fn assert_symbols_are_distinct<'a, 'tcx, I>(tcx: TyCtxt<'a, 'tcx, 'tcx>, tra
4242
let trans_item1 = pair[0].0;
4343
let trans_item2 = pair[1].0;
4444

45-
let span1 = trans_item1.local_span(tcx);
46-
let span2 = trans_item2.local_span(tcx);
47-
48-
// Deterministically select one of the spans for error reporting
49-
let span = match (span1, span2) {
50-
(Some(span1), Some(span2)) => {
51-
Some(if span1.lo().0 > span2.lo().0 {
52-
span1
53-
} else {
54-
span2
55-
})
56-
}
57-
(Some(span), None) |
58-
(None, Some(span)) => Some(span),
59-
_ => None
60-
};
61-
62-
let error_message = format!("symbol `{}` is already defined", sym1);
63-
64-
if let Some(span) = span {
65-
tcx.sess.span_fatal(span, &error_message)
66-
} else {
67-
tcx.sess.fatal(&error_message)
68-
}
45+
bug!("encountered two distinct MonoItems with the same symbol name:\n\
46+
symbol name: {}\n\
47+
item 1: {:?}\n\
48+
item 2: {:?}",
49+
sym1,
50+
trans_item1,
51+
trans_item2)
52+
53+
// let span1 = trans_item1.local_span(tcx);
54+
// let span2 = trans_item2.local_span(tcx);
55+
56+
// // Deterministically select one of the spans for error reporting
57+
// let span = match (span1, span2) {
58+
// (Some(span1), Some(span2)) => {
59+
// Some(if span1.lo().0 > span2.lo().0 {
60+
// span1
61+
// } else {
62+
// span2
63+
// })
64+
// }
65+
// (Some(span), None) |
66+
// (None, Some(span)) => Some(span),
67+
// _ => None
68+
// };
69+
70+
71+
// let error_message = format!("assert_symbols_are_distinct: symbol `{}` is already defined", sym1);
72+
73+
// if let Some(span) = span {
74+
// tcx.sess.span_fatal(span, &error_message)
75+
// span_bug!(span, "{}", )
76+
77+
// } else {
78+
// tcx.sess.fatal(&error_message)
79+
// }
6980
}
7081
}
7182
}

0 commit comments

Comments
 (0)