From 154f81b0be502b401c2900ce1bd0db8afb474ff6 Mon Sep 17 00:00:00 2001 From: Niko Matsakis Date: Fri, 6 Jan 2012 19:39:18 -0800 Subject: [PATCH] revert metrics --- src/comp/middle/trans.rs | 164 +++++++++++++++++++--------------- src/comp/middle/trans_uniq.rs | 12 +-- 2 files changed, 94 insertions(+), 82 deletions(-) diff --git a/src/comp/middle/trans.rs b/src/comp/middle/trans.rs index 080a5819970..f6539e4f0f3 100644 --- a/src/comp/middle/trans.rs +++ b/src/comp/middle/trans.rs @@ -414,32 +414,29 @@ fn llalign_of(cx: @crate_ctxt, t: TypeRef) -> ValueRef { False); } -fn size_of(bcx: @block_ctxt, t: ty::t) -> result { - let {bcx, sz, align: _} = metrics(bcx, t, none); - rslt(bcx, sz) +fn size_of(cx: @block_ctxt, t: ty::t) -> result { + size_of_(cx, t, align_total) } -fn align_of(bcx: @block_ctxt, t: ty::t) -> result { - let {bcx, sz: _, align} = metrics(bcx, t, none); - rslt(bcx, align) +tag align_mode { + align_total; + align_next(ty::t); } -// Computes the size/alignment of the type `t`. `opt_v`, if provided, should -// be a pointer to the instance of type `t` whose size/alignment are being -// computed. For most types, `opt_v` is not needed, because all instances -// have the same size/alignment. However, for opaque types like closures, the -// instance is required. -fn metrics(bcx: @block_ctxt, t: ty::t, opt_v: option) - -> metrics_result { - let ccx = bcx_ccx(bcx); +fn size_of_(cx: @block_ctxt, t: ty::t, mode: align_mode) -> result { + let ccx = bcx_ccx(cx); if check type_has_static_size(ccx, t) { - let sp = bcx.sp; - let sz = llsize_of(bcx_ccx(bcx), type_of(ccx, sp, t)); - let align = llalign_of(bcx_ccx(bcx), type_of(ccx, sp, t)); - ret {bcx: bcx, sz: sz, align: align}; - } else { - ret dynamic_metrics(bcx, t, opt_v); - } + let sp = cx.sp; + rslt(cx, llsize_of(bcx_ccx(cx), type_of(ccx, sp, t))) + } else { dynamic_size_of(cx, t, mode) } +} + +fn align_of(cx: @block_ctxt, t: ty::t) -> result { + let ccx = bcx_ccx(cx); + if check type_has_static_size(ccx, t) { + let sp = cx.sp; + rslt(cx, llalign_of(bcx_ccx(cx), type_of(ccx, sp, t))) + } else { dynamic_align_of(cx, t) } } fn alloca(cx: @block_ctxt, t: TypeRef) -> ValueRef { @@ -545,18 +542,9 @@ fn static_size_of_tag(cx: @crate_ctxt, sp: span, t: ty::t) } } -type metrics_result = { - bcx: @block_ctxt, - sz: ValueRef, - align: ValueRef -}; - -fn dynamic_metrics(bcx: @block_ctxt, - t: ty::t, - opt_v: option) -> metrics_result { - fn c_struct_metrics(bcx: @block_ctxt, - elts: [ty::t], - opt_v: option) -> metrics_result { +fn dynamic_size_of(cx: @block_ctxt, t: ty::t, mode: align_mode) -> result { + fn align_elements(cx: @block_ctxt, elts: [ty::t], + mode: align_mode) -> result { // // C padding rules: // @@ -565,45 +553,50 @@ fn c_struct_metrics(bcx: @block_ctxt, // - Pad after final structure member so that whole structure // is aligned to max alignment of interior. // - let bcx = bcx; - let off = C_int(bcx_ccx(bcx), 0); - let max_align = C_int(bcx_ccx(bcx), 1); + + let off = C_int(bcx_ccx(cx), 0); + let max_align = C_int(bcx_ccx(cx), 1); + let bcx = cx; for e: ty::t in elts { - let opt_ev = option::map(opt_v) {|v| ptr_offs(bcx, v, off) }; - let elt_metrics = metrics(bcx, e, opt_ev); - bcx = elt_metrics.bcx; - let aligned_off = align_to(bcx, off, elt_metrics.align); - off = Add(bcx, aligned_off, elt_metrics.sz); - max_align = umax(bcx, max_align, elt_metrics.align); + let elt_align = align_of(bcx, e); + bcx = elt_align.bcx; + let elt_size = size_of(bcx, e); + bcx = elt_size.bcx; + let aligned_off = align_to(bcx, off, elt_align.val); + off = Add(bcx, aligned_off, elt_size.val); + max_align = umax(bcx, max_align, elt_align.val); } - off = align_to(bcx, off, max_align); - ret { bcx: bcx, sz: off, align: max_align }; + off = alt mode { + align_total. { + align_to(bcx, off, max_align) + } + align_next(t) { + let {bcx, val: align} = align_of(bcx, t); + align_to(bcx, off, align) + } + }; + ret rslt(bcx, off); } - - alt ty::struct(bcx_tcx(bcx), t) { + alt ty::struct(bcx_tcx(cx), t) { ty::ty_param(p, _) { - let ti = none::<@tydesc_info>; - let {bcx, val: tydesc} = - get_tydesc(bcx, t, false, tps_normal, ti).result; - let sz = Load(bcx, GEPi(bcx, tydesc, [0, abi::tydesc_field_size])); - let al = Load(bcx, GEPi(bcx, tydesc, [0, abi::tydesc_field_align])); - ret { bcx: bcx, sz: sz, align: al }; + let szptr = field_of_tydesc(cx, t, false, abi::tydesc_field_size); + ret rslt(szptr.bcx, Load(szptr.bcx, szptr.val)); } ty::ty_rec(flds) { let tys: [ty::t] = []; for f: ty::field in flds { tys += [f.mt.ty]; } - ret c_struct_metrics(bcx, tys, opt_v); + ret align_elements(cx, tys, mode); } ty::ty_tup(elts) { let tys = []; for tp in elts { tys += [tp]; } - ret c_struct_metrics(bcx, tys, opt_v); + ret align_elements(cx, tys, mode); } ty::ty_tag(tid, tps) { - let bcx = bcx; + let bcx = cx; let ccx = bcx_ccx(bcx); + // Compute max(variant sizes). - // Compute max(variant sizes) and max(variant alignments). let max_size: ValueRef = alloca(bcx, ccx.int_type); Store(bcx, C_int(ccx, 0), max_size); let variants = ty::tag_variants(bcx_tcx(bcx), tid); @@ -613,19 +606,12 @@ fn c_struct_metrics(bcx: @block_ctxt, let raw_tys: [ty::t] = variant.args; let tys: [ty::t] = []; for raw_ty: ty::t in raw_tys { - let t = ty::substitute_type_params(bcx_tcx(bcx), tps, raw_ty); + let t = ty::substitute_type_params(bcx_tcx(cx), tps, raw_ty); tys += [t]; } - - // Note: we do not pass in opt_v here for the value but rather - // none. The reason is that what we would want to pass in is a - // ptr to the blob data of the tag, but this is impossible until - // we know the size/alignment of the blob data. Therefore, it is - // not legal to have a tag type that contains an interior opaque - // type. Fortunately this will never happen. - let rslt = c_struct_metrics(bcx, tys, none); + let rslt = align_elements(bcx, tys, mode); bcx = rslt.bcx; - let this_size = rslt.sz; + let this_size = rslt.val; let old_max_size = Load(bcx, max_size); Store(bcx, umax(bcx, this_size, old_max_size), max_size); } @@ -634,8 +620,41 @@ fn c_struct_metrics(bcx: @block_ctxt, if vec::len(*variants) != 1u { Add(bcx, max_size_val, llsize_of(ccx, ccx.int_type)) } else { max_size_val }; - let total_align = C_int(bcx_ccx(bcx), 1); // FIXME: stub - ret {bcx: bcx, sz: total_size, align: total_align}; + ret rslt(bcx, total_size); + } + } +} + +fn dynamic_align_of(cx: @block_ctxt, t: ty::t) -> result { +// FIXME: Typestate constraint that shows this alt is +// exhaustive + alt ty::struct(bcx_tcx(cx), t) { + ty::ty_param(p, _) { + let aptr = field_of_tydesc(cx, t, false, abi::tydesc_field_align); + ret rslt(aptr.bcx, Load(aptr.bcx, aptr.val)); + } + ty::ty_rec(flds) { + let a = C_int(bcx_ccx(cx), 1); + let bcx = cx; + for f: ty::field in flds { + let align = align_of(bcx, f.mt.ty); + bcx = align.bcx; + a = umax(bcx, a, align.val); + } + ret rslt(bcx, a); + } + ty::ty_tag(_, _) { + ret rslt(cx, C_int(bcx_ccx(cx), 1)); // FIXME: stub + } + ty::ty_tup(elts) { + let a = C_int(bcx_ccx(cx), 1); + let bcx = cx; + for e in elts { + let align = align_of(bcx, e); + bcx = align.bcx; + a = umax(bcx, a, align.val); + } + ret rslt(bcx, a); } } } @@ -744,10 +763,9 @@ fn split_type(ccx: @crate_ctxt, t: ty::t, ixs: [int], n: uint) -> let args = []; for typ: ty::t in s.prefix { args += [typ]; } let prefix_ty = ty::mk_tup(bcx_tcx(bcx), args); - let {bcx, sz: prefix_sz, align: _} = metrics(bcx, prefix_ty, some(base)); - let {bcx, val: align} = align_of(bcx, s.target); - let sz = align_to(bcx, prefix_sz, align); - ret rslt(bcx, bump_ptr(bcx, s.target, base, sz)); + + let sz = size_of_(bcx, prefix_ty, align_next(s.target)); + ret rslt(sz.bcx, bump_ptr(sz.bcx, s.target, base, sz.val)); } @@ -1999,7 +2017,7 @@ fn memmove_ty(bcx: @block_ctxt, dst: ValueRef, src: ValueRef, t: ty::t) -> ret bcx; } - let {bcx, sz: llsz, align: _} = metrics(bcx, t, some(src)); + let {bcx, val: llsz} = size_of(bcx, t); ret call_memmove(bcx, dst, src, llsz).bcx; } diff --git a/src/comp/middle/trans_uniq.rs b/src/comp/middle/trans_uniq.rs index a7b6f58d393..5c4905207c8 100644 --- a/src/comp/middle/trans_uniq.rs +++ b/src/comp/middle/trans_uniq.rs @@ -5,7 +5,6 @@ import trans::{ trans_shared_malloc, type_of_inner, - metrics, size_of, node_id_type, INIT, @@ -34,15 +33,10 @@ fn trans_uniq(bcx: @block_ctxt, contents: @ast::expr, ret trans::store_in_dest(bcx, llptr, dest); } -fn alloc_uniq(cx: @block_ctxt, uniq_ty: ty::t) - : type_is_unique_box(cx, uniq_ty) -> result { - ret alloc_uniq_(cx, uniq_ty, none); -} - -fn alloc_uniq_(bcx: @block_ctxt, uniq_ty: ty::t, opt_v: option) +fn alloc_uniq(bcx: @block_ctxt, uniq_ty: ty::t) : type_is_unique_box(bcx, uniq_ty) -> result { let contents_ty = content_ty(bcx, uniq_ty); - let {bcx, sz: llsz, align: _} = metrics(bcx, contents_ty, opt_v); + let {bcx, val: llsz} = size_of(bcx, contents_ty); let ccx = bcx_ccx(bcx); check non_ty_var(ccx, contents_ty); let llptrty = T_ptr(type_of_inner(ccx, bcx.sp, contents_ty)); @@ -84,7 +78,7 @@ fn duplicate(bcx: @block_ctxt, v: ValueRef, t: ty::t) : type_is_unique_box(bcx, t) -> result { let content_ty = content_ty(bcx, t); - let {bcx, val: llptr} = alloc_uniq_(bcx, t, some(v)); + let {bcx, val: llptr} = alloc_uniq(bcx, t); let src = load_if_immediate(bcx, v, content_ty); let dst = llptr; -- 2.44.0