Skip to content

Commit b5e3ac0

Browse files
committed
---
yaml --- r: 1453 b: refs/heads/master c: d08f3a1 h: refs/heads/master i: 1451: b166aa0 v: v3
1 parent ca6e0a1 commit b5e3ac0

File tree

2 files changed

+116
-39
lines changed

2 files changed

+116
-39
lines changed

[refs]

Lines changed: 1 addition & 1 deletion
Original file line numberDiff line numberDiff line change
@@ -1,2 +1,2 @@
11
---
2-
refs/heads/master: 1291cc2df90c36eee8642048e1bf1b69a690781f
2+
refs/heads/master: d08f3a1c702c337c494bbc03d8bed9664ac1dddf

trunk/src/comp/middle/trans.rs

Lines changed: 115 additions & 38 deletions
Original file line numberDiff line numberDiff line change
@@ -1493,27 +1493,50 @@ fn mk_plain_tag(ast.def_id tid) -> @ty.t {
14931493

14941494
type val_and_ty_fn = fn(@block_ctxt cx, ValueRef v, @ty.t t) -> result;
14951495

1496+
type val_pair_and_ty_fn =
1497+
fn(@block_ctxt cx, ValueRef av, ValueRef bv, @ty.t t) -> result;
1498+
14961499
// Iterates through the elements of a structural type.
14971500
fn iter_structural_ty(@block_ctxt cx,
14981501
ValueRef v,
14991502
@ty.t t,
15001503
val_and_ty_fn f)
15011504
-> result {
1505+
fn adaptor_fn(val_and_ty_fn f,
1506+
@block_ctxt cx,
1507+
ValueRef av,
1508+
ValueRef bv,
1509+
@ty.t t) -> result {
1510+
ret f(cx, av, t);
1511+
}
1512+
be iter_structural_ty_full(cx, v, v, t,
1513+
bind adaptor_fn(f, _, _, _, _));
1514+
}
1515+
1516+
1517+
fn iter_structural_ty_full(@block_ctxt cx,
1518+
ValueRef av,
1519+
ValueRef bv,
1520+
@ty.t t,
1521+
val_pair_and_ty_fn f)
1522+
-> result {
15021523
let result r = res(cx, C_nil());
15031524

15041525
fn iter_boxpp(@block_ctxt cx,
1505-
ValueRef box_cell,
1506-
val_and_ty_fn f) -> result {
1507-
auto box_ptr = cx.build.Load(box_cell);
1526+
ValueRef box_a_cell,
1527+
ValueRef box_b_cell,
1528+
val_pair_and_ty_fn f) -> result {
1529+
auto box_a_ptr = cx.build.Load(box_a_cell);
1530+
auto box_b_ptr = cx.build.Load(box_b_cell);
15081531
auto tnil = plain_ty(ty.ty_nil);
15091532
auto tbox = plain_ty(ty.ty_box(tnil));
15101533

15111534
auto inner_cx = new_sub_block_ctxt(cx, "iter box");
15121535
auto next_cx = new_sub_block_ctxt(cx, "next");
1513-
auto null_test = cx.build.IsNull(box_ptr);
1536+
auto null_test = cx.build.IsNull(box_a_ptr);
15141537
cx.build.CondBr(null_test, next_cx.llbb, inner_cx.llbb);
15151538

1516-
auto r = f(inner_cx, box_ptr, tbox);
1539+
auto r = f(inner_cx, box_a_ptr, box_b_ptr, tbox);
15171540
r.bcx.build.Br(next_cx.llbb);
15181541
ret res(next_cx, r.val);
15191542
}
@@ -1522,19 +1545,23 @@ fn iter_structural_ty(@block_ctxt cx,
15221545
case (ty.ty_tup(?args)) {
15231546
let int i = 0;
15241547
for (@ty.t arg in args) {
1525-
auto elt = r.bcx.build.GEP(v, vec(C_int(0), C_int(i)));
1548+
auto elt_a = r.bcx.build.GEP(av, vec(C_int(0), C_int(i)));
1549+
auto elt_b = r.bcx.build.GEP(bv, vec(C_int(0), C_int(i)));
15261550
r = f(r.bcx,
1527-
load_scalar_or_boxed(r.bcx, elt, arg),
1551+
load_scalar_or_boxed(r.bcx, elt_a, arg),
1552+
load_scalar_or_boxed(r.bcx, elt_b, arg),
15281553
arg);
15291554
i += 1;
15301555
}
15311556
}
15321557
case (ty.ty_rec(?fields)) {
15331558
let int i = 0;
15341559
for (ty.field fld in fields) {
1535-
auto llfld = r.bcx.build.GEP(v, vec(C_int(0), C_int(i)));
1560+
auto llfld_a = r.bcx.build.GEP(av, vec(C_int(0), C_int(i)));
1561+
auto llfld_b = r.bcx.build.GEP(bv, vec(C_int(0), C_int(i)));
15361562
r = f(r.bcx,
1537-
load_scalar_or_boxed(r.bcx, llfld, fld.ty),
1563+
load_scalar_or_boxed(r.bcx, llfld_a, fld.ty),
1564+
load_scalar_or_boxed(r.bcx, llfld_b, fld.ty),
15381565
fld.ty);
15391566
i += 1;
15401567
}
@@ -1545,53 +1572,69 @@ fn iter_structural_ty(@block_ctxt cx,
15451572
auto variants = tag_variants(cx.fcx.ccx, tid);
15461573
auto n_variants = _vec.len[ast.variant](variants);
15471574

1548-
auto lldiscrim_ptr = cx.build.GEP(v, vec(C_int(0), C_int(0)));
1549-
auto llunion_ptr = cx.build.GEP(v, vec(C_int(0), C_int(1)));
1550-
auto lldiscrim = cx.build.Load(lldiscrim_ptr);
1575+
auto lldiscrim_a_ptr = cx.build.GEP(av, vec(C_int(0), C_int(0)));
1576+
auto llunion_a_ptr = cx.build.GEP(av, vec(C_int(0), C_int(1)));
1577+
auto lldiscrim_a = cx.build.Load(lldiscrim_a_ptr);
1578+
1579+
auto lldiscrim_b_ptr = cx.build.GEP(bv, vec(C_int(0), C_int(0)));
1580+
auto llunion_b_ptr = cx.build.GEP(bv, vec(C_int(0), C_int(1)));
1581+
auto lldiscrim_b = cx.build.Load(lldiscrim_b_ptr);
15511582

15521583
auto unr_cx = new_sub_block_ctxt(cx, "tag-iter-unr");
15531584
unr_cx.build.Unreachable();
15541585

1555-
auto llswitch = cx.build.Switch(lldiscrim, unr_cx.llbb,
1556-
n_variants);
1586+
auto llswitch = cx.build.Switch(lldiscrim_a, unr_cx.llbb,
1587+
n_variants);
15571588

15581589
auto next_cx = new_sub_block_ctxt(cx, "tag-iter-next");
15591590

15601591
auto i = 0u;
15611592
for (ast.variant variant in variants) {
1562-
auto variant_cx = new_sub_block_ctxt(cx, "tag-iter-variant-" +
1593+
auto variant_cx = new_sub_block_ctxt(cx,
1594+
"tag-iter-variant-" +
15631595
_uint.to_str(i, 10u));
15641596
llvm.LLVMAddCase(llswitch, C_int(i as int), variant_cx.llbb);
15651597

15661598
if (_vec.len[ast.variant_arg](variant.args) > 0u) {
15671599
// N-ary variant.
1568-
let vec[ValueRef] vals = vec(C_int(0), C_int(1),
1569-
C_int(i as int));
1570-
auto llvar = variant_cx.build.GEP(v, vals);
15711600
auto llvarty = type_of_variant(cx.fcx.ccx, variants.(i));
15721601

15731602
auto fn_ty = ty.ann_to_type(variants.(i).ann);
15741603
alt (fn_ty.struct) {
15751604
case (ty.ty_fn(_, ?args, _)) {
1576-
auto llvarp = variant_cx.build.
1577-
TruncOrBitCast(llunion_ptr, T_ptr(llvarty));
1605+
auto llvarp_a = variant_cx.build.
1606+
TruncOrBitCast(llunion_a_ptr, T_ptr(llvarty));
1607+
1608+
auto llvarp_b = variant_cx.build.
1609+
TruncOrBitCast(llunion_b_ptr, T_ptr(llvarty));
15781610

15791611
auto ty_params = tag_ty_params(cx.fcx.ccx, tid);
15801612

15811613
auto j = 0u;
15821614
for (ty.arg a in args) {
15831615
auto v = vec(C_int(0), C_int(j as int));
1584-
auto llfldp = variant_cx.build.GEP(llvarp, v);
1616+
1617+
auto llfldp_a =
1618+
variant_cx.build.GEP(llvarp_a, v);
1619+
1620+
auto llfldp_b =
1621+
variant_cx.build.GEP(llvarp_b, v);
15851622

15861623
auto ty_subst = ty.substitute_ty_params(
15871624
ty_params, tps, a.ty);
15881625

1589-
auto llfld =
1626+
auto llfld_a =
15901627
load_scalar_or_boxed(variant_cx,
1591-
llfldp,
1628+
llfldp_a,
15921629
ty_subst);
15931630

1594-
auto res = f(variant_cx, llfld, ty_subst);
1631+
auto llfld_b =
1632+
load_scalar_or_boxed(variant_cx,
1633+
llfldp_b,
1634+
ty_subst);
1635+
1636+
auto res = f(variant_cx,
1637+
llfld_a, llfld_b, ty_subst);
15951638
variant_cx = res.bcx;
15961639
j += 1u;
15971640
}
@@ -1611,21 +1654,29 @@ fn iter_structural_ty(@block_ctxt cx,
16111654
ret res(next_cx, C_nil());
16121655
}
16131656
case (ty.ty_fn(_,_,_)) {
1614-
auto box_cell =
1615-
cx.build.GEP(v,
1657+
auto box_cell_a =
1658+
cx.build.GEP(av,
1659+
vec(C_int(0),
1660+
C_int(abi.fn_field_box)));
1661+
auto box_cell_b =
1662+
cx.build.GEP(bv,
16161663
vec(C_int(0),
16171664
C_int(abi.fn_field_box)));
1618-
ret iter_boxpp(cx, box_cell, f);
1665+
ret iter_boxpp(cx, box_cell_a, box_cell_b, f);
16191666
}
16201667
case (ty.ty_obj(_)) {
1621-
auto box_cell =
1622-
cx.build.GEP(v,
1668+
auto box_cell_a =
1669+
cx.build.GEP(av,
1670+
vec(C_int(0),
1671+
C_int(abi.obj_field_box)));
1672+
auto box_cell_b =
1673+
cx.build.GEP(bv,
16231674
vec(C_int(0),
16241675
C_int(abi.obj_field_box)));
1625-
ret iter_boxpp(cx, box_cell, f);
1676+
ret iter_boxpp(cx, box_cell_a, box_cell_b, f);
16261677
}
16271678
case (_) {
1628-
cx.fcx.ccx.sess.unimpl("type in iter_structural_ty");
1679+
cx.fcx.ccx.sess.unimpl("type in iter_structural_ty_full");
16291680
}
16301681
}
16311682
ret r;
@@ -1965,21 +2016,47 @@ fn trans_compare(@block_ctxt cx, ast.binop op, @ty.t t,
19652016
ret res(cx, trans_scalar_compare(cx, op, t, lhs, rhs));
19662017

19672018
} else if (ty.type_is_structural(t)) {
1968-
auto scx = new_sub_block_ctxt(cx, "structural compare body");
1969-
auto next = new_sub_block_ctxt(cx, "structural compare completion");
2019+
auto scx = new_sub_block_ctxt(cx, "structural compare start");
2020+
auto next = new_sub_block_ctxt(cx, "structural compare end");
19702021
cx.build.Br(scx.llbb);
19712022

19722023
// Start with the assumptioin that our predicate holds.
19732024
auto flag = scx.build.Alloca(T_i1());
19742025
scx.build.Store(C_integral(1, T_i1()), flag);
19752026

1976-
// Attempt to prove otherwise by inverting the sense of the comparison
1977-
// on each inner element and bailing if any succeed.
2027+
// Attempt to prove otherwise by assuming true, comparing each element
2028+
// and writing 0 + early-exiting if any comparisons fail.
2029+
2030+
fn inner(@block_ctxt next_cx,
2031+
ValueRef flag,
2032+
ast.binop op,
2033+
@block_ctxt cx,
2034+
ValueRef av,
2035+
ValueRef bv,
2036+
@ty.t t) -> result {
2037+
// Compare av op bv
2038+
auto cnt_cx = new_sub_block_ctxt(cx, "continue comparison");
2039+
auto stop_cx = new_sub_block_ctxt(cx, "stop comparison");
2040+
2041+
auto r = trans_compare(cx, op, t, av, bv);
2042+
2043+
// if true, then carry on, else write 0 to flag, branch to 'next'.
2044+
r.bcx.build.CondBr(r.val, cnt_cx.llbb, stop_cx.llbb);
2045+
stop_cx.build.Store(C_integral(0, T_i1()), flag);
2046+
stop_cx.build.Br(next_cx.llbb);
2047+
2048+
ret res(cnt_cx, C_nil());
2049+
}
2050+
2051+
// FIXME: this is wrong for tag types; need to confirm discriminants
2052+
// are equal before blindly walking over elements.
19782053

1979-
// FIXME: finish this.
2054+
auto r = iter_structural_ty_full(scx, lhs, rhs, t,
2055+
bind inner(next, flag, op,
2056+
_, _, _, _));
19802057

1981-
auto v = scx.build.Load(flag);
1982-
scx.build.Br(next.llbb);
2058+
r.bcx.build.Br(next.llbb);
2059+
auto v = next.build.Load(flag);
19832060
ret res(next, v);
19842061

19852062
} else {

0 commit comments

Comments
 (0)