/* Integrated Register Allocator (IRA) entry point.
- Copyright (C) 2006, 2007, 2008, 2009
+ Copyright (C) 2006, 2007, 2008, 2009, 2010
Free Software Foundation, Inc.
Contributed by Vladimir Makarov <vmakarov@redhat.com>.
#include "bitmap.h"
#include "hard-reg-set.h"
#include "basic-block.h"
+#include "df.h"
#include "expr.h"
#include "recog.h"
#include "params.h"
#include "output.h"
#include "except.h"
#include "reload.h"
-#include "errors.h"
+#include "toplev.h"
#include "integrate.h"
-#include "df.h"
#include "ggc.h"
#include "ira-int.h"
allocation order. */
short ira_class_hard_regs[N_REG_CLASSES][FIRST_PSEUDO_REGISTER];
+/* Array of the number of hard registers of given class which are
+ available for allocation. The order is defined by the
+ the hard register numbers. */
+short ira_non_ordered_class_hard_regs[N_REG_CLASSES][FIRST_PSEUDO_REGISTER];
+
/* The number of elements of the above array for given register
class. */
int ira_class_hard_regs_num[N_REG_CLASSES];
HARD_REG_SET processed_hard_reg_set;
ira_assert (SHRT_MAX >= FIRST_PSEUDO_REGISTER);
- /* We could call ORDER_REGS_FOR_LOCAL_ALLOC here (it is usually
- putting hard callee-used hard registers first). But our
- heuristics work better. */
for (cl = (int) N_REG_CLASSES - 1; cl >= 0; cl--)
{
COPY_HARD_REG_SET (temp_hard_regset, reg_class_contents[cl]);
AND_COMPL_HARD_REG_SET (temp_hard_regset, no_unit_alloc_regs);
CLEAR_HARD_REG_SET (processed_hard_reg_set);
for (i = 0; i < FIRST_PSEUDO_REGISTER; i++)
- ira_class_hard_reg_index[cl][0] = -1;
+ {
+ ira_non_ordered_class_hard_regs[cl][0] = -1;
+ ira_class_hard_reg_index[cl][0] = -1;
+ }
for (n = 0, i = 0; i < FIRST_PSEUDO_REGISTER; i++)
{
#ifdef REG_ALLOC_ORDER
}
}
ira_class_hard_regs_num[cl] = n;
+ for (n = 0, i = 0; i < FIRST_PSEUDO_REGISTER; i++)
+ if (TEST_HARD_REG_BIT (temp_hard_regset, i))
+ ira_non_ordered_class_hard_regs[cl][n++] = i;
+ ira_assert (ira_class_hard_regs_num[cl] == n);
}
}
static void
setup_alloc_regs (bool use_hard_frame_p)
{
+#ifdef ADJUST_REG_ALLOC_ORDER
+ ADJUST_REG_ALLOC_ORDER;
+#endif
COPY_HARD_REG_SET (no_unit_alloc_regs, fixed_reg_set);
if (! use_hard_frame_p)
SET_HARD_REG_BIT (no_unit_alloc_regs, HARD_FRAME_POINTER_REGNUM);
FOR_EACH_BB (bb)
{
/* We don't use LIVE info in IRA. */
- regset r = DF_LR_IN (bb);
+ bitmap r = DF_LR_IN (bb);
if (REGNO_REG_SET_P (r, from))
{
}
}
+/* In DEBUG_INSN location adjust REGs from CLEARED_REGS bitmap to the
+ equivalent replacement. */
+
+static rtx
+adjust_cleared_regs (rtx loc, const_rtx old_rtx ATTRIBUTE_UNUSED, void *data)
+{
+ if (REG_P (loc))
+ {
+ bitmap cleared_regs = (bitmap) data;
+ if (bitmap_bit_p (cleared_regs, REGNO (loc)))
+ return simplify_replace_fn_rtx (*reg_equiv[REGNO (loc)].src_p,
+ NULL_RTX, adjust_cleared_regs, data);
+ }
+ return NULL_RTX;
+}
+
/* Nonzero if we recorded an equivalence for a LABEL_REF. */
static int recorded_label_ref;
}
if (!bitmap_empty_p (cleared_regs))
- FOR_EACH_BB (bb)
- {
- bitmap_and_compl_into (DF_LIVE_IN (bb), cleared_regs);
- bitmap_and_compl_into (DF_LIVE_OUT (bb), cleared_regs);
- bitmap_and_compl_into (DF_LR_IN (bb), cleared_regs);
- bitmap_and_compl_into (DF_LR_OUT (bb), cleared_regs);
- }
+ {
+ FOR_EACH_BB (bb)
+ {
+ bitmap_and_compl_into (DF_LIVE_IN (bb), cleared_regs);
+ bitmap_and_compl_into (DF_LIVE_OUT (bb), cleared_regs);
+ bitmap_and_compl_into (DF_LR_IN (bb), cleared_regs);
+ bitmap_and_compl_into (DF_LR_OUT (bb), cleared_regs);
+ }
+
+ /* Last pass - adjust debug insns referencing cleared regs. */
+ if (MAY_HAVE_DEBUG_INSNS)
+ for (insn = get_insns (); insn; insn = NEXT_INSN (insn))
+ if (DEBUG_INSN_P (insn))
+ {
+ rtx old_loc = INSN_VAR_LOCATION_LOC (insn);
+ INSN_VAR_LOCATION_LOC (insn)
+ = simplify_replace_fn_rtx (old_loc, NULL_RTX,
+ adjust_cleared_regs,
+ (void *) cleared_regs);
+ if (old_loc != INSN_VAR_LOCATION_LOC (insn))
+ df_insn_rescan (insn);
+ }
+ }
BITMAP_FREE (cleared_regs);
timevar_push (TV_IRA);
+ if (flag_caller_saves)
+ init_caller_save ();
+
if (flag_ira_verbose < 10)
{
internal_flag_ira_verbose = flag_ira_verbose;