Skip to content

Commit c5417be

Browse files
committed
---
yaml --- r: 1589 b: refs/heads/master c: 8e8c336 h: refs/heads/master i: 1587: 43b38ef v: v3
1 parent f1e92ce commit c5417be

File tree

6 files changed

+168
-69
lines changed

6 files changed

+168
-69
lines changed

[refs]

+1-1
Original file line numberDiff line numberDiff line change
@@ -1,2 +1,2 @@
11
---
2-
refs/heads/master: fb246e4e478b487da3a0ad36583217b32f483116
2+
refs/heads/master: 8e8c336f93becbc394b99e978cc3d8145e7e9d7c

trunk/src/Makefile

+2
Original file line numberDiff line numberDiff line change
@@ -402,6 +402,7 @@ TEST_XFAILS_BOOT := $(TASK_XFAILS) \
402402
$(NOMINAL_TAG_XFAILS) \
403403
$(CONST_TAG_XFAILS) \
404404
test/run-pass/arith-unsigned.rs \
405+
test/run-pass/box-compare.rs \
405406
test/run-pass/child-outlives-parent.rs \
406407
test/run-pass/clone-with-exterior.rs \
407408
test/run-pass/constrained-type.rs \
@@ -416,6 +417,7 @@ TEST_XFAILS_BOOT := $(TASK_XFAILS) \
416417
test/run-pass/lib-io.rs \
417418
test/run-pass/mlist-cycle.rs \
418419
test/run-pass/obj-as.rs \
420+
test/run-pass/seq-compare.rs \
419421
test/run-pass/task-comm.rs \
420422
test/run-pass/task-comm-3.rs \
421423
test/run-pass/vec-slice.rs \

trunk/src/comp/middle/trans.rs

+137-68
Original file line numberDiff line numberDiff line change
@@ -890,6 +890,11 @@ fn umax(@block_ctxt cx, ValueRef a, ValueRef b) -> ValueRef {
890890
ret cx.build.Select(cond, b, a);
891891
}
892892

