diff options
author | Jan Hubicka <jh@suse.cz> | 2001-01-07 14:06:43 +0100 |
---|---|---|
committer | Jan Hubicka <hubicka@gcc.gnu.org> | 2001-01-07 13:06:43 +0000 |
commit | 91b2d1199a36e4799d1a238a6ec52ecb36893661 (patch) | |
tree | a6cc4c90e6c6bd79c136ac5f230c44bcb11cc27c /gcc | |
parent | 796cdb659f4c0f015e92c41b3fcf3ff1ad7c3f88 (diff) | |
download | gcc-91b2d1199a36e4799d1a238a6ec52ecb36893661.zip gcc-91b2d1199a36e4799d1a238a6ec52ecb36893661.tar.gz gcc-91b2d1199a36e4799d1a238a6ec52ecb36893661.tar.bz2 |
rtlanal.c (set_of_1): New static function.
* rtlanal.c (set_of_1): New static function.
(reg_set_last_1, reg_set_p_1, reg_set_reg, reg_set_flag,
reg_set_last_unknown, reg_set_last_value, reg_set_last_first_regno,
reg_set_last_last_regno): Remove.
(set_of): New global function.
(set_of_data): New structure.
(reg_set_p, reg_set_last): Revamp for set_of.
* rtl.h (set_of): New.
From-SVN: r38772
Diffstat (limited to 'gcc')
-rw-r--r-- | gcc/ChangeLog | 11 | ||||
-rw-r--r-- | gcc/rtl.h | 1 | ||||
-rw-r--r-- | gcc/rtlanal.c | 131 |
3 files changed, 59 insertions, 84 deletions
diff --git a/gcc/ChangeLog b/gcc/ChangeLog index 2aa50d0..887605c 100644 --- a/gcc/ChangeLog +++ b/gcc/ChangeLog @@ -1,3 +1,14 @@ +Sun Jan 7 13:49:19 MET 2001 Jan Hubicka <jh@suse.cz> + + * rtlanal.c (set_of_1): New static function. + (reg_set_last_1, reg_set_p_1, reg_set_reg, reg_set_flag, + reg_set_last_unknown, reg_set_last_value, reg_set_last_first_regno, + reg_set_last_last_regno): Remove. + (set_of): New global function. + (set_of_data): New structure. + (reg_set_p, reg_set_last): Revamp for set_of. + * rtl.h (set_of): New. + 2001-01-07 Joseph S. Myers <jsm28@cam.ac.uk> * c-common.c (c_common_nodes_and_builtins): Add _Exit builtin. @@ -1378,6 +1378,7 @@ extern rtx find_last_value PARAMS ((rtx, rtx *, rtx, int)); extern int refers_to_regno_p PARAMS ((unsigned int, unsigned int, rtx, rtx *)); extern int reg_overlap_mentioned_p PARAMS ((rtx, rtx)); +extern rtx set_of PARAMS ((rtx, rtx)); extern void note_stores PARAMS ((rtx, void (*) (rtx, rtx, void *), void *)); diff --git a/gcc/rtlanal.c b/gcc/rtlanal.c index b0fbcf31..d58f392 100644 --- a/gcc/rtlanal.c +++ b/gcc/rtlanal.c @@ -25,10 +25,8 @@ Boston, MA 02111-1307, USA. */ #include "toplev.h" #include "rtl.h" -static void reg_set_p_1 PARAMS ((rtx, rtx, void *)); +static void set_of_1 PARAMS ((rtx, rtx, void *)); static void insn_dependent_p_1 PARAMS ((rtx, rtx, void *)); -static void reg_set_last_1 PARAMS ((rtx, rtx, void *)); - /* Forward declarations */ static int jmp_uses_reg_or_mem PARAMS ((rtx)); @@ -617,24 +615,6 @@ reg_set_between_p (reg, from_insn, to_insn) } /* Internals of reg_set_between_p. */ - -static rtx reg_set_reg; -static int reg_set_flag; - -static void -reg_set_p_1 (x, pat, data) - rtx x; - rtx pat ATTRIBUTE_UNUSED; - void *data ATTRIBUTE_UNUSED; -{ - /* We don't want to return 1 if X is a MEM that contains a register - within REG_SET_REG. */ - - if ((GET_CODE (x) != MEM) - && reg_overlap_mentioned_p (reg_set_reg, x)) - reg_set_flag = 1; -} - int reg_set_p (reg, insn) rtx reg, insn; @@ -662,10 +642,7 @@ reg_set_p (reg, insn) body = PATTERN (insn); } - reg_set_reg = reg; - reg_set_flag = 0; - note_stores (body, reg_set_p_1, NULL); - return reg_set_flag; + return set_of (reg, insn) != NULL_RTX; } /* Similar to reg_set_between_p, but check all registers in X. Return 0 @@ -863,6 +840,38 @@ insn_dependent_p_1 (x, pat, data) *pinsn = NULL_RTX; } +/* Helper function for set_of. */ +struct set_of_data + { + rtx found; + rtx pat; + }; + +static void +set_of_1 (x, pat, data1) + rtx x; + rtx pat; + void *data1; +{ + struct set_of_data *data = (struct set_of_data *) (data1); + if (rtx_equal_p (x, data->pat) + || (GET_CODE (x) != MEM && reg_overlap_mentioned_p (data->pat, x))) + data->found = pat; +} + +/* Give an INSN, return a SET or CLOBBER expression that does modify PAT + (eighter directly or via STRICT_LOW_PART and similar modifiers). */ +rtx +set_of (pat, insn) + rtx pat, insn; +{ + struct set_of_data data; + data.found = NULL_RTX; + data.pat = pat; + note_stores (INSN_P (insn) ? PATTERN (insn) : insn, set_of_1, &data); + return data.found; +} + /* Given an INSN, return a SET expression if this insn has only a single SET. It may also have CLOBBERs, USEs, or SET whose output will not be used, which we ignore. */ @@ -1196,45 +1205,6 @@ reg_overlap_mentioned_p (x, in) abort (); } -/* Used for communications between the next few functions. */ - -static int reg_set_last_unknown; -static rtx reg_set_last_value; -static unsigned int reg_set_last_first_regno, reg_set_last_last_regno; - -/* Called via note_stores from reg_set_last. */ - -static void -reg_set_last_1 (x, pat, data) - rtx x; - rtx pat; - void *data ATTRIBUTE_UNUSED; -{ - unsigned int first, last; - - /* If X is not a register, or is not one in the range we care - about, ignore. */ - if (GET_CODE (x) != REG) - return; - - first = REGNO (x); - last = first + (first < FIRST_PSEUDO_REGISTER - ? HARD_REGNO_NREGS (first, GET_MODE (x)) : 1); - - if (first >= reg_set_last_last_regno - || last <= reg_set_last_first_regno) - return; - - /* If this is a CLOBBER or is some complex LHS, or doesn't modify - exactly the registers we care about, show we don't know the value. */ - if (GET_CODE (pat) == CLOBBER || SET_DEST (pat) != x - || first != reg_set_last_first_regno - || last != reg_set_last_last_regno) - reg_set_last_unknown = 1; - else - reg_set_last_value = SET_SRC (pat); -} - /* Return the last value to which REG was set prior to INSN. If we can't find it easily, return 0. @@ -1248,16 +1218,6 @@ reg_set_last (x, insn) { rtx orig_insn = insn; - reg_set_last_first_regno = REGNO (x); - - reg_set_last_last_regno - = reg_set_last_first_regno - + (reg_set_last_first_regno < FIRST_PSEUDO_REGISTER - ? HARD_REGNO_NREGS (reg_set_last_first_regno, GET_MODE (x)) : 1); - - reg_set_last_unknown = 0; - reg_set_last_value = 0; - /* Scan backwards until reg_set_last_1 changed one of the above flags. Stop when we reach a label or X is a hard reg and we reach a CALL_INSN (if reg_set_last_last_regno is a hard reg). @@ -1269,21 +1229,24 @@ reg_set_last (x, insn) for (; insn && GET_CODE (insn) != CODE_LABEL && ! (GET_CODE (insn) == CALL_INSN - && reg_set_last_last_regno <= FIRST_PSEUDO_REGISTER); + && REGNO (x) <= FIRST_PSEUDO_REGISTER); insn = PREV_INSN (insn)) if (INSN_P (insn)) { - note_stores (PATTERN (insn), reg_set_last_1, NULL); - if (reg_set_last_unknown) - return 0; - else if (reg_set_last_value) + rtx set = set_of (x, insn); + /* OK, this function modify our register. See if we understand it. */ + if (set) { - if (CONSTANT_P (reg_set_last_value) - || ((GET_CODE (reg_set_last_value) == REG - || GET_CODE (reg_set_last_value) == SUBREG) - && ! reg_set_between_p (reg_set_last_value, + rtx last_value; + if (GET_CODE (set) != SET || SET_DEST (set) != x) + return 0; + last_value = SET_SRC (x); + if (CONSTANT_P (last_value) + || ((GET_CODE (last_value) == REG + || GET_CODE (last_value) == SUBREG) + && ! reg_set_between_p (last_value, insn, orig_insn))) - return reg_set_last_value; + return last_value; else return 0; } |