Commit d7f88d86 by Bernd Schmidt Committed by Bernd Schmidt

Makefile.in (local-alloc.o): Depend on $(GGC_H) and reload.h.

	* Makefile.in (local-alloc.o): Depend on $(GGC_H) and reload.h.
	* local-alloc.c: Include "ggc.h" and "reload.h".
	(struct equivalence): New member is_arg_equivalence.
	(local_alloc): Always call update_equiv_regs.
	(update_equiv_regs): Allocate reg_equiv_init; set reg_equiv_init_size.
	Detect equivalences made by stores to memory in a second pass.
	Return early if not optimizing.
	Initialize reg_equiv_init for all equivalences; treat equivalences for
	REG_EQUIV notes existing before this pass specially.
	(no_equiv): Don't clear reg_equiv_init or remove notes if the
	is_arg_equivalence field is set.
	* reload.h (reg_equiv_init, reg_equiv_init_size): Declare.
	* reload1.c (reg_equiv_init): No longer static.
	(reg_equiv_init_size): New variable.
	(reload): Don't allocate reg_equiv_init; don't free it when done but
	clear it.
	Restructure equivalence set up code not to set reg_equiv_init, but to
	clear it when we can't use an equivalence.
	Undo change disabling equivalences for MEM_READONLY_P memrefs.
	Dump equivalencing insns to dump_file.

