From mboxrd@z Thu Jan 1 00:00:00 1970 Return-Path: Received: by sourceware.org (Postfix, from userid 1666) id 24C6C3858C54; Wed, 26 Apr 2023 06:42:36 +0000 (GMT) DKIM-Filter: OpenDKIM Filter v2.11.0 sourceware.org 24C6C3858C54 DKIM-Signature: v=1; a=rsa-sha256; c=relaxed/relaxed; d=gcc.gnu.org; s=default; t=1682491356; bh=tRSotdjH4PaMO3ZJCEIllm5QmbFij6rC96r/TdaI1vY=; h=From:To:Subject:Date:From; b=dvdH6nOzPfVF2eJIF9A2QQvB6Ntl9fcyTfZywolhuVNo3ZReB2Cd9ngy593ThpJDZ TQSmdi5mP1FpZHZFcRzcuLZj9ueidfoZuaEGqSLpchhzBEbB7DeCd/shmiuK+EdHce 8kRIsz2/7BQK1Ird8+lNVnQsBUG6wpOYcjuHyh08= MIME-Version: 1.0 Content-Transfer-Encoding: 7bit Content-Type: text/plain; charset="utf-8" From: Richard Biener To: gcc-cvs@gcc.gnu.org Subject: [gcc r14-242] More last_stmt removal X-Act-Checkin: gcc X-Git-Author: Richard Biener X-Git-Refname: refs/heads/master X-Git-Oldrev: 5fce06b868ec0d4f75530a17d6fe6b12b7c9b5f0 X-Git-Newrev: db29daa5e627c185aa599aa0dad093ae3a86317c Message-Id: <20230426064236.24C6C3858C54@sourceware.org> Date: Wed, 26 Apr 2023 06:42:36 +0000 (GMT) List-Id: https://gcc.gnu.org/g:db29daa5e627c185aa599aa0dad093ae3a86317c commit r14-242-gdb29daa5e627c185aa599aa0dad093ae3a86317c Author: Richard Biener Date: Tue Apr 25 16:38:44 2023 +0200 More last_stmt removal This adjusts more users of last_stmt where it is clear that debug stmt skipping is unnecessary. In most cases this also allowed significant code simplification. gcc/c/ * gimple-parser.cc (c_parser_parse_gimple_body): Avoid last_stmt. gcc/ * gimple-range-path.cc (path_range_query::compute_outgoing_relations): Avoid last_stmt. * ipa-pure-const.cc (pass_nothrow::execute): Likewise. * predict.cc (apply_return_prediction): Likewise. * sese.cc (set_ifsese_condition): Likewise. Simplify. * tree-cfg.cc (assert_unreachable_fallthru_edge_p): Avoid last_stmt. (make_edges_bb): Likewise. (make_cond_expr_edges): Likewise. (end_recording_case_labels): Likewise. (make_gimple_asm_edges): Likewise. (cleanup_dead_labels): Likewise. (group_case_labels): Likewise. (gimple_can_merge_blocks_p): Likewise. (gimple_merge_blocks): Likewise. (find_taken_edge): Likewise. Also handle empty fallthru blocks. (gimple_duplicate_sese_tail): Avoid last_stmt. (find_loop_dist_alias): Likewise. (gimple_block_ends_with_condjump_p): Likewise. (gimple_purge_dead_eh_edges): Likewise. (gimple_purge_dead_abnormal_call_edges): Likewise. (pass_warn_function_return::execute): Likewise. (execute_fixup_cfg): Likewise. * tree-eh.cc (redirect_eh_edge_1): Likewise. (pass_lower_resx::execute): Likewise. (pass_lower_eh_dispatch::execute): Likewise. (cleanup_empty_eh): Likewise. * tree-if-conv.cc (if_convertible_bb_p): Likewise. (predicate_bbs): Likewise. (ifcvt_split_critical_edges): Likewise. * tree-loop-distribution.cc (create_edge_for_control_dependence): Likewise. (loop_distribution::transform_reduction_loop): Likewise. * tree-parloops.cc (transform_to_exit_first_loop_alt): Likewise. (try_transform_to_exit_first_loop_alt): Likewise. (transform_to_exit_first_loop): Likewise. (create_parallel_loop): Likewise. * tree-scalar-evolution.cc (get_loop_exit_condition): Likewise. * tree-ssa-dce.cc (mark_last_stmt_necessary): Likewise. (eliminate_unnecessary_stmts): Likewise. * tree-ssa-dom.cc (dom_opt_dom_walker::set_global_ranges_from_unreachable_edges): Likewise. * tree-ssa-ifcombine.cc (ifcombine_ifandif): Likewise. (pass_tree_ifcombine::execute): Likewise. * tree-ssa-loop-ch.cc (entry_loop_condition_is_static): Likewise. (should_duplicate_loop_header_p): Likewise. * tree-ssa-loop-ivcanon.cc (create_canonical_iv): Likewise. (tree_estimate_loop_size): Likewise. (try_unroll_loop_completely): Likewise. * tree-ssa-loop-ivopts.cc (tree_ssa_iv_optimize_loop): Likewise. * tree-ssa-loop-manip.cc (ip_normal_pos): Likewise. (canonicalize_loop_ivs): Likewise. * tree-ssa-loop-niter.cc (determine_value_range): Likewise. (bound_difference): Likewise. (number_of_iterations_popcount): Likewise. (number_of_iterations_cltz): Likewise. (number_of_iterations_cltz_complement): Likewise. (simplify_using_initial_conditions): Likewise. (number_of_iterations_exit_assumptions): Likewise. (loop_niter_by_eval): Likewise. (estimate_numbers_of_iterations): Likewise. Diff: --- gcc/c/gimple-parser.cc | 3 +- gcc/gimple-range-path.cc | 2 +- gcc/ipa-pure-const.cc | 19 +++++------ gcc/predict.cc | 6 ++-- gcc/sese.cc | 16 ++++----- gcc/tree-cfg.cc | 76 +++++++++++++++++++------------------------ gcc/tree-eh.cc | 16 ++++----- gcc/tree-if-conv.cc | 11 ++----- gcc/tree-loop-distribution.cc | 4 +-- gcc/tree-parloops.cc | 10 +++--- gcc/tree-scalar-evolution.cc | 8 +---- gcc/tree-ssa-dce.cc | 5 ++- gcc/tree-ssa-dom.cc | 2 +- gcc/tree-ssa-ifcombine.cc | 18 +++------- gcc/tree-ssa-loop-ch.cc | 4 +-- gcc/tree-ssa-loop-ivcanon.cc | 8 ++--- gcc/tree-ssa-loop-ivopts.cc | 3 +- gcc/tree-ssa-loop-manip.cc | 7 ++-- gcc/tree-ssa-loop-niter.cc | 32 ++++++------------ 19 files changed, 100 insertions(+), 150 deletions(-) diff --git a/gcc/c/gimple-parser.cc b/gcc/c/gimple-parser.cc index 19e06bcaf4d..5423a790cc0 100644 --- a/gcc/c/gimple-parser.cc +++ b/gcc/c/gimple-parser.cc @@ -294,8 +294,7 @@ c_parser_parse_gimple_body (c_parser *cparser, char *gimple_pass, FOR_EACH_BB_FN (bb, cfun) if (EDGE_COUNT (bb->succs) == 0) { - gimple *last = last_stmt (bb); - if (gswitch *sw = safe_dyn_cast (last)) + if (gswitch *sw = safe_dyn_cast (*gsi_last_bb (bb))) for (unsigned i = 0; i < gimple_switch_num_labels (sw); ++i) { basic_block label_bb = gimple_switch_label_bb (cfun, sw, i); diff --git a/gcc/gimple-range-path.cc b/gcc/gimple-range-path.cc index 394d610c1b3..f68b2029476 100644 --- a/gcc/gimple-range-path.cc +++ b/gcc/gimple-range-path.cc @@ -794,7 +794,7 @@ path_range_query::compute_phi_relations (basic_block bb, basic_block prev) void path_range_query::compute_outgoing_relations (basic_block bb, basic_block next) { - if (gcond *cond = safe_dyn_cast (last_stmt (bb))) + if (gcond *cond = safe_dyn_cast (*gsi_last_bb (bb))) { int_range<2> r; edge e0 = EDGE_SUCC (bb, 0); diff --git a/gcc/ipa-pure-const.cc b/gcc/ipa-pure-const.cc index 224a582f77c..058a7dd3019 100644 --- a/gcc/ipa-pure-const.cc +++ b/gcc/ipa-pure-const.cc @@ -2379,16 +2379,15 @@ pass_nothrow::execute (function *) bool cfg_changed = false; if (self_recursive_p (node)) FOR_EACH_BB_FN (this_block, cfun) - if (gimple *g = last_stmt (this_block)) - if (is_gimple_call (g)) - { - tree callee_t = gimple_call_fndecl (g); - if (callee_t - && recursive_call_p (current_function_decl, callee_t) - && maybe_clean_eh_stmt (g) - && gimple_purge_dead_eh_edges (this_block)) - cfg_changed = true; - } + if (gcall *g = safe_dyn_cast (*gsi_last_bb (this_block))) + { + tree callee_t = gimple_call_fndecl (g); + if (callee_t + && recursive_call_p (current_function_decl, callee_t) + && maybe_clean_eh_stmt (g) + && gimple_purge_dead_eh_edges (this_block)) + cfg_changed = true; + } if (dump_file) fprintf (dump_file, "Function found to be nothrow: %s\n", diff --git a/gcc/predict.cc b/gcc/predict.cc index 4a686b08f36..5e3c1d69ca4 100644 --- a/gcc/predict.cc +++ b/gcc/predict.cc @@ -2934,11 +2934,9 @@ apply_return_prediction (void) FOR_EACH_EDGE (e, ei, EXIT_BLOCK_PTR_FOR_FN (cfun)->preds) { - gimple *last = last_stmt (e->src); - if (last - && gimple_code (last) == GIMPLE_RETURN) + if (greturn *last = safe_dyn_cast (*gsi_last_bb (e->src))) { - return_stmt = as_a (last); + return_stmt = last; break; } } diff --git a/gcc/sese.cc b/gcc/sese.cc index 13992a06660..0cf7f648021 100644 --- a/gcc/sese.cc +++ b/gcc/sese.cc @@ -343,19 +343,17 @@ set_ifsese_condition (ifsese if_region, tree condition) sese_info_p region = if_region->region; edge entry = region->region.entry; basic_block bb = entry->dest; - gimple *last = last_stmt (bb); - gimple_stmt_iterator gsi = gsi_last_bb (bb); gcond *cond_stmt; - gcc_assert (gimple_code (last) == GIMPLE_COND); + gimple_stmt_iterator gsi = gsi_last_bb (bb); + gcc_assert (gimple_code (*gsi) == GIMPLE_COND); - gsi_remove (&gsi, true); - gsi = gsi_last_bb (bb); - condition = force_gimple_operand_gsi (&gsi, condition, true, NULL, - false, GSI_NEW_STMT); + condition = force_gimple_operand_gsi_1 (&gsi, condition, + is_gimple_condexpr_for_cond, + NULL_TREE, true, GSI_SAME_STMT); cond_stmt = gimple_build_cond_from_tree (condition, NULL_TREE, NULL_TREE); - gsi = gsi_last_bb (bb); - gsi_insert_after (&gsi, cond_stmt, GSI_NEW_STMT); + gsi_insert_before (&gsi, cond_stmt, GSI_SAME_STMT); + gsi_remove (&gsi, true); } /* Return true when T is defined outside REGION or when no definitions are diff --git a/gcc/tree-cfg.cc b/gcc/tree-cfg.cc index ae53e15158a..5ef201adb25 100644 --- a/gcc/tree-cfg.cc +++ b/gcc/tree-cfg.cc @@ -479,8 +479,7 @@ bool assert_unreachable_fallthru_edge_p (edge e) { basic_block pred_bb = e->src; - gimple *last = last_stmt (pred_bb); - if (last && gimple_code (last) == GIMPLE_COND) + if (safe_is_a (*gsi_last_bb (pred_bb))) { basic_block other_bb = EDGE_SUCC (pred_bb, 0)->dest; if (other_bb == e->dest) @@ -849,7 +848,7 @@ handle_abnormal_edges (basic_block *dispatcher_bbs, basic_block for_bb, static int make_edges_bb (basic_block bb, struct omp_region **pcur_region, int *pomp_index) { - gimple *last = last_stmt (bb); + gimple *last = *gsi_last_bb (bb); bool fallthru = false; int ret = 0; @@ -1274,14 +1273,13 @@ assign_discriminators (void) static void make_cond_expr_edges (basic_block bb) { - gcond *entry = as_a (last_stmt (bb)); + gcond *entry = as_a (*gsi_last_bb (bb)); gimple *then_stmt, *else_stmt; basic_block then_bb, else_bb; tree then_label, else_label; edge e; gcc_assert (entry); - gcc_assert (gimple_code (entry) == GIMPLE_COND); /* Entry basic blocks for each component. */ then_label = gimple_cond_true_label (entry); @@ -1357,9 +1355,8 @@ end_recording_case_labels (void) basic_block bb = BASIC_BLOCK_FOR_FN (cfun, i); if (bb) { - gimple *stmt = last_stmt (bb); - if (stmt && gimple_code (stmt) == GIMPLE_SWITCH) - group_case_labels_stmt (as_a (stmt)); + if (gswitch *stmt = safe_dyn_cast (*gsi_last_bb (bb))) + group_case_labels_stmt (stmt); } } BITMAP_FREE (touched_switch_bbs); @@ -1478,7 +1475,7 @@ make_goto_expr_edges (basic_block bb) static void make_gimple_asm_edges (basic_block bb) { - gasm *stmt = as_a (last_stmt (bb)); + gasm *stmt = as_a (*gsi_last_bb (bb)); int i, n = gimple_asm_nlabels (stmt); for (i = 0; i < n; ++i) @@ -1635,7 +1632,7 @@ cleanup_dead_labels (void) First do so for each block ending in a control statement. */ FOR_EACH_BB_FN (bb, cfun) { - gimple *stmt = last_stmt (bb); + gimple *stmt = *gsi_last_bb (bb); tree label, new_label; if (!stmt) @@ -1923,9 +1920,8 @@ group_case_labels (void) FOR_EACH_BB_FN (bb, cfun) { - gimple *stmt = last_stmt (bb); - if (stmt && gimple_code (stmt) == GIMPLE_SWITCH) - changed |= group_case_labels_stmt (as_a (stmt)); + if (gswitch *stmt = safe_dyn_cast (*gsi_last_bb (bb))) + changed |= group_case_labels_stmt (stmt); } return changed; @@ -1956,7 +1952,7 @@ gimple_can_merge_blocks_p (basic_block a, basic_block b) /* If A ends by a statement causing exceptions or something similar, we cannot merge the blocks. */ - stmt = last_stmt (a); + stmt = *gsi_last_bb (a); if (stmt && stmt_ends_bb_p (stmt)) return false; @@ -2167,7 +2163,8 @@ gimple_merge_blocks (basic_block a, basic_block b) move_block_after (b, a); gcc_assert (single_succ_edge (a)->flags & EDGE_FALLTHRU); - gcc_assert (!last_stmt (a) || !stmt_ends_bb_p (last_stmt (a))); + gcc_assert (!*gsi_last_bb (a) + || !stmt_ends_bb_p (*gsi_last_bb (a))); /* Remove labels from B and set gimple_bb to A for other statements. */ for (gsi = gsi_start_bb (b); !gsi_end_p (gsi);) @@ -2428,19 +2425,19 @@ find_taken_edge (basic_block bb, tree val) { gimple *stmt; - stmt = last_stmt (bb); + stmt = *gsi_last_bb (bb); /* Handle ENTRY and EXIT. */ if (!stmt) - return NULL; + ; - if (gimple_code (stmt) == GIMPLE_COND) + else if (gimple_code (stmt) == GIMPLE_COND) return find_taken_edge_cond_expr (as_a (stmt), val); - if (gimple_code (stmt) == GIMPLE_SWITCH) + else if (gimple_code (stmt) == GIMPLE_SWITCH) return find_taken_edge_switch_expr (as_a (stmt), val); - if (computed_goto_p (stmt)) + else if (computed_goto_p (stmt)) { /* Only optimize if the argument is a label, if the argument is not a label then we cannot construct a proper CFG. @@ -6835,7 +6832,6 @@ gimple_duplicate_sese_tail (edge entry, edge exit, exit_count = profile_count::uninitialized (); edge exits[2], nexits[2], e; gimple_stmt_iterator gsi; - gimple *cond_stmt; edge sorig, snew; basic_block exit_bb; gphi_iterator psi; @@ -6897,18 +6893,17 @@ gimple_duplicate_sese_tail (edge entry, edge exit, /* Create the switch block, and put the exit condition to it. */ entry_bb = entry->dest; nentry_bb = get_bb_copy (entry_bb); - if (!last_stmt (entry->src) - || !stmt_ends_bb_p (last_stmt (entry->src))) + if (!*gsi_last_bb (entry->src) + || !stmt_ends_bb_p (*gsi_last_bb (entry->src))) switch_bb = entry->src; else switch_bb = split_edge (entry); set_immediate_dominator (CDI_DOMINATORS, nentry_bb, switch_bb); - gsi = gsi_last_bb (switch_bb); - cond_stmt = last_stmt (exit->src); - gcc_assert (gimple_code (cond_stmt) == GIMPLE_COND); - cond_stmt = gimple_copy (cond_stmt); + gcond *cond_stmt = as_a (*gsi_last_bb (exit->src)); + cond_stmt = as_a (gimple_copy (cond_stmt)); + gsi = gsi_last_bb (switch_bb); gsi_insert_after (&gsi, cond_stmt, GSI_NEW_STMT); sorig = single_succ_edge (switch_bb); @@ -7671,16 +7666,15 @@ gather_ssa_name_hash_map_from (tree const &from, tree const &, void *data) static gimple * find_loop_dist_alias (basic_block bb) { - gimple *g = last_stmt (bb); - if (g == NULL || gimple_code (g) != GIMPLE_COND) + gimple_stmt_iterator gsi = gsi_last_bb (bb); + if (!safe_is_a (*gsi)) return NULL; - gimple_stmt_iterator gsi = gsi_for_stmt (g); gsi_prev (&gsi); if (gsi_end_p (gsi)) return NULL; - g = gsi_stmt (gsi); + gimple *g = gsi_stmt (gsi); if (gimple_call_internal_p (g, IFN_LOOP_DIST_ALIAS)) return g; return NULL; @@ -8655,8 +8649,7 @@ gimple_block_ends_with_call_p (basic_block bb) static bool gimple_block_ends_with_condjump_p (const_basic_block bb) { - gimple *stmt = last_stmt (CONST_CAST_BB (bb)); - return (stmt && gimple_code (stmt) == GIMPLE_COND); + return safe_is_a (*gsi_last_bb (const_cast (bb))); } @@ -8984,7 +8977,7 @@ gimple_purge_dead_eh_edges (basic_block bb) bool changed = false; edge e; edge_iterator ei; - gimple *stmt = last_stmt (bb); + gimple *stmt = *gsi_last_bb (bb); if (stmt && stmt_can_throw_internal (cfun, stmt)) return false; @@ -9034,7 +9027,7 @@ gimple_purge_dead_abnormal_call_edges (basic_block bb) bool changed = false; edge e; edge_iterator ei; - gimple *stmt = last_stmt (bb); + gimple *stmt = *gsi_last_bb (bb); if (stmt && stmt_can_make_abnormal_goto (stmt)) return false; @@ -9612,7 +9605,7 @@ pass_warn_function_return::execute (function *fun) for (ei = ei_start (EXIT_BLOCK_PTR_FOR_FN (fun)->preds); (e = ei_safe_edge (ei)); ) { - last = last_stmt (e->src); + last = *gsi_last_bb (e->src); if ((gimple_code (last) == GIMPLE_RETURN || gimple_call_builtin_p (last, BUILT_IN_RETURN)) && location == UNKNOWN_LOCATION @@ -9646,13 +9639,12 @@ pass_warn_function_return::execute (function *fun) { FOR_EACH_EDGE (e, ei, EXIT_BLOCK_PTR_FOR_FN (fun)->preds) { - gimple *last = last_stmt (e->src); - greturn *return_stmt = dyn_cast (last); + greturn *return_stmt = dyn_cast (*gsi_last_bb (e->src)); if (return_stmt && gimple_return_retval (return_stmt) == NULL - && !warning_suppressed_p (last, OPT_Wreturn_type)) + && !warning_suppressed_p (return_stmt, OPT_Wreturn_type)) { - location = gimple_location (last); + location = gimple_location (return_stmt); if (LOCATION_LOCUS (location) == UNKNOWN_LOCATION) location = fun->function_end_locus; if (warning_at (location, OPT_Wreturn_type, @@ -9669,7 +9661,7 @@ pass_warn_function_return::execute (function *fun) FOR_EACH_BB_FN (bb, fun) if (EDGE_COUNT (bb->succs) == 0) { - gimple *last = last_stmt (bb); + gimple *last = *gsi_last_bb (bb); const enum built_in_function ubsan_missing_ret = BUILT_IN_UBSAN_HANDLE_MISSING_RETURN; if (last @@ -9934,7 +9926,7 @@ execute_fixup_cfg (void) gsi_next (&gsi); } - if (gimple *last = last_stmt (bb)) + if (gimple *last = *gsi_last_bb (bb)) { if (maybe_clean_eh_stmt (last) && gimple_purge_dead_eh_edges (bb)) diff --git a/gcc/tree-eh.cc b/gcc/tree-eh.cc index 41cf57d2b30..425323ff7d6 100644 --- a/gcc/tree-eh.cc +++ b/gcc/tree-eh.cc @@ -2319,7 +2319,7 @@ redirect_eh_edge_1 (edge edge_in, basic_block new_bb, bool change_region) gcc_assert (old_lp_nr > 0); old_lp = get_eh_landing_pad_from_number (old_lp_nr); - throw_stmt = last_stmt (edge_in->src); + throw_stmt = *gsi_last_bb (edge_in->src); gcc_checking_assert (lookup_stmt_eh_lp (throw_stmt) == old_lp_nr); new_label = gimple_block_label (new_bb); @@ -3515,11 +3515,9 @@ pass_lower_resx::execute (function *fun) FOR_EACH_BB_FN (bb, fun) { - gimple *last = last_stmt (bb); - if (last && is_gimple_resx (last)) + if (gresx *last = safe_dyn_cast (*gsi_last_bb (bb))) { - dominance_invalidated |= - lower_resx (bb, as_a (last), &mnt_map); + dominance_invalidated |= lower_resx (bb, last, &mnt_map); any_rewritten = true; } } @@ -3944,7 +3942,7 @@ pass_lower_eh_dispatch::execute (function *fun) FOR_EACH_BB_FN (bb, fun) { - gimple *last = last_stmt (bb); + gimple *last = *gsi_last_bb (bb); if (last == NULL) continue; if (gimple_code (last) == GIMPLE_EH_DISPATCH) @@ -3979,7 +3977,7 @@ pass_lower_eh_dispatch::execute (function *fun) for (int i = 0; i < rpo_n; ++i) { bb = BASIC_BLOCK_FOR_FN (fun, rpo[i]); - gimple *last = last_stmt (bb); + gimple *last = *gsi_last_bb (bb); if (last && gimple_code (last) == GIMPLE_RESX && !stmt_can_throw_external (fun, last)) @@ -4705,7 +4703,7 @@ cleanup_empty_eh (eh_landing_pad lp) for (ei = ei_start (bb->preds); (e = ei_safe_edge (ei)); ) if (e->flags & EDGE_EH) { - gimple *stmt = last_stmt (e->src); + gimple *stmt = *gsi_last_bb (e->src); remove_stmt_from_eh_lp (stmt); remove_edge (e); } @@ -4721,7 +4719,7 @@ cleanup_empty_eh (eh_landing_pad lp) for (ei = ei_start (bb->preds); (e = ei_safe_edge (ei)); ) if (e->flags & EDGE_EH) { - gimple *stmt = last_stmt (e->src); + gimple *stmt = *gsi_last_bb (e->src); remove_stmt_from_eh_lp (stmt); add_stmt_to_eh_lp (stmt, new_lp_nr); remove_edge (e); diff --git a/gcc/tree-if-conv.cc b/gcc/tree-if-conv.cc index a19450f533d..1393ce184e3 100644 --- a/gcc/tree-if-conv.cc +++ b/gcc/tree-if-conv.cc @@ -1157,8 +1157,7 @@ if_convertible_bb_p (class loop *loop, basic_block bb, basic_block exit_bb) if (EDGE_COUNT (bb->succs) > 2) return false; - gimple *last = last_stmt (bb); - if (gcall *call = safe_dyn_cast (last)) + if (gcall *call = safe_dyn_cast (*gsi_last_bb (bb))) if (gimple_call_ctrl_altering_p (call)) return false; @@ -1302,7 +1301,6 @@ predicate_bbs (loop_p loop) { basic_block bb = ifc_bbs[i]; tree cond; - gimple *stmt; /* The loop latch and loop exit block are always executed and have no extra conditions to be processed: skip them. */ @@ -1314,8 +1312,7 @@ predicate_bbs (loop_p loop) } cond = bb_predicate (bb); - stmt = last_stmt (bb); - if (stmt && gimple_code (stmt) == GIMPLE_COND) + if (gcond *stmt = safe_dyn_cast (*gsi_last_bb (bb))) { tree c2; edge true_edge, false_edge; @@ -3049,7 +3046,6 @@ ifcvt_split_critical_edges (class loop *loop, bool aggressive_if_conv) basic_block bb; unsigned int num = loop->num_nodes; unsigned int i; - gimple *stmt; edge e; edge_iterator ei; auto_vec critical_edges; @@ -3077,9 +3073,8 @@ ifcvt_split_critical_edges (class loop *loop, bool aggressive_if_conv) if (bb == loop->latch || bb_with_exit_edge_p (loop, bb)) continue; - stmt = last_stmt (bb); /* Skip basic blocks not ending with conditional branch. */ - if (!stmt || gimple_code (stmt) != GIMPLE_COND) + if (!safe_is_a (*gsi_last_bb (bb))) continue; FOR_EACH_EDGE (e, ei, bb->succs) diff --git a/gcc/tree-loop-distribution.cc b/gcc/tree-loop-distribution.cc index 431bd45c522..6291f941a21 100644 --- a/gcc/tree-loop-distribution.cc +++ b/gcc/tree-loop-distribution.cc @@ -453,7 +453,7 @@ create_edge_for_control_dependence (struct graph *rdg, basic_block bb, 0, edge_n, bi) { basic_block cond_bb = cd->get_edge_src (edge_n); - gimple *stmt = last_stmt (cond_bb); + gimple *stmt = *gsi_last_bb (cond_bb); if (stmt && is_ctrl_stmt (stmt)) { struct graph_edge *e; @@ -3587,7 +3587,7 @@ loop_distribution::transform_reduction_loop (loop_p loop) data_reference_p load_dr = NULL, store_dr = NULL; edge e = single_exit (loop); - gcond *cond = safe_dyn_cast (last_stmt (e->src)); + gcond *cond = safe_dyn_cast (*gsi_last_bb (e->src)); if (!cond) return false; /* Ensure loop condition is an (in)equality test and loop is exited either if diff --git a/gcc/tree-parloops.cc b/gcc/tree-parloops.cc index dfb75c369d6..eae240b9ffd 100644 --- a/gcc/tree-parloops.cc +++ b/gcc/tree-parloops.cc @@ -2354,7 +2354,7 @@ transform_to_exit_first_loop_alt (class loop *loop, basic_block latch = loop->latch; edge exit = single_dom_exit (loop); basic_block exit_block = exit->dest; - gcond *cond_stmt = as_a (last_stmt (exit->src)); + gcond *cond_stmt = as_a (*gsi_last_bb (exit->src)); tree control = gimple_cond_lhs (cond_stmt); edge e; @@ -2510,7 +2510,7 @@ try_transform_to_exit_first_loop_alt (class loop *loop, /* Check whether the latch contains the loop iv increment. */ edge back = single_succ_edge (loop->latch); edge exit = single_dom_exit (loop); - gcond *cond_stmt = as_a (last_stmt (exit->src)); + gcond *cond_stmt = as_a (*gsi_last_bb (exit->src)); tree control = gimple_cond_lhs (cond_stmt); gphi *phi = as_a (SSA_NAME_DEF_STMT (control)); tree inc_res = gimple_phi_arg_def (phi, back->dest_idx); @@ -2632,7 +2632,7 @@ transform_to_exit_first_loop (class loop *loop, orig_header = single_succ (loop->header); hpred = single_succ_edge (loop->header); - cond_stmt = as_a (last_stmt (exit->src)); + cond_stmt = as_a (*gsi_last_bb (exit->src)); control = gimple_cond_lhs (cond_stmt); gcc_assert (gimple_cond_rhs (cond_stmt) == nit); @@ -2712,7 +2712,7 @@ transform_to_exit_first_loop (class loop *loop, /* Initialize the control variable to number of iterations according to the rhs of the exit condition. */ gimple_stmt_iterator gsi = gsi_after_labels (ex_bb); - cond_nit = as_a (last_stmt (exit->src)); + cond_nit = as_a (*gsi_last_bb (exit->src)); nit_1 = gimple_cond_rhs (cond_nit); nit_1 = force_gimple_operand_gsi (&gsi, fold_convert (TREE_TYPE (control_name), nit_1), @@ -2797,7 +2797,7 @@ create_parallel_loop (class loop *loop, tree loop_fn, tree data, /* Extract data for GIMPLE_OMP_FOR. */ gcc_assert (loop->header == single_dom_exit (loop)->src); - cond_stmt = as_a (last_stmt (loop->header)); + cond_stmt = as_a (*gsi_last_bb (loop->header)); cvar = gimple_cond_lhs (cond_stmt); cvar_base = SSA_NAME_VAR (cvar); diff --git a/gcc/tree-scalar-evolution.cc b/gcc/tree-scalar-evolution.cc index 526b7f68768..672cf9fab62 100644 --- a/gcc/tree-scalar-evolution.cc +++ b/gcc/tree-scalar-evolution.cc @@ -1300,13 +1300,7 @@ get_loop_exit_condition (const class loop *loop) fprintf (dump_file, "(get_loop_exit_condition \n "); if (exit_edge) - { - gimple *stmt; - - stmt = last_stmt (exit_edge->src); - if (gcond *cond_stmt = safe_dyn_cast (stmt)) - res = cond_stmt; - } + res = safe_dyn_cast (*gsi_last_bb (exit_edge->src)); if (dump_file && (dump_flags & TDF_SCEV)) { diff --git a/gcc/tree-ssa-dce.cc b/gcc/tree-ssa-dce.cc index 08876bfc1c7..1fd88e8ee37 100644 --- a/gcc/tree-ssa-dce.cc +++ b/gcc/tree-ssa-dce.cc @@ -330,14 +330,13 @@ mark_stmt_if_obviously_necessary (gimple *stmt, bool aggressive) static bool mark_last_stmt_necessary (basic_block bb) { - gimple *stmt = last_stmt (bb); - if (!bitmap_set_bit (last_stmt_necessary, bb->index)) return true; bitmap_set_bit (bb_contains_live_stmts, bb->index); /* We actually mark the statement only if it is a control statement. */ + gimple *stmt = *gsi_last_bb (bb); if (stmt && is_ctrl_stmt (stmt)) { mark_stmt_necessary (stmt, true); @@ -1523,7 +1522,7 @@ eliminate_unnecessary_stmts (bool aggressive) gimple_purge_dead_abnormal_call_edges would do that and we cannot free dominators yet. */ FOR_EACH_BB_FN (bb, cfun) - if (gcall *stmt = safe_dyn_cast (last_stmt (bb))) + if (gcall *stmt = safe_dyn_cast (*gsi_last_bb (bb))) if (!stmt_can_make_abnormal_goto (stmt)) { edge_iterator ei; diff --git a/gcc/tree-ssa-dom.cc b/gcc/tree-ssa-dom.cc index 32769c2068a..ab31d2e7ee9 100644 --- a/gcc/tree-ssa-dom.cc +++ b/gcc/tree-ssa-dom.cc @@ -1358,7 +1358,7 @@ dom_opt_dom_walker::set_global_ranges_from_unreachable_edges (basic_block bb) if (!pred_e) return; - gimple *stmt = last_stmt (pred_e->src); + gimple *stmt = *gsi_last_bb (pred_e->src); if (!stmt || gimple_code (stmt) != GIMPLE_COND || !assert_unreachable_fallthru_edge_p (pred_e)) diff --git a/gcc/tree-ssa-ifcombine.cc b/gcc/tree-ssa-ifcombine.cc index 58a2281eff9..21a77ddecc7 100644 --- a/gcc/tree-ssa-ifcombine.cc +++ b/gcc/tree-ssa-ifcombine.cc @@ -405,21 +405,15 @@ ifcombine_ifandif (basic_block inner_cond_bb, bool inner_inv, basic_block outer_cond_bb, bool outer_inv, bool result_inv) { gimple_stmt_iterator gsi; - gimple *inner_stmt, *outer_stmt; - gcond *inner_cond, *outer_cond; tree name1, name2, bit1, bit2, bits1, bits2; - inner_stmt = last_stmt (inner_cond_bb); - if (!inner_stmt - || gimple_code (inner_stmt) != GIMPLE_COND) + gcond *inner_cond = safe_dyn_cast (*gsi_last_bb (inner_cond_bb)); + if (!inner_cond) return false; - inner_cond = as_a (inner_stmt); - outer_stmt = last_stmt (outer_cond_bb); - if (!outer_stmt - || gimple_code (outer_stmt) != GIMPLE_COND) + gcond *outer_cond = safe_dyn_cast (*gsi_last_bb (outer_cond_bb)); + if (!outer_cond) return false; - outer_cond = as_a (outer_stmt); /* See if we test a single bit of the same name in both tests. In that case remove the outer test, merging both else edges, @@ -854,10 +848,8 @@ pass_tree_ifcombine::execute (function *fun) for (i = n_basic_blocks_for_fn (fun) - NUM_FIXED_BLOCKS - 1; i >= 0; i--) { basic_block bb = bbs[i]; - gimple *stmt = last_stmt (bb); - if (stmt - && gimple_code (stmt) == GIMPLE_COND) + if (safe_is_a (*gsi_last_bb (bb))) if (tree_ssa_ifcombine_bb (bb)) { /* Clear range info from all stmts in BB which is now executed diff --git a/gcc/tree-ssa-loop-ch.cc b/gcc/tree-ssa-loop-ch.cc index 2fad2a3d7b6..73b24c9a6f2 100644 --- a/gcc/tree-ssa-loop-ch.cc +++ b/gcc/tree-ssa-loop-ch.cc @@ -66,7 +66,7 @@ static bool entry_loop_condition_is_static (class loop *l, gimple_ranger *ranger) { edge e = loop_preheader_edge (l); - gcond *last = safe_dyn_cast (last_stmt (e->dest)); + gcond *last = safe_dyn_cast (*gsi_last_bb (e->dest)); if (!last) return false; @@ -133,7 +133,7 @@ should_duplicate_loop_header_p (basic_block header, class loop *loop, return false; } - gcond *last = safe_dyn_cast (last_stmt (header)); + gcond *last = safe_dyn_cast (*gsi_last_bb (header)); if (!last) { if (dump_file && (dump_flags & TDF_DETAILS)) diff --git a/gcc/tree-ssa-loop-ivcanon.cc b/gcc/tree-ssa-loop-ivcanon.cc index 9f72d534b7c..e965cf94eb7 100644 --- a/gcc/tree-ssa-loop-ivcanon.cc +++ b/gcc/tree-ssa-loop-ivcanon.cc @@ -98,7 +98,7 @@ create_canonical_iv (class loop *loop, edge exit, tree niter, fprintf (dump_file, " iterations.\n"); } - cond = as_a (last_stmt (exit->src)); + cond = as_a (*gsi_last_bb (exit->src)); in = EDGE_SUCC (exit->src, 0); if (in == exit) in = EDGE_SUCC (exit->src, 1); @@ -263,7 +263,7 @@ tree_estimate_loop_size (class loop *loop, edge exit, edge edge_to_cancel, { /* Exit conditional. */ if (exit && body[i] == exit->src - && stmt == last_stmt (exit->src)) + && stmt == *gsi_last_bb (exit->src)) { if (dump_file && (dump_flags & TDF_DETAILS)) fprintf (dump_file, " Exit condition will be eliminated " @@ -271,7 +271,7 @@ tree_estimate_loop_size (class loop *loop, edge exit, edge edge_to_cancel, likely_eliminated_peeled = true; } if (edge_to_cancel && body[i] == edge_to_cancel->src - && stmt == last_stmt (edge_to_cancel->src)) + && stmt == *gsi_last_bb (edge_to_cancel->src)) { if (dump_file && (dump_flags & TDF_DETAILS)) fprintf (dump_file, " Exit condition will be eliminated " @@ -923,7 +923,7 @@ try_unroll_loop_completely (class loop *loop, /* Remove the conditional from the last copy of the loop. */ if (edge_to_cancel) { - gcond *cond = as_a (last_stmt (edge_to_cancel->src)); + gcond *cond = as_a (*gsi_last_bb (edge_to_cancel->src)); force_edge_cold (edge_to_cancel, true); if (edge_to_cancel->flags & EDGE_TRUE_VALUE) gimple_cond_make_false (cond); diff --git a/gcc/tree-ssa-loop-ivopts.cc b/gcc/tree-ssa-loop-ivopts.cc index 0dd47910f97..78e8cbc75b5 100644 --- a/gcc/tree-ssa-loop-ivopts.cc +++ b/gcc/tree-ssa-loop-ivopts.cc @@ -8131,7 +8131,8 @@ tree_ssa_iv_optimize_loop (struct ivopts_data *data, class loop *loop, { fprintf (dump_file, " single exit %d -> %d, exit condition ", exit->src->index, exit->dest->index); - print_gimple_stmt (dump_file, last_stmt (exit->src), 0, TDF_SLIM); + print_gimple_stmt (dump_file, *gsi_last_bb (exit->src), + 0, TDF_SLIM); fprintf (dump_file, "\n"); } diff --git a/gcc/tree-ssa-loop-manip.cc b/gcc/tree-ssa-loop-manip.cc index a52277abdbf..909b705d00d 100644 --- a/gcc/tree-ssa-loop-manip.cc +++ b/gcc/tree-ssa-loop-manip.cc @@ -768,7 +768,6 @@ ip_end_pos (class loop *loop) basic_block ip_normal_pos (class loop *loop) { - gimple *last; basic_block bb; edge exit; @@ -776,9 +775,7 @@ ip_normal_pos (class loop *loop) return NULL; bb = single_pred (loop->latch); - last = last_stmt (bb); - if (!last - || gimple_code (last) != GIMPLE_COND) + if (!safe_is_a (*gsi_last_bb (bb))) return NULL; exit = EDGE_SUCC (bb, 0); @@ -1588,7 +1585,7 @@ canonicalize_loop_ivs (class loop *loop, tree *nit, bool bump_in_latch) rewrite_all_phi_nodes_with_iv (loop, var_before); - stmt = as_a (last_stmt (exit->src)); + stmt = as_a (*gsi_last_bb (exit->src)); /* Make the loop exit if the control condition is not satisfied. */ if (exit->flags & EDGE_TRUE_VALUE) { diff --git a/gcc/tree-ssa-loop-niter.cc b/gcc/tree-ssa-loop-niter.cc index adf9937b88a..33233979ba0 100644 --- a/gcc/tree-ssa-loop-niter.cc +++ b/gcc/tree-ssa-loop-niter.cc @@ -436,7 +436,6 @@ determine_value_range (class loop *loop, tree type, tree var, mpz_t off, { edge e; tree c0, c1; - gimple *cond; enum tree_code cmp; if (!single_pred_p (bb)) @@ -446,7 +445,7 @@ determine_value_range (class loop *loop, tree type, tree var, mpz_t off, if (!(e->flags & (EDGE_TRUE_VALUE | EDGE_FALSE_VALUE))) continue; - cond = last_stmt (e->src); + gcond *cond = as_a (*gsi_last_bb (e->src)); c0 = gimple_cond_lhs (cond); cmp = gimple_cond_code (cond); c1 = gimple_cond_rhs (cond); @@ -719,7 +718,6 @@ bound_difference (class loop *loop, tree x, tree y, bounds *bnds) edge e; basic_block bb; tree c0, c1; - gimple *cond; enum tree_code cmp; /* Get rid of unnecessary casts, but preserve the value of @@ -771,7 +769,7 @@ bound_difference (class loop *loop, tree x, tree y, bounds *bnds) if (!(e->flags & (EDGE_TRUE_VALUE | EDGE_FALSE_VALUE))) continue; - cond = last_stmt (e->src); + gcond *cond = as_a (*gsi_last_bb (e->src)); c0 = gimple_cond_lhs (cond); cmp = gimple_cond_code (cond); c1 = gimple_cond_rhs (cond); @@ -2100,9 +2098,8 @@ number_of_iterations_popcount (loop_p loop, edge exit, /* Check that condition for staying inside the loop is like if (iv != 0). */ - gimple *cond_stmt = last_stmt (exit->src); + gcond *cond_stmt = safe_dyn_cast (*gsi_last_bb (exit->src)); if (!cond_stmt - || gimple_code (cond_stmt) != GIMPLE_COND || code != NE_EXPR || !integer_zerop (gimple_cond_rhs (cond_stmt)) || TREE_CODE (gimple_cond_lhs (cond_stmt)) != SSA_NAME) @@ -2320,9 +2317,8 @@ number_of_iterations_cltz (loop_p loop, edge exit, /* Check that condition for staying inside the loop is like if (iv == 0). */ - gimple *cond_stmt = last_stmt (exit->src); + gcond *cond_stmt = safe_dyn_cast (*gsi_last_bb (exit->src)); if (!cond_stmt - || gimple_code (cond_stmt) != GIMPLE_COND || (code != EQ_EXPR && code != GE_EXPR) || !integer_zerop (gimple_cond_rhs (cond_stmt)) || TREE_CODE (gimple_cond_lhs (cond_stmt)) != SSA_NAME) @@ -2481,9 +2477,8 @@ number_of_iterations_cltz_complement (loop_p loop, edge exit, /* Check that condition for staying inside the loop is like if (iv != 0). */ - gimple *cond_stmt = last_stmt (exit->src); + gcond *cond_stmt = safe_dyn_cast (*gsi_last_bb (exit->src)); if (!cond_stmt - || gimple_code (cond_stmt) != GIMPLE_COND || code != NE_EXPR || !integer_zerop (gimple_cond_rhs (cond_stmt)) || TREE_CODE (gimple_cond_lhs (cond_stmt)) != SSA_NAME) @@ -2964,7 +2959,6 @@ simplify_using_initial_conditions (class loop *loop, tree expr) { edge e; basic_block bb; - gimple *stmt; tree cond, expanded, backup; int cnt = 0; @@ -2987,7 +2981,7 @@ simplify_using_initial_conditions (class loop *loop, tree expr) if (!(e->flags & (EDGE_TRUE_VALUE | EDGE_FALSE_VALUE))) continue; - stmt = last_stmt (e->src); + gcond *stmt = as_a (*gsi_last_bb (e->src)); cond = fold_build2 (gimple_cond_code (stmt), boolean_type_node, gimple_cond_lhs (stmt), @@ -3096,8 +3090,6 @@ number_of_iterations_exit_assumptions (class loop *loop, edge exit, gcond **at_stmt, bool every_iteration, basic_block *body) { - gimple *last; - gcond *stmt; tree type; tree op0, op1; enum tree_code code; @@ -3122,10 +3114,7 @@ number_of_iterations_exit_assumptions (class loop *loop, edge exit, niter->control.base = NULL_TREE; niter->control.step = NULL_TREE; niter->control.no_overflow = false; - last = last_stmt (exit->src); - if (!last) - return false; - stmt = dyn_cast (last); + gcond *stmt = safe_dyn_cast (*gsi_last_bb (exit->src)); if (!stmt) return false; @@ -3536,12 +3525,11 @@ loop_niter_by_eval (class loop *loop, edge exit) tree acnd; tree op[2], val[2], next[2], aval[2]; gphi *phi; - gimple *cond; unsigned i, j; enum tree_code cmp; - cond = last_stmt (exit->src); - if (!cond || gimple_code (cond) != GIMPLE_COND) + gcond *cond = safe_dyn_cast (*gsi_last_bb (exit->src)); + if (!cond) return chrec_dont_know; cmp = gimple_cond_code (cond); @@ -4808,7 +4796,7 @@ estimate_numbers_of_iterations (class loop *loop) { if (ex == likely_exit) { - gimple *stmt = last_stmt (ex->src); + gimple *stmt = *gsi_last_bb (ex->src); if (stmt != NULL) { gcond *cond = dyn_cast (stmt);