* [PATCH] Fix PR63476
@ 2014-10-10 11:08 Richard Biener
0 siblings, 0 replies; only message in thread
From: Richard Biener @ 2014-10-10 11:08 UTC (permalink / raw)
To: gcc-patches
This fixes PRE not keeping virtual SSA form up-to-date during insertion
and thus eventual VOP walks from the devirt code during elimination.
Bootstrapped and tested on x86_64-unknown-linux-gnu, applied to trunk.
Richard.
2014-10-10 Richard Biener <rguenther@suse.de>
PR tree-optimization/63476
* tree-ssa-pre.c (struct bb_bitmap_sets): Add vop_on_exit member.
(BB_LIVE_VOP_ON_EXIT): New define.
(create_expression_by_pieces): Assign VUSEs to stmts.
(compute_avail): Track BB_LIVE_VOP_ON_EXIT.
(pass_pre::execute): Assert virtual SSA form is up-to-date
after insertion.
* g++.dg/torture/pr63476.C: New testcase.
Index: gcc/tree-ssa-pre.c
===================================================================
--- gcc/tree-ssa-pre.c (revision 216037)
+++ gcc/tree-ssa-pre.c (working copy)
@@ -423,6 +423,9 @@ typedef struct bb_bitmap_sets
/* A cache for value_dies_in_block_x. */
bitmap expr_dies;
+ /* The live virtual operand on successor edges. */
+ tree vop_on_exit;
+
/* True if we have visited this block during ANTIC calculation. */
unsigned int visited : 1;
@@ -440,6 +443,7 @@ typedef struct bb_bitmap_sets
#define EXPR_DIES(BB) ((bb_value_sets_t) ((BB)->aux))->expr_dies
#define BB_VISITED(BB) ((bb_value_sets_t) ((BB)->aux))->visited
#define BB_MAY_NOTRETURN(BB) ((bb_value_sets_t) ((BB)->aux))->contains_may_not_return_call
+#define BB_LIVE_VOP_ON_EXIT(BB) ((bb_value_sets_t) ((BB)->aux))->vop_on_exit
/* Basic block list in postorder. */
@@ -2886,12 +2890,15 @@ create_expression_by_pieces (basic_block
bitmap_value_replace_in_set (NEW_SETS (block), nameexpr);
bitmap_value_replace_in_set (AVAIL_OUT (block), nameexpr);
}
+
+ gimple_set_vuse (stmt, BB_LIVE_VOP_ON_EXIT (block));
}
gimple_seq_add_seq (stmts, forced_stmts);
}
name = make_temp_ssa_name (exprtype, NULL, "pretmp");
newstmt = gimple_build_assign (name, folded);
+ gimple_set_vuse (newstmt, BB_LIVE_VOP_ON_EXIT (block));
gimple_set_plf (newstmt, NECESSARY, false);
gimple_seq_add_stmt (stmts, newstmt);
@@ -3593,6 +3623,9 @@ compute_avail (void)
son = next_dom_son (CDI_DOMINATORS, son))
worklist[sp++] = son;
+ BB_LIVE_VOP_ON_EXIT (ENTRY_BLOCK_PTR_FOR_FN (cfun))
+ = ssa_default_def (cfun, gimple_vop (cfun));
+
/* Loop until the worklist is empty. */
while (sp)
{
@@ -3607,7 +3640,10 @@ compute_avail (void)
its immediate dominator. */
dom = get_immediate_dominator (CDI_DOMINATORS, block);
if (dom)
- bitmap_set_copy (AVAIL_OUT (block), AVAIL_OUT (dom));
+ {
+ bitmap_set_copy (AVAIL_OUT (block), AVAIL_OUT (dom));
+ BB_LIVE_VOP_ON_EXIT (block) = BB_LIVE_VOP_ON_EXIT (dom);
+ }
/* Generate values for PHI nodes. */
for (gsi = gsi_start_phis (block); !gsi_end_p (gsi); gsi_next (&gsi))
@@ -3617,7 +3653,10 @@ compute_avail (void)
/* We have no need for virtual phis, as they don't represent
actual computations. */
if (virtual_operand_p (result))
- continue;
+ {
+ BB_LIVE_VOP_ON_EXIT (block) = result;
+ continue;
+ }
pre_expr e = get_or_alloc_expr_for_name (result);
add_to_value (get_expr_value_id (e), e);
@@ -3661,6 +3700,9 @@ compute_avail (void)
bitmap_value_insert_into_set (AVAIL_OUT (block), e);
}
+ if (gimple_vdef (stmt))
+ BB_LIVE_VOP_ON_EXIT (block) = gimple_vdef (stmt);
+
if (gimple_has_side_effects (stmt)
|| stmt_could_throw_p (stmt)
|| is_gimple_debug (stmt))
@@ -4758,6 +4794,10 @@ pass_pre::execute (function *fun)
remove_fake_exit_edges ();
gsi_commit_edge_inserts ();
+ /* Eliminate folds statements which might (should not...) end up
+ not keeping virtual operands up-to-date. */
+ gcc_assert (!need_ssa_update_p (fun));
+
/* Remove all the redundant expressions. */
todo |= eliminate (true);
Index: gcc/testsuite/g++.dg/torture/pr63476.C
===================================================================
--- gcc/testsuite/g++.dg/torture/pr63476.C (revision 0)
+++ gcc/testsuite/g++.dg/torture/pr63476.C (working copy)
@@ -0,0 +1,39 @@
+// { dg-do compile }
+// { dg-additional-options "-std=gnu++11" }
+
+enum class nsresult;
+class A;
+class B
+{
+public:
+ B (int);
+ A *operator->();
+};
+class C
+{
+};
+class A
+{
+public:
+ virtual nsresult AddObserver (const char *, C *, bool) = 0;
+};
+class D : A
+{
+ nsresult
+ AddObserver (const char *p1, C *p2, bool p3)
+ {
+ AddObserver (p1, p2, p3);
+ }
+};
+char *prefList[]{};
+class F : C
+{
+ nsresult Install ();
+};
+nsresult
+F::Install ()
+{
+ B branch = 0;
+ for (int i;;)
+ branch->AddObserver (prefList[i], this, false);
+}
^ permalink raw reply [flat|nested] only message in thread
only message in thread, other threads:[~2014-10-10 11:07 UTC | newest]
Thread overview: (only message) (download: mbox.gz / follow: Atom feed)
-- links below jump to the message on this page --
2014-10-10 11:08 [PATCH] Fix PR63476 Richard Biener
This is a public inbox, see mirroring instructions
for how to clone and mirror all data and code used for this inbox;
as well as URLs for read-only IMAP folder(s) and NNTP newsgroup(s).