mirror of
https://github.com/rust-lang/rust.git
synced 2024-11-29 10:13:54 +00:00
Replace init with get_entry_block.
This commit is contained in:
parent
cbbdb73eb0
commit
c4f6173af8
@ -657,11 +657,11 @@ impl<'blk, 'tcx> FunctionContext<'blk, 'tcx> {
|
|||||||
|
|
||||||
// Builds the return block for a function.
|
// Builds the return block for a function.
|
||||||
pub fn build_return_block(&self, ret_cx: &BlockAndBuilder<'blk, 'tcx>) {
|
pub fn build_return_block(&self, ret_cx: &BlockAndBuilder<'blk, 'tcx>) {
|
||||||
if self.llretslotptr.get().is_none() || self.fn_ty.ret.is_indirect() {
|
if self.llretslotptr.is_none() || self.fn_ty.ret.is_indirect() {
|
||||||
return ret_cx.ret_void();
|
return ret_cx.ret_void();
|
||||||
}
|
}
|
||||||
|
|
||||||
let retslot = self.llretslotptr.get().unwrap();
|
let retslot = self.llretslotptr.unwrap();
|
||||||
let retptr = Value(retslot);
|
let retptr = Value(retslot);
|
||||||
let llty = self.fn_ty.ret.original_ty;
|
let llty = self.fn_ty.ret.original_ty;
|
||||||
match (retptr.get_dominating_store(ret_cx), self.fn_ty.ret.cast) {
|
match (retptr.get_dominating_store(ret_cx), self.fn_ty.ret.cast) {
|
||||||
@ -751,7 +751,7 @@ pub fn trans_instance<'a, 'tcx>(ccx: &CrateContext<'a, 'tcx>, instance: Instance
|
|||||||
|
|
||||||
let fn_ty = FnType::new(ccx, abi, &sig, &[]);
|
let fn_ty = FnType::new(ccx, abi, &sig, &[]);
|
||||||
|
|
||||||
let fcx = FunctionContext::new(ccx, lldecl, fn_ty, Some((instance, &sig, abi)));
|
let fcx = FunctionContext::new(ccx, lldecl, fn_ty, Some((instance, &sig, abi)), true);
|
||||||
|
|
||||||
if fcx.mir.is_none() {
|
if fcx.mir.is_none() {
|
||||||
bug!("attempted translation of `{}` w/o MIR", instance);
|
bug!("attempted translation of `{}` w/o MIR", instance);
|
||||||
@ -774,11 +774,11 @@ 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 sig = ccx.tcx().erase_late_bound_regions_and_normalize(&ctor_ty.fn_sig());
|
||||||
let fn_ty = FnType::new(ccx, Abi::Rust, &sig, &[]);
|
let fn_ty = FnType::new(ccx, Abi::Rust, &sig, &[]);
|
||||||
|
|
||||||
let fcx = FunctionContext::new(ccx, llfndecl, fn_ty, None);
|
let fcx = FunctionContext::new(ccx, llfndecl, fn_ty, None, false);
|
||||||
let bcx = fcx.init(false);
|
let bcx = fcx.get_entry_block();
|
||||||
|
|
||||||
if !fcx.fn_ty.ret.is_ignore() {
|
if !fcx.fn_ty.ret.is_ignore() {
|
||||||
let dest = fcx.llretslotptr.get().unwrap();
|
let dest = fcx.llretslotptr.unwrap();
|
||||||
let dest_val = adt::MaybeSizedValue::sized(dest); // Can return unsized value
|
let dest_val = adt::MaybeSizedValue::sized(dest); // Can return unsized value
|
||||||
let mut llarg_idx = fcx.fn_ty.ret.is_indirect() as usize;
|
let mut llarg_idx = fcx.fn_ty.ret.is_indirect() as usize;
|
||||||
let mut arg_idx = 0;
|
let mut arg_idx = 0;
|
||||||
|
@ -347,8 +347,8 @@ fn trans_fn_once_adapter_shim<'a, 'tcx>(
|
|||||||
let lloncefn = declare::define_internal_fn(ccx, &function_name, llonce_fn_ty);
|
let lloncefn = declare::define_internal_fn(ccx, &function_name, llonce_fn_ty);
|
||||||
attributes::set_frame_pointer_elimination(ccx, lloncefn);
|
attributes::set_frame_pointer_elimination(ccx, lloncefn);
|
||||||
|
|
||||||
let fcx = FunctionContext::new(ccx, lloncefn, fn_ty, None);
|
let fcx = FunctionContext::new(ccx, lloncefn, fn_ty, None, false);
|
||||||
let mut bcx = fcx.init(false);
|
let mut bcx = fcx.get_entry_block();
|
||||||
|
|
||||||
// the first argument (`self`) will be the (by value) closure env.
|
// the first argument (`self`) will be the (by value) closure env.
|
||||||
|
|
||||||
@ -378,8 +378,6 @@ fn trans_fn_once_adapter_shim<'a, 'tcx>(
|
|||||||
llargs[self_idx] = llenv;
|
llargs[self_idx] = llenv;
|
||||||
}
|
}
|
||||||
|
|
||||||
let dest = fcx.llretslotptr.get();
|
|
||||||
|
|
||||||
let callee = Callee {
|
let callee = Callee {
|
||||||
data: Fn(llreffn),
|
data: Fn(llreffn),
|
||||||
ty: llref_fn_ty
|
ty: llref_fn_ty
|
||||||
@ -392,7 +390,7 @@ fn trans_fn_once_adapter_shim<'a, 'tcx>(
|
|||||||
let fn_ty = callee.direct_fn_type(bcx.ccx(), &[]);
|
let fn_ty = callee.direct_fn_type(bcx.ccx(), &[]);
|
||||||
|
|
||||||
let first_llarg = if fn_ty.ret.is_indirect() {
|
let first_llarg = if fn_ty.ret.is_indirect() {
|
||||||
dest
|
fcx.llretslotptr
|
||||||
} else {
|
} else {
|
||||||
None
|
None
|
||||||
};
|
};
|
||||||
@ -411,7 +409,7 @@ fn trans_fn_once_adapter_shim<'a, 'tcx>(
|
|||||||
fn_ty.apply_attrs_callsite(llret);
|
fn_ty.apply_attrs_callsite(llret);
|
||||||
|
|
||||||
if !fn_ty.ret.is_indirect() {
|
if !fn_ty.ret.is_indirect() {
|
||||||
if let Some(llretslot) = dest {
|
if let Some(llretslot) = fcx.llretslotptr {
|
||||||
fn_ty.ret.store(&bcx, llret, llretslot);
|
fn_ty.ret.store(&bcx, llret, llretslot);
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
@ -521,8 +519,8 @@ fn trans_fn_pointer_shim<'a, 'tcx>(
|
|||||||
let llfn = declare::define_internal_fn(ccx, &function_name, tuple_fn_ty);
|
let llfn = declare::define_internal_fn(ccx, &function_name, tuple_fn_ty);
|
||||||
attributes::set_frame_pointer_elimination(ccx, llfn);
|
attributes::set_frame_pointer_elimination(ccx, llfn);
|
||||||
//
|
//
|
||||||
let fcx = FunctionContext::new(ccx, llfn, fn_ty, None);
|
let fcx = FunctionContext::new(ccx, llfn, fn_ty, None, false);
|
||||||
let bcx = fcx.init(false);
|
let bcx = fcx.get_entry_block();
|
||||||
|
|
||||||
let llargs = get_params(fcx.llfn);
|
let llargs = get_params(fcx.llfn);
|
||||||
|
|
||||||
@ -536,13 +534,11 @@ fn trans_fn_pointer_shim<'a, 'tcx>(
|
|||||||
}
|
}
|
||||||
});
|
});
|
||||||
|
|
||||||
let dest = fcx.llretslotptr.get();
|
|
||||||
|
|
||||||
let callee = Callee {
|
let callee = Callee {
|
||||||
data: Fn(llfnpointer),
|
data: Fn(llfnpointer),
|
||||||
ty: bare_fn_ty
|
ty: bare_fn_ty
|
||||||
};
|
};
|
||||||
let bcx = callee.call(bcx, &llargs[(self_idx + 1)..], dest, None).0;
|
let bcx = callee.call(bcx, &llargs[(self_idx + 1)..], fcx.llretslotptr, None).0;
|
||||||
fcx.finish(&bcx);
|
fcx.finish(&bcx);
|
||||||
|
|
||||||
ccx.fn_pointer_shims().borrow_mut().insert(bare_fn_ty_maybe_ref, llfn);
|
ccx.fn_pointer_shims().borrow_mut().insert(bare_fn_ty_maybe_ref, llfn);
|
||||||
|
@ -276,7 +276,7 @@ pub struct FunctionContext<'a, 'tcx: 'a> {
|
|||||||
// immediate, this points to an alloca in the function. Otherwise, it's a
|
// immediate, this points to an alloca in the function. Otherwise, it's a
|
||||||
// pointer to the hidden first parameter of the function. After function
|
// pointer to the hidden first parameter of the function. After function
|
||||||
// construction, this should always be Some.
|
// construction, this should always be Some.
|
||||||
pub llretslotptr: Cell<Option<ValueRef>>,
|
pub llretslotptr: Option<ValueRef>,
|
||||||
|
|
||||||
// These pub elements: "hoisted basic blocks" containing
|
// These pub elements: "hoisted basic blocks" containing
|
||||||
// administrative activities that have to happen in only one place in
|
// administrative activities that have to happen in only one place in
|
||||||
@ -311,13 +311,14 @@ pub struct FunctionContext<'a, 'tcx: 'a> {
|
|||||||
|
|
||||||
impl<'a, 'tcx> FunctionContext<'a, 'tcx> {
|
impl<'a, 'tcx> FunctionContext<'a, 'tcx> {
|
||||||
/// Create a function context for the given function.
|
/// Create a function context for the given function.
|
||||||
/// Beware that you must call `fcx.init` before doing anything with the returned function
|
/// Call FunctionContext::get_entry_block for the first entry block.
|
||||||
/// context.
|
pub fn new(
|
||||||
pub fn new(ccx: &'a CrateContext<'a, 'tcx>,
|
ccx: &'a CrateContext<'a, 'tcx>,
|
||||||
llfndecl: ValueRef,
|
llfndecl: ValueRef,
|
||||||
fn_ty: FnType,
|
fn_ty: FnType,
|
||||||
definition: Option<(Instance<'tcx>, &ty::FnSig<'tcx>, Abi)>)
|
definition: Option<(Instance<'tcx>, &ty::FnSig<'tcx>, Abi)>,
|
||||||
-> FunctionContext<'a, 'tcx> {
|
skip_retptr: bool,
|
||||||
|
) -> FunctionContext<'a, 'tcx> {
|
||||||
let (param_substs, def_id) = match definition {
|
let (param_substs, def_id) = match definition {
|
||||||
Some((instance, ..)) => {
|
Some((instance, ..)) => {
|
||||||
validate_substs(instance.substs);
|
validate_substs(instance.substs);
|
||||||
@ -350,7 +351,7 @@ impl<'a, 'tcx> FunctionContext<'a, 'tcx> {
|
|||||||
let mut fcx = FunctionContext {
|
let mut fcx = FunctionContext {
|
||||||
mir: mir,
|
mir: mir,
|
||||||
llfn: llfndecl,
|
llfn: llfndecl,
|
||||||
llretslotptr: Cell::new(None),
|
llretslotptr: None,
|
||||||
param_env: ccx.tcx().empty_parameter_environment(),
|
param_env: ccx.tcx().empty_parameter_environment(),
|
||||||
alloca_insert_pt: None,
|
alloca_insert_pt: None,
|
||||||
landingpad_alloca: Cell::new(None),
|
landingpad_alloca: Cell::new(None),
|
||||||
@ -372,31 +373,28 @@ impl<'a, 'tcx> FunctionContext<'a, 'tcx> {
|
|||||||
// This is later removed in the drop of FunctionContext.
|
// This is later removed in the drop of FunctionContext.
|
||||||
fcx.alloca_insert_pt = Some(val);
|
fcx.alloca_insert_pt = Some(val);
|
||||||
|
|
||||||
fcx
|
// 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.
|
||||||
/// Performs setup on a newly created function, creating the entry
|
if !fcx.fn_ty.ret.is_ignore() && !skip_retptr {
|
||||||
/// scope block and allocating space for the return pointer.
|
|
||||||
pub fn init(&'a self, skip_retptr: bool) -> BlockAndBuilder<'a, 'tcx> {
|
|
||||||
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.
|
|
||||||
|
|
||||||
// But if there are no nested returns, we skip the indirection
|
// But if there are no nested returns, we skip the indirection
|
||||||
// and have a single retslot
|
// and have a single retslot
|
||||||
let slot = if self.fn_ty.ret.is_indirect() {
|
let slot = if fcx.fn_ty.ret.is_indirect() {
|
||||||
get_param(self.llfn, 0)
|
get_param(fcx.llfn, 0)
|
||||||
} else {
|
} else {
|
||||||
// We create an alloca to hold a pointer of type `ret.original_ty`
|
// 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
|
// which will hold the pointer to the right alloca which has the
|
||||||
// final ret value
|
// final ret value
|
||||||
self.alloca(self.fn_ty.ret.memory_ty(self.ccx), "sret_slot")
|
fcx.alloca(fcx.fn_ty.ret.memory_ty(ccx), "sret_slot")
|
||||||
};
|
};
|
||||||
|
|
||||||
self.llretslotptr.set(Some(slot));
|
fcx.llretslotptr = Some(slot);
|
||||||
}
|
}
|
||||||
|
|
||||||
|
fcx
|
||||||
|
}
|
||||||
|
|
||||||
|
pub fn get_entry_block(&'a self) -> BlockAndBuilder<'a, 'tcx> {
|
||||||
BlockAndBuilder::new(unsafe {
|
BlockAndBuilder::new(unsafe {
|
||||||
llvm::LLVMGetFirstBasicBlock(self.llfn)
|
llvm::LLVMGetFirstBasicBlock(self.llfn)
|
||||||
}, self)
|
}, self)
|
||||||
|
@ -202,9 +202,8 @@ pub fn implement_drop_glue<'a, 'tcx>(ccx: &CrateContext<'a, 'tcx>,
|
|||||||
assert_eq!(g.ty(), get_drop_glue_type(tcx, g.ty()));
|
assert_eq!(g.ty(), get_drop_glue_type(tcx, g.ty()));
|
||||||
let (llfn, fn_ty) = ccx.drop_glues().borrow().get(&g).unwrap().clone();
|
let (llfn, fn_ty) = ccx.drop_glues().borrow().get(&g).unwrap().clone();
|
||||||
|
|
||||||
let fcx = FunctionContext::new(ccx, llfn, fn_ty, None);
|
let fcx = FunctionContext::new(ccx, llfn, fn_ty, None, false);
|
||||||
|
let bcx = fcx.get_entry_block();
|
||||||
let bcx = fcx.init(false);
|
|
||||||
|
|
||||||
ccx.stats().n_glues_created.set(ccx.stats().n_glues_created.get() + 1);
|
ccx.stats().n_glues_created.set(ccx.stats().n_glues_created.get() + 1);
|
||||||
// All glue functions take values passed *by alias*; this is a
|
// All glue functions take values passed *by alias*; this is a
|
||||||
|
@ -965,8 +965,8 @@ fn gen_fn<'a, 'tcx>(fcx: &FunctionContext<'a, 'tcx>,
|
|||||||
sig: ty::Binder(sig)
|
sig: ty::Binder(sig)
|
||||||
}));
|
}));
|
||||||
let llfn = declare::define_internal_fn(ccx, name, rust_fn_ty);
|
let llfn = declare::define_internal_fn(ccx, name, rust_fn_ty);
|
||||||
let fcx = FunctionContext::new(ccx, llfn, fn_ty, None);
|
let fcx = FunctionContext::new(ccx, llfn, fn_ty, None, true);
|
||||||
trans(fcx.init(true));
|
trans(fcx.get_entry_block());
|
||||||
llfn
|
llfn
|
||||||
}
|
}
|
||||||
|
|
||||||
|
@ -81,12 +81,12 @@ pub fn trans_object_shim<'a, 'tcx>(ccx: &'a CrateContext<'a, 'tcx>,
|
|||||||
let llfn = declare::define_internal_fn(ccx, &function_name, callee.ty);
|
let llfn = declare::define_internal_fn(ccx, &function_name, callee.ty);
|
||||||
attributes::set_frame_pointer_elimination(ccx, llfn);
|
attributes::set_frame_pointer_elimination(ccx, llfn);
|
||||||
|
|
||||||
let fcx = FunctionContext::new(ccx, llfn, fn_ty, None);
|
let fcx = FunctionContext::new(ccx, llfn, fn_ty, None, false);
|
||||||
let mut bcx = fcx.init(false);
|
let mut bcx = fcx.get_entry_block();
|
||||||
|
|
||||||
let dest = fcx.llretslotptr.get();
|
|
||||||
let llargs = get_params(fcx.llfn);
|
let llargs = get_params(fcx.llfn);
|
||||||
bcx = callee.call(bcx, &llargs[fcx.fn_ty.ret.is_indirect() as usize..], dest, None).0;
|
bcx = callee.call(bcx, &llargs[fcx.fn_ty.ret.is_indirect() as usize..], fcx.llretslotptr,
|
||||||
|
None).0;
|
||||||
|
|
||||||
fcx.finish(&bcx);
|
fcx.finish(&bcx);
|
||||||
|
|
||||||
|
@ -180,7 +180,7 @@ impl<'tcx> LocalRef<'tcx> {
|
|||||||
///////////////////////////////////////////////////////////////////////////
|
///////////////////////////////////////////////////////////////////////////
|
||||||
|
|
||||||
pub fn trans_mir<'blk, 'tcx: 'blk>(fcx: &'blk FunctionContext<'blk, 'tcx>) {
|
pub fn trans_mir<'blk, 'tcx: 'blk>(fcx: &'blk FunctionContext<'blk, 'tcx>) {
|
||||||
let bcx = fcx.init(true);
|
let bcx = fcx.get_entry_block();
|
||||||
let mir = fcx.mir();
|
let mir = fcx.mir();
|
||||||
|
|
||||||
// Analyze the temps to determine which must be lvalues
|
// Analyze the temps to determine which must be lvalues
|
||||||
|
Loading…
Reference in New Issue
Block a user