Skip to content

Commit 9f41bc8

Browse files
committed
Don't duplicate ivec-iterating loop code
trans_ivec is starting to look almost pleasant
1 parent 9084a3c commit 9f41bc8

File tree

1 file changed

+42
-90
lines changed

1 file changed

+42
-90
lines changed

src/comp/middle/trans_ivec.rs

Lines changed: 42 additions & 90 deletions
Original file line numberDiff line numberDiff line change
@@ -151,37 +151,22 @@ fn trans_append(cx: &@block_ctxt, vec_ty: ty::t, lhsptr: ValueRef,
151151

152152
let lhs_data = get_dataptr(bcx, lhs, llunitty);
153153
let lhs_off = lfill;
154-
if strings { lhs_off = Sub(bcx, lfill, C_int(1)); }
154+
if strings { lhs_off = Sub(bcx, lhs_off, C_int(1)); }
155155
let write_ptr = pointer_add(bcx, lhs_data, lhs_off);
156156
let write_ptr_ptr = do_spill(bcx, write_ptr);
157-
let end_ptr = pointer_add(bcx, write_ptr, rfill);
158-
let read_ptr_ptr = do_spill(bcx, get_dataptr(bcx, rhs, llunitty));
159-
160-
let header_cx = new_sub_block_ctxt(bcx, ~"copy_loop_header");
161-
Br(bcx, header_cx.llbb);
162-
let write_ptr = Load(header_cx, write_ptr_ptr);
163-
let not_yet_at_end = ICmp(header_cx, lib::llvm::LLVMIntNE,
164-
write_ptr, end_ptr);
165-
let body_cx = new_sub_block_ctxt(bcx, ~"copy_loop_body");
166-
let next_cx = new_sub_block_ctxt(bcx, ~"next");
167-
CondBr(header_cx, not_yet_at_end,
168-
body_cx.llbb, next_cx.llbb);
169-
170-
let read_ptr = Load(body_cx, read_ptr_ptr);
171-
let body_cx = copy_val(body_cx, INIT, write_ptr,
172-
load_if_immediate(body_cx, read_ptr, unit_ty),
173-
unit_ty);
174-
// Increment both pointers.
175-
if dynamic {
176-
// We have to increment by the dynamically-computed size.
177-
incr_ptr(body_cx, write_ptr, unit_sz, write_ptr_ptr);
178-
incr_ptr(body_cx, read_ptr, unit_sz, read_ptr_ptr);
179-
} else {
180-
incr_ptr(body_cx, write_ptr, C_int(1), write_ptr_ptr);
181-
incr_ptr(body_cx, read_ptr, C_int(1), read_ptr_ptr);
182-
}
183-
Br(body_cx, header_cx.llbb);
184-
ret rslt(next_cx, C_nil());
157+
let bcx = iter_ivec_raw(bcx, rhs, vec_ty, rfill, { | &bcx, addr, _ty |
158+
let write_ptr = Load(bcx, write_ptr_ptr);
159+
let bcx = copy_val(bcx, INIT, write_ptr,
160+
load_if_immediate(bcx, addr, unit_ty), unit_ty);
161+
if dynamic {
162+
// We have to increment by the dynamically-computed size.
163+
incr_ptr(bcx, write_ptr, unit_sz, write_ptr_ptr);
164+
} else {
165+
incr_ptr(bcx, write_ptr, C_int(1), write_ptr_ptr);
166+
}
167+
ret rslt(bcx, C_nil());
168+
}).bcx;
169+
ret rslt(bcx, C_nil());
185170
}
186171

