diff options
author | rguenth <rguenth@138bc75d-0d04-0410-961f-82ee72b054a4> | 2014-10-10 11:04:39 +0000 |
---|---|---|
committer | rguenth <rguenth@138bc75d-0d04-0410-961f-82ee72b054a4> | 2014-10-10 11:04:39 +0000 |
commit | 7fb143175ad89b782aaa27590154793ff6a3eeee (patch) | |
tree | e638431b48966d3cc553743c8149eefa811f8246 /gcc/tree-ssa-pre.c | |
parent | 5154c2c35c32af9692c702aa2d88b283019be8b4 (diff) | |
download | gcc-7fb143175ad89b782aaa27590154793ff6a3eeee.tar.gz |
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.
git-svn-id: svn+ssh://gcc.gnu.org/svn/gcc/trunk@216065 138bc75d-0d04-0410-961f-82ee72b054a4
Diffstat (limited to 'gcc/tree-ssa-pre.c')
-rw-r--r-- | gcc/tree-ssa-pre.c | 27 |
1 files changed, 25 insertions, 2 deletions
diff --git a/gcc/tree-ssa-pre.c b/gcc/tree-ssa-pre.c index cbbd4220433..a447c1e4f06 100644 --- a/gcc/tree-ssa-pre.c +++ b/gcc/tree-ssa-pre.c @@ -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 block, pre_expr expr, 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 +3600,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 +3617,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 +3630,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 +3677,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 +4777,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); |