diff options
| author | Mark-Simulacrum <mark.simulacrum@gmail.com> | 2016-12-16 08:28:20 -0700 |
|---|---|---|
| committer | Mark Simulacrum <mark.simulacrum@gmail.com> | 2016-12-20 20:02:52 -0700 |
| commit | 28f511cfbd9faaec4cc54ea002b43bacb3da497c (patch) | |
| tree | 578c7aeb0c4f8dc39e58b2fe9627d1ecec6eed3b /src | |
| parent | e0ccc81bbf0069bf968a741594dd81338cf98ac3 (diff) | |
| download | rust-28f511cfbd9faaec4cc54ea002b43bacb3da497c.tar.gz rust-28f511cfbd9faaec4cc54ea002b43bacb3da497c.zip | |
Remove global Builder
Diffstat (limited to 'src')
| -rw-r--r-- | src/librustc_trans/base.rs | 96 | ||||
| -rw-r--r-- | src/librustc_trans/common.rs | 104 | ||||
| -rw-r--r-- | src/librustc_trans/context.rs | 5 |
3 files changed, 99 insertions, 106 deletions
diff --git a/src/librustc_trans/base.rs b/src/librustc_trans/base.rs index 06a368e896c..4f346f8897e 100644 --- a/src/librustc_trans/base.rs +++ b/src/librustc_trans/base.rs @@ -53,7 +53,7 @@ use builder::{Builder, noname}; use callee::{Callee}; use common::{BlockAndBuilder, C_bool, C_bytes_in_context, C_i32, C_uint}; use collector::{self, TransItemCollectionMode}; -use common::{C_null, C_struct_in_context, C_u64, C_u8, C_undef}; +use common::{C_struct_in_context, C_u64, C_u8, C_undef}; use common::{CrateContext, FunctionContext}; use common::{fulfill_obligation}; use common::{type_is_zero_size, val_ty}; @@ -77,10 +77,9 @@ use value::Value; use Disr; use util::nodemap::{NodeSet, FxHashMap, FxHashSet}; -use arena::TypedArena; use libc::c_uint; use std::ffi::{CStr, CString}; -use std::cell::{Cell, RefCell}; +use std::cell::RefCell; use std::ptr; use std::rc::Rc; use std::str; @@ -655,97 +654,6 @@ pub fn alloca(cx: &BlockAndBuilder, ty: Type, name: &str) -> ValueRef { } impl<'blk, 'tcx> FunctionContext<'blk, 'tcx> { - /// Create a function context for the given function. - /// Beware that you must call `fcx.init` or `fcx.bind_args` - /// before doing anything with the returned function context. - pub fn new(ccx: &'blk CrateContext<'blk, 'tcx>, - llfndecl: ValueRef, - fn_ty: FnType, - definition: Option<(Instance<'tcx>, &ty::FnSig<'tcx>, Abi)>) - -> FunctionContext<'blk, 'tcx> { - let (param_substs, def_id) = match definition { - Some((instance, ..)) => { - common::validate_substs(instance.substs); - (instance.substs, Some(instance.def)) - } - None => (ccx.tcx().intern_substs(&[]), None) - }; - - let local_id = def_id.and_then(|id| ccx.tcx().map.as_local_node_id(id)); - - debug!("FunctionContext::new({})", - definition.map_or(String::new(), |d| d.0.to_string())); - - let no_debug = if let Some(id) = local_id { - ccx.tcx().map.attrs(id) - .iter().any(|item| item.check_name("no_debug")) - } else if let Some(def_id) = def_id { - ccx.sess().cstore.item_attrs(def_id) - .iter().any(|item| item.check_name("no_debug")) - } else { - false - }; - - let mir = def_id.map(|id| ccx.tcx().item_mir(id)); - - let debug_context = if let (false, Some((instance, sig, abi)), &Some(ref mir)) = - (no_debug, definition, &mir) { - debuginfo::create_function_debug_context(ccx, instance, sig, abi, llfndecl, mir) - } else { - debuginfo::empty_function_debug_context(ccx) - }; - - FunctionContext { - mir: mir, - llfn: llfndecl, - llretslotptr: Cell::new(None), - param_env: ccx.tcx().empty_parameter_environment(), - alloca_insert_pt: Cell::new(None), - landingpad_alloca: Cell::new(None), - fn_ty: fn_ty, - param_substs: param_substs, - span: None, - funclet_arena: TypedArena::new(), - ccx: ccx, - debug_context: debug_context, - } - } - - /// Performs setup on a newly created function, creating the entry - /// scope block and allocating space for the return pointer. - pub fn init(&'blk self, skip_retptr: bool) -> BlockAndBuilder<'blk, 'tcx> { - let entry_bcx = self.build_new_block("entry-block"); - - // Use a dummy instruction as the insertion point for all allocas. - // This is later removed in FunctionContext::cleanup. - self.alloca_insert_pt.set(Some(unsafe { - entry_bcx.load(C_null(Type::i8p(self.ccx))); - llvm::LLVMGetFirstInstruction(entry_bcx.llbb()) - })); - - if !self.fn_ty.ret.is_ignore() && !skip_retptr { - // We normally allocate the llretslotptr, unless we - // have been instructed to skip it for immediate return - // values, or there is nothing to return at all. - - // 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 - // final ret value - let llty = self.fn_ty.ret.memory_ty(self.ccx); - // But if there are no nested returns, we skip the indirection - // and have a single retslot - let slot = if self.fn_ty.ret.is_indirect() { - get_param(self.llfn, 0) - } else { - self.alloca(llty, "sret_slot") - }; - - self.llretslotptr.set(Some(slot)); - } - - entry_bcx - } - /// Ties up the llstaticallocas -> llloadenv -> lltop edges, /// and builds the return block. pub fn finish(&'blk self, ret_cx: &BlockAndBuilder<'blk, 'tcx>) { diff --git a/src/librustc_trans/common.rs b/src/librustc_trans/common.rs index 6306312c58e..e4c3d6497fd 100644 --- a/src/librustc_trans/common.rs +++ b/src/librustc_trans/common.rs @@ -15,7 +15,8 @@ use session::Session; use llvm; use llvm::{ValueRef, BasicBlockRef, BuilderRef, ContextRef, TypeKind}; -use llvm::{True, False, Bool, OperandBundleDef}; +use llvm::{True, False, Bool, OperandBundleDef, get_param}; +use monomorphize::Instance; use rustc::hir::def::Def; use rustc::hir::def_id::DefId; use rustc::hir::map::DefPathData; @@ -311,18 +312,109 @@ pub struct FunctionContext<'a, 'tcx: 'a> { // Used and maintained by the debuginfo module. pub debug_context: debuginfo::FunctionDebugContext, + + owned_builder: OwnedBuilder<'a, 'tcx>, } impl<'a, 'tcx> FunctionContext<'a, 'tcx> { + /// Create a function context for the given function. + /// Beware that you must call `fcx.init` or `fcx.bind_args` + /// before doing anything with the returned function context. + pub fn new(ccx: &'a CrateContext<'a, 'tcx>, + llfndecl: ValueRef, + fn_ty: FnType, + definition: Option<(Instance<'tcx>, &ty::FnSig<'tcx>, Abi)>) + -> FunctionContext<'a, 'tcx> { + let (param_substs, def_id) = match definition { + Some((instance, ..)) => { + validate_substs(instance.substs); + (instance.substs, Some(instance.def)) + } + None => (ccx.tcx().intern_substs(&[]), None) + }; + + let local_id = def_id.and_then(|id| ccx.tcx().map.as_local_node_id(id)); + + debug!("FunctionContext::new({})", definition.map_or(String::new(), |d| d.0.to_string())); + + let no_debug = if let Some(id) = local_id { + ccx.tcx().map.attrs(id).iter().any(|item| item.check_name("no_debug")) + } else if let Some(def_id) = def_id { + ccx.sess().cstore.item_attrs(def_id).iter().any(|item| item.check_name("no_debug")) + } else { + false + }; + + let mir = def_id.map(|id| ccx.tcx().item_mir(id)); + + let debug_context = if let (false, Some((instance, sig, abi)), &Some(ref mir)) = + (no_debug, definition, &mir) { + debuginfo::create_function_debug_context(ccx, instance, sig, abi, llfndecl, mir) + } else { + debuginfo::empty_function_debug_context(ccx) + }; + + FunctionContext { + mir: mir, + llfn: llfndecl, + llretslotptr: Cell::new(None), + param_env: ccx.tcx().empty_parameter_environment(), + alloca_insert_pt: Cell::new(None), + landingpad_alloca: Cell::new(None), + fn_ty: fn_ty, + param_substs: param_substs, + span: None, + funclet_arena: TypedArena::new(), + ccx: ccx, + debug_context: debug_context, + owned_builder: OwnedBuilder::new_with_ccx(ccx), + } + } + + /// Performs setup on a newly created function, creating the entry + /// scope block and allocating space for the return pointer. + pub fn init(&'a self, skip_retptr: bool) -> BlockAndBuilder<'a, 'tcx> { + let entry_bcx = self.build_new_block("entry-block"); + + // Use a dummy instruction as the insertion point for all allocas. + // This is later removed in FunctionContext::cleanup. + self.alloca_insert_pt.set(Some(unsafe { + entry_bcx.load(C_null(Type::i8p(self.ccx))); + llvm::LLVMGetFirstInstruction(entry_bcx.llbb()) + })); + + self.owned_builder.builder.position_at_start(entry_bcx.llbb()); + + if !self.fn_ty.ret.is_ignore() && !skip_retptr { + // We normally allocate the llretslotptr, unless we + // have been instructed to skip it for immediate return + // values, or there is nothing to return at all. + + // 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 + // final ret value + let llty = self.fn_ty.ret.memory_ty(self.ccx); + // But if there are no nested returns, we skip the indirection + // and have a single retslot + let slot = if self.fn_ty.ret.is_indirect() { + get_param(self.llfn, 0) + } else { + self.alloca(llty, "sret_slot") + }; + + self.llretslotptr.set(Some(slot)); + } + + entry_bcx + } + pub fn mir(&self) -> Ref<'tcx, Mir<'tcx>> { self.mir.as_ref().map(Ref::clone).expect("fcx.mir was empty") } pub fn cleanup(&self) { unsafe { - llvm::LLVMInstructionEraseFromParent(self.alloca_insert_pt - .get() - .unwrap()); + llvm::LLVMInstructionEraseFromParent(self.alloca_insert_pt.get().unwrap()); } } @@ -431,9 +523,7 @@ impl<'a, 'tcx> FunctionContext<'a, 'tcx> { } pub fn alloca(&self, ty: Type, name: &str) -> ValueRef { - let b = self.ccx.builder(); - b.position_before(self.alloca_insert_pt.get().unwrap()); - b.alloca(ty, name) + self.owned_builder.builder.alloca(ty, name) } } diff --git a/src/librustc_trans/context.rs b/src/librustc_trans/context.rs index 6435b20eeaa..4f524af2945 100644 --- a/src/librustc_trans/context.rs +++ b/src/librustc_trans/context.rs @@ -17,7 +17,6 @@ use rustc::hir::def::ExportMap; use rustc::hir::def_id::DefId; use rustc::traits; use base; -use builder::Builder; use common::BuilderRef_res; use debuginfo; use declare; @@ -731,10 +730,6 @@ impl<'b, 'tcx> CrateContext<'b, 'tcx> { &self.shared.tcx.sess } - pub fn builder<'a>(&'a self) -> Builder<'a, 'tcx> { - Builder::new(self) - } - pub fn raw_builder<'a>(&'a self) -> BuilderRef { self.local().builder.b } |
