Skip to content

Commit 386ba3a

Browse files
committed
Further work on vec-append. Almost working.
1 parent d39da6f commit 386ba3a

File tree

1 file changed

+135
-45
lines changed

1 file changed

+135
-45
lines changed

src/comp/middle/trans.rs

Lines changed: 135 additions & 45 deletions
Original file line numberDiff line numberDiff line change
@@ -1723,6 +1723,8 @@ fn mk_plain_tag(ast.def_id tid) -> @ty.t {
17231723
}
17241724

17251725

1726+
type val_fn = fn(@block_ctxt cx, ValueRef v) -> result;
1727+
17261728
type val_and_ty_fn = fn(@block_ctxt cx, ValueRef v, @ty.t t) -> result;
17271729

17281730
type val_pair_and_ty_fn =
@@ -1922,23 +1924,17 @@ fn iter_structural_ty_full(@block_ctxt cx,
19221924
ret r;
19231925
}
19241926

1925-
// Iterates through a pair of sequences, until the src* hits the src_lim*.
1926-
fn iter_sequence_pair_inner(@block_ctxt cx,
1927-
ValueRef dst, // elt*
1928-
ValueRef src, // elt*
1929-
ValueRef src_lim, // elt*
1930-
@ty.t elt_ty,
1931-
val_pair_and_ty_fn f) -> result {
1927+
// Iterates through a pointer range, until the src* hits the src_lim*.
1928+
fn iter_sequence_raw(@block_ctxt cx,
1929+
ValueRef src, // elt*
1930+
ValueRef src_lim, // elt*
1931+
ValueRef elt_sz,
1932+
val_fn f) -> result {
19321933

19331934
auto bcx = cx;
19341935

1935-
auto llunit_ty = type_of(cx.fcx.ccx, elt_ty);
1936-
auto unit_sz = size_of(bcx, elt_ty);
1937-
bcx = unit_sz.bcx;
1938-
19391936
let ValueRef src_int = vp2i(bcx, src);
19401937
let ValueRef src_lim_int = vp2i(bcx, src_lim);
1941-
let ValueRef dst_int = vp2i(bcx, dst);
19421938

19431939
auto cond_cx = new_scope_block_ctxt(cx, "sequence-iter cond");
19441940
auto body_cx = new_scope_block_ctxt(cx, "sequence-iter body");
@@ -1948,33 +1944,23 @@ fn iter_sequence_pair_inner(@block_ctxt cx,
19481944

19491945
let ValueRef src_curr = cond_cx.build.Phi(T_int(),
19501946
vec(src_int), vec(bcx.llbb));
1951-
let ValueRef dst_curr = cond_cx.build.Phi(T_int(),
1952-
vec(dst_int), vec(bcx.llbb));
19531947

1954-
auto end_test = cond_cx.build.ICmp(lib.llvm.LLVMIntNE,
1948+
auto end_test = cond_cx.build.ICmp(lib.llvm.LLVMIntULT,
19551949
src_curr, src_lim_int);
19561950

19571951
cond_cx.build.CondBr(end_test, body_cx.llbb, next_cx.llbb);
19581952

1959-
auto src_curr_ptr = vi2p(body_cx, src_curr, T_ptr(llunit_ty));
1960-
auto dst_curr_ptr = vi2p(body_cx, dst_curr, T_ptr(llunit_ty));
1953+
auto src_curr_ptr = vi2p(body_cx, src_curr, T_ptr(T_i8()));
19611954

1962-
auto body_res = f(body_cx,
1963-
dst_curr_ptr,
1964-
load_scalar_or_boxed(body_cx, src_curr_ptr, elt_ty),
1965-
elt_ty);
1955+
auto body_res = f(body_cx, src_curr_ptr);
19661956
body_cx = body_res.bcx;
19671957

1968-
auto src_next = body_cx.build.Add(src_curr, unit_sz.val);
1969-
auto dst_next = body_cx.build.Add(dst_curr, unit_sz.val);
1958+
auto src_next = body_cx.build.Add(src_curr, elt_sz);
19701959
body_cx.build.Br(cond_cx.llbb);
19711960

19721961
cond_cx.build.AddIncomingToPhi(src_curr, vec(src_next),
19731962
vec(body_cx.llbb));
19741963

1975-
cond_cx.build.AddIncomingToPhi(dst_curr, vec(dst_next),
1976-
vec(body_cx.llbb));
1977-
19781964
ret res(next_cx, C_nil());
19791965
}
19801966

@@ -1985,15 +1971,17 @@ fn iter_sequence_inner(@block_ctxt cx,
19851971
@ty.t elt_ty,
19861972
val_and_ty_fn f) -> result {
19871973
fn adaptor_fn(val_and_ty_fn f,
1974+
@ty.t elt_ty,
19881975
@block_ctxt cx,
1989-
ValueRef av,
1990-
ValueRef bv,
1991-
@ty.t t) -> result {
1992-
ret f(cx, bv, t);
1976+
ValueRef v) -> result {
1977+
auto llty = type_of(cx.fcx.ccx, elt_ty);
1978+
auto p = cx.build.PointerCast(v, T_ptr(llty));
1979+
ret f(cx, load_scalar_or_boxed(cx, p, elt_ty), elt_ty);
19931980
}
19941981

1995-
be iter_sequence_pair_inner(cx, src, src, src_lim, elt_ty,
1996-
bind adaptor_fn(f, _, _, _, _));
1982+
auto elt_sz = size_of(cx, elt_ty);
1983+
be iter_sequence_raw(elt_sz.bcx, src, src_lim, elt_sz.val,
1984+
bind adaptor_fn(f, elt_ty, _, _));
19971985
}
19981986

19991987

@@ -5475,34 +5463,136 @@ fn trans_vec_append_glue(@crate_ctxt cx) {
54755463

54765464
auto bcx = new_top_block_ctxt(fcx);
54775465

5466+
auto lldst_vec = bcx.build.Load(lldst_vec_ptr);
5467+
54785468
// First the dst vec needs to grow to accommodate the src vec.
54795469
// To do this we have to figure out how many bytes to add.
5480-
auto n_bytes =
5481-
bcx.build.Load(bcx.build.GEP(llsrc_vec,
5482-
vec(C_int(0),
5483-
C_int(abi.vec_elt_fill))));
54845470

5485-
n_bytes = bcx.build.Select(llskipnull,
5486-
bcx.build.Sub(n_bytes, C_int(1)),
5487-
n_bytes);
5471+
fn vec_fill(@block_ctxt bcx, ValueRef v) -> ValueRef {
5472+
ret bcx.build.Load(bcx.build.GEP(v, vec(C_int(0),
5473+
C_int(abi.vec_elt_fill))));
5474+
}
5475+
5476+
fn put_vec_fill(@block_ctxt bcx, ValueRef v, ValueRef fill) -> ValueRef {
5477+
ret bcx.build.Store(fill,
5478+
bcx.build.GEP(v,
5479+
vec(C_int(0),
5480+
C_int(abi.vec_elt_fill))));
5481+
}
54885482

5483+
fn vec_fill_adjusted(@block_ctxt bcx, ValueRef v,
5484+
ValueRef skipnull) -> ValueRef {
5485+
auto f = bcx.build.Load(bcx.build.GEP(v,
5486+
vec(C_int(0),
5487+
C_int(abi.vec_elt_fill))));
5488+
ret bcx.build.Select(skipnull, bcx.build.Sub(f, C_int(1)), f);
5489+
}
54895490

5490-
auto llneed_copy_ptr = bcx.build.Alloca(T_int());
5491+
fn vec_p0(@block_ctxt bcx, ValueRef v) -> ValueRef {
5492+
auto p = bcx.build.GEP(v, vec(C_int(0),
5493+
C_int(abi.vec_elt_data)));
5494+
ret bcx.build.PointerCast(p, T_ptr(T_i8()));
5495+
}
5496+
5497+
5498+
fn vec_p1(@block_ctxt bcx, ValueRef v) -> ValueRef {
5499+
auto len = vec_fill(bcx, v);
5500+
ret bcx.build.GEP(vec_p0(bcx, v), vec(len));
5501+
}
5502+
5503+
fn vec_p1_adjusted(@block_ctxt bcx, ValueRef v,
5504+
ValueRef skipnull) -> ValueRef {
5505+
auto len = vec_fill_adjusted(bcx, v, skipnull);
5506+
ret bcx.build.GEP(vec_p0(bcx, v), vec(len));
5507+
}
5508+
5509+
5510+
auto llcopy_dst_ptr = bcx.build.Alloca(T_int());
54915511
auto llnew_vec_res =
54925512
trans_upcall(bcx, "upcall_vec_grow",
5493-
vec(vp2i(bcx, bcx.build.Load(lldst_vec_ptr)),
5494-
n_bytes,
5495-
vp2i(bcx, llneed_copy_ptr),
5513+
vec(vp2i(bcx, lldst_vec),
5514+
vec_fill_adjusted(bcx, llsrc_vec, llskipnull),
5515+
vp2i(bcx, llcopy_dst_ptr),
54965516
vp2i(bcx, llvec_tydesc)));
54975517

54985518
bcx = llnew_vec_res.bcx;
54995519
auto llnew_vec = vi2p(bcx, llnew_vec_res.val,
55005520
T_opaque_vec_ptr());
55015521

5522+
put_vec_fill(bcx, llnew_vec, C_int(0));
55025523

5503-
// FIXME: complete this.
5524+
auto copy_dst_cx = new_sub_block_ctxt(bcx, "copy new <- dst");
5525+
auto copy_src_cx = new_sub_block_ctxt(bcx, "copy new <- src");
55045526

5505-
bcx.build.RetVoid();
5527+
auto pp0 = bcx.build.Alloca(T_ptr(T_i8()));
5528+
bcx.build.Store(vec_p0(bcx, llnew_vec), pp0);
5529+
5530+
bcx.build.CondBr(bcx.build.TruncOrBitCast
5531+
(bcx.build.Load(llcopy_dst_ptr),
5532+
T_i1()),
5533+
copy_dst_cx.llbb,
5534+
copy_src_cx.llbb);
5535+
5536+
5537+
fn copy_elts(@block_ctxt cx,
5538+
ValueRef elt_tydesc,
5539+
ValueRef dst,
5540+
ValueRef src,
5541+
ValueRef n_bytes) -> result {
5542+
5543+
auto src_lim = cx.build.GEP(src, vec(n_bytes));
5544+
5545+
auto elt_llsz =
5546+
cx.build.Load(cx.build.GEP(elt_tydesc,
5547+
vec(C_int(0),
5548+
C_int(abi.tydesc_field_size))));
5549+
5550+
fn take_one(ValueRef elt_tydesc,
5551+
@block_ctxt cx, ValueRef v) -> result {
5552+
call_tydesc_glue_full(cx, v,
5553+
elt_tydesc,
5554+
abi.tydesc_field_take_glue_off);
5555+
ret res(cx, v);
5556+
}
5557+
5558+
auto bcx = iter_sequence_raw(cx, src, src_lim,
5559+
elt_llsz, bind take_one(elt_tydesc,
5560+
_, _)).bcx;
5561+
5562+
ret call_memcpy(bcx, dst, src, n_bytes);
5563+
}
5564+
5565+
// Copy any dst elements in, omitting null if doing str.
5566+
auto n_bytes = vec_fill_adjusted(copy_dst_cx, lldst_vec, llskipnull);
5567+
copy_dst_cx = copy_elts(copy_dst_cx,
5568+
llelt_tydesc,
5569+
copy_dst_cx.build.Load(pp0),
5570+
vec_p0(copy_dst_cx, lldst_vec),
5571+
n_bytes).bcx;
5572+
5573+
put_vec_fill(copy_dst_cx, llnew_vec, n_bytes);
5574+
copy_dst_cx.build.Store(vec_p1_adjusted(copy_dst_cx,
5575+
llnew_vec, llskipnull),
5576+
pp0);
5577+
copy_dst_cx.build.Br(copy_src_cx.llbb);
5578+
5579+
5580+
// Copy any src elements in, carrying along null if doing str.
5581+
n_bytes = vec_fill(copy_src_cx, llsrc_vec);
5582+
copy_src_cx = copy_elts(copy_src_cx,
5583+
llelt_tydesc,
5584+
copy_src_cx.build.Load(pp0),
5585+
vec_p0(copy_src_cx, llsrc_vec),
5586+
n_bytes).bcx;
5587+
5588+
put_vec_fill(copy_src_cx, llnew_vec,
5589+
copy_src_cx.build.Add(vec_fill(copy_src_cx,
5590+
llnew_vec),
5591+
n_bytes));
5592+
5593+
// Write new_vec back through the alias we were given.
5594+
copy_src_cx.build.Store(llnew_vec, lldst_vec_ptr);
5595+
copy_src_cx.build.RetVoid();
55065596
}
55075597

55085598

0 commit comments

Comments
 (0)