diff options
author | bstarynk <bstarynk@138bc75d-0d04-0410-961f-82ee72b054a4> | 2008-12-08 17:52:47 +0000 |
---|---|---|
committer | bstarynk <bstarynk@138bc75d-0d04-0410-961f-82ee72b054a4> | 2008-12-08 17:52:47 +0000 |
commit | 005927ac5d0090e0405b3401fbeee84251f091ff (patch) | |
tree | 01747a73ce7036ad011a130b219a7c40b14c4515 /gcc/cse.c | |
parent | da9055d29af60e521b94ef9d06e5e99f4e79e6a9 (diff) | |
download | gcc-005927ac5d0090e0405b3401fbeee84251f091ff.tar.gz |
2008-12-08 Basile Starynkevitch <basile@starynkevitch.net>
MELT branch merged with trunk r142553
2008-12-08 Basile Starynkevitch <basile@starynkevitch.net>
* gcc/Makefile.in: using BACKENDLIBS as merged from trunk r142553
git-svn-id: svn+ssh://gcc.gnu.org/svn/gcc/branches/melt-branch@142557 138bc75d-0d04-0410-961f-82ee72b054a4
Diffstat (limited to 'gcc/cse.c')
-rw-r--r-- | gcc/cse.c | 32 |
1 files changed, 19 insertions, 13 deletions
diff --git a/gcc/cse.c b/gcc/cse.c index f52f0a9c93d..91cb108e94c 100644 --- a/gcc/cse.c +++ b/gcc/cse.c @@ -1364,17 +1364,6 @@ lookup_as_function (rtx x, enum rtx_code code) struct table_elt *p = lookup (x, SAFE_HASH (x, VOIDmode), GET_MODE (x)); - /* If we are looking for a CONST_INT, the mode doesn't really matter, as - long as we are narrowing. So if we looked in vain for a mode narrower - than word_mode before, look for word_mode now. */ - if (p == 0 && code == CONST_INT - && GET_MODE_SIZE (GET_MODE (x)) < GET_MODE_SIZE (word_mode)) - { - x = copy_rtx (x); - PUT_MODE (x, word_mode); - p = lookup (x, SAFE_HASH (x, VOIDmode), word_mode); - } - if (p == 0) return 0; @@ -3641,6 +3630,8 @@ equiv_constant (rtx x) if (GET_CODE (x) == SUBREG) { + enum machine_mode mode = GET_MODE (x); + enum machine_mode imode = GET_MODE (SUBREG_REG (x)); rtx new_rtx; /* See if we previously assigned a constant value to this SUBREG. */ @@ -3649,10 +3640,25 @@ equiv_constant (rtx x) || (new_rtx = lookup_as_function (x, CONST_FIXED)) != 0) return new_rtx; + /* If we didn't and if doing so makes sense, see if we previously + assigned a constant value to the enclosing word mode SUBREG. */ + if (GET_MODE_SIZE (mode) < GET_MODE_SIZE (word_mode) + && GET_MODE_SIZE (word_mode) < GET_MODE_SIZE (imode)) + { + int byte = SUBREG_BYTE (x) - subreg_lowpart_offset (mode, word_mode); + if (byte >= 0 && (byte % UNITS_PER_WORD) == 0) + { + rtx y = gen_rtx_SUBREG (word_mode, SUBREG_REG (x), byte); + new_rtx = lookup_as_function (y, CONST_INT); + if (new_rtx) + return gen_lowpart (mode, new_rtx); + } + } + + /* Otherwise see if we already have a constant for the inner REG. */ if (REG_P (SUBREG_REG (x)) && (new_rtx = equiv_constant (SUBREG_REG (x))) != 0) - return simplify_subreg (GET_MODE (x), new_rtx, - GET_MODE (SUBREG_REG (x)), SUBREG_BYTE (x)); + return simplify_subreg (mode, new_rtx, imode, SUBREG_BYTE (x)); return 0; } |