Skip to content

Commit 1939b76

Browse files
committed
Auto merge of #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 a4d2424 + 118cc9e commit 1939b76

13 files changed

+541
-495
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
@@ -68,7 +68,7 @@ use common::{node_id_type, fulfill_obligation};
6868
use common::{type_is_immediate, type_is_zero_size, val_ty};
6969
use common;
7070
use consts;
71-
use context::SharedCrateContext;
71+
use context::{SharedCrateContext, CrateContextList};
7272
use controlflow;
7373
use datum;
7474
use debuginfo::{self, DebugLoc, ToDebugLoc};
@@ -81,7 +81,7 @@ use machine::{llalign_of_min, llsize_of, llsize_of_real};
8181
use meth;
8282
use mir;
8383
use monomorphize::{self, Instance};
84-
use partitioning::{self, PartitioningStrategy, InstantiationMode};
84+
use partitioning::{self, PartitioningStrategy, InstantiationMode, CodegenUnit};
8585
use symbol_names_test;
8686
use tvec;
8787
use type_::Type;
@@ -664,7 +664,7 @@ pub fn coerce_unsized_into<'blk, 'tcx>(bcx: Block<'blk, 'tcx>,
664664
}
665665
}
666666

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

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

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

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

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

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

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

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

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

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

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

2743-
collector::print_collection_results(&ccx);
2747+
collector::print_collection_results(ccx.shared());
27442748

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

2748-
for ccx in shared_ccx.iter() {
2752+
for ccx in crate_context_list.iter() {
27492753
if ccx.sess().opts.debuginfo != NoDebugInfo {
27502754
debuginfo::finalize(&ccx);
27512755
}
@@ -2794,7 +2798,7 @@ pub fn trans_crate<'tcx>(tcx: &TyCtxt<'tcx>,
27942798
}
27952799
}
27962800

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

@@ -2820,14 +2824,14 @@ pub fn trans_crate<'tcx>(tcx: &TyCtxt<'tcx>,
28202824
}
28212825
}
28222826

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

28282832
if sess.target.target.options.is_like_msvc &&
28292833
sess.crate_types.borrow().iter().any(|ct| *ct == config::CrateTypeRlib) {
2830-
create_imps(&shared_ccx);
2834+
create_imps(&crate_context_list);
28312835
}
28322836

28332837
let metadata_module = ModuleTranslation {
@@ -2912,10 +2916,11 @@ impl<'a, 'tcx, 'v> Visitor<'v> for TransItemsWithinModVisitor<'a, 'tcx> {
29122916
}
29132917
}
29142918

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

2918-
let collection_mode = match ccx.sess().opts.debugging_opts.print_trans_items {
2923+
let collection_mode = match scx.sess().opts.debugging_opts.print_trans_items {
29192924
Some(ref s) => {
29202925
let mode_string = s.to_lowercase();
29212926
let mode_string = mode_string.trim();
@@ -2926,7 +2931,7 @@ fn collect_translation_items<'a, 'tcx>(ccx: &CrateContext<'a, 'tcx>) {
29262931
let message = format!("Unknown codegen-item collection mode '{}'. \
29272932
Falling back to 'lazy' mode.",
29282933
mode_string);
2929-
ccx.sess().warn(&message);
2934+
scx.sess().warn(&message);
29302935
}
29312936

29322937
TransItemCollectionMode::Lazy
@@ -2936,27 +2941,27 @@ fn collect_translation_items<'a, 'tcx>(ccx: &CrateContext<'a, 'tcx>) {
29362941
};
29372942

29382943
let (items, reference_map) = time(time_passes, "translation item collection", || {
2939-
collector::collect_crate_translation_items(&ccx, collection_mode)
2944+
collector::collect_crate_translation_items(scx, collection_mode)
29402945
});
29412946

2942-
let strategy = if ccx.sess().opts.debugging_opts.incremental.is_some() {
2947+
let strategy = if scx.sess().opts.debugging_opts.incremental.is_some() {
29432948
PartitioningStrategy::PerModule
29442949
} else {
2945-
PartitioningStrategy::FixedUnitCount(ccx.sess().opts.cg.codegen_units)
2950+
PartitioningStrategy::FixedUnitCount(scx.sess().opts.cg.codegen_units)
29462951
};
29472952

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

2955-
if ccx.sess().opts.debugging_opts.print_trans_items.is_some() {
2960+
if scx.sess().opts.debugging_opts.print_trans_items.is_some() {
29562961
let mut item_to_cgus = HashMap::new();
29572962

2958-
for cgu in codegen_units {
2959-
for (trans_item, linkage) in cgu.items {
2963+
for cgu in &codegen_units {
2964+
for (&trans_item, &linkage) in &cgu.items {
29602965
item_to_cgus.entry(trans_item)
29612966
.or_insert(Vec::new())
29622967
.push((cgu.name.clone(), linkage));
@@ -2966,7 +2971,7 @@ fn collect_translation_items<'a, 'tcx>(ccx: &CrateContext<'a, 'tcx>) {
29662971
let mut item_keys: Vec<_> = items
29672972
.iter()
29682973
.map(|i| {
2969-
let mut output = i.to_string(ccx);
2974+
let mut output = i.to_string(scx.tcx());
29702975
output.push_str(" @@");
29712976
let mut empty = Vec::new();
29722977
let mut cgus = item_to_cgus.get_mut(i).unwrap_or(&mut empty);
@@ -3005,10 +3010,12 @@ fn collect_translation_items<'a, 'tcx>(ccx: &CrateContext<'a, 'tcx>) {
30053010
println!("TRANS_ITEM {}", item);
30063011
}
30073012

3008-
let mut ccx_map = ccx.translation_items().borrow_mut();
3013+
let mut ccx_map = scx.translation_items().borrow_mut();
30093014

30103015
for cgi in items {
30113016
ccx_map.insert(cgi, TransItemState::PredictedButNotGenerated);
30123017
}
30133018
}
3019+
3020+
codegen_units
30143021
}

src/librustc_trans/callee.rs

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

0 commit comments

Comments
 (0)