Commit 40f64141 by Richard Guenther Committed by Richard Biener

re PR tree-optimization/37542 (PRE doesn't simplify during phi-translation)

2008-11-02  Richard Guenther  <rguenther@suse.de>

	PR tree-optimization/37542
	* tree-ssa-pre.c (fully_constant_expression): Handle more cases.
	* tree-ssa-sccvn.c (vn_get_expr_for): Fix typo.
	(vn_nary_op_lookup_stmt): Adjust for unary reference trees.
	(vn_nary_op_insert_stmt): Likewise.
	(visit_use): Likewise.

	* gcc.dg/tree-ssa/ssa-pre-22.c: New testcase.
	* gcc.c-torture/compile/20081101-1.c: Likewise.

From-SVN: r141534
parent 15fe850f
2008-11-02 Richard Guenther <rguenther@suse.de>
PR tree-optimization/37542
* tree-ssa-pre.c (fully_constant_expression): Handle more cases.
* tree-ssa-sccvn.c (vn_get_expr_for): Fix typo.
(vn_nary_op_lookup_stmt): Adjust for unary reference trees.
(vn_nary_op_insert_stmt): Likewise.
(visit_use): Likewise.
2008-11-02 Anatoly Sokolov <aesok@post.ru> 2008-11-02 Anatoly Sokolov <aesok@post.ru>
* config/avr/avr.md (UNSPEC_SWAP): Remove constants. * config/avr/avr.md (UNSPEC_SWAP): Remove constants.
......
2008-11-02 Richard Guenther <rguenther@suse.de> 2008-11-02 Richard Guenther <rguenther@suse.de>
PR tree-optimization/37542
* gcc.dg/tree-ssa/ssa-pre-22.c: New testcase.
* gcc.c-torture/compile/20081101-1.c: Likewise.
2008-11-02 Richard Guenther <rguenther@suse.de>
PR tree-optimization/37991 PR tree-optimization/37991
* gcc.c-torture/compile/pr37991.c: New testcase. * gcc.c-torture/compile/pr37991.c: New testcase.
......
int foo (int i, int b)
{
int mask;
int result;
if (b)
mask = -1;
else
mask = 0;
result = i + 1;
result = result & mask;
return result;
}
/* { dg-do compile } */
/* { dg-options "-O2 -fdump-tree-pre-stats" } */
int foo (int i, int b)
{
int j = 1;
if (b)
j = i;
return j - i;
}
/* { dg-final { scan-tree-dump "Eliminated: 1" "pre" } } */
/* { dg-final { cleanup-tree-dump "pre" } } */
...@@ -1088,47 +1088,59 @@ fully_constant_expression (pre_expr e) ...@@ -1088,47 +1088,59 @@ fully_constant_expression (pre_expr e)
vn_nary_op_t nary = PRE_EXPR_NARY (e); vn_nary_op_t nary = PRE_EXPR_NARY (e);
switch (TREE_CODE_CLASS (nary->opcode)) switch (TREE_CODE_CLASS (nary->opcode))
{ {
case tcc_expression:
if (nary->opcode == TRUTH_NOT_EXPR)
goto do_unary;
if (nary->opcode != TRUTH_AND_EXPR
&& nary->opcode != TRUTH_OR_EXPR
&& nary->opcode != TRUTH_XOR_EXPR)
return e;
/* Fallthrough. */
case tcc_binary: case tcc_binary:
case tcc_comparison:
{ {
/* We have to go from trees to pre exprs to value ids to /* We have to go from trees to pre exprs to value ids to
constants. */ constants. */
tree naryop0 = nary->op[0]; tree naryop0 = nary->op[0];
tree naryop1 = nary->op[1]; tree naryop1 = nary->op[1];
tree const0, const1, result; tree result;
if (is_gimple_min_invariant (naryop0)) if (!is_gimple_min_invariant (naryop0))
const0 = naryop0;
else
{ {
pre_expr rep0 = get_or_alloc_expr_for (naryop0); pre_expr rep0 = get_or_alloc_expr_for (naryop0);
unsigned int vrep0 = get_expr_value_id (rep0); unsigned int vrep0 = get_expr_value_id (rep0);
const0 = get_constant_for_value_id (vrep0); tree const0 = get_constant_for_value_id (vrep0);
if (const0)
naryop0 = fold_convert (TREE_TYPE (naryop0), const0);
} }
if (is_gimple_min_invariant (naryop1)) if (!is_gimple_min_invariant (naryop1))
const1 = naryop1;
else
{ {
pre_expr rep1 = get_or_alloc_expr_for (naryop1); pre_expr rep1 = get_or_alloc_expr_for (naryop1);
unsigned int vrep1 = get_expr_value_id (rep1); unsigned int vrep1 = get_expr_value_id (rep1);
const1 = get_constant_for_value_id (vrep1); tree const1 = get_constant_for_value_id (vrep1);
} if (const1)
result = NULL; naryop1 = fold_convert (TREE_TYPE (naryop1), const1);
if (const0 && const1)
{
tree type1 = TREE_TYPE (nary->op[0]);
tree type2 = TREE_TYPE (nary->op[1]);
const0 = fold_convert (type1, const0);
const1 = fold_convert (type2, const1);
result = fold_binary (nary->opcode, nary->type, const0,
const1);
} }
result = fold_binary (nary->opcode, nary->type,
naryop0, naryop1);
if (result && is_gimple_min_invariant (result)) if (result && is_gimple_min_invariant (result))
return get_or_alloc_expr_for_constant (result); return get_or_alloc_expr_for_constant (result);
/* We might have simplified the expression to a
SSA_NAME for example from x_1 * 1. But we cannot
insert a PHI for x_1 unconditionally as x_1 might
not be available readily. */
return e; return e;
} }
case tcc_reference:
if (nary->opcode != REALPART_EXPR
&& nary->opcode != IMAGPART_EXPR
&& nary->opcode != VIEW_CONVERT_EXPR)
return e;
/* Fallthrough. */
case tcc_unary: case tcc_unary:
do_unary:
{ {
/* We have to go from trees to pre exprs to value ids to /* We have to go from trees to pre exprs to value ids to
constants. */ constants. */
tree naryop0 = nary->op[0]; tree naryop0 = nary->op[0];
tree const0, result; tree const0, result;
if (is_gimple_min_invariant (naryop0)) if (is_gimple_min_invariant (naryop0))
...@@ -1146,7 +1158,6 @@ fully_constant_expression (pre_expr e) ...@@ -1146,7 +1158,6 @@ fully_constant_expression (pre_expr e)
const0 = fold_convert (type1, const0); const0 = fold_convert (type1, const0);
result = fold_unary (nary->opcode, nary->type, const0); result = fold_unary (nary->opcode, nary->type, const0);
} }
if (result && is_gimple_min_invariant (result)) if (result && is_gimple_min_invariant (result))
return get_or_alloc_expr_for_constant (result); return get_or_alloc_expr_for_constant (result);
return e; return e;
......
...@@ -258,8 +258,8 @@ vn_get_expr_for (tree name) ...@@ -258,8 +258,8 @@ vn_get_expr_for (tree name)
{ {
case tcc_reference: case tcc_reference:
if (gimple_assign_rhs_code (def_stmt) == VIEW_CONVERT_EXPR if (gimple_assign_rhs_code (def_stmt) == VIEW_CONVERT_EXPR
&& gimple_assign_rhs_code (def_stmt) == REALPART_EXPR || gimple_assign_rhs_code (def_stmt) == REALPART_EXPR
&& gimple_assign_rhs_code (def_stmt) == IMAGPART_EXPR) || gimple_assign_rhs_code (def_stmt) == IMAGPART_EXPR)
expr = fold_build1 (gimple_assign_rhs_code (def_stmt), expr = fold_build1 (gimple_assign_rhs_code (def_stmt),
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));
...@@ -1281,6 +1281,10 @@ vn_nary_op_lookup_stmt (gimple stmt, vn_nary_op_t *vnresult) ...@@ -1281,6 +1281,10 @@ vn_nary_op_lookup_stmt (gimple stmt, vn_nary_op_t *vnresult)
vno1.type = TREE_TYPE (gimple_assign_lhs (stmt)); vno1.type = TREE_TYPE (gimple_assign_lhs (stmt));
for (i = 0; i < vno1.length; ++i) for (i = 0; i < vno1.length; ++i)
vno1.op[i] = gimple_op (stmt, i + 1); vno1.op[i] = gimple_op (stmt, i + 1);
if (vno1.opcode == REALPART_EXPR
|| vno1.opcode == IMAGPART_EXPR
|| vno1.opcode == VIEW_CONVERT_EXPR)
vno1.op[0] = TREE_OPERAND (vno1.op[0], 0);
vno1.hashcode = vn_nary_op_compute_hash (&vno1); vno1.hashcode = vn_nary_op_compute_hash (&vno1);
slot = htab_find_slot_with_hash (current_info->nary, &vno1, vno1.hashcode, slot = htab_find_slot_with_hash (current_info->nary, &vno1, vno1.hashcode,
NO_INSERT); NO_INSERT);
...@@ -1385,6 +1389,10 @@ vn_nary_op_insert_stmt (gimple stmt, tree result) ...@@ -1385,6 +1389,10 @@ vn_nary_op_insert_stmt (gimple stmt, tree result)
vno1->type = TREE_TYPE (gimple_assign_lhs (stmt)); vno1->type = TREE_TYPE (gimple_assign_lhs (stmt));
for (i = 0; i < vno1->length; ++i) for (i = 0; i < vno1->length; ++i)
vno1->op[i] = gimple_op (stmt, i + 1); vno1->op[i] = gimple_op (stmt, i + 1);
if (vno1->opcode == REALPART_EXPR
|| vno1->opcode == IMAGPART_EXPR
|| vno1->opcode == VIEW_CONVERT_EXPR)
vno1->op[0] = TREE_OPERAND (vno1->op[0], 0);
vno1->result = result; vno1->result = result;
vno1->hashcode = vn_nary_op_compute_hash (vno1); vno1->hashcode = vn_nary_op_compute_hash (vno1);
slot = htab_find_slot_with_hash (current_info->nary, vno1, vno1->hashcode, slot = htab_find_slot_with_hash (current_info->nary, vno1, vno1->hashcode,
...@@ -2380,8 +2388,18 @@ visit_use (tree use) ...@@ -2380,8 +2388,18 @@ visit_use (tree use)
case GIMPLE_SINGLE_RHS: case GIMPLE_SINGLE_RHS:
switch (TREE_CODE_CLASS (gimple_assign_rhs_code (stmt))) switch (TREE_CODE_CLASS (gimple_assign_rhs_code (stmt)))
{ {
case tcc_declaration:
case tcc_reference: case tcc_reference:
/* VOP-less references can go through unary case. */
if ((gimple_assign_rhs_code (stmt) == REALPART_EXPR
|| gimple_assign_rhs_code (stmt) == IMAGPART_EXPR
|| gimple_assign_rhs_code (stmt) == VIEW_CONVERT_EXPR )
&& TREE_CODE (TREE_OPERAND (gimple_assign_rhs1 (stmt), 0)) == SSA_NAME)
{
changed = visit_unary_op (lhs, stmt);
break;
}
/* Fallthrough. */
case tcc_declaration:
changed = visit_reference_op_load changed = visit_reference_op_load
(lhs, gimple_assign_rhs1 (stmt), stmt); (lhs, gimple_assign_rhs1 (stmt), stmt);
break; break;
......
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