Skip to content

Commit 16ca6e8

Browse files
committed
Change vector append to no longer rely on an intrinsic
Issue #1981
1 parent 0545e4a commit 16ca6e8

File tree

1 file changed

+27
-13
lines changed

1 file changed

+27
-13
lines changed

src/rustc/middle/trans/tvec.rs

Lines changed: 27 additions & 13 deletions
Original file line numberDiff line numberDiff line change
@@ -14,6 +14,12 @@ fn get_fill(bcx: block, vptr: ValueRef) -> ValueRef {
1414
let _icx = bcx.insn_ctxt("tvec::get_fill");
1515
Load(bcx, GEPi(bcx, vptr, [0, abi::vec_elt_fill]))
1616
}
17+
fn set_fill(bcx: block, vptr: ValueRef, fill: ValueRef) {
18+
Store(bcx, fill, GEPi(bcx, vptr, [0, abi::vec_elt_fill]));
19+
}
20+
fn get_alloc(bcx: block, vptr: ValueRef) -> ValueRef {
21+
Load(bcx, GEPi(bcx, vptr, [0, abi::vec_elt_alloc]))
22+
}
1723
fn get_dataptr(bcx: block, vptr: ValueRef, unit_ty: TypeRef)
1824
-> ValueRef {
1925
let _icx = bcx.insn_ctxt("tvec::get_dataptr");
@@ -185,21 +191,29 @@ fn trans_append_literal(bcx: block, vptrptr: ValueRef, vec_ty: ty::t,
185191
let _icx = bcx.insn_ctxt("tvec::trans_append_literal");
186192
let mut bcx = bcx, ccx = bcx.ccx();
187193
let elt_ty = ty::sequence_element_type(bcx.tcx(), vec_ty);
188-
let mut ti = none;
189-
let td = get_tydesc(ccx, elt_ty, ti);
190-
base::lazily_emit_tydesc_glue(ccx, abi::tydesc_field_take_glue, ti);
191-
let opaque_v = PointerCast(bcx, vptrptr,
192-
T_ptr(T_ptr(ccx.opaque_vec_type)));
194+
let elt_llty = type_of::type_of(ccx, elt_ty);
195+
let elt_sz = shape::llsize_of(ccx, elt_llty);
196+
let scratch = base::alloca(bcx, elt_llty);
193197
for val in vals {
194-
let {bcx: e_bcx, val: elt} = base::trans_temp_expr(bcx, val);
195-
bcx = e_bcx;
196-
let r = base::spill_if_immediate(bcx, elt, elt_ty);
197-
let spilled = r.val;
198-
bcx = r.bcx;
199-
Call(bcx, bcx.ccx().upcalls.vec_push,
200-
[opaque_v, td, PointerCast(bcx, spilled, T_ptr(T_i8()))]);
198+
bcx = base::trans_expr_save_in(bcx, val, scratch);
199+
let vptr = Load(bcx, vptrptr);
200+
let old_fill = get_fill(bcx, vptr);
201+
let new_fill = Add(bcx, old_fill, elt_sz);
202+
let do_grow = ICmp(bcx, lib::llvm::IntUGT, new_fill,
203+
get_alloc(bcx, vptr));
204+
bcx = base::with_cond(bcx, do_grow) {|bcx|
205+
let pt = PointerCast(bcx, vptrptr,
206+
T_ptr(T_ptr(ccx.opaque_vec_type)));
207+
Call(bcx, ccx.upcalls.vec_grow, [pt, new_fill]);
208+
bcx
209+
};
210+
let vptr = Load(bcx, vptrptr);
211+
set_fill(bcx, vptr, new_fill);
212+
let targetptr = pointer_add(bcx, get_dataptr(bcx, vptr, elt_llty),
213+
old_fill);
214+
bcx = call_memmove(bcx, targetptr, scratch, elt_sz).bcx;
201215
}
202-
ret bcx;
216+
bcx
203217
}
204218

205219
fn trans_add(bcx: block, vec_ty: ty::t, lhs: ValueRef,

0 commit comments

Comments
 (0)