From e1c4290953dd46b282a540e692f939b7c9d2da3c Mon Sep 17 00:00:00 2001
From: David Malcolm <dmalcolm@redhat.com>
Date: Thu, 15 May 2014 13:45:38 -0400
Subject: [PATCH 24/29] Use gasm throughout

This corresponds to:
  "[PATCH 23/89] Introduce gimple_asm"
    https://gcc.gnu.org/ml/gcc-patches/2014-04/msg01234.html
from v1 of the patch series.

gcc/
	* coretypes.h (gasm): Add forward declaration.

	* gimple.h (gimple_build_asm_vec): Return a gasm rather than
	just a gimple.
	(gimple_asm_clobbers_memory_p): Require a const gasm rather
	than just a const gimple.
	(gimple_asm_ninputs): Likewise.
	(gimple_asm_noutputs): Likewise.
	(gimple_asm_nclobbers): Likewise.
	(gimple_asm_nlabels): Likewise.
	(gimple_asm_input_op): Likewise.
	(gimple_asm_input_op_ptr): Likewise.
	(gimple_asm_output_op): Likewise.
	(gimple_asm_output_op_ptr): Likewise.
	(gimple_asm_clobber_op): Likewise.
	(gimple_asm_label_op): Likewise.
	(gimple_asm_string): Likewise.
	(gimple_asm_volatile_p): Likewise.
	(gimple_asm_input_p): Likewise.
	(gimple_asm_set_input_op): Require a gasm rather than a plain
	gimple.
	(gimple_asm_set_output_op): Likewise.
	(gimple_asm_set_clobber_op): Likewise.
	(gimple_asm_set_label_op): Likewise.
	(gimple_asm_set_volatile): Likewise.
	(gimple_asm_set_input): Likewise.

	* cfgexpand.c (expand_asm_stmt): Require a gasm rather than
	a plain gimple.
	(expand_gimple_stmt_1): Add checked cast to gasm within
	GIMPLE_ASM case of switch statement.

	* gimple-fold.c (fold_stmt_1): Add new local from checked cast to
	gasm within case GIMPLE_ASM.

	* gimple-pretty-print.c (dump_gimple_asm): Require a gasm rather
	than a plain gimple.
	(pp_gimple_stmt_1): Add checked cast to gasm within
	GIMPLE_ASM case of switch statement.

	* gimple-streamer-in.c (input_gimple_stmt): Add a checked cast to
	gasm.

	* gimple-streamer-out.c (output_gimple_stmt): Add new local from
	checked cast to gasm within case GIMPLE_ASM.

	* gimple-walk.c (walk_gimple_asm): Require a gasm rather than
	a plain gimple.
	(walk_gimple_op): Add checked cast to gasm within GIMPLE_ASM
	case of switch statement.
	(walk_stmt_load_store_addr_ops): Use dyn_cast <gasm *> in place
	of a code check against GIMPLE_ASM to introduce a new gasm
	local.

	* gimple.c (gimple_build_asm_1): Return a gasm rather than
	a plain gimple.
	(gimple_build_asm_vec): Likewise.
	(gimple_has_side_effects): Add a checked cast to gasm.
	(gimple_could_trap_p_1): Likewise.
	(gimple_call_builtin_p): Require a const gasm rather then
	a const gimple.

	* gimplify-me.c (gimple_regimplify_operands): Add a checked cast
	and a new local of type gasm within GIMPLE_ASM case.

	* gimplify.c (gimplify_asm_expr): Convert a local from gimple to
	gasm.

	* ipa-pure-const.c (check_stmt): Add checked casts within
	GIMPLE_ASM case.

	* ssa-iterators.h (op_iter_init): Likewise.

	* tree-cfg.c (make_goto_expr_edges): Convert a local from gimple to
	gasm.
	(cleanup_dead_labels): Add a checked cast and a new local of type
	gasm within GIMPLE_ASM case.
	(gimple_redirect_edge_and_branch): Likewise.
	(is_ctrl_altering_stmt): Add a checked cast.
	(need_fake_edge_p): Replace a code check against GIMPLE_ASM with a
	dyn_cast <gasm *>.

	* tree-complex.c (expand_complex_comparison): Convert a local from
	gimple to gasm.

	* tree-data-ref.c (get_references_in_stmt): Add a checked cast to
	gasm.

	* tree-eh.c (stmt_could_throw_p): Likewise.

	* tree-inline.c (estimate_num_insns): Likewise.

	* tree-sra.c (scan_function): Add a checked cast and a new local
	of type gasm within GIMPLE_ASM case.
	(sra_modify_function_body): Likewise.
	(ipa_sra_modify_function_body): Likewise.

	* tree-ssa-coalesce.c (create_outofssa_var_map): Likewise.

	* tree-ssa-dce.c (propagate_necessity): Replace a code check
	against GIMPLE_ASM with a dyn_cast <gasm *>.

	* tree-ssa-operands.c (maybe_add_call_vops): Require a gasm
	rather than a plain gimple.
	(parse_ssa_operands): Add a checked cast to gasm.

	* tree-ssa-structalias.c (find_func_aliases): Add a checked cast
	and a new local of type gasm within clause guarded by
	code check.

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

	* tree-ssa.c (execute_update_addresses_taken): Add checked casts
	and new locals of type gasm within clauses guarded by code check.

	* doc/gimple.texi: Update for above changes.
---
 gcc/cfgexpand.c            |   4 +-
 gcc/coretypes.h            |   1 +
 gcc/doc/gimple.texi        |  26 ++++-----
 gcc/gimple-fold.c          |  11 ++--
 gcc/gimple-pretty-print.c  |   4 +-
 gcc/gimple-streamer-in.c   |   5 +-
 gcc/gimple-streamer-out.c  |  15 +++--
 gcc/gimple-walk.c          |  16 +++---
 gcc/gimple.c               |  12 ++--
 gcc/gimple.h               | 135 +++++++++++++++++++--------------------------
 gcc/gimplify-me.c          |   9 +--
 gcc/gimplify.c             |   2 +-
 gcc/ipa-pure-const.c       |   4 +-
 gcc/ssa-iterators.h        |   2 +-
 gcc/tree-cfg.c             |  20 ++++---
 gcc/tree-complex.c         |   2 +-
 gcc/tree-data-ref.c        |   3 +-
 gcc/tree-eh.c              |   2 +-
 gcc/tree-inline.c          |   3 +-
 gcc/tree-sra.c             |  77 ++++++++++++++------------
 gcc/tree-ssa-coalesce.c    |   9 +--
 gcc/tree-ssa-dce.c         |   6 +-
 gcc/tree-ssa-operands.c    |   4 +-
 gcc/tree-ssa-structalias.c |   9 +--
 gcc/tree-ssa-threadedge.c  |   3 +-
 gcc/tree-ssa.c             |  18 +++---
 26 files changed, 204 insertions(+), 198 deletions(-)

