This is the mail archive of the
gcc-patches@gcc.gnu.org
mailing list for the GCC project.
[PATCH] More PRE TLC
- From: Richard Guenther <rguenther at suse dot de>
- To: gcc-patches at gcc dot gnu dot org
- Date: Thu, 3 May 2012 15:04:03 +0200 (CEST)
- Subject: [PATCH] More PRE TLC
This moves handling of trapping ops to prune_clobbered_mems and
compute_avail, similar to how I moved handling of clobbered mems
earlier. It fixes one existing testcase even.
Bootstrapped and tested on x86_64-unknown-linux-gnu, applied.
Richard.
2012-05-03 Richard Guenther <rguenther@suse.de>
* tree-ssa-pre.c (valid_in_sets): Remove checking of trapping
operations.
(prune_clobbered_mems): Do it here. Do not uselessly sort
expressions.
(compute_avail): Do not add possibly trapping operations to
EXP_GEN if they might not be executed in the block.
* gcc.dg/tree-ssa/ssa-pre-27.c: Remove XFAIL.
Index: gcc/tree-ssa-pre.c
===================================================================
*** gcc/tree-ssa-pre.c (revision 187092)
--- gcc/tree-ssa-pre.c (working copy)
*************** valid_in_sets (bitmap_set_t set1, bitmap
*** 2069,2081 ****
for (i = 0; i < nary->length; i++)
if (!op_valid_in_sets (set1, set2, nary->op[i]))
return false;
- /* If the NARY may trap make sure the block does not contain
- a possible exit point.
- ??? This is overly conservative if we translate AVAIL_OUT
- as the available expression might be after the exit point. */
- if (BB_MAY_NOTRETURN (block)
- && vn_nary_may_trap (nary))
- return false;
return true;
}
break;
--- 2069,2074 ----
*************** clean (bitmap_set_t set, basic_block blo
*** 2140,2174 ****
}
/* 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;
--- 2133,2176 ----
}
/* Clean the set of expressions that are no longer valid in SET because
! they are clobbered in BLOCK or because they trap and may not be executed. */
static void
prune_clobbered_mems (bitmap_set_t set, basic_block block)
{
! bitmap_iterator bi;
! unsigned i;
! FOR_EACH_EXPR_ID_IN_SET (set, i, bi)
{
! pre_expr expr = expression_for_id (i);
! if (expr->kind == REFERENCE)
! {
! vn_reference_t 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);
! }
! }
! else if (expr->kind == NARY)
{
! vn_nary_op_t nary = PRE_EXPR_NARY (expr);
! /* If the NARY may trap make sure the block does not contain
! a possible exit point.
! ??? This is overly conservative if we translate AVAIL_OUT
! as the available expression might be after the exit point. */
! if (BB_MAY_NOTRETURN (block)
! && vn_nary_may_trap (nary))
bitmap_remove_from_set (set, expr);
}
}
}
static sbitmap has_abnormal_preds;
*************** compute_avail (void)
*** 4119,4124 ****
--- 4121,4133 ----
if (TREE_CODE (nary->op[i]) == SSA_NAME)
add_to_exp_gen (block, nary->op[i]);
+ /* If the NARY traps and there was a preceeding
+ point in the block that might not return avoid
+ adding the nary to EXP_GEN. */
+ if (BB_MAY_NOTRETURN (block)
+ && vn_nary_may_trap (nary))
+ continue;
+
result = (pre_expr) pool_alloc (pre_expr_pool);
result->kind = NARY;
result->id = 0;
Index: gcc/testsuite/gcc.dg/tree-ssa/ssa-pre-27.c
===================================================================
*** gcc/testsuite/gcc.dg/tree-ssa/ssa-pre-27.c (revision 187091)
--- gcc/testsuite/gcc.dg/tree-ssa/ssa-pre-27.c (working copy)
*************** int foo2 (int i, int j, int b)
*** 17,29 ****
int res = 0;
if (b)
res = i/j;
! /* But we fail so here because of the possibly not returning
! call in the same basic-block. */
res += i/j;
bar ();
return res;
}
! /* { dg-final { scan-tree-dump-times "# prephitmp" 1 "pre" } } */
! /* { dg-final { scan-tree-dump-times "# prephitmp" 2 "pre" { xfail *-*-* } } } */
/* { dg-final { cleanup-tree-dump "pre" } } */
--- 17,28 ----
int res = 0;
if (b)
res = i/j;
! /* And here, the possibly not returning call in the same basic-block
! comes after the trapping i/j. */
res += i/j;
bar ();
return res;
}
! /* { dg-final { scan-tree-dump-times "# prephitmp" 2 "pre" } } */
/* { dg-final { cleanup-tree-dump "pre" } } */