diff options
author | hubicka <hubicka@138bc75d-0d04-0410-961f-82ee72b054a4> | 2000-09-29 11:24:13 +0000 |
---|---|---|
committer | hubicka <hubicka@138bc75d-0d04-0410-961f-82ee72b054a4> | 2000-09-29 11:24:13 +0000 |
commit | 6531eca959da0a7e2999f602420911093844e742 (patch) | |
tree | daf24fe6a604f9c91a67080db41f6d3f1e17db76 /gcc/rtlanal.c | |
parent | 15bb264be412ea9e9a9875d4dbe37408bf0e4fe7 (diff) | |
download | gcc-6531eca959da0a7e2999f602420911093844e742.tar.gz |
* recog.c (recog_memoized): Rename to recog_memoized_1.
* recog.h (recog_memoized): Rename to recog_memoized_1.
(recog_memoized): New macro.
* rtl.h (single_set): Rename to single_set_1
(single_set): New macro.
* rtlanal.c (single_set): Rename to single_set_1; expect clobbers
to be last.
* i386.md (strmovsi_1, strmovhi_1 strmovqi_1):
Do not use match_dup of input operands at outputs.
Use register_operand for memory expression.
(rep_movsi): Put use last, canonicalize.
Use register_operand for memory expression.
(rep_movqi): Put use last.
Use register_operand for memory expression.
(strsetsi_1, strset_hi_1, strsetqi_1): Do not use match_dup
of input operands at outputs. Use register_operand for memory
expression.
(rep_stossi): Put use last; canonicalize; fix match_dup in
the address expression
(rep_stosqi): Likewise.
(memcmp expander): Update calls.
(cmpstrsi_nz_1, cmpstrsi_1, strlensi_1): Avoid match_dups in
the clobbers.
* i386.md (fp_jcc_3, fp_jcc_4, jp_fcc_5): if_then_else operand is
VOIDmode.
(fp_jcc_4, fp_jcc_3): Refuse unordered comparisons.
git-svn-id: svn+ssh://gcc.gnu.org/svn/gcc/trunk@36664 138bc75d-0d04-0410-961f-82ee72b054a4
Diffstat (limited to 'gcc/rtlanal.c')
-rw-r--r-- | gcc/rtlanal.c | 99 |
1 files changed, 72 insertions, 27 deletions
diff --git a/gcc/rtlanal.c b/gcc/rtlanal.c index c19b3f5fa97..0d922c66c43 100644 --- a/gcc/rtlanal.c +++ b/gcc/rtlanal.c @@ -842,46 +842,91 @@ insn_dependent_p_1 (x, pat, data) will not be used, which we ignore. */ rtx -single_set (insn) +single_set_1 (insn) rtx insn; { rtx set; + rtx pat = PATTERN (insn); int i; - if (! INSN_P (insn)) - return 0; - - if (GET_CODE (PATTERN (insn)) == SET) - return PATTERN (insn); - - else if (GET_CODE (PATTERN (insn)) == PARALLEL) + if (GET_CODE (pat) == PARALLEL) { - for (i = 0, set = 0; i < XVECLEN (PATTERN (insn), 0); i++) + 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)) { - rtx sub = XVECEXP (PATTERN (insn), 0, i); - - switch (GET_CODE (sub)) +#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. */ + abort(); +#endif + case SET: + break; + default: + return NULL_RTX; + } + x = XVECEXP (pat, 0, 1); + switch (GET_CODE (x)) + { + 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) + abort(); +#endif + return set; + case SET: + /* Multiple set insns - we are off the critical path now. */ + for (i = XVECLEN (pat, 0) - 1; i > 0; i--) { - case USE: - case CLOBBER: - break; - - case SET: - if (! find_reg_note (insn, REG_UNUSED, SET_DEST (sub)) - || side_effects_p (sub)) + sub = XVECEXP (pat, 0, i); + switch GET_CODE (sub) { - if (set) - return 0; - else + case USE: + case CLOBBER: + break; + + case SET: + if (!set + || (find_reg_note (insn, REG_UNUSED, SET_DEST (set)) + && side_effects_p (set))) set = sub; - } - break; + else if (! find_reg_note (insn, REG_UNUSED, SET_DEST (sub)) + || side_effects_p (sub)) + return NULL_RTX; + break; - default: - return 0; + default: + return NULL_RTX; + } } + return set; + default: + return NULL_RTX; } - return set; } return 0; |