The following patch makes GCC bootstrap successful on mips64el with LRA
usage.
Committed as rev. 186198.
2012-04-06 Vladimir Makarov <vmaka...@redhat.com>
* config/mips/mips.c: Include lra.h.
(mips_expand_fcc_reload): Add code for LRA.
* lra-int.h (lra_get_allocno_class, lra_create_new_reg): Move
to ...
* lra.h: ... here.
* lra.c (collect_non_operand_hard_regs): Use REGMODE_NATURAL_SIZE.
* lra-assign.c (assign_by_spills): Set up changed_pseudo_bitmap
for pseudo got a hard reg.
Index: lra-assigns.c
===================================================================
--- lra-assigns.c (revision 186168)
+++ lra-assigns.c (working copy)
@@ -1142,7 +1142,6 @@ assign_by_spills (void)
hard_regno = find_hard_regno_for (regno, &cost, -1);
if (hard_regno >= 0)
{
- bitmap_set_bit (&changed_pseudo_bitmap, regno);
assign_hard_regno (hard_regno, regno);
/* We change allocation for non-reload pseudo on
this iteration -- mark it for invalidation used
Index: lra.c
===================================================================
--- lra.c (revision 186168)
+++ lra.c (working copy)
@@ -828,7 +828,7 @@ collect_non_operand_hard_regs (rtx *x, l
if (GET_MODE_SIZE (mode) < GET_MODE_SIZE (GET_MODE (op)))
{
mode = GET_MODE (op);
- if (GET_MODE_SIZE (mode) >= UNITS_PER_WORD)
+ if (GET_MODE_SIZE (mode) > REGMODE_NATURAL_SIZE (mode))
subreg_p = true;
}
}
@@ -1480,7 +1480,7 @@ add_regs_to_insn_regno_info (lra_insn_re
if (GET_MODE_SIZE (mode) < GET_MODE_SIZE (GET_MODE (x)))
{
mode = GET_MODE (x);
- if (GET_MODE_SIZE (mode) >= UNITS_PER_WORD)
+ if (GET_MODE_SIZE (mode) > REGMODE_NATURAL_SIZE (mode))
subreg_p = true;
}
}
Index: lra.h
===================================================================
--- lra.h (revision 186168)
+++ lra.h (working copy)
@@ -20,6 +20,18 @@ You should have received a copy of the G
along with GCC; see the file COPYING3. If not see
<http://www.gnu.org/licenses/>. */
+/* Return the allocno reg class of REGNO. If it is a reload pseudo,
+ the pseudo should finally get hard register of the allocno
+ class. */
+static inline enum reg_class
+lra_get_allocno_class (int regno)
+{
+ resize_reg_info ();
+ return reg_allocno_class (regno);
+}
+
+extern rtx lra_create_new_reg (enum machine_mode, rtx, enum reg_class,
+ const char *);
extern void lra_init_elimination (void);
extern rtx lra_eliminate_regs (rtx, enum machine_mode, rtx);
extern void lra (FILE *);
Index: lra-int.h
===================================================================
--- lra-int.h (revision 186168)
+++ lra-int.h (working copy)
@@ -38,16 +38,6 @@ lra_get_regno_hard_regno (int regno)
return reg_renumber[regno];
}
-/* Return the allocno reg class of REGNO. If it is a reload pseudo,
- the pseudo should finally get hard register of the allocno
- class. */
-static inline enum reg_class
-lra_get_allocno_class (int regno)
-{
- resize_reg_info ();
- return reg_allocno_class (regno);
-}
-
typedef struct lra_live_range *lra_live_range_t;
/* The structure describes program points where a given pseudo lives.
@@ -254,8 +244,6 @@ extern void lra_push_insn_and_update_ins
extern rtx lra_create_new_reg_with_unique_value (enum machine_mode, rtx,
enum reg_class, const char *);
-extern rtx lra_create_new_reg (enum machine_mode, rtx, enum reg_class,
- const char *);
extern void lra_set_regno_unique_value (int);
extern void lra_invalidate_insn_data (rtx);
extern void lra_set_insn_deleted (rtx);
Index: config/mips/mips.c
===================================================================
--- config/mips/mips.c (revision 186168)
+++ config/mips/mips.c (working copy)
@@ -59,6 +59,7 @@ along with GCC; see the file COPYING3.
#include "diagnostic.h"
#include "target-globals.h"
#include "opts.h"
+#include "lra.h"
/* True if X is an UNSPEC wrapper around a SYMBOL_REF or LABEL_REF. */
#define UNSPEC_ADDRESS_P(X) \
@@ -6664,11 +6665,26 @@ mips_expand_fcc_reload (rtx dest, rtx sr
if (MEM_P (src))
src = adjust_address (src, SFmode, 0);
else if (REG_P (src) || GET_CODE (src) == SUBREG)
- src = gen_rtx_REG (SFmode, true_regnum (src));
-
- fp1 = gen_rtx_REG (SFmode, REGNO (scratch));
- fp2 = gen_rtx_REG (SFmode, REGNO (scratch) + MAX_FPRS_PER_FMT);
+ {
+ if (! flag_lra)
+ src = gen_rtx_REG (SFmode, true_regnum (src));
+ else if (GET_MODE (src) != SFmode)
+ src = gen_rtx_SUBREG (SFmode,
+ GET_CODE (src) == SUBREG ? SUBREG_REG (src) : src,
+ 0);
+ }
+ if (flag_lra)
+ {
+ enum reg_class rclass = lra_get_allocno_class (REGNO (scratch));
+ fp1 = lra_create_new_reg (SFmode, NULL_RTX, rclass, "new scratch");
+ fp2 = lra_create_new_reg (SFmode, NULL_RTX, rclass, "zero");
+ }
+ else
+ {
+ fp1 = gen_rtx_REG (SFmode, REGNO (scratch));
+ fp2 = gen_rtx_REG (SFmode, REGNO (scratch) + MAX_FPRS_PER_FMT);
+ }
mips_emit_move (copy_rtx (fp1), src);
mips_emit_move (copy_rtx (fp2), CONST0_RTX (SFmode));
emit_insn (gen_slt_sf (dest, fp2, fp1));