Commit 1a60c352 by Richard Guenther Committed by Richard Biener

re PR tree-optimization/48149 (Piecewise complex pass-through not optimized)

2011-09-06  Richard Guenther  <rguenther@suse.de>

	PR tree-optimization/48149
	* tree-ssa-sccvn.c (vn_get_expr_for): Simplify.  Fix tuplification bug.
	(vn_valueize): Move earlier.
	(valueize_expr): Use vn_valueize.
	(simplify_binary_expression): Simplify, also combine COMPLEX_EXPR
	operands.
	(simplify_unary_expression): Simplify.

	* gcc.dg/tree-ssa/ssa-fre-32.c: New testcase.

From-SVN: r178597
parent ef417be1
2011-09-06 Richard Guenther <rguenther@suse.de> 2011-09-06 Richard Guenther <rguenther@suse.de>
PR tree-optimization/48149
* tree-ssa-sccvn.c (vn_get_expr_for): Simplify. Fix tuplification bug.
(vn_valueize): Move earlier.
(valueize_expr): Use vn_valueize.
(simplify_binary_expression): Simplify, also combine COMPLEX_EXPR
operands.
(simplify_unary_expression): Simplify.
2011-09-06 Richard Guenther <rguenther@suse.de>
PR tree-optimization/48317 PR tree-optimization/48317
* tree-ssa-sccvn.h (struct vn_nary_op_s): Make op a true * tree-ssa-sccvn.h (struct vn_nary_op_s): Make op a true
trailing array. trailing array.
2011-09-06 Richard Guenther <rguenther@suse.de> 2011-09-06 Richard Guenther <rguenther@suse.de>
PR tree-optimization/48149
* gcc.dg/tree-ssa/ssa-fre-32.c: New testcase.
2011-09-06 Richard Guenther <rguenther@suse.de>
PR tree-optimization/48317 PR tree-optimization/48317
* gcc.dg/tree-ssa/ssa-fre-31.c: New testcase. * gcc.dg/tree-ssa/ssa-fre-31.c: New testcase.
......
/* { dg-do compile } */
/* { dg-options "-O -fdump-tree-fre1-details" } */
_Complex float
foo (_Complex float x)
{
float r = __real x;
float i = __imag x;
_Complex float z;
__real z = r;
__imag z = i;
return z;
}
_Complex float
bar (_Complex float x)
{
float r = __real x;
float i = __imag x;
_Complex float z = x;
__real z = r;
__imag z = i;
return z;
}
/* We should CSE all the way to replace the final assignment to z with x. */
/* { dg-final { scan-tree-dump-times "with x_1\\\(D\\\) in z" 3 "fre1" } } */
/* { dg-final { cleanup-tree-dump "fre1" } } */
...@@ -217,6 +217,7 @@ vn_get_expr_for (tree name) ...@@ -217,6 +217,7 @@ vn_get_expr_for (tree name)
vn_ssa_aux_t vn = VN_INFO (name); vn_ssa_aux_t vn = VN_INFO (name);
gimple def_stmt; gimple def_stmt;
tree expr = NULL_TREE; tree expr = NULL_TREE;
enum tree_code code;
if (vn->valnum == VN_TOP) if (vn->valnum == VN_TOP)
return name; return name;
...@@ -241,37 +242,34 @@ vn_get_expr_for (tree name) ...@@ -241,37 +242,34 @@ vn_get_expr_for (tree name)
/* Otherwise use the defining statement to build the expression. */ /* Otherwise use the defining statement to build the expression. */
def_stmt = SSA_NAME_DEF_STMT (vn->valnum); def_stmt = SSA_NAME_DEF_STMT (vn->valnum);
/* If the value number is a default-definition or a PHI result /* If the value number is not an assignment use it directly. */
use it directly. */
if (gimple_nop_p (def_stmt)
|| gimple_code (def_stmt) == GIMPLE_PHI)
return vn->valnum;
if (!is_gimple_assign (def_stmt)) if (!is_gimple_assign (def_stmt))
return vn->valnum; return vn->valnum;
/* FIXME tuples. This is incomplete and likely will miss some /* FIXME tuples. This is incomplete and likely will miss some
simplifications. */ simplifications. */
switch (TREE_CODE_CLASS (gimple_assign_rhs_code (def_stmt))) code = gimple_assign_rhs_code (def_stmt);
switch (TREE_CODE_CLASS (code))
{ {
case tcc_reference: case tcc_reference:
if ((gimple_assign_rhs_code (def_stmt) == VIEW_CONVERT_EXPR if ((code == REALPART_EXPR
|| gimple_assign_rhs_code (def_stmt) == REALPART_EXPR || code == IMAGPART_EXPR
|| gimple_assign_rhs_code (def_stmt) == IMAGPART_EXPR) || code == VIEW_CONVERT_EXPR)
&& TREE_CODE (gimple_assign_rhs1 (def_stmt)) == SSA_NAME) && TREE_CODE (TREE_OPERAND (gimple_assign_rhs1 (def_stmt),
expr = fold_build1 (gimple_assign_rhs_code (def_stmt), 0)) == SSA_NAME)
expr = fold_build1 (code,
gimple_expr_type (def_stmt), gimple_expr_type (def_stmt),
TREE_OPERAND (gimple_assign_rhs1 (def_stmt), 0)); TREE_OPERAND (gimple_assign_rhs1 (def_stmt), 0));
break; break;
case tcc_unary: case tcc_unary:
expr = fold_build1 (gimple_assign_rhs_code (def_stmt), expr = fold_build1 (code,
gimple_expr_type (def_stmt), gimple_expr_type (def_stmt),
gimple_assign_rhs1 (def_stmt)); gimple_assign_rhs1 (def_stmt));
break; break;
case tcc_binary: case tcc_binary:
expr = fold_build2 (gimple_assign_rhs_code (def_stmt), expr = fold_build2 (code,
gimple_expr_type (def_stmt), gimple_expr_type (def_stmt),
gimple_assign_rhs1 (def_stmt), gimple_assign_rhs1 (def_stmt),
gimple_assign_rhs2 (def_stmt)); gimple_assign_rhs2 (def_stmt));
...@@ -2822,6 +2820,19 @@ stmt_has_constants (gimple stmt) ...@@ -2822,6 +2820,19 @@ stmt_has_constants (gimple stmt)
return false; return false;
} }
/* Valueize NAME if it is an SSA name, otherwise just return it. */
static inline tree
vn_valueize (tree name)
{
if (TREE_CODE (name) == SSA_NAME)
{
tree tem = SSA_VAL (name);
return tem == VN_TOP ? name : tem;
}
return name;
}
/* Replace SSA_NAMES in expr with their value numbers, and return the /* Replace SSA_NAMES in expr with their value numbers, and return the
result. result.
This is performed in place. */ This is performed in place. */
...@@ -2831,21 +2842,13 @@ valueize_expr (tree expr) ...@@ -2831,21 +2842,13 @@ valueize_expr (tree expr)
{ {
switch (TREE_CODE_CLASS (TREE_CODE (expr))) switch (TREE_CODE_CLASS (TREE_CODE (expr)))
{ {
case tcc_unary:
if (TREE_CODE (TREE_OPERAND (expr, 0)) == SSA_NAME
&& SSA_VAL (TREE_OPERAND (expr, 0)) != VN_TOP)
TREE_OPERAND (expr, 0) = SSA_VAL (TREE_OPERAND (expr, 0));
break;
case tcc_binary: case tcc_binary:
if (TREE_CODE (TREE_OPERAND (expr, 0)) == SSA_NAME TREE_OPERAND (expr, 1) = vn_valueize (TREE_OPERAND (expr, 1));
&& SSA_VAL (TREE_OPERAND (expr, 0)) != VN_TOP) /* Fallthru. */
TREE_OPERAND (expr, 0) = SSA_VAL (TREE_OPERAND (expr, 0)); case tcc_unary:
if (TREE_CODE (TREE_OPERAND (expr, 1)) == SSA_NAME TREE_OPERAND (expr, 0) = vn_valueize (TREE_OPERAND (expr, 0));
&& SSA_VAL (TREE_OPERAND (expr, 1)) != VN_TOP)
TREE_OPERAND (expr, 1) = SSA_VAL (TREE_OPERAND (expr, 1));
break;
default:
break; break;
default:;
} }
return expr; return expr;
} }
...@@ -2859,6 +2862,7 @@ simplify_binary_expression (gimple stmt) ...@@ -2859,6 +2862,7 @@ simplify_binary_expression (gimple stmt)
tree result = NULL_TREE; tree result = NULL_TREE;
tree op0 = gimple_assign_rhs1 (stmt); tree op0 = gimple_assign_rhs1 (stmt);
tree op1 = gimple_assign_rhs2 (stmt); tree op1 = gimple_assign_rhs2 (stmt);
enum tree_code code = gimple_assign_rhs_code (stmt);
/* This will not catch every single case we could combine, but will /* This will not catch every single case we could combine, but will
catch those with constants. The goal here is to simultaneously catch those with constants. The goal here is to simultaneously
...@@ -2867,23 +2871,25 @@ simplify_binary_expression (gimple stmt) ...@@ -2867,23 +2871,25 @@ simplify_binary_expression (gimple stmt)
if (TREE_CODE (op0) == SSA_NAME) if (TREE_CODE (op0) == SSA_NAME)
{ {
if (VN_INFO (op0)->has_constants if (VN_INFO (op0)->has_constants
|| TREE_CODE_CLASS (gimple_assign_rhs_code (stmt)) == tcc_comparison) || TREE_CODE_CLASS (code) == tcc_comparison
|| code == COMPLEX_EXPR)
op0 = valueize_expr (vn_get_expr_for (op0)); op0 = valueize_expr (vn_get_expr_for (op0));
else if (SSA_VAL (op0) != VN_TOP && SSA_VAL (op0) != op0) else
op0 = SSA_VAL (op0); op0 = vn_valueize (op0);
} }
if (TREE_CODE (op1) == SSA_NAME) if (TREE_CODE (op1) == SSA_NAME)
{ {
if (VN_INFO (op1)->has_constants) if (VN_INFO (op1)->has_constants
|| code == COMPLEX_EXPR)
op1 = valueize_expr (vn_get_expr_for (op1)); op1 = valueize_expr (vn_get_expr_for (op1));
else if (SSA_VAL (op1) != VN_TOP && SSA_VAL (op1) != op1) else
op1 = SSA_VAL (op1); op1 = vn_valueize (op1);
} }
/* Pointer plus constant can be represented as invariant address. /* Pointer plus constant can be represented as invariant address.
Do so to allow further propatation, see also tree forwprop. */ Do so to allow further propatation, see also tree forwprop. */
if (gimple_assign_rhs_code (stmt) == POINTER_PLUS_EXPR if (code == POINTER_PLUS_EXPR
&& host_integerp (op1, 1) && host_integerp (op1, 1)
&& TREE_CODE (op0) == ADDR_EXPR && TREE_CODE (op0) == ADDR_EXPR
&& is_gimple_min_invariant (op0)) && is_gimple_min_invariant (op0))
...@@ -2898,8 +2904,7 @@ simplify_binary_expression (gimple stmt) ...@@ -2898,8 +2904,7 @@ simplify_binary_expression (gimple stmt)
fold_defer_overflow_warnings (); fold_defer_overflow_warnings ();
result = fold_binary (gimple_assign_rhs_code (stmt), result = fold_binary (code, gimple_expr_type (stmt), op0, op1);
gimple_expr_type (stmt), op0, op1);
if (result) if (result)
STRIP_USELESS_TYPE_CONVERSION (result); STRIP_USELESS_TYPE_CONVERSION (result);
...@@ -2924,12 +2929,13 @@ simplify_unary_expression (gimple stmt) ...@@ -2924,12 +2929,13 @@ simplify_unary_expression (gimple stmt)
{ {
tree result = NULL_TREE; tree result = NULL_TREE;
tree orig_op0, op0 = gimple_assign_rhs1 (stmt); tree orig_op0, op0 = gimple_assign_rhs1 (stmt);
enum tree_code code = gimple_assign_rhs_code (stmt);
/* We handle some tcc_reference codes here that are all /* We handle some tcc_reference codes here that are all
GIMPLE_ASSIGN_SINGLE codes. */ GIMPLE_ASSIGN_SINGLE codes. */
if (gimple_assign_rhs_code (stmt) == REALPART_EXPR if (code == REALPART_EXPR
|| gimple_assign_rhs_code (stmt) == IMAGPART_EXPR || code == IMAGPART_EXPR
|| gimple_assign_rhs_code (stmt) == VIEW_CONVERT_EXPR) || code == VIEW_CONVERT_EXPR)
op0 = TREE_OPERAND (op0, 0); op0 = TREE_OPERAND (op0, 0);
if (TREE_CODE (op0) != SSA_NAME) if (TREE_CODE (op0) != SSA_NAME)
...@@ -2938,10 +2944,10 @@ simplify_unary_expression (gimple stmt) ...@@ -2938,10 +2944,10 @@ simplify_unary_expression (gimple stmt)
orig_op0 = op0; orig_op0 = op0;
if (VN_INFO (op0)->has_constants) if (VN_INFO (op0)->has_constants)
op0 = valueize_expr (vn_get_expr_for (op0)); op0 = valueize_expr (vn_get_expr_for (op0));
else if (gimple_assign_cast_p (stmt) else if (CONVERT_EXPR_CODE_P (code)
|| gimple_assign_rhs_code (stmt) == REALPART_EXPR || code == REALPART_EXPR
|| gimple_assign_rhs_code (stmt) == IMAGPART_EXPR || code == IMAGPART_EXPR
|| gimple_assign_rhs_code (stmt) == VIEW_CONVERT_EXPR) || code == VIEW_CONVERT_EXPR)
{ {
/* We want to do tree-combining on conversion-like expressions. /* We want to do tree-combining on conversion-like expressions.
Make sure we feed only SSA_NAMEs or constants to fold though. */ Make sure we feed only SSA_NAMEs or constants to fold though. */
...@@ -2958,8 +2964,7 @@ simplify_unary_expression (gimple stmt) ...@@ -2958,8 +2964,7 @@ simplify_unary_expression (gimple stmt)
if (op0 == orig_op0) if (op0 == orig_op0)
return NULL_TREE; return NULL_TREE;
result = fold_unary_ignore_overflow (gimple_assign_rhs_code (stmt), result = fold_unary_ignore_overflow (code, gimple_expr_type (stmt), op0);
gimple_expr_type (stmt), op0);
if (result) if (result)
{ {
STRIP_USELESS_TYPE_CONVERSION (result); STRIP_USELESS_TYPE_CONVERSION (result);
...@@ -2970,19 +2975,6 @@ simplify_unary_expression (gimple stmt) ...@@ -2970,19 +2975,6 @@ simplify_unary_expression (gimple stmt)
return NULL_TREE; return NULL_TREE;
} }
/* Valueize NAME if it is an SSA name, otherwise just return it. */
static inline tree
vn_valueize (tree name)
{
if (TREE_CODE (name) == SSA_NAME)
{
tree tem = SSA_VAL (name);
return tem == VN_TOP ? name : tem;
}
return name;
}
/* Try to simplify RHS using equivalences and constant folding. */ /* Try to simplify RHS using equivalences and constant folding. */
static tree static tree
......
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