@@ -572,10 +572,17 @@ fn T_opaque_vec_ptr() -> TypeRef {
572
572
// Interior vector.
573
573
//
574
574
// TODO: Support user-defined vector sizes.
575
- fn T_ivec ( ) -> TypeRef {
575
+ fn T_ivec ( TypeRef t ) -> TypeRef {
576
576
ret T_struct ( [ T_int ( ) , // Length ("fill"; if zero, heapified)
577
577
T_int ( ) , // Alloc
578
- T_array ( T_i8 ( ) , abi:: ivec_default_size) ] ) ; // Body elements
578
+ T_array ( t, abi:: ivec_default_length) ] ) ; // Body elements
579
+ }
580
+
581
+ // Note that the size of this one is in bytes.
582
+ fn T_opaque_ivec ( ) -> TypeRef {
583
+ ret T_struct ( [ T_int ( ) , // Length ("fill"; if zero, heapified)
584
+ T_int ( ) , // Alloc
585
+ T_array ( T_i8 ( ) , abi:: ivec_default_size) ] ) ; // Body elements
579
586
}
580
587
581
588
// Interior vector on the heap. Cast to this when the allocated length (second
@@ -868,7 +875,7 @@ fn type_of_inner(&@crate_ctxt cx, &span sp, &ty::t t) -> TypeRef {
868
875
}
869
876
case ( ty:: ty_char) { llty = T_char ( ) ; }
870
877
case ( ty:: ty_str) { llty = T_ptr ( T_str ( ) ) ; }
871
- case ( ty:: ty_istr) { llty = T_ivec ( ) ; }
878
+ case ( ty:: ty_istr) { llty = T_ivec ( T_i8 ( ) ) ; }
872
879
case ( ty:: ty_tag ( _, _) ) {
873
880
if ( ty:: type_has_dynamic_size ( cx. tcx , t) ) {
874
881
llty = T_opaque_tag ( cx. tn ) ;
@@ -884,7 +891,11 @@ fn type_of_inner(&@crate_ctxt cx, &span sp, &ty::t t) -> TypeRef {
884
891
llty = T_ptr ( T_vec ( type_of_inner ( cx, sp, mt. ty ) ) ) ;
885
892
}
886
893
case ( ty:: ty_ivec ( ?mt) ) {
887
- llty = T_ivec ( ) ;
894
+ if ( ty:: type_has_dynamic_size ( cx. tcx , mt. ty ) ) {
895
+ llty = T_opaque_ivec ( ) ;
896
+ } else {
897
+ llty = T_ivec ( type_of_inner ( cx, sp, mt. ty ) ) ;
898
+ }
888
899
}
889
900
case ( ty:: ty_ptr ( ?mt) ) {
890
901
llty = T_ptr ( type_of_inner ( cx, sp, mt. ty ) ) ;
@@ -2661,9 +2672,8 @@ fn get_ivec_len_and_data(&@block_ctxt bcx, ValueRef v, ty::t unit_ty) ->
2661
2672
auto stack_len = bcx. build . Load ( bcx. build . InBoundsGEP ( v,
2662
2673
[ C_int ( 0 ) , C_uint ( abi:: ivec_elt_len) ] ) ) ;
2663
2674
auto stack_elem = bcx. build . InBoundsGEP ( v, [ C_int ( 0 ) ,
2664
- C_uint ( abi:: ivec_elt_elems) ] ) ;
2665
- stack_elem = bcx. build . PointerCast ( stack_elem,
2666
- T_ptr ( T_array ( llunitty, 0 u) ) ) ;
2675
+ C_uint ( abi:: ivec_elt_elems) ,
2676
+ C_int ( 0 ) ] ) ;
2667
2677
2668
2678
auto on_heap = bcx. build . ICmp ( lib:: llvm:: LLVMIntEQ , stack_len, C_int ( 0 ) ) ;
2669
2679
@@ -2691,22 +2701,22 @@ fn get_ivec_len_and_data(&@block_ctxt bcx, ValueRef v, ty::t unit_ty) ->
2691
2701
// Technically this context is unnecessary, but it makes this function
2692
2702
// clearer.
2693
2703
auto zero_len = C_int ( 0 ) ;
2694
- auto zero_elem = C_null ( T_ptr ( T_array ( llunitty, 0 u ) ) ) ;
2704
+ auto zero_elem = C_null ( T_ptr ( llunitty) ) ;
2695
2705
zero_len_cx. build . Br ( next_cx. llbb ) ;
2696
2706
2697
2707
// If we're here, then we actually have a heapified vector.
2698
2708
auto heap_len = nonzero_len_cx. build . Load (
2699
2709
nonzero_len_cx. build . InBoundsGEP ( heap_ptr,
2700
2710
[ C_int ( 0 ) , C_uint ( abi:: ivec_heap_elt_len) ] ) ) ;
2701
2711
auto heap_elem = nonzero_len_cx. build . InBoundsGEP ( heap_ptr,
2702
- [ C_int ( 0 ) , C_uint ( abi:: ivec_heap_elt_elems) ] ) ;
2712
+ [ C_int ( 0 ) , C_uint ( abi:: ivec_heap_elt_elems) , C_int ( 0 ) ] ) ;
2703
2713
nonzero_len_cx. build . Br ( next_cx. llbb ) ;
2704
2714
2705
2715
// Now we can figure out the length of `v` and get a pointer to its first
2706
2716
// element.
2707
2717
auto len = next_cx. build . Phi ( T_int ( ) , [ stack_len, zero_len, heap_len] ,
2708
2718
[ bcx. llbb , zero_len_cx. llbb , nonzero_len_cx. llbb ] ) ;
2709
- auto elem = next_cx. build . Phi ( T_ptr ( T_array ( llunitty, 0 u ) ) ,
2719
+ auto elem = next_cx. build . Phi ( T_ptr ( llunitty) ,
2710
2720
[ stack_elem, zero_elem, heap_elem] ,
2711
2721
[ bcx. llbb , zero_len_cx. llbb , nonzero_len_cx. llbb ] ) ;
2712
2722
ret tup( len, elem, next_cx) ;
@@ -2791,6 +2801,8 @@ fn iter_structural_ty_full(&@block_ctxt cx,
2791
2801
bcx = b_len_and_data. _2 ;
2792
2802
2793
2803
// Calculate the last pointer address we want to handle.
2804
+ // TODO: Optimize this when the size of the unit type is statically
2805
+ // known to not use pointer casts, which tend to confuse LLVM.
2794
2806
auto len = umin ( bcx, a_len, b_len) ;
2795
2807
auto b_elem_i8 = bcx. build . PointerCast ( b_elem, T_ptr ( T_i8 ( ) ) ) ;
2796
2808
auto b_end_i8 = bcx. build . GEP ( b_elem_i8, [ len] ) ;
@@ -4817,16 +4829,17 @@ fn trans_index(&@block_ctxt cx, &span sp, &@ast::expr base,
4817
4829
alt ( interior_len_and_data) {
4818
4830
case ( some ( ?lad) ) { body = lad. _1 ; }
4819
4831
case ( none) {
4820
- body = next_cx. build . GEP ( v, [ C_int ( 0 ) , C_int ( abi:: vec_elt_data) ] ) ;
4832
+ body = next_cx. build . GEP ( v,
4833
+ [ C_int ( 0 ) , C_int ( abi:: vec_elt_data) , C_int ( 0 ) ] ) ;
4821
4834
}
4822
4835
}
4823
4836
4824
4837
auto elt;
4825
4838
if ( ty:: type_has_dynamic_size ( cx. fcx . lcx . ccx . tcx , unit_ty) ) {
4826
- body = next_cx. build . PointerCast ( body, T_ptr ( T_array ( T_i8 ( ) , 0 u ) ) ) ;
4827
- elt = next_cx. build . GEP ( body, [ C_int ( 0 ) , scaled_ix] ) ;
4839
+ body = next_cx. build . PointerCast ( body, T_ptr ( T_i8 ( ) ) ) ;
4840
+ elt = next_cx. build . GEP ( body, [ scaled_ix] ) ;
4828
4841
} else {
4829
- elt = next_cx. build . GEP ( body, [ C_int ( 0 ) , ix_val] ) ;
4842
+ elt = next_cx. build . GEP ( body, [ ix_val] ) ;
4830
4843
4831
4844
// We're crossing a box boundary here, so we may need to pointer cast.
4832
4845
auto llunitty = type_of ( next_cx. fcx . lcx . ccx , sp, unit_ty) ;
@@ -5649,7 +5662,13 @@ fn trans_ivec(@block_ctxt bcx, &vec[@ast::expr] args, &ast::ann ann)
5649
5662
bcx = rslt. bcx;
5650
5663
5651
5664
auto llunitty = type_of_or_i8( bcx, unit_ty) ;
5652
- auto llvecptr = alloca( bcx, T_ivec ( ) ) ;
5665
+ auto llvecptr;
5666
+ if ( ty:: type_has_dynamic_size( bcx. fcx. lcx. ccx. tcx, unit_ty) ) {
5667
+ llvecptr = alloca( bcx, T_opaque_ivec ( ) ) ;
5668
+ } else {
5669
+ llvecptr = alloca( bcx, T_ivec ( llunitty) ) ;
5670
+ }
5671
+
5653
5672
auto lllen = bcx. build. Mul ( C_uint ( vec:: len( args) ) , unit_sz) ;
5654
5673
5655
5674
// Allocate the vector pieces and store length and allocated length.
@@ -5661,7 +5680,7 @@ fn trans_ivec(@block_ctxt bcx, &vec[@ast::expr] args, &ast::ann ann)
5661
5680
bcx. build. Store ( C_uint ( abi:: ivec_elt_alen) , bcx. build. GEP ( llvecptr,
5662
5681
[ C_int ( 0 ) , C_uint ( abi:: ivec_elt_alen) ] ) ) ;
5663
5682
llfirsteltptr = bcx. build. GEP ( llvecptr,
5664
- [ C_int ( 0 ) , C_uint ( abi:: ivec_elt_elems) ] ) ;
5683
+ [ C_int ( 0 ) , C_uint ( abi:: ivec_elt_elems) , C_int ( 0 ) ] ) ;
5665
5684
} else {
5666
5685
// Heap case.
5667
5686
auto llstubty = T_ivec_heap ( llunitty) ;
@@ -5690,12 +5709,10 @@ fn trans_ivec(@block_ctxt bcx, &vec[@ast::expr] args, &ast::ann ann)
5690
5709
bcx. build. Store ( lllen, bcx. build. GEP ( llheapptr,
5691
5710
[ C_int ( 0 ) , C_uint ( abi:: ivec_heap_elt_len) ] ) ) ;
5692
5711
llfirsteltptr = bcx. build. GEP ( llheapptr,
5693
- [ C_int ( 0 ) , C_uint ( abi:: ivec_heap_elt_elems) ] ) ;
5712
+ [ C_int ( 0 ) , C_uint ( abi:: ivec_heap_elt_elems) , C_int ( 0 ) ] ) ;
5694
5713
}
5695
5714
}
5696
5715
5697
- llfirsteltptr = bcx. build. PointerCast ( llfirsteltptr, T_ptr ( llunitty) ) ;
5698
-
5699
5716
// Store the individual elements.
5700
5717
auto i = 0 u;
5701
5718
for ( @ast:: expr e in args) {
@@ -5705,10 +5722,10 @@ fn trans_ivec(@block_ctxt bcx, &vec[@ast::expr] args, &ast::ann ann)
5705
5722
5706
5723
auto lleltptr;
5707
5724
if ( ty:: type_has_dynamic_size ( bcx. fcx . lcx . ccx . tcx , unit_ty) ) {
5708
- lleltptr = bcx. build . GEP ( llfirsteltptr,
5725
+ lleltptr = bcx. build . InBoundsGEP ( llfirsteltptr,
5709
5726
[ bcx. build . Mul ( C_uint ( i) , unit_align) ] ) ;
5710
5727
} else {
5711
- lleltptr = bcx. build . GEP ( llfirsteltptr, [ C_uint ( i) ] ) ;
5728
+ lleltptr = bcx. build . InBoundsGEP ( llfirsteltptr, [ C_uint ( i) ] ) ;
5712
5729
}
5713
5730
5714
5731
bcx = copy_val ( bcx, INIT , lleltptr, llsrc, unit_ty) . bcx ;
0 commit comments