typically moves that have many alternatives, and restricting
reload pseudos for one alternative may lead to situations
where other reload pseudos are no longer allocatable. */
- || INSN_UID (curr_insn) >= new_insn_uid_start)
+ || (INSN_UID (curr_insn) >= new_insn_uid_start
+ && curr_insn_set != NULL
+ && (OBJECT_P (SET_SRC (curr_insn_set))
+ || (GET_CODE (SET_SRC (curr_insn_set)) == SUBREG
+ && OBJECT_P (SUBREG_REG (SET_SRC (curr_insn_set)))))))
/* When we don't know what class will be used finally for reload
pseudos, we use ALL_REGS. */
return ((regno >= new_regno_start && rclass == ALL_REGS)
curr_insn_input_reloads_num = 0;
}
-/* Change class of pseudo REGNO to NEW_CLASS. Print info about it
- using TITLE. Output a new line if NL_P. */
-static void
-change_class (int regno, enum reg_class new_class,
- const char *title, bool nl_p)
-{
- lra_assert (regno >= FIRST_PSEUDO_REGISTER);
- if (lra_dump_file != NULL)
- fprintf (lra_dump_file, "%s to class %s for r%d",
- title, reg_class_names[new_class], regno);
- setup_reg_classes (regno, new_class, NO_REGS, new_class);
- if (lra_dump_file != NULL && nl_p)
- fprintf (lra_dump_file, "\n");
-}
-
/* Create a new pseudo using MODE, RCLASS, ORIGINAL or reuse already
created input reload pseudo (only if TYPE is not OP_OUT). The
result pseudo is returned through RESULT_REG. Return TRUE if we
dump_value_slim (lra_dump_file, original, 1);
}
if (new_class != lra_get_allocno_class (regno))
- change_class (regno, new_class, ", change", false);
+ lra_change_class (regno, new_class, ", change to", false);
if (lra_dump_file != NULL)
fprintf (lra_dump_file, "\n");
return false;
if (! REG_P (reg) || (int) REGNO (reg) < new_regno_start)
return;
if (in_class_p (reg, cl, &rclass) && rclass != cl)
- change_class (REGNO (reg), rclass, " Change", true);
+ lra_change_class (REGNO (reg), rclass, " Change to", true);
}
/* Generate reloads for matching OUT and INS (array of input operand
}
else if (new_class != NO_REGS && rclass != new_class)
{
- change_class (regno, new_class, " Change", true);
+ lra_change_class (regno, new_class, " Change to", true);
return false;
}
else
regno = REGNO (*ad.base_term);
if (regno >= FIRST_PSEUDO_REGISTER
&& cl != lra_get_allocno_class (regno))
- change_class (regno, cl, " Change", true);
+ lra_change_class (regno, cl, " Change to", true);
new_reg = SET_SRC (set);
delete_insns_since (PREV_INSN (last_insn));
}
if (new_class != NO_REGS && get_reg_class (regno) != new_class)
{
lra_assert (ok_p);
- change_class (regno, new_class, " Change", true);
+ lra_change_class (regno, new_class, " Change to", true);
}
}
}
&& lra_former_scratch_operand_p (curr_insn, i))
{
int regno = REGNO (op);
- change_class (regno, NO_REGS, " Change", true);
+ lra_change_class (regno, NO_REGS, " Change to", true);
if (lra_get_regno_hard_regno (regno) >= 0)
/* We don't have to mark all insn affected by the
spilled pseudo as there is only one such insn, the
&& lra_undo_inheritance_iter < LRA_MAX_INHERITANCE_PASSES
&& goal_alt[i] != NO_REGS && REG_P (op)
&& (regno = REGNO (op)) >= FIRST_PSEUDO_REGISTER
+ && regno < new_regno_start
&& ! lra_former_scratch_p (regno)
&& reg_renumber[regno] < 0
&& (curr_insn_set == NULL_RTX
base and index registers might require a reload too. */
#define LRA_MAX_INSN_RELOADS (MAX_RECOG_OPERANDS * 3)
-/* Return the hard register which given pseudo REGNO assigned to.
- Negative value means that the register got memory or we don't know
- allocation yet. */
-static inline int
-lra_get_regno_hard_regno (int regno)
-{
- resize_reg_info ();
- return reg_renumber[regno];
-}
-
typedef struct lra_live_range *lra_live_range_t;
/* The structure describes program points where a given pseudo lives.
\f
+/* Return the hard register which given pseudo REGNO assigned to.
+ Negative value means that the register got memory or we don't know
+ allocation yet. */
+static inline int
+lra_get_regno_hard_regno (int regno)
+{
+ resize_reg_info ();
+ return reg_renumber[regno];
+}
+
+/* Change class of pseudo REGNO to NEW_CLASS. Print info about it
+ using TITLE. Output a new line if NL_P. */
+static void inline
+lra_change_class (int regno, enum reg_class new_class,
+ const char *title, bool nl_p)
+{
+ lra_assert (regno >= FIRST_PSEUDO_REGISTER);
+ if (lra_dump_file != NULL)
+ fprintf (lra_dump_file, "%s class %s for r%d",
+ title, reg_class_names[new_class], regno);
+ setup_reg_classes (regno, new_class, NO_REGS, new_class);
+ if (lra_dump_file != NULL && nl_p)
+ fprintf (lra_dump_file, "\n");
+}
+
/* Update insn operands which are duplication of NOP operand. The
insn is represented by its LRA internal representation ID. */
static inline void
/* Expand all regno related info needed for LRA. */
static void
-expand_reg_data (void)
+expand_reg_data (int old)
{
resize_reg_info ();
expand_reg_info ();
ira_expand_reg_equiv ();
+ for (int i = (int) max_reg_num () - 1; i >= old; i--)
+ lra_change_class (i, ALL_REGS, " Set", true);
}
/* Create and return a new reg of ORIGINAL mode. If ORIGINAL is NULL
title, REGNO (new_reg));
fprintf (lra_dump_file, "\n");
}
- expand_reg_data ();
+ expand_reg_data (max_reg_num ());
setup_reg_classes (REGNO (new_reg), rclass, NO_REGS, rclass);
return new_reg;
}
/* Functions emit_... can create pseudos -- so expand the pseudo
data. */
if (old != max_reg_num ())
- expand_reg_data ();
+ expand_reg_data (old);
}
/* The number of emitted reload insns so far. */
/* Function emit_move can create pseudos -- so expand the pseudo
data. */
if (old != max_reg_num ())
- expand_reg_data ();
+ expand_reg_data (old);
return;
}
lra_emit_add (x, XEXP (y, 0), XEXP (y, 1));