gcc/
        * coretypes.h (gimple_transaction): New typedef.
        (const_gimple_transaction): New typedef.

        * gimple.h (gimple_statement_base::as_a_gimple_transaction): New.
        (gimple_statement_base::dyn_cast_gimple_transaction): New.
        (gimple_build_transaction): Return a gimple_transaction rather than
        a plain gimple.
        (gimple_transaction_body_ptr): Require a gimple_transaction rather
        than a plain gimple.
        (gimple_transaction_body): Likewise.
        (gimple_transaction_label_ptr): Likewise.
        (gimple_transaction_set_body): Likewise.
        (gimple_transaction_set_label): Likewise.
        (gimple_transaction_set_subcode): Likewise.
        (gimple_transaction_label): Require a const_gimple_transaction rather
        than a plain const_gimple.
        (gimple_transaction_subcode): Likewise.

        * gimple-low.c (lower_stmt): Add checked cast to gimple_transaction
        within GIMPLE_TRANSACTION case of switch statement.

        * gimple-pretty-print.c (dump_gimple_transaction): Require a
        gimple_transaction rather than a plain gimple.
        (pp_gimple_stmt_1): Add checked cast to gimple_transaction within
        GIMPLE_TRANSACTION case of switch statement.
        * gimple-streamer-in.c (input_gimple_stmt): Likewise.
        * gimple-streamer-out.c (output_gimple_stmt): Likewise.
        * gimple-walk.c (walk_gimple_op): Likewise.
        (walk_gimple_stmt): Likewise.

        * gimple.c (gimple_build_transaction): Return a gimple_transaction
        rather than a plain gimple.
        (gimple_copy): Add checked casts to gimple_transaction within
        GIMPLE_TRANSACTION case of switch statement.

        * gimplify.c (gimplify_transaction): Split local "g" into "body_stmt"
        and "trans_stmt", strengthening the type of the latter from gimple to
        gimple_transaction.

        * omp-low.c (lower_omp_1): Add checked cast to gimple_transaction
        within GIMPLE_TRANSACTION case of switch statement.

        * trans-mem.c (diagnose_tm_1): Add checked cast within
        GIMPLE_TRANSACTION case of switch statement, introducing a new
        local "trans_stmt".  Use it in place of "stmt".
        (examine_call_tm): Convert local from gimple to gimple_transaction.
        (tm_region::get_transaction_stmt): New method.
        (tm_region::transaction_stmt): Add clarification of type to the comment.
        (tm_region_init_0): Require a gimple_transaction rather than a
        plain gimple.
        (tm_region_init): Convert a check against GIMPLE_TRANSACTION to a
        dyn_cast_gimple_transaction and new local.
        (transaction_subcode_ior): Add a new local, using the new
        get_transaction_stmt method to perform a checked cast.
        (propagate_tm_flags_out): Likewise.
        (expand_transaction): Add a checked cast using the new
        get_transaction_stmt method.
        (generate_tm_state): Likewise.
        (execute_tm_mark): Likewise.
        (ipa_tm_diagnose_transaction): Likewise.

        * tree-cfg.c (verify_gimple_transaction): Require a
        gimple_transaction rather than a plain gimple.
        (make_edges): Add checked cast within GIMPLE_TRANSACTION case of
        switch statement
        (cleanup_dead_labels): Likewise.
        (verify_gimple_stmt): Likewise.
        (verify_gimple_in_seq_2): Likewise.
        (verify_gimple_in_seq_2): Likewise.
        (gimple_redirect_edge_and_branch): Add checked cast.

        * tree-inline.c (remap_gimple_stmt): Add checked cast within
        GIMPLE_TRANSACTION case of switch statement, introducing a new
        local "old_trans_stmt".  Use it in place of "stmt".  Add new
        local "new_trans_stmt", using it to initialize "copy", and for
        type-safe operations as a transaction.
        (estimate_num_insns): Add checked cast within GIMPLE_TRANSACTION
        case of switch statement.
