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

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

	* gimple.h (gimple_statement_base::as_a_gimple_call): New.
	(gimple_statement_base::dyn_cast_gimple_call): New.
	(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
	within 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               | 11 +++---
 gcc/builtins.h               |  2 +-
 gcc/cfgexpand.c              |  4 +-
 gcc/cgraph.c                 |  4 +-
 gcc/cgraphunit.c             |  2 +-
 gcc/coretypes.h              |  4 ++
 gcc/gimple-fold.c            | 10 +++--
 gcc/gimple-fold.h            |  2 +-
 gcc/gimple-pretty-print.c    |  6 +--
 gcc/gimple-streamer-in.c     | 10 ++---
 gcc/gimple-walk.c            |  3 +-
 gcc/gimple.c                 | 42 +++++++++++----------
 gcc/gimple.h                 | 90 ++++++++++++++++++++++++--------------------
 gcc/gimplify.c               | 14 +++----
 gcc/internal-fn.c            | 42 ++++++++++-----------
 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         |  2 +-
 gcc/tree-ssa-ccp.c           |  2 +-
 gcc/tree-ssa-dce.c           |  2 +-
 gcc/tree-ssa-loop-prefetch.c |  2 +-
 gcc/tree-ssa-math-opts.c     |  4 +-
 gcc/tree-ssa-operands.c      |  4 +-
 gcc/tree-ssa-pre.c           |  3 +-
 gcc/tree-ssa-sccvn.c         | 15 ++++----
 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/tree.h                   |  5 ++-
 gcc/value-prof.c             | 22 ++++++-----
 gcc/vtable-verify.c          |  2 +-
 52 files changed, 280 insertions(+), 244 deletions(-)

diff --git a/gcc/asan.c b/gcc/asan.c
index 8bfe25d..cab4d44 100644
--- a/gcc/asan.c
+++ b/gcc/asan.c
@@ -462,7 +462,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,
@@ -816,7 +816,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 (stmt->as_a_gimple_call (),
 					&src0, &src0_len, &src0_is_store,
 					&src1, &src1_len, &src1_is_store,
 					&dest, &dest_len, &dest_is_store,
@@ -1836,7 +1836,7 @@ instrument_mem_region_access (tree base, tree len,
 static bool
 instrument_strlen_call (gimple_stmt_iterator *iter)
 {
-  gimple call = gsi_stmt (*iter);
+  gimple_call call = gsi_stmt (*iter)->as_a_gimple_call ();
   gcc_assert (is_gimple_call (call));
 
   tree callee = gimple_call_fndecl (call);
@@ -1912,7 +1912,7 @@ instrument_builtin_call (gimple_stmt_iterator *iter)
     return false;
 
   bool iter_advanced_p = false;
-  gimple call = gsi_stmt (*iter);
+  gimple_call call = gsi_stmt (*iter)->as_a_gimple_call ();
 
   gcc_checking_assert (gimple_call_builtin_p (call, BUILT_IN_NORMAL));
 
diff --git a/gcc/builtins.c b/gcc/builtins.c
index dd57b1a..17206f9 100644
--- a/gcc/builtins.c
+++ b/gcc/builtins.c
@@ -11415,7 +11415,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;
@@ -14154,7 +14154,8 @@ do_mpc_arg2 (tree arg0, tree arg1, tree type, int do_nonfinite,
    inline.  FCODE is either BUILT_IN_SPRINTF_CHK or BUILT_IN_VSPRINTF_CHK.  */
 
 static tree
-gimple_fold_builtin_sprintf_chk (gimple stmt, enum built_in_function fcode)
+gimple_fold_builtin_sprintf_chk (gimple_call stmt,
+				 enum built_in_function fcode)
 {
   int nargs = gimple_call_num_args (stmt);
 
@@ -14171,7 +14172,7 @@ gimple_fold_builtin_sprintf_chk (gimple stmt, enum built_in_function fcode)
    passed as second argument.  */
 
 tree
-gimple_fold_builtin_snprintf_chk (gimple stmt, tree maxlen,
+gimple_fold_builtin_snprintf_chk (gimple_call stmt, tree maxlen,
                                   enum built_in_function fcode)
 {
   int nargs = gimple_call_num_args (stmt);
@@ -14190,7 +14191,7 @@ gimple_fold_builtin_snprintf_chk (gimple stmt, tree maxlen,
    result of the function call is ignored.  */
 
 static tree
-gimple_fold_builtin_varargs (tree fndecl, gimple stmt,
+gimple_fold_builtin_varargs (tree fndecl, gimple_call stmt,
 			     bool ignore ATTRIBUTE_UNUSED)
 {
   enum built_in_function fcode = DECL_FUNCTION_CODE (fndecl);
@@ -14224,7 +14225,7 @@ gimple_fold_builtin_varargs (tree fndecl, gimple stmt,
    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 5eb9303..a288693 100644
--- a/gcc/builtins.h
+++ b/gcc/builtins.h
@@ -44,6 +44,6 @@ extern struct target_builtins *this_target_builtins;
 #define this_target_builtins (&default_target_builtins)
 #endif
 
-extern bool validate_gimple_arglist (const_gimple, ...);
+extern bool validate_gimple_arglist (const_gimple_call, ...);
 
 #endif
diff --git a/gcc/cfgexpand.c b/gcc/cfgexpand.c
index 679933d..175a9f4 100644
--- a/gcc/cfgexpand.c
+++ b/gcc/cfgexpand.c
@@ -2179,7 +2179,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;
@@ -3153,7 +3153,7 @@ expand_gimple_stmt_1 (gimple stmt)
       expand_asm_stmt (stmt);
       break;
     case GIMPLE_CALL:
-      expand_call_stmt (stmt);
+      expand_call_stmt (stmt->as_a_gimple_call ());
       break;
 
     case GIMPLE_RETURN:
diff --git a/gcc/cgraph.c b/gcc/cgraph.c
index dcab984..3652796 100644
--- a/gcc/cgraph.c
+++ b/gcc/cgraph.c
@@ -1332,7 +1332,7 @@ cgraph_redirect_edge_call_stmt_to_callee (struct cgraph_edge *e)
 {
   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
   struct cgraph_node *node;
@@ -1469,7 +1469,7 @@ cgraph_redirect_edge_call_stmt_to_callee (struct cgraph_edge *e)
     }
   else
     {
-      new_stmt = e->call_stmt;
+      new_stmt = e->call_stmt->as_a_gimple_call ();
       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 06283fc..588fe13 100644
--- a/gcc/cgraphunit.c
+++ b/gcc/cgraphunit.c
@@ -1531,7 +1531,7 @@ expand_thunk (struct cgraph_node *node, bool output_asm_thunks)
       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 e199b0c..0f884fd 100644
--- a/gcc/coretypes.h
+++ b/gcc/coretypes.h
@@ -89,6 +89,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 59f7ada..aa62bef 100644
--- a/gcc/gimple-fold.c
+++ b/gcc/gimple-fold.c
@@ -871,7 +871,7 @@ get_maxval_strlen (tree arg, tree *length, bitmap visited, int type)
    be valid in GIMPLE.  Callers must take care.  */
 
 tree
-gimple_fold_builtin (gimple stmt)
+gimple_fold_builtin (gimple_call stmt)
 {
   tree result, val[3];
   tree callee, a;
@@ -1080,7 +1080,7 @@ gimple_fold_builtin (gimple stmt)
 static bool
 gimple_fold_call (gimple_stmt_iterator *gsi, bool inplace)
 {
-  gimple stmt = gsi_stmt (*gsi);
+  gimple_call stmt = gsi_stmt (*gsi)->as_a_gimple_call ();
   tree callee;
   bool changed = false;
   unsigned i;
@@ -2713,6 +2713,7 @@ gimple_fold_stmt_to_constant_1 (gimple stmt, tree (*valueize) (tree))
     case GIMPLE_CALL:
       {
 	tree fn;
+	gimple_call call_stmt = stmt->as_a_gimple_call ();
 
 	if (gimple_call_internal_p (stmt))
 	  {
@@ -2777,14 +2778,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-fold.h b/gcc/gimple-fold.h
index 6b43066..d5a3e94 100644
--- a/gcc/gimple-fold.h
+++ b/gcc/gimple-fold.h
@@ -25,7 +25,7 @@ along with GCC; see the file COPYING3.  If not see
 extern tree canonicalize_constructor_val (tree, tree);
 extern tree get_symbol_constant_value (tree);
 extern void gimplify_and_update_call_from_tree (gimple_stmt_iterator *, tree);
-extern tree gimple_fold_builtin (gimple);
+extern tree gimple_fold_builtin (gimple_call);
 extern bool fold_stmt (gimple_stmt_iterator *);
 extern bool fold_stmt_inplace (gimple_stmt_iterator *);
 extern tree maybe_fold_and_comparisons (enum tree_code, tree, tree, 
diff --git a/gcc/gimple-pretty-print.c b/gcc/gimple-pretty-print.c
index bf5f286..6b903aa 100644
--- a/gcc/gimple-pretty-print.c
+++ b/gcc/gimple-pretty-print.c
@@ -569,7 +569,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;
 
@@ -642,7 +642,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);
@@ -2103,7 +2103,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, gs->as_a_gimple_call (), spc, flags);
       break;
 
     case GIMPLE_COND:
diff --git a/gcc/gimple-streamer-in.c b/gcc/gimple-streamer-in.c
index fad04cd..2d5885f 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 = stmt->dyn_cast_gimple_call ())
 	{
-	  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 (stmt->as_a_gimple_call ());
 
   /* 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 85b6dcd..0bb86db 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 (stmt->as_a_gimple_call ()),
+		       callback_op, wi, pset);
       if (ret)
         return ret;
 
diff --git a/gcc/gimple.c b/gcc/gimple.c
index 943fa7c..6acf60b 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,11 @@ 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 = gimple_build_with_ops (GIMPLE_CALL, ERROR_MARK,
+					 nargs + 3)->as_a_gimple_call ();
   if (TREE_CODE (fn) == FUNCTION_DECL)
     fn = build_fold_addr_expr (fn);
   gimple_set_op (s, 1, fn);
@@ -222,12 +223,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 +240,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 +263,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 +284,11 @@ 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 = gimple_build_with_ops (GIMPLE_CALL, ERROR_MARK,
+					 nargs + 3)->as_a_gimple_call ();
   s->subcode |= GF_CALL_INTERNAL;
   gimple_call_set_internal_fn (s, fn);
   gimple_call_reset_alias_info (s);
@@ -297,11 +299,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 +319,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 +338,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);
@@ -1387,7 +1389,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)
 {
   tree attr;
 
@@ -2011,13 +2013,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 62f9756..4e0be1f 100644
--- a/gcc/gimple.h
+++ b/gcc/gimple.h
@@ -240,6 +240,18 @@ public:
     return as_a <gimple_statement_assign> (this);
   }
 
+  inline gimple_call
+  as_a_gimple_call ()
+  {
+    return as_a <gimple_statement_call> (this);
+  }
+
+  inline const_gimple_call
+  as_a_gimple_call () const
+  {
+    return as_a <const gimple_statement_call> (this);
+  }
+
   inline gimple_bind
   as_a_gimple_bind ()
   {
@@ -290,6 +302,12 @@ public:
     return dyn_cast <gimple_statement_assign> (this);
   }
 
+  inline gimple_call
+  dyn_cast_gimple_call ()
+  {
+    return dyn_cast <gimple_statement_call> (this);
+  }
+
   inline gimple_bind
   dyn_cast_gimple_bind ()
   {
@@ -1363,13 +1381,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,
@@ -1434,7 +1452,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);
@@ -1452,7 +1470,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);
@@ -2726,13 +2744,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;
 }
 
@@ -2751,7 +2768,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);
 
@@ -2774,23 +2791,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);
 }
 
 
@@ -2867,9 +2881,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
@@ -2891,9 +2904,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
@@ -2904,9 +2916,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;
 }
 
@@ -2915,9 +2926,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
@@ -2929,9 +2939,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;
 }
 
@@ -2974,9 +2983,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
@@ -2986,9 +2994,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;
 }
 
@@ -5831,11 +5838,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 = stmt->as_a_gimple_call ();
+	  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 46dc786..bfb8f98 100644
--- a/gcc/gimplify.c
+++ b/gcc/gimplify.c
@@ -2214,7 +2214,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);
 
@@ -3142,7 +3142,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);
@@ -3189,7 +3189,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
@@ -4580,7 +4580,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 (assign->as_a_gimple_call ());
       if (!gimple_call_noreturn_p (assign))
 	gimple_call_set_lhs (assign, *to_p);
     }
@@ -7519,8 +7519,8 @@ 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_build_call_internal (IFN_ANNOTATE, 2,
-						      cond, id);
+	    gimple_call call = gimple_build_call_internal (IFN_ANNOTATE, 2,
+							   cond, id);
 	    gimple_call_set_lhs (call, tmp);
 	    gimplify_seq_add_stmt (pre_p, call);
 	    *expr_p = tmp;
@@ -8739,7 +8739,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 1062ea8..38a06f3 100644
--- a/gcc/internal-fn.c
+++ b/gcc/internal-fn.c
@@ -76,7 +76,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;
@@ -100,7 +100,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;
@@ -122,7 +122,7 @@ expand_STORE_LANES (gimple stmt)
 }
 
 static void
-expand_ANNOTATE (gimple stmt ATTRIBUTE_UNUSED)
+expand_ANNOTATE (gimple_call stmt ATTRIBUTE_UNUSED)
 {
   gcc_unreachable ();
 }
@@ -130,7 +130,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 ();
 }
@@ -138,7 +138,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 ();
 }
@@ -146,7 +146,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 ();
 }
@@ -154,7 +154,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 ();
 }
@@ -163,7 +163,7 @@ expand_UBSAN_NULL (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;
@@ -311,7 +311,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;
@@ -387,7 +387,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;
@@ -782,7 +782,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);
 }
@@ -790,7 +790,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);
@@ -801,7 +801,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);
 }
@@ -809,13 +809,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;
@@ -840,7 +840,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;
@@ -863,12 +863,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 ());
@@ -887,10 +887,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) expand_##CODE,
 #include "internal-fn.def"
 #undef DEF_INTERNAL_FN
@@ -900,7 +900,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 31dc4c9..99013f4 100644
--- a/gcc/internal-fn.def
+++ b/gcc/internal-fn.def
@@ -34,7 +34,7 @@ along with GCC; see the file COPYING3.  If not see
    ECF_* flags.  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 9c3215f..014f39f 100644
--- a/gcc/internal-fn.h
+++ b/gcc/internal-fn.h
@@ -48,6 +48,6 @@ internal_fn_flags (enum internal_fn fn)
   return internal_fn_flags_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 9f144fa..45d540e 100644
--- a/gcc/ipa-prop.c
+++ b/gcc/ipa-prop.c
@@ -3665,7 +3665,7 @@ ipa_modify_call_arguments (struct cgraph_edge *cs, gimple stmt,
   struct cgraph_node *current_node = cgraph_get_node (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 7d35880..e5ec305 100644
--- a/gcc/ipa-pure-const.c
+++ b/gcc/ipa-pure-const.c
@@ -464,7 +464,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);
@@ -685,7 +685,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, stmt->as_a_gimple_call (), 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 38bd883..dbcc787 100644
--- a/gcc/ipa-split.c
+++ b/gcc/ipa-split.c
@@ -1091,7 +1091,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 cbf13d2..af50d89 100644
--- a/gcc/omp-low.c
+++ b/gcc/omp-low.c
@@ -2717,7 +2717,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;
@@ -3147,7 +3147,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 f3300c3..1d992f6 100644
--- a/gcc/trans-mem.c
+++ b/gcc/trans-mem.c
@@ -2096,12 +2096,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;
@@ -2168,12 +2168,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;
@@ -2729,7 +2729,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 4b2ad87..d7941e3 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);
     }
 
@@ -875,15 +875,14 @@ tree_call_cdce (void)
   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, cfun)
     {
       /* 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 = gsi_stmt (i)->dyn_cast_gimple_call ();
+          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 53c4808..8168d97 100644
--- a/gcc/tree-cfg.c
+++ b/gcc/tree-cfg.c
@@ -1899,7 +1899,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 c15d6ab..e291a0c 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 8b335cc..55b120e 100644
--- a/gcc/tree-complex.c
+++ b/gcc/tree-complex.c
@@ -948,7 +948,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 9cea36c..9f06006 100644
--- a/gcc/tree-inline.c
+++ b/gcc/tree-inline.c
@@ -1518,7 +1518,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 (copy->as_a_gimple_call ());
 	    }
 	    break;
 
@@ -1660,13 +1660,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 (stmt->as_a_gimple_call ())
 	      && 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;
@@ -1868,7 +1868,7 @@ copy_bb (copy_body_data *id, basic_block bb, int frequency_scale,
 		    }
 		}
 
-	      notice_special_calls (stmt);
+	      notice_special_calls (stmt->as_a_gimple_call ());
 	    }
 
 	  maybe_duplicate_eh_stmt_fn (cfun, stmt, id->src_cfun, orig_stmt,
@@ -3349,7 +3349,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 (stmt->as_a_gimple_call ())
 	  && !lookup_attribute ("always_inline", DECL_ATTRIBUTES (fn)))
 	{
 	  inline_forbidden_reason
diff --git a/gcc/tree-nested.c b/gcc/tree-nested.c
index 78de464..4009311 100644
--- a/gcc/tree-nested.c
+++ b/gcc/tree-nested.c
@@ -411,7 +411,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;
 
@@ -1864,7 +1864,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;
   void **slot;
-  gimple call;
+  gimple_call call;
   gimple stmt = gsi_stmt (*gsi);
 
   if (gimple_code (stmt) != GIMPLE_GOTO)
@@ -1982,7 +1982,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))
@@ -2125,8 +2125,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 (stmt->as_a_gimple_call (),
+				 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 b443388..5a5a5d8 100644
--- a/gcc/tree-nrv.c
+++ b/gcc/tree-nrv.c
@@ -323,7 +323,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);
 
@@ -363,10 +363,11 @@ execute_return_slot_opt (void)
       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 = gsi_stmt (gsi)->dyn_cast_gimple_call ();
+	  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 994845b..6a7e17b 100644
--- a/gcc/tree-object-size.c
+++ b/gcc/tree-object-size.c
@@ -58,8 +58,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 = stmt->as_a_gimple_call ();
+        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 = stmt->as_a_gimple_call ();
+        tree arg = pass_through_call (call_stmt);
         if (arg)
           {
             if (TREE_CODE (arg) == SSA_NAME)
@@ -1222,7 +1224,7 @@ compute_object_sizes (void)
 	    continue;
 
 	  init_object_sizes ();
-	  result = fold_call_stmt (call, false);
+	  result = fold_call_stmt (call->as_a_gimple_call (), false);
 	  if (!result)
 	    {
 	      if (gimple_call_num_args (call) == 2
diff --git a/gcc/tree-profile.c b/gcc/tree-profile.c
index 02e9ff2..e79fedc 100644
--- a/gcc/tree-profile.c
+++ b/gcc/tree-profile.c
@@ -328,7 +328,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);
@@ -354,7 +354,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,
@@ -374,7 +374,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,
@@ -492,7 +492,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);
@@ -527,7 +527,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,
@@ -548,7 +548,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 e706275..3fd2789 100644
--- a/gcc/tree-ssa-alias.c
+++ b/gcc/tree-ssa-alias.c
@@ -1329,7 +1329,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;
@@ -1640,7 +1640,7 @@ process_args:
 }
 
 static bool
-ref_maybe_used_by_call_p (gimple call, tree ref)
+ref_maybe_used_by_call_p (gimple_call call, tree ref)
 {
   ao_ref r;
   bool res;
@@ -1677,7 +1677,7 @@ ref_maybe_used_by_stmt_p (gimple stmt, tree 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 (stmt->as_a_gimple_call (), ref);
   else if (gimple_code (stmt) == GIMPLE_RETURN)
     {
       tree retval = gimple_return_retval (stmt);
@@ -1706,7 +1706,7 @@ ref_maybe_used_by_stmt_p (gimple stmt, tree ref)
    return true, otherwise return false.  */
 
 static 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;
@@ -1969,7 +1969,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;
@@ -2001,7 +2001,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 (stmt->as_a_gimple_call (), ref);
     }
   else if (gimple_assign_single_p (stmt))
     {
diff --git a/gcc/tree-ssa-alias.h b/gcc/tree-ssa-alias.h
index 3544aaf..be91bc6 100644
--- a/gcc/tree-ssa-alias.h
+++ b/gcc/tree-ssa-alias.h
@@ -109,7 +109,7 @@ extern bool ref_maybe_used_by_stmt_p (gimple, tree);
 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 (gimple_call, tree);
 extern bool stmt_kills_ref_p (gimple, tree);
 extern tree get_continuation_for_phi (gimple, ao_ref *,
 				      unsigned int *, bitmap *, bool);
diff --git a/gcc/tree-ssa-ccp.c b/gcc/tree-ssa-ccp.c
index 41debfb..d10f9ba 100644
--- a/gcc/tree-ssa-ccp.c
+++ b/gcc/tree-ssa-ccp.c
@@ -2613,7 +2613,7 @@ execute_fold_all_builtins (void)
 	    }
 	  fcode = DECL_FUNCTION_CODE (callee);
 
-	  result = gimple_fold_builtin (stmt);
+	  result = gimple_fold_builtin (stmt->as_a_gimple_call ());
 
 	  if (result)
 	    gimple_remove_stmt_histograms (cfun, stmt);
diff --git a/gcc/tree-ssa-dce.c b/gcc/tree-ssa-dce.c
index c5a530b..8d3fc5b 100644
--- a/gcc/tree-ssa-dce.c
+++ b/gcc/tree-ssa-dce.c
@@ -1217,7 +1217,7 @@ eliminate_unnecessary_stmts (void)
 	    {
 	      tree name = gimple_call_lhs (stmt);
 
-	      notice_special_calls (stmt);
+	      notice_special_calls (stmt->as_a_gimple_call ());
 
 	      /* 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 c0968c8..be34d05 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 9ff857c..c9e5674 100644
--- a/gcc/tree-ssa-math-opts.c
+++ b/gcc/tree-ssa-math-opts.c
@@ -1072,7 +1072,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);
@@ -1965,7 +1965,7 @@ execute_optimize_bswap (void)
 	  tree bswap_tmp;
 	  tree fndecl = NULL_TREE;
 	  int type_size;
-	  gimple call;
+	  gimple_call call;
 
 	  if (!is_gimple_assign (stmt)
 	      || gimple_assign_rhs_code (stmt) != BIT_IOR_EXPR)
diff --git a/gcc/tree-ssa-operands.c b/gcc/tree-ssa-operands.c
index 352ccca..b95a273 100644
--- a/gcc/tree-ssa-operands.c
+++ b/gcc/tree-ssa-operands.c
@@ -639,7 +639,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);
 
@@ -936,7 +936,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, stmt->as_a_gimple_call ());
       /* FALLTHRU */
 
     case GIMPLE_ASSIGN:
diff --git a/gcc/tree-ssa-pre.c b/gcc/tree-ssa-pre.c
index 1e55356..044d59d 100644
--- a/gcc/tree-ssa-pre.c
+++ b/gcc/tree-ssa-pre.c
@@ -3831,7 +3831,8 @@ compute_avail (void)
 		if (gimple_call_internal_p (stmt))
 		  continue;
 
-		copy_reference_ops_from_call (stmt, &ops);
+		copy_reference_ops_from_call (stmt->as_a_gimple_call (),
+					      &ops);
 		vn_reference_lookup_pieces (gimple_vuse (stmt), 0,
 					    gimple_expr_type (stmt),
 					    ops, &ref, VN_NOWALK);
diff --git a/gcc/tree-ssa-sccvn.c b/gcc/tree-ssa-sccvn.c
index 6516a4f..27ff70d 100644
--- a/gcc/tree-ssa-sccvn.c
+++ b/gcc/tree-ssa-sccvn.c
@@ -1098,7 +1098,7 @@ ao_ref_init_from_vn_reference (ao_ref *ref,
    vn_reference_op_s's.  */
 
 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;
@@ -1140,7 +1140,7 @@ copy_reference_ops_from_call (gimple call,
    call statement.  The vector is not shared.  */
 
 static vec<vn_reference_op_s> 
-create_reference_ops_from_call (gimple call)
+create_reference_ops_from_call (gimple_call call)
 {
   vec<vn_reference_op_s> result = vNULL;
 
@@ -1433,7 +1433,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;
@@ -2771,7 +2771,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;
@@ -3552,7 +3552,7 @@ visit_use (tree use)
 	  else
 	    changed = defs_to_varying (stmt);
 	}
-      else if (is_gimple_call (stmt))
+      else if (gimple_call call_stmt = stmt->dyn_cast_gimple_call ())
 	{
 	  tree lhs = gimple_call_lhs (stmt);
 
@@ -3596,8 +3596,9 @@ 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))))
-	    changed = visit_reference_op_call (lhs, stmt);
+		      && !(gimple_call_return_flags (call_stmt)
+			   & ERF_NOALIAS))))
+	    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 f52783a..5d1095c 100644
--- a/gcc/tree-ssa-sccvn.h
+++ b/gcc/tree-ssa-sccvn.h
@@ -203,7 +203,7 @@ vn_nary_op_t vn_nary_op_insert_pieces (unsigned int, enum tree_code,
 void vn_reference_fold_indirect (vec<vn_reference_op_s> *,
 				 unsigned int *);
 void copy_reference_ops_from_ref (tree, vec<vn_reference_op_s> *);
-void copy_reference_ops_from_call (gimple, vec<vn_reference_op_s> *);
+void copy_reference_ops_from_call (gimple_call, vec<vn_reference_op_s> *);
 bool ao_ref_init_from_vn_reference (ao_ref *, alias_set_type, tree,
 				    vec<vn_reference_op_s> );
 tree vn_reference_lookup_pieces (tree, alias_set_type, tree,
diff --git a/gcc/tree-ssa-structalias.c b/gcc/tree-ssa-structalias.c
index 8201cb4..01905cf 100644
--- a/gcc/tree-ssa-structalias.c
+++ b/gcc/tree-ssa-structalias.c
@@ -398,7 +398,7 @@ static struct pointer_map_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)
 {
   void **slot_p;
   varinfo_t vi, vi2;
@@ -429,7 +429,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)
 {
   void **slot_p;
 
@@ -444,7 +444,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)
@@ -457,7 +457,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);
 }
@@ -466,7 +466,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));
 }
@@ -3851,7 +3851,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;
@@ -3953,7 +3953,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;
@@ -4017,7 +4017,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;
@@ -4058,7 +4058,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;
@@ -4105,7 +4105,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);
 
@@ -4136,7 +4136,7 @@ get_fi_for_callee (gimple call)
    was handled, otherwise false.  */
 
 static bool
-find_func_aliases_for_builtin_call (gimple t)
+find_func_aliases_for_builtin_call (gimple_call t)
 {
   tree fndecl = gimple_call_fndecl (t);
   vec<ce_s> lhsc = vNULL;
@@ -4502,7 +4502,7 @@ find_func_aliases_for_builtin_call (gimple t)
 /* Create constraints for the call T.  */
 
 static void
-find_func_aliases_for_call (gimple t)
+find_func_aliases_for_call (gimple_call t)
 {
   tree fndecl = gimple_call_fndecl (t);
   vec<ce_s> lhsc = vNULL;
@@ -4665,7 +4665,7 @@ find_func_aliases (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 (t);
+    find_func_aliases_for_call (t->as_a_gimple_call ());
     
   /* Otherwise, just a regular assignment statement.  Only care about
      operations with pointer result, others are dealt with as escape
@@ -4934,7 +4934,7 @@ find_func_clobbers (gimple origt)
 	}
     }
 
-  if (is_gimple_call (t))
+  if (gimple_call call_stmt = t->dyn_cast_gimple_call ())
     {
       varinfo_t cfi = NULL;
       tree decl = gimple_call_fndecl (t);
@@ -5074,7 +5074,7 @@ find_func_clobbers (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))
@@ -5098,10 +5098,10 @@ find_func_clobbers (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;
@@ -6858,9 +6858,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 = gsi_stmt (gsi)->dyn_cast_gimple_call ();
+	  if (!stmt)
 	    continue;
 
 	  pt = gimple_call_use_set (stmt);
@@ -7306,12 +7308,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;
 	      tree decl;
 
-	      if (!is_gimple_call (stmt))
+	      stmt = gsi_stmt (gsi)->dyn_cast_gimple_call ();
+	      if (!stmt)
 		continue;
 
 	      /* Handle direct calls to external functions.  */
diff --git a/gcc/tree-ssa-threadedge.c b/gcc/tree-ssa-threadedge.c
index a332456..0a4af13 100644
--- a/gcc/tree-ssa-threadedge.c
+++ b/gcc/tree-ssa-threadedge.c
@@ -474,7 +474,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 (stmt->as_a_gimple_call (), false);
 	  else
             cached_lhs = fold_assignment_stmt (stmt);
 
diff --git a/gcc/tree-tailcall.c b/gcc/tree-tailcall.c
index 4c85f3d..71e3c3b 100644
--- a/gcc/tree-tailcall.c
+++ b/gcc/tree-tailcall.c
@@ -396,7 +396,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;
@@ -423,8 +424,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 = stmt->as_a_gimple_call ();
+	  ass_var = gimple_call_lhs (call);
 	  break;
 	}
 
diff --git a/gcc/tree-vect-data-refs.c b/gcc/tree-vect-data-refs.c
index fbc35a3..fe8cd9d 100644
--- a/gcc/tree-vect-data-refs.c
+++ b/gcc/tree-vect-data-refs.c
@@ -4600,7 +4600,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;
@@ -4695,6 +4694,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);
@@ -4731,6 +4731,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 5db023f..ef79cd4 100644
--- a/gcc/tree-vect-patterns.c
+++ b/gcc/tree-vect-patterns.c
@@ -809,7 +809,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 884e769..a166d1e 100644
--- a/gcc/tree-vect-stmts.c
+++ b/gcc/tree-vect-stmts.c
@@ -1705,7 +1705,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);
 
@@ -2176,20 +2176,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;
@@ -2212,8 +2213,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 = gs->dyn_cast_gimple_call ();
+  if (!stmt)
     return false;
 
   if (gimple_call_internal_p (stmt)
diff --git a/gcc/tree-vectorizer.h b/gcc/tree-vectorizer.h
index f8efe47..f71a70c 100644
--- a/gcc/tree-vectorizer.h
+++ b/gcc/tree-vectorizer.h
@@ -998,7 +998,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/tree.h b/gcc/tree.h
index 9fbc5c4..d8ff456 100644
--- a/gcc/tree.h
+++ b/gcc/tree.h
@@ -4573,8 +4573,9 @@ extern unsigned int get_object_alignment (tree);
 extern bool get_pointer_alignment_1 (tree, unsigned int *,
 				     unsigned HOST_WIDE_INT *);
 extern unsigned int get_pointer_alignment (tree);
-extern tree fold_call_stmt (gimple, bool);
-extern tree gimple_fold_builtin_snprintf_chk (gimple, tree, enum built_in_function);
+extern tree fold_call_stmt (gimple_call, bool);
+extern tree gimple_fold_builtin_snprintf_chk (gimple_call, tree,
+					      enum built_in_function);
 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/value-prof.c b/gcc/value-prof.c
index 555f3a4..a635bf7 100644
--- a/gcc/value-prof.c
+++ b/gcc/value-prof.c
@@ -1293,7 +1293,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))
@@ -1458,12 +1458,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 = gsi_stmt (*gsi)->dyn_cast_gimple_call ();
+  if (!stmt)
     return false;
 
   if (gimple_call_fndecl (stmt) != NULL_TREE)
@@ -1545,7 +1546,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);
 
@@ -1582,7 +1583,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;
@@ -1676,7 +1677,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;
@@ -1688,7 +1689,8 @@ gimple_stringops_transform (gimple_stmt_iterator *gsi)
   tree tree_val;
   int size_arg;
 
-  if (gimple_code (stmt) != GIMPLE_CALL)
+  stmt = gsi_stmt (*gsi)->dyn_cast_gimple_call ();
+  if (!stmt)
     return false;
   fndecl = gimple_call_fndecl (stmt);
   if (!fndecl)
@@ -1892,14 +1894,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 = gs->dyn_cast_gimple_call ();
+  if (!stmt)
     return;
   fndecl = gimple_call_fndecl (stmt);
   if (!fndecl)
diff --git a/gcc/vtable-verify.c b/gcc/vtable-verify.c
index 4e4c21a..8af7829 100644
--- a/gcc/vtable-verify.c
+++ b/gcc/vtable-verify.c
@@ -598,7 +598,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

