[PATCH v2 2/4] Refactor loop_version
Richard Biener
rguenther@suse.de
Fri Oct 29 11:52:43 GMT 2021
On Wed, 27 Oct 2021, Xionghu Luo wrote:
> loop_version currently does lv_adjust_loop_entry_edge
> before it loopifys the copy inserted on the header. This patch moves
> the condition generation later and thus we have four pieces to help
> understanding of how the adjustment works:
> 1) duplicating the loop on the entry edge.
> 2) loopify the duplicated new loop.
> 3) adjusting the CFG to insert a condition branching to either loop
> with lv_adjust_loop_entry_edge.
> 4) From loopify extract the scale_loop_frequencies bits.
>
> Also removed some piece of code seems obviously useless which is not
> completely sure:
> - redirect_all_edges since it is false and loopify only called once.
> - extract_cond_bb_edges and lv_flush_pending_stmts (false_edge) as the
> edge is not redirected actually.
This is OK (you can also commit this independently), thanks for the
cleanup.
Richard.
> gcc/ChangeLog:
>
> * cfgloopmanip.c (loop_version): Refactor loopify to
> loop_version. Move condition generation after loopify.
> (loopify): Delete.
> * cfgloopmanip.h (loopify): Delete.
> ---
> gcc/cfgloopmanip.c | 113 ++++++++++++---------------------------------
> gcc/cfgloopmanip.h | 3 --
> 2 files changed, 29 insertions(+), 87 deletions(-)
>
> diff --git a/gcc/cfgloopmanip.c b/gcc/cfgloopmanip.c
> index 82c242dd720..a30ebe1cdb4 100644
> --- a/gcc/cfgloopmanip.c
> +++ b/gcc/cfgloopmanip.c
> @@ -846,71 +846,6 @@ create_empty_loop_on_edge (edge entry_edge,
> return loop;
> }
>
> -/* Make area between HEADER_EDGE and LATCH_EDGE a loop by connecting
> - latch to header and update loop tree and dominators
> - accordingly. Everything between them plus LATCH_EDGE destination must
> - be dominated by HEADER_EDGE destination, and back-reachable from
> - LATCH_EDGE source. HEADER_EDGE is redirected to basic block SWITCH_BB,
> - FALSE_EDGE of SWITCH_BB to original destination of HEADER_EDGE and
> - TRUE_EDGE of SWITCH_BB to original destination of LATCH_EDGE.
> - Returns the newly created loop. Frequencies and counts in the new loop
> - are scaled by FALSE_SCALE and in the old one by TRUE_SCALE. */
> -
> -class loop *
> -loopify (edge latch_edge, edge header_edge,
> - basic_block switch_bb, edge true_edge, edge false_edge,
> - bool redirect_all_edges, profile_probability true_scale,
> - profile_probability false_scale)
> -{
> - basic_block succ_bb = latch_edge->dest;
> - basic_block pred_bb = header_edge->src;
> - class loop *loop = alloc_loop ();
> - class loop *outer = loop_outer (succ_bb->loop_father);
> - profile_count cnt;
> -
> - loop->header = header_edge->dest;
> - loop->latch = latch_edge->src;
> -
> - cnt = header_edge->count ();
> -
> - /* Redirect edges. */
> - loop_redirect_edge (latch_edge, loop->header);
> - loop_redirect_edge (true_edge, succ_bb);
> -
> - /* During loop versioning, one of the switch_bb edge is already properly
> - set. Do not redirect it again unless redirect_all_edges is true. */
> - if (redirect_all_edges)
> - {
> - loop_redirect_edge (header_edge, switch_bb);
> - loop_redirect_edge (false_edge, loop->header);
> -
> - /* Update dominators. */
> - set_immediate_dominator (CDI_DOMINATORS, switch_bb, pred_bb);
> - set_immediate_dominator (CDI_DOMINATORS, loop->header, switch_bb);
> - }
> -
> - set_immediate_dominator (CDI_DOMINATORS, succ_bb, switch_bb);
> -
> - /* Compute new loop. */
> - add_loop (loop, outer);
> -
> - /* Add switch_bb to appropriate loop. */
> - if (switch_bb->loop_father)
> - remove_bb_from_loops (switch_bb);
> - add_bb_to_loop (switch_bb, outer);
> -
> - /* Fix counts. */
> - if (redirect_all_edges)
> - {
> - switch_bb->count = cnt;
> - }
> - scale_loop_frequencies (loop, false_scale);
> - scale_loop_frequencies (succ_bb->loop_father, true_scale);
> - update_dominators_in_loop (loop);
> -
> - return loop;
> -}
> -
> /* Remove the latch edge of a LOOP and update loops to indicate that
> the LOOP was removed. After this function, original loop latch will
> have no successor, which caller is expected to fix somehow.
> @@ -1681,7 +1616,7 @@ loop_version (class loop *loop,
> bool place_after)
> {
> basic_block first_head, second_head;
> - edge entry, latch_edge, true_edge, false_edge;
> + edge entry, latch_edge;
> int irred_flag;
> class loop *nloop;
> basic_block cond_bb;
> @@ -1694,7 +1629,7 @@ loop_version (class loop *loop,
> /* Note down head of loop as first_head. */
> first_head = entry->dest;
>
> - /* Duplicate loop. */
> + /* 1) Duplicate loop on the entry edge. */
> if (!cfg_hook_duplicate_loop_to_header_edge (loop, entry, 1,
> NULL, NULL, NULL, 0))
> {
> @@ -1702,11 +1637,28 @@ loop_version (class loop *loop,
> return NULL;
> }
>
> + /* 2) loopify the duplicated new loop. */
> + latch_edge = single_succ_edge (get_bb_copy (loop->latch));
> + nloop = alloc_loop ();
> + class loop *outer = loop_outer (latch_edge->dest->loop_father);
> + edge new_header_edge = single_pred_edge (get_bb_copy (loop->header));
> + nloop->header = new_header_edge->dest;
> + nloop->latch = latch_edge->src;
> + loop_redirect_edge (latch_edge, nloop->header);
> +
> + /* Compute new loop. */
> + add_loop (nloop, outer);
> + copy_loop_info (loop, nloop);
> + set_loop_copy (loop, nloop);
> +
> + /* loopify redirected latch_edge. Update its PENDING_STMTS. */
> + lv_flush_pending_stmts (latch_edge);
> +
> /* After duplication entry edge now points to new loop head block.
> Note down new head as second_head. */
> second_head = entry->dest;
>
> - /* Split loop entry edge and insert new block with cond expr. */
> + /* 3) Split loop entry edge and insert new block with cond expr. */
> cond_bb = lv_adjust_loop_entry_edge (first_head, second_head,
> entry, cond_expr, then_prob, else_prob);
> if (condition_bb)
> @@ -1718,24 +1670,17 @@ loop_version (class loop *loop,
> return NULL;
> }
>
> - latch_edge = single_succ_edge (get_bb_copy (loop->latch));
> -
> - extract_cond_bb_edges (cond_bb, &true_edge, &false_edge);
> - nloop = loopify (latch_edge,
> - single_pred_edge (get_bb_copy (loop->header)),
> - cond_bb, true_edge, false_edge,
> - false /* Do not redirect all edges. */,
> - then_scale, else_scale);
> -
> - copy_loop_info (loop, nloop);
> - set_loop_copy (loop, nloop);
> + /* Add cond_bb to appropriate loop. */
> + if (cond_bb->loop_father)
> + remove_bb_from_loops (cond_bb);
> + add_bb_to_loop (cond_bb, outer);
>
> - /* loopify redirected latch_edge. Update its PENDING_STMTS. */
> - lv_flush_pending_stmts (latch_edge);
> + /* 4) Scale the original loop and new loop frequency. */
> + scale_loop_frequencies (loop, then_scale);
> + scale_loop_frequencies (nloop, else_scale);
> + update_dominators_in_loop (loop);
> + update_dominators_in_loop (nloop);
>
> - /* loopify redirected condition_bb's succ edge. Update its PENDING_STMTS. */
> - extract_cond_bb_edges (cond_bb, &true_edge, &false_edge);
> - lv_flush_pending_stmts (false_edge);
> /* Adjust irreducible flag. */
> if (irred_flag)
> {
> diff --git a/gcc/cfgloopmanip.h b/gcc/cfgloopmanip.h
> index 07d5f925b79..312a3b48d05 100644
> --- a/gcc/cfgloopmanip.h
> +++ b/gcc/cfgloopmanip.h
> @@ -42,9 +42,6 @@ extern void scale_loop_profile (class loop *, profile_probability, gcov_type);
> extern edge create_empty_if_region_on_edge (edge, tree);
> extern class loop *create_empty_loop_on_edge (edge, tree, tree, tree, tree,
> tree *, tree *, class loop *);
> -extern class loop *loopify (edge, edge,
> - basic_block, edge, edge, bool,
> - profile_probability, profile_probability);
> extern void unloop (class loop *, bool *, bitmap);
> extern void copy_loop_info (class loop *loop, class loop *target);
> extern class loop * duplicate_loop (class loop *, class loop *,
>
--
Richard Biener <rguenther@suse.de>
SUSE Software Solutions Germany GmbH, Maxfeldstrasse 5, 90409 Nuernberg,
Germany; GF: Ivo Totev; HRB 36809 (AG Nuernberg)
More information about the Gcc-patches
mailing list