From f4d00610b22cee78e879357a90c9e96d65bc2b13 Mon Sep 17 00:00:00 2001
From: David Malcolm <dmalcolm@redhat.com>
Date: Wed, 26 Mar 2014 17:12:36 -0400
Subject: [PATCH 18/88] Introduce gimple_call

gcc/
	* coretypes.h (gimple_call): New typedef.
	(const_gimple_call): New typedef.

	* gimple.h (gimple_call_reset_alias_info): Require a gimple_call
	rather than a plain gimple.
	(gimple_call_set_internal_fn): Likewise.
	(gimple_call_set_chain): Likewise.

	(gimple_call_set_return_slot_opt): Likewise; remove redundant
	GIMPLE_CHECK.
	(gimple_call_set_from_thunk): Likewise.
	(gimple_call_from_thunk_p): Likewise.
	(gimple_call_set_va_arg_pack): Likewise.
	(gimple_call_va_arg_pack_p): Likewise.
	(gimple_call_set_alloca_for_var): Likewise.
	(gimple_call_alloca_for_var_p): Likewise.

	(gimple_build_call_vec): Return a gimple_call rather than a gimple.
	(gimple_build_call): Likewise.
	(gimple_build_call_valist): Likewise.
	(gimple_build_call_internal): Likewise.
	(gimple_build_call_internal_vec): Likewise.
	(gimple_build_call_from_tree): Likewise.
	(gimple_call_copy_skip_args): Likewise.

	(gimple_call_return_flags): Require a const_gimple_call rather than
	a plain const_gimple.
	(gimple_call_chain_ptr): Likewise.

	(gimple_expr_type): Introduce local "call_stmt", once we know we have
	a GIMPLE_CALL.

	* asan.c (get_mem_refs_of_builtin_call): Require a const_gimple_call
	rather than a plain const_gimple.
	(has_stmt_been_instrumented_p): Add checked cast to gimple_call in
	region where stmt is known to be a GIMPLE_CALL (owing to it being
	a builtin call).
	(instrument_strlen_call): Add checked cast to gimple_call.
	(instrument_builtin_call): Likewise.

	* builtins.c (validate_gimple_arglist): Require a const_gimple_call
	rather than a plain const_gimple.
	(gimple_fold_builtin_sprintf_chk): Require a gimple_call rather than
	a plain gimple.
	(gimple_fold_builtin_snprintf_chk): Likewise.
	(gimple_fold_builtin_varargs): Likewise.
	(fold_call_stmt): Likewise.

	* builtins.h (validate_gimple_arglist): Require a const_gimple_call
	rather than a plain const_gimple.

	* cfgexpand.c (expand_call_stmt): Require a gimple_call rather
	than a plain gimple.
	(expand_gimple_stmt_1): Add a checked cast to gimple_call within
	GIMPLE_CALL case of switch statement.

	* cgraph.c (cgraph_redirect_edge_call_stmt_to_callee): Strengthen
	"new_stmt" from gimple to gimple_call; add checked cast.

	* cgraphunit.c (expand_thunk): Strengthen local "call" from gimple
	to a gimple_call.

	* gimple-fold.c (gimple_fold_builtin): Require a gimple_call rather
	than a plain gimple.
	(gimple_fold_call): Strengthen local "call" from gimple to a
	gimple_call.
	(gimple_fold_stmt_to_constant_1): Add a checked cast to gimple_call
	within GIMPLE_CALL case of switch statement.

	* gimple-fold.h (gimple_fold_builtin): Require a gimple_call rather
	than a plain gimple.

	* gimple-pretty-print.c (dump_gimple_call_args): Likewise.
	(dump_gimple_call): Likewise.
	(pp_gimple_stmt_1): Add a checked cast to gimple_call within
	GIMPLE_CALL case of switch statement.

	* gimple-streamer-in.c (input_gimple_stmt): Replace is_gimple_call
	with dyn_cast <gimple_call> and a new local.  Add a checked cast to
	gimple_call when resetting alias information.

	* gimple-walk.c (walk_gimple_op): Add a checked cast to gimple_call
	within GIMPLE_CALL case of switch statement.

	* gimple.c (gimple_call_reset_alias_info): Require a gimple_call
	rather than a plain gimple.
	(gimple_build_call_1): Return a gimple_call rather than a gimple.
	(gimple_build_call_vec): Likewise.
	(gimple_build_call): Likewise.
	(gimple_build_call_valist): Likewise.
	(gimple_build_call_internal_1): Likewise.
	(gimple_build_call_internal): Likewise.
	(gimple_build_call_internal_vec): Likewise.
	(gimple_build_call_from_tree): Likewise.
	(gimple_call_copy_skip_args): Likewise.
	(gimple_call_return_flags): Require a const_gimple_call
	rather than a plain const_gimple.

	* gimplify.c (gimplify_call_expr): Convert local from gimple to
	gimple_call.
	(gimplify_modify_expr_to_memcpy): Likewise.
	(gimplify_modify_expr_to_memset): Likewise.
	(gimplify_expr): Likewise.
	(gimplify_function_tree): Likewise.
	(gimplify_modify_expr): Add checked cast to gimple_call.

	* internal-fn.def: Update comment to indicate that each
	expand_NAME now takes a gimple_call, rather than just a gimple.

	* internal-fn.c (expand_LOAD_LANES): Require a gimple_call
	rather than a plain gimple.
	(expand_STORE_LANES): Likewise.
	(expand_ANNOTATE): Likewise.
	(expand_GOMP_SIMD_LANE): Likewise.
	(expand_GOMP_SIMD_VF): Likewise.
	(expand_GOMP_SIMD_LAST_LANE): Likewise.
	(expand_UBSAN_NULL): Likewise.
	(ubsan_expand_si_overflow_addsub_check): Likewise.
	(ubsan_expand_si_overflow_neg_check): Likewise.
	(ubsan_expand_si_overflow_mul_check): Likewise.
	(expand_UBSAN_CHECK_ADD): Likewise.
	(expand_UBSAN_CHECK_SUB): Likewise.
	(expand_UBSAN_CHECK_MUL): Likewise.
	(expand_LOOP_VECTORIZED): Likewise.
	(expand_MASK_LOAD): Likewise.
	(expand_MASK_STORE): Likewise.
	(expand_ABNORMAL_DISPATCHER): Likewise.
	(expand_BUILTIN_EXPECT): Likewise.
	(internal_fn_expanders): Likewise.
	(expand_internal_call): Likewise.

	* internal-fn.h (expand_internal_call): Likewise.

	* ipa-prop.c (ipa_modify_call_arguments): Convert local from
	gimple to gimple_call.

	* ipa-pure-const.c (check_call): Require a gimple_call rather than
	just a gimple.
	(check_stmt): Add checked cast to gimple_call within GIMPLE_CALL
	case of switch statement.

	* ipa-split.c (split_function): Convert local from gimple to
	gimple_call.

	* omp-low.c (build_omp_barrier): Likewise.
	(lower_rec_input_clauses): Likewise.

	* trans-mem.c (build_tm_load): Return a gimple_call rather than a
	plain gimple.
	(build_tm_store): Likewise.
	(expand_transaction): Convert local from gimple to gimple_call.

	* tree-call-cdce.c (check_pow): Require a gimple_call rather than
	just a gimple.
	(check_builtin_call): Likewise.
	(is_call_dce_candidate): Likewise.
	(gen_conditions_for_pow): Likewise.
	(gen_shrink_wrap_conditions): Likewise.
	(shrink_wrap_one_built_in_call): Likewise.
	(shrink_wrap_conditional_dead_built_in_calls): Require a
	vec<gimple_call> rather than a vec<gimple>.
	(tree_call_cdce): Convert local "cond_dead_built_in_calls" from
	an auto_vec<gimple> to an auto_vec<gimple_call>; convert invocation
	of is_gimple_call to dyn_cast <gimple_call> and new local.

	* tree-cfg.c (notice_special_calls): Require a gimple_call rather
	than just a gimple.
	* tree-cfg.h (notice_special_calls): Require a gimple_call rather
	than just a gimple.

	* tree-complex.c (expand_complex_libcall): Convert local from
	gimple to gimple_call.

	* tree-inline.c (remap_gimple_stmt): Add checked cast to
	gimple_call.
	(copy_bb): Likewise; convert local from gimple to gimple_call.
	(inline_forbidden_p_stmt): Add checked cast to gimple_call.

	* tree-nested.c (init_tmp_var_with_call): Require a gimple_call
	rather than a gimple.
	(convert_nl_goto_reference): Convert local from gimple to
	gimple_call.
	(convert_tramp_reference_op): Likewise.
	(convert_gimple_call): Add checked cast to gimple_call.

	* tree-nrv.c (dest_safe_for_nrv_p): Require a gimple_call
	rather than a gimple.
	(execute_return_slot_opt): Convert local from gimple to
	gimple_call.  Convert is_gimple_call to dyn_cast <gimple_call>
	and new local.

	* tree-object-size.c (alloc_object_size): Require a
	const_gimple_call rather than a plain const_gimple.
	(pass_through_call): Likewise.
	(call_object_size): Require a gimple_call rather than a plain
	gimple.
	(collect_object_sizes_for): Add checked cast to gimple_call within
	GIMPLE_CALL case of switch statement.
	(check_for_plus_in_loops_1): Likewise.
	(compute_object_sizes): Add checked cast to gimple_call.

	* tree-profile.c (gimple_gen_interval_profiler): Convert local
	from gimple_call to gimple.
	(gimple_gen_pow2_profiler): Likewise.
	(gimple_gen_one_value_profiler): Likewise.
	(gimple_gen_time_profiler): Likewise.
	(gimple_gen_average_profiler): Likewise.
	(gimple_gen_ior_profiler): Likewise.

	* tree-ssa-alias.c (ref_maybe_used_by_call_p_1): Require a
	gimple_call rather than a plain gimple.
	(ref_maybe_used_by_call_p): Likewise.
	(ref_maybe_used_by_stmt_p): Add checked cast to gimple_call.
	(call_may_clobber_ref_p_1): Require a gimple_call rather than a
	plain gimple.
	(call_may_clobber_ref_p): Likewise.
	(stmt_may_clobber_ref_p_1): Add checked cast to gimple_call.

	* tree-ssa-alias.h (call_may_clobber_ref_p): Require a gimple_call
	rather than a plain gimple.

	* tree-ssa-ccp.c (execute_fold_all_builtins): Add checked cast to
	gimple_call.

	* tree-ssa-dce.c (eliminate_unnecessary_stmts): Likewise.

	* tree-ssa-loop-prefetch.c (emit_mfence_after_loop): Convert local
	from gimple to gimple_call.

	* tree-ssa-math-opts.c (build_and_insert_call): Likewise.
	(execute_optimize_bswap): Likewise.

	* tree-ssa-operands.c (maybe_add_call_vops): Require a gimple_call
	rather than a plain gimple.
	(parse_ssa_operands): Add checked cast to gimple_call within
	GIMPLE_CALL case of switch statement.

	* tree-ssa-pre.c (compute_avail): Add checked cast to gimple_call.

	* tree-ssa-sccvn.c (copy_reference_ops_from_call): Require a
	gimple_call rather than a plain gimple.
	(create_reference_ops_from_call): Likewise.
	(valueize_shared_reference_ops_from_call): Likewise.
	(visit_reference_op_call): Likewise.
	(visit_use): Replace is_gimple_call with dyn_cast <gimple_call> and
	a new local.

	* tree-ssa-sccvn.h  (copy_reference_ops_from_call): Require a
	gimple_call rather than a plain gimple.

	* tree-ssa-structalias.c (get_call_vi): Likewise.
	(lookup_call_use_vi): Likewise.
	(lookup_call_clobber_vi): Likewise.
	(get_call_use_vi): Likewise.
	(get_call_clobber_vi): Likewise.
	(handle_rhs_call): Likewise.
	(handle_lhs_call): Likewise.
	(handle_const_call): Likewise.
	(handle_pure_call): Likewise.
	(get_fi_for_callee): Likewise.
	(find_func_aliases_for_builtin_call): Likewise.
	(find_func_aliases_for_call): Likewise.
	(find_func_aliases): Add checked cast to gimple_call.
	(find_func_clobbers): Replace is_gimple_call with
	dyn_cast <gimple_call> and a new local.
	(compute_points_to_sets): Likewise.
	(ipa_pta_execute): Likewise.

	* tree-ssa-threadedge.c
	(record_temporary_equivalences_from_stmts_at_dest): Add checked cast
	to gimple_call.

	* tree-tailcall.c (find_tail_calls): Convert local from gimple to
	gimple_call.  Add checked cast to gimple_call.

	* tree-vect-data-refs.c (vect_setup_realignment): Split local
	new_stmt into two with more tight scopes, one as a gimple_assign,
	the other as a gimple_call.

	* tree-vect-patterns.c (vect_recog_pow_pattern): Convert local to a
	gimple_bind.

	* tree-vect-stmts.c (vectorizable_function): Require a gimple_call
	rather than a plain gimple.
	(vectorizable_call): Convert "stmt" to a gimple_call, by renaming
	parameter, and making stmt be the result of a dyn_cast.

	* tree-vectorizer.h (vectorizable_function): Require a gimple_call
	rather than a plain gimple.

	* tree.h (fold_call_stmt): Likewise.
	(gimple_fold_builtin_snprintf_chk): Likewise.

	* value-prof.c (check_ic_target): Likewise.
	(gimple_ic_transform): Replace check for GIMPLE_CALL with
	dyn_cast <gimple_call>.
	(interesting_stringop_to_profile_p): Require a gimple_call rather
	than a plain gimple.
	(gimple_stringop_fixed_value): Likewise.
	(gimple_stringops_transform): Replace check for GIMPLE_CALL with
	dyn_cast <gimple_call>.
	(gimple_stringops_values_to_profile): Likewise.

	* vtable-verify.c (verify_bb_vtables): Convert local from a gimple
	to a gimple_call.