187172
fn trans_append_literal(bcx: &@block_ctxt, vptrptr: ValueRef, vec_ty: ty::t,
@@ -216,75 +201,35 @@ fn trans_add(bcx: &@block_ctxt, vec_ty: ty::t, lhs: ValueRef,
216201
let {bcx, val: new_vec, unit_ty, llunitsz, llunitty} =
217202
alloc(bcx, vec_ty, new_fill, true);
218203

219-
// Emit the copy loop
220204
let write_ptr_ptr = do_spill(bcx, get_dataptr(bcx, new_vec, llunitty));
221-
let lhs_ptr = get_dataptr(bcx, lhs, llunitty);
222-
let lhs_ptr_ptr = do_spill(bcx, lhs_ptr);
223-
let lhs_end_ptr = pointer_add(bcx, lhs_ptr, lhs_fill);
224-
let rhs_ptr = get_dataptr(bcx, rhs, llunitty);
225-
let rhs_ptr_ptr = do_spill(bcx, rhs_ptr);
226-
let rhs_end_ptr = pointer_add(bcx, rhs_ptr, rhs_fill);
205+
let copy_block = { | &bcx, addr, _ty |
206+
let write_ptr = Load(bcx, write_ptr_ptr);
207+
let bcx = copy_val(bcx, INIT, write_ptr,
208+
load_if_immediate(bcx, addr, unit_ty), unit_ty);
209+
if ty::type_has_dynamic_size(bcx_tcx(bcx), unit_ty) {
210+
// We have to increment by the dynamically-computed size.
211+
incr_ptr(bcx, write_ptr, llunitsz, write_ptr_ptr);
212+
} else {
213+
incr_ptr(bcx, write_ptr, C_int(1), write_ptr_ptr);
214+
}
215+
ret rslt(bcx, C_nil());
216+
};
227217

228-
// Copy in elements from the LHS.
229-
let lhs_cx = new_sub_block_ctxt(bcx, ~"lhs_copy_header");
230-
Br(bcx, lhs_cx.llbb);
231-
let lhs_ptr = Load(lhs_cx, lhs_ptr_ptr);
232-
let not_at_end_lhs =
233-
ICmp(lhs_cx, lib::llvm::LLVMIntNE, lhs_ptr, lhs_end_ptr);
234-
let lhs_copy_cx = new_sub_block_ctxt(bcx, ~"lhs_copy_body");
235-
let rhs_cx = new_sub_block_ctxt(bcx, ~"rhs_copy_header");
236-
CondBr(lhs_cx, not_at_end_lhs, lhs_copy_cx.llbb, rhs_cx.llbb);
237-
let write_ptr = Load(lhs_copy_cx, write_ptr_ptr);
238-
lhs_copy_cx =
239-
copy_val(lhs_copy_cx, INIT, write_ptr,
240-
load_if_immediate(lhs_copy_cx, lhs_ptr, unit_ty), unit_ty);
241-
// Increment both pointers.
242-
if ty::type_has_dynamic_size(bcx_tcx(bcx), unit_ty) {
243-
// We have to increment by the dynamically-computed size.
244-
incr_ptr(lhs_copy_cx, write_ptr, llunitsz, write_ptr_ptr);
245-
incr_ptr(lhs_copy_cx, lhs_ptr, llunitsz, lhs_ptr_ptr);
246-
} else {
247-
incr_ptr(lhs_copy_cx, write_ptr, C_int(1), write_ptr_ptr);
248-
incr_ptr(lhs_copy_cx, lhs_ptr, C_int(1), lhs_ptr_ptr);
249-
}
250-
Br(lhs_copy_cx, lhs_cx.llbb);
218+
let bcx = iter_ivec_raw(bcx, lhs, vec_ty, lhs_fill, copy_block).bcx;
219+
let bcx = iter_ivec_raw(bcx, rhs, vec_ty, rhs_fill, copy_block).bcx;
220+
ret rslt(bcx, new_vec);
221+
}
251222

252-
// Copy in elements from the RHS.
253-
let rhs_ptr = Load(rhs_cx, rhs_ptr_ptr);
254-
let not_at_end_rhs =
255-
ICmp(rhs_cx, lib::llvm::LLVMIntNE, rhs_ptr, rhs_end_ptr);
256-
let rhs_copy_cx = new_sub_block_ctxt(bcx, ~"rhs_copy_body");
257-
let next_cx = new_sub_block_ctxt(bcx, ~"next");
258-
CondBr(rhs_cx, not_at_end_rhs, rhs_copy_cx.llbb, next_cx.llbb);
259-
let write_ptr = Load(rhs_copy_cx, write_ptr_ptr);
260-
rhs_copy_cx =
261-
copy_val(rhs_copy_cx, INIT, write_ptr,
262-
load_if_immediate(rhs_copy_cx, rhs_ptr, unit_ty), unit_ty);
263-
// Increment both pointers.
264-
if ty::type_has_dynamic_size(bcx_tcx(bcx), unit_ty) {
265-
// We have to increment by the dynamically-computed size.
266-
incr_ptr(rhs_copy_cx, write_ptr, llunitsz, write_ptr_ptr);
267-
incr_ptr(rhs_copy_cx, rhs_ptr, llunitsz, rhs_ptr_ptr);
268-
} else {
269-
incr_ptr(rhs_copy_cx, write_ptr, C_int(1), write_ptr_ptr);
270-
incr_ptr(rhs_copy_cx, rhs_ptr, C_int(1), rhs_ptr_ptr);
271-
}
272-
Br(rhs_copy_cx, rhs_cx.llbb);
223+
type val_and_ty_fn = fn(&@block_ctxt, ValueRef, ty::t) -> result;
273224

274-
ret rslt(next_cx, new_vec);
275-
}
225+
type iter_ivec_block = block(&@block_ctxt, ValueRef, ty::t) -> result;
276226

277-
// FIXME factor out a utility that can be used to create the loops built
278-
// above
279-
fn iter_ivec(bcx: &@block_ctxt, vptrptr: ValueRef, vec_ty: ty::t,
280-
f: &trans::val_and_ty_fn) -> result {
227+
fn iter_ivec_raw(bcx: &@block_ctxt, vptr: ValueRef, vec_ty: ty::t,
228+
fill: ValueRef, f: &iter_ivec_block) -> result {
281229
let unit_ty = ty::sequence_element_type(bcx_tcx(bcx), vec_ty);
282230
let llunitty = type_of_or_i8(bcx, unit_ty);
283231
let {bcx, val: unit_sz} = size_of(bcx, unit_ty);
284-
285-
let vptr = Load(bcx, PointerCast(bcx, vptrptr,
286-
T_ptr(T_ptr(T_ivec(llunitty)))));
287-
let fill = get_fill(bcx, vptr);
232+
let vptr = PointerCast(bcx, vptr, T_ptr(T_ivec(llunitty)));
288233
let data_ptr = get_dataptr(bcx, vptr, llunitty);
289234

290235
// Calculate the last pointer address we want to handle.
@@ -312,6 +257,13 @@ fn iter_ivec(bcx: &@block_ctxt, vptrptr: ValueRef, vec_ty: ty::t,
312257
ret rslt(next_cx, C_nil());
313258
}
314259

260+
fn iter_ivec(bcx: &@block_ctxt, vptrptr: ValueRef, vec_ty: ty::t,
261+
f: &iter_ivec_block) -> result {
262+
let vptr = Load(bcx, PointerCast(bcx, vptrptr,
263+
T_ptr(T_ptr(T_opaque_ivec()))));
264+
ret iter_ivec_raw(bcx, vptr, vec_ty, get_fill(bcx, vptr), f);
265+
}
266+
315267
//
316268
// Local Variables:
317269
// mode: rust

0 commit comments

Comments
 (0)