diff options
author | Richard Biener <rguenther@suse.de> | 2024-04-24 08:42:40 +0200 |
---|---|---|
committer | Richard Biener <rguenther@suse.de> | 2024-04-24 10:11:00 +0200 |
commit | cc48418cfc2e555d837ae9138cbfac23acb3cdf9 (patch) | |
tree | 32d95b47915d733e81bc0f41a3ee48f64a954235 /gcc/tree-cfg.cc | |
parent | e28e8ab1a92e9b49f7c4045377577c8dc17751b7 (diff) | |
download | gcc-cc48418cfc2e555d837ae9138cbfac23acb3cdf9.zip gcc-cc48418cfc2e555d837ae9138cbfac23acb3cdf9.tar.gz gcc-cc48418cfc2e555d837ae9138cbfac23acb3cdf9.tar.bz2 |
tree-optimization/114787 - more careful loop update with CFG cleanup
When CFG cleanup removes a backedge we have to be more careful with
loop update. In particular we need to clear niter info and estimates
and if we remove the last backedge of a loop we have to also mark
it for removal to prevent a following basic block merging to associate
loop info with an unrelated header.
PR tree-optimization/114787
* tree-cfg.cc (remove_edge_and_dominated_blocks): When
removing a loop backedge clear niter info and when removing
the last backedge of a loop mark that loop for removal.
* gcc.dg/torture/pr114787.c: New testcase.
Diffstat (limited to 'gcc/tree-cfg.cc')
-rw-r--r-- | gcc/tree-cfg.cc | 26 |
1 files changed, 23 insertions, 3 deletions
diff --git a/gcc/tree-cfg.cc b/gcc/tree-cfg.cc index d98b68d..b1ba330 100644 --- a/gcc/tree-cfg.cc +++ b/gcc/tree-cfg.cc @@ -9013,10 +9013,30 @@ remove_edge_and_dominated_blocks (edge e) /* If we are removing a path inside a non-root loop that may change loop ownership of blocks or remove loops. Mark loops for fixup. */ + class loop *src_loop = e->src->loop_father; if (current_loops - && loop_outer (e->src->loop_father) != NULL - && e->src->loop_father == e->dest->loop_father) - loops_state_set (LOOPS_NEED_FIXUP); + && loop_outer (src_loop) != NULL + && src_loop == e->dest->loop_father) + { + loops_state_set (LOOPS_NEED_FIXUP); + /* If we are removing a backedge clear the number of iterations + and estimates. */ + class loop *dest_loop = e->dest->loop_father; + if (e->dest == src_loop->header + || (e->dest == dest_loop->header + && flow_loop_nested_p (dest_loop, src_loop))) + { + free_numbers_of_iterations_estimates (dest_loop); + /* If we removed the last backedge mark the loop for removal. */ + FOR_EACH_EDGE (f, ei, dest_loop->header->preds) + if (f != e + && (f->src->loop_father == dest_loop + || flow_loop_nested_p (dest_loop, f->src->loop_father))) + break; + if (!f) + mark_loop_for_removal (dest_loop); + } + } if (!dom_info_available_p (CDI_DOMINATORS)) { |