@@ -1293,6 +1293,20 @@ fn simplify_type(&@crate_ctxt ccx, &ty::t typ) -> ty::t {
1293
1293
case ( ty:: ty_vec ( _) ) {
1294
1294
ret ty:: mk_imm_vec ( ccx. tcx , ty:: mk_nil ( ccx. tcx ) ) ;
1295
1295
}
1296
+ case ( ty:: ty_fn ( _, _, _, _) ) {
1297
+ ret ty:: mk_imm_tup ( ccx. tcx ,
1298
+ [ ty:: mk_imm_box ( ccx. tcx ,
1299
+ ty:: mk_nil ( ccx. tcx ) ) ,
1300
+ ty:: mk_imm_box ( ccx. tcx ,
1301
+ ty:: mk_nil ( ccx. tcx ) ) ] ) ;
1302
+ }
1303
+ case ( ty:: ty_obj ( _) ) {
1304
+ ret ty:: mk_imm_tup ( ccx. tcx ,
1305
+ [ ty:: mk_imm_box ( ccx. tcx ,
1306
+ ty:: mk_nil ( ccx. tcx ) ) ,
1307
+ ty:: mk_imm_box ( ccx. tcx ,
1308
+ ty:: mk_nil ( ccx. tcx ) ) ] ) ;
1309
+ }
1296
1310
case ( _) { ret typ; }
1297
1311
}
1298
1312
}
@@ -2396,11 +2410,11 @@ fn make_cmp_glue(&@block_ctxt cx,
2396
2410
2397
2411
// If we hit == all the way through the minimum-shared-length
2398
2412
// section, default to judging the relative sequence lengths.
2399
- r = compare_numerical_values ( scx,
2400
- vec_fill ( scx, lhs) ,
2401
- vec_fill ( scx, rhs) ,
2402
- unsigned_int ,
2403
- llop) ;
2413
+ r = compare_integral_values ( scx,
2414
+ vec_fill ( scx, lhs) ,
2415
+ vec_fill ( scx, rhs) ,
2416
+ false ,
2417
+ llop) ;
2404
2418
r. bcx . build . Store ( r. val , flag) ;
2405
2419
2406
2420
} else {
@@ -2486,111 +2500,88 @@ fn make_cmp_glue(&@block_ctxt cx,
2486
2500
}
2487
2501
}
2488
2502
2489
- // Used only for creating scalar comparsion glue.
2490
- tag numerical_type {
2491
- signed_int;
2492
- unsigned_int;
2493
- floating_point;
2494
- }
2495
-
2496
2503
// A helper function to create scalar comparison glue.
2497
2504
fn make_scalar_cmp_glue ( & @block_ctxt cx , ValueRef lhs, ValueRef rhs,
2498
2505
& ty:: t t, ValueRef llop) {
2499
- // assert ty::type_is_scalar(cx.fcx.lcx.ccx.tcx, t);
2506
+ if ( ty:: type_is_fp ( cx. fcx . lcx . ccx . tcx , t) ) {
2507
+ make_fp_cmp_glue ( cx, lhs, rhs, t, llop) ;
2508
+ ret;
2509
+ }
2500
2510
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) ;
2511
+ if ( ty:: type_is_integral ( cx. fcx . lcx . ccx . tcx , t) ||
2512
+ ty:: type_is_bool ( cx. fcx . lcx . ccx . tcx , t) ) {
2513
+ make_integral_cmp_glue ( cx, lhs, rhs, t, llop) ;
2514
+ ret;
2515
+ }
2504
2516
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
- }
2517
+ if ( ty:: type_is_nil ( cx. fcx . lcx . ccx . tcx , t) ) {
2518
+ cx. build . Store ( C_bool ( true ) , cx. fcx . llretptr ) ;
2519
+ cx. build . RetVoid ( ) ;
2520
+ ret;
2541
2521
}
2522
+
2523
+ trans_fail ( cx, none[ common:: span] ,
2524
+ "attempt to compare values of type " +
2525
+ ty:: ty_to_str ( cx. fcx . lcx . ccx . tcx , t) ) ;
2542
2526
}
2543
2527
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;
2528
+ // A helper function to create floating point comparison glue.
2529
+ fn make_fp_cmp_glue ( & @block_ctxt cx , ValueRef lhs, ValueRef rhs,
2530
+ & ty:: t fptype , ValueRef llop) {
2531
+ auto last_cx = new_sub_block_ctxt ( cx, "last" ) ;
2532
+
2533
+ auto eq_cx = new_sub_block_ctxt ( cx, "eq" ) ;
2534
+ auto eq_result = eq_cx. build . FCmp ( lib:: llvm:: LLVMRealUEQ , lhs, rhs) ;
2535
+ eq_cx. build . Br ( last_cx. llbb ) ;
2536
+
2537
+ auto lt_cx = new_sub_block_ctxt ( cx, "lt" ) ;
2538
+ auto lt_result = lt_cx. build . FCmp ( lib:: llvm:: LLVMRealULT , lhs, rhs) ;
2539
+ lt_cx. build . Br ( last_cx. llbb ) ;
2540
+
2541
+ auto le_cx = new_sub_block_ctxt ( cx, "le" ) ;
2542
+ auto le_result = le_cx. build . FCmp ( lib:: llvm:: LLVMRealULE , lhs, rhs) ;
2543
+ le_cx. build . Br ( last_cx. llbb ) ;
2544
+
2545
+ auto unreach_cx = new_sub_block_ctxt ( cx, "unreach" ) ;
2546
+ unreach_cx. build . Unreachable ( ) ;
2547
+
2548
+ auto llswitch = cx. build . Switch ( llop, unreach_cx. llbb , 3 u) ;
2549
+ llvm:: LLVMAddCase ( llswitch, C_u8 ( abi:: cmp_glue_op_eq) , eq_cx. llbb ) ;
2550
+ llvm:: LLVMAddCase ( llswitch, C_u8 ( abi:: cmp_glue_op_lt) , lt_cx. llbb ) ;
2551
+ llvm:: LLVMAddCase ( llswitch, C_u8 ( abi:: cmp_glue_op_le) , le_cx. llbb ) ;
2552
+
2553
+ auto last_result =
2554
+ last_cx. build . Phi ( T_i1 ( ) , [ eq_result, lt_result, le_result] ,
2555
+ [ eq_cx. llbb , lt_cx. llbb , le_cx. llbb ] ) ;
2556
+ last_cx. build . Store ( last_result, cx. fcx . llretptr ) ;
2557
+ last_cx. build . RetVoid ( ) ;
2558
+ }
2559
+
2560
+ // A helper function to compare integral values. This is used by both
2561
+ // `make_integral_cmp_glue` and `make_cmp_glue`.
2562
+ fn compare_integral_values ( & @block_ctxt cx , ValueRef lhs, ValueRef rhs,
2563
+ bool signed , ValueRef llop) -> result {
2564
+ auto lt_cmp; auto le_cmp;
2565
+ if ( signed) {
2566
+ lt_cmp = lib:: llvm:: LLVMIntSLT ;
2567
+ le_cmp = lib:: llvm:: LLVMIntSLE ;
2568
+ } else {
2569
+ lt_cmp = lib:: llvm:: LLVMIntULT ;
2570
+ le_cmp = lib:: llvm:: LLVMIntULE ;
2580
2571
}
2581
2572
2582
2573
auto last_cx = new_sub_block_ctxt ( cx, "last" ) ;
2583
2574
2584
2575
auto eq_cx = new_sub_block_ctxt ( cx, "eq" ) ;
2585
- auto eq_result = generic_cmp ( eq_cx, nt , eq_cmp , lhs, rhs) ;
2576
+ auto eq_result = eq_cx. build . ICmp ( lib :: llvm :: LLVMIntEQ , lhs, rhs) ;
2586
2577
eq_cx. build . Br ( last_cx. llbb ) ;
2587
2578
2588
2579
auto lt_cx = new_sub_block_ctxt ( cx, "lt" ) ;
2589
- auto lt_result = generic_cmp ( lt_cx, nt , lt_cmp, lhs, rhs) ;
2580
+ auto lt_result = lt_cx. build . ICmp ( lt_cmp, lhs, rhs) ;
2590
2581
lt_cx. build . Br ( last_cx. llbb ) ;
2591
2582
2592
2583
auto le_cx = new_sub_block_ctxt ( cx, "le" ) ;
2593
- auto le_result = generic_cmp ( le_cx, nt , le_cmp, lhs, rhs) ;
2584
+ auto le_result = le_cx. build . ICmp ( le_cmp, lhs, rhs) ;
2594
2585
le_cx. build . Br ( last_cx. llbb ) ;
2595
2586
2596
2587
auto unreach_cx = new_sub_block_ctxt ( cx, "unreach" ) ;
@@ -2607,10 +2598,11 @@ fn compare_numerical_values(&@block_ctxt cx, ValueRef lhs, ValueRef rhs,
2607
2598
ret res( last_cx, last_result) ;
2608
2599
}
2609
2600
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) ;
2601
+ // A helper function to create integral comparison glue.
2602
+ fn make_integral_cmp_glue ( & @block_ctxt cx , ValueRef lhs, ValueRef rhs,
2603
+ & ty:: t intype , ValueRef llop) {
2604
+ auto r = compare_integral_values ( cx, lhs, rhs,
2605
+ ty:: type_is_signed ( cx. fcx . lcx . ccx . tcx , intype) , llop) ;
2614
2606
r. bcx . build . Store ( r. val , r. bcx . fcx . llretptr ) ;
2615
2607
r. bcx . build . RetVoid ( ) ;
2616
2608
}
0 commit comments