diff options
author | Roger Sayle <roger@eyesopen.com> | 2003-09-07 20:34:13 +0000 |
---|---|---|
committer | Roger Sayle <sayle@gcc.gnu.org> | 2003-09-07 20:34:13 +0000 |
commit | eb698c5883ecbe510585bf6c37a9ae198577cea2 (patch) | |
tree | 9b2ed270edaa17237187e1b284596268edbe916e | |
parent | 4f61b3b722d34b8cd37376bc1e21879c01296c1b (diff) | |
download | gcc-eb698c5883ecbe510585bf6c37a9ae198577cea2.zip gcc-eb698c5883ecbe510585bf6c37a9ae198577cea2.tar.gz gcc-eb698c5883ecbe510585bf6c37a9ae198577cea2.tar.bz2 |
expr.c (expand_operands): New function to expand an operand pair.
* expr.c (expand_operands): New function to expand an operand pair.
(expand_expr): Call expand_operands whenever we need to expand both
operands of a binary operator.
(do_store_flag): Likewise for operands of comparison operations.
From-SVN: r71179
-rw-r--r-- | gcc/ChangeLog | 7 | ||||
-rw-r--r-- | gcc/expr.c | 104 |
2 files changed, 60 insertions, 51 deletions
diff --git a/gcc/ChangeLog b/gcc/ChangeLog index 5b10868..3308345 100644 --- a/gcc/ChangeLog +++ b/gcc/ChangeLog @@ -1,5 +1,12 @@ 2003-09-07 Roger Sayle <roger@eyesopen.com> + * expr.c (expand_operands): New function to expand an operand pair. + (expand_expr): Call expand_operands whenever we need to expand both + operands of a binary operator. + (do_store_flag): Likewise for operands of comparison operations. + +2003-09-07 Roger Sayle <roger@eyesopen.com> + * combine.c (combine_simplify_rtx): Don't convert -(A*B) into (-A)*B if we care about sign-dependent rounding. @@ -164,6 +164,8 @@ static unsigned HOST_WIDE_INT highest_pow2_factor_for_type (tree, tree); static int is_aligning_offset (tree, tree); static rtx expand_increment (tree, int, int); +static void expand_operands (tree, tree, rtx, rtx*, rtx*, + enum expand_modifier); static rtx do_store_flag (tree, rtx, enum machine_mode, int); #ifdef PUSH_ROUNDING static void emit_single_push_insn (enum machine_mode, rtx, tree); @@ -6523,6 +6525,30 @@ find_placeholder (tree exp, tree *plist) return 0; } + +/* Subroutine of expand_expr. Expand the two operands of a binary + expression EXP0 and EXP1 placing the results in OP0 and OP1. + The value may be stored in TARGET if TARGET is nonzero. The + MODIFIER argument is as documented by expand_expr. */ + +static void +expand_operands (tree exp0, tree exp1, rtx target, rtx *op0, rtx *op1, + enum expand_modifier modifier) +{ + if (! safe_from_p (target, exp1, 1)) + target = 0; + if (operand_equal_p (exp0, exp1, 0)) + { + *op0 = expand_expr (exp0, target, VOIDmode, modifier); + *op1 = copy_rtx (*op0); + } + else + { + *op0 = expand_expr (exp0, target, VOIDmode, modifier); + *op1 = expand_expr (exp1, NULL_RTX, VOIDmode, modifier); + } +} + /* expand_expr: generate code for computing expression EXP. An rtx for the computed value is returned. The value is never null. @@ -6567,7 +6593,8 @@ find_placeholder (tree exp, tree *plist) emit_block_move will be flagged with BLOCK_OP_CALL_PARM. */ rtx -expand_expr (tree exp, rtx target, enum machine_mode tmode, enum expand_modifier modifier) +expand_expr (tree exp, rtx target, enum machine_mode tmode, + enum expand_modifier modifier) { rtx op0, op1, temp; tree type = TREE_TYPE (exp); @@ -8141,12 +8168,8 @@ expand_expr (tree exp, rtx target, enum machine_mode tmode, enum expand_modifier if ((modifier != EXPAND_SUM && modifier != EXPAND_INITIALIZER) || mode != ptr_mode) { - op0 = expand_expr (TREE_OPERAND (exp, 0), subtarget, VOIDmode, 0); - if (! operand_equal_p (TREE_OPERAND (exp, 0), - TREE_OPERAND (exp, 1), 0)) - op1 = expand_expr (TREE_OPERAND (exp, 1), NULL_RTX, VOIDmode, 0); - else - op1 = op0; + expand_operands (TREE_OPERAND (exp, 0), TREE_OPERAND (exp, 1), + subtarget, &op0, &op1, 0); if (op0 == const0_rtx) return op1; if (op1 == const0_rtx) @@ -8154,13 +8177,8 @@ expand_expr (tree exp, rtx target, enum machine_mode tmode, enum expand_modifier goto binop2; } - op0 = expand_expr (TREE_OPERAND (exp, 0), subtarget, VOIDmode, modifier); - if (! operand_equal_p (TREE_OPERAND (exp, 0), - TREE_OPERAND (exp, 1), 0)) - op1 = expand_expr (TREE_OPERAND (exp, 1), NULL_RTX, - VOIDmode, modifier); - else - op1 = op0; + expand_operands (TREE_OPERAND (exp, 0), TREE_OPERAND (exp, 1), + subtarget, &op0, &op1, modifier); return simplify_gen_binary (PLUS, mode, op0, op1); case MINUS_EXPR: @@ -8173,10 +8191,8 @@ expand_expr (tree exp, rtx target, enum machine_mode tmode, enum expand_modifier && really_constant_p (TREE_OPERAND (exp, 0)) && really_constant_p (TREE_OPERAND (exp, 1))) { - rtx op0 = expand_expr (TREE_OPERAND (exp, 0), NULL_RTX, VOIDmode, - modifier); - rtx op1 = expand_expr (TREE_OPERAND (exp, 1), NULL_RTX, VOIDmode, - modifier); + expand_operands (TREE_OPERAND (exp, 0), TREE_OPERAND (exp, 1), + NULL_RTX, &op0, &op1, modifier); /* If the last operand is a CONST_INT, use plus_constant of the negated constant. Else make the MINUS. */ @@ -8198,11 +8214,8 @@ expand_expr (tree exp, rtx target, enum machine_mode tmode, enum expand_modifier || mode != ptr_mode) goto binop; - if (! safe_from_p (subtarget, TREE_OPERAND (exp, 1), 1)) - subtarget = 0; - - op0 = expand_expr (TREE_OPERAND (exp, 0), subtarget, VOIDmode, modifier); - op1 = expand_expr (TREE_OPERAND (exp, 1), NULL_RTX, VOIDmode, modifier); + expand_operands (TREE_OPERAND (exp, 0), TREE_OPERAND (exp, 1), + subtarget, &op0, &op1, modifier); /* Convert A - const to A + (-const). */ if (GET_CODE (op1) == CONST_INT) @@ -8297,14 +8310,14 @@ expand_expr (tree exp, rtx target, enum machine_mode tmode, enum expand_modifier { if (this_optab->handlers[(int) mode].insn_code != CODE_FOR_nothing) { - op0 = expand_expr (TREE_OPERAND (TREE_OPERAND (exp, 0), 0), - NULL_RTX, VOIDmode, 0); if (TREE_CODE (TREE_OPERAND (exp, 1)) == INTEGER_CST) - op1 = expand_expr (TREE_OPERAND (exp, 1), NULL_RTX, - VOIDmode, 0); + expand_operands (TREE_OPERAND (TREE_OPERAND (exp, 0), 0), + TREE_OPERAND (exp, 1), + NULL_RTX, &op0, &op1, 0); else - op1 = expand_expr (TREE_OPERAND (TREE_OPERAND (exp, 1), 0), - NULL_RTX, VOIDmode, 0); + expand_operands (TREE_OPERAND (TREE_OPERAND (exp, 0), 0), + TREE_OPERAND (TREE_OPERAND (exp, 1), 0), + NULL_RTX, &op0, &op1, 0); goto binop2; } else if (other_optab->handlers[(int) mode].insn_code != CODE_FOR_nothing @@ -8333,12 +8346,8 @@ expand_expr (tree exp, rtx target, enum machine_mode tmode, enum expand_modifier } } } - op0 = expand_expr (TREE_OPERAND (exp, 0), subtarget, VOIDmode, 0); - if (! operand_equal_p (TREE_OPERAND (exp, 0), - TREE_OPERAND (exp, 1), 0)) - op1 = expand_expr (TREE_OPERAND (exp, 1), NULL_RTX, VOIDmode, 0); - else - op1 = op0; + expand_operands (TREE_OPERAND (exp, 0), TREE_OPERAND (exp, 1), + subtarget, &op0, &op1, 0); return expand_mult (mode, op0, op1, target, unsignedp); case TRUNC_DIV_EXPR: @@ -8346,15 +8355,13 @@ expand_expr (tree exp, rtx target, enum machine_mode tmode, enum expand_modifier case CEIL_DIV_EXPR: case ROUND_DIV_EXPR: case EXACT_DIV_EXPR: - if (! safe_from_p (subtarget, TREE_OPERAND (exp, 1), 1)) - subtarget = 0; if (modifier == EXPAND_STACK_PARM) target = 0; /* Possible optimization: compute the dividend with EXPAND_SUM then if the divisor is constant can optimize the case where some terms of the dividend have coeffs divisible by it. */ - op0 = expand_expr (TREE_OPERAND (exp, 0), subtarget, VOIDmode, 0); - op1 = expand_expr (TREE_OPERAND (exp, 1), NULL_RTX, VOIDmode, 0); + expand_operands (TREE_OPERAND (exp, 0), TREE_OPERAND (exp, 1), + subtarget, &op0, &op1, 0); return expand_divmod (0, code, mode, op0, op1, target, unsignedp); case RDIV_EXPR: @@ -8376,12 +8383,10 @@ expand_expr (tree exp, rtx target, enum machine_mode tmode, enum expand_modifier case FLOOR_MOD_EXPR: case CEIL_MOD_EXPR: case ROUND_MOD_EXPR: - if (! safe_from_p (subtarget, TREE_OPERAND (exp, 1), 1)) - subtarget = 0; if (modifier == EXPAND_STACK_PARM) target = 0; - op0 = expand_expr (TREE_OPERAND (exp, 0), subtarget, VOIDmode, 0); - op1 = expand_expr (TREE_OPERAND (exp, 1), NULL_RTX, VOIDmode, 0); + expand_operands (TREE_OPERAND (exp, 0), TREE_OPERAND (exp, 1), + subtarget, &op0, &op1, 0); return expand_divmod (1, code, mode, op0, op1, target, unsignedp); case FIX_ROUND_EXPR: @@ -8450,8 +8455,8 @@ expand_expr (tree exp, rtx target, enum machine_mode tmode, enum expand_modifier || (GET_CODE (target) == REG && REGNO (target) < FIRST_PSEUDO_REGISTER)) target = gen_reg_rtx (mode); - op1 = expand_expr (TREE_OPERAND (exp, 1), NULL_RTX, VOIDmode, 0); - op0 = expand_expr (TREE_OPERAND (exp, 0), target, VOIDmode, 0); + expand_operands (TREE_OPERAND (exp, 0), TREE_OPERAND (exp, 1), + target, &op0, &op1, 0); /* First try to do it with a special MIN or MAX instruction. If that does not win, use a conditional jump to select the proper @@ -9506,10 +9511,8 @@ expand_expr (tree exp, rtx target, enum machine_mode tmode, enum expand_modifier /* Here to do an ordinary binary operator, generating an instruction from the optab already placed in `this_optab'. */ binop: - if (! safe_from_p (subtarget, TREE_OPERAND (exp, 1), 1)) - subtarget = 0; - op0 = expand_expr (TREE_OPERAND (exp, 0), subtarget, VOIDmode, 0); - op1 = expand_expr (TREE_OPERAND (exp, 1), NULL_RTX, VOIDmode, 0); + expand_operands (TREE_OPERAND (exp, 0), TREE_OPERAND (exp, 1), + subtarget, &op0, &op1, 0); binop2: if (modifier == EXPAND_STACK_PARM) target = 0; @@ -10008,8 +10011,7 @@ do_store_flag (tree exp, rtx target, enum machine_mode mode, int only_cheap) || ! safe_from_p (subtarget, arg1, 1)) subtarget = 0; - op0 = expand_expr (arg0, subtarget, VOIDmode, 0); - op1 = expand_expr (arg1, NULL_RTX, VOIDmode, 0); + expand_operands (arg0, arg1, subtarget, &op0, &op1, 0); if (target == 0) target = gen_reg_rtx (mode); |