diff mbox

[gimple-classes,committed,53/92] Use gimple_call for callgraph edges

Message ID 1414442490-14841-54-git-send-email-dmalcolm@redhat.com
State New
Headers show

Commit Message

David Malcolm Oct. 27, 2014, 8:40 p.m. UTC
This corresponds to:
  [PATCH 55/89] Use gimple_call for callgraph edges
  https://gcc.gnu.org/ml/gcc-patches/2014-04/msg01221.html
from the original 89-patch kit

That earlier patch was approved by Jeff:
> OK once prereqs go in.
in https://gcc.gnu.org/ml/gcc-patches/2014-05/msg00867.html

gcc/
	* cgraph.h (cgraph_edge::call_stmt): Strengthen field from plain
	gimple to a gimple_call.
	(cgraph_node::set_call_stmt_including_clones): Likewise for param
	"new_stmt".
	(cgraph_node::create_edge): Likewise for param "call_stmt".
	(cgraph_node::create_indirect_edge): Likewise.
	(cgraph_node::create_edge_including_clones): Likewise for param
	"stmt".
	(cgraph_edge::set_call_stmt): Likewise for param "new_stmt".
	(cgraph_edge::clone): Likewise for param "call_stmt".
	(symbol_table::create_edge): Likewise.

	* cgraph.c (cgraph_edge::set_call_stmt): Require a gimple_call
	rather than a plain gimple.
	(symbol_table::create_edge): Likewise.
	(cgraph_node::create_edge): Likewise.
	(cgraph_node::create_indirect_edge): Likewise.
	(cgraph_edge::redirect_call_stmt_to_callee): Strengthen local
	"new_stmt" from gimple to gimple_call.
	(cgraph_update_edges_for_call_stmt_node): Add checked casts to
	gimple_call.

	* cgraphbuild.c (pass_build_cgraph_edges::execute): Replace
	is_gimple_call with dyn_cast<gimple_call> and new local
	"call_stmt".
	(cgraph_edge::rebuild_edges): Likewise.

	* cgraphclones.c (cgraph_edge::clone): Require a gimple_call
	rather than a plain gimple.
	(cgraph_node::set_call_stmt_including_clones): Likewise.
	(cgraph_node::create_edge_including_clones): Likewise.

	* lto-streamer-in.c (fixup_call_stmt_edges_1): Add checked casts
	to gimple_call.

	* omp-low.c (simd_clone_adjust): Strengthen local "call" from
	gimple to gimple_call.

	* trans-mem.c (ipa_tm_insert_irr_call): Likewise for "g".
	(ipa_tm_insert_gettmclone_call): Likewise; also strengthen "g2"
	to gimple_assign.

	* tree-emutls.c (gen_emutls_addr): Strengthen local "x" from
	gimple to gimple_call.

	* tree-inline.c (copy_bb): Replace is_gimple_call with
	dyn_cast<gimple_call> and new local "call_stmt".

	* value-prof.c (gimple_ic): Require and return a gimple_call,
	rather than a plain gimple.
	* value-prof.h (gimple_ic): Likewise.
---
 gcc/ChangeLog.gimple-classes | 56 ++++++++++++++++++++++++++++++++++++++++++++
 gcc/cgraph.c                 | 21 +++++++++--------
 gcc/cgraph.h                 | 16 ++++++-------
 gcc/cgraphbuild.c            | 24 +++++++++----------
 gcc/cgraphclones.c           |  7 +++---
 gcc/lto-streamer-in.c        |  4 ++--
 gcc/omp-low.c                |  2 +-
 gcc/trans-mem.c              |  5 ++--
 gcc/tree-emutls.c            |  2 +-
 gcc/tree-inline.c            | 14 +++++------
 gcc/value-prof.c             |  8 +++----
 gcc/value-prof.h             |  3 ++-
 12 files changed, 111 insertions(+), 51 deletions(-)
diff mbox

Patch

