+2011-03-30 Jeff Law <law@redhat.com>
+
+ * reload.h (reg_equiv_constant): Move into new structure reg_equivs,
+ define accessor macro.
+ (reg_equiv_invariant, reg_equiv_memory_loc): Likewise.
+ (reg_equiv_address, reg_equiv_mem, reg_equiv_alt_mem_list): Likewise.
+ (reg_equiv_init): Likewise.
+ (reg_equivs_size): New variable.
+ (reg_equiv_init_size): Remove.
+ (allocate_initial_values): Move prototype to here from....
+ * integrate.h (allocate_initial_values): Remove prototype.
+ * integrate.c: Include reload.h.
+ (allocate_initial_values): Corresponding changes.
+ * ira.c (find_reg_equiv_invariant_cost): Corresponding changes.
+ (fix_reg_equiv_init, no_equiv): Corresponding changes.
+ (update_equiv_regs): Corresponding changes.
+ (ira): Corresponding changes.
+ * reload.c (push_reg_equiv_alt_mem): Corresponding changes.
+ (push_secondary_reload): Corresponding changes.
+ (push_reload, find_reloads, find_reloads_toplev): Corresponding changes.
+ (make_memloc, find_reloads_address): Corresponding changes.
+ (subst_reg_equivs, subst_indexed_address): Corresponding changes.
+ (find_reloads_address_1): Corresponding changes.
+ (find_reloads_subreg_address, subst_reloads): Corresponding changes.
+ (refers_to_regno_for_reload_p): Corresponding changes.
+ (reg_overlap_mentioned_for_reload_p): Corresponding changes.
+ (refers_to_mem_for_reload_p, find_equiv_reg): Corresponding changes.
+ * reload1.c: Include ggc.h.
+ (grow_reg_equivs): New function.
+ (replace_pseudos_in, reload): Corresponding changes.
+ (calculate_needs_all_insns, alter_regs): Corresponding changes.
+ (eliminate_regs_1, elimination_effects): Corresponding changes.
+ (emit_input_reload_insns, emit_output_reload_insns): Likewise.
+ (delete_output_reload): Likewise.
+ * caller-save.c (mark_referenced_regs): Corresponding changes.
+ * alpha/alpha.c (resolve_reload_operand): Corresponding changes.
+ * frv/predicates.md (frv_load_operand): Corresponding changes.
+ * microblaze/microblaze.c (double_memory_operand): Corresponding
+ changes.
+ * avr/avr.h (LEGITIMIZE_RELOAD_ADDRESS): Corresponding changes.
+ * xtensa/xtensa.c (fixup_subreg_mem): Corresponding changes.
+ * mn10300/mn10300.c (mn10300_secondary_reload): Corresponding
+ changes.
+ * m68k/m68k.c (emit_move_sequence): Corresponding changes.
+ * arm/arm.c (arm_reload_in_hi, arm_reload_out_hi): Corresponding
+ changes.
+ * pa/pa.c (emit_move_sequence): Corresponding changes.
+ * vax/vax.c (nonindexed_address_p): Corresponding changes.
+
2011-03-30 Richard Sandiford <richard.sandiford@linaro.org>
PR target/47551
/* If this is a pseudo that did not get a hard register, scan its
memory location, since it might involve the use of another
register, which might be saved. */
- else if (reg_equiv_mem[regno] != 0)
- mark_referenced_regs (&XEXP (reg_equiv_mem[regno], 0), mark, arg);
- else if (reg_equiv_address[regno] != 0)
- mark_referenced_regs (®_equiv_address[regno], mark, arg);
+ else if (reg_equiv_mem (regno) != 0)
+ mark_referenced_regs (&XEXP (reg_equiv_mem (regno), 0), mark, arg);
+ else if (reg_equiv_address (regno) != 0)
+ mark_referenced_regs (®_equiv_address (regno), mark, arg);
return;
}
if (REG_P (tmp)
&& REGNO (tmp) >= FIRST_PSEUDO_REGISTER)
{
- op = reg_equiv_memory_loc[REGNO (tmp)];
+ op = reg_equiv_memory_loc (REGNO (tmp));
if (op == 0)
return 0;
}
are two cases here: the first where there is a simple
stack-slot replacement and a second where the stack-slot is
out of range, or is used as a subreg. */
- if (reg_equiv_mem[REGNO (ref)])
+ if (reg_equiv_mem (REGNO (ref)))
{
- ref = reg_equiv_mem[REGNO (ref)];
+ ref = reg_equiv_mem (REGNO (ref));
base = find_replacement (&XEXP (ref, 0));
}
else
/* The slot is out of range, or was dressed up in a SUBREG. */
- base = reg_equiv_address[REGNO (ref)];
+ base = reg_equiv_address (REGNO (ref));
}
else
base = find_replacement (&XEXP (ref, 0));
are two cases here: the first where there is a simple
stack-slot replacement and a second where the stack-slot is
out of range, or is used as a subreg. */
- if (reg_equiv_mem[REGNO (ref)])
+ if (reg_equiv_mem (REGNO (ref)))
{
- ref = reg_equiv_mem[REGNO (ref)];
+ ref = reg_equiv_mem (REGNO (ref));
base = find_replacement (&XEXP (ref, 0));
}
else
/* The slot is out of range, or was dressed up in a SUBREG. */
- base = reg_equiv_address[REGNO (ref)];
+ base = reg_equiv_address (REGNO (ref));
}
else
base = find_replacement (&XEXP (ref, 0));
} \
if (GET_CODE (X) == PLUS \
&& REG_P (XEXP (X, 0)) \
- && reg_equiv_constant[REGNO (XEXP (X, 0))] == 0 \
+ && (reg_equiv_constant (REGNO (XEXP (X, 0))) == 0) \
&& GET_CODE (XEXP (X, 1)) == CONST_INT \
&& INTVAL (XEXP (X, 1)) >= 1) \
{ \
int fit = INTVAL (XEXP (X, 1)) <= (64 - GET_MODE_SIZE (MODE)); \
if (fit) \
{ \
- if (reg_equiv_address[REGNO (XEXP (X, 0))] != 0) \
+ if (reg_equiv_address (REGNO (XEXP (X, 0))) != 0) \
{ \
int regno = REGNO (XEXP (X, 0)); \
rtx mem = make_memloc (X, regno); \
tmp = SUBREG_REG (tmp);
if (GET_CODE (tmp) == REG
&& REGNO (tmp) >= FIRST_PSEUDO_REGISTER)
- op = reg_equiv_memory_loc[REGNO (tmp)];
+ op = reg_equiv_memory_loc (REGNO (tmp));
}
return op && memory_operand (op, mode);
if (scratch_reg
&& reload_in_progress && GET_CODE (operand0) == REG
&& REGNO (operand0) >= FIRST_PSEUDO_REGISTER)
- operand0 = reg_equiv_mem[REGNO (operand0)];
+ operand0 = reg_equiv_mem (REGNO (operand0));
else if (scratch_reg
&& reload_in_progress && GET_CODE (operand0) == SUBREG
&& GET_CODE (SUBREG_REG (operand0)) == REG
/* We must not alter SUBREG_BYTE (operand0) since that would confuse
the code which tracks sets/uses for delete_output_reload. */
rtx temp = gen_rtx_SUBREG (GET_MODE (operand0),
- reg_equiv_mem [REGNO (SUBREG_REG (operand0))],
+ reg_equiv_mem (REGNO (SUBREG_REG (operand0))),
SUBREG_BYTE (operand0));
operand0 = alter_subreg (&temp);
}
if (scratch_reg
&& reload_in_progress && GET_CODE (operand1) == REG
&& REGNO (operand1) >= FIRST_PSEUDO_REGISTER)
- operand1 = reg_equiv_mem[REGNO (operand1)];
+ operand1 = reg_equiv_mem (REGNO (operand1));
else if (scratch_reg
&& reload_in_progress && GET_CODE (operand1) == SUBREG
&& GET_CODE (SUBREG_REG (operand1)) == REG
/* We must not alter SUBREG_BYTE (operand0) since that would confuse
the code which tracks sets/uses for delete_output_reload. */
rtx temp = gen_rtx_SUBREG (GET_MODE (operand1),
- reg_equiv_mem [REGNO (SUBREG_REG (operand1))],
+ reg_equiv_mem (REGNO (SUBREG_REG (operand1))),
SUBREG_BYTE (operand1));
operand1 = alter_subreg (&temp);
}
&& GET_CODE (op) == REG
&& REGNO (op) >= FIRST_PSEUDO_REGISTER
&& reg_renumber[REGNO (op)] < 0
- && reg_equiv_mem[REGNO (op)] != 0
- && double_memory_operand (reg_equiv_mem[REGNO (op)], mode))
+ && reg_equiv_mem (REGNO (op)) != 0
+ && double_memory_operand (reg_equiv_mem (REGNO (op)), mode))
return 1;
return 0;
}
if (xregno >= FIRST_PSEUDO_REGISTER && xregno != INVALID_REGNUM)
{
- addr = reg_equiv_mem [xregno];
+ addr = reg_equiv_mem (xregno);
if (addr)
addr = XEXP (addr, 0);
}
if (scratch_reg
&& reload_in_progress && GET_CODE (operand0) == REG
&& REGNO (operand0) >= FIRST_PSEUDO_REGISTER)
- operand0 = reg_equiv_mem[REGNO (operand0)];
+ operand0 = reg_equiv_mem (REGNO (operand0));
else if (scratch_reg
&& reload_in_progress && GET_CODE (operand0) == SUBREG
&& GET_CODE (SUBREG_REG (operand0)) == REG
/* We must not alter SUBREG_BYTE (operand0) since that would confuse
the code which tracks sets/uses for delete_output_reload. */
rtx temp = gen_rtx_SUBREG (GET_MODE (operand0),
- reg_equiv_mem [REGNO (SUBREG_REG (operand0))],
+ reg_equiv_mem (REGNO (SUBREG_REG (operand0))),
SUBREG_BYTE (operand0));
operand0 = alter_subreg (&temp);
}
if (scratch_reg
&& reload_in_progress && GET_CODE (operand1) == REG
&& REGNO (operand1) >= FIRST_PSEUDO_REGISTER)
- operand1 = reg_equiv_mem[REGNO (operand1)];
+ operand1 = reg_equiv_mem (REGNO (operand1));
else if (scratch_reg
&& reload_in_progress && GET_CODE (operand1) == SUBREG
&& GET_CODE (SUBREG_REG (operand1)) == REG
/* We must not alter SUBREG_BYTE (operand0) since that would confuse
the code which tracks sets/uses for delete_output_reload. */
rtx temp = gen_rtx_SUBREG (GET_MODE (operand1),
- reg_equiv_mem [REGNO (SUBREG_REG (operand1))],
+ reg_equiv_mem (REGNO (SUBREG_REG (operand1))),
SUBREG_BYTE (operand1));
operand1 = alter_subreg (&temp);
}
rtx xfoo0;
if (REG_P (x))
{
- extern rtx *reg_equiv_mem;
if (! reload_in_progress
- || reg_equiv_mem[REGNO (x)] == 0
- || indirectable_address_p (reg_equiv_mem[REGNO (x)], strict, false))
+ || reg_equiv_mem (REGNO (x)) == 0
+ || indirectable_address_p (reg_equiv_mem (REGNO (x)), strict, false))
return true;
}
if (indirectable_constant_address_p (x, false))
{
rtx temp =
gen_rtx_SUBREG (GET_MODE (x),
- reg_equiv_mem [REGNO (SUBREG_REG (x))],
+ reg_equiv_mem (REGNO (SUBREG_REG (x))),
SUBREG_BYTE (x));
x = alter_subreg (&temp);
}
#include "expr.h"
#include "output.h"
#include "recog.h"
+/* For reg_equivs. */
+#include "reload.h"
#include "integrate.h"
#include "except.h"
#include "function.h"
/* If the backend knows where to allocate pseudos for hard
register initial values, register these allocations now. */
void
-allocate_initial_values (rtx *reg_equiv_memory_loc)
+allocate_initial_values (VEC (reg_equivs_t, gc) *reg_equivs)
{
if (targetm.allocate_initial_value)
{
if (x && REG_N_SETS (REGNO (ivs->entries[i].pseudo)) <= 1)
{
if (MEM_P (x))
- reg_equiv_memory_loc[regno] = x;
+ reg_equiv_memory_loc (regno) = x;
else
{
basic_block bb;
extern rtx get_hard_reg_initial_reg (rtx);
/* Called from rest_of_compilation. */
extern unsigned int emit_initial_value_sets (void);
-extern void allocate_initial_values (rtx *);
/* Check whether there's any attribute in a function declaration that
makes the function uninlinable. Returns false if it finds any,
static void
find_reg_equiv_invariant_const (void)
{
- int i;
+ unsigned int i;
bool invariant_p;
rtx list, insn, note, constant, x;
- for (i = FIRST_PSEUDO_REGISTER; i < reg_equiv_init_size; i++)
+ for (i = FIRST_PSEUDO_REGISTER; i < VEC_length (reg_equivs_t, reg_equivs); i++)
{
constant = NULL_RTX;
invariant_p = false;
- for (list = reg_equiv_init[i]; list != NULL_RTX; list = XEXP (list, 1))
+ for (list = reg_equiv_init (i); list != NULL_RTX; list = XEXP (list, 1))
{
insn = XEXP (list, 0);
note = find_reg_note (insn, REG_EQUIV, NULL_RTX);
static void
fix_reg_equiv_init (void)
{
- int max_regno = max_reg_num ();
- int i, new_regno;
+ unsigned int max_regno = max_reg_num ();
+ int i, new_regno, max;
rtx x, prev, next, insn, set;
- if (reg_equiv_init_size < max_regno)
+ if (VEC_length (reg_equivs_t, reg_equivs) < max_regno)
{
- reg_equiv_init = GGC_RESIZEVEC (rtx, reg_equiv_init, max_regno);
- while (reg_equiv_init_size < max_regno)
- reg_equiv_init[reg_equiv_init_size++] = NULL_RTX;
- for (i = FIRST_PSEUDO_REGISTER; i < reg_equiv_init_size; i++)
- for (prev = NULL_RTX, x = reg_equiv_init[i]; x != NULL_RTX; x = next)
+ max = VEC_length (reg_equivs_t, reg_equivs);
+ grow_reg_equivs ();
+ for (i = FIRST_PSEUDO_REGISTER; i < max; i++)
+ for (prev = NULL_RTX, x = reg_equiv_init (i);
+ x != NULL_RTX;
+ x = next)
{
next = XEXP (x, 1);
insn = XEXP (x, 0);
else
{
if (prev == NULL_RTX)
- reg_equiv_init[i] = next;
+ reg_equiv_init (i) = next;
else
XEXP (prev, 1) = next;
- XEXP (x, 1) = reg_equiv_init[new_regno];
- reg_equiv_init[new_regno] = x;
+ XEXP (x, 1) = reg_equiv_init (new_regno);
+ reg_equiv_init (new_regno) = x;
}
}
}
should keep their initialization insns. */
if (reg_equiv[regno].is_arg_equivalence)
return;
- reg_equiv_init[regno] = NULL_RTX;
+ reg_equiv_init (regno) = NULL_RTX;
for (; list; list = XEXP (list, 1))
{
rtx insn = XEXP (list, 0);
recorded_label_ref = 0;
reg_equiv = XCNEWVEC (struct equivalence, max_regno);
- reg_equiv_init = ggc_alloc_cleared_vec_rtx (max_regno);
- reg_equiv_init_size = max_regno;
+ grow_reg_equivs ();
init_alias_analysis ();
/* Record for reload that this is an equivalencing insn. */
if (rtx_equal_p (src, XEXP (note, 0)))
- reg_equiv_init[regno]
- = gen_rtx_INSN_LIST (VOIDmode, insn, reg_equiv_init[regno]);
+ reg_equiv_init (regno)
+ = gen_rtx_INSN_LIST (VOIDmode, insn, reg_equiv_init (regno));
/* Continue normally in case this is a candidate for
replacements. */
/* If we haven't done so, record for reload that this is an
equivalencing insn. */
if (!reg_equiv[regno].is_arg_equivalence)
- reg_equiv_init[regno]
- = gen_rtx_INSN_LIST (VOIDmode, insn, reg_equiv_init[regno]);
+ reg_equiv_init (regno)
+ = gen_rtx_INSN_LIST (VOIDmode, insn, reg_equiv_init (regno));
/* Record whether or not we created a REG_EQUIV note for a LABEL_REF.
We might end up substituting the LABEL_REF for uses of the
{
/* This insn makes the equivalence, not the one initializing
the register. */
- reg_equiv_init[regno]
+ reg_equiv_init (regno)
= gen_rtx_INSN_LIST (VOIDmode, insn, NULL_RTX);
df_notes_rescan (init_insn);
}
reg_equiv[regno].init_insns
= XEXP (reg_equiv[regno].init_insns, 1);
- reg_equiv_init[regno] = NULL_RTX;
+ reg_equiv_init (regno) = NULL_RTX;
bitmap_set_bit (cleared_regs, regno);
}
/* Move the initialization of the register to just before
if (insn == BB_HEAD (bb))
BB_HEAD (bb) = PREV_INSN (insn);
- reg_equiv_init[regno]
+ reg_equiv_init (regno)
= gen_rtx_INSN_LIST (VOIDmode, new_insn, NULL_RTX);
bitmap_set_bit (cleared_regs, regno);
}
if (dump_file)
print_insn_chains (dump_file);
}
-\f
-/* Allocate memory for reg_equiv_memory_loc. */
-static void
-init_reg_equiv_memory_loc (void)
-{
- max_regno = max_reg_num ();
- /* And the reg_equiv_memory_loc array. */
- VEC_safe_grow (rtx, gc, reg_equiv_memory_loc_vec, max_regno);
- memset (VEC_address (rtx, reg_equiv_memory_loc_vec), 0,
- sizeof (rtx) * max_regno);
- reg_equiv_memory_loc = VEC_address (rtx, reg_equiv_memory_loc_vec);
-}
+\f
/* All natural loops. */
struct loops ira_loops;
record_loop_exits ();
current_loops = &ira_loops;
- init_reg_equiv_memory_loc ();
-
if (internal_flag_ira_verbose > 0 && ira_dump_file != NULL)
fprintf (ira_dump_file, "Building IRA IR\n");
loops_p = ira_build (optimize
if (delete_trivially_dead_insns (get_insns (), max_reg_num ()))
df_analyze ();
- init_reg_equiv_memory_loc ();
+ grow_reg_equivs ();
if (max_regno != max_regno_before_ira)
{
regstat_compute_ri ();
}
- allocate_initial_values (reg_equiv_memory_loc);
+ allocate_initial_values (reg_equivs);
overall_cost_before = ira_overall_cost;
if (ira_conflicts_p)
{
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]
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)
|| MEM_P (operand))
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
{
/* 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))
&& (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),
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)))
int inc;
/* A reg for which reload_in is the equivalent.
If reload_in is a symbol_ref which came from
- reg_equiv_constant, then this is the pseudo
+ reg_equiv_consant, then this is the pseudo
which has that symbol_ref as equivalent. */
rtx in_reg;
rtx out_reg;
#define caller_save_initialized_p \
(this_target_reload->x_caller_save_initialized_p)
-extern GTY (()) VEC(rtx,gc) *reg_equiv_memory_loc_vec;
-extern rtx *reg_equiv_constant;
-extern rtx *reg_equiv_invariant;
-extern rtx *reg_equiv_memory_loc;
-extern rtx *reg_equiv_address;
-extern rtx *reg_equiv_mem;
-extern rtx *reg_equiv_alt_mem_list;
-
-/* Element N is the list of insns that initialized reg N from its equivalent
- constant or memory slot. */
-extern GTY((length("reg_equiv_init_size"))) rtx *reg_equiv_init;
-
-/* The size of the previous array, for GC purposes. */
-extern GTY(()) int reg_equiv_init_size;
+/* Register equivalences. Indexed by register number. */
+typedef struct reg_equivs
+{
+ /* The constant value to which pseudo reg N is equivalent,
+ or zero if pseudo reg N is not equivalent to a constant.
+ find_reloads looks at this in order to replace pseudo reg N
+ with the constant it stands for. */
+ rtx constant;
+
+ /* An invariant value to which pseudo reg N is equivalent.
+ eliminate_regs_in_insn uses this to replace pseudos in particular
+ contexts. */
+ rtx invariant;
+
+ /* A memory location to which pseudo reg N is equivalent,
+ prior to any register elimination (such as frame pointer to stack
+ pointer). Depending on whether or not it is a valid address, this value
+ is transferred to either equiv_address or equiv_mem. */
+ rtx memory_loc;
+
+ /* The address of stack slot to which pseudo reg N is equivalent.
+ This is used when the address is not valid as a memory address
+ (because its displacement is too big for the machine.) */
+ rtx address;
+
+ /* The memory slot to which pseudo reg N is equivalent,
+ or zero if pseudo reg N is not equivalent to a memory slot. */
+ rtx mem;
+
+ /* An EXPR_LIST of REG_EQUIVs containing MEMs with
+ alternate representations of the location of pseudo reg N. */
+ rtx alt_mem_list;
+
+ /* The list of insns that initialized reg N from its equivalent
+ constant or memory slot. */
+ rtx init;
+} reg_equivs_t;
+
+#define reg_equiv_constant(ELT) \
+ VEC_index (reg_equivs_t, reg_equivs, (ELT))->constant
+#define reg_equiv_invariant(ELT) \
+ VEC_index (reg_equivs_t, reg_equivs, (ELT))->invariant
+#define reg_equiv_memory_loc(ELT) \
+ VEC_index (reg_equivs_t, reg_equivs, (ELT))->memory_loc
+#define reg_equiv_address(ELT) \
+ VEC_index (reg_equivs_t, reg_equivs, (ELT))->address
+#define reg_equiv_mem(ELT) \
+ VEC_index (reg_equivs_t, reg_equivs, (ELT))->mem
+#define reg_equiv_alt_mem_list(ELT) \
+ VEC_index (reg_equivs_t, reg_equivs, (ELT))->alt_mem_list
+#define reg_equiv_init(ELT) \
+ VEC_index (reg_equivs_t, reg_equivs, (ELT))->init
+
+DEF_VEC_O(reg_equivs_t);
+DEF_VEC_ALLOC_O(reg_equivs_t, gc);
+extern VEC(reg_equivs_t,gc) *reg_equivs;
/* All the "earlyclobber" operands of the current insn
are recorded here. */
/* Compute the actual register we should reload to, in case we're
reloading to/from a register that is wider than a word. */
extern rtx reload_adjust_reg_for_mode (rtx, enum machine_mode);
+
+/* Ideally this function would be in ira.c or reload, but due to dependencies
+ on integrate.h, it's part of integrate.c. */
+extern void allocate_initial_values (VEC (reg_equivs_t, gc) *);
+
+/* Allocate or grow the reg_equiv tables, initializing new entries to 0. */
+extern void grow_reg_equivs (void);
#include "tm_p.h"
#include "obstack.h"
#include "insn-config.h"
+#include "ggc.h"
#include "flags.h"
#include "function.h"
#include "expr.h"
in the current insn. */
static HARD_REG_SET reg_is_output_reload;
-/* Element N is the constant value to which pseudo reg N is equivalent,
- or zero if pseudo reg N is not equivalent to a constant.
- find_reloads looks at this in order to replace pseudo reg N
- with the constant it stands for. */
-rtx *reg_equiv_constant;
-
-/* Element N is an invariant value to which pseudo reg N is equivalent.
- eliminate_regs_in_insn uses this to replace pseudos in particular
- contexts. */
-rtx *reg_equiv_invariant;
-
-/* Element N is a memory location to which pseudo reg N is equivalent,
- prior to any register elimination (such as frame pointer to stack
- pointer). Depending on whether or not it is a valid address, this value
- is transferred to either reg_equiv_address or reg_equiv_mem. */
-rtx *reg_equiv_memory_loc;
-
-/* We allocate reg_equiv_memory_loc inside a varray so that the garbage
- collector can keep track of what is inside. */
-VEC(rtx,gc) *reg_equiv_memory_loc_vec;
-
-/* Element N is the address of stack slot to which pseudo reg N is equivalent.
- This is used when the address is not valid as a memory address
- (because its displacement is too big for the machine.) */
-rtx *reg_equiv_address;
-
-/* Element N is the memory slot to which pseudo reg N is equivalent,
- or zero if pseudo reg N is not equivalent to a memory slot. */
-rtx *reg_equiv_mem;
-
-/* Element N is an EXPR_LIST of REG_EQUIVs containing MEMs with
- alternate representations of the location of pseudo reg N. */
-rtx *reg_equiv_alt_mem_list;
-
/* Widest width in which each pseudo reg is referred to (via subreg). */
static unsigned int *reg_max_ref_width;
-/* Element N is the list of insns that initialized reg N from its equivalent
- constant or memory slot. */
-rtx *reg_equiv_init;
-int reg_equiv_init_size;
-
/* Vector to remember old contents of reg_renumber before spilling. */
static short *reg_old_renumber;
static char *offsets_known_at;
static HOST_WIDE_INT (*offsets_at)[NUM_ELIMINABLE_REGS];
+VEC(reg_equivs_t,gc) *reg_equivs;
+
/* Stack of addresses where an rtx has been changed. We can undo the
changes by popping items off the stack and restoring the original
value at each location.
return;
}
- if (reg_equiv_constant[regno])
- *loc = reg_equiv_constant[regno];
- else if (reg_equiv_invariant[regno])
- *loc = reg_equiv_invariant[regno];
- else if (reg_equiv_mem[regno])
- *loc = reg_equiv_mem[regno];
- else if (reg_equiv_address[regno])
- *loc = gen_rtx_MEM (GET_MODE (x), reg_equiv_address[regno]);
+ if (reg_equiv_constant (regno))
+ *loc = reg_equiv_constant (regno);
+ else if (reg_equiv_invariant (regno))
+ *loc = reg_equiv_invariant (regno);
+ else if (reg_equiv_mem (regno))
+ *loc = reg_equiv_mem (regno);
+ else if (reg_equiv_address (regno))
+ *loc = gen_rtx_MEM (GET_MODE (x), reg_equiv_address (regno));
else
{
gcc_assert (!REG_P (regno_reg_rtx[regno])
return false;
}
+/* Grow (or allocate) the REG_EQUIVS array from its current size (which may be
+ zero elements) to MAX_REG_NUM elements.
+
+ Initialize all new fields to NULL and update REG_EQUIVS_SIZE. */
+void
+grow_reg_equivs (void)
+{
+ int old_size = VEC_length (reg_equivs_t, reg_equivs);
+ int max_regno = max_reg_num ();
+ int i;
+
+ VEC_reserve (reg_equivs_t, gc, reg_equivs, max_regno);
+ for (i = old_size; i < max_regno; i++)
+ {
+ VEC_quick_insert (reg_equivs_t, reg_equivs, i, 0);
+ memset (VEC_index (reg_equivs_t, reg_equivs, i), 0, sizeof (reg_equivs_t));
+ }
+
+}
+
\f
/* Global variables used by reload and its subroutines. */
if (! call_used_regs[i] && ! fixed_regs[i] && ! LOCAL_REGNO (i))
df_set_regs_ever_live (i, true);
+ /* Find all the pseudo registers that didn't get hard regs
+ but do have known equivalent constants or memory slots.
+ These include parameters (known equivalent to parameter slots)
+ and cse'd or loop-moved constant memory addresses.
+
+ Record constant equivalents in reg_equiv_constant
+ so they will be substituted by find_reloads.
+ Record memory equivalents in reg_mem_equiv so they can
+ be substituted eventually by altering the REG-rtx's. */
+
+ grow_reg_equivs ();
+ reg_max_ref_width = XCNEWVEC (unsigned int, max_regno);
reg_old_renumber = XCNEWVEC (short, max_regno);
memcpy (reg_old_renumber, reg_renumber, max_regno * sizeof (short));
pseudo_forbidden_regs = XNEWVEC (HARD_REG_SET, max_regno);
so this problem goes away. But that's very hairy. */
for (i = FIRST_PSEUDO_REGISTER; i < max_regno; i++)
- if (reg_renumber[i] < 0 && reg_equiv_memory_loc[i])
+ if (reg_renumber[i] < 0 && reg_equiv_memory_loc (i))
{
- rtx x = eliminate_regs (reg_equiv_memory_loc[i], VOIDmode,
+ rtx x = eliminate_regs (reg_equiv_memory_loc (i), VOIDmode,
NULL_RTX);
if (strict_memory_address_addr_space_p
(GET_MODE (regno_reg_rtx[i]), XEXP (x, 0),
MEM_ADDR_SPACE (x)))
- reg_equiv_mem[i] = x, reg_equiv_address[i] = 0;
+ reg_equiv_mem (i) = x, reg_equiv_address (i) = 0;
else if (CONSTANT_P (XEXP (x, 0))
|| (REG_P (XEXP (x, 0))
&& REGNO (XEXP (x, 0)) < FIRST_PSEUDO_REGISTER)
&& (REGNO (XEXP (XEXP (x, 0), 0))
< FIRST_PSEUDO_REGISTER)
&& CONSTANT_P (XEXP (XEXP (x, 0), 1))))
- reg_equiv_address[i] = XEXP (x, 0), reg_equiv_mem[i] = 0;
+ reg_equiv_mem (i) = XEXP (x, 0), reg_equiv_mem (i) = 0;
else
{
/* Make a new stack slot. Then indicate that something
below might change some offset. reg_equiv_{mem,address}
will be set up for this pseudo on the next pass around
the loop. */
- reg_equiv_memory_loc[i] = 0;
- reg_equiv_init[i] = 0;
+ reg_equiv_memory_loc (i) = 0;
+ reg_equiv_init (i) = 0;
alter_reg (i, -1, true);
}
}
for (i = FIRST_PSEUDO_REGISTER; i < max_regno; i++)
{
- if (reg_renumber[i] < 0 && reg_equiv_init[i] != 0)
+ if (reg_renumber[i] < 0 && reg_equiv_init (i) != 0)
{
rtx list;
- for (list = reg_equiv_init[i]; list; list = XEXP (list, 1))
+ for (list = reg_equiv_init (i); list; list = XEXP (list, 1))
{
rtx equiv_insn = XEXP (list, 0);
{
rtx addr = 0;
- if (reg_equiv_mem[i])
- addr = XEXP (reg_equiv_mem[i], 0);
+ if (reg_equiv_mem (i))
+ addr = XEXP (reg_equiv_mem (i), 0);
- if (reg_equiv_address[i])
- addr = reg_equiv_address[i];
+ if (reg_equiv_address (i))
+ addr = reg_equiv_address (i);
if (addr)
{
REG_USERVAR_P (reg) = 0;
PUT_CODE (reg, MEM);
XEXP (reg, 0) = addr;
- if (reg_equiv_memory_loc[i])
- MEM_COPY_ATTRIBUTES (reg, reg_equiv_memory_loc[i]);
+ if (reg_equiv_memory_loc (i))
+ MEM_COPY_ATTRIBUTES (reg, reg_equiv_memory_loc (i));
else
{
MEM_IN_STRUCT_P (reg) = MEM_SCALAR_P (reg) = 0;
}
MEM_NOTRAP_P (reg) = 1;
}
- else if (reg_equiv_mem[i])
- XEXP (reg_equiv_mem[i], 0) = addr;
+ else if (reg_equiv_mem (i))
+ XEXP (reg_equiv_mem (i), 0) = addr;
}
/* We don't want complex addressing modes in debug insns
rtx equiv = 0;
df_ref use, next;
- if (reg_equiv_constant[i])
- equiv = reg_equiv_constant[i];
- else if (reg_equiv_invariant[i])
- equiv = reg_equiv_invariant[i];
+ if (reg_equiv_constant (i))
+ equiv = reg_equiv_constant (i);
+ else if (reg_equiv_invariant (i))
+ equiv = reg_equiv_invariant (i);
else if (reg && MEM_P (reg))
equiv = targetm.delegitimize_address (reg);
else if (reg && REG_P (reg) && (int)REGNO (reg) != i)
/* Indicate that we no longer have known memory locations or constants. */
free_reg_equiv ();
- reg_equiv_init = 0;
+
free (reg_max_ref_width);
free (reg_old_renumber);
free (pseudo_previous_regs);
/* Skip insns that only set an equivalence. */
if (set && REG_P (SET_DEST (set))
&& reg_renumber[REGNO (SET_DEST (set))] < 0
- && (reg_equiv_constant[REGNO (SET_DEST (set))]
- || (reg_equiv_invariant[REGNO (SET_DEST (set))]))
- && reg_equiv_init[REGNO (SET_DEST (set))])
+ && (reg_equiv_constant (REGNO (SET_DEST (set)))
+ || (reg_equiv_invariant (REGNO (SET_DEST (set)))))
+ && reg_equiv_init (REGNO (SET_DEST (set))))
continue;
/* If needed, eliminate any eliminable registers. */
|| (REG_P (SET_SRC (set)) && REG_P (SET_DEST (set))
&& reg_renumber[REGNO (SET_SRC (set))] < 0
&& reg_renumber[REGNO (SET_DEST (set))] < 0
- && reg_equiv_memory_loc[REGNO (SET_SRC (set))] != NULL
- && reg_equiv_memory_loc[REGNO (SET_DEST (set))] != NULL
- && rtx_equal_p (reg_equiv_memory_loc
- [REGNO (SET_SRC (set))],
- reg_equiv_memory_loc
- [REGNO (SET_DEST (set))]))))
+ && reg_equiv_memory_loc (REGNO (SET_SRC (set))) != NULL
+ && reg_equiv_memory_loc (REGNO (SET_DEST (set))) != NULL
+ && rtx_equal_p (reg_equiv_memory_loc (REGNO (SET_SRC (set))),
+ reg_equiv_memory_loc (REGNO (SET_DEST (set)))))))
{
if (ira_conflicts_p)
/* Inform IRA about the insn deletion. */
/* Skip insns that only set an equivalence. */
if (set && REG_P (SET_DEST (set))
&& reg_renumber[REGNO (SET_DEST (set))] < 0
- && (reg_equiv_constant[REGNO (SET_DEST (set))]
- || (reg_equiv_invariant[REGNO (SET_DEST (set))])))
+ && (reg_equiv_constant (REGNO (SET_DEST (set)))
+ || reg_equiv_invariant (REGNO (SET_DEST (set)))))
{
unsigned regno = REGNO (SET_DEST (set));
- rtx init = reg_equiv_init[regno];
+ rtx init = reg_equiv_init (regno);
if (init)
{
rtx t = eliminate_regs_1 (SET_SRC (set), VOIDmode, insn,
}
for (i = FIRST_PSEUDO_REGISTER; i < max_regno; i++)
{
- if (reg_equiv_invariant[i])
+ if (reg_equiv_invariant (i))
{
- if (reg_equiv_init[i])
+ if (reg_equiv_init (i))
{
int cost = reg_equiv_init_cost[i];
if (dump_file)
}
}
- free_reg_equiv ();
free (reg_equiv_init_cost);
}
\f
if (reg_renumber[i] < 0
&& REG_N_REFS (i) > 0
- && reg_equiv_constant[i] == 0
- && (reg_equiv_invariant[i] == 0 || reg_equiv_init[i] == 0)
- && reg_equiv_memory_loc[i] == 0)
+ && reg_equiv_constant (i) == 0
+ && (reg_equiv_invariant (i) == 0
+ || reg_equiv_init (i) == 0)
+ && reg_equiv_memory_loc (i) == 0)
{
rtx x = NULL_RTX;
enum machine_mode mode = GET_MODE (regno_reg_rtx[i]);
set_mem_attrs_for_spill (x);
/* Save the stack slot for later. */
- reg_equiv_memory_loc[i] = x;
+ reg_equiv_memory_loc (i) = x;
}
}
if (REG_P (x)
&& REGNO (x) >= FIRST_PSEUDO_REGISTER
- && reg_equiv_init[REGNO (x)]
- && reg_equiv_invariant[REGNO (x)])
+ && reg_equiv_init (REGNO (x))
+ && reg_equiv_invariant (REGNO (x)))
{
- rtx t = reg_equiv_invariant[REGNO (x)];
+ rtx t = reg_equiv_invariant (REGNO (x));
rtx new_rtx = eliminate_regs_1 (t, Pmode, insn, true, true);
int cost = rtx_cost (new_rtx, SET, optimize_bb_for_speed_p (elim_bb));
int freq = REG_FREQ_FROM_BB (elim_bb);
}
else if (reg_renumber && reg_renumber[regno] < 0
- && reg_equiv_invariant && reg_equiv_invariant[regno])
+ && reg_equivs
+ && reg_equiv_invariant (regno))
{
if (may_use_invariant || (insn && DEBUG_INSN_P (insn)))
- return eliminate_regs_1 (copy_rtx (reg_equiv_invariant[regno]),
+ return eliminate_regs_1 (copy_rtx (reg_equiv_invariant (regno)),
mem_mode, insn, true, for_costs);
/* There exists at least one use of REGNO that cannot be
eliminated. Prevent the defining insn from being deleted. */
- reg_equiv_init[regno] = NULL_RTX;
+ reg_equiv_init (regno) = NULL_RTX;
if (!for_costs)
alter_reg (regno, -1, true);
}
if (GET_CODE (new0) == PLUS && REG_P (new1)
&& REGNO (new1) >= FIRST_PSEUDO_REGISTER
&& reg_renumber[REGNO (new1)] < 0
- && reg_equiv_constant != 0
- && reg_equiv_constant[REGNO (new1)] != 0)
- new1 = reg_equiv_constant[REGNO (new1)];
+ && reg_equivs
+ && reg_equiv_constant (REGNO (new1)) != 0)
+ new1 = reg_equiv_constant (REGNO (new1));
else if (GET_CODE (new1) == PLUS && REG_P (new0)
&& REGNO (new0) >= FIRST_PSEUDO_REGISTER
&& reg_renumber[REGNO (new0)] < 0
- && reg_equiv_constant[REGNO (new0)] != 0)
- new0 = reg_equiv_constant[REGNO (new0)];
+ && reg_equiv_constant (REGNO (new0)) != 0)
+ new0 = reg_equiv_constant (REGNO (new0));
new_rtx = form_sum (GET_MODE (x), new0, new1);
if (REG_P (SUBREG_REG (x))
&& (GET_MODE_SIZE (GET_MODE (x))
<= GET_MODE_SIZE (GET_MODE (SUBREG_REG (x))))
- && reg_equiv_memory_loc != 0
- && reg_equiv_memory_loc[REGNO (SUBREG_REG (x))] != 0)
+ && reg_equivs
+ && reg_equiv_memory_loc (REGNO (SUBREG_REG (x))) != 0)
{
new_rtx = SUBREG_REG (x);
}
else
- new_rtx = eliminate_regs_1 (SUBREG_REG (x), mem_mode, insn, false,
- for_costs);
+ new_rtx = eliminate_regs_1 (SUBREG_REG (x), mem_mode, insn, false, for_costs);
if (new_rtx != SUBREG_REG (x))
{
}
}
- else if (reg_renumber[regno] < 0 && reg_equiv_constant
- && reg_equiv_constant[regno]
- && ! function_invariant_p (reg_equiv_constant[regno]))
- elimination_effects (reg_equiv_constant[regno], mem_mode);
+ else if (reg_renumber[regno] < 0
+ && reg_equiv_constant (0)
+ && reg_equiv_constant (regno)
+ && ! function_invariant_p (reg_equiv_constant (regno)))
+ elimination_effects (reg_equiv_constant (regno), mem_mode);
return;
case PRE_INC:
if (REG_P (SUBREG_REG (x))
&& (GET_MODE_SIZE (GET_MODE (x))
<= GET_MODE_SIZE (GET_MODE (SUBREG_REG (x))))
- && reg_equiv_memory_loc != 0
- && reg_equiv_memory_loc[REGNO (SUBREG_REG (x))] != 0)
+ && reg_equivs != 0
+ && reg_equiv_memory_loc (REGNO (SUBREG_REG (x))) != 0)
return;
elimination_effects (SUBREG_REG (x), mem_mode);
int i;
rtx insn;
- reg_equiv_constant = XCNEWVEC (rtx, max_regno);
- reg_equiv_invariant = XCNEWVEC (rtx, max_regno);
- reg_equiv_mem = XCNEWVEC (rtx, max_regno);
- reg_equiv_alt_mem_list = XCNEWVEC (rtx, max_regno);
- reg_equiv_address = XCNEWVEC (rtx, max_regno);
+ grow_reg_equivs ();
if (do_subregs)
reg_max_ref_width = XCNEWVEC (unsigned int, max_regno);
else
/* Always unshare the equivalence, so we can
substitute into this insn without touching the
equivalence. */
- reg_equiv_memory_loc[i] = copy_rtx (x);
+ reg_equiv_memory_loc (i) = copy_rtx (x);
}
else if (function_invariant_p (x))
{
{
/* This is PLUS of frame pointer and a constant,
and might be shared. Unshare it. */
- reg_equiv_invariant[i] = copy_rtx (x);
+ reg_equiv_invariant (i) = copy_rtx (x);
num_eliminable_invariants++;
}
else if (x == frame_pointer_rtx || x == arg_pointer_rtx)
{
- reg_equiv_invariant[i] = x;
+ reg_equiv_invariant (i) = x;
num_eliminable_invariants++;
}
else if (LEGITIMATE_CONSTANT_P (x))
- reg_equiv_constant[i] = x;
+ reg_equiv_constant (i) = x;
else
{
- reg_equiv_memory_loc[i]
+ reg_equiv_memory_loc (i)
= force_const_mem (GET_MODE (SET_DEST (set)), x);
- if (! reg_equiv_memory_loc[i])
- reg_equiv_init[i] = NULL_RTX;
+ if (! reg_equiv_memory_loc (i))
+ reg_equiv_init (i) = NULL_RTX;
}
}
else
{
- reg_equiv_init[i] = NULL_RTX;
+ reg_equiv_init (i) = NULL_RTX;
continue;
}
}
else
- reg_equiv_init[i] = NULL_RTX;
+ reg_equiv_init (i) = NULL_RTX;
}
}
if (dump_file)
for (i = FIRST_PSEUDO_REGISTER; i < max_regno; i++)
- if (reg_equiv_init[i])
+ if (reg_equiv_init (i))
{
fprintf (dump_file, "init_insns for %u: ", i);
- print_inline_rtx (dump_file, reg_equiv_init[i], 20);
+ print_inline_rtx (dump_file, reg_equiv_init (i), 20);
fprintf (dump_file, "\n");
}
}
{
int i;
- if (reg_equiv_constant)
- free (reg_equiv_constant);
- if (reg_equiv_invariant)
- free (reg_equiv_invariant);
- reg_equiv_constant = 0;
- reg_equiv_invariant = 0;
- VEC_free (rtx, gc, reg_equiv_memory_loc_vec);
- reg_equiv_memory_loc = 0;
if (offsets_known_at)
free (offsets_known_at);
offsets_known_at = 0;
for (i = 0; i < FIRST_PSEUDO_REGISTER; i++)
- if (reg_equiv_alt_mem_list[i])
- free_EXPR_LIST_list (®_equiv_alt_mem_list[i]);
- free (reg_equiv_alt_mem_list);
+ if (reg_equiv_alt_mem_list (i))
+ free_EXPR_LIST_list (®_equiv_alt_mem_list (i));
+ VEC_free (reg_equivs_t, gc, reg_equivs);
+ reg_equivs = NULL;
- free (reg_equiv_mem);
- free (reg_equiv_address);
}
\f
/* Kick all pseudos out of hard register REGNO.
tmp = SUBREG_REG (tmp);
if (REG_P (tmp)
&& REGNO (tmp) >= FIRST_PSEUDO_REGISTER
- && (reg_equiv_memory_loc[REGNO (tmp)] != 0
- || reg_equiv_constant[REGNO (tmp)] != 0))
+ && (reg_equiv_memory_loc (REGNO (tmp)) != 0
+ || reg_equiv_constant (REGNO (tmp)) != 0))
{
- if (! reg_equiv_mem[REGNO (tmp)]
+ if (! reg_equiv_mem (REGNO (tmp))
|| num_not_at_initial_offset
|| GET_CODE (oldequiv) == SUBREG)
real_oldequiv = rl->in;
else
- real_oldequiv = reg_equiv_mem[REGNO (tmp)];
+ real_oldequiv = reg_equiv_mem (REGNO (tmp));
}
tmp = old;
tmp = SUBREG_REG (tmp);
if (REG_P (tmp)
&& REGNO (tmp) >= FIRST_PSEUDO_REGISTER
- && (reg_equiv_memory_loc[REGNO (tmp)] != 0
- || reg_equiv_constant[REGNO (tmp)] != 0))
+ && (reg_equiv_memory_loc (REGNO (tmp)) != 0
+ || reg_equiv_constant (REGNO (tmp)) != 0))
{
- if (! reg_equiv_mem[REGNO (tmp)]
+ if (! reg_equiv_mem (REGNO (tmp))
|| num_not_at_initial_offset
|| GET_CODE (old) == SUBREG)
real_old = rl->in;
else
- real_old = reg_equiv_mem[REGNO (tmp)];
+ real_old = reg_equiv_mem (REGNO (tmp));
}
second_reload_reg = rld[secondary_reload].reg_rtx;
if ((REG_P (oldequiv)
&& REGNO (oldequiv) >= FIRST_PSEUDO_REGISTER
- && (reg_equiv_memory_loc[REGNO (oldequiv)] != 0
- || reg_equiv_constant[REGNO (oldequiv)] != 0))
+ && (reg_equiv_memory_loc (REGNO (oldequiv)) != 0
+ || reg_equiv_constant (REGNO (oldequiv)) != 0))
|| (GET_CODE (oldequiv) == SUBREG
&& REG_P (SUBREG_REG (oldequiv))
&& (REGNO (SUBREG_REG (oldequiv))
>= FIRST_PSEUDO_REGISTER)
- && ((reg_equiv_memory_loc
- [REGNO (SUBREG_REG (oldequiv))] != 0)
- || (reg_equiv_constant
- [REGNO (SUBREG_REG (oldequiv))] != 0)))
+ && ((reg_equiv_memory_loc (REGNO (SUBREG_REG (oldequiv))) != 0)
+ || (reg_equiv_constant (REGNO (SUBREG_REG (oldequiv))) != 0)))
|| (CONSTANT_P (oldequiv)
&& (targetm.preferred_reload_class (oldequiv,
REGNO_REG_CLASS (REGNO (reloadreg)))
int tertiary_reload = rld[secondary_reload].secondary_out_reload;
if (REG_P (old) && REGNO (old) >= FIRST_PSEUDO_REGISTER
- && reg_equiv_mem[REGNO (old)] != 0)
- real_old = reg_equiv_mem[REGNO (old)];
+ && reg_equiv_mem (REGNO (old)) != 0)
+ real_old = reg_equiv_mem (REGNO (old));
if (secondary_reload_class (0, rl->rclass, mode, real_old) != NO_REGS)
{
while (GET_CODE (reg) == SUBREG)
reg = SUBREG_REG (reg);
- substed = reg_equiv_memory_loc[REGNO (reg)];
+ substed = reg_equiv_memory_loc (REGNO (reg));
/* This is unsafe if the operand occurs more often in the current
insn than it is inherited. */
n_occurrences += count_occurrences (PATTERN (insn),
eliminate_regs (substed, VOIDmode,
NULL_RTX), 0);
- for (i1 = reg_equiv_alt_mem_list[REGNO (reg)]; i1; i1 = XEXP (i1, 1))
+ for (i1 = reg_equiv_alt_mem_list (REGNO (reg)); i1; i1 = XEXP (i1, 1))
{
gcc_assert (!rtx_equal_p (XEXP (i1, 0), substed));
n_occurrences += count_occurrences (PATTERN (insn), XEXP (i1, 0), 0);