public inbox for gcc-patches@gcc.gnu.org
 help / color / mirror / Atom feed
* [PATCH] More last_stmt removal
@ 2023-04-25 15:11 Richard Biener
  0 siblings, 0 replies; 2+ messages in thread
From: Richard Biener @ 2023-04-25 15:11 UTC (permalink / raw)
  To: gcc-patches

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.

Bootstrapped on x86_64-unknown-linux-gnu, testing in progress.

Richard.

	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.
---
 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 <gswitch *> (last))
+	    if (gswitch *sw = safe_dyn_cast <gswitch *> (*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 <gcond *> (last_stmt (bb)))
+  if (gcond *cond = safe_dyn_cast <gcond *> (*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 <gcall *> (*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 <greturn *> (*gsi_last_bb (e->src)))
 	{
-	  return_stmt = as_a <greturn *> (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 <gcond *> (*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 <gcond *> (last_stmt (bb));
+  gcond *entry = as_a <gcond *> (*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 <gswitch *> (stmt));
+	  if (gswitch *stmt = safe_dyn_cast <gswitch *> (*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 <gasm *> (last_stmt (bb));
+  gasm *stmt = as_a <gasm *> (*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 <gswitch *> (stmt));
+      if (gswitch *stmt = safe_dyn_cast <gswitch *> (*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 <gcond *> (stmt), val);
 
-  if (gimple_code (stmt) == GIMPLE_SWITCH)
+  else if (gimple_code (stmt) == GIMPLE_SWITCH)
     return find_taken_edge_switch_expr (as_a <gswitch *> (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 <gcond *> (*gsi_last_bb (exit->src));
+  cond_stmt = as_a <gcond *> (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 <gcond *> (*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 <gcond *> (*gsi_last_bb (const_cast <basic_block> (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 <greturn *> (last);
+	  greturn *return_stmt = dyn_cast <greturn *> (*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 <gresx *> (*gsi_last_bb (bb)))
 	{
-	  dominance_invalidated |=
-	    lower_resx (bb, as_a <gresx *> (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 <gcall *> (last))
+  if (gcall *call = safe_dyn_cast <gcall *> (*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 <gcond *> (*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<edge> 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 <gcond *> (*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 <gcond *> (last_stmt (e->src));
+  gcond *cond = safe_dyn_cast <gcond *> (*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 <gcond *> (last_stmt (exit->src));
+  gcond *cond_stmt = as_a <gcond *> (*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 <gcond *> (last_stmt (exit->src));
+  gcond *cond_stmt = as_a <gcond *> (*gsi_last_bb (exit->src));
   tree control = gimple_cond_lhs (cond_stmt);
   gphi *phi = as_a <gphi *> (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 <gcond *> (last_stmt (exit->src));
+  cond_stmt = as_a <gcond *> (*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 <gcond *> (last_stmt (exit->src));
+  cond_nit = as_a <gcond *> (*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 <gcond *> (last_stmt (loop->header));
+  cond_stmt = as_a <gcond *> (*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 <gcond *> (stmt))
-	res = cond_stmt;
-    }
+    res = safe_dyn_cast <gcond *> (*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 <gcall *> (last_stmt (bb)))
+	if (gcall *stmt = safe_dyn_cast <gcall *> (*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 <gcond *> (*gsi_last_bb (inner_cond_bb));
+  if (!inner_cond)
     return false;
-  inner_cond = as_a <gcond *> (inner_stmt);
 
-  outer_stmt = last_stmt (outer_cond_bb);
-  if (!outer_stmt
-      || gimple_code (outer_stmt) != GIMPLE_COND)
+  gcond *outer_cond = safe_dyn_cast <gcond *> (*gsi_last_bb (outer_cond_bb));
+  if (!outer_cond)
     return false;
-  outer_cond = as_a <gcond *> (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 <gcond *> (*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 <gcond *> (last_stmt (e->dest));
+  gcond *last = safe_dyn_cast <gcond *> (*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 <gcond *> (last_stmt (header));
+  gcond *last = safe_dyn_cast <gcond *> (*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 <gcond *> (last_stmt (exit->src));
+  cond = as_a <gcond *> (*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 <gcond *> (last_stmt (edge_to_cancel->src));
+      gcond *cond = as_a <gcond *> (*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 <gcond *> (*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 <gcond *> (last_stmt (exit->src));
+  stmt = as_a <gcond *> (*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 <gcond *> (*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 <gcond *> (*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 <gcond *> (*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 <gcond *> (*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 <gcond *> (*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 <gcond *> (*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 <gcond *> (last);
+  gcond *stmt = safe_dyn_cast <gcond *> (*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 <gcond *> (*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<gcond *> (stmt);
-- 
2.35.3

^ permalink raw reply	[flat|nested] 2+ messages in thread

* [PATCH] More last_stmt removal
@ 2023-05-03 12:58 Richard Biener
  0 siblings, 0 replies; 2+ messages in thread
From: Richard Biener @ 2023-05-03 12:58 UTC (permalink / raw)
  To: gcc-patches

This is the last set of changes removing calls to last_stmt in favor of
*gsi_last_bb where this is obviously correct.  As with the last changes
I tried to cleanup the code as far as dependences are concerned.

Bootstrapped and tested on x86_64-unknown-linux-gnu, pushed.

	* tree-ssa-loop-split.cc (split_at_bb_p): Avoid last_stmt.
	(patch_loop_exit): Likewise.
	(connect_loops): Likewise.
	(split_loop): Likewise.
	(control_dep_semi_invariant_p): Likewise.
	(do_split_loop_on_cond): Likewise.
	(split_loop_on_cond): Likewise.
	* tree-ssa-loop-unswitch.cc (find_unswitching_predicates_for_bb):
	Likewise.
	(simplify_loop_version): Likewise.
	(evaluate_bbs): Likewise.
	(find_loop_guard): Likewise.
	(clean_up_after_unswitching): Likewise.
	* tree-ssa-math-opts.cc (maybe_optimize_guarding_check):
	Likewise.
	(optimize_spaceship): Take a gcond * argument, avoid
	last_stmt.
	(math_opts_dom_walker::after_dom_children): Adjust call to
	optimize_spaceship.
	* tree-vrp.cc (maybe_set_nonzero_bits): Avoid last_stmt.
	* value-pointer-equiv.cc (pointer_equiv_analyzer::visit_edge):
	Likewise.
---
 gcc/tree-ssa-loop-split.cc    | 29 +++++++++++---------------
 gcc/tree-ssa-loop-unswitch.cc | 10 ++++-----
 gcc/tree-ssa-math-opts.cc     | 39 ++++++++++++++---------------------
 gcc/tree-vrp.cc               | 13 ++++++------
 gcc/value-pointer-equiv.cc    |  5 ++---
 5 files changed, 41 insertions(+), 55 deletions(-)

diff --git a/gcc/tree-ssa-loop-split.cc b/gcc/tree-ssa-loop-split.cc
index fca678113eb..e5e6aa8eede 100644
--- a/gcc/tree-ssa-loop-split.cc
+++ b/gcc/tree-ssa-loop-split.cc
@@ -76,15 +76,13 @@ along with GCC; see the file COPYING3.  If not see
 static tree
 split_at_bb_p (class loop *loop, basic_block bb, tree *border, affine_iv *iv)
 {
-  gimple *last;
   gcond *stmt;
   affine_iv iv2;
 
   /* BB must end in a simple conditional jump.  */
-  last = last_stmt (bb);
-  if (!last || gimple_code (last) != GIMPLE_COND)
+  stmt = safe_dyn_cast <gcond *> (*gsi_last_bb (bb));
+  if (!stmt)
     return NULL_TREE;
-  stmt = as_a <gcond *> (last);
 
   enum tree_code code = gimple_cond_code (stmt);
 
@@ -158,7 +156,7 @@ patch_loop_exit (class loop *loop, gcond *guard, tree nextval, tree newbound,
 		 bool initial_true)
 {
   edge exit = single_exit (loop);
-  gcond *stmt = as_a <gcond *> (last_stmt (exit->src));
+  gcond *stmt = as_a <gcond *> (*gsi_last_bb (exit->src));
   gimple_cond_set_condition (stmt, gimple_cond_code (guard),
 			     nextval, newbound);
   update_stmt (stmt);
@@ -335,7 +333,7 @@ connect_loops (class loop *loop1, class loop *loop2)
   gimple_stmt_iterator gsi;
   edge new_e, skip_e;
 
-  gimple *stmt = last_stmt (exit->src);
+  gcond *stmt = as_a <gcond *> (*gsi_last_bb (exit->src));
   skip_stmt = gimple_build_cond (gimple_cond_code (stmt),
 				 gimple_cond_lhs (stmt),
 				 gimple_cond_rhs (stmt),
@@ -571,7 +569,7 @@ split_loop (class loop *loop1)
 	gphi *phi = find_or_create_guard_phi (loop1, guard_iv, &iv);
 	if (!phi)
 	  continue;
-	gcond *guard_stmt = as_a<gcond *> (last_stmt (bbs[i]));
+	gcond *guard_stmt = as_a<gcond *> (*gsi_last_bb (bbs[i]));
 	tree guard_init = PHI_ARG_DEF_FROM_EDGE (phi,
 						 loop_preheader_edge (loop1));
 	enum tree_code guard_code = gimple_cond_code (guard_stmt);
@@ -655,8 +653,8 @@ split_loop (class loop *loop1)
 
 	/* Finally patch out the two copies of the condition to be always
 	   true/false (or opposite).  */
-	gcond *force_true = as_a<gcond *> (last_stmt (bbs[i]));
-	gcond *force_false = as_a<gcond *> (last_stmt (get_bb_copy (bbs[i])));
+	gcond *force_true = as_a<gcond *> (*gsi_last_bb (bbs[i]));
+	gcond *force_false = as_a<gcond *> (*gsi_last_bb (get_bb_copy (bbs[i])));
 	if (!initial_true)
 	  std::swap (force_true, force_false);
 	gimple_cond_make_true (force_true);
@@ -1148,8 +1146,7 @@ control_dep_semi_invariant_p (struct loop *loop, basic_block bb,
   for (hash_set<basic_block>::iterator iter = dep_bbs->begin ();
        iter != dep_bbs->end (); ++iter)
     {
-      gimple *last = last_stmt (*iter);
-
+      gimple *last = *gsi_last_bb (*iter);
       if (!last)
 	return false;
 
@@ -1520,7 +1517,7 @@ do_split_loop_on_cond (struct loop *loop1, edge invar_branch)
 {
   basic_block cond_bb = invar_branch->src;
   bool true_invar = !!(invar_branch->flags & EDGE_TRUE_VALUE);
-  gcond *cond = as_a <gcond *> (last_stmt (cond_bb));
+  gcond *cond = as_a <gcond *> (*gsi_last_bb (cond_bb));
 
   gcc_assert (cond_bb->loop_father == loop1);
 
@@ -1544,7 +1541,7 @@ do_split_loop_on_cond (struct loop *loop1, edge invar_branch)
     }
 
   basic_block cond_bb_copy = get_bb_copy (cond_bb);
-  gcond *cond_copy = as_a<gcond *> (last_stmt (cond_bb_copy));
+  gcond *cond_copy = as_a<gcond *> (*gsi_last_bb (cond_bb_copy));
 
   /* Replace the condition in loop2 with a bool constant to let PassManager
      remove the variant branch after current pass completes.  */
@@ -1628,12 +1625,10 @@ split_loop_on_cond (struct loop *loop)
       if (!dominated_by_p (CDI_DOMINATORS, loop->latch, bb))
 	continue;
 
-      gimple *last = last_stmt (bb);
-
-      if (!last || gimple_code (last) != GIMPLE_COND)
+      gcond *cond = safe_dyn_cast <gcond *> (*gsi_last_bb (bb));
+      if (!cond)
 	continue;
 
-      gcond *cond = as_a <gcond *> (last);
       edge branch_edge = get_cond_branch_to_split_loop (loop, cond);
 
       if (branch_edge)
diff --git a/gcc/tree-ssa-loop-unswitch.cc b/gcc/tree-ssa-loop-unswitch.cc
index 081fb42ba54..95580768804 100644
--- a/gcc/tree-ssa-loop-unswitch.cc
+++ b/gcc/tree-ssa-loop-unswitch.cc
@@ -506,7 +506,7 @@ find_unswitching_predicates_for_bb (basic_block bb, class loop *loop,
   ssa_op_iter iter;
 
   /* BB must end in a simple conditional jump.  */
-  last = last_stmt (bb);
+  last = *gsi_last_bb (bb);
   if (!last)
     return;
 
@@ -806,7 +806,7 @@ simplify_loop_version (class loop *loop, predicate_vector &predicate_path,
       if (predicates.is_empty ())
 	continue;
 
-      gimple *stmt = last_stmt (bbs[i]);
+      gimple *stmt = *gsi_last_bb (bbs[i]);
       tree folded = evaluate_control_stmt_using_entry_checks (stmt,
 							      predicate_path,
 							      ignored_edge_flag,
@@ -886,7 +886,7 @@ evaluate_bbs (class loop *loop, predicate_vector *predicate_path,
       if (visit (bb))
 	break;
 
-      gimple *last = last_stmt (bb);
+      gimple *last = *gsi_last_bb (bb);
       if (gcond *cond = safe_dyn_cast <gcond *> (last))
 	{
 	  if (gimple_cond_true_p (cond))
@@ -1218,7 +1218,7 @@ find_loop_guard (class loop *loop, vec<gimple *> &dbg_to_reset)
 	next = single_succ (header);
       else
 	{
-	  cond = safe_dyn_cast <gcond *> (last_stmt (header));
+	  cond = safe_dyn_cast <gcond *> (*gsi_last_bb (header));
 	  if (! cond)
 	    return NULL;
 	  extract_true_false_edges_from_block (header, &te, &fe);
@@ -1638,7 +1638,7 @@ clean_up_after_unswitching (int ignored_edge_flag)
 
   FOR_EACH_BB_FN (bb, cfun)
     {
-      gswitch *stmt= safe_dyn_cast <gswitch *> (last_stmt (bb));
+      gswitch *stmt= safe_dyn_cast <gswitch *> (*gsi_last_bb (bb));
       if (stmt && !CONSTANT_CLASS_P (gimple_switch_index (stmt)))
 	{
 	  unsigned nlabels = gimple_switch_num_labels (stmt);
diff --git a/gcc/tree-ssa-math-opts.cc b/gcc/tree-ssa-math-opts.cc
index 15eed3e960c..b58a2ac9e6a 100644
--- a/gcc/tree-ssa-math-opts.cc
+++ b/gcc/tree-ssa-math-opts.cc
@@ -3605,9 +3605,8 @@ maybe_optimize_guarding_check (vec<gimple *> &mul_stmts, gimple *cond_stmt,
     }
   else if (!single_succ_p (bb) || other_edge->dest != single_succ (bb))
     return;
-  gimple *zero_cond = last_stmt (pred_bb);
+  gcond *zero_cond = safe_dyn_cast <gcond *> (*gsi_last_bb (pred_bb));
   if (zero_cond == NULL
-      || gimple_code (zero_cond) != GIMPLE_COND
       || (gimple_cond_code (zero_cond)
 	  != ((pred_edge->flags & EDGE_TRUE_VALUE) ? NE_EXPR : EQ_EXPR))
       || !integer_zerop (gimple_cond_rhs (zero_cond)))
@@ -3726,11 +3725,10 @@ maybe_optimize_guarding_check (vec<gimple *> &mul_stmts, gimple *cond_stmt,
       else if (!integer_onep (other_val))
 	return;
     }
-  gcond *zero_gcond = as_a <gcond *> (zero_cond);
   if (pred_edge->flags & EDGE_TRUE_VALUE)
-    gimple_cond_make_true (zero_gcond);
+    gimple_cond_make_true (zero_cond);
   else
-    gimple_cond_make_false (zero_gcond);
+    gimple_cond_make_false (zero_cond);
   update_stmt (zero_cond);
   *cfg_changed = true;
 }
@@ -4778,7 +4776,7 @@ convert_mult_to_highpart (gassign *stmt, gimple_stmt_iterator *gsi)
    conditional jump sequence.  */
 
 static void
-optimize_spaceship (gimple *stmt)
+optimize_spaceship (gcond *stmt)
 {
   enum tree_code code = gimple_cond_code (stmt);
   if (code != EQ_EXPR && code != NE_EXPR)
@@ -4797,9 +4795,8 @@ optimize_spaceship (gimple *stmt)
   if (((EDGE_SUCC (bb0, 0)->flags & EDGE_TRUE_VALUE) != 0) ^ (code == EQ_EXPR))
     bb1 = EDGE_SUCC (bb0, 0)->dest;
 
-  gimple *g = last_stmt (bb1);
+  gcond *g = safe_dyn_cast <gcond *> (*gsi_last_bb (bb1));
   if (g == NULL
-      || gimple_code (g) != GIMPLE_COND
       || !single_pred_p (bb1)
       || (operand_equal_p (gimple_cond_lhs (g), arg1, 0)
 	  ? !operand_equal_p (gimple_cond_rhs (g), arg2, 0)
@@ -4833,9 +4830,8 @@ optimize_spaceship (gimple *stmt)
 	continue;
 
       bb2 = EDGE_SUCC (bb1, i)->dest;
-      g = last_stmt (bb2);
+      g = safe_dyn_cast <gcond *> (*gsi_last_bb (bb2));
       if (g == NULL
-	  || gimple_code (g) != GIMPLE_COND
 	  || !single_pred_p (bb2)
 	  || (operand_equal_p (gimple_cond_lhs (g), arg1, 0)
 	      ? !operand_equal_p (gimple_cond_rhs (g), arg2, 0)
@@ -4899,19 +4895,17 @@ optimize_spaceship (gimple *stmt)
 	}
     }
 
-  g = gimple_build_call_internal (IFN_SPACESHIP, 2, arg1, arg2);
+  gcall *gc = gimple_build_call_internal (IFN_SPACESHIP, 2, arg1, arg2);
   tree lhs = make_ssa_name (integer_type_node);
-  gimple_call_set_lhs (g, lhs);
+  gimple_call_set_lhs (gc, lhs);
   gimple_stmt_iterator gsi = gsi_for_stmt (stmt);
-  gsi_insert_before (&gsi, g, GSI_SAME_STMT);
+  gsi_insert_before (&gsi, gc, GSI_SAME_STMT);
 
-  gcond *cond = as_a <gcond *> (stmt);
-  gimple_cond_set_lhs (cond, lhs);
-  gimple_cond_set_rhs (cond, integer_zero_node);
+  gimple_cond_set_lhs (stmt, lhs);
+  gimple_cond_set_rhs (stmt, integer_zero_node);
   update_stmt (stmt);
 
-  g = last_stmt (bb1);
-  cond = as_a <gcond *> (g);
+  gcond *cond = as_a <gcond *> (*gsi_last_bb (bb1));
   gimple_cond_set_lhs (cond, lhs);
   if (em1->src == bb1 && e2 != em1)
     {
@@ -4926,12 +4920,11 @@ optimize_spaceship (gimple *stmt)
       gimple_cond_set_code (cond, (e1->flags & EDGE_TRUE_VALUE)
 				  ? EQ_EXPR : NE_EXPR);
     }
-  update_stmt (g);
+  update_stmt (cond);
 
   if (e2 != e1 && e2 != em1)
     {
-      g = last_stmt (bb2);
-      cond = as_a <gcond *> (g);
+      cond = as_a <gcond *> (*gsi_last_bb (bb2));
       gimple_cond_set_lhs (cond, lhs);
       if (em1->src == bb2)
 	gimple_cond_set_rhs (cond, integer_minus_one_node);
@@ -4942,7 +4935,7 @@ optimize_spaceship (gimple *stmt)
 	}
       gimple_cond_set_code (cond,
 			    (e2->flags & EDGE_TRUE_VALUE) ? NE_EXPR : EQ_EXPR);
-      update_stmt (g);
+      update_stmt (cond);
     }
 
   wide_int wm1 = wi::minus_one (TYPE_PRECISION (integer_type_node));
@@ -5113,7 +5106,7 @@ math_opts_dom_walker::after_dom_children (basic_block bb)
 	    }
 	}
       else if (gimple_code (stmt) == GIMPLE_COND)
-	optimize_spaceship (stmt);
+	optimize_spaceship (as_a <gcond *> (stmt));
       gsi_next (&gsi);
     }
   if (fma_state.m_deferring_p
diff --git a/gcc/tree-vrp.cc b/gcc/tree-vrp.cc
index 0761b6896fe..89707a56b21 100644
--- a/gcc/tree-vrp.cc
+++ b/gcc/tree-vrp.cc
@@ -650,18 +650,17 @@ void
 maybe_set_nonzero_bits (edge e, tree var)
 {
   basic_block cond_bb = e->src;
-  gimple *stmt = last_stmt (cond_bb);
+  gcond *cond = safe_dyn_cast <gcond *> (*gsi_last_bb (cond_bb));
   tree cst;
 
-  if (stmt == NULL
-      || gimple_code (stmt) != GIMPLE_COND
-      || gimple_cond_code (stmt) != ((e->flags & EDGE_TRUE_VALUE)
+  if (cond == NULL
+      || gimple_cond_code (cond) != ((e->flags & EDGE_TRUE_VALUE)
 				     ? EQ_EXPR : NE_EXPR)
-      || TREE_CODE (gimple_cond_lhs (stmt)) != SSA_NAME
-      || !integer_zerop (gimple_cond_rhs (stmt)))
+      || TREE_CODE (gimple_cond_lhs (cond)) != SSA_NAME
+      || !integer_zerop (gimple_cond_rhs (cond)))
     return;
 
-  stmt = SSA_NAME_DEF_STMT (gimple_cond_lhs (stmt));
+  gimple *stmt = SSA_NAME_DEF_STMT (gimple_cond_lhs (cond));
   if (!is_gimple_assign (stmt)
       || gimple_assign_rhs_code (stmt) != BIT_AND_EXPR
       || TREE_CODE (gimple_assign_rhs2 (stmt)) != INTEGER_CST)
diff --git a/gcc/value-pointer-equiv.cc b/gcc/value-pointer-equiv.cc
index aeff2e879b9..52365837ac7 100644
--- a/gcc/value-pointer-equiv.cc
+++ b/gcc/value-pointer-equiv.cc
@@ -302,12 +302,11 @@ pointer_equiv_analyzer::visit_stmt (gimple *stmt)
 void
 pointer_equiv_analyzer::visit_edge (edge e)
 {
-  gimple *stmt = last_stmt (e->src);
+  gcond *stmt = safe_dyn_cast <gcond *> (*gsi_last_bb (e->src));
   tree lhs;
   // Recognize: x_13 [==,!=] &foo.
   if (stmt
-      && gimple_code (stmt) == GIMPLE_COND
-      && (lhs = gimple_cond_lhs (stmt))
+      && ((lhs = gimple_cond_lhs (stmt)), true)
       && TREE_CODE (lhs) == SSA_NAME
       && POINTER_TYPE_P (TREE_TYPE (lhs))
       && TREE_CODE (gimple_cond_rhs (stmt)) == ADDR_EXPR)
-- 
2.35.3

^ permalink raw reply	[flat|nested] 2+ messages in thread

end of thread, other threads:[~2023-05-03 12:58 UTC | newest]

Thread overview: 2+ messages (download: mbox.gz / follow: Atom feed)
-- links below jump to the message on this page --
2023-04-25 15:11 [PATCH] More last_stmt removal Richard Biener
2023-05-03 12:58 Richard Biener

This is a public inbox, see mirroring instructions
for how to clone and mirror all data and code used for this inbox;
as well as URLs for read-only IMAP folder(s) and NNTP newsgroup(s).