diff mbox series

[RFC] Add gimple-cfg.h.

Message ID db5db1c1-a46c-5cc7-03c4-c7b1cb3e2a0a@suse.cz
State New
Headers show
Series [RFC] Add gimple-cfg.h. | expand

Commit Message

Martin Liška Aug. 21, 2018, 12:58 p.m. UTC
Hi.

I'm considering adding couple of new gimple-related functions that
are related to gswitch statement.

Is it a good idea?
Martin

gcc/ChangeLog:

2018-08-06  Martin Liska  <mliska@suse.cz>

	* gimple-cfg.h: New file.
	* ipa-fnsummary.c (set_switch_stmt_execution_predicate):
        Use gimple_switch_edge (and gimple_switch_default_edge).
	* tree-switch-conversion.c (switch_conversion::collect): Likewise.
	(switch_decision_tree::compute_cases_per_edge): Likewise.
	(switch_decision_tree::analyze_switch_statement): Likewise.
	(switch_decision_tree::try_switch_expansion): Likewise.
---
 gcc/gimple-cfg.h             | 44 ++++++++++++++++++++++++++++++++++++
 gcc/ipa-fnsummary.c          |  7 +++---
 gcc/tree-switch-conversion.c | 38 ++++++++++++-------------------
 3 files changed, 62 insertions(+), 27 deletions(-)
 create mode 100644 gcc/gimple-cfg.h

Comments

Richard Biener Aug. 21, 2018, 1:55 p.m. UTC | #1
On Tue, Aug 21, 2018 at 2:58 PM Martin Liška <mliska@suse.cz> wrote:
>
> Hi.
>
> I'm considering adding couple of new gimple-related functions that
> are related to gswitch statement.
>
> Is it a good idea?

Just add them to tree-cfg.h?  That's what should be really called
gimple-cfg.h these days...

Richard.

> Martin
>
> gcc/ChangeLog:
>
> 2018-08-06  Martin Liska  <mliska@suse.cz>
>
>         * gimple-cfg.h: New file.
>         * ipa-fnsummary.c (set_switch_stmt_execution_predicate):
>         Use gimple_switch_edge (and gimple_switch_default_edge).
>         * tree-switch-conversion.c (switch_conversion::collect): Likewise.
>         (switch_decision_tree::compute_cases_per_edge): Likewise.
>         (switch_decision_tree::analyze_switch_statement): Likewise.
>         (switch_decision_tree::try_switch_expansion): Likewise.
> ---
>  gcc/gimple-cfg.h             | 44 ++++++++++++++++++++++++++++++++++++
>  gcc/ipa-fnsummary.c          |  7 +++---
>  gcc/tree-switch-conversion.c | 38 ++++++++++++-------------------
>  3 files changed, 62 insertions(+), 27 deletions(-)
>  create mode 100644 gcc/gimple-cfg.h
>
>
Martin Liška Aug. 23, 2018, 10:24 a.m. UTC | #2
On 08/21/2018 03:55 PM, Richard Biener wrote:
> On Tue, Aug 21, 2018 at 2:58 PM Martin Liška <mliska@suse.cz> wrote:
>>
>> Hi.
>>
>> I'm considering adding couple of new gimple-related functions that
>> are related to gswitch statement.
>>
>> Is it a good idea?
> 
> Just add them to tree-cfg.h?  That's what should be really called
> gimple-cfg.h these days...

Yes, done in the patch. I actually added 2 more functions:

extern basic_block gimple_switch_bb (gswitch *gs, unsigned index);
extern basic_block gimple_switch_default_bb (gswitch *gs);

and I clean up the implementation. Apart from that I noticed
label_to_block_fn can be removed as all callers use cfun as argument.

Patch can bootstrap on ppc64le-redhat-linux and survives regression tests.

Ready to be installed?
Martin
> 
> Richard.
> 
>> Martin
>>
>> gcc/ChangeLog:
>>
>> 2018-08-06  Martin Liska  <mliska@suse.cz>
>>
>>         * gimple-cfg.h: New file.
>>         * ipa-fnsummary.c (set_switch_stmt_execution_predicate):
>>         Use gimple_switch_edge (and gimple_switch_default_edge).
>>         * tree-switch-conversion.c (switch_conversion::collect): Likewise.
>>         (switch_decision_tree::compute_cases_per_edge): Likewise.
>>         (switch_decision_tree::analyze_switch_statement): Likewise.
>>         (switch_decision_tree::try_switch_expansion): Likewise.
>> ---
>>  gcc/gimple-cfg.h             | 44 ++++++++++++++++++++++++++++++++++++
>>  gcc/ipa-fnsummary.c          |  7 +++---
>>  gcc/tree-switch-conversion.c | 38 ++++++++++++-------------------
>>  3 files changed, 62 insertions(+), 27 deletions(-)
>>  create mode 100644 gcc/gimple-cfg.h
>>
>>
From e59865447c1f19988bc0c6db05d8d4ba78d6785e Mon Sep 17 00:00:00 2001
From: marxin <mliska@suse.cz>
Date: Fri, 3 Aug 2018 14:54:32 +0200
Subject: [PATCH] Add new gswitch related functions into tree-cfg.c.

gcc/ChangeLog:

2018-08-23  Martin Liska  <mliska@suse.cz>

	* cfgexpand.c (expand_asm_stmt): Use label_to_block
        instead of label_to_block_fn.
	* hsa-gen.c (gen_hsa_insns_for_switch_stmt): Use new
        function gimple_switch_default_bb.
	(convert_switch_statements): Use cfun directly and
        use label_to_block.
	(expand_builtins): Use cfun directly.
	* ipa-fnsummary.c (set_switch_stmt_execution_predicate):
        Use new function gimple_switch_edge.
	* stmt.c (label_to_block_fn): Remove declaration.
	(expand_case): Use label_to_block.
	* tree-cfg.c (make_gimple_switch_edges): Use new
        function gimple_switch_bb.
	(label_to_block_fn): Remove.
	(label_to_block): Replace implementation done
        in label_to_block_fn.
	(group_case_labels_stmt): Use gimple_switch_default_bb.
	(gimple_verify_flow_info): Use gimple_switch_bb.
	(gimple_switch_bb): New.
	(gimple_switch_default_bb): Likewise.
	(gimple_switch_edge): Likewise.
	(gimple_switch_default_edge): Likewise.
	* tree-cfg.h (label_to_block_fn): Remove.
	(label_to_block): Make proper extern symbol.
	(gimple_switch_bb): New.
	(gimple_switch_default_bb): Likewise.
	(gimple_switch_edge): Likewise.
	(gimple_switch_default_edge): Likewise.
	* tree-cfgcleanup.c (convert_single_case_switch):
        Use gimple_switch_default_bb.
	* tree-switch-conversion.c (switch_conversion::collect):
        Use gimple_switch_default_edge and gimple_switch_edge
        functions.
	(switch_conversion::check_final_bb): Use gimple_switch_bb.
	(switch_decision_tree::compute_cases_per_edge):
        Use gimple_switch_edge.
	(switch_decision_tree::analyze_switch_statement): Do not
        use label_to_block_fn.
	(switch_decision_tree::try_switch_expansion): Use
        gimple_switch_default_edge.
---
 gcc/cfgexpand.c              |  2 +-
 gcc/hsa-gen.c                | 21 +++++---------
 gcc/ipa-fnsummary.c          |  2 +-
 gcc/stmt.c                   |  4 +--
 gcc/tree-cfg.c               | 54 ++++++++++++++++++++++++++++--------
 gcc/tree-cfg.h               |  8 ++++--
 gcc/tree-cfgcleanup.c        |  5 ++--
 gcc/tree-switch-conversion.c | 40 +++++++++-----------------
 8 files changed, 74 insertions(+), 62 deletions(-)

diff --git a/gcc/cfgexpand.c b/gcc/cfgexpand.c
index 3c5b30b79f8..156a529d730 100644
--- a/gcc/cfgexpand.c
+++ b/gcc/cfgexpand.c
@@ -3239,7 +3239,7 @@ expand_asm_stmt (gasm *stmt)
 	     may insert further instructions into the same basic block after
 	     asm goto and if we don't do this, insertion of instructions on
 	     the fallthru edge might misbehave.  See PR58670.  */
