Skip to content

Commit cd9efdf

Browse files
committed
Rollup merge of rust-lang#33473 - michaelwoerister:split-cratecontext, r=nikomatsakis
Preparatory refactorings for collector-driven trans. This is a set of refactorings that allows to do translation item collection and partitioning before LocalCrateContext instances or LLVM modules are generated. As a consequence we can now create LocalCrateContexts already with knowledge of the codegen unit it will be used for. This is a preparation step for driving trans by the results of codegen unit partitioning.
2 parents 3f6d7c1 + b37d7a4 commit cd9efdf

File tree

12 files changed

+539
-493
lines changed

12 files changed

+539
-493
lines changed

src/librustc_trans/back/write.rs

+2-1
Original file line numberDiff line numberDiff line change
@@ -639,7 +639,8 @@ pub fn run_passes(sess: &Session,
639639
}
640640

641641
// Sanity check
642-
assert!(trans.modules.len() == sess.opts.cg.codegen_units);
642+
assert!(trans.modules.len() == sess.opts.cg.codegen_units ||
643+
sess.opts.debugging_opts.incremental.is_some());
643644

644645
let tm = create_target_machine(sess);
645646

src/librustc_trans/base.rs

+49-42
Original file line numberDiff line numberDiff line change
@@ -69,7 +69,7 @@ use common::{node_id_type, fulfill_obligation};
6969
use common::{type_is_immediate, type_is_zero_size, val_ty};
7070
use common;
7171
use consts;
72-
use context::SharedCrateContext;
72+
use context::{SharedCrateContext, CrateContextList};
7373
use controlflow;
7474
use datum;
7575
use debuginfo::{self, DebugLoc, ToDebugLoc};
@@ -82,7 +82,7 @@ use machine::{llalign_of_min, llsize_of, llsize_of_real};
8282
use meth;
8383
use mir;
8484
use monomorphize::{self, Instance};
85-
use partitioning::{self, PartitioningStrategy, InstantiationMode};
85+
use partitioning::{self, PartitioningStrategy, InstantiationMode, CodegenUnit};
8686
use symbol_names_test;
8787
use tvec;
8888
use type_::Type;
@@ -665,7 +665,7 @@ pub fn coerce_unsized_into<'blk, 'tcx>(bcx: Block<'blk, 'tcx>,
665665
}
666666
}
667667