diff --git a/gcc/ChangeLog.gimple-classes b/gcc/ChangeLog.gimple-classes
index 9654b49..115f7ea 100644
--- a/gcc/ChangeLog.gimple-classes
+++ b/gcc/ChangeLog.gimple-classes
@@ -1,5 +1,61 @@ 
 2014-10-24  David Malcolm  <dmalcolm@redhat.com>
 
+	Use gimple_call for callgraph edges
+
+	* cgraph.h (cgraph_edge::call_stmt): Strengthen field from plain
+	gimple to a gimple_call.
+	(cgraph_node::set_call_stmt_including_clones): Likewise for param
+	"new_stmt".
+	(cgraph_node::create_edge): Likewise for param "call_stmt".
+	(cgraph_node::create_indirect_edge): Likewise.
+	(cgraph_node::create_edge_including_clones): Likewise for param
+	"stmt".
+	(cgraph_edge::set_call_stmt): Likewise for param "new_stmt".
+	(cgraph_edge::clone): Likewise for param "call_stmt".
+	(symbol_table::create_edge): Likewise.
+
+	* cgraph.c (cgraph_edge::set_call_stmt): Require a gimple_call
+	rather than a plain gimple.
+	(symbol_table::create_edge): Likewise.
+	(cgraph_node::create_edge): Likewise.
+	(cgraph_node::create_indirect_edge): Likewise.
+	(cgraph_edge::redirect_call_stmt_to_callee): Strengthen local
+	"new_stmt" from gimple to gimple_call.
+	(cgraph_update_edges_for_call_stmt_node): Add checked casts to
+	gimple_call.
+
+	* cgraphbuild.c (pass_build_cgraph_edges::execute): Replace
+	is_gimple_call with dyn_cast<gimple_call> and new local
+	"call_stmt".
+	(cgraph_edge::rebuild_edges): Likewise.
+
+	* cgraphclones.c (cgraph_edge::clone): Require a gimple_call
+	rather than a plain gimple.
+	(cgraph_node::set_call_stmt_including_clones): Likewise.
+	(cgraph_node::create_edge_including_clones): Likewise.
+
+	* lto-streamer-in.c (fixup_call_stmt_edges_1): Add checked casts
+	to gimple_call.
+
+	* omp-low.c (simd_clone_adjust): Strengthen local "call" from
+	gimple to gimple_call.
+
+	* trans-mem.c (ipa_tm_insert_irr_call): Likewise for "g".
+	(ipa_tm_insert_gettmclone_call): Likewise; also strengthen "g2"
+	to gimple_assign.
+
+	* tree-emutls.c (gen_emutls_addr): Strengthen local "x" from
+	gimple to gimple_call.
+
+	* tree-inline.c (copy_bb): Replace is_gimple_call with
+	dyn_cast<gimple_call> and new local "call_stmt".
+
+	* value-prof.c (gimple_ic): Require and return a gimple_call,
+	rather than a plain gimple.
+	* value-prof.h (gimple_ic): Likewise.
+
+2014-10-24  David Malcolm  <dmalcolm@redhat.com>
+
 	Make gimple_call_return_slot_opt_p require a gimple_call.
 
 	* gimple.h (gimple_call_return_slot_opt_p): Require a gimple_call
diff --git a/gcc/cgraph.c b/gcc/cgraph.c
index 2694c40..947d432 100644
--- a/gcc/cgraph.c
+++ b/gcc/cgraph.c
@@ -691,7 +691,7 @@  cgraph_node::get_edge (gimple call_stmt)
    edge, then update all components.  */
 
 void
