diff options
author | Mark Mitchell <mark@codesourcery.com> | 2001-03-19 18:53:04 +0000 |
---|---|---|
committer | Mark Mitchell <mmitchel@gcc.gnu.org> | 2001-03-19 18:53:04 +0000 |
commit | 68e568c28eb6e4d15b06dc23b27168e783ce008c (patch) | |
tree | b54bc88743a41fe139d4d714ef19b50f51dcb79b /gcc/cse.c | |
parent | d4b6faf649a1b8f5d84e1e1711a8e66476250de3 (diff) | |
download | gcc-68e568c28eb6e4d15b06dc23b27168e783ce008c.zip gcc-68e568c28eb6e4d15b06dc23b27168e783ce008c.tar.gz gcc-68e568c28eb6e4d15b06dc23b27168e783ce008c.tar.bz2 |
cse.c (find_comparison_args): Update documentation.
* cse.c (find_comparison_args): Update documentation. Fix
mishandling of COMPARE operations.
* tree.def (ABS_EXPR): Add documentation.
* fold-const.c (fold): Improve folding of ABS_EXPRs.
From-SVN: r40630
Diffstat (limited to 'gcc/cse.c')
-rw-r--r-- | gcc/cse.c | 78 |
1 files changed, 47 insertions, 31 deletions
@@ -3086,17 +3086,25 @@ find_best_addr (insn, loc, mode) #endif } -/* Given an operation (CODE, *PARG1, *PARG2), where code is a comparison - operation (EQ, NE, GT, etc.), follow it back through the hash table and - what values are being compared. +/* This routine accepts a comparison as input and attempts to return a + comparision that is cheaper to compute. - *PARG1 and *PARG2 are updated to contain the rtx representing the values - actually being compared. For example, if *PARG1 was (cc0) and *PARG2 - was (const_int 0), *PARG1 and *PARG2 will be set to the objects that were - compared to produce cc0. + On input, *PARG1 and *PARG2 should be set to the first and second + arguments to the comparison, respectively. CODE is the comparision + code. For example, if the comparison is: - The return value is the comparison operator and is either the code of - A or the code corresponding to the inverse of the comparison. */ + (ne:SI (reg:CC 24 cc) + (const_int 0 [0x0]))) + + The CODE should be NE, *PARG1 should be `(reg:CC 24 cc)' and + *PARG2 should be `(const_int 0)'. + + Upon return, *PARG1 and and *PARG2 may have new values, indicating + arguments to a cheaper comparison. *PMODE1 and *PMODE2 will be the + modes that should be used for those arguments. The return value + itself will be the comparison code that should be used to compare + *PARG1 and *PARG2 in order to obtain a value equivalent to that + given by the original comparison. */ static enum rtx_code find_comparison_args (code, parg1, parg2, pmode1, pmode2) @@ -3187,30 +3195,38 @@ find_comparison_args (code, parg1, parg2, pmode1, pmode2) if (! exp_equiv_p (p->exp, p->exp, 1, 0)) continue; - if (GET_CODE (p->exp) == COMPARE - /* Another possibility is that this machine has a compare insn - that includes the comparison code. In that case, ARG1 would - be equivalent to a comparison operation that would set ARG1 to - either STORE_FLAG_VALUE or zero. If this is an NE operation, - ORIG_CODE is the actual comparison being done; if it is an EQ, - we must reverse ORIG_CODE. On machine with a negative value - for STORE_FLAG_VALUE, also look at LT and GE operations. */ - || ((code == NE - || (code == LT - && GET_MODE_CLASS (inner_mode) == MODE_INT - && (GET_MODE_BITSIZE (inner_mode) - <= HOST_BITS_PER_WIDE_INT) - && (STORE_FLAG_VALUE - & ((HOST_WIDE_INT) 1 - << (GET_MODE_BITSIZE (inner_mode) - 1)))) + /* `(COMPARE A B) != 0)' is equivalent to `(COMPARE A B)'. + If CODE is EQ, rather than NE, then we are out of luck; + there is no way to reverse the sense of a COMPARE. */ + if (code == NE && GET_CODE (p->exp) == COMPARE) + { + x = p->exp; + break; + } + /* Another possibility is that this machine has a compare + insn that includes the comparison code. In that case, + ARG1 would be equivalent to a comparison operation that + would set ARG1 to either STORE_FLAG_VALUE or zero. If + this is an NE operation, ORIG_CODE is the actual + comparison being done; if it is an EQ, we must reverse + ORIG_CODE. On machine with a negative value for + STORE_FLAG_VALUE, also look at LT and GE operations. */ + else if ((code == NE + || (code == LT + && GET_MODE_CLASS (inner_mode) == MODE_INT + && (GET_MODE_BITSIZE (inner_mode) + <= HOST_BITS_PER_WIDE_INT) + && (STORE_FLAG_VALUE + & ((HOST_WIDE_INT) 1 + << (GET_MODE_BITSIZE (inner_mode) - 1)))) #ifdef FLOAT_STORE_FLAG_VALUE - || (code == LT - && GET_MODE_CLASS (inner_mode) == MODE_FLOAT - && (REAL_VALUE_NEGATIVE - (FLOAT_STORE_FLAG_VALUE (GET_MODE (arg1))))) + || (code == LT + && GET_MODE_CLASS (inner_mode) == MODE_FLOAT + && (REAL_VALUE_NEGATIVE + (FLOAT_STORE_FLAG_VALUE (GET_MODE (arg1))))) #endif - ) - && GET_RTX_CLASS (GET_CODE (p->exp)) == '<')) + ) + && GET_RTX_CLASS (GET_CODE (p->exp)) == '<') { x = p->exp; break; |