---
 gcc/asan.c                   |  8 ++---
 gcc/builtins.c               |  4 +--
 gcc/builtins.h               |  4 +--
 gcc/cfgexpand.c              |  4 +--
 gcc/cgraph.c                 |  4 +--
 gcc/cgraphunit.c             |  2 +-
 gcc/coretypes.h              |  4 +++
 gcc/gimple-fold.c            | 14 +++++----
 gcc/gimple-pretty-print.c    |  6 ++--
 gcc/gimple-streamer-in.c     | 10 +++---
 gcc/gimple-walk.c            |  3 +-
 gcc/gimple.c                 | 44 +++++++++++++++------------
 gcc/gimple.h                 | 72 +++++++++++++++++++-------------------------
 gcc/gimplify.c               | 12 ++++----
 gcc/internal-fn.c            | 46 ++++++++++++++--------------
 gcc/internal-fn.def          |  2 +-
 gcc/internal-fn.h            |  2 +-
 gcc/ipa-prop.c               |  2 +-
 gcc/ipa-pure-const.c         |  4 +--
 gcc/ipa-split.c              |  2 +-
 gcc/omp-low.c                |  4 +--
 gcc/trans-mem.c              | 10 +++---
 gcc/tree-call-cdce.c         | 25 ++++++++-------
 gcc/tree-cfg.c               |  2 +-
 gcc/tree-cfg.h               |  2 +-
 gcc/tree-complex.c           |  3 +-
 gcc/tree-inline.c            | 10 +++---
 gcc/tree-nested.c            | 11 ++++---
 gcc/tree-nrv.c               |  7 +++--
 gcc/tree-object-size.c       | 20 ++++++------
 gcc/tree-profile.c           | 12 ++++----
 gcc/tree-ssa-alias.c         | 12 ++++----
 gcc/tree-ssa-alias.h         |  4 +--
 gcc/tree-ssa-dce.c           |  2 +-
 gcc/tree-ssa-loop-prefetch.c |  2 +-
 gcc/tree-ssa-math-opts.c     |  2 +-
 gcc/tree-ssa-operands.c      |  4 +--
 gcc/tree-ssa-pre.c           |  2 +-
 gcc/tree-ssa-sccvn.c         | 17 ++++++-----
 gcc/tree-ssa-sccvn.h         |  2 +-
 gcc/tree-ssa-structalias.c   | 45 ++++++++++++++-------------
 gcc/tree-ssa-threadedge.c    |  2 +-
 gcc/tree-tailcall.c          |  7 +++--
 gcc/tree-vect-data-refs.c    |  3 +-
 gcc/tree-vect-patterns.c     |  2 +-
 gcc/tree-vect-stmts.c        | 14 +++++----
 gcc/tree-vectorizer.h        |  2 +-
 gcc/value-prof.c             | 22 ++++++++------
 gcc/vtable-verify.c          |  2 +-
 49 files changed, 259 insertions(+), 242 deletions(-)

