Skip to content

Commit ba1bdf6

Browse files
Clean up trans::trans_crate() after making things collector driven.
1 parent 267f72f commit ba1bdf6

File tree

2 files changed

+69
-62
lines changed

2 files changed

+69
-62
lines changed

src/librustc_trans/base.rs

Lines changed: 61 additions & 54 deletions
Original file line numberDiff line numberDiff line change
@@ -2199,34 +2199,17 @@ pub fn set_link_section(ccx: &CrateContext,
21992199
}
22002200
}
22012201

2202-
pub fn trans_item(ccx: &CrateContext, item: &hir::Item) {
2202+
fn trans_item(ccx: &CrateContext, item: &hir::Item) {
22032203
let _icx = push_ctxt("trans_item");
22042204

2205-
let tcx = ccx.tcx();
22062205
match item.node {
2207-
hir::ItemFn(_, _, _, _, _, _) => {
2208-
let def_id = tcx.map.local_def_id(item.id);
2209-
// check for the #[rustc_error] annotation, which forces an
2210-
// error in trans. This is used to write compile-fail tests
2211-
// that actually test that compilation succeeds without
2212-
// reporting an error.
2213-
if is_entry_fn(ccx.sess(), item.id) {
2214-
let empty_substs = ccx.empty_substs_for_def_id(def_id);
2215-
let llfn = Callee::def(ccx, def_id, empty_substs).reify(ccx).val;
2216-
create_entry_wrapper(ccx, item.span, llfn);
2217-
if tcx.has_attr(def_id, "rustc_error") {
2218-
tcx.sess.span_fatal(item.span, "compilation successful");
2219-
}
2220-
}
2221-
2222-
// Function is actually translated in trans_instance
2223-
}
22242206
hir::ItemEnum(ref enum_definition, ref gens) => {
22252207
if gens.ty_params.is_empty() {
22262208
// sizes only make sense for non-generic types
22272209
enum_variant_size_lint(ccx, enum_definition, item.span, item.id);
22282210
}
22292211
}
2212+
hir::ItemFn(..) |
22302213
hir::ItemImpl(..) |
22312214
hir::ItemStatic(..) => {
22322215
// Don't do anything here. Translation has been moved to
@@ -2236,22 +2219,40 @@ pub fn trans_item(ccx: &CrateContext, item: &hir::Item) {
22362219
}
22372220
}
22382221

2239-
pub fn is_entry_fn(sess: &Session, node_id: ast::NodeId) -> bool {
2240-
match *sess.entry_fn.borrow() {
2241-
Some((entry_id, _)) => node_id == entry_id,
2242-
None => false,
2222+
/// Create the `main` function which will initialise the rust runtime and call
2223+
/// users’ main function.
2224+
pub fn maybe_create_entry_wrapper(ccx: &CrateContext) {
2225+
let (main_def_id, span) = match *ccx.sess().entry_fn.borrow() {
2226+
Some((id, span)) => {
2227+
(ccx.tcx().map.local_def_id(id), span)
2228+
}
2229+
None => return,
2230+
};
2231+
2232+
// check for the #[rustc_error] annotation, which forces an
2233+
// error in trans. This is used to write compile-fail tests
2234+
// that actually test that compilation succeeds without
2235+
// reporting an error.
2236+
if ccx.tcx().has_attr(main_def_id, "rustc_error") {
2237+
ccx.tcx().sess.span_fatal(span, "compilation successful");
2238+
}
2239+
2240+
let instance = Instance::mono(ccx.shared(), main_def_id);
2241+
2242+
if !ccx.codegen_unit().items.contains_key(&TransItem::Fn(instance)) {
2243+
// We want to create the wrapper in the same codegen unit as Rust's main
2244+
// function.
2245+
return;
22432246
}
2244-
}
22452247

2246-
/// Create the `main` function which will initialise the rust runtime and call users’ main
2247-
/// function.
2248-
pub fn create_entry_wrapper(ccx: &CrateContext, sp: Span, main_llfn: ValueRef) {
2248+
let main_llfn = Callee::def(ccx, main_def_id, instance.substs).reify(ccx).val;
2249+
22492250
let et = ccx.sess().entry_type.get().unwrap();
22502251
match et {
22512252
config::EntryMain => {
2252-
create_entry_fn(ccx, sp, main_llfn, true);
2253+
create_entry_fn(ccx, span, main_llfn, true);
22532254
}
2254-
config::EntryStart => create_entry_fn(ccx, sp, main_llfn, false),
2255+
config::EntryStart => create_entry_fn(ccx, span, main_llfn, false),
22552256
config::EntryNone => {} // Do nothing.
22562257
}
22572258

@@ -2591,13 +2592,11 @@ pub fn trans_crate<'a, 'tcx>(tcx: TyCtxt<'a, 'tcx, 'tcx>,
25912592
};
25922593
let no_builtins = attr::contains_name(&krate.attrs, "no_builtins");
25932594

2594-
let (codegen_units, symbol_map) =
2595-
collect_and_partition_translation_items(&shared_ccx);
2595+
// Run the translation item collector and partition the collected items into
2596+
// codegen units.
2597+
let (codegen_units, symbol_map) = collect_and_partition_translation_items(&shared_ccx);
25962598
let codegen_unit_count = codegen_units.len();
25972599

2598-
assert!(tcx.sess.opts.cg.codegen_units == codegen_unit_count ||
2599-
tcx.sess.opts.debugging_opts.incremental.is_some());
2600-
26012600
let symbol_map = Rc::new(symbol_map);
26022601

26032602
let crate_context_list = CrateContextList::new(&shared_ccx,
@@ -2643,35 +2642,39 @@ pub fn trans_crate<'a, 'tcx>(tcx: TyCtxt<'a, 'tcx, 'tcx>,
26432642
for (trans_item, _) in trans_items {
26442643
trans_item.define(&ccx);
26452644
}
2646-
}
2647-
2648-
{
2649-
let ccx = crate_context_list.get_ccx(0);
2650-
2651-
// Translate all items. See `TransModVisitor` for
2652-
// details on why we walk in this particular way.
2653-
{
2654-
let _icx = push_ctxt("text");
2655-
intravisit::walk_mod(&mut TransItemsWithinModVisitor { ccx: &ccx }, &krate.module);
2656-
krate.visit_all_items(&mut TransModVisitor { ccx: &ccx });
2657-
}
26582645

2659-
collector::print_collection_results(ccx.shared());
2646+
// If this codegen unit contains the main function, also create the
2647+
// wrapper here
2648+
maybe_create_entry_wrapper(&ccx);
26602649

2661-
symbol_names_test::report_symbol_names(&ccx);
2662-
}
2663-
2664-
for ccx in crate_context_list.iter() {
2665-
if ccx.sess().opts.debuginfo != NoDebugInfo {
2666-
debuginfo::finalize(&ccx);
2667-
}
2650+
// Run replace-all-uses-with for statics that need it
26682651
for &(old_g, new_g) in ccx.statics_to_rauw().borrow().iter() {
26692652
unsafe {
26702653
let bitcast = llvm::LLVMConstPointerCast(new_g, llvm::LLVMTypeOf(old_g));
26712654
llvm::LLVMReplaceAllUsesWith(old_g, bitcast);
26722655
llvm::LLVMDeleteGlobal(old_g);
26732656
}
26742657
}
2658+
2659+
// Finalize debuginfo
2660+
if ccx.sess().opts.debuginfo != NoDebugInfo {
2661+
debuginfo::finalize(&ccx);
2662+
}
2663+
}
2664+
2665+
collector::print_collection_results(&shared_ccx);
2666+
symbol_names_test::report_symbol_names(&shared_ccx);
2667+
2668+
{
2669+
let ccx = crate_context_list.get_ccx(0);
2670+
2671+
// At this point, we only walk the HIR for running
2672+
// enum_variant_size_lint(). This should arguably be moved somewhere
2673+
// else
2674+
{
2675+
intravisit::walk_mod(&mut TransItemsWithinModVisitor { ccx: &ccx }, &krate.module);
2676+
krate.visit_all_items(&mut TransModVisitor { ccx: &ccx });
2677+
}
26752678
}
26762679

26772680
if shared_ccx.sess().trans_stats() {
@@ -2697,6 +2700,7 @@ pub fn trans_crate<'a, 'tcx>(tcx: TyCtxt<'a, 'tcx, 'tcx>,
26972700
}
26982701
}
26992702
}
2703+
27002704
if shared_ccx.sess().count_llvm_insns() {
27012705
for (k, v) in shared_ccx.stats().llvm_insns.borrow().iter() {
27022706
println!("{:7} {}", *v, *k);
@@ -2868,6 +2872,9 @@ fn collect_and_partition_translation_items<'a, 'tcx>(scx: &SharedCrateContext<'a
28682872
scx.reachable())
28692873
});
28702874

2875+
assert!(scx.tcx().sess.opts.cg.codegen_units == codegen_units.len() ||
2876+
scx.tcx().sess.opts.debugging_opts.incremental.is_some());
2877+
28712878
if scx.sess().opts.debugging_opts.print_trans_items.is_some() {
28722879
let mut item_to_cgus = HashMap::new();
28732880

src/librustc_trans/symbol_names_test.rs

Lines changed: 8 additions & 8 deletions
Original file line numberDiff line numberDiff line change
@@ -19,40 +19,40 @@ use rustc::hir::intravisit::{self, Visitor};
1919
use syntax::ast;
2020
use syntax::attr::AttrMetaMethods;
2121

22-
use common::CrateContext;
22+
use common::SharedCrateContext;
2323
use monomorphize::Instance;
2424

2525
const SYMBOL_NAME: &'static str = "rustc_symbol_name";
2626
const ITEM_PATH: &'static str = "rustc_item_path";
2727

28-
pub fn report_symbol_names(ccx: &CrateContext) {
28+
pub fn report_symbol_names(scx: &SharedCrateContext) {
2929
// if the `rustc_attrs` feature is not enabled, then the
3030
// attributes we are interested in cannot be present anyway, so
3131
// skip the walk.
32-
let tcx = ccx.tcx();
32+
let tcx = scx.tcx();
3333
if !tcx.sess.features.borrow().rustc_attrs {
3434
return;
3535
}
3636

3737
let _ignore = tcx.dep_graph.in_ignore();
38-
let mut visitor = SymbolNamesTest { ccx: ccx };
38+
let mut visitor = SymbolNamesTest { scx: scx };
3939
tcx.map.krate().visit_all_items(&mut visitor);
4040
}
4141

4242
struct SymbolNamesTest<'a, 'tcx:'a> {
43-
ccx: &'a CrateContext<'a, 'tcx>,
43+
scx: &'a SharedCrateContext<'a, 'tcx>,
4444
}
4545

4646
impl<'a, 'tcx> SymbolNamesTest<'a, 'tcx> {
4747
fn process_attrs(&mut self,
4848
node_id: ast::NodeId) {
49-
let tcx = self.ccx.tcx();
49+
let tcx = self.scx.tcx();
5050
let def_id = tcx.map.local_def_id(node_id);
5151
for attr in tcx.get_attrs(def_id).iter() {
5252
if attr.check_name(SYMBOL_NAME) {
5353
// for now, can only use on monomorphic names
54-
let instance = Instance::mono(self.ccx.shared(), def_id);
55-
let name = instance.symbol_name(self.ccx.shared());
54+
let instance = Instance::mono(self.scx, def_id);
55+
let name = instance.symbol_name(self.scx);
5656
tcx.sess.span_err(attr.span, &format!("symbol-name({})", name));
5757
} else if attr.check_name(ITEM_PATH) {
5858
let path = tcx.item_path_str(def_id);

0 commit comments

Comments
 (0)