From: Jan Hubicka Date: Thu, 17 May 2001 21:21:21 +0000 (+0200) Subject: integrate.c (copy_rtx_and_substitute): Use simplify_gen_subreg. X-Git-Url: https://git.libre-soc.org/?a=commitdiff_plain;h=e5c56fd9bf8418ff01126783bcd984fb151b21a2;p=gcc.git integrate.c (copy_rtx_and_substitute): Use simplify_gen_subreg. * integrate.c (copy_rtx_and_substitute): Use simplify_gen_subreg. (simplify_subreg): Handle complex types represented as CONCAT. * recog.c (validate_replace_rtx_1): Properly canonicalize expression * rtl.h (swap_commutative_operands_p): Declare. * rtlanal.c (swap_commutative_operands_p): New. (operand_preference): New static function. * combine.c (combine_simplify_rtx): Use swap_commutative_operands_p. (gen_binary): Likewise. * optabs.c (emit_cmp_and_jump_insns, emit_conditional_move): Likewise. * simplify-rtx.c (simplify_gen_binary, simplify_gen_relational): Likewise. From-SVN: r42224 --- diff --git a/gcc/ChangeLog b/gcc/ChangeLog index b5be8d85fb1..1bd75c2f1b4 100644 --- a/gcc/ChangeLog +++ b/gcc/ChangeLog @@ -1,3 +1,19 @@ +Thu May 17 23:19:46 CEST 2001 Jan Hubicka + + * integrate.c (copy_rtx_and_substitute): Use simplify_gen_subreg. + (simplify_subreg): Handle complex types represented as CONCAT. + + * recog.c (validate_replace_rtx_1): Properly canonicalize expression + * rtl.h (swap_commutative_operands_p): Declare. + * rtlanal.c (swap_commutative_operands_p): New. + (operand_preference): New static function. + + * combine.c (combine_simplify_rtx): Use swap_commutative_operands_p. + (gen_binary): Likewise. + * optabs.c (emit_cmp_and_jump_insns, emit_conditional_move): Likewise. + * simplify-rtx.c (simplify_gen_binary, + simplify_gen_relational): Likewise. + Thu May 17 20:43:36 CEST 2001 Jan Hubicka * cse.c (fold_rtx): Use simplify_subreg. diff --git a/gcc/combine.c b/gcc/combine.c index 53df2f58c86..ceb6dc77b76 100644 --- a/gcc/combine.c +++ b/gcc/combine.c @@ -3514,12 +3514,7 @@ combine_simplify_rtx (x, op0_mode, last, in_dest) /* If this is a commutative operation, put a constant last and a complex expression first. We don't need to do this for comparisons here. */ if (GET_RTX_CLASS (code) == 'c' - && ((CONSTANT_P (XEXP (x, 0)) && GET_CODE (XEXP (x, 1)) != CONST_INT) - || (GET_RTX_CLASS (GET_CODE (XEXP (x, 0))) == 'o' - && GET_RTX_CLASS (GET_CODE (XEXP (x, 1))) != 'o') - || (GET_CODE (XEXP (x, 0)) == SUBREG - && GET_RTX_CLASS (GET_CODE (SUBREG_REG (XEXP (x, 0)))) == 'o' - && GET_RTX_CLASS (GET_CODE (XEXP (x, 1))) != 'o'))) + && swap_commutative_operands_p (XEXP (x, 0), XEXP (x, 1))) { temp = XEXP (x, 0); SUBST (XEXP (x, 0), XEXP (x, 1)); @@ -9818,12 +9813,7 @@ gen_binary (code, mode, op0, op1) /* Put complex operands first and constants second. */ if (GET_RTX_CLASS (code) == 'c' - && ((CONSTANT_P (op0) && GET_CODE (op1) != CONST_INT) - || (GET_RTX_CLASS (GET_CODE (op0)) == 'o' - && GET_RTX_CLASS (GET_CODE (op1)) != 'o') - || (GET_CODE (op0) == SUBREG - && GET_RTX_CLASS (GET_CODE (SUBREG_REG (op0))) == 'o' - && GET_RTX_CLASS (GET_CODE (op1)) != 'o'))) + && swap_commutative_operands_p (op0, op1)) return gen_rtx_fmt_ee (code, mode, op1, op0); /* If we are turning off bits already known off in OP0, we need not do diff --git a/gcc/emit-rtl.c b/gcc/emit-rtl.c index b22e3467380..e1e26df1022 100644 --- a/gcc/emit-rtl.c +++ b/gcc/emit-rtl.c @@ -1308,10 +1308,6 @@ int subreg_lowpart_p (x) rtx x; { - unsigned int offset = 0; - int difference = (GET_MODE_SIZE (GET_MODE (SUBREG_REG (x))) - - GET_MODE_SIZE (GET_MODE (x))); - if (GET_CODE (x) != SUBREG) return 1; else if (GET_MODE (SUBREG_REG (x)) == VOIDmode) diff --git a/gcc/integrate.c b/gcc/integrate.c index 6795d823cc5..29acaf2939f 100644 --- a/gcc/integrate.c +++ b/gcc/integrate.c @@ -1902,35 +1902,9 @@ copy_rtx_and_substitute (orig, map, for_lhs) case SUBREG: copy = copy_rtx_and_substitute (SUBREG_REG (orig), map, for_lhs); - /* SUBREG is ordinary, but don't make nested SUBREGs. */ - if (GET_CODE (copy) == SUBREG) - { - int final_offset = SUBREG_BYTE (orig) + SUBREG_BYTE (copy); - - /* When working with SUBREGs the rule is that the byte - offset must be a multiple of the SUBREG's mode. */ - final_offset = (final_offset / GET_MODE_SIZE (GET_MODE (orig))); - final_offset = (final_offset * GET_MODE_SIZE (GET_MODE (orig))); - return gen_rtx_SUBREG (GET_MODE (orig), SUBREG_REG (copy), - final_offset); - } - else if (GET_CODE (copy) == CONCAT) - { - rtx retval = subreg_realpart_p (orig) ? XEXP (copy, 0) : XEXP (copy, 1); - int final_offset; - - if (GET_MODE (retval) == GET_MODE (orig)) - return retval; - - final_offset = SUBREG_BYTE (orig) % - GET_MODE_UNIT_SIZE (GET_MODE (SUBREG_REG (orig))); - final_offset = (final_offset / GET_MODE_SIZE (GET_MODE (orig))); - final_offset = (final_offset * GET_MODE_SIZE (GET_MODE (orig))); - return gen_rtx_SUBREG (GET_MODE (orig), retval, final_offset); - } - else - return gen_rtx_SUBREG (GET_MODE (orig), copy, - SUBREG_BYTE (orig)); + return simplify_gen_subreg (GET_MODE (orig), copy, + GET_MODE (SUBREG_REG (orig)), + SUBREG_BYTE (orig)); case ADDRESSOF: copy = gen_rtx_ADDRESSOF (mode, diff --git a/gcc/optabs.c b/gcc/optabs.c index c28b4d97c77..a2a42c636b1 100644 --- a/gcc/optabs.c +++ b/gcc/optabs.c @@ -3290,8 +3290,7 @@ emit_cmp_and_jump_insns (x, y, comparison, size, mode, unsignedp, align, label) rtx op0; rtx op1; - if ((CONSTANT_P (x) && ! CONSTANT_P (y)) - || (GET_CODE (x) == CONST_INT && GET_CODE (y) != CONST_INT)) + if (swap_commutative_operands_p (x, y)) { /* Swap operands and condition to ensure canonical RTL. */ op0 = y; @@ -3609,12 +3608,12 @@ emit_conditional_move (target, code, op0, op1, cmode, op2, op3, mode, { rtx tem, subtarget, comparison, insn; enum insn_code icode; + enum rtx_code reversed; /* If one operand is constant, make it the second one. Only do this if the other operand is not constant as well. */ - if ((CONSTANT_P (op0) && ! CONSTANT_P (op1)) - || (GET_CODE (op0) == CONST_INT && GET_CODE (op1) != CONST_INT)) + if (swap_commutative_operands_p (op0, op1)) { tem = op0; op0 = op1; @@ -3633,16 +3632,14 @@ emit_conditional_move (target, code, op0, op1, cmode, op2, op3, mode, if (cmode == VOIDmode) cmode = GET_MODE (op0); - if (((CONSTANT_P (op2) && ! CONSTANT_P (op3)) - || (GET_CODE (op2) == CONST_INT && GET_CODE (op3) != CONST_INT)) - && (GET_MODE_CLASS (GET_MODE (op1)) != MODE_FLOAT - || TARGET_FLOAT_FORMAT != IEEE_FLOAT_FORMAT - || flag_unsafe_math_optimizations)) + if (swap_commutative_operands_p (op2, op3) + && ((reversed = reversed_comparison_code_parts (code, op0, op1, NULL)) + != UNKNOWN)) { tem = op2; op2 = op3; op3 = tem; - code = reverse_condition (code); + code = reversed; } if (mode == VOIDmode) diff --git a/gcc/rtl.h b/gcc/rtl.h index 7ba5440ef74..44c61ef863e 100644 --- a/gcc/rtl.h +++ b/gcc/rtl.h @@ -1370,6 +1370,7 @@ extern int reg_used_between_p PARAMS ((rtx, rtx, rtx)); extern int reg_referenced_between_p PARAMS ((rtx, rtx, rtx)); extern int reg_set_between_p PARAMS ((rtx, rtx, rtx)); extern int regs_set_between_p PARAMS ((rtx, rtx, rtx)); +extern int swap_commutative_operands_p PARAMS ((rtx, rtx)); extern int modified_between_p PARAMS ((rtx, rtx, rtx)); extern int no_labels_between_p PARAMS ((rtx, rtx)); extern int no_jumps_between_p PARAMS ((rtx, rtx)); diff --git a/gcc/rtlanal.c b/gcc/rtlanal.c index b0e2f4eeb0f..af0f81fc817 100644 --- a/gcc/rtlanal.c +++ b/gcc/rtlanal.c @@ -30,6 +30,7 @@ Boston, MA 02111-1307, USA. */ static void set_of_1 PARAMS ((rtx, rtx, void *)); static void insn_dependent_p_1 PARAMS ((rtx, rtx, void *)); static int computed_jump_p_1 PARAMS ((rtx)); +static int operand_preference PARAMS ((rtx)); /* Bit flags that specify the machine subtype we are compiling for. Bits are tested using macros TARGET_... defined in the tm.h file @@ -2533,6 +2534,52 @@ regno_use_in (regno, x) return NULL_RTX; } +/* Return a value indicating whether OP, an operand of a commutative + operation, is preferred as the first or second operand. The higher + the value, the stronger the preference for being the first operand. + We use negative values to indicate a preference for the first operand + and positive values for the second operand. */ + +static int +operand_preference (op) + rtx op; +{ + /* Constants always come the second operand. Prefer "nice" constants. */ + if (GET_CODE (op) == CONST_INT) + return -4; + if (GET_CODE (op) == CONST_DOUBLE) + return -3; + if (CONSTANT_P (op)) + return -2; + + /* SUBREGs of objects should come second. */ + if (GET_CODE (op) == SUBREG + && GET_RTX_CLASS (GET_CODE (SUBREG_REG (op))) == 'o') + return -1; + + /* If only one operand is a `neg', `not', + `mult', `plus', or `minus' expression, it will be the first + operand. */ + if (GET_CODE (op) == NEG || GET_CODE (op) == NOT + || GET_CODE (op) == MULT || GET_CODE (op) == PLUS + || GET_CODE (op) == MINUS) + return 2; + + /* Complex expressions should be the first. */ + if (GET_RTX_CLASS (GET_CODE (op)) == 'o') + return 1; + return 0; +} + +/* Return 1 iff it is neccesary to swap operands of commutative operation + in order to canonicalize expression. */ + +int +swap_commutative_operands_p (x, y) + rtx x, y; +{ + return operand_preference (x) < operand_preference (y); +} /* Return 1 if X is an autoincrement side effect and the register is not the stack pointer. */ diff --git a/gcc/simplify-rtx.c b/gcc/simplify-rtx.c index a64b33e1836..e586b015413 100644 --- a/gcc/simplify-rtx.c +++ b/gcc/simplify-rtx.c @@ -113,12 +113,7 @@ simplify_gen_binary (code, mode, op0, op1) /* Put complex operands first and constants second if commutative. */ if (GET_RTX_CLASS (code) == 'c' - && ((CONSTANT_P (op0) && GET_CODE (op1) != CONST_INT) - || (GET_RTX_CLASS (GET_CODE (op0)) == 'o' - && GET_RTX_CLASS (GET_CODE (op1)) != 'o') - || (GET_CODE (op0) == SUBREG - && GET_RTX_CLASS (GET_CODE (SUBREG_REG (op0))) == 'o' - && GET_RTX_CLASS (GET_CODE (op1)) != 'o'))) + && swap_commutative_operands_p (op0, op1)) tem = op0, op0 = op1, op1 = tem; /* If this simplifies, do it. */ @@ -194,12 +189,7 @@ simplify_gen_relational (code, mode, cmp_mode, op0, op1) return tem; /* Put complex operands first and constants second. */ - if ((CONSTANT_P (op0) && GET_CODE (op1) != CONST_INT) - || (GET_RTX_CLASS (GET_CODE (op0)) == 'o' - && GET_RTX_CLASS (GET_CODE (op1)) != 'o') - || (GET_CODE (op0) == SUBREG - && GET_RTX_CLASS (GET_CODE (SUBREG_REG (op0))) == 'o' - && GET_RTX_CLASS (GET_CODE (op1)) != 'o')) + if (swap_commutative_operands_p (op0, op1)) tem = op0, op0 = op1, op1 = tem, code = swap_condition (code); return gen_rtx_fmt_ee (code, mode, op0, op1); @@ -2212,6 +2202,9 @@ simplify_subreg (outermode, op, innermode, byte) || byte >= GET_MODE_SIZE (innermode)) abort (); + if (outermode == innermode && !byte) + return op; + /* Attempt to simplify constant to non-SUBREG expression. */ if (CONSTANT_P (op)) { @@ -2388,6 +2381,19 @@ simplify_subreg (outermode, op, innermode, byte) MEM_COPY_ATTRIBUTES (new, op); return new; } + + /* Handle complex values represented as CONCAT + of real and imaginary part. */ + if (GET_CODE (op) == CONCAT) + { + int is_realpart = byte < GET_MODE_UNIT_SIZE (innermode) / 2; + rtx part = is_realpart ? XEXP (op, 0) : XEXP (op, 1); + unsigned int final_offset; + + final_offset = SUBREG_BYTE (op) % (GET_MODE_UNIT_SIZE (innermode) / 2); + return simplify_subreg (outermode, part, GET_MODE (part), final_offset); + } + return NULL_RTX; } /* Make a SUBREG operation or equivalent if it folds. */