From d9c695fff183dd61b20b19160b2743d9a9286ce3 Mon Sep 17 00:00:00 2001 From: Richard Kenner Date: Tue, 13 Feb 2001 20:43:13 +0000 Subject: [PATCH] rtlanal.c (find_reg_equal_equiv_note): New function. * rtlanal.c (find_reg_equal_equiv_note): New function. * simplify-rtx.c (simplify_gen_unary, simplify_gen_ternary): New fns. (simplify_gen_relational, simplify_replace_rtx): Likewise. * rtl.h: Add declarations for above functions. From-SVN: r39644 --- gcc/ChangeLog | 7 +++ gcc/rtl.h | 34 ++++++++++-- gcc/rtlanal.c | 17 ++++++ gcc/simplify-rtx.c | 135 ++++++++++++++++++++++++++++++++++++++++++--- 4 files changed, 180 insertions(+), 13 deletions(-) diff --git a/gcc/ChangeLog b/gcc/ChangeLog index f48ac5403e6..ed6a413a326 100644 --- a/gcc/ChangeLog +++ b/gcc/ChangeLog @@ -1,3 +1,10 @@ +Tue Feb 13 15:42:05 2001 Richard Kenner + + * rtlanal.c (find_reg_equal_equiv_note): New function. + * simplify-rtx.c (simplify_gen_unary, simplify_gen_ternary): New fns. + (simplify_gen_relational, simplify_replace_rtx): Likewise. + * rtl.h: Add declarations for above functions. + Tue Feb 13 21:09:11 CET 2001 Jan Hubicka * cse.c (cse_main): Converts ifdefs on PIC_OFFSET_TABLE_REGNUM to diff --git a/gcc/rtl.h b/gcc/rtl.h index 003e92dc316..f6eb251d6ce 100644 --- a/gcc/rtl.h +++ b/gcc/rtl.h @@ -1311,12 +1311,33 @@ extern rtx try_split PARAMS ((rtx, rtx, int)); extern rtx split_insns PARAMS ((rtx, rtx)); /* In simplify-rtx.c */ -extern rtx simplify_unary_operation PARAMS ((enum rtx_code, enum machine_mode, rtx, enum machine_mode)); -extern rtx simplify_binary_operation PARAMS ((enum rtx_code, enum machine_mode, rtx, rtx)); -extern rtx simplify_ternary_operation PARAMS ((enum rtx_code, enum machine_mode, enum machine_mode, rtx, rtx, rtx)); -extern rtx simplify_relational_operation PARAMS ((enum rtx_code, enum machine_mode, rtx, rtx)); -extern rtx simplify_gen_binary PARAMS ((enum rtx_code, enum machine_mode, - rtx, rtx)); +extern rtx simplify_unary_operation PARAMS ((enum rtx_code, + enum machine_mode, rtx, + enum machine_mode)); +extern rtx simplify_binary_operation PARAMS ((enum rtx_code, + enum machine_mode, rtx, + rtx)); +extern rtx simplify_ternary_operation PARAMS ((enum rtx_code, + enum machine_mode, + enum machine_mode, rtx, rtx, + rtx)); +extern rtx simplify_relational_operation PARAMS ((enum rtx_code, + enum machine_mode, rtx, + rtx)); +extern rtx simplify_gen_binary PARAMS ((enum rtx_code, + enum machine_mode, + rtx, rtx)); +extern rtx simplify_gen_unary PARAMS ((enum rtx_code, + enum machine_mode, rtx, + enum machine_mode)); +extern rtx simplify_gen_ternary PARAMS ((enum rtx_code, + enum machine_mode, + enum machine_mode, + rtx, rtx, rtx)); +extern rtx simplify_gen_relational PARAMS ((enum rtx_code, + enum machine_mode, + rtx, rtx)); +extern rtx simplify_replace_rtx PARAMS ((rtx, rtx, rtx)); extern rtx simplify_rtx PARAMS ((rtx)); /* In optabs.c */ @@ -1388,6 +1409,7 @@ extern int dead_or_set_regno_p PARAMS ((rtx, unsigned int)); extern rtx find_reg_note PARAMS ((rtx, enum reg_note, rtx)); extern rtx find_regno_note PARAMS ((rtx, enum reg_note, unsigned int)); +extern rtx find_reg_equal_equiv_note PARAMS ((rtx)); extern int find_reg_fusage PARAMS ((rtx, enum rtx_code, rtx)); extern int find_regno_fusage PARAMS ((rtx, enum rtx_code, unsigned int)); diff --git a/gcc/rtlanal.c b/gcc/rtlanal.c index a738acb28a5..0eefa70da52 100644 --- a/gcc/rtlanal.c +++ b/gcc/rtlanal.c @@ -1485,6 +1485,23 @@ find_regno_note (insn, kind, regno) return 0; } +/* Return a REG_EQUIV or REG_EQUAL note if insn has only a single set and + has such a note. */ + +rtx +find_reg_equal_equiv_note (insn) + rtx insn; +{ + rtx note; + + if (single_set (insn) == 0) + return 0; + else if ((note = find_reg_note (insn, REG_EQUIV, NULL_RTX)) != 0) + return note; + else + return find_reg_note (insn, REG_EQUAL, NULL_RTX); +} + /* Return true if DATUM, or any overlap of DATUM, of kind CODE is found in the CALL_INSN_FUNCTION_USAGE information of INSN. */ diff --git a/gcc/simplify-rtx.c b/gcc/simplify-rtx.c index fa3dfe17f0f..43d650c387d 100644 --- a/gcc/simplify-rtx.c +++ b/gcc/simplify-rtx.c @@ -140,6 +140,128 @@ simplify_gen_binary (code, mode, op0, op1) return gen_rtx_fmt_ee (code, mode, op0, op1); } +/* Make a unary operation by first seeing if it folds and otherwise making + the specified operation. */ + +rtx +simplify_gen_unary (code, mode, op, op_mode) + enum rtx_code code; + enum machine_mode mode; + rtx op; + enum machine_mode op_mode; +{ + rtx tem; + + /* If this simplifies, use it. */ + if ((tem = simplify_unary_operation (code, mode, op, op_mode)) != 0) + return tem; + + return gen_rtx_fmt_e (code, mode, op); +} + +/* Likewise for ternary operations. */ + +rtx +simplify_gen_ternary (code, mode, op0_mode, op0, op1, op2) + enum rtx_code code; + enum machine_mode mode, op0_mode; + rtx op0, op1, op2; +{ + rtx tem; + + /* If this simplifies, use it. */ + if (0 != (tem = simplify_ternary_operation (code, mode, op0_mode, + op0, op1, op2))) + return tem; + + return gen_rtx_fmt_eee (code, mode, op0, op1, op2); +} + +/* Likewise, for relational operations. */ + +rtx +simplify_gen_relational (code, mode, op0, op1) + enum rtx_code code; + enum machine_mode mode; + rtx op0, op1; +{ + rtx tem; + + if ((tem = simplify_relational_operation (code, mode, op0, op1)) != 0) + 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')) + tem = op0, op0 = op1, op1 = tem, code = swap_condition (code); + + return gen_rtx_fmt_ee (code, mode, op0, op1); +} + +/* Replace all occurrences of OLD in X with NEW and try to simplify the + resulting RTX. Return a new RTX which is as simplified as possible. */ + +rtx +simplify_replace_rtx (x, old, new) + rtx x; + rtx old; + rtx new; +{ + enum rtx_code code = GET_CODE (x); + enum machine_mode mode = GET_MODE (x); + + /* If X is OLD, return NEW. Otherwise, if this is an expression, try + to build a new expression substituting recursively. If we can't do + anything, return our input. */ + + if (x == old) + return new; + + switch (GET_RTX_CLASS (code)) + { + case '1': + { + enum machine_mode op_mode = GET_MODE (XEXP (x, 0)); + rtx op = (XEXP (x, 0) == old + ? new : simplify_replace_rtx (XEXP (x, 0), old, new)); + + return simplify_gen_unary (code, mode, op, op_mode); + } + + case '2': + case 'c': + return + simplify_gen_binary (code, mode, + simplify_replace_rtx (XEXP (x, 0), old, new), + simplify_replace_rtx (XEXP (x, 1), old, new)); + + case '3': + case 'b': + return + simplify_gen_ternary (code, mode, GET_MODE (XEXP (x, 0)), + simplify_replace_rtx (XEXP (x, 0), old, new), + simplify_replace_rtx (XEXP (x, 1), old, new), + simplify_replace_rtx (XEXP (x, 2), old, new)); + + case 'x': + /* The only case we try to handle is a lowpart SUBREG of a single-word + CONST_INT. */ + if (code == SUBREG && subreg_lowpart_p (x) && old == SUBREG_REG (x) + && GET_CODE (new) == CONST_INT + && GET_MODE_SIZE (GET_MODE (old)) <= UNITS_PER_WORD) + return GEN_INT (INTVAL (new) & GET_MODE_MASK (mode)); + + return x; + + default: + return x; + } +} + /* Try to simplify a unary operation CODE whose output mode is to be MODE with input operand OP whose mode was originally OP_MODE. Return zero if no simplification can be made. */ @@ -2063,11 +2185,8 @@ rtx simplify_rtx (x) rtx x; { - enum rtx_code code; - enum machine_mode mode; - - mode = GET_MODE (x); - code = GET_CODE (x); + enum rtx_code code = GET_CODE (x); + enum machine_mode mode = GET_MODE (x); switch (GET_RTX_CLASS (code)) { @@ -2081,11 +2200,13 @@ simplify_rtx (x) case '3': case 'b': return simplify_ternary_operation (code, mode, GET_MODE (XEXP (x, 0)), - XEXP (x, 0), XEXP (x, 1), XEXP (x, 2)); + XEXP (x, 0), XEXP (x, 1), + XEXP (x, 2)); case '<': return simplify_relational_operation (code, - (GET_MODE (XEXP (x, 0)) != VOIDmode + ((GET_MODE (XEXP (x, 0)) + != VOIDmode) ? GET_MODE (XEXP (x, 0)) : GET_MODE (XEXP (x, 1))), XEXP (x, 0), XEXP (x, 1)); -- 2.30.2