aboutsummaryrefslogtreecommitdiff
path: root/src/comp
diff options
context:
space:
mode:
authorPatrick Walton <[email protected]>2011-04-15 10:18:23 -0700
committerPatrick Walton <[email protected]>2011-04-15 15:16:06 -0700
commitcc6a9c88766c3822522d48145d9f5778a21147a6 (patch)
tree251d30672ff8cac1c97e06ea8b62668d6ffead46 /src/comp
parentAdd a -S option for producing assembly. I will move more of it to (diff)
downloadrust-cc6a9c88766c3822522d48145d9f5778a21147a6.tar.xz
rust-cc6a9c88766c3822522d48145d9f5778a21147a6.zip
rustc: Remove the "boxed" check, and make the static_size_of_tag recursion-eliminating transformation deep
Diffstat (limited to 'src/comp')
-rw-r--r--src/comp/middle/trans.rs65
1 files changed, 32 insertions, 33 deletions
diff --git a/src/comp/middle/trans.rs b/src/comp/middle/trans.rs
index 187265e9..bab94982 100644
--- a/src/comp/middle/trans.rs
+++ b/src/comp/middle/trans.rs
@@ -532,7 +532,7 @@ fn type_of(@crate_ctxt cx, @ty.t t) -> TypeRef {
fail;
}
- ret type_of_inner(cx, t, false);
+ ret type_of_inner(cx, t);
}
fn type_of_explicit_args(@crate_ctxt cx,
@@ -546,10 +546,10 @@ fn type_of_explicit_args(@crate_ctxt cx,
let TypeRef t;
alt (arg.mode) {
case (ast.alias) {
- t = T_ptr(type_of_inner(cx, arg.ty, true));
+ t = T_ptr(type_of_inner(cx, arg.ty));
}
case (_) {
- t = type_of_inner(cx, arg.ty, false);
+ t = type_of_inner(cx, arg.ty);
}
}
atys += vec(t);
@@ -577,7 +577,7 @@ fn type_of_fn_full(@crate_ctxt cx,
if (ty.type_has_dynamic_size(output)) {
atys += vec(T_typaram_ptr(cx.tn));
} else {
- atys += vec(T_ptr(type_of_inner(cx, output, false)));
+ atys += vec(T_ptr(type_of_inner(cx, output)));
}
// Arg 1: Task pointer.
@@ -644,10 +644,10 @@ fn type_of_native_fn(@crate_ctxt cx, ast.native_abi abi,
}
}
atys += type_of_explicit_args(cx, inputs);
- ret T_fn(atys, type_of_inner(cx, output, false));
+ ret T_fn(atys, type_of_inner(cx, output));
}
-fn type_of_inner(@crate_ctxt cx, @ty.t t, bool boxed) -> TypeRef {
+fn type_of_inner(@crate_ctxt cx, @ty.t t) -> TypeRef {
let TypeRef llty = 0 as TypeRef;
alt (t.struct) {
@@ -682,28 +682,28 @@ fn type_of_inner(@crate_ctxt cx, @ty.t t, bool boxed) -> TypeRef {
}
}
case (ty.ty_box(?mt)) {
- llty = T_ptr(T_box(type_of_inner(cx, mt.ty, true)));
+ llty = T_ptr(T_box(type_of_inner(cx, mt.ty)));
}
case (ty.ty_vec(?mt)) {
- llty = T_ptr(T_vec(type_of_inner(cx, mt.ty, true)));
+ llty = T_ptr(T_vec(type_of_inner(cx, mt.ty)));
}
case (ty.ty_port(?t)) {
- llty = T_ptr(T_port(type_of_inner(cx, t, true)));
+ llty = T_ptr(T_port(type_of_inner(cx, t)));
}
case (ty.ty_chan(?t)) {
- llty = T_ptr(T_chan(type_of_inner(cx, t, true)));
+ llty = T_ptr(T_chan(type_of_inner(cx, t)));
}
case (ty.ty_tup(?elts)) {
let vec[TypeRef] tys = vec();
for (ty.mt elt in elts) {
- tys += vec(type_of_inner(cx, elt.ty, boxed));
+ tys += vec(type_of_inner(cx, elt.ty));
}
llty = T_struct(tys);
}
case (ty.ty_rec(?fields)) {
let vec[TypeRef] tys = vec();
for (ty.field f in fields) {
- tys += vec(type_of_inner(cx, f.mt.ty, boxed));
+ tys += vec(type_of_inner(cx, f.mt.ty));
}
llty = T_struct(tys);
}
@@ -768,9 +768,9 @@ fn type_of_arg(@crate_ctxt cx, &ty.arg arg) -> TypeRef {
auto typ;
if (arg.mode == ast.alias) {
- typ = T_ptr(type_of_inner(cx, arg.ty, true));
+ typ = T_ptr(type_of_inner(cx, arg.ty));
} else {
- typ = type_of_inner(cx, arg.ty, false);
+ typ = type_of_inner(cx, arg.ty);
}
ret typ;
}
@@ -1099,6 +1099,23 @@ fn array_alloca(@block_ctxt cx, TypeRef t, ValueRef n) -> ValueRef {
}
+// Creates a simpler, size-equivalent type. The resulting type is guaranteed
+// to have (a) the same size as the type that was passed in; (b) to be non-
+// recursive. This is done by replacing all boxes in a type with boxed unit
+// types.
+fn simplify_type(@ty.t typ) -> @ty.t {
+ fn simplifier(@ty.t typ) -> @ty.t {
+ alt (typ.struct) {
+ case (ty.ty_box(_)) {
+ ret ty.plain_box_ty(ty.plain_ty(ty.ty_nil), ast.imm);
+ }
+ case (_) { ret typ; }
+ }
+ }
+ auto f = simplifier;
+ ret ty.fold_ty(f, typ);
+}
+
// Computes the size of the data part of a non-dynamically-sized tag.
fn static_size_of_tag(@crate_ctxt cx, @ty.t t) -> uint {
if (ty.type_has_dynamic_size(t)) {
@@ -1127,25 +1144,7 @@ fn static_size_of_tag(@crate_ctxt cx, @ty.t t) -> uint {
auto max_size = 0u;
auto variants = tag_variants(cx, tid);
for (variant_info variant in variants) {
-
- let vec[@ty.t] args = vec();
- for (@ty.t t in variant.args) {
- alt (t.struct) {
- // NB: We're just going for 'size' here, so we can do a little
- // faking work here and substitute all boxes to boxed ints;
- // this will break any tag cycles we might otherwise traverse
- // (which would cause infinite recursion while measuring
- // size).
- case (ty.ty_box(_)) {
- args += vec(ty.plain_box_ty(ty.plain_ty(ty.ty_int),
- ast.imm));
- }
- case (_) {
- args += vec(t);
- }
- }
- }
- auto tup_ty = ty.plain_tup_ty(args);
+ auto tup_ty = simplify_type(ty.plain_tup_ty(variant.args));
// Perform any type parameter substitutions.
tup_ty = ty.bind_params_in_type(tup_ty);