From: Richard Biener Date: Wed, 18 May 2022 09:57:10 +0000 (+0200) Subject: Make sure to cost bb[0], work around unreachable predicates X-Git-Url: http://git.ipfire.org/cgi-bin/gitweb.cgi?a=commitdiff_plain;h=399a970a9e2302fa0ffefc03fad7d8d56801c2e6;p=thirdparty%2Fgcc.git Make sure to cost bb[0], work around unreachable predicates This applies a workaround to avoid unswitching on predicates from BBs that are considered unreachable and to that effect makes sure to always cost bb[0] which we always put on the worklist as reachable. --- diff --git a/gcc/tree-ssa-loop-unswitch.cc b/gcc/tree-ssa-loop-unswitch.cc index c5d3762e8678..d5ec23e276dd 100644 --- a/gcc/tree-ssa-loop-unswitch.cc +++ b/gcc/tree-ssa-loop-unswitch.cc @@ -793,9 +793,11 @@ evaluate_insns (class loop *loop, basic_block *bbs, int reachable_flag, int ignored_edge_flag) { auto_vec worklist (loop->num_nodes); - worklist.quick_push (bbs[0]); hash_set ignored_edges; + bbs[0]->flags |= reachable_flag; + worklist.quick_push (bbs[0]); + while (!worklist.is_empty ()) { edge e; @@ -804,10 +806,7 @@ evaluate_insns (class loop *loop, basic_block *bbs, basic_block bb = worklist.pop (); gimple *last = last_stmt (bb); - gcond *cond = last != NULL ? dyn_cast (last) : NULL; - gswitch *swtch = last != NULL ? dyn_cast (last) : NULL; - - if (cond != NULL) + if (gcond *cond = safe_dyn_cast (last)) { if (gimple_cond_true_p (cond)) flags = EDGE_FALSE_VALUE; @@ -824,11 +823,11 @@ evaluate_insns (class loop *loop, basic_block *bbs, ? EDGE_FALSE_VALUE : EDGE_TRUE_VALUE); } } - else if (swtch != NULL - && !get_predicates_for_bb (bb).is_empty ()) - evaluate_control_stmt_using_entry_checks (swtch, predicate_path, - ignored_edge_flag, - &ignored_edges); + else if (gswitch *swtch = safe_dyn_cast (last)) + if (!get_predicates_for_bb (bb).is_empty ()) + evaluate_control_stmt_using_entry_checks (swtch, predicate_path, + ignored_edge_flag, + &ignored_edges); /* ??? We fail to account for removed condition or switch stmts. */ @@ -909,6 +908,9 @@ tree_unswitch_single_loop (class loop *loop, dump_user_location_t loc, for (unsigned i = 0; i < loop->num_nodes; i++) { + /* ??? The caller computed reachability of blocks when + evaluating costs but we are still processing predicates + on unreachable ones. */ for (auto pred : get_predicates_for_bb (bbs[i])) { if (bitmap_bit_p (handled, pred->num)) @@ -917,8 +919,13 @@ tree_unswitch_single_loop (class loop *loop, dump_user_location_t loc, evaluate_loop_insns_for_predicate (loop, bbs, predicate_path, pred, ignored_edge_flag, &true_size, &false_size); + gcc_assert (true_size + false_size >= loop_size); + /* When the block was unreachable the predicate has no effect. */ + if (true_size == loop_size && false_size == loop_size) + continue; + /* FIXME: right now we select first candidate, but we can choose the cheapest or hottest one. */ if (true_size + false_size < budget + loop_size)