diff options
| author | kenner <kenner@138bc75d-0d04-0410-961f-82ee72b054a4> | 2004-02-12 20:48:21 +0000 |
|---|---|---|
| committer | kenner <kenner@138bc75d-0d04-0410-961f-82ee72b054a4> | 2004-02-12 20:48:21 +0000 |
| commit | 8182cbafcc5ae4f08eee29b9b15f49bbc40dbfc9 (patch) | |
| tree | ae858341fd9a06eaed05e5227868eec8273bc89c | |
| parent | d504c2c9de5c6fc7a83c8057760bc72f4a0e3485 (diff) | |
| download | ppe42-gcc-8182cbafcc5ae4f08eee29b9b15f49bbc40dbfc9.tar.gz ppe42-gcc-8182cbafcc5ae4f08eee29b9b15f49bbc40dbfc9.zip | |
* function.c (update_epilogue_consts): Teach about binary operations.
git-svn-id: svn+ssh://gcc.gnu.org/svn/gcc/trunk@77727 138bc75d-0d04-0410-961f-82ee72b054a4
| -rw-r--r-- | gcc/ChangeLog | 2 | ||||
| -rw-r--r-- | gcc/function.c | 30 |
2 files changed, 29 insertions, 3 deletions
diff --git a/gcc/ChangeLog b/gcc/ChangeLog index d8ad3f506f6..d252e8ca512 100644 --- a/gcc/ChangeLog +++ b/gcc/ChangeLog @@ -30,6 +30,8 @@ 2004-02-12 Richard Kenner <kenner@vlsi1.ultra.nyu.edu> + * function.c (update_epilogue_consts): Teach about binary operations. + * emit-rtl.c (set_mem_attributes_minus_bitpos): Don't kill previous MEM_VOLATILE in REF. * function.c (fixup_var_refs): Save volatile_ok and set to 1. diff --git a/gcc/function.c b/gcc/function.c index ca26cf82517..d51edde1a1a 100644 --- a/gcc/function.c +++ b/gcc/function.c @@ -7654,14 +7654,38 @@ static void update_epilogue_consts (rtx dest, rtx x, void *data) { struct epi_info *p = (struct epi_info *) data; + rtx new; if (GET_CODE (dest) != REG || REGNO (dest) >= FIRST_PSEUDO_REGISTER) return; - else if (GET_CODE (x) == CLOBBER || ! rtx_equal_p (dest, SET_DEST (x)) - || GET_CODE (SET_SRC (x)) != CONST_INT) + + /* If we are either clobbering a register or doing a partial set, + show we don't know the value. */ + else if (GET_CODE (x) == CLOBBER || ! rtx_equal_p (dest, SET_DEST (x))) p->const_equiv[REGNO (dest)] = 0; - else + + /* If we are setting it to a constant, record that constant. */ + else if (GET_CODE (SET_SRC (x)) == CONST_INT) p->const_equiv[REGNO (dest)] = SET_SRC (x); + + /* If this is a binary operation between a register we have been tracking + and a constant, see if we can compute a new constant value. */ + else if ((GET_RTX_CLASS (GET_CODE (SET_SRC (x))) == 'c' + || GET_RTX_CLASS (GET_CODE (SET_SRC (x))) == '2') + && GET_CODE (XEXP (SET_SRC (x), 0)) == REG + && REGNO (XEXP (SET_SRC (x), 0)) < FIRST_PSEUDO_REGISTER + && p->const_equiv[REGNO (XEXP (SET_SRC (x), 0))] != 0 + && GET_CODE (XEXP (SET_SRC (x), 1)) == CONST_INT + && 0 != (new = simplify_binary_operation + (GET_CODE (SET_SRC (x)), GET_MODE (dest), + p->const_equiv[REGNO (XEXP (SET_SRC (x), 0))], + XEXP (SET_SRC (x), 1))) + && GET_CODE (new) == CONST_INT) + p->const_equiv[REGNO (dest)] = new; + + /* Otherwise, we can't do anything with this value. */ + else + p->const_equiv[REGNO (dest)] = 0; } /* Emit an insn to do the load shown in p->equiv_reg_src, if needed. */ |

