Commit 574af2d6 by Richard Sandiford Committed by Richard Sandiford

caller-save.c (add_used_regs_1, [...]): New functions.

gcc/
	* caller-save.c (add_used_regs_1, add_used_regs): New functions.
	(insert_one_insn): Use them instead of REG_DEAD and REG_INC notes.
	Also use them when walking CALL_INSN_FUNCTION_USAGE.

From-SVN: r143409
parent adc8a1e3
2009-01-15 Richard Sandiford <rdsandiford@googlemail.com>
* caller-save.c (add_used_regs_1, add_used_regs): New functions.
(insert_one_insn): Use them instead of REG_DEAD and REG_INC notes.
Also use them when walking CALL_INSN_FUNCTION_USAGE.
2009-01-15 H.J. Lu <hongjiu.lu@intel.com> 2009-01-15 H.J. Lu <hongjiu.lu@intel.com>
Joey Ye <joey.ye@intel.com> Joey Ye <joey.ye@intel.com>
......
...@@ -1179,6 +1179,39 @@ insert_save (struct insn_chain *chain, int before_p, int regno, ...@@ -1179,6 +1179,39 @@ insert_save (struct insn_chain *chain, int before_p, int regno,
return numregs - 1; return numregs - 1;
} }
/* A for_each_rtx callback used by add_used_regs. Add the hard-register
equivalent of each REG to regset DATA. */
static int
add_used_regs_1 (rtx *loc, void *data)
{
int regno, i;
regset live;
rtx x;
x = *loc;
live = (regset) data;
if (REG_P (x))
{
regno = REGNO (x);
if (!HARD_REGISTER_NUM_P (regno))
regno = reg_renumber[regno];
if (regno >= 0)
for (i = hard_regno_nregs[regno][GET_MODE (x)] - 1; i >= 0; i--)
SET_REGNO_REG_SET (live, regno + i);
}
return 0;
}
/* A note_uses callback used by insert_one_insn. Add the hard-register
equivalent of each REG to regset DATA. */
static void
add_used_regs (rtx *loc, void *data)
{
for_each_rtx (loc, add_used_regs_1, data);
}
/* Emit a new caller-save insn and set the code. */ /* Emit a new caller-save insn and set the code. */
static struct insn_chain * static struct insn_chain *
insert_one_insn (struct insn_chain *chain, int before_p, int code, rtx pat) insert_one_insn (struct insn_chain *chain, int before_p, int code, rtx pat)
...@@ -1216,58 +1249,16 @@ insert_one_insn (struct insn_chain *chain, int before_p, int code, rtx pat) ...@@ -1216,58 +1249,16 @@ insert_one_insn (struct insn_chain *chain, int before_p, int code, rtx pat)
/* ??? It would be nice if we could exclude the already / still saved /* ??? It would be nice if we could exclude the already / still saved
registers from the live sets. */ registers from the live sets. */
COPY_REG_SET (&new_chain->live_throughout, &chain->live_throughout); COPY_REG_SET (&new_chain->live_throughout, &chain->live_throughout);
/* Registers that die in CHAIN->INSN still live in the new insn. note_uses (&PATTERN (chain->insn), add_used_regs,
Likewise for those which are autoincremented or autodecremented. */ &new_chain->live_throughout);
for (link = REG_NOTES (chain->insn); link; link = XEXP (link, 1))
{
enum reg_note kind = REG_NOTE_KIND (link);
if (kind == REG_DEAD || kind == REG_INC)
{
rtx reg = XEXP (link, 0);
int regno, i;
gcc_assert (REG_P (reg));
regno = REGNO (reg);
if (regno >= FIRST_PSEUDO_REGISTER)
regno = reg_renumber[regno];
if (regno < 0)
continue;
for (i = hard_regno_nregs[regno][GET_MODE (reg)] - 1;
i >= 0; i--)
SET_REGNO_REG_SET (&new_chain->live_throughout, regno + i);
}
}
/* If CHAIN->INSN is a call, then the registers which contain /* If CHAIN->INSN is a call, then the registers which contain
the arguments to the function are live in the new insn. */ the arguments to the function are live in the new insn. */
if (CALL_P (chain->insn)) if (CALL_P (chain->insn))
{ for (link = CALL_INSN_FUNCTION_USAGE (chain->insn);
for (link = CALL_INSN_FUNCTION_USAGE (chain->insn); link != NULL_RTX;
link != NULL_RTX; link = XEXP (link, 1))
link = XEXP (link, 1)) note_uses (&XEXP (link, 0), add_used_regs,
{ &new_chain->live_throughout);
rtx arg = XEXP (link, 0);
if (GET_CODE (arg) == USE)
{
rtx reg = XEXP (arg, 0);
if (REG_P (reg))
{
int i, regno = REGNO (reg);
/* Registers in CALL_INSN_FUNCTION_USAGE are always
hard registers. */
gcc_assert (regno < FIRST_PSEUDO_REGISTER);
for (i = hard_regno_nregs[regno][GET_MODE (reg)] - 1;
i >= 0; i--)
SET_REGNO_REG_SET (&new_chain->live_throughout, regno + i);
}
}
}
}
CLEAR_REG_SET (&new_chain->dead_or_set); CLEAR_REG_SET (&new_chain->dead_or_set);
if (chain->insn == BB_HEAD (BASIC_BLOCK (chain->block))) if (chain->insn == BB_HEAD (BASIC_BLOCK (chain->block)))
......
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