From 99b86c051f74bd0a801569a8c93da9cd2f6b80da Mon Sep 17 00:00:00 2001 From: kenner Date: Sat, 17 Feb 2001 19:50:58 +0000 Subject: [PATCH] * recog.c (validate_replace_src_1): New. (validate_replace_src_data): Likewise. (validate_replace_src): Use note_uses. * rtl.h (note_uses): Declare. * rtlanal.c (note_uses): New. git-svn-id: svn+ssh://gcc.gnu.org/svn/gcc/trunk@39804 138bc75d-0d04-0410-961f-82ee72b054a4 --- gcc/ChangeLog | 9 +++++++ gcc/recog.c | 40 ++++++++++++++++----------- gcc/rtl.h | 3 +++ gcc/rtlanal.c | 86 +++++++++++++++++++++++++++++++++++++++++++++++++++++++++-- 4 files changed, 120 insertions(+), 18 deletions(-) diff --git a/gcc/ChangeLog b/gcc/ChangeLog index 1c1c425..11e9a8e 100644 --- a/gcc/ChangeLog +++ b/gcc/ChangeLog @@ -1,3 +1,12 @@ +Sat Feb 17 14:48:30 2001 Richard Kenner + Jan Hubicka + + * recog.c (validate_replace_src_1): New. + (validate_replace_src_data): Likewise. + (validate_replace_src): Use note_uses. + * rtl.h (note_uses): Declare. + * rtlanal.c (note_uses): New. + Sat Feb 17 10:52:34 CET 2001 Jan Hubicka * reg-stack.c (stack_def): Make field reg unsigned. diff --git a/gcc/recog.c b/gcc/recog.c index f778f60..d6cdf54 100644 --- a/gcc/recog.c +++ b/gcc/recog.c @@ -1,6 +1,6 @@ /* Subroutines used by or related to instruction recognition. Copyright (C) 1987, 1988, 1991, 1992, 1993, 1994, 1995, 1996, 1997, 1998 - 1999, 2000 Free Software Foundation, Inc. + 1999, 2000, 2001 Free Software Foundation, Inc. This file is part of GNU CC. @@ -59,6 +59,7 @@ static void validate_replace_rtx_1 PARAMS ((rtx *, rtx, rtx, rtx)); static rtx *find_single_use_1 PARAMS ((rtx, rtx *)); static rtx *find_constant_term_loc PARAMS ((rtx *)); static int insn_invalid_p PARAMS ((rtx)); +static void validate_replace_src_1 PARAMS ((rtx *, void *)); /* Nonzero means allow operands to be volatile. This should be 0 if you are generating rtl, such as if you are calling @@ -741,6 +742,23 @@ validate_replace_rtx_group (from, to, insn) validate_replace_rtx_1 (&PATTERN (insn), from, to, insn); } +/* Function called by note_uses to replace used subexpressions. */ +struct validate_replace_src_data + { + rtx from, to, insn; + }; + +static void +validate_replace_src_1 (x, data) + rtx *x; + void *data; +{ + struct validate_replace_src_data *d + = (struct validate_replace_src_data *) data; + + validate_replace_rtx_1 (x, d->from, d->to, d->insn); +} + /* Try replacing every occurrence of FROM in INSN with TO, avoiding SET_DESTs. After all changes have been made, validate by seeing if INSN is still valid. */ @@ -749,22 +767,12 @@ int validate_replace_src (from, to, insn) rtx from, to, insn; { - if ((GET_CODE (insn) != INSN && GET_CODE (insn) != JUMP_INSN) - || GET_CODE (PATTERN (insn)) != SET) - abort (); - - validate_replace_rtx_1 (&SET_SRC (PATTERN (insn)), from, to, insn); - if (GET_CODE (SET_DEST (PATTERN (insn))) == MEM) - validate_replace_rtx_1 (&XEXP (SET_DEST (PATTERN (insn)), 0), - from, to, insn); - else if (GET_CODE (SET_DEST (PATTERN (insn))) == ZERO_EXTRACT) - { - validate_replace_rtx_1 (&XEXP (SET_DEST (PATTERN (insn)), 1), - from, to, insn); - validate_replace_rtx_1 (&XEXP (SET_DEST (PATTERN (insn)), 2), - from, to, insn); - } + struct validate_replace_src_data d; + d.from = from; + d.to = to; + d.insn = insn; + note_uses (&PATTERN (insn), validate_replace_src_1, &d); return apply_change_group (); } diff --git a/gcc/rtl.h b/gcc/rtl.h index f6eb251..ecbde55 100644 --- a/gcc/rtl.h +++ b/gcc/rtl.h @@ -1403,6 +1403,9 @@ extern rtx set_of PARAMS ((rtx, rtx)); extern void note_stores PARAMS ((rtx, void (*) (rtx, rtx, void *), void *)); +extern void note_uses PARAMS ((rtx *, + void (*) (rtx *, void *), + void *)); extern rtx reg_set_last PARAMS ((rtx, rtx)); extern int dead_or_set_p PARAMS ((rtx, rtx)); extern int dead_or_set_regno_p PARAMS ((rtx, unsigned int)); diff --git a/gcc/rtlanal.c b/gcc/rtlanal.c index 0eefa70..5dc2af5 100644 --- a/gcc/rtlanal.c +++ b/gcc/rtlanal.c @@ -25,10 +25,9 @@ Boston, MA 02111-1307, USA. */ #include "toplev.h" #include "rtl.h" +/* Forward declarations */ static void set_of_1 PARAMS ((rtx, rtx, void *)); static void insn_dependent_p_1 PARAMS ((rtx, rtx, void *)); - -/* Forward declarations */ static int computed_jump_p_1 PARAMS ((rtx)); /* Bit flags that specify the machine subtype we are compiling for. @@ -1303,6 +1302,89 @@ note_stores (x, fun, data) note_stores (XVECEXP (x, 0, i), fun, data); } +/* Like notes_stores, but call FUN for each expression that is being + referenced in PBODY, a pointer to the PATTERN of an insn. We only call + FUN for each expression, not any interior subexpressions. FUN receives a + pointer to the expression and the DATA passed to this function. + + Note that this is not quite the same test as that done in reg_referenced_p + since that considers something as being referenced if it is being + partially set, while we do not. */ + +void +note_uses (pbody, fun, data) + rtx *pbody; + void (*fun) PARAMS ((rtx *, void *)); + void *data; +{ + rtx body = *pbody; + int i; + + switch (GET_CODE (body)) + { + case COND_EXEC: + (*fun) (&COND_EXEC_TEST (body), data); + note_uses (&COND_EXEC_CODE (body), fun, data); + return; + + case PARALLEL: + for (i = XVECLEN (body, 0) - 1; i >= 0; i--) + note_uses (&XVECEXP (body, 0, i), fun, data); + return; + + case USE: + (*fun) (&XEXP (body, 0), data); + return; + + case ASM_OPERANDS: + for (i = ASM_OPERANDS_INPUT_LENGTH (body) - 1; i >= 0; i--) + (*fun) (&ASM_OPERANDS_INPUT (body, i), data); + return; + + case TRAP_IF: + (*fun) (&TRAP_CONDITION (body), data); + return; + + case UNSPEC: + case UNSPEC_VOLATILE: + for (i = XVECLEN (body, 0) - 1; i >= 0; i--) + (*fun) (&XVECEXP (body, 0, i), data); + return; + + case CLOBBER: + if (GET_CODE (XEXP (body, 0)) == MEM) + (*fun) (&XEXP (XEXP (body, 0), 0), data); + return; + + case SET: + { + rtx dest = SET_DEST (body); + + /* For sets we replace everything in source plus registers in memory + expression in store and operands of a ZERO_EXTRACT. */ + (*fun) (&SET_SRC (body), data); + + if (GET_CODE (dest) == ZERO_EXTRACT) + { + (*fun) (&XEXP (dest, 1), data); + (*fun) (&XEXP (dest, 2), data); + } + + while (GET_CODE (dest) == SUBREG || GET_CODE (dest) == STRICT_LOW_PART) + dest = XEXP (dest, 0); + + if (GET_CODE (dest) == MEM) + (*fun) (&XEXP (dest, 0), data); + } + return; + + default: + /* All the other possibilities never store. */ + (*fun) (pbody, data); + return; + } +} + /* Return nonzero if X's old contents don't survive after INSN. This will be true if X is (cc0) or if X is a register and X dies in INSN or because INSN entirely sets X. -- 2.7.4