893+
fn umin(@block_ctxt cx, ValueRef a, ValueRef b) -> ValueRef {
894+
auto cond = cx.build.ICmp(lib.llvm.LLVMIntULT, a, b);
895+
ret cx.build.Select(cond, a, b);
896+
}
897+
893898
fn align_to(@block_ctxt cx, ValueRef off, ValueRef align) -> ValueRef {
894899
auto mask = cx.build.Sub(align, C_int(1));
895900
auto bumped = cx.build.Add(off, mask);
@@ -1774,7 +1779,7 @@ fn mk_plain_tag(ast.def_id tid) -> @ty.t {
17741779
}
17751780

17761781

1777-
type val_fn = fn(@block_ctxt cx, ValueRef v) -> result;
1782+
type val_pair_fn = fn(@block_ctxt cx, ValueRef dst, ValueRef src) -> result;
17781783

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

@@ -1987,13 +1992,15 @@ fn iter_structural_ty_full(@block_ctxt cx,
19871992

19881993
// Iterates through a pointer range, until the src* hits the src_lim*.
19891994
fn iter_sequence_raw(@block_ctxt cx,
1995+
ValueRef dst, // elt*
19901996
ValueRef src, // elt*
19911997
ValueRef src_lim, // elt*
19921998
ValueRef elt_sz,
1993-
val_fn f) -> result {
1999+
val_pair_fn f) -> result {
19942000

19952001
auto bcx = cx;
19962002

2003+
let ValueRef dst_int = vp2i(bcx, dst);
19972004
let ValueRef src_int = vp2i(bcx, src);
19982005
let ValueRef src_lim_int = vp2i(bcx, src_lim);
19992006

@@ -2003,6 +2010,8 @@ fn iter_sequence_raw(@block_ctxt cx,
20032010

20042011
bcx.build.Br(cond_cx.llbb);
20052012

2013+
let ValueRef dst_curr = cond_cx.build.Phi(T_int(),
2014+
vec(dst_int), vec(bcx.llbb));
20062015
let ValueRef src_curr = cond_cx.build.Phi(T_int(),
20072016
vec(src_int), vec(bcx.llbb));
20082017

@@ -2011,14 +2020,18 @@ fn iter_sequence_raw(@block_ctxt cx,
20112020

20122021
cond_cx.build.CondBr(end_test, body_cx.llbb, next_cx.llbb);
20132022

2023+
auto dst_curr_ptr = vi2p(body_cx, dst_curr, T_ptr(T_i8()));
20142024
auto src_curr_ptr = vi2p(body_cx, src_curr, T_ptr(T_i8()));
20152025

2016-
auto body_res = f(body_cx, src_curr_ptr);
2026+
auto body_res = f(body_cx, dst_curr_ptr, src_curr_ptr);
20172027
body_cx = body_res.bcx;
20182028

2029+
auto dst_next = body_cx.build.Add(dst_curr, elt_sz);
20192030
auto src_next = body_cx.build.Add(src_curr, elt_sz);
20202031
body_cx.build.Br(cond_cx.llbb);
20212032

2033+
cond_cx.build.AddIncomingToPhi(dst_curr, vec(dst_next),
2034+
vec(body_cx.llbb));
20222035
cond_cx.build.AddIncomingToPhi(src_curr, vec(src_next),
20232036
vec(body_cx.llbb));
20242037

@@ -2034,15 +2047,16 @@ fn iter_sequence_inner(@block_ctxt cx,
20342047
fn adaptor_fn(val_and_ty_fn f,
20352048
@ty.t elt_ty,
20362049
@block_ctxt cx,
2037-
ValueRef v) -> result {
2050+
ValueRef dst,
2051+
ValueRef src) -> result {
20382052
auto llty = type_of(cx.fcx.ccx, elt_ty);
2039-
auto p = cx.build.PointerCast(v, T_ptr(llty));
2053+
auto p = cx.build.PointerCast(src, T_ptr(llty));
20402054
ret f(cx, load_scalar_or_boxed(cx, p, elt_ty), elt_ty);
20412055
}
20422056

20432057
auto elt_sz = size_of(cx, elt_ty);
2044-
be iter_sequence_raw(elt_sz.bcx, src, src_lim, elt_sz.val,
2045-
bind adaptor_fn(f, elt_ty, _, _));
2058+
be iter_sequence_raw(elt_sz.bcx, src, src, src_lim, elt_sz.val,
2059+
bind adaptor_fn(f, elt_ty, _, _, _));
20462060
}
20472061

20482062

@@ -2378,13 +2392,27 @@ fn trans_unary(@block_ctxt cx, ast.unop op,
23782392
fail;
23792393
}
23802394

2381-
fn trans_compare(@block_ctxt cx, ast.binop op, @ty.t t,
2382-
ValueRef lhs, ValueRef rhs) -> result {
2395+
fn trans_compare(@block_ctxt cx0, ast.binop op, @ty.t t0,
2396+
ValueRef lhs0, ValueRef rhs0) -> result {
2397+
2398+
auto cx = cx0;
2399+
2400+
auto lhs_r = autoderef(cx, lhs0, t0);
2401+
auto lhs = lhs_r.val;
2402+
cx = lhs_r.bcx;
2403+
2404+
auto rhs_r = autoderef(cx, rhs0, t0);
2405+
auto rhs = rhs_r.val;
2406+
cx = rhs_r.bcx;
2407+
2408+
auto t = autoderefed_ty(t0);
23832409

23842410
if (ty.type_is_scalar(t)) {
23852411
ret res(cx, trans_scalar_compare(cx, op, t, lhs, rhs));
23862412

2387-
} else if (ty.type_is_structural(t)) {
2413+
} else if (ty.type_is_structural(t)
2414+
|| ty.type_is_sequence(t)) {
2415+
23882416
auto scx = new_sub_block_ctxt(cx, "structural compare start");
23892417
auto next = new_sub_block_ctxt(cx, "structural compare end");
23902418
cx.build.Br(scx.llbb);
@@ -2415,28 +2443,52 @@ fn trans_compare(@block_ctxt cx, ast.binop op, @ty.t t,
24152443

24162444
auto flag = scx.build.Alloca(T_i1());
24172445

2418-
alt (op) {
2419-
// ==, <= and >= default to true if they find == all the way.
2420-
case (ast.eq) { scx.build.Store(C_integral(1, T_i1()), flag); }
2421-
case (ast.le) { scx.build.Store(C_integral(1, T_i1()), flag); }
2422-
case (ast.ge) { scx.build.Store(C_integral(1, T_i1()), flag); }
2423-
case (_) {
2424-
// ==, <= and >= default to false if they find == all the way.
2425-
scx.build.Store(C_integral(0, T_i1()), flag);
2446+
if (ty.type_is_sequence(t)) {
2447+
2448+
// If we hit == all the way through the minimum-shared-length
2449+
// section, default to judging the relative sequence lengths.
2450+
auto len_cmp =
2451+
trans_integral_compare(scx, op, plain_ty(ty.ty_uint),
2452+
vec_fill(scx, lhs),
2453+
vec_fill(scx, rhs));
2454+
scx.build.Store(len_cmp, flag);
2455+
2456+
} else {
2457+
auto T = C_integral(1, T_i1());
2458+
auto F = C_integral(0, T_i1());
2459+
2460+
alt (op) {
2461+
// ==, <= and >= default to true if they find == all the way.
2462+
case (ast.eq) { scx.build.Store(T, flag); }
2463+
case (ast.le) { scx.build.Store(T, flag); }
2464+
case (ast.ge) { scx.build.Store(T, flag); }
2465+
case (_) {
2466+
// < > default to false if they find == all the way.
2467+
scx.build.Store(F, flag);
2468+
}
2469+
24262470
}
24272471
}
24282472

24292473
fn inner(@block_ctxt last_cx,
2474+
bool load_inner,
24302475
ValueRef flag,
24312476
ast.binop op,
24322477
@block_ctxt cx,
2433-
ValueRef av,
2434-
ValueRef bv,
2478+
ValueRef av0,
2479+
ValueRef bv0,
24352480
@ty.t t) -> result {
24362481

24372482
auto cnt_cx = new_sub_block_ctxt(cx, "continue comparison");
24382483
auto stop_cx = new_sub_block_ctxt(cx, "stop comparison");
24392484

2485+
auto av = av0;
2486+
auto bv = bv0;
2487+
if (load_inner) {
2488+
av = load_scalar_or_boxed(cx, av, t);
2489+
bv = load_scalar_or_boxed(cx, bv, t);
2490+
}
2491+
24402492
// First 'eq' comparison: if so, continue to next elts.
24412493
auto eq_r = trans_compare(cx, ast.eq, t, av, bv);
24422494
eq_r.bcx.build.CondBr(eq_r.val, cnt_cx.llbb, stop_cx.llbb);
@@ -2448,16 +2500,32 @@ fn trans_compare(@block_ctxt cx, ast.binop op, @ty.t t,
24482500
ret res(cnt_cx, C_nil());
24492501
}
24502502

2451-
auto r = iter_structural_ty_full(scx, lhs, rhs, t,
2452-
bind inner(next, flag, op,
2453-
_, _, _, _));
2503+
auto r;
2504+
if (ty.type_is_structural(t)) {
2505+
r = iter_structural_ty_full(scx, lhs, rhs, t,
2506+
bind inner(next, false, flag, op,
2507+
_, _, _, _));
2508+
} else {
2509+
auto lhs_p0 = vec_p0(scx, lhs);
2510+
auto rhs_p0 = vec_p0(scx, rhs);
2511+
auto min_len = umin(scx, vec_fill(scx, lhs), vec_fill(scx, rhs));
2512+
auto rhs_lim = scx.build.GEP(rhs_p0, vec(min_len));
2513+
auto elt_ty = ty.sequence_element_type(t);
2514+
auto elt_llsz_r = size_of(scx, elt_ty);
2515+
scx = elt_llsz_r.bcx;
2516+
r = iter_sequence_raw(scx, lhs, rhs, rhs_lim,
2517+
elt_llsz_r.val,
2518+
bind inner(next, true, flag, op,
2519+
_, _, _, elt_ty));
2520+
}
24542521

24552522
r.bcx.build.Br(next.llbb);
24562523
auto v = next.build.Load(flag);
24572524
ret res(next, v);
24582525

2526+
24592527
} else {
2460-
// FIXME: compare vec, str, box?
2528+
// FIXME: compare obj, fn by pointer?
24612529
cx.fcx.ccx.sess.unimpl("type in trans_compare");
24622530
ret res(cx, C_bool(false));
24632531
}
@@ -5670,6 +5738,45 @@ fn make_vec_append_glue(ModuleRef llmod, type_names tn) -> ValueRef {
56705738
ret llfn;
56715739
}
56725740

5741+
5742+
fn vec_fill(@block_ctxt bcx, ValueRef v) -> ValueRef {
5743+
ret bcx.build.Load(bcx.build.GEP(v, vec(C_int(0),
5744+
C_int(abi.vec_elt_fill))));
5745+
}
5746+
5747+
fn put_vec_fill(@block_ctxt bcx, ValueRef v, ValueRef fill) -> ValueRef {
5748+
ret bcx.build.Store(fill,
5749+
bcx.build.GEP(v,
5750+
vec(C_int(0),
5751+
C_int(abi.vec_elt_fill))));
5752+
}
5753+
5754+
fn vec_fill_adjusted(@block_ctxt bcx, ValueRef v,
5755+
ValueRef skipnull) -> ValueRef {
5756+
auto f = bcx.build.Load(bcx.build.GEP(v,
5757+
vec(C_int(0),
5758+
C_int(abi.vec_elt_fill))));
5759+
ret bcx.build.Select(skipnull, bcx.build.Sub(f, C_int(1)), f);
5760+
}
5761+
5762+
fn vec_p0(@block_ctxt bcx, ValueRef v) -> ValueRef {
5763+
auto p = bcx.build.GEP(v, vec(C_int(0),
5764+
C_int(abi.vec_elt_data)));
5765+
ret bcx.build.PointerCast(p, T_ptr(T_i8()));
5766+
}
5767+
5768+
5769+
fn vec_p1(@block_ctxt bcx, ValueRef v) -> ValueRef {
5770+
auto len = vec_fill(bcx, v);
5771+
ret bcx.build.GEP(vec_p0(bcx, v), vec(len));
5772+
}
5773+
5774+
fn vec_p1_adjusted(@block_ctxt bcx, ValueRef v,
5775+
ValueRef skipnull) -> ValueRef {
5776+
auto len = vec_fill_adjusted(bcx, v, skipnull);
5777+
ret bcx.build.GEP(vec_p0(bcx, v), vec(len));
5778+
}
5779+
56735780
fn trans_vec_append_glue(@crate_ctxt cx) {
56745781

56755782
auto llfn = cx.glues.vec_append_glue;
@@ -5700,45 +5807,6 @@ fn trans_vec_append_glue(@crate_ctxt cx) {
57005807
// First the dst vec needs to grow to accommodate the src vec.
57015808
// To do this we have to figure out how many bytes to add.
57025809

5703-
fn vec_fill(@block_ctxt bcx, ValueRef v) -> ValueRef {
5704-
ret bcx.build.Load(bcx.build.GEP(v, vec(C_int(0),
5705-
C_int(abi.vec_elt_fill))));
5706-
}
5707-
5708-
fn put_vec_fill(@block_ctxt bcx, ValueRef v, ValueRef fill) -> ValueRef {
5709-
ret bcx.build.Store(fill,
5710-
bcx.build.GEP(v,
5711-
vec(C_int(0),
5712-
C_int(abi.vec_elt_fill))));
5713-
}
5714-
5715-
fn vec_fill_adjusted(@block_ctxt bcx, ValueRef v,
5716-
ValueRef skipnull) -> ValueRef {
5717-
auto f = bcx.build.Load(bcx.build.GEP(v,
5718-
vec(C_int(0),
5719-
C_int(abi.vec_elt_fill))));
5720-
ret bcx.build.Select(skipnull, bcx.build.Sub(f, C_int(1)), f);
5721-
}
5722-
5723-
fn vec_p0(@block_ctxt bcx, ValueRef v) -> ValueRef {
5724-
auto p = bcx.build.GEP(v, vec(C_int(0),
5725-
C_int(abi.vec_elt_data)));
5726-
ret bcx.build.PointerCast(p, T_ptr(T_i8()));
5727-
}
5728-
5729-
5730-
fn vec_p1(@block_ctxt bcx, ValueRef v) -> ValueRef {
5731-
auto len = vec_fill(bcx, v);
5732-
ret bcx.build.GEP(vec_p0(bcx, v), vec(len));
5733-
}
5734-
5735-
fn vec_p1_adjusted(@block_ctxt bcx, ValueRef v,
5736-
ValueRef skipnull) -> ValueRef {
5737-
auto len = vec_fill_adjusted(bcx, v, skipnull);
5738-
ret bcx.build.GEP(vec_p0(bcx, v), vec(len));
5739-
}
5740-
5741-
57425810
auto llcopy_dst_ptr = bcx.build.Alloca(T_int());
57435811
auto llnew_vec_res =
57445812
trans_upcall(bcx, "upcall_vec_grow",
@@ -5780,16 +5848,17 @@ fn trans_vec_append_glue(@crate_ctxt cx) {
57805848
C_int(abi.tydesc_field_size))));
57815849

57825850
fn take_one(ValueRef elt_tydesc,
5783-
@block_ctxt cx, ValueRef v) -> result {
5784-
call_tydesc_glue_full(cx, v,
5851+
@block_ctxt cx,
5852+
ValueRef dst, ValueRef src) -> result {
5853+
call_tydesc_glue_full(cx, src,
57855854
elt_tydesc,
57865855
abi.tydesc_field_take_glue_off);
5787-
ret res(cx, v);
5856+
ret res(cx, src);
57885857
}
57895858

5790-
auto bcx = iter_sequence_raw(cx, src, src_lim,
5859+
auto bcx = iter_sequence_raw(cx, dst, src, src_lim,
57915860
elt_llsz, bind take_one(elt_tydesc,
5792-
_, _)).bcx;
5861+
_, _, _)).bcx;
57935862

57945863
ret call_memcpy(bcx, dst, src, n_bytes);
57955864
}

trunk/src/comp/middle/ty.rs

+8
Original file line numberDiff line numberDiff line change
@@ -373,6 +373,14 @@ fn get_element_type(@t ty, uint i) -> @t {
373373
fail;
374374
}
375375

376+
fn type_is_box(@t ty) -> bool {
377+
alt (ty.struct) {
378+
case (ty_box(_)) { ret true; }
379+
case (_) { ret false; }
380+
}
381+
fail;
382+
}
383+
376384
fn type_is_boxed(@t ty) -> bool {
377385
alt (ty.struct) {
378386
case (ty_str) { ret true; }
+5
Original file line numberDiff line numberDiff line change
@@ -0,0 +1,5 @@
1+
fn main() {
2+
check (@1 < @3);
3+
check (@@"hello " > @@"hello");
4+
check (@@@"hello" != @@@"there");
5+
}
+15
Original file line numberDiff line numberDiff line change
@@ -0,0 +1,15 @@
1+
fn main() {
2+
check ("hello" < "hellr");
3+
check ("hello " > "hello");
4+
check ("hello" != "there");
5+
6+
check (vec(1,2,3,4) > vec(1,2,3));
7+
check (vec(1,2,3) < vec(1,2,3,4));
8+
check (vec(1,2,4,4) > vec(1,2,3,4));
9+
check (vec(1,2,3,4) < vec(1,2,4,4));
10+
check (vec(1,2,3) <= vec(1,2,3));
11+
check (vec(1,2,3) <= vec(1,2,3,3));
12+
check (vec(1,2,3,4) > vec(1,2,3));
13+
check (vec(1,2,3) == vec(1,2,3));
14+
check (vec(1,2,3) != vec(1,1,3));
15+
}

0 commit comments

Comments
 (0)