@@ -890,6 +890,11 @@ fn umax(@block_ctxt cx, ValueRef a, ValueRef b) -> ValueRef {
890
890
ret cx. build . Select ( cond, b, a) ;
891
891
}
892
892
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
+
893
898
fn align_to ( @block_ctxt cx , ValueRef off, ValueRef align) -> ValueRef {
894
899
auto mask = cx. build . Sub ( align, C_int ( 1 ) ) ;
895
900
auto bumped = cx. build . Add ( off, mask) ;
@@ -1774,7 +1779,7 @@ fn mk_plain_tag(ast.def_id tid) -> @ty.t {
1774
1779
}
1775
1780
1776
1781
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;
1778
1783
1779
1784
type val_and_ty_fn = fn ( @block_ctxt cx, ValueRef v, @ty. t t) -> result;
1780
1785
@@ -1987,13 +1992,15 @@ fn iter_structural_ty_full(@block_ctxt cx,
1987
1992
1988
1993
// Iterates through a pointer range, until the src* hits the src_lim*.
1989
1994
fn iter_sequence_raw( @block_ctxt cx,
1995
+ ValueRef dst, // elt*
1990
1996
ValueRef src, // elt*
1991
1997
ValueRef src_lim, // elt*
1992
1998
ValueRef elt_sz,
1993
- val_fn f) -> result {
1999
+ val_pair_fn f) -> result {
1994
2000
1995
2001
auto bcx = cx;
1996
2002
2003
+ let ValueRef dst_int = vp2i( bcx, dst) ;
1997
2004
let ValueRef src_int = vp2i( bcx, src) ;
1998
2005
let ValueRef src_lim_int = vp2i( bcx, src_lim) ;
1999
2006
@@ -2003,6 +2010,8 @@ fn iter_sequence_raw(@block_ctxt cx,
2003
2010
2004
2011
bcx. build. Br ( cond_cx. llbb) ;
2005
2012
2013
+ let ValueRef dst_curr = cond_cx. build. Phi ( T_int( ) ,
2014
+ vec( dst_int) , vec( bcx. llbb) ) ;
2006
2015
let ValueRef src_curr = cond_cx. build. Phi ( T_int( ) ,
2007
2016
vec( src_int) , vec( bcx. llbb) ) ;
2008
2017
@@ -2011,14 +2020,18 @@ fn iter_sequence_raw(@block_ctxt cx,
2011
2020
2012
2021
cond_cx. build. CondBr ( end_test, body_cx. llbb, next_cx. llbb) ;
2013
2022
2023
+ auto dst_curr_ptr = vi2p( body_cx, dst_curr, T_ptr ( T_i8 ( ) ) ) ;
2014
2024
auto src_curr_ptr = vi2p( body_cx, src_curr, T_ptr ( T_i8 ( ) ) ) ;
2015
2025
2016
- auto body_res = f( body_cx, src_curr_ptr) ;
2026
+ auto body_res = f( body_cx, dst_curr_ptr , src_curr_ptr) ;
2017
2027
body_cx = body_res. bcx;
2018
2028
2029
+ auto dst_next = body_cx. build. Add ( dst_curr, elt_sz) ;
2019
2030
auto src_next = body_cx. build. Add ( src_curr, elt_sz) ;
2020
2031
body_cx. build. Br ( cond_cx. llbb) ;
2021
2032
2033
+ cond_cx. build. AddIncomingToPhi ( dst_curr, vec( dst_next) ,
2034
+ vec( body_cx. llbb) ) ;
2022
2035
cond_cx. build. AddIncomingToPhi ( src_curr, vec( src_next) ,
2023
2036
vec( body_cx. llbb) ) ;
2024
2037
@@ -2034,15 +2047,16 @@ fn iter_sequence_inner(@block_ctxt cx,
2034
2047
fn adaptor_fn( val_and_ty_fn f,
2035
2048
@ty. t elt_ty,
2036
2049
@block_ctxt cx,
2037
- ValueRef v) -> result {
2050
+ ValueRef dst,
2051
+ ValueRef src) -> result {
2038
2052
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) ) ;
2040
2054
ret f( cx, load_scalar_or_boxed( cx, p, elt_ty) , elt_ty) ;
2041
2055
}
2042
2056
2043
2057
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, _, _, _ ) ) ;
2046
2060
}
2047
2061
2048
2062
@@ -2378,13 +2392,27 @@ fn trans_unary(@block_ctxt cx, ast.unop op,
2378
2392
fail;
2379
2393
}
2380
2394
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) ;
2383
2409
2384
2410
if ( ty. type_is_scalar( t) ) {
2385
2411
ret res( cx, trans_scalar_compare( cx, op, t, lhs, rhs) ) ;
2386
2412
2387
- } else if ( ty. type_is_structural( t) ) {
2413
+ } else if ( ty. type_is_structural( t)
2414
+ || ty. type_is_sequence( t) ) {
2415
+
2388
2416
auto scx = new_sub_block_ctxt( cx, "structural compare start") ;
2389
2417
auto next = new_sub_block_ctxt( cx, "structural compare end") ;
2390
2418
cx. build. Br ( scx. llbb) ;
@@ -2415,28 +2443,52 @@ fn trans_compare(@block_ctxt cx, ast.binop op, @ty.t t,
2415
2443
2416
2444
auto flag = scx. build. Alloca ( T_i1 ( ) ) ;
2417
2445
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
+
2426
2470
}
2427
2471
}
2428
2472
2429
2473
fn inner( @block_ctxt last_cx,
2474
+ bool load_inner,
2430
2475
ValueRef flag,
2431
2476
ast. binop op,
2432
2477
@block_ctxt cx,
2433
- ValueRef av ,
2434
- ValueRef bv ,
2478
+ ValueRef av0 ,
2479
+ ValueRef bv0 ,
2435
2480
@ty. t t) -> result {
2436
2481
2437
2482
auto cnt_cx = new_sub_block_ctxt( cx, "continue comparison") ;
2438
2483
auto stop_cx = new_sub_block_ctxt( cx, "stop comparison") ;
2439
2484
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
+
2440
2492
// First 'eq' comparison: if so, continue to next elts.
2441
2493
auto eq_r = trans_compare( cx, ast. eq, t, av, bv) ;
2442
2494
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,
2448
2500
ret res( cnt_cx, C_nil ( ) ) ;
2449
2501
}
2450
2502
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
+ }
2454
2521
2455
2522
r. bcx. build. Br ( next. llbb) ;
2456
2523
auto v = next. build. Load ( flag) ;
2457
2524
ret res( next, v) ;
2458
2525
2526
+
2459
2527
} else {
2460
- // FIXME: compare vec, str, box ?
2528
+ // FIXME: compare obj, fn by pointer ?
2461
2529
cx. fcx. ccx. sess. unimpl( "type in trans_compare") ;
2462
2530
ret res( cx, C_bool ( false) ) ;
2463
2531
}
@@ -5670,6 +5738,45 @@ fn make_vec_append_glue(ModuleRef llmod, type_names tn) -> ValueRef {
5670
5738
ret llfn;
5671
5739
}
5672
5740
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
+
5673
5780
fn trans_vec_append_glue ( @crate_ctxt cx ) {
5674
5781
5675
5782
auto llfn = cx. glues . vec_append_glue ;
@@ -5700,45 +5807,6 @@ fn trans_vec_append_glue(@crate_ctxt cx) {
5700
5807
// First the dst vec needs to grow to accommodate the src vec.
5701
5808
// To do this we have to figure out how many bytes to add.
5702
5809
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
-
5742
5810
auto llcopy_dst_ptr = bcx. build . Alloca ( T_int ( ) ) ;
5743
5811
auto llnew_vec_res =
5744
5812
trans_upcall ( bcx, "upcall_vec_grow" ,
@@ -5780,16 +5848,17 @@ fn trans_vec_append_glue(@crate_ctxt cx) {
5780
5848
C_int ( abi. tydesc_field_size ) ) ) ) ;
5781
5849
5782
5850
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,
5785
5854
elt_tydesc,
5786
5855
abi. tydesc_field_take_glue_off ) ;
5787
- ret res( cx, v ) ;
5856
+ ret res( cx, src ) ;
5788
5857
}
5789
5858
5790
- auto bcx = iter_sequence_raw ( cx, src, src_lim,
5859
+ auto bcx = iter_sequence_raw ( cx, dst , src, src_lim,
5791
5860
elt_llsz, bind take_one ( elt_tydesc,
5792
- _, _) ) . bcx ;
5861
+ _, _, _ ) ) . bcx ;
5793
5862
5794
5863
ret call_memcpy ( bcx, dst, src, n_bytes) ;
5795
5864
}
0 commit comments