summaryrefslogtreecommitdiff
path: root/gcc/cselib.c
diff options
context:
space:
mode:
authorbstarynk <bstarynk@138bc75d-0d04-0410-961f-82ee72b054a4>2009-09-14 05:17:41 +0000
committerbstarynk <bstarynk@138bc75d-0d04-0410-961f-82ee72b054a4>2009-09-14 05:17:41 +0000
commit4f61e50d1cb81f3caced1e4cfe6ae22327a93925 (patch)
treef88d3a397949e313a970b9ac73ff0020ab38fcda /gcc/cselib.c
parentf213a307a1e54b1a4a61904f697c605085fd4c84 (diff)
downloadgcc-4f61e50d1cb81f3caced1e4cfe6ae22327a93925.tar.gz
2009-09-14 Basile Starynkevitch <basile@starynkevitch.net>
MELT branch merged with trunk rev 151679 git-svn-id: svn+ssh://gcc.gnu.org/svn/gcc/branches/melt-branch@151680 138bc75d-0d04-0410-961f-82ee72b054a4
Diffstat (limited to 'gcc/cselib.c')
-rw-r--r--gcc/cselib.c50
1 files changed, 31 insertions, 19 deletions
diff --git a/gcc/cselib.c b/gcc/cselib.c
index 927f93cbb79..e6e5c143dad 100644
--- a/gcc/cselib.c
+++ b/gcc/cselib.c
@@ -1053,7 +1053,10 @@ cselib_expand_value_rtx (rtx orig, bitmap regs_active, int max_depth)
}
/* Same as cselib_expand_value_rtx, but using a callback to try to
- resolve VALUEs that expand to nothing. */
+ resolve some expressions. The CB function should return ORIG if it
+ can't or does not want to deal with a certain RTX. Any other
+ return value, including NULL, will be used as the expansion for
+ VALUE, without any further changes. */
rtx
cselib_expand_value_rtx_cb (rtx orig, bitmap regs_active, int max_depth,
@@ -1068,6 +1071,9 @@ cselib_expand_value_rtx_cb (rtx orig, bitmap regs_active, int max_depth,
return cselib_expand_value_rtx_1 (orig, &evd, max_depth);
}
+/* Internal implementation of cselib_expand_value_rtx and
+ cselib_expand_value_rtx_cb. */
+
static rtx
cselib_expand_value_rtx_1 (rtx orig, struct expand_value_data *evd,
int max_depth)
@@ -1158,26 +1164,36 @@ cselib_expand_value_rtx_1 (rtx orig, struct expand_value_data *evd,
case SUBREG:
{
- rtx subreg = cselib_expand_value_rtx_1 (SUBREG_REG (orig), evd,
- max_depth - 1);
+ rtx subreg;
+
+ if (evd->callback)
+ {
+ subreg = evd->callback (orig, evd->regs_active, max_depth,
+ evd->callback_arg);
+ if (subreg != orig)
+ return subreg;
+ }
+
+ subreg = cselib_expand_value_rtx_1 (SUBREG_REG (orig), evd,
+ max_depth - 1);
if (!subreg)
return NULL;
scopy = simplify_gen_subreg (GET_MODE (orig), subreg,
GET_MODE (SUBREG_REG (orig)),
SUBREG_BYTE (orig));
- if ((scopy == NULL
- || (GET_CODE (scopy) == SUBREG
- && !REG_P (SUBREG_REG (scopy))
- && !MEM_P (SUBREG_REG (scopy))))
- && (REG_P (SUBREG_REG (orig))
- || MEM_P (SUBREG_REG (orig))))
- return shallow_copy_rtx (orig);
+ if (scopy == NULL
+ || (GET_CODE (scopy) == SUBREG
+ && !REG_P (SUBREG_REG (scopy))
+ && !MEM_P (SUBREG_REG (scopy))))
+ return NULL;
+
return scopy;
}
case VALUE:
{
rtx result;
+
if (dump_file && (dump_flags & TDF_DETAILS))
{
fputs ("\nexpanding ", dump_file);
@@ -1185,20 +1201,16 @@ cselib_expand_value_rtx_1 (rtx orig, struct expand_value_data *evd,
fputs (" into...", dump_file);
}
- if (!evd->callback)
- result = NULL;
- else
+ if (evd->callback)
{
result = evd->callback (orig, evd->regs_active, max_depth,
evd->callback_arg);
- if (result == orig)
- result = NULL;
- else if (result)
- result = cselib_expand_value_rtx_1 (result, evd, max_depth);
+
+ if (result != orig)
+ return result;
}
- if (!result)
- result = expand_loc (CSELIB_VAL_PTR (orig)->locs, evd, max_depth);
+ result = expand_loc (CSELIB_VAL_PTR (orig)->locs, evd, max_depth);
return result;
}
default: