Skip to content

Commit d455d78

Browse files
committed
---
yaml --- r: 2912 b: refs/heads/master c: 3a6b557 h: refs/heads/master v: v3
1 parent ac61320 commit d455d78

File tree

2 files changed

+96
-74
lines changed

2 files changed

+96
-74
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: 12f86e6f2f5e7a5fc4ea61f3c63c790be100688f
2+
refs/heads/master: 3a6b5576acbcd0ee2ae3e28847d0b41e2b82ed32

trunk/src/comp/middle/trans.rs

Lines changed: 95 additions & 73 deletions
Original file line numberDiff line numberDiff line change
@@ -2396,11 +2396,11 @@ fn make_cmp_glue(&@block_ctxt cx,
23962396

23972397
// If we hit == all the way through the minimum-shared-length
23982398
// section, default to judging the relative sequence lengths.
2399-
r = compare_integral_values(scx,
2400-
vec_fill(scx, lhs),
2401-
vec_fill(scx, rhs),
2402-
false,
2403-
llop);
2399+
r = compare_numerical_values(scx,
2400+
vec_fill(scx, lhs),
2401+
vec_fill(scx, rhs),
2402+
unsigned_int,
2403+
llop);
24042404
r.bcx.build.Store(r.val, flag);
24052405

24062406
} else {
@@ -2486,88 +2486,111 @@ fn make_cmp_glue(&@block_ctxt cx,
24862486
}
24872487
}
24882488

