Skip to content

Commit a95a50f

Browse files
Restructure trans_crate() so that codegen unit partitioning happens before creating LocalCrateContexts.
1 parent a66224d commit a95a50f

File tree

4 files changed

+45
-23
lines changed

4 files changed

+45
-23
lines changed

src/librustc_trans/back/write.rs

Lines changed: 2 additions & 1 deletion
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

Lines changed: 25 additions & 18 deletions
Original file line numberDiff line numberDiff line change
@@ -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;
@@ -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.
@@ -2724,12 +2725,15 @@ pub fn trans_crate<'tcx>(tcx: &TyCtxt<'tcx>,
27242725
check_overflow,
27252726
check_dropflag);
27262727

2727-
let codegen_units = tcx.sess.opts.cg.codegen_units;
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+
27282733
let crate_context_list = CrateContextList::new(&shared_ccx, codegen_units);
27292734

27302735
{
27312736
let ccx = crate_context_list.get_ccx(0);
2732-
collect_translation_items(&ccx);
27332737

27342738
// Translate all items. See `TransModVisitor` for
27352739
// details on why we walk in this particular way.
@@ -2819,7 +2823,7 @@ pub fn trans_crate<'tcx>(tcx: &TyCtxt<'tcx>,
28192823
}
28202824
}
28212825

2822-
if codegen_units > 1 {
2826+
if codegen_unit_count > 1 {
28232827
internalize_symbols(&crate_context_list,
28242828
&reachable_symbols.iter().map(|x| &x[..]).collect());
28252829
}
@@ -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.shared(), 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.tcx());
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/context.rs

Lines changed: 5 additions & 3 deletions
Original file line numberDiff line numberDiff line change
@@ -28,6 +28,7 @@ use mir::CachedMir;
2828
use monomorphize::Instance;
2929

3030
use collector::{TransItem, TransItemState};
31+
use partitioning::CodegenUnit;
3132
use type_::{Type, TypeNames};
3233
use rustc::ty::subst::{Substs, VecPerParamSpace};
3334
use rustc::ty::{self, Ty, TyCtxt};
@@ -193,11 +194,12 @@ pub struct CrateContextList<'a, 'tcx: 'a> {
193194
impl<'a, 'tcx: 'a> CrateContextList<'a, 'tcx> {
194195

195196
pub fn new(shared_ccx: &'a SharedCrateContext<'a, 'tcx>,
196-
local_count: usize)
197+
codegen_units: Vec<CodegenUnit<'tcx>>)
197198
-> CrateContextList<'a, 'tcx> {
198199
CrateContextList {
199200
shared: shared_ccx,
200-
local_ccxs: (0..local_count).map(|index| {
201+
// FIXME: We don't actually use the codegen unit partitioning yet.
202+
local_ccxs: codegen_units.iter().map(|cgu| {
201203
// Append ".rs" to crate name as LLVM module identifier.
202204
//
203205
// LLVM code generator emits a ".file filename" directive
@@ -206,7 +208,7 @@ impl<'a, 'tcx: 'a> CrateContextList<'a, 'tcx> {
206208
// crashes if the module identifier is same as other symbols
207209
// such as a function name in the module.
208210
// 1. http://llvm.org/bugs/show_bug.cgi?id=11479
209-
let llmod_id = format!("{}.{}.rs", shared_ccx.link_meta.crate_name, index);
211+
let llmod_id = format!("{}.rs", cgu.name);
210212
LocalCrateContext::new(shared_ccx, &llmod_id[..])
211213
}).collect()
212214
}

src/librustc_trans/partitioning.rs

Lines changed: 13 additions & 1 deletion
Original file line numberDiff line numberDiff line change
@@ -182,7 +182,19 @@ pub fn partition<'tcx, I>(tcx: &TyCtxt<'tcx>,
182182
// easily determine which declarations need to be placed within each one.
183183
let post_declarations = place_declarations(post_inlining, reference_map);
184184

185-
post_declarations.0
185+
let mut final_partitioning = post_declarations.0;
186+
187+
if final_partitioning.len() == 0 {
188+
// Some crates don't contain anything that will result in a translation
189+
// item. We still want to have at least one (empty) codegen unit in that
190+
// case.
191+
final_partitioning.push(CodegenUnit {
192+
name: token::intern_and_get_ident(&format!("{}.0", tcx.crate_name)[..]),
193+
items: FnvHashMap()
194+
});
195+
}
196+
197+
final_partitioning
186198
}
187199

188200
struct PreInliningPartitioning<'tcx> {

0 commit comments

Comments
 (0)