diff options
author | Richard Biener <rguenther@suse.de> | 2023-08-08 12:46:42 +0200 |
---|---|---|
committer | Richard Biener <rguenther@suse.de> | 2023-08-08 14:24:12 +0200 |
commit | 31ec413098bd334115aff73fc755e49afd3ac371 (patch) | |
tree | 7f50ee79560b42cfb2c673638627441d58bf57b4 /gcc | |
parent | 25c4b1620ebc10fceabd86a34fdbbaf8037e7e82 (diff) | |
download | gcc-31ec413098bd334115aff73fc755e49afd3ac371.zip gcc-31ec413098bd334115aff73fc755e49afd3ac371.tar.gz gcc-31ec413098bd334115aff73fc755e49afd3ac371.tar.bz2 |
tree-optimization/110924 - fix vop liveness for noreturn const CFG parts
The virtual operand live problem used by sinking assumes we have
virtual uses at each end point of the CFG but as shown in the PR
this isn't true for parts for example ending in __builtin_unreachable.
The following removes the optimization made possible by this and
now requires marking backedges.
PR tree-optimization/110924
* tree-ssa-live.h (virtual_operand_live): Update comment.
* tree-ssa-live.cc (virtual_operand_live::get_live_in): Remove
optimization, look at each predecessor.
* tree-ssa-sink.cc (pass_sink_code::execute): Mark backedges.
* gcc.dg/torture/pr110924.c: New testcase.
Diffstat (limited to 'gcc')
-rw-r--r-- | gcc/testsuite/gcc.dg/torture/pr110924.c | 23 | ||||
-rw-r--r-- | gcc/tree-ssa-live.cc | 32 | ||||
-rw-r--r-- | gcc/tree-ssa-live.h | 3 | ||||
-rw-r--r-- | gcc/tree-ssa-sink.cc | 1 |
4 files changed, 44 insertions, 15 deletions
diff --git a/gcc/testsuite/gcc.dg/torture/pr110924.c b/gcc/testsuite/gcc.dg/torture/pr110924.c new file mode 100644 index 0000000..7b39577 --- /dev/null +++ b/gcc/testsuite/gcc.dg/torture/pr110924.c @@ -0,0 +1,23 @@ +/* { dg-do compile } */ + +int a[1], b, c, d, e, f, g; +void h(int i, int j) { + int *k = 0; + if (*k) + h(0, 0); + g = i && d; +} +int main() { + if (c) + goto l; + if (!a) + while (1) { + f = 1; + while (f) + h(b && main(), e); + while (1) + ; + l:; + } + return 0; +} diff --git a/gcc/tree-ssa-live.cc b/gcc/tree-ssa-live.cc index c9c2fde..61789fa 100644 --- a/gcc/tree-ssa-live.cc +++ b/gcc/tree-ssa-live.cc @@ -1676,23 +1676,27 @@ virtual_operand_live::get_live_in (basic_block bb) if (!liveout) init (); - /* Since we don't have a virtual PHI we can now pick any of the - incoming edges liveout value. All returns from the function have - a virtual use forcing generation of virtual PHIs. */ + /* Since we don't have a virtual PHI and we don't know whether there's + a downstream virtual use (and thus PHIs are inserted where necessary) + we now have to check each incoming edge live-out. */ edge_iterator ei; edge e; + tree livein = NULL_TREE; FOR_EACH_EDGE (e, ei, bb->preds) - if (liveout[e->src->index]) - { - if (EDGE_PRED (bb, 0) != e) - liveout[EDGE_PRED (bb, 0)->src->index] = liveout[e->src->index]; - return liveout[e->src->index]; - } - - /* Since virtuals are in SSA form at most the immediate dominator can - contain the definition of the live version. Skipping to that deals - with CFG cycles as well. */ - return get_live_out (get_immediate_dominator (CDI_DOMINATORS, bb)); + if (e->flags & EDGE_DFS_BACK) + /* We can ignore backedges since if there's a def there it would + have forced a PHI in the source because it also acts as use + downstream. */ + continue; + else if (!livein) + livein = get_live_out (e->src); + else if (get_live_out (e->src) != livein) + /* When there's no virtual use downstream this indicates a point + where we'd insert a PHI merging the different live virtual + operands. */ + return NULL_TREE; + + return livein; } /* Compute live-out of BB. */ diff --git a/gcc/tree-ssa-live.h b/gcc/tree-ssa-live.h index a760444..d175ad7 100644 --- a/gcc/tree-ssa-live.h +++ b/gcc/tree-ssa-live.h @@ -332,7 +332,8 @@ make_live_on_entry (tree_live_info_p live, basic_block bb , int p) /* On-demand virtual operand global live analysis. There is at most a single virtual operand live at a time, the following computes and caches the virtual operand live at the exit of a basic block - supporting related live-in and live-on-edge queries. */ + supporting related live-in and live-on-edge queries. It requires + up-to-date marked backedges. */ class virtual_operand_live { diff --git a/gcc/tree-ssa-sink.cc b/gcc/tree-ssa-sink.cc index 6ad9d21..a360c5c 100644 --- a/gcc/tree-ssa-sink.cc +++ b/gcc/tree-ssa-sink.cc @@ -822,6 +822,7 @@ pass_sink_code::execute (function *fun) /* Arrange for the critical edge splitting to be undone if requested. */ unsigned todo = unsplit_edges ? TODO_cleanup_cfg : 0; connect_infinite_loops_to_exit (); + mark_dfs_back_edges (fun); memset (&sink_stats, 0, sizeof (sink_stats)); calculate_dominance_info (CDI_DOMINATORS); |