@@ -7,6 +7,7 @@ use driver::session;
7
7
use driver:: session:: session;
8
8
use trans:: base;
9
9
use middle:: trans:: common:: * ;
10
+ use middle:: trans:: machine:: * ;
10
11
use back:: abi;
11
12
use middle:: ty;
12
13
use middle:: ty:: field;
@@ -634,151 +635,8 @@ fn gen_shape_tables(ccx: @crate_ctxt) {
634
635
lib:: llvm:: InternalLinkage ) ;
635
636
}
636
637
637
- // ______________________________________________________________________
638
- // compute sizeof / alignof
639
-
640
- type metrics = {
641
- bcx : block,
642
- sz : ValueRef ,
643
- align : ValueRef
644
- } ;
645
-
646
- type tag_metrics = {
647
- bcx : block,
648
- sz : ValueRef ,
649
- align : ValueRef ,
650
- payload_align : ValueRef
651
- } ;
652
-
653
- // Returns the number of bytes clobbered by a Store to this type.
654
- fn llsize_of_store ( cx : @crate_ctxt , t : TypeRef ) -> uint {
655
- return llvm:: LLVMStoreSizeOfType ( cx. td . lltd , t) as uint ;
656
- }
657
-
658
- // Returns the number of bytes between successive elements of type T in an
659
- // array of T. This is the "ABI" size. It includes any ABI-mandated padding.
660
- fn llsize_of_alloc ( cx : @crate_ctxt , t : TypeRef ) -> uint {
661
- return llvm:: LLVMABISizeOfType ( cx. td . lltd , t) as uint ;
662
- }
663
-
664
- // Returns, as near as we can figure, the "real" size of a type. As in, the
665
- // bits in this number of bytes actually carry data related to the datum
666
- // with the type. Not junk, padding, accidentally-damaged words, or
667
- // whatever. Rounds up to the nearest byte though, so if you have a 1-bit
668
- // value, we return 1 here, not 0. Most of rustc works in bytes.
669
- fn llsize_of_real ( cx : @crate_ctxt , t : TypeRef ) -> uint {
670
- let nbits = llvm:: LLVMSizeOfTypeInBits ( cx. td . lltd , t) as uint ;
671
- if nbits & 7 u != 0 u {
672
- // Not an even number of bytes, spills into "next" byte.
673
- 1 u + ( nbits >> 3 )
674
- } else {
675
- nbits >> 3
676
- }
677
- }
678
-
679
- // Returns the "default" size of t, which is calculated by casting null to a
680
- // *T and then doing gep(1) on it and measuring the result. Really, look in
681
- // the LLVM sources. It does that. So this is likely similar to the ABI size
682
- // (i.e. including alignment-padding), but goodness knows which alignment it
683
- // winds up using. Probably the ABI one? Not recommended.
684
- fn llsize_of ( cx : @crate_ctxt , t : TypeRef ) -> ValueRef {
685
- return llvm:: LLVMConstIntCast ( lib:: llvm:: llvm:: LLVMSizeOf ( t) , cx. int_type ,
686
- False ) ;
687
- }
688
-
689
- // Returns the preferred alignment of the given type for the current target.
690
- // The preffered alignment may be larger than the alignment used when
691
- // packing the type into structs. This will be used for things like
692
- // allocations inside a stack frame, which LLVM has a free hand in.
693
- fn llalign_of_pref ( cx : @crate_ctxt , t : TypeRef ) -> uint {
694
- return llvm:: LLVMPreferredAlignmentOfType ( cx. td . lltd , t) as uint ;
695
- }
696
-
697
- // Returns the minimum alignment of a type required by the plattform.
698
- // This is the alignment that will be used for struct fields, arrays,
699
- // and similar ABI-mandated things.
700
- fn llalign_of_min ( cx : @crate_ctxt , t : TypeRef ) -> uint {
701
- return llvm:: LLVMABIAlignmentOfType ( cx. td . lltd , t) as uint ;
702
- }
703
-
704
- // Returns the "default" alignment of t, which is calculated by casting
705
- // null to a record containing a single-bit followed by a t value, then
706
- // doing gep(0,1) to get at the trailing (and presumably padded) t cell.
707
- fn llalign_of ( cx : @crate_ctxt , t : TypeRef ) -> ValueRef {
708
- return llvm:: LLVMConstIntCast (
709
- lib:: llvm:: llvm:: LLVMAlignOf ( t) , cx. int_type , False ) ;
710
- }
711
-
712
638
// Computes the static size of a enum, without using mk_tup(), which is
713
639
// bad for performance.
714
640
//
715
641
// NB: Migrate trans over to use this.
716
642
717
- // Computes the size of the data part of an enum.
718
- fn static_size_of_enum ( cx : @crate_ctxt , t : ty:: t ) -> uint {
719
- if cx. enum_sizes . contains_key ( t) { return cx. enum_sizes . get ( t) ; }
720
- match ty:: get ( t) . sty {
721
- ty:: ty_enum( tid, ref substs) => {
722
- // Compute max(variant sizes).
723
- let mut max_size = 0 u;
724
- let variants = ty:: enum_variants ( cx. tcx , tid) ;
725
- for vec:: each( * variants) |variant| {
726
- let tup_ty = simplify_type ( cx. tcx ,
727
- ty:: mk_tup ( cx. tcx , variant. args ) ) ;
728
- // Perform any type parameter substitutions.
729
- let tup_ty = ty:: subst ( cx. tcx , substs, tup_ty) ;
730
- // Here we possibly do a recursive call.
731
- let this_size =
732
- llsize_of_real ( cx, type_of:: type_of ( cx, tup_ty) ) ;
733
- if max_size < this_size { max_size = this_size; }
734
- }
735
- cx. enum_sizes . insert ( t, max_size) ;
736
- return max_size;
737
- }
738
- _ => cx. sess . bug ( ~"static_size_of_enum called on non-enum")
739
- }
740
- }
741
-
742
- // Creates a simpler, size-equivalent type. The resulting type is guaranteed
743
- // to have (a) the same size as the type that was passed in; (b) to be non-
744
- // recursive. This is done by replacing all boxes in a type with boxed unit
745
- // types.
746
- // This should reduce all pointers to some simple pointer type, to
747
- // ensure that we don't recurse endlessly when computing the size of a
748
- // nominal type that has pointers to itself in it.
749
- fn simplify_type ( tcx : ty:: ctxt , typ : ty:: t ) -> ty:: t {
750
- fn nilptr ( tcx : ty:: ctxt ) -> ty:: t {
751
- ty:: mk_ptr ( tcx, { ty: ty:: mk_nil ( tcx) , mutbl: ast:: m_imm} )
752
- }
753
- fn simplifier ( tcx : ty:: ctxt , typ : ty:: t ) -> ty:: t {
754
- match ty:: get ( typ) . sty {
755
- ty:: ty_box( _) | ty:: ty_opaque_box | ty:: ty_uniq( _) |
756
- ty:: ty_evec( _, ty:: vstore_uniq) | ty:: ty_evec( _, ty:: vstore_box) |
757
- ty:: ty_estr( ty:: vstore_uniq) | ty:: ty_estr( ty:: vstore_box) |
758
- ty:: ty_ptr( _) | ty:: ty_rptr( _, _) => nilptr ( tcx) ,
759
- ty:: ty_fn( _) => ty:: mk_tup ( tcx, ~[ nilptr ( tcx) , nilptr ( tcx) ] ) ,
760
- ty:: ty_evec( _, ty:: vstore_slice( _) ) |
761
- ty:: ty_estr( ty:: vstore_slice( _) ) => {
762
- ty:: mk_tup ( tcx, ~[ nilptr ( tcx) , ty:: mk_int ( tcx) ] )
763
- }
764
- // Reduce a class type to a record type in which all the fields are
765
- // simplified
766
- ty:: ty_class( did, ref substs) => {
767
- let simpl_fields = ( if ty:: ty_dtor ( tcx, did) . is_some ( ) {
768
- // remember the drop flag
769
- ~[ { ident: syntax:: parse:: token:: special_idents:: dtor,
770
- mt : { ty : ty:: mk_u8 ( tcx) ,
771
- mutbl : ast:: m_mutbl} } ] }
772
- else { ~[ ] } ) +
773
- do ty:: lookup_class_fields ( tcx, did) . map |f| {
774
- let t = ty:: lookup_field_type ( tcx, did, f. id , substs) ;
775
- { ident: f. ident ,
776
- mt : { ty : simplify_type ( tcx, t) , mutbl : ast:: m_const} }
777
- } ;
778
- ty:: mk_rec ( tcx, simpl_fields)
779
- }
780
- _ => typ
781
- }
782
- }
783
- ty:: fold_ty ( tcx, typ, |t| simplifier ( tcx, t) )
784
- }
0 commit comments