/* Search an insn for pseudo regs that must be in hard regs and are not.
Copyright (C) 1987, 1988, 1989, 1992, 1993, 1994, 1995, 1996, 1997, 1998,
- 1999, 2000, 2001, 2002, 2003, 2004, 2005, 2006, 2007, 2008, 2009
+ 1999, 2000, 2001, 2002, 2003, 2004, 2005, 2006, 2007, 2008, 2009, 2010
Free Software Foundation, Inc.
This file is part of GCC.
#include "system.h"
#include "coretypes.h"
#include "tm.h"
-#include "rtl.h"
+#include "rtl-error.h"
#include "tm_p.h"
#include "insn-config.h"
#include "expr.h"
#include "flags.h"
#include "output.h"
#include "function.h"
-#include "toplev.h"
#include "params.h"
#include "target.h"
#include "ira.h"
/* True if C is a non-empty register class that has too few registers
to be safely used as a reload target class. */
-#define SMALL_REGISTER_CLASS_P(C) \
- (reg_class_size [(C)] == 1 \
- || (reg_class_size [(C)] >= 1 && CLASS_LIKELY_SPILLED_P (C)))
+
+static inline bool
+small_register_class_p (reg_class_t rclass)
+{
+ return (reg_class_size [(int) rclass] == 1
+ || (reg_class_size [(int) rclass] >= 1
+ && targetm.class_likely_spilled_p (rclass)));
+}
\f
/* All reloads of the current insn are recorded here. See reload.h for
static int find_reusable_reload (rtx *, rtx, enum reg_class,
enum reload_type, int, int);
static rtx find_dummy_reload (rtx, rtx, rtx *, rtx *, enum machine_mode,
- enum machine_mode, enum reg_class, int, int);
+ enum machine_mode, reg_class_t, int, int);
static int hard_reg_set_here_p (unsigned int, unsigned int, rtx);
static struct decomposition decompose (rtx);
static int immune_p (rtx, rtx, struct decomposition);
sri.icode = CODE_FOR_nothing;
sri.prev_sri = prev_sri;
- rclass = targetm.secondary_reload (in_p, x, reload_class, reload_mode, &sri);
+ rclass = (enum reg_class) targetm.secondary_reload (in_p, x, reload_class,
+ reload_mode, &sri);
icode = (enum insn_code) sri.icode;
/* If we don't need any secondary registers, done. */
|| (! in_p && rld[s_reload].secondary_out_reload == t_reload))
&& ((in_p && rld[s_reload].secondary_in_icode == t_icode)
|| (! in_p && rld[s_reload].secondary_out_icode == t_icode))
- && (SMALL_REGISTER_CLASS_P (rclass)
+ && (small_register_class_p (rclass)
|| targetm.small_register_classes_for_mode_p (VOIDmode))
&& MERGABLE_RELOADS (secondary_type, rld[s_reload].when_needed,
opnum, rld[s_reload].opnum))
/* If a secondary reload is needed, return its class. If both an intermediate
register and a scratch register is needed, we return the class of the
intermediate register. */
-enum reg_class
-secondary_reload_class (bool in_p, enum reg_class rclass,
- enum machine_mode mode, rtx x)
+reg_class_t
+secondary_reload_class (bool in_p, reg_class_t rclass, enum machine_mode mode,
+ rtx x)
{
enum insn_code icode;
secondary_reload_info sri;
sri.icode = CODE_FOR_nothing;
sri.prev_sri = NULL;
- rclass = targetm.secondary_reload (in_p, x, rclass, mode, &sri);
+ rclass
+ = (enum reg_class) targetm.secondary_reload (in_p, x, rclass, mode, &sri);
icode = (enum insn_code) sri.icode;
/* If there are no secondary reloads at all, we return NO_REGS.
if (bad || !good)
continue;
- cost = REGISTER_MOVE_COST (outer, (enum reg_class) rclass, dest_class);
+ cost = register_move_cost (outer, (enum reg_class) rclass, dest_class);
if ((reg_class_size[rclass] > best_size
&& (best_cost < 0 || best_cost >= cost))
{
best_class = (enum reg_class) rclass;
best_size = reg_class_size[rclass];
- best_cost = REGISTER_MOVE_COST (outer, (enum reg_class) rclass,
+ best_cost = register_move_cost (outer, (enum reg_class) rclass,
dest_class);
}
}
|| (out != 0 && MATCHES (rld[i].out, out)
&& (in == 0 || rld[i].in == 0 || MATCHES (rld[i].in, in))))
&& (rld[i].out == 0 || ! earlyclobber_operand_p (rld[i].out))
- && (SMALL_REGISTER_CLASS_P (rclass)
+ && (small_register_class_p (rclass)
|| targetm.small_register_classes_for_mode_p (VOIDmode))
&& MERGABLE_RELOADS (type, rld[i].when_needed, opnum, rld[i].opnum))
return i;
&& GET_RTX_CLASS (GET_CODE (in)) == RTX_AUTOINC
&& MATCHES (XEXP (in, 0), rld[i].in)))
&& (rld[i].out == 0 || ! earlyclobber_operand_p (rld[i].out))
- && (SMALL_REGISTER_CLASS_P (rclass)
+ && (small_register_class_p (rclass)
|| targetm.small_register_classes_for_mode_p (VOIDmode))
&& MERGABLE_RELOADS (type, rld[i].when_needed,
opnum, rld[i].opnum))
/* Narrow down the class of register wanted if that is
desirable on this machine for efficiency. */
{
- enum reg_class preferred_class = rclass;
+ reg_class_t preferred_class = rclass;
if (in != 0)
- preferred_class = PREFERRED_RELOAD_CLASS (in, rclass);
+ preferred_class = targetm.preferred_reload_class (in, rclass);
- /* Output reloads may need analogous treatment, different in detail. */
-#ifdef PREFERRED_OUTPUT_RELOAD_CLASS
+ /* Output reloads may need analogous treatment, different in detail. */
if (out != 0)
- preferred_class = PREFERRED_OUTPUT_RELOAD_CLASS (out, preferred_class);
-#endif
+ preferred_class
+ = targetm.preferred_output_reload_class (out, preferred_class);
/* Discard what the target said if we cannot do it. */
if (preferred_class != NO_REGS
|| (optional && type == RELOAD_FOR_OUTPUT))
- rclass = preferred_class;
+ rclass = (enum reg_class) preferred_class;
}
/* Make sure we use a class that can handle the actual pseudo
static rtx
find_dummy_reload (rtx real_in, rtx real_out, rtx *inloc, rtx *outloc,
enum machine_mode inmode, enum machine_mode outmode,
- enum reg_class rclass, int for_real, int earlyclobber)
+ reg_class_t rclass, int for_real, int earlyclobber)
{
rtx in = real_in;
rtx out = real_out;
/* Narrow down the reg class, the same way push_reload will;
otherwise we might find a dummy now, but push_reload won't. */
{
- enum reg_class preferred_class = PREFERRED_RELOAD_CLASS (in, rclass);
+ reg_class_t preferred_class = targetm.preferred_reload_class (in, rclass);
if (preferred_class != NO_REGS)
- rclass = preferred_class;
+ rclass = (enum reg_class) preferred_class;
}
/* See if OUT will do. */
enum reload_usage { RELOAD_READ, RELOAD_READ_WRITE, RELOAD_WRITE } modified[MAX_RECOG_OPERANDS];
int no_input_reloads = 0, no_output_reloads = 0;
int n_alternatives;
- enum reg_class this_alternative[MAX_RECOG_OPERANDS];
+ reg_class_t this_alternative[MAX_RECOG_OPERANDS];
char this_alternative_match_win[MAX_RECOG_OPERANDS];
char this_alternative_win[MAX_RECOG_OPERANDS];
char this_alternative_offmemok[MAX_RECOG_OPERANDS];
char this_alternative_earlyclobber[MAX_RECOG_OPERANDS];
int this_alternative_matches[MAX_RECOG_OPERANDS];
int swapped;
- int goal_alternative[MAX_RECOG_OPERANDS];
+ reg_class_t goal_alternative[MAX_RECOG_OPERANDS];
int this_alternative_number;
int goal_alternative_number = 0;
int operand_reloadnum[MAX_RECOG_OPERANDS];
char goal_alternative_earlyclobber[MAX_RECOG_OPERANDS];
int goal_alternative_swapped;
int best;
- int best_small_class_operands_num;
int commutative;
char operands_match[MAX_RECOG_OPERANDS][MAX_RECOG_OPERANDS];
rtx substed_operand[MAX_RECOG_OPERANDS];
&& REGNO (SET_DEST (body)) < FIRST_PSEUDO_REGISTER
&& REG_P (SET_SRC (body))
&& REGNO (SET_SRC (body)) < FIRST_PSEUDO_REGISTER
- && REGISTER_MOVE_COST (GET_MODE (SET_SRC (body)),
+ && register_move_cost (GET_MODE (SET_SRC (body)),
REGNO_REG_CLASS (REGNO (SET_SRC (body))),
REGNO_REG_CLASS (REGNO (SET_DEST (body)))) == 2)
return 0;
all the operands together against the register constraints. */
best = MAX_RECOG_OPERANDS * 2 + 600;
- best_small_class_operands_num = 0;
swapped = 0;
goal_alternative_swapped = 0;
/* If this operand could be handled with a reg,
and some reg is allowed, then this operand can be handled. */
- if (winreg && this_alternative[i] != NO_REGS)
+ if (winreg && this_alternative[i] != NO_REGS
+ && (win || !class_only_fixed_regs[this_alternative[i]]))
badop = 0;
/* Record which operands fit this alternative. */
precisely the same as in the code below that calls
force_const_mem. */
if (CONST_POOL_OK_P (operand)
- && ((PREFERRED_RELOAD_CLASS (operand, this_alternative[i])
+ && ((targetm.preferred_reload_class (operand,
+ this_alternative[i])
== NO_REGS)
|| no_input_reloads)
&& operand_mode[i] != VOIDmode)
if (! CONSTANT_P (operand) && this_alternative[i] != NO_REGS)
{
- if (PREFERRED_RELOAD_CLASS (operand, this_alternative[i])
+ if (targetm.preferred_reload_class (operand, this_alternative[i])
== NO_REGS)
reject = 600;
-#ifdef PREFERRED_OUTPUT_RELOAD_CLASS
if (operand_type[i] == RELOAD_FOR_OUTPUT
- && (PREFERRED_OUTPUT_RELOAD_CLASS (operand,
- this_alternative[i])
+ && (targetm.preferred_output_reload_class (operand,
+ this_alternative[i])
== NO_REGS))
reject = 600;
-#endif
}
/* We prefer to reload pseudos over reloading other things,
&& this_alternative[i] != NO_REGS
&& GET_MODE_SIZE (operand_mode[i]) <= UNITS_PER_WORD
&& reg_class_size [(int) preferred_class[i]] > 0
- && ! SMALL_REGISTER_CLASS_P (preferred_class[i]))
+ && ! small_register_class_p (preferred_class[i]))
{
if (! reg_class_subset_p (this_alternative[i],
preferred_class[i]))
{
/* If the output is in a non-empty few-regs class,
it's costly to reload it, so reload the input instead. */
- if (SMALL_REGISTER_CLASS_P (this_alternative[i])
+ if (small_register_class_p (this_alternative[i])
&& (REG_P (recog_data.operand[j])
|| GET_CODE (recog_data.operand[j]) == SUBREG))
{
record it as the chosen goal for reloading. */
if (! bad)
{
- bool change_p = false;
- int small_class_operands_num = 0;
-
- if (best >= losers)
- {
- for (i = 0; i < noperands; i++)
- small_class_operands_num
- += SMALL_REGISTER_CLASS_P (this_alternative[i]) ? 1 : 0;
- if (best > losers
- || (best == losers
- /* If the cost of the reloads is the same,
- prefer alternative which requires minimal
- number of small register classes for the
- operands. This improves chances of reloads
- for insn requiring small register
- classes. */
- && (small_class_operands_num
- < best_small_class_operands_num)))
- change_p = true;
- }
- if (change_p)
+ if (best > losers)
{
for (i = 0; i < noperands; i++)
{
}
goal_alternative_swapped = swapped;
best = losers;
- best_small_class_operands_num = small_class_operands_num;
goal_alternative_number = this_alternative_number;
goal_earlyclobber = this_earlyclobber;
}
}
if (CONST_POOL_OK_P (op)
- && ((PREFERRED_RELOAD_CLASS (op,
- (enum reg_class) goal_alternative[i])
+ && ((targetm.preferred_reload_class (op, goal_alternative[i])
== NO_REGS)
|| no_input_reloads)
&& mode != VOIDmode)
/* If this is only for an output, the optional reload would not
actually cause us to use a register now, just note that
something is stored here. */
- && ((enum reg_class) goal_alternative[i] != NO_REGS
+ && (goal_alternative[i] != NO_REGS
|| modified[i] == RELOAD_WRITE)
&& ! no_input_reloads
/* An optional output reload might allow to delete INSN later.
if ((MEM_P (operand)
|| (REG_P (operand)
&& REGNO (operand) >= FIRST_PSEUDO_REGISTER))
- && ((enum reg_class) goal_alternative[goal_alternative_matches[i]]
- != NO_REGS))
+ && (goal_alternative[goal_alternative_matches[i]] != NO_REGS))
operand_reloadnum[i] = operand_reloadnum[goal_alternative_matches[i]]
= push_reload (recog_data.operand[goal_alternative_matches[i]],
recog_data.operand[i],
if ((regno_ok_for_base_p (REGNO (operand), mode, inner_code,
GET_CODE (addend))
|| operand == frame_pointer_rtx
-#if FRAME_POINTER_REGNUM != HARD_FRAME_POINTER_REGNUM
+#if !HARD_FRAME_POINTER_IS_FRAME_POINTER
|| operand == hard_frame_pointer_rtx
#endif
#if FRAME_POINTER_REGNUM != ARG_POINTER_REGNUM
rtx equiv = (MEM_P (XEXP (x, 0))
? XEXP (x, 0)
: reg_equiv_mem[regno]);
- int icode
- = (int) optab_handler (add_optab, GET_MODE (x))->insn_code;
+ int icode = (int) optab_handler (add_optab, GET_MODE (x));
if (insn && NONJUMP_INSN_P (insn) && equiv
&& memory_operand (equiv, GET_MODE (equiv))
#ifdef HAVE_cc0
{
if (CONSTANT_P (x)
&& (! LEGITIMATE_CONSTANT_P (x)
- || PREFERRED_RELOAD_CLASS (x, rclass) == NO_REGS))
+ || targetm.preferred_reload_class (x, rclass) == NO_REGS))
{
x = force_const_mem (mode, x);
find_reloads_address (mode, &x, XEXP (x, 0), &XEXP (x, 0),
else if (GET_CODE (x) == PLUS
&& CONSTANT_P (XEXP (x, 1))
&& (! LEGITIMATE_CONSTANT_P (XEXP (x, 1))
- || PREFERRED_RELOAD_CLASS (XEXP (x, 1), rclass) == NO_REGS))
+ || targetm.preferred_reload_class (XEXP (x, 1), rclass)
+ == NO_REGS))
{
rtx tem;