Remove fn_ty from FunctionContext

This commit is contained in:
Mark Simulacrum 2016-12-19 19:16:36 -07:00
parent 15b9b27bb0
commit bd009dc444
8 changed files with 40 additions and 50 deletions

View File

@ -598,10 +598,9 @@ 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, fn_ty);
let fcx = FunctionContext::new(ccx, lldecl);
let mir = ccx.tcx().item_mir(instance.def);
mir::trans_mir(&fcx, &mir, instance, &sig, abi);
mir::trans_mir(&fcx, fn_ty, &mir, instance, &sig, abi);
}
pub fn trans_ctor_shim<'a, 'tcx>(ccx: &CrateContext<'a, 'tcx>,
@ -618,28 +617,28 @@ 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, fn_ty);
let fcx = FunctionContext::new(ccx, llfndecl);
let bcx = fcx.get_entry_block();
if !fcx.fn_ty.ret.is_ignore() {
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 fcx.fn_ty.ret.is_indirect() {
let dest = if fn_ty.ret.is_indirect() {
get_param(fcx.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
// final ret value
fcx.alloca(fcx.fn_ty.ret.memory_ty(ccx), "sret_slot")
fcx.alloca(fn_ty.ret.memory_ty(ccx), "sret_slot")
};
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 = fn_ty.ret.is_indirect() as usize;
let mut arg_idx = 0;
for (i, arg_ty) in sig.inputs().iter().enumerate() {
let lldestptr = adt::trans_field_ptr(&bcx, sig.output(), dest_val, Disr::from(disr), i);
let arg = &fcx.fn_ty.args[arg_idx];
let arg = &fn_ty.args[arg_idx];
arg_idx += 1;
if common::type_is_fat_ptr(bcx.ccx, arg_ty) {
let meta = &fcx.fn_ty.args[arg_idx];
let meta = &fn_ty.args[arg_idx];
arg_idx += 1;
arg.store_fn_arg(&bcx, &mut llarg_idx, get_dataptr(&bcx, lldestptr));
meta.store_fn_arg(&bcx, &mut llarg_idx, get_meta(&bcx, lldestptr));
@ -649,14 +648,14 @@ pub fn trans_ctor_shim<'a, 'tcx>(ccx: &CrateContext<'a, 'tcx>,
}
adt::trans_set_discr(&bcx, sig.output(), dest, disr);
if fcx.fn_ty.ret.is_indirect() {
if fn_ty.ret.is_indirect() {
bcx.ret_void();
return;
}
if let Some(cast_ty) = fcx.fn_ty.ret.cast {
if let Some(cast_ty) = fn_ty.ret.cast {
let load = bcx.load(bcx.pointercast(dest, cast_ty.ptr_to()));
let llalign = llalign_of_min(ccx, fcx.fn_ty.ret.ty);
let llalign = llalign_of_min(ccx, fn_ty.ret.ty);
unsafe {
llvm::LLVMSetAlignment(load, llalign);
}

View File

@ -328,7 +328,8 @@ fn trans_fn_once_adapter_shim<'a, 'tcx>(
let lloncefn = declare::define_internal_fn(ccx, &function_name, llonce_fn_ty);
attributes::set_frame_pointer_elimination(ccx, lloncefn);
let fcx = FunctionContext::new(ccx, lloncefn, fn_ty);
let orig_fn_ty = fn_ty;
let fcx = FunctionContext::new(ccx, lloncefn);
let mut bcx = fcx.get_entry_block();
let callee = Callee {
@ -342,7 +343,7 @@ fn trans_fn_once_adapter_shim<'a, 'tcx>(
let fn_ret = callee.ty.fn_ret();
let fn_ty = callee.direct_fn_type(bcx.ccx, &[]);
let idx = fn_ty.ret.is_indirect() as usize;
let env_arg = &fcx.fn_ty.args[0];
let env_arg = &orig_fn_ty.args[0];
let llenv = if env_arg.is_indirect() {
llargs[idx]
} else {
@ -494,12 +495,12 @@ 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, fn_ty);
let fcx = FunctionContext::new(ccx, llfn);
let bcx = fcx.get_entry_block();
let mut llargs = get_params(fcx.llfn);
let self_arg = llargs.remove(fcx.fn_ty.ret.is_indirect() as usize);
let self_arg = llargs.remove(fn_ty.ret.is_indirect() as usize);
let llfnpointer = llfnpointer.unwrap_or_else(|| {
// the first argument (`self`) will be ptr to the fn pointer
if is_by_ref {

View File

@ -21,7 +21,7 @@ use rustc::hir::def_id::DefId;
use rustc::hir::map::DefPathData;
use rustc::util::common::MemoizationMap;
use middle::lang_items::LangItem;
use abi::{Abi, FnType};
use abi::Abi;
use base;
use builder::Builder;
use callee::Callee;
@ -236,9 +236,6 @@ pub struct FunctionContext<'a, 'tcx: 'a> {
// allocas, so that LLVM will coalesce them into a single alloca call.
alloca_insert_pt: Option<ValueRef>,
// Describes the return/argument LLVM types and their ABI handling.
pub fn_ty: FnType,
// This function's enclosing crate context.
pub ccx: &'a CrateContext<'a, 'tcx>,
@ -248,15 +245,10 @@ pub struct FunctionContext<'a, 'tcx: 'a> {
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,
fn_ty: FnType,
) -> FunctionContext<'a, 'tcx> {
pub fn new(ccx: &'a CrateContext<'a, 'tcx>, llfndecl: ValueRef) -> FunctionContext<'a, 'tcx> {
let mut fcx = FunctionContext {
llfn: llfndecl,
alloca_insert_pt: None,
fn_ty: fn_ty,
ccx: ccx,
alloca_builder: Builder::with_ccx(ccx),
};

View File

@ -186,9 +186,9 @@ fn get_drop_glue_core<'a, 'tcx>(ccx: &CrateContext<'a, 'tcx>, g: DropGlueKind<'t
pub fn implement_drop_glue<'a, 'tcx>(ccx: &CrateContext<'a, 'tcx>, g: DropGlueKind<'tcx>) {
assert_eq!(g.ty(), get_drop_glue_type(ccx.shared(), g.ty()));
let (llfn, fn_ty) = ccx.drop_glues().borrow().get(&g).unwrap().clone();
let (llfn, _) = ccx.drop_glues().borrow().get(&g).unwrap().clone();
let fcx = FunctionContext::new(ccx, llfn, fn_ty);
let fcx = FunctionContext::new(ccx, llfn);
let bcx = fcx.get_entry_block();
ccx.stats().n_glues_created.set(ccx.stats().n_glues_created.get() + 1);

View File

@ -878,7 +878,6 @@ fn gen_fn<'a, 'tcx>(fcx: &FunctionContext<'a, 'tcx>,
-> ValueRef {
let ccx = fcx.ccx;
let sig = ccx.tcx().mk_fn_sig(inputs.into_iter(), output, false);
let fn_ty = FnType::new(ccx, Abi::Rust, &sig, &[]);
let rust_fn_ty = ccx.tcx().mk_fn_ptr(ccx.tcx().mk_bare_fn(ty::BareFnTy {
unsafety: hir::Unsafety::Unsafe,
@ -886,7 +885,7 @@ 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, fn_ty);
let fcx = FunctionContext::new(ccx, llfn);
trans(fcx.get_entry_block());
llfn
}

View File

@ -11,7 +11,6 @@
use attributes;
use llvm::{ValueRef, get_params};
use rustc::traits;
use abi::FnType;
use callee::{Callee, CalleeData};
use common::*;
use consts;
@ -63,25 +62,20 @@ pub fn get_virtual_method<'a, 'tcx>(bcx: &BlockAndBuilder<'a, 'tcx>,
pub fn trans_object_shim<'a, 'tcx>(ccx: &'a CrateContext<'a, 'tcx>,
callee: Callee<'tcx>)
-> ValueRef {
let tcx = ccx.tcx();
debug!("trans_object_shim({:?})", callee);
let (sig, abi, function_name) = match callee.ty.sty {
ty::TyFnDef(def_id, substs, f) => {
let function_name = match callee.ty.sty {
ty::TyFnDef(def_id, substs, _) => {
let instance = Instance::new(def_id, substs);
(&f.sig, f.abi, instance.symbol_name(ccx.shared()))
instance.symbol_name(ccx.shared())
}
_ => bug!()
};
let sig = tcx.erase_late_bound_regions_and_normalize(sig);
let fn_ty = FnType::new(ccx, abi, &sig, &[]);
let llfn = declare::define_internal_fn(ccx, &function_name, callee.ty);
attributes::set_frame_pointer_elimination(ccx, llfn);
let fcx = FunctionContext::new(ccx, llfn, fn_ty);
let fcx = FunctionContext::new(ccx, llfn);
let bcx = fcx.get_entry_block();
let mut llargs = get_params(fcx.llfn);
@ -103,7 +97,7 @@ pub fn trans_object_shim<'a, 'tcx>(ccx: &'a CrateContext<'a, 'tcx>,
if fn_ret.0.is_never() {
bcx.unreachable();
} else {
if fn_ty.ret.is_indirect() || fcx.fn_ty.ret.is_ignore() {
if fn_ty.ret.is_indirect() || fn_ty.ret.is_ignore() {
bcx.ret_void();
} else {
bcx.ret(llret);

View File

@ -192,7 +192,7 @@ impl<'a, 'tcx> MirContext<'a, 'tcx> {
}
mir::TerminatorKind::Return => {
let ret = bcx.fcx().fn_ty.ret;
let ret = self.fn_ty.ret;
if ret.is_ignore() || ret.is_indirect() {
bcx.ret_void();
return;

View File

@ -22,6 +22,7 @@ use base;
use common::{self, BlockAndBuilder, CrateContext, FunctionContext, C_null, Funclet};
use debuginfo::{self, declare_local, VariableAccess, VariableKind, FunctionDebugContext};
use monomorphize::{self, Instance};
use abi::FnType;
use machine;
use type_of;
@ -52,6 +53,8 @@ pub struct MirContext<'a, 'tcx:'a> {
ccx: &'a CrateContext<'a, 'tcx>,
fn_ty: FnType,
/// When unwinding is initiated, we have to store this personality
/// value somewhere so that we can load it and re-use it in the
/// resume instruction. The personality is (afaik) some kind of
@ -197,6 +200,7 @@ impl<'tcx> LocalRef<'tcx> {
pub fn trans_mir<'a, 'tcx: 'a>(
fcx: &'a FunctionContext<'a, 'tcx>,
fn_ty: FnType,
mir: &'a Mir<'tcx>,
instance: Instance<'tcx>,
sig: &ty::FnSig<'tcx>,
@ -224,6 +228,7 @@ pub fn trans_mir<'a, 'tcx: 'a>(
let mut mircx = MirContext {
mir: mir,
fcx: fcx,
fn_ty: fn_ty,
ccx: fcx.ccx,
llpersonalityslot: None,
blocks: block_bcxs,
@ -271,7 +276,7 @@ pub fn trans_mir<'a, 'tcx: 'a>(
LocalRef::Lvalue(lvalue)
} else {
// Temporary or return pointer
if local == mir::RETURN_POINTER && fcx.fn_ty.ret.is_indirect() {
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);
LocalRef::Lvalue(LvalueRef::new_sized(llretptr, LvalueTy::from_ty(ty)))
@ -351,7 +356,7 @@ fn arg_local_refs<'a, 'tcx>(bcx: &BlockAndBuilder<'a, 'tcx>,
let fcx = bcx.fcx();
let tcx = bcx.tcx();
let mut idx = 0;
let mut llarg_idx = fcx.fn_ty.ret.is_indirect() as usize;
let mut llarg_idx = mircx.fn_ty.ret.is_indirect() as usize;
// Get the argument scope, if it exists and if we need it.
let arg_scope = scopes[mir::ARGUMENT_VISIBILITY_SCOPE];
@ -379,12 +384,12 @@ fn arg_local_refs<'a, 'tcx>(bcx: &BlockAndBuilder<'a, 'tcx>,
let lltemp = base::alloc_ty(&bcx, arg_ty, &format!("arg{}", arg_index));
for (i, &tupled_arg_ty) in tupled_arg_tys.iter().enumerate() {
let dst = bcx.struct_gep(lltemp, i);
let arg = &fcx.fn_ty.args[idx];
let arg = &mircx.fn_ty.args[idx];
idx += 1;
if common::type_is_fat_ptr(bcx.ccx, tupled_arg_ty) {
// We pass fat pointers as two words, but inside the tuple
// they are the two sub-fields of a single aggregate field.
let meta = &fcx.fn_ty.args[idx];
let meta = &mircx.fn_ty.args[idx];
idx += 1;
arg.store_fn_arg(bcx, &mut llarg_idx, base::get_dataptr(bcx, dst));
meta.store_fn_arg(bcx, &mut llarg_idx, base::get_meta(bcx, dst));
@ -413,7 +418,7 @@ fn arg_local_refs<'a, 'tcx>(bcx: &BlockAndBuilder<'a, 'tcx>,
return LocalRef::Lvalue(LvalueRef::new_sized(lltemp, LvalueTy::from_ty(arg_ty)));
}
let arg = &fcx.fn_ty.args[idx];
let arg = &mircx.fn_ty.args[idx];
idx += 1;
let llval = if arg.is_indirect() && bcx.sess().opts.debuginfo != FullDebugInfo {
// Don't copy an indirect argument to an alloca, the caller
@ -442,7 +447,7 @@ fn arg_local_refs<'a, 'tcx>(bcx: &BlockAndBuilder<'a, 'tcx>,
let llarg = llvm::get_param(fcx.llfn, llarg_idx as c_uint);
llarg_idx += 1;
let val = if common::type_is_fat_ptr(bcx.ccx, arg_ty) {
let meta = &fcx.fn_ty.args[idx];
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);
@ -462,7 +467,7 @@ fn arg_local_refs<'a, 'tcx>(bcx: &BlockAndBuilder<'a, 'tcx>,
// we pass fat pointers as two words, but we want to
// represent them internally as a pointer to two words,
// so make an alloca to store them in.
let meta = &fcx.fn_ty.args[idx];
let meta = &mircx.fn_ty.args[idx];
idx += 1;
arg.store_fn_arg(bcx, &mut llarg_idx, base::get_dataptr(bcx, lltemp));
meta.store_fn_arg(bcx, &mut llarg_idx, base::get_meta(bcx, lltemp));