diff --git a/src/librustc_trans/base.rs b/src/librustc_trans/base.rs index cb45f9c0512..cdd909477fd 100644 --- a/src/librustc_trans/base.rs +++ b/src/librustc_trans/base.rs @@ -54,7 +54,7 @@ use callee::{Callee}; use common::{C_bool, C_bytes_in_context, C_i32, C_uint}; use collector::{self, TransItemCollectionMode}; use common::{C_struct_in_context, C_u64, C_undef}; -use common::{CrateContext, FunctionContext}; +use common::CrateContext; use common::{fulfill_obligation}; use common::{type_is_zero_size, val_ty}; use common; @@ -590,18 +590,17 @@ pub fn trans_instance<'a, 'tcx>(ccx: &CrateContext<'a, 'tcx>, instance: Instance let fn_ty = FnType::new(ccx, abi, &sig, &[]); - let fcx = FunctionContext::new(ccx, lldecl); let mir = ccx.tcx().item_mir(instance.def); - mir::trans_mir(&fcx, fn_ty, &mir, instance, &sig, abi); + mir::trans_mir(ccx, lldecl, fn_ty, &mir, instance, &sig, abi); } pub fn trans_ctor_shim<'a, 'tcx>(ccx: &CrateContext<'a, 'tcx>, def_id: DefId, substs: &'tcx Substs<'tcx>, disr: Disr, - llfndecl: ValueRef) { - attributes::inline(llfndecl, attributes::InlineAttr::Hint); - attributes::set_frame_pointer_elimination(ccx, llfndecl); + llfn: ValueRef) { + attributes::inline(llfn, attributes::InlineAttr::Hint); + attributes::set_frame_pointer_elimination(ccx, llfn); let ctor_ty = ccx.tcx().item_type(def_id); let ctor_ty = monomorphize::apply_param_substs(ccx.shared(), substs, &ctor_ty); @@ -609,13 +608,12 @@ pub fn trans_ctor_shim<'a, 'tcx>(ccx: &CrateContext<'a, 'tcx>, let sig = ccx.tcx().erase_late_bound_regions_and_normalize(&ctor_ty.fn_sig()); let fn_ty = FnType::new(ccx, Abi::Rust, &sig, &[]); - let fcx = FunctionContext::new(ccx, llfndecl); - let bcx = fcx.get_entry_block(); + let bcx = Builder::entry_block(ccx, llfn); if !fn_ty.ret.is_ignore() { // But if there are no nested returns, we skip the indirection // and have a single retslot let dest = if fn_ty.ret.is_indirect() { - get_param(fcx.llfn, 0) + get_param(llfn, 0) } else { // We create an alloca to hold a pointer of type `ret.original_ty` // which will hold the pointer to the right alloca which has the diff --git a/src/librustc_trans/builder.rs b/src/librustc_trans/builder.rs index 6ea048d7ed3..610446d316d 100644 --- a/src/librustc_trans/builder.rs +++ b/src/librustc_trans/builder.rs @@ -50,6 +50,10 @@ fn noname() -> *const c_char { } impl<'a, 'tcx> Builder<'a, 'tcx> { + pub fn entry_block(ccx: &'a CrateContext<'a, 'tcx>, llfn: ValueRef) -> Self { + Builder::new_block(ccx, llfn, "entry-block") + } + pub fn new_block<'b>(ccx: &'a CrateContext<'a, 'tcx>, llfn: ValueRef, name: &'b str) -> Self { let builder = Builder::with_ccx(ccx); let llbb = unsafe { diff --git a/src/librustc_trans/callee.rs b/src/librustc_trans/callee.rs index aabd3083ff5..e73bfd73e9b 100644 --- a/src/librustc_trans/callee.rs +++ b/src/librustc_trans/callee.rs @@ -23,9 +23,9 @@ use rustc::traits; use abi::{Abi, FnType}; use attributes; use base; -use common::{ - self, CrateContext, FunctionContext, SharedCrateContext -}; +use builder::Builder; +use common::{self, CrateContext, SharedCrateContext}; +use cleanup::CleanupScope; use adt::MaybeSizedValue; use consts; use declare; @@ -329,8 +329,7 @@ fn trans_fn_once_adapter_shim<'a, 'tcx>( attributes::set_frame_pointer_elimination(ccx, lloncefn); let orig_fn_ty = fn_ty; - let fcx = FunctionContext::new(ccx, lloncefn); - let mut bcx = fcx.get_entry_block(); + let mut bcx = Builder::entry_block(ccx, lloncefn); let callee = Callee { data: Fn(llreffn), @@ -339,7 +338,7 @@ fn trans_fn_once_adapter_shim<'a, 'tcx>( // the first argument (`self`) will be the (by value) closure env. - let mut llargs = get_params(fcx.llfn); + let mut llargs = get_params(lloncefn); let fn_ret = callee.ty.fn_ret(); let fn_ty = callee.direct_fn_type(bcx.ccx, &[]); let self_idx = fn_ty.ret.is_indirect() as usize; @@ -364,7 +363,9 @@ fn trans_fn_once_adapter_shim<'a, 'tcx>( // Call the by-ref closure body with `self` in a cleanup scope, // to drop `self` when the body returns, or in case it unwinds. - let self_scope = fcx.schedule_drop_mem(&bcx, MaybeSizedValue::sized(llenv), closure_ty); + let self_scope = CleanupScope::schedule_drop_mem( + &bcx, MaybeSizedValue::sized(llenv), closure_ty + ); let llfn = callee.reify(bcx.ccx); let llret; @@ -488,10 +489,9 @@ fn trans_fn_pointer_shim<'a, 'tcx>( let llfn = declare::define_internal_fn(ccx, &function_name, tuple_fn_ty); attributes::set_frame_pointer_elimination(ccx, llfn); // - let fcx = FunctionContext::new(ccx, llfn); - let bcx = fcx.get_entry_block(); + let bcx = Builder::entry_block(ccx, llfn); - let mut llargs = get_params(fcx.llfn); + let mut llargs = get_params(llfn); let self_arg = llargs.remove(fn_ty.ret.is_indirect() as usize); let llfnpointer = llfnpointer.unwrap_or_else(|| { diff --git a/src/librustc_trans/cleanup.rs b/src/librustc_trans/cleanup.rs index bb8faefffec..b41b26e1d06 100644 --- a/src/librustc_trans/cleanup.rs +++ b/src/librustc_trans/cleanup.rs @@ -22,7 +22,7 @@ use llvm::BasicBlockRef; use base; use adt::MaybeSizedValue; use builder::Builder; -use common::{FunctionContext, Funclet}; +use common::Funclet; use glue; use type_::Type; use rustc::ty::Ty; @@ -93,12 +93,12 @@ impl<'tcx> DropValue<'tcx> { } } -impl<'a, 'tcx> FunctionContext<'a, 'tcx> { +impl<'a, 'tcx> CleanupScope<'tcx> { /// Schedules a (deep) drop of `val`, which is a pointer to an instance of `ty` pub fn schedule_drop_mem( - &self, bcx: &Builder<'a, 'tcx>, val: MaybeSizedValue, ty: Ty<'tcx> + bcx: &Builder<'a, 'tcx>, val: MaybeSizedValue, ty: Ty<'tcx> ) -> CleanupScope<'tcx> { - if !self.ccx.shared().type_needs_drop(ty) { return CleanupScope::noop(); } + if !bcx.ccx.shared().type_needs_drop(ty) { return CleanupScope::noop(); } let drop = DropValue { val: val, ty: ty, @@ -114,11 +114,11 @@ impl<'a, 'tcx> FunctionContext<'a, 'tcx> { /// and dropping the contents associated with that variant /// *without* executing any associated drop implementation. pub fn schedule_drop_adt_contents( - &self, bcx: &Builder<'a, 'tcx>, val: MaybeSizedValue, ty: Ty<'tcx> + bcx: &Builder<'a, 'tcx>, val: MaybeSizedValue, ty: Ty<'tcx> ) -> CleanupScope<'tcx> { // `if` below could be "!contents_needs_drop"; skipping drop // is just an optimization, so sound to be conservative. - if !self.ccx.shared().type_needs_drop(ty) { return CleanupScope::noop(); } + if !bcx.ccx.shared().type_needs_drop(ty) { return CleanupScope::noop(); } let drop = DropValue { val: val, @@ -128,10 +128,8 @@ impl<'a, 'tcx> FunctionContext<'a, 'tcx> { CleanupScope::new(bcx, drop) } -} -impl<'tcx> CleanupScope<'tcx> { - fn new<'a>(bcx: &Builder<'a, 'tcx>, drop_val: DropValue<'tcx>) -> CleanupScope<'tcx> { + fn new(bcx: &Builder<'a, 'tcx>, drop_val: DropValue<'tcx>) -> CleanupScope<'tcx> { CleanupScope { cleanup: Some(drop_val), landing_pad: if !bcx.ccx.sess().no_landing_pads() { @@ -149,7 +147,7 @@ impl<'tcx> CleanupScope<'tcx> { } } - pub fn trans<'a>(self, bcx: &'a Builder<'a, 'tcx>) { + pub fn trans(self, bcx: &'a Builder<'a, 'tcx>) { if let Some(cleanup) = self.cleanup { cleanup.trans(None, &bcx); } diff --git a/src/librustc_trans/common.rs b/src/librustc_trans/common.rs index 09be09a2b0a..8dcb835350b 100644 --- a/src/librustc_trans/common.rs +++ b/src/librustc_trans/common.rs @@ -13,7 +13,7 @@ //! Code that is useful in various trans modules. use llvm; -use llvm::{ValueRef, BasicBlockRef, ContextRef, TypeKind}; +use llvm::{ValueRef, ContextRef, TypeKind}; use llvm::{True, False, Bool, OperandBundleDef}; use rustc::hir::def::Def; use rustc::hir::def_id::DefId; @@ -36,7 +36,6 @@ use rustc::hir; use libc::{c_uint, c_char}; use std::borrow::Cow; use std::iter; -use std::ffi::CString; use syntax::ast; use syntax::symbol::{Symbol, InternedString}; @@ -219,71 +218,6 @@ impl<'a, 'tcx> VariantInfo<'tcx> { } } -// Function context. Every LLVM function we create will have one of these. -pub struct FunctionContext<'a, 'tcx: 'a> { - // The ValueRef returned from a call to llvm::LLVMAddFunction; the - // address of the first instruction in the sequence of - // instructions for this function that will go in the .text - // section of the executable we're generating. - pub llfn: ValueRef, - - // A marker for the place where we want to insert the function's static - // allocas, so that LLVM will coalesce them into a single alloca call. - alloca_insert_pt: Option, - - // This function's enclosing crate context. - pub ccx: &'a CrateContext<'a, 'tcx>, -} - -impl<'a, 'tcx> FunctionContext<'a, 'tcx> { - /// Create a function context for the given function. - /// Call FunctionContext::get_entry_block for the first entry block. - pub fn new(ccx: &'a CrateContext<'a, 'tcx>, llfndecl: ValueRef) -> FunctionContext<'a, 'tcx> { - let mut fcx = FunctionContext { - llfn: llfndecl, - alloca_insert_pt: None, - ccx: ccx, - }; - - let entry_bcx = Builder::new_block(fcx.ccx, fcx.llfn, "entry-block"); - entry_bcx.position_at_start(entry_bcx.llbb()); - // Use a dummy instruction as the insertion point for all allocas. - // This is later removed in the drop of FunctionContext. - fcx.alloca_insert_pt = Some(entry_bcx.load(C_null(Type::i8p(ccx)))); - - fcx - } - - pub fn new_block(&self, name: &str) -> BasicBlockRef { - unsafe { - let name = CString::new(name).unwrap(); - llvm::LLVMAppendBasicBlockInContext( - self.ccx.llcx(), - self.llfn, - name.as_ptr() - ) - } - } - - pub fn build_new_block(&self, name: &str) -> Builder<'a, 'tcx> { - Builder::new_block(self.ccx, self.llfn, name) - } - - pub fn get_entry_block(&'a self) -> Builder<'a, 'tcx> { - let builder = Builder::with_ccx(self.ccx); - builder.position_at_end(unsafe { llvm::LLVMGetFirstBasicBlock(self.llfn) }); - builder - } -} - -impl<'a, 'tcx> Drop for FunctionContext<'a, 'tcx> { - fn drop(&mut self) { - unsafe { - llvm::LLVMInstructionEraseFromParent(self.alloca_insert_pt.unwrap()); - } - } -} - /// A structure representing an active landing pad for the duration of a basic /// block. /// diff --git a/src/librustc_trans/debuginfo/create_scope_map.rs b/src/librustc_trans/debuginfo/create_scope_map.rs index f5a8eeacf38..c6f8ba7b6dc 100644 --- a/src/librustc_trans/debuginfo/create_scope_map.rs +++ b/src/librustc_trans/debuginfo/create_scope_map.rs @@ -14,7 +14,7 @@ use super::utils::{DIB, span_start}; use llvm; use llvm::debuginfo::{DIScope, DISubprogram}; -use common::{CrateContext, FunctionContext}; +use common::CrateContext; use rustc::mir::{Mir, VisibilityScope}; use libc::c_uint; @@ -44,7 +44,7 @@ impl MirDebugScope { /// Produce DIScope DIEs for each MIR Scope which has variables defined in it. /// If debuginfo is disabled, the returned vector is empty. -pub fn create_mir_scopes(fcx: &FunctionContext, mir: &Mir, debug_context: &FunctionDebugContext) +pub fn create_mir_scopes(ccx: &CrateContext, mir: &Mir, debug_context: &FunctionDebugContext) -> IndexVec { let null_scope = MirDebugScope { scope_metadata: ptr::null_mut(), @@ -71,7 +71,7 @@ pub fn create_mir_scopes(fcx: &FunctionContext, mir: &Mir, debug_context: &Funct // Instantiate all scopes. for idx in 0..mir.visibility_scopes.len() { let scope = VisibilityScope::new(idx); - make_mir_scope(fcx.ccx, &mir, &has_variables, fn_metadata, scope, &mut scopes); + make_mir_scope(ccx, &mir, &has_variables, fn_metadata, scope, &mut scopes); } scopes diff --git a/src/librustc_trans/debuginfo/doc.rs b/src/librustc_trans/debuginfo/doc.rs index bcf5eb99200..7a739071506 100644 --- a/src/librustc_trans/debuginfo/doc.rs +++ b/src/librustc_trans/debuginfo/doc.rs @@ -45,7 +45,7 @@ //! //! All private state used by the module is stored within either the //! CrateDebugContext struct (owned by the CrateContext) or the -//! FunctionDebugContext (owned by the FunctionContext). +//! FunctionDebugContext (owned by the MirContext). //! //! This file consists of three conceptual sections: //! 1. The public interface of the module diff --git a/src/librustc_trans/glue.rs b/src/librustc_trans/glue.rs index c27576f9016..d055e33919d 100644 --- a/src/librustc_trans/glue.rs +++ b/src/librustc_trans/glue.rs @@ -25,6 +25,7 @@ use rustc::ty::subst::Kind; use adt::{self, MaybeSizedValue}; use base::*; use callee::Callee; +use cleanup::CleanupScope; use common::*; use machine::*; use monomorphize; @@ -34,7 +35,6 @@ use type_of::{type_of, sizing_type_of, align_of}; use type_::Type; use value::Value; use Disr; -use cleanup::CleanupScope; use builder::Builder; use syntax_pos::DUMMY_SP; @@ -174,8 +174,7 @@ pub fn implement_drop_glue<'a, 'tcx>(ccx: &CrateContext<'a, 'tcx>, g: DropGlueKi assert_eq!(g.ty(), get_drop_glue_type(ccx.shared(), g.ty())); let (llfn, _) = ccx.drop_glues().borrow().get(&g).unwrap().clone(); - let fcx = FunctionContext::new(ccx, llfn); - let mut bcx = fcx.get_entry_block(); + let mut bcx = Builder::entry_block(ccx, llfn); ccx.stats().n_glues_created.set(ccx.stats().n_glues_created.get() + 1); // All glue functions take values passed *by alias*; this is a @@ -246,7 +245,7 @@ pub fn implement_drop_glue<'a, 'tcx>(ccx: &CrateContext<'a, 'tcx>, g: DropGlueKi // Issue #23611: schedule cleanup of contents, re-inspecting the // discriminant (if any) in case of variant swap in drop code. let contents_scope = if !shallow_drop { - fcx.schedule_drop_adt_contents(&bcx, ptr, t) + CleanupScope::schedule_drop_adt_contents(&bcx, ptr, t) } else { CleanupScope::noop() }; diff --git a/src/librustc_trans/intrinsic.rs b/src/librustc_trans/intrinsic.rs index af3050fef0d..7d094b89a05 100644 --- a/src/librustc_trans/intrinsic.rs +++ b/src/librustc_trans/intrinsic.rs @@ -89,7 +89,6 @@ fn get_simple_intrinsic(ccx: &CrateContext, name: &str) -> Option { /// and in libcore/intrinsics.rs; if you need access to any llvm intrinsics, /// add them to librustc_trans/trans/context.rs pub fn trans_intrinsic_call<'a, 'tcx>(bcx: &Builder<'a, 'tcx>, - fcx: &FunctionContext, callee_ty: Ty<'tcx>, fn_ty: &FnType, llargs: &[ValueRef], @@ -127,7 +126,7 @@ pub fn trans_intrinsic_call<'a, 'tcx>(bcx: &Builder<'a, 'tcx>, bcx.call(expect, &[llargs[0], C_bool(ccx, false)], None) } "try" => { - try_intrinsic(bcx, fcx, llargs[0], llargs[1], llargs[2], llresult); + try_intrinsic(bcx, ccx, llargs[0], llargs[1], llargs[2], llresult); C_nil(ccx) } "breakpoint" => { @@ -689,7 +688,7 @@ fn memset_intrinsic<'a, 'tcx>( fn try_intrinsic<'a, 'tcx>( bcx: &Builder<'a, 'tcx>, - fcx: &FunctionContext, + ccx: &CrateContext, func: ValueRef, data: ValueRef, local_ptr: ValueRef, @@ -701,7 +700,7 @@ fn try_intrinsic<'a, 'tcx>( } else if wants_msvc_seh(bcx.sess()) { trans_msvc_try(bcx, fcx, func, data, local_ptr, dest); } else { - trans_gnu_try(bcx, fcx, func, data, local_ptr, dest); + trans_gnu_try(bcx, ccx, func, data, local_ptr, dest); } } @@ -713,12 +712,12 @@ fn try_intrinsic<'a, 'tcx>( // writing, however, LLVM does not recommend the usage of these new instructions // as the old ones are still more optimized. fn trans_msvc_try<'a, 'tcx>(bcx: &Builder<'a, 'tcx>, - fcx: &FunctionContext, + ccx: &CrateContext, func: ValueRef, data: ValueRef, local_ptr: ValueRef, dest: ValueRef) { - let llfn = get_rust_try_fn(fcx, &mut |bcx| { + let llfn = get_rust_try_fn(ccx, &mut |bcx| { let ccx = bcx.ccx; bcx.set_personality_fn(bcx.ccx.eh_personality()); @@ -817,12 +816,12 @@ fn trans_msvc_try<'a, 'tcx>(bcx: &Builder<'a, 'tcx>, // functions in play. By calling a shim we're guaranteed that our shim will have // the right personality function. fn trans_gnu_try<'a, 'tcx>(bcx: &Builder<'a, 'tcx>, - fcx: &FunctionContext, + ccx: &CrateContext, func: ValueRef, data: ValueRef, local_ptr: ValueRef, dest: ValueRef) { - let llfn = get_rust_try_fn(fcx, &mut |bcx| { + let llfn = get_rust_try_fn(ccx, &mut |bcx| { let ccx = bcx.ccx; // Translates the shims described above: @@ -874,13 +873,12 @@ fn trans_gnu_try<'a, 'tcx>(bcx: &Builder<'a, 'tcx>, // Helper function to give a Block to a closure to translate a shim function. // This is currently primarily used for the `try` intrinsic functions above. -fn gen_fn<'a, 'tcx>(fcx: &FunctionContext<'a, 'tcx>, +fn gen_fn<'a, 'tcx>(ccx: &CrateContext<'a, 'tcx>, name: &str, inputs: Vec>, output: Ty<'tcx>, trans: &mut for<'b> FnMut(Builder<'b, 'tcx>)) -> ValueRef { - let ccx = fcx.ccx; let sig = ccx.tcx().mk_fn_sig(inputs.into_iter(), output, false); let rust_fn_ty = ccx.tcx().mk_fn_ptr(ccx.tcx().mk_bare_fn(ty::BareFnTy { @@ -889,8 +887,8 @@ fn gen_fn<'a, 'tcx>(fcx: &FunctionContext<'a, 'tcx>, sig: ty::Binder(sig) })); let llfn = declare::define_internal_fn(ccx, name, rust_fn_ty); - let fcx = FunctionContext::new(ccx, llfn); - trans(fcx.get_entry_block()); + let bcx = Builder::entry_block(ccx, llfn); + trans(bcx); llfn } @@ -898,10 +896,9 @@ fn gen_fn<'a, 'tcx>(fcx: &FunctionContext<'a, 'tcx>, // catch exceptions. // // This function is only generated once and is then cached. -fn get_rust_try_fn<'a, 'tcx>(fcx: &FunctionContext<'a, 'tcx>, +fn get_rust_try_fn<'a, 'tcx>(ccx: &CrateContext<'a, 'tcx>, trans: &mut for<'b> FnMut(Builder<'b, 'tcx>)) -> ValueRef { - let ccx = fcx.ccx; if let Some(llfn) = ccx.rust_try_fn().get() { return llfn; } @@ -915,7 +912,7 @@ fn get_rust_try_fn<'a, 'tcx>(fcx: &FunctionContext<'a, 'tcx>, sig: ty::Binder(tcx.mk_fn_sig(iter::once(i8p), tcx.mk_nil(), false)), })); let output = tcx.types.i32; - let rust_try = gen_fn(fcx, "__rust_try", vec![fn_ty, i8p, i8p], output, trans); + let rust_try = gen_fn(ccx, "__rust_try", vec![fn_ty, i8p, i8p], output, trans); ccx.rust_try_fn().set(Some(rust_try)); return rust_try } diff --git a/src/librustc_trans/meth.rs b/src/librustc_trans/meth.rs index 1765d6e73b3..e83b79f11f4 100644 --- a/src/librustc_trans/meth.rs +++ b/src/librustc_trans/meth.rs @@ -76,10 +76,9 @@ pub fn trans_object_shim<'a, 'tcx>(ccx: &'a CrateContext<'a, 'tcx>, let llfn = declare::define_internal_fn(ccx, &function_name, callee.ty); attributes::set_frame_pointer_elimination(ccx, llfn); - let fcx = FunctionContext::new(ccx, llfn); - let bcx = fcx.get_entry_block(); + let bcx = Builder::entry_block(ccx, llfn); - let mut llargs = get_params(fcx.llfn); + let mut llargs = get_params(llfn); let fn_ret = callee.ty.fn_ret(); let fn_ty = callee.direct_fn_type(ccx, &[]); diff --git a/src/librustc_trans/mir/block.rs b/src/librustc_trans/mir/block.rs index a818694267b..7f720f723b8 100644 --- a/src/librustc_trans/mir/block.rs +++ b/src/librustc_trans/mir/block.rs @@ -302,7 +302,7 @@ impl<'a, 'tcx> MirContext<'a, 'tcx> { // Create the failure block and the conditional branch to it. let lltarget = llblock(self, &bcx, target); - let panic_block = self.fcx.build_new_block("panic"); + let panic_block = bcx.build_new_block("panic"); if expected { bcx.cond_br(cond, lltarget, panic_block.llbb()); } else { @@ -546,7 +546,7 @@ impl<'a, 'tcx> MirContext<'a, 'tcx> { bug!("Cannot use direct operand with an intrinsic call") }; - trans_intrinsic_call(&bcx, self.fcx, callee.ty, &fn_ty, &llargs, dest, + trans_intrinsic_call(&bcx, callee.ty, &fn_ty, &llargs, dest, terminator.source_info.span); if let ReturnDest::IndirectOperand(dst, _) = ret_dest { @@ -793,13 +793,13 @@ impl<'a, 'tcx> MirContext<'a, 'tcx> { let target = self.build_block(target_bb); - let bcx = self.fcx.build_new_block("cleanup"); + let bcx = target.build_new_block("cleanup"); self.landing_pads[target_bb] = Some(bcx.llbb()); let ccx = bcx.ccx; let llpersonality = self.ccx.eh_personality(); let llretty = Type::struct_(ccx, &[Type::i8p(ccx), Type::i32(ccx)], false); - let llretval = bcx.landing_pad(llretty, llpersonality, 1, self.fcx.llfn); + let llretval = bcx.landing_pad(llretty, llpersonality, 1, self.llfn); bcx.set_cleanup(llretval); let slot = self.get_personality_slot(&bcx); bcx.store(llretval, slot, None); @@ -809,7 +809,7 @@ impl<'a, 'tcx> MirContext<'a, 'tcx> { fn unreachable_block(&mut self) -> BasicBlockRef { self.unreachable_block.unwrap_or_else(|| { - let bl = self.fcx.build_new_block("unreachable"); + let bl = self.build_block(mir::START_BLOCK).build_new_block("unreachable"); bl.unreachable(); self.unreachable_block = Some(bl.llbb()); bl.llbb() @@ -817,7 +817,7 @@ impl<'a, 'tcx> MirContext<'a, 'tcx> { } pub fn build_block(&self, bb: mir::BasicBlock) -> Builder<'a, 'tcx> { - let builder = Builder::with_ccx(self.fcx.ccx); + let builder = Builder::with_ccx(self.ccx); builder.position_at_end(self.blocks[bb]); builder } diff --git a/src/librustc_trans/mir/mod.rs b/src/librustc_trans/mir/mod.rs index 94427ee9aef..b7b3663b85a 100644 --- a/src/librustc_trans/mir/mod.rs +++ b/src/librustc_trans/mir/mod.rs @@ -20,7 +20,7 @@ use rustc::ty::TypeFoldable; use session::config::FullDebugInfo; use base; use builder::Builder; -use common::{self, CrateContext, FunctionContext, C_null, Funclet}; +use common::{self, CrateContext, C_null, Funclet}; use debuginfo::{self, declare_local, VariableAccess, VariableKind, FunctionDebugContext}; use monomorphize::{self, Instance}; use abi::FnType; @@ -31,6 +31,7 @@ use syntax::symbol::keywords; use syntax::abi::Abi; use std::iter; +use std::ffi::CString; use rustc_data_structures::bitvec::BitVector; use rustc_data_structures::indexed_vec::{IndexVec, Idx}; @@ -49,7 +50,7 @@ pub struct MirContext<'a, 'tcx:'a> { debug_context: debuginfo::FunctionDebugContext, - fcx: &'a common::FunctionContext<'a, 'tcx>, + llfn: ValueRef, ccx: &'a CrateContext<'a, 'tcx>, @@ -199,7 +200,8 @@ impl<'tcx> LocalRef<'tcx> { /////////////////////////////////////////////////////////////////////////// pub fn trans_mir<'a, 'tcx: 'a>( - fcx: &'a FunctionContext<'a, 'tcx>, + ccx: &'a CrateContext<'a, 'tcx>, + llfn: ValueRef, fn_ty: FnType, mir: &'a Mir<'tcx>, instance: Instance<'tcx>, @@ -208,29 +210,36 @@ pub fn trans_mir<'a, 'tcx: 'a>( ) { debug!("fn_ty: {:?}", fn_ty); let debug_context = - debuginfo::create_function_debug_context(fcx.ccx, instance, sig, abi, fcx.llfn, mir); - let bcx = fcx.get_entry_block(); + debuginfo::create_function_debug_context(ccx, instance, sig, abi, llfn, mir); + let bcx = Builder::entry_block(ccx, llfn); let cleanup_kinds = analyze::cleanup_kinds(&mir); // Allocate a `Block` for every basic block let block_bcxs: IndexVec = mir.basic_blocks().indices().map(|bb| { - if bb == mir::START_BLOCK { - fcx.new_block("start") + let name = if bb == mir::START_BLOCK { + CString::new("start").unwrap() } else { - fcx.new_block(&format!("{:?}", bb)) + CString::new(format!("{:?}", bb)).unwrap() + }; + unsafe { + llvm::LLVMAppendBasicBlockInContext( + ccx.llcx(), + llfn, + name.as_ptr() + ) } }).collect(); // Compute debuginfo scopes from MIR scopes. - let scopes = debuginfo::create_mir_scopes(fcx, mir, &debug_context); + let scopes = debuginfo::create_mir_scopes(ccx, mir, &debug_context); let mut mircx = MirContext { mir: mir, - fcx: fcx, + llfn: llfn, fn_ty: fn_ty, - ccx: fcx.ccx, + ccx: ccx, llpersonalityslot: None, blocks: block_bcxs, unreachable_block: None, @@ -281,7 +290,7 @@ pub fn trans_mir<'a, 'tcx: 'a>( // Temporary or return pointer if local == mir::RETURN_POINTER && mircx.fn_ty.ret.is_indirect() { debug!("alloc: {:?} (return pointer) -> lvalue", local); - let llretptr = llvm::get_param(fcx.llfn, 0); + let llretptr = llvm::get_param(llfn, 0); LocalRef::Lvalue(LvalueRef::new_sized(llretptr, LvalueTy::from_ty(ty))) } else if lvalue_locals.contains(local.index()) { debug!("alloc: {:?} -> lvalue", local); @@ -319,7 +328,7 @@ pub fn trans_mir<'a, 'tcx: 'a>( if let CleanupKind::Funclet = *cleanup_kind { let bcx = mircx.build_block(bb); bcx.set_personality_fn(mircx.ccx.eh_personality()); - if base::wants_msvc_seh(fcx.ccx.sess()) { + if base::wants_msvc_seh(ccx.sess()) { return Some(Funclet::new(bcx.cleanup_pad(None, &[]))); } } @@ -358,7 +367,6 @@ fn arg_local_refs<'a, 'tcx>(bcx: &Builder<'a, 'tcx>, lvalue_locals: &BitVector) -> Vec> { let mir = mircx.mir; - let fcx = mircx.fcx; let tcx = bcx.ccx.tcx(); let mut idx = 0; let mut llarg_idx = mircx.fn_ty.ret.is_indirect() as usize; @@ -433,7 +441,7 @@ fn arg_local_refs<'a, 'tcx>(bcx: &Builder<'a, 'tcx>, if arg.pad.is_some() { llarg_idx += 1; } - let llarg = llvm::get_param(fcx.llfn, llarg_idx as c_uint); + let llarg = llvm::get_param(bcx.llfn(), llarg_idx as c_uint); llarg_idx += 1; llarg } else if !lvalue_locals.contains(local.index()) && @@ -449,13 +457,13 @@ fn arg_local_refs<'a, 'tcx>(bcx: &Builder<'a, 'tcx>, if arg.pad.is_some() { llarg_idx += 1; } - let llarg = llvm::get_param(fcx.llfn, llarg_idx as c_uint); + let llarg = llvm::get_param(bcx.llfn(), llarg_idx as c_uint); llarg_idx += 1; let val = if common::type_is_fat_ptr(bcx.ccx, arg_ty) { let meta = &mircx.fn_ty.args[idx]; idx += 1; assert_eq!((meta.cast, meta.pad), (None, None)); - let llmeta = llvm::get_param(fcx.llfn, llarg_idx as c_uint); + let llmeta = llvm::get_param(bcx.llfn(), llarg_idx as c_uint); llarg_idx += 1; OperandValue::Pair(llarg, llmeta) } else {