@@ -233,6 +233,34 @@ get_reg_class (int regno)
233
233
return NO_REGS;
234
234
}
235
235
236
+ /* Return true if REG_CLASS has enough allocatable hard regs to keep value of
237
+ REG_MODE. */
238
+ static bool
239
+ enough_allocatable_hard_regs_p (enum reg_class reg_class,
240
+ enum machine_mode reg_mode)
241
+ {
242
+ int i, j, hard_regno, class_size, nregs;
243
+
244
+ if (hard_reg_set_subset_p (reg_class_contents[reg_class], lra_no_alloc_regs))
245
+ return false ;
246
+ class_size = ira_class_hard_regs_num[reg_class];
247
+ for (i = 0 ; i < class_size; i++)
248
+ {
249
+ hard_regno = ira_class_hard_regs[reg_class][i];
250
+ nregs = hard_regno_nregs (hard_regno, reg_mode);
251
+ if (nregs == 1 )
252
+ return true ;
253
+ for (j = 0 ; j < nregs; j++)
254
+ if (TEST_HARD_REG_BIT (lra_no_alloc_regs, hard_regno + j)
255
+ || ! TEST_HARD_REG_BIT (reg_class_contents[reg_class],
256
+ hard_regno + j))
257
+ break ;
258
+ if (j >= nregs)
259
+ return true ;
260
+ }
261
+ return false ;
262
+ }
263
+
236
264
/* Return true if REG satisfies (or will satisfy) reg class constraint
237
265
CL. Use elimination first if REG is a hard register. If REG is a
238
266
reload pseudo created by this constraints pass, assume that it will
@@ -252,7 +280,6 @@ in_class_p (rtx reg, enum reg_class cl, enum reg_class *new_class,
252
280
enum reg_class rclass, common_class;
253
281
machine_mode reg_mode;
254
282
rtx src;
255
- int class_size, hard_regno, nregs, i, j;
256
283
int regno = REGNO (reg);
257
284
258
285
if (new_class != NULL )
@@ -291,26 +318,7 @@ in_class_p (rtx reg, enum reg_class cl, enum reg_class *new_class,
291
318
common_class = ira_reg_class_subset[rclass][cl];
292
319
if (new_class != NULL )
293
320
*new_class = common_class;
294
- if (hard_reg_set_subset_p (reg_class_contents[common_class],
295
- lra_no_alloc_regs))
296
- return false ;
297
- /* Check that there are enough allocatable regs. */
298
- class_size = ira_class_hard_regs_num[common_class];
299
- for (i = 0 ; i < class_size; i++)
300
- {
301
- hard_regno = ira_class_hard_regs[common_class][i];
302
- nregs = hard_regno_nregs (hard_regno, reg_mode);
303
- if (nregs == 1 )
304
- return true ;
305
- for (j = 0 ; j < nregs; j++)
306
- if (TEST_HARD_REG_BIT (lra_no_alloc_regs, hard_regno + j)
307
- || ! TEST_HARD_REG_BIT (reg_class_contents[common_class],
308
- hard_regno + j))
309
- break ;
310
- if (j >= nregs)
311
- return true ;
312
- }
313
- return false ;
321
+ return enough_allocatable_hard_regs_p (common_class, reg_mode);
314
322
}
315
323
}
316
324
@@ -2046,6 +2054,23 @@ update_and_check_small_class_inputs (int nop, int nalt,
2046
2054
return false ;
2047
2055
}
2048
2056
2057
+ /* Print operand constraints for alternative ALT_NUMBER of the current
2058
+ insn. */
2059
+ static void
2060
+ print_curr_insn_alt (int alt_number)
2061
+ {
2062
+ for (int i = 0 ; i < curr_static_id->n_operands ; i++)
2063
+ {
2064
+ const char *p = (curr_static_id->operand_alternative
2065
+ [alt_number * curr_static_id->n_operands + i].constraint );
2066
+ if (*p == ' \0 ' )
2067
+ continue ;
2068
+ fprintf (lra_dump_file, " (%d) " , i);
2069
+ for (; *p != ' \0 ' && *p != ' ,' && *p != ' #' ; p++)
2070
+ fputc (*p, lra_dump_file);
2071
+ }
2072
+ }
2073
+
2049
2074
/* Major function to choose the current insn alternative and what
2050
2075
operands should be reloaded and how. If ONLY_ALTERNATIVE is not
2051
2076
negative we should consider only this alternative. Return false if
@@ -2145,6 +2170,14 @@ process_alt_operands (int only_alternative)
2145
2170
if (!TEST_BIT (preferred, nalt))
2146
2171
continue ;
2147
2172
2173
+ if (lra_dump_file != NULL )
2174
+ {
2175
+ fprintf (lra_dump_file, " Considering alt=%d of insn %d: " ,
2176
+ nalt, INSN_UID (curr_insn));
2177
+ print_curr_insn_alt (nalt);
2178
+ fprintf (lra_dump_file, " \n " );
2179
+ }
2180
+
2148
2181
bool matching_early_clobber[MAX_RECOG_OPERANDS];
2149
2182
curr_small_class_check++;
2150
2183
overall = losers = addr_losers = 0 ;
@@ -2671,8 +2704,7 @@ process_alt_operands (int only_alternative)
2671
2704
{
2672
2705
if (lra_dump_file != NULL )
2673
2706
fprintf (lra_dump_file,
2674
- " alt=%d: Bad operand -- refuse\n " ,
2675
- nalt);
2707
+ " Bad operand -- refuse\n " );
2676
2708
goto fail;
2677
2709
}
2678
2710
@@ -2701,8 +2733,7 @@ process_alt_operands (int only_alternative)
2701
2733
{
2702
2734
if (lra_dump_file != NULL )
2703
2735
fprintf (lra_dump_file,
2704
- " alt=%d: Wrong mode -- refuse\n " ,
2705
- nalt);
2736
+ " Wrong mode -- refuse\n " );
2706
2737
goto fail;
2707
2738
}
2708
2739
}
@@ -2769,8 +2800,7 @@ process_alt_operands (int only_alternative)
2769
2800
if (lra_dump_file != NULL )
2770
2801
fprintf
2771
2802
(lra_dump_file,
2772
- " alt=%d: Strict low subreg reload -- refuse\n " ,
2773
- nalt);
2803
+ " Strict low subreg reload -- refuse\n " );
2774
2804
goto fail;
2775
2805
}
2776
2806
losers++;
@@ -2832,8 +2862,7 @@ process_alt_operands (int only_alternative)
2832
2862
if (lra_dump_file != NULL )
2833
2863
fprintf
2834
2864
(lra_dump_file,
2835
- " alt=%d: No input/output reload -- refuse\n " ,
2836
- nalt);
2865
+ " No input/output reload -- refuse\n " );
2837
2866
goto fail;
2838
2867
}
2839
2868
@@ -2860,9 +2889,9 @@ process_alt_operands (int only_alternative)
2860
2889
{
2861
2890
if (lra_dump_file != NULL )
2862
2891
fprintf (lra_dump_file,
2863
- " alt=%d: reload pseudo for op %d "
2892
+ " reload pseudo for op %d "
2864
2893
" cannot hold the mode value -- refuse\n " ,
2865
- nalt, nop);
2894
+ nop);
2866
2895
goto fail;
2867
2896
}
2868
2897
@@ -2989,7 +3018,7 @@ process_alt_operands (int only_alternative)
2989
3018
2990
3019
/* If reload requires moving value through secondary
2991
3020
memory, it will need one more insn at least. */
2992
- if (this_alternative != NO_REGS
3021
+ if (this_alternative != NO_REGS
2993
3022
&& REG_P (op) && (cl = get_reg_class (REGNO (op))) != NO_REGS
2994
3023
&& ((curr_static_id->operand [nop].type != OP_OUT
2995
3024
&& targetm.secondary_memory_needed (GET_MODE (op), cl,
@@ -3046,8 +3075,8 @@ process_alt_operands (int only_alternative)
3046
3075
{
3047
3076
if (lra_dump_file != NULL )
3048
3077
fprintf (lra_dump_file,
3049
- " alt=%d, overall=%d,losers=%d -- refuse\n " ,
3050
- nalt, overall, losers);
3078
+ " overall=%d,losers=%d -- refuse\n " ,
3079
+ overall, losers);
3051
3080
goto fail;
3052
3081
}
3053
3082
@@ -3056,8 +3085,7 @@ process_alt_operands (int only_alternative)
3056
3085
{
3057
3086
if (lra_dump_file != NULL )
3058
3087
fprintf (lra_dump_file,
3059
- " alt=%d, not enough small class regs -- refuse\n " ,
3060
- nalt);
3088
+ " not enough small class regs -- refuse\n " );
3061
3089
goto fail;
3062
3090
}
3063
3091
curr_alt[nop] = this_alternative;
@@ -3238,8 +3266,8 @@ process_alt_operands (int only_alternative)
3238
3266
overall += LRA_LOSER_COST_FACTOR - 1 ;
3239
3267
}
3240
3268
if (lra_dump_file != NULL )
3241
- fprintf (lra_dump_file, " alt=%d, overall=%d,losers=%d,rld_nregs=%d\n " ,
3242
- nalt, overall, losers, reload_nregs);
3269
+ fprintf (lra_dump_file, " overall=%d,losers=%d,rld_nregs=%d\n " ,
3270
+ overall, losers, reload_nregs);
3243
3271
3244
3272
/* If this alternative can be made to work by reloading, and it
3245
3273
needs less reloading than the others checked so far, record
@@ -4355,18 +4383,9 @@ curr_insn_transform (bool check_only_p)
4355
4383
{
4356
4384
const char *p;
4357
4385
4358
- fprintf (lra_dump_file, " Choosing alt %d in insn %u:" ,
4386
+ fprintf (lra_dump_file, " Choosing alt %d in insn %u:" ,
4359
4387
goal_alt_number, INSN_UID (curr_insn));
4360
- for (i = 0 ; i < n_operands; i++)
4361
- {
4362
- p = (curr_static_id->operand_alternative
4363
- [goal_alt_number * n_operands + i].constraint );
4364
- if (*p == ' \0 ' )
4365
- continue ;
4366
- fprintf (lra_dump_file, " (%d) " , i);
4367
- for (; *p != ' \0 ' && *p != ' ,' && *p != ' #' ; p++)
4368
- fputc (*p, lra_dump_file);
4369
- }
4388
+ print_curr_insn_alt (goal_alt_number);
4370
4389
if (INSN_CODE (curr_insn) >= 0
4371
4390
&& (p = get_insn_name (INSN_CODE (curr_insn))) != NULL )
4372
4391
fprintf (lra_dump_file, " {%s}" , p);
@@ -4564,7 +4583,22 @@ curr_insn_transform (bool check_only_p)
4564
4583
continue ;
4565
4584
}
4566
4585
else
4567
- continue ;
4586
+ {
4587
+ enum reg_class rclass, common_class;
4588
+
4589
+ if (REG_P (op) && goal_alt[i] != NO_REGS
4590
+ && (regno = REGNO (op)) >= new_regno_start
4591
+ && (rclass = get_reg_class (regno)) == ALL_REGS
4592
+ && ((common_class = ira_reg_class_subset[rclass][goal_alt[i]])
4593
+ != NO_REGS)
4594
+ && common_class != ALL_REGS
4595
+ && enough_allocatable_hard_regs_p (common_class,
4596
+ GET_MODE (op)))
4597
+ /* Refine reload pseudo class from chosen alternative
4598
+ constraint. */
4599
+ lra_change_class (regno, common_class, " Change to" , true );
4600
+ continue ;
4601
+ }
4568
4602
}
4569
4603
4570
4604
/* Operands that match previous ones have already been handled. */
@@ -5249,7 +5283,7 @@ lra_constraints (bool first_p)
5249
5283
the equiv. We could update the equiv insns after
5250
5284
transformations including an equiv insn deletion
5251
5285
but it is not worthy as such cases are extremely
5252
- rare. */
5286
+ rare. */
5253
5287
|| contains_deleted_insn_p (ira_reg_equiv[i].init_insns )
5254
5288
/* If it is not a reverse equivalence, we check that a
5255
5289
pseudo in rhs of the init insn is not dying in the
0 commit comments