about summary refs log tree commit diff
path: root/src/comp
diff options
context:
space:
mode:
authorNiko Matsakis <niko@alum.mit.edu>2012-01-06 19:39:18 -0800
committerNiko Matsakis <niko@alum.mit.edu>2012-01-06 22:40:32 -0800
commit154f81b0be502b401c2900ce1bd0db8afb474ff6 (patch)
treec51d09cc17bac974543f92255453e7abc73d9142 /src/comp
parent6237368cc2e640e50ee3616386be65e7f0fc98ad (diff)
downloadrust-154f81b0be502b401c2900ce1bd0db8afb474ff6.tar.gz
rust-154f81b0be502b401c2900ce1bd0db8afb474ff6.zip
revert metrics
Diffstat (limited to 'src/comp')
-rw-r--r--src/comp/middle/trans.rs164
-rw-r--r--src/comp/middle/trans_uniq.rs12
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<ValueRef>)
-    -> 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<ValueRef>) -> metrics_result {
-    fn c_struct_metrics(bcx: @block_ctxt,
-                        elts: [ty::t],
-                        opt_v: option<ValueRef>) -> 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 dynamic_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 dynamic_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 dynamic_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 GEP_tup_like(bcx: @block_ctxt, t: ty::t, base: ValueRef, ixs: [int])
     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_build::*;
 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<ValueRef>)
+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;