diff --git a/gcc/asan.c b/gcc/asan.c
index 7bef0a6..e3e1de1 100644
--- a/gcc/asan.c
+++ b/gcc/asan.c
@@ -482,7 +482,7 @@ get_mem_ref_of_assignment (const_gimple_assign assignment,
    representing a builtin call that has to do with memory access.  */
 
 static bool
-get_mem_refs_of_builtin_call (const gimple call,
+get_mem_refs_of_builtin_call (const_gimple_call call,
 			      asan_mem_ref *src0,
 			      tree *src0_len,
 			      bool *src0_is_store,
@@ -836,7 +836,7 @@ has_stmt_been_instrumented_p (gimple stmt)
       tree src0_len = NULL_TREE, src1_len = NULL_TREE, dest_len = NULL_TREE;
       bool src0_is_store = false, src1_is_store = false,
 	dest_is_store = false, dest_is_deref = false;
-      if (get_mem_refs_of_builtin_call (stmt,
+      if (get_mem_refs_of_builtin_call (as_a <gimple_call> (stmt),
 					&src0, &src0_len, &src0_is_store,
 					&src1, &src1_len, &src1_is_store,
 					&dest, &dest_len, &dest_is_store,
@@ -1842,7 +1842,7 @@ static bool
 instrument_strlen_call (gimple_stmt_iterator *iter)
 {
   gimple g;
-  gimple call = gsi_stmt (*iter);
+  gimple_call call = as_a <gimple_call> (gsi_stmt (*iter));
   gcc_assert (is_gimple_call (call));
 
   tree callee = gimple_call_fndecl (call);
@@ -1905,7 +1905,7 @@ instrument_builtin_call (gimple_stmt_iterator *iter)
     return false;
 
   bool iter_advanced_p = false;
-  gimple call = gsi_stmt (*iter);
+  gimple_call call = as_a <gimple_call> (gsi_stmt (*iter));
 
   gcc_checking_assert (gimple_call_builtin_p (call, BUILT_IN_NORMAL));
 
diff --git a/gcc/builtins.c b/gcc/builtins.c
index 975f696..b571b7d 100644
--- a/gcc/builtins.c
+++ b/gcc/builtins.c
@@ -10631,7 +10631,7 @@ validate_arg (const_tree arg, enum tree_code code)
    validate_arglist will then be removed.  */
 
 bool
-validate_gimple_arglist (const_gimple call, ...)
+validate_gimple_arglist (const_gimple_call call, ...)
 {
   enum tree_code code;
   bool res = 0;
@@ -12541,7 +12541,7 @@ do_mpc_arg2 (tree arg0, tree arg1, tree type, int do_nonfinite,
    call node earlier than the warning is generated.  */
 
 tree
-fold_call_stmt (gimple stmt, bool ignore)
+fold_call_stmt (gimple_call stmt, bool ignore)
 {
   tree ret = NULL_TREE;
   tree fndecl = gimple_call_fndecl (stmt);
diff --git a/gcc/builtins.h b/gcc/builtins.h
index dd1cdbc..d93422e 100644
--- a/gcc/builtins.h
+++ b/gcc/builtins.h
@@ -75,11 +75,11 @@ extern tree fold_fma (location_t, tree, tree, tree, tree);
 extern bool avoid_folding_inline_builtin (tree);
 extern tree fold_call_expr (location_t, tree, bool);
 extern tree fold_builtin_call_array (location_t, tree, tree, int, tree *);
-extern bool validate_gimple_arglist (const_gimple, ...);
+extern bool validate_gimple_arglist (const_gimple_call, ...);
 extern rtx default_expand_builtin (tree, rtx, rtx, enum machine_mode, int);
 extern bool fold_builtin_next_arg (tree, bool);
 extern tree do_mpc_arg2 (tree, tree, tree, int, int (*)(mpc_ptr, mpc_srcptr, mpc_srcptr, mpc_rnd_t));
-extern tree fold_call_stmt (gimple, bool);
+extern tree fold_call_stmt (gimple_call, bool);
 extern void set_builtin_user_assembler_name (tree decl, const char *asmspec);
 extern bool is_simple_builtin (tree);
 extern bool is_inexpensive_builtin (tree);
diff --git a/gcc/cfgexpand.c b/gcc/cfgexpand.c
index 5799ef3..2e1d31b 100644
--- a/gcc/cfgexpand.c
+++ b/gcc/cfgexpand.c
@@ -2241,7 +2241,7 @@ mark_transaction_restart_calls (gimple stmt)
    statement STMT.  */
 
 static void
-expand_call_stmt (gimple stmt)
+expand_call_stmt (gimple_call stmt)
 {
   tree exp, decl, lhs;
   bool builtin_p;
@@ -3215,7 +3215,7 @@ expand_gimple_stmt_1 (gimple stmt)
       expand_asm_stmt (stmt);
       break;
     case GIMPLE_CALL:
-      expand_call_stmt (stmt);
+      expand_call_stmt (as_a <gimple_call> (stmt));
       break;
 
     case GIMPLE_RETURN:
diff --git a/gcc/cgraph.c b/gcc/cgraph.c
index fdcaf79..2ec2402 100644
--- a/gcc/cgraph.c
+++ b/gcc/cgraph.c
@@ -1241,7 +1241,7 @@ cgraph_edge::redirect_call_stmt_to_callee (void)
 
   tree decl = gimple_call_fndecl (e->call_stmt);
   tree lhs = gimple_call_lhs (e->call_stmt);
-  gimple new_stmt;
+  gimple_call new_stmt;
   gimple_stmt_iterator gsi;
 #ifdef ENABLE_CHECKING
   cgraph_node *node;
@@ -1378,7 +1378,7 @@ cgraph_edge::redirect_call_stmt_to_callee (void)
     }
   else
     {
-      new_stmt = e->call_stmt;
+      new_stmt = as_a <gimple_call> (e->call_stmt);
       gimple_call_set_fndecl (new_stmt, e->callee->decl);
       update_stmt_fn (DECL_STRUCT_FUNCTION (e->caller->decl), new_stmt);
     }
diff --git a/gcc/cgraphunit.c b/gcc/cgraphunit.c
index d463505..0304121 100644
--- a/gcc/cgraphunit.c
+++ b/gcc/cgraphunit.c
@@ -1494,7 +1494,7 @@ cgraph_node::expand_thunk (bool output_asm_thunks, bool force_gimple_thunk)
       tree resdecl;
       tree restmp = NULL;
 
-      gimple call;
+      gimple_call call;
       gimple ret;
 
       if (in_lto_p)
diff --git a/gcc/coretypes.h b/gcc/coretypes.h
index 9b5a007..4981e7c 100644
--- a/gcc/coretypes.h
+++ b/gcc/coretypes.h
@@ -110,6 +110,10 @@ struct gimple_statement_assign;
 typedef struct gimple_statement_assign *gimple_assign;
 typedef const struct gimple_statement_assign *const_gimple_assign;
 
+struct gimple_statement_call;
+typedef struct gimple_statement_call *gimple_call;
+typedef const struct gimple_statement_call *const_gimple_call;
+
 struct gimple_statement_bind;
 typedef struct gimple_statement_bind *gimple_bind;
 typedef const struct gimple_statement_bind *const_gimple_bind;
diff --git a/gcc/gimple-fold.c b/gcc/gimple-fold.c
index 1231647..1d8f0dcb 100644
--- a/gcc/gimple-fold.c
+++ b/gcc/gimple-fold.c
@@ -1970,7 +1970,7 @@ static bool
 gimple_fold_builtin_snprintf_chk (gimple_stmt_iterator *gsi,
 				  enum built_in_function fcode)
 {
-  gimple stmt = gsi_stmt (*gsi);
+  gimple_call stmt = as_a <gimple_call> (gsi_stmt (*gsi));
   tree dest, size, len, fn, fmt, flag;
   const char *fmt_str;
 
@@ -2273,7 +2273,7 @@ gimple_fold_builtin_sprintf (gimple_stmt_iterator *gsi)
 static bool
 gimple_fold_builtin_snprintf (gimple_stmt_iterator *gsi)
 {
-  gimple stmt = gsi_stmt (*gsi);
+  gimple_call stmt = as_a <gimple_call> (gsi_stmt (*gsi));
   tree dest = gimple_call_arg (stmt, 0);
   tree destsize = gimple_call_arg (stmt, 1);
   tree fmt = gimple_call_arg (stmt, 2);
@@ -2423,7 +2423,7 @@ gimple_fold_builtin_strlen (gimple_stmt_iterator *gsi)
 static bool
 gimple_fold_builtin (gimple_stmt_iterator *gsi)
 {
-  gimple stmt = gsi_stmt (*gsi);
+  gimple_call stmt = as_a <gimple_call >(gsi_stmt (*gsi));
   tree callee = gimple_call_fndecl (stmt);
 
   /* Give up for always_inline inline builtins until they are
@@ -2538,7 +2538,7 @@ gimple_fold_builtin (gimple_stmt_iterator *gsi)
 static bool
 gimple_fold_call (gimple_stmt_iterator *gsi, bool inplace)
 {
-  gimple stmt = gsi_stmt (*gsi);
+  gimple_call stmt = as_a <gimple_call> (gsi_stmt (*gsi));
   tree callee;
   bool changed = false;
   unsigned i;
@@ -4316,6 +4316,7 @@ gimple_fold_stmt_to_constant_1 (gimple stmt, tree (*valueize) (tree))
     case GIMPLE_CALL:
       {
 	tree fn;
+	gimple_call call_stmt = as_a <gimple_call> (stmt);
 
 	if (gimple_call_internal_p (stmt))
 	  {
@@ -4380,14 +4381,15 @@ gimple_fold_stmt_to_constant_1 (gimple stmt, tree (*valueize) (tree))
 	    for (i = 0; i < gimple_call_num_args (stmt); ++i)
 	      args[i] = (*valueize) (gimple_call_arg (stmt, i));
 	    call = build_call_array_loc (loc,
-					 gimple_call_return_type (stmt),
+					 gimple_call_return_type (call_stmt),
 					 fn, gimple_call_num_args (stmt), args);
 	    retval = fold_call_expr (EXPR_LOCATION (call), call, false);
 	    if (retval)
 	      {
 		/* fold_call_expr wraps the result inside a NOP_EXPR.  */
 		STRIP_NOPS (retval);
-		retval = fold_convert (gimple_call_return_type (stmt), retval);
+		retval = fold_convert (gimple_call_return_type (call_stmt),
+				       retval);
 	      }
 	    return retval;
 	  }
diff --git a/gcc/gimple-pretty-print.c b/gcc/gimple-pretty-print.c
index 34fa21e..aa2901c 100644
--- a/gcc/gimple-pretty-print.c
+++ b/gcc/gimple-pretty-print.c
@@ -579,7 +579,7 @@ dump_gimple_return (pretty_printer *buffer, gimple gs, int spc, int flags)
    dump_gimple_call.  */
 
 static void
-dump_gimple_call_args (pretty_printer *buffer, gimple gs, int flags)
+dump_gimple_call_args (pretty_printer *buffer, gimple_call gs, int flags)
 {
   size_t i;
 
@@ -652,7 +652,7 @@ pp_points_to_solution (pretty_printer *buffer, struct pt_solution *pt)
    pp_gimple_stmt_1.  */
 
 static void
-dump_gimple_call (pretty_printer *buffer, gimple gs, int spc, int flags)
+dump_gimple_call (pretty_printer *buffer, gimple_call gs, int spc, int flags)
 {
   tree lhs = gimple_call_lhs (gs);
   tree fn = gimple_call_fn (gs);
@@ -2123,7 +2123,7 @@ pp_gimple_stmt_1 (pretty_printer *buffer, gimple gs, int spc, int flags)
       break;
 
     case GIMPLE_CALL:
-      dump_gimple_call (buffer, gs, spc, flags);
+      dump_gimple_call (buffer, as_a <gimple_call> (gs), spc, flags);
       break;
 
     case GIMPLE_COND:
diff --git a/gcc/gimple-streamer-in.c b/gcc/gimple-streamer-in.c
index f7b5d01..2741ea7 100644
--- a/gcc/gimple-streamer-in.c
+++ b/gcc/gimple-streamer-in.c
@@ -185,13 +185,13 @@ input_gimple_stmt (struct lto_input_block *ib, struct data_in *data_in,
 		  == TREE_TYPE (TREE_OPERAND (TREE_OPERAND (*opp, 0), 0))))
 	    *opp = TREE_OPERAND (TREE_OPERAND (*opp, 0), 0);
 	}
-      if (is_gimple_call (stmt))
+      if (gimple_call call_stmt = dyn_cast <gimple_call> (stmt))
 	{
-	  if (gimple_call_internal_p (stmt))
+	  if (gimple_call_internal_p (call_stmt))
 	    gimple_call_set_internal_fn
-	      (stmt, streamer_read_enum (ib, internal_fn, IFN_LAST));
+	      (call_stmt, streamer_read_enum (ib, internal_fn, IFN_LAST));
 	  else
-	    gimple_call_set_fntype (stmt, stream_read_tree (ib, data_in));
+	    gimple_call_set_fntype (call_stmt, stream_read_tree (ib, data_in));
 	}
       break;
 
@@ -230,7 +230,7 @@ input_gimple_stmt (struct lto_input_block *ib, struct data_in *data_in,
 
   /* Reset alias information.  */
   if (code == GIMPLE_CALL)
-    gimple_call_reset_alias_info (stmt);
+    gimple_call_reset_alias_info (as_a <gimple_call> (stmt));
 
   /* Mark the statement modified so its operand vectors can be filled in.  */
   gimple_set_modified (stmt, true);
diff --git a/gcc/gimple-walk.c b/gcc/gimple-walk.c
index 830516e..661a69e 100644
--- a/gcc/gimple-walk.c
+++ b/gcc/gimple-walk.c
@@ -236,7 +236,8 @@ walk_gimple_op (gimple stmt, walk_tree_fn callback_op,
 	  wi->val_only = true;
 	}
 
-      ret = walk_tree (gimple_call_chain_ptr (stmt), callback_op, wi, pset);
+      ret = walk_tree (gimple_call_chain_ptr (as_a <gimple_call> (stmt)),
+		       callback_op, wi, pset);
       if (ret)
         return ret;
 
diff --git a/gcc/gimple.c b/gcc/gimple.c
index b99e0d4..5f5b33f 100644
--- a/gcc/gimple.c
+++ b/gcc/gimple.c
@@ -189,7 +189,7 @@ gimple_build_return (tree retval)
 /* Reset alias information on call S.  */
 
 void
-gimple_call_reset_alias_info (gimple s)
+gimple_call_reset_alias_info (gimple_call s)
 {
   if (gimple_call_flags (s) & ECF_CONST)
     memset (gimple_call_use_set (s), 0, sizeof (struct pt_solution));
@@ -206,10 +206,12 @@ gimple_call_reset_alias_info (gimple s)
    components of a GIMPLE_CALL statement to function FN with NARGS
    arguments.  */
 
-static inline gimple
+static inline gimple_call
 gimple_build_call_1 (tree fn, unsigned nargs)
 {
-  gimple s = gimple_build_with_ops (GIMPLE_CALL, ERROR_MARK, nargs + 3);
+  gimple_call s =
+    as_a <gimple_call> (gimple_build_with_ops (GIMPLE_CALL, ERROR_MARK,
+					       nargs + 3));
   if (TREE_CODE (fn) == FUNCTION_DECL)
     fn = build_fold_addr_expr (fn);
   gimple_set_op (s, 1, fn);
@@ -222,12 +224,12 @@ gimple_build_call_1 (tree fn, unsigned nargs)
 /* Build a GIMPLE_CALL statement to function FN with the arguments
    specified in vector ARGS.  */
 
-gimple
+gimple_call
 gimple_build_call_vec (tree fn, vec<tree> args)
 {
   unsigned i;
   unsigned nargs = args.length ();
-  gimple call = gimple_build_call_1 (fn, nargs);
+  gimple_call call = gimple_build_call_1 (fn, nargs);
 
   for (i = 0; i < nargs; i++)
     gimple_call_set_arg (call, i, args[i]);
@@ -239,11 +241,11 @@ gimple_build_call_vec (tree fn, vec<tree> args)
 /* Build a GIMPLE_CALL statement to function FN.  NARGS is the number of
    arguments.  The ... are the arguments.  */
 
-gimple
+gimple_call
 gimple_build_call (tree fn, unsigned nargs, ...)
 {
   va_list ap;
-  gimple call;
+  gimple_call call;
   unsigned i;
 
   gcc_assert (TREE_CODE (fn) == FUNCTION_DECL || is_gimple_call_addr (fn));
@@ -262,10 +264,10 @@ gimple_build_call (tree fn, unsigned nargs, ...)
 /* Build a GIMPLE_CALL statement to function FN.  NARGS is the number of
    arguments.  AP contains the arguments.  */
 
-gimple
+gimple_call
 gimple_build_call_valist (tree fn, unsigned nargs, va_list ap)
 {
-  gimple call;
+  gimple_call call;
   unsigned i;
 
   gcc_assert (TREE_CODE (fn) == FUNCTION_DECL || is_gimple_call_addr (fn));
@@ -283,10 +285,12 @@ gimple_build_call_valist (tree fn, unsigned nargs, va_list ap)
    Build the basic components of a GIMPLE_CALL statement to internal
    function FN with NARGS arguments.  */
 
-static inline gimple
+static inline gimple_call
 gimple_build_call_internal_1 (enum internal_fn fn, unsigned nargs)
 {
-  gimple s = gimple_build_with_ops (GIMPLE_CALL, ERROR_MARK, nargs + 3);
+  gimple_call s =
+    as_a <gimple_call> (gimple_build_with_ops (GIMPLE_CALL, ERROR_MARK,
+					       nargs + 3));
   s->subcode |= GF_CALL_INTERNAL;
   gimple_call_set_internal_fn (s, fn);
   gimple_call_reset_alias_info (s);
@@ -297,11 +301,11 @@ gimple_build_call_internal_1 (enum internal_fn fn, unsigned nargs)
 /* Build a GIMPLE_CALL statement to internal function FN.  NARGS is
    the number of arguments.  The ... are the arguments.  */
 
-gimple
+gimple_call
 gimple_build_call_internal (enum internal_fn fn, unsigned nargs, ...)
 {
   va_list ap;
-  gimple call;
+  gimple_call call;
   unsigned i;
 
   call = gimple_build_call_internal_1 (fn, nargs);
@@ -317,11 +321,11 @@ gimple_build_call_internal (enum internal_fn fn, unsigned nargs, ...)
 /* Build a GIMPLE_CALL statement to internal function FN with the arguments
    specified in vector ARGS.  */
 
-gimple
+gimple_call
 gimple_build_call_internal_vec (enum internal_fn fn, vec<tree> args)
 {
   unsigned i, nargs;
-  gimple call;
+  gimple_call call;
 
   nargs = args.length ();
   call = gimple_build_call_internal_1 (fn, nargs);
@@ -336,11 +340,11 @@ gimple_build_call_internal_vec (enum internal_fn fn, vec<tree> args)
    assumed to be in GIMPLE form already.  Minimal checking is done of
    this fact.  */
 
-gimple
+gimple_call
 gimple_build_call_from_tree (tree t)
 {
   unsigned i, nargs;
-  gimple call;
+  gimple_call call;
   tree fndecl = get_callee_fndecl (t);
 
   gcc_assert (TREE_CODE (t) == CALL_EXPR);
@@ -1403,7 +1407,7 @@ gimple_call_arg_flags (const_gimple stmt, unsigned arg)
 /* Detects return flags for the call STMT.  */
 
 int
-gimple_call_return_flags (const_gimple stmt)
+gimple_call_return_flags (const_gimple_call stmt)
 {
   const_tree attr;
 
@@ -2028,13 +2032,13 @@ canonicalize_cond_expr_cond (tree t)
 /* Build a GIMPLE_CALL identical to STMT but skipping the arguments in
    the positions marked by the set ARGS_TO_SKIP.  */
 
-gimple
+gimple_call
 gimple_call_copy_skip_args (gimple stmt, bitmap args_to_skip)
 {
   int i;
   int nargs = gimple_call_num_args (stmt);
   auto_vec<tree> vargs (nargs);
-  gimple new_stmt;
+  gimple_call new_stmt;
 
   for (i = 0; i < nargs; i++)
     if (!bitmap_bit_p (args_to_skip, i))
diff --git a/gcc/gimple.h b/gcc/gimple.h
index de0fae4..e68cc44 100644
--- a/gcc/gimple.h
+++ b/gcc/gimple.h
@@ -1261,13 +1261,13 @@ extern gimple currently_expanding_gimple_stmt;
 #define gimple_alloc(c, n) gimple_alloc_stat (c, n MEM_STAT_INFO)
 gimple gimple_alloc_stat (enum gimple_code, unsigned MEM_STAT_DECL);
 gimple gimple_build_return (tree);
-void gimple_call_reset_alias_info (gimple);
-gimple gimple_build_call_vec (tree, vec<tree> );
-gimple gimple_build_call (tree, unsigned, ...);
-gimple gimple_build_call_valist (tree, unsigned, va_list);
-gimple gimple_build_call_internal (enum internal_fn, unsigned, ...);
-gimple gimple_build_call_internal_vec (enum internal_fn, vec<tree> );
-gimple gimple_build_call_from_tree (tree);
+void gimple_call_reset_alias_info (gimple_call);
+gimple_call gimple_build_call_vec (tree, vec<tree> );
+gimple_call gimple_build_call (tree, unsigned, ...);
+gimple_call gimple_build_call_valist (tree, unsigned, va_list);
+gimple_call gimple_build_call_internal (enum internal_fn, unsigned, ...);
+gimple_call gimple_build_call_internal_vec (enum internal_fn, vec<tree> );
+gimple_call gimple_build_call_from_tree (tree);
 gimple_assign gimple_build_assign_stat (tree, tree MEM_STAT_DECL);
 #define gimple_build_assign(l,r) gimple_build_assign_stat (l, r MEM_STAT_INFO)
 gimple_assign gimple_build_assign_with_ops (enum tree_code, tree,
@@ -1333,7 +1333,7 @@ gimple_seq gimple_seq_copy (gimple_seq);
 bool gimple_call_same_target_p (const_gimple, const_gimple);
 int gimple_call_flags (const_gimple);
 int gimple_call_arg_flags (const_gimple, unsigned);
-int gimple_call_return_flags (const_gimple);
+int gimple_call_return_flags (const_gimple_call);
 bool gimple_assign_copy_p (gimple);
 bool gimple_assign_ssa_name_copy_p (gimple);
 bool gimple_assign_unary_nop_p (gimple);
@@ -1351,7 +1351,7 @@ bool gimple_assign_rhs_could_trap_p (gimple);
 extern void dump_gimple_statistics (void);
 unsigned get_gimple_rhs_num_ops (enum tree_code);
 extern tree canonicalize_cond_expr_cond (tree);
-gimple gimple_call_copy_skip_args (gimple, bitmap);
+gimple_call gimple_call_copy_skip_args (gimple, bitmap);
 extern bool gimple_compare_field_offset (tree, tree);
 extern tree gimple_unsigned_type (tree);
 extern tree gimple_signed_type (tree);
@@ -2657,13 +2657,12 @@ gimple_call_set_fndecl (gimple gs, tree decl)
 }
 
 
-/* Set internal function FN to be the function called by call statement GS.  */
+/* Set internal function FN to be the function called by call statement CALL_STMT.  */
 
 static inline void
-gimple_call_set_internal_fn (gimple gs, enum internal_fn fn)
+gimple_call_set_internal_fn (gimple_call call_stmt, enum internal_fn fn)
 {
-  gimple_statement_call *call_stmt = as_a <gimple_statement_call *> (gs);
-  gcc_gimple_checking_assert (gimple_call_internal_p (gs));
+  gcc_gimple_checking_assert (gimple_call_internal_p (call_stmt));
   call_stmt->u.internal_fn = fn;
 }
 
@@ -2682,7 +2681,7 @@ gimple_call_fndecl (const_gimple gs)
 /* Return the type returned by call statement GS.  */
 
 static inline tree
-gimple_call_return_type (const_gimple gs)
+gimple_call_return_type (const_gimple_call gs)
 {
   tree type = gimple_call_fntype (gs);
 
@@ -2705,23 +2704,20 @@ gimple_call_chain (const_gimple gs)
 }
 
 
-/* Return a pointer to the static chain for call statement GS.  */
+/* Return a pointer to the static chain for call statement CALL_STMT.  */
 
 static inline tree *
-gimple_call_chain_ptr (const_gimple gs)
+gimple_call_chain_ptr (const_gimple_call call_stmt)
 {
-  GIMPLE_CHECK (gs, GIMPLE_CALL);
-  return gimple_op_ptr (gs, 2);
+  return gimple_op_ptr (call_stmt, 2);
 }
 
-/* Set CHAIN to be the static chain for call statement GS.  */
+/* Set CHAIN to be the static chain for call statement CALL_STMT.  */
 
 static inline void
-gimple_call_set_chain (gimple gs, tree chain)
+gimple_call_set_chain (gimple_call call_stmt, tree chain)
 {
-  GIMPLE_CHECK (gs, GIMPLE_CALL);
-
-  gimple_set_op (gs, 2, chain);
+  gimple_set_op (call_stmt, 2, chain);
 }
 
 
@@ -2798,9 +2794,8 @@ gimple_call_tail_p (gimple s)
    expansion as the return slot for calls that return in memory.  */
 
 static inline void
-gimple_call_set_return_slot_opt (gimple s, bool return_slot_opt_p)
+gimple_call_set_return_slot_opt (gimple_call s, bool return_slot_opt_p)
 {
-  GIMPLE_CHECK (s, GIMPLE_CALL);
   if (return_slot_opt_p)
     s->subcode |= GF_CALL_RETURN_SLOT_OPT;
   else
@@ -2822,9 +2817,8 @@ gimple_call_return_slot_opt_p (gimple s)
    thunk to the thunked-to function.  */
 
 static inline void
-gimple_call_set_from_thunk (gimple s, bool from_thunk_p)
+gimple_call_set_from_thunk (gimple_call s, bool from_thunk_p)
 {
-  GIMPLE_CHECK (s, GIMPLE_CALL);
   if (from_thunk_p)
     s->subcode |= GF_CALL_FROM_THUNK;
   else
@@ -2835,9 +2829,8 @@ gimple_call_set_from_thunk (gimple s, bool from_thunk_p)
 /* Return true if GIMPLE_CALL S is a jump from a thunk.  */
 
 static inline bool
-gimple_call_from_thunk_p (gimple s)
+gimple_call_from_thunk_p (gimple_call s)
 {
-  GIMPLE_CHECK (s, GIMPLE_CALL);
   return (s->subcode & GF_CALL_FROM_THUNK) != 0;
 }
 
@@ -2846,9 +2839,8 @@ gimple_call_from_thunk_p (gimple s)
    argument pack in its argument list.  */
 
 static inline void
-gimple_call_set_va_arg_pack (gimple s, bool pass_arg_pack_p)
+gimple_call_set_va_arg_pack (gimple_call s, bool pass_arg_pack_p)
 {
-  GIMPLE_CHECK (s, GIMPLE_CALL);
   if (pass_arg_pack_p)
     s->subcode |= GF_CALL_VA_ARG_PACK;
   else
@@ -2860,9 +2852,8 @@ gimple_call_set_va_arg_pack (gimple s, bool pass_arg_pack_p)
    argument pack in its argument list.  */
 
 static inline bool
-gimple_call_va_arg_pack_p (gimple s)
+gimple_call_va_arg_pack_p (gimple_call s)
 {
-  GIMPLE_CHECK (s, GIMPLE_CALL);
   return (s->subcode & GF_CALL_VA_ARG_PACK) != 0;
 }
 
@@ -2905,9 +2896,8 @@ gimple_call_nothrow_p (gimple s)
    stack growth even when they occur in loops.  */
 
 static inline void
-gimple_call_set_alloca_for_var (gimple s, bool for_var)
+gimple_call_set_alloca_for_var (gimple_call s, bool for_var)
 {
-  GIMPLE_CHECK (s, GIMPLE_CALL);
   if (for_var)
     s->subcode |= GF_CALL_ALLOCA_FOR_VAR;
   else
@@ -2917,9 +2907,8 @@ gimple_call_set_alloca_for_var (gimple s, bool for_var)
 /* Return true of S is a call to builtin_alloca emitted for VLA objects.  */
 
 static inline bool
-gimple_call_alloca_for_var_p (gimple s)
+gimple_call_alloca_for_var_p (gimple_call s)
 {
-  GIMPLE_CHECK (s, GIMPLE_CALL);
   return (s->subcode & GF_CALL_ALLOCA_FOR_VAR) != 0;
 }
 
@@ -5762,11 +5751,12 @@ gimple_expr_type (const_gimple stmt)
 	 original RHS type as far as we can reconstruct it.  */
       if (code == GIMPLE_CALL)
 	{
-	  if (gimple_call_internal_p (stmt)
-	      && gimple_call_internal_fn (stmt) == IFN_MASK_STORE)
-	    type = TREE_TYPE (gimple_call_arg (stmt, 3));
+	  const_gimple_call call_stmt = as_a <const_gimple_call> (stmt);
+	  if (gimple_call_internal_p (call_stmt)
+	      && gimple_call_internal_fn (call_stmt) == IFN_MASK_STORE)
+	    type = TREE_TYPE (gimple_call_arg (call_stmt, 3));
 	  else
-	    type = gimple_call_return_type (stmt);
+	    type = gimple_call_return_type (call_stmt);
 	}
       else
 	switch (gimple_assign_rhs_code (stmt))
diff --git a/gcc/gimplify.c b/gcc/gimplify.c
index 9e01873..b99cda4 100644
--- a/gcc/gimplify.c
+++ b/gcc/gimplify.c
@@ -2252,7 +2252,7 @@ gimplify_call_expr (tree *expr_p, gimple_seq *pre_p, bool want_value)
   tree fndecl, parms, p, fnptrtype;
   enum gimplify_status ret;
   int i, nargs;
-  gimple call;
+  gimple_call call;
   bool builtin_va_start_p = false;
   location_t loc = EXPR_LOCATION (*expr_p);
 
@@ -3205,7 +3205,7 @@ gimplify_modify_expr_to_memcpy (tree *expr_p, tree size, bool want_value,
     				gimple_seq *seq_p)
 {
   tree t, to, to_ptr, from, from_ptr;
-  gimple gs;
+  gimple_call gs;
   location_t loc = EXPR_LOCATION (*expr_p);
 
   to = TREE_OPERAND (*expr_p, 0);
@@ -3252,7 +3252,7 @@ gimplify_modify_expr_to_memset (tree *expr_p, tree size, bool want_value,
     				gimple_seq *seq_p)
 {
   tree t, from, to, to_ptr;
-  gimple gs;
+  gimple_call gs;
   location_t loc = EXPR_LOCATION (*expr_p);
 
   /* Assert our assumptions, to abort instead of producing wrong code
@@ -4637,7 +4637,7 @@ gimplify_modify_expr (tree *expr_p, gimple_seq *pre_p, gimple_seq *post_p,
 	  assign = gimple_build_call_from_tree (*from_p);
 	  gimple_call_set_fntype (assign, TREE_TYPE (fnptrtype));
 	}
-      notice_special_calls (assign);
+      notice_special_calls (as_a <gimple_call> (assign));
       if (!gimple_call_noreturn_p (assign))
 	gimple_call_set_lhs (assign, *to_p);
     }
@@ -7728,7 +7728,7 @@ gimplify_expr (tree *expr_p, gimple_seq *pre_p, gimple_seq *post_p,
 	      }
 	    tree tmp = create_tmp_var (type, NULL);
 	    gimplify_arg (&cond, pre_p, EXPR_LOCATION (*expr_p));
-	    gimple call
+	    gimple_call call
 	      = gimple_build_call_internal (IFN_ANNOTATE, 2, cond, kind);
 	    gimple_call_set_lhs (call, tmp);
 	    gimplify_seq_add_stmt (pre_p, call);
@@ -8949,7 +8949,7 @@ gimplify_function_tree (tree fndecl)
       gimple tf;
       gimple_seq cleanup = NULL, body = NULL;
       tree tmp_var;
-      gimple call;
+      gimple_call call;
 
       x = builtin_decl_implicit (BUILT_IN_RETURN_ADDRESS);
       call = gimple_build_call (x, 1, integer_zero_node);
diff --git a/gcc/internal-fn.c b/gcc/internal-fn.c
index c2a44b6..8bcc5e0 100644
--- a/gcc/internal-fn.c
+++ b/gcc/internal-fn.c
@@ -90,7 +90,7 @@ get_multi_vector_move (tree array_type, convert_optab optab)
 /* Expand LOAD_LANES call STMT.  */
 
 static void
-expand_LOAD_LANES (gimple stmt)
+expand_LOAD_LANES (gimple_call stmt)
 {
   struct expand_operand ops[2];
   tree type, lhs, rhs;
@@ -114,7 +114,7 @@ expand_LOAD_LANES (gimple stmt)
 /* Expand STORE_LANES call STMT.  */
 
 static void
-expand_STORE_LANES (gimple stmt)
+expand_STORE_LANES (gimple_call stmt)
 {
   struct expand_operand ops[2];
   tree type, lhs, rhs;
@@ -136,7 +136,7 @@ expand_STORE_LANES (gimple stmt)
 }
 
 static void
-expand_ANNOTATE (gimple stmt ATTRIBUTE_UNUSED)
+expand_ANNOTATE (gimple_call stmt ATTRIBUTE_UNUSED)
 {
   gcc_unreachable ();
 }
@@ -144,7 +144,7 @@ expand_ANNOTATE (gimple stmt ATTRIBUTE_UNUSED)
 /* This should get expanded in adjust_simduid_builtins.  */
 
 static void
-expand_GOMP_SIMD_LANE (gimple stmt ATTRIBUTE_UNUSED)
+expand_GOMP_SIMD_LANE (gimple_call stmt ATTRIBUTE_UNUSED)
 {
   gcc_unreachable ();
 }
@@ -152,7 +152,7 @@ expand_GOMP_SIMD_LANE (gimple stmt ATTRIBUTE_UNUSED)
 /* This should get expanded in adjust_simduid_builtins.  */
 
 static void
-expand_GOMP_SIMD_VF (gimple stmt ATTRIBUTE_UNUSED)
+expand_GOMP_SIMD_VF (gimple_call stmt ATTRIBUTE_UNUSED)
 {
   gcc_unreachable ();
 }
@@ -160,7 +160,7 @@ expand_GOMP_SIMD_VF (gimple stmt ATTRIBUTE_UNUSED)
 /* This should get expanded in adjust_simduid_builtins.  */
 
 static void
-expand_GOMP_SIMD_LAST_LANE (gimple stmt ATTRIBUTE_UNUSED)
+expand_GOMP_SIMD_LAST_LANE (gimple_call stmt ATTRIBUTE_UNUSED)
 {
   gcc_unreachable ();
 }
@@ -168,7 +168,7 @@ expand_GOMP_SIMD_LAST_LANE (gimple stmt ATTRIBUTE_UNUSED)
 /* This should get expanded in the sanopt pass.  */
 
 static void
-expand_UBSAN_NULL (gimple stmt ATTRIBUTE_UNUSED)
+expand_UBSAN_NULL (gimple_call stmt ATTRIBUTE_UNUSED)
 {
   gcc_unreachable ();
 }
@@ -176,7 +176,7 @@ expand_UBSAN_NULL (gimple stmt ATTRIBUTE_UNUSED)
 /* This should get expanded in the sanopt pass.  */
 
 static void
-expand_UBSAN_BOUNDS (gimple stmt ATTRIBUTE_UNUSED)
+expand_UBSAN_BOUNDS (gimple_call stmt ATTRIBUTE_UNUSED)
 {
   gcc_unreachable ();
 }
@@ -184,7 +184,7 @@ expand_UBSAN_BOUNDS (gimple stmt ATTRIBUTE_UNUSED)
 /* This should get expanded in the sanopt pass.  */
 
 static void
-expand_ASAN_CHECK (gimple stmt ATTRIBUTE_UNUSED)
+expand_ASAN_CHECK (gimple_call stmt ATTRIBUTE_UNUSED)
 {
   gcc_unreachable ();
 }
@@ -193,7 +193,7 @@ expand_ASAN_CHECK (gimple stmt ATTRIBUTE_UNUSED)
    CODE says whether the operation is +, or -.  */
 
 void
-ubsan_expand_si_overflow_addsub_check (tree_code code, gimple stmt)
+ubsan_expand_si_overflow_addsub_check (tree_code code, gimple_call stmt)
 {
   rtx res, op0, op1;
   tree lhs, fn, arg0, arg1;
@@ -342,7 +342,7 @@ ubsan_expand_si_overflow_addsub_check (tree_code code, gimple stmt)
 /* Add negate overflow checking to the statement STMT.  */
 
 void
-ubsan_expand_si_overflow_neg_check (gimple stmt)
+ubsan_expand_si_overflow_neg_check (gimple_call stmt)
 {
   rtx res, op1;
   tree lhs, fn, arg1;
@@ -419,7 +419,7 @@ ubsan_expand_si_overflow_neg_check (gimple stmt)
 /* Add mul overflow checking to the statement STMT.  */
 
 void
-ubsan_expand_si_overflow_mul_check (gimple stmt)
+ubsan_expand_si_overflow_mul_check (gimple_call stmt)
 {
   rtx res, op0, op1;
   tree lhs, fn, arg0, arg1;
@@ -813,7 +813,7 @@ ubsan_expand_si_overflow_mul_check (gimple stmt)
 /* Expand UBSAN_CHECK_ADD call STMT.  */
 
 static void
-expand_UBSAN_CHECK_ADD (gimple stmt)
+expand_UBSAN_CHECK_ADD (gimple_call stmt)
 {
   ubsan_expand_si_overflow_addsub_check (PLUS_EXPR, stmt);
 }
@@ -821,7 +821,7 @@ expand_UBSAN_CHECK_ADD (gimple stmt)
 /* Expand UBSAN_CHECK_SUB call STMT.  */
 
 static void
-expand_UBSAN_CHECK_SUB (gimple stmt)
+expand_UBSAN_CHECK_SUB (gimple_call stmt)
 {
   if (integer_zerop (gimple_call_arg (stmt, 0)))
     ubsan_expand_si_overflow_neg_check (stmt);
@@ -832,7 +832,7 @@ expand_UBSAN_CHECK_SUB (gimple stmt)
 /* Expand UBSAN_CHECK_MUL call STMT.  */
 
 static void
-expand_UBSAN_CHECK_MUL (gimple stmt)
+expand_UBSAN_CHECK_MUL (gimple_call stmt)
 {
   ubsan_expand_si_overflow_mul_check (stmt);
 }
@@ -840,13 +840,13 @@ expand_UBSAN_CHECK_MUL (gimple stmt)
 /* This should get folded in tree-vectorizer.c.  */
 
 static void
-expand_LOOP_VECTORIZED (gimple stmt ATTRIBUTE_UNUSED)
+expand_LOOP_VECTORIZED (gimple_call stmt ATTRIBUTE_UNUSED)
 {
   gcc_unreachable ();
 }
 
 static void
-expand_MASK_LOAD (gimple stmt)
+expand_MASK_LOAD (gimple_call stmt)
 {
   struct expand_operand ops[3];
   tree type, lhs, rhs, maskt;
@@ -871,7 +871,7 @@ expand_MASK_LOAD (gimple stmt)
 }
 
 static void
-expand_MASK_STORE (gimple stmt)
+expand_MASK_STORE (gimple_call stmt)
 {
   struct expand_operand ops[3];
   tree type, lhs, rhs, maskt;
@@ -894,12 +894,12 @@ expand_MASK_STORE (gimple stmt)
 }
 
 static void
-expand_ABNORMAL_DISPATCHER (gimple)
+expand_ABNORMAL_DISPATCHER (gimple_call)
 {
 }
 
 static void
-expand_BUILTIN_EXPECT (gimple stmt)
+expand_BUILTIN_EXPECT (gimple_call stmt)
 {
   /* When guessing was done, the hints should be already stripped away.  */
   gcc_assert (!flag_guess_branch_prob || optimize == 0 || seen_error ());
@@ -918,10 +918,10 @@ expand_BUILTIN_EXPECT (gimple stmt)
 /* Routines to expand each internal function, indexed by function number.
    Each routine has the prototype:
 
-       expand_<NAME> (gimple stmt)
+       expand_<NAME> (gimple_call stmt)
 
    where STMT is the statement that performs the call. */
-static void (*const internal_fn_expanders[]) (gimple) = {
+static void (*const internal_fn_expanders[]) (gimple_call) = {
 #define DEF_INTERNAL_FN(CODE, FLAGS, FNSPEC) expand_##CODE,
 #include "internal-fn.def"
 #undef DEF_INTERNAL_FN
@@ -931,7 +931,7 @@ static void (*const internal_fn_expanders[]) (gimple) = {
 /* Expand STMT, which is a call to internal function FN.  */
 
 void
-expand_internal_call (gimple stmt)
+expand_internal_call (gimple_call stmt)
 {
   internal_fn_expanders[(int) gimple_call_internal_fn (stmt)] (stmt);
 }
diff --git a/gcc/internal-fn.def b/gcc/internal-fn.def
index 54ade9f..b4c2578 100644
--- a/gcc/internal-fn.def
+++ b/gcc/internal-fn.def
@@ -35,7 +35,7 @@ along with GCC; see the file COPYING3.  If not see
    
    Each entry must have a corresponding expander of the form:
 
-     void expand_NAME (gimple stmt)
+     void expand_NAME (gimple_call stmt)
 
    where STMT is the statement that performs the call.  */
 
diff --git a/gcc/internal-fn.h b/gcc/internal-fn.h
index 14573aa..390a6e9 100644
--- a/gcc/internal-fn.h
+++ b/gcc/internal-fn.h
@@ -57,6 +57,6 @@ internal_fn_fnspec (enum internal_fn fn)
   return internal_fn_fnspec_array[(int) fn];
 }
 
-extern void expand_internal_call (gimple);
+extern void expand_internal_call (gimple_call);
 
 #endif
diff --git a/gcc/ipa-prop.c b/gcc/ipa-prop.c
index 5ac5dc5..7a9c999 100644
--- a/gcc/ipa-prop.c
+++ b/gcc/ipa-prop.c
@@ -4102,7 +4102,7 @@ ipa_modify_call_arguments (struct cgraph_edge *cs, gimple stmt,
   struct cgraph_node *current_node = cgraph_node::get (current_function_decl);
   vec<tree> vargs;
   vec<tree, va_gc> **debug_args = NULL;
-  gimple new_stmt;
+  gimple_call new_stmt;
   gimple_stmt_iterator gsi, prev_gsi;
   tree callee_decl;
   int i, len;
diff --git a/gcc/ipa-pure-const.c b/gcc/ipa-pure-const.c
index b5ded3e..6beca09 100644
--- a/gcc/ipa-pure-const.c
+++ b/gcc/ipa-pure-const.c
@@ -465,7 +465,7 @@ special_builtin_state (enum pure_const_state_e *state, bool *looping,
    the entire call expression.  */
 
 static void
-check_call (funct_state local, gimple call, bool ipa)
+check_call (funct_state local, gimple_call call, bool ipa)
 {
   int flags = gimple_call_flags (call);
   tree callee_t = gimple_call_fndecl (call);
@@ -686,7 +686,7 @@ check_stmt (gimple_stmt_iterator *gsip, funct_state local, bool ipa)
   switch (gimple_code (stmt))
     {
     case GIMPLE_CALL:
-      check_call (local, stmt, ipa);
+      check_call (local, as_a <gimple_call> (stmt), ipa);
       break;
     case GIMPLE_LABEL:
       if (DECL_NONLOCAL (gimple_label_label (stmt)))
diff --git a/gcc/ipa-split.c b/gcc/ipa-split.c
index f57ce9c..572467c 100644
--- a/gcc/ipa-split.c
+++ b/gcc/ipa-split.c
@@ -1119,7 +1119,7 @@ split_function (struct split_point *split_point)
   basic_block return_bb = find_return_bb ();
   basic_block call_bb;
   gimple_stmt_iterator gsi;
-  gimple call;
+  gimple_call call;
   edge e;
   edge_iterator ei;
   tree retval = NULL, real_retval = NULL;
diff --git a/gcc/omp-low.c b/gcc/omp-low.c
index ffec0d0..0a4f572 100644
--- a/gcc/omp-low.c
+++ b/gcc/omp-low.c
@@ -2884,7 +2884,7 @@ build_omp_barrier (tree lhs)
 {
   tree fndecl = builtin_decl_explicit (lhs ? BUILT_IN_GOMP_BARRIER_CANCEL
 					   : BUILT_IN_GOMP_BARRIER);
-  gimple g = gimple_build_call (fndecl, 0);
+  gimple_call g = gimple_build_call (fndecl, 0);
   if (lhs)
     gimple_call_set_lhs (g, lhs);
   return g;
@@ -3347,7 +3347,7 @@ lower_rec_input_clauses (tree clauses, gimple_seq *ilist, gimple_seq *dlist,
 
 	      if (c_kind != OMP_CLAUSE_FIRSTPRIVATE || !is_task_ctx (ctx))
 		{
-		  gimple stmt;
+		  gimple_call stmt;
 		  tree tmp, atmp;
 
 		  ptr = DECL_VALUE_EXPR (new_var);
diff --git a/gcc/trans-mem.c b/gcc/trans-mem.c
index 883efbb..fe8be6c 100644
--- a/gcc/trans-mem.c
+++ b/gcc/trans-mem.c
@@ -2084,12 +2084,12 @@ transaction_subcode_ior (struct tm_region *region, unsigned flags)
 
    LOC is the location to use for the new statement(s).  */
 
-static gimple
+static gimple_call
 build_tm_load (location_t loc, tree lhs, tree rhs, gimple_stmt_iterator *gsi)
 {
   enum built_in_function code = END_BUILTINS;
   tree t, type = TREE_TYPE (rhs), decl;
-  gimple gcall;
+  gimple_call gcall;
 
   if (type == float_type_node)
     code = BUILT_IN_TM_LOAD_FLOAT;
@@ -2156,12 +2156,12 @@ build_tm_load (location_t loc, tree lhs, tree rhs, gimple_stmt_iterator *gsi)
 
 /* Similarly for storing TYPE in a transactional context.  */
 
-static gimple
+static gimple_call
 build_tm_store (location_t loc, tree lhs, tree rhs, gimple_stmt_iterator *gsi)
 {
   enum built_in_function code = END_BUILTINS;
   tree t, fn, type = TREE_TYPE (rhs), simple_type;
-  gimple gcall;
+  gimple_call gcall;
 
   if (type == float_type_node)
     code = BUILT_IN_TM_STORE_FLOAT;
@@ -2717,7 +2717,7 @@ expand_transaction (struct tm_region *region, void *data ATTRIBUTE_UNUSED)
     if (subcode & GTMA_IS_OUTER)
       region->original_transaction_was_outer = true;
     tree t = build_int_cst (tm_state_type, flags);
-    gimple call = gimple_build_call (tm_start, 1, t);
+    gimple_call call = gimple_build_call (tm_start, 1, t);
     gimple_call_set_lhs (call, tm_state);
     gimple_set_location (call, gimple_location (region->transaction_stmt));
 
diff --git a/gcc/tree-call-cdce.c b/gcc/tree-call-cdce.c
index 65027e8..0a2f563 100644
--- a/gcc/tree-call-cdce.c
+++ b/gcc/tree-call-cdce.c
@@ -174,7 +174,7 @@ check_target_format (tree arg)
 #define MAX_BASE_INT_BIT_SIZE 32
 
 static bool
-check_pow (gimple pow_call)
+check_pow (gimple_call pow_call)
 {
   tree base, expn;
   enum tree_code bc, ec;
@@ -248,7 +248,7 @@ check_pow (gimple pow_call)
    Returns true if the function call is a candidate.  */
 
 static bool
-check_builtin_call (gimple bcall)
+check_builtin_call (gimple_call bcall)
 {
   tree arg;
 
@@ -261,7 +261,7 @@ check_builtin_call (gimple bcall)
    is a candidate.  */
 
 static bool
-is_call_dce_candidate (gimple call)
+is_call_dce_candidate (gimple_call call)
 {
   tree fn;
   enum built_in_function fnc;
@@ -537,7 +537,7 @@ gen_conditions_for_pow_int_base (tree base, tree expn,
    and *NCONDS is the number of logical conditions.  */
 
 static void
-gen_conditions_for_pow (gimple pow_call, vec<gimple> conds,
+gen_conditions_for_pow (gimple_call pow_call, vec<gimple> conds,
                         unsigned *nconds)
 {
   tree base, expn;
@@ -673,10 +673,10 @@ get_no_error_domain (enum built_in_function fnc)
    condition are separated by NULL tree in the vector.  */
 
 static void
-gen_shrink_wrap_conditions (gimple bi_call, vec<gimple> conds,
+gen_shrink_wrap_conditions (gimple_call bi_call, vec<gimple> conds,
                             unsigned int *nconds)
 {
-  gimple call;
+  gimple_call call;
   tree fn;
   enum built_in_function fnc;
 
@@ -714,7 +714,7 @@ gen_shrink_wrap_conditions (gimple bi_call, vec<gimple> conds,
    transformation actually happens.  */
 
 static bool
-shrink_wrap_one_built_in_call (gimple bi_call)
+shrink_wrap_one_built_in_call (gimple_call bi_call)
 {
   gimple_stmt_iterator bi_call_bsi;
   basic_block bi_call_bb, join_tgt_bb, guard_bb, guard_bb0;
@@ -849,7 +849,7 @@ shrink_wrap_one_built_in_call (gimple bi_call)
    wrapping transformation.  */
 
 static bool
-shrink_wrap_conditional_dead_built_in_calls (vec<gimple> calls)
+shrink_wrap_conditional_dead_built_in_calls (vec<gimple_call> calls)
 {
   bool changed = false;
   unsigned i = 0;
@@ -860,7 +860,7 @@ shrink_wrap_conditional_dead_built_in_calls (vec<gimple> calls)
 
   for (; i < n ; i++)
     {
-      gimple bi_call = calls[i];
+      gimple_call bi_call = calls[i];
       changed |= shrink_wrap_one_built_in_call (bi_call);
     }
 
@@ -909,15 +909,14 @@ pass_call_cdce::execute (function *fun)
   basic_block bb;
   gimple_stmt_iterator i;
   bool something_changed = false;
-  auto_vec<gimple> cond_dead_built_in_calls;
+  auto_vec<gimple_call> cond_dead_built_in_calls;
   FOR_EACH_BB_FN (bb, fun)
     {
       /* Collect dead call candidates.  */
       for (i = gsi_start_bb (bb); !gsi_end_p (i); gsi_next (&i))
         {
-	  gimple stmt = gsi_stmt (i);
-          if (is_gimple_call (stmt)
-              && is_call_dce_candidate (stmt))
+	  gimple_call stmt = dyn_cast <gimple_call> (gsi_stmt (i));
+          if (stmt && is_call_dce_candidate (stmt))
             {
               if (dump_file && (dump_flags & TDF_DETAILS))
                 {
diff --git a/gcc/tree-cfg.c b/gcc/tree-cfg.c
index f3e804e..819c36e 100644
--- a/gcc/tree-cfg.c
+++ b/gcc/tree-cfg.c
@@ -1952,7 +1952,7 @@ single_noncomplex_succ (basic_block bb)
 /* T is CALL_EXPR.  Set current_function_calls_* flags.  */
 
 void
-notice_special_calls (gimple call)
+notice_special_calls (gimple_call call)
 {
   int flags = gimple_call_flags (call);
 
diff --git a/gcc/tree-cfg.h b/gcc/tree-cfg.h
index 2be38df..20a2e06 100644
--- a/gcc/tree-cfg.h
+++ b/gcc/tree-cfg.h
@@ -36,7 +36,7 @@ extern void group_case_labels_stmt (gimple_switch);
 extern void group_case_labels (void);
 extern void replace_uses_by (tree, tree);
 extern basic_block single_noncomplex_succ (basic_block bb);
-extern void notice_special_calls (gimple);
+extern void notice_special_calls (gimple_call);
 extern void clear_special_calls (void);
 extern edge find_taken_edge (basic_block, tree);
 extern void gimple_debug_bb (basic_block);
diff --git a/gcc/tree-complex.c b/gcc/tree-complex.c
index 25dcad8..c259504 100644
--- a/gcc/tree-complex.c
+++ b/gcc/tree-complex.c
@@ -950,7 +950,8 @@ expand_complex_libcall (gimple_stmt_iterator *gsi, tree ar, tree ai,
   enum machine_mode mode;
   enum built_in_function bcode;
   tree fn, type, lhs;
-  gimple old_stmt, stmt;
+  gimple old_stmt;
+  gimple_call stmt;
 
   old_stmt = gsi_stmt (*gsi);
   lhs = gimple_assign_lhs (old_stmt);
diff --git a/gcc/tree-inline.c b/gcc/tree-inline.c
index 593c02d..5ecdfe3 100644
--- a/gcc/tree-inline.c
+++ b/gcc/tree-inline.c
@@ -1563,7 +1563,7 @@ remap_gimple_stmt (gimple stmt, copy_body_data *id)
 		 keep it valid over inlining by setting DECL_PT_UID.  */
 	      if (!id->src_cfun->gimple_df
 		  || !id->src_cfun->gimple_df->ipa_pta)
-		gimple_call_reset_alias_info (copy);
+		gimple_call_reset_alias_info (as_a <gimple_call> (copy));
 	    }
 	    break;
 
@@ -1705,13 +1705,13 @@ copy_bb (copy_body_data *id, basic_block bb, int frequency_scale,
 
 	  stmt = gsi_stmt (copy_gsi);
 	  if (is_gimple_call (stmt)
-	      && gimple_call_va_arg_pack_p (stmt)
+	      && gimple_call_va_arg_pack_p (as_a <gimple_call> (stmt))
 	      && id->gimple_call)
 	    {
 	      /* __builtin_va_arg_pack () should be replaced by
 		 all arguments corresponding to ... in the caller.  */
 	      tree p;
-	      gimple new_call;
+	      gimple_call new_call;
 	      vec<tree> argarray;
 	      size_t nargs = gimple_call_num_args (id->gimple_call);
 	      size_t n;
@@ -1913,7 +1913,7 @@ copy_bb (copy_body_data *id, basic_block bb, int frequency_scale,
 		    }
 		}
 
-	      notice_special_calls (stmt);
+	      notice_special_calls (as_a <gimple_call> (stmt));
 	    }
 
 	  maybe_duplicate_eh_stmt_fn (cfun, stmt, id->src_cfun, orig_stmt,
@@ -3393,7 +3393,7 @@ inline_forbidden_p_stmt (gimple_stmt_iterator *gsi, bool *handled_ops_p,
 	 VLA objects as those can't cause unbounded growth (they're always
 	 wrapped inside stack_save/stack_restore regions.  */
       if (gimple_alloca_call_p (stmt)
-	  && !gimple_call_alloca_for_var_p (stmt)
+	  && !gimple_call_alloca_for_var_p (as_a <gimple_call> (stmt))
 	  && !lookup_attribute ("always_inline", DECL_ATTRIBUTES (fn)))
 	{
 	  inline_forbidden_reason
diff --git a/gcc/tree-nested.c b/gcc/tree-nested.c
index 1f54a07..3caa335 100644
--- a/gcc/tree-nested.c
+++ b/gcc/tree-nested.c
@@ -408,7 +408,7 @@ get_chain_field (struct nesting_info *info)
 
 static tree
 init_tmp_var_with_call (struct nesting_info *info, gimple_stmt_iterator *gsi,
-		        gimple call)
+		        gimple_call call)
 {
   tree t;
 
@@ -2063,7 +2063,7 @@ convert_nl_goto_reference (gimple_stmt_iterator *gsi, bool *handled_ops_p,
 {
   struct nesting_info *const info = (struct nesting_info *) wi->info, *i;
   tree label, new_label, target_context, x, field;
-  gimple call;
+  gimple_call call;
   gimple stmt = gsi_stmt (*gsi);
 
   if (gimple_code (stmt) != GIMPLE_GOTO)
@@ -2180,7 +2180,7 @@ convert_tramp_reference_op (tree *tp, int *walk_subtrees, void *data)
   struct walk_stmt_info *wi = (struct walk_stmt_info *) data;
   struct nesting_info *const info = (struct nesting_info *) wi->info, *i;
   tree t = *tp, decl, target_context, x, builtin;
-  gimple call;
+  gimple_call call;
 
   *walk_subtrees = 0;
   switch (TREE_CODE (t))
@@ -2329,8 +2329,9 @@ convert_gimple_call (gimple_stmt_iterator *gsi, bool *handled_ops_p,
       target_context = decl_function_context (decl);
       if (target_context && DECL_STATIC_CHAIN (decl))
 	{
-	  gimple_call_set_chain (stmt, get_static_chain (info, target_context,
-							 &wi->gsi));
+	  gimple_call_set_chain (as_a <gimple_call> (stmt),
+				 get_static_chain (info, target_context,
+						   &wi->gsi));
 	  info->static_chain_added |= (1 << (info->context != target_context));
 	}
       break;
diff --git a/gcc/tree-nrv.c b/gcc/tree-nrv.c
index f2f3147..e989f91 100644
--- a/gcc/tree-nrv.c
+++ b/gcc/tree-nrv.c
@@ -316,7 +316,7 @@ make_pass_nrv (gcc::context *ctxt)
    DEST is available if it is not clobbered or used by the call.  */
 
 static bool
-dest_safe_for_nrv_p (gimple call)
+dest_safe_for_nrv_p (gimple_call call)
 {
   tree dest = gimple_call_lhs (call);
 
@@ -383,10 +383,11 @@ pass_return_slot::execute (function *fun)
       gimple_stmt_iterator gsi;
       for (gsi = gsi_start_bb (bb); !gsi_end_p (gsi); gsi_next (&gsi))
 	{
-	  gimple stmt = gsi_stmt (gsi);
+	  gimple_call stmt;
 	  bool slot_opt_p;
 
-	  if (is_gimple_call (stmt)
+	  stmt = dyn_cast <gimple_call> (gsi_stmt (gsi));
+	  if (stmt
 	      && gimple_call_lhs (stmt)
 	      && !gimple_call_return_slot_opt_p (stmt)
 	      && aggregate_value_p (TREE_TYPE (gimple_call_lhs (stmt)),
diff --git a/gcc/tree-object-size.c b/gcc/tree-object-size.c
index 220ad1f..27633e2 100644
--- a/gcc/tree-object-size.c
+++ b/gcc/tree-object-size.c
@@ -59,8 +59,8 @@ static const unsigned HOST_WIDE_INT unknown[4] = { -1, -1, 0, 0 };
 static tree compute_object_offset (const_tree, const_tree);
 static unsigned HOST_WIDE_INT addr_object_size (struct object_size_info *,
 						const_tree, int);
-static unsigned HOST_WIDE_INT alloc_object_size (const_gimple, int);
-static tree pass_through_call (const_gimple);
+static unsigned HOST_WIDE_INT alloc_object_size (const_gimple_call, int);
+static tree pass_through_call (const_gimple_call);
 static void collect_object_sizes_for (struct object_size_info *, tree);
 static void expr_object_size (struct object_size_info *, tree, tree);
 static bool merge_object_sizes (struct object_size_info *, tree, tree,
@@ -392,7 +392,7 @@ addr_object_size (struct object_size_info *osi, const_tree ptr,
    unknown[object_size_type].  */
 
 static unsigned HOST_WIDE_INT
-alloc_object_size (const_gimple call, int object_size_type)
+alloc_object_size (const_gimple_call call, int object_size_type)
 {
   tree callee, bytes = NULL_TREE;
   tree alloc_size;
@@ -455,7 +455,7 @@ alloc_object_size (const_gimple call, int object_size_type)
    Otherwise return NULL.  */
 
 static tree
-pass_through_call (const_gimple call)
+pass_through_call (const_gimple_call call)
 {
   tree callee = gimple_call_fndecl (call);
 
@@ -669,7 +669,7 @@ expr_object_size (struct object_size_info *osi, tree ptr, tree value)
 /* Compute object_sizes for PTR, defined to the result of a call.  */
 
 static void
-call_object_size (struct object_size_info *osi, tree ptr, gimple call)
+call_object_size (struct object_size_info *osi, tree ptr, gimple_call call)
 {
   int object_size_type = osi->object_size_type;
   unsigned int varno = SSA_NAME_VERSION (ptr);
@@ -966,7 +966,8 @@ collect_object_sizes_for (struct object_size_info *osi, tree var)
 
     case GIMPLE_CALL:
       {
-        tree arg = pass_through_call (stmt);
+	gimple_call call_stmt = as_a <gimple_call> (stmt);
+        tree arg = pass_through_call (call_stmt);
         if (arg)
           {
             if (TREE_CODE (arg) == SSA_NAME
@@ -976,7 +977,7 @@ collect_object_sizes_for (struct object_size_info *osi, tree var)
               expr_object_size (osi, var, arg);
           }
         else
-          call_object_size (osi, var, stmt);
+          call_object_size (osi, var, call_stmt);
 	break;
       }
 
@@ -1102,7 +1103,8 @@ check_for_plus_in_loops_1 (struct object_size_info *osi, tree var,
 
     case GIMPLE_CALL:
       {
-        tree arg = pass_through_call (stmt);
+	gimple_call call_stmt = as_a <gimple_call> (stmt);
+        tree arg = pass_through_call (call_stmt);
         if (arg)
           {
             if (TREE_CODE (arg) == SSA_NAME)
@@ -1250,7 +1252,7 @@ pass_object_sizes::execute (function *fun)
 	    continue;
 
 	  init_object_sizes ();
-	  result = fold_call_stmt (call, false);
+	  result = fold_call_stmt (as_a <gimple_call> (call), false);
 	  if (!result)
 	    {
 	      if (gimple_call_num_args (call) == 2
diff --git a/gcc/tree-profile.c b/gcc/tree-profile.c
index ba90196..d9b9b6b 100644
--- a/gcc/tree-profile.c
+++ b/gcc/tree-profile.c
@@ -326,7 +326,7 @@ gimple_gen_interval_profiler (histogram_value value, unsigned tag, unsigned base
   gimple stmt = value->hvalue.stmt;
   gimple_stmt_iterator gsi = gsi_for_stmt (stmt);
   tree ref = tree_coverage_counter_ref (tag, base), ref_ptr;
-  gimple call;
+  gimple_call call;
   tree val;
   tree start = build_int_cst_type (integer_type_node,
 				   value->hdata.intvl.int_start);
@@ -352,7 +352,7 @@ gimple_gen_pow2_profiler (histogram_value value, unsigned tag, unsigned base)
   gimple stmt = value->hvalue.stmt;
   gimple_stmt_iterator gsi = gsi_for_stmt (stmt);
   tree ref_ptr = tree_coverage_counter_addr (tag, base);
-  gimple call;
+  gimple_call call;
   tree val;
 
   ref_ptr = force_gimple_operand_gsi (&gsi, ref_ptr,
@@ -372,7 +372,7 @@ gimple_gen_one_value_profiler (histogram_value value, unsigned tag, unsigned bas
   gimple stmt = value->hvalue.stmt;
   gimple_stmt_iterator gsi = gsi_for_stmt (stmt);
   tree ref_ptr = tree_coverage_counter_addr (tag, base);
-  gimple call;
+  gimple_call call;
   tree val;
 
   ref_ptr = force_gimple_operand_gsi (&gsi, ref_ptr,
@@ -490,7 +490,7 @@ gimple_gen_time_profiler (unsigned tag, unsigned base,
                           gimple_stmt_iterator &gsi)
 {
   tree ref_ptr = tree_coverage_counter_addr (tag, base);
-  gimple call;
+  gimple_call call;
 
   ref_ptr = force_gimple_operand_gsi (&gsi, ref_ptr,
 				      true, NULL_TREE, true, GSI_SAME_STMT);
@@ -525,7 +525,7 @@ gimple_gen_average_profiler (histogram_value value, unsigned tag, unsigned base)
   gimple stmt = value->hvalue.stmt;
   gimple_stmt_iterator gsi = gsi_for_stmt (stmt);
   tree ref_ptr = tree_coverage_counter_addr (tag, base);
-  gimple call;
+  gimple_call call;
   tree val;
 
   ref_ptr = force_gimple_operand_gsi (&gsi, ref_ptr,
@@ -546,7 +546,7 @@ gimple_gen_ior_profiler (histogram_value value, unsigned tag, unsigned base)
   gimple stmt = value->hvalue.stmt;
   gimple_stmt_iterator gsi = gsi_for_stmt (stmt);
   tree ref_ptr = tree_coverage_counter_addr (tag, base);
-  gimple call;
+  gimple_call call;
   tree val;
 
   ref_ptr = force_gimple_operand_gsi (&gsi, ref_ptr,
diff --git a/gcc/tree-ssa-alias.c b/gcc/tree-ssa-alias.c
index 1bf88e2..611b16f 100644
--- a/gcc/tree-ssa-alias.c
+++ b/gcc/tree-ssa-alias.c
@@ -1477,7 +1477,7 @@ refs_output_dependent_p (tree store1, tree store2)
    otherwise return false.  */
 
 static bool
-ref_maybe_used_by_call_p_1 (gimple call, ao_ref *ref)
+ref_maybe_used_by_call_p_1 (gimple_call call, ao_ref *ref)
 {
   tree base, callee;
   unsigned i;
@@ -1790,7 +1790,7 @@ process_args:
 }
 
 static bool
-ref_maybe_used_by_call_p (gimple call, ao_ref *ref)
+ref_maybe_used_by_call_p (gimple_call call, ao_ref *ref)
 {
   bool res;
   res = ref_maybe_used_by_call_p_1 (call, ref);
@@ -1825,7 +1825,7 @@ ref_maybe_used_by_stmt_p (gimple stmt, ao_ref *ref)
       return refs_may_alias_p (rhs, ref);
     }
   else if (is_gimple_call (stmt))
-    return ref_maybe_used_by_call_p (stmt, ref);
+    return ref_maybe_used_by_call_p (as_a <gimple_call> (stmt), ref);
   else if (gimple_code (stmt) == GIMPLE_RETURN)
     {
       tree retval = gimple_return_retval (stmt);
@@ -1861,7 +1861,7 @@ ref_maybe_used_by_stmt_p (gimple stmt, tree ref)
    return true, otherwise return false.  */
 
 bool
-call_may_clobber_ref_p_1 (gimple call, ao_ref *ref)
+call_may_clobber_ref_p_1 (gimple_call call, ao_ref *ref)
 {
   tree base;
   tree callee;
@@ -2134,7 +2134,7 @@ call_may_clobber_ref_p_1 (gimple call, ao_ref *ref)
    return true, otherwise return false.  */
 
 bool
-call_may_clobber_ref_p (gimple call, tree ref)
+call_may_clobber_ref_p (gimple_call call, tree ref)
 {
   bool res;
   ao_ref r;
@@ -2166,7 +2166,7 @@ stmt_may_clobber_ref_p_1 (gimple stmt, ao_ref *ref)
 	    return true;
 	}
 
-      return call_may_clobber_ref_p_1 (stmt, ref);
+      return call_may_clobber_ref_p_1 (as_a <gimple_call> (stmt), ref);
     }
   else if (gimple_assign_single_p (stmt))
     {
diff --git a/gcc/tree-ssa-alias.h b/gcc/tree-ssa-alias.h
index 0d35283..42395bd 100644
--- a/gcc/tree-ssa-alias.h
+++ b/gcc/tree-ssa-alias.h
@@ -112,8 +112,8 @@ extern bool ref_maybe_used_by_stmt_p (gimple, ao_ref *);
 extern bool stmt_may_clobber_global_p (gimple);
 extern bool stmt_may_clobber_ref_p (gimple, tree);
 extern bool stmt_may_clobber_ref_p_1 (gimple, ao_ref *);
-extern bool call_may_clobber_ref_p (gimple, tree);
-extern bool call_may_clobber_ref_p_1 (gimple, ao_ref *);
+extern bool call_may_clobber_ref_p (gimple_call, tree);
+extern bool call_may_clobber_ref_p_1 (gimple_call, ao_ref *);
 extern bool stmt_kills_ref_p (gimple, tree);
 extern bool stmt_kills_ref_p (gimple, ao_ref *);
 extern tree get_continuation_for_phi (gimple, ao_ref *,
diff --git a/gcc/tree-ssa-dce.c b/gcc/tree-ssa-dce.c
index 70b405c..f95c0ea 100644
--- a/gcc/tree-ssa-dce.c
+++ b/gcc/tree-ssa-dce.c
@@ -1221,7 +1221,7 @@ eliminate_unnecessary_stmts (void)
 	    {
 	      tree name = gimple_call_lhs (stmt);
 
-	      notice_special_calls (stmt);
+	      notice_special_calls (as_a <gimple_call> (stmt));
 
 	      /* When LHS of var = call (); is dead, simplify it into
 		 call (); saving one operand.  */
diff --git a/gcc/tree-ssa-loop-prefetch.c b/gcc/tree-ssa-loop-prefetch.c
index 29b02f0..a8127d5 100644
--- a/gcc/tree-ssa-loop-prefetch.c
+++ b/gcc/tree-ssa-loop-prefetch.c
@@ -1244,7 +1244,7 @@ emit_mfence_after_loop (struct loop *loop)
 {
   vec<edge> exits = get_loop_exit_edges (loop);
   edge exit;
-  gimple call;
+  gimple_call call;
   gimple_stmt_iterator bsi;
   unsigned i;
 
diff --git a/gcc/tree-ssa-math-opts.c b/gcc/tree-ssa-math-opts.c
index 3c6e935..3495a76 100644
--- a/gcc/tree-ssa-math-opts.c
+++ b/gcc/tree-ssa-math-opts.c
@@ -1065,7 +1065,7 @@ static tree
 build_and_insert_call (gimple_stmt_iterator *gsi, location_t loc,
 		       tree fn, tree arg)
 {
-  gimple call_stmt;
+  gimple_call call_stmt;
   tree ssa_target;
 
   call_stmt = gimple_build_call (fn, 1, arg);
diff --git a/gcc/tree-ssa-operands.c b/gcc/tree-ssa-operands.c
index a7ccf04..1e59b76 100644
--- a/gcc/tree-ssa-operands.c
+++ b/gcc/tree-ssa-operands.c
@@ -634,7 +634,7 @@ get_tmr_operands (struct function *fn, gimple stmt, tree expr, int flags)
    escape, add them to the VDEF/VUSE lists for it.  */
 
 static void
-maybe_add_call_vops (struct function *fn, gimple stmt)
+maybe_add_call_vops (struct function *fn, gimple_call stmt)
 {
   int call_flags = gimple_call_flags (stmt);
 
@@ -930,7 +930,7 @@ parse_ssa_operands (struct function *fn, gimple stmt)
 
     case GIMPLE_CALL:
       /* Add call-clobbered operands, if needed.  */
-      maybe_add_call_vops (fn, stmt);
+      maybe_add_call_vops (fn, as_a <gimple_call> (stmt));
       /* FALLTHRU */
 
     case GIMPLE_ASSIGN:
diff --git a/gcc/tree-ssa-pre.c b/gcc/tree-ssa-pre.c
index f82f341..817f240 100644
--- a/gcc/tree-ssa-pre.c
+++ b/gcc/tree-ssa-pre.c
@@ -3689,7 +3689,7 @@ compute_avail (void)
 		if (gimple_call_internal_p (stmt))
 		  continue;
 
-		vn_reference_lookup_call (stmt, &ref, &ref1);
+		vn_reference_lookup_call (as_a <gimple_call> (stmt), &ref, &ref1);
 		if (!ref)
 		  continue;
 
diff --git a/gcc/tree-ssa-sccvn.c b/gcc/tree-ssa-sccvn.c
index f1fd0f5..4f0ab06 100644
--- a/gcc/tree-ssa-sccvn.c
+++ b/gcc/tree-ssa-sccvn.c
@@ -1119,7 +1119,7 @@ ao_ref_init_from_vn_reference (ao_ref *ref,
    vn_reference_op_s's.  */
 
 static void
-copy_reference_ops_from_call (gimple call,
+copy_reference_ops_from_call (gimple_call call,
 			      vec<vn_reference_op_s> *result)
 {
   vn_reference_op_s temp;
@@ -1443,7 +1443,7 @@ valueize_shared_reference_ops_from_ref (tree ref, bool *valueized_anything)
    this function.  */
 
 static vec<vn_reference_op_s> 
-valueize_shared_reference_ops_from_call (gimple call)
+valueize_shared_reference_ops_from_call (gimple_call call)
 {
   if (!call)
     return vNULL;
@@ -1617,7 +1617,8 @@ vn_reference_lookup_3 (ao_ref *ref, tree vuse, void *vr_,
 	}
       if (valueized_anything)
 	{
-	  bool res = call_may_clobber_ref_p_1 (def_stmt, ref);
+	  bool res = call_may_clobber_ref_p_1 (as_a <gimple_call> (def_stmt),
+					       ref);
 	  for (unsigned i = 0; i < gimple_call_num_args (def_stmt); ++i)
 	    gimple_call_set_arg (def_stmt, i, oldargs[i]);
 	  if (!res)
@@ -2143,7 +2144,7 @@ vn_reference_lookup (tree op, tree vuse, vn_lookup_kind kind,
    *VNRESULT if found.  Populates *VR for the hashtable lookup.  */
 
 void
-vn_reference_lookup_call (gimple call, vn_reference_t *vnresult,
+vn_reference_lookup_call (gimple_call call, vn_reference_t *vnresult,
 			  vn_reference_t vr)
 {
   if (vnresult)
@@ -2846,7 +2847,7 @@ visit_nary_op (tree lhs, gimple stmt)
    of the LHS has changed as a result.  */
 
 static bool
-visit_reference_op_call (tree lhs, gimple stmt)
+visit_reference_op_call (tree lhs, gimple_call stmt)
 {
   bool changed = false;
   struct vn_reference_s vr1;
@@ -3580,7 +3581,7 @@ visit_use (tree use)
 	  else
 	    changed = defs_to_varying (stmt);
 	}
-      else if (is_gimple_call (stmt))
+      else if (gimple_call call_stmt = dyn_cast <gimple_call> (stmt))
 	{
 	  tree lhs = gimple_call_lhs (stmt);
 	  if (lhs && TREE_CODE (lhs) == SSA_NAME)
@@ -3666,11 +3667,11 @@ visit_use (tree use)
 		         not alias with anything else.  In which case the
 			 information that the values are distinct are encoded
 			 in the IL.  */
-		      && !(gimple_call_return_flags (stmt) & ERF_NOALIAS)
+		      && !(gimple_call_return_flags (call_stmt) & ERF_NOALIAS)
 		      /* Only perform the following when being called from PRE
 			 which embeds tail merging.  */
 		      && default_vn_walk_kind == VN_WALK)))
-	    changed = visit_reference_op_call (lhs, stmt);
+	    changed = visit_reference_op_call (lhs, call_stmt);
 	  else
 	    changed = defs_to_varying (stmt);
 	}
diff --git a/gcc/tree-ssa-sccvn.h b/gcc/tree-ssa-sccvn.h
index ad99604..e3def8a 100644
--- a/gcc/tree-ssa-sccvn.h
+++ b/gcc/tree-ssa-sccvn.h
@@ -210,7 +210,7 @@ tree vn_reference_lookup_pieces (tree, alias_set_type, tree,
 				 vec<vn_reference_op_s> ,
 				 vn_reference_t *, vn_lookup_kind);
 tree vn_reference_lookup (tree, tree, vn_lookup_kind, vn_reference_t *);
-void vn_reference_lookup_call (gimple, vn_reference_t *, vn_reference_t);
+void vn_reference_lookup_call (gimple_call, vn_reference_t *, vn_reference_t);
 vn_reference_t vn_reference_insert_pieces (tree, alias_set_type, tree,
 					   vec<vn_reference_op_s> ,
 					   tree, unsigned int);
diff --git a/gcc/tree-ssa-structalias.c b/gcc/tree-ssa-structalias.c
index 0169087..4bde124 100644
--- a/gcc/tree-ssa-structalias.c
+++ b/gcc/tree-ssa-structalias.c
@@ -397,7 +397,7 @@ static hash_map<gimple, varinfo_t> *call_stmt_vars;
 /* Lookup or create the variable for the call statement CALL.  */
 
 static varinfo_t
-get_call_vi (gimple call)
+get_call_vi (gimple_call call)
 {
   varinfo_t vi, vi2;
 
@@ -428,7 +428,7 @@ get_call_vi (gimple call)
    the uses.  Returns NULL if there is nothing special about this call.  */
 
 static varinfo_t
-lookup_call_use_vi (gimple call)
+lookup_call_use_vi (gimple_call call)
 {
   varinfo_t *slot_p = call_stmt_vars->get (call);
   if (slot_p)
@@ -441,7 +441,7 @@ lookup_call_use_vi (gimple call)
    the clobbers.  Returns NULL if there is nothing special about this call.  */
 
 static varinfo_t
-lookup_call_clobber_vi (gimple call)
+lookup_call_clobber_vi (gimple_call call)
 {
   varinfo_t uses = lookup_call_use_vi (call);
   if (!uses)
@@ -454,7 +454,7 @@ lookup_call_clobber_vi (gimple call)
    the uses.  */
 
 static varinfo_t
-get_call_use_vi (gimple call)
+get_call_use_vi (gimple_call call)
 {
   return get_call_vi (call);
 }
@@ -463,7 +463,7 @@ get_call_use_vi (gimple call)
    the clobbers.  */
 
 static varinfo_t ATTRIBUTE_UNUSED
-get_call_clobber_vi (gimple call)
+get_call_clobber_vi (gimple_call call)
 {
   return vi_next (get_call_vi (call));
 }
@@ -3842,7 +3842,7 @@ get_function_part_constraint (varinfo_t fi, unsigned part)
    RHS.  */
 
 static void
-handle_rhs_call (gimple stmt, vec<ce_s> *results)
+handle_rhs_call (gimple_call stmt, vec<ce_s> *results)
 {
   struct constraint_expr rhsc;
   unsigned i;
@@ -3944,7 +3944,7 @@ handle_rhs_call (gimple stmt, vec<ce_s> *results)
    the LHS point to global and escaped variables.  */
 
 static void
-handle_lhs_call (gimple stmt, tree lhs, int flags, vec<ce_s> rhsc,
+handle_lhs_call (gimple_call stmt, tree lhs, int flags, vec<ce_s> rhsc,
 		 tree fndecl)
 {
   auto_vec<ce_s> lhsc;
@@ -4007,7 +4007,7 @@ handle_lhs_call (gimple stmt, tree lhs, int flags, vec<ce_s> rhsc,
    const function that returns a pointer in the statement STMT.  */
 
 static void
-handle_const_call (gimple stmt, vec<ce_s> *results)
+handle_const_call (gimple_call stmt, vec<ce_s> *results)
 {
   struct constraint_expr rhsc;
   unsigned int k;
@@ -4048,7 +4048,7 @@ handle_const_call (gimple stmt, vec<ce_s> *results)
    pure function in statement STMT.  */
 
 static void
-handle_pure_call (gimple stmt, vec<ce_s> *results)
+handle_pure_call (gimple_call stmt, vec<ce_s> *results)
 {
   struct constraint_expr rhsc;
   unsigned i;
@@ -4095,7 +4095,7 @@ handle_pure_call (gimple stmt, vec<ce_s> *results)
 /* Return the varinfo for the callee of CALL.  */
 
 static varinfo_t
-get_fi_for_callee (gimple call)
+get_fi_for_callee (gimple_call call)
 {
   tree decl, fn = gimple_call_fn (call);
 
@@ -4126,7 +4126,7 @@ get_fi_for_callee (gimple call)
    was handled, otherwise false.  */
 
 static bool
-find_func_aliases_for_builtin_call (struct function *fn, gimple t)
+find_func_aliases_for_builtin_call (struct function *fn, gimple_call t)
 {
   tree fndecl = gimple_call_fndecl (t);
   auto_vec<ce_s, 2> lhsc;
@@ -4484,7 +4484,7 @@ find_func_aliases_for_builtin_call (struct function *fn, gimple t)
 /* Create constraints for the call T.  */
 
 static void
-find_func_aliases_for_call (struct function *fn, gimple t)
+find_func_aliases_for_call (struct function *fn, gimple_call t)
 {
   tree fndecl = gimple_call_fndecl (t);
   varinfo_t fi;
@@ -4647,7 +4647,7 @@ find_func_aliases (struct function *fn, gimple origt)
      In non-ipa mode, we need to generate constraints for each
      pointer passed by address.  */
   else if (is_gimple_call (t))
-    find_func_aliases_for_call (fn, t);
+    find_func_aliases_for_call (fn, as_a <gimple_call> (t));
     
   /* Otherwise, just a regular assignment statement.  Only care about
      operations with pointer result, others are dealt with as escape
@@ -4910,7 +4910,7 @@ find_func_clobbers (struct function *fn, gimple origt)
 	}
     }
 
-  if (is_gimple_call (t))
+  if (gimple_call call_stmt = dyn_cast <gimple_call> (t))
     {
       varinfo_t cfi = NULL;
       tree decl = gimple_call_fndecl (t);
@@ -5047,7 +5047,7 @@ find_func_clobbers (struct function *fn, gimple origt)
 
       /* Build constraints for propagating clobbers/uses along the
 	 callgraph edges.  */
-      cfi = get_fi_for_callee (t);
+      cfi = get_fi_for_callee (call_stmt);
       if (cfi->id == anything_id)
 	{
 	  if (gimple_vdef (t))
@@ -5071,10 +5071,10 @@ find_func_clobbers (struct function *fn, gimple origt)
 	  make_copy_constraint (first_vi_for_offset (fi, fi_uses), escaped_id);
 
 	  /* Also honor the call statement use/clobber info.  */
-	  if ((vi = lookup_call_clobber_vi (t)) != NULL)
+	  if ((vi = lookup_call_clobber_vi (call_stmt)) != NULL)
 	    make_copy_constraint (first_vi_for_offset (fi, fi_clobbers),
 				  vi->id);
-	  if ((vi = lookup_call_use_vi (t)) != NULL)
+	  if ((vi = lookup_call_use_vi (call_stmt)) != NULL)
 	    make_copy_constraint (first_vi_for_offset (fi, fi_uses),
 				  vi->id);
 	  return;
@@ -6825,9 +6825,11 @@ compute_points_to_sets (void)
 
       for (gsi = gsi_start_bb (bb); !gsi_end_p (gsi); gsi_next (&gsi))
 	{
-	  gimple stmt = gsi_stmt (gsi);
+	  gimple_call stmt;
 	  struct pt_solution *pt;
-	  if (!is_gimple_call (stmt))
+
+	  stmt = dyn_cast <gimple_call> (gsi_stmt (gsi));
+	  if (!stmt)
 	    continue;
 
 	  pt = gimple_call_use_set (stmt);
@@ -7235,12 +7237,13 @@ ipa_pta_execute (void)
 
 	  for (gsi = gsi_start_bb (bb); !gsi_end_p (gsi); gsi_next (&gsi))
 	    {
-	      gimple stmt = gsi_stmt (gsi);
+	      gimple_call stmt;
 	      struct pt_solution *pt;
 	      varinfo_t vi, fi;
 	      tree decl;
 
-	      if (!is_gimple_call (stmt))
+	      stmt = dyn_cast <gimple_call> (gsi_stmt (gsi));
+	      if (!stmt)
 		continue;
 
 	      /* Handle direct calls to functions with body.  */
diff --git a/gcc/tree-ssa-threadedge.c b/gcc/tree-ssa-threadedge.c
index da4419d..45083df 100644
--- a/gcc/tree-ssa-threadedge.c
+++ b/gcc/tree-ssa-threadedge.c
@@ -463,7 +463,7 @@ record_temporary_equivalences_from_stmts_at_dest (edge e,
 	  /* Try to fold/lookup the new expression.  Inserting the
 	     expression into the hash table is unlikely to help.  */
           if (is_gimple_call (stmt))
-            cached_lhs = fold_call_stmt (stmt, false);
+            cached_lhs = fold_call_stmt (as_a <gimple_call> (stmt), false);
 	  else
             cached_lhs = fold_assignment_stmt (stmt);
 
diff --git a/gcc/tree-tailcall.c b/gcc/tree-tailcall.c
index c45c89e..361f2ea 100644
--- a/gcc/tree-tailcall.c
+++ b/gcc/tree-tailcall.c
@@ -406,7 +406,8 @@ static void
 find_tail_calls (basic_block bb, struct tailcall **ret)
 {
   tree ass_var = NULL_TREE, ret_var, func, param;
-  gimple stmt, call = NULL;
+  gimple stmt;
+  gimple_call call = NULL;
   gimple_stmt_iterator gsi, agsi;
   bool tail_recursion;
   struct tailcall *nw;
@@ -433,8 +434,8 @@ find_tail_calls (basic_block bb, struct tailcall **ret)
       /* Check for a call.  */
       if (is_gimple_call (stmt))
 	{
-	  call = stmt;
-	  ass_var = gimple_call_lhs (stmt);
+	  call = as_a <gimple_call> (stmt);
+	  ass_var = gimple_call_lhs (call);
 	  break;
 	}
 
diff --git a/gcc/tree-vect-data-refs.c b/gcc/tree-vect-data-refs.c
index e4befc0..4c3e161 100644
--- a/gcc/tree-vect-data-refs.c
+++ b/gcc/tree-vect-data-refs.c
@@ -4769,7 +4769,6 @@ vect_setup_realignment (gimple stmt, gimple_stmt_iterator *gsi,
   gimple inc;
   tree ptr;
   tree data_ref;
-  gimple new_stmt;
   basic_block new_bb;
   tree msq_init = NULL_TREE;
   tree new_temp;
@@ -4864,6 +4863,7 @@ vect_setup_realignment (gimple stmt, gimple_stmt_iterator *gsi,
   if (alignment_support_scheme == dr_explicit_realign_optimized)
     {
       /* Create msq_init = *(floor(p1)) in the loop preheader  */
+      gimple_assign new_stmt;
 
       gcc_assert (!compute_in_loop);
       vec_dest = vect_create_destination_var (scalar_dest, vectype);
@@ -4900,6 +4900,7 @@ vect_setup_realignment (gimple stmt, gimple_stmt_iterator *gsi,
 
   if (targetm.vectorize.builtin_mask_for_load)
     {
+      gimple_call new_stmt;
       tree builtin_decl;
 
       /* Compute INIT_ADDR - the initial addressed accessed by this memref.  */
diff --git a/gcc/tree-vect-patterns.c b/gcc/tree-vect-patterns.c
index ea3d542..9a1bbfb 100644
--- a/gcc/tree-vect-patterns.c
+++ b/gcc/tree-vect-patterns.c
@@ -1119,7 +1119,7 @@ vect_recog_pow_pattern (vec<gimple> *stmts, tree *type_in,
       *type_in = get_vectype_for_scalar_type (TREE_TYPE (base));
       if (*type_in)
 	{
-	  gimple stmt = gimple_build_call (newfn, 1, base);
+	  gimple_call stmt = gimple_build_call (newfn, 1, base);
 	  if (vectorizable_function (stmt, *type_in, *type_in)
 	      != NULL_TREE)
 	    {
diff --git a/gcc/tree-vect-stmts.c b/gcc/tree-vect-stmts.c
index 350557c..dd3a9b8 100644
--- a/gcc/tree-vect-stmts.c
+++ b/gcc/tree-vect-stmts.c
@@ -1707,7 +1707,7 @@ vect_finish_stmt_generation (gimple stmt, gimple vec_stmt,
    of the function, or NULL_TREE if the function cannot be vectorized.  */
 
 tree
-vectorizable_function (gimple call, tree vectype_out, tree vectype_in)
+vectorizable_function (gimple_call call, tree vectype_out, tree vectype_in)
 {
   tree fndecl = gimple_call_fndecl (call);
 
@@ -2178,20 +2178,21 @@ vectorizable_mask_load_store (gimple stmt, gimple_stmt_iterator *gsi,
 
 /* Function vectorizable_call.
 
-   Check if STMT performs a function call that can be vectorized.
+   Check if GS performs a function call that can be vectorized.
    If VEC_STMT is also passed, vectorize the STMT: create a vectorized
    stmt to replace it, put it in VEC_STMT, and insert it at BSI.
    Return FALSE if not a vectorizable STMT, TRUE otherwise.  */
 
 static bool
-vectorizable_call (gimple stmt, gimple_stmt_iterator *gsi, gimple *vec_stmt,
+vectorizable_call (gimple gs, gimple_stmt_iterator *gsi, gimple *vec_stmt,
 		   slp_tree slp_node)
 {
+  gimple_call stmt;
   tree vec_dest;
   tree scalar_dest;
   tree op, type;
   tree vec_oprnd0 = NULL_TREE, vec_oprnd1 = NULL_TREE;
-  stmt_vec_info stmt_info = vinfo_for_stmt (stmt), prev_stmt_info;
+  stmt_vec_info stmt_info = vinfo_for_stmt (gs), prev_stmt_info;
   tree vectype_out, vectype_in;
   int nunits_in;
   int nunits_out;
@@ -2214,8 +2215,9 @@ vectorizable_call (gimple stmt, gimple_stmt_iterator *gsi, gimple *vec_stmt,
   if (STMT_VINFO_DEF_TYPE (stmt_info) != vect_internal_def)
     return false;
 
-  /* Is STMT a vectorizable call?   */
-  if (!is_gimple_call (stmt))
+  /* Is GS a vectorizable call?   */
+  stmt = dyn_cast <gimple_call> (gs);
+  if (!stmt)
     return false;
 
   if (gimple_call_internal_p (stmt)
diff --git a/gcc/tree-vectorizer.h b/gcc/tree-vectorizer.h
index 93aa73e..5fe3a6c 100644
--- a/gcc/tree-vectorizer.h
+++ b/gcc/tree-vectorizer.h
@@ -1004,7 +1004,7 @@ extern bool supportable_narrowing_operation (enum tree_code, tree, tree,
 extern stmt_vec_info new_stmt_vec_info (gimple stmt, loop_vec_info,
                                         bb_vec_info);
 extern void free_stmt_vec_info (gimple stmt);
-extern tree vectorizable_function (gimple, tree, tree);
+extern tree vectorizable_function (gimple_call, tree, tree);
 extern void vect_model_simple_cost (stmt_vec_info, int, enum vect_def_type *,
                                     stmt_vector_for_cost *,
 				    stmt_vector_for_cost *);
diff --git a/gcc/value-prof.c b/gcc/value-prof.c
index 80f8bad..b1e4c83 100644
--- a/gcc/value-prof.c
+++ b/gcc/value-prof.c
@@ -1321,7 +1321,7 @@ find_func_by_profile_id (int profile_id)
    Returns true if TARGET is considered ok for call CALL_STMT.  */
 
 static bool
-check_ic_target (gimple call_stmt, struct cgraph_node *target)
+check_ic_target (gimple_call call_stmt, struct cgraph_node *target)
 {
    location_t locus;
    if (gimple_check_call_matching_types (call_stmt, target->decl, true))
@@ -1486,12 +1486,13 @@ gimple_ic (gimple icall_stmt, struct cgraph_node *direct_call,
 static bool
 gimple_ic_transform (gimple_stmt_iterator *gsi)
 {
-  gimple stmt = gsi_stmt (*gsi);
+  gimple_call stmt;
   histogram_value histogram;
   gcov_type val, count, all, bb_all;
   struct cgraph_node *direct_call;
 
-  if (gimple_code (stmt) != GIMPLE_CALL)
+  stmt = dyn_cast <gimple_call> (gsi_stmt (*gsi));
+  if (!stmt)
     return false;
 
   if (gimple_call_fndecl (stmt) != NULL_TREE)
@@ -1573,7 +1574,7 @@ gimple_ic_transform (gimple_stmt_iterator *gsi)
    operation.
 */
 static bool
-interesting_stringop_to_profile_p (tree fndecl, gimple call, int *size_arg)
+interesting_stringop_to_profile_p (tree fndecl, gimple_call call, int *size_arg)
 {
   enum built_in_function fcode = DECL_FUNCTION_CODE (fndecl);
 
@@ -1610,7 +1611,7 @@ interesting_stringop_to_profile_p (tree fndecl, gimple call, int *size_arg)
    assuming we'll propagate a true constant into ICALL_SIZE later.  */
 
 static void
-gimple_stringop_fixed_value (gimple vcall_stmt, tree icall_size, int prob,
+gimple_stringop_fixed_value (gimple_call vcall_stmt, tree icall_size, int prob,
 			     gcov_type count, gcov_type all)
 {
   gimple tmp_stmt, cond_stmt, icall_stmt;
@@ -1704,7 +1705,7 @@ gimple_stringop_fixed_value (gimple vcall_stmt, tree icall_size, int prob,
 static bool
 gimple_stringops_transform (gimple_stmt_iterator *gsi)
 {
-  gimple stmt = gsi_stmt (*gsi);
+  gimple_call stmt;
   tree fndecl;
   tree blck_size;
   enum built_in_function fcode;
@@ -1716,7 +1717,8 @@ gimple_stringops_transform (gimple_stmt_iterator *gsi)
   tree tree_val;
   int size_arg;
 
-  if (gimple_code (stmt) != GIMPLE_CALL)
+  stmt = dyn_cast <gimple_call> (gsi_stmt (*gsi));
+  if (!stmt)
     return false;
   fndecl = gimple_call_fndecl (stmt);
   if (!fndecl)
@@ -1929,14 +1931,16 @@ gimple_indirect_call_to_profile (gimple stmt, histogram_values *values)
 /* Find values inside STMT for that we want to measure histograms for
    string operations.  */
 static void
-gimple_stringops_values_to_profile (gimple stmt, histogram_values *values)
+gimple_stringops_values_to_profile (gimple gs, histogram_values *values)
 {
+  gimple_call stmt;
   tree fndecl;
   tree blck_size;
   tree dest;
   int size_arg;
 
-  if (gimple_code (stmt) != GIMPLE_CALL)
+  stmt = dyn_cast <gimple_call> (gs);
+  if (!stmt)
     return;
   fndecl = gimple_call_fndecl (stmt);
   if (!fndecl)
diff --git a/gcc/vtable-verify.c b/gcc/vtable-verify.c
index cb331d2..bf23d29 100644
--- a/gcc/vtable-verify.c
+++ b/gcc/vtable-verify.c
@@ -594,7 +594,7 @@ verify_bb_vtables (basic_block bb)
           tree vtbl_var_decl = NULL_TREE;
           struct vtbl_map_node *vtable_map_node;
           tree vtbl_decl = NULL_TREE;
-          gimple call_stmt;
+          gimple_call call_stmt;
           const char *vtable_name = "<unknown>";
           tree tmp0;
           bool found;
-- 
1.8.5.3

