https://gcc.gnu.org/g:8a7e9581280c41f3c18cba7fafe110b4108a07a7
commit 8a7e9581280c41f3c18cba7fafe110b4108a07a7 Author: Alexandre Oliva <ol...@gnu.org> Date: Sat Sep 14 03:40:26 2024 -0300 support noncontiguous ifcombine Diff: --- gcc/tree-ssa-ifcombine.cc | 33 ++++++++++++++++++++++++++------- 1 file changed, 26 insertions(+), 7 deletions(-) diff --git a/gcc/tree-ssa-ifcombine.cc b/gcc/tree-ssa-ifcombine.cc index eb4317bebdfb..b52d343feb91 100644 --- a/gcc/tree-ssa-ifcombine.cc +++ b/gcc/tree-ssa-ifcombine.cc @@ -782,13 +782,13 @@ tree_ssa_ifcombine_bb_1 (basic_block inner_cond_bb, basic_block outer_cond_bb, if-conversion helper. We start with BB as the innermost worker basic-block. Returns true if a transformation was done. */ -static bool +static basic_block tree_ssa_ifcombine_bb (basic_block inner_cond_bb) { basic_block then_bb = NULL, else_bb = NULL; if (!recognize_if_then_else (inner_cond_bb, &then_bb, &else_bb)) - return false; + return NULL; /* Recognize && and || of two conditions with a common then/else block which entry edges we can merge. That is: @@ -805,7 +805,7 @@ tree_ssa_ifcombine_bb (basic_block inner_cond_bb) if (tree_ssa_ifcombine_bb_1 (inner_cond_bb, outer_cond_bb, then_bb, else_bb, inner_cond_bb)) - return true; + return bb; if (forwarder_block_to (else_bb, then_bb)) { @@ -817,7 +817,7 @@ tree_ssa_ifcombine_bb (basic_block inner_cond_bb) edge from outer_cond_bb and the forwarder block. */ if (tree_ssa_ifcombine_bb_1 (inner_cond_bb, outer_cond_bb, else_bb, then_bb, else_bb)) - return true; + return bb; } else if (forwarder_block_to (then_bb, else_bb)) { @@ -829,11 +829,11 @@ tree_ssa_ifcombine_bb (basic_block inner_cond_bb) edge from outer_cond_bb and the forwarder block. */ if (tree_ssa_ifcombine_bb_1 (inner_cond_bb, outer_cond_bb, else_bb, then_bb, then_bb)) - return true; + return bb; } } - return false; + return NULL; } /* Main entry for the tree if-conversion pass. */ @@ -884,12 +884,14 @@ pass_tree_ifcombine::execute (function *fun) inner ones, and also that we do not try to visit a removed block. This is opposite of PHI-OPT, because we cascade the combining rather than cascading PHIs. */ + basic_block seen = NULL; + bool changed = false; for (i = n_basic_blocks_for_fn (fun) - NUM_FIXED_BLOCKS - 1; i >= 0; i--) { basic_block bb = bbs[i]; if (safe_is_a <gcond *> (*gsi_last_bb (bb))) - if (tree_ssa_ifcombine_bb (bb)) + if (basic_block outer_bb = tree_ssa_ifcombine_bb (bb)) { /* Clear range info from all stmts in BB which is now executed conditional on a always true/false condition. */ @@ -908,7 +910,24 @@ pass_tree_ifcombine::execute (function *fun) rewrite_to_defined_overflow (&gsi); } cfg_changed |= true; + if (seen) + changed |= true; + else + seen = bb; + /* Go back and check whether the modified outer_bb can be further + optimized. ??? How could it? */ + do + i++; + while (bbs[i] != outer_bb); + continue; } + + if (bb == seen) + { + gcc_assert (!changed); + seen = NULL; + changed = false; + } } free (bbs);