Skip to content

Commit 5f5b7e3

Browse files
committed
rustc: Don't call cmp glue if the type is a simple scalar
1 parent 0dc2aa3 commit 5f5b7e3

File tree

1 file changed

+60
-39
lines changed

1 file changed

+60
-39
lines changed

src/comp/middle/trans.rs

Lines changed: 60 additions & 39 deletions
Original file line numberDiff line numberDiff line change
@@ -2199,7 +2199,7 @@ fn make_cmp_glue(&@block_ctxt cx, ValueRef lhs0, ValueRef rhs0, &ty::t t,
21992199
alt (ty::struct(cx.fcx.lcx.ccx.tcx, t)) {
22002200
case (ty::ty_box(?ti)) { ti.ty }
22012201
};
2202-
auto rslt = call_cmp_glue(cx, lhs, rhs, t_inner, llop);
2202+
auto rslt = compare(cx, lhs, rhs, t_inner, llop);
22032203
rslt.bcx.build.Store(rslt.val, cx.fcx.llretptr);
22042204
rslt.bcx.build.RetVoid();
22052205
} else if (ty::type_is_structural(cx.fcx.lcx.ccx.tcx, t) ||
@@ -2291,14 +2291,13 @@ fn make_cmp_glue(&@block_ctxt cx, ValueRef lhs0, ValueRef rhs0, &ty::t t,
22912291
av = load_if_immediate(cx, av, t);
22922292
bv = load_if_immediate(cx, bv, t);
22932293
}
2294-
// First 'eq' comparison: if so, continue to next elts.
22952294

2296-
auto eq_r =
2297-
call_cmp_glue(cx, av, bv, t, C_u8(abi::cmp_glue_op_eq));
2295+
// First 'eq' comparison: if so, continue to next elts.
2296+
auto eq_r = compare(cx, av, bv, t, C_u8(abi::cmp_glue_op_eq));
22982297
eq_r.bcx.build.CondBr(eq_r.val, cnt_cx.llbb, stop_cx.llbb);
2299-
// Second 'op' comparison: find out how this elt-pair decides.
23002298

2301-
auto stop_r = call_cmp_glue(stop_cx, av, bv, t, llop);
2299+
// Second 'op' comparison: find out how this elt-pair decides.
2300+
auto stop_r = compare(stop_cx, av, bv, t, llop);
23022301
stop_r.bcx.build.Store(stop_r.val, flag);
23032302
stop_r.bcx.build.Br(last_cx.llbb);
23042303
ret rslt(cnt_cx, C_nil());
@@ -2339,63 +2338,75 @@ fn make_cmp_glue(&@block_ctxt cx, ValueRef lhs0, ValueRef rhs0, &ty::t t,
23392338
tag numerical_type { signed_int; unsigned_int; floating_point; }
23402339

23412340

2342-
// A helper function to create scalar comparison glue.
2343-
fn make_scalar_cmp_glue(&@block_ctxt cx, ValueRef lhs, ValueRef rhs, &ty::t t,
2344-
ValueRef llop) {
2345-
// assert ty::type_is_scalar(cx.fcx.lcx.ccx.tcx, t);
2346-
2347-
// In most cases, we need to know whether to do signed, unsigned, or float
2348-
// comparison.
2349-
2350-
auto f = bind make_numerical_cmp_glue(cx, lhs, rhs, _, llop);
2351-
2341+
fn compare_scalar_types(@block_ctxt cx, ValueRef lhs, ValueRef rhs, &ty::t t,
2342+
ValueRef llop) -> result {
23522343
// FIXME: this could be a lot shorter if we could combine multiple cases
23532344
// of alt expressions (issue #449).
2345+
2346+
auto f = bind compare_numerical_values(cx, lhs, rhs, _, llop);
2347+
23542348
alt (ty::struct(cx.fcx.lcx.ccx.tcx, t)) {
2355-
case (ty::ty_nil) {
2356-
cx.build.Store(C_bool(true), cx.fcx.llretptr);
2357-
cx.build.RetVoid();
2358-
}
2359-
case (ty::ty_bool) { f(unsigned_int); }
2360-
case (ty::ty_int) { f(signed_int); }
2361-
case (ty::ty_float) { f(floating_point); }
2362-
case (ty::ty_uint) { f(unsigned_int); }
2349+
case (ty::ty_nil) { ret rslt(cx, C_bool(true)); }
2350+
case (ty::ty_bool) { ret f(unsigned_int); }
2351+
case (ty::ty_int) { ret f(signed_int); }
2352+
case (ty::ty_float) { ret f(floating_point); }
2353+
case (ty::ty_uint) { ret f(unsigned_int); }
23632354
case (ty::ty_machine(_)) {
23642355

2365-
// Floating point machine types
23662356
if (ty::type_is_fp(cx.fcx.lcx.ccx.tcx, t)) {
2367-
f(floating_point);
2368-
} else if (
2369-
// Signed, integral machine types
2370-
ty::type_is_signed(cx.fcx.lcx.ccx.tcx, t)) {
2371-
f(signed_int);
2372-
} else
2373-
// Unsigned, integral machine types
2374-
{
2375-
f(unsigned_int);
2357+
// Floating point machine types
2358+
ret f(floating_point);
2359+
} else if (ty::type_is_signed(cx.fcx.lcx.ccx.tcx, t)) {
2360+
// Signed, integral machine types
2361+
ret f(signed_int);
2362+
} else {
2363+
// Unsigned, integral machine types
2364+
ret f(unsigned_int);
23762365
}
23772366
}
2378-
case (ty::ty_char) { f(unsigned_int); }
2367+
case (ty::ty_char) { ret f(unsigned_int); }
23792368
case (ty::ty_type) {
23802369
trans_fail(cx, none[common::span],
23812370
"attempt to compare values of type type");
2371+
2372+
// This is a bit lame, because we return a dummy block to the
2373+
// caller that's actually unreachable, but I don't think it
2374+
// matters.
2375+
ret rslt(new_sub_block_ctxt(cx, "after_fail_dummy"),
2376+
C_bool(false));
23822377
}
23832378
case (ty::ty_native) {
23842379
trans_fail(cx, none[common::span],
23852380
"attempt to compare values of type native");
2381+
ret rslt(new_sub_block_ctxt(cx, "after_fail_dummy"),
2382+
C_bool(false));
23862383
}
23872384
case (ty::ty_ptr(_)) {
2388-
f(unsigned_int);
2385+
ret f(unsigned_int);
23892386
}
23902387
case (_) {
23912388
// Should never get here, because t is scalar.
2392-
23932389
cx.fcx.lcx.ccx.sess.bug("non-scalar type passed to " +
2394-
"make_scalar_cmp_glue");
2390+
"compare_scalar_types");
23952391
}
23962392
}
23972393
}
23982394

2395+
// A helper function to create scalar comparison glue.
2396+
fn make_scalar_cmp_glue(&@block_ctxt cx, ValueRef lhs, ValueRef rhs, &ty::t t,
2397+
ValueRef llop) {
2398+
assert ty::type_is_scalar(cx.fcx.lcx.ccx.tcx, t);
2399+
2400+
// In most cases, we need to know whether to do signed, unsigned, or float
2401+
// comparison.
2402+
2403+
auto rslt = compare_scalar_types(cx, lhs, rhs, t, llop);
2404+
auto bcx = rslt.bcx;
2405+
auto compare_result = rslt.val;
2406+
bcx.build.Store(compare_result, cx.fcx.llretptr);
2407+
bcx.build.RetVoid();
2408+
}
2409+
23992410

24002411
// A helper function to compare numerical values.
24012412
fn compare_numerical_values(&@block_ctxt cx, ValueRef lhs, ValueRef rhs,
@@ -3032,6 +3043,16 @@ fn call_cmp_glue(&@block_ctxt cx, ValueRef lhs, ValueRef rhs, &ty::t t,
30323043
ret rslt(r.bcx, r.bcx.build.Load(llcmpresultptr));
30333044
}
30343045

3046+
// Compares two values. Performs the simple scalar comparison if the types are
3047+
// scalar and calls to comparison glue otherwise.
3048+
fn compare(&@block_ctxt cx, ValueRef lhs, ValueRef rhs, &ty::t t,
3049+
ValueRef llop) -> result {
3050+
if (ty::type_is_scalar(cx.fcx.lcx.ccx.tcx, t)) {
3051+
ret compare_scalar_types(cx, lhs, rhs, t, llop);
3052+
}
3053+
ret call_cmp_glue(cx, lhs, rhs, t, llop);
3054+
}
3055+
30353056
fn take_ty(&@block_ctxt cx, ValueRef v, ty::t t) -> result {
30363057
if (ty::type_has_pointers(cx.fcx.lcx.ccx.tcx, t)) {
30373058
ret call_tydesc_glue(cx, v, t, abi::tydesc_field_take_glue);
@@ -3327,7 +3348,7 @@ fn trans_compare(&@block_ctxt cx0, ast::binop op, &ty::t t0, ValueRef lhs0,
33273348
case (ast::ge) { llop = C_u8(abi::cmp_glue_op_lt); }
33283349
case (ast::gt) { llop = C_u8(abi::cmp_glue_op_le); }
33293350
}
3330-
auto rs = call_cmp_glue(cx, lhs, rhs, t, llop);
3351+
auto rs = compare(cx, lhs, rhs, t, llop);
33313352

33323353
// Invert the result if necessary.
33333354
// FIXME: Use or-patterns when we have them.

0 commit comments

Comments
 (0)