Skip to content

Commit bebcb28

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

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
@@ -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;
@@ -2186,7 +2186,8 @@ pub fn update_linkage(ccx: &CrateContext,
21862186
// `llval` is a translation of an item defined in a separate
21872187
// compilation unit. This only makes sense if there are at least
21882188
// two compilation units.
2189-
assert!(ccx.sess().opts.cg.codegen_units > 1);
2189+
assert!(ccx.sess().opts.cg.codegen_units > 1 ||
2190+
ccx.sess().opts.debugging_opts.incremental.is_some());
21902191
// `llval` is a copy of something defined elsewhere, so use
21912192
// `AvailableExternallyLinkage` to avoid duplicating code in the
21922193
// output.
@@ -2723,12 +2724,15 @@ pub fn trans_crate<'tcx>(tcx: &TyCtxt<'tcx>,
27232724
check_overflow,
27242725
check_dropflag);
27252726

2726-
let codegen_units = tcx.sess.opts.cg.codegen_units;
2727+
let codegen_units = collect_and_partition_translation_items(&shared_ccx);
2728+
let codegen_unit_count = codegen_units.len();
2729+
assert!(tcx.sess.opts.cg.codegen_units == codegen_unit_count ||
2730+
tcx.sess.opts.debugging_opts.incremental.is_some());
2731+
27272732
let crate_context_list = CrateContextList::new(&shared_ccx, codegen_units);
27282733

27292734
{
27302735
let ccx = crate_context_list.get_ccx(0);
2731-
collect_translation_items(&ccx);
27322736

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

2821-
if codegen_units > 1 {
2825+
if codegen_unit_count > 1 {
28222826
internalize_symbols(&crate_context_list,
28232827
&reachable_symbols.iter().map(|x| &x[..]).collect());
28242828
}
@@ -2910,10 +2914,11 @@ impl<'a, 'tcx, 'v> Visitor<'v> for TransItemsWithinModVisitor<'a, 'tcx> {
29102914
}
29112915
}
29122916

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

2916-
let collection_mode = match ccx.sess().opts.debugging_opts.print_trans_items {
2921+
let collection_mode = match scx.sess().opts.debugging_opts.print_trans_items {
29172922
Some(ref s) => {
29182923
let mode_string = s.to_lowercase();
29192924
let mode_string = mode_string.trim();
@@ -2924,7 +2929,7 @@ fn collect_translation_items<'a, 'tcx>(ccx: &CrateContext<'a, 'tcx>) {
29242929
let message = format!("Unknown codegen-item collection mode '{}'. \
29252930
Falling back to 'lazy' mode.",
29262931
mode_string);
2927-
ccx.sess().warn(&message);
2932+
scx.sess().warn(&message);
29282933
}
29292934

29302935
TransItemCollectionMode::Lazy
@@ -2934,27 +2939,27 @@ fn collect_translation_items<'a, 'tcx>(ccx: &CrateContext<'a, 'tcx>) {
29342939
};
29352940

29362941
let (items, reference_map) = time(time_passes, "translation item collection", || {
2937-
collector::collect_crate_translation_items(ccx.shared(), collection_mode)
2942+
collector::collect_crate_translation_items(scx, collection_mode)
29382943
});
29392944

2940-
let strategy = if ccx.sess().opts.debugging_opts.incremental.is_some() {
2945+
let strategy = if scx.sess().opts.debugging_opts.incremental.is_some() {
29412946
PartitioningStrategy::PerModule
29422947
} else {
2943-
PartitioningStrategy::FixedUnitCount(ccx.sess().opts.cg.codegen_units)
2948+
PartitioningStrategy::FixedUnitCount(scx.sess().opts.cg.codegen_units)
29442949
};
29452950

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

2953-
if ccx.sess().opts.debugging_opts.print_trans_items.is_some() {
2958+
if scx.sess().opts.debugging_opts.print_trans_items.is_some() {
29542959
let mut item_to_cgus = HashMap::new();
29552960

2956-
for cgu in codegen_units {
2957-
for (trans_item, linkage) in cgu.items {
2961+
for cgu in &codegen_units {
2962+
for (&trans_item, &linkage) in &cgu.items {
29582963
item_to_cgus.entry(trans_item)
29592964
.or_insert(Vec::new())
29602965
.push((cgu.name.clone(), linkage));
@@ -2964,7 +2969,7 @@ fn collect_translation_items<'a, 'tcx>(ccx: &CrateContext<'a, 'tcx>) {
29642969
let mut item_keys: Vec<_> = items
29652970
.iter()
29662971
.map(|i| {
2967-
let mut output = i.to_string(ccx.tcx());
2972+
let mut output = i.to_string(scx.tcx());
29682973
output.push_str(" @@");
29692974
let mut empty = Vec::new();
29702975
let mut cgus = item_to_cgus.get_mut(i).unwrap_or(&mut empty);
@@ -3003,10 +3008,12 @@ fn collect_translation_items<'a, 'tcx>(ccx: &CrateContext<'a, 'tcx>) {
30033008
println!("TRANS_ITEM {}", item);
30043009
}
30053010

3006-
let mut ccx_map = ccx.translation_items().borrow_mut();
3011+
let mut ccx_map = scx.translation_items().borrow_mut();
30073012

30083013
for cgi in items {
30093014
ccx_map.insert(cgi, TransItemState::PredictedButNotGenerated);
30103015
}
30113016
}
3017+
3018+
codegen_units
30123019
}

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};
@@ -196,11 +197,12 @@ pub struct CrateContextList<'a, 'tcx: 'a> {
196197
impl<'a, 'tcx: 'a> CrateContextList<'a, 'tcx> {
197198

198199
pub fn new(shared_ccx: &'a SharedCrateContext<'a, 'tcx>,
199-
local_count: usize)
200+
codegen_units: Vec<CodegenUnit<'tcx>>)
200201
-> CrateContextList<'a, 'tcx> {
201202
CrateContextList {
202203
shared: shared_ccx,
203-
local_ccxs: (0..local_count).map(|index| {
204+
// FIXME: We don't actually use the codegen unit partitioning yet.
205+
local_ccxs: codegen_units.iter().map(|cgu| {
204206
// Append ".rs" to crate name as LLVM module identifier.
205207
//
206208
// LLVM code generator emits a ".file filename" directive
@@ -209,7 +211,7 @@ impl<'a, 'tcx: 'a> CrateContextList<'a, 'tcx> {
209211
// crashes if the module identifier is same as other symbols
210212
// such as a function name in the module.
211213
// 1. http://llvm.org/bugs/show_bug.cgi?id=11479
212-
let llmod_id = format!("{}.{}.rs", shared_ccx.link_meta.crate_name, index);
214+
let llmod_id = format!("{}.rs", cgu.name);
213215
LocalCrateContext::new(shared_ccx, &llmod_id[..])
214216
}).collect()
215217
}

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)