Commit cd32bb90 by Richard Guenther Committed by Richard Biener

re PR tree-optimization/52548 (missed PRE optimization when function call…

re PR tree-optimization/52548 (missed PRE optimization when function call follows to-be hoisted variable)

2012-03-22  Richard Guenther  <rguenther@suse.de>

	PR tree-optimization/52548
	* tree-ssa-pre.c (valid_in_sets): Remove handling of invalidation
	because of clobbers.
	(prune_clobbered_mems): New function.
	(compute_antic_aux): Use it to prune ANTIC_OUT.
	(compute_partial_antic_aux): Use it to prune PA_IN.
	(compute_avail): Only insert expressions into EXP_GEN that
	are not invalidated when translated up to the beginning of
	the block.

	* gcc.dg/tree-ssa/ssa-pre-29.c: New testcase.

From-SVN: r185691
parent 4b74f2b4
2012-03-22 Richard Guenther <rguenther@suse.de>
PR tree-optimization/52548
* tree-ssa-pre.c (valid_in_sets): Remove handling of invalidation
because of clobbers.
(prune_clobbered_mems): New function.
(compute_antic_aux): Use it to prune ANTIC_OUT.
(compute_partial_antic_aux): Use it to prune PA_IN.
(compute_avail): Only insert expressions into EXP_GEN that
are not invalidated when translated up to the beginning of
the block.
2012-03-22 Richard Guenther <rguenther@suse.de>
PR tree-optimization/52638
* tree-vect-stmts.c (vect_init_vector_1): New function, split
out from ...
......
2012-03-22 Richard Guenther <rguenther@suse.de>
PR tree-optimization/52548
* gcc.dg/tree-ssa/ssa-pre-29.c: New testcase.
2012-03-22 Bernhard Reutner-Fischer <aldot@gcc.gnu.org>
* lib/fortran-modules.exp (list-module-names-1): Remove
......
/* { dg-do compile } */
/* { dg-options "-O2 -fdump-tree-pre-details" } */
int flag, hoist, y, z;
void
foo (void)
{
if (flag)
y = hoist + 4;
else
flag = 888;
z = hoist + 4;
bark ();
}
/* We should see the partial redundancy of hoist + 4, not being confused
about bark () possibly clobbering hoist. */
/* { dg-final { scan-tree-dump "Replaced hoist" "pre" } } */
/* { dg-final { cleanup-tree-dump "pre" } } */
......@@ -2123,16 +2123,7 @@ valid_in_sets (bitmap_set_t set1, bitmap_set_t set2, pre_expr expr,
if (!vro_valid_in_sets (set1, set2, vro))
return false;
}
if (ref->vuse)
{
gimple def_stmt = SSA_NAME_DEF_STMT (ref->vuse);
if (!gimple_nop_p (def_stmt)
&& gimple_bb (def_stmt) != block
&& !dominated_by_p (CDI_DOMINATORS,
block, gimple_bb (def_stmt)))
return false;
}
return !value_dies_in_block_x (expr, block);
return true;
}
default:
gcc_unreachable ();
......@@ -2179,6 +2170,38 @@ clean (bitmap_set_t set, basic_block block)
VEC_free (pre_expr, heap, exprs);
}
/* Clean the set of expressions that are no longer valid in SET because
they are clobbered in BLOCK. */
static void
prune_clobbered_mems (bitmap_set_t set, basic_block block)
{
VEC (pre_expr, heap) *exprs = sorted_array_from_bitmap_set (set);
pre_expr expr;
int i;
FOR_EACH_VEC_ELT (pre_expr, exprs, i, expr)
{
vn_reference_t ref;
if (expr->kind != REFERENCE)
continue;
ref = PRE_EXPR_REFERENCE (expr);
if (ref->vuse)
{
gimple def_stmt = SSA_NAME_DEF_STMT (ref->vuse);
if (!gimple_nop_p (def_stmt)
&& ((gimple_bb (def_stmt) != block
&& !dominated_by_p (CDI_DOMINATORS,
block, gimple_bb (def_stmt)))
|| (gimple_bb (def_stmt) == block
&& value_dies_in_block_x (expr, block))))
bitmap_remove_from_set (set, expr);
}
}
VEC_free (pre_expr, heap, exprs);
}
static sbitmap has_abnormal_preds;
/* List of blocks that may have changed during ANTIC computation and
......@@ -2320,6 +2343,10 @@ compute_antic_aux (basic_block block, bool block_has_abnormal_pred_edge)
VEC_free (basic_block, heap, worklist);
}
/* Prune expressions that are clobbered in block and thus become
invalid if translated from ANTIC_OUT to ANTIC_IN. */
prune_clobbered_mems (ANTIC_OUT, block);
/* Generate ANTIC_OUT - TMP_GEN. */
S = bitmap_set_subtract (ANTIC_OUT, TMP_GEN (block));
......@@ -2474,6 +2501,10 @@ compute_partial_antic_aux (basic_block block,
VEC_free (basic_block, heap, worklist);
}
/* Prune expressions that are clobbered in block and thus become
invalid if translated from PA_OUT to PA_IN. */
prune_clobbered_mems (PA_OUT, block);
/* PA_IN starts with PA_OUT - TMP_GEN.
Then we subtract things from ANTIC_IN. */
PA_IN (block) = bitmap_set_subtract (PA_OUT, TMP_GEN (block));
......@@ -4027,15 +4058,26 @@ compute_avail (void)
if (vro->op2 && TREE_CODE (vro->op2) == SSA_NAME)
add_to_exp_gen (block, vro->op2);
}
result = (pre_expr) pool_alloc (pre_expr_pool);
result->kind = REFERENCE;
result->id = 0;
PRE_EXPR_REFERENCE (result) = ref;
get_or_alloc_expression_id (result);
add_to_value (get_expr_value_id (result), result);
if (!in_fre)
bitmap_value_insert_into_set (EXP_GEN (block), result);
/* If the value of the call is not invalidated in
this block until it is computed, add the expression
to EXP_GEN. */
if (!gimple_vuse (stmt)
|| gimple_code
(SSA_NAME_DEF_STMT (gimple_vuse (stmt))) == GIMPLE_PHI
|| gimple_bb (SSA_NAME_DEF_STMT
(gimple_vuse (stmt))) != block)
{
result = (pre_expr) pool_alloc (pre_expr_pool);
result->kind = REFERENCE;
result->id = 0;
PRE_EXPR_REFERENCE (result) = ref;
get_or_alloc_expression_id (result);
add_to_value (get_expr_value_id (result), result);
if (!in_fre)
bitmap_value_insert_into_set (EXP_GEN (block), result);
}
continue;
}
......@@ -4095,6 +4137,32 @@ compute_avail (void)
if (vro->op2 && TREE_CODE (vro->op2) == SSA_NAME)
add_to_exp_gen (block, vro->op2);
}
/* If the value of the reference is not invalidated in
this block until it is computed, add the expression
to EXP_GEN. */
if (gimple_vuse (stmt))
{
gimple def_stmt;
bool ok = true;
def_stmt = SSA_NAME_DEF_STMT (gimple_vuse (stmt));
while (!gimple_nop_p (def_stmt)
&& gimple_code (def_stmt) != GIMPLE_PHI
&& gimple_bb (def_stmt) == block)
{
if (stmt_may_clobber_ref_p
(def_stmt, gimple_assign_rhs1 (stmt)))
{
ok = false;
break;
}
def_stmt
= SSA_NAME_DEF_STMT (gimple_vuse (def_stmt));
}
if (!ok)
continue;
}
result = (pre_expr) pool_alloc (pre_expr_pool);
result->kind = REFERENCE;
result->id = 0;
......
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