2489+
// Used only for creating scalar comparsion glue.
2490+
tag numerical_type {
2491+
signed_int;
2492+
unsigned_int;
2493+
floating_point;
2494+
}
2495+
24892496
// A helper function to create scalar comparison glue.
24902497
fn make_scalar_cmp_glue(&@block_ctxt cx, ValueRef lhs, ValueRef rhs,
24912498
&ty::t t, ValueRef llop) {
2492-
if (ty::type_is_fp(cx.fcx.lcx.ccx.tcx, t)) {
2493-
make_fp_cmp_glue(cx, lhs, rhs, t, llop);
2494-
ret;
2495-
}
2499+
// assert ty::type_is_scalar(cx.fcx.lcx.ccx.tcx, t);
24962500

2497-
if (ty::type_is_integral(cx.fcx.lcx.ccx.tcx, t) ||
2498-
ty::type_is_bool(cx.fcx.lcx.ccx.tcx, t)) {
2499-
make_integral_cmp_glue(cx, lhs, rhs, t, llop);
2500-
ret;
2501-
}
2501+
// In most cases, we need to know whether to do signed, unsigned, or float
2502+
// comparison.
2503+
auto f = bind make_numerical_cmp_glue(cx, lhs, rhs, _, llop);
25022504

2503-
if (ty::type_is_nil(cx.fcx.lcx.ccx.tcx, t)) {
2504-
cx.build.Store(C_bool(true), cx.fcx.llretptr);
2505-
cx.build.RetVoid();
2506-
ret;
2505+
// FIXME: this could be a lot shorter if we could combine multiple cases
2506+
// of alt expressions (issue #449).
2507+
alt (ty::struct(cx.fcx.lcx.ccx.tcx, t)) {
2508+
case (ty::ty_nil) {
2509+
cx.build.Store(C_bool(true), cx.fcx.llretptr);
2510+
cx.build.RetVoid();
2511+
}
2512+
case (ty::ty_bool) { f(unsigned_int); }
2513+
case (ty::ty_int) { f(signed_int); }
2514+
case (ty::ty_float) { f(floating_point); }
2515+
case (ty::ty_uint) { f(unsigned_int); }
2516+
case (ty::ty_machine(_)) {
2517+
// Floating point machine types
2518+
if (ty::type_is_fp(cx.fcx.lcx.ccx.tcx, t)) {
2519+
f(floating_point);
2520+
}
2521+
// Signed, integral machine types
2522+
else if (ty::type_is_signed(cx.fcx.lcx.ccx.tcx, t)) {
2523+
f(signed_int);
2524+
}
2525+
// Unsigned, integral machine types
2526+
else { f(unsigned_int); }
2527+
}
2528+
case (ty::ty_char) { f(unsigned_int); }
2529+
case (ty::ty_type) {
2530+
trans_fail(cx, none[common::span],
2531+
"attempt to compare values of type type");
2532+
}
2533+
case (ty::ty_native) {
2534+
trans_fail(cx, none[common::span],
2535+
"attempt to compare values of type native");
2536+
}
2537+
case (_) {
2538+
// Should never get here, because t is scalar.
2539+
fail;
2540+
}
25072541
}
2508-
2509-
trans_fail(cx, none[common::span],
2510-
"attempt to compare values of type " +
2511-
ty::ty_to_str(cx.fcx.lcx.ccx.tcx, t));
25122542
}
25132543

2514-
// A helper function to create floating point comparison glue.
2515-
fn make_fp_cmp_glue(&@block_ctxt cx, ValueRef lhs, ValueRef rhs,
2516-
&ty::t fptype, ValueRef llop) {
2517-
auto last_cx = new_sub_block_ctxt(cx, "last");
2518-
2519-
auto eq_cx = new_sub_block_ctxt(cx, "eq");
2520-
auto eq_result = eq_cx.build.FCmp(lib::llvm::LLVMRealUEQ, lhs, rhs);
2521-
eq_cx.build.Br(last_cx.llbb);
2522-
2523-
auto lt_cx = new_sub_block_ctxt(cx, "lt");
2524-
auto lt_result = lt_cx.build.FCmp(lib::llvm::LLVMRealULT, lhs, rhs);
2525-
lt_cx.build.Br(last_cx.llbb);
2526-
2527-
auto le_cx = new_sub_block_ctxt(cx, "le");
2528-
auto le_result = le_cx.build.FCmp(lib::llvm::LLVMRealULE, lhs, rhs);
2529-
le_cx.build.Br(last_cx.llbb);
2530-
2531-
auto unreach_cx = new_sub_block_ctxt(cx, "unreach");
2532-
unreach_cx.build.Unreachable();
2533-
2534-
auto llswitch = cx.build.Switch(llop, unreach_cx.llbb, 3u);
2535-
llvm::LLVMAddCase(llswitch, C_u8(abi::cmp_glue_op_eq), eq_cx.llbb);
2536-
llvm::LLVMAddCase(llswitch, C_u8(abi::cmp_glue_op_lt), lt_cx.llbb);
2537-
llvm::LLVMAddCase(llswitch, C_u8(abi::cmp_glue_op_le), le_cx.llbb);
2538-
2539-
auto last_result =
2540-
last_cx.build.Phi(T_i1(), [eq_result, lt_result, le_result],
2541-
[eq_cx.llbb, lt_cx.llbb, le_cx.llbb]);
2542-
last_cx.build.Store(last_result, cx.fcx.llretptr);
2543-
last_cx.build.RetVoid();
2544-
}
2545-
2546-
// A helper function to compare integral values. This is used by both
2547-
// `make_integral_cmp_glue` and `make_cmp_glue`.
2548-
fn compare_integral_values(&@block_ctxt cx, ValueRef lhs, ValueRef rhs,
2549-
bool signed, ValueRef llop) -> result {
2550-
auto lt_cmp; auto le_cmp;
2551-
if (signed) {
2552-
lt_cmp = lib::llvm::LLVMIntSLT;
2553-
le_cmp = lib::llvm::LLVMIntSLE;
2554-
} else {
2555-
lt_cmp = lib::llvm::LLVMIntULT;
2556-
le_cmp = lib::llvm::LLVMIntULE;
2544+
// A helper function to compare numerical values.
2545+
fn compare_numerical_values(&@block_ctxt cx, ValueRef lhs, ValueRef rhs,
2546+
numerical_type nt, ValueRef llop) -> result {
2547+
auto eq_cmp; auto lt_cmp; auto le_cmp;
2548+
alt (nt) {
2549+
case (floating_point) {
2550+
eq_cmp = lib::llvm::LLVMRealUEQ;
2551+
lt_cmp = lib::llvm::LLVMRealULT;
2552+
le_cmp = lib::llvm::LLVMRealULE;
2553+
}
2554+
case (signed_int) {
2555+
eq_cmp = lib::llvm::LLVMIntEQ;
2556+
lt_cmp = lib::llvm::LLVMIntSLT;
2557+
le_cmp = lib::llvm::LLVMIntSLE;
2558+
}
2559+
case (unsigned_int) {
2560+
eq_cmp = lib::llvm::LLVMIntEQ;
2561+
lt_cmp = lib::llvm::LLVMIntULT;
2562+
le_cmp = lib::llvm::LLVMIntULE;
2563+
}
2564+
}
2565+
2566+
// FIXME: This wouldn't be necessary if we could bind methods off of
2567+
// objects and therefore abstract over FCmp and ICmp (issue #435). Then
2568+
// we could just write, e.g., "cmp_fn = bind cx.build.FCmp(_, _, _);" in
2569+
// the above, and "auto eq_result = cmp_fn(eq_cmp, lhs, rhs);" in the
2570+
// below.
2571+
fn generic_cmp(&@block_ctxt cx, numerical_type nt,
2572+
uint op, ValueRef lhs, ValueRef rhs) -> ValueRef {
2573+
let ValueRef r;
2574+
if (nt == floating_point) {
2575+
r = cx.build.FCmp(op, lhs, rhs);
2576+
} else {
2577+
r = cx.build.ICmp(op, lhs, rhs);
2578+
}
2579+
ret r;
25572580
}
25582581

25592582
auto last_cx = new_sub_block_ctxt(cx, "last");
25602583

25612584
auto eq_cx = new_sub_block_ctxt(cx, "eq");
2562-
auto eq_result = eq_cx.build.ICmp(lib::llvm::LLVMIntEQ, lhs, rhs);
2585+
auto eq_result = generic_cmp(eq_cx, nt, eq_cmp, lhs, rhs);
25632586
eq_cx.build.Br(last_cx.llbb);
25642587

25652588
auto lt_cx = new_sub_block_ctxt(cx, "lt");
2566-
auto lt_result = lt_cx.build.ICmp(lt_cmp, lhs, rhs);
2589+
auto lt_result = generic_cmp(lt_cx, nt, lt_cmp, lhs, rhs);
25672590
lt_cx.build.Br(last_cx.llbb);
25682591

25692592
auto le_cx = new_sub_block_ctxt(cx, "le");
2570-
auto le_result = le_cx.build.ICmp(le_cmp, lhs, rhs);
2593+
auto le_result = generic_cmp(le_cx, nt, le_cmp, lhs, rhs);
25712594
le_cx.build.Br(last_cx.llbb);
25722595

25732596
auto unreach_cx = new_sub_block_ctxt(cx, "unreach");
@@ -2584,11 +2607,10 @@ fn compare_integral_values(&@block_ctxt cx, ValueRef lhs, ValueRef rhs,
25842607
ret res(last_cx, last_result);
25852608
}
25862609

2587-
// A helper function to create integral comparison glue.
2588-
fn make_integral_cmp_glue(&@block_ctxt cx, ValueRef lhs, ValueRef rhs,
2589-
&ty::t intype, ValueRef llop) {
2590-
auto r = compare_integral_values(cx, lhs, rhs,
2591-
ty::type_is_signed(cx.fcx.lcx.ccx.tcx, intype), llop);
2610+
// A helper function to create numerical comparison glue.
2611+
fn make_numerical_cmp_glue(&@block_ctxt cx, ValueRef lhs, ValueRef rhs,
2612+
numerical_type nt, ValueRef llop) {
2613+
auto r = compare_numerical_values(cx, lhs, rhs, nt, llop);
25922614
r.bcx.build.Store(r.val, r.bcx.fcx.llretptr);
25932615
r.bcx.build.RetVoid();
25942616
}

0 commit comments

Comments
 (0)