---
 gcc/coretypes.h           |  4 +++
 gcc/gimple-low.c          |  4 ++-
 gcc/gimple-pretty-print.c |  6 +++--
 gcc/gimple-streamer-in.c  |  3 ++-
 gcc/gimple-streamer-out.c |  7 +++--
 gcc/gimple-walk.c         |  8 +++---
 gcc/gimple.c              | 11 +++++---
 gcc/gimple.h              | 58 ++++++++++++++++++++++-------------------
 gcc/gimplify.c            | 13 +++++-----
 gcc/omp-low.c             |  4 ++-
 gcc/trans-mem.c           | 66 +++++++++++++++++++++++++++++++++--------------
 gcc/tree-cfg.c            | 19 ++++++++------
 gcc/tree-inline.c         | 19 +++++++++++---
 13 files changed, 143 insertions(+), 79 deletions(-)

diff --git a/gcc/coretypes.h b/gcc/coretypes.h
index 7c869e9..284fcb6 100644
--- a/gcc/coretypes.h
+++ b/gcc/coretypes.h
@@ -101,6 +101,10 @@ struct gimple_statement_call;
 typedef struct gimple_statement_call *gimple_call;
 typedef const struct gimple_statement_call *const_gimple_call;
 
+struct gimple_statement_transaction;
+typedef struct gimple_statement_transaction *gimple_transaction;
+typedef const struct gimple_statement_transaction *const_gimple_transaction;
+
 struct gimple_statement_return;
 typedef struct gimple_statement_return *gimple_return;
 typedef const struct gimple_statement_return *const_gimple_return;
diff --git a/gcc/gimple-low.c b/gcc/gimple-low.c
index 98e001d..5f19f6e 100644
--- a/gcc/gimple-low.c
+++ b/gcc/gimple-low.c
@@ -363,7 +363,9 @@ lower_stmt (gimple_stmt_iterator *gsi, struct lower_data 
*data)
       return;
 
     case GIMPLE_TRANSACTION:
-      lower_sequence (gimple_transaction_body_ptr (stmt), data);
+      lower_sequence (gimple_transaction_body_ptr (
+                       stmt->as_a_gimple_transaction ()),
+                     data);
       break;
 
     default:
diff --git a/gcc/gimple-pretty-print.c b/gcc/gimple-pretty-print.c
index da27f21..dfb6459 100644
--- a/gcc/gimple-pretty-print.c
+++ b/gcc/gimple-pretty-print.c
@@ -1493,7 +1493,8 @@ dump_gimple_omp_return (pretty_printer *buffer, gimple 
gs, int spc, int flags)
 /* Dump a GIMPLE_TRANSACTION tuple on the pretty_printer BUFFER.  */
 
 static void