668-
pub fn custom_coerce_unsize_info<'ccx, 'tcx>(ccx: &CrateContext<'ccx, 'tcx>,
668+
pub fn custom_coerce_unsize_info<'scx, 'tcx>(scx: &SharedCrateContext<'scx, 'tcx>,
669669
source_ty: Ty<'tcx>,
670670
target_ty: Ty<'tcx>)
671671
-> CustomCoerceUnsized {
@@ -675,13 +675,13 @@ pub fn custom_coerce_unsize_info<'ccx, 'tcx>(ccx: &CrateContext<'ccx, 'tcx>,
675675
subst::VecPerParamSpace::empty());
676676

677677
let trait_ref = ty::Binder(ty::TraitRef {
678-
def_id: ccx.tcx().lang_items.coerce_unsized_trait().unwrap(),
679-
substs: ccx.tcx().mk_substs(trait_substs)
678+
def_id: scx.tcx().lang_items.coerce_unsized_trait().unwrap(),
679+
substs: scx.tcx().mk_substs(trait_substs)
680680
});
681681

682-
match fulfill_obligation(ccx, DUMMY_SP, trait_ref) {
682+
match fulfill_obligation(scx, DUMMY_SP, trait_ref) {
683683
traits::VtableImpl(traits::VtableImplData { impl_def_id, .. }) => {
684-
ccx.tcx().custom_coerce_unsized_kind(impl_def_id)
684+
scx.tcx().custom_coerce_unsized_kind(impl_def_id)
685685
}
686686
vtable => {
687687
bug!("invalid CoerceUnsized vtable: {:?}", vtable);
@@ -1825,7 +1825,7 @@ pub fn trans_closure<'a, 'tcx>(ccx: &CrateContext<'a, 'tcx>,
18251825
closure_env: closure::ClosureEnv) {
18261826
ccx.stats().n_closures.set(ccx.stats().n_closures.get() + 1);
18271827

1828-
if collector::collecting_debug_information(ccx) {
1828+
if collector::collecting_debug_information(ccx.shared()) {
18291829
ccx.record_translation_item_as_generated(TransItem::Fn(instance));
18301830
}
18311831

@@ -2187,7 +2187,8 @@ pub fn update_linkage(ccx: &CrateContext,
21872187
// `llval` is a translation of an item defined in a separate
21882188
// compilation unit. This only makes sense if there are at least
21892189
// two compilation units.
2190-
assert!(ccx.sess().opts.cg.codegen_units > 1);
2190+
assert!(ccx.sess().opts.cg.codegen_units > 1 ||
2191+
ccx.sess().opts.debugging_opts.incremental.is_some());
21912192
// `llval` is a copy of something defined elsewhere, so use
21922193
// `AvailableExternallyLinkage` to avoid duplicating code in the
21932194
// output.
@@ -2523,7 +2524,7 @@ pub fn write_metadata<'a, 'tcx>(cx: &SharedCrateContext<'a, 'tcx>,
25232524

25242525
/// Find any symbols that are defined in one compilation unit, but not declared
25252526
/// in any other compilation unit. Give these symbols internal linkage.
2526-
fn internalize_symbols(cx: &SharedCrateContext, reachable: &HashSet<&str>) {
2527+
fn internalize_symbols(cx: &CrateContextList, reachable: &HashSet<&str>) {
25272528
unsafe {
25282529
let mut declared = HashSet::new();
25292530

@@ -2578,12 +2579,12 @@ fn internalize_symbols(cx: &SharedCrateContext, reachable: &HashSet<&str>) {
25782579
// when using MSVC linker. We do this only for data, as linker can fix up
25792580
// code references on its own.
25802581
// See #26591, #27438
2581-
fn create_imps(cx: &SharedCrateContext) {
2582+
fn create_imps(cx: &CrateContextList) {
25822583
// The x86 ABI seems to require that leading underscores are added to symbol
25832584
// names, so we need an extra underscore on 32-bit. There's also a leading
25842585
// '\x01' here which disables LLVM's symbol mangling (e.g. no extra
25852586
// underscores added in front).
2586-
let prefix = if cx.sess().target.target.target_pointer_width == "32" {
2587+
let prefix = if cx.shared().sess().target.target.target_pointer_width == "32" {
25872588
"\x01__imp__"
25882589
} else {
25892590
"\x01__imp_"
@@ -2660,10 +2661,10 @@ fn iter_functions(llmod: llvm::ModuleRef) -> ValueIter {
26602661
///
26612662
/// This list is later used by linkers to determine the set of symbols needed to
26622663
/// be exposed from a dynamic library and it's also encoded into the metadata.
2663-
pub fn filter_reachable_ids(ccx: &SharedCrateContext) -> NodeSet {
2664-
ccx.reachable().iter().map(|x| *x).filter(|id| {
2664+
pub fn filter_reachable_ids(scx: &SharedCrateContext) -> NodeSet {
2665+
scx.reachable().iter().map(|x| *x).filter(|id| {
26652666
// First, only worry about nodes which have a symbol name
2666-
ccx.item_symbols().borrow().contains_key(id)
2667+
scx.item_symbols().borrow().contains_key(id)
26672668
}).filter(|&id| {
26682669
// Next, we want to ignore some FFI functions that are not exposed from
26692670
// this crate. Reachable FFI functions can be lumped into two
@@ -2678,9 +2679,9 @@ pub fn filter_reachable_ids(ccx: &SharedCrateContext) -> NodeSet {
26782679
//
26792680
// As a result, if this id is an FFI item (foreign item) then we only
26802681
// let it through if it's included statically.
2681-
match ccx.tcx().map.get(id) {
2682+
match scx.tcx().map.get(id) {
26822683
hir_map::NodeForeignItem(..) => {
2683-
ccx.sess().cstore.is_statically_included_foreign_item(id)
2684+
scx.sess().cstore.is_statically_included_foreign_item(id)
26842685
}
26852686
_ => true,
26862687
}
@@ -2715,10 +2716,7 @@ pub fn trans_crate<'tcx>(tcx: &TyCtxt<'tcx>,
27152716

27162717
let link_meta = link::build_link_meta(&tcx, name);
27172718

2718-
let codegen_units = tcx.sess.opts.cg.codegen_units;
2719-
let shared_ccx = SharedCrateContext::new(&link_meta.crate_name,
2720-
codegen_units,
2721-
tcx,
2719+
let shared_ccx = SharedCrateContext::new(tcx,
27222720
&mir_map,
27232721
export_map,
27242722
Sha256::new(),
@@ -2727,9 +2725,15 @@ pub fn trans_crate<'tcx>(tcx: &TyCtxt<'tcx>,
27272725
check_overflow,
27282726
check_dropflag);
27292727

2728+
let codegen_units = collect_and_partition_translation_items(&shared_ccx);
2729+
let codegen_unit_count = codegen_units.len();
2730+
assert!(tcx.sess.opts.cg.codegen_units == codegen_unit_count ||
2731+
tcx.sess.opts.debugging_opts.incremental.is_some());
2732+
2733+
let crate_context_list = CrateContextList::new(&shared_ccx, codegen_units);
2734+
27302735
{
2731-
let ccx = shared_ccx.get_ccx(0);
2732-
collect_translation_items(&ccx);
2736+
let ccx = crate_context_list.get_ccx(0);
27332737

27342738
// Translate all items. See `TransModVisitor` for
27352739
// details on why we walk in this particular way.
@@ -2739,12 +2743,12 @@ pub fn trans_crate<'tcx>(tcx: &TyCtxt<'tcx>,
27392743
krate.visit_all_items(&mut TransModVisitor { ccx: &ccx });
27402744
}
27412745

2742-
collector::print_collection_results(&ccx);
2746+
collector::print_collection_results(ccx.shared());
27432747

27442748
symbol_names_test::report_symbol_names(&ccx);
27452749
}
27462750

2747-
for ccx in shared_ccx.iter() {
2751+
for ccx in crate_context_list.iter() {
27482752
if ccx.sess().opts.debuginfo != NoDebugInfo {
27492753
debuginfo::finalize(&ccx);
27502754
}
@@ -2793,7 +2797,7 @@ pub fn trans_crate<'tcx>(tcx: &TyCtxt<'tcx>,
27932797
}
27942798
}
27952799

2796-
let modules = shared_ccx.iter()
2800+
let modules = crate_context_list.iter()
27972801
.map(|ccx| ModuleTranslation { llcx: ccx.llcx(), llmod: ccx.llmod() })
27982802
.collect();
27992803

@@ -2819,14 +2823,14 @@ pub fn trans_crate<'tcx>(tcx: &TyCtxt<'tcx>,
28192823
}
28202824
}
28212825

2822-
if codegen_units > 1 {
2823-
internalize_symbols(&shared_ccx,
2826+
if codegen_unit_count > 1 {
2827+
internalize_symbols(&crate_context_list,
28242828
&reachable_symbols.iter().map(|x| &x[..]).collect());
28252829
}
28262830

28272831
if sess.target.target.options.is_like_msvc &&
28282832
sess.crate_types.borrow().iter().any(|ct| *ct == config::CrateTypeRlib) {
2829-
create_imps(&shared_ccx);
2833+
create_imps(&crate_context_list);
28302834
}
28312835

28322836
let metadata_module = ModuleTranslation {
@@ -2911,10 +2915,11 @@ impl<'a, 'tcx, 'v> Visitor<'v> for TransItemsWithinModVisitor<'a, 'tcx> {
29112915
}
29122916
}
29132917

2914-
fn collect_translation_items<'a, 'tcx>(ccx: &CrateContext<'a, 'tcx>) {
2915-
let time_passes = ccx.sess().time_passes();
2918+
fn collect_and_partition_translation_items<'a, 'tcx>(scx: &SharedCrateContext<'a, 'tcx>)
2919+
-> Vec<CodegenUnit<'tcx>> {
2920+
let time_passes = scx.sess().time_passes();
29162921

2917-
let collection_mode = match ccx.sess().opts.debugging_opts.print_trans_items {
2922+
let collection_mode = match scx.sess().opts.debugging_opts.print_trans_items {
29182923
Some(ref s) => {
29192924
let mode_string = s.to_lowercase();
29202925
let mode_string = mode_string.trim();
@@ -2925,7 +2930,7 @@ fn collect_translation_items<'a, 'tcx>(ccx: &CrateContext<'a, 'tcx>) {
29252930
let message = format!("Unknown codegen-item collection mode '{}'. \
29262931
Falling back to 'lazy' mode.",
29272932
mode_string);
2928-
ccx.sess().warn(&message);
2933+
scx.sess().warn(&message);
29292934
}
29302935

29312936
TransItemCollectionMode::Lazy
@@ -2935,27 +2940,27 @@ fn collect_translation_items<'a, 'tcx>(ccx: &CrateContext<'a, 'tcx>) {
29352940
};
29362941

29372942
let (items, reference_map) = time(time_passes, "translation item collection", || {
2938-
collector::collect_crate_translation_items(&ccx, collection_mode)
2943+
collector::collect_crate_translation_items(scx, collection_mode)
29392944
});
29402945

2941-
let strategy = if ccx.sess().opts.debugging_opts.incremental.is_some() {
2946+
let strategy = if scx.sess().opts.debugging_opts.incremental.is_some() {
29422947
PartitioningStrategy::PerModule
29432948
} else {
2944-
PartitioningStrategy::FixedUnitCount(ccx.sess().opts.cg.codegen_units)
2949+
PartitioningStrategy::FixedUnitCount(scx.sess().opts.cg.codegen_units)
29452950
};
29462951

29472952
let codegen_units = time(time_passes, "codegen unit partitioning", || {
2948-
partitioning::partition(ccx.tcx(),
2953+
partitioning::partition(scx.tcx(),
29492954
items.iter().cloned(),
29502955
strategy,
29512956
&reference_map)
29522957
});
29532958

2954-
if ccx.sess().opts.debugging_opts.print_trans_items.is_some() {
2959+
if scx.sess().opts.debugging_opts.print_trans_items.is_some() {
29552960
let mut item_to_cgus = HashMap::new();
29562961

2957-
for cgu in codegen_units {
2958-
for (trans_item, linkage) in cgu.items {
2962+
for cgu in &codegen_units {
2963+
for (&trans_item, &linkage) in &cgu.items {
29592964
item_to_cgus.entry(trans_item)
29602965
.or_insert(Vec::new())
29612966
.push((cgu.name.clone(), linkage));
@@ -2965,7 +2970,7 @@ fn collect_translation_items<'a, 'tcx>(ccx: &CrateContext<'a, 'tcx>) {
29652970
let mut item_keys: Vec<_> = items
29662971
.iter()
29672972
.map(|i| {
2968-
let mut output = i.to_string(ccx);
2973+
let mut output = i.to_string(scx.tcx());
29692974
output.push_str(" @@");
29702975
let mut empty = Vec::new();
29712976
let mut cgus = item_to_cgus.get_mut(i).unwrap_or(&mut empty);
@@ -3004,10 +3009,12 @@ fn collect_translation_items<'a, 'tcx>(ccx: &CrateContext<'a, 'tcx>) {
30043009
println!("TRANS_ITEM {}", item);
30053010
}
30063011

3007-
let mut ccx_map = ccx.translation_items().borrow_mut();
3012+
let mut ccx_map = scx.translation_items().borrow_mut();
30083013

30093014
for cgi in items {
30103015
ccx_map.insert(cgi, TransItemState::PredictedButNotGenerated);
30113016
}
30123017
}
3018+
3019+
codegen_units
30133020
}

src/librustc_trans/callee.rs

+1-1
Original file line numberDiff line numberDiff line change
@@ -155,7 +155,7 @@ impl<'tcx> Callee<'tcx> {
155155
let method_item = tcx.impl_or_trait_item(def_id);
156156
let trait_id = method_item.container().id();
157157
let trait_ref = ty::Binder(substs.to_trait_ref(tcx, trait_id));
158-
match common::fulfill_obligation(ccx, DUMMY_SP, trait_ref) {
158+
match common::fulfill_obligation(ccx.shared(), DUMMY_SP, trait_ref) {
159159
traits::VtableImpl(vtable_impl) => {
160160
let impl_did = vtable_impl.impl_def_id;
161161
let mname = tcx.item_name(def_id);

0 commit comments

Comments
 (0)