diff options
author | Jakub Jelinek <jakub@redhat.com> | 2009-08-03 19:31:09 +0000 |
---|---|---|
committer | Jakub Jelinek <jakub@redhat.com> | 2009-08-03 19:31:09 +0000 |
commit | d9cc2ed8afa926b1036d9a2b5309b04faf3d8146 (patch) | |
tree | db4ce4c0d140cf75922026711e431f5138645845 | |
parent | 24a97ed6950f8d2e0f582cc10b801cf4e931f2d8 (diff) |
* combine.c (cleanup_auto_inc_dec): Make sure the return value is
always unshared.
git-svn-id: https://gcc.gnu.org/svn/gcc/branches/var-tracking-assignments-4_4-branch@150382 138bc75d-0d04-0410-961f-82ee72b054a4
-rw-r--r-- | gcc/ChangeLog.vta | 5 | ||||
-rw-r--r-- | gcc/combine.c | 71 |
2 files changed, 51 insertions, 25 deletions
diff --git a/gcc/ChangeLog.vta b/gcc/ChangeLog.vta index f0dfeefa8d5..827ef494cae 100644 --- a/gcc/ChangeLog.vta +++ b/gcc/ChangeLog.vta @@ -1,3 +1,8 @@ +2009-08-03 Jakub Jelinek <jakub@redhat.com> + + * combine.c (cleanup_auto_inc_dec): Make sure the return value is + always unshared. + 2009-07-30 Jakub Jelinek <jakub@redhat.com> * dwarf2out.c (dw_long_long_const): Remove. diff --git a/gcc/combine.c b/gcc/combine.c index 188579d5287..0617aa56e79 100644 --- a/gcc/combine.c +++ b/gcc/combine.c @@ -2167,13 +2167,35 @@ reg_subword_p (rtx x, rtx reg) static rtx cleanup_auto_inc_dec (rtx src, bool after, enum machine_mode mem_mode) { - rtx x = src, n, o; + rtx x = src; const RTX_CODE code = GET_CODE (x); int i; const char *fmt; switch (code) { + case REG: + case CONST_INT: + case CONST_DOUBLE: + case CONST_FIXED: + case CONST_VECTOR: + case SYMBOL_REF: + case CODE_LABEL: + case PC: + case CC0: + case SCRATCH: + /* SCRATCH must be shared because they represent distinct values. */ + return x; + case CLOBBER: + if (REG_P (XEXP (x, 0)) && REGNO (XEXP (x, 0)) < FIRST_PSEUDO_REGISTER) + return x; + break; + + case CONST: + if (shared_const_p (x)) + return x; + break; + case MEM: mem_mode = GET_MODE (x); break; @@ -2184,13 +2206,14 @@ cleanup_auto_inc_dec (rtx src, bool after, enum machine_mode mem_mode) case POST_DEC: gcc_assert (mem_mode != VOIDmode && mem_mode != BLKmode); if (after == (code == PRE_INC || code == PRE_DEC)) - x = XEXP (x, 0); + x = cleanup_auto_inc_dec (XEXP (x, 0), after, mem_mode); else - x = gen_rtx_PLUS (GET_MODE (x), XEXP (x, 0), + x = gen_rtx_PLUS (GET_MODE (x), + cleanup_auto_inc_dec (XEXP (x, 0), after, mem_mode), GEN_INT ((code == PRE_INC || code == POST_INC) ? GET_MODE_SIZE (mem_mode) : -GET_MODE_SIZE (mem_mode))); - return cleanup_auto_inc_dec (x, after, mem_mode); + return x; case PRE_MODIFY: case POST_MODIFY: @@ -2204,33 +2227,31 @@ cleanup_auto_inc_dec (rtx src, bool after, enum machine_mode mem_mode) break; } + /* Copy the various flags, fields, and other information. We assume + that all fields need copying, and then clear the fields that should + not be copied. That is the sensible default behavior, and forces + us to explicitly document why we are *not* copying a flag. */ + x = shallow_copy_rtx (x); + + /* We do not copy the USED flag, which is used as a mark bit during + walks over the RTL. */ + RTX_FLAG (x, used) = 0; + + /* We do not copy FRAME_RELATED for INSNs. */ + if (INSN_P (x)) + RTX_FLAG (x, frame_related) = 0; + fmt = GET_RTX_FORMAT (code); for (i = GET_RTX_LENGTH (code) - 1; i >= 0; i--) if (fmt[i] == 'e') - { - o = XEXP (x, i); - n = cleanup_auto_inc_dec (o, after, mem_mode); - if (o != n) - { - if (x == src) - x = shallow_copy_rtx (x); - XEXP (x, i) = n; - } - } - else if (fmt[i] == 'E') + XEXP (x, i) = cleanup_auto_inc_dec (XEXP (x, i), after, mem_mode); + else if (fmt[i] == 'E' || fmt[i] == 'V') { int j; + XVEC (x, i) = rtvec_alloc (XVECLEN (x, i)); for (j = 0; j < XVECLEN (x, i); j++) - { - o = XVECEXP (x, i, j); - n = cleanup_auto_inc_dec (o, after, mem_mode); - if (o != n) - { - if (x == src) - x = shallow_copy_rtx (x); - XVECEXP (x, i, j) = n; - } - } + XVECEXP (x, i, j) + = cleanup_auto_inc_dec (XVECEXP (src, i, j), after, mem_mode); } return x; |