diff --git a/gcc/cfgexpand.c b/gcc/cfgexpand.c
index dd36c57..a3627e6 100644
--- a/gcc/cfgexpand.c
+++ b/gcc/cfgexpand.c
@@ -2911,7 +2911,7 @@ expand_asm_operands (tree string, tree outputs, tree inputs,
 
 
 static void
-expand_asm_stmt (gimple *stmt)
+expand_asm_stmt (gasm *stmt)
 {
   int noutputs;
   tree outputs, tail, t;
@@ -3196,7 +3196,7 @@ expand_gimple_stmt_1 (gimple *stmt)
       expand_case (as_a <gswitch *> (stmt));
       break;
     case GIMPLE_ASM:
-      expand_asm_stmt (stmt);
+      expand_asm_stmt (as_a <gasm *> (stmt));
       break;
     case GIMPLE_CALL:
       expand_call_stmt (as_a <gcall *> (stmt));
diff --git a/gcc/coretypes.h b/gcc/coretypes.h
index d0ae01d..66f9f49 100644
--- a/gcc/coretypes.h
+++ b/gcc/coretypes.h
@@ -76,6 +76,7 @@ class ggoto;
 class glabel;
 class gswitch;
 class gassign;
+class gasm;
 class gcall;
 class greturn;
 class gbind;
diff --git a/gcc/doc/gimple.texi b/gcc/doc/gimple.texi
index 0c1296b..4339606 100644
--- a/gcc/doc/gimple.texi
+++ b/gcc/doc/gimple.texi
@@ -1071,64 +1071,64 @@ registers.  The rest of the arguments trees for each input,
 output, and clobbered registers.
 @end deftypefn
 
-@deftypefn {GIMPLE function} gimple *gimple_build_asm_vec (@
+@deftypefn {GIMPLE function} gasm *gimple_build_asm_vec (@
 const char *, VEC(tree,gc) *, VEC(tree,gc) *, VEC(tree,gc) *)
 Identical to gimple_build_asm, but the arguments are passed in
 VECs.
 @end deftypefn
 
-@deftypefn {GIMPLE function} unsigned gimple_asm_ninputs (gimple *g)
+@deftypefn {GIMPLE function} unsigned gimple_asm_ninputs (const gasm *g)
 Return the number of input operands for @code{GIMPLE_ASM} @code{G}.
 @end deftypefn
 
-@deftypefn {GIMPLE function} unsigned gimple_asm_noutputs (gimple *g)
+@deftypefn {GIMPLE function} unsigned gimple_asm_noutputs (const gasm *g)
 Return the number of output operands for @code{GIMPLE_ASM} @code{G}.
 @end deftypefn
 
-@deftypefn {GIMPLE function} unsigned gimple_asm_nclobbers (gimple *g)
+@deftypefn {GIMPLE function} unsigned gimple_asm_nclobbers (const gasm *g)
 Return the number of clobber operands for @code{GIMPLE_ASM} @code{G}.
 @end deftypefn
 
-@deftypefn {GIMPLE function} tree gimple_asm_input_op (gimple *g, @
+@deftypefn {GIMPLE function} tree gimple_asm_input_op (const gasm *g, @
 unsigned index)
 Return input operand @code{INDEX} of @code{GIMPLE_ASM} @code{G}.
 @end deftypefn
 
-@deftypefn {GIMPLE function} void gimple_asm_set_input_op (gimple *g, @
+@deftypefn {GIMPLE function} void gimple_asm_set_input_op (gasm *g, @
 unsigned index, tree in_op)
 Set @code{IN_OP} to be input operand @code{INDEX} in @code{GIMPLE_ASM} @code{G}.
 @end deftypefn
 
-@deftypefn {GIMPLE function} tree gimple_asm_output_op (gimple *g, @
+@deftypefn {GIMPLE function} tree gimple_asm_output_op (const gasm *g, @
 unsigned index)
 Return output operand @code{INDEX} of @code{GIMPLE_ASM} @code{G}.
 @end deftypefn
 
-@deftypefn {GIMPLE function} void gimple_asm_set_output_op (gimple *g, @
+@deftypefn {GIMPLE function} void gimple_asm_set_output_op (gasm *g, @
 unsigned index, tree out_op)
 Set @code{OUT_OP} to be output operand @code{INDEX} in @code{GIMPLE_ASM} @code{G}.
 @end deftypefn
 
-@deftypefn {GIMPLE function} tree gimple_asm_clobber_op (gimple *g, @
+@deftypefn {GIMPLE function} tree gimple_asm_clobber_op (const gasm *g, @
 unsigned index)
 Return clobber operand @code{INDEX} of @code{GIMPLE_ASM} @code{G}.
 @end deftypefn
 
-@deftypefn {GIMPLE function} void gimple_asm_set_clobber_op (gimple *g, @
+@deftypefn {GIMPLE function} void gimple_asm_set_clobber_op (gasm *g, @
 unsigned index, tree clobber_op)
 Set @code{CLOBBER_OP} to be clobber operand @code{INDEX} in @code{GIMPLE_ASM} @code{G}.
 @end deftypefn
 
-@deftypefn {GIMPLE function} {const char *} gimple_asm_string (gimple *g)
+@deftypefn {GIMPLE function} {const char *} gimple_asm_string (const gasm *g)
 Return the string representing the assembly instruction in
 @code{GIMPLE_ASM} @code{G}.
 @end deftypefn
 
-@deftypefn {GIMPLE function} bool gimple_asm_volatile_p (gimple *g)
+@deftypefn {GIMPLE function} bool gimple_asm_volatile_p (const gasm *g)
 Return true if @code{G} is an asm statement marked volatile.
 @end deftypefn
 
-@deftypefn {GIMPLE function} void gimple_asm_set_volatile (gimple *g)
+@deftypefn {GIMPLE function} void gimple_asm_set_volatile (gasm *g)
 Mark asm statement @code{G} as volatile.
 @end deftypefn
 
diff --git a/gcc/gimple-fold.c b/gcc/gimple-fold.c
index c8336f3..9ad862d 100644
--- a/gcc/gimple-fold.c
+++ b/gcc/gimple-fold.c
@@ -1304,17 +1304,18 @@ fold_stmt_1 (gimple_stmt_iterator *gsi, bool inplace)
     case GIMPLE_ASM:
       /* Fold *& in asm operands.  */
       {
+	gasm *asm_stmt = as_a <gasm *> (stmt);
 	size_t noutputs;
 	const char **oconstraints;
 	const char *constraint;
 	bool allows_mem, allows_reg;
 
-	noutputs = gimple_asm_noutputs (stmt);
+	noutputs = gimple_asm_noutputs (asm_stmt);
 	oconstraints = XALLOCAVEC (const char *, noutputs);
 
-	for (i = 0; i < gimple_asm_noutputs (stmt); ++i)
+	for (i = 0; i < gimple_asm_noutputs (asm_stmt); ++i)
 	  {
-	    tree link = gimple_asm_output_op (stmt, i);
+	    tree link = gimple_asm_output_op (asm_stmt, i);
 	    tree op = TREE_VALUE (link);
 	    oconstraints[i]
 	      = TREE_STRING_POINTER (TREE_VALUE (TREE_PURPOSE (link)));
@@ -1325,9 +1326,9 @@ fold_stmt_1 (gimple_stmt_iterator *gsi, bool inplace)
 		changed = true;
 	      }
 	  }
-	for (i = 0; i < gimple_asm_ninputs (stmt); ++i)
+	for (i = 0; i < gimple_asm_ninputs (asm_stmt); ++i)
 	  {
-	    tree link = gimple_asm_input_op (stmt, i);
+	    tree link = gimple_asm_input_op (asm_stmt, i);
 	    tree op = TREE_VALUE (link);
 	    constraint
 	      = TREE_STRING_POINTER (TREE_VALUE (TREE_PURPOSE (link)));
diff --git a/gcc/gimple-pretty-print.c b/gcc/gimple-pretty-print.c
index 402094e..77daa4c 100644
--- a/gcc/gimple-pretty-print.c
+++ b/gcc/gimple-pretty-print.c
@@ -1579,7 +1579,7 @@ dump_gimple_transaction (pretty_printer *buffer, gimple *gs, int spc, int flags)
    dumpfile.h).  */
 
 static void
-dump_gimple_asm (pretty_printer *buffer, gimple *gs, int spc, int flags)
+dump_gimple_asm (pretty_printer *buffer, gasm *gs, int spc, int flags)
 {
   unsigned int i, n, f, fields;
 
@@ -2084,7 +2084,7 @@ pp_gimple_stmt_1 (pretty_printer *buffer, gimple *gs, int spc, int flags)
   switch (gimple_code (gs))
     {
     case GIMPLE_ASM:
-      dump_gimple_asm (buffer, gs, spc, flags);
+      dump_gimple_asm (buffer, as_a <gasm *> (gs), spc, flags);
       break;
 
     case GIMPLE_ASSIGN:
diff --git a/gcc/gimple-streamer-in.c b/gcc/gimple-streamer-in.c
index 457b4c9..f5160bb 100644
--- a/gcc/gimple-streamer-in.c
+++ b/gcc/gimple-streamer-in.c
@@ -218,11 +218,12 @@ input_gimple_stmt (struct lto_input_block *ib, struct data_in *data_in,
     }
   else if (code == GIMPLE_ASM)
     {
+      gasm *asm_stmt = as_a <gasm *> (stmt);
       unsigned i;
 
-      for (i = 0; i < gimple_asm_noutputs (stmt); i++)
+      for (i = 0; i < gimple_asm_noutputs (asm_stmt); i++)
 	{
-	  tree op = TREE_VALUE (gimple_asm_output_op (stmt, i));
+	  tree op = TREE_VALUE (gimple_asm_output_op (asm_stmt, i));
 	  if (TREE_CODE (op) == SSA_NAME)
 	    SSA_NAME_DEF_STMT (op) = stmt;
 	}
diff --git a/gcc/gimple-streamer-out.c b/gcc/gimple-streamer-out.c
index 5750d5f..c96e752 100644
--- a/gcc/gimple-streamer-out.c
+++ b/gcc/gimple-streamer-out.c
@@ -109,12 +109,15 @@ output_gimple_stmt (struct output_block *ob, gimple *stmt)
       break;
 
     case GIMPLE_ASM:
-      streamer_write_uhwi (ob, gimple_asm_ninputs (stmt));
-      streamer_write_uhwi (ob, gimple_asm_noutputs (stmt));
-      streamer_write_uhwi (ob, gimple_asm_nclobbers (stmt));
-      streamer_write_uhwi (ob, gimple_asm_nlabels (stmt));
-      streamer_write_string (ob, ob->main_stream, gimple_asm_string (stmt),
-			     true);
+      {
+	gasm *asm_stmt = as_a <gasm *> (stmt);
+	streamer_write_uhwi (ob, gimple_asm_ninputs (asm_stmt));
+	streamer_write_uhwi (ob, gimple_asm_noutputs (asm_stmt));
+	streamer_write_uhwi (ob, gimple_asm_nclobbers (asm_stmt));
+	streamer_write_uhwi (ob, gimple_asm_nlabels (asm_stmt));
+	streamer_write_string (ob, ob->main_stream,
+			       gimple_asm_string (asm_stmt), true);
+      }
       /* Fallthru  */
 
     case GIMPLE_ASSIGN:
diff --git a/gcc/gimple-walk.c b/gcc/gimple-walk.c
index 9ec37c0..7cb1cf412 100644
--- a/gcc/gimple-walk.c
+++ b/gcc/gimple-walk.c
@@ -94,7 +94,7 @@ walk_gimple_seq (gimple_seq seq, walk_stmt_fn callback_stmt,
 /* Helper function for walk_gimple_stmt.  Walk operands of a GIMPLE_ASM.  */
 
 static tree
-walk_gimple_asm (gimple *stmt, walk_tree_fn callback_op,
+walk_gimple_asm (gasm *stmt, walk_tree_fn callback_op,
 		 struct walk_stmt_info *wi)
 {
   tree ret, op;
@@ -292,7 +292,7 @@ walk_gimple_op (gimple *stmt, walk_tree_fn callback_op,
       break;
 
     case GIMPLE_ASM:
-      ret = walk_gimple_asm (stmt, callback_op, wi);
+      ret = walk_gimple_asm (as_a <gasm *> (stmt), callback_op, wi);
       if (ret)
 	return ret;
       break;
@@ -779,18 +779,18 @@ walk_stmt_load_store_addr_ops (gimple *stmt, void *data,
 	ret |= visit_addr (stmt, gimple_call_lhs (stmt),
 			   gimple_call_lhs (stmt), data);
     }
-  else if (gimple_code (stmt) == GIMPLE_ASM)
+  else if (gasm *asm_stmt = dyn_cast <gasm *> (stmt))
     {
       unsigned noutputs;
       const char *constraint;
       const char **oconstraints;
       bool allows_mem, allows_reg, is_inout;
-      noutputs = gimple_asm_noutputs (stmt);
+      noutputs = gimple_asm_noutputs (asm_stmt);
       oconstraints = XALLOCAVEC (const char *, noutputs);
       if (visit_store || visit_addr)
-	for (i = 0; i < gimple_asm_noutputs (stmt); ++i)
+	for (i = 0; i < gimple_asm_noutputs (asm_stmt); ++i)
 	  {
-	    tree link = gimple_asm_output_op (stmt, i);
+	    tree link = gimple_asm_output_op (asm_stmt, i);
 	    tree op = get_base_loadstore (TREE_VALUE (link));
 	    if (op && visit_store)
 	      ret |= visit_store (stmt, op, TREE_VALUE (link), data);
@@ -806,9 +806,9 @@ walk_stmt_load_store_addr_ops (gimple *stmt, void *data,
 	      }
 	  }
       if (visit_load || visit_addr)
-	for (i = 0; i < gimple_asm_ninputs (stmt); ++i)
+	for (i = 0; i < gimple_asm_ninputs (asm_stmt); ++i)
 	  {
-	    tree link = gimple_asm_input_op (stmt, i);
+	    tree link = gimple_asm_input_op (asm_stmt, i);
 	    tree op = TREE_VALUE (link);
 	    if (visit_addr
 		&& TREE_CODE (op) == ADDR_EXPR)
diff --git a/gcc/gimple.c b/gcc/gimple.c
index e8151a9..d375a4c 100644
--- a/gcc/gimple.c
+++ b/gcc/gimple.c
@@ -539,7 +539,7 @@ gimple_build_bind (tree vars, gimple_seq body, tree block)
    NCLOBBERS is the number of clobbered registers.
    */
 
-static inline gimple *
+static inline gasm *
 gimple_build_asm_1 (const char *string, unsigned ninputs, unsigned noutputs,
                     unsigned nclobbers, unsigned nlabels)
 {
@@ -577,12 +577,12 @@ gimple_build_asm_1 (const char *string, unsigned ninputs, unsigned noutputs,
    CLOBBERS is a vector of the clobbered register parameters.
    LABELS is a vector of destination labels.  */
 
-gimple *
+gasm *
 gimple_build_asm_vec (const char *string, vec<tree, va_gc> *inputs,
                       vec<tree, va_gc> *outputs, vec<tree, va_gc> *clobbers,
 		      vec<tree, va_gc> *labels)
 {
-  gimple *p;
+  gasm *p;
   unsigned i;
 
   p = gimple_build_asm_1 (string,
@@ -1803,7 +1803,7 @@ gimple_has_side_effects (const gimple *s)
     return true;
 
   if (gimple_code (s) == GIMPLE_ASM
-      && gimple_asm_volatile_p (s))
+      && gimple_asm_volatile_p (as_a <const gasm *> (s)))
     return true;
 
   if (is_gimple_call (s))
@@ -1844,7 +1844,7 @@ gimple_could_trap_p_1 (gimple *s, bool include_mem, bool include_stores)
   switch (gimple_code (s))
     {
     case GIMPLE_ASM:
-      return gimple_asm_volatile_p (s);
+      return gimple_asm_volatile_p (as_a <gasm *> (s));
 
     case GIMPLE_CALL:
       t = gimple_call_fndecl (s);
@@ -2458,7 +2458,7 @@ gimple_call_builtin_p (const gimple *stmt, enum built_in_function code)
    GIMPLE_ASM.  */
 
 bool
-gimple_asm_clobbers_memory_p (const gimple *stmt)
+gimple_asm_clobbers_memory_p (const gasm *stmt)
 {
   unsigned i;
 
diff --git a/gcc/gimple.h b/gcc/gimple.h
index 955167f..40ee565 100644
--- a/gcc/gimple.h
+++ b/gcc/gimple.h
@@ -1312,9 +1312,9 @@ glabel *gimple_build_label (tree label);
 ggoto *gimple_build_goto (tree dest);
 gimple *gimple_build_nop (void);
 gbind *gimple_build_bind (tree, gimple_seq, tree);
-gimple *gimple_build_asm_vec (const char *, vec<tree, va_gc> *,
-			     vec<tree, va_gc> *, vec<tree, va_gc> *,
-			     vec<tree, va_gc> *);
+gasm *gimple_build_asm_vec (const char *, vec<tree, va_gc> *,
+			    vec<tree, va_gc> *, vec<tree, va_gc> *,
+			    vec<tree, va_gc> *);
 gimple *gimple_build_catch (tree, gimple_seq);
 gimple *gimple_build_eh_filter (tree, gimple_seq);
 gimple *gimple_build_eh_must_not_throw (tree);
@@ -1390,7 +1390,7 @@ extern bool gimple_builtin_call_types_compatible_p (const gimple *, tree);
 extern bool gimple_call_builtin_p (const gimple *);
 extern bool gimple_call_builtin_p (const gimple *, enum built_in_class);
 extern bool gimple_call_builtin_p (const gimple *, enum built_in_function);
-extern bool gimple_asm_clobbers_memory_p (const gimple *);
+extern bool gimple_asm_clobbers_memory_p (const gasm *);
 extern void dump_decl_set (FILE *, bitmap);
 extern bool nonfreeing_call_p (gimple *);
 extern bool infer_nonnull_range (gimple *, tree, bool, bool);
@@ -3290,207 +3290,188 @@ gimple_bind_set_block (gbind *bind_stmt, tree block)
 }
 
 
-/* Return the number of input operands for GIMPLE_ASM GS.  */
+/* Return the number of input operands for GIMPLE_ASM ASM_STMT.  */
 
 static inline unsigned
-gimple_asm_ninputs (const gimple *gs)
+gimple_asm_ninputs (const gasm *asm_stmt)
 {
-  const gasm *asm_stmt = as_a <const gasm *> (gs);
   return asm_stmt->ni;
 }
 
 
-/* Return the number of output operands for GIMPLE_ASM GS.  */
+/* Return the number of output operands for GIMPLE_ASM ASM_STMT.  */
 
 static inline unsigned
-gimple_asm_noutputs (const gimple *gs)
+gimple_asm_noutputs (const gasm *asm_stmt)
 {
-  const gasm *asm_stmt = as_a <const gasm *> (gs);
   return asm_stmt->no;
 }
 
 
-/* Return the number of clobber operands for GIMPLE_ASM GS.  */
+/* Return the number of clobber operands for GIMPLE_ASM ASM_STMT.  */
 
 static inline unsigned
-gimple_asm_nclobbers (const gimple *gs)
+gimple_asm_nclobbers (const gasm *asm_stmt)
 {
-  const gasm *asm_stmt = as_a <const gasm *> (gs);
   return asm_stmt->nc;
 }
 
-/* Return the number of label operands for GIMPLE_ASM GS.  */
+/* Return the number of label operands for GIMPLE_ASM ASM_STMT.  */
 
 static inline unsigned
-gimple_asm_nlabels (const gimple *gs)
+gimple_asm_nlabels (const gasm *asm_stmt)
 {
-  const gasm *asm_stmt = as_a <const gasm *> (gs);
   return asm_stmt->nl;
 }
 
-/* Return input operand INDEX of GIMPLE_ASM GS.  */
+/* Return input operand INDEX of GIMPLE_ASM ASM_STMT.  */
 
 static inline tree
-gimple_asm_input_op (const gimple *gs, unsigned index)
+gimple_asm_input_op (const gasm *asm_stmt, unsigned index)
 {
-  const gasm *asm_stmt = as_a <const gasm *> (gs);
   gcc_gimple_checking_assert (index < asm_stmt->ni);
-  return gimple_op (gs, index + asm_stmt->no);
+  return gimple_op (asm_stmt, index + asm_stmt->no);
 }
 
-/* Return a pointer to input operand INDEX of GIMPLE_ASM GS.  */
+/* Return a pointer to input operand INDEX of GIMPLE_ASM ASM_STMT.  */
 
 static inline tree *
-gimple_asm_input_op_ptr (const gimple *gs, unsigned index)
+gimple_asm_input_op_ptr (const gasm *asm_stmt, unsigned index)
 {
-  const gasm *asm_stmt = as_a <const gasm *> (gs);
   gcc_gimple_checking_assert (index < asm_stmt->ni);
-  return gimple_op_ptr (gs, index + asm_stmt->no);
+  return gimple_op_ptr (asm_stmt, index + asm_stmt->no);
 }
 
 
-/* Set IN_OP to be input operand INDEX in GIMPLE_ASM GS.  */
+/* Set IN_OP to be input operand INDEX in GIMPLE_ASM ASM_STMT.  */
 
 static inline void
-gimple_asm_set_input_op (gimple *gs, unsigned index, tree in_op)
+gimple_asm_set_input_op (gasm *asm_stmt, unsigned index, tree in_op)
 {
-  gasm *asm_stmt = as_a <gasm *> (gs);
   gcc_gimple_checking_assert (index < asm_stmt->ni
 			      && TREE_CODE (in_op) == TREE_LIST);
-  gimple_set_op (gs, index + asm_stmt->no, in_op);
+  gimple_set_op (asm_stmt, index + asm_stmt->no, in_op);
 }
 
 
-/* Return output operand INDEX of GIMPLE_ASM GS.  */
+/* Return output operand INDEX of GIMPLE_ASM ASM_STMT.  */
 
 static inline tree
-gimple_asm_output_op (const gimple *gs, unsigned index)
+gimple_asm_output_op (const gasm *asm_stmt, unsigned index)
 {
-  const gasm *asm_stmt = as_a <const gasm *> (gs);
   gcc_gimple_checking_assert (index < asm_stmt->no);
-  return gimple_op (gs, index);
+  return gimple_op (asm_stmt, index);
 }
 
-/* Return a pointer to output operand INDEX of GIMPLE_ASM GS.  */
+/* Return a pointer to output operand INDEX of GIMPLE_ASM ASM_STMT.  */
 
 static inline tree *
-gimple_asm_output_op_ptr (const gimple *gs, unsigned index)
+gimple_asm_output_op_ptr (const gasm *asm_stmt, unsigned index)
 {
-  const gasm *asm_stmt = as_a <const gasm *> (gs);
   gcc_gimple_checking_assert (index < asm_stmt->no);
-  return gimple_op_ptr (gs, index);
+  return gimple_op_ptr (asm_stmt, index);
 }
 
 
-/* Set OUT_OP to be output operand INDEX in GIMPLE_ASM GS.  */
+/* Set OUT_OP to be output operand INDEX in GIMPLE_ASM ASM_STMT.  */
 
 static inline void
-gimple_asm_set_output_op (gimple *gs, unsigned index, tree out_op)
+gimple_asm_set_output_op (gasm *asm_stmt, unsigned index, tree out_op)
 {
-  gasm *asm_stmt = as_a <gasm *> (gs);
   gcc_gimple_checking_assert (index < asm_stmt->no
 			      && TREE_CODE (out_op) == TREE_LIST);
-  gimple_set_op (gs, index, out_op);
+  gimple_set_op (asm_stmt, index, out_op);
 }
 
 
-/* Return clobber operand INDEX of GIMPLE_ASM GS.  */
+/* Return clobber operand INDEX of GIMPLE_ASM ASM_STMT.  */
 
 static inline tree
-gimple_asm_clobber_op (const gimple *gs, unsigned index)
+gimple_asm_clobber_op (const gasm *asm_stmt, unsigned index)
 {
-  const gasm *asm_stmt = as_a <const gasm *> (gs);
   gcc_gimple_checking_assert (index < asm_stmt->nc);
-  return gimple_op (gs, index + asm_stmt->ni + asm_stmt->no);
+  return gimple_op (asm_stmt, index + asm_stmt->ni + asm_stmt->no);
 }
 
 
-/* Set CLOBBER_OP to be clobber operand INDEX in GIMPLE_ASM GS.  */
+/* Set CLOBBER_OP to be clobber operand INDEX in GIMPLE_ASM ASM_STMT.  */
 
 static inline void
-gimple_asm_set_clobber_op (gimple *gs, unsigned index, tree clobber_op)
+gimple_asm_set_clobber_op (gasm *asm_stmt, unsigned index, tree clobber_op)
 {
-  gasm *asm_stmt = as_a <gasm *> (gs);
   gcc_gimple_checking_assert (index < asm_stmt->nc
 			      && TREE_CODE (clobber_op) == TREE_LIST);
-  gimple_set_op (gs, index + asm_stmt->ni + asm_stmt->no, clobber_op);
+  gimple_set_op (asm_stmt, index + asm_stmt->ni + asm_stmt->no, clobber_op);
 }
 
-/* Return label operand INDEX of GIMPLE_ASM GS.  */
+/* Return label operand INDEX of GIMPLE_ASM ASM_STMT.  */
 
 static inline tree
-gimple_asm_label_op (const gimple *gs, unsigned index)
+gimple_asm_label_op (const gasm *asm_stmt, unsigned index)
 {
-  const gasm *asm_stmt = as_a <const gasm *> (gs);
   gcc_gimple_checking_assert (index < asm_stmt->nl);
-  return gimple_op (gs, index + asm_stmt->ni + asm_stmt->nc);
+  return gimple_op (asm_stmt, index + asm_stmt->ni + asm_stmt->nc);
 }
 
-/* Set LABEL_OP to be label operand INDEX in GIMPLE_ASM GS.  */
+/* Set LABEL_OP to be label operand INDEX in GIMPLE_ASM ASM_STMT.  */
 
 static inline void
-gimple_asm_set_label_op (gimple *gs, unsigned index, tree label_op)
+gimple_asm_set_label_op (gasm *asm_stmt, unsigned index, tree label_op)
 {
-  gasm *asm_stmt = as_a <gasm *> (gs);
   gcc_gimple_checking_assert (index < asm_stmt->nl
 			      && TREE_CODE (label_op) == TREE_LIST);
-  gimple_set_op (gs, index + asm_stmt->ni + asm_stmt->nc, label_op);
+  gimple_set_op (asm_stmt, index + asm_stmt->ni + asm_stmt->nc, label_op);
 }
 
 /* Return the string representing the assembly instruction in
-   GIMPLE_ASM GS.  */
+   GIMPLE_ASM ASM_STMT.  */
 
 static inline const char *
-gimple_asm_string (const gimple *gs)
+gimple_asm_string (const gasm *asm_stmt)
 {
-  const gasm *asm_stmt = as_a <const gasm *> (gs);
   return asm_stmt->string;
 }
 
 
-/* Return true if GS is an asm statement marked volatile.  */
+/* Return true ASM_STMT ASM_STMT is an asm statement marked volatile.  */
 
 static inline bool
-gimple_asm_volatile_p (const gimple *gs)
+gimple_asm_volatile_p (const gasm *asm_stmt)
 {
-  GIMPLE_CHECK (gs, GIMPLE_ASM);
-  return (gs->subcode & GF_ASM_VOLATILE) != 0;
+  return (asm_stmt->subcode & GF_ASM_VOLATILE) != 0;
 }
 
 
-/* If VOLATLE_P is true, mark asm statement GS as volatile.  */
+/* If VOLATLE_P is true, mark asm statement ASM_STMT as volatile.  */
 
 static inline void
-gimple_asm_set_volatile (gimple *gs, bool volatile_p)
+gimple_asm_set_volatile (gasm *asm_stmt, bool volatile_p)
 {
-  GIMPLE_CHECK (gs, GIMPLE_ASM);
   if (volatile_p)
-    gs->subcode |= GF_ASM_VOLATILE;
+    asm_stmt->subcode |= GF_ASM_VOLATILE;
   else
-    gs->subcode &= ~GF_ASM_VOLATILE;
+    asm_stmt->subcode &= ~GF_ASM_VOLATILE;
 }
 
 
-/* If INPUT_P is true, mark asm GS as an ASM_INPUT.  */
+/* If INPUT_P is true, mark asm ASM_STMT as an ASM_INPUT.  */
 
 static inline void
-gimple_asm_set_input (gimple *gs, bool input_p)
+gimple_asm_set_input (gasm *asm_stmt, bool input_p)
 {
-  GIMPLE_CHECK (gs, GIMPLE_ASM);
   if (input_p)
-    gs->subcode |= GF_ASM_INPUT;
+    asm_stmt->subcode |= GF_ASM_INPUT;
   else
-    gs->subcode &= ~GF_ASM_INPUT;
+    asm_stmt->subcode &= ~GF_ASM_INPUT;
 }
 
 
-/* Return true if asm GS is an ASM_INPUT.  */
+/* Return true if asm ASM_STMT is an ASM_INPUT.  */
 
 static inline bool
-gimple_asm_input_p (const gimple *gs)
+gimple_asm_input_p (const gasm *asm_stmt)
 {
-  GIMPLE_CHECK (gs, GIMPLE_ASM);
-  return (gs->subcode & GF_ASM_INPUT) != 0;
+  return (asm_stmt->subcode & GF_ASM_INPUT) != 0;
 }
 
 
diff --git a/gcc/gimplify-me.c b/gcc/gimplify-me.c
index 0357331..643c25a 100644
--- a/gcc/gimplify-me.c
+++ b/gcc/gimplify-me.c
@@ -183,7 +183,8 @@ gimple_regimplify_operands (gimple *stmt, gimple_stmt_iterator *gsi_p)
       break;
     case GIMPLE_ASM:
       {
-	size_t i, noutputs = gimple_asm_noutputs (stmt);
+	gasm *asm_stmt = as_a <gasm *> (stmt);
+	size_t i, noutputs = gimple_asm_noutputs (asm_stmt);
 	const char *constraint, **oconstraints;
 	bool allows_mem, allows_reg, is_inout;
 
@@ -191,7 +192,7 @@ gimple_regimplify_operands (gimple *stmt, gimple_stmt_iterator *gsi_p)
 	  = (const char **) alloca ((noutputs) * sizeof (const char *));
 	for (i = 0; i < noutputs; i++)
 	  {
-	    tree op = gimple_asm_output_op (stmt, i);
+	    tree op = gimple_asm_output_op (asm_stmt, i);
 	    constraint = TREE_STRING_POINTER (TREE_VALUE (TREE_PURPOSE (op)));
 	    oconstraints[i] = constraint;
 	    parse_output_constraint (&constraint, i, 0, 0, &allows_mem,
@@ -200,9 +201,9 @@ gimple_regimplify_operands (gimple *stmt, gimple_stmt_iterator *gsi_p)
 			   is_inout ? is_gimple_min_lval : is_gimple_lvalue,
 			   fb_lvalue | fb_mayfail);
 	  }
-	for (i = 0; i < gimple_asm_ninputs (stmt); i++)
+	for (i = 0; i < gimple_asm_ninputs (asm_stmt); i++)
 	  {
-	    tree op = gimple_asm_input_op (stmt, i);
+	    tree op = gimple_asm_input_op (asm_stmt, i);
 	    constraint = TREE_STRING_POINTER (TREE_VALUE (TREE_PURPOSE (op)));
 	    parse_input_constraint (&constraint, 0, 0, noutputs, 0,
 				    oconstraints, &allows_mem, &allows_reg);
diff --git a/gcc/gimplify.c b/gcc/gimplify.c
index 22afe63..aa6efef 100644
--- a/gcc/gimplify.c
+++ b/gcc/gimplify.c
@@ -4883,7 +4883,7 @@ gimplify_asm_expr (tree *expr_p, gimple_seq *pre_p, gimple_seq *post_p)
   const char *constraint;
   bool allows_mem, allows_reg, is_inout;
   enum gimplify_status ret, tret;
-  gimple *stmt;
+  gasm *stmt;
   vec<tree, va_gc> *inputs;
   vec<tree, va_gc> *outputs;
   vec<tree, va_gc> *clobbers;
diff --git a/gcc/ipa-pure-const.c b/gcc/ipa-pure-const.c
index d91b73e..6519bd2 100644
--- a/gcc/ipa-pure-const.c
+++ b/gcc/ipa-pure-const.c
@@ -697,14 +697,14 @@ check_stmt (gimple_stmt_iterator *gsip, funct_state local, bool ipa)
 	}
       break;
     case GIMPLE_ASM:
-      if (gimple_asm_clobbers_memory_p (stmt))
+      if (gimple_asm_clobbers_memory_p (as_a <gasm *> (stmt)))
 	{
 	  if (dump_file)
 	    fprintf (dump_file, "    memory asm clobber is not const/pure\n");
 	  /* Abandon all hope, ye who enter here. */
 	  local->pure_const_state = IPA_NEITHER;
 	}
-      if (gimple_asm_volatile_p (stmt))
+      if (gimple_asm_volatile_p (as_a <gasm *> (stmt)))
 	{
 	  if (dump_file)
 	    fprintf (dump_file, "    volatile is not const/pure\n");
diff --git a/gcc/ssa-iterators.h b/gcc/ssa-iterators.h
index 0c60fd0..464af70 100644
--- a/gcc/ssa-iterators.h
+++ b/gcc/ssa-iterators.h
@@ -610,7 +610,7 @@ op_iter_init (ssa_op_iter *ptr, gimple *stmt, int flags)
 	    ptr->numops = 1;
 	    break;
 	  case GIMPLE_ASM:
-	    ptr->numops = gimple_asm_noutputs (stmt);
+	    ptr->numops = gimple_asm_noutputs (as_a <gasm *> (stmt));
 	    break;
 	  default:
 	    ptr->numops = 0;
diff --git a/gcc/tree-cfg.c b/gcc/tree-cfg.c
index 387def1..e9a9967 100644
--- a/gcc/tree-cfg.c
+++ b/gcc/tree-cfg.c
@@ -1216,7 +1216,7 @@ make_goto_expr_edges (basic_block bb)
 static void
 make_gimple_asm_edges (basic_block bb)
 {
-  gimple *stmt = last_stmt (bb);
+  gasm *stmt = as_a <gasm *> (last_stmt (bb));
   int i, n = gimple_asm_nlabels (stmt);
 
   for (i = 0; i < n; ++i)
@@ -1416,11 +1416,12 @@ cleanup_dead_labels (void)
 
 	case GIMPLE_ASM:
 	  {
-	    int i, n = gimple_asm_nlabels (stmt);
+	    gasm *asm_stmt = as_a <gasm *> (stmt);
+	    int i, n = gimple_asm_nlabels (asm_stmt);
 
 	    for (i = 0; i < n; ++i)
 	      {
-		tree cons = gimple_asm_label_op (stmt, i);
+		tree cons = gimple_asm_label_op (asm_stmt, i);
 		tree label = main_block_label (TREE_VALUE (cons));
 		TREE_VALUE (cons) = label;
 	      }
@@ -2392,7 +2393,7 @@ is_ctrl_altering_stmt (gimple *t)
       return true;
 
     case GIMPLE_ASM:
-      if (gimple_asm_nlabels (t) > 0)
+      if (gimple_asm_nlabels (as_a <gasm *> (t)) > 0)
 	return true;
       break;
 
@@ -5479,12 +5480,13 @@ gimple_redirect_edge_and_branch (edge e, basic_block dest)
 
     case GIMPLE_ASM:
       {
-	int i, n = gimple_asm_nlabels (stmt);
+	gasm *asm_stmt = as_a <gasm *> (stmt);
+	int i, n = gimple_asm_nlabels (asm_stmt);
 	tree label = NULL;
 
 	for (i = 0; i < n; ++i)
 	  {
-	    tree cons = gimple_asm_label_op (stmt, i);
+	    tree cons = gimple_asm_label_op (asm_stmt, i);
 	    if (label_to_block (TREE_VALUE (cons)) == e->dest)
 	      {
 		if (!label)
@@ -7523,9 +7525,9 @@ need_fake_edge_p (gimple *t)
 	  return true;
     }
 
-  if (gimple_code (t) == GIMPLE_ASM
-       && (gimple_asm_volatile_p (t) || gimple_asm_input_p (t)))
-    return true;
+  if (gasm *asm_stmt = dyn_cast <gasm *> (t))
+    if (gimple_asm_volatile_p (asm_stmt) || gimple_asm_input_p (asm_stmt))
+      return true;
 
   return false;
 }
diff --git a/gcc/tree-complex.c b/gcc/tree-complex.c
index 18a44bf..633fdc7 100644
--- a/gcc/tree-complex.c
+++ b/gcc/tree-complex.c
@@ -1424,7 +1424,7 @@ expand_complex_comparison (gimple_stmt_iterator *gsi, tree ar, tree ai,
 static void
 expand_complex_asm (gimple_stmt_iterator *gsi)
 {
-  gimple *stmt = gsi_stmt (*gsi);
+  gasm *stmt = as_a <gasm *> (gsi_stmt (*gsi));
   unsigned int i;
 
   for (i = 0; i < gimple_asm_noutputs (stmt); ++i)
diff --git a/gcc/tree-data-ref.c b/gcc/tree-data-ref.c
index 03075f3..2e78f14 100644
--- a/gcc/tree-data-ref.c
+++ b/gcc/tree-data-ref.c
@@ -4370,7 +4370,8 @@ get_references_in_stmt (gimple *stmt, vec<data_ref_loc, va_heap> *references)
 	clobbers_memory = true;
     }
   else if (stmt_code == GIMPLE_ASM
-	   && (gimple_asm_volatile_p (stmt) || gimple_vuse (stmt)))
+	   && (gimple_asm_volatile_p (as_a <gasm *> (stmt))
+	       || gimple_vuse (stmt)))
     clobbers_memory = true;
 
   if (!gimple_vuse (stmt))
diff --git a/gcc/tree-eh.c b/gcc/tree-eh.c
index e6c9030..7a9c414 100644
--- a/gcc/tree-eh.c
+++ b/gcc/tree-eh.c
@@ -2801,7 +2801,7 @@ stmt_could_throw_p (gimple *stmt)
     case GIMPLE_ASM:
       if (!cfun->can_throw_non_call_exceptions)
         return false;
-      return gimple_asm_volatile_p (stmt);
+      return gimple_asm_volatile_p (as_a <gasm *> (stmt));
 
     default:
       return false;
diff --git a/gcc/tree-inline.c b/gcc/tree-inline.c
index 2a3742e..525c481 100644
--- a/gcc/tree-inline.c
+++ b/gcc/tree-inline.c
@@ -3901,7 +3901,8 @@ estimate_num_insns (gimple *stmt, eni_weights *weights)
 
     case GIMPLE_ASM:
       {
-	int count = asm_str_count (gimple_asm_string (stmt));
+	int count =
+	  asm_str_count (gimple_asm_string (as_a <gasm *> (stmt)));
 	/* 1000 means infinity. This avoids overflows later
 	   with very long asm statements.  */
 	if (count > 1000)
diff --git a/gcc/tree-sra.c b/gcc/tree-sra.c
index 58e5def..f5dc769 100644
--- a/gcc/tree-sra.c
+++ b/gcc/tree-sra.c
@@ -1348,21 +1348,24 @@ scan_function (void)
 	      break;
 
 	    case GIMPLE_ASM:
-	      walk_stmt_load_store_addr_ops (stmt, NULL, NULL, NULL,
-					     asm_visit_addr);
-	      if (final_bbs)
-		bitmap_set_bit (final_bbs, bb->index);
+	      {
+		gasm *asm_stmt = as_a <gasm *> (stmt);
+		walk_stmt_load_store_addr_ops (asm_stmt, NULL, NULL, NULL,
+					       asm_visit_addr);
+		if (final_bbs)
+		  bitmap_set_bit (final_bbs, bb->index);
 
-	      for (i = 0; i < gimple_asm_ninputs (stmt); i++)
-		{
-		  t = TREE_VALUE (gimple_asm_input_op (stmt, i));
-		  ret |= build_access_from_expr (t, stmt, false);
-		}
-	      for (i = 0; i < gimple_asm_noutputs (stmt); i++)
-		{
-		  t = TREE_VALUE (gimple_asm_output_op (stmt, i));
-		  ret |= build_access_from_expr (t, stmt, true);
-		}
+		for (i = 0; i < gimple_asm_ninputs (asm_stmt); i++)
+		  {
+		    t = TREE_VALUE (gimple_asm_input_op (asm_stmt, i));
+		    ret |= build_access_from_expr (t, asm_stmt, false);
+		  }
+		for (i = 0; i < gimple_asm_noutputs (asm_stmt); i++)
+		  {
+		    t = TREE_VALUE (gimple_asm_output_op (asm_stmt, i));
+		    ret |= build_access_from_expr (t, asm_stmt, true);
+		  }
+	      }
 	      break;
 
 	    default:
@@ -3434,16 +3437,19 @@ sra_modify_function_body (void)
 	      break;
 
 	    case GIMPLE_ASM:
-	      for (i = 0; i < gimple_asm_ninputs (stmt); i++)
-		{
-		  t = &TREE_VALUE (gimple_asm_input_op (stmt, i));
-		  modified |= sra_modify_expr (t, &gsi, false);
-		}
-	      for (i = 0; i < gimple_asm_noutputs (stmt); i++)
-		{
-		  t = &TREE_VALUE (gimple_asm_output_op (stmt, i));
-		  modified |= sra_modify_expr (t, &gsi, true);
-		}
+	      {
+		gasm *asm_stmt = as_a <gasm *> (stmt);
+		for (i = 0; i < gimple_asm_ninputs (asm_stmt); i++)
+		  {
+		    t = &TREE_VALUE (gimple_asm_input_op (asm_stmt, i));
+		    modified |= sra_modify_expr (t, &gsi, false);
+		  }
+		for (i = 0; i < gimple_asm_noutputs (asm_stmt); i++)
+		  {
+		    t = &TREE_VALUE (gimple_asm_output_op (asm_stmt, i));
+		    modified |= sra_modify_expr (t, &gsi, true);
+		  }
+	      }
 	      break;
 
 	    default:
@@ -4699,16 +4705,19 @@ ipa_sra_modify_function_body (ipa_parm_adjustment_vec adjustments)
 	      break;
 
 	    case GIMPLE_ASM:
-	      for (i = 0; i < gimple_asm_ninputs (stmt); i++)
-		{
-		  t = &TREE_VALUE (gimple_asm_input_op (stmt, i));
-		  modified |= ipa_modify_expr (t, true, adjustments);
-		}
-	      for (i = 0; i < gimple_asm_noutputs (stmt); i++)
-		{
-		  t = &TREE_VALUE (gimple_asm_output_op (stmt, i));
-		  modified |= ipa_modify_expr (t, false, adjustments);
-		}
+	      {
+		gasm *asm_stmt = as_a <gasm *> (stmt);
+		for (i = 0; i < gimple_asm_ninputs (asm_stmt); i++)
+		  {
+		    t = &TREE_VALUE (gimple_asm_input_op (asm_stmt, i));
+		    modified |= ipa_modify_expr (t, true, adjustments);
+		  }
+		for (i = 0; i < gimple_asm_noutputs (asm_stmt); i++)
+		  {
+		    t = &TREE_VALUE (gimple_asm_output_op (asm_stmt, i));
+		    modified |= ipa_modify_expr (t, false, adjustments);
+		  }
+	      }
 	      break;
 
 	    default:
diff --git a/gcc/tree-ssa-coalesce.c b/gcc/tree-ssa-coalesce.c
index 13353a1..f92572d 100644
--- a/gcc/tree-ssa-coalesce.c
+++ b/gcc/tree-ssa-coalesce.c
@@ -1007,15 +1007,16 @@ create_outofssa_var_map (coalesce_list_p cl, bitmap used_in_copy)
 
 	    case GIMPLE_ASM:
 	      {
+		gasm *asm_stmt = as_a <gasm *> (stmt);
 		unsigned long noutputs, i;
 		unsigned long ninputs;
 		tree *outputs, link;
-		noutputs = gimple_asm_noutputs (stmt);
-		ninputs = gimple_asm_ninputs (stmt);
+		noutputs = gimple_asm_noutputs (asm_stmt);
+		ninputs = gimple_asm_ninputs (asm_stmt);
 		outputs = (tree *) alloca (noutputs * sizeof (tree));
 		for (i = 0; i < noutputs; ++i)
 		  {
-		    link = gimple_asm_output_op (stmt, i);
+		    link = gimple_asm_output_op (asm_stmt, i);
 		    outputs[i] = TREE_VALUE (link);
 		  }
 
@@ -1026,7 +1027,7 @@ create_outofssa_var_map (coalesce_list_p cl, bitmap used_in_copy)
 		    char *end;
 		    unsigned long match;
 
-		    link = gimple_asm_input_op (stmt, i);
+		    link = gimple_asm_input_op (asm_stmt, i);
 		    constraint
 		      = TREE_STRING_POINTER (TREE_VALUE (TREE_PURPOSE (link)));
 		    input = TREE_VALUE (link);
diff --git a/gcc/tree-ssa-dce.c b/gcc/tree-ssa-dce.c
index 5aae24d..d7e47b2 100644
--- a/gcc/tree-ssa-dce.c
+++ b/gcc/tree-ssa-dce.c
@@ -882,14 +882,14 @@ propagate_necessity (bool aggressive)
 		    mark_all_reaching_defs_necessary (stmt);
 		}
 	    }
-	  else if (gimple_code (stmt) == GIMPLE_ASM)
+	  else if (gasm *asm_stmt = dyn_cast <gasm *> (stmt))
 	    {
 	      unsigned i;
 	      mark_all_reaching_defs_necessary (stmt);
 	      /* Inputs may perform loads.  */
-	      for (i = 0; i < gimple_asm_ninputs (stmt); ++i)
+	      for (i = 0; i < gimple_asm_ninputs (asm_stmt); ++i)
 		{
-		  tree op = TREE_VALUE (gimple_asm_input_op (stmt, i));
+		  tree op = TREE_VALUE (gimple_asm_input_op (asm_stmt, i));
 		  if (TREE_CODE (op) != SSA_NAME
 		      && !is_gimple_min_invariant (op)
 		      && TREE_CODE (op) != CONSTRUCTOR
diff --git a/gcc/tree-ssa-operands.c b/gcc/tree-ssa-operands.c
index 2006463..f1c9b53 100644
--- a/gcc/tree-ssa-operands.c
+++ b/gcc/tree-ssa-operands.c
@@ -655,7 +655,7 @@ maybe_add_call_vops (struct function *fn, gcall *stmt)
 /* Scan operands in the ASM_EXPR stmt referred to in INFO.  */
 
 static void
-get_asm_stmt_operands (struct function *fn, gimple *stmt)
+get_asm_stmt_operands (struct function *fn, gasm *stmt)
 {
   size_t i, noutputs;
   const char **oconstraints;
@@ -908,7 +908,7 @@ parse_ssa_operands (struct function *fn, gimple *stmt)
   switch (code)
     {
     case GIMPLE_ASM:
-      get_asm_stmt_operands (fn, stmt);
+      get_asm_stmt_operands (fn, as_a <gasm *> (stmt));
       break;
 
     case GIMPLE_TRANSACTION:
diff --git a/gcc/tree-ssa-structalias.c b/gcc/tree-ssa-structalias.c
index a08612b..edf26c2 100644
--- a/gcc/tree-ssa-structalias.c
+++ b/gcc/tree-ssa-structalias.c
@@ -4773,17 +4773,18 @@ find_func_aliases (struct function *fn, gimple *origt)
   /* Handle asms conservatively by adding escape constraints to everything.  */
   else if (gimple_code (t) == GIMPLE_ASM)
     {
+      gasm *asm_stmt = as_a <gasm *> (t);
       unsigned i, noutputs;
       const char **oconstraints;
       const char *constraint;
       bool allows_mem, allows_reg, is_inout;
 
-      noutputs = gimple_asm_noutputs (t);
+      noutputs = gimple_asm_noutputs (asm_stmt);
       oconstraints = XALLOCAVEC (const char *, noutputs);
 
       for (i = 0; i < noutputs; ++i)
 	{
-	  tree link = gimple_asm_output_op (t, i);
+	  tree link = gimple_asm_output_op (asm_stmt, i);
 	  tree op = TREE_VALUE (link);
 
 	  constraint = TREE_STRING_POINTER (TREE_VALUE (TREE_PURPOSE (link)));
@@ -4811,9 +4812,9 @@ find_func_aliases (struct function *fn, gimple *origt)
 	      lhsc.release ();
 	    }
 	}
-      for (i = 0; i < gimple_asm_ninputs (t); ++i)
+      for (i = 0; i < gimple_asm_ninputs (asm_stmt); ++i)
 	{
-	  tree link = gimple_asm_input_op (t, i);
+	  tree link = gimple_asm_input_op (asm_stmt, i);
 	  tree op = TREE_VALUE (link);
 
 	  constraint = TREE_STRING_POINTER (TREE_VALUE (TREE_PURPOSE (link)));
diff --git a/gcc/tree-ssa-threadedge.c b/gcc/tree-ssa-threadedge.c
index df2c2b5..77142bc 100644
--- a/gcc/tree-ssa-threadedge.c
+++ b/gcc/tree-ssa-threadedge.c
@@ -370,7 +370,8 @@ record_temporary_equivalences_from_stmts_at_dest (edge e,
       /* If the statement has volatile operands, then we assume we
 	 can not thread through this block.  This is overly
 	 conservative in some ways.  */
-      if (gimple_code (stmt) == GIMPLE_ASM && gimple_asm_volatile_p (stmt))
+      if (gimple_code (stmt) == GIMPLE_ASM
+	  && gimple_asm_volatile_p (as_a <gasm *> (stmt)))
 	return NULL;
 
       /* If duplicating this block is going to cause too much code
diff --git a/gcc/tree-ssa.c b/gcc/tree-ssa.c
index 15375bf..9529145 100644
--- a/gcc/tree-ssa.c
+++ b/gcc/tree-ssa.c
@@ -1515,9 +1515,10 @@ execute_update_addresses_taken (void)
 
 	  else if (code == GIMPLE_ASM)
 	    {
-	      for (i = 0; i < gimple_asm_noutputs (stmt); ++i)
+	      gasm *asm_stmt = as_a <gasm *> (stmt);
+	      for (i = 0; i < gimple_asm_noutputs (asm_stmt); ++i)
 		{
-		  tree link = gimple_asm_output_op (stmt, i);
+		  tree link = gimple_asm_output_op (asm_stmt, i);
 		  tree lhs = TREE_VALUE (link);
 		  if (TREE_CODE (lhs) != SSA_NAME)
 		    {
@@ -1532,9 +1533,9 @@ execute_update_addresses_taken (void)
 			bitmap_set_bit (not_reg_needs, DECL_UID (decl));
 		    }
 		}
-	      for (i = 0; i < gimple_asm_ninputs (stmt); ++i)
+	      for (i = 0; i < gimple_asm_ninputs (asm_stmt); ++i)
 		{
-		  tree link = gimple_asm_input_op (stmt, i);
+		  tree link = gimple_asm_input_op (asm_stmt, i);
 		  if ((decl = non_rewritable_mem_ref_base (TREE_VALUE (link))))
 		    bitmap_set_bit (not_reg_needs, DECL_UID (decl));
 		}
@@ -1645,16 +1646,17 @@ execute_update_addresses_taken (void)
 
 	    else if (gimple_code (stmt) == GIMPLE_ASM)
 	      {
+		gasm *asm_stmt = as_a <gasm *> (stmt);
 		unsigned i;
-		for (i = 0; i < gimple_asm_noutputs (stmt); ++i)
+		for (i = 0; i < gimple_asm_noutputs (asm_stmt); ++i)
 		  {
-		    tree link = gimple_asm_output_op (stmt, i);
+		    tree link = gimple_asm_output_op (asm_stmt, i);
 		    maybe_rewrite_mem_ref_base (&TREE_VALUE (link),
 						suitable_for_renaming);
 		  }
-		for (i = 0; i < gimple_asm_ninputs (stmt); ++i)
+		for (i = 0; i < gimple_asm_ninputs (asm_stmt); ++i)
 		  {
-		    tree link = gimple_asm_input_op (stmt, i);
+		    tree link = gimple_asm_input_op (asm_stmt, i);
 		    maybe_rewrite_mem_ref_base (&TREE_VALUE (link),
 						suitable_for_renaming);
 		  }
-- 
1.8.5.3

