diff options
author | Adam Nemet <anemet@caviumnetworks.com> | 2009-05-03 17:20:30 +0000 |
---|---|---|
committer | Adam Nemet <nemet@gcc.gnu.org> | 2009-05-03 17:20:30 +0000 |
commit | 8c7926c4c73c20a4097710c4ffd92d30a839c0fc (patch) | |
tree | ffc56de6b1acc6ed83fb02fefd7abf41c0890808 /gcc | |
parent | b91cc3b9dcc840b259b0d7e6551b047a42695f87 (diff) | |
download | gcc-8c7926c4c73c20a4097710c4ffd92d30a839c0fc.zip gcc-8c7926c4c73c20a4097710c4ffd92d30a839c0fc.tar.gz gcc-8c7926c4c73c20a4097710c4ffd92d30a839c0fc.tar.bz2 |
expr.c (get_def_for_expr): New function.
* expr.c (get_def_for_expr): New function.
(expand_expr_real_1) <PLUS_EXPR, MINUS_EXPR>: Adjust to work with
SSA rather than trees.
<MULT_EXPR>: Likewise. Use subexp0 and subexp1 instead of
TREE_OPERAND (exp, 0) and TREE_OPERAND (exp, 1).
Co-Authored-By: Richard Guenther <rguenther@suse.de>
From-SVN: r147078
Diffstat (limited to 'gcc')
-rw-r--r-- | gcc/ChangeLog | 9 | ||||
-rw-r--r-- | gcc/expr.c | 191 |
2 files changed, 115 insertions, 85 deletions
diff --git a/gcc/ChangeLog b/gcc/ChangeLog index 225919e..8fb45c1 100644 --- a/gcc/ChangeLog +++ b/gcc/ChangeLog @@ -1,3 +1,12 @@ +2009-05-03 Adam Nemet <anemet@caviumnetworks.com> + Richard Guenther <rguenther@suse.de> + + * expr.c (get_def_for_expr): New function. + (expand_expr_real_1) <PLUS_EXPR, MINUS_EXPR>: Adjust to work with + SSA rather than trees. + <MULT_EXPR>: Likewise. Use subexp0 and subexp1 instead of + TREE_OPERAND (exp, 0) and TREE_OPERAND (exp, 1). + 2009-05-03 Joseph Myers <joseph@codesourcery.com> * c-common.c (reswords): Add _Imaginary. @@ -6992,6 +6992,26 @@ expand_constructor (tree exp, rtx target, enum expand_modifier modifier, return target; } +/* Return the defining gimple statement for SSA_NAME NAME if it is an + assigment and the code of the expresion on the RHS is CODE. Return + NULL otherwise. */ + +static gimple +get_def_for_expr (tree name, enum tree_code code) +{ + gimple def_stmt; + + if (TREE_CODE (name) != SSA_NAME) + return NULL; + + def_stmt = get_gimple_for_ssa_name (name); + if (!def_stmt + || gimple_assign_rhs_code (def_stmt) != code) + return NULL; + + return def_stmt; +} + /* expand_expr: generate code for computing expression EXP. An rtx for the computed value is returned. The value is never null. @@ -7130,6 +7150,8 @@ expand_expr_real_1 (tree exp, rtx target, enum machine_mode tmode, int ignore; tree context, subexp0, subexp1; bool reduce_bit_field; + gimple subexp0_def, subexp1_def; + tree top0, top1; #define REDUCE_BIT_FIELD(expr) (reduce_bit_field \ ? reduce_to_bit_field_precision ((expr), \ target, \ @@ -8322,27 +8344,30 @@ expand_expr_real_1 (tree exp, rtx target, enum machine_mode tmode, /* Check if this is a case for multiplication and addition. */ if ((TREE_CODE (type) == INTEGER_TYPE || TREE_CODE (type) == FIXED_POINT_TYPE) - && TREE_CODE (TREE_OPERAND (exp, 0)) == MULT_EXPR) + && (subexp0_def = get_def_for_expr (TREE_OPERAND (exp, 0), + MULT_EXPR))) { tree subsubexp0, subsubexp1; - enum tree_code code0, code1, this_code; + gimple subsubexp0_def, subsubexp1_def; + enum tree_code this_code; - subexp0 = TREE_OPERAND (exp, 0); - subsubexp0 = TREE_OPERAND (subexp0, 0); - subsubexp1 = TREE_OPERAND (subexp0, 1); - code0 = TREE_CODE (subsubexp0); - code1 = TREE_CODE (subsubexp1); this_code = TREE_CODE (type) == INTEGER_TYPE ? NOP_EXPR : FIXED_CONVERT_EXPR; - if (code0 == this_code && code1 == this_code - && (TYPE_PRECISION (TREE_TYPE (TREE_OPERAND (subsubexp0, 0))) + subsubexp0 = gimple_assign_rhs1 (subexp0_def); + subsubexp0_def = get_def_for_expr (subsubexp0, this_code); + subsubexp1 = gimple_assign_rhs2 (subexp0_def); + subsubexp1_def = get_def_for_expr (subsubexp1, this_code); + if (subsubexp0_def && subsubexp1_def + && (top0 = gimple_assign_rhs1 (subsubexp0_def)) + && (top1 = gimple_assign_rhs1 (subsubexp1_def)) + && (TYPE_PRECISION (TREE_TYPE (top0)) < TYPE_PRECISION (TREE_TYPE (subsubexp0))) - && (TYPE_PRECISION (TREE_TYPE (TREE_OPERAND (subsubexp0, 0))) - == TYPE_PRECISION (TREE_TYPE (TREE_OPERAND (subsubexp1, 0)))) - && (TYPE_UNSIGNED (TREE_TYPE (TREE_OPERAND (subsubexp0, 0))) - == TYPE_UNSIGNED (TREE_TYPE (TREE_OPERAND (subsubexp1, 0))))) + && (TYPE_PRECISION (TREE_TYPE (top0)) + == TYPE_PRECISION (TREE_TYPE (top1))) + && (TYPE_UNSIGNED (TREE_TYPE (top0)) + == TYPE_UNSIGNED (TREE_TYPE (top1)))) { - tree op0type = TREE_TYPE (TREE_OPERAND (subsubexp0, 0)); + tree op0type = TREE_TYPE (top0); enum machine_mode innermode = TYPE_MODE (op0type); bool zextend_p = TYPE_UNSIGNED (op0type); bool sat_p = TYPE_SATURATING (TREE_TYPE (subsubexp0)); @@ -8355,9 +8380,8 @@ expand_expr_real_1 (tree exp, rtx target, enum machine_mode tmode, && (optab_handler (this_optab, mode)->insn_code != CODE_FOR_nothing)) { - expand_operands (TREE_OPERAND (subsubexp0, 0), - TREE_OPERAND (subsubexp1, 0), - NULL_RTX, &op0, &op1, EXPAND_NORMAL); + expand_operands (top0, top1, NULL_RTX, &op0, &op1, + EXPAND_NORMAL); op2 = expand_expr (TREE_OPERAND (exp, 1), subtarget, VOIDmode, EXPAND_NORMAL); temp = expand_ternary_op (mode, this_optab, op0, op1, op2, @@ -8485,27 +8509,30 @@ expand_expr_real_1 (tree exp, rtx target, enum machine_mode tmode, /* Check if this is a case for multiplication and subtraction. */ if ((TREE_CODE (type) == INTEGER_TYPE || TREE_CODE (type) == FIXED_POINT_TYPE) - && TREE_CODE (TREE_OPERAND (exp, 1)) == MULT_EXPR) + && (subexp1_def = get_def_for_expr (TREE_OPERAND (exp, 1), + MULT_EXPR))) { tree subsubexp0, subsubexp1; - enum tree_code code0, code1, this_code; + gimple subsubexp0_def, subsubexp1_def; + enum tree_code this_code; - subexp1 = TREE_OPERAND (exp, 1); - subsubexp0 = TREE_OPERAND (subexp1, 0); - subsubexp1 = TREE_OPERAND (subexp1, 1); - code0 = TREE_CODE (subsubexp0); - code1 = TREE_CODE (subsubexp1); this_code = TREE_CODE (type) == INTEGER_TYPE ? NOP_EXPR : FIXED_CONVERT_EXPR; - if (code0 == this_code && code1 == this_code - && (TYPE_PRECISION (TREE_TYPE (TREE_OPERAND (subsubexp0, 0))) + subsubexp0 = gimple_assign_rhs1 (subexp1_def); + subsubexp0_def = get_def_for_expr (subsubexp0, this_code); + subsubexp1 = gimple_assign_rhs2 (subexp1_def); + subsubexp1_def = get_def_for_expr (subsubexp1, this_code); + if (subsubexp0_def && subsubexp1_def + && (top0 = gimple_assign_rhs1 (subsubexp0_def)) + && (top1 = gimple_assign_rhs1 (subsubexp1_def)) + && (TYPE_PRECISION (TREE_TYPE (top0)) < TYPE_PRECISION (TREE_TYPE (subsubexp0))) - && (TYPE_PRECISION (TREE_TYPE (TREE_OPERAND (subsubexp0, 0))) - == TYPE_PRECISION (TREE_TYPE (TREE_OPERAND (subsubexp1, 0)))) - && (TYPE_UNSIGNED (TREE_TYPE (TREE_OPERAND (subsubexp0, 0))) - == TYPE_UNSIGNED (TREE_TYPE (TREE_OPERAND (subsubexp1, 0))))) + && (TYPE_PRECISION (TREE_TYPE (top0)) + == TYPE_PRECISION (TREE_TYPE (top1))) + && (TYPE_UNSIGNED (TREE_TYPE (top0)) + == TYPE_UNSIGNED (TREE_TYPE (top1)))) { - tree op0type = TREE_TYPE (TREE_OPERAND (subsubexp0, 0)); + tree op0type = TREE_TYPE (top0); enum machine_mode innermode = TYPE_MODE (op0type); bool zextend_p = TYPE_UNSIGNED (op0type); bool sat_p = TYPE_SATURATING (TREE_TYPE (subsubexp0)); @@ -8518,9 +8545,8 @@ expand_expr_real_1 (tree exp, rtx target, enum machine_mode tmode, && (optab_handler (this_optab, mode)->insn_code != CODE_FOR_nothing)) { - expand_operands (TREE_OPERAND (subsubexp0, 0), - TREE_OPERAND (subsubexp1, 0), - NULL_RTX, &op0, &op1, EXPAND_NORMAL); + expand_operands (top0, top1, NULL_RTX, &op0, &op1, + EXPAND_NORMAL); op2 = expand_expr (TREE_OPERAND (exp, 0), subtarget, VOIDmode, EXPAND_NORMAL); temp = expand_ternary_op (mode, this_optab, op0, op1, op2, @@ -8619,66 +8645,65 @@ expand_expr_real_1 (tree exp, rtx target, enum machine_mode tmode, subexp0 = TREE_OPERAND (exp, 0); subexp1 = TREE_OPERAND (exp, 1); + subexp0_def = get_def_for_expr (subexp0, NOP_EXPR); + subexp1_def = get_def_for_expr (subexp1, NOP_EXPR); + top0 = top1 = NULL_TREE; + /* First, check if we have a multiplication of one signed and one unsigned operand. */ - if (TREE_CODE (subexp0) == NOP_EXPR - && TREE_CODE (subexp1) == NOP_EXPR + if (subexp0_def + && (top0 = gimple_assign_rhs1 (subexp0_def)) + && subexp1_def + && (top1 = gimple_assign_rhs1 (subexp1_def)) && TREE_CODE (type) == INTEGER_TYPE - && (TYPE_PRECISION (TREE_TYPE (TREE_OPERAND (subexp0, 0))) - < TYPE_PRECISION (TREE_TYPE (TREE_OPERAND (exp, 0)))) - && (TYPE_PRECISION (TREE_TYPE (TREE_OPERAND (subexp0, 0))) - == TYPE_PRECISION (TREE_TYPE (TREE_OPERAND (subexp1, 0)))) - && (TYPE_UNSIGNED (TREE_TYPE (TREE_OPERAND (subexp0, 0))) - != TYPE_UNSIGNED (TREE_TYPE (TREE_OPERAND (subexp1, 0))))) + && (TYPE_PRECISION (TREE_TYPE (top0)) + < TYPE_PRECISION (TREE_TYPE (subexp0))) + && (TYPE_PRECISION (TREE_TYPE (top0)) + == TYPE_PRECISION (TREE_TYPE (top1))) + && (TYPE_UNSIGNED (TREE_TYPE (top0)) + != TYPE_UNSIGNED (TREE_TYPE (top1)))) { enum machine_mode innermode - = TYPE_MODE (TREE_TYPE (TREE_OPERAND (subexp0, 0))); + = TYPE_MODE (TREE_TYPE (top0)); this_optab = usmul_widen_optab; if (mode == GET_MODE_WIDER_MODE (innermode)) { if (optab_handler (this_optab, mode)->insn_code != CODE_FOR_nothing) { - if (TYPE_UNSIGNED (TREE_TYPE (TREE_OPERAND (subexp0, 0)))) - expand_operands (TREE_OPERAND (subexp0, 0), - TREE_OPERAND (subexp1, 0), - NULL_RTX, &op0, &op1, EXPAND_NORMAL); + if (TYPE_UNSIGNED (TREE_TYPE (top0))) + expand_operands (top0, top1, NULL_RTX, &op0, &op1, + EXPAND_NORMAL); else - expand_operands (TREE_OPERAND (subexp0, 0), - TREE_OPERAND (subexp1, 0), - NULL_RTX, &op1, &op0, EXPAND_NORMAL); + expand_operands (top0, top1, NULL_RTX, &op1, &op0, + EXPAND_NORMAL); goto binop3; } } } - /* Check for a multiplication with matching signedness. */ - else if (TREE_CODE (TREE_OPERAND (exp, 0)) == NOP_EXPR + /* Check for a multiplication with matching signedness. If + valid, TOP0 and TOP1 were set in the previous if + condition. */ + else if (top0 && TREE_CODE (type) == INTEGER_TYPE - && (TYPE_PRECISION (TREE_TYPE (TREE_OPERAND (TREE_OPERAND (exp, 0), 0))) - < TYPE_PRECISION (TREE_TYPE (TREE_OPERAND (exp, 0)))) - && ((TREE_CODE (TREE_OPERAND (exp, 1)) == INTEGER_CST - && int_fits_type_p (TREE_OPERAND (exp, 1), - TREE_TYPE (TREE_OPERAND (TREE_OPERAND (exp, 0), 0))) + && (TYPE_PRECISION (TREE_TYPE (top0)) + < TYPE_PRECISION (TREE_TYPE (subexp0))) + && ((TREE_CODE (subexp1) == INTEGER_CST + && int_fits_type_p (subexp1, TREE_TYPE (top0)) /* Don't use a widening multiply if a shift will do. */ - && ((GET_MODE_BITSIZE (TYPE_MODE (TREE_TYPE (TREE_OPERAND (exp, 1)))) + && ((GET_MODE_BITSIZE (TYPE_MODE (TREE_TYPE (subexp1))) > HOST_BITS_PER_WIDE_INT) - || exact_log2 (TREE_INT_CST_LOW (TREE_OPERAND (exp, 1))) < 0)) + || exact_log2 (TREE_INT_CST_LOW (subexp1)) < 0)) || - (TREE_CODE (TREE_OPERAND (exp, 1)) == NOP_EXPR - && (TYPE_PRECISION (TREE_TYPE - (TREE_OPERAND (TREE_OPERAND (exp, 1), 0))) - == TYPE_PRECISION (TREE_TYPE - (TREE_OPERAND - (TREE_OPERAND (exp, 0), 0)))) + (top1 + && (TYPE_PRECISION (TREE_TYPE (top1)) + == TYPE_PRECISION (TREE_TYPE (top0)) /* If both operands are extended, they must either both be zero-extended or both be sign-extended. */ - && (TYPE_UNSIGNED (TREE_TYPE - (TREE_OPERAND (TREE_OPERAND (exp, 1), 0))) - == TYPE_UNSIGNED (TREE_TYPE - (TREE_OPERAND - (TREE_OPERAND (exp, 0), 0))))))) + && (TYPE_UNSIGNED (TREE_TYPE (top1)) + == TYPE_UNSIGNED (TREE_TYPE (top0))))))) { - tree op0type = TREE_TYPE (TREE_OPERAND (TREE_OPERAND (exp, 0), 0)); + tree op0type = TREE_TYPE (top0); enum machine_mode innermode = TYPE_MODE (op0type); bool zextend_p = TYPE_UNSIGNED (op0type); optab other_optab = zextend_p ? smul_widen_optab : umul_widen_optab; @@ -8688,27 +8713,24 @@ expand_expr_real_1 (tree exp, rtx target, enum machine_mode tmode, { if (optab_handler (this_optab, mode)->insn_code != CODE_FOR_nothing) { - if (TREE_CODE (TREE_OPERAND (exp, 1)) == INTEGER_CST) - expand_operands (TREE_OPERAND (TREE_OPERAND (exp, 0), 0), - TREE_OPERAND (exp, 1), - NULL_RTX, &op0, &op1, EXPAND_NORMAL); + if (TREE_CODE (subexp1) == INTEGER_CST) + expand_operands (top0, subexp1, NULL_RTX, &op0, &op1, + EXPAND_NORMAL); else - expand_operands (TREE_OPERAND (TREE_OPERAND (exp, 0), 0), - TREE_OPERAND (TREE_OPERAND (exp, 1), 0), - NULL_RTX, &op0, &op1, EXPAND_NORMAL); + expand_operands (top0, top1, NULL_RTX, &op0, &op1, + EXPAND_NORMAL); goto binop3; } else if (optab_handler (other_optab, mode)->insn_code != CODE_FOR_nothing && innermode == word_mode) { rtx htem, hipart; - op0 = expand_normal (TREE_OPERAND (TREE_OPERAND (exp, 0), 0)); - if (TREE_CODE (TREE_OPERAND (exp, 1)) == INTEGER_CST) + op0 = expand_normal (top0); + if (TREE_CODE (subexp1) == INTEGER_CST) op1 = convert_modes (innermode, mode, - expand_normal (TREE_OPERAND (exp, 1)), - unsignedp); + expand_normal (subexp1), unsignedp); else - op1 = expand_normal (TREE_OPERAND (TREE_OPERAND (exp, 1), 0)); + op1 = expand_normal (top1); temp = expand_binop (mode, other_optab, op0, op1, target, unsignedp, OPTAB_LIB_WIDEN); hipart = gen_highpart (innermode, temp); @@ -8721,8 +8743,7 @@ expand_expr_real_1 (tree exp, rtx target, enum machine_mode tmode, } } } - expand_operands (TREE_OPERAND (exp, 0), TREE_OPERAND (exp, 1), - subtarget, &op0, &op1, EXPAND_NORMAL); + expand_operands (subexp0, subexp1, subtarget, &op0, &op1, EXPAND_NORMAL); return REDUCE_BIT_FIELD (expand_mult (mode, op0, op1, target, unsignedp)); case TRUNC_DIV_EXPR: |