tree-optimization/112991 - re-do PR112961 fix
The following does away with the fake edge adding as in the original PR112961 fix and instead exposes handling of entry PHIs as additional parameter of the region VN run. PR tree-optimization/112991 PR tree-optimization/112961 * tree-ssa-sccvn.h (do_rpo_vn): Add skip_entry_phis argument. * tree-ssa-sccvn.cc (do_rpo_vn): Likewise. (do_rpo_vn_1): Likewise, merge with auto-processing. (run_rpo_vn): Adjust. (pass_fre::execute): Likewise. * tree-if-conv.cc (tree_if_conversion): Revert last change. Value-number latch block but disable value-numbering of entry PHIs. * tree-ssa-uninit.cc (execute_early_warn_uninitialized): Adjust. * gcc.dg/torture/pr112991.c: New testcase.
This commit is contained in:
parent
b9baead90d
commit
93db32a414
5 changed files with 48 additions and 26 deletions
21
gcc/testsuite/gcc.dg/torture/pr112991.c
Normal file
21
gcc/testsuite/gcc.dg/torture/pr112991.c
Normal file
|
@ -0,0 +1,21 @@
|
|||
/* { dg-do compile } */
|
||||
|
||||
typedef struct {
|
||||
unsigned links[2];
|
||||
} RMF_unit;
|
||||
long RMF_recurseListsBound_count;
|
||||
int RMF_recurseListsBound_tbl, RMF_recurseListsBound_list_head_1;
|
||||
unsigned RMF_recurseListsBound_list_head_0;
|
||||
void RMF_recurseListsBound() {
|
||||
int list_count = RMF_recurseListsBound_list_head_1;
|
||||
long link = RMF_recurseListsBound_list_head_0;
|
||||
for (; RMF_recurseListsBound_count;) {
|
||||
long next_link =
|
||||
((RMF_unit *)&RMF_recurseListsBound_tbl)[link >> 2].links[0];
|
||||
if (link)
|
||||
--RMF_recurseListsBound_count;
|
||||
link = next_link;
|
||||
}
|
||||
while (list_count)
|
||||
;
|
||||
}
|
|
@ -3734,7 +3734,7 @@ tree_if_conversion (class loop *loop, vec<gimple *> *preds)
|
|||
auto_vec <gassign *, 4> reads_to_lower;
|
||||
auto_vec <gassign *, 4> writes_to_lower;
|
||||
bitmap exit_bbs;
|
||||
edge pe, e;
|
||||
edge pe;
|
||||
auto_vec<data_reference_p, 10> refs;
|
||||
bool loop_versioned;
|
||||
|
||||
|
@ -3891,27 +3891,21 @@ tree_if_conversion (class loop *loop, vec<gimple *> *preds)
|
|||
combine_blocks (loop, loop_versioned);
|
||||
}
|
||||
|
||||
/* Perform local CSE, this esp. helps the vectorizer analysis if loads
|
||||
and stores are involved. CSE only the loop body, not the entry
|
||||
PHIs, those are to be kept in sync with the non-if-converted copy.
|
||||
Do this by adding a fake entry edge - we do want to include the
|
||||
latch as otherwise copies on a reduction path cannot be propagated out.
|
||||
??? We'll still keep dead stores though. */
|
||||
e = make_edge (ENTRY_BLOCK_PTR_FOR_FN (cfun), loop->header, EDGE_FAKE);
|
||||
exit_bbs = BITMAP_ALLOC (NULL);
|
||||
for (edge exit : get_loop_exit_edges (loop))
|
||||
bitmap_set_bit (exit_bbs, exit->dest->index);
|
||||
|
||||
std::pair <tree, tree> *name_pair;
|
||||
unsigned ssa_names_idx;
|
||||
FOR_EACH_VEC_ELT (redundant_ssa_names, ssa_names_idx, name_pair)
|
||||
replace_uses_by (name_pair->first, name_pair->second);
|
||||
redundant_ssa_names.release ();
|
||||
|
||||
todo |= do_rpo_vn (cfun, loop_preheader_edge (loop), exit_bbs);
|
||||
|
||||
/* Remove the fake edge again. */
|
||||
remove_edge (e);
|
||||
/* Perform local CSE, this esp. helps the vectorizer analysis if loads
|
||||
and stores are involved. CSE only the loop body, not the entry
|
||||
PHIs, those are to be kept in sync with the non-if-converted copy.
|
||||
??? We'll still keep dead stores though. */
|
||||
exit_bbs = BITMAP_ALLOC (NULL);
|
||||
for (edge exit : get_loop_exit_edges (loop))
|
||||
bitmap_set_bit (exit_bbs, exit->dest->index);
|
||||
todo |= do_rpo_vn (cfun, loop_preheader_edge (loop), exit_bbs,
|
||||
false, true, true);
|
||||
|
||||
/* Delete dead predicate computations. */
|
||||
ifcvt_local_dce (loop);
|
||||
|
|
|
@ -7584,12 +7584,13 @@ eliminate_with_rpo_vn (bitmap inserted_exprs)
|
|||
|
||||
static unsigned
|
||||
do_rpo_vn_1 (function *fn, edge entry, bitmap exit_bbs,
|
||||
bool iterate, bool eliminate, vn_lookup_kind kind);
|
||||
bool iterate, bool eliminate, bool skip_entry_phis,
|
||||
vn_lookup_kind kind);
|
||||
|
||||
void
|
||||
run_rpo_vn (vn_lookup_kind kind)
|
||||
{
|
||||
do_rpo_vn_1 (cfun, NULL, NULL, true, false, kind);
|
||||
do_rpo_vn_1 (cfun, NULL, NULL, true, false, false, kind);
|
||||
|
||||
/* ??? Prune requirement of these. */
|
||||
constant_to_value_id = new hash_table<vn_constant_hasher> (23);
|
||||
|
@ -8290,11 +8291,13 @@ do_unwind (unwind_state *to, rpo_elim &avail)
|
|||
/* Do VN on a SEME region specified by ENTRY and EXIT_BBS in FN.
|
||||
If ITERATE is true then treat backedges optimistically as not
|
||||
executed and iterate. If ELIMINATE is true then perform
|
||||
elimination, otherwise leave that to the caller. */
|
||||
elimination, otherwise leave that to the caller. If SKIP_ENTRY_PHIS
|
||||
is true then force PHI nodes in ENTRY->dest to VARYING. */
|
||||
|
||||
static unsigned
|
||||
do_rpo_vn_1 (function *fn, edge entry, bitmap exit_bbs,
|
||||
bool iterate, bool eliminate, vn_lookup_kind kind)
|
||||
bool iterate, bool eliminate, bool skip_entry_phis,
|
||||
vn_lookup_kind kind)
|
||||
{
|
||||
unsigned todo = 0;
|
||||
default_vn_walk_kind = kind;
|
||||
|
@ -8335,10 +8338,10 @@ do_rpo_vn_1 (function *fn, edge entry, bitmap exit_bbs,
|
|||
if (e != entry
|
||||
&& !(e->flags & EDGE_DFS_BACK))
|
||||
break;
|
||||
bool skip_entry_phis = e != NULL;
|
||||
if (skip_entry_phis && dump_file && (dump_flags & TDF_DETAILS))
|
||||
if (e != NULL && dump_file && (dump_flags & TDF_DETAILS))
|
||||
fprintf (dump_file, "Region does not contain all edges into "
|
||||
"the entry block, skipping its PHIs.\n");
|
||||
skip_entry_phis |= e != NULL;
|
||||
|
||||
int *bb_to_rpo = XNEWVEC (int, last_basic_block_for_fn (fn));
|
||||
for (int i = 0; i < n; ++i)
|
||||
|
@ -8715,14 +8718,17 @@ do_rpo_vn_1 (function *fn, edge entry, bitmap exit_bbs,
|
|||
If ITERATE is true then treat backedges optimistically as not
|
||||
executed and iterate. If ELIMINATE is true then perform
|
||||
elimination, otherwise leave that to the caller.
|
||||
If SKIP_ENTRY_PHIS is true then force PHI nodes in ENTRY->dest to VARYING.
|
||||
KIND specifies the amount of work done for handling memory operations. */
|
||||
|
||||
unsigned
|
||||
do_rpo_vn (function *fn, edge entry, bitmap exit_bbs,
|
||||
bool iterate, bool eliminate, vn_lookup_kind kind)
|
||||
bool iterate, bool eliminate, bool skip_entry_phis,
|
||||
vn_lookup_kind kind)
|
||||
{
|
||||
auto_timevar tv (TV_TREE_RPO_VN);
|
||||
unsigned todo = do_rpo_vn_1 (fn, entry, exit_bbs, iterate, eliminate, kind);
|
||||
unsigned todo = do_rpo_vn_1 (fn, entry, exit_bbs, iterate, eliminate,
|
||||
skip_entry_phis, kind);
|
||||
free_rpo_vn ();
|
||||
return todo;
|
||||
}
|
||||
|
@ -8778,7 +8784,7 @@ pass_fre::execute (function *fun)
|
|||
if (iterate_p)
|
||||
loop_optimizer_init (AVOID_CFG_MODIFICATIONS);
|
||||
|
||||
todo = do_rpo_vn_1 (fun, NULL, NULL, iterate_p, true, VN_WALKREWRITE);
|
||||
todo = do_rpo_vn_1 (fun, NULL, NULL, iterate_p, true, false, VN_WALKREWRITE);
|
||||
free_rpo_vn ();
|
||||
|
||||
if (iterate_p)
|
||||
|
|
|
@ -298,6 +298,7 @@ tree vn_nary_simplify (vn_nary_op_t);
|
|||
unsigned do_rpo_vn (function *, edge, bitmap,
|
||||
/* iterate */ bool = false,
|
||||
/* eliminate */ bool = true,
|
||||
/* skip_entry_phis */ bool = false,
|
||||
vn_lookup_kind = VN_WALKREWRITE);
|
||||
|
||||
/* Private interface for PRE. */
|
||||
|
|
|
@ -1500,7 +1500,7 @@ execute_early_warn_uninitialized (struct function *fun)
|
|||
elimination to compute edge reachability. Don't bother when
|
||||
we only warn for unconditionally executed code though. */
|
||||
if (!optimize)
|
||||
do_rpo_vn (fun, NULL, NULL, false, false, VN_NOWALK);
|
||||
do_rpo_vn (fun, NULL, NULL, false, false, false, VN_NOWALK);
|
||||
else
|
||||
set_all_edges_as_executable (fun);
|
||||
|
||||
|
|
Loading…
Add table
Reference in a new issue