about summary refs log tree commit diff
path: root/src/rustc
diff options
context:
space:
mode:
authorPatrick Walton <pcwalton@mimiga.net>2012-09-25 15:21:16 -0700
committerPatrick Walton <pcwalton@mimiga.net>2012-09-25 15:22:08 -0700
commita770d86201d5b41573b6b5f5bdfe3b70df919b28 (patch)
treec63aeb511f2af3ff2f0a3f0330c2528ead5a6fda /src/rustc
parent349ef79ce7aca24f6633893285cc9a5fc9dd7f37 (diff)
downloadrust-a770d86201d5b41573b6b5f5bdfe3b70df919b28.tar.gz
rust-a770d86201d5b41573b6b5f5bdfe3b70df919b28.zip
rustc: Move generally useful functions out of shape.rs in preparation for its destruction
Diffstat (limited to 'src/rustc')
-rw-r--r--src/rustc/middle/trans/machine.rs148
-rw-r--r--src/rustc/middle/trans/shape.rs144
-rw-r--r--src/rustc/rustc.rc1
3 files changed, 150 insertions, 143 deletions
diff --git a/src/rustc/middle/trans/machine.rs b/src/rustc/middle/trans/machine.rs
new file mode 100644
index 00000000000..5515d80f4bd
--- /dev/null
+++ b/src/rustc/middle/trans/machine.rs
@@ -0,0 +1,148 @@
+// Information concerning the machine representation of various types.
+
+use middle::trans::common::*;
+
+// 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.
+// This should reduce all pointers to some simple pointer type, to
+// ensure that we don't recurse endlessly when computing the size of a
+// nominal type that has pointers to itself in it.
+pub fn simplify_type(tcx: ty::ctxt, typ: ty::t) -> ty::t {
+    fn nilptr(tcx: ty::ctxt) -> ty::t {
+        ty::mk_ptr(tcx, {ty: ty::mk_nil(tcx), mutbl: ast::m_imm})
+    }
+    fn simplifier(tcx: ty::ctxt, typ: ty::t) -> ty::t {
+        match ty::get(typ).sty {
+          ty::ty_box(_) | ty::ty_opaque_box | ty::ty_uniq(_) |
+          ty::ty_evec(_, ty::vstore_uniq) | ty::ty_evec(_, ty::vstore_box) |
+          ty::ty_estr(ty::vstore_uniq) | ty::ty_estr(ty::vstore_box) |
+          ty::ty_ptr(_) | ty::ty_rptr(_,_) => nilptr(tcx),
+          ty::ty_fn(_) => ty::mk_tup(tcx, ~[nilptr(tcx), nilptr(tcx)]),
+          ty::ty_evec(_, ty::vstore_slice(_)) |
+          ty::ty_estr(ty::vstore_slice(_)) => {
+            ty::mk_tup(tcx, ~[nilptr(tcx), ty::mk_int(tcx)])
+          }
+          // Reduce a class type to a record type in which all the fields are
+          // simplified
+          ty::ty_class(did, ref substs) => {
+            let simpl_fields = (if ty::ty_dtor(tcx, did).is_some() {
+                // remember the drop flag
+                  ~[{ident: syntax::parse::token::special_idents::dtor,
+                     mt: {ty: ty::mk_u8(tcx),
+                          mutbl: ast::m_mutbl}}] }
+                else { ~[] }) +
+                do ty::lookup_class_fields(tcx, did).map |f| {
+                 let t = ty::lookup_field_type(tcx, did, f.id, substs);
+                 {ident: f.ident,
+                  mt: {ty: simplify_type(tcx, t), mutbl: ast::m_const}}
+            };
+            ty::mk_rec(tcx, simpl_fields)
+          }
+          _ => typ
+        }
+    }
+    ty::fold_ty(tcx, typ, |t| simplifier(tcx, t))
+}
+
+// ______________________________________________________________________
+// compute sizeof / alignof
+
+pub type metrics = {
+    bcx: block,
+    sz: ValueRef,
+    align: ValueRef
+};
+
+pub type tag_metrics = {
+    bcx: block,
+    sz: ValueRef,
+    align: ValueRef,
+    payload_align: ValueRef
+};
+
+// Returns the number of bytes clobbered by a Store to this type.
+pub fn llsize_of_store(cx: @crate_ctxt, t: TypeRef) -> uint {
+    return llvm::LLVMStoreSizeOfType(cx.td.lltd, t) as uint;
+}
+
+// Returns the number of bytes between successive elements of type T in an
+// array of T. This is the "ABI" size. It includes any ABI-mandated padding.
+pub fn llsize_of_alloc(cx: @crate_ctxt, t: TypeRef) -> uint {
+    return llvm::LLVMABISizeOfType(cx.td.lltd, t) as uint;
+}
+
+// Returns, as near as we can figure, the "real" size of a type. As in, the
+// bits in this number of bytes actually carry data related to the datum
+// with the type. Not junk, padding, accidentally-damaged words, or
+// whatever. Rounds up to the nearest byte though, so if you have a 1-bit
+// value, we return 1 here, not 0. Most of rustc works in bytes.
+pub fn llsize_of_real(cx: @crate_ctxt, t: TypeRef) -> uint {
+    let nbits = llvm::LLVMSizeOfTypeInBits(cx.td.lltd, t) as uint;
+    if nbits & 7u != 0u {
+        // Not an even number of bytes, spills into "next" byte.
+        1u + (nbits >> 3)
+    } else {
+        nbits >> 3
+    }
+}
+
+// Returns the "default" size of t, which is calculated by casting null to a
+// *T and then doing gep(1) on it and measuring the result. Really, look in
+// the LLVM sources. It does that. So this is likely similar to the ABI size
+// (i.e. including alignment-padding), but goodness knows which alignment it
+// winds up using. Probably the ABI one? Not recommended.
+pub fn llsize_of(cx: @crate_ctxt, t: TypeRef) -> ValueRef {
+    return llvm::LLVMConstIntCast(lib::llvm::llvm::LLVMSizeOf(t), cx.int_type,
+                               False);
+}
+
+// Returns the preferred alignment of the given type for the current target.
+// The preffered alignment may be larger than the alignment used when
+// packing the type into structs. This will be used for things like
+// allocations inside a stack frame, which LLVM has a free hand in.
+pub fn llalign_of_pref(cx: @crate_ctxt, t: TypeRef) -> uint {
+    return llvm::LLVMPreferredAlignmentOfType(cx.td.lltd, t) as uint;
+}
+
+// Returns the minimum alignment of a type required by the plattform.
+// This is the alignment that will be used for struct fields, arrays,
+// and similar ABI-mandated things.
+pub fn llalign_of_min(cx: @crate_ctxt, t: TypeRef) -> uint {
+    return llvm::LLVMABIAlignmentOfType(cx.td.lltd, t) as uint;
+}
+
+// Returns the "default" alignment of t, which is calculated by casting
+// null to a record containing a single-bit followed by a t value, then
+// doing gep(0,1) to get at the trailing (and presumably padded) t cell.
+pub fn llalign_of(cx: @crate_ctxt, t: TypeRef) -> ValueRef {
+    return llvm::LLVMConstIntCast(
+        lib::llvm::llvm::LLVMAlignOf(t), cx.int_type, False);
+}
+
+// Computes the size of the data part of an enum.
+pub fn static_size_of_enum(cx: @crate_ctxt, t: ty::t) -> uint {
+    if cx.enum_sizes.contains_key(t) { return cx.enum_sizes.get(t); }
+    match ty::get(t).sty {
+      ty::ty_enum(tid, ref substs) => {
+        // Compute max(variant sizes).
+        let mut max_size = 0u;
+        let variants = ty::enum_variants(cx.tcx, tid);
+        for vec::each(*variants) |variant| {
+            let tup_ty = simplify_type(cx.tcx,
+                                       ty::mk_tup(cx.tcx, variant.args));
+            // Perform any type parameter substitutions.
+            let tup_ty = ty::subst(cx.tcx, substs, tup_ty);
+            // Here we possibly do a recursive call.
+            let this_size =
+                llsize_of_real(cx, type_of::type_of(cx, tup_ty));
+            if max_size < this_size { max_size = this_size; }
+        }
+        cx.enum_sizes.insert(t, max_size);
+        return max_size;
+      }
+      _ => cx.sess.bug(~"static_size_of_enum called on non-enum")
+    }
+}
+
diff --git a/src/rustc/middle/trans/shape.rs b/src/rustc/middle/trans/shape.rs
index e09e3d9493d..28d24be77df 100644
--- a/src/rustc/middle/trans/shape.rs
+++ b/src/rustc/middle/trans/shape.rs
@@ -7,6 +7,7 @@ use driver::session;
 use driver::session::session;
 use trans::base;
 use middle::trans::common::*;
