summaryrefslogtreecommitdiff
diff options
context:
space:
mode:
authoramodra <amodra@138bc75d-0d04-0410-961f-82ee72b054a4>2016-05-05 00:01:26 +0000
committeramodra <amodra@138bc75d-0d04-0410-961f-82ee72b054a4>2016-05-05 00:01:26 +0000
commitc3e85fddcd03616119198c3586e6ec8b0ce0fa67 (patch)
tree7fabab87e61ae6d96ba30a8ed3c6d9da53515048
parent2cbd4b917b0b716c3524e955872d7d2802cff2c7 (diff)
downloadgcc-c3e85fddcd03616119198c3586e6ec8b0ce0fa67.tar.gz
[RS6000] Rewrite rs6000_frame_related to use simplify_replace_rtx
Modify SETs rather than using replace_rtx on the whole insn. Removes fragile hacks preventing USE and CLOBBER being modified. * config/rs6000/rs6000.c (rs6000_frame_related): Rewrite. git-svn-id: svn+ssh://gcc.gnu.org/svn/gcc/trunk@235913 138bc75d-0d04-0410-961f-82ee72b054a4
-rw-r--r--gcc/ChangeLog4
-rw-r--r--gcc/config/rs6000/rs6000.c114
2 files changed, 48 insertions, 70 deletions
diff --git a/gcc/ChangeLog b/gcc/ChangeLog
index 629ee45c06e..64b2541eaa0 100644
--- a/gcc/ChangeLog
+++ b/gcc/ChangeLog
@@ -1,5 +1,9 @@
2016-05-05 Alan Modra <amodra@gmail.com>
+ * config/rs6000/rs6000.c (rs6000_frame_related): Rewrite.
+
+2016-05-05 Alan Modra <amodra@gmail.com>
+
* config/rs6000/rs6000.c (rs6000_savres_strategy): Don't use
out-of-line gpr restore for one or two regs if that would add
a save of lr.
diff --git a/gcc/config/rs6000/rs6000.c b/gcc/config/rs6000/rs6000.c
index 77092fa3f8b..701530205fc 100644
--- a/gcc/config/rs6000/rs6000.c
+++ b/gcc/config/rs6000/rs6000.c
@@ -24718,7 +24718,7 @@ output_probe_stack_range (rtx reg1, rtx reg2)
}
/* Add to 'insn' a note which is PATTERN (INSN) but with REG replaced
- with (plus:P (reg 1) VAL), and with REG2 replaced with RREG if REG2
+ with (plus:P (reg 1) VAL), and with REG2 replaced with REPL2 if REG2
is not NULL. It would be nice if dwarf2out_frame_debug_expr could
deduce these equivalences by itself so it wasn't necessary to hold
its hand so much. Don't be tempted to always supply d2_f_d_e with
@@ -24728,22 +24728,28 @@ output_probe_stack_range (rtx reg1, rtx reg2)
static rtx
rs6000_frame_related (rtx insn, rtx reg, HOST_WIDE_INT val,
- rtx reg2, rtx rreg)
+ rtx reg2, rtx repl2)
{
- rtx real, temp;
+ rtx repl;
- if (REGNO (reg) == STACK_POINTER_REGNUM && reg2 == NULL_RTX)
+ if (REGNO (reg) == STACK_POINTER_REGNUM)
{
- /* No need for any replacement. Just set RTX_FRAME_RELATED_P. */
- int i;
-
gcc_checking_assert (val == 0);
- real = PATTERN (insn);
- if (GET_CODE (real) == PARALLEL)
- for (i = 0; i < XVECLEN (real, 0); i++)
- if (GET_CODE (XVECEXP (real, 0, i)) == SET)
+ repl = NULL_RTX;
+ }
+ else
+ repl = gen_rtx_PLUS (Pmode, gen_rtx_REG (Pmode, STACK_POINTER_REGNUM),
+ GEN_INT (val));
+
+ rtx pat = PATTERN (insn);
+ if (!repl && !reg2)
+ {
+ /* No need for any replacement. Just set RTX_FRAME_RELATED_P. */
+ if (GET_CODE (pat) == PARALLEL)
+ for (int i = 0; i < XVECLEN (pat, 0); i++)
+ if (GET_CODE (XVECEXP (pat, 0, i)) == SET)
{
- rtx set = XVECEXP (real, 0, i);
+ rtx set = XVECEXP (pat, 0, i);
/* If this PARALLEL has been emitted for out-of-line
register save functions, or store multiple, then omit
@@ -24758,79 +24764,47 @@ rs6000_frame_related (rtx insn, rtx reg, HOST_WIDE_INT val,
return insn;
}
- /* copy_rtx will not make unique copies of registers, so we need to
- ensure we don't have unwanted sharing here. */
- if (reg == reg2)
- reg = gen_raw_REG (GET_MODE (reg), REGNO (reg));
-
- if (reg == rreg)
- reg = gen_raw_REG (GET_MODE (reg), REGNO (reg));
-
- real = copy_rtx (PATTERN (insn));
-
- if (reg2 != NULL_RTX)
- real = replace_rtx (real, reg2, rreg);
-
- if (REGNO (reg) == STACK_POINTER_REGNUM)
- gcc_checking_assert (val == 0);
- else
- real = replace_rtx (real, reg,
- gen_rtx_PLUS (Pmode, gen_rtx_REG (Pmode,
- STACK_POINTER_REGNUM),
- GEN_INT (val)));
-
- /* We expect that 'real' is either a SET or a PARALLEL containing
+ /* We expect that 'pat' is either a SET or a PARALLEL containing
SETs (and possibly other stuff). In a PARALLEL, all the SETs
- are important so they all have to be marked RTX_FRAME_RELATED_P. */
+ are important so they all have to be marked RTX_FRAME_RELATED_P.
+ Call simplify_replace_rtx on the SETs rather than the whole insn
+ so as to leave the other stuff alone (for example USE of r12). */
- if (GET_CODE (real) == SET)
+ if (GET_CODE (pat) == SET)
{
- rtx set = real;
-
- temp = simplify_rtx (SET_SRC (set));
- if (temp)
- SET_SRC (set) = temp;
- temp = simplify_rtx (SET_DEST (set));
- if (temp)
- SET_DEST (set) = temp;
- if (GET_CODE (SET_DEST (set)) == MEM)
- {
- temp = simplify_rtx (XEXP (SET_DEST (set), 0));
- if (temp)
- XEXP (SET_DEST (set), 0) = temp;
- }
+ if (repl)
+ pat = simplify_replace_rtx (pat, reg, repl);
+ if (reg2)
+ pat = simplify_replace_rtx (pat, reg2, repl2);
}
- else
+ else if (GET_CODE (pat) == PARALLEL)
{
- int i;
+ pat = shallow_copy_rtx (pat);
+ XVEC (pat, 0) = shallow_copy_rtvec (XVEC (pat, 0));
- gcc_assert (GET_CODE (real) == PARALLEL);
- for (i = 0; i < XVECLEN (real, 0); i++)
- if (GET_CODE (XVECEXP (real, 0, i)) == SET)
+ for (int i = 0; i < XVECLEN (pat, 0); i++)
+ if (GET_CODE (XVECEXP (pat, 0, i)) == SET)
{
- rtx set = XVECEXP (real, 0, i);
-
- temp = simplify_rtx (SET_SRC (set));
- if (temp)
- SET_SRC (set) = temp;
- temp = simplify_rtx (SET_DEST (set));
- if (temp)
- SET_DEST (set) = temp;
- if (GET_CODE (SET_DEST (set)) == MEM)
- {
- temp = simplify_rtx (XEXP (SET_DEST (set), 0));
- if (temp)
- XEXP (SET_DEST (set), 0) = temp;
- }
+ rtx set = XVECEXP (pat, 0, i);
+
+ if (repl)
+ set = simplify_replace_rtx (set, reg, repl);
+ if (reg2)
+ set = simplify_replace_rtx (set, reg2, repl2);
+ XVECEXP (pat, 0, i) = set;
+
/* Omit eh_frame info for any user-defined global regs. */
if (!REG_P (SET_SRC (set))
|| !fixed_reg_p (REGNO (SET_SRC (set))))
RTX_FRAME_RELATED_P (set) = 1;
}
}
+ else
+ gcc_unreachable ();
RTX_FRAME_RELATED_P (insn) = 1;
- add_reg_note (insn, REG_FRAME_RELATED_EXPR, real);
+ if (repl || reg2)
+ add_reg_note (insn, REG_FRAME_RELATED_EXPR, pat);
return insn;
}