From d9ad3c89f428fa36b1ff2e977fb6261b13c30ce4 Mon Sep 17 00:00:00 2001 From: mmitchel Date: Mon, 19 Mar 2001 18:41:07 +0000 Subject: [PATCH] * 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. git-svn-id: svn+ssh://gcc.gnu.org/svn/gcc/branches/gcc-3_0-branch@40629 138bc75d-0d04-0410-961f-82ee72b054a4 --- gcc/ChangeLog | 26 ++++++++++++++++++- gcc/cse.c | 78 ++++++++++++++++++++++++++++++++++---------------------- gcc/fold-const.c | 12 +++++++-- gcc/tree.def | 6 +++++ 4 files changed, 88 insertions(+), 34 deletions(-) diff --git a/gcc/ChangeLog b/gcc/ChangeLog index 3ef6f372778..eecd6163b00 100644 --- a/gcc/ChangeLog +++ b/gcc/ChangeLog @@ -1,3 +1,11 @@ +2001-03-19 Mark Mitchell + + * 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-16 Andrew Haley * config/ia64/libgcc-ia64.ver: Add __ia64_backtrace. @@ -507,7 +515,23 @@ Thu Mar 8 06:32:50 2001 Richard Kenner (*return_16bit, *unnamed peepholes): Likewise. 2001-03-03 Laurynas Biveinis - +<<<<<<< ChangeLog +>>>>>>> 1.9240.2.146 + +<<<<<<< ChangeLog +2001-03-03 Laurynas Biveinis + + * gcc.c (convert_filename): Append executable suffix + if NO_AUTO_EXE_SUFFIX is not defined. + * gcc.texi: Document NO_AUTO_EXE_SUFFIX. + * config/i386/djgpp.h: Define NO_AUTO_EXE_SUFFIX. +======= +>>>>>>> 1.9240.2.165 + +<<<<<<< ChangeLog +======= +======= +>>>>>>> 1.9240.2.165 * gcc.c (convert_filename): Append executable suffix if NO_AUTO_EXE_SUFFIX is not defined. * gcc.texi: Document NO_AUTO_EXE_SUFFIX. diff --git a/gcc/cse.c b/gcc/cse.c index fbe9d4afc25..a51b1eaec42 100644 --- a/gcc/cse.c +++ b/gcc/cse.c @@ -3083,17 +3083,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) @@ -3184,30 +3192,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; diff --git a/gcc/fold-const.c b/gcc/fold-const.c index b6100d3e54e..dcbb293fb30 100644 --- a/gcc/fold-const.c +++ b/gcc/fold-const.c @@ -5266,8 +5266,16 @@ fold (expr) { if (TREE_CODE (arg0) == INTEGER_CST) { - if (! TREE_UNSIGNED (type) - && TREE_INT_CST_HIGH (arg0) < 0) + /* If the value is unsigned, then the absolute value is + 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; HOST_WIDE_INT high; diff --git a/gcc/tree.def b/gcc/tree.def index 4ccd6e38944..399e05706a8 100644 --- a/gcc/tree.def +++ b/gcc/tree.def @@ -602,7 +602,13 @@ DEFTREECODE (NEGATE_EXPR, "negate_expr", '1', 1) DEFTREECODE (MIN_EXPR, "min_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 (FFS_EXPR, "ffs_expr", '1', 1) /* Shift operations for shift and rotate. -- 2.11.4.GIT