Lra branch was merged with trunk at 191030. The following patch was
added to fix build/bootstrap failure for x86/x86-64.
The patch was successfuly bootstrapped on x86/x86-64, ppc64 and ARM.
2012-09-14 Vladimir Makarov <vmaka...@redhat.com>
* lra-int.h (lra_optional_reload_pseudos): New external.
* lra.c (lra_optional_reload_pseudos): New global bitmap.
(lra): Initialize and clear the bitmap.
* lra-assigns.c (lra_setup_reg_renumber): Print optional reload.
(spill_for): Ditto. Check lra_optional_reload_pseudos.
(assign_by_spills): Make optional assigning for optional reload
pseudos. Fix typo of usage of split pseudos during processing
inheriatance pseudos.
* lra-constraints.c (in_class_p): Add argument reg_mode. Check
that there are enough allocatable regs.
(get_reload_reg, process_addr_reg): Pass the new argument to
in_class_p.
(process_alt_operands): Ditto. Ignore early clobber for matched
equal pseudos.
(simplify_operand_subreg): Set up lra_optional_reload_pseudos.
(curr_insn_transform): Pass the new argument to in_class_p.
Index: lra-assigns.c
===================================================================
--- lra-assigns.c (revision 191029)
+++ lra-assigns.c (working copy)
@@ -624,7 +624,9 @@ lra_setup_reg_renumber (int regno, int h
regno < lra_constraint_new_regno_start
? ""
: bitmap_bit_p (&lra_inheritance_pseudos, regno) ? "inheritance "
- : bitmap_bit_p (&lra_split_pseudos, regno) ? "split " : "reload ",
+ : bitmap_bit_p (&lra_split_pseudos, regno) ? "split "
+ : bitmap_bit_p (&lra_optional_reload_pseudos, regno)
+ ? "optional reload ": "reload ",
regno, lra_reg_info[regno].freq);
if (hard_regno >= 0)
{
@@ -768,7 +770,8 @@ spill_for (int regno, bitmap spilled_pse
if ((int) spill_regno >= lra_constraint_new_regno_start
/* ??? */
&& ! bitmap_bit_p (&lra_inheritance_pseudos, spill_regno)
- && ! bitmap_bit_p (&lra_split_pseudos, spill_regno))
+ && ! bitmap_bit_p (&lra_split_pseudos, spill_regno)
+ && ! bitmap_bit_p (&lra_optional_reload_pseudos, spill_regno))
goto fail;
insn_pseudos_num = 0;
if (lra_dump_file != NULL)
@@ -889,7 +892,9 @@ spill_for (int regno, bitmap spilled_pse
: bitmap_bit_p (&lra_inheritance_pseudos, spill_regno)
? "inheritance "
: bitmap_bit_p (&lra_split_pseudos, spill_regno)
- ? "split " : "reload "),
+ ? "split "
+ : bitmap_bit_p (&lra_optional_reload_pseudos, spill_regno)
+ ? "optional reload " : "reload "),
spill_regno, reg_renumber[spill_regno],
lra_reg_info[spill_regno].freq, regno);
update_lives (spill_regno, true);
@@ -1081,6 +1086,7 @@ assign_by_spills (void)
rtx insn;
basic_block bb;
bitmap_head changed_insns, do_not_assign_nonreload_pseudos;
+ bitmap_head non_reload_pseudos;
unsigned int u;
bitmap_iterator bi;
@@ -1101,6 +1107,9 @@ assign_by_spills (void)
bitmap_initialize (&try_hard_reg_pseudos[i], ®_obstack);
curr_pseudo_check = 0;
bitmap_initialize (&changed_insns, ®_obstack);
+ bitmap_initialize (&non_reload_pseudos, ®_obstack);
+ bitmap_ior (&non_reload_pseudos, &lra_inheritance_pseudos, &lra_split_pseudos);
+ bitmap_ior_into (&non_reload_pseudos, &lra_optional_reload_pseudos);
for (iter = 0; iter <= 1; iter++)
{
qsort (sorted_pseudos, n, sizeof (int), reload_pseudo_compare_func);
@@ -1117,13 +1126,11 @@ assign_by_spills (void)
regno_assign_info[regno_assign_info[regno].first].freq);
hard_regno = find_hard_regno_for (regno, &cost, -1);
if (hard_regno < 0
- && ! bitmap_bit_p (&lra_inheritance_pseudos, regno)
- && ! bitmap_bit_p (&lra_split_pseudos, regno))
+ && ! bitmap_bit_p (&non_reload_pseudos, regno))
hard_regno = spill_for (regno, &all_spilled_pseudos);
if (hard_regno < 0)
{
- if (! bitmap_bit_p (&lra_inheritance_pseudos, regno)
- && ! bitmap_bit_p (&lra_split_pseudos, regno))
+ if (! bitmap_bit_p (&non_reload_pseudos, regno))
sorted_pseudos[nfails++] = regno;
}
else
@@ -1166,6 +1173,8 @@ assign_by_spills (void)
for (r = data->regs; r != NULL; r = r->next)
{
regno = r->regno;
+ /* We can use inheritance pseudos in original insns
+ (not reload ones). */
if (regno < lra_constraint_new_regno_start
|| bitmap_bit_p (&lra_inheritance_pseudos, regno)
|| reg_renumber[regno] < 0)
@@ -1183,6 +1192,7 @@ assign_by_spills (void)
n = nfails;
}
improve_inheritance (&changed_pseudo_bitmap);
+ bitmap_clear (&non_reload_pseudos);
bitmap_clear (&changed_insns);
/* We should not assign to original pseudos of inheritance pseudos
or split pseudos if any its inheritance pseudo did not get hard
@@ -1192,10 +1202,11 @@ assign_by_spills (void)
bitmap_initialize (&do_not_assign_nonreload_pseudos, ®_obstack);
EXECUTE_IF_SET_IN_BITMAP (&lra_inheritance_pseudos, 0, u, bi)
if ((restore_regno = lra_reg_info[u].restore_regno) >= 0
- && ((reg_renumber[u] < 0
- && bitmap_bit_p (&lra_inheritance_pseudos, u))
- || (reg_renumber[u] >= 0
- && bitmap_bit_p (&lra_split_pseudos, u))))
+ && reg_renumber[u] < 0 && bitmap_bit_p (&lra_inheritance_pseudos, u))
+ bitmap_set_bit (&do_not_assign_nonreload_pseudos, restore_regno);
+ EXECUTE_IF_SET_IN_BITMAP (&lra_split_pseudos, 0, u, bi)
+ if ((restore_regno = lra_reg_info[u].restore_regno) >= 0
+ && reg_renumber[u] >= 0 && bitmap_bit_p (&lra_split_pseudos, u))
bitmap_set_bit (&do_not_assign_nonreload_pseudos, restore_regno);
for (n = 0, i = FIRST_PSEUDO_REGISTER; i < max_reg_num (); i++)
if (((i < lra_constraint_new_regno_start
@@ -1203,7 +1214,8 @@ assign_by_spills (void)
|| (bitmap_bit_p (&lra_inheritance_pseudos, i)
&& lra_reg_info[i].restore_regno >= 0)
|| (bitmap_bit_p (&lra_split_pseudos, i)
- && lra_reg_info[i].restore_regno >= 0))
+ && lra_reg_info[i].restore_regno >= 0)
+ || bitmap_bit_p (&lra_optional_reload_pseudos, i))
&& reg_renumber[i] < 0 && lra_reg_info[i].nrefs != 0
&& regno_allocno_class_array[i] != NO_REGS)
sorted_pseudos[n++] = i;
Index: lra.c
===================================================================
--- lra.c (revision 191029)
+++ lra.c (working copy)
@@ -2153,6 +2153,10 @@ bitmap_head lra_inheritance_pseudos;
/* Split pseudo regnos before the new spill pass. */
bitmap_head lra_split_pseudos;
+/* Reload pseudo regnos before the new assign pass which still can be
+ spilled after the assinment pass. */
+bitmap_head lra_optional_reload_pseudos;
+
/* First UID of insns generated before a new spill pass. */
int lra_constraint_new_insn_uid_start;
@@ -2243,11 +2247,13 @@ lra (FILE *f)
lra_constraint_new_insn_uid_start = get_max_uid ();
bitmap_initialize (&lra_inheritance_pseudos, ®_obstack);
bitmap_initialize (&lra_split_pseudos, ®_obstack);
+ bitmap_initialize (&lra_optional_reload_pseudos, ®_obstack);
live_p = false;
for (;;)
{
for (;;)
{
+ bitmap_clear (&lra_optional_reload_pseudos);
/* We should try to assign hard registers to scratches even
if there were no RTL transformations in
lra_constraints. */
Index: lra-constraints.c
===================================================================
--- lra-constraints.c (revision 191029)
+++ lra-constraints.c (working copy)
@@ -216,14 +216,16 @@ get_reg_class (int regno)
return NO_REGS;
}
-/* Return true if REGNO satisfies reg class constraint CL. For new
- reload pseudos we should make more accurate class *NEW_CLASS
- (we set up it if it is not NULL) to satisfy the constraints.
- Otherwise, set up NEW_CLASS to NO_REGS. */
+/* Return true if REGNO in REG_MODE satisfies reg class constraint CL.
+ For new reload pseudos we should make more accurate class
+ *NEW_CLASS (we set up it if it is not NULL) to satisfy the
+ constraints. Otherwise, set up NEW_CLASS to NO_REGS. */
static bool
-in_class_p (int regno, enum reg_class cl, enum reg_class *new_class)
+in_class_p (int regno, enum machine_mode reg_mode,
+ enum reg_class cl, enum reg_class *new_class)
{
enum reg_class rclass, common_class;
+ int class_size, hard_regno, nregs, i, j;
if (new_class != NULL)
*new_class = NO_REGS;
@@ -237,16 +239,33 @@ in_class_p (int regno, enum reg_class cl
impossibility of find registers for several reloads of one
insn. */
|| INSN_UID (curr_insn) >= new_insn_uid_start)
- return (rclass != NO_REGS && ira_class_subset_p[rclass][cl]
- && ! hard_reg_set_subset_p (reg_class_contents[cl],
- lra_no_alloc_regs));
+ return ((regno >= new_regno_start && rclass == ALL_REGS)
+ || (rclass != NO_REGS && ira_class_subset_p[rclass][cl]
+ && ! hard_reg_set_subset_p (reg_class_contents[cl],
+ lra_no_alloc_regs)));
else
{
common_class = ira_reg_class_subset[rclass][cl];
if (new_class != NULL)
*new_class = common_class;
- return ! hard_reg_set_subset_p (reg_class_contents[common_class],
- lra_no_alloc_regs);
+ if (hard_reg_set_subset_p (reg_class_contents[common_class],
+ lra_no_alloc_regs))
+ return false;
+ /* Check that there are enough allocatable regs. */
+ class_size = ira_class_hard_regs_num[common_class];
+ for (i = 0; i < class_size; i++)
+ {
+ hard_regno = ira_class_hard_regs[common_class][i];
+ nregs = hard_regno_nregs[hard_regno][reg_mode];
+ if (nregs == 1)
+ return true;
+ for (j = 0; j < nregs; j++)
+ if (TEST_HARD_REG_BIT (lra_no_alloc_regs, hard_regno + j))
+ break;
+ if (j >= nregs)
+ return true;
+ }
+ return false;
}
}
@@ -344,7 +363,8 @@ get_reload_reg (enum op_type type, enum
break;
if (i >= curr_insn_input_reloads_num
|| ! in_class_p (REGNO (curr_insn_input_reloads[i].reg),
- rclass, &new_class))
+ GET_MODE (curr_insn_input_reloads[i].reg),
+ rclass, &new_class))
{
res_p = true;
*result_reg = lra_create_new_reg (mode, original, rclass, title);
@@ -1396,7 +1416,7 @@ process_addr_reg (rtx *loc, rtx *before,
*loc = copy_rtx (*loc);
change_p = true;
}
- if (*loc != reg || ! in_class_p (final_regno, cl, &new_class))
+ if (*loc != reg || ! in_class_p (final_regno, GET_MODE (reg), cl, &new_class))
{
reg = *loc;
if (get_reload_reg (OP_IN, mode, reg, cl, "address", &new_reg))
@@ -1476,9 +1496,11 @@ simplify_operand_subreg (int nop, enum m
enum reg_class rclass
= (enum reg_class) targetm.preferred_reload_class (reg, ALL_REGS);
- if (get_reload_reg (type, reg_mode, reg, rclass, "subreg reg", &new_reg)
- && (type != OP_OUT
- || GET_MODE_SIZE (GET_MODE (reg)) > GET_MODE_SIZE (mode)))
+ new_reg = lra_create_new_reg_with_unique_value (reg_mode, reg, rclass,
+ "subreg reg");
+ bitmap_set_bit (&lra_optional_reload_pseudos, REGNO (new_reg));
+ if (type != OP_OUT
+ || GET_MODE_SIZE (GET_MODE (reg)) > GET_MODE_SIZE (mode))
{
push_to_sequence (before);
lra_emit_move (new_reg, reg);
@@ -2104,7 +2126,7 @@ process_alt_operands (int only_alternati
mode, hard_regno[nop]))
win = true;
else if (hard_regno[nop] < 0
- && in_class_p (REGNO (op),
+ && in_class_p (REGNO (op), GET_MODE (op),
this_alternative, NULL))
win = true;
}
@@ -2138,6 +2160,7 @@ process_alt_operands (int only_alternati
conditions. */
reject++;
if (in_class_p (REGNO (operand_reg[nop]),
+ GET_MODE (operand_reg[nop]),
this_costly_alternative, NULL))
reject++;
}
@@ -2180,7 +2203,7 @@ process_alt_operands (int only_alternati
|| ! in_hard_reg_set_p (this_alternative_set,
mode, hard_regno[nop]))
&& (hard_regno[nop] >= 0
- || ! in_class_p (REGNO (op),
+ || ! in_class_p (REGNO (op), GET_MODE (op),
this_alternative, NULL))))
losers++;
if (operand_reg[nop] != NULL_RTX)
@@ -2330,15 +2353,21 @@ process_alt_operands (int only_alternati
conflict by forcing to use the same pseudo for the
operands hoping that the pseudo gets the same hard
regno as the operands and the reloads are gone. */
- curr_alt_win[i] = false;
- curr_alt_match_win[j] = false;
+ if (*curr_id->operand_loc[i] != *curr_id->operand_loc[j])
+ {
+ curr_alt_win[i] = false;
+ curr_alt_match_win[j] = false;
+ }
continue;
}
else if (curr_alt_matches[i] == j && curr_alt_match_win[i])
{
/* See the comment for the previous case. */
- curr_alt_win[j] = false;
- curr_alt_match_win[i] = false;
+ if (*curr_id->operand_loc[i] != *curr_id->operand_loc[j])
+ {
+ curr_alt_win[j] = false;
+ curr_alt_match_win[i] = false;
+ }
continue;
}
else if (uses_hard_regs_p (curr_id->operand_loc[j], temp_set))
@@ -3205,7 +3234,8 @@ curr_insn_transform (void)
if (REG_P (reg) && (regno = REGNO (reg)) >= FIRST_PSEUDO_REGISTER)
{
- bool ok_p = in_class_p (regno, goal_alt[i], &new_class);
+ bool ok_p = in_class_p (regno, GET_MODE (reg),
+ goal_alt[i], &new_class);
if (new_class != NO_REGS && get_reg_class (regno) != new_class)
{
Index: lra-int.h
===================================================================
--- lra-int.h (revision 191029)
+++ lra-int.h (working copy)
@@ -289,6 +289,7 @@ extern bool lra_former_scratch_operand_p
extern int lra_constraint_new_regno_start;
extern bitmap_head lra_inheritance_pseudos;
extern bitmap_head lra_split_pseudos;
+extern bitmap_head lra_optional_reload_pseudos;
extern int lra_constraint_new_insn_uid_start;
/* lra-constraints.c: */