@@ -31,33 +31,39 @@ fn pointer_add(bcx: &@block_ctxt, ptr: ValueRef, bytes: ValueRef)
31
31
ret PointerCast ( bcx, InBoundsGEP ( bcx, bptr, [ bytes] ) , old_ty) ;
32
32
}
33
33
34
- // FIXME factor out a scaling version wrapping a non-scaling version
35
- fn alloc ( bcx : & @block_ctxt , vec_ty : & ty:: t , vecsz : ValueRef , is_scaled : bool )
36
- -> { bcx : @block_ctxt ,
37
- val : ValueRef ,
38
- unit_ty : ty:: t ,
39
- llunitsz : ValueRef ,
40
- llunitty : TypeRef } {
34
+ fn alloc_raw ( bcx : & @block_ctxt , fill : ValueRef , alloc : ValueRef ) -> result {
35
+ let llvecty = T_opaque_ivec ( ) ;
36
+ let vecsize = Add ( bcx, alloc, llsize_of ( llvecty) ) ;
37
+ let { bcx, val: vecptr } =
38
+ trans_shared_malloc ( bcx, T_ptr ( llvecty) , vecsize) ;
39
+ Store ( bcx, fill, InBoundsGEP
40
+ ( bcx, vecptr, [ C_int ( 0 ) , C_uint ( abi:: ivec_elt_fill) ] ) ) ;
41
+ Store ( bcx, alloc, InBoundsGEP
42
+ ( bcx, vecptr, [ C_int ( 0 ) , C_uint ( abi:: ivec_elt_alloc) ] ) ) ;
43
+ ret { bcx : bcx, val : vecptr} ;
44
+ }
45
+
46
+ type alloc_result = { bcx : @block_ctxt ,
47
+ val : ValueRef ,
48
+ unit_ty : ty:: t ,
49
+ llunitsz : ValueRef ,
50
+ llunitty : TypeRef } ;
41
51
52
+ fn alloc ( bcx : & @block_ctxt , vec_ty : & ty:: t , elts : uint ) -> alloc_result {
42
53
let unit_ty = ty:: sequence_element_type ( bcx_tcx ( bcx) , vec_ty) ;
43
54
let llunitty = type_of_or_i8 ( bcx, unit_ty) ;
44
55
let llvecty = T_ivec ( llunitty) ;
45
56
let { bcx, val: unit_sz } = size_of ( bcx, unit_ty) ;
46
57
47
- let fill = if is_scaled { vecsz }
48
- else { Mul ( bcx, vecsz, unit_sz) } ;
49
- let vecsize = Add ( bcx, fill, llsize_of ( llvecty) ) ;
50
- let { bcx, val: vecptr } =
51
- trans_shared_malloc ( bcx, T_ptr ( llvecty) , vecsize) ;
52
- add_clean_temp ( bcx, vecptr, vec_ty) ;
53
-
54
- Store ( bcx, fill, InBoundsGEP
55
- ( bcx, vecptr, [ C_int ( 0 ) , C_uint ( abi:: ivec_elt_fill) ] ) ) ;
56
- Store ( bcx, fill, InBoundsGEP
57
- ( bcx, vecptr, [ C_int ( 0 ) , C_uint ( abi:: ivec_elt_alloc) ] ) ) ;
58
- ret { bcx : bcx, val : vecptr,
59
- unit_ty : unit_ty, llunitsz : unit_sz, llunitty : llunitty} ;
58
+ let fill = Mul ( bcx, C_uint ( elts) , unit_sz) ;
59
+ let alloc = if elts < 4 u { Mul ( bcx, C_int ( 4 ) , unit_sz) } else { fill } ;
60
+ let { bcx, val: vptr } = alloc_raw ( bcx, fill, alloc) ;
61
+ let vptr = PointerCast ( bcx, vptr, T_ptr ( llvecty) ) ;
62
+ add_clean_temp ( bcx, vptr, vec_ty) ;
63
+ ret { bcx : bcx, val : vptr, unit_ty : unit_ty,
64
+ llunitsz : unit_sz, llunitty : llunitty} ;
60
65
}
66
+
61
67
fn duplicate ( bcx : & @block_ctxt , vptrptr : ValueRef ) -> @block_ctxt {
62
68
let vptr = Load ( bcx, vptrptr) ;
63
69
let fill = get_fill ( bcx, vptr) ;
@@ -89,7 +95,7 @@ fn trans_ivec(bcx: &@block_ctxt, args: &[@ast::expr],
89
95
id : ast:: node_id ) -> result {
90
96
let vec_ty = node_id_type ( bcx_ccx ( bcx) , id) ;
91
97
let { bcx, val: vptr , llunitsz , unit_ty , llunitty } =
92
- alloc ( bcx, vec_ty, C_uint ( vec:: len ( args) ) , false ) ;
98
+ alloc ( bcx, vec_ty, vec:: len ( args) ) ;
93
99
94
100
// Store the individual elements.
95
101
let dataptr = get_dataptr ( bcx, vptr, llunitty) ;
@@ -110,7 +116,7 @@ fn trans_ivec(bcx: &@block_ctxt, args: &[@ast::expr],
110
116
fn trans_istr ( bcx : & @block_ctxt , s : istr ) -> result {
111
117
let veclen = std:: istr:: byte_len ( s) + 1 u; // +1 for \0
112
118
let { bcx, val: sptr , _} =
113
- alloc ( bcx, ty:: mk_istr ( bcx_tcx ( bcx) ) , C_uint ( veclen) , false ) ;
119
+ alloc ( bcx, ty:: mk_istr ( bcx_tcx ( bcx) ) , veclen) ;
114
120
115
121
let llcstr = C_cstr ( bcx_ccx ( bcx) , s) ;
116
122
let bcx = call_memmove ( bcx, get_dataptr ( bcx, sptr, T_i8 ( ) ) ,
@@ -194,12 +200,17 @@ fn trans_add(bcx: &@block_ctxt, vec_ty: ty::t, lhs: ValueRef,
194
200
ty:: ty_istr. { true }
195
201
ty:: ty_vec ( _) { false }
196
202
} ;
203
+ let unit_ty = ty:: sequence_element_type ( bcx_tcx ( bcx) , vec_ty) ;
204
+ let llunitty = type_of_or_i8 ( bcx, unit_ty) ;
205
+ let { bcx, val: llunitsz } = size_of ( bcx, unit_ty) ;
206
+
197
207
let lhs_fill = get_fill ( bcx, lhs) ;
198
208
if strings { lhs_fill = Sub ( bcx, lhs_fill, C_int ( 1 ) ) ; }
199
209
let rhs_fill = get_fill ( bcx, rhs) ;
200
210
let new_fill = Add ( bcx, lhs_fill, rhs_fill) ;
201
- let { bcx, val: new_vec , unit_ty , llunitsz , llunitty } =
202
- alloc ( bcx, vec_ty, new_fill, true ) ;
211
+ let { bcx, val: new_vec } = alloc_raw ( bcx, new_fill, new_fill) ;
212
+ let new_vec = PointerCast ( bcx, new_vec, T_ptr ( T_ivec ( llunitty) ) ) ;
213
+ add_clean_temp ( bcx, new_vec, vec_ty) ;
203
214
204
215
let write_ptr_ptr = do_spill ( bcx, get_dataptr ( bcx, new_vec, llunitty) ) ;
205
216
let copy_fn = bind fn( bcx: & @block_ctxt, addr: ValueRef , _ty: ty:: t,
0 commit comments