Commit 8c7926c4 by Adam Nemet Committed by Adam Nemet

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
parent b91cc3b9
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> 2009-05-03 Joseph Myers <joseph@codesourcery.com>
* c-common.c (reswords): Add _Imaginary. * c-common.c (reswords): Add _Imaginary.
......
...@@ -6992,6 +6992,26 @@ expand_constructor (tree exp, rtx target, enum expand_modifier modifier, ...@@ -6992,6 +6992,26 @@ expand_constructor (tree exp, rtx target, enum expand_modifier modifier,
return target; 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. /* expand_expr: generate code for computing expression EXP.
An rtx for the computed value is returned. The value is never null. 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, ...@@ -7130,6 +7150,8 @@ expand_expr_real_1 (tree exp, rtx target, enum machine_mode tmode,
int ignore; int ignore;
tree context, subexp0, subexp1; tree context, subexp0, subexp1;
bool reduce_bit_field; bool reduce_bit_field;
gimple subexp0_def, subexp1_def;
tree top0, top1;
#define REDUCE_BIT_FIELD(expr) (reduce_bit_field \ #define REDUCE_BIT_FIELD(expr) (reduce_bit_field \
? reduce_to_bit_field_precision ((expr), \ ? reduce_to_bit_field_precision ((expr), \
target, \ target, \
...@@ -8322,27 +8344,30 @@ expand_expr_real_1 (tree exp, rtx target, enum machine_mode tmode, ...@@ -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. */ /* Check if this is a case for multiplication and addition. */
if ((TREE_CODE (type) == INTEGER_TYPE if ((TREE_CODE (type) == INTEGER_TYPE
|| TREE_CODE (type) == FIXED_POINT_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; 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 this_code = TREE_CODE (type) == INTEGER_TYPE ? NOP_EXPR
: FIXED_CONVERT_EXPR; : FIXED_CONVERT_EXPR;
if (code0 == this_code && code1 == this_code subsubexp0 = gimple_assign_rhs1 (subexp0_def);
&& (TYPE_PRECISION (TREE_TYPE (TREE_OPERAND (subsubexp0, 0))) 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 (subsubexp0)))
&& (TYPE_PRECISION (TREE_TYPE (TREE_OPERAND (subsubexp0, 0))) && (TYPE_PRECISION (TREE_TYPE (top0))
== TYPE_PRECISION (TREE_TYPE (TREE_OPERAND (subsubexp1, 0)))) == TYPE_PRECISION (TREE_TYPE (top1)))
&& (TYPE_UNSIGNED (TREE_TYPE (TREE_OPERAND (subsubexp0, 0))) && (TYPE_UNSIGNED (TREE_TYPE (top0))
== TYPE_UNSIGNED (TREE_TYPE (TREE_OPERAND (subsubexp1, 0))))) == 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); enum machine_mode innermode = TYPE_MODE (op0type);
bool zextend_p = TYPE_UNSIGNED (op0type); bool zextend_p = TYPE_UNSIGNED (op0type);
bool sat_p = TYPE_SATURATING (TREE_TYPE (subsubexp0)); bool sat_p = TYPE_SATURATING (TREE_TYPE (subsubexp0));
...@@ -8355,9 +8380,8 @@ expand_expr_real_1 (tree exp, rtx target, enum machine_mode tmode, ...@@ -8355,9 +8380,8 @@ expand_expr_real_1 (tree exp, rtx target, enum machine_mode tmode,
&& (optab_handler (this_optab, mode)->insn_code && (optab_handler (this_optab, mode)->insn_code
!= CODE_FOR_nothing)) != CODE_FOR_nothing))
{ {
expand_operands (TREE_OPERAND (subsubexp0, 0), expand_operands (top0, top1, NULL_RTX, &op0, &op1,
TREE_OPERAND (subsubexp1, 0), EXPAND_NORMAL);
NULL_RTX, &op0, &op1, EXPAND_NORMAL);
op2 = expand_expr (TREE_OPERAND (exp, 1), subtarget, op2 = expand_expr (TREE_OPERAND (exp, 1), subtarget,
VOIDmode, EXPAND_NORMAL); VOIDmode, EXPAND_NORMAL);
temp = expand_ternary_op (mode, this_optab, op0, op1, op2, 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, ...@@ -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. */ /* Check if this is a case for multiplication and subtraction. */
if ((TREE_CODE (type) == INTEGER_TYPE if ((TREE_CODE (type) == INTEGER_TYPE
|| TREE_CODE (type) == FIXED_POINT_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; 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 this_code = TREE_CODE (type) == INTEGER_TYPE ? NOP_EXPR
: FIXED_CONVERT_EXPR; : FIXED_CONVERT_EXPR;
if (code0 == this_code && code1 == this_code subsubexp0 = gimple_assign_rhs1 (subexp1_def);
&& (TYPE_PRECISION (TREE_TYPE (TREE_OPERAND (subsubexp0, 0))) 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 (subsubexp0)))
&& (TYPE_PRECISION (TREE_TYPE (TREE_OPERAND (subsubexp0, 0))) && (TYPE_PRECISION (TREE_TYPE (top0))
== TYPE_PRECISION (TREE_TYPE (TREE_OPERAND (subsubexp1, 0)))) == TYPE_PRECISION (TREE_TYPE (top1)))
&& (TYPE_UNSIGNED (TREE_TYPE (TREE_OPERAND (subsubexp0, 0))) && (TYPE_UNSIGNED (TREE_TYPE (top0))
== TYPE_UNSIGNED (TREE_TYPE (TREE_OPERAND (subsubexp1, 0))))) == 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); enum machine_mode innermode = TYPE_MODE (op0type);
bool zextend_p = TYPE_UNSIGNED (op0type); bool zextend_p = TYPE_UNSIGNED (op0type);
bool sat_p = TYPE_SATURATING (TREE_TYPE (subsubexp0)); bool sat_p = TYPE_SATURATING (TREE_TYPE (subsubexp0));
...@@ -8518,9 +8545,8 @@ expand_expr_real_1 (tree exp, rtx target, enum machine_mode tmode, ...@@ -8518,9 +8545,8 @@ expand_expr_real_1 (tree exp, rtx target, enum machine_mode tmode,
&& (optab_handler (this_optab, mode)->insn_code && (optab_handler (this_optab, mode)->insn_code
!= CODE_FOR_nothing)) != CODE_FOR_nothing))
{ {
expand_operands (TREE_OPERAND (subsubexp0, 0), expand_operands (top0, top1, NULL_RTX, &op0, &op1,
TREE_OPERAND (subsubexp1, 0), EXPAND_NORMAL);
NULL_RTX, &op0, &op1, EXPAND_NORMAL);
op2 = expand_expr (TREE_OPERAND (exp, 0), subtarget, op2 = expand_expr (TREE_OPERAND (exp, 0), subtarget,
VOIDmode, EXPAND_NORMAL); VOIDmode, EXPAND_NORMAL);
temp = expand_ternary_op (mode, this_optab, op0, op1, op2, 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, ...@@ -8619,66 +8645,65 @@ expand_expr_real_1 (tree exp, rtx target, enum machine_mode tmode,
subexp0 = TREE_OPERAND (exp, 0); subexp0 = TREE_OPERAND (exp, 0);
subexp1 = TREE_OPERAND (exp, 1); 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 /* First, check if we have a multiplication of one signed and one
unsigned operand. */ unsigned operand. */
if (TREE_CODE (subexp0) == NOP_EXPR if (subexp0_def
&& TREE_CODE (subexp1) == NOP_EXPR && (top0 = gimple_assign_rhs1 (subexp0_def))
&& subexp1_def
&& (top1 = gimple_assign_rhs1 (subexp1_def))
&& TREE_CODE (type) == INTEGER_TYPE && TREE_CODE (type) == INTEGER_TYPE
&& (TYPE_PRECISION (TREE_TYPE (TREE_OPERAND (subexp0, 0))) && (TYPE_PRECISION (TREE_TYPE (top0))
< TYPE_PRECISION (TREE_TYPE (TREE_OPERAND (exp, 0)))) < TYPE_PRECISION (TREE_TYPE (subexp0)))
&& (TYPE_PRECISION (TREE_TYPE (TREE_OPERAND (subexp0, 0))) && (TYPE_PRECISION (TREE_TYPE (top0))
== TYPE_PRECISION (TREE_TYPE (TREE_OPERAND (subexp1, 0)))) == TYPE_PRECISION (TREE_TYPE (top1)))
&& (TYPE_UNSIGNED (TREE_TYPE (TREE_OPERAND (subexp0, 0))) && (TYPE_UNSIGNED (TREE_TYPE (top0))
!= TYPE_UNSIGNED (TREE_TYPE (TREE_OPERAND (subexp1, 0))))) != TYPE_UNSIGNED (TREE_TYPE (top1))))
{ {
enum machine_mode innermode enum machine_mode innermode
= TYPE_MODE (TREE_TYPE (TREE_OPERAND (subexp0, 0))); = TYPE_MODE (TREE_TYPE (top0));
this_optab = usmul_widen_optab; this_optab = usmul_widen_optab;
if (mode == GET_MODE_WIDER_MODE (innermode)) if (mode == GET_MODE_WIDER_MODE (innermode))
{ {
if (optab_handler (this_optab, mode)->insn_code != CODE_FOR_nothing) if (optab_handler (this_optab, mode)->insn_code != CODE_FOR_nothing)
{ {
if (TYPE_UNSIGNED (TREE_TYPE (TREE_OPERAND (subexp0, 0)))) if (TYPE_UNSIGNED (TREE_TYPE (top0)))
expand_operands (TREE_OPERAND (subexp0, 0), expand_operands (top0, top1, NULL_RTX, &op0, &op1,
TREE_OPERAND (subexp1, 0), EXPAND_NORMAL);
NULL_RTX, &op0, &op1, EXPAND_NORMAL);
else else
expand_operands (TREE_OPERAND (subexp0, 0), expand_operands (top0, top1, NULL_RTX, &op1, &op0,
TREE_OPERAND (subexp1, 0), EXPAND_NORMAL);
NULL_RTX, &op1, &op0, EXPAND_NORMAL);
goto binop3; goto binop3;
} }
} }
} }
/* Check for a multiplication with matching signedness. */ /* Check for a multiplication with matching signedness. If
else if (TREE_CODE (TREE_OPERAND (exp, 0)) == NOP_EXPR valid, TOP0 and TOP1 were set in the previous if
condition. */
else if (top0
&& TREE_CODE (type) == INTEGER_TYPE && TREE_CODE (type) == INTEGER_TYPE
&& (TYPE_PRECISION (TREE_TYPE (TREE_OPERAND (TREE_OPERAND (exp, 0), 0))) && (TYPE_PRECISION (TREE_TYPE (top0))
< TYPE_PRECISION (TREE_TYPE (TREE_OPERAND (exp, 0)))) < TYPE_PRECISION (TREE_TYPE (subexp0)))
&& ((TREE_CODE (TREE_OPERAND (exp, 1)) == INTEGER_CST && ((TREE_CODE (subexp1) == INTEGER_CST
&& int_fits_type_p (TREE_OPERAND (exp, 1), && int_fits_type_p (subexp1, TREE_TYPE (top0))
TREE_TYPE (TREE_OPERAND (TREE_OPERAND (exp, 0), 0)))
/* Don't use a widening multiply if a shift will do. */ /* 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) > 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 (top1
&& (TYPE_PRECISION (TREE_TYPE && (TYPE_PRECISION (TREE_TYPE (top1))
(TREE_OPERAND (TREE_OPERAND (exp, 1), 0))) == TYPE_PRECISION (TREE_TYPE (top0))
== TYPE_PRECISION (TREE_TYPE
(TREE_OPERAND
(TREE_OPERAND (exp, 0), 0))))
/* If both operands are extended, they must either both /* If both operands are extended, they must either both
be zero-extended or both be sign-extended. */ be zero-extended or both be sign-extended. */
&& (TYPE_UNSIGNED (TREE_TYPE && (TYPE_UNSIGNED (TREE_TYPE (top1))
(TREE_OPERAND (TREE_OPERAND (exp, 1), 0))) == TYPE_UNSIGNED (TREE_TYPE (top0)))))))
== TYPE_UNSIGNED (TREE_TYPE
(TREE_OPERAND
(TREE_OPERAND (exp, 0), 0)))))))
{ {
tree op0type = TREE_TYPE (TREE_OPERAND (TREE_OPERAND (exp, 0), 0)); tree op0type = TREE_TYPE (top0);
enum machine_mode innermode = TYPE_MODE (op0type); enum machine_mode innermode = TYPE_MODE (op0type);
bool zextend_p = TYPE_UNSIGNED (op0type); bool zextend_p = TYPE_UNSIGNED (op0type);
optab other_optab = zextend_p ? smul_widen_optab : umul_widen_optab; 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, ...@@ -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 (optab_handler (this_optab, mode)->insn_code != CODE_FOR_nothing)
{ {
if (TREE_CODE (TREE_OPERAND (exp, 1)) == INTEGER_CST) if (TREE_CODE (subexp1) == INTEGER_CST)
expand_operands (TREE_OPERAND (TREE_OPERAND (exp, 0), 0), expand_operands (top0, subexp1, NULL_RTX, &op0, &op1,
TREE_OPERAND (exp, 1), EXPAND_NORMAL);
NULL_RTX, &op0, &op1, EXPAND_NORMAL);
else else
expand_operands (TREE_OPERAND (TREE_OPERAND (exp, 0), 0), expand_operands (top0, top1, NULL_RTX, &op0, &op1,
TREE_OPERAND (TREE_OPERAND (exp, 1), 0), EXPAND_NORMAL);
NULL_RTX, &op0, &op1, EXPAND_NORMAL);
goto binop3; goto binop3;
} }
else if (optab_handler (other_optab, mode)->insn_code != CODE_FOR_nothing else if (optab_handler (other_optab, mode)->insn_code != CODE_FOR_nothing
&& innermode == word_mode) && innermode == word_mode)
{ {
rtx htem, hipart; rtx htem, hipart;
op0 = expand_normal (TREE_OPERAND (TREE_OPERAND (exp, 0), 0)); op0 = expand_normal (top0);
if (TREE_CODE (TREE_OPERAND (exp, 1)) == INTEGER_CST) if (TREE_CODE (subexp1) == INTEGER_CST)
op1 = convert_modes (innermode, mode, op1 = convert_modes (innermode, mode,
expand_normal (TREE_OPERAND (exp, 1)), expand_normal (subexp1), unsignedp);
unsignedp);
else else
op1 = expand_normal (TREE_OPERAND (TREE_OPERAND (exp, 1), 0)); op1 = expand_normal (top1);
temp = expand_binop (mode, other_optab, op0, op1, target, temp = expand_binop (mode, other_optab, op0, op1, target,
unsignedp, OPTAB_LIB_WIDEN); unsignedp, OPTAB_LIB_WIDEN);
hipart = gen_highpart (innermode, temp); hipart = gen_highpart (innermode, temp);
...@@ -8721,8 +8743,7 @@ expand_expr_real_1 (tree exp, rtx target, enum machine_mode tmode, ...@@ -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), expand_operands (subexp0, subexp1, subtarget, &op0, &op1, EXPAND_NORMAL);
subtarget, &op0, &op1, EXPAND_NORMAL);
return REDUCE_BIT_FIELD (expand_mult (mode, op0, op1, target, unsignedp)); return REDUCE_BIT_FIELD (expand_mult (mode, op0, op1, target, unsignedp));
case TRUNC_DIV_EXPR: case TRUNC_DIV_EXPR:
......
Markdown is supported
0% or
You are about to add 0 people to the discussion. Proceed with caution.
Finish editing this message first!
Please register or to comment