@@ -610,8 +610,8 @@ int ir_compute_live_ranges(ir_ctx *ctx)
610610 len = ir_bitset_len (ctx -> vregs_count + 1 );
611611 bb_live = ir_mem_malloc ((ctx -> cfg_blocks_count + 1 ) * len * sizeof (ir_bitset_base_t ));
612612
613- /* vregs + tmp + fixed + SRATCH + ALL */
614- ctx -> live_intervals = ir_mem_calloc (ctx -> vregs_count + 1 + IR_REG_NUM + 2 , sizeof (ir_live_interval * ));
613+ /* vregs + tmp + fixed + special */
614+ ctx -> live_intervals = ir_mem_calloc (ctx -> vregs_count + 1 + IR_REG_NUM + IR_REG_SPECIAL_NUM , sizeof (ir_live_interval * ));
615615
616616#ifdef IR_DEBUG
617617 visited = ir_bitset_malloc (ctx -> cfg_blocks_count + 1 );
@@ -1262,8 +1262,8 @@ int ir_compute_live_ranges(ir_ctx *ctx)
12621262 /* Compute Live Ranges */
12631263 ctx -> flags2 &= ~IR_LR_HAVE_DESSA_MOVES ;
12641264
1265- /* vregs + tmp + fixed + SRATCH + ALL */
1266- ctx -> live_intervals = ir_mem_calloc (ctx -> vregs_count + 1 + IR_REG_NUM + 2 , sizeof (ir_live_interval * ));
1265+ /* vregs + tmp + fixed + special */
1266+ ctx -> live_intervals = ir_mem_calloc (ctx -> vregs_count + 1 + IR_REG_NUM + IR_REG_SPECIAL_NUM , sizeof (ir_live_interval * ));
12671267
12681268 if (!ctx -> arena ) {
12691269 ctx -> arena = ir_arena_create (16 * 1024 );
@@ -2036,8 +2036,8 @@ int ir_coalesce(ir_ctx *ctx)
20362036 n -- ;
20372037 if (n != ctx -> vregs_count ) {
20382038 j = ctx -> vregs_count - n ;
2039- /* vregs + tmp + fixed + SRATCH + ALL */
2040- for (i = n + 1 ; i <= n + IR_REG_NUM + 2 ; i ++ ) {
2039+ /* vregs + tmp + fixed + special */
2040+ for (i = n + 1 ; i <= n + IR_REG_NUM + IR_REG_SPECIAL_NUM ; i ++ ) {
20412041 ctx -> live_intervals [i ] = ctx -> live_intervals [i + j ];
20422042 if (ctx -> live_intervals [i ]) {
20432043 ctx -> live_intervals [i ]-> vreg = i ;
@@ -2804,6 +2804,35 @@ static void ir_add_to_unhandled_spill(ir_live_interval **unhandled, ir_live_inte
28042804 }
28052805}
28062806
2807+ static ir_regset ir_special_reg_regset (ir_ctx * ctx , uint8_t reg )
2808+ {
2809+ IR_ASSERT (reg >= IR_REG_SCRATCH );
2810+
2811+ switch (reg ) {
2812+ case IR_REG_SCRATCH :
2813+ return IR_REGSET_SCRATCH ;
2814+ case IR_REG_PRESERVED :
2815+ return IR_REGSET_PRESERVED ;
2816+ case IR_REG_FIXED_SAVED :
2817+ IR_ASSERT (ctx -> fixed_stack_frame_size != -1 );
2818+ return (ir_regset )ctx -> fixed_save_regset ;
2819+ case IR_REG_ARGS :
2820+ return IR_REGSET_ARGS ;
2821+ #ifdef IR_HAVE_FASTCALL
2822+ case IR_REG_FCARGS :
2823+ return IR_REGSET_FCARGS ;
2824+ #endif
2825+ #ifdef IR_HAVE_PRESERVE_NONE
2826+ case IR_REG_PNARGS :
2827+ return IR_REGSET_PNARGS ;
2828+ #endif
2829+ case IR_REG_ALL :
2830+ return ~0 ;
2831+ default :
2832+ IR_ASSERT (0 );
2833+ }
2834+ }
2835+
28072836static ir_reg ir_try_allocate_free_reg (ir_ctx * ctx , ir_live_interval * ival , ir_live_interval * * active , ir_live_interval * inactive , ir_live_interval * * unhandled )
28082837{
28092838 ir_live_pos freeUntilPos [IR_REG_NUM ];
@@ -2846,12 +2875,7 @@ static ir_reg ir_try_allocate_free_reg(ir_ctx *ctx, ir_live_interval *ival, ir_l
28462875 reg = other -> reg ;
28472876 IR_ASSERT (reg >= 0 );
28482877 if (reg >= IR_REG_SCRATCH ) {
2849- if (reg == IR_REG_SCRATCH ) {
2850- available = IR_REGSET_DIFFERENCE (available , IR_REGSET_SCRATCH );
2851- } else {
2852- IR_ASSERT (reg == IR_REG_ALL );
2853- available = IR_REGSET_EMPTY ;
2854- }
2878+ available = IR_REGSET_DIFFERENCE (available , ir_special_reg_regset (ctx , reg ));
28552879 } else {
28562880 IR_REGSET_EXCL (available , reg );
28572881 }
@@ -2874,14 +2898,8 @@ static ir_reg ir_try_allocate_free_reg(ir_ctx *ctx, ir_live_interval *ival, ir_l
28742898 reg = other -> reg ;
28752899 IR_ASSERT (reg >= 0 );
28762900 if (reg >= IR_REG_SCRATCH ) {
2877- ir_regset regset ;
2901+ ir_regset regset = IR_REGSET_INTERSECTION ( available , ir_special_reg_regset ( ctx , reg )) ;
28782902
2879- if (reg == IR_REG_SCRATCH ) {
2880- regset = IR_REGSET_INTERSECTION (available , IR_REGSET_SCRATCH );
2881- } else {
2882- IR_ASSERT (reg == IR_REG_ALL );
2883- regset = available ;
2884- }
28852903 overlapped = IR_REGSET_UNION (overlapped , regset );
28862904 IR_REGSET_FOREACH (regset , reg ) {
28872905 if (next < freeUntilPos [reg ]) {
@@ -3087,14 +3105,8 @@ static ir_reg ir_allocate_blocked_reg(ir_ctx *ctx, ir_live_interval *ival, ir_li
30873105 reg = other -> reg ;
30883106 IR_ASSERT (reg >= 0 );
30893107 if (reg >= IR_REG_SCRATCH ) {
3090- ir_regset regset ;
3108+ ir_regset regset = IR_REGSET_INTERSECTION ( available , ir_special_reg_regset ( ctx , reg )) ;
30913109
3092- if (reg == IR_REG_SCRATCH ) {
3093- regset = IR_REGSET_INTERSECTION (available , IR_REGSET_SCRATCH );
3094- } else {
3095- IR_ASSERT (reg == IR_REG_ALL );
3096- regset = available ;
3097- }
30983110 IR_REGSET_FOREACH (regset , reg ) {
30993111 blockPos [reg ] = nextUsePos [reg ] = 0 ;
31003112 } IR_REGSET_FOREACH_END ();
@@ -3122,14 +3134,8 @@ static ir_reg ir_allocate_blocked_reg(ir_ctx *ctx, ir_live_interval *ival, ir_li
31223134 ir_live_pos overlap = ir_ivals_overlap (& ival -> range , other -> current_range );
31233135
31243136 if (overlap ) {
3125- ir_regset regset ;
3137+ ir_regset regset = IR_REGSET_INTERSECTION ( available , ir_special_reg_regset ( ctx , reg )) ;
31263138
3127- if (reg == IR_REG_SCRATCH ) {
3128- regset = IR_REGSET_INTERSECTION (available , IR_REGSET_SCRATCH );
3129- } else {
3130- IR_ASSERT (reg == IR_REG_ALL );
3131- regset = available ;
3132- }
31333139 IR_REGSET_FOREACH (regset , reg ) {
31343140 if (overlap < nextUsePos [reg ]) {
31353141 nextUsePos [reg ] = overlap ;
@@ -3562,8 +3568,8 @@ static int ir_linear_scan(ir_ctx *ctx)
35623568 ir_merge_to_unhandled (& unhandled , ival );
35633569 }
35643570
3565- /* vregs + tmp + fixed + SRATCH + ALL */
3566- for (j = ctx -> vregs_count + 1 ; j <= ctx -> vregs_count + IR_REG_NUM + 2 ; j ++ ) {
3571+ /* vregs + tmp + fixed + special */
3572+ for (j = ctx -> vregs_count + 1 ; j <= ctx -> vregs_count + IR_REG_NUM + IR_REG_SPECIAL_NUM ; j ++ ) {
35673573 ival = ctx -> live_intervals [j ];
35683574 if (ival ) {
35693575 ival -> current_range = & ival -> range ;
0 commit comments