+use middle::trans::machine::*;
 use back::abi;
 use middle::ty;
 use middle::ty::field;
@@ -634,151 +635,8 @@ fn gen_shape_tables(ccx: @crate_ctxt) {
                           lib::llvm::InternalLinkage);
 }
 
-// ______________________________________________________________________
-// compute sizeof / alignof
-
-type metrics = {
-    bcx: block,
-    sz: ValueRef,
-    align: ValueRef
-};
-
-type tag_metrics = {
-    bcx: block,
-    sz: ValueRef,
-    align: ValueRef,
-    payload_align: ValueRef
-};
-
-// Returns the number of bytes clobbered by a Store to this type.
-fn llsize_of_store(cx: @crate_ctxt, t: TypeRef) -> uint {
-    return llvm::LLVMStoreSizeOfType(cx.td.lltd, t) as uint;
-}
-
-// Returns the number of bytes between successive elements of type T in an
-// array of T. This is the "ABI" size. It includes any ABI-mandated padding.
-fn llsize_of_alloc(cx: @crate_ctxt, t: TypeRef) -> uint {
-    return llvm::LLVMABISizeOfType(cx.td.lltd, t) as uint;
-}
-
-// Returns, as near as we can figure, the "real" size of a type. As in, the
-// bits in this number of bytes actually carry data related to the datum
-// with the type. Not junk, padding, accidentally-damaged words, or
-// whatever. Rounds up to the nearest byte though, so if you have a 1-bit
-// value, we return 1 here, not 0. Most of rustc works in bytes.
-fn llsize_of_real(cx: @crate_ctxt, t: TypeRef) -> uint {
-    let nbits = llvm::LLVMSizeOfTypeInBits(cx.td.lltd, t) as uint;
-    if nbits & 7u != 0u {
-        // Not an even number of bytes, spills into "next" byte.
-        1u + (nbits >> 3)
-    } else {
-        nbits >> 3
-    }
-}
-
-// Returns the "default" size of t, which is calculated by casting null to a
-// *T and then doing gep(1) on it and measuring the result. Really, look in
-// the LLVM sources. It does that. So this is likely similar to the ABI size
-// (i.e. including alignment-padding), but goodness knows which alignment it
-// winds up using. Probably the ABI one? Not recommended.
-fn llsize_of(cx: @crate_ctxt, t: TypeRef) -> ValueRef {
-    return llvm::LLVMConstIntCast(lib::llvm::llvm::LLVMSizeOf(t), cx.int_type,
-                               False);
-}
-
-// Returns the preferred alignment of the given type for the current target.
-// The preffered alignment may be larger than the alignment used when
-// packing the type into structs. This will be used for things like
-// allocations inside a stack frame, which LLVM has a free hand in.
-fn llalign_of_pref(cx: @crate_ctxt, t: TypeRef) -> uint {
-    return llvm::LLVMPreferredAlignmentOfType(cx.td.lltd, t) as uint;
-}
-
-// Returns the minimum alignment of a type required by the plattform.
-// This is the alignment that will be used for struct fields, arrays,
-// and similar ABI-mandated things.
-fn llalign_of_min(cx: @crate_ctxt, t: TypeRef) -> uint {
-    return llvm::LLVMABIAlignmentOfType(cx.td.lltd, t) as uint;
-}
-
-// Returns the "default" alignment of t, which is calculated by casting
-// null to a record containing a single-bit followed by a t value, then
-// doing gep(0,1) to get at the trailing (and presumably padded) t cell.
-fn llalign_of(cx: @crate_ctxt, t: TypeRef) -> ValueRef {
-    return llvm::LLVMConstIntCast(
-        lib::llvm::llvm::LLVMAlignOf(t), cx.int_type, False);
-}
-
 // Computes the static size of a enum, without using mk_tup(), which is
 // bad for performance.
 //
 // NB: Migrate trans over to use this.
 
