From 574af2d680da3388a6b26afa549e5306602aa8f7 Mon Sep 17 00:00:00 2001 From: Richard Sandiford Date: Thu, 15 Jan 2009 21:22:32 +0000 Subject: 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 --- gcc/caller-save.c | 89 +++++++++++++++++++++++++------------------------------ 1 file changed, 40 insertions(+), 49 deletions(-) (limited to 'gcc/caller-save.c') diff --git a/gcc/caller-save.c b/gcc/caller-save.c index 002f760..be1718c 100644 --- a/gcc/caller-save.c +++ b/gcc/caller-save.c @@ -1179,6 +1179,39 @@ insert_save (struct insn_chain *chain, int before_p, int regno, 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. */ static struct insn_chain * 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 registers from the live sets. */ COPY_REG_SET (&new_chain->live_throughout, &chain->live_throughout); - /* Registers that die in CHAIN->INSN still live in the new insn. - Likewise for those which are autoincremented or autodecremented. */ - 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); - } - } - + note_uses (&PATTERN (chain->insn), add_used_regs, + &new_chain->live_throughout); /* If CHAIN->INSN is a call, then the registers which contain the arguments to the function are live in the new insn. */ if (CALL_P (chain->insn)) - { - for (link = CALL_INSN_FUNCTION_USAGE (chain->insn); - link != NULL_RTX; - link = XEXP (link, 1)) - { - 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); - } - } - } - - } + for (link = CALL_INSN_FUNCTION_USAGE (chain->insn); + link != NULL_RTX; + link = XEXP (link, 1)) + note_uses (&XEXP (link, 0), add_used_regs, + &new_chain->live_throughout); CLEAR_REG_SET (&new_chain->dead_or_set); if (chain->insn == BB_HEAD (BASIC_BLOCK (chain->block))) -- cgit v1.1