From-SVN: r100975
parent ae973d6a
2005-06-15 Bernd Schmidt <bernd.schmidt@analog.com>
* Makefile.in (local-alloc.o): Depend on $(GGC_H) and reload.h.
* local-alloc.c: Include "ggc.h" and "reload.h".
(struct equivalence): New member is_arg_equivalence.
(local_alloc): Always call update_equiv_regs.
(update_equiv_regs): Allocate reg_equiv_init; set reg_equiv_init_size.
Detect equivalences made by stores to memory in a second pass.
Return early if not optimizing.
Initialize reg_equiv_init for all equivalences; treat equivalences for
REG_EQUIV notes existing before this pass specially.
(no_equiv): Don't clear reg_equiv_init or remove notes if the
is_arg_equivalence field is set.
* reload.h (reg_equiv_init, reg_equiv_init_size): Declare.
* reload1.c (reg_equiv_init): No longer static.
(reg_equiv_init_size): New variable.
(reload): Don't allocate reg_equiv_init; don't free it when done but
clear it.
Restructure equivalence set up code not to set reg_equiv_init, but to
clear it when we can't use an equivalence.
Undo change disabling equivalences for MEM_READONLY_P memrefs.
Dump equivalencing insns to dump_file.
2005-06-14 Richard Sandiford <richard@codesourcery.com> 2005-06-14 Richard Sandiford <richard@codesourcery.com>
* config/mips/mips.c (machine_function): Add varargs_size field. * config/mips/mips.c (machine_function): Add varargs_size field.
......
...@@ -2241,8 +2241,8 @@ regclass.o : regclass.c $(CONFIG_H) $(SYSTEM_H) coretypes.h $(TM_H) $(RTL_H) \ ...@@ -2241,8 +2241,8 @@ regclass.o : regclass.c $(CONFIG_H) $(SYSTEM_H) coretypes.h $(TM_H) $(RTL_H) \
$(TM_P_H) $(EXPR_H) $(TIMEVAR_H) gt-regclass.h $(HASHTAB_H) $(TM_P_H) $(EXPR_H) $(TIMEVAR_H) gt-regclass.h $(HASHTAB_H)
local-alloc.o : local-alloc.c $(CONFIG_H) $(SYSTEM_H) coretypes.h $(TM_H) \ local-alloc.o : local-alloc.c $(CONFIG_H) $(SYSTEM_H) coretypes.h $(TM_H) \
$(RTL_H) $(FLAGS_H) $(REGS_H) hard-reg-set.h insn-config.h $(RECOG_H) \ $(RTL_H) $(FLAGS_H) $(REGS_H) hard-reg-set.h insn-config.h $(RECOG_H) \
output.h function.h $(INSN_ATTR_H) toplev.h except.h $(TM_P_H) \ output.h function.h $(INSN_ATTR_H) toplev.h except.h reload.h $(TM_P_H) \
$(INTEGRATE_H) $(GGC_H) $(INTEGRATE_H)
bitmap.o : bitmap.c $(CONFIG_H) $(SYSTEM_H) coretypes.h $(TM_H) $(RTL_H) \ bitmap.o : bitmap.c $(CONFIG_H) $(SYSTEM_H) coretypes.h $(TM_H) $(RTL_H) \
$(FLAGS_H) $(GGC_H) gt-bitmap.h bitmap.h $(OBSTACK_H) $(FLAGS_H) $(GGC_H) gt-bitmap.h bitmap.h $(OBSTACK_H)
global.o : global.c $(CONFIG_H) $(SYSTEM_H) coretypes.h $(TM_H) $(RTL_H) \ global.o : global.c $(CONFIG_H) $(SYSTEM_H) coretypes.h $(TM_H) $(RTL_H) \
......
...@@ -170,6 +170,13 @@ extern rtx *reg_equiv_memory_loc; ...@@ -170,6 +170,13 @@ extern rtx *reg_equiv_memory_loc;
extern rtx *reg_equiv_address; extern rtx *reg_equiv_address;
extern rtx *reg_equiv_mem; extern rtx *reg_equiv_mem;
/* 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;
/* All the "earlyclobber" operands of the current insn /* All the "earlyclobber" operands of the current insn
are recorded here. */ are recorded here. */
extern int n_earlyclobbers; extern int n_earlyclobbers;
......
...@@ -120,7 +120,8 @@ static unsigned int *reg_max_ref_width; ...@@ -120,7 +120,8 @@ static unsigned int *reg_max_ref_width;
/* Element N is the list of insns that initialized reg N from its equivalent /* Element N is the list of insns that initialized reg N from its equivalent
constant or memory slot. */ constant or memory slot. */
static rtx *reg_equiv_init; rtx *reg_equiv_init;
int reg_equiv_init_size;
/* Vector to remember old contents of reg_renumber before spilling. */ /* Vector to remember old contents of reg_renumber before spilling. */
static short *reg_old_renumber; static short *reg_old_renumber;
...@@ -693,7 +694,6 @@ reload (rtx first, int global) ...@@ -693,7 +694,6 @@ reload (rtx first, int global)
reg_equiv_constant = xcalloc (max_regno, sizeof (rtx)); reg_equiv_constant = xcalloc (max_regno, sizeof (rtx));
reg_equiv_mem = xcalloc (max_regno, sizeof (rtx)); reg_equiv_mem = xcalloc (max_regno, sizeof (rtx));
reg_equiv_init = xcalloc (max_regno, sizeof (rtx));
reg_equiv_address = xcalloc (max_regno, sizeof (rtx)); reg_equiv_address = xcalloc (max_regno, sizeof (rtx));
reg_max_ref_width = xcalloc (max_regno, sizeof (int)); reg_max_ref_width = xcalloc (max_regno, sizeof (int));
reg_old_renumber = xcalloc (max_regno, sizeof (short)); reg_old_renumber = xcalloc (max_regno, sizeof (short));
...@@ -719,40 +719,37 @@ reload (rtx first, int global) ...@@ -719,40 +719,37 @@ reload (rtx first, int global)
&& GET_MODE (insn) != VOIDmode) && GET_MODE (insn) != VOIDmode)
PUT_MODE (insn, VOIDmode); PUT_MODE (insn, VOIDmode);
if (INSN_P (insn))
scan_paradoxical_subregs (PATTERN (insn));
if (set != 0 && REG_P (SET_DEST (set))) if (set != 0 && REG_P (SET_DEST (set)))
{ {
rtx note = find_reg_note (insn, REG_EQUIV, NULL_RTX); rtx note = find_reg_note (insn, REG_EQUIV, NULL_RTX);
if (note rtx x;
&& (! function_invariant_p (XEXP (note, 0))
if (! note)
continue;
i = REGNO (SET_DEST (set));
x = XEXP (note, 0);
if (i <= LAST_VIRTUAL_REGISTER)
continue;
if (! function_invariant_p (x)
|| ! flag_pic || ! flag_pic
/* A function invariant is often CONSTANT_P but may /* A function invariant is often CONSTANT_P but may
include a register. We promise to only pass include a register. We promise to only pass
CONSTANT_P objects to LEGITIMATE_PIC_OPERAND_P. */ CONSTANT_P objects to LEGITIMATE_PIC_OPERAND_P. */
|| (CONSTANT_P (XEXP (note, 0)) || (CONSTANT_P (x)
&& LEGITIMATE_PIC_OPERAND_P (XEXP (note, 0))))) && LEGITIMATE_PIC_OPERAND_P (x)))
{
rtx x = XEXP (note, 0);
i = REGNO (SET_DEST (set));
if (i > LAST_VIRTUAL_REGISTER)
{ {
/* It can happen that a REG_EQUIV note contains a MEM /* It can happen that a REG_EQUIV note contains a MEM
that is not a legitimate memory operand. As later that is not a legitimate memory operand. As later
stages of reload assume that all addresses found stages of reload assume that all addresses found
in the reg_equiv_* arrays were originally legitimate, in the reg_equiv_* arrays were originally legitimate,
we ignore such REG_EQUIV notes. */
It can also happen that a REG_EQUIV note contains a if (memory_operand (x, VOIDmode))
readonly memory location. If the destination pseudo
is set from some other value (typically a different
pseudo), and the destination pseudo does not get a
hard reg, then reload will replace the destination
pseudo with its equivalent memory location. This
is horribly bad as it creates a store to a readonly
memory location and a runtime segfault. To avoid
this problem we reject readonly memory locations
for equivalences. This is overly conservative as
we could find all sets of the destination pseudo
and remove them as they should be redundant. */
if (memory_operand (x, VOIDmode) && ! MEM_READONLY_P (x))
{ {
/* Always unshare the equivalence, so we can /* Always unshare the equivalence, so we can
substitute into this insn without touching the substitute into this insn without touching the
...@@ -780,38 +777,28 @@ reload (rtx first, int global) ...@@ -780,38 +777,28 @@ reload (rtx first, int global)
{ {
reg_equiv_memory_loc[i] reg_equiv_memory_loc[i]
= force_const_mem (GET_MODE (SET_DEST (set)), x); = force_const_mem (GET_MODE (SET_DEST (set)), x);
if (!reg_equiv_memory_loc[i]) if (! reg_equiv_memory_loc[i])
continue; reg_equiv_init[i] = NULL_RTX;
} }
} }
else else
{
reg_equiv_init[i] = NULL_RTX;
continue; continue;
/* If this register is being made equivalent to a MEM
and the MEM is not SET_SRC, the equivalencing insn
is one with the MEM as a SET_DEST and it occurs later.
So don't mark this insn now. */
if (!MEM_P (x)
|| rtx_equal_p (SET_SRC (set), x))
reg_equiv_init[i]
= gen_rtx_INSN_LIST (VOIDmode, insn, reg_equiv_init[i]);
} }
} }
else
reg_equiv_init[i] = NULL_RTX;
}
} }
/* If this insn is setting a MEM from a register equivalent to it, if (dump_file)
this is the equivalencing insn. */ for (i = FIRST_PSEUDO_REGISTER; i < max_regno; i++)
else if (set && MEM_P (SET_DEST (set)) if (reg_equiv_init[i])
&& REG_P (SET_SRC (set)) {
&& reg_equiv_memory_loc[REGNO (SET_SRC (set))] fprintf (dump_file, "init_insns for %u: ", i);
&& rtx_equal_p (SET_DEST (set), print_inline_rtx (dump_file, reg_equiv_init[i], 20);
reg_equiv_memory_loc[REGNO (SET_SRC (set))])) fprintf (dump_file, "\n");
reg_equiv_init[REGNO (SET_SRC (set))]
= gen_rtx_INSN_LIST (VOIDmode, insn,
reg_equiv_init[REGNO (SET_SRC (set))]);
if (INSN_P (insn))
scan_paradoxical_subregs (PATTERN (insn));
} }
init_elim_table (); init_elim_table ();
...@@ -1260,7 +1247,7 @@ reload (rtx first, int global) ...@@ -1260,7 +1247,7 @@ reload (rtx first, int global)
free (offsets_at); free (offsets_at);
free (reg_equiv_mem); free (reg_equiv_mem);
free (reg_equiv_init); reg_equiv_init = 0;
free (reg_equiv_address); free (reg_equiv_address);
free (reg_max_ref_width); free (reg_max_ref_width);
free (reg_old_renumber); free (reg_old_renumber);
......
Markdown is supported
0% or
You are about to add 0 people to the discussion. Proceed with caution.
Finish editing this message first!
Please register or to comment