From mboxrd@z Thu Jan 1 00:00:00 1970 Return-Path: Received: by sourceware.org (Postfix, from userid 1851) id 8580F3858018; Tue, 7 Dec 2021 16:50:06 +0000 (GMT) DKIM-Filter: OpenDKIM Filter v2.11.0 sourceware.org 8580F3858018 Content-Type: text/plain; charset="us-ascii" MIME-Version: 1.0 Content-Transfer-Encoding: 7bit From: Martin Liska To: gcc-cvs@gcc.gnu.org Subject: [gcc(refs/users/marxin/heads/loop-unswitch-improvement-v7)] It hopefully works. X-Act-Checkin: gcc X-Git-Author: Martin Liska X-Git-Refname: refs/users/marxin/heads/loop-unswitch-improvement-v7 X-Git-Oldrev: 1ffcf681dd93901c55305bcc8b5e39a2a369cfc9 X-Git-Newrev: da3669b18cce30525a18a34596d82d6a103b6b30 Message-Id: <20211207165006.8580F3858018@sourceware.org> Date: Tue, 7 Dec 2021 16:50:06 +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: Tue, 07 Dec 2021 16:50:06 -0000 https://gcc.gnu.org/g:da3669b18cce30525a18a34596d82d6a103b6b30 commit da3669b18cce30525a18a34596d82d6a103b6b30 Author: Martin Liska Date: Thu Dec 2 16:54:52 2021 +0100 It hopefully works. Diff: --- gcc/tree-ssa-loop-unswitch.c | 93 +++++++++++++++++++++++++++++++++----------- 1 file changed, 71 insertions(+), 22 deletions(-) diff --git a/gcc/tree-ssa-loop-unswitch.c b/gcc/tree-ssa-loop-unswitch.c index a17ede748e6..dab329a5436 100644 --- a/gcc/tree-ssa-loop-unswitch.c +++ b/gcc/tree-ssa-loop-unswitch.c @@ -131,6 +131,7 @@ static bool used_outside_loop_p (class loop *, tree); static void hoist_guard (class loop *, edge); static bool check_exit_phi (class loop *); static tree get_vop_from_header (class loop *); +static void clean_up_after_unswitching (const auto_edge_flag &ignored_edge_flag); /* Return vector of predicates that belong to a basic block. */ @@ -233,9 +234,11 @@ tree_ssa_unswitch_loops (void) disable_ranger (cfun); clear_aux_for_blocks (); + clean_up_after_unswitching (ignored_edge_flag); if (changed) return TODO_cleanup_cfg; + return 0; } @@ -362,11 +365,9 @@ find_unswitching_predicates_for_bb (basic_block bb, class loop *loop, extract_true_false_edges_from_block (bb, &edge_true, &edge_false); unswitch_predicate *predicate = new unswitch_predicate (cond, lhs); - if (irange::supports_type_p (TREE_TYPE (lhs)) && CONSTANT_CLASS_P (rhs)) - { - ranger->range_on_edge (predicate->true_range, edge_true, lhs); - predicate->init_false_edge (); - } + ranger->gori().outgoing_edge_range_p (predicate->true_range, edge_true, + lhs, *get_global_range_query ()); + predicate->init_false_edge (); candidates.safe_push (predicate); } @@ -431,11 +432,9 @@ find_unswitching_predicates_for_bb (basic_block bb, class loop *loop, if (expr != NULL_TREE) { unswitch_predicate *predicate = new unswitch_predicate (expr, idx, edge_index); - if (irange::supports_type_p (TREE_TYPE (idx))) - { - ranger->range_on_edge (predicate->true_range, e, idx); - predicate->init_false_edge (); - } + ranger->gori().outgoing_edge_range_p (predicate->true_range, e, + idx, *get_global_range_query ()); + predicate->init_false_edge (); candidates.safe_push (predicate); } @@ -530,6 +529,7 @@ evaluate_control_stmt_using_entry_checks (gimple *stmt, { int_range_max r; int_range_max path_range; + find_range_for_lhs (predicate_path, lhs, path_range); if (!path_range.undefined_p () && fold_range (r, stmt, path_range) @@ -542,6 +542,8 @@ evaluate_control_stmt_using_entry_checks (gimple *stmt, unsigned nlabels = gimple_switch_num_labels (swtch); unsigned ignored = 0; + tree idx = gimple_switch_index (swtch); + tree result = NULL_TREE; for (unsigned i = 0; i < nlabels; ++i) { tree lab = gimple_switch_label (swtch, i); @@ -550,26 +552,27 @@ evaluate_control_stmt_using_entry_checks (gimple *stmt, int_range_max r; int_range_max path_range; - tree idx = gimple_switch_index (swtch); - find_range_for_lhs (predicate_path, idx, path_range); - - int_range_max xx; - fold_range (xx, stmt, e); - if (!path_range.undefined_p () - && fold_range (r, stmt, path_range) - && r.singleton_p () - && r.zero_p ()) + ranger->gori().outgoing_edge_range_p (r, e, + idx, *get_global_range_query ()); + find_range_for_lhs (predicate_path, idx, path_range); + if (!path_range.undefined_p ()) { - ignored_edges->add (e); - ignored++; + r.intersect (path_range); + if (r.undefined_p ()) + { + ignored_edges->add (e); + ignored++; + } + else + result = CASE_LOW (lab); } } /* Only one edge from the switch is alive. */ gcc_checking_assert (ignored + 1 <= nlabels); if (ignored + 1 == nlabels) - return true_edge ? boolean_true_node : boolean_false_node; + return result; } return NULL_TREE; @@ -1394,6 +1397,52 @@ check_exit_phi (class loop *loop) return true; } +/* Remove all dead cases from switches that are unswitched. */ + +static void +clean_up_after_unswitching (const auto_edge_flag &ignored_edge_flag) +{ + basic_block bb; + + FOR_EACH_BB_FN (bb, cfun) + { + gimple *last = last_stmt (bb); + if (gswitch *stmt = safe_dyn_cast (last)) + { + unsigned nlabels = gimple_switch_num_labels (stmt); + unsigned index = 1; + for (unsigned i = 1; i < nlabels; ++i) + { + tree lab = gimple_switch_label (stmt, i); + basic_block dest = label_to_block (cfun, CASE_LABEL (lab)); + edge e = find_edge (gimple_bb (stmt), dest); + if (e == NULL) + ; /* The edge is already removed. */ + else if (e->flags & ignored_edge_flag) + remove_edge (e); + else + { + gimple_switch_set_label (stmt, index, lab); + ++index; + } + } + + if (index != nlabels) + gimple_switch_set_num_labels (stmt, index); + } + } + + /* Clean up the ignored_edge_flag from edges. */ + FOR_EACH_BB_FN (bb, cfun) + { + edge e; + edge_iterator ei; + + FOR_EACH_EDGE (e, ei, bb->succs) + e->flags &= ~ignored_edge_flag; + } +} + /* Loop unswitching pass. */ namespace {