rustc_trans: collapse {Local,Shared}CrateContext.
This commit is contained in:
parent
b762c2d9dd
commit
d0d13204a6
12 changed files with 113 additions and 243 deletions
|
@ -57,9 +57,9 @@ use builder::Builder;
|
|||
use callee;
|
||||
use common::{C_bool, C_bytes_in_context, C_i32, C_usize};
|
||||
use rustc_mir::monomorphize::collector::{self, MonoItemCollectionMode};
|
||||
use common::{self, C_struct_in_context, C_array, CrateContext, val_ty};
|
||||
use common::{self, C_struct_in_context, C_array, val_ty};
|
||||
use consts;
|
||||
use context::{self, LocalCrateContext, SharedCrateContext};
|
||||
use context::{self, CrateContext};
|
||||
use debuginfo;
|
||||
use declare;
|
||||
use meth;
|
||||
|
@ -232,13 +232,13 @@ pub fn unsize_thin_ptr<'a, 'tcx>(
|
|||
&ty::TyRawPtr(ty::TypeAndMut { ty: b, .. })) |
|
||||
(&ty::TyRawPtr(ty::TypeAndMut { ty: a, .. }),
|
||||
&ty::TyRawPtr(ty::TypeAndMut { ty: b, .. })) => {
|
||||
assert!(bcx.ccx.shared().type_is_sized(a));
|
||||
assert!(bcx.ccx.type_is_sized(a));
|
||||
let ptr_ty = bcx.ccx.layout_of(b).llvm_type(bcx.ccx).ptr_to();
|
||||
(bcx.pointercast(src, ptr_ty), unsized_info(bcx.ccx, a, b, None))
|
||||
}
|
||||
(&ty::TyAdt(def_a, _), &ty::TyAdt(def_b, _)) if def_a.is_box() && def_b.is_box() => {
|
||||
let (a, b) = (src_ty.boxed_ty(), dst_ty.boxed_ty());
|
||||
assert!(bcx.ccx.shared().type_is_sized(a));
|
||||
assert!(bcx.ccx.type_is_sized(a));
|
||||
let ptr_ty = bcx.ccx.layout_of(b).llvm_type(bcx.ccx).ptr_to();
|
||||
(bcx.pointercast(src, ptr_ty), unsized_info(bcx.ccx, a, b, None))
|
||||
}
|
||||
|
@ -721,7 +721,6 @@ pub fn trans_crate<'a, 'tcx>(tcx: TyCtxt<'a, 'tcx, 'tcx>,
|
|||
let link_meta = link::build_link_meta(crate_hash);
|
||||
let exported_symbol_node_ids = find_exported_symbols(tcx);
|
||||
|
||||
let shared_ccx = SharedCrateContext::new(tcx);
|
||||
// Translate the metadata.
|
||||
let llmod_id = "metadata";
|
||||
let (metadata_llcx, metadata_llmod, metadata) =
|
||||
|
@ -770,7 +769,7 @@ pub fn trans_crate<'a, 'tcx>(tcx: TyCtxt<'a, 'tcx, 'tcx>,
|
|||
// Run the translation item collector and partition the collected items into
|
||||
// codegen units.
|
||||
let codegen_units =
|
||||
shared_ccx.tcx().collect_and_partition_translation_items(LOCAL_CRATE).1;
|
||||
tcx.collect_and_partition_translation_items(LOCAL_CRATE).1;
|
||||
let codegen_units = (*codegen_units).clone();
|
||||
|
||||
// Force all codegen_unit queries so they are already either red or green
|
||||
|
@ -910,7 +909,7 @@ pub fn trans_crate<'a, 'tcx>(tcx: TyCtxt<'a, 'tcx, 'tcx>,
|
|||
|
||||
symbol_names_test::report_symbol_names(tcx);
|
||||
|
||||
if shared_ccx.sess().trans_stats() {
|
||||
if tcx.sess.trans_stats() {
|
||||
println!("--- trans stats ---");
|
||||
println!("n_glues_created: {}", all_stats.n_glues_created);
|
||||
println!("n_null_glues: {}", all_stats.n_null_glues);
|
||||
|
@ -926,7 +925,7 @@ pub fn trans_crate<'a, 'tcx>(tcx: TyCtxt<'a, 'tcx, 'tcx>,
|
|||
}
|
||||
}
|
||||
|
||||
if shared_ccx.sess().count_llvm_insns() {
|
||||
if tcx.sess.count_llvm_insns() {
|
||||
for (k, v) in all_stats.llvm_insns.iter() {
|
||||
println!("{:7} {}", *v, *k);
|
||||
}
|
||||
|
@ -1204,10 +1203,8 @@ fn compile_codegen_unit<'a, 'tcx>(tcx: TyCtxt<'a, 'tcx, 'tcx>,
|
|||
.to_fingerprint().to_hex());
|
||||
|
||||
// Instantiate translation items without filling out definitions yet...
|
||||
let scx = SharedCrateContext::new(tcx);
|
||||
let lcx = LocalCrateContext::new(&scx, cgu, &llmod_id);
|
||||
let ccx = CrateContext::new(tcx, cgu, &llmod_id);
|
||||
let module = {
|
||||
let ccx = CrateContext::new(&scx, &lcx);
|
||||
let trans_items = ccx.codegen_unit()
|
||||
.items_in_deterministic_order(ccx.tcx());
|
||||
for &(trans_item, (linkage, visibility)) in &trans_items {
|
||||
|
@ -1268,7 +1265,7 @@ fn compile_codegen_unit<'a, 'tcx>(tcx: TyCtxt<'a, 'tcx, 'tcx>,
|
|||
}
|
||||
};
|
||||
|
||||
(lcx.into_stats(), module)
|
||||
(ccx.into_stats(), module)
|
||||
}
|
||||
}
|
||||
|
||||
|
|
|
@ -38,7 +38,7 @@ use syntax::abi::Abi;
|
|||
use syntax::symbol::InternedString;
|
||||
use syntax_pos::{Span, DUMMY_SP};
|
||||
|
||||
pub use context::{CrateContext, SharedCrateContext};
|
||||
pub use context::CrateContext;
|
||||
|
||||
pub fn type_needs_drop<'a, 'tcx>(tcx: TyCtxt<'a, 'tcx, 'tcx>, ty: Ty<'tcx>) -> bool {
|
||||
ty.needs_drop(tcx, ty::ParamEnv::empty(traits::Reveal::All))
|
||||
|
|
|
@ -299,7 +299,7 @@ pub fn trans_static<'a, 'tcx>(ccx: &CrateContext<'a, 'tcx>,
|
|||
// As an optimization, all shared statics which do not have interior
|
||||
// mutability are placed into read-only memory.
|
||||
if m != hir::MutMutable {
|
||||
if ccx.shared().type_is_freeze(ty) {
|
||||
if ccx.type_is_freeze(ty) {
|
||||
llvm::LLVMSetGlobalConstant(g, llvm::True);
|
||||
}
|
||||
}
|
||||
|
|
|
@ -11,10 +11,9 @@
|
|||
use common;
|
||||
use llvm;
|
||||
use llvm::{ContextRef, ModuleRef, ValueRef};
|
||||
use rustc::dep_graph::{DepGraph, DepGraphSafe};
|
||||
use rustc::dep_graph::DepGraphSafe;
|
||||
use rustc::hir;
|
||||
use rustc::hir::def_id::DefId;
|
||||
use rustc::ich::StableHashingContext;
|
||||
use rustc::traits;
|
||||
use debuginfo;
|
||||
use callee;
|
||||
|
@ -28,7 +27,6 @@ use type_of::PointeeInfo;
|
|||
|
||||
use rustc_data_structures::base_n;
|
||||
use rustc::mir::mono::Stats;
|
||||
use rustc_data_structures::stable_hasher::StableHashingContextProvider;
|
||||
use rustc::session::config::{self, NoDebugInfo};
|
||||
use rustc::session::Session;
|
||||
use rustc::ty::layout::{LayoutError, LayoutOf, Size, TyLayout};
|
||||
|
@ -41,26 +39,18 @@ use std::ptr;
|
|||
use std::iter;
|
||||
use std::str;
|
||||
use std::sync::Arc;
|
||||
use std::marker::PhantomData;
|
||||
use syntax::symbol::InternedString;
|
||||
use abi::Abi;
|
||||
|
||||
/// The shared portion of a `CrateContext`. There is one `SharedCrateContext`
|
||||
/// per crate. The data here is shared between all compilation units of the
|
||||
/// crate, so it must not contain references to any LLVM data structures
|
||||
/// (aside from metadata-related ones).
|
||||
pub struct SharedCrateContext<'a, 'tcx: 'a> {
|
||||
/// There is one `CrateContext` 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 `CrateContext` are tied to that `ContextRef`.
|
||||
pub struct CrateContext<'a, 'tcx: 'a> {
|
||||
tcx: TyCtxt<'a, 'tcx, 'tcx>,
|
||||
check_overflow: bool,
|
||||
use_dll_storage_attrs: bool,
|
||||
tls_model: llvm::ThreadLocalMode,
|
||||
}
|
||||
|
||||
/// 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<'a, 'tcx: 'a> {
|
||||
llmod: ModuleRef,
|
||||
llcx: ContextRef,
|
||||
stats: RefCell<Stats>,
|
||||
|
@ -115,41 +105,11 @@ pub struct LocalCrateContext<'a, 'tcx: 'a> {
|
|||
|
||||
/// A counter that is used for generating local symbol names
|
||||
local_gen_sym_counter: Cell<usize>,
|
||||
|
||||
/// A placeholder so we can add lifetimes
|
||||
placeholder: PhantomData<&'a ()>,
|
||||
}
|
||||
|
||||
/// A CrateContext value binds together one LocalCrateContext with the
|
||||
/// SharedCrateContext. It exists as a convenience wrapper, so we don't have to
|
||||
/// pass around (SharedCrateContext, LocalCrateContext) tuples all over trans.
|
||||
pub struct CrateContext<'a, 'tcx: 'a> {
|
||||
shared: &'a SharedCrateContext<'a, 'tcx>,
|
||||
local_ccx: &'a LocalCrateContext<'a, 'tcx>,
|
||||
}
|
||||
|
||||
impl<'a, 'tcx> CrateContext<'a, 'tcx> {
|
||||
pub fn new(shared: &'a SharedCrateContext<'a, 'tcx>,
|
||||
local_ccx: &'a LocalCrateContext<'a, 'tcx>)
|
||||
-> Self {
|
||||
CrateContext { shared, local_ccx }
|
||||
}
|
||||
}
|
||||
|
||||
impl<'a, 'tcx> DepGraphSafe for CrateContext<'a, 'tcx> {
|
||||
}
|
||||
|
||||
impl<'a, 'tcx> DepGraphSafe for SharedCrateContext<'a, 'tcx> {
|
||||
}
|
||||
|
||||
impl<'a, 'tcx> StableHashingContextProvider for SharedCrateContext<'a, 'tcx> {
|
||||
type ContextType = StableHashingContext<'tcx>;
|
||||
|
||||
fn create_stable_hashing_context(&self) -> Self::ContextType {
|
||||
self.tcx.create_stable_hashing_context()
|
||||
}
|
||||
}
|
||||
|
||||
pub fn get_reloc_model(sess: &Session) -> llvm::RelocMode {
|
||||
let reloc_model_arg = match sess.opts.cg.relocation_model {
|
||||
Some(ref s) => &s[..],
|
||||
|
@ -252,8 +212,11 @@ pub unsafe fn create_context_and_module(sess: &Session, mod_name: &str) -> (Cont
|
|||
(llcx, llmod)
|
||||
}
|
||||
|
||||
impl<'b, 'tcx> SharedCrateContext<'b, 'tcx> {
|
||||
pub fn new(tcx: TyCtxt<'b, 'tcx, 'tcx>) -> SharedCrateContext<'b, 'tcx> {
|
||||
impl<'a, 'tcx> CrateContext<'a, 'tcx> {
|
||||
pub fn new(tcx: TyCtxt<'a, 'tcx, 'tcx>,
|
||||
codegen_unit: Arc<CodegenUnit<'tcx>>,
|
||||
llmod_id: &str)
|
||||
-> CrateContext<'a, 'tcx> {
|
||||
// An interesting part of Windows which MSVC forces our hand on (and
|
||||
// apparently MinGW didn't) is the usage of `dllimport` and `dllexport`
|
||||
// attributes in LLVM IR as well as native dependencies (in C these
|
||||
|
@ -303,78 +266,25 @@ impl<'b, 'tcx> SharedCrateContext<'b, 'tcx> {
|
|||
|
||||
let tls_model = get_tls_model(&tcx.sess);
|
||||
|
||||
SharedCrateContext {
|
||||
tcx,
|
||||
check_overflow,
|
||||
use_dll_storage_attrs,
|
||||
tls_model,
|
||||
}
|
||||
}
|
||||
|
||||
pub fn type_needs_drop(&self, ty: Ty<'tcx>) -> bool {
|
||||
common::type_needs_drop(self.tcx, ty)
|
||||
}
|
||||
|
||||
pub fn type_is_sized(&self, ty: Ty<'tcx>) -> bool {
|
||||
common::type_is_sized(self.tcx, ty)
|
||||
}
|
||||
|
||||
pub fn type_is_freeze(&self, ty: Ty<'tcx>) -> bool {
|
||||
common::type_is_freeze(self.tcx, ty)
|
||||
}
|
||||
|
||||
pub fn type_has_metadata(&self, ty: Ty<'tcx>) -> bool {
|
||||
use syntax_pos::DUMMY_SP;
|
||||
if ty.is_sized(self.tcx, ty::ParamEnv::empty(traits::Reveal::All), DUMMY_SP) {
|
||||
return false;
|
||||
}
|
||||
|
||||
let tail = self.tcx.struct_tail(ty);
|
||||
match tail.sty {
|
||||
ty::TyForeign(..) => false,
|
||||
ty::TyStr | ty::TySlice(..) | ty::TyDynamic(..) => true,
|
||||
_ => bug!("unexpected unsized tail: {:?}", tail.sty),
|
||||
}
|
||||
}
|
||||
|
||||
pub fn tcx(&self) -> TyCtxt<'b, 'tcx, 'tcx> {
|
||||
self.tcx
|
||||
}
|
||||
|
||||
pub fn sess<'a>(&'a self) -> &'a Session {
|
||||
&self.tcx.sess
|
||||
}
|
||||
|
||||
pub fn dep_graph<'a>(&'a self) -> &'a DepGraph {
|
||||
&self.tcx.dep_graph
|
||||
}
|
||||
|
||||
pub fn use_dll_storage_attrs(&self) -> bool {
|
||||
self.use_dll_storage_attrs
|
||||
}
|
||||
}
|
||||
|
||||
impl<'a, 'tcx> LocalCrateContext<'a, 'tcx> {
|
||||
pub fn new(shared: &SharedCrateContext<'a, 'tcx>,
|
||||
codegen_unit: Arc<CodegenUnit<'tcx>>,
|
||||
llmod_id: &str)
|
||||
-> LocalCrateContext<'a, 'tcx> {
|
||||
unsafe {
|
||||
let (llcx, llmod) = create_context_and_module(&shared.tcx.sess,
|
||||
let (llcx, llmod) = create_context_and_module(&tcx.sess,
|
||||
&llmod_id[..]);
|
||||
|
||||
let dbg_cx = if shared.tcx.sess.opts.debuginfo != NoDebugInfo {
|
||||
let dbg_cx = if tcx.sess.opts.debuginfo != NoDebugInfo {
|
||||
let dctx = debuginfo::CrateDebugContext::new(llmod);
|
||||
debuginfo::metadata::compile_unit_metadata(shared,
|
||||
debuginfo::metadata::compile_unit_metadata(tcx,
|
||||
codegen_unit.name(),
|
||||
&dctx,
|
||||
shared.tcx.sess);
|
||||
&dctx);
|
||||
Some(dctx)
|
||||
} else {
|
||||
None
|
||||
};
|
||||
|
||||
let local_ccx = LocalCrateContext {
|
||||
let mut ccx = CrateContext {
|
||||
tcx,
|
||||
check_overflow,
|
||||
use_dll_storage_attrs,
|
||||
tls_model,
|
||||
llmod,
|
||||
llcx,
|
||||
stats: RefCell::new(Stats::default()),
|
||||
|
@ -397,41 +307,9 @@ impl<'a, 'tcx> LocalCrateContext<'a, 'tcx> {
|
|||
rust_try_fn: Cell::new(None),
|
||||
intrinsics: RefCell::new(FxHashMap()),
|
||||
local_gen_sym_counter: Cell::new(0),
|
||||
placeholder: PhantomData,
|
||||
};
|
||||
|
||||
let (isize_ty, mut local_ccx) = {
|
||||
// Do a little dance to create a dummy CrateContext, so we can
|
||||
// create some things in the LLVM module of this codegen unit
|
||||
let mut local_ccxs = vec![local_ccx];
|
||||
let isize_ty = {
|
||||
let dummy_ccx = LocalCrateContext::dummy_ccx(shared,
|
||||
local_ccxs.as_mut_slice());
|
||||
Type::isize(&dummy_ccx)
|
||||
};
|
||||
(isize_ty, local_ccxs.pop().unwrap())
|
||||
};
|
||||
|
||||
local_ccx.isize_ty = isize_ty;
|
||||
|
||||
local_ccx
|
||||
}
|
||||
}
|
||||
|
||||
/// Create a dummy `CrateContext` from `self` and the provided
|
||||
/// `SharedCrateContext`. This is somewhat dangerous because `self` may
|
||||
/// not be fully initialized.
|
||||
///
|
||||
/// 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(shared: &'a SharedCrateContext<'a, 'tcx>,
|
||||
local_ccxs: &'a [LocalCrateContext<'a, 'tcx>])
|
||||
-> CrateContext<'a, 'tcx> {
|
||||
assert!(local_ccxs.len() == 1);
|
||||
CrateContext {
|
||||
shared,
|
||||
local_ccx: &local_ccxs[0]
|
||||
ccx.isize_ty = Type::isize(&ccx);
|
||||
ccx
|
||||
}
|
||||
}
|
||||
|
||||
|
@ -441,20 +319,12 @@ impl<'a, 'tcx> LocalCrateContext<'a, 'tcx> {
|
|||
}
|
||||
|
||||
impl<'b, 'tcx> CrateContext<'b, 'tcx> {
|
||||
pub fn shared(&self) -> &'b SharedCrateContext<'b, 'tcx> {
|
||||
self.shared
|
||||
}
|
||||
|
||||
fn local(&self) -> &'b LocalCrateContext<'b, 'tcx> {
|
||||
self.local_ccx
|
||||
}
|
||||
|
||||
pub fn tcx(&self) -> TyCtxt<'b, 'tcx, 'tcx> {
|
||||
self.shared.tcx
|
||||
self.tcx
|
||||
}
|
||||
|
||||
pub fn sess<'a>(&'a self) -> &'a Session {
|
||||
&self.shared.tcx.sess
|
||||
&self.tcx.sess
|
||||
}
|
||||
|
||||
pub fn get_intrinsic(&self, key: &str) -> ValueRef {
|
||||
|
@ -468,15 +338,15 @@ impl<'b, 'tcx> CrateContext<'b, 'tcx> {
|
|||
}
|
||||
|
||||
pub fn llmod(&self) -> ModuleRef {
|
||||
self.local().llmod
|
||||
self.llmod
|
||||
}
|
||||
|
||||
pub fn llcx(&self) -> ContextRef {
|
||||
self.local().llcx
|
||||
self.llcx
|
||||
}
|
||||
|
||||
pub fn codegen_unit(&self) -> &CodegenUnit<'tcx> {
|
||||
&self.local().codegen_unit
|
||||
&self.codegen_unit
|
||||
}
|
||||
|
||||
pub fn td(&self) -> llvm::TargetDataRef {
|
||||
|
@ -484,89 +354,89 @@ impl<'b, 'tcx> CrateContext<'b, 'tcx> {
|
|||
}
|
||||
|
||||
pub fn instances<'a>(&'a self) -> &'a RefCell<FxHashMap<Instance<'tcx>, ValueRef>> {
|
||||
&self.local().instances
|
||||
&self.instances
|
||||
}
|
||||
|
||||
pub fn vtables<'a>(&'a self)
|
||||
-> &'a RefCell<FxHashMap<(Ty<'tcx>,
|
||||
Option<ty::PolyExistentialTraitRef<'tcx>>), ValueRef>> {
|
||||
&self.local().vtables
|
||||
&self.vtables
|
||||
}
|
||||
|
||||
pub fn const_cstr_cache<'a>(&'a self) -> &'a RefCell<FxHashMap<InternedString, ValueRef>> {
|
||||
&self.local().const_cstr_cache
|
||||
&self.const_cstr_cache
|
||||
}
|
||||
|
||||
pub fn const_unsized<'a>(&'a self) -> &'a RefCell<FxHashMap<ValueRef, ValueRef>> {
|
||||
&self.local().const_unsized
|
||||
&self.const_unsized
|
||||
}
|
||||
|
||||
pub fn const_globals<'a>(&'a self) -> &'a RefCell<FxHashMap<ValueRef, ValueRef>> {
|
||||
&self.local().const_globals
|
||||
&self.const_globals
|
||||
}
|
||||
|
||||
pub fn statics<'a>(&'a self) -> &'a RefCell<FxHashMap<ValueRef, DefId>> {
|
||||
&self.local().statics
|
||||
&self.statics
|
||||
}
|
||||
|
||||
pub fn statics_to_rauw<'a>(&'a self) -> &'a RefCell<Vec<(ValueRef, ValueRef)>> {
|
||||
&self.local().statics_to_rauw
|
||||
&self.statics_to_rauw
|
||||
}
|
||||
|
||||
pub fn used_statics<'a>(&'a self) -> &'a RefCell<Vec<ValueRef>> {
|
||||
&self.local().used_statics
|
||||
&self.used_statics
|
||||
}
|
||||
|
||||
pub fn lltypes<'a>(&'a self) -> &'a RefCell<FxHashMap<(Ty<'tcx>, Option<usize>), Type>> {
|
||||
&self.local().lltypes
|
||||
&self.lltypes
|
||||
}
|
||||
|
||||
pub fn scalar_lltypes<'a>(&'a self) -> &'a RefCell<FxHashMap<Ty<'tcx>, Type>> {
|
||||
&self.local().scalar_lltypes
|
||||
&self.scalar_lltypes
|
||||
}
|
||||
|
||||
pub fn pointee_infos<'a>(&'a self)
|
||||
-> &'a RefCell<FxHashMap<(Ty<'tcx>, Size), Option<PointeeInfo>>> {
|
||||
&self.local().pointee_infos
|
||||
&self.pointee_infos
|
||||
}
|
||||
|
||||
pub fn stats<'a>(&'a self) -> &'a RefCell<Stats> {
|
||||
&self.local().stats
|
||||
&self.stats
|
||||
}
|
||||
|
||||
pub fn isize_ty(&self) -> Type {
|
||||
self.local().isize_ty
|
||||
self.isize_ty
|
||||
}
|
||||
|
||||
pub fn dbg_cx<'a>(&'a self) -> &'a Option<debuginfo::CrateDebugContext<'tcx>> {
|
||||
&self.local().dbg_cx
|
||||
&self.dbg_cx
|
||||
}
|
||||
|
||||
pub fn rust_try_fn<'a>(&'a self) -> &'a Cell<Option<ValueRef>> {
|
||||
&self.local().rust_try_fn
|
||||
&self.rust_try_fn
|
||||
}
|
||||
|
||||
fn intrinsics<'a>(&'a self) -> &'a RefCell<FxHashMap<&'static str, ValueRef>> {
|
||||
&self.local().intrinsics
|
||||
&self.intrinsics
|
||||
}
|
||||
|
||||
pub fn check_overflow(&self) -> bool {
|
||||
self.shared.check_overflow
|
||||
self.check_overflow
|
||||
}
|
||||
|
||||
pub fn use_dll_storage_attrs(&self) -> bool {
|
||||
self.shared.use_dll_storage_attrs()
|
||||
self.use_dll_storage_attrs
|
||||
}
|
||||
|
||||
pub fn tls_model(&self) -> llvm::ThreadLocalMode {
|
||||
self.shared.tls_model
|
||||
self.tls_model
|
||||
}
|
||||
|
||||
/// Generate a new symbol name with the given prefix. This symbol name must
|
||||
/// only be used for definitions with `internal` or `private` linkage.
|
||||
pub fn generate_local_symbol_name(&self, prefix: &str) -> String {
|
||||
let idx = self.local().local_gen_sym_counter.get();
|
||||
self.local().local_gen_sym_counter.set(idx + 1);
|
||||
let idx = self.local_gen_sym_counter.get();
|
||||
self.local_gen_sym_counter.set(idx + 1);
|
||||
// Include a '.' character, so there can be no accidental conflicts with
|
||||
// user defined names
|
||||
let mut name = String::with_capacity(prefix.len() + 6);
|
||||
|
@ -597,7 +467,7 @@ impl<'b, 'tcx> CrateContext<'b, 'tcx> {
|
|||
// `rust_eh_personality` function, but rather we wired it up to the
|
||||
// CRT's custom personality function, which forces LLVM to consider
|
||||
// landing pads as "landing pads for SEH".
|
||||
if let Some(llpersonality) = self.local().eh_personality.get() {
|
||||
if let Some(llpersonality) = self.eh_personality.get() {
|
||||
return llpersonality
|
||||
}
|
||||
let tcx = self.tcx();
|
||||
|
@ -615,7 +485,7 @@ impl<'b, 'tcx> CrateContext<'b, 'tcx> {
|
|||
declare::declare_cfn(self, name, fty)
|
||||
}
|
||||
};
|
||||
self.local().eh_personality.set(Some(llfn));
|
||||
self.eh_personality.set(Some(llfn));
|
||||
llfn
|
||||
}
|
||||
|
||||
|
@ -623,7 +493,7 @@ impl<'b, 'tcx> CrateContext<'b, 'tcx> {
|
|||
// otherwise declares it as an external function.
|
||||
pub fn eh_unwind_resume(&self) -> ValueRef {
|
||||
use attributes;
|
||||
let unwresume = &self.local().eh_unwind_resume;
|
||||
let unwresume = &self.eh_unwind_resume;
|
||||
if let Some(llfn) = unwresume.get() {
|
||||
return llfn;
|
||||
}
|
||||
|
@ -649,33 +519,47 @@ impl<'b, 'tcx> CrateContext<'b, 'tcx> {
|
|||
unwresume.set(Some(llfn));
|
||||
llfn
|
||||
}
|
||||
}
|
||||
|
||||
impl<'a, 'tcx> ty::layout::HasDataLayout for &'a SharedCrateContext<'a, 'tcx> {
|
||||
fn data_layout(&self) -> &ty::layout::TargetDataLayout {
|
||||
&self.tcx.data_layout
|
||||
pub fn type_needs_drop(&self, ty: Ty<'tcx>) -> bool {
|
||||
common::type_needs_drop(self.tcx, ty)
|
||||
}
|
||||
}
|
||||
|
||||
impl<'a, 'tcx> ty::layout::HasTyCtxt<'tcx> for &'a SharedCrateContext<'a, 'tcx> {
|
||||
fn tcx<'b>(&'b self) -> TyCtxt<'b, 'tcx, 'tcx> {
|
||||
self.tcx
|
||||
pub fn type_is_sized(&self, ty: Ty<'tcx>) -> bool {
|
||||
common::type_is_sized(self.tcx, ty)
|
||||
}
|
||||
|
||||
pub fn type_is_freeze(&self, ty: Ty<'tcx>) -> bool {
|
||||
common::type_is_freeze(self.tcx, ty)
|
||||
}
|
||||
|
||||
pub fn type_has_metadata(&self, ty: Ty<'tcx>) -> bool {
|
||||
use syntax_pos::DUMMY_SP;
|
||||
if ty.is_sized(self.tcx, ty::ParamEnv::empty(traits::Reveal::All), DUMMY_SP) {
|
||||
return false;
|
||||
}
|
||||
|
||||
let tail = self.tcx.struct_tail(ty);
|
||||
match tail.sty {
|
||||
ty::TyForeign(..) => false,
|
||||
ty::TyStr | ty::TySlice(..) | ty::TyDynamic(..) => true,
|
||||
_ => bug!("unexpected unsized tail: {:?}", tail.sty),
|
||||
}
|
||||
}
|
||||
}
|
||||
|
||||
impl<'a, 'tcx> ty::layout::HasDataLayout for &'a CrateContext<'a, 'tcx> {
|
||||
fn data_layout(&self) -> &ty::layout::TargetDataLayout {
|
||||
&self.shared.tcx.data_layout
|
||||
&self.tcx.data_layout
|
||||
}
|
||||
}
|
||||
|
||||
impl<'a, 'tcx> ty::layout::HasTyCtxt<'tcx> for &'a CrateContext<'a, 'tcx> {
|
||||
fn tcx<'b>(&'b self) -> TyCtxt<'b, 'tcx, 'tcx> {
|
||||
self.shared.tcx
|
||||
self.tcx
|
||||
}
|
||||
}
|
||||
|
||||
impl<'a, 'tcx> LayoutOf<Ty<'tcx>> for &'a SharedCrateContext<'a, 'tcx> {
|
||||
impl<'a, 'tcx> LayoutOf<Ty<'tcx>> for &'a CrateContext<'a, 'tcx> {
|
||||
type TyLayout = TyLayout<'tcx>;
|
||||
|
||||
fn layout_of(self, ty: Ty<'tcx>) -> Self::TyLayout {
|
||||
|
@ -688,15 +572,6 @@ impl<'a, 'tcx> LayoutOf<Ty<'tcx>> for &'a SharedCrateContext<'a, 'tcx> {
|
|||
}
|
||||
}
|
||||
|
||||
impl<'a, 'tcx> LayoutOf<Ty<'tcx>> for &'a CrateContext<'a, 'tcx> {
|
||||
type TyLayout = TyLayout<'tcx>;
|
||||
|
||||
|
||||
fn layout_of(self, ty: Ty<'tcx>) -> Self::TyLayout {
|
||||
self.shared.layout_of(ty)
|
||||
}
|
||||
}
|
||||
|
||||
/// Declare any llvm intrinsics that you might need
|
||||
fn declare_intrinsic(ccx: &CrateContext, key: &str) -> Option<ValueRef> {
|
||||
macro_rules! ifn {
|
||||
|
|
|
@ -18,7 +18,6 @@ use super::namespace::mangled_name_of_item;
|
|||
use super::type_names::compute_debuginfo_type_name;
|
||||
use super::{CrateDebugContext};
|
||||
use abi;
|
||||
use context::SharedCrateContext;
|
||||
|
||||
use llvm::{self, ValueRef};
|
||||
use llvm::debuginfo::{DIType, DIFile, DIScope, DIDescriptor,
|
||||
|
@ -31,9 +30,9 @@ use rustc::ty::util::TypeIdHasher;
|
|||
use rustc::ich::Fingerprint;
|
||||
use rustc::ty::Instance;
|
||||
use common::CrateContext;
|
||||
use rustc::ty::{self, AdtKind, Ty};
|
||||
use rustc::ty::{self, AdtKind, Ty, TyCtxt};
|
||||
use rustc::ty::layout::{self, Align, LayoutOf, Size, TyLayout};
|
||||
use rustc::session::{Session, config};
|
||||
use rustc::session::config;
|
||||
use rustc::util::nodemap::FxHashMap;
|
||||
use rustc::util::common::path2cstr;
|
||||
|
||||
|
@ -785,21 +784,20 @@ fn pointer_type_metadata<'a, 'tcx>(cx: &CrateContext<'a, 'tcx>,
|
|||
}
|
||||
}
|
||||
|
||||
pub fn compile_unit_metadata(scc: &SharedCrateContext,
|
||||
pub fn compile_unit_metadata(tcx: TyCtxt,
|
||||
codegen_unit_name: &str,
|
||||
debug_context: &CrateDebugContext,
|
||||
sess: &Session)
|
||||
debug_context: &CrateDebugContext)
|
||||
-> DIDescriptor {
|
||||
let mut name_in_debuginfo = match sess.local_crate_source_file {
|
||||
let mut name_in_debuginfo = match tcx.sess.local_crate_source_file {
|
||||
Some(ref path) => path.clone(),
|
||||
None => PathBuf::from(&*scc.tcx().crate_name(LOCAL_CRATE).as_str()),
|
||||
None => PathBuf::from(&*tcx.crate_name(LOCAL_CRATE).as_str()),
|
||||
};
|
||||
|
||||
// The OSX linker has an idiosyncrasy where it will ignore some debuginfo
|
||||
// if multiple object files with the same DW_AT_name are linked together.
|
||||
// As a workaround we generate unique names for each object file. Those do
|
||||
// not correspond to an actual source file but that should be harmless.
|
||||
if scc.sess().target.target.options.is_like_osx {
|
||||
if tcx.sess.target.target.options.is_like_osx {
|
||||
name_in_debuginfo.push("@");
|
||||
name_in_debuginfo.push(codegen_unit_name);
|
||||
}
|
||||
|
@ -811,7 +809,7 @@ pub fn compile_unit_metadata(scc: &SharedCrateContext,
|
|||
|
||||
let name_in_debuginfo = name_in_debuginfo.to_string_lossy().into_owned();
|
||||
let name_in_debuginfo = CString::new(name_in_debuginfo).unwrap();
|
||||
let work_dir = CString::new(&sess.working_dir.0.to_string_lossy()[..]).unwrap();
|
||||
let work_dir = CString::new(&tcx.sess.working_dir.0.to_string_lossy()[..]).unwrap();
|
||||
let producer = CString::new(producer).unwrap();
|
||||
let flags = "\0";
|
||||
let split_name = "\0";
|
||||
|
@ -825,20 +823,20 @@ pub fn compile_unit_metadata(scc: &SharedCrateContext,
|
|||
DW_LANG_RUST,
|
||||
file_metadata,
|
||||
producer.as_ptr(),
|
||||
sess.opts.optimize != config::OptLevel::No,
|
||||
tcx.sess.opts.optimize != config::OptLevel::No,
|
||||
flags.as_ptr() as *const _,
|
||||
0,
|
||||
split_name.as_ptr() as *const _);
|
||||
|
||||
if sess.opts.debugging_opts.profile {
|
||||
if tcx.sess.opts.debugging_opts.profile {
|
||||
let cu_desc_metadata = llvm::LLVMRustMetadataAsValue(debug_context.llcontext,
|
||||
unit_metadata);
|
||||
|
||||
let gcov_cu_info = [
|
||||
path_to_mdstring(debug_context.llcontext,
|
||||
&scc.tcx().output_filenames(LOCAL_CRATE).with_extension("gcno")),
|
||||
&tcx.output_filenames(LOCAL_CRATE).with_extension("gcno")),
|
||||
path_to_mdstring(debug_context.llcontext,
|
||||
&scc.tcx().output_filenames(LOCAL_CRATE).with_extension("gcda")),
|
||||
&tcx.output_filenames(LOCAL_CRATE).with_extension("gcda")),
|
||||
cu_desc_metadata,
|
||||
];
|
||||
let gcov_metadata = llvm::LLVMMDNodeInContext(debug_context.llcontext,
|
||||
|
|
|
@ -27,7 +27,7 @@ pub fn size_and_align_of_dst<'a, 'tcx>(bcx: &Builder<'a, 'tcx>, t: Ty<'tcx>, inf
|
|||
-> (ValueRef, ValueRef) {
|
||||
debug!("calculate size of DST: {}; with lost info: {:?}",
|
||||
t, Value(info));
|
||||
if bcx.ccx.shared().type_is_sized(t) {
|
||||
if bcx.ccx.type_is_sized(t) {
|
||||
let (size, align) = bcx.ccx.size_and_align_of(t);
|
||||
debug!("size_and_align_of_dst t={} info={:?} size: {:?} align: {:?}",
|
||||
t, Value(info), size, align);
|
||||
|
|
|
@ -196,7 +196,7 @@ pub fn trans_intrinsic_call<'a, 'tcx>(bcx: &Builder<'a, 'tcx>,
|
|||
"needs_drop" => {
|
||||
let tp_ty = substs.type_at(0);
|
||||
|
||||
C_bool(ccx, bcx.ccx.shared().type_needs_drop(tp_ty))
|
||||
C_bool(ccx, bcx.ccx.type_needs_drop(tp_ty))
|
||||
}
|
||||
"offset" => {
|
||||
let ptr = args[0].immediate();
|
||||
|
@ -620,7 +620,7 @@ pub fn trans_intrinsic_call<'a, 'tcx>(bcx: &Builder<'a, 'tcx>,
|
|||
// This assumes the type is "simple", i.e. no
|
||||
// destructors, and the contents are SIMD
|
||||
// etc.
|
||||
assert!(!bcx.ccx.shared().type_needs_drop(arg.layout.ty));
|
||||
assert!(!bcx.ccx.type_needs_drop(arg.layout.ty));
|
||||
let (ptr, align) = match arg.val {
|
||||
OperandValue::Ref(ptr, align) => (ptr, align),
|
||||
_ => bug!()
|
||||
|
|
|
@ -204,7 +204,7 @@ impl<'mir, 'a, 'tcx> Visitor<'tcx> for LocalAnalyzer<'mir, 'a, 'tcx> {
|
|||
let ty = self.cx.monomorphize(&ty.to_ty(self.cx.ccx.tcx()));
|
||||
|
||||
// Only need the place if we're actually dropping it.
|
||||
if self.cx.ccx.shared().type_needs_drop(ty) {
|
||||
if self.cx.ccx.type_needs_drop(ty) {
|
||||
self.mark_as_memory(index);
|
||||
}
|
||||
}
|
||||
|
|
|
@ -528,7 +528,7 @@ impl<'a, 'tcx> MirConstContext<'a, 'tcx> {
|
|||
.projection_ty(tcx, &projection.elem);
|
||||
let base = tr_base.to_const(span);
|
||||
let projected_ty = self.monomorphize(&projected_ty).to_ty(tcx);
|
||||
let has_metadata = self.ccx.shared().type_has_metadata(projected_ty);
|
||||
let has_metadata = self.ccx.type_has_metadata(projected_ty);
|
||||
|
||||
let (projected, llextra) = match projection.elem {
|
||||
mir::ProjectionElem::Deref => {
|
||||
|
@ -742,7 +742,7 @@ impl<'a, 'tcx> MirConstContext<'a, 'tcx> {
|
|||
mir::CastKind::Unsize => {
|
||||
let pointee_ty = operand.ty.builtin_deref(true, ty::NoPreference)
|
||||
.expect("consts: unsizing got non-pointer type").ty;
|
||||
let (base, old_info) = if !self.ccx.shared().type_is_sized(pointee_ty) {
|
||||
let (base, old_info) = if !self.ccx.type_is_sized(pointee_ty) {
|
||||
// Normally, the source is a thin pointer and we are
|
||||
// adding extra info to make a fat pointer. The exception
|
||||
// is when we are upcasting an existing object fat pointer
|
||||
|
@ -857,7 +857,7 @@ impl<'a, 'tcx> MirConstContext<'a, 'tcx> {
|
|||
let base = match tr_place.base {
|
||||
Base::Value(llval) => {
|
||||
// FIXME: may be wrong for &*(&simd_vec as &fmt::Debug)
|
||||
let align = if self.ccx.shared().type_is_sized(ty) {
|
||||
let align = if self.ccx.type_is_sized(ty) {
|
||||
self.ccx.align_of(ty)
|
||||
} else {
|
||||
self.ccx.tcx().data_layout.pointer_align
|
||||
|
@ -872,7 +872,7 @@ impl<'a, 'tcx> MirConstContext<'a, 'tcx> {
|
|||
Base::Static(llval) => llval
|
||||
};
|
||||
|
||||
let ptr = if self.ccx.shared().type_is_sized(ty) {
|
||||
let ptr = if self.ccx.type_is_sized(ty) {
|
||||
base
|
||||
} else {
|
||||
C_fat_ptr(self.ccx, base, tr_place.llextra)
|
||||
|
@ -941,7 +941,7 @@ impl<'a, 'tcx> MirConstContext<'a, 'tcx> {
|
|||
}
|
||||
|
||||
mir::Rvalue::NullaryOp(mir::NullOp::SizeOf, ty) => {
|
||||
assert!(self.ccx.shared().type_is_sized(ty));
|
||||
assert!(self.ccx.type_is_sized(ty));
|
||||
let llval = C_usize(self.ccx, self.ccx.size_of(ty).bytes());
|
||||
Const::new(llval, tcx.types.usize)
|
||||
}
|
||||
|
|
|
@ -178,7 +178,7 @@ impl<'a, 'tcx> PlaceRef<'tcx> {
|
|||
PlaceRef {
|
||||
// HACK(eddyb) have to bitcast pointers until LLVM removes pointee types.
|
||||
llval: bcx.pointercast(llval, field.llvm_type(ccx).ptr_to()),
|
||||
llextra: if ccx.shared().type_has_metadata(field.ty) {
|
||||
llextra: if ccx.type_has_metadata(field.ty) {
|
||||
self.llextra
|
||||
} else {
|
||||
ptr::null_mut()
|
||||
|
|
|
@ -341,7 +341,7 @@ impl<'a, 'tcx> MirContext<'a, 'tcx> {
|
|||
|
||||
// Note: places are indirect, so storing the `llval` into the
|
||||
// destination effectively creates a reference.
|
||||
let val = if !bcx.ccx.shared().type_has_metadata(ty) {
|
||||
let val = if !bcx.ccx.type_has_metadata(ty) {
|
||||
OperandValue::Immediate(tr_place.llval)
|
||||
} else {
|
||||
OperandValue::Pair(tr_place.llval, tr_place.llextra)
|
||||
|
@ -435,7 +435,7 @@ impl<'a, 'tcx> MirContext<'a, 'tcx> {
|
|||
}
|
||||
|
||||
mir::Rvalue::NullaryOp(mir::NullOp::SizeOf, ty) => {
|
||||
assert!(bcx.ccx.shared().type_is_sized(ty));
|
||||
assert!(bcx.ccx.type_is_sized(ty));
|
||||
let val = C_usize(bcx.ccx, bcx.ccx.size_of(ty).bytes());
|
||||
let tcx = bcx.tcx();
|
||||
(bcx, OperandRef {
|
||||
|
|
|
@ -417,14 +417,14 @@ impl<'tcx> LayoutLlvmExt<'tcx> for TyLayout<'tcx> {
|
|||
let (size, align) = ccx.size_and_align_of(mt.ty);
|
||||
|
||||
let kind = match mt.mutbl {
|
||||
hir::MutImmutable => if ccx.shared().type_is_freeze(mt.ty) {
|
||||
hir::MutImmutable => if ccx.type_is_freeze(mt.ty) {
|
||||
PointerKind::Frozen
|
||||
} else {
|
||||
PointerKind::Shared
|
||||
},
|
||||
hir::MutMutable => {
|
||||
if ccx.shared().tcx().sess.opts.debugging_opts.mutable_noalias ||
|
||||
ccx.shared().tcx().sess.panic_strategy() == PanicStrategy::Abort {
|
||||
if ccx.tcx().sess.opts.debugging_opts.mutable_noalias ||
|
||||
ccx.tcx().sess.panic_strategy() == PanicStrategy::Abort {
|
||||
PointerKind::UniqueBorrowed
|
||||
} else {
|
||||
PointerKind::Shared
|
||||
|
|
Loading…
Add table
Reference in a new issue