-// Computes the size of the data part of an enum.
-fn static_size_of_enum(cx: @crate_ctxt, t: ty::t) -> uint {
-    if cx.enum_sizes.contains_key(t) { return cx.enum_sizes.get(t); }
-    match ty::get(t).sty {
-      ty::ty_enum(tid, ref substs) => {
-        // Compute max(variant sizes).
-        let mut max_size = 0u;
-        let variants = ty::enum_variants(cx.tcx, tid);
-        for vec::each(*variants) |variant| {
-            let tup_ty = simplify_type(cx.tcx,
-                                       ty::mk_tup(cx.tcx, variant.args));
-            // Perform any type parameter substitutions.
-            let tup_ty = ty::subst(cx.tcx, substs, tup_ty);
-            // Here we possibly do a recursive call.
-            let this_size =
-                llsize_of_real(cx, type_of::type_of(cx, tup_ty));
-            if max_size < this_size { max_size = this_size; }
-        }
-        cx.enum_sizes.insert(t, max_size);
-        return max_size;
-      }
-      _ => cx.sess.bug(~"static_size_of_enum called on non-enum")
-    }
-}
-
-// 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.
-// This should reduce all pointers to some simple pointer type, to
-// ensure that we don't recurse endlessly when computing the size of a
-// nominal type that has pointers to itself in it.
-fn simplify_type(tcx: ty::ctxt, typ: ty::t) -> ty::t {
-    fn nilptr(tcx: ty::ctxt) -> ty::t {
-        ty::mk_ptr(tcx, {ty: ty::mk_nil(tcx), mutbl: ast::m_imm})
-    }
-    fn simplifier(tcx: ty::ctxt, typ: ty::t) -> ty::t {
-        match ty::get(typ).sty {
-          ty::ty_box(_) | ty::ty_opaque_box | ty::ty_uniq(_) |
-          ty::ty_evec(_, ty::vstore_uniq) | ty::ty_evec(_, ty::vstore_box) |
-          ty::ty_estr(ty::vstore_uniq) | ty::ty_estr(ty::vstore_box) |
-          ty::ty_ptr(_) | ty::ty_rptr(_,_) => nilptr(tcx),
-          ty::ty_fn(_) => ty::mk_tup(tcx, ~[nilptr(tcx), nilptr(tcx)]),
-          ty::ty_evec(_, ty::vstore_slice(_)) |
-          ty::ty_estr(ty::vstore_slice(_)) => {
-            ty::mk_tup(tcx, ~[nilptr(tcx), ty::mk_int(tcx)])
-          }
-          // Reduce a class type to a record type in which all the fields are
-          // simplified
-          ty::ty_class(did, ref substs) => {
-            let simpl_fields = (if ty::ty_dtor(tcx, did).is_some() {
-                // remember the drop flag
-                  ~[{ident: syntax::parse::token::special_idents::dtor,
-                     mt: {ty: ty::mk_u8(tcx),
-                          mutbl: ast::m_mutbl}}] }
-                else { ~[] }) +
-                do ty::lookup_class_fields(tcx, did).map |f| {
-                 let t = ty::lookup_field_type(tcx, did, f.id, substs);
-                 {ident: f.ident,
-                  mt: {ty: simplify_type(tcx, t), mutbl: ast::m_const}}
-            };
-            ty::mk_rec(tcx, simpl_fields)
-          }
-          _ => typ
-        }
-    }
-    ty::fold_ty(tcx, typ, |t| simplifier(tcx, t))
-}
diff --git a/src/rustc/rustc.rc b/src/rustc/rustc.rc
index d34ae4e35f3..ca5491245e0 100644
--- a/src/rustc/rustc.rc
+++ b/src/rustc/rustc.rc
@@ -86,6 +86,7 @@ mod middle {
         mod type_use;
         #[legacy_exports]
         mod reachable;
+        mod machine;
     }
     #[legacy_exports]
     mod ty;