diff options
-rw-r--r-- | gcc/ChangeLog | 4 | ||||
-rw-r--r-- | gcc/cse.c | 78 | ||||
-rw-r--r-- | gcc/ifcvt.c | 8 |
3 files changed, 43 insertions, 47 deletions
diff --git a/gcc/ChangeLog b/gcc/ChangeLog index 043a1f9..15a3dc9 100644 --- a/gcc/ChangeLog +++ b/gcc/ChangeLog @@ -1,5 +1,9 @@ Wed Mar 21 14:27:11 2001 Richard Kenner <kenner@vlsi1.ultra.nyu.edu> + * cse.c (find_comparison_args): Remove previous change. + * ifcvt.c (noce_process_if_block): When moving an insn, remove any + REG_EQUAL notes. + * config/i386/i386.md (conditional_trap): Remove warning. * recog.c (push_operand): Fix error in last change that caused @@ -3086,25 +3086,17 @@ find_best_addr (insn, loc, mode) #endif } -/* This routine accepts a comparison as input and attempts to return a - comparision that is cheaper to compute. +/* 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. - 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: + *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. - (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. */ + The return value is the comparison operator and is either the code of + A or the code corresponding to the inverse of the comparison. */ static enum rtx_code find_comparison_args (code, parg1, parg2, pmode1, pmode2) @@ -3195,38 +3187,30 @@ find_comparison_args (code, parg1, parg2, pmode1, pmode2) if (! exp_equiv_p (p->exp, p->exp, 1, 0)) continue; - /* `(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)))) + 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)))) #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/ifcvt.c b/gcc/ifcvt.c index ceb7d49..d21cb4d 100644 --- a/gcc/ifcvt.c +++ b/gcc/ifcvt.c @@ -1563,9 +1563,17 @@ noce_process_if_block (test_bb, then_bb, else_bb, join_bb) that case don't do anything and let the code below delete INSN_A. */ if (insn_b && else_bb) { + rtx note; + if (else_bb && insn_b == else_bb->end) else_bb->end = PREV_INSN (insn_b); reorder_insns (insn_b, insn_b, PREV_INSN (if_info.cond_earliest)); + + /* If there was a REG_EQUAL note, delete it since it may have been + true due to this insn being after a jump. */ + if ((note = find_reg_note (insn_b, REG_EQUAL, NULL_RTX)) != 0) + remove_note (insn_b, note); + insn_b = NULL_RTX; } /* If we have "x = b; if (...) x = a;", and x has side-effects, then |