@@ -233,6 +233,34 @@ get_reg_class (int regno)
233233 return NO_REGS;
234234}
235235
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+
236264/* Return true if REG satisfies (or will satisfy) reg class constraint
237265 CL. Use elimination first if REG is a hard register. If REG is a
238266 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,
252280 enum reg_class rclass, common_class;
253281 machine_mode reg_mode;
254282 rtx src;
255- int class_size, hard_regno, nregs, i, j;
256283 int regno = REGNO (reg);
257284
258285 if (new_class != NULL )
@@ -291,26 +318,7 @@ in_class_p (rtx reg, enum reg_class cl, enum reg_class *new_class,
291318 common_class = ira_reg_class_subset[rclass][cl];
292319 if (new_class != NULL )
293320 *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);
314322 }
315323}
316324
@@ -2046,6 +2054,23 @@ update_and_check_small_class_inputs (int nop, int nalt,
20462054 return false ;
20472055}
20482056
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+
20492074/* Major function to choose the current insn alternative and what
20502075 operands should be reloaded and how. If ONLY_ALTERNATIVE is not
20512076 negative we should consider only this alternative. Return false if
@@ -2145,6 +2170,14 @@ process_alt_operands (int only_alternative)
21452170 if (!TEST_BIT (preferred, nalt))
21462171 continue ;
21472172
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+
21482181 bool matching_early_clobber[MAX_RECOG_OPERANDS];
21492182 curr_small_class_check++;
21502183 overall = losers = addr_losers = 0 ;
@@ -2671,8 +2704,7 @@ process_alt_operands (int only_alternative)
26712704 {
26722705 if (lra_dump_file != NULL )
26732706 fprintf (lra_dump_file,
2674- " alt=%d: Bad operand -- refuse\n " ,
2675- nalt);
2707+ " Bad operand -- refuse\n " );
26762708 goto fail;
26772709 }
26782710
@@ -2701,8 +2733,7 @@ process_alt_operands (int only_alternative)
27012733 {
27022734 if (lra_dump_file != NULL )
27032735 fprintf (lra_dump_file,
2704- " alt=%d: Wrong mode -- refuse\n " ,
2705- nalt);
2736+ " Wrong mode -- refuse\n " );
27062737 goto fail;
27072738 }
27082739 }
@@ -2769,8 +2800,7 @@ process_alt_operands (int only_alternative)
27692800 if (lra_dump_file != NULL )
27702801 fprintf
27712802 (lra_dump_file,
2772- " alt=%d: Strict low subreg reload -- refuse\n " ,
2773- nalt);
2803+ " Strict low subreg reload -- refuse\n " );
27742804 goto fail;
27752805 }
27762806 losers++;
@@ -2832,8 +2862,7 @@ process_alt_operands (int only_alternative)
28322862 if (lra_dump_file != NULL )
28332863 fprintf
28342864 (lra_dump_file,
2835- " alt=%d: No input/output reload -- refuse\n " ,
2836- nalt);
2865+ " No input/output reload -- refuse\n " );
28372866 goto fail;
28382867 }
28392868
@@ -2860,9 +2889,9 @@ process_alt_operands (int only_alternative)
28602889 {
28612890 if (lra_dump_file != NULL )
28622891 fprintf (lra_dump_file,
2863- " alt=%d: reload pseudo for op %d "
2892+ " reload pseudo for op %d "
28642893 " cannot hold the mode value -- refuse\n " ,
2865- nalt, nop);
2894+ nop);
28662895 goto fail;
28672896 }
28682897
@@ -2989,7 +3018,7 @@ process_alt_operands (int only_alternative)
29893018
29903019 /* If reload requires moving value through secondary
29913020 memory, it will need one more insn at least. */
2992- if (this_alternative != NO_REGS
3021+ if (this_alternative != NO_REGS
29933022 && REG_P (op) && (cl = get_reg_class (REGNO (op))) != NO_REGS
29943023 && ((curr_static_id->operand [nop].type != OP_OUT
29953024 && targetm.secondary_memory_needed (GET_MODE (op), cl,
@@ -3046,8 +3075,8 @@ process_alt_operands (int only_alternative)
30463075 {
30473076 if (lra_dump_file != NULL )
30483077 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);
30513080 goto fail;
30523081 }
30533082
@@ -3056,8 +3085,7 @@ process_alt_operands (int only_alternative)
30563085 {
30573086 if (lra_dump_file != NULL )
30583087 fprintf (lra_dump_file,
3059- " alt=%d, not enough small class regs -- refuse\n " ,
3060- nalt);
3088+ " not enough small class regs -- refuse\n " );
30613089 goto fail;
30623090 }
30633091 curr_alt[nop] = this_alternative;
@@ -3238,8 +3266,8 @@ process_alt_operands (int only_alternative)
32383266 overall += LRA_LOSER_COST_FACTOR - 1 ;
32393267 }
32403268 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);
32433271
32443272 /* If this alternative can be made to work by reloading, and it
32453273 needs less reloading than the others checked so far, record
@@ -4355,18 +4383,9 @@ curr_insn_transform (bool check_only_p)
43554383 {
43564384 const char *p;
43574385
4358- fprintf (lra_dump_file, " Choosing alt %d in insn %u:" ,
4386+ fprintf (lra_dump_file, " Choosing alt %d in insn %u:" ,
43594387 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);
43704389 if (INSN_CODE (curr_insn) >= 0
43714390 && (p = get_insn_name (INSN_CODE (curr_insn))) != NULL )
43724391 fprintf (lra_dump_file, " {%s}" , p);
@@ -4564,7 +4583,22 @@ curr_insn_transform (bool check_only_p)
45644583 continue ;
45654584 }
45664585 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+ }
45684602 }
45694603
45704604 /* Operands that match previous ones have already been handled. */
@@ -5249,7 +5283,7 @@ lra_constraints (bool first_p)
52495283 the equiv. We could update the equiv insns after
52505284 transformations including an equiv insn deletion
52515285 but it is not worthy as such cases are extremely
5252- rare. */
5286+ rare. */
52535287 || contains_deleted_insn_p (ira_reg_equiv[i].init_insns )
52545288 /* If it is not a reverse equivalence, we check that a
52555289 pseudo in rhs of the init insn is not dying in the
0 commit comments