-cgraph_edge::set_call_stmt (gimple new_stmt, bool update_speculative)
+cgraph_edge::set_call_stmt (gimple_call new_stmt, bool update_speculative)
 {
   tree decl;
 
@@ -744,8 +744,8 @@  cgraph_edge::set_call_stmt (gimple new_stmt, bool update_speculative)
 
 cgraph_edge *
 symbol_table::create_edge (cgraph_node *caller, cgraph_node *callee,
-		     gimple call_stmt, gcov_type count, int freq,
-		     bool indir_unknown_callee)
+			   gimple_call call_stmt, gcov_type count, int freq,
+			   bool indir_unknown_callee)
 {
   cgraph_edge *edge;
 
@@ -825,7 +825,7 @@  symbol_table::create_edge (cgraph_node *caller, cgraph_node *callee,
 
 cgraph_edge *
 cgraph_node::create_edge (cgraph_node *callee,
-			  gimple call_stmt, gcov_type count, int freq)
+			  gimple_call call_stmt, gcov_type count, int freq)
 {
   cgraph_edge *edge = symtab->create_edge (this, callee, call_stmt, count,
 					   freq, false);
@@ -861,7 +861,7 @@  cgraph_allocate_init_indirect_info (void)
    PARAM_INDEX. */
 
 cgraph_edge *
-cgraph_node::create_indirect_edge (gimple call_stmt, int ecf_flags,
+cgraph_node::create_indirect_edge (gimple_call call_stmt, int ecf_flags,
 				   gcov_type count, int freq,
 				   bool compute_indirect_info)
 {
@@ -1247,7 +1247,7 @@  cgraph_edge::redirect_call_stmt_to_callee (void)
   if (e->speculative)
     {
       cgraph_edge *e2;
-      gimple new_stmt;
+      gimple_call new_stmt;
       ipa_ref *ref;
 
       e->speculative_call_info (e, e2, ref);
@@ -1375,7 +1375,7 @@  cgraph_edge::redirect_call_stmt_to_callee (void)
     }
   else
     {
-      new_stmt = as_a <gimple_call> (e->call_stmt);
+      new_stmt = e->call_stmt;
       gimple_call_set_fndecl (new_stmt, e->callee->decl);
       update_stmt_fn (DECL_STRUCT_FUNCTION (e->caller->decl), new_stmt);
     }
@@ -1454,7 +1454,7 @@  cgraph_update_edges_for_call_stmt_node (cgraph_node *node,
 		  if (callee->decl == new_call
 		      || callee->former_clone_of == new_call)
 		    {
-		      e->set_call_stmt (new_stmt);
+		      e->set_call_stmt (as_a <gimple_call> (new_stmt));
 		      return;
 		    }
 		  callee = callee->clone_of;
@@ -1483,13 +1483,14 @@  cgraph_update_edges_for_call_stmt_node (cgraph_node *node,
       if (new_call)
 	{
 	  ne = node->create_edge (cgraph_node::get_create (new_call),
-				  new_stmt, count, frequency);
+				  as_a <gimple_call> (new_stmt), count,
+				  frequency);
 	  gcc_assert (ne->inline_failed);
 	}
     }
   /* We only updated the call stmt; update pointer in cgraph edge..  */
   else if (old_stmt != new_stmt)
-    node->get_edge (old_stmt)->set_call_stmt (new_stmt);
+    node->get_edge (old_stmt)->set_call_stmt (as_a <gimple_call> (new_stmt));
 }
 
 /* Update or remove the corresponding cgraph edge if a GIMPLE_CALL
diff --git a/gcc/cgraph.h b/gcc/cgraph.h
index a5777c2..de66165 100644
--- a/gcc/cgraph.h
+++ b/gcc/cgraph.h
@@ -779,7 +779,7 @@  public:
      When WHOLE_SPECULATIVE_EDGES is true, all three components of
      speculative edge gets updated.  Otherwise we update only direct
      call.  */
-  void set_call_stmt_including_clones (gimple old_stmt, gimple new_stmt,
+  void set_call_stmt_including_clones (gimple old_stmt, gimple_call new_stmt,
 				       bool update_speculative = true);
 
   /* Walk the alias chain to return the function cgraph_node is alias of.
@@ -955,13 +955,13 @@  public:
 
   /* Create edge from a given function to CALLEE in the cgraph.  */
   cgraph_edge *create_edge (cgraph_node *callee,
-			    gimple call_stmt, gcov_type count,
+			    gimple_call call_stmt, gcov_type count,
 			    int freq);
 
   /* Create an indirect edge with a yet-undetermined callee where the call
      statement destination is a formal parameter of the caller with index
      PARAM_INDEX. */
-  cgraph_edge *create_indirect_edge (gimple call_stmt, int ecf_flags,
+  cgraph_edge *create_indirect_edge (gimple_call call_stmt, int ecf_flags,
 				     gcov_type count, int freq,
 				     bool compute_indirect_info = true);
 
@@ -969,7 +969,7 @@  public:
    same function body.  If clones already have edge for OLD_STMT; only
    update the edge same way as cgraph_set_call_stmt_including_clones does.  */
   void create_edge_including_clones (cgraph_node *callee,
-				     gimple old_stmt, gimple stmt,
+				     gimple old_stmt, gimple_call stmt,
 				     gcov_type count,
 				     int freq,
 				     cgraph_inline_failed_t reason);
@@ -1427,7 +1427,7 @@  struct GTY((chain_next ("%h.next_caller"), chain_prev ("%h.prev_caller"),
   /* Change field call_stmt of edge to NEW_STMT.
      If UPDATE_SPECULATIVE and E is any component of speculative
      edge, then update all components.  */
-  void set_call_stmt (gimple new_stmt, bool update_speculative = true);
+  void set_call_stmt (gimple_call new_stmt, bool update_speculative = true);
 
   /* Redirect callee of the edge to N.  The function does not update underlying
      call expression.  */
@@ -1460,7 +1460,7 @@  struct GTY((chain_next ("%h.next_caller"), chain_prev ("%h.prev_caller"),
 
   /* Create clone of edge in the node N represented
      by CALL_EXPR the callgraph.  */
-  cgraph_edge * clone (cgraph_node *n, gimple call_stmt, unsigned stmt_uid,
+  cgraph_edge * clone (cgraph_node *n, gimple_call call_stmt, unsigned stmt_uid,
 		       gcov_type count_scale, int freq_scale, bool update_original);
 
   /* Return true when call of edge can not lead to return from caller
@@ -1490,7 +1490,7 @@  struct GTY((chain_next ("%h.next_caller"), chain_prev ("%h.prev_caller"),
   cgraph_edge *next_caller;
   cgraph_edge *prev_callee;
   cgraph_edge *next_callee;
-  gimple call_stmt;
+  gimple_call call_stmt;
   /* Additional information about an indirect call.  Not cleared when an edge
      becomes direct.  */
   cgraph_indirect_call_info *indirect_info;
@@ -2018,7 +2018,7 @@  private:
      parameters of which only CALLEE can be NULL (when creating an indirect call
      edge).  */
   cgraph_edge *create_edge (cgraph_node *caller, cgraph_node *callee,
-			    gimple call_stmt, gcov_type count, int freq,
+			    gimple_call call_stmt, gcov_type count, int freq,
 			    bool indir_unknown_callee);
 
   /* Put the edge onto the free list.  */
diff --git a/gcc/cgraphbuild.c b/gcc/cgraphbuild.c
index be3e866..a97e397 100644
--- a/gcc/cgraphbuild.c
+++ b/gcc/cgraphbuild.c
@@ -337,18 +337,18 @@  pass_build_cgraph_edges::execute (function *fun)
 	  if (is_gimple_debug (stmt))
 	    continue;
 
-	  if (is_gimple_call (stmt))
+	  if (gimple_call call_stmt = dyn_cast <gimple_call> (stmt))
 	    {
 	      int freq = compute_call_stmt_bb_frequency (current_function_decl,
 							 bb);
-	      decl = gimple_call_fndecl (stmt);
+	      decl = gimple_call_fndecl (call_stmt);
 	      if (decl)
-		node->create_edge (cgraph_node::get_create (decl), stmt, bb->count, freq);
-	      else if (gimple_call_internal_p (stmt))
+		node->create_edge (cgraph_node::get_create (decl), call_stmt, bb->count, freq);
+	      else if (gimple_call_internal_p (call_stmt))
 		;
 	      else
-		node->create_indirect_edge (stmt,
-					    gimple_call_flags (stmt),
+		node->create_indirect_edge (call_stmt,
+					    gimple_call_flags (call_stmt),
 					    bb->count, freq);
 	    }
 	  node->record_stmt_references (stmt);
@@ -433,19 +433,19 @@  cgraph_edge::rebuild_edges (void)
 	  gimple stmt = gsi_stmt (gsi);
 	  tree decl;
 
-	  if (is_gimple_call (stmt))
+	  if (gimple_call call_stmt = dyn_cast <gimple_call> (stmt))
 	    {
 	      int freq = compute_call_stmt_bb_frequency (current_function_decl,
 							 bb);
-	      decl = gimple_call_fndecl (stmt);
+	      decl = gimple_call_fndecl (call_stmt);
 	      if (decl)
-		node->create_edge (cgraph_node::get_create (decl), stmt,
+		node->create_edge (cgraph_node::get_create (decl), call_stmt,
 				   bb->count, freq);
-	      else if (gimple_call_internal_p (stmt))
+	      else if (gimple_call_internal_p (call_stmt))
 		;
 	      else
-		node->create_indirect_edge (stmt,
-					    gimple_call_flags (stmt),
+		node->create_indirect_edge (call_stmt,
+					    gimple_call_flags (call_stmt),
 					    bb->count, freq);
 	    }
 	  node->record_stmt_references (stmt);
diff --git a/gcc/cgraphclones.c b/gcc/cgraphclones.c
index c487c13..d5c2697 100644
--- a/gcc/cgraphclones.c
+++ b/gcc/cgraphclones.c
@@ -106,7 +106,7 @@  along with GCC; see the file COPYING3.  If not see
    the callgraph.  */
 
 cgraph_edge *
-cgraph_edge::clone (cgraph_node *n, gimple call_stmt, unsigned stmt_uid,
+cgraph_edge::clone (cgraph_node *n, gimple_call call_stmt, unsigned stmt_uid,
 		    gcov_type count_scale, int freq_scale, bool update_original)
 {
   cgraph_edge *new_edge;
@@ -688,7 +688,8 @@  cgraph_node::find_replacement (void)
    call.  */
 
 void
-cgraph_node::set_call_stmt_including_clones (gimple old_stmt, gimple new_stmt,
+cgraph_node::set_call_stmt_including_clones (gimple old_stmt,
+					     gimple_call new_stmt,
 					     bool update_speculative)
 {
   cgraph_node *node;
@@ -743,7 +744,7 @@  cgraph_node::set_call_stmt_including_clones (gimple old_stmt, gimple new_stmt,
 
 void
 cgraph_node::create_edge_including_clones (cgraph_node *callee,
-					   gimple old_stmt, gimple stmt,
+					   gimple old_stmt, gimple_call stmt,
 					   gcov_type count,
 					   int freq,
 					   cgraph_inline_failed_t reason)
diff --git a/gcc/lto-streamer-in.c b/gcc/lto-streamer-in.c
index 271b51c..150e7ba 100644
--- a/gcc/lto-streamer-in.c
+++ b/gcc/lto-streamer-in.c
@@ -788,7 +788,7 @@  fixup_call_stmt_edges_1 (struct cgraph_node *node, gimple *stmts,
     {
       if (gimple_stmt_max_uid (fn) < cedge->lto_stmt_uid)
         fatal_error ("Cgraph edge statement index out of range");
-      cedge->call_stmt = stmts[cedge->lto_stmt_uid - 1];
+      cedge->call_stmt = as_a <gimple_call> (stmts[cedge->lto_stmt_uid - 1]);
       if (!cedge->call_stmt)
         fatal_error ("Cgraph edge statement index not found");
     }
@@ -796,7 +796,7 @@  fixup_call_stmt_edges_1 (struct cgraph_node *node, gimple *stmts,
     {
       if (gimple_stmt_max_uid (fn) < cedge->lto_stmt_uid)
         fatal_error ("Cgraph edge statement index out of range");
-      cedge->call_stmt = stmts[cedge->lto_stmt_uid - 1];
+      cedge->call_stmt = as_a <gimple_call> (stmts[cedge->lto_stmt_uid - 1]);
       if (!cedge->call_stmt)
         fatal_error ("Cgraph edge statement index not found");
     }
diff --git a/gcc/omp-low.c b/gcc/omp-low.c
index 327c6e1..7b4e325 100644
--- a/gcc/omp-low.c
+++ b/gcc/omp-low.c
@@ -12136,7 +12136,7 @@  simd_clone_adjust (struct cgraph_node *node)
 	    tree fn = builtin_decl_explicit (BUILT_IN_ASSUME_ALIGNED);
 	    gimple_seq seq = NULL;
 	    bool need_cvt = false;
-	    gimple call
+	    gimple_call call
 	      = gimple_build_call (fn, 2, def, size_int (alignment));
 	    g = call;
 	    if (!useless_type_conversion_p (TREE_TYPE (orig_arg),
diff --git a/gcc/trans-mem.c b/gcc/trans-mem.c
index 86a081a..9e90812 100644
--- a/gcc/trans-mem.c
+++ b/gcc/trans-mem.c
@@ -4965,7 +4965,7 @@  ipa_tm_insert_irr_call (struct cgraph_node *node, struct tm_region *region,
 			basic_block bb)
 {
   gimple_stmt_iterator gsi;
-  gimple g;
+  gimple_call g;
 
   transaction_subcode_ior (region, GTMA_MAY_ENTER_IRREVOCABLE);
 
@@ -4991,7 +4991,8 @@  ipa_tm_insert_gettmclone_call (struct cgraph_node *node,
 			       gimple_stmt_iterator *gsi, gimple stmt)
 {
   tree gettm_fn, ret, old_fn, callfn;
-  gimple g, g2;
+  gimple_call g;
+  gimple_assign g2;
   bool safe;
 
   old_fn = gimple_call_fn (stmt);
diff --git a/gcc/tree-emutls.c b/gcc/tree-emutls.c
index c915e33..8d62dba 100644
--- a/gcc/tree-emutls.c
+++ b/gcc/tree-emutls.c
@@ -406,7 +406,7 @@  gen_emutls_addr (tree decl, struct lower_emutls_data *d)
     {
       varpool_node *cvar;
       tree cdecl;
-      gimple x;
+      gimple_call x;
 
       cvar = data->control_var;
       cdecl = cvar->decl;
diff --git a/gcc/tree-inline.c b/gcc/tree-inline.c
index beae377..a95aa09 100644
--- a/gcc/tree-inline.c
+++ b/gcc/tree-inline.c
@@ -1811,7 +1811,7 @@  copy_bb (copy_body_data *id, basic_block bb, int frequency_scale,
 
 	  /* We're duplicating a CALL_EXPR.  Find any corresponding
 	     callgraph edges and update or duplicate them.  */
-	  if (is_gimple_call (stmt))
+	  if (gimple_call call_stmt = dyn_cast <gimple_call> (stmt))
 	    {
 	      struct cgraph_edge *edge;
 
@@ -1824,7 +1824,7 @@  copy_bb (copy_body_data *id, basic_block bb, int frequency_scale,
 		      int edge_freq = edge->frequency;
 		      int new_freq;
 		      struct cgraph_edge *old_edge = edge;
-		      edge = edge->clone (id->dst_node, stmt,
+		      edge = edge->clone (id->dst_node, call_stmt,
 					  gimple_uid (stmt),
 					  REG_BR_PROB_BASE, CGRAPH_FREQ_BASE,
 					  true);
@@ -1843,7 +1843,7 @@  copy_bb (copy_body_data *id, basic_block bb, int frequency_scale,
 
 			  gcc_assert (!edge->indirect_unknown_callee);
 			  old_edge->speculative_call_info (direct, indirect, ref);
-			  indirect = indirect->clone (id->dst_node, stmt,
+			  indirect = indirect->clone (id->dst_node, call_stmt,
 						      gimple_uid (stmt),
 						      REG_BR_PROB_BASE, CGRAPH_FREQ_BASE,
 						      true);
@@ -1882,14 +1882,14 @@  copy_bb (copy_body_data *id, basic_block bb, int frequency_scale,
 
 		case CB_CGE_MOVE_CLONES:
 		  id->dst_node->set_call_stmt_including_clones (orig_stmt,
-								stmt);
+								call_stmt);
 		  edge = id->dst_node->get_edge (stmt);
 		  break;
 
 		case CB_CGE_MOVE:
 		  edge = id->dst_node->get_edge (orig_stmt);
 		  if (edge)
-		    edge->set_call_stmt (stmt);
+		    edge->set_call_stmt (call_stmt);
 		  break;
 
 		default:
@@ -1918,12 +1918,12 @@  copy_bb (copy_body_data *id, basic_block bb, int frequency_scale,
 			      || !id->dst_node->definition);
 		  if (id->transform_call_graph_edges == CB_CGE_MOVE_CLONES)
 		    id->dst_node->create_edge_including_clones
-		      (dest, orig_stmt, stmt, bb->count,
+		      (dest, orig_stmt, call_stmt, bb->count,
 		       compute_call_stmt_bb_frequency (id->dst_node->decl,
 		       				       copy_basic_block),
 		       CIF_ORIGINALLY_INDIRECT_CALL);
 		  else
-		    id->dst_node->create_edge (dest, stmt,
+		    id->dst_node->create_edge (dest, call_stmt,
 					bb->count,
 					compute_call_stmt_bb_frequency
 					  (id->dst_node->decl,
diff --git a/gcc/value-prof.c b/gcc/value-prof.c
index e5ccf48..a2d62e9 100644
--- a/gcc/value-prof.c
+++ b/gcc/value-prof.c
@@ -1370,11 +1370,11 @@  check_ic_target (gimple_call call_stmt, struct cgraph_node *target)
     old call
  */
 
-gimple
-gimple_ic (gimple icall_stmt, struct cgraph_node *direct_call,
+gimple_call
+gimple_ic (gimple_call icall_stmt, struct cgraph_node *direct_call,
 	   int prob, gcov_type count, gcov_type all)
 {
-  gimple dcall_stmt;
+  gimple_call dcall_stmt;
   gimple_assign load_stmt;
   gimple_cond cond_stmt;
   tree tmp0, tmp1, tmp;
@@ -1407,7 +1407,7 @@  gimple_ic (gimple icall_stmt, struct cgraph_node *direct_call,
   gimple_set_vdef (icall_stmt, NULL_TREE);
   gimple_set_vuse (icall_stmt, NULL_TREE);
   update_stmt (icall_stmt);
-  dcall_stmt = gimple_copy (icall_stmt);
+  dcall_stmt = as_a <gimple_call> (gimple_copy (icall_stmt));
   gimple_call_set_fndecl (dcall_stmt, direct_call->decl);
   dflags = flags_from_decl_or_type (direct_call->decl);
   if ((dflags & ECF_NORETURN) != 0)
diff --git a/gcc/value-prof.h b/gcc/value-prof.h
index 00a89fa..dec879b 100644
--- a/gcc/value-prof.h
+++ b/gcc/value-prof.h
@@ -90,7 +90,8 @@  void gimple_move_stmt_histograms (struct function *, gimple, gimple);
 void verify_histograms (void);
 void free_histograms (void);
 void stringop_block_profile (gimple, unsigned int *, HOST_WIDE_INT *);
-gimple gimple_ic (gimple, struct cgraph_node *, int, gcov_type, gcov_type);
+gimple_call gimple_ic (gimple_call, struct cgraph_node *, int, gcov_type,
+		       gcov_type);
 
 
 /* In tree-profile.c.  */