/* Allocate registers within a basic block, for GNU compiler.
Copyright (C) 1987, 1988, 1991, 1993, 1994, 1995, 1996, 1997, 1998,
- 1999, 2000, 2001, 2002, 2003, 2004, 2005 Free Software Foundation, Inc.
+ 1999, 2000, 2001, 2002, 2003, 2004, 2005, 2006 Free Software Foundation,
+ Inc.
This file is part of GCC.
REG_EQUAL note on the insn. Since this note would be redundant,
there's no point creating it earlier than here. */
if (! note && ! rtx_varies_p (src, 0))
- note = set_unique_reg_note (insn, REG_EQUAL, src);
+ note = set_unique_reg_note (insn, REG_EQUAL, copy_rtx (src));
/* Don't bother considering a REG_EQUAL note containing an EXPR_LIST
since it represents a function call */
/* If this register is known to be equal to a constant, record that
it is always equivalent to the constant. */
- if (note && ! rtx_varies_p (XEXP (note, 0), 0))
- PUT_MODE (note, (enum machine_mode) REG_EQUIV);
+ if (REG_N_SETS (regno) == 1
+ && note && ! rtx_varies_p (XEXP (note, 0), 0))
+ {
+ rtx note_value = XEXP (note, 0);
+ remove_note (insn, note);
+ set_unique_reg_note (insn, REG_EQUIV, note_value);
+ }
/* If this insn introduces a "constant" register, decrease the priority
of that register. Record this insn if the register is only used once
if (note == 0 && REG_BASIC_BLOCK (regno) >= 0
&& MEM_P (SET_SRC (set))
&& validate_equiv_mem (insn, dest, SET_SRC (set)))
- REG_NOTES (insn) = note = gen_rtx_EXPR_LIST (REG_EQUIV, SET_SRC (set),
- REG_NOTES (insn));
+ note = set_unique_reg_note (insn, REG_EQUIV, copy_rtx (SET_SRC (set)));
if (note)
{
/* If we haven't done so, record for reload that this is an
equivalencing insn. */
- if (!reg_equiv[regno].is_arg_equivalence
- && (!MEM_P (x) || rtx_equal_p (src, x)))
+ if (!reg_equiv[regno].is_arg_equivalence)
reg_equiv_init[regno]
= gen_rtx_INSN_LIST (VOIDmode, insn, reg_equiv_init[regno]);
{
rtx init_insn = XEXP (reg_equiv[regno].init_insns, 0);
if (validate_equiv_mem (init_insn, src, dest)
- && ! memref_used_between_p (dest, init_insn, insn))
+ && ! memref_used_between_p (dest, init_insn, insn)
+ /* Attaching a REG_EQUIV note will fail if INIT_INSN has
+ multiple sets. */
+ && set_unique_reg_note (init_insn, REG_EQUIV, copy_rtx (dest)))
{
- REG_NOTES (init_insn)
- = gen_rtx_EXPR_LIST (REG_EQUIV, dest,
- REG_NOTES (init_insn));
/* This insn makes the equivalence, not the one initializing
the register. */
reg_equiv_init[regno]
/* Run old register allocator. Return TRUE if we must exit
rest_of_compilation upon return. */
-static void
+static unsigned int
rest_of_handle_local_alloc (void)
{
int rebuild_notes;
allocate_reg_info (max_regno, FALSE, TRUE);
/* And the reg_equiv_memory_loc array. */
- VARRAY_GROW (reg_equiv_memory_loc_varray, max_regno);
- reg_equiv_memory_loc = &VARRAY_RTX (reg_equiv_memory_loc_varray, 0);
+ 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);
allocate_initial_values (reg_equiv_memory_loc);
dump_local_alloc (dump_file);
timevar_pop (TV_DUMP);
}
+ return 0;
}
struct tree_opt_pass pass_local_alloc =