From 7822b812793ef4babd29704a325c1be46c7a6ff8 Mon Sep 17 00:00:00 2001
From: David Malcolm <dmalcolm@redhat.com>
Date: Thu, 27 Mar 2014 12:16:23 -0400
Subject: [PATCH 60/88] Concretize gimple_label_label

gcc/
	* gimple.h (gimple_label_label): Require a const_gimple_label
	rather than just a const_gimple.

	* cfgexpand.c (label_rtx_for_bb): Convert local from gimple to
	gimple_label, replacing a check against GIMPLE_LABEL with a
	dyn_cast<gimple_label>.
	* predict.c (tree_estimate_probability_bb): Likewise.
	* tree-cfg.c (make_edges): Likewise.
	(cleanup_dead_labels): Likewise (twice).
	(gimple_can_merge_blocks_p): Likewise.
	(gimple_block_label): Likewise.
	* tree-eh.c (unsplit_eh): Likewise.
	(cleanup_empty_eh_unsplit): Likewise.
	* tree-inline.c (mark_local_labels_stmt): Likewise.
	* tree-nested.c (convert_nl_goto_receiver): Likewise.

	* cfgexpand.c (expand_gimple_stmt_1): Add a checked cast to
	gimple_label when invoking gimple_label_label in a region where
	we've checked the code is GIMPLE_LABEL.
	* gimple-pretty-print.c (pp_cfg_jump): Likewise.
	* gimple.c (gimple_set_bb): Likewise.
	* ipa-pure-const.c (check_stmt): Likewise.
	* omp-low.c (diagnose_sb_1): Likewise.
	* tree-cfg.c (gimple_verify_flow_info): Likewise.
	* tree-cfgcleanup.c (tree_forwarder_block_p): Likewise.
	(remove_forwarder_block): Likewise.
	* tree-eh.c (collect_finally_tree): Likewise.

	* ipa-split.c (verify_non_ssa_vars): Replace a check against
	GIMPLE_LABEL with a dyn_cast<gimple_label>, introducing a
	gimple_label local.
	* tree-cfg.c (gimple_can_merge_blocks_p): Likewise.
	(gimple_merge_blocks): Likewise.
	(remove_bb): Likewise.
	(stmt_starts_bb_p): Likewise.
	(gimple_verify_flow_info): Likewise.
	(move_block_to_fn): Likewise.
	* tree-cfgcleanup.c (remove_forwarder_block): Likewise.
	(remove_forwarder_block_with_phi): Likewise.
	* tree-ssa-ccp.c (optimize_unreachable): Likewise.
---
 gcc/cfgexpand.c           |  9 +++---
 gcc/gimple-pretty-print.c |  4 ++-
 gcc/gimple.c              |  2 +-
 gcc/gimple.h              |  3 +-
 gcc/ipa-pure-const.c      |  2 +-
 gcc/ipa-split.c           | 31 +++++++++++---------
 gcc/omp-low.c             |  4 ++-
 gcc/predict.c             |  7 +++--
 gcc/tree-cfg.c            | 73 ++++++++++++++++++++++++-----------------------
 gcc/tree-cfgcleanup.c     | 22 +++++++-------
 gcc/tree-eh.c             | 12 ++++----
 gcc/tree-inline.c         |  4 +--
 gcc/tree-nested.c         |  4 +--
 gcc/tree-ssa-ccp.c        |  4 +--
 14 files changed, 96 insertions(+), 85 deletions(-)

