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;
&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))
}
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) =
// 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
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);
}
}
- 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);
}
.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 {
}
};
- (lcx.into_stats(), module)
+ (ccx.into_stats(), module)
}
}
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;
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};
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>,
/// 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[..],
(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
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()),
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
}
}
}
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 {
}
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 {
}
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);
// `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();
declare::declare_cfn(self, name, fty)
}
};
- self.local().eh_personality.set(Some(llfn));
+ self.eh_personality.set(Some(llfn));
llfn
}
// 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;
}
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 {
}
}
-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 {
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,
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;
}
}
-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);
}
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";
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,