Commit 68e568c2 by Mark Mitchell Committed by Mark Mitchell

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
parent d4b6faf6
2001-03-19 Mark Mitchell <mark@codesourcery.com>
* 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.
2001-03-19 Zack Weinberg <zackw@stanford.edu> 2001-03-19 Zack Weinberg <zackw@stanford.edu>
* Makefile.in (hash.o): Depend on $(GCONFIG_H), not $(CONFIG_H). * Makefile.in (hash.o): Depend on $(GCONFIG_H), not $(CONFIG_H).
......
...@@ -3086,17 +3086,25 @@ find_best_addr (insn, loc, mode) ...@@ -3086,17 +3086,25 @@ find_best_addr (insn, loc, mode)
#endif #endif
} }
/* Given an operation (CODE, *PARG1, *PARG2), where code is a comparison /* This routine accepts a comparison as input and attempts to return a
operation (EQ, NE, GT, etc.), follow it back through the hash table and comparision that is cheaper to compute.
what values are being compared.
*PARG1 and *PARG2 are updated to contain the rtx representing the values On input, *PARG1 and *PARG2 should be set to the first and second
actually being compared. For example, if *PARG1 was (cc0) and *PARG2 arguments to the comparison, respectively. CODE is the comparision
was (const_int 0), *PARG1 and *PARG2 will be set to the objects that were code. For example, if the comparison is:
compared to produce cc0.
The return value is the comparison operator and is either the code of (ne:SI (reg:CC 24 cc)
A or the code corresponding to the inverse of the comparison. */ (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 static enum rtx_code
find_comparison_args (code, parg1, parg2, pmode1, pmode2) find_comparison_args (code, parg1, parg2, pmode1, pmode2)
...@@ -3187,30 +3195,38 @@ 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)) if (! exp_equiv_p (p->exp, p->exp, 1, 0))
continue; continue;
if (GET_CODE (p->exp) == COMPARE /* `(COMPARE A B) != 0)' is equivalent to `(COMPARE A B)'.
/* Another possibility is that this machine has a compare insn If CODE is EQ, rather than NE, then we are out of luck;
that includes the comparison code. In that case, ARG1 would there is no way to reverse the sense of a COMPARE. */
be equivalent to a comparison operation that would set ARG1 to if (code == NE && GET_CODE (p->exp) == COMPARE)
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, x = p->exp;
we must reverse ORIG_CODE. On machine with a negative value break;
for STORE_FLAG_VALUE, also look at LT and GE operations. */ }
|| ((code == NE /* Another possibility is that this machine has a compare
|| (code == LT insn that includes the comparison code. In that case,
&& GET_MODE_CLASS (inner_mode) == MODE_INT ARG1 would be equivalent to a comparison operation that
&& (GET_MODE_BITSIZE (inner_mode) would set ARG1 to either STORE_FLAG_VALUE or zero. If
<= HOST_BITS_PER_WIDE_INT) this is an NE operation, ORIG_CODE is the actual
&& (STORE_FLAG_VALUE comparison being done; if it is an EQ, we must reverse
& ((HOST_WIDE_INT) 1 ORIG_CODE. On machine with a negative value for
<< (GET_MODE_BITSIZE (inner_mode) - 1)))) 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 #ifdef FLOAT_STORE_FLAG_VALUE
|| (code == LT || (code == LT
&& GET_MODE_CLASS (inner_mode) == MODE_FLOAT && GET_MODE_CLASS (inner_mode) == MODE_FLOAT
&& (REAL_VALUE_NEGATIVE && (REAL_VALUE_NEGATIVE
(FLOAT_STORE_FLAG_VALUE (GET_MODE (arg1))))) (FLOAT_STORE_FLAG_VALUE (GET_MODE (arg1)))))
#endif #endif
) )
&& GET_RTX_CLASS (GET_CODE (p->exp)) == '<')) && GET_RTX_CLASS (GET_CODE (p->exp)) == '<')
{ {
x = p->exp; x = p->exp;
break; break;
......
...@@ -5275,8 +5275,16 @@ fold (expr) ...@@ -5275,8 +5275,16 @@ fold (expr)
{ {
if (TREE_CODE (arg0) == INTEGER_CST) if (TREE_CODE (arg0) == INTEGER_CST)
{ {
if (! TREE_UNSIGNED (type) /* If the value is unsigned, then the absolute value is
&& TREE_INT_CST_HIGH (arg0) < 0) the same as the ordinary value. */
if (TREE_UNSIGNED (type))
return arg0;
/* Similarly, if the value is non-negative. */
else if (INT_CST_LT (integer_minus_one_node, arg0))
return arg0;
/* If the value is negative, then the absolute value is
its negation. */
else
{ {
unsigned HOST_WIDE_INT low; unsigned HOST_WIDE_INT low;
HOST_WIDE_INT high; HOST_WIDE_INT high;
......
...@@ -602,7 +602,13 @@ DEFTREECODE (NEGATE_EXPR, "negate_expr", '1', 1) ...@@ -602,7 +602,13 @@ DEFTREECODE (NEGATE_EXPR, "negate_expr", '1', 1)
DEFTREECODE (MIN_EXPR, "min_expr", '2', 2) DEFTREECODE (MIN_EXPR, "min_expr", '2', 2)
DEFTREECODE (MAX_EXPR, "max_expr", '2', 2) DEFTREECODE (MAX_EXPR, "max_expr", '2', 2)
/* Represents the absolute value of the operand.
An ABS_EXPR must have either an INTEGER_TYPE or a REAL_TYPE. The
operand of the ABS_EXPR must have the same type. */
DEFTREECODE (ABS_EXPR, "abs_expr", '1', 1) DEFTREECODE (ABS_EXPR, "abs_expr", '1', 1)
DEFTREECODE (FFS_EXPR, "ffs_expr", '1', 1) DEFTREECODE (FFS_EXPR, "ffs_expr", '1', 1)
/* Shift operations for shift and rotate. /* Shift operations for shift and rotate.
......
Markdown is supported
0% or
You are about to add 0 people to the discussion. Proceed with caution.
Finish editing this message first!
Please register or to comment