diff --git a/gcc/cfgexpand.c b/gcc/cfgexpand.c
index 9bf8882..6490004 100644
--- a/gcc/cfgexpand.c
+++ b/gcc/cfgexpand.c
@@ -1983,7 +1983,6 @@ label_rtx_for_bb (basic_block bb ATTRIBUTE_UNUSED)
 {
   gimple_stmt_iterator gsi;
   tree lab;
-  gimple lab_stmt;
 
   if (bb->flags & BB_RTL)
     return block_label (bb);
@@ -1996,8 +1995,10 @@ label_rtx_for_bb (basic_block bb ATTRIBUTE_UNUSED)
 
   for (gsi = gsi_start_bb (bb); !gsi_end_p (gsi); gsi_next (&gsi))
     {
-      lab_stmt = gsi_stmt (gsi);
-      if (gimple_code (lab_stmt) != GIMPLE_LABEL)
+      gimple_label lab_stmt;
+
+      lab_stmt = dyn_cast <gimple_label> (gsi_stmt (gsi));
+      if (!lab_stmt)
 	break;
 
       lab = gimple_label_label (lab_stmt);
@@ -3203,7 +3204,7 @@ expand_gimple_stmt_1 (gimple stmt)
 	expand_computed_goto (op0);
       break;
     case GIMPLE_LABEL:
-      expand_label (gimple_label_label (stmt));
+      expand_label (gimple_label_label (as_a <gimple_label> (stmt)));
       break;
     case GIMPLE_NOP:
     case GIMPLE_PREDICT:
diff --git a/gcc/gimple-pretty-print.c b/gcc/gimple-pretty-print.c
index 43681e2..b024e3d 100644
--- a/gcc/gimple-pretty-print.c
+++ b/gcc/gimple-pretty-print.c
@@ -2374,7 +2374,9 @@ pp_cfg_jump (pretty_printer *buffer, basic_block bb)
   if (stmt && gimple_code (stmt) == GIMPLE_LABEL)
     {
       pp_string (buffer, " (");
-      dump_generic_node (buffer, gimple_label_label (stmt), 0, 0, false);
+      dump_generic_node (buffer,
+			 gimple_label_label (as_a <gimple_label> (stmt)),
+			 0, 0, false);
       pp_right_paren (buffer);
       pp_semicolon (buffer);
     }
diff --git a/gcc/gimple.c b/gcc/gimple.c
index f99ee0f..8721316 100644
--- a/gcc/gimple.c
+++ b/gcc/gimple.c
@@ -1514,7 +1514,7 @@ gimple_set_bb (gimple stmt, basic_block bb)
       tree t;
       int uid;
 
-      t = gimple_label_label (stmt);
+      t = gimple_label_label (as_a <gimple_label> (stmt));
       uid = LABEL_DECL_UID (t);
       if (uid == -1)
 	{
diff --git a/gcc/gimple.h b/gcc/gimple.h
index 6055e33..1a017ca 100644
--- a/gcc/gimple.h
+++ b/gcc/gimple.h
@@ -3205,9 +3205,8 @@ gimple_cond_set_condition (gimple_cond stmt, enum tree_code code, tree lhs,
 /* Return the LABEL_DECL node used by GIMPLE_LABEL statement GS.  */
 
 static inline tree
-gimple_label_label (const_gimple gs)
+gimple_label_label (const_gimple_label gs)
 {
-  GIMPLE_CHECK (gs, GIMPLE_LABEL);
   return gimple_op (gs, 0);
 }
 
diff --git a/gcc/ipa-pure-const.c b/gcc/ipa-pure-const.c
index 8375381..ebf53dd 100644
--- a/gcc/ipa-pure-const.c
+++ b/gcc/ipa-pure-const.c
@@ -689,7 +689,7 @@ check_stmt (gimple_stmt_iterator *gsip, funct_state local, bool ipa)
       check_call (local, as_a <gimple_call> (stmt), ipa);
       break;
     case GIMPLE_LABEL:
-      if (DECL_NONLOCAL (gimple_label_label (stmt)))
+      if (DECL_NONLOCAL (gimple_label_label (as_a <gimple_label> (stmt))))
 	/* Target of long jump. */
 	{
           if (dump_file)
diff --git a/gcc/ipa-split.c b/gcc/ipa-split.c
index 5678251..59901dc 100644
--- a/gcc/ipa-split.c
+++ b/gcc/ipa-split.c
@@ -252,13 +252,13 @@ verify_non_ssa_vars (struct split_point *current, bitmap non_ssa_vars,
 	      ok = false;
 	      goto done;
 	    }
-	  if (gimple_code (stmt) == GIMPLE_LABEL
-	      && test_nonssa_use (stmt, gimple_label_label (stmt),
-				  NULL_TREE, non_ssa_vars))
-	    {
-	      ok = false;
-	      goto done;
-	    }
+	  if (gimple_label label_stmt = dyn_cast <gimple_label> (stmt))
+	    if (test_nonssa_use (stmt, gimple_label_label (label_stmt),
+				 NULL_TREE, non_ssa_vars))
+	      {
+		ok = false;
+		goto done;
+	      }
 	}
       for (bsi = gsi_start_phis (bb); !gsi_end_p (bsi); gsi_next (&bsi))
 	{
@@ -300,15 +300,18 @@ verify_non_ssa_vars (struct split_point *current, bitmap non_ssa_vars,
       {
         gimple_stmt_iterator bsi;
         for (bsi = gsi_start_bb (bb); !gsi_end_p (bsi); gsi_next (&bsi))
-	  if (gimple_code (gsi_stmt (bsi)) == GIMPLE_LABEL
-	      && test_nonssa_use (gsi_stmt (bsi),
-				  gimple_label_label (gsi_stmt (bsi)),
-				  NULL_TREE, non_ssa_vars))
+	  if (gimple_label label_stmt =
+	        dyn_cast <gimple_label> (gsi_stmt (bsi)))
 	    {
-	      ok = false;
-	      goto done;
+	      if (test_nonssa_use (label_stmt,
+				   gimple_label_label (label_stmt),
+				   NULL_TREE, non_ssa_vars))
+		{
+		  ok = false;
+		  goto done;
+		}
 	    }
-	  else if (gimple_code (gsi_stmt (bsi)) != GIMPLE_LABEL)
+	  else
 	    break;
       }
     
diff --git a/gcc/omp-low.c b/gcc/omp-low.c
index 7b4e325..6174c3f 100644
--- a/gcc/omp-low.c
+++ b/gcc/omp-low.c
@@ -10860,7 +10860,9 @@ diagnose_sb_1 (gimple_stmt_iterator *gsi_p, bool *handled_ops_p,
       break;
 
     case GIMPLE_LABEL:
-      splay_tree_insert (all_labels, (splay_tree_key) gimple_label_label (stmt),
+      splay_tree_insert (all_labels,
+			 (splay_tree_key) gimple_label_label (
+					    as_a <gimple_label> (stmt)),
 			 (splay_tree_value) context);
       break;
 
diff --git a/gcc/predict.c b/gcc/predict.c
index bd3f138..5e8a0e9 100644
--- a/gcc/predict.c
+++ b/gcc/predict.c
@@ -2275,12 +2275,13 @@ tree_estimate_probability_bb (basic_block bb)
 	  gimple_stmt_iterator gi;
 	  for (gi = gsi_start_bb (e->dest); !gsi_end_p (gi); gsi_next (&gi))
 	    {
-	      gimple stmt = gsi_stmt (gi);
+	      gimple_label label_stmt =
+		dyn_cast <gimple_label> (gsi_stmt (gi));
 	      tree decl;
 
-	      if (gimple_code (stmt) != GIMPLE_LABEL)
+	      if (!label_stmt)
 		break;
-	      decl = gimple_label_label (stmt);
+	      decl = gimple_label_label (label_stmt);
 	      if (DECL_ARTIFICIAL (decl))
 		continue;
 
diff --git a/gcc/tree-cfg.c b/gcc/tree-cfg.c
index 73a31c3..af2f806 100644
--- a/gcc/tree-cfg.c
+++ b/gcc/tree-cfg.c
@@ -909,10 +909,11 @@ make_edges (void)
 	{
 	  for (gsi = gsi_start_bb (bb); !gsi_end_p (gsi); gsi_next (&gsi))
 	    {
-	      gimple label_stmt = gsi_stmt (gsi);
+	      gimple_label label_stmt =
+		dyn_cast <gimple_label> (gsi_stmt (gsi));
 	      tree target;
 
-	      if (gimple_code (label_stmt) != GIMPLE_LABEL)
+	      if (!label_stmt)
 		break;
 
 	      target = gimple_label_label (label_stmt);
@@ -1373,12 +1374,12 @@ cleanup_dead_labels (void)
       for (i = gsi_start_bb (bb); !gsi_end_p (i); gsi_next (&i))
 	{
 	  tree label;
-	  gimple stmt = gsi_stmt (i);
+	  gimple_label label_stmt = dyn_cast <gimple_label> (gsi_stmt (i));
 
-	  if (gimple_code (stmt) != GIMPLE_LABEL)
+	  if (!label_stmt)
 	    break;
 
-	  label = gimple_label_label (stmt);
+	  label = gimple_label_label (label_stmt);
 
 	  /* If we have not yet seen a label for the current block,
 	     remember this one and see if there are more labels.  */
@@ -1513,12 +1514,12 @@ cleanup_dead_labels (void)
       for (i = gsi_start_bb (bb); !gsi_end_p (i); )
 	{
 	  tree label;
-	  gimple stmt = gsi_stmt (i);
+	  gimple_label label_stmt = dyn_cast <gimple_label> (gsi_stmt (i));
 
-	  if (gimple_code (stmt) != GIMPLE_LABEL)
+	  if (!label_stmt)
 	    break;
 
-	  label = gimple_label_label (stmt);
+	  label = gimple_label_label (label_stmt);
 
 	  if (label == label_for_this_bb
 	      || !DECL_ARTIFICIAL (label)
@@ -1660,19 +1661,19 @@ gimple_can_merge_blocks_p (basic_block a, basic_block b)
     return false;
 
   /* Do not allow a block with only a non-local label to be merged.  */
-  if (stmt
-      && gimple_code (stmt) == GIMPLE_LABEL
-      && DECL_NONLOCAL (gimple_label_label (stmt)))
-    return false;
+  if (stmt)
+    if (gimple_label label_stmt = dyn_cast <gimple_label> (stmt))
+      if (DECL_NONLOCAL (gimple_label_label (label_stmt)))
+	return false;
 
   /* Examine the labels at the beginning of B.  */
   for (gsi = gsi_start_bb (b); !gsi_end_p (gsi); gsi_next (&gsi))
     {
       tree lab;
-      stmt = gsi_stmt (gsi);
-      if (gimple_code (stmt) != GIMPLE_LABEL)
+      gimple_label label_stmt = dyn_cast <gimple_label> (gsi_stmt (gsi));
+      if (!label_stmt)
 	break;
-      lab = gimple_label_label (stmt);
+      lab = gimple_label_label (label_stmt);
 
       /* Do not remove user forced labels or for -O0 any user labels.  */
       if (!DECL_ARTIFICIAL (lab) && (!optimize || FORCED_LABEL (lab)))
@@ -1872,9 +1873,9 @@ gimple_merge_blocks (basic_block a, basic_block b)
   for (gsi = gsi_start_bb (b); !gsi_end_p (gsi);)
     {
       gimple stmt = gsi_stmt (gsi);
-      if (gimple_code (stmt) == GIMPLE_LABEL)
+      if (gimple_label label_stmt = dyn_cast <gimple_label> (stmt))
 	{
-	  tree label = gimple_label_label (stmt);
+	  tree label = gimple_label_label (label_stmt);
 	  int lp_nr;
 
 	  gsi_remove (&gsi, false);
@@ -2032,9 +2033,10 @@ remove_bb (basic_block bb)
       for (i = gsi_last_bb (bb); !gsi_end_p (i);)
 	{
 	  gimple stmt = gsi_stmt (i);
-	  if (gimple_code (stmt) == GIMPLE_LABEL
-	      && (FORCED_LABEL (gimple_label_label (stmt))
-		  || DECL_NONLOCAL (gimple_label_label (stmt))))
+	  gimple_label label_stmt = dyn_cast <gimple_label> (stmt);
+	  if (label_stmt
+	      && (FORCED_LABEL (gimple_label_label (label_stmt))
+		  || DECL_NONLOCAL (gimple_label_label (label_stmt))))
 	    {
 	      basic_block new_bb;
 	      gimple_stmt_iterator new_gsi;
@@ -2042,10 +2044,10 @@ remove_bb (basic_block bb)
 	      /* A non-reachable non-local label may still be referenced.
 		 But it no longer needs to carry the extra semantics of
 		 non-locality.  */
-	      if (DECL_NONLOCAL (gimple_label_label (stmt)))
+	      if (DECL_NONLOCAL (gimple_label_label (label_stmt)))
 		{
-		  DECL_NONLOCAL (gimple_label_label (stmt)) = 0;
-		  FORCED_LABEL (gimple_label_label (stmt)) = 1;
+		  DECL_NONLOCAL (gimple_label_label (label_stmt)) = 0;
+		  FORCED_LABEL (gimple_label_label (label_stmt)) = 1;
 		}
 
 	      new_bb = bb->prev_bb;
@@ -2467,16 +2469,17 @@ stmt_starts_bb_p (gimple stmt, gimple prev_stmt)
   /* Labels start a new basic block only if the preceding statement
      wasn't a label of the same type.  This prevents the creation of
      consecutive blocks that have nothing but a single label.  */
-  if (gimple_code (stmt) == GIMPLE_LABEL)
+  if (gimple_label label_stmt = dyn_cast <gimple_label> (stmt))
     {
       /* Nonlocal and computed GOTO targets always start a new block.  */
-      if (DECL_NONLOCAL (gimple_label_label (stmt))
-	  || FORCED_LABEL (gimple_label_label (stmt)))
+      if (DECL_NONLOCAL (gimple_label_label (label_stmt))
+	  || FORCED_LABEL (gimple_label_label (label_stmt)))
 	return true;
 
       if (prev_stmt && gimple_code (prev_stmt) == GIMPLE_LABEL)
 	{
-	  if (DECL_NONLOCAL (gimple_label_label (prev_stmt)))
+	  if (DECL_NONLOCAL (gimple_label_label (
+			       as_a <gimple_label> (prev_stmt))))
 	    return true;
 
 	  cfg_stats.num_merged_labels++;
@@ -5081,7 +5084,7 @@ gimple_verify_flow_info (void)
 	  if (gimple_code (stmt) != GIMPLE_LABEL)
 	    break;
 
-	  label = gimple_label_label (stmt);
+	  label = gimple_label_label (as_a <gimple_label> (stmt));
 	  if (prev_stmt && DECL_NONLOCAL (label))
 	    {
 	      error ("nonlocal label ");
@@ -5134,10 +5137,10 @@ gimple_verify_flow_info (void)
 	  if (stmt_ends_bb_p (stmt))
 	    found_ctrl_stmt = true;
 
-	  if (gimple_code (stmt) == GIMPLE_LABEL)
+	  if (gimple_label label_stmt = dyn_cast <gimple_label> (stmt))
 	    {
 	      error ("label ");
-	      print_generic_expr (stderr, gimple_label_label (stmt), 0);
+	      print_generic_expr (stderr, gimple_label_label (label_stmt), 0);
 	      fprintf (stderr, " in the middle of basic block %d", bb->index);
 	      err = 1;
 	    }
@@ -5396,12 +5399,12 @@ gimple_block_label (basic_block bb)
   gimple_stmt_iterator i, s = gsi_start_bb (bb);
   bool first = true;
   tree label;
-  gimple stmt;
+  gimple_label stmt;
 
   for (i = s; !gsi_end_p (i); first = false, gsi_next (&i))
     {
-      stmt = gsi_stmt (i);
-      if (gimple_code (stmt) != GIMPLE_LABEL)
+      stmt = dyn_cast <gimple_label> (gsi_stmt (i));
+      if (!stmt)
 	break;
       label = gimple_label_label (stmt);
       if (!DECL_NONLOCAL (label))
@@ -6692,9 +6695,9 @@ move_block_to_fn (struct function *dest_cfun, basic_block bb,
       wi.info = d;
       walk_gimple_stmt (&si, move_stmt_r, move_stmt_op, &wi);
 
-      if (gimple_code (stmt) == GIMPLE_LABEL)
+      if (gimple_label label_stmt = dyn_cast <gimple_label> (stmt))
 	{
-	  tree label = gimple_label_label (stmt);
+	  tree label = gimple_label_label (label_stmt);
 	  int uid = LABEL_DECL_UID (label);
 
 	  gcc_assert (uid > -1);
diff --git a/gcc/tree-cfgcleanup.c b/gcc/tree-cfgcleanup.c
index f4abe53..7ec9145 100644
--- a/gcc/tree-cfgcleanup.c
+++ b/gcc/tree-cfgcleanup.c
@@ -309,7 +309,7 @@ tree_forwarder_block_p (basic_block bb, bool phi_wanted)
       switch (gimple_code (stmt))
 	{
 	case GIMPLE_LABEL:
-	  if (DECL_NONLOCAL (gimple_label_label (stmt)))
+	  if (DECL_NONLOCAL (gimple_label_label (as_a <gimple_label> (stmt))))
 	    return false;
 	  if (optimize == 0 && gimple_location (stmt) != locus)
 	    return false;
@@ -406,11 +406,11 @@ remove_forwarder_block (basic_block bb)
   /* If the destination block consists of a nonlocal label or is a
      EH landing pad, do not merge it.  */
   label = first_stmt (dest);
-  if (label
-      && gimple_code (label) == GIMPLE_LABEL
-      && (DECL_NONLOCAL (gimple_label_label (label))
-	  || EH_LANDING_PAD_NR (gimple_label_label (label)) != 0))
-    return false;
+  if (label)
+    if (gimple_label label_stmt = dyn_cast <gimple_label> (label))
+      if (DECL_NONLOCAL (gimple_label_label (label_stmt))
+	  || EH_LANDING_PAD_NR (gimple_label_label (label_stmt)) != 0)
+	return false;
 
   /* If there is an abnormal edge to basic block BB, but not into
      dest, problems might occur during removal of the phi node at out
@@ -492,7 +492,7 @@ remove_forwarder_block (basic_block bb)
       label = gsi_stmt (gsi);
       if (is_gimple_debug (label))
 	break;
-      decl = gimple_label_label (label);
+      decl = gimple_label_label (as_a <gimple_label> (label));
       if (EH_LANDING_PAD_NR (decl) != 0
 	  || DECL_NONLOCAL (decl)
 	  || FORCED_LABEL (decl)
@@ -840,10 +840,10 @@ remove_forwarder_block_with_phi (basic_block bb)
   /* If the destination block consists of a nonlocal label, do not
      merge it.  */
   label = first_stmt (dest);
-  if (label
-      && gimple_code (label) == GIMPLE_LABEL
-      && DECL_NONLOCAL (gimple_label_label (label)))
-    return false;
+  if (label)
+    if (gimple_label label_stmt = dyn_cast <gimple_label> (label))
+      if (DECL_NONLOCAL (gimple_label_label (label_stmt)))
+	return false;
 
   /* Record BB's single pred in case we need to update the father
      loop's latch information later.  */
diff --git a/gcc/tree-eh.c b/gcc/tree-eh.c
index 1138696..b496c08 100644
--- a/gcc/tree-eh.c
+++ b/gcc/tree-eh.c
@@ -243,7 +243,7 @@ collect_finally_tree (gimple stmt, gimple_try region)
   switch (gimple_code (stmt))
     {
     case GIMPLE_LABEL:
-      temp.t = gimple_label_label (stmt);
+      temp.t = gimple_label_label (as_a <gimple_label> (stmt));
       record_in_finally_tree (temp, region);
       break;
 
@@ -4004,13 +4004,13 @@ unsplit_eh (eh_landing_pad lp)
      for a different region.  */
   for (gsi = gsi_start_bb (e_out->dest); !gsi_end_p (gsi); gsi_next (&gsi))
     {
-      gimple stmt = gsi_stmt (gsi);
+      gimple_label label_stmt = dyn_cast <gimple_label> (gsi_stmt (gsi));
       tree lab;
       int lp_nr;
 
-      if (gimple_code (stmt) != GIMPLE_LABEL)
+      if (!label_stmt)
 	break;
-      lab = gimple_label_label (stmt);
+      lab = gimple_label_label (label_stmt);
       lp_nr = EH_LANDING_PAD_NR (lab);
       if (lp_nr && get_eh_region_from_lp_number (lp_nr) != lp->region)
 	return false;
@@ -4275,10 +4275,10 @@ cleanup_empty_eh_unsplit (basic_block bb, edge e_out, eh_landing_pad lp)
   lab = NULL;
   for (gsi = gsi_start_bb (e_out->dest); !gsi_end_p (gsi); gsi_next (&gsi))
     {
-      gimple stmt = gsi_stmt (gsi);
+      gimple_label stmt = dyn_cast <gimple_label> (gsi_stmt (gsi));
       int lp_nr;
 
-      if (gimple_code (stmt) != GIMPLE_LABEL)
+      if (!stmt)
 	break;
       lab = gimple_label_label (stmt);
       lp_nr = EH_LANDING_PAD_NR (lab);
diff --git a/gcc/tree-inline.c b/gcc/tree-inline.c
index 6e7f67a..96e3ec4 100644
--- a/gcc/tree-inline.c
+++ b/gcc/tree-inline.c
@@ -4837,9 +4837,9 @@ mark_local_labels_stmt (gimple_stmt_iterator *gsip,
 		        struct walk_stmt_info *wi)
 {
   copy_body_data *id = (copy_body_data *) wi->info;
-  gimple stmt = gsi_stmt (*gsip);
+  gimple_label stmt = dyn_cast <gimple_label> (gsi_stmt (*gsip));
 
-  if (gimple_code (stmt) == GIMPLE_LABEL)
+  if (stmt)
     {
       tree decl = gimple_label_label (stmt);
 
diff --git a/gcc/tree-nested.c b/gcc/tree-nested.c
index e6f5c1a..3957e11 100644
--- a/gcc/tree-nested.c
+++ b/gcc/tree-nested.c
@@ -2136,9 +2136,9 @@ convert_nl_goto_receiver (gimple_stmt_iterator *gsi, bool *handled_ops_p,
   struct nesting_info *const info = (struct nesting_info *) wi->info;
   tree label, new_label;
   gimple_stmt_iterator tmp_gsi;
-  gimple stmt = gsi_stmt (*gsi);
+  gimple_label stmt = dyn_cast <gimple_label> (gsi_stmt (*gsi));
 
-  if (gimple_code (stmt) != GIMPLE_LABEL)
+  if (!stmt)
     {
       *handled_ops_p = false;
       return NULL_TREE;
diff --git a/gcc/tree-ssa-ccp.c b/gcc/tree-ssa-ccp.c
index 6650d3c..3a5632f 100644
--- a/gcc/tree-ssa-ccp.c
+++ b/gcc/tree-ssa-ccp.c
@@ -2564,10 +2564,10 @@ optimize_unreachable (gimple_stmt_iterator i)
       if (is_gimple_debug (stmt))
        continue;
 
-      if (gimple_code (stmt) == GIMPLE_LABEL)
+      if (gimple_label label_stmt = dyn_cast <gimple_label> (stmt))
 	{
 	  /* Verify we do not need to preserve the label.  */
-	  if (FORCED_LABEL (gimple_label_label (stmt)))
+	  if (FORCED_LABEL (gimple_label_label (label_stmt)))
 	    return false;
 
 	  continue;
-- 
1.8.5.3