-dump_gimple_transaction (pretty_printer *buffer, gimple gs, int spc, int flags)
+dump_gimple_transaction (pretty_printer *buffer, gimple_transaction gs,
+                        int spc, int flags)
 {
   unsigned subcode = gimple_transaction_subcode (gs);
 
@@ -2237,7 +2238,8 @@ pp_gimple_stmt_1 (pretty_printer *buffer, gimple gs, int 
spc, int flags)
       break;
 
     case GIMPLE_TRANSACTION:
-      dump_gimple_transaction (buffer, gs, spc, flags);
+      dump_gimple_transaction (buffer, gs->as_a_gimple_transaction (), spc,
+                              flags);
       break;
 
     default:
diff --git a/gcc/gimple-streamer-in.c b/gcc/gimple-streamer-in.c
index 25d871c..0e94369 100644
--- a/gcc/gimple-streamer-in.c
+++ b/gcc/gimple-streamer-in.c
@@ -200,7 +200,8 @@ input_gimple_stmt (struct lto_input_block *ib, struct 
data_in *data_in,
       break;
 
     case GIMPLE_TRANSACTION:
-      gimple_transaction_set_label (stmt, stream_read_tree (ib, data_in));
+      gimple_transaction_set_label (stmt->as_a_gimple_transaction (),
+                                   stream_read_tree (ib, data_in));
       break;
 
     default:
diff --git a/gcc/gimple-streamer-out.c b/gcc/gimple-streamer-out.c
index 7aafba1..b3c3b25 100644
--- a/gcc/gimple-streamer-out.c
+++ b/gcc/gimple-streamer-out.c
@@ -177,8 +177,11 @@ output_gimple_stmt (struct output_block *ob, gimple stmt)
       break;
 
     case GIMPLE_TRANSACTION:
-      gcc_assert (gimple_transaction_body (stmt) == NULL);
-      stream_write_tree (ob, gimple_transaction_label (stmt), true);
+      {
+       gimple_transaction trans_stmt = stmt->as_a_gimple_transaction ();
+       gcc_assert (gimple_transaction_body (trans_stmt) == NULL);
+       stream_write_tree (ob, gimple_transaction_label (trans_stmt), true);
+      }
       break;
 
     default:
diff --git a/gcc/gimple-walk.c b/gcc/gimple-walk.c
index f71b0db..2d987c6 100644
--- a/gcc/gimple-walk.c
+++ b/gcc/gimple-walk.c
@@ -438,8 +438,9 @@ walk_gimple_op (gimple stmt, walk_tree_fn callback_op,
       break;
 
     case GIMPLE_TRANSACTION:
-      ret = walk_tree (gimple_transaction_label_ptr (stmt), callback_op,
-                      wi, pset);
+      ret = walk_tree (gimple_transaction_label_ptr (
+                        stmt->as_a_gimple_transaction ()),
+                      callback_op, wi, pset);
       if (ret)
        return ret;
       break;
@@ -618,7 +619,8 @@ walk_gimple_stmt (gimple_stmt_iterator *gsi, walk_stmt_fn 
callback_stmt,
       break;
 
     case GIMPLE_TRANSACTION:
-      ret = walk_gimple_seq_mod (gimple_transaction_body_ptr (stmt),
+      ret = walk_gimple_seq_mod (gimple_transaction_body_ptr (
+                                  stmt->as_a_gimple_transaction ()),
                             callback_stmt, callback_op, wi);
       if (ret)
        return wi->callback_result;
diff --git a/gcc/gimple.c b/gcc/gimple.c
index e037c05..7ee7da1 100644
--- a/gcc/gimple.c
+++ b/gcc/gimple.c
@@ -1100,10 +1100,11 @@ gimple_build_omp_atomic_store (tree val)
 
 /* Build a GIMPLE_TRANSACTION statement.  */
 
-gimple
+gimple_transaction
 gimple_build_transaction (gimple_seq body, tree label)
 {
-  gimple p = gimple_alloc (GIMPLE_TRANSACTION, 0);
+  gimple_transaction p =
+    gimple_alloc (GIMPLE_TRANSACTION, 0)->as_a_gimple_transaction ();
   gimple_transaction_set_body (p, body);
   gimple_transaction_set_label (p, label);
   return p;
@@ -1746,8 +1747,10 @@ gimple_copy (gimple stmt)
          break;
 
        case GIMPLE_TRANSACTION:
-         new_seq = gimple_seq_copy (gimple_transaction_body (stmt));
-         gimple_transaction_set_body (copy, new_seq);
+         new_seq = gimple_seq_copy (gimple_transaction_body (
+                                      stmt->as_a_gimple_transaction ()));
+         gimple_transaction_set_body (copy->as_a_gimple_transaction (),
+                                      new_seq);
          break;
 
        case GIMPLE_WITH_CLEANUP_EXPR:
diff --git a/gcc/gimple.h b/gcc/gimple.h
index 944e473..7cb778d 100644
--- a/gcc/gimple.h
+++ b/gcc/gimple.h
@@ -264,6 +264,12 @@ public:
     return as_a <gimple_statement_call> (this);
   }
 
+  inline gimple_transaction
+  as_a_gimple_transaction ()
+  {
+    return as_a <gimple_statement_transaction> (this);
+  }
+
   inline gimple_return
   as_a_gimple_return ()
   {
@@ -344,6 +350,12 @@ public:
     return dyn_cast <gimple_statement_call> (this);
   }
 
+  inline gimple_transaction
+  dyn_cast_gimple_transaction ()
+  {
+    return dyn_cast <gimple_statement_transaction> (this);
+  }
+
   inline gimple_return
   dyn_cast_gimple_return ()
   {
@@ -1521,7 +1533,7 @@ gimple gimple_build_omp_target (gimple_seq, int, tree);
 gimple gimple_build_omp_teams (gimple_seq, tree);
 gimple gimple_build_omp_atomic_load (tree, tree);
 gimple gimple_build_omp_atomic_store (tree);
-gimple gimple_build_transaction (gimple_seq, tree);
+gimple_transaction gimple_build_transaction (gimple_seq, tree);
 gimple gimple_build_predict (enum br_predictor, enum prediction);
 extern void gimple_seq_add_stmt (gimple_seq *, gimple);
 extern void gimple_seq_add_stmt_without_update (gimple_seq *, gimple);
@@ -5674,78 +5686,70 @@ gimple_omp_continue_set_control_use (gimple g, tree use)
   omp_continue_stmt->control_use = use;
 }
 
-/* Return a pointer to the body for the GIMPLE_TRANSACTION statement GS.  */
+/* Return a pointer to the body for the GIMPLE_TRANSACTION statement
+   TRANSACTION_STMT.  */
 
 static inline gimple_seq *
-gimple_transaction_body_ptr (gimple gs)
+gimple_transaction_body_ptr (gimple_transaction transaction_stmt)
 {
-  gimple_statement_transaction *transaction_stmt =
-    as_a <gimple_statement_transaction> (gs);
   return &transaction_stmt->body;
 }
 
-/* Return the body for the GIMPLE_TRANSACTION statement GS.  */
+/* Return the body for the GIMPLE_TRANSACTION statement TRANSACTION_STMT.  */
 
 static inline gimple_seq
-gimple_transaction_body (gimple gs)
+gimple_transaction_body (gimple_transaction transaction_stmt)
 {
-  return *gimple_transaction_body_ptr (gs);
+  return *gimple_transaction_body_ptr (transaction_stmt);
 }
 
 /* Return the label associated with a GIMPLE_TRANSACTION.  */
 
 static inline tree
-gimple_transaction_label (const_gimple gs)
+gimple_transaction_label (const_gimple_transaction transaction_stmt)
 {
-  const gimple_statement_transaction *transaction_stmt =
-    as_a <const gimple_statement_transaction> (gs);
   return transaction_stmt->label;
 }
 
 static inline tree *
-gimple_transaction_label_ptr (gimple gs)
+gimple_transaction_label_ptr (gimple_transaction transaction_stmt)
 {
-  gimple_statement_transaction *transaction_stmt =
-    as_a <gimple_statement_transaction> (gs);
   return &transaction_stmt->label;
 }
 
 /* Return the subcode associated with a GIMPLE_TRANSACTION.  */
 
 static inline unsigned int
-gimple_transaction_subcode (const_gimple gs)
+gimple_transaction_subcode (const_gimple_transaction transaction_stmt)
 {
-  GIMPLE_CHECK (gs, GIMPLE_TRANSACTION);
-  return gs->subcode;
+  return transaction_stmt->subcode;
 }
 
-/* Set BODY to be the body for the GIMPLE_TRANSACTION statement GS.  */
+/* Set BODY to be the body for the GIMPLE_TRANSACTION statement
+   TRANSACTION_STMT.  */
 
 static inline void
-gimple_transaction_set_body (gimple gs, gimple_seq body)
+gimple_transaction_set_body (gimple_transaction transaction_stmt,
+                            gimple_seq body)
 {
-  gimple_statement_transaction *transaction_stmt =
-    as_a <gimple_statement_transaction> (gs);
   transaction_stmt->body = body;
 }
 
 /* Set the label associated with a GIMPLE_TRANSACTION.  */
 
 static inline void
-gimple_transaction_set_label (gimple gs, tree label)
+gimple_transaction_set_label (gimple_transaction transaction_stmt, tree label)
 {
-  gimple_statement_transaction *transaction_stmt =
-    as_a <gimple_statement_transaction> (gs);
   transaction_stmt->label = label;
 }
 
 /* Set the subcode associated with a GIMPLE_TRANSACTION.  */
 
 static inline void
-gimple_transaction_set_subcode (gimple gs, unsigned int subcode)
+gimple_transaction_set_subcode (gimple_transaction transaction_stmt,
+                               unsigned int subcode)
 {
-  GIMPLE_CHECK (gs, GIMPLE_TRANSACTION);
-  gs->subcode = subcode;
+  transaction_stmt->subcode = subcode;
 }
 
 
diff --git a/gcc/gimplify.c b/gcc/gimplify.c
index e0444ca..520e71e 100644
--- a/gcc/gimplify.c
+++ b/gcc/gimplify.c
@@ -7150,7 +7150,8 @@ static enum gimplify_status
 gimplify_transaction (tree *expr_p, gimple_seq *pre_p)
 {
   tree expr = *expr_p, temp, tbody = TRANSACTION_EXPR_BODY (expr);
-  gimple g;
+  gimple body_stmt;
+  gimple_transaction trans_stmt;
   gimple_seq body = NULL;
   int subcode = 0;
 
@@ -7167,17 +7168,17 @@ gimplify_transaction (tree *expr_p, gimple_seq *pre_p)
   push_gimplify_context ();
   temp = voidify_wrapper_expr (*expr_p, NULL);
 
-  g = gimplify_and_return_first (TRANSACTION_EXPR_BODY (expr), &body);
-  pop_gimplify_context (g);
+  body_stmt = gimplify_and_return_first (TRANSACTION_EXPR_BODY (expr), &body);
+  pop_gimplify_context (body_stmt);
 
-  g = gimple_build_transaction (body, NULL);
+  trans_stmt = gimple_build_transaction (body, NULL);
   if (TRANSACTION_EXPR_OUTER (expr))
     subcode = GTMA_IS_OUTER;
   else if (TRANSACTION_EXPR_RELAXED (expr))
     subcode = GTMA_IS_RELAXED;
-  gimple_transaction_set_subcode (g, subcode);
+  gimple_transaction_set_subcode (trans_stmt, subcode);
 
-  gimplify_seq_add_stmt (pre_p, g);
+  gimplify_seq_add_stmt (pre_p, trans_stmt);
 
   if (temp)
     {
diff --git a/gcc/omp-low.c b/gcc/omp-low.c
index af50d89..b1eb22d 100644
--- a/gcc/omp-low.c
+++ b/gcc/omp-low.c
@@ -10012,7 +10012,9 @@ lower_omp_1 (gimple_stmt_iterator *gsi_p, omp_context 
*ctx)
       lower_omp (gimple_try_cleanup_ptr (stmt), ctx);
       break;
     case GIMPLE_TRANSACTION:
-      lower_omp (gimple_transaction_body_ptr (stmt), ctx);
+      lower_omp (gimple_transaction_body_ptr (
+                   stmt->as_a_gimple_transaction ()),
+                ctx);
       break;
     case GIMPLE_BIND:
       lower_omp (gimple_bind_body_ptr (stmt->as_a_gimple_bind ()), ctx);
diff --git a/gcc/trans-mem.c b/gcc/trans-mem.c
index 1d992f6..7911ad6 100644
--- a/gcc/trans-mem.c
+++ b/gcc/trans-mem.c
@@ -763,9 +763,10 @@ diagnose_tm_1 (gimple_stmt_iterator *gsi, bool 
*handled_ops_p,
 
     case GIMPLE_TRANSACTION:
       {
+       gimple_transaction trans_stmt = stmt->as_a_gimple_transaction ();
        unsigned char inner_flags = DIAG_TM_SAFE;
 
-       if (gimple_transaction_subcode (stmt) & GTMA_IS_RELAXED)
+       if (gimple_transaction_subcode (trans_stmt) & GTMA_IS_RELAXED)
          {
            if (d->block_flags & DIAG_TM_SAFE)
              error_at (gimple_location (stmt),
@@ -775,7 +776,7 @@ diagnose_tm_1 (gimple_stmt_iterator *gsi, bool 
*handled_ops_p,
                        "relaxed transaction in %<transaction_safe%> function");
            inner_flags = DIAG_TM_RELAXED;
          }
-       else if (gimple_transaction_subcode (stmt) & GTMA_IS_OUTER)
+       else if (gimple_transaction_subcode (trans_stmt) & GTMA_IS_OUTER)
          {
            if (d->block_flags)
              error_at (gimple_location (stmt),
@@ -791,7 +792,7 @@ diagnose_tm_1 (gimple_stmt_iterator *gsi, bool 
*handled_ops_p,
          }
 
        *handled_ops_p = true;
-       if (gimple_transaction_body (stmt))
+       if (gimple_transaction_body (trans_stmt))
          {
            struct walk_stmt_info wi_inner;
            struct diagnose_tm d_inner;
@@ -804,7 +805,7 @@ diagnose_tm_1 (gimple_stmt_iterator *gsi, bool 
*handled_ops_p,
            memset (&wi_inner, 0, sizeof (wi_inner));
            wi_inner.info = &d_inner;
 
-           walk_gimple_seq (gimple_transaction_body (stmt),
+           walk_gimple_seq (gimple_transaction_body (trans_stmt),
                             diagnose_tm_1, diagnose_tm_1_op, &wi_inner);
          }
       }
@@ -1606,7 +1607,8 @@ examine_call_tm (unsigned *state, gimple_stmt_iterator 
*gsi)
 static void
 lower_transaction (gimple_stmt_iterator *gsi, struct walk_stmt_info *wi)
 {
-  gimple g, stmt = gsi_stmt (*gsi);
+  gimple g;
+  gimple_transaction stmt = gsi_stmt (*gsi)->as_a_gimple_transaction ();
   unsigned int *outer_state = (unsigned int *) wi->info;
   unsigned int this_state = 0;
   struct walk_stmt_info this_wi;
@@ -1804,6 +1806,22 @@ make_pass_lower_tm (gcc::context *ctxt)
 
 struct tm_region
 {
+public:
+
+  /* The field "transaction_stmt" is initially a gimple_transaction,
+     but eventually gets lowered to a gimple_call (to BUILT_IN_TM_START).
+
+     Helper method to get it as a gimple_transaction, with code-checking
+     in a checked-build.  */
+
+  gimple_transaction
+  get_transaction_stmt () const
+  {
+    return transaction_stmt->as_a_gimple_transaction ();
+  }
+
+public:
+
   /* Link to the next unnested transaction.  */
   struct tm_region *next;
 
@@ -1815,7 +1833,8 @@ struct tm_region
 
   /* The GIMPLE_TRANSACTION statement beginning this transaction.
      After TM_MARK, this gets replaced by a call to
-     BUILT_IN_TM_START.  */
+     BUILT_IN_TM_START.
+     Hence this will be either a gimple_transaction or a gimple_call.  */
   gimple transaction_stmt;
 
   /* After TM_MARK expands the GIMPLE_TRANSACTION into a call to
@@ -1858,7 +1877,8 @@ static bitmap_obstack tm_obstack;
    GIMPLE_TRANSACTION statement in a tree of tm_region elements.  */
 
 static struct tm_region *
-tm_region_init_0 (struct tm_region *outer, basic_block bb, gimple stmt)
+tm_region_init_0 (struct tm_region *outer, basic_block bb,
+                 gimple_transaction stmt)
 {
   struct tm_region *region;
 
@@ -1973,8 +1993,9 @@ tm_region_init (struct tm_region *region)
       /* Check for the last statement in the block beginning a new region.  */
       g = last_stmt (bb);
       old_region = region;
-      if (g && gimple_code (g) == GIMPLE_TRANSACTION)
-       region = tm_region_init_0 (region, bb, g);
+      if (g)
+       if (gimple_transaction trans_stmt = g->dyn_cast_gimple_transaction ())
+         region = tm_region_init_0 (region, bb, trans_stmt);
 
       /* Process subsequent blocks.  */
       FOR_EACH_EDGE (e, ei, bb->succs)
@@ -2085,8 +2106,9 @@ transaction_subcode_ior (struct tm_region *region, 
unsigned flags)
 {
   if (region && region->transaction_stmt)
     {
-      flags |= gimple_transaction_subcode (region->transaction_stmt);
-      gimple_transaction_set_subcode (region->transaction_stmt, flags);
+      gimple_transaction transaction_stmt = region->get_transaction_stmt ();
+      flags |= gimple_transaction_subcode (transaction_stmt);
+      gimple_transaction_set_subcode (transaction_stmt, flags);
     }
 }
 
@@ -2710,7 +2732,7 @@ expand_transaction (struct tm_region *region, void *data 
ATTRIBUTE_UNUSED)
 
   /* ??? There are plenty of bits here we're not computing.  */
   {
-    int subcode = gimple_transaction_subcode (region->transaction_stmt);
+    int subcode = gimple_transaction_subcode (region->get_transaction_stmt ());
     int flags = 0;
     if (subcode & GTMA_DOES_GO_IRREVOCABLE)
       flags |= PR_DOESGOIRREVOCABLE;
@@ -2921,8 +2943,8 @@ generate_tm_state (struct tm_region *region, void *data 
ATTRIBUTE_UNUSED)
   // again as we process blocks.
   if (region->exit_blocks)
     {
-      unsigned int subcode
-       = gimple_transaction_subcode (region->transaction_stmt);
+      gimple_transaction transaction_stmt = region->get_transaction_stmt ();
+      unsigned int subcode = gimple_transaction_subcode (transaction_stmt);
 
       if (subcode & GTMA_DOES_GO_IRREVOCABLE)
        subcode &= (GTMA_DECLARATION_MASK | GTMA_DOES_GO_IRREVOCABLE
@@ -2930,7 +2952,7 @@ generate_tm_state (struct tm_region *region, void *data 
ATTRIBUTE_UNUSED)
                    | GTMA_HAS_NO_INSTRUMENTATION);
       else
        subcode &= GTMA_DECLARATION_MASK;
-      gimple_transaction_set_subcode (region->transaction_stmt, subcode);
+      gimple_transaction_set_subcode (transaction_stmt, subcode);
     }
 
   return NULL;
@@ -2946,11 +2968,13 @@ propagate_tm_flags_out (struct tm_region *region)
 
   if (region->outer && region->outer->transaction_stmt)
     {
-      unsigned s = gimple_transaction_subcode (region->transaction_stmt);
+      unsigned s =
+       gimple_transaction_subcode (region->get_transaction_stmt ());
       s &= (GTMA_HAVE_ABORT | GTMA_HAVE_LOAD | GTMA_HAVE_STORE
             | GTMA_MAY_ENTER_IRREVOCABLE);
-      s |= gimple_transaction_subcode (region->outer->transaction_stmt);
-      gimple_transaction_set_subcode (region->outer->transaction_stmt, s);
+      s |= gimple_transaction_subcode (region->outer->get_transaction_stmt ());
+      gimple_transaction_set_subcode (region->outer->get_transaction_stmt (),
+                                     s);
     }
 
   propagate_tm_flags_out (region->next);
@@ -2985,7 +3009,8 @@ execute_tm_mark (void)
        {
          if (r->transaction_stmt)
            {
-             unsigned sub = gimple_transaction_subcode (r->transaction_stmt);
+             unsigned sub =
+               gimple_transaction_subcode (r->get_transaction_stmt ());
 
              /* If we're sure to go irrevocable, there won't be
                 anything to expand, since the run-time will go
@@ -4693,7 +4718,8 @@ ipa_tm_diagnose_transaction (struct cgraph_node *node,
   struct tm_region *r;
 
   for (r = all_tm_regions; r ; r = r->next)
-    if (gimple_transaction_subcode (r->transaction_stmt) & GTMA_IS_RELAXED)
+    if (gimple_transaction_subcode (r->get_transaction_stmt ())
+       & GTMA_IS_RELAXED)
       {
        /* Atomic transactions can be nested inside relaxed.  */
        if (r->inner)
diff --git a/gcc/tree-cfg.c b/gcc/tree-cfg.c
index 6c0f157..a2557e4 100644
--- a/gcc/tree-cfg.c
+++ b/gcc/tree-cfg.c
@@ -161,7 +161,7 @@ static inline bool stmt_starts_bb_p (gimple, gimple);
 static int gimple_verify_flow_info (void);
 static void gimple_make_forwarder_block (edge);
 static gimple first_non_label_stmt (basic_block);
-static bool verify_gimple_transaction (gimple);
+static bool verify_gimple_transaction (gimple_transaction);
 
 /* Flowgraph optimization and cleanup.  */
 static void gimple_merge_blocks (basic_block, basic_block);
@@ -813,7 +813,8 @@ make_edges (void)
 
            case GIMPLE_TRANSACTION:
              {
-               tree abort_label = gimple_transaction_label (last);
+               tree abort_label = gimple_transaction_label (
+                                     last->as_a_gimple_transaction ());
                if (abort_label)
                  make_edge (bb, label_to_block (abort_label), EDGE_TM_ABORT);
                fallthru = true;
@@ -1429,12 +1430,13 @@ cleanup_dead_labels (void)
 
        case GIMPLE_TRANSACTION:
          {
-           tree label = gimple_transaction_label (stmt);
+           gimple_transaction trans_stmt = stmt->as_a_gimple_transaction ();
+           tree label = gimple_transaction_label (trans_stmt);
            if (label)
              {
                tree new_label = main_block_label (label);
                if (new_label != label)
-                 gimple_transaction_set_label (stmt, new_label);
+                 gimple_transaction_set_label (trans_stmt, new_label);
              }
          }
          break;
@@ -4442,7 +4444,7 @@ verify_gimple_stmt (gimple stmt)
       return false;
 
     case GIMPLE_TRANSACTION:
-      return verify_gimple_transaction (stmt);
+      return verify_gimple_transaction (stmt->as_a_gimple_transaction ());
 
     /* Tuples that do not have tree operands.  */
     case GIMPLE_NOP:
@@ -4571,7 +4573,7 @@ verify_gimple_in_seq_2 (gimple_seq stmts)
          break;
 
        case GIMPLE_TRANSACTION:
-         err |= verify_gimple_transaction (stmt);
+         err |= verify_gimple_transaction (stmt->as_a_gimple_transaction ());
          break;
 
        default:
@@ -4591,7 +4593,7 @@ verify_gimple_in_seq_2 (gimple_seq stmts)
    is a problem, otherwise false.  */
 
 static bool
-verify_gimple_transaction (gimple stmt)
+verify_gimple_transaction (gimple_transaction stmt)
 {
   tree lab = gimple_transaction_label (stmt);
   if (lab != NULL && TREE_CODE (lab) != LABEL_DECL)
@@ -5509,7 +5511,8 @@ gimple_redirect_edge_and_branch (edge e, basic_block dest)
       /* The ABORT edge has a stored label associated with it, otherwise
         the edges are simply redirectable.  */
       if (e->flags == 0)
-       gimple_transaction_set_label (stmt, gimple_block_label (dest));
+       gimple_transaction_set_label (stmt->as_a_gimple_transaction (),
+                                     gimple_block_label (dest));
       break;
 
     default:
diff --git a/gcc/tree-inline.c b/gcc/tree-inline.c
index 3c935b8..69d5953 100644
--- a/gcc/tree-inline.c
+++ b/gcc/tree-inline.c
@@ -1413,9 +1413,19 @@ remap_gimple_stmt (gimple stmt, copy_body_data *id)
          break;
 
        case GIMPLE_TRANSACTION:
-         s1 = remap_gimple_seq (gimple_transaction_body (stmt), id);
-         copy = gimple_build_transaction (s1, gimple_transaction_label (stmt));
-         gimple_transaction_set_subcode (copy, gimple_transaction_subcode 
(stmt));
+         {
+           gimple_transaction old_trans_stmt =
+             stmt->as_a_gimple_transaction ();
+           gimple_transaction new_trans_stmt;
+           s1 = remap_gimple_seq (gimple_transaction_body (old_trans_stmt),
+                                  id);
+           copy = new_trans_stmt =
+             gimple_build_transaction (s1,
+                                       gimple_transaction_label 
(old_trans_stmt));
+           gimple_transaction_set_subcode (
+              new_trans_stmt,
+             gimple_transaction_subcode (old_trans_stmt));
+         }
          break;
 
        default:
@@ -3964,7 +3974,8 @@ estimate_num_insns (gimple stmt, eni_weights *weights)
 
     case GIMPLE_TRANSACTION:
       return (weights->tm_cost
-             + estimate_num_insns_seq (gimple_transaction_body (stmt),
+             + estimate_num_insns_seq (gimple_transaction_body (
+                                         stmt->as_a_gimple_transaction ()),
                                        weights));
 
     default:
-- 
1.8.5.3

Reply via email to