re PR middle-end/39976 (Big sixtrack degradation on powerpc 32/64 after revision r146817)

2011-12-08  Bill Schmidt  <wschmidt@linux.vnet.ibm.com>

	PR middle-end/39976
	* tree-ssa-dom.c (enum expr_kind): Add EXPR_PHI.
	(struct hashable_expr): Add struct phi field.
	(initialize_hash_element): Handle phis; change to use XCNEWVEC.
	(hashable_expr_equal_p): Handle phis.
	(iterative_hash_hashable_expr): Likewise.
	(print_expr_hash_elt): Likewise.
	(free_expr_hash_elt): Likewise.
	(dom_opt_enter_block): Create equivalences from redundant phis.
	(eliminate_redundant_computations): Handle redundant phis.
	(lookup_avail_expr): Handle phis.

From-SVN: r182140
This commit is contained in:
Bill Schmidt 2011-12-08 22:00:38 +00:00 committed by William Schmidt
parent 4be257dcc4
commit 13a3e5b6d8
2 changed files with 102 additions and 5 deletions

View File

@ -1,3 +1,17 @@
2011-12-08 Bill Schmidt <wschmidt@linux.vnet.ibm.com>
PR middle-end/39976
* tree-ssa-dom.c (enum expr_kind): Add EXPR_PHI.
(struct hashable_expr): Add struct phi field.
(initialize_hash_element): Handle phis; change to use XCNEWVEC.
(hashable_expr_equal_p): Handle phis.
(iterative_hash_hashable_expr): Likewise.
(print_expr_hash_elt): Likewise.
(free_expr_hash_elt): Likewise.
(dom_opt_enter_block): Create equivalences from redundant phis.
(eliminate_redundant_computations): Handle redundant phis.
(lookup_avail_expr): Handle phis.
2011-12-08 Jakub Jelinek <jakub@redhat.com>
PR tree-optimization/51466

View File

