diff options
author | Jan Hubicka <jh@suse.cz> | 2000-10-03 07:26:42 +0000 |
---|---|---|
committer | Jan Hubicka <hubicka@gcc.gnu.org> | 2000-10-03 07:26:42 +0000 |
commit | c9b89a214a0213a9363cf5e729b7b6e041c90af2 (patch) | |
tree | 1a1fd2ed2c67e31f0881d9a70fd142817a5f3f44 /gcc | |
parent | 81bce466fe3e4220142dc0604248b6f4c723b4ce (diff) | |
download | gcc-c9b89a214a0213a9363cf5e729b7b6e041c90af2.zip gcc-c9b89a214a0213a9363cf5e729b7b6e041c90af2.tar.gz gcc-c9b89a214a0213a9363cf5e729b7b6e041c90af2.tar.bz2 |
rtlanal.c (single_set_1): Do not require USE and CLOBBERs to come last.
* rtlanal.c (single_set_1): Do not require USE and CLOBBERs
to come last.
From-SVN: r36699
Diffstat (limited to 'gcc')
-rw-r--r-- | gcc/ChangeLog | 5 | ||||
-rw-r--r-- | gcc/rtlanal.c | 122 |
2 files changed, 43 insertions, 84 deletions
diff --git a/gcc/ChangeLog b/gcc/ChangeLog index 7626655..405b691 100644 --- a/gcc/ChangeLog +++ b/gcc/ChangeLog @@ -1,3 +1,8 @@ +Mon Oct 2 14:50:14 MET DST 2000 Jan Hubicka <jh@suse.cz> + + * rtlanal.c (single_set_1): Do not require USE and CLOBBERs + to come last. + 2000-10-03 Michael Hayes <m.hayes@elec.canterbury.ac.nz> * config/float-c4x.h: New. diff --git a/gcc/rtlanal.c b/gcc/rtlanal.c index 2e1ae14..8edcdbc 100644 --- a/gcc/rtlanal.c +++ b/gcc/rtlanal.c @@ -846,98 +846,52 @@ rtx single_set_1 (insn) rtx insn; { - rtx set; + rtx set = NULL; + int set_verified = 1; rtx pat = PATTERN (insn); int i; - + if (GET_CODE (pat) == PARALLEL) { - rtx x, sub; - /* This part is is performance critical for targets that use a lot of - parallels, such as i386. We want to accept as single set - instructions even an instructions with multiple sets where only - one has live result, but we attempt to delay this tests only for - multiple set instructions to reduce amount of calls to - find_reg_note and side_effects_p. - - We expect the "common" instruction to be parallel with first SET - followed by the clobbers. So first we get the set, then look - if it is followed by USE or CLOBBER. If so, we just return expect - no SETs after these. When SET is followed by another SET, we - continue by the clomplex loop trought all members of PARALLEL. - */ -#ifdef ENABLE_CHECKING - if (XVECLEN (pat, 0) < 2) - abort (); -#endif - set = XVECEXP (pat, 0, 0); - switch (GET_CODE (set)) - { -#ifdef ENABLE_CHECKING - case USE: - case CLOBBER: - /* Instruction should not consist only from USEs and CLOBBERS, - since then gcc is allowed to remove it entirely. In case - something else is present, it should be first in the pattern. */ - fatal_insn ("USE or CLOBBER before SET:", insn); -#endif - case SET: - break; - default: - return NULL_RTX; - } - x = XVECEXP (pat, 0, 1); - switch (GET_CODE (x)) + for (i = 0; i < XVECLEN (pat, 0); i++) { - case USE: - case CLOBBER: -#ifdef ENABLE_CHECKING - /* The USEs and CLOBBERs should always come last in the pattern. */ - for (i = XVECLEN (pat, 0) - 1; i > 1; i--) - if (GET_CODE (XVECEXP (pat, 0, i)) != USE - && GET_CODE (XVECEXP (pat, 0, i)) != CLOBBER) - fatal_insn ("USE or CLOBBER before SET:", insn); -#endif - return set; - case SET: - { - int seen_clobber = 0; + rtx sub = XVECEXP (pat, 0, i); + switch (GET_CODE (sub)) + { + case USE: + case CLOBBER: + break; - /* Multiple set insns - we are off the critical path now. */ - for (i = 1; i < XVECLEN (pat, 0); i++) - { - sub = XVECEXP (pat, 0, i); - switch GET_CODE (sub) - { - case USE: - case CLOBBER: - seen_clobber = 1; - break; - - case SET: - if (seen_clobber) - fatal_insn ("USE or CLOBBER before SET:", insn); - if (!set - || (find_reg_note (insn, REG_UNUSED, SET_DEST (set)) - && side_effects_p (set))) - set = sub; - else if (! find_reg_note (insn, REG_UNUSED, SET_DEST (sub)) - || side_effects_p (sub)) - return NULL_RTX; - break; - - default: - return NULL_RTX; - } - } - } - return set; - default: - return NULL_RTX; + case SET: + /* We can consider insns having multiple sets, where all + but one are dead as single set insns. In common case + only single set is present in the pattern so we want + to avoid checking for REG_UNUSED notes unless neccesary. + + When we reach set first time, we just expect this is + the single set we are looking for and only when more + sets are found in the insn, we check them. */ + if (!set_verified) + { + if (find_reg_note (insn, REG_UNUSED, SET_DEST (set)) + && !side_effects_p (set)) + set = NULL; + else + set_verified = 1; + } + if (!set) + set = sub, set_verified = 0; + else if (!find_reg_note (insn, REG_UNUSED, SET_DEST (sub)) + || side_effects_p (sub)) + return NULL_RTX; + break; + + default: + return NULL_RTX; + } } } - - return 0; + return set; } /* Given an INSN, return nonzero if it has more than one SET, else return |