Skip to content

Commit 0ab27b1

Browse files
committed
split CrateContext into shared and local pieces
Break up `CrateContext` into `SharedCrateContext` and `LocalCrateContext`. The local piece corresponds to a single compilation unit, and contains all LLVM-related components. (LLVM data structures are tied to a specific `LLVMContext`, and we will need separate `LLVMContext`s to safely run multithreaded optimization.) The shared piece contains data structures that need to be shared across all compilation units, such as the `ty::ctxt` and some tables related to crate metadata.
1 parent cf35cb3 commit 0ab27b1

File tree

6 files changed

+327
-182
lines changed

6 files changed

+327
-182
lines changed

src/librustc/back/link.rs

Lines changed: 1 addition & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -405,6 +405,7 @@ pub mod write {
405405

406406
llvm::LLVMRustDisposeTargetMachine(tm);
407407
llvm::LLVMDisposeModule(trans.metadata_module);
408+
llvm::LLVMContextDispose(trans.metadata_context);
408409
llvm::LLVMDisposeModule(llmod);
409410
llvm::LLVMContextDispose(llcx);
410411
if sess.time_llvm_passes() { llvm::LLVMRustPrintPassTimings(); }

src/librustc/driver/driver.rs

Lines changed: 1 addition & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -444,6 +444,7 @@ pub fn phase_save_analysis(sess: &Session,
444444
pub struct CrateTranslation {
445445
pub context: ContextRef,
446446
pub module: ModuleRef,
447+
pub metadata_context: ContextRef,
447448
pub metadata_module: ModuleRef,
448449
pub link: LinkMeta,
449450
pub metadata: Vec<u8>,

src/librustc/middle/trans/base.rs

Lines changed: 56 additions & 52 deletions
Original file line numberDiff line numberDiff line change
@@ -56,6 +56,7 @@ use middle::trans::common::{tydesc_info, type_is_immediate};
5656
use middle::trans::common::{type_is_zero_size, val_ty};
5757
use middle::trans::common;
5858
use middle::trans::consts;
59+
use middle::trans::context::SharedCrateContext;
5960
use middle::trans::controlflow;
6061
use middle::trans::datum;
6162
use middle::trans::debuginfo;
@@ -136,7 +137,7 @@ pub fn push_ctxt(s: &'static str) -> _InsnCtxt {
136137
}
137138

138139
pub struct StatRecorder<'a> {
139-
ccx: &'a CrateContext,
140+
ccx: &'a CrateContext<'a>,
140141
name: Option<String>,
141142
start: u64,
142143
istart: uint,
@@ -2114,7 +2115,7 @@ fn enum_variant_size_lint(ccx: &CrateContext, enum_def: &ast::EnumDef, sp: Span,
21142115
}
21152116

21162117
pub struct TransItemVisitor<'a> {
2117-
pub ccx: &'a CrateContext,
2118+
pub ccx: &'a CrateContext<'a>,
21182119
}
21192120

21202121
impl<'a> Visitor<()> for TransItemVisitor<'a> {
@@ -2895,80 +2896,81 @@ pub fn trans_crate(krate: ast::Crate,
28952896

28962897
let link_meta = link::build_link_meta(&tcx.sess, &krate, name);
28972898

2898-
// Append ".rs" to crate name as LLVM module identifier.
2899-
//
2900-
// LLVM code generator emits a ".file filename" directive
2901-
// for ELF backends. Value of the "filename" is set as the
2902-
// LLVM module identifier. Due to a LLVM MC bug[1], LLVM
2903-
// crashes if the module identifier is same as other symbols
2904-
// such as a function name in the module.
2905-
// 1. http://llvm.org/bugs/show_bug.cgi?id=11479
2906-
let mut llmod_id = link_meta.crate_name.clone();
2907-
llmod_id.push_str(".rs");
2899+
// Multiple compilation units won't be supported until a later commit.
2900+
let codegen_units = 1;
2901+
let shared_ccx = SharedCrateContext::new(link_meta.crate_name.as_slice(),
2902+
codegen_units,
2903+
tcx,
2904+
exp_map2,
2905+
Sha256::new(),
2906+
link_meta.clone(),
2907+
reachable);
29082908

2909-
let ccx = CrateContext::new(llmod_id.as_slice(), tcx, exp_map2,
2910-
Sha256::new(), link_meta, reachable);
2909+
let metadata = {
2910+
let ccx = shared_ccx.get_ccx(0);
29112911

2912-
// First, verify intrinsics.
2913-
intrinsic::check_intrinsics(&ccx);
2912+
// First, verify intrinsics.
2913+
intrinsic::check_intrinsics(&ccx);
29142914

2915-
// Next, translate the module.
2916-
{
2917-
let _icx = push_ctxt("text");
2918-
trans_mod(&ccx, &krate.module);
2919-
}
2915+
// Next, translate the module.
2916+
{
2917+
let _icx = push_ctxt("text");
2918+
trans_mod(&ccx, &krate.module);
2919+
}
29202920

2921-
glue::emit_tydescs(&ccx);
2922-
if ccx.sess().opts.debuginfo != NoDebugInfo {
2923-
debuginfo::finalize(&ccx);
2924-
}
2921+
glue::emit_tydescs(&ccx);
2922+
if ccx.sess().opts.debuginfo != NoDebugInfo {
2923+
debuginfo::finalize(&ccx);
2924+
}
2925+
2926+
// Translate the metadata.
2927+
write_metadata(&ccx, &krate)
2928+
};
29252929

2926-
// Translate the metadata.
2927-
let metadata = write_metadata(&ccx, &krate);
2928-
if ccx.sess().trans_stats() {
2930+
if shared_ccx.sess().trans_stats() {
2931+
let stats = shared_ccx.stats();
29292932
println!("--- trans stats ---");
2930-
println!("n_static_tydescs: {}", ccx.stats().n_static_tydescs.get());
2931-
println!("n_glues_created: {}", ccx.stats().n_glues_created.get());
2932-
println!("n_null_glues: {}", ccx.stats().n_null_glues.get());
2933-
println!("n_real_glues: {}", ccx.stats().n_real_glues.get());
2934-
2935-
println!("n_fns: {}", ccx.stats().n_fns.get());
2936-
println!("n_monos: {}", ccx.stats().n_monos.get());
2937-
println!("n_inlines: {}", ccx.stats().n_inlines.get());
2938-
println!("n_closures: {}", ccx.stats().n_closures.get());
2933+
println!("n_static_tydescs: {}", stats.n_static_tydescs.get());
2934+
println!("n_glues_created: {}", stats.n_glues_created.get());
2935+
println!("n_null_glues: {}", stats.n_null_glues.get());
2936+
println!("n_real_glues: {}", stats.n_real_glues.get());
2937+
2938+
println!("n_fns: {}", stats.n_fns.get());
2939+
println!("n_monos: {}", stats.n_monos.get());
2940+
println!("n_inlines: {}", stats.n_inlines.get());
2941+
println!("n_closures: {}", stats.n_closures.get());
29392942
println!("fn stats:");
2940-
ccx.stats().fn_stats.borrow_mut().sort_by(|&(_, _, insns_a), &(_, _, insns_b)| {
2943+
stats.fn_stats.borrow_mut().sort_by(|&(_, _, insns_a), &(_, _, insns_b)| {
29412944
insns_b.cmp(&insns_a)
29422945
});
2943-
for tuple in ccx.stats().fn_stats.borrow().iter() {
2946+
for tuple in stats.fn_stats.borrow().iter() {
29442947
match *tuple {
29452948
(ref name, ms, insns) => {
29462949
println!("{} insns, {} ms, {}", insns, ms, *name);
29472950
}
29482951
}
29492952
}
29502953
}
2951-
if ccx.sess().count_llvm_insns() {
2952-
for (k, v) in ccx.stats().llvm_insns.borrow().iter() {
2954+
if shared_ccx.sess().count_llvm_insns() {
2955+
for (k, v) in shared_ccx.stats().llvm_insns.borrow().iter() {
29532956
println!("{:7u} {}", *v, *k);
29542957
}
29552958
}
29562959

2957-
let llcx = ccx.llcx();
2958-
let link_meta = ccx.link_meta().clone();
2959-
let llmod = ccx.llmod();
2960+
let llcx = shared_ccx.get_ccx(0).llcx();
2961+
let llmod = shared_ccx.get_ccx(0).llmod();
29602962

2961-
let mut reachable: Vec<String> = ccx.reachable().iter().filter_map(|id| {
2962-
ccx.item_symbols().borrow().find(id).map(|s| s.to_string())
2963+
let mut reachable: Vec<String> = shared_ccx.reachable().iter().filter_map(|id| {
2964+
shared_ccx.item_symbols().borrow().find(id).map(|s| s.to_string())
29632965
}).collect();
29642966

29652967
// For the purposes of LTO, we add to the reachable set all of the upstream
29662968
// reachable extern fns. These functions are all part of the public ABI of
29672969
// the final product, so LTO needs to preserve them.
2968-
ccx.sess().cstore.iter_crate_data(|cnum, _| {
2969-
let syms = csearch::get_reachable_extern_fns(&ccx.sess().cstore, cnum);
2970+
shared_ccx.sess().cstore.iter_crate_data(|cnum, _| {
2971+
let syms = csearch::get_reachable_extern_fns(&shared_ccx.sess().cstore, cnum);
29702972
reachable.extend(syms.move_iter().map(|did| {
2971-
csearch::get_symbol(&ccx.sess().cstore, did)
2973+
csearch::get_symbol(&shared_ccx.sess().cstore, did)
29722974
}));
29732975
});
29742976

@@ -2986,15 +2988,17 @@ pub fn trans_crate(krate: ast::Crate,
29862988
// referenced from rt/rust_try.ll
29872989
reachable.push("rust_eh_personality_catch".to_string());
29882990

2989-
let metadata_module = ccx.metadata_llmod();
2990-
let formats = ccx.tcx().dependency_formats.borrow().clone();
2991+
let metadata_module = shared_ccx.metadata_llmod();
2992+
let metadata_context = shared_ccx.metadata_llcx();
2993+
let formats = shared_ccx.tcx().dependency_formats.borrow().clone();
29912994
let no_builtins = attr::contains_name(krate.attrs.as_slice(), "no_builtins");
29922995

2993-
(ccx.take_tcx(), CrateTranslation {
2996+
(shared_ccx.take_tcx(), CrateTranslation {
29942997
context: llcx,
29952998
module: llmod,
29962999
link: link_meta,
29973000
metadata_module: metadata_module,
3001+
metadata_context: metadata_context,
29983002
metadata: metadata,
29993003
reachable: reachable,
30003004
crate_formats: formats,

src/librustc/middle/trans/builder.rs

Lines changed: 1 addition & 1 deletion
Original file line numberDiff line numberDiff line change
@@ -25,7 +25,7 @@ use syntax::codemap::Span;
2525

2626
pub struct Builder<'a> {
2727
pub llbuilder: BuilderRef,
28-
pub ccx: &'a CrateContext,
28+
pub ccx: &'a CrateContext<'a>,
2929
}
3030

3131
// This is a really awful way to get a zero-length c-string, but better (and a

src/librustc/middle/trans/common.rs

Lines changed: 2 additions & 2 deletions
Original file line numberDiff line numberDiff line change
@@ -297,7 +297,7 @@ pub struct FunctionContext<'a> {
297297
pub block_arena: &'a TypedArena<Block<'a>>,
298298

299299
// This function's enclosing crate context.
300-
pub ccx: &'a CrateContext,
300+
pub ccx: &'a CrateContext<'a>,
301301

302302
// Used and maintained by the debuginfo module.
303303
pub debug_context: debuginfo::FunctionDebugContext,
@@ -449,7 +449,7 @@ impl<'a> Block<'a> {
449449
})
450450
}
451451

452-
pub fn ccx(&self) -> &'a CrateContext { self.fcx.ccx }
452+
pub fn ccx(&self) -> &'a CrateContext<'a> { self.fcx.ccx }
453453
pub fn tcx(&self) -> &'a ty::ctxt {
454454
self.fcx.ccx.tcx()
455455
}

0 commit comments

Comments
 (0)