#include "target.h"
#include "ira.h"
-/* True if X is a constant that can be forced into the constant pool. */
-#define CONST_POOL_OK_P(X) \
- (CONSTANT_P (X) \
+/* True if X is a constant that can be forced into the constant pool.
+ MODE is the mode of the operand, or VOIDmode if not known. */
+#define CONST_POOL_OK_P(MODE, X) \
+ ((MODE) != VOIDmode \
+ && CONSTANT_P (X) \
&& GET_CODE (X) != HIGH \
- && !targetm.cannot_force_const_mem (X))
+ && !targetm.cannot_force_const_mem (MODE, X))
/* True if C is a non-empty register class that has too few registers
to be safely used as a reload target class. */
{
rtx it;
- for (it = reg_equiv_alt_mem_list [regno]; it; it = XEXP (it, 1))
+ for (it = reg_equiv_alt_mem_list (regno); it; it = XEXP (it, 1))
if (rtx_equal_p (XEXP (it, 0), mem))
return;
- reg_equiv_alt_mem_list [regno]
+ reg_equiv_alt_mem_list (regno)
= alloc_EXPR_LIST (REG_EQUIV, mem,
- reg_equiv_alt_mem_list [regno]);
+ reg_equiv_alt_mem_list (regno));
}
\f
/* Determine if any secondary reloads are needed for loading (if IN_P is
might be sensitive to the form of the MEM. */
if (REG_P (x) && REGNO (x) >= FIRST_PSEUDO_REGISTER
- && reg_equiv_mem[REGNO (x)] != 0)
- x = reg_equiv_mem[REGNO (x)];
+ && reg_equiv_mem (REGNO (x)))
+ x = reg_equiv_mem (REGNO (x));
sri.icode = CODE_FOR_nothing;
sri.prev_sri = prev_sri;
gcc_assert (regno < FIRST_PSEUDO_REGISTER
|| reg_renumber[regno] >= 0
- || reg_equiv_constant[regno] == NULL_RTX);
+ || reg_equiv_constant (regno) == NULL_RTX);
}
/* reg_equiv_constant only contains constants which are obviously
gcc_assert (regno < FIRST_PSEUDO_REGISTER
|| reg_renumber[regno] >= 0
- || reg_equiv_constant[regno] == NULL_RTX);
+ || reg_equiv_constant (regno) == NULL_RTX);
}
/* If we have a read-write operand with an address side-effect,
&& REG_P (reg)
&& (GET_MODE_SIZE (GET_MODE (reg))
>= GET_MODE_SIZE (GET_MODE (op)))
- && reg_equiv_constant[REGNO (reg)] == 0)
+ && reg_equiv_constant (REGNO (reg)) == 0)
set_unique_reg_note (emit_insn_before (gen_rtx_USE (VOIDmode, reg),
insn),
- REG_EQUAL, reg_equiv_memory_loc[REGNO (reg)]);
+ REG_EQUAL, reg_equiv_memory_loc (REGNO (reg)));
substed_operand[i] = recog_data.operand[i] = op;
}
that we don't try to replace it in the insn in which it
is being set. */
int regno = REGNO (recog_data.operand[i]);
- if (reg_equiv_constant[regno] != 0
+ if (reg_equiv_constant (regno) != 0
&& (set == 0 || &SET_DEST (set) != recog_data.operand_loc[i]))
{
/* Record the existing mode so that the check if constants are
operand_mode[i] = GET_MODE (recog_data.operand[i]);
substed_operand[i] = recog_data.operand[i]
- = reg_equiv_constant[regno];
+ = reg_equiv_constant (regno);
}
- if (reg_equiv_memory_loc[regno] != 0
- && (reg_equiv_address[regno] != 0 || num_not_at_initial_offset))
+ if (reg_equiv_memory_loc (regno) != 0
+ && (reg_equiv_address (regno) != 0 || num_not_at_initial_offset))
/* We need not give a valid is_set_dest argument since the case
of a constant equivalence was checked above. */
substed_operand[i] = recog_data.operand[i]
&& REGNO (operand) >= FIRST_PSEUDO_REGISTER
&& reg_renumber[REGNO (operand)] < 0))
win = 1;
- if (CONST_POOL_OK_P (operand))
+ if (CONST_POOL_OK_P (operand_mode[i], operand))
badop = 0;
constmemok = 1;
break;
to override the handling of reg_equiv_address. */
&& !(REG_P (XEXP (operand, 0))
&& (ind_levels == 0
- || reg_equiv_address[REGNO (XEXP (operand, 0))] != 0)))
+ || reg_equiv_address (REGNO (XEXP (operand, 0))) != 0)))
win = 1;
break;
loading it into a register; hence it will be
offsettable, but we cannot say that reg_equiv_mem
is offsettable without checking. */
- && ((reg_equiv_mem[REGNO (operand)] != 0
- && offsettable_memref_p (reg_equiv_mem[REGNO (operand)]))
- || (reg_equiv_address[REGNO (operand)] != 0))))
+ && ((reg_equiv_mem (REGNO (operand)) != 0
+ && offsettable_memref_p (reg_equiv_mem (REGNO (operand))))
+ || (reg_equiv_address (REGNO (operand)) != 0))))
win = 1;
- if (CONST_POOL_OK_P (operand)
+ if (CONST_POOL_OK_P (operand_mode[i], operand)
|| MEM_P (operand))
badop = 0;
constmemok = 1;
else if (REG_P (operand)
&& REGNO (operand) >= FIRST_PSEUDO_REGISTER
&& reg_renumber[REGNO (operand)] < 0
- && ((reg_equiv_mem[REGNO (operand)] != 0
- && EXTRA_CONSTRAINT_STR (reg_equiv_mem[REGNO (operand)], c, p))
- || (reg_equiv_address[REGNO (operand)] != 0)))
+ && ((reg_equiv_mem (REGNO (operand)) != 0
+ && EXTRA_CONSTRAINT_STR (reg_equiv_mem (REGNO (operand)), c, p))
+ || (reg_equiv_address (REGNO (operand)) != 0)))
win = 1;
/* If we didn't already win, we can reload
constants via force_const_mem, and other
MEMs by reloading the address like for 'o'. */
- if (CONST_POOL_OK_P (operand)
+ if (CONST_POOL_OK_P (operand_mode[i], operand)
|| MEM_P (operand))
badop = 0;
constmemok = 1;
an early reload pass. Note that the test here is
precisely the same as in the code below that calls
force_const_mem. */
- if (CONST_POOL_OK_P (operand)
+ if (CONST_POOL_OK_P (operand_mode[i], operand)
&& ((targetm.preferred_reload_class (operand,
this_alternative[i])
== NO_REGS)
- || no_input_reloads)
- && operand_mode[i] != VOIDmode)
+ || no_input_reloads))
{
const_to_mem = 1;
if (this_alternative[i] != NO_REGS)
op = XEXP (op, 1);
}
- if (CONST_POOL_OK_P (op)
+ if (CONST_POOL_OK_P (mode, op)
&& ((targetm.preferred_reload_class (op, goal_alternative[i])
== NO_REGS)
- || no_input_reloads)
- && mode != VOIDmode)
+ || no_input_reloads))
{
int this_address_reloaded;
rtx tem = force_const_mem (mode, op);
{
/* This code is duplicated for speed in find_reloads. */
int regno = REGNO (x);
- if (reg_equiv_constant[regno] != 0 && !is_set_dest)
- x = reg_equiv_constant[regno];
+ if (reg_equiv_constant (regno) != 0 && !is_set_dest)
+ x = reg_equiv_constant (regno);
#if 0
/* This creates (subreg (mem...)) which would cause an unnecessary
reload of the mem. */
- else if (reg_equiv_mem[regno] != 0)
- x = reg_equiv_mem[regno];
+ else if (reg_equiv_mem (regno) != 0)
+ x = reg_equiv_mem (regno);
#endif
- else if (reg_equiv_memory_loc[regno]
- && (reg_equiv_address[regno] != 0 || num_not_at_initial_offset))
+ else if (reg_equiv_memory_loc (regno)
+ && (reg_equiv_address (regno) != 0 || num_not_at_initial_offset))
{
rtx mem = make_memloc (x, regno);
- if (reg_equiv_address[regno]
- || ! rtx_equal_p (mem, reg_equiv_mem[regno]))
+ if (reg_equiv_address (regno)
+ || ! rtx_equal_p (mem, reg_equiv_mem (regno)))
{
/* If this is not a toplevel operand, find_reloads doesn't see
this substitution. We have to emit a USE of the pseudo so
if (regno >= FIRST_PSEUDO_REGISTER
&& reg_renumber[regno] < 0
- && reg_equiv_constant[regno] != 0)
+ && reg_equiv_constant (regno) != 0)
{
tem =
- simplify_gen_subreg (GET_MODE (x), reg_equiv_constant[regno],
+ simplify_gen_subreg (GET_MODE (x), reg_equiv_constant (regno),
GET_MODE (SUBREG_REG (x)), SUBREG_BYTE (x));
gcc_assert (tem);
- if (CONSTANT_P (tem) && !LEGITIMATE_CONSTANT_P (tem))
+ if (CONSTANT_P (tem)
+ && !targetm.legitimate_constant_p (GET_MODE (x), tem))
{
tem = force_const_mem (GET_MODE (x), tem);
i = find_reloads_address (GET_MODE (tem), &tem, XEXP (tem, 0),
&& (GET_MODE_SIZE (GET_MODE (x))
<= GET_MODE_SIZE (GET_MODE (SUBREG_REG (x))))
#endif
- && (reg_equiv_address[regno] != 0
- || (reg_equiv_mem[regno] != 0
+ && (reg_equiv_address (regno) != 0
+ || (reg_equiv_mem (regno) != 0
&& (! strict_memory_address_addr_space_p
- (GET_MODE (x), XEXP (reg_equiv_mem[regno], 0),
- MEM_ADDR_SPACE (reg_equiv_mem[regno]))
- || ! offsettable_memref_p (reg_equiv_mem[regno])
+ (GET_MODE (x), XEXP (reg_equiv_mem (regno), 0),
+ MEM_ADDR_SPACE (reg_equiv_mem (regno)))
+ || ! offsettable_memref_p (reg_equiv_mem (regno))
|| num_not_at_initial_offset))))
x = find_reloads_subreg_address (x, 1, opnum, type, ind_levels,
insn, address_reloaded);
/* We must rerun eliminate_regs, in case the elimination
offsets have changed. */
rtx tem
- = XEXP (eliminate_regs (reg_equiv_memory_loc[regno], VOIDmode, NULL_RTX),
+ = XEXP (eliminate_regs (reg_equiv_memory_loc (regno), VOIDmode, NULL_RTX),
0);
/* If TEM might contain a pseudo, we must copy it to avoid
if (rtx_varies_p (tem, 0))
tem = copy_rtx (tem);
- tem = replace_equiv_address_nv (reg_equiv_memory_loc[regno], tem);
+ tem = replace_equiv_address_nv (reg_equiv_memory_loc (regno), tem);
tem = adjust_address_nv (tem, GET_MODE (ad), 0);
/* Copy the result if it's still the same as the equivalence, to avoid
modifying it when we do the substitution for the reload. */
- if (tem == reg_equiv_memory_loc[regno])
+ if (tem == reg_equiv_memory_loc (regno))
tem = copy_rtx (tem);
return tem;
}
{
regno = REGNO (ad);
- if (reg_equiv_constant[regno] != 0)
+ if (reg_equiv_constant (regno) != 0)
{
- find_reloads_address_part (reg_equiv_constant[regno], loc,
+ find_reloads_address_part (reg_equiv_constant (regno), loc,
base_reg_class (mode, MEM, SCRATCH),
GET_MODE (ad), opnum, type, ind_levels);
return 1;
}
- tem = reg_equiv_memory_loc[regno];
+ tem = reg_equiv_memory_loc (regno);
if (tem != 0)
{
- if (reg_equiv_address[regno] != 0 || num_not_at_initial_offset)
+ if (reg_equiv_address (regno) != 0 || num_not_at_initial_offset)
{
tem = make_memloc (ad, regno);
if (! strict_memory_address_addr_space_p (GET_MODE (tem),
in the final reload pass. */
if (replace_reloads
&& num_not_at_initial_offset
- && ! rtx_equal_p (tem, reg_equiv_mem[regno]))
+ && ! rtx_equal_p (tem, reg_equiv_mem (regno)))
{
*loc = tem;
/* We mark the USE with QImode so that we
if (GET_CODE (ad) == PLUS
&& CONST_INT_P (XEXP (ad, 1))
&& REG_P (XEXP (ad, 0))
- && reg_equiv_constant[REGNO (XEXP (ad, 0))] == 0)
+ && reg_equiv_constant (REGNO (XEXP (ad, 0))) == 0)
return 0;
subst_reg_equivs_changed = 0;
{
int regno = REGNO (ad);
- if (reg_equiv_constant[regno] != 0)
+ if (reg_equiv_constant (regno) != 0)
{
subst_reg_equivs_changed = 1;
- return reg_equiv_constant[regno];
+ return reg_equiv_constant (regno);
}
- if (reg_equiv_memory_loc[regno] && num_not_at_initial_offset)
+ if (reg_equiv_memory_loc (regno) && num_not_at_initial_offset)
{
rtx mem = make_memloc (ad, regno);
- if (! rtx_equal_p (mem, reg_equiv_mem[regno]))
+ if (! rtx_equal_p (mem, reg_equiv_mem (regno)))
{
subst_reg_equivs_changed = 1;
/* We mark the USE with QImode so that we recognize it
if (REG_P (op0)
&& (regno = REGNO (op0)) >= FIRST_PSEUDO_REGISTER
&& reg_renumber[regno] < 0
- && reg_equiv_constant[regno] != 0)
- op0 = reg_equiv_constant[regno];
+ && reg_equiv_constant (regno) != 0)
+ op0 = reg_equiv_constant (regno);
else if (REG_P (op1)
&& (regno = REGNO (op1)) >= FIRST_PSEUDO_REGISTER
&& reg_renumber[regno] < 0
- && reg_equiv_constant[regno] != 0)
- op1 = reg_equiv_constant[regno];
+ && reg_equiv_constant (regno) != 0)
+ op1 = reg_equiv_constant (regno);
else if (GET_CODE (op0) == PLUS
&& (tem = subst_indexed_address (op0)) != op0)
op0 = tem;
/* A register that is incremented cannot be constant! */
gcc_assert (regno < FIRST_PSEUDO_REGISTER
- || reg_equiv_constant[regno] == 0);
+ || reg_equiv_constant (regno) == 0);
/* Handle a register that is equivalent to a memory location
which cannot be addressed directly. */
- if (reg_equiv_memory_loc[regno] != 0
- && (reg_equiv_address[regno] != 0
+ if (reg_equiv_memory_loc (regno) != 0
+ && (reg_equiv_address (regno) != 0
|| num_not_at_initial_offset))
{
rtx tem = make_memloc (XEXP (x, 0), regno);
- if (reg_equiv_address[regno]
- || ! rtx_equal_p (tem, reg_equiv_mem[regno]))
+ if (reg_equiv_address (regno)
+ || ! rtx_equal_p (tem, reg_equiv_mem (regno)))
{
rtx orig = tem;
/* A register that is incremented cannot be constant! */
gcc_assert (regno < FIRST_PSEUDO_REGISTER
- || reg_equiv_constant[regno] == 0);
+ || reg_equiv_constant (regno) == 0);
/* Handle a register that is equivalent to a memory location
which cannot be addressed directly. */
- if (reg_equiv_memory_loc[regno] != 0
- && (reg_equiv_address[regno] != 0 || num_not_at_initial_offset))
+ if (reg_equiv_memory_loc (regno) != 0
+ && (reg_equiv_address (regno) != 0 || num_not_at_initial_offset))
{
rtx tem = make_memloc (XEXP (x, 0), regno);
- if (reg_equiv_address[regno]
- || ! rtx_equal_p (tem, reg_equiv_mem[regno]))
+ if (reg_equiv_address (regno)
+ || ! rtx_equal_p (tem, reg_equiv_mem (regno)))
{
rtx orig = tem;
Also don't do this if we can probably update x directly. */
rtx equiv = (MEM_P (XEXP (x, 0))
? XEXP (x, 0)
- : reg_equiv_mem[regno]);
+ : reg_equiv_mem (regno));
enum insn_code icode = optab_handler (add_optab, GET_MODE (x));
if (insn && NONJUMP_INSN_P (insn) && equiv
&& memory_operand (equiv, GET_MODE (equiv))
{
int regno = REGNO (x);
- if (reg_equiv_constant[regno] != 0)
+ if (reg_equiv_constant (regno) != 0)
{
- find_reloads_address_part (reg_equiv_constant[regno], loc,
+ find_reloads_address_part (reg_equiv_constant (regno), loc,
context_reg_class,
GET_MODE (x), opnum, type, ind_levels);
return 1;
#if 0 /* This might screw code in reload1.c to delete prior output-reload
that feeds this insn. */
- if (reg_equiv_mem[regno] != 0)
+ if (reg_equiv_mem (regno) != 0)
{
- push_reload (reg_equiv_mem[regno], NULL_RTX, loc, (rtx*) 0,
+ push_reload (reg_equiv_mem (regno), NULL_RTX, loc, (rtx*) 0,
context_reg_class,
GET_MODE (x), VOIDmode, 0, 0, opnum, type);
return 1;
}
#endif
- if (reg_equiv_memory_loc[regno]
- && (reg_equiv_address[regno] != 0 || num_not_at_initial_offset))
+ if (reg_equiv_memory_loc (regno)
+ && (reg_equiv_address (regno) != 0 || num_not_at_initial_offset))
{
rtx tem = make_memloc (x, regno);
- if (reg_equiv_address[regno] != 0
- || ! rtx_equal_p (tem, reg_equiv_mem[regno]))
+ if (reg_equiv_address (regno) != 0
+ || ! rtx_equal_p (tem, reg_equiv_mem (regno)))
{
x = tem;
find_reloads_address (GET_MODE (x), &x, XEXP (x, 0),
enum reload_type type, int ind_levels)
{
if (CONSTANT_P (x)
- && (! LEGITIMATE_CONSTANT_P (x)
+ && (!targetm.legitimate_constant_p (mode, x)
|| targetm.preferred_reload_class (x, rclass) == NO_REGS))
{
x = force_const_mem (mode, x);
else if (GET_CODE (x) == PLUS
&& CONSTANT_P (XEXP (x, 1))
- && (! LEGITIMATE_CONSTANT_P (XEXP (x, 1))
+ && (!targetm.legitimate_constant_p (GET_MODE (x), XEXP (x, 1))
|| targetm.preferred_reload_class (XEXP (x, 1), rclass)
== NO_REGS))
{
int regno = REGNO (SUBREG_REG (x));
int reloaded = 0;
- if (reg_equiv_memory_loc[regno])
+ if (reg_equiv_memory_loc (regno))
{
/* If the address is not directly addressable, or if the address is not
offsettable, then it must be replaced. */
if (! force_replace
- && (reg_equiv_address[regno]
- || ! offsettable_memref_p (reg_equiv_mem[regno])))
+ && (reg_equiv_address (regno)
+ || ! offsettable_memref_p (reg_equiv_mem (regno))))
force_replace = 1;
if (force_replace || num_not_at_initial_offset)
/* If the address changes because of register elimination, then
it must be replaced. */
if (force_replace
- || ! rtx_equal_p (tem, reg_equiv_mem[regno]))
+ || ! rtx_equal_p (tem, reg_equiv_mem (regno)))
{
unsigned outer_size = GET_MODE_SIZE (GET_MODE (x));
unsigned inner_size = GET_MODE_SIZE (GET_MODE (SUBREG_REG (x)));
If find_reloads_address already completed replaced
the address, there is nothing further to do. */
if (reloaded == 0
- && reg_equiv_mem[regno] != 0
+ && reg_equiv_mem (regno) != 0
&& !strict_memory_address_addr_space_p
- (GET_MODE (x), XEXP (reg_equiv_mem[regno], 0),
- MEM_ADDR_SPACE (reg_equiv_mem[regno])))
+ (GET_MODE (x), XEXP (reg_equiv_mem (regno), 0),
+ MEM_ADDR_SPACE (reg_equiv_mem (regno))))
{
push_reload (XEXP (tem, 0), NULL_RTX, &XEXP (tem, 0), (rtx*) 0,
base_reg_class (GET_MODE (tem), MEM, SCRATCH),
for (check_regno = 0; check_regno < max_regno; check_regno++)
{
#define CHECK_MODF(ARRAY) \
- gcc_assert (!ARRAY[check_regno] \
+ gcc_assert (!VEC_index (reg_equivs_t, reg_equivs, check_regno).ARRAY \
|| !loc_mentioned_in_p (r->where, \
- ARRAY[check_regno]))
+ VEC_index (reg_equivs_t, reg_equivs, check_regno).ARRAY))
- CHECK_MODF (reg_equiv_constant);
- CHECK_MODF (reg_equiv_memory_loc);
- CHECK_MODF (reg_equiv_address);
- CHECK_MODF (reg_equiv_mem);
+ CHECK_MODF (equiv_constant);
+ CHECK_MODF (equiv_memory_loc);
+ CHECK_MODF (equiv_address);
+ CHECK_MODF (equiv_mem);
#undef CHECK_MODF
}
#endif /* DEBUG_RELOAD */
X must therefore either be a constant or be in memory. */
if (r >= FIRST_PSEUDO_REGISTER)
{
- if (reg_equiv_memory_loc[r])
+ if (reg_equiv_memory_loc (r))
return refers_to_regno_for_reload_p (regno, endregno,
- reg_equiv_memory_loc[r],
+ reg_equiv_memory_loc (r),
(rtx*) 0);
- gcc_assert (reg_equiv_constant[r] || reg_equiv_invariant[r]);
+ gcc_assert (reg_equiv_constant (r) || reg_equiv_invariant (r));
return 0;
}
if (regno >= FIRST_PSEUDO_REGISTER)
{
- if (reg_equiv_memory_loc[regno])
+ if (reg_equiv_memory_loc (regno))
return refers_to_mem_for_reload_p (in);
- gcc_assert (reg_equiv_constant[regno]);
+ gcc_assert (reg_equiv_constant (regno));
return 0;
}
if (REG_P (x))
return (REGNO (x) >= FIRST_PSEUDO_REGISTER
- && reg_equiv_memory_loc[REGNO (x)]);
+ && reg_equiv_memory_loc (REGNO (x)));
fmt = GET_RTX_FORMAT (GET_CODE (x));
for (i = GET_RTX_LENGTH (GET_CODE (x)) - 1; i >= 0; i--)
&& ! push_operand (dest, GET_MODE (dest)))
return 0;
else if (MEM_P (dest) && regno >= FIRST_PSEUDO_REGISTER
- && reg_equiv_memory_loc[regno] != 0)
+ && reg_equiv_memory_loc (regno) != 0)
return 0;
else if (need_stable_sp && push_operand (dest, GET_MODE (dest)))
return 0;
&& ! push_operand (dest, GET_MODE (dest)))
return 0;
else if (MEM_P (dest) && regno >= FIRST_PSEUDO_REGISTER
- && reg_equiv_memory_loc[regno] != 0)
+ && reg_equiv_memory_loc (regno) != 0)
return 0;
else if (need_stable_sp
&& push_operand (dest, GET_MODE (dest)))