-	  if (fallthru_bb && label_to_block_fn (cfun, label) == fallthru_bb)
+	  if (fallthru_bb && label_to_block (label) == fallthru_bb)
 	    {
 	      if (fallthru_label == NULL_RTX)
 	        fallthru_label = gen_label_rtx ();
diff --git a/gcc/hsa-gen.c b/gcc/hsa-gen.c
index 6595bedac82..39bd42e4522 100644
--- a/gcc/hsa-gen.c
+++ b/gcc/hsa-gen.c
@@ -3475,7 +3475,6 @@ gen_hsa_insns_for_switch_stmt (gswitch *s, hsa_bb *hbb)
   e->flags &= ~EDGE_FALLTHRU;
   e->flags |= EDGE_TRUE_VALUE;
 
-  function *func = DECL_STRUCT_FUNCTION (current_function_decl);
   tree index_tree = gimple_switch_index (s);
   tree lowest = get_switch_low (s);
   tree highest = get_switch_high (s);
@@ -3499,9 +3498,7 @@ gen_hsa_insns_for_switch_stmt (gswitch *s, hsa_bb *hbb)
 
   hbb->append_insn (new hsa_insn_cbr (cmp_reg));
 
-  tree default_label = gimple_switch_default_label (s);
-  basic_block default_label_bb = label_to_block_fn (func,
-						    CASE_LABEL (default_label));
+  basic_block default_label_bb = gimple_switch_default_bb (s);
 
   if (!gimple_seq_empty_p (phi_nodes (default_label_bb)))
     {
@@ -3536,7 +3533,7 @@ gen_hsa_insns_for_switch_stmt (gswitch *s, hsa_bb *hbb)
   for (unsigned i = 1; i < labels; i++)
     {
       tree label = gimple_switch_label (s, i);
-      basic_block bb = label_to_block_fn (func, CASE_LABEL (label));
+      basic_block bb = label_to_block (CASE_LABEL (label));
 
       unsigned HOST_WIDE_INT sub_low
 	= tree_to_uhwi (int_const_binop (MINUS_EXPR, CASE_LOW (label), lowest));
@@ -6290,12 +6287,11 @@ LD:    hard_work_3 ();
 static bool
 convert_switch_statements (void)
 {
-  function *func = DECL_STRUCT_FUNCTION (current_function_decl);
   basic_block bb;
 
   bool modified_cfg = false;
 
-  FOR_EACH_BB_FN (bb, func)
+  FOR_EACH_BB_FN (bb, cfun)
   {
     gimple_stmt_iterator gsi = gsi_last_bb (bb);
     if (gsi_end_p (gsi))
@@ -6318,7 +6314,7 @@ convert_switch_statements (void)
 	tree index_type = TREE_TYPE (index);
 	tree default_label = gimple_switch_default_label (s);
 	basic_block default_label_bb
-	  = label_to_block_fn (func, CASE_LABEL (default_label));
+	  = label_to_block (CASE_LABEL (default_label));
 	basic_block cur_bb = bb;
 
 	auto_vec <edge> new_edges;
@@ -6330,8 +6326,7 @@ convert_switch_statements (void)
 	   should be fixed after we add new collection of edges.  */
 	for (unsigned i = 0; i < labels; i++)
 	  {
-	    tree label = gimple_switch_label (s, i);
-	    basic_block label_bb = label_to_block_fn (func, CASE_LABEL (label));
+	    basic_block label_bb = gimple_switch_bb (s, i);
 	    edge e = find_edge (bb, label_bb);
 	    edge_counts.safe_push (e->count ());
 	    edge_probabilities.safe_push (e->probability);
@@ -6413,8 +6408,7 @@ convert_switch_statements (void)
 
 	    gsi_insert_before (&cond_gsi, c, GSI_SAME_STMT);
 
-	    basic_block label_bb
-	      = label_to_block_fn (func, CASE_LABEL (label));
+	    basic_block label_bb = label_to_block (CASE_LABEL (label));
 	    edge new_edge = make_edge (cur_bb, label_bb, EDGE_TRUE_VALUE);
 	    profile_probability prob_sum = sum_slice <profile_probability>
 		 (edge_probabilities, i, labels, profile_probability::never ())
@@ -6481,10 +6475,9 @@ convert_switch_statements (void)
 static void
 expand_builtins ()
 {
-  function *func = DECL_STRUCT_FUNCTION (current_function_decl);
   basic_block bb;
 
-  FOR_EACH_BB_FN (bb, func)
+  FOR_EACH_BB_FN (bb, cfun)
   {
     for (gimple_stmt_iterator gsi = gsi_start_bb (bb); !gsi_end_p (gsi);
 	 gsi_next (&gsi))
diff --git a/gcc/ipa-fnsummary.c b/gcc/ipa-fnsummary.c
index a8fc2c2df9a..8aac26812f6 100644
--- a/gcc/ipa-fnsummary.c
+++ b/gcc/ipa-fnsummary.c
@@ -1291,7 +1291,7 @@ set_switch_stmt_execution_predicate (struct ipa_func_body_info *fbi,
       tree min, max;
       predicate p;
 
-      e = find_edge (bb, label_to_block (CASE_LABEL (cl)));
+      e = gimple_switch_edge (last, case_idx);
       min = CASE_LOW (cl);
       max = CASE_HIGH (cl);
 
diff --git a/gcc/stmt.c b/gcc/stmt.c
index b8df1818137..dc443a6fd66 100644
--- a/gcc/stmt.c
+++ b/gcc/stmt.c
@@ -82,8 +82,6 @@ struct simple_case_node
   tree m_code_label;
 };
 
-extern basic_block label_to_block_fn (struct function *, tree);
-
 static bool check_unique_operand_names (tree, tree, tree);
 static char *resolve_operand_name_1 (char *, tree, tree, tree);
 
@@ -907,7 +905,7 @@ expand_case (gswitch *stmt)
   /* Find the default case target label.  */
   tree default_lab = CASE_LABEL (gimple_switch_default_label (stmt));
   default_label = jump_target_rtx (default_lab);
-  basic_block default_bb = label_to_block_fn (cfun, default_lab);
+  basic_block default_bb = label_to_block (default_lab);
   edge default_edge = find_edge (bb, default_bb);
 
   /* Get upper and lower bounds of case values.  */
diff --git a/gcc/tree-cfg.c b/gcc/tree-cfg.c
index 463dd8a3bf9..bbfc21158a3 100644
--- a/gcc/tree-cfg.c
+++ b/gcc/tree-cfg.c
@@ -1397,17 +1397,16 @@ make_gimple_switch_edges (gswitch *entry, basic_block bb)
 
   for (i = 0; i < n; ++i)
     {
-      tree lab = CASE_LABEL (gimple_switch_label (entry, i));
-      basic_block label_bb = label_to_block (lab);
+      basic_block label_bb = gimple_switch_bb (entry, i);
       make_edge (bb, label_bb, 0);
     }
 }
 
 
-/* Return the basic block holding label DEST.  */
+/* Return the basic block holding label DEST for current function.  */
 
 basic_block
-label_to_block_fn (struct function *ifun, tree dest)
+label_to_block (tree dest)
 {
   int uid = LABEL_DECL_UID (dest);
 
@@ -1424,9 +1423,9 @@ label_to_block_fn (struct function *ifun, tree dest)
       gsi_insert_before (&gsi, stmt, GSI_NEW_STMT);
       uid = LABEL_DECL_UID (dest);
     }
-  if (vec_safe_length (ifun->cfg->x_label_to_block_map) <= (unsigned int) uid)
+  if (vec_safe_length (cfun->cfg->x_label_to_block_map) <= (unsigned int) uid)
     return NULL;
-  return (*ifun->cfg->x_label_to_block_map)[uid];
+  return (*cfun->cfg->x_label_to_block_map)[uid];
 }
 
 /* Create edges for a goto statement at block BB.  Returns true
@@ -1773,7 +1772,7 @@ group_case_labels_stmt (gswitch *stmt)
   int i, next_index, new_size;
   basic_block default_bb = NULL;
 
-  default_bb = label_to_block (CASE_LABEL (gimple_switch_default_label (stmt)));
+  default_bb = gimple_switch_default_bb (stmt);
 
   /* Look for possible opportunities to merge cases.  */
   new_size = i = 1;
@@ -5655,8 +5654,7 @@ gimple_verify_flow_info (void)
 	    /* Mark all the destination basic blocks.  */
 	    for (i = 0; i < n; ++i)
 	      {
-		tree lab = CASE_LABEL (gimple_switch_label (switch_stmt, i));
-		basic_block label_bb = label_to_block (lab);
+		basic_block label_bb = gimple_switch_bb (switch_stmt, i);
 		gcc_assert (!label_bb->aux || label_bb->aux == (void *)1);
 		label_bb->aux = (void *)1;
 	      }
@@ -5711,8 +5709,7 @@ gimple_verify_flow_info (void)
 	    /* Check that we have all of them.  */
 	    for (i = 0; i < n; ++i)
 	      {
-		tree lab = CASE_LABEL (gimple_switch_label (switch_stmt, i));
-		basic_block label_bb = label_to_block (lab);
+		basic_block label_bb = gimple_switch_bb (switch_stmt, i);
 
 		if (label_bb->aux != (void *)2)
 		  {
@@ -9143,6 +9140,41 @@ generate_range_test (basic_block bb, tree index, tree low, tree high,
   gsi_insert_seq_before (&gsi, seq, GSI_SAME_STMT);
 }
 
+/* Return the basic block that belongs to label numbered INDEX
+   of a switch statement.  */
+
+basic_block
+gimple_switch_bb (gswitch *gs, unsigned index)
+{
+  return label_to_block (CASE_LABEL (gimple_switch_label (gs, index)));
+}
+
+/* Return the default basic block of a switch statement.  */
+
+basic_block
+gimple_switch_default_bb (gswitch *gs)
+{
+  return gimple_switch_bb (gs, 0);
+}
+
+/* Return the edge that belongs to label numbered INDEX
+   of a switch statement.  */
+
+edge
+gimple_switch_edge (gswitch *gs, unsigned index)
+{
+  return find_edge (gimple_bb (gs), gimple_switch_bb (gs, index));
+}
+
+/* Return the default edge of a switch statement.  */
+
+edge
+gimple_switch_default_edge (gswitch *gs)
+{
+  return gimple_switch_edge (gs, 0);
+}
+
+
 /* Emit return warnings.  */
 
 namespace {
diff --git a/gcc/tree-cfg.h b/gcc/tree-cfg.h
index 9491bb45feb..d8e9c1a56f6 100644
--- a/gcc/tree-cfg.h
+++ b/gcc/tree-cfg.h
@@ -33,8 +33,7 @@ extern void init_empty_tree_cfg_for_function (struct function *);
 extern void init_empty_tree_cfg (void);
 extern void start_recording_case_labels (void);
 extern void end_recording_case_labels (void);
-extern basic_block label_to_block_fn (struct function *, tree);
-#define label_to_block(t) (label_to_block_fn (cfun, t))
+extern basic_block label_to_block (tree);
 extern void cleanup_dead_labels (void);
 extern bool group_case_labels_stmt (gswitch *);
 extern bool group_case_labels (void);
@@ -112,6 +111,10 @@ extern bool extract_true_false_controlled_edges (basic_block, basic_block,
 						 edge *, edge *);
 extern void generate_range_test (basic_block bb, tree index, tree low,
 				 tree high, tree *lhs, tree *rhs);
+extern basic_block gimple_switch_bb (gswitch *gs, unsigned index);
+extern basic_block gimple_switch_default_bb (gswitch *gs);
+extern edge gimple_switch_edge (gswitch *gs, unsigned index);
+extern edge gimple_switch_default_edge (gswitch *gs);
 
 /* Return true if the LHS of a call should be removed.  */
 
@@ -122,5 +125,6 @@ should_remove_lhs_p (tree lhs)
 	  && TREE_CODE (TYPE_SIZE_UNIT (TREE_TYPE (lhs))) == INTEGER_CST
 	  && !TREE_ADDRESSABLE (TREE_TYPE (lhs)));
 }
+edge gimple_switch_default_edge (gswitch *gs);
 
 #endif /* _TREE_CFG_H  */
diff --git a/gcc/tree-cfgcleanup.c b/gcc/tree-cfgcleanup.c
index b27ba8a7333..adac1d5f487 100644
--- a/gcc/tree-cfgcleanup.c
+++ b/gcc/tree-cfgcleanup.c
@@ -84,13 +84,12 @@ convert_single_case_switch (gswitch *swtch, gimple_stmt_iterator &gsi)
     return false;
 
   tree index = gimple_switch_index (swtch);
-  tree default_label = CASE_LABEL (gimple_switch_default_label (swtch));
   tree label = gimple_switch_label (swtch, 1);
   tree low = CASE_LOW (label);
   tree high = CASE_HIGH (label);
 
-  basic_block default_bb = label_to_block_fn (cfun, default_label);
-  basic_block case_bb = label_to_block_fn (cfun, CASE_LABEL (label));
+  basic_block default_bb = gimple_switch_default_bb (swtch);
+  basic_block case_bb = label_to_block (CASE_LABEL (label));
 
   basic_block bb = gimple_bb (swtch);
   gcond *cond;
diff --git a/gcc/tree-switch-conversion.c b/gcc/tree-switch-conversion.c
index 9a594a01fc4..c3d52fb3e74 100644
--- a/gcc/tree-switch-conversion.c
+++ b/gcc/tree-switch-conversion.c
@@ -78,7 +78,6 @@ switch_conversion::collect (gswitch *swtch)
   unsigned int i;
   edge e, e_default, e_first;
   edge_iterator ei;
-  basic_block first;
 
   m_switch = swtch;
 
@@ -87,9 +86,8 @@ switch_conversion::collect (gswitch *swtch)
      Collect the bits we can deduce from the CFG.  */
   m_index_expr = gimple_switch_index (swtch);
   m_switch_bb = gimple_bb (swtch);
-  m_default_bb
-    = label_to_block (CASE_LABEL (gimple_switch_default_label (swtch)));
-  e_default = find_edge (m_switch_bb, m_default_bb);
+  e_default = gimple_switch_default_edge (swtch);
+  m_default_bb = e_default->dest;
   m_default_prob = e_default->probability;
   m_default_count = e_default->count ();
   FOR_EACH_EDGE (e, ei, m_switch_bb->succs)
@@ -120,15 +118,9 @@ switch_conversion::collect (gswitch *swtch)
     }
 
   if (m_contiguous_range)
-    {
-      first = label_to_block (CASE_LABEL (gimple_switch_label (swtch, 1)));
-      e_first = find_edge (m_switch_bb, first);
-    }
+    e_first = gimple_switch_edge (swtch, 1);
   else
-    {
-      first = m_default_bb;
-      e_first = e_default;
-    }
+    e_first = e_default;
 
   /* See if there is one common successor block for all branch
      targets.  If it exists, record it in FINAL_BB.
@@ -306,8 +298,7 @@ switch_conversion::check_final_bb ()
 		  unsigned int branch_num = gimple_switch_num_labels (m_switch);
 		  for (unsigned int i = 1; i < branch_num; i++)
 		    {
-		      tree lab = CASE_LABEL (gimple_switch_label (m_switch, i));
-		      if (label_to_block (lab) == bb)
+		      if (gimple_switch_bb (m_switch, i) == bb)
 			{
 			  m_reason = reason;
 			  return false;
@@ -1577,15 +1568,11 @@ bit_test_cluster::hoist_edge_and_branch_if_true (gimple_stmt_iterator *gsip,
 void
 switch_decision_tree::compute_cases_per_edge ()
 {
-  basic_block bb = gimple_bb (m_switch);
   reset_out_edges_aux ();
   int ncases = gimple_switch_num_labels (m_switch);
   for (int i = ncases - 1; i >= 1; --i)
     {
-      tree elt = gimple_switch_label (m_switch, i);
-      tree lab = CASE_LABEL (elt);
-      basic_block case_bb = label_to_block_fn (cfun, lab);
-      edge case_edge = find_edge (bb, case_bb);
+      edge case_edge = gimple_switch_edge (m_switch, i);
       case_edge->aux = (void *) ((intptr_t) (case_edge->aux) + 1);
     }
 }
@@ -1601,8 +1588,7 @@ switch_decision_tree::analyze_switch_statement ()
   auto_vec<cluster *> clusters;
   clusters.create (l - 1);
 
-  tree default_label = CASE_LABEL (gimple_switch_default_label (m_switch));
-  basic_block default_bb = label_to_block_fn (cfun, default_label);
+  basic_block default_bb = gimple_switch_default_bb (m_switch);
   m_case_bbs.reserve (l);
   m_case_bbs.quick_push (default_bb);
 
@@ -1612,15 +1598,16 @@ switch_decision_tree::analyze_switch_statement ()
     {
       tree elt = gimple_switch_label (m_switch, i);
       tree lab = CASE_LABEL (elt);
-      basic_block case_bb = label_to_block_fn (cfun, lab);
+      basic_block case_bb = label_to_block (lab);
       edge case_edge = find_edge (bb, case_bb);
       tree low = CASE_LOW (elt);
       tree high = CASE_HIGH (elt);
 
       profile_probability p
 	= case_edge->probability.apply_scale (1, (intptr_t) (case_edge->aux));
-      clusters.quick_push (new simple_cluster (low, high, elt, case_bb, p));
-      m_case_bbs.quick_push (case_bb);
+      clusters.quick_push (new simple_cluster (low, high, elt, case_edge->dest,
+					       p));
+      m_case_bbs.quick_push (case_edge->dest);
     }
 
   reset_out_edges_aux ();
@@ -1694,9 +1681,8 @@ switch_decision_tree::try_switch_expansion (vec<cluster *> &clusters)
     return false;
 
   /* Find the default case target label.  */
-  tree default_label_expr = CASE_LABEL (gimple_switch_default_label (m_switch));
-  m_default_bb = label_to_block_fn (cfun, default_label_expr);
-  edge default_edge = find_edge (bb, m_default_bb);
+  edge default_edge = gimple_switch_default_edge (m_switch);
+  m_default_bb = default_edge->dest;
 
   /* Do the insertion of a case label into m_case_list.  The labels are
      fed to us in descending order from the sorted vector of case labels used
Martin Liška Aug. 27, 2018, 7:13 a.m. UTC | #3
Hi.

There's updated version with notes that were discussed with Richi
on IRC. As pointed out label_to_block can potentially lead to
quadratic complexity, but it's not ambition of the patch to resolve
that.

Martin
From 393a0b87d7d667f0db6e512a840f2da3f51c8f7b Mon Sep 17 00:00:00 2001
From: marxin <mliska@suse.cz>
Date: Fri, 3 Aug 2018 14:54:32 +0200
Subject: [PATCH] Add new gswitch related functions into tree-cfg.c.

gcc/ChangeLog:

2018-08-23  Martin Liska  <mliska@suse.cz>

	* cfgexpand.c (expand_asm_stmt): Use label_to_block
        instead of label_to_block_fn.
	* hsa-gen.c (gen_hsa_insns_for_switch_stmt): Use new
        function gimple_switch_default_bb.
	(convert_switch_statements): Use cfun directly and
        use label_to_block.
	(expand_builtins): Use cfun directly.
	* ipa-fnsummary.c (set_switch_stmt_execution_predicate):
        Use new function gimple_switch_edge.
	* stmt.c (label_to_block_fn): Remove declaration.
	(expand_case): Use label_to_block.
	* tree-cfg.c (make_gimple_switch_edges): Use new
        function gimple_switch_bb.
	(group_case_labels_stmt): Use gimple_switch_default_bb.
	(gimple_verify_flow_info): Use gimple_switch_bb.
	(gimple_switch_bb): New.
	(gimple_switch_default_bb): Likewise.
	(gimple_switch_edge): Likewise.
	(gimple_switch_default_edge): Likewise.
	* tree-cfg.h (label_to_block): Make proper extern symbol.
	(gimple_switch_bb): New.
	(gimple_switch_default_bb): Likewise.
	(gimple_switch_edge): Likewise.
	(gimple_switch_default_edge): Likewise.
	* tree-cfgcleanup.c (convert_single_case_switch):
        Use gimple_switch_default_bb.
	* tree-switch-conversion.c (switch_conversion::collect):
        Use gimple_switch_default_edge and gimple_switch_edge
        functions.
	(switch_conversion::check_final_bb): Use gimple_switch_bb.
	(switch_decision_tree::compute_cases_per_edge):
        Use gimple_switch_edge.
	(switch_decision_tree::analyze_switch_statement): Do not
        use label_to_block_fn.
	(switch_decision_tree::try_switch_expansion): Use
        gimple_switch_default_edge.
---
 gcc/cfgexpand.c              |  2 +-
 gcc/hsa-gen.c                | 21 ++++++----------
 gcc/ipa-fnsummary.c          |  2 +-
 gcc/stmt.c                   |  4 +---
 gcc/tree-cfg.c               | 46 ++++++++++++++++++++++++++++++------
 gcc/tree-cfg.h               |  4 ++++
 gcc/tree-cfgcleanup.c        |  5 ++--
 gcc/tree-switch-conversion.c | 40 ++++++++++---------------------
 8 files changed, 68 insertions(+), 56 deletions(-)

diff --git a/gcc/cfgexpand.c b/gcc/cfgexpand.c
index 3c5b30b79f8..156a529d730 100644
--- a/gcc/cfgexpand.c
+++ b/gcc/cfgexpand.c
@@ -3239,7 +3239,7 @@ expand_asm_stmt (gasm *stmt)
 	     may insert further instructions into the same basic block after
 	     asm goto and if we don't do this, insertion of instructions on
 	     the fallthru edge might misbehave.  See PR58670.  */
-	  if (fallthru_bb && label_to_block_fn (cfun, label) == fallthru_bb)
+	  if (fallthru_bb && label_to_block (label) == fallthru_bb)
 	    {
 	      if (fallthru_label == NULL_RTX)
 	        fallthru_label = gen_label_rtx ();
diff --git a/gcc/hsa-gen.c b/gcc/hsa-gen.c
index 6595bedac82..39bd42e4522 100644
--- a/gcc/hsa-gen.c
+++ b/gcc/hsa-gen.c
@@ -3475,7 +3475,6 @@ gen_hsa_insns_for_switch_stmt (gswitch *s, hsa_bb *hbb)
   e->flags &= ~EDGE_FALLTHRU;
   e->flags |= EDGE_TRUE_VALUE;
 
-  function *func = DECL_STRUCT_FUNCTION (current_function_decl);
   tree index_tree = gimple_switch_index (s);
   tree lowest = get_switch_low (s);
   tree highest = get_switch_high (s);
@@ -3499,9 +3498,7 @@ gen_hsa_insns_for_switch_stmt (gswitch *s, hsa_bb *hbb)
 
   hbb->append_insn (new hsa_insn_cbr (cmp_reg));
 
-  tree default_label = gimple_switch_default_label (s);
-  basic_block default_label_bb = label_to_block_fn (func,
-						    CASE_LABEL (default_label));
+  basic_block default_label_bb = gimple_switch_default_bb (s);
 
   if (!gimple_seq_empty_p (phi_nodes (default_label_bb)))
     {
@@ -3536,7 +3533,7 @@ gen_hsa_insns_for_switch_stmt (gswitch *s, hsa_bb *hbb)
   for (unsigned i = 1; i < labels; i++)
     {
       tree label = gimple_switch_label (s, i);
-      basic_block bb = label_to_block_fn (func, CASE_LABEL (label));
+      basic_block bb = label_to_block (CASE_LABEL (label));
 
       unsigned HOST_WIDE_INT sub_low
 	= tree_to_uhwi (int_const_binop (MINUS_EXPR, CASE_LOW (label), lowest));
@@ -6290,12 +6287,11 @@ LD:    hard_work_3 ();
 static bool
 convert_switch_statements (void)
 {
-  function *func = DECL_STRUCT_FUNCTION (current_function_decl);
   basic_block bb;
 
   bool modified_cfg = false;
 
-  FOR_EACH_BB_FN (bb, func)
+  FOR_EACH_BB_FN (bb, cfun)
   {
     gimple_stmt_iterator gsi = gsi_last_bb (bb);
     if (gsi_end_p (gsi))
@@ -6318,7 +6314,7 @@ convert_switch_statements (void)
 	tree index_type = TREE_TYPE (index);
 	tree default_label = gimple_switch_default_label (s);
 	basic_block default_label_bb
-	  = label_to_block_fn (func, CASE_LABEL (default_label));
+	  = label_to_block (CASE_LABEL (default_label));
 	basic_block cur_bb = bb;
 
 	auto_vec <edge> new_edges;
@@ -6330,8 +6326,7 @@ convert_switch_statements (void)
 	   should be fixed after we add new collection of edges.  */
 	for (unsigned i = 0; i < labels; i++)
 	  {
-	    tree label = gimple_switch_label (s, i);
-	    basic_block label_bb = label_to_block_fn (func, CASE_LABEL (label));
+	    basic_block label_bb = gimple_switch_bb (s, i);
 	    edge e = find_edge (bb, label_bb);
 	    edge_counts.safe_push (e->count ());
 	    edge_probabilities.safe_push (e->probability);
@@ -6413,8 +6408,7 @@ convert_switch_statements (void)
 
 	    gsi_insert_before (&cond_gsi, c, GSI_SAME_STMT);
 
-	    basic_block label_bb
-	      = label_to_block_fn (func, CASE_LABEL (label));
+	    basic_block label_bb = label_to_block (CASE_LABEL (label));
 	    edge new_edge = make_edge (cur_bb, label_bb, EDGE_TRUE_VALUE);
 	    profile_probability prob_sum = sum_slice <profile_probability>
 		 (edge_probabilities, i, labels, profile_probability::never ())
@@ -6481,10 +6475,9 @@ convert_switch_statements (void)
 static void
 expand_builtins ()
 {
-  function *func = DECL_STRUCT_FUNCTION (current_function_decl);
   basic_block bb;
 
-  FOR_EACH_BB_FN (bb, func)
+  FOR_EACH_BB_FN (bb, cfun)
   {
     for (gimple_stmt_iterator gsi = gsi_start_bb (bb); !gsi_end_p (gsi);
 	 gsi_next (&gsi))
diff --git a/gcc/ipa-fnsummary.c b/gcc/ipa-fnsummary.c
index a8fc2c2df9a..8aac26812f6 100644
--- a/gcc/ipa-fnsummary.c
+++ b/gcc/ipa-fnsummary.c
@@ -1291,7 +1291,7 @@ set_switch_stmt_execution_predicate (struct ipa_func_body_info *fbi,
       tree min, max;
       predicate p;
 
-      e = find_edge (bb, label_to_block (CASE_LABEL (cl)));
+      e = gimple_switch_edge (last, case_idx);
       min = CASE_LOW (cl);
       max = CASE_HIGH (cl);
 
diff --git a/gcc/stmt.c b/gcc/stmt.c
index b8df1818137..dc443a6fd66 100644
--- a/gcc/stmt.c
+++ b/gcc/stmt.c
@@ -82,8 +82,6 @@ struct simple_case_node
   tree m_code_label;
 };
 
-extern basic_block label_to_block_fn (struct function *, tree);
-
 static bool check_unique_operand_names (tree, tree, tree);
 static char *resolve_operand_name_1 (char *, tree, tree, tree);
 
@@ -907,7 +905,7 @@ expand_case (gswitch *stmt)
   /* Find the default case target label.  */
   tree default_lab = CASE_LABEL (gimple_switch_default_label (stmt));
   default_label = jump_target_rtx (default_lab);
-  basic_block default_bb = label_to_block_fn (cfun, default_lab);
+  basic_block default_bb = label_to_block (default_lab);
   edge default_edge = find_edge (bb, default_bb);
 
   /* Get upper and lower bounds of case values.  */
diff --git a/gcc/tree-cfg.c b/gcc/tree-cfg.c
index 463dd8a3bf9..39157ade8aa 100644
--- a/gcc/tree-cfg.c
+++ b/gcc/tree-cfg.c
@@ -1397,8 +1397,7 @@ make_gimple_switch_edges (gswitch *entry, basic_block bb)
 
   for (i = 0; i < n; ++i)
     {
-      tree lab = CASE_LABEL (gimple_switch_label (entry, i));
-      basic_block label_bb = label_to_block (lab);
+      basic_block label_bb = gimple_switch_bb (entry, i);
       make_edge (bb, label_bb, 0);
     }
 }
@@ -1773,7 +1772,7 @@ group_case_labels_stmt (gswitch *stmt)
   int i, next_index, new_size;
   basic_block default_bb = NULL;
 
-  default_bb = label_to_block (CASE_LABEL (gimple_switch_default_label (stmt)));
+  default_bb = gimple_switch_default_bb (stmt);
 
   /* Look for possible opportunities to merge cases.  */
   new_size = i = 1;
@@ -5655,8 +5654,7 @@ gimple_verify_flow_info (void)
 	    /* Mark all the destination basic blocks.  */
 	    for (i = 0; i < n; ++i)
 	      {
-		tree lab = CASE_LABEL (gimple_switch_label (switch_stmt, i));
-		basic_block label_bb = label_to_block (lab);
+		basic_block label_bb = gimple_switch_bb (switch_stmt, i);
 		gcc_assert (!label_bb->aux || label_bb->aux == (void *)1);
 		label_bb->aux = (void *)1;
 	      }
@@ -5711,8 +5709,7 @@ gimple_verify_flow_info (void)
 	    /* Check that we have all of them.  */
 	    for (i = 0; i < n; ++i)
 	      {
-		tree lab = CASE_LABEL (gimple_switch_label (switch_stmt, i));
-		basic_block label_bb = label_to_block (lab);
+		basic_block label_bb = gimple_switch_bb (switch_stmt, i);
 
 		if (label_bb->aux != (void *)2)
 		  {
@@ -9143,6 +9140,41 @@ generate_range_test (basic_block bb, tree index, tree low, tree high,
   gsi_insert_seq_before (&gsi, seq, GSI_SAME_STMT);
 }
 
+/* Return the basic block that belongs to label numbered INDEX
+   of a switch statement.  */
+
+basic_block
+gimple_switch_bb (gswitch *gs, unsigned index)
+{
+  return label_to_block (CASE_LABEL (gimple_switch_label (gs, index)));
+}
+
+/* Return the default basic block of a switch statement.  */
+
+basic_block
+gimple_switch_default_bb (gswitch *gs)
+{
+  return gimple_switch_bb (gs, 0);
+}
+
+/* Return the edge that belongs to label numbered INDEX
+   of a switch statement.  */
+
+edge
+gimple_switch_edge (gswitch *gs, unsigned index)
+{
+  return find_edge (gimple_bb (gs), gimple_switch_bb (gs, index));
+}
+
+/* Return the default edge of a switch statement.  */
+
+edge
+gimple_switch_default_edge (gswitch *gs)
+{
+  return gimple_switch_edge (gs, 0);
+}
+
+
 /* Emit return warnings.  */
 
 namespace {
diff --git a/gcc/tree-cfg.h b/gcc/tree-cfg.h
index 9491bb45feb..28194476cd1 100644
--- a/gcc/tree-cfg.h
+++ b/gcc/tree-cfg.h
@@ -112,6 +112,10 @@ extern bool extract_true_false_controlled_edges (basic_block, basic_block,
 						 edge *, edge *);
 extern void generate_range_test (basic_block bb, tree index, tree low,
 				 tree high, tree *lhs, tree *rhs);
+extern basic_block gimple_switch_bb (gswitch *gs, unsigned index);
+extern basic_block gimple_switch_default_bb (gswitch *gs);
+extern edge gimple_switch_edge (gswitch *gs, unsigned index);
+extern edge gimple_switch_default_edge (gswitch *gs);
 
 /* Return true if the LHS of a call should be removed.  */
 
diff --git a/gcc/tree-cfgcleanup.c b/gcc/tree-cfgcleanup.c
index b27ba8a7333..adac1d5f487 100644
--- a/gcc/tree-cfgcleanup.c
+++ b/gcc/tree-cfgcleanup.c
@@ -84,13 +84,12 @@ convert_single_case_switch (gswitch *swtch, gimple_stmt_iterator &gsi)
     return false;
 
   tree index = gimple_switch_index (swtch);
-  tree default_label = CASE_LABEL (gimple_switch_default_label (swtch));
   tree label = gimple_switch_label (swtch, 1);
   tree low = CASE_LOW (label);
   tree high = CASE_HIGH (label);
 
-  basic_block default_bb = label_to_block_fn (cfun, default_label);
-  basic_block case_bb = label_to_block_fn (cfun, CASE_LABEL (label));
+  basic_block default_bb = gimple_switch_default_bb (swtch);
+  basic_block case_bb = label_to_block (CASE_LABEL (label));
 
   basic_block bb = gimple_bb (swtch);
   gcond *cond;
diff --git a/gcc/tree-switch-conversion.c b/gcc/tree-switch-conversion.c
index 9a594a01fc4..c3d52fb3e74 100644
--- a/gcc/tree-switch-conversion.c
+++ b/gcc/tree-switch-conversion.c
@@ -78,7 +78,6 @@ switch_conversion::collect (gswitch *swtch)
   unsigned int i;
   edge e, e_default, e_first;
   edge_iterator ei;
-  basic_block first;
 
   m_switch = swtch;
 
@@ -87,9 +86,8 @@ switch_conversion::collect (gswitch *swtch)
      Collect the bits we can deduce from the CFG.  */
   m_index_expr = gimple_switch_index (swtch);
   m_switch_bb = gimple_bb (swtch);
-  m_default_bb
-    = label_to_block (CASE_LABEL (gimple_switch_default_label (swtch)));
-  e_default = find_edge (m_switch_bb, m_default_bb);
+  e_default = gimple_switch_default_edge (swtch);
+  m_default_bb = e_default->dest;
   m_default_prob = e_default->probability;
   m_default_count = e_default->count ();
   FOR_EACH_EDGE (e, ei, m_switch_bb->succs)
@@ -120,15 +118,9 @@ switch_conversion::collect (gswitch *swtch)
     }
 
   if (m_contiguous_range)
-    {
-      first = label_to_block (CASE_LABEL (gimple_switch_label (swtch, 1)));
-      e_first = find_edge (m_switch_bb, first);
-    }
+    e_first = gimple_switch_edge (swtch, 1);
   else
-    {
-      first = m_default_bb;
-      e_first = e_default;
-    }
+    e_first = e_default;
 
   /* See if there is one common successor block for all branch
      targets.  If it exists, record it in FINAL_BB.
@@ -306,8 +298,7 @@ switch_conversion::check_final_bb ()
 		  unsigned int branch_num = gimple_switch_num_labels (m_switch);
 		  for (unsigned int i = 1; i < branch_num; i++)
 		    {
-		      tree lab = CASE_LABEL (gimple_switch_label (m_switch, i));
-		      if (label_to_block (lab) == bb)
+		      if (gimple_switch_bb (m_switch, i) == bb)
 			{
 			  m_reason = reason;
 			  return false;
@@ -1577,15 +1568,11 @@ bit_test_cluster::hoist_edge_and_branch_if_true (gimple_stmt_iterator *gsip,
 void
 switch_decision_tree::compute_cases_per_edge ()
 {
-  basic_block bb = gimple_bb (m_switch);
   reset_out_edges_aux ();
   int ncases = gimple_switch_num_labels (m_switch);
   for (int i = ncases - 1; i >= 1; --i)
     {
-      tree elt = gimple_switch_label (m_switch, i);
-      tree lab = CASE_LABEL (elt);
-      basic_block case_bb = label_to_block_fn (cfun, lab);
-      edge case_edge = find_edge (bb, case_bb);
+      edge case_edge = gimple_switch_edge (m_switch, i);
       case_edge->aux = (void *) ((intptr_t) (case_edge->aux) + 1);
     }
 }
@@ -1601,8 +1588,7 @@ switch_decision_tree::analyze_switch_statement ()
   auto_vec<cluster *> clusters;
   clusters.create (l - 1);
 
-  tree default_label = CASE_LABEL (gimple_switch_default_label (m_switch));
-  basic_block default_bb = label_to_block_fn (cfun, default_label);
+  basic_block default_bb = gimple_switch_default_bb (m_switch);
   m_case_bbs.reserve (l);
   m_case_bbs.quick_push (default_bb);
 
@@ -1612,15 +1598,16 @@ switch_decision_tree::analyze_switch_statement ()
     {
       tree elt = gimple_switch_label (m_switch, i);
       tree lab = CASE_LABEL (elt);
-      basic_block case_bb = label_to_block_fn (cfun, lab);
+      basic_block case_bb = label_to_block (lab);
       edge case_edge = find_edge (bb, case_bb);
       tree low = CASE_LOW (elt);
       tree high = CASE_HIGH (elt);
 
       profile_probability p
 	= case_edge->probability.apply_scale (1, (intptr_t) (case_edge->aux));
-      clusters.quick_push (new simple_cluster (low, high, elt, case_bb, p));
-      m_case_bbs.quick_push (case_bb);
+      clusters.quick_push (new simple_cluster (low, high, elt, case_edge->dest,
+					       p));
+      m_case_bbs.quick_push (case_edge->dest);
     }
 
   reset_out_edges_aux ();
@@ -1694,9 +1681,8 @@ switch_decision_tree::try_switch_expansion (vec<cluster *> &clusters)
     return false;
 
   /* Find the default case target label.  */
-  tree default_label_expr = CASE_LABEL (gimple_switch_default_label (m_switch));
-  m_default_bb = label_to_block_fn (cfun, default_label_expr);
-  edge default_edge = find_edge (bb, m_default_bb);
+  edge default_edge = gimple_switch_default_edge (m_switch);
+  m_default_bb = default_edge->dest;
 
   /* Do the insertion of a case label into m_case_list.  The labels are
      fed to us in descending order from the sorted vector of case labels used
Richard Biener Aug. 27, 2018, 7:56 a.m. UTC | #4
On Mon, Aug 27, 2018 at 9:13 AM Martin Liška <mliska@suse.cz> wrote:
>
> Hi.
>
> There's updated version with notes that were discussed with Richi
> on IRC. As pointed out label_to_block can potentially lead to
> quadratic complexity, but it's not ambition of the patch to resolve
> that.

Please don't

@@ -3239,7 +3239,7 @@ expand_asm_stmt (gasm *stmt)
             may insert further instructions into the same basic block after
             asm goto and if we don't do this, insertion of instructions on
             the fallthru edge might misbehave.  See PR58670.  */
-         if (fallthru_bb && label_to_block_fn (cfun, label) == fallthru_bb)
+         if (fallthru_bb && label_to_block (label) == fallthru_bb)
            {
              if (fallthru_label == NULL_RTX)
                fallthru_label = gen_label_rtx ();

rather the label_to_block function should go away.  OK with removing any
such instances in the patch.

Richard.

> Martin
Martin Liška Aug. 27, 2018, 8:43 a.m. UTC | #5
On 08/27/2018 09:56 AM, Richard Biener wrote:
> On Mon, Aug 27, 2018 at 9:13 AM Martin Liška <mliska@suse.cz> wrote:
>>
>> Hi.
>>
>> There's updated version with notes that were discussed with Richi
>> on IRC. As pointed out label_to_block can potentially lead to
>> quadratic complexity, but it's not ambition of the patch to resolve
>> that.
> 
> Please don't
> 
> @@ -3239,7 +3239,7 @@ expand_asm_stmt (gasm *stmt)
>              may insert further instructions into the same basic block after
>              asm goto and if we don't do this, insertion of instructions on
>              the fallthru edge might misbehave.  See PR58670.  */
> -         if (fallthru_bb && label_to_block_fn (cfun, label) == fallthru_bb)
> +         if (fallthru_bb && label_to_block (label) == fallthru_bb)
>             {
>               if (fallthru_label == NULL_RTX)
>                 fallthru_label = gen_label_rtx ();
> 
> rather the label_to_block function should go away.  OK with removing any
> such instances in the patch.
> 
> Richard.
> 
>> Martin

Ok, I'm sending one more version where I completely removed label_to_block_fn.
Richi, out of the modified function, which would be subject for introduction
of a new argument (struct *function)?

Martin
From aae3a43220a75268b01837a77f7d720a1eeba573 Mon Sep 17 00:00:00 2001
From: marxin <mliska@suse.cz>
Date: Fri, 3 Aug 2018 14:54:32 +0200
Subject: [PATCH] Add new gswitch related functions into tree-cfg.c.

gcc/ChangeLog:

2018-08-27  Martin Liska  <mliska@suse.cz>

	* cfgexpand.c (expand_asm_stmt): Use label_to_block and pass
        cfun argument explicitly.
	* gimple-pretty-print.c (dump_gimple_switch): Likewise.
	* hsa-gen.c (gen_hsa_insns_for_switch_stmt): Use new
        function gimple_switch_default_bb.
	(convert_switch_statements):
	(expand_builtins):
	* ipa-fnsummary.c (set_switch_stmt_execution_predicate):
	* stmt.c (label_to_block_fn): Use label_to_block and pass
        cfun argument explicitly and use gimple_switch_bb.
	(expand_case): Likewise.
	* tree-cfg.c (lower_phi_internal_fn): Use label_to_block and pass
        cfun argument explicitly. Likewise.
	(make_edges_bb): Likewise.
	(make_cond_expr_edges): Likewise.
	(get_cases_for_edge): Likewise.
	(make_gimple_switch_edges): Likewise.
	(label_to_block_fn): Likewise.
	(label_to_block): Likewise.
	(make_goto_expr_edges): Likewise.
	(make_gimple_asm_edges): Likewise.
	(main_block_label): Likewise.
	(group_case_labels_stmt): Likewise.
	(find_taken_edge_computed_goto): Likewise.
	(find_taken_edge_switch_expr): Likewise.
	(gimple_verify_flow_info): Likewise.
	(gimple_redirect_edge_and_branch): Likewise.
	(gimple_switch_bb): New function.
	(gimple_switch_default_bb): Likewise.
	(gimple_switch_edge): Likewise.
	(gimple_switch_default_edge): Likewise.
	* tree-cfg.h (label_to_block_fn): Remove and replace ...
	(label_to_block): ... with this.
	(gimple_switch_bb): New.
	(gimple_switch_default_bb): Likewise.
	(gimple_switch_edge): Likewise.
	(gimple_switch_default_edge): Likewise.
	* tree-cfgcleanup.c (convert_single_case_switch): Use
        new gimple functions and pass new argument to label_to_block.
	(cleanup_control_flow_bb):
	* tree-eh.c (make_eh_dispatch_edges): Use label_to_block and pass
        cfun argument explicitly.
	(make_eh_edges): Likewise.
	(redirect_eh_dispatch_edge): Likewise.
	(lower_resx): Likewise.
	(lower_eh_dispatch): Likewise.
	(maybe_remove_unreachable_handlers): Likewise.
	(unsplit_eh): Likewise.
	(cleanup_empty_eh): Likewise.
	(verify_eh_edges): Likewise.
	(verify_eh_dispatch_edge): Likewise.
	* tree-ssa-dom.c (record_edge_info): Likewise.
	* tree-ssa-forwprop.c (simplify_gimple_switch_label_vec): Likewise.
	* tree-ssa-threadedge.c (thread_around_empty_blocks): Likewise.
	(thread_through_normal_block): Likewise.
	* tree-ssa-uncprop.c (associate_equivalences_with_edges): Likewise.
	* tree-ssa-uninit.c (convert_control_dep_chain_into_preds):
	* tree-switch-conversion.c (switch_conversion::collect): Use new
        gimple functions.
	(switch_conversion::check_final_bb): Likewise.
	(switch_conversion::gather_default_values): Pass new argument
        to label_to_block.
	(switch_conversion::build_constructors): Likewise.
	(switch_decision_tree::compute_cases_per_edge): Use new
        gimple_switch_edge function.
	(switch_decision_tree::analyze_switch_statement): Pass new argument
        to label_to_block.
	(switch_decision_tree::try_switch_expansion): Use
        gimple_switch_default_edge.
	* tree-vrp.c (find_switch_asserts): Pass new argument
        to label_to_block.
	* vr-values.c (vr_values::vrp_visit_switch_stmt): Likewise.
	(vr_values::simplify_switch_using_ranges): Likewise.
---
 gcc/cfgexpand.c              |  2 +-
 gcc/gimple-pretty-print.c    |  2 +-
 gcc/hsa-gen.c                | 21 +++------
 gcc/ipa-fnsummary.c          |  2 +-
 gcc/stmt.c                   |  4 +-
 gcc/tree-cfg.c               | 82 +++++++++++++++++++++++++-----------
 gcc/tree-cfg.h               |  7 ++-
 gcc/tree-cfgcleanup.c        |  7 ++-
 gcc/tree-eh.c                | 26 ++++++------
 gcc/tree-ssa-dom.c           |  3 +-
 gcc/tree-ssa-forwprop.c      |  2 +-
 gcc/tree-ssa-threadedge.c    |  4 +-
 gcc/tree-ssa-uncprop.c       |  2 +-
 gcc/tree-ssa-uninit.c        |  2 +-
 gcc/tree-switch-conversion.c | 44 +++++++------------
 gcc/tree-vrp.c               |  2 +-
 gcc/vr-values.c              |  5 ++-
 17 files changed, 115 insertions(+), 102 deletions(-)

diff --git a/gcc/cfgexpand.c b/gcc/cfgexpand.c
index 3c5b30b79f8..647764b0e94 100644
--- a/gcc/cfgexpand.c
+++ b/gcc/cfgexpand.c
@@ -3239,7 +3239,7 @@ expand_asm_stmt (gasm *stmt)
 	     may insert further instructions into the same basic block after
 	     asm goto and if we don't do this, insertion of instructions on
 	     the fallthru edge might misbehave.  See PR58670.  */
-	  if (fallthru_bb && label_to_block_fn (cfun, label) == fallthru_bb)
+	  if (fallthru_bb && label_to_block (cfun, label) == fallthru_bb)
 	    {
 	      if (fallthru_label == NULL_RTX)
 	        fallthru_label = gen_label_rtx ();
diff --git a/gcc/gimple-pretty-print.c b/gcc/gimple-pretty-print.c
index d3c5ec6f79b..dd63a28761b 100644
--- a/gcc/gimple-pretty-print.c
+++ b/gcc/gimple-pretty-print.c
@@ -992,7 +992,7 @@ dump_gimple_switch (pretty_printer *buffer, gswitch *gs, int spc,
 
       if (cfun && cfun->cfg)
 	{
-	  basic_block dest = label_to_block (label);
+	  basic_block dest = label_to_block (cfun, label);
 	  if (dest)
 	    {
 	      edge label_edge = find_edge (gimple_bb (gs), dest);
diff --git a/gcc/hsa-gen.c b/gcc/hsa-gen.c
index 6595bedac82..927b5813952 100644
--- a/gcc/hsa-gen.c
+++ b/gcc/hsa-gen.c
@@ -3475,7 +3475,6 @@ gen_hsa_insns_for_switch_stmt (gswitch *s, hsa_bb *hbb)
   e->flags &= ~EDGE_FALLTHRU;
   e->flags |= EDGE_TRUE_VALUE;
 
-  function *func = DECL_STRUCT_FUNCTION (current_function_decl);
   tree index_tree = gimple_switch_index (s);
   tree lowest = get_switch_low (s);
   tree highest = get_switch_high (s);
@@ -3499,9 +3498,7 @@ gen_hsa_insns_for_switch_stmt (gswitch *s, hsa_bb *hbb)
 
   hbb->append_insn (new hsa_insn_cbr (cmp_reg));
 
-  tree default_label = gimple_switch_default_label (s);
-  basic_block default_label_bb = label_to_block_fn (func,
-						    CASE_LABEL (default_label));
+  basic_block default_label_bb = gimple_switch_default_bb (s);
 
   if (!gimple_seq_empty_p (phi_nodes (default_label_bb)))
     {
@@ -3536,7 +3533,7 @@ gen_hsa_insns_for_switch_stmt (gswitch *s, hsa_bb *hbb)
   for (unsigned i = 1; i < labels; i++)
     {
       tree label = gimple_switch_label (s, i);
-      basic_block bb = label_to_block_fn (func, CASE_LABEL (label));
+      basic_block bb = label_to_block (cfun, CASE_LABEL (label));
 
       unsigned HOST_WIDE_INT sub_low
 	= tree_to_uhwi (int_const_binop (MINUS_EXPR, CASE_LOW (label), lowest));
@@ -6290,12 +6287,11 @@ LD:    hard_work_3 ();
 static bool
 convert_switch_statements (void)
 {
-  function *func = DECL_STRUCT_FUNCTION (current_function_decl);
   basic_block bb;
 
   bool modified_cfg = false;
 
-  FOR_EACH_BB_FN (bb, func)
+  FOR_EACH_BB_FN (bb, cfun)
   {
     gimple_stmt_iterator gsi = gsi_last_bb (bb);
     if (gsi_end_p (gsi))
@@ -6318,7 +6314,7 @@ convert_switch_statements (void)
 	tree index_type = TREE_TYPE (index);
 	tree default_label = gimple_switch_default_label (s);
 	basic_block default_label_bb
-	  = label_to_block_fn (func, CASE_LABEL (default_label));
+	  = label_to_block (cfun, CASE_LABEL (default_label));
 	basic_block cur_bb = bb;
 
 	auto_vec <edge> new_edges;
@@ -6330,8 +6326,7 @@ convert_switch_statements (void)
 	   should be fixed after we add new collection of edges.  */
 	for (unsigned i = 0; i < labels; i++)
 	  {
-	    tree label = gimple_switch_label (s, i);
-	    basic_block label_bb = label_to_block_fn (func, CASE_LABEL (label));
+	    basic_block label_bb = gimple_switch_bb (s, i);
 	    edge e = find_edge (bb, label_bb);
 	    edge_counts.safe_push (e->count ());
 	    edge_probabilities.safe_push (e->probability);
@@ -6413,8 +6408,7 @@ convert_switch_statements (void)
 
 	    gsi_insert_before (&cond_gsi, c, GSI_SAME_STMT);
 
-	    basic_block label_bb
-	      = label_to_block_fn (func, CASE_LABEL (label));
+	    basic_block label_bb = label_to_block (cfun, CASE_LABEL (label));
 	    edge new_edge = make_edge (cur_bb, label_bb, EDGE_TRUE_VALUE);
 	    profile_probability prob_sum = sum_slice <profile_probability>
 		 (edge_probabilities, i, labels, profile_probability::never ())
@@ -6481,10 +6475,9 @@ convert_switch_statements (void)
 static void
 expand_builtins ()
 {
-  function *func = DECL_STRUCT_FUNCTION (current_function_decl);
   basic_block bb;
 
-  FOR_EACH_BB_FN (bb, func)
+  FOR_EACH_BB_FN (bb, cfun)
   {
     for (gimple_stmt_iterator gsi = gsi_start_bb (bb); !gsi_end_p (gsi);
 	 gsi_next (&gsi))
diff --git a/gcc/ipa-fnsummary.c b/gcc/ipa-fnsummary.c
index a8fc2c2df9a..8aac26812f6 100644
--- a/gcc/ipa-fnsummary.c
+++ b/gcc/ipa-fnsummary.c
@@ -1291,7 +1291,7 @@ set_switch_stmt_execution_predicate (struct ipa_func_body_info *fbi,
       tree min, max;
       predicate p;
 
-      e = find_edge (bb, label_to_block (CASE_LABEL (cl)));
+      e = gimple_switch_edge (last, case_idx);
       min = CASE_LOW (cl);
       max = CASE_HIGH (cl);
 
diff --git a/gcc/stmt.c b/gcc/stmt.c
index b8df1818137..07355984de1 100644
--- a/gcc/stmt.c
+++ b/gcc/stmt.c
@@ -81,8 +81,6 @@ struct simple_case_node
   /* Label to jump to when node matches.  */
   tree m_code_label;
 };
-
-extern basic_block label_to_block_fn (struct function *, tree);
 
 static bool check_unique_operand_names (tree, tree, tree);
 static char *resolve_operand_name_1 (char *, tree, tree, tree);
@@ -907,7 +905,7 @@ expand_case (gswitch *stmt)
   /* Find the default case target label.  */
   tree default_lab = CASE_LABEL (gimple_switch_default_label (stmt));
   default_label = jump_target_rtx (default_lab);
-  basic_block default_bb = label_to_block_fn (cfun, default_lab);
+  basic_block default_bb = label_to_block (cfun, default_lab);
   edge default_edge = find_edge (bb, default_bb);
 
   /* Get upper and lower bounds of case values.  */
diff --git a/gcc/tree-cfg.c b/gcc/tree-cfg.c
index 463dd8a3bf9..6a776e3b7c1 100644
--- a/gcc/tree-cfg.c
+++ b/gcc/tree-cfg.c
@@ -389,7 +389,7 @@ lower_phi_internal_fn ()
 	    {
 	      tree arg = gimple_call_arg (stmt, i);
 	      if (TREE_CODE (arg) == LABEL_DECL)
-		pred = label_to_block (arg);
+		pred = label_to_block (cfun, arg);
 	      else
 		{
 		  edge e = find_edge (pred, bb);
@@ -972,15 +972,15 @@ make_edges_bb (basic_block bb, struct omp_region **pcur_region, int *pomp_index)
 	tree label2 = gimple_transaction_label_uninst (txn);
 
 	if (label1)
-	  make_edge (bb, label_to_block (label1), EDGE_FALLTHRU);
+	  make_edge (bb, label_to_block (cfun, label1), EDGE_FALLTHRU);
 	if (label2)
-	  make_edge (bb, label_to_block (label2),
+	  make_edge (bb, label_to_block (cfun, label2),
 		     EDGE_TM_UNINSTRUMENTED | (label1 ? 0 : EDGE_FALLTHRU));
 
 	tree label3 = gimple_transaction_label_over (txn);
 	if (gimple_transaction_subcode (txn)
 	    & (GTMA_HAVE_ABORT | GTMA_IS_OUTER))
-	  make_edge (bb, label_to_block (label3), EDGE_TM_ABORT);
+	  make_edge (bb, label_to_block (cfun, label3), EDGE_TM_ABORT);
 
 	fallthru = false;
       }
@@ -1265,8 +1265,8 @@ make_cond_expr_edges (basic_block bb)
   /* Entry basic blocks for each component.  */
   then_label = gimple_cond_true_label (entry);
   else_label = gimple_cond_false_label (entry);
-  then_bb = label_to_block (then_label);
-  else_bb = label_to_block (else_label);
+  then_bb = label_to_block (cfun, then_label);
+  else_bb = label_to_block (cfun, else_label);
   then_stmt = first_stmt (then_bb);
   else_stmt = first_stmt (else_bb);
 
@@ -1373,7 +1373,7 @@ get_cases_for_edge (edge e, gswitch *t)
     {
       tree elt = gimple_switch_label (t, i);
       tree lab = CASE_LABEL (elt);
-      basic_block label_bb = label_to_block (lab);
+      basic_block label_bb = label_to_block (cfun, lab);
       edge this_edge = find_edge (e->src, label_bb);
 
       /* Add it to the chain of CASE_LABEL_EXPRs referencing E, or create
@@ -1397,8 +1397,7 @@ make_gimple_switch_edges (gswitch *entry, basic_block bb)
 
   for (i = 0; i < n; ++i)
     {
-      tree lab = CASE_LABEL (gimple_switch_label (entry, i));
-      basic_block label_bb = label_to_block (lab);
+      basic_block label_bb = gimple_switch_bb (entry, i);
       make_edge (bb, label_bb, 0);
     }
 }
@@ -1407,7 +1406,7 @@ make_gimple_switch_edges (gswitch *entry, basic_block bb)
 /* Return the basic block holding label DEST.  */
 
 basic_block
-label_to_block_fn (struct function *ifun, tree dest)
+label_to_block (struct function *ifun, tree dest)
 {
   int uid = LABEL_DECL_UID (dest);
 
@@ -1442,7 +1441,7 @@ make_goto_expr_edges (basic_block bb)
   if (simple_goto_p (goto_t))
     {
       tree dest = gimple_goto_dest (goto_t);
-      basic_block label_bb = label_to_block (dest);
+      basic_block label_bb = label_to_block (cfun, dest);
       edge e = make_edge (bb, label_bb, EDGE_FALLTHRU);
       e->goto_locus = gimple_location (goto_t);
       gsi_remove (&last, true);
@@ -1464,7 +1463,7 @@ make_gimple_asm_edges (basic_block bb)
   for (i = 0; i < n; ++i)
     {
       tree label = TREE_VALUE (gimple_asm_label_op (stmt, i));
-      basic_block label_bb = label_to_block (label);
+      basic_block label_bb = label_to_block (cfun, label);
       make_edge (bb, label_bb, 0);
     }
 }
@@ -1496,7 +1495,7 @@ static struct label_record
 static tree
 main_block_label (tree label)
 {
-  basic_block bb = label_to_block (label);
+  basic_block bb = label_to_block (cfun, label);
   tree main_label = label_for_bb[bb->index].label;
 
   /* label_to_block possibly inserted undefined label into the chain.  */
@@ -1773,7 +1772,7 @@ group_case_labels_stmt (gswitch *stmt)
   int i, next_index, new_size;
   basic_block default_bb = NULL;
 
-  default_bb = label_to_block (CASE_LABEL (gimple_switch_default_label (stmt)));
+  default_bb = gimple_switch_default_bb (stmt);
 
   /* Look for possible opportunities to merge cases.  */
   new_size = i = 1;
@@ -1785,7 +1784,7 @@ group_case_labels_stmt (gswitch *stmt)
       base_case = gimple_switch_label (stmt, i);
 
       gcc_assert (base_case);
-      base_bb = label_to_block (CASE_LABEL (base_case));
+      base_bb = label_to_block (cfun, CASE_LABEL (base_case));
 
       /* Discard cases that have the same destination as the default case or
 	 whose destiniation blocks have already been removed as unreachable.  */
@@ -1806,7 +1805,7 @@ group_case_labels_stmt (gswitch *stmt)
       while (next_index < old_size)
 	{
 	  tree merge_case = gimple_switch_label (stmt, next_index);
-	  basic_block merge_bb = label_to_block (CASE_LABEL (merge_case));
+	  basic_block merge_bb = label_to_block (cfun, CASE_LABEL (merge_case));
 	  wide_int bhp1 = wi::to_wide (base_high) + 1;
 
 	  /* Merge the cases if they jump to the same place,
@@ -2387,7 +2386,7 @@ find_taken_edge_computed_goto (basic_block bb, tree val)
   basic_block dest;
   edge e = NULL;
 
-  dest = label_to_block (val);
+  dest = label_to_block (cfun, val);
   if (dest)
     e = find_edge (bb, dest);
 
@@ -2455,7 +2454,7 @@ find_taken_edge_switch_expr (const gswitch *switch_stmt, tree val)
       else
 	taken_case = find_case_label_for_value (switch_stmt, val);
     }
-  dest_bb = label_to_block (CASE_LABEL (taken_case));
+  dest_bb = label_to_block (cfun, CASE_LABEL (taken_case));
 
   e = find_edge (gimple_bb (switch_stmt), dest_bb);
   gcc_assert (e);
@@ -5498,7 +5497,7 @@ gimple_verify_flow_info (void)
 	      err = 1;
 	    }
 
-	  if (label_to_block (label) != bb)
+	  if (label_to_block (cfun, label) != bb)
 	    {
 	      error ("label ");
 	      print_generic_expr (stderr, label);
@@ -5655,8 +5654,7 @@ gimple_verify_flow_info (void)
 	    /* Mark all the destination basic blocks.  */
 	    for (i = 0; i < n; ++i)
 	      {
-		tree lab = CASE_LABEL (gimple_switch_label (switch_stmt, i));
-		basic_block label_bb = label_to_block (lab);
+		basic_block label_bb = gimple_switch_bb (switch_stmt, i);
 		gcc_assert (!label_bb->aux || label_bb->aux == (void *)1);
 		label_bb->aux = (void *)1;
 	      }
@@ -5711,8 +5709,7 @@ gimple_verify_flow_info (void)
 	    /* Check that we have all of them.  */
 	    for (i = 0; i < n; ++i)
 	      {
-		tree lab = CASE_LABEL (gimple_switch_label (switch_stmt, i));
-		basic_block label_bb = label_to_block (lab);
+		basic_block label_bb = gimple_switch_bb (switch_stmt, i);
 
 		if (label_bb->aux != (void *)2)
 		  {
@@ -5936,7 +5933,7 @@ gimple_redirect_edge_and_branch (edge e, basic_block dest)
 	    for (i = 0; i < n; i++)
 	      {
 		tree elt = gimple_switch_label (switch_stmt, i);
-		if (label_to_block (CASE_LABEL (elt)) == e->dest)
+		if (label_to_block (cfun, CASE_LABEL (elt)) == e->dest)
 		  CASE_LABEL (elt) = label;
 	      }
 	  }
@@ -5952,7 +5949,7 @@ gimple_redirect_edge_and_branch (edge e, basic_block dest)
 	for (i = 0; i < n; ++i)
 	  {
 	    tree cons = gimple_asm_label_op (asm_stmt, i);
-	    if (label_to_block (TREE_VALUE (cons)) == e->dest)
+	    if (label_to_block (cfun, TREE_VALUE (cons)) == e->dest)
 	      {
 		if (!label)
 		  label = gimple_block_label (dest);
@@ -9143,6 +9140,41 @@ generate_range_test (basic_block bb, tree index, tree low, tree high,
   gsi_insert_seq_before (&gsi, seq, GSI_SAME_STMT);
 }
 
+/* Return the basic block that belongs to label numbered INDEX
+   of a switch statement.  */
+
+basic_block
+gimple_switch_bb (gswitch *gs, unsigned index)
+{
+  return label_to_block (cfun, CASE_LABEL (gimple_switch_label (gs, index)));
+}
+
+/* Return the default basic block of a switch statement.  */
+
+basic_block
+gimple_switch_default_bb (gswitch *gs)
+{
+  return gimple_switch_bb (gs, 0);
+}
+
+/* Return the edge that belongs to label numbered INDEX
+   of a switch statement.  */
+
+edge
+gimple_switch_edge (gswitch *gs, unsigned index)
+{
+  return find_edge (gimple_bb (gs), gimple_switch_bb (gs, index));
+}
+
+/* Return the default edge of a switch statement.  */
+
+edge
+gimple_switch_default_edge (gswitch *gs)
+{
+  return gimple_switch_edge (gs, 0);
+}
+
+
 /* Emit return warnings.  */
 
 namespace {
diff --git a/gcc/tree-cfg.h b/gcc/tree-cfg.h
index 9491bb45feb..fd4217acf57 100644
--- a/gcc/tree-cfg.h
+++ b/gcc/tree-cfg.h
@@ -33,8 +33,7 @@ extern void init_empty_tree_cfg_for_function (struct function *);
 extern void init_empty_tree_cfg (void);
 extern void start_recording_case_labels (void);
 extern void end_recording_case_labels (void);
-extern basic_block label_to_block_fn (struct function *, tree);
-#define label_to_block(t) (label_to_block_fn (cfun, t))
+extern basic_block label_to_block (struct function *, tree);
 extern void cleanup_dead_labels (void);
 extern bool group_case_labels_stmt (gswitch *);
 extern bool group_case_labels (void);
@@ -112,6 +111,10 @@ extern bool extract_true_false_controlled_edges (basic_block, basic_block,
 						 edge *, edge *);
 extern void generate_range_test (basic_block bb, tree index, tree low,
 				 tree high, tree *lhs, tree *rhs);
+extern basic_block gimple_switch_bb (gswitch *gs, unsigned index);
+extern basic_block gimple_switch_default_bb (gswitch *gs);
+extern edge gimple_switch_edge (gswitch *gs, unsigned index);
+extern edge gimple_switch_default_edge (gswitch *gs);
 
 /* Return true if the LHS of a call should be removed.  */
 
diff --git a/gcc/tree-cfgcleanup.c b/gcc/tree-cfgcleanup.c
index b27ba8a7333..9717e98e8dd 100644
--- a/gcc/tree-cfgcleanup.c
+++ b/gcc/tree-cfgcleanup.c
@@ -84,13 +84,12 @@ convert_single_case_switch (gswitch *swtch, gimple_stmt_iterator &gsi)
     return false;
 
   tree index = gimple_switch_index (swtch);
-  tree default_label = CASE_LABEL (gimple_switch_default_label (swtch));
   tree label = gimple_switch_label (swtch, 1);
   tree low = CASE_LOW (label);
   tree high = CASE_HIGH (label);
 
-  basic_block default_bb = label_to_block_fn (cfun, default_label);
-  basic_block case_bb = label_to_block_fn (cfun, CASE_LABEL (label));
+  basic_block default_bb = gimple_switch_default_bb (swtch);
+  basic_block case_bb = label_to_block (cfun, CASE_LABEL (label));
 
   basic_block bb = gimple_bb (swtch);
   gcond *cond;
@@ -266,7 +265,7 @@ cleanup_control_flow_bb (basic_block bb)
       label = TREE_OPERAND (gimple_goto_dest (stmt), 0);
       if (DECL_CONTEXT (label) != cfun->decl)
 	return retval;
-      target_block = label_to_block (label);
+      target_block = label_to_block (cfun, label);
       for (ei = ei_start (bb->succs); (e = ei_safe_edge (ei)); )
 	{
 	  if (e->dest != target_block)
diff --git a/gcc/tree-eh.c b/gcc/tree-eh.c
index f367040af45..20e2db9e29a 100644
--- a/gcc/tree-eh.c
+++ b/gcc/tree-eh.c
@@ -2231,7 +2231,7 @@ make_eh_dispatch_edges (geh_dispatch *stmt)
     case ERT_TRY:
       for (c = r->u.eh_try.first_catch; c ; c = c->next_catch)
 	{
-	  dst = label_to_block (c->label);
+	  dst = label_to_block (cfun, c->label);
 	  make_edge (src, dst, 0);
 
 	  /* A catch-all handler doesn't have a fallthru.  */
@@ -2241,7 +2241,7 @@ make_eh_dispatch_edges (geh_dispatch *stmt)
       break;
 
     case ERT_ALLOWED_EXCEPTIONS:
-      dst = label_to_block (r->u.allowed.label);
+      dst = label_to_block (cfun, r->u.allowed.label);
       make_edge (src, dst, 0);
       break;
 
@@ -2270,7 +2270,7 @@ make_eh_edges (gimple *stmt)
   gcc_assert (lp != NULL);
 
   src = gimple_bb (stmt);
-  dst = label_to_block (lp->post_landing_pad);
+  dst = label_to_block (cfun, lp->post_landing_pad);
   make_edge (src, dst, EDGE_EH);
 }
 
@@ -2389,7 +2389,7 @@ redirect_eh_dispatch_edge (geh_dispatch *stmt, edge e, basic_block new_bb)
     case ERT_TRY:
       for (c = r->u.eh_try.first_catch; c ; c = c->next_catch)
 	{
-	  old_bb = label_to_block (c->label);
+	  old_bb = label_to_block (cfun, c->label);
 	  if (old_bb == e->dest)
 	    {
 	      c->label = new_lab;
@@ -2399,7 +2399,7 @@ redirect_eh_dispatch_edge (geh_dispatch *stmt, edge e, basic_block new_bb)
       break;
 
     case ERT_ALLOWED_EXCEPTIONS:
-      old_bb = label_to_block (r->u.allowed.label);
+      old_bb = label_to_block (cfun, r->u.allowed.label);
       gcc_assert (old_bb == e->dest);
       r->u.allowed.label = new_lab;
       any_changed = true;
@@ -3329,7 +3329,7 @@ lower_resx (basic_block bb, gresx *stmt,
 	  else
 	    {
 	      lab = *slot;
-	      new_bb = label_to_block (lab);
+	      new_bb = label_to_block (cfun, lab);
 	    }
 
 	  gcc_assert (EDGE_COUNT (bb->succs) == 0);
@@ -3733,7 +3733,7 @@ lower_eh_dispatch (basic_block src, geh_dispatch *stmt)
 	    while (tp_node);
 	    if (! have_label)
 	      {
-	        remove_edge (find_edge (src, label_to_block (lab)));
+		remove_edge (find_edge (src, label_to_block (cfun, lab)));
 	        redirected = true;
 	      }
 	  }
@@ -4046,7 +4046,7 @@ maybe_remove_unreachable_handlers (void)
   FOR_EACH_VEC_SAFE_ELT (cfun->eh->lp_array, i, lp)
     if (lp && lp->post_landing_pad)
       {
-	if (label_to_block (lp->post_landing_pad) == NULL)
+	if (label_to_block (cfun, lp->post_landing_pad) == NULL)
 	  {
 	    remove_unreachable_handlers ();
 	    return;
@@ -4110,7 +4110,7 @@ remove_unreachable_handlers_no_lp (void)
 static bool
 unsplit_eh (eh_landing_pad lp)
 {
-  basic_block bb = label_to_block (lp->post_landing_pad);
+  basic_block bb = label_to_block (cfun, lp->post_landing_pad);
   gimple_stmt_iterator gsi;
   edge e_in, e_out;
 
@@ -4475,7 +4475,7 @@ infinite_empty_loop_p (edge e_first)
 static bool
 cleanup_empty_eh (eh_landing_pad lp)
 {
-  basic_block bb = label_to_block (lp->post_landing_pad);
+  basic_block bb = label_to_block (cfun, lp->post_landing_pad);
   gimple_stmt_iterator gsi;
   gimple *resx;
   eh_region new_region;
@@ -4795,7 +4795,7 @@ verify_eh_edges (gimple *stmt)
       return true;
     }
 
-  if (eh_edge->dest != label_to_block (lp->post_landing_pad))
+  if (eh_edge->dest != label_to_block (cfun, lp->post_landing_pad))
     {
       error ("Incorrect EH edge %i->%i", bb->index, eh_edge->dest->index);
       return true;
@@ -4827,7 +4827,7 @@ verify_eh_dispatch_edge (geh_dispatch *stmt)
     case ERT_TRY:
       for (c = r->u.eh_try.first_catch; c ; c = c->next_catch)
 	{
-	  dst = label_to_block (c->label);
+	  dst = label_to_block (cfun, c->label);
 	  e = find_edge (src, dst);
 	  if (e == NULL)
 	    {
@@ -4846,7 +4846,7 @@ verify_eh_dispatch_edge (geh_dispatch *stmt)
       break;
 
     case ERT_ALLOWED_EXCEPTIONS:
-      dst = label_to_block (r->u.allowed.label);
+      dst = label_to_block (cfun, r->u.allowed.label);
       e = find_edge (src, dst);
       if (e == NULL)
 	{
diff --git a/gcc/tree-ssa-dom.c b/gcc/tree-ssa-dom.c
index 267880f3b5c..7430fd7e706 100644
--- a/gcc/tree-ssa-dom.c
+++ b/gcc/tree-ssa-dom.c
@@ -436,7 +436,8 @@ record_edge_info (basic_block bb)
 	      for (i = 0; i < n_labels; i++)
 		{
 		  tree label = gimple_switch_label (switch_stmt, i);
-		  basic_block target_bb = label_to_block (CASE_LABEL (label));
+		  basic_block target_bb
+		    = label_to_block (cfun, CASE_LABEL (label));
 		  if (CASE_HIGH (label)
 		      || !CASE_LOW (label)
 		      || info[target_bb->index])
diff --git a/gcc/tree-ssa-forwprop.c b/gcc/tree-ssa-forwprop.c
index 56078110b39..4ed61c37a5f 100644
--- a/gcc/tree-ssa-forwprop.c
+++ b/gcc/tree-ssa-forwprop.c
@@ -1071,7 +1071,7 @@ simplify_gimple_switch_label_vec (gswitch *stmt, tree index_type)
       for (i = 0; i < gimple_switch_num_labels (stmt); i++)
 	{
 	  tree elt = gimple_switch_label (stmt, i);
-	  basic_block target = label_to_block (CASE_LABEL (elt));
+	  basic_block target = label_to_block (cfun, CASE_LABEL (elt));
 	  bitmap_set_bit (target_blocks, target->index);
 	}
       for (ei = ei_start (gimple_bb (stmt)->succs); (e = ei_safe_edge (ei)); )
diff --git a/gcc/tree-ssa-threadedge.c b/gcc/tree-ssa-threadedge.c
index dbc0bbd772a..a2304493495 100644
--- a/gcc/tree-ssa-threadedge.c
+++ b/gcc/tree-ssa-threadedge.c
@@ -977,7 +977,7 @@ thread_around_empty_blocks (edge taken_edge,
 	  || TREE_CODE (cond) == CASE_LABEL_EXPR))
     {
       if (TREE_CODE (cond) == CASE_LABEL_EXPR)
-	taken_edge = find_edge (bb, label_to_block (CASE_LABEL (cond)));
+	taken_edge = find_edge (bb, label_to_block (cfun, CASE_LABEL (cond)));
       else
 	taken_edge = find_taken_edge (bb, cond);
 
@@ -1109,7 +1109,7 @@ thread_through_normal_block (edge e,
 	  edge taken_edge;
 	  if (TREE_CODE (cond) == CASE_LABEL_EXPR)
 	    taken_edge = find_edge (e->dest,
-				    label_to_block (CASE_LABEL (cond)));
+				    label_to_block (cfun, CASE_LABEL (cond)));
 	  else
 	    taken_edge = find_taken_edge (e->dest, cond);
 
diff --git a/gcc/tree-ssa-uncprop.c b/gcc/tree-ssa-uncprop.c
index 7d863a71551..98cc79e8607 100644
--- a/gcc/tree-ssa-uncprop.c
+++ b/gcc/tree-ssa-uncprop.c
@@ -184,7 +184,7 @@ associate_equivalences_with_edges (void)
 	      for (i = 0; i < n_labels; i++)
 		{
 		  tree label = gimple_switch_label (switch_stmt, i);
-		  basic_block bb = label_to_block (CASE_LABEL (label));
+		  basic_block bb = label_to_block (cfun, CASE_LABEL (label));
 
 		  if (CASE_HIGH (label)
 		      || !CASE_LOW (label)
diff --git a/gcc/tree-ssa-uninit.c b/gcc/tree-ssa-uninit.c
index a93610084f2..f3e42ddbd7f 100644
--- a/gcc/tree-ssa-uninit.c
+++ b/gcc/tree-ssa-uninit.c
@@ -725,7 +725,7 @@ convert_control_dep_chain_into_preds (vec<edge> *dep_chains,
 	      for (idx = 0; idx < gimple_switch_num_labels (gs); ++idx)
 		{
 		  tree tl = gimple_switch_label (gs, idx);
-		  if (e->dest == label_to_block (CASE_LABEL (tl)))
+		  if (e->dest == label_to_block (cfun, CASE_LABEL (tl)))
 		    {
 		      if (!l)
 			l = tl;
diff --git a/gcc/tree-switch-conversion.c b/gcc/tree-switch-conversion.c
index 9a594a01fc4..684fdd0583a 100644
--- a/gcc/tree-switch-conversion.c
+++ b/gcc/tree-switch-conversion.c
@@ -78,7 +78,6 @@ switch_conversion::collect (gswitch *swtch)
   unsigned int i;
   edge e, e_default, e_first;
   edge_iterator ei;
-  basic_block first;
 
   m_switch = swtch;
 
@@ -87,9 +86,8 @@ switch_conversion::collect (gswitch *swtch)
      Collect the bits we can deduce from the CFG.  */
   m_index_expr = gimple_switch_index (swtch);
   m_switch_bb = gimple_bb (swtch);
-  m_default_bb
-    = label_to_block (CASE_LABEL (gimple_switch_default_label (swtch)));
-  e_default = find_edge (m_switch_bb, m_default_bb);
+  e_default = gimple_switch_default_edge (swtch);
+  m_default_bb = e_default->dest;
   m_default_prob = e_default->probability;
   m_default_count = e_default->count ();
   FOR_EACH_EDGE (e, ei, m_switch_bb->succs)
@@ -120,15 +118,9 @@ switch_conversion::collect (gswitch *swtch)
     }
 
   if (m_contiguous_range)
-    {
-      first = label_to_block (CASE_LABEL (gimple_switch_label (swtch, 1)));
-      e_first = find_edge (m_switch_bb, first);
-    }
+    e_first = gimple_switch_edge (swtch, 1);
   else
-    {
-      first = m_default_bb;
-      e_first = e_default;
-    }
+    e_first = e_default;
 
   /* See if there is one common successor block for all branch
      targets.  If it exists, record it in FINAL_BB.
@@ -306,8 +298,7 @@ switch_conversion::check_final_bb ()
 		  unsigned int branch_num = gimple_switch_num_labels (m_switch);
 		  for (unsigned int i = 1; i < branch_num; i++)
 		    {
-		      tree lab = CASE_LABEL (gimple_switch_label (m_switch, i));
-		      if (label_to_block (lab) == bb)
+		      if (gimple_switch_bb (m_switch, i) == bb)
 			{
 			  m_reason = reason;
 			  return false;
@@ -351,7 +342,7 @@ void
 switch_conversion::gather_default_values (tree default_case)
 {
   gphi_iterator gsi;
-  basic_block bb = label_to_block (CASE_LABEL (default_case));
+  basic_block bb = label_to_block (cfun, CASE_LABEL (default_case));
   edge e;
   int i = 0;
 
@@ -388,7 +379,7 @@ switch_conversion::build_constructors ()
   for (i = 1; i < branch_num; i++)
     {
       tree cs = gimple_switch_label (m_switch, i);
-      basic_block bb = label_to_block (CASE_LABEL (cs));
+      basic_block bb = label_to_block (cfun, CASE_LABEL (cs));
       edge e;
       tree high;
       gphi_iterator gsi;
@@ -1577,15 +1568,11 @@ bit_test_cluster::hoist_edge_and_branch_if_true (gimple_stmt_iterator *gsip,
 void
 switch_decision_tree::compute_cases_per_edge ()
 {
-  basic_block bb = gimple_bb (m_switch);
   reset_out_edges_aux ();
   int ncases = gimple_switch_num_labels (m_switch);
   for (int i = ncases - 1; i >= 1; --i)
     {
-      tree elt = gimple_switch_label (m_switch, i);
-      tree lab = CASE_LABEL (elt);
-      basic_block case_bb = label_to_block_fn (cfun, lab);
-      edge case_edge = find_edge (bb, case_bb);
+      edge case_edge = gimple_switch_edge (m_switch, i);
       case_edge->aux = (void *) ((intptr_t) (case_edge->aux) + 1);
     }
 }
@@ -1601,8 +1588,7 @@ switch_decision_tree::analyze_switch_statement ()
   auto_vec<cluster *> clusters;
   clusters.create (l - 1);
 
-  tree default_label = CASE_LABEL (gimple_switch_default_label (m_switch));
-  basic_block default_bb = label_to_block_fn (cfun, default_label);
+  basic_block default_bb = gimple_switch_default_bb (m_switch);
   m_case_bbs.reserve (l);
   m_case_bbs.quick_push (default_bb);
 
@@ -1612,15 +1598,16 @@ switch_decision_tree::analyze_switch_statement ()
     {
       tree elt = gimple_switch_label (m_switch, i);
       tree lab = CASE_LABEL (elt);
-      basic_block case_bb = label_to_block_fn (cfun, lab);
+      basic_block case_bb = label_to_block (cfun, lab);
       edge case_edge = find_edge (bb, case_bb);
       tree low = CASE_LOW (elt);
       tree high = CASE_HIGH (elt);
 
       profile_probability p
 	= case_edge->probability.apply_scale (1, (intptr_t) (case_edge->aux));
-      clusters.quick_push (new simple_cluster (low, high, elt, case_bb, p));
-      m_case_bbs.quick_push (case_bb);
+      clusters.quick_push (new simple_cluster (low, high, elt, case_edge->dest,
+					       p));
+      m_case_bbs.quick_push (case_edge->dest);
     }
 
   reset_out_edges_aux ();
@@ -1694,9 +1681,8 @@ switch_decision_tree::try_switch_expansion (vec<cluster *> &clusters)
     return false;
 
   /* Find the default case target label.  */
-  tree default_label_expr = CASE_LABEL (gimple_switch_default_label (m_switch));
-  m_default_bb = label_to_block_fn (cfun, default_label_expr);
-  edge default_edge = find_edge (bb, m_default_bb);
+  edge default_edge = gimple_switch_default_edge (m_switch);
+  m_default_bb = default_edge->dest;
 
   /* Do the insertion of a case label into m_case_list.  The labels are
      fed to us in descending order from the sorted vector of case labels used
diff --git a/gcc/tree-vrp.c b/gcc/tree-vrp.c
index f20730a85ba..e8eb9292506 100644
--- a/gcc/tree-vrp.c
+++ b/gcc/tree-vrp.c
@@ -3474,7 +3474,7 @@ find_switch_asserts (basic_block bb, gswitch *last)
   for (idx = 0; idx < n; ++idx)
     {
       ci[idx].expr = gimple_switch_label (last, idx);
-      ci[idx].bb = label_to_block (CASE_LABEL (ci[idx].expr));
+      ci[idx].bb = label_to_block (cfun, CASE_LABEL (ci[idx].expr));
     }
   edge default_edge = find_edge (bb, ci[0].bb);
   qsort (ci, n, sizeof (struct case_info), compare_case_labels);
diff --git a/gcc/vr-values.c b/gcc/vr-values.c
index 072d9a7b454..11df1023b6e 100644
--- a/gcc/vr-values.c
+++ b/gcc/vr-values.c
@@ -2707,7 +2707,7 @@ vr_values::vrp_visit_switch_stmt (gswitch *stmt, edge *taken_edge_p)
     }
 
   *taken_edge_p = find_edge (gimple_bb (stmt),
-			     label_to_block (CASE_LABEL (val)));
+			     label_to_block (cfun, CASE_LABEL (val)));
 
   if (dump_file && (dump_flags & TDF_DETAILS))
     {
@@ -3760,7 +3760,8 @@ vr_values::simplify_switch_using_ranges (gswitch *stmt)
   for (i = 0; i < n2; ++i)
     {
       e = find_edge (gimple_bb (stmt),
-		     label_to_block (CASE_LABEL (TREE_VEC_ELT (vec2, i))));
+		     label_to_block (cfun,
+				     CASE_LABEL (TREE_VEC_ELT (vec2, i))));
       e->aux = (void *)-1;
     }
Richard Biener Aug. 27, 2018, 10 a.m. UTC | #6
On Mon, Aug 27, 2018 at 10:43 AM Martin Liška <mliska@suse.cz> wrote:
>
> On 08/27/2018 09:56 AM, Richard Biener wrote:
> > On Mon, Aug 27, 2018 at 9:13 AM Martin Liška <mliska@suse.cz> wrote:
> >>
> >> Hi.
> >>
> >> There's updated version with notes that were discussed with Richi
> >> on IRC. As pointed out label_to_block can potentially lead to
> >> quadratic complexity, but it's not ambition of the patch to resolve
> >> that.
> >
> > Please don't
> >
> > @@ -3239,7 +3239,7 @@ expand_asm_stmt (gasm *stmt)
> >              may insert further instructions into the same basic block after
> >              asm goto and if we don't do this, insertion of instructions on
> >              the fallthru edge might misbehave.  See PR58670.  */
> > -         if (fallthru_bb && label_to_block_fn (cfun, label) == fallthru_bb)
> > +         if (fallthru_bb && label_to_block (label) == fallthru_bb)
> >             {
> >               if (fallthru_label == NULL_RTX)
> >                 fallthru_label = gen_label_rtx ();
> >
> > rather the label_to_block function should go away.  OK with removing any
> > such instances in the patch.
> >
> > Richard.
> >
> >> Martin
>
> Ok, I'm sending one more version where I completely removed label_to_block_fn.
> Richi, out of the modified function, which would be subject for introduction
> of a new argument (struct *function)?

Esp. gimple_switch_bb would be ... also, sorry for noticing so late,
gimple_switch_bb
awfully sounds like gimple_bb which means better call it
gimple_switch_label_bb ()?

Note doing both things in one patch (adding your wrappers) and cleaning up
label_to_block isn't necessary (but I have no issue with that).

So - may I ask you for a) change name to gimple_switch_label_bb b) add a
cfun argument to this function?

To your last question, it's most of the time easy to look up the call chain for
static functions and you'll find a function that is called with struct
function *.
When I(?) added label_to_block_fn I did so for the places I "cleaned up", so
it would be nice to not introduce cfun references where it's easy to avoid.
From a quick look important cases seem to be
 - set_switch_stmt_execution_predicate
 - find_taken_edge_switch_expr (and thus callers)
 - gimple_redirect_edge_and_branch
 - gimple_switch_label_bb

in most passes using cfun should be "easy" to avoid by passing down
the struct function arg from the pass execute() method but that's a bit
tedious and IMHO not too important.

You'll notice that in GIMPLE / CFG infrastructure one of the ugly facts
is that there's no way to go from a basic-block to the containing
struct function.

Thanks,
Richard.

>
> Martin
Martin Liška Aug. 27, 2018, 12:10 p.m. UTC | #7
On 08/27/2018 12:00 PM, Richard Biener wrote:
> On Mon, Aug 27, 2018 at 10:43 AM Martin Liška <mliska@suse.cz> wrote:
>>
>> On 08/27/2018 09:56 AM, Richard Biener wrote:
>>> On Mon, Aug 27, 2018 at 9:13 AM Martin Liška <mliska@suse.cz> wrote:
>>>>
>>>> Hi.
>>>>
>>>> There's updated version with notes that were discussed with Richi
>>>> on IRC. As pointed out label_to_block can potentially lead to
>>>> quadratic complexity, but it's not ambition of the patch to resolve
>>>> that.
>>>
>>> Please don't
>>>
>>> @@ -3239,7 +3239,7 @@ expand_asm_stmt (gasm *stmt)
>>>              may insert further instructions into the same basic block after
>>>              asm goto and if we don't do this, insertion of instructions on
>>>              the fallthru edge might misbehave.  See PR58670.  */
>>> -         if (fallthru_bb && label_to_block_fn (cfun, label) == fallthru_bb)
>>> +         if (fallthru_bb && label_to_block (label) == fallthru_bb)
>>>             {
>>>               if (fallthru_label == NULL_RTX)
>>>                 fallthru_label = gen_label_rtx ();
>>>
>>> rather the label_to_block function should go away.  OK with removing any
>>> such instances in the patch.
>>>
>>> Richard.
>>>
>>>> Martin
>>
>> Ok, I'm sending one more version where I completely removed label_to_block_fn.
>> Richi, out of the modified function, which would be subject for introduction
>> of a new argument (struct *function)?
> 
> Esp. gimple_switch_bb would be ... also, sorry for noticing so late,
> gimple_switch_bb
> awfully sounds like gimple_bb which means better call it
> gimple_switch_label_bb ()?

Good, done that.

> 
> Note doing both things in one patch (adding your wrappers) and cleaning up
> label_to_block isn't necessary (but I have no issue with that).
> 
> So - may I ask you for a) change name to gimple_switch_label_bb b) add a
> cfun argument to this function?

Done that and sending updated version of that patch. I'm going to install for
now.

> 
> To your last question, it's most of the time easy to look up the call chain for
> static functions and you'll find a function that is called with struct
> function *.
> When I(?) added label_to_block_fn I did so for the places I "cleaned up", so
> it would be nice to not introduce cfun references where it's easy to avoid.
> From a quick look important cases seem to be
>  - set_switch_stmt_execution_predicate
>  - find_taken_edge_switch_expr (and thus callers)
>  - gimple_redirect_edge_and_branch
>  - gimple_switch_label_bb
> 
> in most passes using cfun should be "easy" to avoid by passing down
> the struct function arg from the pass execute() method but that's a bit
> tedious and IMHO not too important.

Ok, so if it's tedious, I'm leaving that.

Martin

> 
> You'll notice that in GIMPLE / CFG infrastructure one of the ugly facts
> is that there's no way to go from a basic-block to the containing
> struct function.
> 
> Thanks,
> Richard.
> 
>>
>> Martin
From 8410a46301056a2f39b785ed715df27c32a47c99 Mon Sep 17 00:00:00 2001
From: marxin <mliska@suse.cz>
Date: Fri, 3 Aug 2018 14:54:32 +0200
Subject: [PATCH] Add new gswitch related functions into tree-cfg.c.

gcc/ChangeLog:

2018-08-27  Martin Liska  <mliska@suse.cz>

	* cfgexpand.c (expand_asm_stmt): Use label_to_block and pass
        cfun argument explicitly.
	* gimple-pretty-print.c (dump_gimple_switch): Likewise.
	* hsa-gen.c (gen_hsa_insns_for_switch_stmt): Use new
        function gimple_switch_default_bb.
	(convert_switch_statements):
	(expand_builtins):
	* ipa-fnsummary.c (set_switch_stmt_execution_predicate):
	* stmt.c (label_to_block_fn): Use label_to_block and pass
        cfun argument explicitly and use gimple_switch_label_bb.
	(expand_case): Likewise.
	* tree-cfg.c (lower_phi_internal_fn): Use label_to_block and pass
        cfun argument explicitly. Likewise.
	(make_edges_bb): Likewise.
	(make_cond_expr_edges): Likewise.
	(get_cases_for_edge): Likewise.
	(make_gimple_switch_edges): Likewise.
	(label_to_block_fn): Likewise.
	(label_to_block): Likewise.
	(make_goto_expr_edges): Likewise.
	(make_gimple_asm_edges): Likewise.
	(main_block_label): Likewise.
	(group_case_labels_stmt): Likewise.
	(find_taken_edge_computed_goto): Likewise.
	(find_taken_edge_switch_expr): Likewise.
	(gimple_verify_flow_info): Likewise.
	(gimple_redirect_edge_and_branch): Likewise.
	(gimple_switch_label_bb): New function.
	(gimple_switch_default_bb): Likewise.
	(gimple_switch_edge): Likewise.
	(gimple_switch_default_edge): Likewise.
	* tree-cfg.h (label_to_block_fn): Remove and replace ...
	(label_to_block): ... with this.
	(gimple_switch_label_bb): New.
	(gimple_switch_default_bb): Likewise.
	(gimple_switch_edge): Likewise.
	(gimple_switch_default_edge): Likewise.
	* tree-cfgcleanup.c (convert_single_case_switch): Use
        new gimple functions and pass new argument to label_to_block.
	(cleanup_control_flow_bb):
	* tree-eh.c (make_eh_dispatch_edges): Use label_to_block and pass
        cfun argument explicitly.
	(make_eh_edges): Likewise.
	(redirect_eh_dispatch_edge): Likewise.
	(lower_resx): Likewise.
	(lower_eh_dispatch): Likewise.
	(maybe_remove_unreachable_handlers): Likewise.
	(unsplit_eh): Likewise.
	(cleanup_empty_eh): Likewise.
	(verify_eh_edges): Likewise.
	(verify_eh_dispatch_edge): Likewise.
	* tree-ssa-dom.c (record_edge_info): Likewise.
	* tree-ssa-forwprop.c (simplify_gimple_switch_label_vec): Likewise.
	* tree-ssa-threadedge.c (thread_around_empty_blocks): Likewise.
	(thread_through_normal_block): Likewise.
	* tree-ssa-uncprop.c (associate_equivalences_with_edges): Likewise.
	* tree-ssa-uninit.c (convert_control_dep_chain_into_preds):
	* tree-switch-conversion.c (switch_conversion::collect): Use new
        gimple functions.
	(switch_conversion::check_final_bb): Likewise.
	(switch_conversion::gather_default_values): Pass new argument
        to label_to_block.
	(switch_conversion::build_constructors): Likewise.
	(switch_decision_tree::compute_cases_per_edge): Use new
        gimple_switch_edge function.
	(switch_decision_tree::analyze_switch_statement): Pass new argument
        to label_to_block.
	(switch_decision_tree::try_switch_expansion): Use
        gimple_switch_default_edge.
	* tree-vrp.c (find_switch_asserts): Pass new argument
        to label_to_block.
	* vr-values.c (vr_values::vrp_visit_switch_stmt): Likewise.
	(vr_values::simplify_switch_using_ranges): Likewise.
---
 gcc/cfgexpand.c              |  2 +-
 gcc/gimple-pretty-print.c    |  2 +-
 gcc/hsa-gen.c                | 21 +++------
 gcc/ipa-fnsummary.c          |  2 +-
 gcc/stmt.c                   |  4 +-
 gcc/tree-cfg.c               | 83 +++++++++++++++++++++++++-----------
 gcc/tree-cfg.h               |  7 ++-
 gcc/tree-cfgcleanup.c        |  7 ++-
 gcc/tree-eh.c                | 26 +++++------
 gcc/tree-ssa-dom.c           |  3 +-
 gcc/tree-ssa-forwprop.c      |  2 +-
 gcc/tree-ssa-threadedge.c    |  4 +-
 gcc/tree-ssa-uncprop.c       |  2 +-
 gcc/tree-ssa-uninit.c        |  2 +-
 gcc/tree-switch-conversion.c | 44 +++++++------------
 gcc/tree-vrp.c               |  2 +-
 gcc/vr-values.c              |  5 ++-
 17 files changed, 116 insertions(+), 102 deletions(-)

diff --git a/gcc/cfgexpand.c b/gcc/cfgexpand.c
index 3c5b30b79f8..647764b0e94 100644
--- a/gcc/cfgexpand.c
+++ b/gcc/cfgexpand.c
@@ -3239,7 +3239,7 @@ expand_asm_stmt (gasm *stmt)
 	     may insert further instructions into the same basic block after
 	     asm goto and if we don't do this, insertion of instructions on
 	     the fallthru edge might misbehave.  See PR58670.  */
-	  if (fallthru_bb && label_to_block_fn (cfun, label) == fallthru_bb)
+	  if (fallthru_bb && label_to_block (cfun, label) == fallthru_bb)
 	    {
 	      if (fallthru_label == NULL_RTX)
 	        fallthru_label = gen_label_rtx ();
diff --git a/gcc/gimple-pretty-print.c b/gcc/gimple-pretty-print.c
index d3c5ec6f79b..dd63a28761b 100644
--- a/gcc/gimple-pretty-print.c
+++ b/gcc/gimple-pretty-print.c
@@ -992,7 +992,7 @@ dump_gimple_switch (pretty_printer *buffer, gswitch *gs, int spc,
 
       if (cfun && cfun->cfg)
 	{
-	  basic_block dest = label_to_block (label);
+	  basic_block dest = label_to_block (cfun, label);
 	  if (dest)
 	    {
 	      edge label_edge = find_edge (gimple_bb (gs), dest);
diff --git a/gcc/hsa-gen.c b/gcc/hsa-gen.c
index 6595bedac82..416de933a22 100644
--- a/gcc/hsa-gen.c
+++ b/gcc/hsa-gen.c
@@ -3475,7 +3475,6 @@ gen_hsa_insns_for_switch_stmt (gswitch *s, hsa_bb *hbb)
   e->flags &= ~EDGE_FALLTHRU;
   e->flags |= EDGE_TRUE_VALUE;
 
-  function *func = DECL_STRUCT_FUNCTION (current_function_decl);
   tree index_tree = gimple_switch_index (s);
   tree lowest = get_switch_low (s);
   tree highest = get_switch_high (s);
@@ -3499,9 +3498,7 @@ gen_hsa_insns_for_switch_stmt (gswitch *s, hsa_bb *hbb)
 
   hbb->append_insn (new hsa_insn_cbr (cmp_reg));
 
-  tree default_label = gimple_switch_default_label (s);
-  basic_block default_label_bb = label_to_block_fn (func,
-						    CASE_LABEL (default_label));
+  basic_block default_label_bb = gimple_switch_default_bb (cfun, s);
 
   if (!gimple_seq_empty_p (phi_nodes (default_label_bb)))
     {
@@ -3536,7 +3533,7 @@ gen_hsa_insns_for_switch_stmt (gswitch *s, hsa_bb *hbb)
   for (unsigned i = 1; i < labels; i++)
     {
       tree label = gimple_switch_label (s, i);
-      basic_block bb = label_to_block_fn (func, CASE_LABEL (label));
+      basic_block bb = label_to_block (cfun, CASE_LABEL (label));
 
       unsigned HOST_WIDE_INT sub_low
 	= tree_to_uhwi (int_const_binop (MINUS_EXPR, CASE_LOW (label), lowest));
@@ -6290,12 +6287,11 @@ LD:    hard_work_3 ();
 static bool
 convert_switch_statements (void)
 {
-  function *func = DECL_STRUCT_FUNCTION (current_function_decl);
   basic_block bb;
 
   bool modified_cfg = false;
 
-  FOR_EACH_BB_FN (bb, func)
+  FOR_EACH_BB_FN (bb, cfun)
   {
     gimple_stmt_iterator gsi = gsi_last_bb (bb);
     if (gsi_end_p (gsi))
@@ -6318,7 +6314,7 @@ convert_switch_statements (void)
 	tree index_type = TREE_TYPE (index);
 	tree default_label = gimple_switch_default_label (s);
 	basic_block default_label_bb
-	  = label_to_block_fn (func, CASE_LABEL (default_label));
+	  = label_to_block (cfun, CASE_LABEL (default_label));
 	basic_block cur_bb = bb;
 
 	auto_vec <edge> new_edges;
@@ -6330,8 +6326,7 @@ convert_switch_statements (void)
 	   should be fixed after we add new collection of edges.  */
 	for (unsigned i = 0; i < labels; i++)
 	  {
-	    tree label = gimple_switch_label (s, i);
-	    basic_block label_bb = label_to_block_fn (func, CASE_LABEL (label));
+	    basic_block label_bb = gimple_switch_label_bb (cfun, s, i);
 	    edge e = find_edge (bb, label_bb);
 	    edge_counts.safe_push (e->count ());
 	    edge_probabilities.safe_push (e->probability);
@@ -6413,8 +6408,7 @@ convert_switch_statements (void)
 
 	    gsi_insert_before (&cond_gsi, c, GSI_SAME_STMT);
 
-	    basic_block label_bb
-	      = label_to_block_fn (func, CASE_LABEL (label));
+	    basic_block label_bb = label_to_block (cfun, CASE_LABEL (label));
 	    edge new_edge = make_edge (cur_bb, label_bb, EDGE_TRUE_VALUE);
 	    profile_probability prob_sum = sum_slice <profile_probability>
 		 (edge_probabilities, i, labels, profile_probability::never ())
@@ -6481,10 +6475,9 @@ convert_switch_statements (void)
 static void
 expand_builtins ()
 {
-  function *func = DECL_STRUCT_FUNCTION (current_function_decl);
   basic_block bb;
 
-  FOR_EACH_BB_FN (bb, func)
+  FOR_EACH_BB_FN (bb, cfun)
   {
     for (gimple_stmt_iterator gsi = gsi_start_bb (bb); !gsi_end_p (gsi);
 	 gsi_next (&gsi))
diff --git a/gcc/ipa-fnsummary.c b/gcc/ipa-fnsummary.c
index a8fc2c2df9a..d8311d25ab2 100644
--- a/gcc/ipa-fnsummary.c
+++ b/gcc/ipa-fnsummary.c
@@ -1291,7 +1291,7 @@ set_switch_stmt_execution_predicate (struct ipa_func_body_info *fbi,
       tree min, max;
       predicate p;
 
-      e = find_edge (bb, label_to_block (CASE_LABEL (cl)));
+      e = gimple_switch_edge (cfun, last, case_idx);
       min = CASE_LOW (cl);
       max = CASE_HIGH (cl);
 
diff --git a/gcc/stmt.c b/gcc/stmt.c
index b8df1818137..07355984de1 100644
--- a/gcc/stmt.c
+++ b/gcc/stmt.c
@@ -81,8 +81,6 @@ struct simple_case_node
   /* Label to jump to when node matches.  */
   tree m_code_label;
 };
-
-extern basic_block label_to_block_fn (struct function *, tree);
 
 static bool check_unique_operand_names (tree, tree, tree);
 static char *resolve_operand_name_1 (char *, tree, tree, tree);
@@ -907,7 +905,7 @@ expand_case (gswitch *stmt)
   /* Find the default case target label.  */
   tree default_lab = CASE_LABEL (gimple_switch_default_label (stmt));
   default_label = jump_target_rtx (default_lab);
-  basic_block default_bb = label_to_block_fn (cfun, default_lab);
+  basic_block default_bb = label_to_block (cfun, default_lab);
   edge default_edge = find_edge (bb, default_bb);
 
   /* Get upper and lower bounds of case values.  */
diff --git a/gcc/tree-cfg.c b/gcc/tree-cfg.c
index 463dd8a3bf9..b021fb0f97b 100644
--- a/gcc/tree-cfg.c
+++ b/gcc/tree-cfg.c
@@ -389,7 +389,7 @@ lower_phi_internal_fn ()
 	    {
 	      tree arg = gimple_call_arg (stmt, i);
 	      if (TREE_CODE (arg) == LABEL_DECL)
-		pred = label_to_block (arg);
+		pred = label_to_block (cfun, arg);
 	      else
 		{
 		  edge e = find_edge (pred, bb);
@@ -972,15 +972,15 @@ make_edges_bb (basic_block bb, struct omp_region **pcur_region, int *pomp_index)
 	tree label2 = gimple_transaction_label_uninst (txn);
 
 	if (label1)
-	  make_edge (bb, label_to_block (label1), EDGE_FALLTHRU);
+	  make_edge (bb, label_to_block (cfun, label1), EDGE_FALLTHRU);
 	if (label2)
-	  make_edge (bb, label_to_block (label2),
+	  make_edge (bb, label_to_block (cfun, label2),
 		     EDGE_TM_UNINSTRUMENTED | (label1 ? 0 : EDGE_FALLTHRU));
 
 	tree label3 = gimple_transaction_label_over (txn);
 	if (gimple_transaction_subcode (txn)
 	    & (GTMA_HAVE_ABORT | GTMA_IS_OUTER))
-	  make_edge (bb, label_to_block (label3), EDGE_TM_ABORT);
+	  make_edge (bb, label_to_block (cfun, label3), EDGE_TM_ABORT);
 
 	fallthru = false;
       }
@@ -1265,8 +1265,8 @@ make_cond_expr_edges (basic_block bb)
   /* Entry basic blocks for each component.  */
   then_label = gimple_cond_true_label (entry);
   else_label = gimple_cond_false_label (entry);
-  then_bb = label_to_block (then_label);
-  else_bb = label_to_block (else_label);
+  then_bb = label_to_block (cfun, then_label);
+  else_bb = label_to_block (cfun, else_label);
   then_stmt = first_stmt (then_bb);
   else_stmt = first_stmt (else_bb);
 
@@ -1373,7 +1373,7 @@ get_cases_for_edge (edge e, gswitch *t)
     {
       tree elt = gimple_switch_label (t, i);
       tree lab = CASE_LABEL (elt);
-      basic_block label_bb = label_to_block (lab);
+      basic_block label_bb = label_to_block (cfun, lab);
       edge this_edge = find_edge (e->src, label_bb);
 
       /* Add it to the chain of CASE_LABEL_EXPRs referencing E, or create
@@ -1397,8 +1397,7 @@ make_gimple_switch_edges (gswitch *entry, basic_block bb)
 
   for (i = 0; i < n; ++i)
     {
-      tree lab = CASE_LABEL (gimple_switch_label (entry, i));
-      basic_block label_bb = label_to_block (lab);
+      basic_block label_bb = gimple_switch_label_bb (cfun, entry, i);
       make_edge (bb, label_bb, 0);
     }
 }
@@ -1407,7 +1406,7 @@ make_gimple_switch_edges (gswitch *entry, basic_block bb)
 /* Return the basic block holding label DEST.  */
 
 basic_block
-label_to_block_fn (struct function *ifun, tree dest)
+label_to_block (struct function *ifun, tree dest)
 {
   int uid = LABEL_DECL_UID (dest);
 
@@ -1442,7 +1441,7 @@ make_goto_expr_edges (basic_block bb)
   if (simple_goto_p (goto_t))
     {
       tree dest = gimple_goto_dest (goto_t);
-      basic_block label_bb = label_to_block (dest);
+      basic_block label_bb = label_to_block (cfun, dest);
       edge e = make_edge (bb, label_bb, EDGE_FALLTHRU);
       e->goto_locus = gimple_location (goto_t);
       gsi_remove (&last, true);
@@ -1464,7 +1463,7 @@ make_gimple_asm_edges (basic_block bb)
   for (i = 0; i < n; ++i)
     {
       tree label = TREE_VALUE (gimple_asm_label_op (stmt, i));
-      basic_block label_bb = label_to_block (label);
+      basic_block label_bb = label_to_block (cfun, label);
       make_edge (bb, label_bb, 0);
     }
 }
@@ -1496,7 +1495,7 @@ static struct label_record
 static tree
 main_block_label (tree label)
 {
-  basic_block bb = label_to_block (label);
+  basic_block bb = label_to_block (cfun, label);
   tree main_label = label_for_bb[bb->index].label;
 
   /* label_to_block possibly inserted undefined label into the chain.  */
@@ -1773,7 +1772,7 @@ group_case_labels_stmt (gswitch *stmt)
   int i, next_index, new_size;
   basic_block default_bb = NULL;
 
-  default_bb = label_to_block (CASE_LABEL (gimple_switch_default_label (stmt)));
+  default_bb = gimple_switch_default_bb (cfun, stmt);
 
   /* Look for possible opportunities to merge cases.  */
   new_size = i = 1;
@@ -1785,7 +1784,7 @@ group_case_labels_stmt (gswitch *stmt)
       base_case = gimple_switch_label (stmt, i);
 
       gcc_assert (base_case);
-      base_bb = label_to_block (CASE_LABEL (base_case));
+      base_bb = label_to_block (cfun, CASE_LABEL (base_case));
 
       /* Discard cases that have the same destination as the default case or
 	 whose destiniation blocks have already been removed as unreachable.  */
@@ -1806,7 +1805,7 @@ group_case_labels_stmt (gswitch *stmt)
       while (next_index < old_size)
 	{
 	  tree merge_case = gimple_switch_label (stmt, next_index);
-	  basic_block merge_bb = label_to_block (CASE_LABEL (merge_case));
+	  basic_block merge_bb = label_to_block (cfun, CASE_LABEL (merge_case));
 	  wide_int bhp1 = wi::to_wide (base_high) + 1;
 
 	  /* Merge the cases if they jump to the same place,
@@ -2387,7 +2386,7 @@ find_taken_edge_computed_goto (basic_block bb, tree val)
   basic_block dest;
   edge e = NULL;
 
-  dest = label_to_block (val);
+  dest = label_to_block (cfun, val);
   if (dest)
     e = find_edge (bb, dest);
 
@@ -2455,7 +2454,7 @@ find_taken_edge_switch_expr (const gswitch *switch_stmt, tree val)
       else
 	taken_case = find_case_label_for_value (switch_stmt, val);
     }
-  dest_bb = label_to_block (CASE_LABEL (taken_case));
+  dest_bb = label_to_block (cfun, CASE_LABEL (taken_case));
 
   e = find_edge (gimple_bb (switch_stmt), dest_bb);
   gcc_assert (e);
@@ -5498,7 +5497,7 @@ gimple_verify_flow_info (void)
 	      err = 1;
 	    }
 
-	  if (label_to_block (label) != bb)
+	  if (label_to_block (cfun, label) != bb)
 	    {
 	      error ("label ");
 	      print_generic_expr (stderr, label);
@@ -5655,8 +5654,7 @@ gimple_verify_flow_info (void)
 	    /* Mark all the destination basic blocks.  */
 	    for (i = 0; i < n; ++i)
 	      {
-		tree lab = CASE_LABEL (gimple_switch_label (switch_stmt, i));
-		basic_block label_bb = label_to_block (lab);
+		basic_block label_bb = gimple_switch_label_bb (cfun, switch_stmt, i);
 		gcc_assert (!label_bb->aux || label_bb->aux == (void *)1);
 		label_bb->aux = (void *)1;
 	      }
@@ -5711,8 +5709,8 @@ gimple_verify_flow_info (void)
 	    /* Check that we have all of them.  */
 	    for (i = 0; i < n; ++i)
 	      {
-		tree lab = CASE_LABEL (gimple_switch_label (switch_stmt, i));
-		basic_block label_bb = label_to_block (lab);
+		basic_block label_bb = gimple_switch_label_bb (cfun,
+							       switch_stmt, i);
 
 		if (label_bb->aux != (void *)2)
 		  {
@@ -5936,7 +5934,7 @@ gimple_redirect_edge_and_branch (edge e, basic_block dest)
 	    for (i = 0; i < n; i++)
 	      {
 		tree elt = gimple_switch_label (switch_stmt, i);
-		if (label_to_block (CASE_LABEL (elt)) == e->dest)
+		if (label_to_block (cfun, CASE_LABEL (elt)) == e->dest)
 		  CASE_LABEL (elt) = label;
 	      }
 	  }
@@ -5952,7 +5950,7 @@ gimple_redirect_edge_and_branch (edge e, basic_block dest)
 	for (i = 0; i < n; ++i)
 	  {
 	    tree cons = gimple_asm_label_op (asm_stmt, i);
-	    if (label_to_block (TREE_VALUE (cons)) == e->dest)
+	    if (label_to_block (cfun, TREE_VALUE (cons)) == e->dest)
 	      {
 		if (!label)
 		  label = gimple_block_label (dest);
@@ -9143,6 +9141,41 @@ generate_range_test (basic_block bb, tree index, tree low, tree high,
   gsi_insert_seq_before (&gsi, seq, GSI_SAME_STMT);
 }
 
+/* Return the basic block that belongs to label numbered INDEX
+   of a switch statement.  */
+
+basic_block
+gimple_switch_label_bb (function *ifun, gswitch *gs, unsigned index)
+{
+  return label_to_block (ifun, CASE_LABEL (gimple_switch_label (gs, index)));
+}
+
+/* Return the default basic block of a switch statement.  */
+
+basic_block
+gimple_switch_default_bb (function *ifun, gswitch *gs)
+{
+  return gimple_switch_label_bb (ifun, gs, 0);
+}
+
+/* Return the edge that belongs to label numbered INDEX
+   of a switch statement.  */
+
+edge
+gimple_switch_edge (function *ifun, gswitch *gs, unsigned index)
+{
+  return find_edge (gimple_bb (gs), gimple_switch_label_bb (ifun, gs, index));
+}
+
+/* Return the default edge of a switch statement.  */
+
+edge
+gimple_switch_default_edge (function *ifun, gswitch *gs)
+{
+  return gimple_switch_edge (ifun, gs, 0);
+}
+
+
 /* Emit return warnings.  */
 
 namespace {
diff --git a/gcc/tree-cfg.h b/gcc/tree-cfg.h
index 9491bb45feb..349a9543168 100644
--- a/gcc/tree-cfg.h
+++ b/gcc/tree-cfg.h
@@ -33,8 +33,7 @@ extern void init_empty_tree_cfg_for_function (struct function *);
 extern void init_empty_tree_cfg (void);
 extern void start_recording_case_labels (void);
 extern void end_recording_case_labels (void);
-extern basic_block label_to_block_fn (struct function *, tree);
-#define label_to_block(t) (label_to_block_fn (cfun, t))
+extern basic_block label_to_block (struct function *, tree);
 extern void cleanup_dead_labels (void);
 extern bool group_case_labels_stmt (gswitch *);
 extern bool group_case_labels (void);
@@ -112,6 +111,10 @@ extern bool extract_true_false_controlled_edges (basic_block, basic_block,
 						 edge *, edge *);
 extern void generate_range_test (basic_block bb, tree index, tree low,
 				 tree high, tree *lhs, tree *rhs);
+extern basic_block gimple_switch_label_bb (function *, gswitch *, unsigned);
+extern basic_block gimple_switch_default_bb (function *, gswitch *);
+extern edge gimple_switch_edge (function *, gswitch *, unsigned);
+extern edge gimple_switch_default_edge (function *, gswitch *);
 
 /* Return true if the LHS of a call should be removed.  */
 
diff --git a/gcc/tree-cfgcleanup.c b/gcc/tree-cfgcleanup.c
index b27ba8a7333..7fd0430d6cf 100644
--- a/gcc/tree-cfgcleanup.c
+++ b/gcc/tree-cfgcleanup.c
@@ -84,13 +84,12 @@ convert_single_case_switch (gswitch *swtch, gimple_stmt_iterator &gsi)
     return false;
 
   tree index = gimple_switch_index (swtch);
-  tree default_label = CASE_LABEL (gimple_switch_default_label (swtch));
   tree label = gimple_switch_label (swtch, 1);
   tree low = CASE_LOW (label);
   tree high = CASE_HIGH (label);
 
-  basic_block default_bb = label_to_block_fn (cfun, default_label);
-  basic_block case_bb = label_to_block_fn (cfun, CASE_LABEL (label));
+  basic_block default_bb = gimple_switch_default_bb (cfun, swtch);
+  basic_block case_bb = label_to_block (cfun, CASE_LABEL (label));
 
   basic_block bb = gimple_bb (swtch);
   gcond *cond;
@@ -266,7 +265,7 @@ cleanup_control_flow_bb (basic_block bb)
       label = TREE_OPERAND (gimple_goto_dest (stmt), 0);
       if (DECL_CONTEXT (label) != cfun->decl)
 	return retval;
-      target_block = label_to_block (label);
+      target_block = label_to_block (cfun, label);
       for (ei = ei_start (bb->succs); (e = ei_safe_edge (ei)); )
 	{
 	  if (e->dest != target_block)
diff --git a/gcc/tree-eh.c b/gcc/tree-eh.c
index f367040af45..20e2db9e29a 100644
--- a/gcc/tree-eh.c
+++ b/gcc/tree-eh.c
@@ -2231,7 +2231,7 @@ make_eh_dispatch_edges (geh_dispatch *stmt)
     case ERT_TRY:
       for (c = r->u.eh_try.first_catch; c ; c = c->next_catch)
 	{
-	  dst = label_to_block (c->label);
+	  dst = label_to_block (cfun, c->label);
 	  make_edge (src, dst, 0);
 
 	  /* A catch-all handler doesn't have a fallthru.  */
@@ -2241,7 +2241,7 @@ make_eh_dispatch_edges (geh_dispatch *stmt)
       break;
 
     case ERT_ALLOWED_EXCEPTIONS:
-      dst = label_to_block (r->u.allowed.label);
+      dst = label_to_block (cfun, r->u.allowed.label);
       make_edge (src, dst, 0);
       break;
 
@@ -2270,7 +2270,7 @@ make_eh_edges (gimple *stmt)
   gcc_assert (lp != NULL);
 
   src = gimple_bb (stmt);
-  dst = label_to_block (lp->post_landing_pad);
+  dst = label_to_block (cfun, lp->post_landing_pad);
   make_edge (src, dst, EDGE_EH);
 }
 
@@ -2389,7 +2389,7 @@ redirect_eh_dispatch_edge (geh_dispatch *stmt, edge e, basic_block new_bb)
     case ERT_TRY:
       for (c = r->u.eh_try.first_catch; c ; c = c->next_catch)
 	{
-	  old_bb = label_to_block (c->label);
+	  old_bb = label_to_block (cfun, c->label);
 	  if (old_bb == e->dest)
 	    {
 	      c->label = new_lab;
@@ -2399,7 +2399,7 @@ redirect_eh_dispatch_edge (geh_dispatch *stmt, edge e, basic_block new_bb)
       break;
 
     case ERT_ALLOWED_EXCEPTIONS:
-      old_bb = label_to_block (r->u.allowed.label);
+      old_bb = label_to_block (cfun, r->u.allowed.label);
       gcc_assert (old_bb == e->dest);
       r->u.allowed.label = new_lab;
       any_changed = true;
@@ -3329,7 +3329,7 @@ lower_resx (basic_block bb, gresx *stmt,
 	  else
 	    {
 	      lab = *slot;
-	      new_bb = label_to_block (lab);
+	      new_bb = label_to_block (cfun, lab);
 	    }
 
 	  gcc_assert (EDGE_COUNT (bb->succs) == 0);
@@ -3733,7 +3733,7 @@ lower_eh_dispatch (basic_block src, geh_dispatch *stmt)
 	    while (tp_node);
 	    if (! have_label)
 	      {
-	        remove_edge (find_edge (src, label_to_block (lab)));
+		remove_edge (find_edge (src, label_to_block (cfun, lab)));
 	        redirected = true;
 	      }
 	  }
@@ -4046,7 +4046,7 @@ maybe_remove_unreachable_handlers (void)
   FOR_EACH_VEC_SAFE_ELT (cfun->eh->lp_array, i, lp)
     if (lp && lp->post_landing_pad)
       {
-	if (label_to_block (lp->post_landing_pad) == NULL)
+	if (label_to_block (cfun, lp->post_landing_pad) == NULL)
 	  {
 	    remove_unreachable_handlers ();
 	    return;
@@ -4110,7 +4110,7 @@ remove_unreachable_handlers_no_lp (void)
 static bool
 unsplit_eh (eh_landing_pad lp)
 {
-  basic_block bb = label_to_block (lp->post_landing_pad);
+  basic_block bb = label_to_block (cfun, lp->post_landing_pad);
   gimple_stmt_iterator gsi;
   edge e_in, e_out;
 
@@ -4475,7 +4475,7 @@ infinite_empty_loop_p (edge e_first)
 static bool
 cleanup_empty_eh (eh_landing_pad lp)
 {
-  basic_block bb = label_to_block (lp->post_landing_pad);
+  basic_block bb = label_to_block (cfun, lp->post_landing_pad);
   gimple_stmt_iterator gsi;
   gimple *resx;
   eh_region new_region;
@@ -4795,7 +4795,7 @@ verify_eh_edges (gimple *stmt)
       return true;
     }
 
-  if (eh_edge->dest != label_to_block (lp->post_landing_pad))
+  if (eh_edge->dest != label_to_block (cfun, lp->post_landing_pad))
     {
       error ("Incorrect EH edge %i->%i", bb->index, eh_edge->dest->index);
       return true;
@@ -4827,7 +4827,7 @@ verify_eh_dispatch_edge (geh_dispatch *stmt)
     case ERT_TRY:
       for (c = r->u.eh_try.first_catch; c ; c = c->next_catch)
 	{
-	  dst = label_to_block (c->label);
+	  dst = label_to_block (cfun, c->label);
 	  e = find_edge (src, dst);
 	  if (e == NULL)
 	    {
@@ -4846,7 +4846,7 @@ verify_eh_dispatch_edge (geh_dispatch *stmt)
       break;
 
     case ERT_ALLOWED_EXCEPTIONS:
-      dst = label_to_block (r->u.allowed.label);
+      dst = label_to_block (cfun, r->u.allowed.label);
       e = find_edge (src, dst);
       if (e == NULL)
 	{
diff --git a/gcc/tree-ssa-dom.c b/gcc/tree-ssa-dom.c
index 267880f3b5c..7430fd7e706 100644
--- a/gcc/tree-ssa-dom.c
+++ b/gcc/tree-ssa-dom.c
@@ -436,7 +436,8 @@ record_edge_info (basic_block bb)
 	      for (i = 0; i < n_labels; i++)
 		{
 		  tree label = gimple_switch_label (switch_stmt, i);
-		  basic_block target_bb = label_to_block (CASE_LABEL (label));
+		  basic_block target_bb
+		    = label_to_block (cfun, CASE_LABEL (label));
 		  if (CASE_HIGH (label)
 		      || !CASE_LOW (label)
 		      || info[target_bb->index])
diff --git a/gcc/tree-ssa-forwprop.c b/gcc/tree-ssa-forwprop.c
index 56078110b39..4ed61c37a5f 100644
--- a/gcc/tree-ssa-forwprop.c
+++ b/gcc/tree-ssa-forwprop.c
@@ -1071,7 +1071,7 @@ simplify_gimple_switch_label_vec (gswitch *stmt, tree index_type)
       for (i = 0; i < gimple_switch_num_labels (stmt); i++)
 	{
 	  tree elt = gimple_switch_label (stmt, i);
-	  basic_block target = label_to_block (CASE_LABEL (elt));
+	  basic_block target = label_to_block (cfun, CASE_LABEL (elt));
 	  bitmap_set_bit (target_blocks, target->index);
 	}
       for (ei = ei_start (gimple_bb (stmt)->succs); (e = ei_safe_edge (ei)); )
diff --git a/gcc/tree-ssa-threadedge.c b/gcc/tree-ssa-threadedge.c
index dbc0bbd772a..a2304493495 100644
--- a/gcc/tree-ssa-threadedge.c
+++ b/gcc/tree-ssa-threadedge.c
@@ -977,7 +977,7 @@ thread_around_empty_blocks (edge taken_edge,
 	  || TREE_CODE (cond) == CASE_LABEL_EXPR))
     {
       if (TREE_CODE (cond) == CASE_LABEL_EXPR)
-	taken_edge = find_edge (bb, label_to_block (CASE_LABEL (cond)));
+	taken_edge = find_edge (bb, label_to_block (cfun, CASE_LABEL (cond)));
       else
 	taken_edge = find_taken_edge (bb, cond);
 
@@ -1109,7 +1109,7 @@ thread_through_normal_block (edge e,
 	  edge taken_edge;
 	  if (TREE_CODE (cond) == CASE_LABEL_EXPR)
 	    taken_edge = find_edge (e->dest,
-				    label_to_block (CASE_LABEL (cond)));
+				    label_to_block (cfun, CASE_LABEL (cond)));
 	  else
 	    taken_edge = find_taken_edge (e->dest, cond);
 
diff --git a/gcc/tree-ssa-uncprop.c b/gcc/tree-ssa-uncprop.c
index 7d863a71551..98cc79e8607 100644
--- a/gcc/tree-ssa-uncprop.c
+++ b/gcc/tree-ssa-uncprop.c
@@ -184,7 +184,7 @@ associate_equivalences_with_edges (void)
 	      for (i = 0; i < n_labels; i++)
 		{
 		  tree label = gimple_switch_label (switch_stmt, i);
-		  basic_block bb = label_to_block (CASE_LABEL (label));
+		  basic_block bb = label_to_block (cfun, CASE_LABEL (label));
 
 		  if (CASE_HIGH (label)
 		      || !CASE_LOW (label)
diff --git a/gcc/tree-ssa-uninit.c b/gcc/tree-ssa-uninit.c
index a93610084f2..f3e42ddbd7f 100644
--- a/gcc/tree-ssa-uninit.c
+++ b/gcc/tree-ssa-uninit.c
@@ -725,7 +725,7 @@ convert_control_dep_chain_into_preds (vec<edge> *dep_chains,
 	      for (idx = 0; idx < gimple_switch_num_labels (gs); ++idx)
 		{
 		  tree tl = gimple_switch_label (gs, idx);
-		  if (e->dest == label_to_block (CASE_LABEL (tl)))
+		  if (e->dest == label_to_block (cfun, CASE_LABEL (tl)))
 		    {
 		      if (!l)
 			l = tl;
diff --git a/gcc/tree-switch-conversion.c b/gcc/tree-switch-conversion.c
index 9a594a01fc4..ef08bdc990d 100644
--- a/gcc/tree-switch-conversion.c
+++ b/gcc/tree-switch-conversion.c
@@ -78,7 +78,6 @@ switch_conversion::collect (gswitch *swtch)
   unsigned int i;
   edge e, e_default, e_first;
   edge_iterator ei;
-  basic_block first;
 
   m_switch = swtch;
 
@@ -87,9 +86,8 @@ switch_conversion::collect (gswitch *swtch)
      Collect the bits we can deduce from the CFG.  */
   m_index_expr = gimple_switch_index (swtch);
   m_switch_bb = gimple_bb (swtch);
-  m_default_bb
-    = label_to_block (CASE_LABEL (gimple_switch_default_label (swtch)));
-  e_default = find_edge (m_switch_bb, m_default_bb);
+  e_default = gimple_switch_default_edge (cfun, swtch);
+  m_default_bb = e_default->dest;
   m_default_prob = e_default->probability;
   m_default_count = e_default->count ();
   FOR_EACH_EDGE (e, ei, m_switch_bb->succs)
@@ -120,15 +118,9 @@ switch_conversion::collect (gswitch *swtch)
     }
 
   if (m_contiguous_range)
-    {
-      first = label_to_block (CASE_LABEL (gimple_switch_label (swtch, 1)));
-      e_first = find_edge (m_switch_bb, first);
-    }
+    e_first = gimple_switch_edge (cfun, swtch, 1);
   else
-    {
-      first = m_default_bb;
-      e_first = e_default;
-    }
+    e_first = e_default;
 
   /* See if there is one common successor block for all branch
      targets.  If it exists, record it in FINAL_BB.
@@ -306,8 +298,7 @@ switch_conversion::check_final_bb ()
 		  unsigned int branch_num = gimple_switch_num_labels (m_switch);
 		  for (unsigned int i = 1; i < branch_num; i++)
 		    {
-		      tree lab = CASE_LABEL (gimple_switch_label (m_switch, i));
-		      if (label_to_block (lab) == bb)
+		      if (gimple_switch_label_bb (cfun, m_switch, i) == bb)
 			{
 			  m_reason = reason;
 			  return false;
@@ -351,7 +342,7 @@ void
 switch_conversion::gather_default_values (tree default_case)
 {
   gphi_iterator gsi;
-  basic_block bb = label_to_block (CASE_LABEL (default_case));
+  basic_block bb = label_to_block (cfun, CASE_LABEL (default_case));
   edge e;
   int i = 0;
 
@@ -388,7 +379,7 @@ switch_conversion::build_constructors ()
   for (i = 1; i < branch_num; i++)
     {
       tree cs = gimple_switch_label (m_switch, i);
-      basic_block bb = label_to_block (CASE_LABEL (cs));
+      basic_block bb = label_to_block (cfun, CASE_LABEL (cs));
       edge e;
       tree high;
       gphi_iterator gsi;
@@ -1577,15 +1568,11 @@ bit_test_cluster::hoist_edge_and_branch_if_true (gimple_stmt_iterator *gsip,
 void
 switch_decision_tree::compute_cases_per_edge ()
 {
-  basic_block bb = gimple_bb (m_switch);
   reset_out_edges_aux ();
   int ncases = gimple_switch_num_labels (m_switch);
   for (int i = ncases - 1; i >= 1; --i)
     {
-      tree elt = gimple_switch_label (m_switch, i);
-      tree lab = CASE_LABEL (elt);
-      basic_block case_bb = label_to_block_fn (cfun, lab);
-      edge case_edge = find_edge (bb, case_bb);
+      edge case_edge = gimple_switch_edge (cfun, m_switch, i);
       case_edge->aux = (void *) ((intptr_t) (case_edge->aux) + 1);
     }
 }
@@ -1601,8 +1588,7 @@ switch_decision_tree::analyze_switch_statement ()
   auto_vec<cluster *> clusters;
   clusters.create (l - 1);
 
-  tree default_label = CASE_LABEL (gimple_switch_default_label (m_switch));
-  basic_block default_bb = label_to_block_fn (cfun, default_label);
+  basic_block default_bb = gimple_switch_default_bb (cfun, m_switch);
   m_case_bbs.reserve (l);
   m_case_bbs.quick_push (default_bb);
 
@@ -1612,15 +1598,16 @@ switch_decision_tree::analyze_switch_statement ()
     {
       tree elt = gimple_switch_label (m_switch, i);
       tree lab = CASE_LABEL (elt);
-      basic_block case_bb = label_to_block_fn (cfun, lab);
+      basic_block case_bb = label_to_block (cfun, lab);
       edge case_edge = find_edge (bb, case_bb);
       tree low = CASE_LOW (elt);
       tree high = CASE_HIGH (elt);
 
       profile_probability p
 	= case_edge->probability.apply_scale (1, (intptr_t) (case_edge->aux));
-      clusters.quick_push (new simple_cluster (low, high, elt, case_bb, p));
-      m_case_bbs.quick_push (case_bb);
+      clusters.quick_push (new simple_cluster (low, high, elt, case_edge->dest,
+					       p));
+      m_case_bbs.quick_push (case_edge->dest);
     }
 
   reset_out_edges_aux ();
@@ -1694,9 +1681,8 @@ switch_decision_tree::try_switch_expansion (vec<cluster *> &clusters)
     return false;
 
   /* Find the default case target label.  */
-  tree default_label_expr = CASE_LABEL (gimple_switch_default_label (m_switch));
-  m_default_bb = label_to_block_fn (cfun, default_label_expr);
-  edge default_edge = find_edge (bb, m_default_bb);
+  edge default_edge = gimple_switch_default_edge (cfun, m_switch);
+  m_default_bb = default_edge->dest;
 
   /* Do the insertion of a case label into m_case_list.  The labels are
      fed to us in descending order from the sorted vector of case labels used
diff --git a/gcc/tree-vrp.c b/gcc/tree-vrp.c
index f20730a85ba..e8eb9292506 100644
--- a/gcc/tree-vrp.c
+++ b/gcc/tree-vrp.c
@@ -3474,7 +3474,7 @@ find_switch_asserts (basic_block bb, gswitch *last)
   for (idx = 0; idx < n; ++idx)
     {
       ci[idx].expr = gimple_switch_label (last, idx);
-      ci[idx].bb = label_to_block (CASE_LABEL (ci[idx].expr));
+      ci[idx].bb = label_to_block (cfun, CASE_LABEL (ci[idx].expr));
     }
   edge default_edge = find_edge (bb, ci[0].bb);
   qsort (ci, n, sizeof (struct case_info), compare_case_labels);
diff --git a/gcc/vr-values.c b/gcc/vr-values.c
index 072d9a7b454..11df1023b6e 100644
--- a/gcc/vr-values.c
+++ b/gcc/vr-values.c
@@ -2707,7 +2707,7 @@ vr_values::vrp_visit_switch_stmt (gswitch *stmt, edge *taken_edge_p)
     }
 
   *taken_edge_p = find_edge (gimple_bb (stmt),
-			     label_to_block (CASE_LABEL (val)));
+			     label_to_block (cfun, CASE_LABEL (val)));
 
   if (dump_file && (dump_flags & TDF_DETAILS))
     {
@@ -3760,7 +3760,8 @@ vr_values::simplify_switch_using_ranges (gswitch *stmt)
   for (i = 0; i < n2; ++i)
     {
       e = find_edge (gimple_bb (stmt),
-		     label_to_block (CASE_LABEL (TREE_VEC_ELT (vec2, i))));
+		     label_to_block (cfun,
+				     CASE_LABEL (TREE_VEC_ELT (vec2, i))));
       e->aux = (void *)-1;
     }
diff mbox series

Patch

diff --git a/gcc/gimple-cfg.h b/gcc/gimple-cfg.h
new file mode 100644
index 00000000000..1e95338bede
--- /dev/null
+++ b/gcc/gimple-cfg.h
@@ -0,0 +1,44 @@ 
+/* Gimple IR definitions related to CFG.
+
+   Copyright (C) 2007-2018 Free Software Foundation, Inc.
+   Contributed by Martin Liska <mliska@suse.cz>
+
+This file is part of GCC.
+
+GCC is free software; you can redistribute it and/or modify it under
+the terms of the GNU General Public License as published by the Free
+Software Foundation; either version 3, or (at your option) any later
+version.
+
+GCC is distributed in the hope that it will be useful, but WITHOUT ANY
+WARRANTY; without even the implied warranty of MERCHANTABILITY or
+FITNESS FOR A PARTICULAR PURPOSE.  See the GNU General Public License
+for more details.
+
+You should have received a copy of the GNU General Public License
+along with GCC; see the file COPYING3.  If not see
+<http://www.gnu.org/licenses/>.  */
+
+#ifndef GCC_GIMPLE_CFG_H
+#define GCC_GIMPLE_CFG_H
+
+/* Return the edge that belongs to label numbered INDEX
+   of a switch statement.  */
+
+static inline edge
+gimple_switch_edge (gswitch *gs, unsigned index)
+{
+  tree label = CASE_LABEL (gimple_switch_label (gs, index));
+  return find_edge (gimple_bb (gs), label_to_block (label));
+}
+
+/* Return the default edge of a switch statement.  */
+
+static inline edge
+gimple_switch_default_edge (gswitch *gs)
+{
+  tree label = CASE_LABEL (gimple_switch_label (gs, 0));
+  return find_edge (gimple_bb (gs), label_to_block (label));
+}
+
+#endif  /* GCC_GIMPLE_CFG_H */
diff --git a/gcc/ipa-fnsummary.c b/gcc/ipa-fnsummary.c
index a8fc2c2df9a..2991e647fc4 100644
--- a/gcc/ipa-fnsummary.c
+++ b/gcc/ipa-fnsummary.c
@@ -56,7 +56,10 @@  along with GCC; see the file COPYING3.  If not see
 #include "coretypes.h"
 #include "backend.h"
 #include "tree.h"
+#include "cfganal.h"
 #include "gimple.h"
+#include "tree-cfg.h"
+#include "gimple-cfg.h"
 #include "alloc-pool.h"
 #include "tree-pass.h"
 #include "ssa.h"
@@ -68,9 +71,7 @@  along with GCC; see the file COPYING3.  If not see
 #include "tree-inline.h"
 #include "gimple-pretty-print.h"
 #include "params.h"
-#include "cfganal.h"
 #include "gimple-iterator.h"
-#include "tree-cfg.h"
 #include "tree-ssa-loop-niter.h"
 #include "tree-ssa-loop.h"
 #include "symbol-summary.h"
@@ -1291,7 +1292,7 @@  set_switch_stmt_execution_predicate (struct ipa_func_body_info *fbi,
       tree min, max;
       predicate p;
 
-      e = find_edge (bb, label_to_block (CASE_LABEL (cl)));
+      e = gimple_switch_edge (last, case_idx);
       min = CASE_LOW (cl);
       max = CASE_HIGH (cl);
 
diff --git a/gcc/tree-switch-conversion.c b/gcc/tree-switch-conversion.c
index 9a594a01fc4..492cd365a30 100644
--- a/gcc/tree-switch-conversion.c
+++ b/gcc/tree-switch-conversion.c
@@ -29,6 +29,8 @@  Software Foundation, 51 Franklin Street, Fifth Floor, Boston, MA
 #include "insn-codes.h"
 #include "rtl.h"
 #include "tree.h"
+#include "cfganal.h"
+#include "tree-cfg.h"
 #include "gimple.h"
 #include "cfghooks.h"
 #include "tree-pass.h"
@@ -40,8 +42,8 @@  Software Foundation, 51 Franklin Street, Fifth Floor, Boston, MA
 #include "fold-const.h"
 #include "varasm.h"
 #include "stor-layout.h"
-#include "cfganal.h"
 #include "gimplify.h"
+#include "gimple-cfg.h"
 #include "gimple-iterator.h"
 #include "gimplify-me.h"
 #include "tree-cfg.h"
@@ -78,7 +80,6 @@  switch_conversion::collect (gswitch *swtch)
   unsigned int i;
   edge e, e_default, e_first;
   edge_iterator ei;
-  basic_block first;
 
   m_switch = swtch;
 
@@ -87,9 +88,8 @@  switch_conversion::collect (gswitch *swtch)
      Collect the bits we can deduce from the CFG.  */
   m_index_expr = gimple_switch_index (swtch);
   m_switch_bb = gimple_bb (swtch);
-  m_default_bb
-    = label_to_block (CASE_LABEL (gimple_switch_default_label (swtch)));
-  e_default = find_edge (m_switch_bb, m_default_bb);
+  e_default = gimple_switch_default_edge (swtch);
+  m_default_bb = e_default->dest;
   m_default_prob = e_default->probability;
   m_default_count = e_default->count ();
   FOR_EACH_EDGE (e, ei, m_switch_bb->succs)
@@ -120,15 +120,9 @@  switch_conversion::collect (gswitch *swtch)
     }
 
   if (m_contiguous_range)
-    {
-      first = label_to_block (CASE_LABEL (gimple_switch_label (swtch, 1)));
-      e_first = find_edge (m_switch_bb, first);
-    }
+    e_first = gimple_switch_edge (swtch, 1);
   else
-    {
-      first = m_default_bb;
-      e_first = e_default;
-    }
+    e_first = e_default;
 
   /* See if there is one common successor block for all branch
      targets.  If it exists, record it in FINAL_BB.
@@ -1577,15 +1571,11 @@  bit_test_cluster::hoist_edge_and_branch_if_true (gimple_stmt_iterator *gsip,
 void
 switch_decision_tree::compute_cases_per_edge ()
 {
-  basic_block bb = gimple_bb (m_switch);
   reset_out_edges_aux ();
   int ncases = gimple_switch_num_labels (m_switch);
   for (int i = ncases - 1; i >= 1; --i)
     {
-      tree elt = gimple_switch_label (m_switch, i);
-      tree lab = CASE_LABEL (elt);
-      basic_block case_bb = label_to_block_fn (cfun, lab);
-      edge case_edge = find_edge (bb, case_bb);
+      edge case_edge = gimple_switch_edge (m_switch, i);
       case_edge->aux = (void *) ((intptr_t) (case_edge->aux) + 1);
     }
 }
@@ -1602,7 +1592,7 @@  switch_decision_tree::analyze_switch_statement ()
   clusters.create (l - 1);
 
   tree default_label = CASE_LABEL (gimple_switch_default_label (m_switch));
-  basic_block default_bb = label_to_block_fn (cfun, default_label);
+  basic_block default_bb = label_to_block (default_label);
   m_case_bbs.reserve (l);
   m_case_bbs.quick_push (default_bb);
 
@@ -1619,8 +1609,9 @@  switch_decision_tree::analyze_switch_statement ()
 
       profile_probability p
 	= case_edge->probability.apply_scale (1, (intptr_t) (case_edge->aux));
-      clusters.quick_push (new simple_cluster (low, high, elt, case_bb, p));
-      m_case_bbs.quick_push (case_bb);
+      clusters.quick_push (new simple_cluster (low, high, elt, case_edge->dest,
+					       p));
+      m_case_bbs.quick_push (case_edge->dest);
     }
 
   reset_out_edges_aux ();
@@ -1694,9 +1685,8 @@  switch_decision_tree::try_switch_expansion (vec<cluster *> &clusters)
     return false;
 
   /* Find the default case target label.  */
-  tree default_label_expr = CASE_LABEL (gimple_switch_default_label (m_switch));
-  m_default_bb = label_to_block_fn (cfun, default_label_expr);
-  edge default_edge = find_edge (bb, m_default_bb);
+  edge default_edge = gimple_switch_default_edge (m_switch);
+  m_default_bb = default_edge->dest;
 
   /* Do the insertion of a case label into m_case_list.  The labels are
      fed to us in descending order from the sorted vector of case labels used