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.
This commit is contained in:
parent
cf35cb365a
commit
0ab27b1d5b
|
@ -405,6 +405,7 @@ pub mod write {
|
||||||
|
|
||||||
llvm::LLVMRustDisposeTargetMachine(tm);
|
llvm::LLVMRustDisposeTargetMachine(tm);
|
||||||
llvm::LLVMDisposeModule(trans.metadata_module);
|
llvm::LLVMDisposeModule(trans.metadata_module);
|
||||||
|
llvm::LLVMContextDispose(trans.metadata_context);
|
||||||
llvm::LLVMDisposeModule(llmod);
|
llvm::LLVMDisposeModule(llmod);
|
||||||
llvm::LLVMContextDispose(llcx);
|
llvm::LLVMContextDispose(llcx);
|
||||||
if sess.time_llvm_passes() { llvm::LLVMRustPrintPassTimings(); }
|
if sess.time_llvm_passes() { llvm::LLVMRustPrintPassTimings(); }
|
||||||
|
|
|
@ -444,6 +444,7 @@ pub fn phase_save_analysis(sess: &Session,
|
||||||
pub struct CrateTranslation {
|
pub struct CrateTranslation {
|
||||||
pub context: ContextRef,
|
pub context: ContextRef,
|
||||||
pub module: ModuleRef,
|
pub module: ModuleRef,
|
||||||
|
pub metadata_context: ContextRef,
|
||||||
pub metadata_module: ModuleRef,
|
pub metadata_module: ModuleRef,
|
||||||
pub link: LinkMeta,
|
pub link: LinkMeta,
|
||||||
pub metadata: Vec<u8>,
|
pub metadata: Vec<u8>,
|
||||||
|
|
|
@ -56,6 +56,7 @@ use middle::trans::common::{tydesc_info, type_is_immediate};
|
||||||
use middle::trans::common::{type_is_zero_size, val_ty};
|
use middle::trans::common::{type_is_zero_size, val_ty};
|
||||||
use middle::trans::common;
|
use middle::trans::common;
|
||||||
use middle::trans::consts;
|
use middle::trans::consts;
|
||||||
|
use middle::trans::context::SharedCrateContext;
|
||||||
use middle::trans::controlflow;
|
use middle::trans::controlflow;
|
||||||
use middle::trans::datum;
|
use middle::trans::datum;
|
||||||
use middle::trans::debuginfo;
|
use middle::trans::debuginfo;
|
||||||
|
@ -136,7 +137,7 @@ pub fn push_ctxt(s: &'static str) -> _InsnCtxt {
|
||||||
}
|
}
|
||||||
|
|
||||||
pub struct StatRecorder<'a> {
|
pub struct StatRecorder<'a> {
|
||||||
ccx: &'a CrateContext,
|
ccx: &'a CrateContext<'a>,
|
||||||
name: Option<String>,
|
name: Option<String>,
|
||||||
start: u64,
|
start: u64,
|
||||||
istart: uint,
|
istart: uint,
|
||||||
|
@ -2114,7 +2115,7 @@ fn enum_variant_size_lint(ccx: &CrateContext, enum_def: &ast::EnumDef, sp: Span,
|
||||||
}
|
}
|
||||||
|
|
||||||
pub struct TransItemVisitor<'a> {
|
pub struct TransItemVisitor<'a> {
|
||||||
pub ccx: &'a CrateContext,
|
pub ccx: &'a CrateContext<'a>,
|
||||||
}
|
}
|
||||||
|
|
||||||
impl<'a> Visitor<()> for TransItemVisitor<'a> {
|
impl<'a> Visitor<()> for TransItemVisitor<'a> {
|
||||||
|
@ -2895,19 +2896,18 @@ pub fn trans_crate(krate: ast::Crate,
|
||||||
|
|
||||||
let link_meta = link::build_link_meta(&tcx.sess, &krate, name);
|
let link_meta = link::build_link_meta(&tcx.sess, &krate, name);
|
||||||
|
|
||||||
// Append ".rs" to crate name as LLVM module identifier.
|
// Multiple compilation units won't be supported until a later commit.
|
||||||
//
|
let codegen_units = 1;
|
||||||
// LLVM code generator emits a ".file filename" directive
|
let shared_ccx = SharedCrateContext::new(link_meta.crate_name.as_slice(),
|
||||||
// for ELF backends. Value of the "filename" is set as the
|
codegen_units,
|
||||||
// LLVM module identifier. Due to a LLVM MC bug[1], LLVM
|
tcx,
|
||||||
// crashes if the module identifier is same as other symbols
|
exp_map2,
|
||||||
// such as a function name in the module.
|
Sha256::new(),
|
||||||
// 1. http://llvm.org/bugs/show_bug.cgi?id=11479
|
link_meta.clone(),
|
||||||
let mut llmod_id = link_meta.crate_name.clone();
|
reachable);
|
||||||
llmod_id.push_str(".rs");
|
|
||||||
|
|
||||||
let ccx = CrateContext::new(llmod_id.as_slice(), tcx, exp_map2,
|
let metadata = {
|
||||||
Sha256::new(), link_meta, reachable);
|
let ccx = shared_ccx.get_ccx(0);
|
||||||
|
|
||||||
// First, verify intrinsics.
|
// First, verify intrinsics.
|
||||||
intrinsic::check_intrinsics(&ccx);
|
intrinsic::check_intrinsics(&ccx);
|
||||||
|
@ -2924,23 +2924,26 @@ pub fn trans_crate(krate: ast::Crate,
|
||||||
}
|
}
|
||||||
|
|
||||||
// Translate the metadata.
|
// Translate the metadata.
|
||||||
let metadata = write_metadata(&ccx, &krate);
|
write_metadata(&ccx, &krate)
|
||||||
if ccx.sess().trans_stats() {
|
};
|
||||||
println!("--- trans stats ---");
|
|
||||||
println!("n_static_tydescs: {}", ccx.stats().n_static_tydescs.get());
|
|
||||||
println!("n_glues_created: {}", ccx.stats().n_glues_created.get());
|
|
||||||
println!("n_null_glues: {}", ccx.stats().n_null_glues.get());
|
|
||||||
println!("n_real_glues: {}", ccx.stats().n_real_glues.get());
|
|
||||||
|
|
||||||
println!("n_fns: {}", ccx.stats().n_fns.get());
|
if shared_ccx.sess().trans_stats() {
|
||||||
println!("n_monos: {}", ccx.stats().n_monos.get());
|
let stats = shared_ccx.stats();
|
||||||
println!("n_inlines: {}", ccx.stats().n_inlines.get());
|
println!("--- trans stats ---");
|
||||||
println!("n_closures: {}", ccx.stats().n_closures.get());
|
println!("n_static_tydescs: {}", stats.n_static_tydescs.get());
|
||||||
|
println!("n_glues_created: {}", stats.n_glues_created.get());
|
||||||
|
println!("n_null_glues: {}", stats.n_null_glues.get());
|
||||||
|
println!("n_real_glues: {}", stats.n_real_glues.get());
|
||||||
|
|
||||||
|
println!("n_fns: {}", stats.n_fns.get());
|
||||||
|
println!("n_monos: {}", stats.n_monos.get());
|
||||||
|
println!("n_inlines: {}", stats.n_inlines.get());
|
||||||
|
println!("n_closures: {}", stats.n_closures.get());
|
||||||
println!("fn stats:");
|
println!("fn stats:");
|
||||||
ccx.stats().fn_stats.borrow_mut().sort_by(|&(_, _, insns_a), &(_, _, insns_b)| {
|
stats.fn_stats.borrow_mut().sort_by(|&(_, _, insns_a), &(_, _, insns_b)| {
|
||||||
insns_b.cmp(&insns_a)
|
insns_b.cmp(&insns_a)
|
||||||
});
|
});
|
||||||
for tuple in ccx.stats().fn_stats.borrow().iter() {
|
for tuple in stats.fn_stats.borrow().iter() {
|
||||||
match *tuple {
|
match *tuple {
|
||||||
(ref name, ms, insns) => {
|
(ref name, ms, insns) => {
|
||||||
println!("{} insns, {} ms, {}", insns, ms, *name);
|
println!("{} insns, {} ms, {}", insns, ms, *name);
|
||||||
|
@ -2948,27 +2951,26 @@ pub fn trans_crate(krate: ast::Crate,
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
if ccx.sess().count_llvm_insns() {
|
if shared_ccx.sess().count_llvm_insns() {
|
||||||
for (k, v) in ccx.stats().llvm_insns.borrow().iter() {
|
for (k, v) in shared_ccx.stats().llvm_insns.borrow().iter() {
|
||||||
println!("{:7u} {}", *v, *k);
|
println!("{:7u} {}", *v, *k);
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
|
|
||||||
let llcx = ccx.llcx();
|
let llcx = shared_ccx.get_ccx(0).llcx();
|
||||||
let link_meta = ccx.link_meta().clone();
|
let llmod = shared_ccx.get_ccx(0).llmod();
|
||||||
let llmod = ccx.llmod();
|
|
||||||
|
|
||||||
let mut reachable: Vec<String> = ccx.reachable().iter().filter_map(|id| {
|
let mut reachable: Vec<String> = shared_ccx.reachable().iter().filter_map(|id| {
|
||||||
ccx.item_symbols().borrow().find(id).map(|s| s.to_string())
|
shared_ccx.item_symbols().borrow().find(id).map(|s| s.to_string())
|
||||||
}).collect();
|
}).collect();
|
||||||
|
|
||||||
// For the purposes of LTO, we add to the reachable set all of the upstream
|
// For the purposes of LTO, we add to the reachable set all of the upstream
|
||||||
// reachable extern fns. These functions are all part of the public ABI of
|
// reachable extern fns. These functions are all part of the public ABI of
|
||||||
// the final product, so LTO needs to preserve them.
|
// the final product, so LTO needs to preserve them.
|
||||||
ccx.sess().cstore.iter_crate_data(|cnum, _| {
|
shared_ccx.sess().cstore.iter_crate_data(|cnum, _| {
|
||||||
let syms = csearch::get_reachable_extern_fns(&ccx.sess().cstore, cnum);
|
let syms = csearch::get_reachable_extern_fns(&shared_ccx.sess().cstore, cnum);
|
||||||
reachable.extend(syms.move_iter().map(|did| {
|
reachable.extend(syms.move_iter().map(|did| {
|
||||||
csearch::get_symbol(&ccx.sess().cstore, did)
|
csearch::get_symbol(&shared_ccx.sess().cstore, did)
|
||||||
}));
|
}));
|
||||||
});
|
});
|
||||||
|
|
||||||
|
@ -2986,15 +2988,17 @@ pub fn trans_crate(krate: ast::Crate,
|
||||||
// referenced from rt/rust_try.ll
|
// referenced from rt/rust_try.ll
|
||||||
reachable.push("rust_eh_personality_catch".to_string());
|
reachable.push("rust_eh_personality_catch".to_string());
|
||||||
|
|
||||||
let metadata_module = ccx.metadata_llmod();
|
let metadata_module = shared_ccx.metadata_llmod();
|
||||||
let formats = ccx.tcx().dependency_formats.borrow().clone();
|
let metadata_context = shared_ccx.metadata_llcx();
|
||||||
|
let formats = shared_ccx.tcx().dependency_formats.borrow().clone();
|
||||||
let no_builtins = attr::contains_name(krate.attrs.as_slice(), "no_builtins");
|
let no_builtins = attr::contains_name(krate.attrs.as_slice(), "no_builtins");
|
||||||
|
|
||||||
(ccx.take_tcx(), CrateTranslation {
|
(shared_ccx.take_tcx(), CrateTranslation {
|
||||||
context: llcx,
|
context: llcx,
|
||||||
module: llmod,
|
module: llmod,
|
||||||
link: link_meta,
|
link: link_meta,
|
||||||
metadata_module: metadata_module,
|
metadata_module: metadata_module,
|
||||||
|
metadata_context: metadata_context,
|
||||||
metadata: metadata,
|
metadata: metadata,
|
||||||
reachable: reachable,
|
reachable: reachable,
|
||||||
crate_formats: formats,
|
crate_formats: formats,
|
||||||
|
|
|
@ -25,7 +25,7 @@ use syntax::codemap::Span;
|
||||||
|
|
||||||
pub struct Builder<'a> {
|
pub struct Builder<'a> {
|
||||||
pub llbuilder: BuilderRef,
|
pub llbuilder: BuilderRef,
|
||||||
pub ccx: &'a CrateContext,
|
pub ccx: &'a CrateContext<'a>,
|
||||||
}
|
}
|
||||||
|
|
||||||
// This is a really awful way to get a zero-length c-string, but better (and a
|
// This is a really awful way to get a zero-length c-string, but better (and a
|
||||||
|
|
|
@ -297,7 +297,7 @@ pub struct FunctionContext<'a> {
|
||||||
pub block_arena: &'a TypedArena<Block<'a>>,
|
pub block_arena: &'a TypedArena<Block<'a>>,
|
||||||
|
|
||||||
// This function's enclosing crate context.
|
// This function's enclosing crate context.
|
||||||
pub ccx: &'a CrateContext,
|
pub ccx: &'a CrateContext<'a>,
|
||||||
|
|
||||||
// Used and maintained by the debuginfo module.
|
// Used and maintained by the debuginfo module.
|
||||||
pub debug_context: debuginfo::FunctionDebugContext,
|
pub debug_context: debuginfo::FunctionDebugContext,
|
||||||
|
@ -449,7 +449,7 @@ impl<'a> Block<'a> {
|
||||||
})
|
})
|
||||||
}
|
}
|
||||||
|
|
||||||
pub fn ccx(&self) -> &'a CrateContext { self.fcx.ccx }
|
pub fn ccx(&self) -> &'a CrateContext<'a> { self.fcx.ccx }
|
||||||
pub fn tcx(&self) -> &'a ty::ctxt {
|
pub fn tcx(&self) -> &'a ty::ctxt {
|
||||||
self.fcx.ccx.tcx()
|
self.fcx.ccx.tcx()
|
||||||
}
|
}
|
||||||
|
|
|
@ -51,18 +51,40 @@ pub struct Stats {
|
||||||
pub fn_stats: RefCell<Vec<(String, uint, uint)> >,
|
pub fn_stats: RefCell<Vec<(String, uint, uint)> >,
|
||||||
}
|
}
|
||||||
|
|
||||||
pub struct CrateContext {
|
/// The shared portion of a `CrateContext`. There is one `SharedCrateContext`
|
||||||
llmod: ModuleRef,
|
/// per crate. The data here is shared between all compilation units of the
|
||||||
llcx: ContextRef,
|
/// crate, so it must not contain references to any LLVM data structures
|
||||||
|
/// (aside from metadata-related ones).
|
||||||
|
pub struct SharedCrateContext {
|
||||||
|
local_ccxs: Vec<LocalCrateContext>,
|
||||||
|
|
||||||
metadata_llmod: ModuleRef,
|
metadata_llmod: ModuleRef,
|
||||||
td: TargetData,
|
metadata_llcx: ContextRef,
|
||||||
tn: TypeNames,
|
|
||||||
externs: RefCell<ExternMap>,
|
|
||||||
item_vals: RefCell<NodeMap<ValueRef>>,
|
|
||||||
exp_map2: resolve::ExportMap2,
|
exp_map2: resolve::ExportMap2,
|
||||||
reachable: NodeSet,
|
reachable: NodeSet,
|
||||||
item_symbols: RefCell<NodeMap<String>>,
|
item_symbols: RefCell<NodeMap<String>>,
|
||||||
link_meta: LinkMeta,
|
link_meta: LinkMeta,
|
||||||
|
/// A set of static items which cannot be inlined into other crates. This
|
||||||
|
/// will prevent in IIItem() structures from being encoded into the metadata
|
||||||
|
/// that is generated
|
||||||
|
non_inlineable_statics: RefCell<NodeSet>,
|
||||||
|
symbol_hasher: RefCell<Sha256>,
|
||||||
|
tcx: ty::ctxt,
|
||||||
|
stats: Stats,
|
||||||
|
}
|
||||||
|
|
||||||
|
/// The local portion of a `CrateContext`. There is one `LocalCrateContext`
|
||||||
|
/// per compilation unit. Each one has its own LLVM `ContextRef` so that
|
||||||
|
/// several compilation units may be optimized in parallel. All other LLVM
|
||||||
|
/// data structures in the `LocalCrateContext` are tied to that `ContextRef`.
|
||||||
|
pub struct LocalCrateContext {
|
||||||
|
llmod: ModuleRef,
|
||||||
|
llcx: ContextRef,
|
||||||
|
td: TargetData,
|
||||||
|
tn: TypeNames,
|
||||||
|
externs: RefCell<ExternMap>,
|
||||||
|
item_vals: RefCell<NodeMap<ValueRef>>,
|
||||||
drop_glues: RefCell<HashMap<ty::t, ValueRef>>,
|
drop_glues: RefCell<HashMap<ty::t, ValueRef>>,
|
||||||
tydescs: RefCell<HashMap<ty::t, Rc<tydesc_info>>>,
|
tydescs: RefCell<HashMap<ty::t, Rc<tydesc_info>>>,
|
||||||
/// Set when running emit_tydescs to enforce that no more tydescs are
|
/// Set when running emit_tydescs to enforce that no more tydescs are
|
||||||
|
@ -73,10 +95,6 @@ pub struct CrateContext {
|
||||||
/// Backwards version of the `external` map (inlined items to where they
|
/// Backwards version of the `external` map (inlined items to where they
|
||||||
/// came from)
|
/// came from)
|
||||||
external_srcs: RefCell<NodeMap<ast::DefId>>,
|
external_srcs: RefCell<NodeMap<ast::DefId>>,
|
||||||
/// A set of static items which cannot be inlined into other crates. This
|
|
||||||
/// will prevent in IIItem() structures from being encoded into the metadata
|
|
||||||
/// that is generated
|
|
||||||
non_inlineable_statics: RefCell<NodeSet>,
|
|
||||||
/// Cache instances of monomorphized functions
|
/// Cache instances of monomorphized functions
|
||||||
monomorphized: RefCell<HashMap<MonoId, ValueRef>>,
|
monomorphized: RefCell<HashMap<MonoId, ValueRef>>,
|
||||||
monomorphizing: RefCell<DefIdMap<uint>>,
|
monomorphizing: RefCell<DefIdMap<uint>>,
|
||||||
|
@ -109,11 +127,8 @@ pub struct CrateContext {
|
||||||
lltypes: RefCell<HashMap<ty::t, Type>>,
|
lltypes: RefCell<HashMap<ty::t, Type>>,
|
||||||
llsizingtypes: RefCell<HashMap<ty::t, Type>>,
|
llsizingtypes: RefCell<HashMap<ty::t, Type>>,
|
||||||
adt_reprs: RefCell<HashMap<ty::t, Rc<adt::Repr>>>,
|
adt_reprs: RefCell<HashMap<ty::t, Rc<adt::Repr>>>,
|
||||||
symbol_hasher: RefCell<Sha256>,
|
|
||||||
type_hashcodes: RefCell<HashMap<ty::t, String>>,
|
type_hashcodes: RefCell<HashMap<ty::t, String>>,
|
||||||
all_llvm_symbols: RefCell<HashSet<String>>,
|
all_llvm_symbols: RefCell<HashSet<String>>,
|
||||||
tcx: ty::ctxt,
|
|
||||||
stats: Stats,
|
|
||||||
int_type: Type,
|
int_type: Type,
|
||||||
opaque_vec_type: Type,
|
opaque_vec_type: Type,
|
||||||
builder: BuilderRef_res,
|
builder: BuilderRef_res,
|
||||||
|
@ -128,86 +143,56 @@ pub struct CrateContext {
|
||||||
intrinsics: RefCell<HashMap<&'static str, ValueRef>>,
|
intrinsics: RefCell<HashMap<&'static str, ValueRef>>,
|
||||||
}
|
}
|
||||||
|
|
||||||
impl CrateContext {
|
pub struct CrateContext<'a> {
|
||||||
pub fn new(name: &str,
|
shared: &'a SharedCrateContext,
|
||||||
tcx: ty::ctxt,
|
local: &'a LocalCrateContext,
|
||||||
emap2: resolve::ExportMap2,
|
}
|
||||||
symbol_hasher: Sha256,
|
|
||||||
link_meta: LinkMeta,
|
unsafe fn create_context_and_module(sess: &Session, mod_name: &str) -> (ContextRef, ModuleRef) {
|
||||||
reachable: NodeSet)
|
|
||||||
-> CrateContext {
|
|
||||||
unsafe {
|
|
||||||
let llcx = llvm::LLVMContextCreate();
|
let llcx = llvm::LLVMContextCreate();
|
||||||
let llmod = name.with_c_str(|buf| {
|
let llmod = mod_name.with_c_str(|buf| {
|
||||||
llvm::LLVMModuleCreateWithNameInContext(buf, llcx)
|
llvm::LLVMModuleCreateWithNameInContext(buf, llcx)
|
||||||
});
|
});
|
||||||
let metadata_llmod = format!("{}_metadata", name).with_c_str(|buf| {
|
sess.targ_cfg
|
||||||
llvm::LLVMModuleCreateWithNameInContext(buf, llcx)
|
|
||||||
});
|
|
||||||
tcx.sess
|
|
||||||
.targ_cfg
|
|
||||||
.target_strs
|
.target_strs
|
||||||
.data_layout
|
.data_layout
|
||||||
.as_slice()
|
.as_slice()
|
||||||
.with_c_str(|buf| {
|
.with_c_str(|buf| {
|
||||||
llvm::LLVMSetDataLayout(llmod, buf);
|
llvm::LLVMSetDataLayout(llmod, buf);
|
||||||
llvm::LLVMSetDataLayout(metadata_llmod, buf);
|
|
||||||
});
|
});
|
||||||
tcx.sess
|
sess.targ_cfg
|
||||||
.targ_cfg
|
|
||||||
.target_strs
|
.target_strs
|
||||||
.target_triple
|
.target_triple
|
||||||
.as_slice()
|
.as_slice()
|
||||||
.with_c_str(|buf| {
|
.with_c_str(|buf| {
|
||||||
llvm::LLVMRustSetNormalizedTarget(llmod, buf);
|
llvm::LLVMRustSetNormalizedTarget(llmod, buf);
|
||||||
llvm::LLVMRustSetNormalizedTarget(metadata_llmod, buf);
|
|
||||||
});
|
});
|
||||||
|
(llcx, llmod)
|
||||||
|
}
|
||||||
|
|
||||||
let td = mk_target_data(tcx.sess
|
impl SharedCrateContext {
|
||||||
.targ_cfg
|
pub fn new(crate_name: &str,
|
||||||
.target_strs
|
local_count: uint,
|
||||||
.data_layout
|
tcx: ty::ctxt,
|
||||||
.as_slice());
|
emap2: resolve::ExportMap2,
|
||||||
|
symbol_hasher: Sha256,
|
||||||
let dbg_cx = if tcx.sess.opts.debuginfo != NoDebugInfo {
|
link_meta: LinkMeta,
|
||||||
Some(debuginfo::CrateDebugContext::new(llmod))
|
reachable: NodeSet)
|
||||||
} else {
|
-> SharedCrateContext {
|
||||||
None
|
let (metadata_llcx, metadata_llmod) = unsafe {
|
||||||
|
create_context_and_module(&tcx.sess, "metadata")
|
||||||
};
|
};
|
||||||
|
|
||||||
let mut ccx = CrateContext {
|
let mut shared_ccx = SharedCrateContext {
|
||||||
llmod: llmod,
|
local_ccxs: Vec::with_capacity(local_count),
|
||||||
llcx: llcx,
|
|
||||||
metadata_llmod: metadata_llmod,
|
metadata_llmod: metadata_llmod,
|
||||||
td: td,
|
metadata_llcx: metadata_llcx,
|
||||||
tn: TypeNames::new(),
|
|
||||||
externs: RefCell::new(HashMap::new()),
|
|
||||||
item_vals: RefCell::new(NodeMap::new()),
|
|
||||||
exp_map2: emap2,
|
exp_map2: emap2,
|
||||||
reachable: reachable,
|
reachable: reachable,
|
||||||
item_symbols: RefCell::new(NodeMap::new()),
|
item_symbols: RefCell::new(NodeMap::new()),
|
||||||
link_meta: link_meta,
|
link_meta: link_meta,
|
||||||
drop_glues: RefCell::new(HashMap::new()),
|
|
||||||
tydescs: RefCell::new(HashMap::new()),
|
|
||||||
finished_tydescs: Cell::new(false),
|
|
||||||
external: RefCell::new(DefIdMap::new()),
|
|
||||||
external_srcs: RefCell::new(NodeMap::new()),
|
|
||||||
non_inlineable_statics: RefCell::new(NodeSet::new()),
|
non_inlineable_statics: RefCell::new(NodeSet::new()),
|
||||||
monomorphized: RefCell::new(HashMap::new()),
|
|
||||||
monomorphizing: RefCell::new(DefIdMap::new()),
|
|
||||||
vtables: RefCell::new(HashMap::new()),
|
|
||||||
const_cstr_cache: RefCell::new(HashMap::new()),
|
|
||||||
const_globals: RefCell::new(HashMap::new()),
|
|
||||||
const_values: RefCell::new(NodeMap::new()),
|
|
||||||
extern_const_values: RefCell::new(DefIdMap::new()),
|
|
||||||
impl_method_cache: RefCell::new(HashMap::new()),
|
|
||||||
closure_bare_wrapper_cache: RefCell::new(HashMap::new()),
|
|
||||||
lltypes: RefCell::new(HashMap::new()),
|
|
||||||
llsizingtypes: RefCell::new(HashMap::new()),
|
|
||||||
adt_reprs: RefCell::new(HashMap::new()),
|
|
||||||
symbol_hasher: RefCell::new(symbol_hasher),
|
symbol_hasher: RefCell::new(symbol_hasher),
|
||||||
type_hashcodes: RefCell::new(HashMap::new()),
|
|
||||||
all_llvm_symbols: RefCell::new(HashSet::new()),
|
|
||||||
tcx: tcx,
|
tcx: tcx,
|
||||||
stats: Stats {
|
stats: Stats {
|
||||||
n_static_tydescs: Cell::new(0u),
|
n_static_tydescs: Cell::new(0u),
|
||||||
|
@ -222,30 +207,63 @@ impl CrateContext {
|
||||||
llvm_insns: RefCell::new(HashMap::new()),
|
llvm_insns: RefCell::new(HashMap::new()),
|
||||||
fn_stats: RefCell::new(Vec::new()),
|
fn_stats: RefCell::new(Vec::new()),
|
||||||
},
|
},
|
||||||
int_type: Type::from_ref(ptr::mut_null()),
|
|
||||||
opaque_vec_type: Type::from_ref(ptr::mut_null()),
|
|
||||||
builder: BuilderRef_res(llvm::LLVMCreateBuilderInContext(llcx)),
|
|
||||||
unboxed_closure_vals: RefCell::new(DefIdMap::new()),
|
|
||||||
dbg_cx: dbg_cx,
|
|
||||||
eh_personality: RefCell::new(None),
|
|
||||||
intrinsics: RefCell::new(HashMap::new()),
|
|
||||||
};
|
};
|
||||||
|
|
||||||
ccx.int_type = Type::int(&ccx);
|
for i in range(0, local_count) {
|
||||||
ccx.opaque_vec_type = Type::opaque_vec(&ccx);
|
// Append ".rs" to crate name as LLVM module identifier.
|
||||||
|
//
|
||||||
let mut str_slice_ty = Type::named_struct(&ccx, "str_slice");
|
// LLVM code generator emits a ".file filename" directive
|
||||||
str_slice_ty.set_struct_body([Type::i8p(&ccx), ccx.int_type()], false);
|
// for ELF backends. Value of the "filename" is set as the
|
||||||
ccx.tn().associate_type("str_slice", &str_slice_ty);
|
// LLVM module identifier. Due to a LLVM MC bug[1], LLVM
|
||||||
|
// crashes if the module identifier is same as other symbols
|
||||||
ccx.tn().associate_type("tydesc", &Type::tydesc(&ccx, str_slice_ty));
|
// such as a function name in the module.
|
||||||
|
// 1. http://llvm.org/bugs/show_bug.cgi?id=11479
|
||||||
if ccx.sess().count_llvm_insns() {
|
let llmod_id = format!("{}.{}.rs", crate_name, i);
|
||||||
base::init_insn_ctxt()
|
let local_ccx = LocalCrateContext::new(&shared_ccx, llmod_id.as_slice());
|
||||||
|
shared_ccx.local_ccxs.push(local_ccx);
|
||||||
}
|
}
|
||||||
|
|
||||||
ccx
|
shared_ccx
|
||||||
}
|
}
|
||||||
|
|
||||||
|
pub fn get_ccx<'a>(&'a self, index: uint) -> CrateContext<'a> {
|
||||||
|
CrateContext {
|
||||||
|
shared: self,
|
||||||
|
local: &self.local_ccxs[index],
|
||||||
|
}
|
||||||
|
}
|
||||||
|
|
||||||
|
|
||||||
|
pub fn metadata_llmod(&self) -> ModuleRef {
|
||||||
|
self.metadata_llmod
|
||||||
|
}
|
||||||
|
|
||||||
|
pub fn metadata_llcx(&self) -> ContextRef {
|
||||||
|
self.metadata_llcx
|
||||||
|
}
|
||||||
|
|
||||||
|
pub fn exp_map2<'a>(&'a self) -> &'a resolve::ExportMap2 {
|
||||||
|
&self.exp_map2
|
||||||
|
}
|
||||||
|
|
||||||
|
pub fn reachable<'a>(&'a self) -> &'a NodeSet {
|
||||||
|
&self.reachable
|
||||||
|
}
|
||||||
|
|
||||||
|
pub fn item_symbols<'a>(&'a self) -> &'a RefCell<NodeMap<String>> {
|
||||||
|
&self.item_symbols
|
||||||
|
}
|
||||||
|
|
||||||
|
pub fn link_meta<'a>(&'a self) -> &'a LinkMeta {
|
||||||
|
&self.link_meta
|
||||||
|
}
|
||||||
|
|
||||||
|
pub fn non_inlineable_statics<'a>(&'a self) -> &'a RefCell<NodeSet> {
|
||||||
|
&self.non_inlineable_statics
|
||||||
|
}
|
||||||
|
|
||||||
|
pub fn symbol_hasher<'a>(&'a self) -> &'a RefCell<Sha256> {
|
||||||
|
&self.symbol_hasher
|
||||||
}
|
}
|
||||||
|
|
||||||
pub fn tcx<'a>(&'a self) -> &'a ty::ctxt {
|
pub fn tcx<'a>(&'a self) -> &'a ty::ctxt {
|
||||||
|
@ -260,20 +278,137 @@ impl CrateContext {
|
||||||
&self.tcx.sess
|
&self.tcx.sess
|
||||||
}
|
}
|
||||||
|
|
||||||
|
pub fn stats<'a>(&'a self) -> &'a Stats {
|
||||||
|
&self.stats
|
||||||
|
}
|
||||||
|
}
|
||||||
|
|
||||||
|
impl LocalCrateContext {
|
||||||
|
fn new(shared: &SharedCrateContext,
|
||||||
|
name: &str)
|
||||||
|
-> LocalCrateContext {
|
||||||
|
unsafe {
|
||||||
|
let (llcx, llmod) = create_context_and_module(&shared.tcx.sess, name);
|
||||||
|
|
||||||
|
let td = mk_target_data(shared.tcx
|
||||||
|
.sess
|
||||||
|
.targ_cfg
|
||||||
|
.target_strs
|
||||||
|
.data_layout
|
||||||
|
.as_slice());
|
||||||
|
|
||||||
|
let dbg_cx = if shared.tcx.sess.opts.debuginfo != NoDebugInfo {
|
||||||
|
Some(debuginfo::CrateDebugContext::new(llmod))
|
||||||
|
} else {
|
||||||
|
None
|
||||||
|
};
|
||||||
|
|
||||||
|
let mut local_ccx = LocalCrateContext {
|
||||||
|
llmod: llmod,
|
||||||
|
llcx: llcx,
|
||||||
|
td: td,
|
||||||
|
tn: TypeNames::new(),
|
||||||
|
externs: RefCell::new(HashMap::new()),
|
||||||
|
item_vals: RefCell::new(NodeMap::new()),
|
||||||
|
drop_glues: RefCell::new(HashMap::new()),
|
||||||
|
tydescs: RefCell::new(HashMap::new()),
|
||||||
|
finished_tydescs: Cell::new(false),
|
||||||
|
external: RefCell::new(DefIdMap::new()),
|
||||||
|
external_srcs: RefCell::new(NodeMap::new()),
|
||||||
|
monomorphized: RefCell::new(HashMap::new()),
|
||||||
|
monomorphizing: RefCell::new(DefIdMap::new()),
|
||||||
|
vtables: RefCell::new(HashMap::new()),
|
||||||
|
const_cstr_cache: RefCell::new(HashMap::new()),
|
||||||
|
const_globals: RefCell::new(HashMap::new()),
|
||||||
|
const_values: RefCell::new(NodeMap::new()),
|
||||||
|
extern_const_values: RefCell::new(DefIdMap::new()),
|
||||||
|
impl_method_cache: RefCell::new(HashMap::new()),
|
||||||
|
closure_bare_wrapper_cache: RefCell::new(HashMap::new()),
|
||||||
|
lltypes: RefCell::new(HashMap::new()),
|
||||||
|
llsizingtypes: RefCell::new(HashMap::new()),
|
||||||
|
adt_reprs: RefCell::new(HashMap::new()),
|
||||||
|
type_hashcodes: RefCell::new(HashMap::new()),
|
||||||
|
all_llvm_symbols: RefCell::new(HashSet::new()),
|
||||||
|
int_type: Type::from_ref(ptr::mut_null()),
|
||||||
|
opaque_vec_type: Type::from_ref(ptr::mut_null()),
|
||||||
|
builder: BuilderRef_res(llvm::LLVMCreateBuilderInContext(llcx)),
|
||||||
|
unboxed_closure_vals: RefCell::new(DefIdMap::new()),
|
||||||
|
dbg_cx: dbg_cx,
|
||||||
|
eh_personality: RefCell::new(None),
|
||||||
|
intrinsics: RefCell::new(HashMap::new()),
|
||||||
|
};
|
||||||
|
|
||||||
|
local_ccx.int_type = Type::int(&local_ccx.dummy_ccx(shared));
|
||||||
|
local_ccx.opaque_vec_type = Type::opaque_vec(&local_ccx.dummy_ccx(shared));
|
||||||
|
|
||||||
|
// Done mutating local_ccx directly. (The rest of the
|
||||||
|
// initialization goes through RefCell.)
|
||||||
|
{
|
||||||
|
let ccx = local_ccx.dummy_ccx(shared);
|
||||||
|
|
||||||
|
let mut str_slice_ty = Type::named_struct(&ccx, "str_slice");
|
||||||
|
str_slice_ty.set_struct_body([Type::i8p(&ccx), ccx.int_type()], false);
|
||||||
|
ccx.tn().associate_type("str_slice", &str_slice_ty);
|
||||||
|
|
||||||
|
ccx.tn().associate_type("tydesc", &Type::tydesc(&ccx, str_slice_ty));
|
||||||
|
|
||||||
|
if ccx.sess().count_llvm_insns() {
|
||||||
|
base::init_insn_ctxt()
|
||||||
|
}
|
||||||
|
}
|
||||||
|
|
||||||
|
local_ccx
|
||||||
|
}
|
||||||
|
}
|
||||||
|
|
||||||
|
/// Create a dummy `CrateContext` from `self` and the provided
|
||||||
|
/// `SharedCrateContext`. This is somewhat dangerous because `self` may
|
||||||
|
/// not actually be an element of `shared.local_ccxs`, which can cause some
|
||||||
|
/// operations to `fail` unexpectedly.
|
||||||
|
///
|
||||||
|
/// This is used in the `LocalCrateContext` constructor to allow calling
|
||||||
|
/// functions that expect a complete `CrateContext`, even before the local
|
||||||
|
/// portion is fully initialized and attached to the `SharedCrateContext`.
|
||||||
|
fn dummy_ccx<'a>(&'a self, shared: &'a SharedCrateContext) -> CrateContext<'a> {
|
||||||
|
CrateContext {
|
||||||
|
shared: shared,
|
||||||
|
local: self,
|
||||||
|
}
|
||||||
|
}
|
||||||
|
}
|
||||||
|
|
||||||
|
impl<'b> CrateContext<'b> {
|
||||||
|
pub fn shared(&self) -> &'b SharedCrateContext {
|
||||||
|
self.shared
|
||||||
|
}
|
||||||
|
|
||||||
|
pub fn local(&self) -> &'b LocalCrateContext {
|
||||||
|
self.local
|
||||||
|
}
|
||||||
|
|
||||||
|
|
||||||
|
pub fn tcx<'a>(&'a self) -> &'a ty::ctxt {
|
||||||
|
&self.shared.tcx
|
||||||
|
}
|
||||||
|
|
||||||
|
pub fn sess<'a>(&'a self) -> &'a Session {
|
||||||
|
&self.shared.tcx.sess
|
||||||
|
}
|
||||||
|
|
||||||
pub fn builder<'a>(&'a self) -> Builder<'a> {
|
pub fn builder<'a>(&'a self) -> Builder<'a> {
|
||||||
Builder::new(self)
|
Builder::new(self)
|
||||||
}
|
}
|
||||||
|
|
||||||
pub fn raw_builder<'a>(&'a self) -> BuilderRef {
|
pub fn raw_builder<'a>(&'a self) -> BuilderRef {
|
||||||
self.builder.b
|
self.local.builder.b
|
||||||
}
|
}
|
||||||
|
|
||||||
pub fn tydesc_type(&self) -> Type {
|
pub fn tydesc_type(&self) -> Type {
|
||||||
self.tn.find_type("tydesc").unwrap()
|
self.local.tn.find_type("tydesc").unwrap()
|
||||||
}
|
}
|
||||||
|
|
||||||
pub fn get_intrinsic(&self, key: & &'static str) -> ValueRef {
|
pub fn get_intrinsic(&self, key: & &'static str) -> ValueRef {
|
||||||
match self.intrinsics.borrow().find_copy(key) {
|
match self.intrinsics().borrow().find_copy(key) {
|
||||||
Some(v) => return v,
|
Some(v) => return v,
|
||||||
_ => {}
|
_ => {}
|
||||||
}
|
}
|
||||||
|
@ -297,160 +432,164 @@ impl CrateContext {
|
||||||
|
|
||||||
|
|
||||||
pub fn llmod(&self) -> ModuleRef {
|
pub fn llmod(&self) -> ModuleRef {
|
||||||
self.llmod
|
self.local.llmod
|
||||||
}
|
}
|
||||||
|
|
||||||
pub fn llcx(&self) -> ContextRef {
|
pub fn llcx(&self) -> ContextRef {
|
||||||
self.llcx
|
self.local.llcx
|
||||||
}
|
}
|
||||||
|
|
||||||
pub fn metadata_llmod(&self) -> ModuleRef {
|
pub fn metadata_llmod(&self) -> ModuleRef {
|
||||||
self.metadata_llmod
|
self.shared.metadata_llmod
|
||||||
|
}
|
||||||
|
|
||||||
|
pub fn metadata_llcx(&self) -> ContextRef {
|
||||||
|
self.shared.metadata_llcx
|
||||||
}
|
}
|
||||||
|
|
||||||
pub fn td<'a>(&'a self) -> &'a TargetData {
|
pub fn td<'a>(&'a self) -> &'a TargetData {
|
||||||
&self.td
|
&self.local.td
|
||||||
}
|
}
|
||||||
|
|
||||||
pub fn tn<'a>(&'a self) -> &'a TypeNames {
|
pub fn tn<'a>(&'a self) -> &'a TypeNames {
|
||||||
&self.tn
|
&self.local.tn
|
||||||
}
|
}
|
||||||
|
|
||||||
pub fn externs<'a>(&'a self) -> &'a RefCell<ExternMap> {
|
pub fn externs<'a>(&'a self) -> &'a RefCell<ExternMap> {
|
||||||
&self.externs
|
&self.local.externs
|
||||||
}
|
}
|
||||||
|
|
||||||
pub fn item_vals<'a>(&'a self) -> &'a RefCell<NodeMap<ValueRef>> {
|
pub fn item_vals<'a>(&'a self) -> &'a RefCell<NodeMap<ValueRef>> {
|
||||||
&self.item_vals
|
&self.local.item_vals
|
||||||
}
|
}
|
||||||
|
|
||||||
pub fn exp_map2<'a>(&'a self) -> &'a resolve::ExportMap2 {
|
pub fn exp_map2<'a>(&'a self) -> &'a resolve::ExportMap2 {
|
||||||
&self.exp_map2
|
&self.shared.exp_map2
|
||||||
}
|
}
|
||||||
|
|
||||||
pub fn reachable<'a>(&'a self) -> &'a NodeSet {
|
pub fn reachable<'a>(&'a self) -> &'a NodeSet {
|
||||||
&self.reachable
|
&self.shared.reachable
|
||||||
}
|
}
|
||||||
|
|
||||||
pub fn item_symbols<'a>(&'a self) -> &'a RefCell<NodeMap<String>> {
|
pub fn item_symbols<'a>(&'a self) -> &'a RefCell<NodeMap<String>> {
|
||||||
&self.item_symbols
|
&self.shared.item_symbols
|
||||||
}
|
}
|
||||||
|
|
||||||
pub fn link_meta<'a>(&'a self) -> &'a LinkMeta {
|
pub fn link_meta<'a>(&'a self) -> &'a LinkMeta {
|
||||||
&self.link_meta
|
&self.shared.link_meta
|
||||||
}
|
}
|
||||||
|
|
||||||
pub fn drop_glues<'a>(&'a self) -> &'a RefCell<HashMap<ty::t, ValueRef>> {
|
pub fn drop_glues<'a>(&'a self) -> &'a RefCell<HashMap<ty::t, ValueRef>> {
|
||||||
&self.drop_glues
|
&self.local.drop_glues
|
||||||
}
|
}
|
||||||
|
|
||||||
pub fn tydescs<'a>(&'a self) -> &'a RefCell<HashMap<ty::t, Rc<tydesc_info>>> {
|
pub fn tydescs<'a>(&'a self) -> &'a RefCell<HashMap<ty::t, Rc<tydesc_info>>> {
|
||||||
&self.tydescs
|
&self.local.tydescs
|
||||||
}
|
}
|
||||||
|
|
||||||
pub fn finished_tydescs<'a>(&'a self) -> &'a Cell<bool> {
|
pub fn finished_tydescs<'a>(&'a self) -> &'a Cell<bool> {
|
||||||
&self.finished_tydescs
|
&self.local.finished_tydescs
|
||||||
}
|
}
|
||||||
|
|
||||||
pub fn external<'a>(&'a self) -> &'a RefCell<DefIdMap<Option<ast::NodeId>>> {
|
pub fn external<'a>(&'a self) -> &'a RefCell<DefIdMap<Option<ast::NodeId>>> {
|
||||||
&self.external
|
&self.local.external
|
||||||
}
|
}
|
||||||
|
|
||||||
pub fn external_srcs<'a>(&'a self) -> &'a RefCell<NodeMap<ast::DefId>> {
|
pub fn external_srcs<'a>(&'a self) -> &'a RefCell<NodeMap<ast::DefId>> {
|
||||||
&self.external_srcs
|
&self.local.external_srcs
|
||||||
}
|
}
|
||||||
|
|
||||||
pub fn non_inlineable_statics<'a>(&'a self) -> &'a RefCell<NodeSet> {
|
pub fn non_inlineable_statics<'a>(&'a self) -> &'a RefCell<NodeSet> {
|
||||||
&self.non_inlineable_statics
|
&self.shared.non_inlineable_statics
|
||||||
}
|
}
|
||||||
|
|
||||||
pub fn monomorphized<'a>(&'a self) -> &'a RefCell<HashMap<MonoId, ValueRef>> {
|
pub fn monomorphized<'a>(&'a self) -> &'a RefCell<HashMap<MonoId, ValueRef>> {
|
||||||
&self.monomorphized
|
&self.local.monomorphized
|
||||||
}
|
}
|
||||||
|
|
||||||
pub fn monomorphizing<'a>(&'a self) -> &'a RefCell<DefIdMap<uint>> {
|
pub fn monomorphizing<'a>(&'a self) -> &'a RefCell<DefIdMap<uint>> {
|
||||||
&self.monomorphizing
|
&self.local.monomorphizing
|
||||||
}
|
}
|
||||||
|
|
||||||
pub fn vtables<'a>(&'a self) -> &'a RefCell<HashMap<(ty::t, MonoId), ValueRef>> {
|
pub fn vtables<'a>(&'a self) -> &'a RefCell<HashMap<(ty::t, MonoId), ValueRef>> {
|
||||||
&self.vtables
|
&self.local.vtables
|
||||||
}
|
}
|
||||||
|
|
||||||
pub fn const_cstr_cache<'a>(&'a self) -> &'a RefCell<HashMap<InternedString, ValueRef>> {
|
pub fn const_cstr_cache<'a>(&'a self) -> &'a RefCell<HashMap<InternedString, ValueRef>> {
|
||||||
&self.const_cstr_cache
|
&self.local.const_cstr_cache
|
||||||
}
|
}
|
||||||
|
|
||||||
pub fn const_globals<'a>(&'a self) -> &'a RefCell<HashMap<int, ValueRef>> {
|
pub fn const_globals<'a>(&'a self) -> &'a RefCell<HashMap<int, ValueRef>> {
|
||||||
&self.const_globals
|
&self.local.const_globals
|
||||||
}
|
}
|
||||||
|
|
||||||
pub fn const_values<'a>(&'a self) -> &'a RefCell<NodeMap<ValueRef>> {
|
pub fn const_values<'a>(&'a self) -> &'a RefCell<NodeMap<ValueRef>> {
|
||||||
&self.const_values
|
&self.local.const_values
|
||||||
}
|
}
|
||||||
|
|
||||||
pub fn extern_const_values<'a>(&'a self) -> &'a RefCell<DefIdMap<ValueRef>> {
|
pub fn extern_const_values<'a>(&'a self) -> &'a RefCell<DefIdMap<ValueRef>> {
|
||||||
&self.extern_const_values
|
&self.local.extern_const_values
|
||||||
}
|
}
|
||||||
|
|
||||||
pub fn impl_method_cache<'a>(&'a self)
|
pub fn impl_method_cache<'a>(&'a self)
|
||||||
-> &'a RefCell<HashMap<(ast::DefId, ast::Name), ast::DefId>> {
|
-> &'a RefCell<HashMap<(ast::DefId, ast::Name), ast::DefId>> {
|
||||||
&self.impl_method_cache
|
&self.local.impl_method_cache
|
||||||
}
|
}
|
||||||
|
|
||||||
pub fn closure_bare_wrapper_cache<'a>(&'a self) -> &'a RefCell<HashMap<ValueRef, ValueRef>> {
|
pub fn closure_bare_wrapper_cache<'a>(&'a self) -> &'a RefCell<HashMap<ValueRef, ValueRef>> {
|
||||||
&self.closure_bare_wrapper_cache
|
&self.local.closure_bare_wrapper_cache
|
||||||
}
|
}
|
||||||
|
|
||||||
pub fn lltypes<'a>(&'a self) -> &'a RefCell<HashMap<ty::t, Type>> {
|
pub fn lltypes<'a>(&'a self) -> &'a RefCell<HashMap<ty::t, Type>> {
|
||||||
&self.lltypes
|
&self.local.lltypes
|
||||||
}
|
}
|
||||||
|
|
||||||
pub fn llsizingtypes<'a>(&'a self) -> &'a RefCell<HashMap<ty::t, Type>> {
|
pub fn llsizingtypes<'a>(&'a self) -> &'a RefCell<HashMap<ty::t, Type>> {
|
||||||
&self.llsizingtypes
|
&self.local.llsizingtypes
|
||||||
}
|
}
|
||||||
|
|
||||||
pub fn adt_reprs<'a>(&'a self) -> &'a RefCell<HashMap<ty::t, Rc<adt::Repr>>> {
|
pub fn adt_reprs<'a>(&'a self) -> &'a RefCell<HashMap<ty::t, Rc<adt::Repr>>> {
|
||||||
&self.adt_reprs
|
&self.local.adt_reprs
|
||||||
}
|
}
|
||||||
|
|
||||||
pub fn symbol_hasher<'a>(&'a self) -> &'a RefCell<Sha256> {
|
pub fn symbol_hasher<'a>(&'a self) -> &'a RefCell<Sha256> {
|
||||||
&self.symbol_hasher
|
&self.shared.symbol_hasher
|
||||||
}
|
}
|
||||||
|
|
||||||
pub fn type_hashcodes<'a>(&'a self) -> &'a RefCell<HashMap<ty::t, String>> {
|
pub fn type_hashcodes<'a>(&'a self) -> &'a RefCell<HashMap<ty::t, String>> {
|
||||||
&self.type_hashcodes
|
&self.local.type_hashcodes
|
||||||
}
|
}
|
||||||
|
|
||||||
pub fn all_llvm_symbols<'a>(&'a self) -> &'a RefCell<HashSet<String>> {
|
pub fn all_llvm_symbols<'a>(&'a self) -> &'a RefCell<HashSet<String>> {
|
||||||
&self.all_llvm_symbols
|
&self.local.all_llvm_symbols
|
||||||
}
|
}
|
||||||
|
|
||||||
pub fn stats<'a>(&'a self) -> &'a Stats {
|
pub fn stats<'a>(&'a self) -> &'a Stats {
|
||||||
&self.stats
|
&self.shared.stats
|
||||||
}
|
}
|
||||||
|
|
||||||
pub fn int_type(&self) -> Type {
|
pub fn int_type(&self) -> Type {
|
||||||
self.int_type
|
self.local.int_type
|
||||||
}
|
}
|
||||||
|
|
||||||
pub fn opaque_vec_type(&self) -> Type {
|
pub fn opaque_vec_type(&self) -> Type {
|
||||||
self.opaque_vec_type
|
self.local.opaque_vec_type
|
||||||
}
|
}
|
||||||
|
|
||||||
pub fn unboxed_closure_vals<'a>(&'a self) -> &'a RefCell<DefIdMap<ValueRef>> {
|
pub fn unboxed_closure_vals<'a>(&'a self) -> &'a RefCell<DefIdMap<ValueRef>> {
|
||||||
&self.unboxed_closure_vals
|
&self.local.unboxed_closure_vals
|
||||||
}
|
}
|
||||||
|
|
||||||
pub fn dbg_cx<'a>(&'a self) -> &'a Option<debuginfo::CrateDebugContext> {
|
pub fn dbg_cx<'a>(&'a self) -> &'a Option<debuginfo::CrateDebugContext> {
|
||||||
&self.dbg_cx
|
&self.local.dbg_cx
|
||||||
}
|
}
|
||||||
|
|
||||||
pub fn eh_personality<'a>(&'a self) -> &'a RefCell<Option<ValueRef>> {
|
pub fn eh_personality<'a>(&'a self) -> &'a RefCell<Option<ValueRef>> {
|
||||||
&self.eh_personality
|
&self.local.eh_personality
|
||||||
}
|
}
|
||||||
|
|
||||||
fn intrinsics<'a>(&'a self) -> &'a RefCell<HashMap<&'static str, ValueRef>> {
|
fn intrinsics<'a>(&'a self) -> &'a RefCell<HashMap<&'static str, ValueRef>> {
|
||||||
&self.intrinsics
|
&self.local.intrinsics
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
|
|
||||||
|
|
Loading…
Reference in New Issue