+2012-11-22 Vladimir Makarov <vmakarov@redhat.com>
+
+ PR middle-end/55430
+ * lra.c: Move #include "hard-reg-set.h" before #include "rtl.h".
+ (new_insn_reg): Update biggest_mode.
+ (collect_non_operand_hard_regs): Check eliminable regs too.
+ (initialize_lra_reg_info_element): Initialize biggest_mode.
+ (add_regs_to_insn_regno_info): Ignore non-allocatable
+ non-eliminable hard regs.
+ (lra.c): Move setting lra_no_alloc_regs before
+ init_insn_recog_data.
+ * lra-constraints.c (simplify_operand_subreg): Add a comment.
+ (lra_constraints): Ignore equivalent memory of
+ regs occuring in paradoxical subregs.
+ * lra-lives.c (lra_create_live_ranges): Add a comment.
+
2012-11-22 Dmitry Vyukov <dvyukov@google.com>
Wei Mi <wmi@google.com>
reg = SUBREG_REG (operand);
/* If we change address for paradoxical subreg of memory, the
address might violate the necessary alignment or the access might
- be slow. So take this into consideration. */
+ be slow. So take this into consideration. We should not worry
+ about access beyond allocated memory for paradoxical memory
+ subregs as we don't substitute such equiv memory (see processing
+ equivalences in function lra_constraints) and because for spilled
+ pseudos we allocate stack memory enough for the biggest
+ corresponding paradoxical subreg. */
if ((MEM_P (reg)
&& (! SLOW_UNALIGNED_ACCESS (mode, MEM_ALIGN (reg))
|| MEM_ALIGN (reg) >= GET_MODE_ALIGNMENT (mode)))
&& (set = single_set (insn)) != NULL_RTX
&& REG_P (SET_DEST (set))
&& (int) REGNO (SET_DEST (set)) == i)
- && init_insn_rhs_dead_pseudo_p (i)))
+ && init_insn_rhs_dead_pseudo_p (i))
+ /* Prevent access beyond equivalent memory for
+ paradoxical subregs. */
+ || (MEM_P (x)
+ && (GET_MODE_SIZE (lra_reg_info[i].biggest_mode)
+ > GET_MODE_SIZE (GET_MODE (x)))))
ira_reg_equiv[i].defined_p = false;
if (contains_reg_p (x, false, true))
ira_reg_equiv[i].profitable_p = false;
#ifdef STACK_REGS
lra_reg_info[i].no_stack_p = false;
#endif
+ /* The biggest mode is already set but its value might be to
+ conservative because of recent transformation. Here in this
+ file we recalculate it again as it costs practically
+ nothing. */
if (regno_reg_rtx[i] != NULL_RTX)
lra_reg_info[i].biggest_mode = GET_MODE (regno_reg_rtx[i]);
else
#include "system.h"
#include "coretypes.h"
#include "tm.h"
+#include "hard-reg-set.h"
#include "rtl.h"
#include "tm_p.h"
#include "regs.h"
#include "recog.h"
#include "output.h"
#include "addresses.h"
-#include "hard-reg-set.h"
#include "flags.h"
#include "function.h"
#include "expr.h"
ir = (struct lra_insn_reg *) pool_alloc (insn_reg_pool);
ir->type = type;
ir->biggest_mode = mode;
+ if (GET_MODE_SIZE (mode) > GET_MODE_SIZE (lra_reg_info[regno].biggest_mode))
+ lra_reg_info[regno].biggest_mode = mode;
ir->subreg_p = subreg_p;
ir->early_clobber = early_clobber;
ir->regno = regno;
for (last = regno + hard_regno_nregs[regno][mode];
regno < last;
regno++)
- if (! TEST_HARD_REG_BIT (lra_no_alloc_regs, regno))
+ if (! TEST_HARD_REG_BIT (lra_no_alloc_regs, regno)
+ || TEST_HARD_REG_BIT (eliminable_regset, regno))
{
for (curr = list; curr != NULL; curr = curr->next)
if (curr->regno == regno && curr->subreg_p == subreg_p
lra_reg_info[i].preferred_hard_regno2 = -1;
lra_reg_info[i].preferred_hard_regno_profit1 = 0;
lra_reg_info[i].preferred_hard_regno_profit2 = 0;
+ lra_reg_info[i].biggest_mode = VOIDmode;
lra_reg_info[i].live_ranges = NULL;
lra_reg_info[i].nrefs = lra_reg_info[i].freq = 0;
lra_reg_info[i].last_reload = 0;
if (REG_P (x))
{
regno = REGNO (x);
+ if (regno < FIRST_PSEUDO_REGISTER
+ && TEST_HARD_REG_BIT (lra_no_alloc_regs, regno)
+ && ! TEST_HARD_REG_BIT (eliminable_regset, regno))
+ return;
expand_reg_info ();
if (bitmap_set_bit (&lra_reg_info[regno].insn_bitmap, uid))
{
timevar_push (TV_LRA);
+ COPY_HARD_REG_SET (lra_no_alloc_regs, ira_no_alloc_regs);
+
init_insn_recog_data ();
#ifdef ENABLE_CHECKING
check_rtl (false);
#endif
- COPY_HARD_REG_SET (lra_no_alloc_regs, ira_no_alloc_regs);
-
lra_live_range_iter = lra_coalesce_iter = 0;
lra_constraint_iter = lra_constraint_iter_after_spill = 0;
lra_inheritance_iter = lra_undo_inheritance_iter = 0;