@ -52,7 +52,8 @@ enum expr_kind
EXPR_UNARY,
EXPR_BINARY,
EXPR_TERNARY,
EXPR_CALL
EXPR_CALL,
EXPR_PHI
};
struct hashable_expr
@ -65,6 +66,7 @@ struct hashable_expr
struct { enum tree_code op; tree opnd0, opnd1; } binary;
struct { enum tree_code op; tree opnd0, opnd1, opnd2; } ternary;
struct { gimple fn_from; bool pure; size_t nargs; tree *args; } call;
struct { size_t nargs; tree *args; } phi;
} ops;
};
@ -265,7 +267,7 @@ initialize_hash_element (gimple stmt, tree lhs,
expr->ops.call.pure = false;
expr->ops.call.nargs = nargs;
expr->ops.call.args = (tree *) xcalloc (nargs, sizeof (tree));
expr->ops.call.args = XCNEWVEC (tree, nargs);
for (i = 0; i < nargs; i++)
expr->ops.call.args[i] = gimple_call_arg (stmt, i);
}
@ -281,6 +283,19 @@ initialize_hash_element (gimple stmt, tree lhs,
expr->kind = EXPR_SINGLE;
expr->ops.single.rhs = gimple_goto_dest (stmt);
}
else if (code == GIMPLE_PHI)
{
size_t nargs = gimple_phi_num_args (stmt);
size_t i;
expr->type = TREE_TYPE (gimple_phi_result (stmt));
expr->kind = EXPR_PHI;
expr->ops.phi.nargs = nargs;
expr->ops.phi.args = XCNEWVEC (tree, nargs);
for (i = 0; i < nargs; i++)
expr->ops.phi.args[i] = gimple_phi_arg_def (stmt, i);
}
else
gcc_unreachable ();
@ -439,6 +454,21 @@ hashable_expr_equal_p (const struct hashable_expr *expr0,
return true;
}
case EXPR_PHI:
{
size_t i;
if (expr0->ops.phi.nargs != expr1->ops.phi.nargs)
return false;
for (i = 0; i < expr0->ops.phi.nargs; i++)
if (! operand_equal_p (expr0->ops.phi.args[i],
expr1->ops.phi.args[i], 0))
return false;
return true;
}
default:
gcc_unreachable ();
}
@ -516,6 +546,15 @@ iterative_hash_hashable_expr (const struct hashable_expr *expr, hashval_t val)
}
break;
case EXPR_PHI:
{
size_t i;
for (i = 0; i < expr->ops.phi.nargs; i++)
val = iterative_hash_expr (expr->ops.phi.args[i], val);
}
break;
default:
gcc_unreachable ();
}
@ -588,6 +627,22 @@ print_expr_hash_elt (FILE * stream, const struct expr_hash_elt *element)
fprintf (stream, ")");
}
break;
case EXPR_PHI:
{
size_t i;
size_t nargs = element->expr.ops.phi.nargs;
fprintf (stream, "PHI <");
for (i = 0; i < nargs; i++)
{
print_generic_expr (stream, element->expr.ops.phi.args[i], 0);
if (i + 1 < nargs)
fprintf (stream, ", ");
}
fprintf (stream, ">");
}
break;
}
fprintf (stream, "\n");
@ -608,6 +663,9 @@ free_expr_hash_elt (void *elt)
if (element->expr.kind == EXPR_CALL)
free (element->expr.ops.call.args);
if (element->expr.kind == EXPR_PHI)
free (element->expr.ops.phi.args);
free (element);
}
@ -1688,6 +1746,14 @@ dom_opt_enter_block (struct dom_walk_data *walk_data ATTRIBUTE_UNUSED,
/* PHI nodes can create equivalences too. */
record_equivalences_from_phis (bb);
/* Create equivalences from redundant PHIs. PHIs are only truly
redundant when they exist in the same block, so push another
marker and unwind right afterwards. */
VEC_safe_push (expr_hash_elt_t, heap, avail_exprs_stack, NULL);
for (gsi = gsi_start_phis (bb); !gsi_end_p (gsi); gsi_next (&gsi))
eliminate_redundant_computations (&gsi);
remove_local_expressions_from_table ();
for (gsi = gsi_start_bb (bb); !gsi_end_p (gsi); gsi_next (&gsi))
optimize_stmt (bb, gsi);
@ -1818,12 +1884,16 @@ eliminate_redundant_computations (gimple_stmt_iterator* gsi)
{
tree expr_type;
tree cached_lhs;
tree def;
bool insert = true;
bool assigns_var_p = false;
gimple stmt = gsi_stmt (*gsi);
tree def = gimple_get_lhs (stmt);
if (gimple_code (stmt) == GIMPLE_PHI)
def = gimple_phi_result (stmt);
else
def = gimple_get_lhs (stmt);
/* Certain expressions on the RHS can be optimized away, but can not
themselves be entered into the hash tables. */
@ -1857,6 +1927,16 @@ eliminate_redundant_computations (gimple_stmt_iterator* gsi)
}
else if (gimple_code (stmt) == GIMPLE_SWITCH)
expr_type = TREE_TYPE (gimple_switch_index (stmt));
else if (gimple_code (stmt) == GIMPLE_PHI)
/* We can't propagate into a phi, so the logic below doesn't apply.
Instead record an equivalence between the cached LHS and the
PHI result of this statement, provided they are in the same block.
This should be sufficient to kill the redundant phi. */
{
if (def && cached_lhs)
record_const_or_copy (def, cached_lhs);
return;
}
else
gcc_unreachable ();
@ -2297,8 +2377,11 @@ lookup_avail_expr (gimple stmt, bool insert)
tree temp;
struct expr_hash_elt element;
/* Get LHS of assignment or call, else NULL_TREE. */
lhs = gimple_get_lhs (stmt);
/* Get LHS of phi, assignment, or call; else NULL_TREE. */
if (gimple_code (stmt) == GIMPLE_PHI)
lhs = gimple_phi_result (stmt);
else
lhs = gimple_get_lhs (stmt);
initialize_hash_element (stmt, lhs, &element);