From mboxrd@z Thu Jan 1 00:00:00 1970 Return-Path: Received: by sourceware.org (Postfix, from userid 1666) id 06E7E3857C4E; Fri, 25 Sep 2020 11:12:03 +0000 (GMT) DKIM-Filter: OpenDKIM Filter v2.11.0 sourceware.org 06E7E3857C4E Content-Type: text/plain; charset="us-ascii" MIME-Version: 1.0 Content-Transfer-Encoding: 7bit From: Richard Biener To: gcc-cvs@gcc.gnu.org Subject: [gcc r11-3456] tree-optimization/97199 - fix virtual operand update in if-conversion X-Act-Checkin: gcc X-Git-Author: Richard Biener X-Git-Refname: refs/heads/master X-Git-Oldrev: 8c775bf447e190024fa08c55e38db94dd013a393 X-Git-Newrev: 4dcc7f03b54087638e084ac69d40d7507fe83bd8 Message-Id: <20200925111203.06E7E3857C4E@sourceware.org> Date: Fri, 25 Sep 2020 11:12:03 +0000 (GMT) X-BeenThere: gcc-cvs@gcc.gnu.org X-Mailman-Version: 2.1.29 Precedence: list List-Id: Gcc-cvs mailing list List-Unsubscribe: , List-Archive: List-Help: List-Subscribe: , X-List-Received-Date: Fri, 25 Sep 2020 11:12:03 -0000 https://gcc.gnu.org/g:4dcc7f03b54087638e084ac69d40d7507fe83bd8 commit r11-3456-g4dcc7f03b54087638e084ac69d40d7507fe83bd8 Author: Richard Biener Date: Fri Sep 25 13:08:48 2020 +0200 tree-optimization/97199 - fix virtual operand update in if-conversion This fixes a corner case with virtual operand update in if-conversion by re-organizing the code to remove edges only after the last point we need virtual PHI operands to be available. 2020-09-25 Richard Biener PR tree-optimization/97199 * tree-if-conv.c (combine_blocks): Remove edges only after looking at virtual PHI args. Diff: --- gcc/tree-if-conv.c | 107 +++++++++++++++++++++++++++++++---------------------- 1 file changed, 63 insertions(+), 44 deletions(-) diff --git a/gcc/tree-if-conv.c b/gcc/tree-if-conv.c index 4b8d457867e..2062758f40f 100644 --- a/gcc/tree-if-conv.c +++ b/gcc/tree-if-conv.c @@ -2544,8 +2544,7 @@ combine_blocks (class loop *loop) if (need_to_predicate) predicate_statements (loop); - /* Merge basic blocks: first remove all the edges in the loop, - except for those from the exit block. */ + /* Merge basic blocks. */ exit_bb = NULL; bool *predicated = XNEWVEC (bool, orig_loop_num_nodes); for (i = 0; i < orig_loop_num_nodes; i++) @@ -2561,43 +2560,6 @@ combine_blocks (class loop *loop) } gcc_assert (exit_bb != loop->latch); - for (i = 1; i < orig_loop_num_nodes; i++) - { - bb = ifc_bbs[i]; - - for (ei = ei_start (bb->preds); (e = ei_safe_edge (ei));) - { - if (e->src == exit_bb) - ei_next (&ei); - else - remove_edge (e); - } - } - - if (exit_bb != NULL) - { - if (exit_bb != loop->header) - { - /* Connect this node to loop header. */ - make_single_succ_edge (loop->header, exit_bb, EDGE_FALLTHRU); - set_immediate_dominator (CDI_DOMINATORS, exit_bb, loop->header); - } - - /* Redirect non-exit edges to loop->latch. */ - FOR_EACH_EDGE (e, ei, exit_bb->succs) - { - if (!loop_exit_edge_p (loop, e)) - redirect_edge_and_branch (e, loop->latch); - } - set_immediate_dominator (CDI_DOMINATORS, loop->latch, exit_bb); - } - else - { - /* If the loop does not have an exit, reconnect header and latch. */ - make_edge (loop->header, loop->latch, EDGE_FALLTHRU); - set_immediate_dominator (CDI_DOMINATORS, loop->latch, loop->header); - } - merge_target_bb = loop->header; /* Get at the virtual def valid for uses starting at the first block @@ -2682,13 +2644,9 @@ combine_blocks (class loop *loop) last = gsi_last_bb (merge_target_bb); gsi_insert_seq_after_without_update (&last, bb_seq (bb), GSI_NEW_STMT); set_bb_seq (bb, NULL); - - delete_basic_block (bb); } - /* If possible, merge loop header to the block with the exit edge. - This reduces the number of basic blocks to two, to please the - vectorizer that handles only loops with two nodes. */ + /* Fixup virtual operands in the exit block. */ if (exit_bb && exit_bb != loop->header) { @@ -2698,6 +2656,11 @@ combine_blocks (class loop *loop) vphi = get_virtual_phi (exit_bb); if (vphi) { + /* When there's just loads inside the loop a stray virtual + PHI merging the uses can appear, update last_vdef from + it. */ + if (!last_vdef) + last_vdef = gimple_phi_arg_def (vphi, 0); imm_use_iterator iter; use_operand_p use_p; gimple *use_stmt; @@ -2711,7 +2674,63 @@ combine_blocks (class loop *loop) gimple_stmt_iterator gsi = gsi_for_stmt (vphi); remove_phi_node (&gsi, true); } + } + + /* Now remove all the edges in the loop, except for those from the exit + block and delete the blocks we elided. */ + for (i = 1; i < orig_loop_num_nodes; i++) + { + bb = ifc_bbs[i]; + + for (ei = ei_start (bb->preds); (e = ei_safe_edge (ei));) + { + if (e->src == exit_bb) + ei_next (&ei); + else + remove_edge (e); + } + } + for (i = 1; i < orig_loop_num_nodes; i++) + { + bb = ifc_bbs[i]; + + if (bb == exit_bb || bb == loop->latch) + continue; + + delete_basic_block (bb); + } + + /* Re-connect the exit block. */ + if (exit_bb != NULL) + { + if (exit_bb != loop->header) + { + /* Connect this node to loop header. */ + make_single_succ_edge (loop->header, exit_bb, EDGE_FALLTHRU); + set_immediate_dominator (CDI_DOMINATORS, exit_bb, loop->header); + } + /* Redirect non-exit edges to loop->latch. */ + FOR_EACH_EDGE (e, ei, exit_bb->succs) + { + if (!loop_exit_edge_p (loop, e)) + redirect_edge_and_branch (e, loop->latch); + } + set_immediate_dominator (CDI_DOMINATORS, loop->latch, exit_bb); + } + else + { + /* If the loop does not have an exit, reconnect header and latch. */ + make_edge (loop->header, loop->latch, EDGE_FALLTHRU); + set_immediate_dominator (CDI_DOMINATORS, loop->latch, loop->header); + } + + /* If possible, merge loop header to the block with the exit edge. + This reduces the number of basic blocks to two, to please the + vectorizer that handles only loops with two nodes. */ + if (exit_bb + && exit_bb != loop->header) + { if (can_merge_blocks_p (loop->header, exit_bb)) merge_blocks (loop->header, exit_bb); }