summaryrefslogtreecommitdiffstats
diff options
context:
space:
mode:
-rw-r--r--gcc/ChangeLog12
-rw-r--r--gcc/testsuite/ChangeLog5
-rw-r--r--gcc/testsuite/gcc.dg/tree-ssa/ssa-pre-29.c21
-rw-r--r--gcc/tree-ssa-pre.c104
4 files changed, 124 insertions, 18 deletions
diff --git a/gcc/ChangeLog b/gcc/ChangeLog
index af9f8701ce6..0ec46e43ee9 100644
--- a/gcc/ChangeLog
+++ b/gcc/ChangeLog
@@ -1,5 +1,17 @@
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 ...
diff --git a/gcc/testsuite/ChangeLog b/gcc/testsuite/ChangeLog
index 7cac7df2269..5bdb9a3d1a6 100644
--- a/gcc/testsuite/ChangeLog
+++ b/gcc/testsuite/ChangeLog
@@ -1,3 +1,8 @@
+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
diff --git a/gcc/testsuite/gcc.dg/tree-ssa/ssa-pre-29.c b/gcc/testsuite/gcc.dg/tree-ssa/ssa-pre-29.c
new file mode 100644
index 00000000000..f2d2c4107ce
--- /dev/null
+++ b/gcc/testsuite/gcc.dg/tree-ssa/ssa-pre-29.c
@@ -0,0 +1,21 @@
+/* { 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" } } */
diff --git a/gcc/tree-ssa-pre.c b/gcc/tree-ssa-pre.c
index 76df3c623c5..3f17e8bce02 100644
--- a/gcc/tree-ssa-pre.c
+++ b/gcc/tree-ssa-pre.c
@@ -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;
OpenPOWER on IntegriCloud