Skip to content

Commit

Permalink
auto merge of #11723 : eddyb/rust/more-trans-cleanup, r=pcwalton
Browse files Browse the repository at this point in the history
  • Loading branch information
bors committed Jan 27, 2014
2 parents feacb59 + e81ab41 commit 760ddb3
Show file tree
Hide file tree
Showing 8 changed files with 62 additions and 146 deletions.
9 changes: 4 additions & 5 deletions src/librustc/back/abi.rs
Expand Up @@ -42,11 +42,10 @@ pub static general_code_alignment: uint = 16u;

pub static tydesc_field_size: uint = 0u;
pub static tydesc_field_align: uint = 1u;
pub static tydesc_field_take_glue: uint = 2u;
pub static tydesc_field_drop_glue: uint = 3u;
pub static tydesc_field_visit_glue: uint = 4u;
pub static tydesc_field_name_offset: uint = 5u;
pub static n_tydesc_fields: uint = 6u;
pub static tydesc_field_drop_glue: uint = 2u;
pub static tydesc_field_visit_glue: uint = 3u;
pub static tydesc_field_name_offset: uint = 4u;
pub static n_tydesc_fields: uint = 5u;

// The two halves of a closure: code and environment.
pub static fn_field_code: uint = 0u;
Expand Down
40 changes: 16 additions & 24 deletions src/librustc/middle/trans/base.rs
Expand Up @@ -777,16 +777,16 @@ pub fn iter_structural_ty<'r,
let variant_cx =
fcx.new_temp_block(~"enum-iter-variant-" +
variant.disr_val.to_str());
let variant_cx =
iter_variant(variant_cx, repr, av, *variant,
substs.tps, |x,y,z| f(x,y,z));
match adt::trans_case(cx, repr, variant.disr_val) {
_match::single_result(r) => {
AddCase(llswitch, r.val, variant_cx.llbb)
}
_ => ccx.sess.unimpl("value from adt::trans_case \
in iter_structural_ty")
}
let variant_cx =
iter_variant(variant_cx, repr, av, *variant,
substs.tps, |x,y,z| f(x,y,z));
Br(variant_cx, next_cx.llbb);
}
cx = next_cx;
Expand Down Expand Up @@ -1458,16 +1458,16 @@ pub fn build_return_block(fcx: &FunctionContext, ret_cx: &Block) {
// trans_closure: Builds an LLVM function out of a source function.
// If the function closes over its environment a closure will be
// returned.
pub fn trans_closure(ccx: @CrateContext,
path: ast_map::Path,
decl: &ast::FnDecl,
body: &ast::Block,
llfndecl: ValueRef,
param_substs: Option<@param_substs>,
id: ast::NodeId,
_attributes: &[ast::Attribute],
output_type: ty::t,
maybe_load_env: |&FunctionContext|) {
pub fn trans_closure<'a>(ccx: @CrateContext,
path: ast_map::Path,
decl: &ast::FnDecl,
body: &ast::Block,
llfndecl: ValueRef,
param_substs: Option<@param_substs>,
id: ast::NodeId,
_attributes: &[ast::Attribute],
output_type: ty::t,
maybe_load_env: |&'a Block<'a>| -> &'a Block<'a>) {
ccx.stats.n_closures.set(ccx.stats.n_closures.get() + 1);

let _icx = push_ctxt("trans_closure");
Expand Down Expand Up @@ -1500,7 +1500,7 @@ pub fn trans_closure(ccx: @CrateContext,

bcx = copy_args_to_allocas(&fcx, arg_scope, bcx, decl.inputs, arg_datums);

maybe_load_env(&fcx);
bcx = maybe_load_env(bcx);

// Up until here, IR instructions for this function have explicitly not been annotated with
// source code location, so we don't step into call setup code. From here on, source location
Expand Down Expand Up @@ -1558,16 +1558,8 @@ pub fn trans_fn(ccx: @CrateContext,
debug!("trans_fn(param_substs={})", param_substs.repr(ccx.tcx));
let _icx = push_ctxt("trans_fn");
let output_type = ty::ty_fn_ret(ty::node_id_to_type(ccx.tcx, id));
trans_closure(ccx,
path.clone(),
decl,
body,
llfndecl,
param_substs,
id,
attrs,
output_type,
|_fcx| { });
trans_closure(ccx, path.clone(), decl, body, llfndecl,
param_substs, id, attrs, output_type, |bcx| bcx);
}

pub fn trans_enum_variant(ccx: @CrateContext,
Expand Down
19 changes: 10 additions & 9 deletions src/librustc/middle/trans/closure.rs
Expand Up @@ -282,23 +282,22 @@ fn build_closure<'a>(bcx0: &'a Block<'a>,
// Given an enclosing block context, a new function context, a closure type,
// and a list of upvars, generate code to load and populate the environment
// with the upvars and type descriptors.
fn load_environment(fcx: &FunctionContext, cdata_ty: ty::t,
cap_vars: &[moves::CaptureVar], sigil: ast::Sigil) {
fn load_environment<'a>(bcx: &'a Block<'a>, cdata_ty: ty::t,
cap_vars: &[moves::CaptureVar],
sigil: ast::Sigil) -> &'a Block<'a> {
let _icx = push_ctxt("closure::load_environment");

// Don't bother to create the block if there's nothing to load
if cap_vars.len() == 0 {
return;
return bcx;
}

let bcx = fcx.entry_bcx.get().unwrap();

// Load a pointer to the closure data, skipping over the box header:
let llcdata = at_box_body(bcx, cdata_ty, fcx.llenv.unwrap());
let llcdata = at_box_body(bcx, cdata_ty, bcx.fcx.llenv.unwrap());

// Store the pointer to closure data in an alloca for debug info because that's what the
// llvm.dbg.declare intrinsic expects
let env_pointer_alloca = if fcx.ccx.sess.opts.extra_debuginfo {
let env_pointer_alloca = if bcx.ccx().sess.opts.extra_debuginfo {
let alloc = alloc_ty(bcx, ty::mk_mut_ptr(bcx.tcx(), cdata_ty), "__debuginfo_env_ptr");
Store(bcx, llcdata, alloc);
Some(alloc)
Expand All @@ -317,7 +316,7 @@ fn load_environment(fcx: &FunctionContext, cdata_ty: ty::t,
let def_id = ast_util::def_id_of_def(cap_var.def);

{
let mut llupvars = fcx.llupvars.borrow_mut();
let mut llupvars = bcx.fcx.llupvars.borrow_mut();
llupvars.get().insert(def_id.node, upvarptr);
}

Expand All @@ -334,6 +333,8 @@ fn load_environment(fcx: &FunctionContext, cdata_ty: ty::t,

i += 1u;
}

bcx
}

fn fill_fn_pair(bcx: &Block, pair: ValueRef, llfn: ValueRef, llenvptr: ValueRef) {
Expand Down Expand Up @@ -405,7 +406,7 @@ pub fn trans_expr_fn<'a>(
trans_closure(ccx, sub_path, decl, body, llfn,
bcx.fcx.param_substs, user_id,
[], ty::ty_fn_ret(fty),
|fcx| load_environment(fcx, cdata_ty, cap_vars, sigil));
|bcx| load_environment(bcx, cdata_ty, cap_vars, sigil));
fill_fn_pair(bcx, dest_addr, llfn, llbox);

bcx
Expand Down
1 change: 0 additions & 1 deletion src/librustc/middle/trans/common.rs
Expand Up @@ -114,7 +114,6 @@ pub struct tydesc_info {
size: ValueRef,
align: ValueRef,
name: ValueRef,
take_glue: Cell<Option<ValueRef>>,
drop_glue: Cell<Option<ValueRef>>,
visit_glue: Cell<Option<ValueRef>>,
}
Expand Down
2 changes: 1 addition & 1 deletion src/librustc/middle/trans/datum.rs
Expand Up @@ -491,7 +491,7 @@ impl Datum<Expr> {
}
ByValue => {
let v = load(bcx, l.val, l.ty);
l.kind.post_store(bcx, l.val, l.ty);
bcx = l.kind.post_store(bcx, l.val, l.ty);
DatumBlock(bcx, Datum(v, l.ty, Rvalue(ByValue)))
}
}
Expand Down
134 changes: 29 additions & 105 deletions src/librustc/middle/trans/glue.rs
Expand Up @@ -58,14 +58,24 @@ pub fn trans_exchange_free<'a>(cx: &'a Block<'a>, v: ValueRef)
Some(expr::Ignore)).bcx
}

pub fn take_ty<'a>(cx: &'a Block<'a>, v: ValueRef, t: ty::t)
pub fn take_ty<'a>(bcx: &'a Block<'a>, v: ValueRef, t: ty::t)
-> &'a Block<'a> {
// NB: v is an *alias* of type t here, not a direct value.
let _icx = push_ctxt("take_ty");
if ty::type_needs_drop(cx.tcx(), t) {
return call_tydesc_glue(cx, v, t, abi::tydesc_field_take_glue);
match ty::get(t).sty {
ty::ty_box(_) |
ty::ty_vec(_, ty::vstore_box) | ty::ty_str(ty::vstore_box) => {
incr_refcnt_of_boxed(bcx, v)
}
ty::ty_trait(_, _, ty::BoxTraitStore, _, _) => {
incr_refcnt_of_boxed(bcx, GEPi(bcx, v, [0u, abi::trt_field_box]))
}
_ if ty::type_is_structural(t)
&& ty::type_needs_drop(bcx.tcx(), t) => {
iter_structural_ty(bcx, v, t, take_ty)
}
_ => bcx
}
return cx;
}

pub fn drop_ty<'a>(cx: &'a Block<'a>, v: ValueRef, t: ty::t)
Expand All @@ -88,30 +98,15 @@ pub fn drop_ty_immediate<'a>(bcx: &'a Block<'a>, v: ValueRef, t: ty::t)

pub fn lazily_emit_all_tydesc_glue(ccx: @CrateContext,
static_ti: @tydesc_info) {
lazily_emit_tydesc_glue(ccx, abi::tydesc_field_take_glue, static_ti);
lazily_emit_tydesc_glue(ccx, abi::tydesc_field_drop_glue, static_ti);
lazily_emit_tydesc_glue(ccx, abi::tydesc_field_visit_glue, static_ti);
}

fn simplified_glue_type(tcx: ty::ctxt, field: uint, t: ty::t) -> ty::t {
if (field == abi::tydesc_field_take_glue || field == abi::tydesc_field_drop_glue)
&& !ty::type_needs_drop(tcx, t) {
return ty::mk_nil();
}

if field == abi::tydesc_field_take_glue {
match ty::get(t).sty {
ty::ty_str(ty::vstore_uniq) | ty::ty_vec(_, ty::vstore_uniq) |
ty::ty_unboxed_vec(..) | ty::ty_uniq(..) => return ty::mk_nil(),
_ => {}
}
}

if field == abi::tydesc_field_take_glue && ty::type_is_boxed(t) {
return ty::mk_box(tcx, ty::mk_nil());
}

if field == abi::tydesc_field_drop_glue {
if !ty::type_needs_drop(tcx, t) {
return ty::mk_nil();
}
match ty::get(t).sty {
ty::ty_box(typ)
if !ty::type_needs_drop(tcx, typ) =>
Expand Down Expand Up @@ -145,9 +140,7 @@ fn lazily_emit_tydesc_glue(ccx: @CrateContext, field: uint, ti: @tydesc_info) {
let simpl_ti = get_tydesc(ccx, simpl);
lazily_emit_tydesc_glue(ccx, field, simpl_ti);

if field == abi::tydesc_field_take_glue {
ti.take_glue.set(simpl_ti.take_glue.get());
} else if field == abi::tydesc_field_drop_glue {
if field == abi::tydesc_field_drop_glue {
ti.drop_glue.set(simpl_ti.drop_glue.get());
} else if field == abi::tydesc_field_visit_glue {
ti.visit_glue.set(simpl_ti.visit_glue.get());
Expand All @@ -158,20 +151,7 @@ fn lazily_emit_tydesc_glue(ccx: @CrateContext, field: uint, ti: @tydesc_info) {

let llfnty = Type::glue_fn(type_of(ccx, ti.ty).ptr_to());

if field == abi::tydesc_field_take_glue {
match ti.take_glue.get() {
Some(_) => (),
None => {
debug!("+++ lazily_emit_tydesc_glue TAKE {}",
ppaux::ty_to_str(ccx.tcx, ti.ty));
let glue_fn = declare_generic_glue(ccx, ti.ty, llfnty, "take");
ti.take_glue.set(Some(glue_fn));
make_generic_glue(ccx, ti.ty, glue_fn, make_take_glue, "take");
debug!("--- lazily_emit_tydesc_glue TAKE {}",
ppaux::ty_to_str(ccx.tcx, ti.ty));
}
}
} else if field == abi::tydesc_field_drop_glue {
if field == abi::tydesc_field_drop_glue {
match ti.drop_glue.get() {
Some(_) => (),
None => {
Expand Down Expand Up @@ -213,9 +193,7 @@ pub fn call_tydesc_glue_full(bcx: &Block, v: ValueRef, tydesc: ValueRef,
None => None,
Some(sti) => {
lazily_emit_tydesc_glue(ccx, field, sti);
if field == abi::tydesc_field_take_glue {
sti.take_glue.get()
} else if field == abi::tydesc_field_drop_glue {
if field == abi::tydesc_field_drop_glue {
sti.drop_glue.get()
} else if field == abi::tydesc_field_visit_glue {
sti.visit_glue.get()
Expand Down Expand Up @@ -472,53 +450,16 @@ fn decr_refcnt_maybe_free<'a>(bcx: &'a Block<'a>, box_ptr_ptr: ValueRef,
next_bcx
}

fn make_take_glue<'a>(bcx: &'a Block<'a>, v: ValueRef, t: ty::t) -> &'a Block<'a> {
let _icx = push_ctxt("make_take_glue");
// NB: v is a *pointer* to type t here, not a direct value.
match ty::get(t).sty {
ty::ty_box(_) |
ty::ty_vec(_, ty::vstore_box) | ty::ty_str(ty::vstore_box) => {
incr_refcnt_of_boxed(bcx, Load(bcx, v)); bcx
}
ty::ty_vec(_, ty::vstore_slice(_))
| ty::ty_str(ty::vstore_slice(_)) => {
bcx
}
ty::ty_closure(_) => bcx,
ty::ty_trait(_, _, ty::BoxTraitStore, _, _) => {
let llbox = Load(bcx, GEPi(bcx, v, [0u, abi::trt_field_box]));
incr_refcnt_of_boxed(bcx, llbox);
bcx
}
ty::ty_trait(_, _, ty::UniqTraitStore, _, _) => {
let lluniquevalue = GEPi(bcx, v, [0, abi::trt_field_box]);
let llvtable = Load(bcx, GEPi(bcx, v, [0, abi::trt_field_vtable]));

// Cast the vtable to a pointer to a pointer to a tydesc.
let llvtable = PointerCast(bcx, llvtable,
bcx.ccx().tydesc_type.ptr_to().ptr_to());
let lltydesc = Load(bcx, llvtable);
call_tydesc_glue_full(bcx,
lluniquevalue,
lltydesc,
abi::tydesc_field_take_glue,
None);
bcx
}
_ if ty::type_is_structural(t) => {
iter_structural_ty(bcx, v, t, take_ty)
}
_ => bcx
}
}

fn incr_refcnt_of_boxed(cx: &Block, box_ptr: ValueRef) {
fn incr_refcnt_of_boxed<'a>(bcx: &'a Block<'a>,
box_ptr_ptr: ValueRef) -> &'a Block<'a> {
let _icx = push_ctxt("incr_refcnt_of_boxed");
let ccx = cx.ccx();
let rc_ptr = GEPi(cx, box_ptr, [0u, abi::box_field_refcnt]);
let rc = Load(cx, rc_ptr);
let rc = Add(cx, rc, C_int(ccx, 1));
Store(cx, rc, rc_ptr);
let ccx = bcx.ccx();
let box_ptr = Load(bcx, box_ptr_ptr);
let rc_ptr = GEPi(bcx, box_ptr, [0u, abi::box_field_refcnt]);
let rc = Load(bcx, rc_ptr);
let rc = Add(bcx, rc, C_int(ccx, 1));
Store(bcx, rc, rc_ptr);
bcx
}


Expand Down Expand Up @@ -554,7 +495,6 @@ pub fn declare_tydesc(ccx: &CrateContext, t: ty::t) -> @tydesc_info {
size: llsize,
align: llalign,
name: ty_name,
take_glue: Cell::new(None),
drop_glue: Cell::new(None),
visit_glue: Cell::new(None),
};
Expand Down Expand Up @@ -616,21 +556,6 @@ pub fn emit_tydescs(ccx: &CrateContext) {
// before being put into the tydesc because we only have a singleton
// tydesc type. Then we'll recast each function to its real type when
// calling it.
let take_glue =
match ti.take_glue.get() {
None => {
ccx.stats.n_null_glues.set(ccx.stats.n_null_glues.get() +
1);
C_null(glue_fn_ty)
}
Some(v) => {
unsafe {
ccx.stats.n_real_glues.set(ccx.stats.n_real_glues.get() +
1);
llvm::LLVMConstPointerCast(v, glue_fn_ty.to_ref())
}
}
};
let drop_glue =
match ti.drop_glue.get() {
None => {
Expand Down Expand Up @@ -665,7 +590,6 @@ pub fn emit_tydescs(ccx: &CrateContext) {
let tydesc = C_named_struct(ccx.tydesc_type,
[ti.size, // size
ti.align, // align
take_glue, // take_glue
drop_glue, // drop_glue
visit_glue, // visit_glue
ti.name]); // name
Expand Down
1 change: 0 additions & 1 deletion src/librustc/middle/trans/type_.rs
Expand Up @@ -211,7 +211,6 @@ impl Type {

let elems = [int_ty, // size
int_ty, // align
glue_fn_ty, // take
glue_fn_ty, // drop
glue_fn_ty, // visit
Type::struct_([Type::i8p(), Type::int(arch)], false)]; // name
Expand Down
2 changes: 2 additions & 0 deletions src/libstd/unstable/intrinsics.rs
Expand Up @@ -57,6 +57,8 @@ pub struct TyDesc {
align: uint,

// Called on a copy of a value of type `T` *after* memcpy
// NOTE remove after next snapshot
#[cfg(stage0)]
take_glue: GlueFn,

// Called when a value of type `T` is no longer needed
Expand Down

0 comments on commit 760ddb3

Please sign in to comment.