This is the mail archive of the gcc-patches@gcc.gnu.org mailing list for the GCC project.


Index Nav: [Date Index] [Subject Index] [Author Index] [Thread Index]
Message Nav: [Date Prev] [Date Next] [Thread Prev] [Thread Next]
Other format: [Raw text]

[trans-mem] make it compile w/ tuples


I'm now working on re-designing how TM regions are expanded, so I stubbed out anything I thought I'd have to re-write. So it doesn't actually *do* anything at the moment. But at least it compiles.


r~
	* Makefile.in (gtm-low.o): Don't depend on gtm-defines.h.
	* builtin-types.def: Don't include it.
	* c-common.c (handle_gtm_unknown_attribute): Stub out
	setting DECL_IS_GTM_UNKNOWN.
	* c-decl.c (merge_decls): Don't propogate it.
	* c-parser.c (c_parser_gtm): Remove decl.
	* c-typeck.c (c_finish_gtm_txn): Don't special-case for OpenMP;
	make that the only case.
	* cgraphbuild.c (prepare_gtm_clone): Use MAIN_NAME_P.  Use concat
	for resetting the assembler name.
	* defaults.h (TINYSTM_VERSION_0_9_5): Set.
	* gimple-low.c (struct lower_data): Add in_transaction.
	(mark_gtm_save_vars): Remove.
	(lower_gtm_directive): Simplify.
	(record_vars_into_tm): Split out from record_vars_into.  When
	inside a transaction, set DECL_IS_GTM_PURE_VAR.
	(lower_gimple_bind): Call it.
	* gimple-pretty-print.c (dump_gimple_gtm_txn): New.
	(dump_gimple_gtm_other): New.
	(dump_gimple_stmt): Call them.
	* gimple.c (gcc_for_code): Add GTM codes.
	(gimple_size): Restructure based on GSS codes.
	(gimple_build_gtm_txn): New.
	(walk_gimple_stmt): Add GTM codes.
	(gimple_rhs_class_table): Make GTM_LOAD/STORE be GIMPLE_SINGLE_RHS.
	* gimple.def (GIMPLE_GTM_TXN, GIMPLE_GTM_RETURN, GIMPLE_GTM_ABORT): New.
	* gimple.h (struct gimple_statement_seq): Rename from 
	gimple_statement_omp.  Update all users.
	(is_gimple_gtm): New.
	* gtm-low.c (new_gtm_region): Remove type code.
	(build_gtm_regions_1): Gimplify.
	(build_gtm_regions): Don't do dominance here.
	(remove_gtm_stmts): Gimpify.
	(collapse_gtm_regions, query_STM_for_flat_nesting): Remove.
	(set_gtm_pure_var, is_gtm_pure_var): Remove.
	(requires_barrier): Merge requires_read_barrier and
	requires_write_barrier; rewrite to match memory variables only.
	(get_real_stm_decl, get_uint_stm_decl, insert_temporary,
	may_repair_rhs, compensate_for_taking_the_address, 
	compose_stm_store_call, compose_stm_load_call, 
	insert_rhs_stm_call, replace_lhs, maybe_replace_rhs_stmt,
	replace_txn_mod_stmt, build_txn_call_expr, replace_txn_stmt,
	setup_recover_bb, setup_begin_bb, expand_gtm_abort, 
	maybe_insert_stm_new, insert_stm_init_thread, 
	maybe_insert_stm_init_thread, insert_stm_exit_thread,
	maybe_insert_stm_exit_thread, expand_gtm_txn_marker,
	expand_gtm_return, insert_stm_init, insert_stm_exit,
	init_label_table, record_bb_into_table, check_and_mark_edges,
	instrument_edges, instrument_return_expr, expand_gtm,
	annotate_gtm_function_body): Remove.
	(maybe_transactify_assign, maybe_transactify_call): New.
	(transactify_stmt): New.
	(checkpoint_live_in_variables, checkpoint_gtm_txn): If 0.
	* omp-low.c (lower_gtm_txn): Remove.
	(diagnose_sb_1): Don't call it.
	* passes.c (pass_checkpoint_gtm): Disable.
	* tree-flow.h (NUM_BB_TXN): Remove.
	(struct gtm_region): Remove txn_bbs, type.
	* tree-pretty-print.c (dump_generic_node): Handle GTM codes.
	* tree.def (GTM_LOAD, GTM_STORE): Add.
	(GTM_RETURN): Remove.
	* tree.h (GTM_DIRECTIVE_P): Remove.
	(DECL_IS_GTM_UNKNOWN): Disable.

--- Makefile.in	(revision 141060)
+++ Makefile.in	(local)
@@ -2023,7 +2023,7 @@ gtype-desc.o: gtype-desc.c $(CONFIG_H) $
 gtm-low.o : gtm-low.c $(CONFIG_H) $(SYSTEM_H) coretypes.h $(TM_H) $(TREE_H) \
         $(RTL_H) $(TREE_GIMPLE_H) $(TREE_INLINE_H) langhooks.h $(DIAGNOSTIC_H) \
         $(TREE_FLOW_H) $(TIMEVAR_H) $(FLAGS_H) $(EXPR_H) toplev.h tree-pass.h \
-        $(GGC_H) $(SPLAY_TREE_H) $(OPTABS_H) $(CFGLOOP_H) gtm-defines.h
+        $(GGC_H) $(SPLAY_TREE_H) $(OPTABS_H) $(CFGLOOP_H)
 
 ggc-common.o: ggc-common.c $(CONFIG_H) $(SYSTEM_H) coretypes.h $(GGC_H) \
 	$(HASHTAB_H) $(TOPLEV_H) $(PARAMS_H) hosthooks.h $(HOSTHOOKS_DEF_H)
--- builtin-types.def	(revision 141060)
+++ builtin-types.def	(local)
@@ -475,8 +475,6 @@ DEF_FUNCTION_TYPE_3 (BT_FN_PTR_PTR_FN_VO
 		     BT_PTR, BT_PTR_FN_VOID_VAR, BT_PTR, BT_SIZE)
 
 
-#include "gtm-defines.h"
-             
 /* GTM special types go here */
 
 #ifdef GTM_EXPL_HANDLE
--- c-common.c	(revision 141060)
+++ c-common.c	(local)
@@ -6502,8 +6502,9 @@ handle_gtm_unknown_attribute (tree *node
                      int ARG_UNUSED (flags), bool *no_add_attrs)
 {
   if (TREE_CODE (*node) == FUNCTION_DECL)
-    DECL_IS_GTM_UNKNOWN (*node) = 1;
-  /* ??? TODO: Support types.  */
+    {
+      /* DECL_IS_GTM_UNKNOWN (*node) = 1; */
+    }
   else
     {
       warning (OPT_Wattributes, "%qE attribute ignored", name);
--- c-decl.c	(revision 141060)
+++ c-decl.c	(local)
@@ -1718,7 +1718,6 @@ merge_decls (tree newdecl, tree olddecl,
 	  DECL_IS_NOVOPS (newdecl) |= DECL_IS_NOVOPS (olddecl);
 	  DECL_IS_GTM_PURE (newdecl) |= DECL_IS_GTM_PURE (olddecl);
 	  DECL_IS_GTM_CALLABLE (newdecl) |= DECL_IS_GTM_CALLABLE (olddecl);
-	  DECL_IS_GTM_UNKNOWN (newdecl) |= DECL_IS_GTM_UNKNOWN (olddecl);
 	}
 
       /* Merge the storage class information.  */
--- c-parser.c	(revision 141060)
+++ c-parser.c	(local)
@@ -913,7 +913,6 @@ static struct c_expr c_parser_postfix_ex
 								   struct c_type_name *);
 static struct c_expr c_parser_postfix_expression_after_primary (c_parser *,
 								struct c_expr);
-static tree c_parser_gtm (c_parser *);
 static tree c_parser_gtm_atomic (c_parser *);
 static struct c_expr c_parser_expression (c_parser *);
 static struct c_expr c_parser_expression_conv (c_parser *);
--- c-typeck.c	(revision 141060)
+++ c-typeck.c	(local)
@@ -8881,55 +8881,20 @@ c_begin_gtm_txn (void)
   return block;
 }
 
-/* Parse like OMP_PARALLEL in case
-   OpenMP is used. The lowering
-   pass of OpenMP will do the rest.
-   In case the OMP lowering pass is not
-   triggered simply introduce a new stmt_list
-   while encountering a BIND_EXPR. Then
-   gimple-low.c should behave nicely and
-   add the GTM_RETURN at the end of the
-   transaction. */
+/* Create a transaction node.  */
 
 tree
 c_finish_gtm_txn (tree block)
 {
-  if (flag_openmp)
-    {
-      tree stmt;
-
-      block = c_end_compound_stmt (block, true);
-
-      stmt = make_node (GTM_TXN);
-      TREE_TYPE (stmt) = void_type_node;
-      GTM_TXN_BODY (stmt) = block;
+  tree stmt;
 
-      return add_stmt (stmt);
-    }
-  else
-    {
-      tree stmt;
-      tree new_body;
-      tree gtm_ret;
-
-      block = c_end_compound_stmt (block, true);
-
-      stmt = make_node (GTM_TXN);
-      TREE_TYPE (stmt) = void_type_node;
-      new_body = block;
-
-      if (TREE_CODE (block) == BIND_EXPR)
-      {
-        new_body = alloc_stmt_list ();
-        append_to_statement_list (block, &new_body);
-        gtm_ret = make_node (GTM_RETURN);
-        append_to_statement_list (gtm_ret, &new_body);
-      }
+  block = c_end_compound_stmt (block, true);
 
-      GTM_TXN_BODY (stmt) = new_body;
+  stmt = make_node (GTM_TXN);
+  TREE_TYPE (stmt) = void_type_node;
+  GTM_TXN_BODY (stmt) = block;
 
-      return add_stmt (stmt);
-    }
+  return add_stmt (stmt);
 }
 
 /* Create a GTM_ABORT node and add it. */
--- cgraphbuild.c	(revision 141060)
+++ cgraphbuild.c	(local)
@@ -131,16 +131,12 @@ prepare_gtm_clone (struct cgraph_node *n
   struct cgraph_node *tm_node;
   tree decl, old_decl, id;
   struct function *saved_cfun;
-  size_t len;
-  char *tm_name;
 
   if (!flag_gtm || flag_openmp)
     return;
 
   /* No need for a TM clone of the main function */
-  const char *orig = get_name (node->decl);
-  if ((strncmp (orig, "main", 4) == 0)
-      && (strlen (orig) == 4))
+  if (MAIN_NAME_P (DECL_NAME (node->decl)))
     return; 
 
   /* Do not prepare functions that are already instances 
@@ -155,7 +151,7 @@ prepare_gtm_clone (struct cgraph_node *n
 
   /* Defer redirecting callers of the node to the
      new versioned node to the gtm expansion pass.  */
-  tm_node = cgraph_function_versioning (node, NULL, NULL); 
+  tm_node = cgraph_function_versioning (node, NULL, NULL, NULL); 
   if (tm_node == NULL)
     return;
 
@@ -171,13 +167,15 @@ prepare_gtm_clone (struct cgraph_node *n
   set_cfun (DECL_STRUCT_FUNCTION (decl));
 
   /* Substitute decl name. */
-  len = strlen (orig);
-  tm_name = (char *) xmalloc (sizeof (char) * (len + 4));
-  strncpy (tm_name, orig, len);
-  strcpy (tm_name + len, "Txn");
-  id = get_identifier (tm_name);
-  DECL_NAME (decl) = id;
-  SET_DECL_ASSEMBLER_NAME(decl, id);
+  {
+    char *tm_name;
+
+    tm_name = concat (get_name (node->decl), ".Txn", NULL);
+    id = get_identifier (tm_name);
+    DECL_NAME (decl) = id;
+    SET_DECL_ASSEMBLER_NAME (decl, id);
+    free (tm_name);
+  }
 
 #ifdef GTM_EXPL_HANDLE
   /* Create parameter declaration for txn_handle and add
--- cp/cp-gimplify.c	(revision 141060)
+++ cp/cp-gimplify.c	(local)
@@ -372,8 +372,8 @@ cp_gimplify_omp_for (tree *expr_p, gimpl
   gimplify_and_add (for_stmt, &seq);
   stmt = gimple_seq_last_stmt (seq);
   if (gimple_code (stmt) == GIMPLE_OMP_FOR)
-    gimple_omp_set_body (stmt, finish_bc_block (bc_continue, cont_block,
-						gimple_omp_body (stmt)));
+    gimple_seq_set_body (stmt, finish_bc_block (bc_continue, cont_block,
+						gimple_seq_body (stmt)));
   else
     seq = finish_bc_block (bc_continue, cont_block, seq);
   gimple_seq_add_seq (pre_p, seq);
--- defaults.h	(revision 141060)
+++ defaults.h	(local)
@@ -949,6 +949,8 @@ along with GCC; see the file COPYING3.  
    In particular the explicit passing of transaction handles and
    the implicit handling of transaction handles are distinguished. */
 
+#define TINYSTM_VERSION_0_9_5
+
 #ifdef TINYSTM_VERSION_0_9_0b1 
 #define GTM_EXPL_HANDLE
 #undef GTM_IMPL_HANDLE
--- gimple-low.c	(revision 141060)
+++ gimple-low.c	(local)
@@ -77,12 +77,16 @@ struct lower_data
 
   /* True if the function calls __builtin_setjmp.  */
   bool calls_builtin_setjmp;
+
+  /* True if we're lowering inside a transaction.  */
+  bool in_transaction;
 };
 
 static void lower_stmt (gimple_stmt_iterator *, struct lower_data *);
 static void lower_gimple_bind (gimple_stmt_iterator *, struct lower_data *);
 static void lower_gimple_return (gimple_stmt_iterator *, struct lower_data *);
 static void lower_builtin_setjmp (gimple_stmt_iterator *);
+static void record_vars_into_tm (tree, tree, bool);
 
 
 /* Lower the body of current_function_decl from High GIMPLE into Low
@@ -217,108 +221,6 @@ struct gimple_opt_pass pass_lower_cf = 
  }
 };
 
-static void
-mark_gtm_save_vars (tree vars)
-{
-  for (; vars; vars = TREE_CHAIN (vars))
-    {
-      tree var = vars;
-      if (TREE_CODE (var) == VAR_DECL)
-        DECL_IS_GTM_PURE_VAR (var) = 1;
-    }
-  return ;
-}
-
-/* Lower the GTM directive statement pointed by TSI.  DATA is
-    passed through the recursion.  */
-
-static void
-lower_gtm_directive (tree_stmt_iterator *tsi, struct lower_data *data)
-{
-  tree stmt;
-
-  stmt = tsi_stmt (*tsi);
-  tree body = GTM_TXN_BODY (stmt);
-  if (TREE_CODE (body) == STATEMENT_LIST)
-    {
-      tree temp;
-      tree_stmt_iterator ttsi = tsi_start (body);
-      if (!tsi_end_p (ttsi))
-        {
-          temp = tsi_stmt (ttsi);
-        }
-      else gcc_unreachable();
-      if (TREE_CODE (temp) == BIND_EXPR)
-        {
-          tree vars = BIND_EXPR_VARS (temp);
-
-          if (vars)
-            {
-              mark_gtm_save_vars(vars);
-            }
-          if (TREE_CODE (BIND_EXPR_BODY (temp)) == STATEMENT_LIST)
-            {
-              tree temp2;
-              tree_stmt_iterator ttsi = tsi_start (BIND_EXPR_BODY (temp));
-
-              if (!tsi_end_p (ttsi))
-                {
-                  temp2 = tsi_stmt (ttsi);
-                }
-              else gcc_unreachable();
-
-            if (TREE_CODE (temp2) == BIND_EXPR)
-              {
-                tree vars = BIND_EXPR_VARS (temp2);
-
-                if (vars)
-                  {
-                    mark_gtm_save_vars(vars);
-                  }
-              }
-          }
-      }
-    }
-  else
-    {
-      if (TREE_CODE (body) == BIND_EXPR)
-        {
-          tree vars = BIND_EXPR_VARS (body);
-
-          if (vars)
-            {
-              mark_gtm_save_vars(vars);
-            }
-        }
-      if (TREE_CODE (BIND_EXPR_BODY (body)) == STATEMENT_LIST)
-      {
-        tree temp;
-        tree_stmt_iterator ttsi = tsi_start (BIND_EXPR_BODY (body));
-
-        if (!tsi_end_p (ttsi))
-          {
-            temp = tsi_stmt (ttsi);
-          }
-        else gcc_unreachable();
-
-        if (TREE_CODE (temp) == BIND_EXPR)
-          {
-            tree vars = BIND_EXPR_VARS (temp);
-
-            if (vars)
-              {
-                mark_gtm_save_vars(vars);
-              }
-          }
-      }
-    }
-
-  lower_stmt_body (body, data);
-  tsi_link_before (tsi, stmt, TSI_SAME_STMT);
-  tsi_link_before (tsi, body, TSI_SAME_STMT);
-  GTM_TXN_BODY (stmt) = NULL_TREE;
-  tsi_delink (tsi);
-}
 
 /* Lower sequence SEQ.  Unlike gimplification the statements are not relowered
    when they are changed -- if this has to be done, the lowering routine must
@@ -334,6 +236,26 @@ lower_sequence (gimple_seq seq, struct l
 }
 
 
+/* Lower the GTM directive statement pointed by TSI.  DATA is
+   passed through the recursion.  */
+
+static void
+lower_gtm_directive (gimple_stmt_iterator *gsi, struct lower_data *data)
+{
+  bool old_in_transaction = data->in_transaction;
+  gimple stmt = gsi_stmt (*gsi);
+
+  data->in_transaction = true;
+
+  lower_sequence (gimple_seq_body (stmt), data);
+  gsi_insert_before (gsi, stmt, GSI_SAME_STMT);
+  gsi_insert_seq_before (gsi, gimple_seq_body (stmt), GSI_SAME_STMT);
+  gimple_seq_set_body (stmt, NULL);
+  gsi_remove (gsi, false);
+
+  data->in_transaction = old_in_transaction;
+}
+
 /* Lower the OpenMP directive statement pointed by GSI.  DATA is
    passed through the recursion.  */
 
@@ -344,10 +266,10 @@ lower_omp_directive (gimple_stmt_iterato
   
   stmt = gsi_stmt (*gsi);
 
-  lower_sequence (gimple_omp_body (stmt), data);
+  lower_sequence (gimple_seq_body (stmt), data);
   gsi_insert_before (gsi, stmt, GSI_SAME_STMT);
-  gsi_insert_seq_before (gsi, gimple_omp_body (stmt), GSI_SAME_STMT);
-  gimple_omp_set_body (stmt, NULL);
+  gsi_insert_seq_before (gsi, gimple_seq_body (stmt), GSI_SAME_STMT);
+  gimple_seq_set_body (stmt, NULL);
   gsi_remove (gsi, false);
 }
 
@@ -433,7 +355,7 @@ lower_stmt (gimple_stmt_iterator *gsi, s
       return;
 
     case GIMPLE_GTM_TXN:
-      lower_gtm_directive (tsi, data);
+      lower_gtm_directive (gsi, data);
       return;
 
     default:
@@ -480,7 +402,8 @@ lower_gimple_bind (gimple_stmt_iterator 
 	}
     }
 
-  record_vars (gimple_bind_vars (stmt));
+  record_vars_into_tm (gimple_bind_vars (stmt), current_function_decl,
+		       data->in_transaction);
   lower_sequence (gimple_bind_body (stmt), data);
 
   if (new_block)
@@ -894,10 +817,11 @@ lower_builtin_setjmp (gimple_stmt_iterat
 }
 
 
-/* Record the variables in VARS into function FN.  */
+/* Record the variables in VARS into function FN.  If IN_TRANSACTION is
+   true, mark them DECL_IS_GTM_PURE_VAR.  */
 
-void
-record_vars_into (tree vars, tree fn)
+static void
+record_vars_into_tm (tree vars, tree fn, bool in_transaction)
 {
   if (fn != current_function_decl)
     push_cfun (DECL_STRUCT_FUNCTION (fn));
@@ -918,19 +842,31 @@ record_vars_into (tree vars, tree fn)
       /* Record the variable.  */
       cfun->local_decls = tree_cons (NULL_TREE, var,
 					     cfun->local_decls);
+
+      /* If we're inside a transaction, mark it for NOT checkpointing.  */
+      if (in_transaction)
+	DECL_IS_GTM_PURE_VAR (var) = 1;
     }
 
   if (fn != current_function_decl)
     pop_cfun ();
 }
 
+/* Record the variables in VARS into function FN.  */
+
+void
+record_vars_into (tree vars, tree fn)
+{
+  record_vars_into_tm (vars, fn, false);
+}
+
 
 /* Record the variables in VARS into current_function_decl.  */
 
 void
 record_vars (tree vars)
 {
-  record_vars_into (vars, current_function_decl);
+  record_vars_into_tm (vars, current_function_decl, false);
 }
 
 
--- gimple-pretty-print.c	(revision 141060)
+++ gimple-pretty-print.c	(local)
@@ -757,7 +757,7 @@ dump_gimple_omp_for (pretty_printer *buf
   if (flags & TDF_RAW)
     {
       dump_gimple_fmt (buffer, spc, flags, "%G <%+BODY <%S>%nCLAUSES <", gs,
-                       gimple_omp_body (gs));
+                       gimple_seq_body (gs));
       dump_omp_clauses (buffer, gimple_omp_for_clauses (gs), spc, flags);
       dump_gimple_fmt (buffer, spc, flags, " >,");
       for (i = 0; i < gimple_omp_for_collapse (gs); i++)
@@ -821,12 +821,12 @@ dump_gimple_omp_for (pretty_printer *buf
 	  pp_character (buffer, ')');
 	}
 
-      if (!gimple_seq_empty_p (gimple_omp_body (gs)))
+      if (!gimple_seq_empty_p (gimple_seq_body (gs)))
 	{
 	  newline_and_indent (buffer, spc + 2);
 	  pp_character (buffer, '{');
 	  pp_newline (buffer);
-	  dump_gimple_seq (buffer, gimple_omp_body (gs), spc + 4, flags);
+	  dump_gimple_seq (buffer, gimple_seq_body (gs), spc + 4, flags);
 	  newline_and_indent (buffer, spc + 2);
 	  pp_character (buffer, '}');
 	}
@@ -865,7 +865,7 @@ dump_gimple_omp_single (pretty_printer *
   if (flags & TDF_RAW)
     {
       dump_gimple_fmt (buffer, spc, flags, "%G <%+BODY <%S>%nCLAUSES <", gs,
-		       gimple_omp_body (gs));
+		       gimple_seq_body (gs));
       dump_omp_clauses (buffer, gimple_omp_single_clauses (gs), spc, flags);
       dump_gimple_fmt (buffer, spc, flags, " >");
     }
@@ -873,12 +873,12 @@ dump_gimple_omp_single (pretty_printer *
     {
       pp_string (buffer, "#pragma omp single");
       dump_omp_clauses (buffer, gimple_omp_single_clauses (gs), spc, flags);
-      if (!gimple_seq_empty_p (gimple_omp_body (gs)))
+      if (!gimple_seq_empty_p (gimple_seq_body (gs)))
 	{
 	  newline_and_indent (buffer, spc + 2);
 	  pp_character (buffer, '{');
 	  pp_newline (buffer);
-	  dump_gimple_seq (buffer, gimple_omp_body (gs), spc + 4, flags);
+	  dump_gimple_seq (buffer, gimple_seq_body (gs), spc + 4, flags);
 	  newline_and_indent (buffer, spc + 2);
 	  pp_character (buffer, '}');
 	}
@@ -894,7 +894,7 @@ dump_gimple_omp_sections (pretty_printer
   if (flags & TDF_RAW)
     {
       dump_gimple_fmt (buffer, spc, flags, "%G <%+BODY <%S>%nCLAUSES <", gs,
-		       gimple_omp_body (gs));
+		       gimple_seq_body (gs));
       dump_omp_clauses (buffer, gimple_omp_sections_clauses (gs), spc, flags);
       dump_gimple_fmt (buffer, spc, flags, " >");
     }
@@ -909,12 +909,12 @@ dump_gimple_omp_sections (pretty_printer
 	  pp_character (buffer, '>');
 	}
       dump_omp_clauses (buffer, gimple_omp_sections_clauses (gs), spc, flags);
-      if (!gimple_seq_empty_p (gimple_omp_body (gs)))
+      if (!gimple_seq_empty_p (gimple_seq_body (gs)))
 	{
 	  newline_and_indent (buffer, spc + 2);
 	  pp_character (buffer, '{');
 	  pp_newline (buffer);
-	  dump_gimple_seq (buffer, gimple_omp_body (gs), spc + 4, flags);
+	  dump_gimple_seq (buffer, gimple_seq_body (gs), spc + 4, flags);
 	  newline_and_indent (buffer, spc + 2);
 	  pp_character (buffer, '}');
 	}
@@ -929,7 +929,7 @@ dump_gimple_omp_block (pretty_printer *b
 {
   if (flags & TDF_RAW)
     dump_gimple_fmt (buffer, spc, flags, "%G <%+BODY <%S> >", gs,
-		     gimple_omp_body (gs));
+		     gimple_seq_body (gs));
   else
     {
       switch (gimple_code (gs))
@@ -946,12 +946,12 @@ dump_gimple_omp_block (pretty_printer *b
 	default:
 	  gcc_unreachable ();
 	}
-      if (!gimple_seq_empty_p (gimple_omp_body (gs)))
+      if (!gimple_seq_empty_p (gimple_seq_body (gs)))
 	{
 	  newline_and_indent (buffer, spc + 2);
 	  pp_character (buffer, '{');
 	  pp_newline (buffer);
-	  dump_gimple_seq (buffer, gimple_omp_body (gs), spc + 4, flags);
+	  dump_gimple_seq (buffer, gimple_seq_body (gs), spc + 4, flags);
 	  newline_and_indent (buffer, spc + 2);
 	  pp_character (buffer, '}');
 	}
@@ -966,7 +966,7 @@ dump_gimple_omp_critical (pretty_printer
 {
   if (flags & TDF_RAW)
     dump_gimple_fmt (buffer, spc, flags, "%G <%+BODY <%S> >", gs,
-		     gimple_omp_body (gs));
+		     gimple_seq_body (gs));
   else
     {
       pp_string (buffer, "#pragma omp critical");
@@ -977,12 +977,12 @@ dump_gimple_omp_critical (pretty_printer
 			     flags, false);
 	  pp_character (buffer, ')');
 	}
-      if (!gimple_seq_empty_p (gimple_omp_body (gs)))
+      if (!gimple_seq_empty_p (gimple_seq_body (gs)))
 	{
 	  newline_and_indent (buffer, spc + 2);
 	  pp_character (buffer, '{');
 	  pp_newline (buffer);
-	  dump_gimple_seq (buffer, gimple_omp_body (gs), spc + 4, flags);
+	  dump_gimple_seq (buffer, gimple_seq_body (gs), spc + 4, flags);
 	  newline_and_indent (buffer, spc + 2);
 	  pp_character (buffer, '}');
 	}
@@ -1007,6 +1007,45 @@ dump_gimple_omp_return (pretty_printer *
     }
 }
 
+/* Dump a GIMPLE_GTM_TXN tuple on the pretty_printer BUFFER.  */
+
+static void
+dump_gimple_gtm_txn (pretty_printer *buffer, gimple gs, int spc, int flags)
+{
+  if (flags & TDF_RAW)
+    dump_gimple_fmt (buffer, spc, flags, "%G <%+BODY <%S> >", gs,
+		     gimple_seq_body (gs));
+  else
+    {
+      pp_string (buffer, "__tm_atomic");
+      if (!gimple_seq_empty_p (gimple_seq_body (gs)))
+	{
+	  newline_and_indent (buffer, spc + 2);
+	  pp_character (buffer, '{');
+	  pp_newline (buffer);
+	  dump_gimple_seq (buffer, gimple_seq_body (gs), spc + 4, flags);
+	  newline_and_indent (buffer, spc + 2);
+	  pp_character (buffer, '}');
+	}
+    }
+}
+
+/* Dump a GIMPLE_GTM_RETURN or GIMPLE_GTM_ABORT tuple on the
+   pretty_printer BUFFER.  */
+
+static void
+dump_gimple_gtm_other (pretty_printer *buffer, gimple gs, int spc, int flags)
+{
+  if (flags & TDF_RAW)
+    {
+      dump_gimple_fmt (buffer, spc, flags, "%G", gs);
+    }
+  else if (gimple_code (gs) == GIMPLE_GTM_RETURN)
+    pp_string (buffer, "__tm_return");
+  else if (gimple_code (gs) == GIMPLE_GTM_ABORT)
+    pp_string (buffer, "__tm_abort");
+}
+
 /* Dump a GIMPLE_ASM tuple on the pretty_printer BUFFER, SPC spaces of
    indent.  FLAGS specifies details to show in the dump (see TDF_* in
    tree-pass.h).  */
@@ -1168,7 +1207,7 @@ dump_gimple_omp_parallel (pretty_printer
   if (flags & TDF_RAW)
     {
       dump_gimple_fmt (buffer, spc, flags, "%G <%+BODY <%S>%nCLAUSES <", gs,
-                       gimple_omp_body (gs));
+                       gimple_seq_body (gs));
       dump_omp_clauses (buffer, gimple_omp_parallel_clauses (gs), spc, flags);
       dump_gimple_fmt (buffer, spc, flags, " >, %T, %T%n>",
                        gimple_omp_parallel_child_fn (gs),
@@ -1192,7 +1231,7 @@ dump_gimple_omp_parallel (pretty_printer
 	    pp_string (buffer, "???");
 	  pp_string (buffer, ")]");
 	}
-      body = gimple_omp_body (gs);
+      body = gimple_seq_body (gs);
       if (body && gimple_code (gimple_seq_first_stmt (body)) != GIMPLE_BIND)
 	{
 	  newline_and_indent (buffer, spc + 2);
@@ -1222,7 +1261,7 @@ dump_gimple_omp_task (pretty_printer *bu
   if (flags & TDF_RAW)
     {
       dump_gimple_fmt (buffer, spc, flags, "%G <%+BODY <%S>%nCLAUSES <", gs,
-                       gimple_omp_body (gs));
+                       gimple_seq_body (gs));
       dump_omp_clauses (buffer, gimple_omp_task_clauses (gs), spc, flags);
       dump_gimple_fmt (buffer, spc, flags, " >, %T, %T, %T, %T, %T%n>",
                        gimple_omp_task_child_fn (gs),
@@ -1249,7 +1288,7 @@ dump_gimple_omp_task (pretty_printer *bu
 	    pp_string (buffer, "???");
 	  pp_string (buffer, ")]");
 	}
-      body = gimple_omp_body (gs);
+      body = gimple_seq_body (gs);
       if (body && gimple_code (gimple_seq_first_stmt (body)) != GIMPLE_BIND)
 	{
 	  newline_and_indent (buffer, spc + 2);
@@ -1583,6 +1622,15 @@ dump_gimple_stmt (pretty_printer *buffer
       pp_string (buffer, " predictor.");
       break;
 
+    case GIMPLE_GTM_TXN:
+      dump_gimple_gtm_txn (buffer, gs, spc, flags);
+      break;
+
+    case GIMPLE_GTM_RETURN:
+    case GIMPLE_GTM_ABORT:
+      dump_gimple_gtm_other (buffer, gs, spc, flags);
+      break;
+
     default:
       GIMPLE_NIY;
     }
--- gimple.c	(revision 141060)
+++ gimple.c	(local)
@@ -117,7 +117,7 @@ gss_for_code (enum gimple_code code)
     case GIMPLE_OMP_FOR:		return GSS_OMP_FOR;
     case GIMPLE_OMP_MASTER:		
     case GIMPLE_OMP_ORDERED:
-    case GIMPLE_OMP_SECTION:		return GSS_OMP;
+    case GIMPLE_OMP_SECTION:		return GSS_SEQ;
     case GIMPLE_OMP_RETURN:
     case GIMPLE_OMP_SECTIONS_SWITCH:    return GSS_BASE;
     case GIMPLE_OMP_CONTINUE:		return GSS_OMP_CONTINUE;
@@ -128,6 +128,9 @@ gss_for_code (enum gimple_code code)
     case GIMPLE_OMP_ATOMIC_LOAD:	return GSS_OMP_ATOMIC_LOAD;
     case GIMPLE_OMP_ATOMIC_STORE:	return GSS_OMP_ATOMIC_STORE;
     case GIMPLE_PREDICT:		return GSS_BASE;
+    case GIMPLE_GTM_TXN:		return GSS_SEQ;
+    case GIMPLE_GTM_RETURN:
+    case GIMPLE_GTM_ABORT:		return GSS_BASE;
     default:				gcc_unreachable ();
     }
 }
@@ -141,64 +144,53 @@ gimple_size (enum gimple_code code)
 {
   enum gimple_statement_structure_enum gss = gss_for_code (code);
 
-  if (gss == GSS_WITH_OPS)
-    return sizeof (struct gimple_statement_with_ops);
-  else if (gss == GSS_WITH_MEM_OPS)
-    return sizeof (struct gimple_statement_with_memory_ops);
-
-  switch (code)
+  switch (gss)
     {
-    case GIMPLE_ASM:
-      return sizeof (struct gimple_statement_asm);
-    case GIMPLE_NOP:
+    case GSS_BASE:
       return sizeof (struct gimple_statement_base);
-    case GIMPLE_BIND:
+    case GSS_WITH_OPS:
+      return sizeof (struct gimple_statement_with_ops);
+    case GSS_WITH_MEM_OPS:
+      return sizeof (struct gimple_statement_with_memory_ops);
+    case GSS_SEQ:
+      return sizeof (struct gimple_statement_seq);
+    case GSS_BIND:
       return sizeof (struct gimple_statement_bind);
-    case GIMPLE_CATCH:
+    case GSS_CATCH:
       return sizeof (struct gimple_statement_catch);
-    case GIMPLE_EH_FILTER:
+    case GSS_EH_FILTER:
       return sizeof (struct gimple_statement_eh_filter);
-    case GIMPLE_TRY:
-      return sizeof (struct gimple_statement_try);
-    case GIMPLE_RESX:
+    case GSS_PHI:
+      return sizeof (struct gimple_statement_phi);
+    case GSS_RESX:
       return sizeof (struct gimple_statement_resx);
-    case GIMPLE_OMP_CRITICAL:
+    case GSS_TRY:
+      return sizeof (struct gimple_statement_try);
+    case GSS_WCE:
+      return sizeof (struct gimple_statement_wce);
+    case GSS_ASM:
+      return sizeof (struct gimple_statement_asm);
+    case GSS_OMP_CRITICAL:
       return sizeof (struct gimple_statement_omp_critical);
-    case GIMPLE_OMP_FOR:
+    case GSS_OMP_FOR:
       return sizeof (struct gimple_statement_omp_for);
-    case GIMPLE_OMP_PARALLEL:
+    case GSS_OMP_PARALLEL:
       return sizeof (struct gimple_statement_omp_parallel);
-    case GIMPLE_OMP_TASK:
+    case GSS_OMP_TASK:
       return sizeof (struct gimple_statement_omp_task);
-    case GIMPLE_OMP_SECTION:
-    case GIMPLE_OMP_MASTER:
-    case GIMPLE_OMP_ORDERED:
-      return sizeof (struct gimple_statement_omp);
-    case GIMPLE_OMP_RETURN:
-      return sizeof (struct gimple_statement_base);
-    case GIMPLE_OMP_CONTINUE:
-      return sizeof (struct gimple_statement_omp_continue);
-    case GIMPLE_OMP_SECTIONS:
+    case GSS_OMP_SECTIONS:
       return sizeof (struct gimple_statement_omp_sections);
-    case GIMPLE_OMP_SECTIONS_SWITCH:
-      return sizeof (struct gimple_statement_base);
-    case GIMPLE_OMP_SINGLE:
+    case GSS_OMP_SINGLE:
       return sizeof (struct gimple_statement_omp_single);
-    case GIMPLE_OMP_ATOMIC_LOAD:
+    case GSS_OMP_CONTINUE:
+      return sizeof (struct gimple_statement_omp_continue);
+    case GSS_OMP_ATOMIC_LOAD:
       return sizeof (struct gimple_statement_omp_atomic_load);
-    case GIMPLE_OMP_ATOMIC_STORE:
+    case GSS_OMP_ATOMIC_STORE:
       return sizeof (struct gimple_statement_omp_atomic_store);
-    case GIMPLE_WITH_CLEANUP_EXPR:
-      return sizeof (struct gimple_statement_wce);
-    case GIMPLE_CHANGE_DYNAMIC_TYPE:
-      return sizeof (struct gimple_statement_with_ops);
-    case GIMPLE_PREDICT:
-      return sizeof (struct gimple_statement_base);
     default:
-      break;
+      gcc_unreachable ();
     }
-
-  gcc_unreachable ();
 }
 
 
@@ -841,7 +833,7 @@ gimple_build_omp_critical (gimple_seq bo
   gimple p = gimple_alloc (GIMPLE_OMP_CRITICAL, 0);
   gimple_omp_critical_set_name (p, name);
   if (body)
-    gimple_omp_set_body (p, body);
+    gimple_seq_set_body (p, body);
 
   return p;
 }
@@ -860,7 +852,7 @@ gimple_build_omp_for (gimple_seq body, t
 {
   gimple p = gimple_alloc (GIMPLE_OMP_FOR, 0);
   if (body)
-    gimple_omp_set_body (p, body);
+    gimple_seq_set_body (p, body);
   gimple_omp_for_set_clauses (p, clauses);
   p->gimple_omp_for.collapse = collapse;
   p->gimple_omp_for.iter = GGC_CNEWVEC (struct gimple_omp_for_iter, collapse);
@@ -884,7 +876,7 @@ gimple_build_omp_parallel (gimple_seq bo
 {
   gimple p = gimple_alloc (GIMPLE_OMP_PARALLEL, 0);
   if (body)
-    gimple_omp_set_body (p, body);
+    gimple_seq_set_body (p, body);
   gimple_omp_parallel_set_clauses (p, clauses);
   gimple_omp_parallel_set_child_fn (p, child_fn);
   gimple_omp_parallel_set_data_arg (p, data_arg);
@@ -909,7 +901,7 @@ gimple_build_omp_task (gimple_seq body, 
 {
   gimple p = gimple_alloc (GIMPLE_OMP_TASK, 0);
   if (body)
-    gimple_omp_set_body (p, body);
+    gimple_seq_set_body (p, body);
   gimple_omp_task_set_clauses (p, clauses);
   gimple_omp_task_set_child_fn (p, child_fn);
   gimple_omp_task_set_data_arg (p, data_arg);
@@ -930,7 +922,7 @@ gimple_build_omp_section (gimple_seq bod
 {
   gimple p = gimple_alloc (GIMPLE_OMP_SECTION, 0);
   if (body)
-    gimple_omp_set_body (p, body);
+    gimple_seq_set_body (p, body);
 
   return p;
 }
@@ -945,7 +937,7 @@ gimple_build_omp_master (gimple_seq body
 {
   gimple p = gimple_alloc (GIMPLE_OMP_MASTER, 0);
   if (body)
-    gimple_omp_set_body (p, body);
+    gimple_seq_set_body (p, body);
 
   return p;
 }
@@ -975,7 +967,7 @@ gimple_build_omp_ordered (gimple_seq bod
 {
   gimple p = gimple_alloc (GIMPLE_OMP_ORDERED, 0);
   if (body)
-    gimple_omp_set_body (p, body);
+    gimple_seq_set_body (p, body);
 
   return p;
 }
@@ -1006,7 +998,7 @@ gimple_build_omp_sections (gimple_seq bo
 {
   gimple p = gimple_alloc (GIMPLE_OMP_SECTIONS, 0);
   if (body)
-    gimple_omp_set_body (p, body);
+    gimple_seq_set_body (p, body);
   gimple_omp_sections_set_clauses (p, clauses);
 
   return p;
@@ -1033,7 +1025,7 @@ gimple_build_omp_single (gimple_seq body
 {
   gimple p = gimple_alloc (GIMPLE_OMP_SINGLE, 0);
   if (body)
-    gimple_omp_set_body (p, body);
+    gimple_seq_set_body (p, body);
   gimple_omp_single_set_clauses (p, clauses);
 
   return p;
@@ -1077,6 +1069,17 @@ gimple_build_omp_atomic_store (tree val)
   return p;
 }
 
+/* Build a GIMPLE_GTM_TXN statement.  */
+
+gimple
+gimple_build_gtm_txn (gimple_seq body)
+{
+  gimple p = gimple_alloc (GIMPLE_GTM_TXN, 0);
+  if (body)
+    gimple_seq_set_body (p, body);
+  return p;
+}
+
 /* Build a GIMPLE_PREDICT statement.  PREDICT is one of the predictors from
    predict.def, OUTCOME is NOT_TAKEN or TAKEN.  */
 
@@ -1767,8 +1770,9 @@ walk_gimple_stmt (gimple_stmt_iterator *
     case GIMPLE_OMP_TASK:
     case GIMPLE_OMP_SECTIONS:
     case GIMPLE_OMP_SINGLE:
-      ret = walk_gimple_seq (gimple_omp_body (stmt), callback_stmt, callback_op,
-	                     wi);
+    case GIMPLE_GTM_TXN:
+      ret = walk_gimple_seq (gimple_seq_body (stmt), callback_stmt,
+			     callback_op, wi);
       if (ret)
 	return wi->callback_result;
       break;
@@ -2208,9 +2212,10 @@ gimple_copy (gimple stmt)
 	case GIMPLE_OMP_SECTION:
 	case GIMPLE_OMP_MASTER:
 	case GIMPLE_OMP_ORDERED:
+        case GIMPLE_GTM_TXN:
 	copy_omp_body:
-	  new_seq = gimple_seq_copy (gimple_omp_body (stmt));
-	  gimple_omp_set_body (copy, new_seq);
+	  new_seq = gimple_seq_copy (gimple_seq_body (stmt));
+	  gimple_seq_set_body (copy, new_seq);
 	  break;
 
 	case GIMPLE_WITH_CLEANUP_EXPR:
@@ -2570,7 +2575,9 @@ get_gimple_rhs_num_ops (enum tree_code c
       || (SYM) == POLYNOMIAL_CHREC					    \
       || (SYM) == DOT_PROD_EXPR						    \
       || (SYM) == VEC_COND_EXPR						    \
-      || (SYM) == REALIGN_LOAD_EXPR) ? GIMPLE_SINGLE_RHS		    \
+      || (SYM) == REALIGN_LOAD_EXPR					    \
+      || (SYM) == GTM_LOAD						    \
+      || (SYM) == GTM_STORE) ? GIMPLE_SINGLE_RHS			    \
    : GIMPLE_INVALID_RHS),
 #define END_OF_BASE_TREE_CODES (unsigned char) GIMPLE_INVALID_RHS,
 
--- gimple.def	(revision 141060)
+++ gimple.def	(local)
@@ -355,3 +355,13 @@ DEFGSCODE(GIMPLE_PREDICT, "gimple_predic
     
     This tuple should not exist outside of the gimplifier proper.  */
 DEFGSCODE(GIMPLE_WITH_CLEANUP_EXPR, "gimple_with_cleanup_expr", NULL)
+
+/* GIMPLE_GTX_TXN <BODY> represents __tm_atomic blocks.
+   BODY is the sequence of statements inside the transaction.  */
+DEFGSCODE(GIMPLE_GTM_TXN, "gimple_gtm_txn", NULL)
+
+/* GIMPLE_GTM_RETURN marks the end of a transaction.  */
+DEFGSCODE(GIMPLE_GTM_RETURN, "gimple_gtm_return", NULL)
+
+/* GIMPLE_GTM_ABORT marks a user abort of the transaction.  */
+DEFGSCODE(GIMPLE_GTM_ABORT, "gimple_gtm_abort", NULL)
--- gimple.h	(revision 141060)
+++ gimple.h	(local)
@@ -391,9 +391,9 @@ struct gimple_statement_with_memory_ops 
 };
 
 
-/* OpenMP statements (#pragma omp).  */
+/* Statements with embedded blocks (#pragma omp, gtm).  */
 
-struct gimple_statement_omp GTY(())
+struct gimple_statement_seq GTY(())
 {
   /* [ WORD 1-4 ]  */
   struct gimple_statement_base gsbase;
@@ -571,7 +571,7 @@ struct gimple_statement_asm GTY(())
 struct gimple_statement_omp_critical GTY(())
 {
   /* [ WORD 1-5 ]  */
-  struct gimple_statement_omp omp;
+  struct gimple_statement_seq omp;
 
   /* [ WORD 6 ]
      Critical section name.  */
@@ -602,7 +602,7 @@ struct gimple_omp_for_iter GTY(())
 struct gimple_statement_omp_for GTY(())
 {
   /* [ WORD 1-5 ]  */
-  struct gimple_statement_omp omp;
+  struct gimple_statement_seq omp;
 
   /* [ WORD 6 ]  */
   tree clauses;
@@ -625,7 +625,7 @@ struct gimple_statement_omp_for GTY(())
 struct gimple_statement_omp_parallel GTY(())
 {
   /* [ WORD 1-5 ]  */
-  struct gimple_statement_omp omp;
+  struct gimple_statement_seq omp;
 
   /* [ WORD 6 ]
      Clauses.  */
@@ -668,7 +668,7 @@ struct gimple_statement_omp_task GTY(())
 struct gimple_statement_omp_sections GTY(())
 {
   /* [ WORD 1-5 ]  */
-  struct gimple_statement_omp omp;
+  struct gimple_statement_seq omp;
 
   /* [ WORD 6 ]  */
   tree clauses;
@@ -701,7 +701,7 @@ struct gimple_statement_omp_continue GTY
 struct gimple_statement_omp_single GTY(())
 {
   /* [ WORD 1-5 ]  */
-  struct gimple_statement_omp omp;
+  struct gimple_statement_seq omp;
 
   /* [ WORD 6 ]  */
   tree clauses;
@@ -749,7 +749,7 @@ union gimple_statement_d GTY ((desc ("gi
   struct gimple_statement_base GTY ((tag ("GSS_BASE"))) gsbase;
   struct gimple_statement_with_ops GTY ((tag ("GSS_WITH_OPS"))) gsops;
   struct gimple_statement_with_memory_ops GTY ((tag ("GSS_WITH_MEM_OPS"))) gsmem;
-  struct gimple_statement_omp GTY ((tag ("GSS_OMP"))) omp;
+  struct gimple_statement_seq GTY ((tag ("GSS_SEQ"))) seq;
   struct gimple_statement_bind GTY ((tag ("GSS_BIND"))) gimple_bind;
   struct gimple_statement_catch GTY ((tag ("GSS_CATCH"))) gimple_catch;
   struct gimple_statement_eh_filter GTY ((tag ("GSS_EH_FILTER"))) gimple_eh_filter;
@@ -816,6 +816,7 @@ gimple gimple_build_omp_single (gimple_s
 gimple gimple_build_cdt (tree, tree);
 gimple gimple_build_omp_atomic_load (tree, tree);
 gimple gimple_build_omp_atomic_store (tree);
+gimple gimple_build_gtm_txn (gimple_seq);
 gimple gimple_build_predict (enum br_predictor, enum prediction);
 enum gimple_statement_structure_enum gimple_statement_structure (gimple);
 enum gimple_statement_structure_enum gss_for_assign (enum tree_code);
@@ -3232,20 +3233,20 @@ gimple_switch_set_default_label (gimple 
 }
 
 
-/* Return the body for the OMP statement GS.  */
+/* Return the body for the SEQ statement GS.  */
 
 static inline gimple_seq 
-gimple_omp_body (gimple gs)
+gimple_seq_body (gimple gs)
 {
-  return gs->omp.body;
+  return gs->seq.body;
 }
 
-/* Set BODY to be the body for the OMP statement GS.  */
+/* Set BODY to be the body for the SEQ statement GS.  */
 
 static inline void
-gimple_omp_set_body (gimple gs, gimple_seq body)
+gimple_seq_set_body (gimple gs, gimple_seq body)
 {
-  gs->omp.body = body;
+  gs->seq.body = body;
 }
 
 
@@ -4169,6 +4170,14 @@ is_gimple_omp (const_gimple stmt)
 	  || gimple_code (stmt) == GIMPLE_OMP_CONTINUE);
 }
 
+/* Returns true when the gimple statement STMT is a GTM type.  */
+
+static inline bool
+is_gimple_gtm (const_gimple stmt)
+{
+  return (gimple_code (stmt) == GIMPLE_GTM_TXN
+	  || gimple_code (stmt) == GIMPLE_GTM_RETURN);
+}
 
 /* Returns TRUE if statement G is a GIMPLE_NOP.  */
 
--- gsstruct.def	(revision 141060)
+++ gsstruct.def	(local)
@@ -28,7 +28,7 @@ along with GCC; see the file COPYING3.  
 DEFGSSTRUCT(GSS_BASE, "base")
 DEFGSSTRUCT(GSS_WITH_OPS, "with_ops")
 DEFGSSTRUCT(GSS_WITH_MEM_OPS, "with_mem_ops")
-DEFGSSTRUCT(GSS_OMP, "omp")
+DEFGSSTRUCT(GSS_SEQ, "seq")
 DEFGSSTRUCT(GSS_BIND, "bind")
 DEFGSSTRUCT(GSS_CATCH, "catch")
 DEFGSSTRUCT(GSS_EH_FILTER, "eh_filter")
--- gtm-low.c	(revision 141060)
+++ gtm-low.c	(local)
@@ -1,5 +1,5 @@
-/* Lowering pass for transactional memory directives. 
-   Converts markers of transactions into explicit calls to 
+/* Lowering pass for transactional memory directives.
+   Converts markers of transactions into explicit calls to
    the STM runtime library.
 
    Copyright (C) 2008 Free Software Foundation, Inc.
@@ -18,7 +18,7 @@
 
    You should have received a copy of the GNU General Public License
    along with GCC; see the file COPYING3.  If not see
-   <http://www.gnu.org/licenses/>.  
+   <http://www.gnu.org/licenses/>.
 
 */
 
@@ -28,8 +28,7 @@
 #include "tm.h"
 #include "tree.h"
 #include "rtl.h"
-#include "tree-gimple.h"
-#include "tree-inline.h"
+#include "gimple.h"
 #include "langhooks.h"
 #include "diagnostic.h"
 #include "tree-flow.h"
@@ -45,49 +44,26 @@
 #include "optabs.h"
 #include "cfgloop.h"
 #include "tree-ssa-live.h"
+#include "tree-flow.h"
 
-struct gtm_region *root_gtm_region;
-unsigned int label_index;
-unsigned int e_index;
-edge edges_to_instrument[NUM_BB_TXN];
-
-/* Function declarations for GTM expansion and checkpointing. */
-void check_and_mark_edges (struct gtm_region *, basic_block); 
-char *check_call_expr (tree); 
-void checkpoint_live_in_variables (struct gtm_region *, block_stmt_iterator *, basic_block); 
-void compensate_for_taking_the_address (tree);
-static void expand_gtm_abort (block_stmt_iterator *, enum bsi_iterator_update, tree);
 
+struct gtm_region *root_gtm_region;
 
 /* Debugging dumps for transactional regions.  */
 void dump_gtm_region (FILE *, struct gtm_region *, int);
 void debug_gtm_region (struct gtm_region *);
 void debug_all_gtm_regions (void);
 
-void execute_lower_gtm (void);
-void execute_checkpoint_gtm (void);
-static bool gate_expand_gtm (void);
-static bool gate_checkpoint_gtm (void);
-
-void init_label_table (void); 
-tree insert_temporary  (block_stmt_iterator, tree);
-void instrument_edges (tree);
-void instrument_return_expr (block_stmt_iterator *, tree);
-
-void may_repair_rhs (tree, block_stmt_iterator, tree);
-void record_bb_into_table (struct gtm_region *, basic_block);
-
-
 /* Dump the gtm region tree rooted at REGION.  */
+
 void
 dump_gtm_region (FILE *file, struct gtm_region *region, int indent)
 {
-  fprintf (file, "%*sbb %d: %s\n", indent, "", region->entry->index,
-	   tree_code_name[region->type]);
+  fprintf (file, "%*sbb %d: GTM_TXN\n", indent, "", region->entry->index);
 
   if (region->inner)
     dump_gtm_region (file, region->inner, indent + 4);
-    
+
   if (region->exit)
     fprintf (file, "%*sbb %d: GTM_RETURN\n", indent, "",
 	     region->exit->index);
@@ -109,14 +85,14 @@ debug_all_gtm_regions (void)
 }
 
 /* Create a new gtm region starting at STMT inside region PARENT.  */
+
 struct gtm_region *
-new_gtm_region (basic_block bb, enum tree_code type, struct gtm_region *parent)
+new_gtm_region (basic_block bb, struct gtm_region *parent)
 {
-  struct gtm_region *region = xcalloc (1, sizeof (*region));
+  struct gtm_region *region = XCNEW (struct gtm_region);
 
   region->outer = parent;
   region->entry = bb;
-  region->type = type;
 
   if (parent)
     {
@@ -137,6 +113,7 @@ new_gtm_region (basic_block bb, enum tre
 }
 
 /* Release the memory associated with the region tree rooted at REGION.  */
+
 static void
 free_gtm_region_1 (struct gtm_region *region)
 {
@@ -156,1598 +133,316 @@ void
 free_gtm_regions (void)
 {
   struct gtm_region *r, *n;
+
   for (r = root_gtm_region; r ; r = n)
     {
       n = r->next;
       free_gtm_region_1 (r);
     }
+
   root_gtm_region = NULL;
 }
 
 
 /* Helper for build_gtm_regions.  Scan the dominator tree starting at
    block BB.  PARENT is the region that contains BB.  If SINGLE_TREE is
-   true, the function ends once a single tree is built (like constructing omp region trees). */
+   true, the function ends once a single tree is built.  */
+
 static void
 build_gtm_regions_1 (basic_block bb, struct gtm_region *parent,
 		     bool single_tree)
 {
-  block_stmt_iterator si;
-  tree stmt;
+  gimple_stmt_iterator gsi;
+  gimple stmt;
   basic_block son;
+  struct gtm_region *region;
 
-  si = bsi_last (bb);
-  if (!bsi_end_p (si)) /* bsi_stmt should not be NULL */
+  gsi = gsi_last_bb (bb);
+  if (!gsi_end_p (gsi))
     {
-      if (GTM_DIRECTIVE_P (bsi_stmt (si)))
+      stmt = gsi_stmt (gsi);
+      switch (gimple_code (stmt))
 	{
-	  struct gtm_region *region;
-	  enum tree_code code;
-	  stmt = bsi_stmt (si);
-	  code = TREE_CODE (stmt);
-	  if (code == GTM_RETURN)
-	    {
-	      /* STMT is the return point out of region PARENT.  Mark it
-		 as the exit point and make PARENT the immediately
-		 enclosing region.  */
-	      gcc_assert (parent);
-	      region = parent;
-	      region->exit = bb;
-	      parent = parent->outer;
-	    }
-	  else if (code == GTM_TXN)
-	    {
-	      /* Otherwise, this directive becomes the parent for a new
-		 region.  GTM_TXN is the only one left for now. */
-	      region = new_gtm_region (bb, code, parent);
-	      parent = region;
-	    }
+	case GIMPLE_GTM_TXN:
+	  region = new_gtm_region (bb, parent);
+	  break;
+
+	case GIMPLE_GTM_RETURN:
+	  /* STMT is the return point out of region PARENT.  Mark it
+	     as the exit point and make PARENT the immediately enclosing
+	     region.  */
+	  gcc_assert (parent);
+	  region = parent;
+	  region->exit = bb;
+	  parent = parent->outer;
+	  break;
+
+	default:
+	  break;
 	}
     }
+
   if (single_tree && !parent)
     return;
-  
+
   for (son = first_dom_son (CDI_DOMINATORS, bb);
        son;
        son = next_dom_son (CDI_DOMINATORS, son))
     build_gtm_regions_1 (son, parent, single_tree);
 }
 
-/* Scan the CFG and build a tree of GTM regions. 
+/* Scan the CFG and build a tree of GTM regions.
    Return the root of the GTM region tree. */
+
 static void
 build_gtm_regions (void)
 {
   gcc_assert (root_gtm_region == NULL);
-  calculate_dominance_info (CDI_DOMINATORS);
   build_gtm_regions_1 (ENTRY_BLOCK_PTR, NULL, false);
 }
 
 /* Remove entry and exit marker from region. */
-static void
+
+static void ATTRIBUTE_UNUSED
 remove_gtm_stmts (struct gtm_region *region)
 {
-  basic_block entry_bb, exit_bb;
-  block_stmt_iterator si;
-  tree stmt;
-  
-  entry_bb = region->entry;
-  exit_bb = region->exit;
-
-  gcc_assert (entry_bb);
-  gcc_assert (exit_bb);
-
-  si = bsi_last (entry_bb);
-  stmt = bsi_stmt (si);
-  
-  gcc_assert (TREE_CODE (stmt) == GTM_TXN);
-
-  bsi_remove (&si, true);
-  single_succ_edge (entry_bb)->flags = EDGE_FALLTHRU;
-
-  if (exit_bb)
-    {
-      si = bsi_last (exit_bb);
-      gcc_assert (!bsi_end_p (si)
-		  && TREE_CODE (bsi_stmt (si)) == GTM_RETURN);
-
-      bsi_remove (&si, true);
-      single_succ_edge (exit_bb)->flags = EDGE_FALLTHRU;
-    }
-
-  return ;
-}
+  gimple_stmt_iterator gsi;
 
-/* If the STM only supports flat nesting, all 
-   nested transactions are collapsed into 
-   the outermost one. */
-static void
-collapse_gtm_regions (struct gtm_region *region)
-{
-  while (region)
-    {
-      /* Collapse only the inner regions.  */
-      if (region->inner) 
-	{
-	  remove_gtm_stmts (region->inner);
-	  collapse_gtm_regions (region->inner);
-	  free (region->inner);
-	  region->inner = NULL;
-	}
+  gcc_assert (region->entry);
+  gcc_assert (region->exit);
 
-      gcc_assert ((region->type) == GTM_TXN);
-      region = region->next;
-    }  
+  gsi = gsi_last_bb (region->entry);
+  gcc_assert (gimple_code (gsi_stmt (gsi)) == GIMPLE_GTM_TXN);
+  gsi_remove (&gsi, true);
 
-  return ;
+  gsi = gsi_last_bb (region->exit);
+  gcc_assert (gimple_code (gsi_stmt (gsi)) == GIMPLE_GTM_RETURN);
+  gsi_remove (&gsi, true);
 }
 
-/* TODO: add mechanism to query the
-   STM for supported features. */
-static bool
-query_STM_for_flat_nesting (void) 
-{
-  return true;
-}
 
-/* This is an enhancement to the TM concept.
-   It allows the programmer to specify where 
-   to drop some instrumentation. Variables in 
-   the source code can be marked as tm_pure. 
-   The helper function sets the corresponding 
-   attribute. */
-static void
-set_gtm_pure_var (tree t)
-{
-  if ((TREE_CODE (t) == INDIRECT_REF)
-      || (TREE_CODE (t) == COMPONENT_REF)
-      || (TREE_CODE (t) == ARRAY_REF))
-    {
-      return set_gtm_pure_var (TREE_OPERAND (t, 0));
-    }
-  
-  if (TREE_CODE (t) == VAR_DECL)
-    {
-      DECL_IS_GTM_PURE_VAR (t) = 1;
-    }
-  return ;
-}
+/* Determine whether X has to be instrumented using a read
+   or write barrier.  */
 
-/* This is an enhancement to the TM concept.
-   It allows the programmer to specify where 
-   to drop some instrumentation. Variables in 
-   the source code can be marked as tm_pure. 
-   The helper function checks whether the 
-   attribute was specified. */
 static bool
-is_gtm_pure_var (tree t) 
+requires_barrier (tree x)
 {
-  if ((TREE_CODE (t) == INDIRECT_REF)
-      || (TREE_CODE (t) == COMPONENT_REF)
-      || (TREE_CODE (t) == ARRAY_REF))
-    {
-      return is_gtm_pure_var (TREE_OPERAND (t, 0));
-    }
+  while (handled_component_p (x))
+    x = TREE_OPERAND (x, 0);
 
-  if (TREE_CODE (t) == VAR_DECL)
+  switch (TREE_CODE (x))
     {
-      if (DECL_IS_GTM_PURE_VAR (t) == 1)
-	{
-	  return true;
-	}
-    }
-  return false;
-} 
+    case INDIRECT_REF:
+      /* ??? Use must-alias information to reduce this.  */
+      return true;
+
+    case ALIGN_INDIRECT_REF:
+    case MISALIGNED_INDIRECT_REF:
+      gcc_unreachable ();
+
+    case VAR_DECL:
+      if (DECL_IS_GTM_PURE_VAR (x))
+	return false;
+      if (is_global_var (x))
+	return !TREE_READONLY (x);
+      return TREE_ADDRESSABLE (x);
 
-/* Determine whether operand has to be 
-   instrumented using a read barrier. */
-/* TODO: check if _all_ cases are covered. */
-static bool
-requires_read_barrier (tree operand) 
-{
-  if (TREE_CODE (operand) == SSA_NAME)
-    operand = SSA_NAME_VAR (operand);
-  
-  /* Check whether we may drop some instrumentation. */
-  if (is_gtm_pure_var (operand))
-    return false;
-
-  if ((TREE_CODE (operand) == COMPONENT_REF) 
-      || (TREE_CODE (operand) == INDIRECT_REF)
-      || (TREE_CODE (operand) == ARRAY_REF))
-    return true;
-
-  /* Casts are ignored - descent recursively. */
-  if ((TREE_CODE (operand) == NOP_EXPR)
-      || (TREE_CODE (operand) == FLOAT_EXPR)
-      || (TREE_CODE (operand) == FIX_TRUNC_EXPR))
-    return requires_read_barrier (TREE_OPERAND (operand, 0)); 
-
-  /* In case the variable is defined inside the scope of 
-     the transaction, there is no need for instrumentation. */
-  if (TREE_CODE (operand) == VAR_DECL) 
-    if (DECL_IS_GTM_PURE_VAR (operand)) 
+    default:
       return false;
-
-  if ((CONSTANT_CLASS_P (operand)) 
-      || (DECL_ARTIFICIAL (operand))) 
-    return false;
-  else 
-    return ((TREE_CODE (operand) == VAR_DECL && is_global_var (operand)) 
-	    || (POINTER_TYPE_P (TREE_TYPE (operand)))
-	    || (TREE_ADDRESSABLE (operand)));
-}
-
-/* Determine whether operand has to be instrumented 
-   using a write barrier. */
-/* TODO: check if _all_ cases are covered. */
-static bool
-requires_write_barrier (tree operand) 
-{
-  if (TREE_CODE (operand) == SSA_NAME)
-    operand = SSA_NAME_VAR (operand);
-
-  /* Check whether we may drop some instrumentation. */
-  if (is_gtm_pure_var (operand))
-    return false;
-
-  if ( (TREE_CODE (operand) == COMPONENT_REF) 
-       || (TREE_CODE (operand) == INDIRECT_REF)
-       || (TREE_CODE (operand) == ARRAY_REF))
-    return true;
-
-  if ((CONSTANT_CLASS_P (operand))
-      || (DECL_ARTIFICIAL (operand))) 
-    return false;
-  else 
-    return ((TREE_CODE (operand) == VAR_DECL && is_global_var (operand)) 
-	    || (POINTER_TYPE_P (TREE_TYPE (operand))) 
-	    || (TREE_ADDRESSABLE (operand)));
-}
-
-/* Helper function returning the declaration 
-   of a builtin stm function if the operand 
-   has a type real. */
-static tree
-get_real_stm_decl (bool store, tree op) 
-{
-  tree decl;
-  tree type = TYPE_MAIN_VARIANT (TREE_TYPE (op));
-  if (!store)
-    {
-      if (type == double_type_node)
-	decl = built_in_decls [BUILT_IN_GTM_LOAD_DOUBLE];
-      else 	
-	{
-	  gcc_assert (type == float_type_node);
-	  decl = built_in_decls [BUILT_IN_GTM_LOAD_FLOAT];
-	}
-    }
-  else 
-    {
-      if (type == double_type_node)
-	decl = built_in_decls [BUILT_IN_GTM_STORE_DOUBLE];
-      else
-	{
-	  gcc_assert (type == float_type_node);
-	  decl = built_in_decls [BUILT_IN_GTM_STORE_FLOAT];
-	}
-    }
-  gcc_assert(decl);
-  
-  return decl;
-}
-
-/* Returns function decl determined by 
-   type size of operand. */
-static tree
-get_uint_stm_decl (int builtin, tree op) 
-{
-  HOST_WIDE_INT index;
-  tree decl;
-  tree type = TYPE_MAIN_VARIANT (TREE_TYPE (op));
-
-  index = tree_low_cst (TYPE_SIZE_UNIT (type), 1);
-  index = exact_log2 (index);
-
-  if (index >= 0 && index <= 4)
-    decl = built_in_decls[builtin + index + 1];
-  else 
-    gcc_unreachable();
-
-  gcc_assert(decl);
-
-  return decl;
-}
-
-/* Insert new temporary variable that 
-   lives in a GIMPLE register and issue 
-   a load of the "old" variable. */
-tree 
-insert_temporary (block_stmt_iterator bsi, tree op)
-{
-  tree new_var;
-  tree stmt;
-  
-  new_var = create_tmp_var (TREE_TYPE (op), get_name(op));
-  stmt = build_gimple_modify_stmt (new_var, op);
-
-  stmt = unshare_expr (stmt);
-
-  bsi_insert_before (&bsi, stmt, BSI_SAME_STMT);
-  return new_var;
-}
-
-/* Check whether variables used in stmts are the 
-   ones to replace by a use of a GIMPLE register. 
-   If they match the replacement is done. */
-void
-may_repair_rhs (tree rhs, block_stmt_iterator bsi, tree op)
-{
-  tree new_var;
-
-  if (UNARY_CLASS_P (rhs))
-    {
-      if (op == rhs)
-	{
-	  new_var = insert_temporary  (bsi, op);
-	  tree stmt = bsi_stmt (bsi);
-	  GIMPLE_STMT_OPERAND (stmt, 1) = new_var;
-	}
-    }
-  else 
-    {
-      if (BINARY_CLASS_P (rhs))
-	{
-	  if (TREE_OPERAND (rhs, 0) == op)
-	    {
-	      new_var = insert_temporary (bsi, op);
-	      TREE_OPERAND (rhs, 0) = new_var;
-	    }
-	  if (TREE_OPERAND (rhs, 1) == op)
-	    {
-	      new_var = insert_temporary (bsi, op);
-	      TREE_OPERAND (rhs, 1) = new_var;
-	    }
-	}
     }
-
-  return;
 }
 
-/* Compensate for taking the address of a local variable. 
-   By using the address of the variable, the variable escapes 
-   the local scope and becomes global. 
-   Since global variables on GIMPLE have to be transferred to 
-   registers before they can be used, this behaviour has to 
-   be added. */
-void 
-compensate_for_taking_the_address (tree op)
-{
-  basic_block bb;
-  block_stmt_iterator bsi;
-  tree stmt;
-  tree rhs;
-
-  FOR_EACH_BB (bb)
-  {
-    for (bsi = bsi_start (bb); !bsi_end_p (bsi); bsi_next (&bsi))
-      {
-	stmt = bsi_stmt (bsi);
-
-	/* TODO: add more possible uses of a variable here! */
-	if (TREE_CODE (stmt) == GIMPLE_MODIFY_STMT)
-	  {
-	    rhs = GIMPLE_STMT_OPERAND (stmt, 1);
-	    may_repair_rhs(rhs, bsi, op);
-	  }
-
-	if (TREE_CODE (stmt) == CALL_EXPR)
-	  {
-	    tree arg;
-	    call_expr_arg_iterator iter;
-	    FOR_EACH_CALL_EXPR_ARG (arg, iter, stmt)
-	      may_repair_rhs (arg, bsi, op);
-	  }
-      }
-  }
-
-  return ;
-}     
-
-/* Helper function that
-   composes the STM store function call. */
-static tree
-compose_stm_store_call (tree op, tree txn_handle, tree value) 
-{
-  tree call;
-  tree decl;
-  bool compensate = false;
-
-  if (TREE_CODE (op) == SSA_NAME)
-    op = SSA_NAME_VAR (op);
-  
-  if (!TREE_ADDRESSABLE (op))
-    compensate = true;
-
-  if (TREE_CODE (TREE_TYPE (op)) == INTEGER_TYPE)
-    decl = get_uint_stm_decl (BUILT_IN_GTM_STORE_N, op); 
-  
-  if (TREE_CODE (TREE_TYPE (op)) == POINTER_TYPE)
-    {
-#ifdef TINYSTM_VERSION_0_9_0b1
-      decl = built_in_decls [BUILT_IN_GTM_STORE_PTR];
-#endif
-#ifdef TANGER
-      decl = built_in_decls [BUILT_IN_GTM_STORE_PTR];
-#endif
-#ifdef TINYSTM_VERSION_0_9_5
-      decl = built_in_decls [BUILT_IN_GTM_STORE_PTR];
-#endif
-    }
-
-  if (TREE_CODE (TREE_TYPE (op)) == REAL_TYPE)
-    decl = get_real_stm_decl (true, op); 
+/* Subsituting a MODIFY_STMT with calls to the STM runtime.  */
 
-  gcc_assert (decl);
-
-  if (txn_handle != NULL_TREE)
-    call = build_call_expr (decl, 3, txn_handle, 
-			    build_fold_addr_expr (op), value); 
-  else 
-    call = build_call_expr (decl, 2, build_fold_addr_expr (op), value); 
-
-  if (compensate)
-    compensate_for_taking_the_address (op);
-
-  return call;
-}
-
-/* Helper function that composes 
-   the STM load function call. */
-static tree
-compose_stm_load_call (tree op, tree txn_handle) 
-{
-  tree decl = NULL_TREE;
-  tree call;
-  bool compensate = false;
-  
-  if (TREE_CODE (op) == SSA_NAME)
-    op = SSA_NAME_VAR (op);
-
-  if (!TREE_ADDRESSABLE (op))
-    compensate = true;
-
-  if (TREE_CODE (TREE_TYPE (op)) == INTEGER_TYPE)
-    decl = get_uint_stm_decl(BUILT_IN_GTM_LOAD_N, op); 
-
-  if (TREE_CODE (TREE_TYPE (op)) == REAL_TYPE)
-    decl = get_real_stm_decl(false, op); 
-
-  if (TREE_CODE (TREE_TYPE (op)) == POINTER_TYPE)
-    {
-#ifdef TINYSTM_VERSION_0_9_0b1
-      decl = built_in_decls [BUILT_IN_GTM_LOAD_PTR];
-#endif
-#ifdef TANGER
-      decl = built_in_decls [BUILT_IN_GTM_LOAD_PTR];
-#endif
-#ifdef TINYSTM_VERSION_0_9_5
-      decl = built_in_decls [BUILT_IN_GTM_LOAD_PTR];
-#endif
-    }
-
-  gcc_assert (decl);
-  
-  if (txn_handle != NULL_TREE)
-    {
-      call = build_call_expr (decl, 2, txn_handle, 
-			      build_fold_addr_expr(op));
-    }
-  else 
-    {
-      call = build_call_expr (decl, 1, build_fold_addr_expr(op));
-    }
-  
-  if (compensate)
-    compensate_for_taking_the_address (op);
-  
-  return call;
-}
-
-/* Emits call to stm_load including the 
-   txn_handle and address of the variable. */
-static tree
-insert_rhs_stm_call (block_stmt_iterator *bsi, enum bsi_iterator_update m, tree op, tree txn_handle)
-{
-  tree stmt;
-  tree t_load = create_tmp_var (TREE_TYPE (op), "txn_tmp");
-  
-  tree call = compose_stm_load_call (op, txn_handle);
-  
-  stmt = build_gimple_modify_stmt (t_load, call);
-  stmt = unshare_expr (stmt);
-  bsi_insert_before (bsi, stmt, m);
-
-  return t_load;
-} 
-
-/* Introduce temporary variable if necessary 
-   and emit call to stm_store. */
 static void
-replace_lhs (block_stmt_iterator *bsi, enum bsi_iterator_update m, tree op, tree txn_handle)
+maybe_transactify_assign (gimple stmt)
 {
-  tree t_store;
-  tree stmt, call;
-  tree op_type = TREE_TYPE (op);
-  tree mod_stmt = bsi_stmt (*bsi);
-  tree rhs = GIMPLE_STMT_OPERAND (mod_stmt, 1);
-  
-  if ((!CONSTANT_CLASS_P (rhs))
-      && (!is_gimple_formal_tmp_var (rhs))) 
-    {
-      t_store = create_tmp_var (op_type, "txn_tmp");
-      stmt = build_gimple_modify_stmt (t_store, rhs);
-      stmt = unshare_expr (stmt);
-      bsi_insert_before (bsi, stmt, m);
-    }
-  else  
-    {
-      t_store = rhs;
-    }
-  
-  call = compose_stm_store_call(op, txn_handle, t_store);
-  call = unshare_expr (call);
-  bsi_insert_after (bsi, call, m);
-  bsi_remove (bsi, true);
-
-  return ;
-}
+  bool load_p = requires_barrier (gimple_assign_rhs1 (stmt));
+  bool store_p = requires_barrier (gimple_assign_lhs (stmt));
 
-/* Check whether the operands need a read 
-   barrier and insert it. 
-   TODO: relax handling of ARRAY_REFs. */
-static void
-maybe_replace_rhs_stmt (block_stmt_iterator *bsi, enum bsi_iterator_update m, tree stmt, tree txn_handle) 
-{
-  tree t_load;
-  tree op1, op2;
-  tree rhs = GIMPLE_STMT_OPERAND (stmt, 1);  
-
-  if ((UNARY_CLASS_P (rhs)) 
-      || (CONSTANT_CLASS_P (rhs))
-      || (TREE_CODE (rhs) == VAR_DECL))
-    {
-      op1 = rhs;
-      if (requires_read_barrier (op1))
-	{
-	  if (TREE_CODE (op1) == NOP_EXPR)
-	    op1 = TREE_OPERAND (op1, 0);
-	  t_load = insert_rhs_stm_call (bsi, m, op1, txn_handle);
-	  GIMPLE_STMT_OPERAND (stmt, 1) = t_load;
-	}
-    }
-  else 
+  if (load_p)
     {
-      if (BINARY_CLASS_P (rhs))
-	{
-	  op1 = TREE_OPERAND (rhs, 0);
-	  if (requires_read_barrier (op1))
-	    {
-	      t_load = insert_rhs_stm_call (bsi, m, op1, txn_handle);
-	      TREE_OPERAND (rhs, 0) = t_load; 
-	    }
-	  op2 = TREE_OPERAND (rhs, 1);
-	  if (requires_read_barrier (op2))
-	    {
-	      t_load = insert_rhs_stm_call (bsi, m, op2, txn_handle);
-	      TREE_OPERAND (rhs, 1) = t_load; 
-	    }
-	}
-      else 
-	{
-	  if ((POINTER_TYPE_P (TREE_TYPE (rhs))
-	       || (TREE_CODE (rhs) == COMPONENT_REF)
-	       || ((TREE_CODE (rhs) == INDIRECT_REF) 
-		   && (DECL_IS_GTM_PURE_VAR (TREE_OPERAND (rhs, 0)) != 1))
-	       || (TREE_CODE (rhs) == ARRAY_REF)) 
-	      && (TREE_CODE (rhs) != CALL_EXPR)
-	      )
-	    {
-	      op1 = rhs;
-	      t_load = insert_rhs_stm_call (bsi, m, op1, txn_handle);
-	      GIMPLE_STMT_OPERAND (stmt, 1) = t_load;
-	    }
-	}
+      gcc_assert (!store_p);
+      gimple_assign_set_rhs_code (stmt, GTM_LOAD);
     }
-
-  return ;
-}  
-
-/* Subsituting a MODIFY_STMT   
-   with calls to the STM runtime, 
-   the worst case looks like this:
-
-   t1 = stm_load(b);
-   t2 = stm_load(c);
-   t3 = t1 * t2;
-   stm_store(a, t3); 
-
-   substitutes for:
-
-   a = b * c; */
-static void
-replace_txn_mod_stmt (block_stmt_iterator *bsi, enum bsi_iterator_update m, tree txn_handle)
-{
-
-  tree stmt = bsi_stmt (*bsi);
-  tree lhs = GIMPLE_STMT_OPERAND (stmt, 0);
-  tree rhs  = GIMPLE_STMT_OPERAND (stmt, 1);
-
-  /* Propagate GTM_PURE_VAR in case of an assignment 
-     to a temporary variable. */
-  if (is_gtm_pure_var (rhs))
-    set_gtm_pure_var (lhs);
-
-  maybe_replace_rhs_stmt (bsi, m, stmt, txn_handle); 
-
-  if (requires_write_barrier (lhs))
-    {
-      replace_lhs (bsi, m, lhs, txn_handle); 
-    }
-  
-  return ;
-} 
-
-/* Build and return a call to a transactional function. 
-   Add one parameter to pass a transaction handle. */
-tree
-build_txn_call_expr (tree orig_ce, struct cgraph_node *tm_node, tree txn_handle) 
-{
-  tree arglist = CALL_EXPR_ARGS (orig_ce);
-
-  if (txn_handle)
-    {
-      arglist = chainon (arglist, build_tree_list (NULL_TREE, txn_handle));
-    }
- 
-  return build_function_call_expr (tm_node->decl, arglist);
-}
-
-/* Return function name or NULL if function 
-   is a STM compiler builtin. */
-char *
-check_call_expr (tree ce) 
-{
-  char *name = get_name (get_callee_fndecl (ce));
-#ifdef TANGER
-  if (strncmp(name, "__builtin_tanger_stm", 20) != 0)
-    return name;
-#else
-  if (strncmp(name, "__builtin_stm", 13) != 0)
-    return name;
-#endif  
-  return NULL;
+  else if (store_p)
+    gimple_assign_set_rhs_code (stmt, GTM_STORE);
 }
 
-/* Helper function that replaces call expressions inside 
-   transactions and issues a warning if no transactional 
+/* Helper function that replaces call expressions inside
+   transactions and issues a warning if no transactional
    clone is found. */
-void
-replace_call_expr_in_txn (tree ce, tree stmt, tree txn_handle) 
-{
-  bool redirected = false;
-  char *name;
-  name = check_call_expr (ce);
-  if (name)
-    {
-      tree fn_decl = get_callee_fndecl (ce);
-      struct cgraph_node *node = cgraph_node (fn_decl);
-      struct cgraph_node *orig_node = node;
-	  
-      /* find transactional clone of function */
-      while (node && node->next_clone)
-	{
-	  node = node->next_clone;
-	  if (DECL_IS_GTM_CLONE (node->decl))
-	    break;
-	}
-
-      if (DECL_IS_GTM_CLONE (node->decl))
-	{
-	  struct cgraph_edge *callers = orig_node->callers;
-	      
-	  /* find appropriate call stmt to redirect */
-	  while (callers) 
-	    {
-	      if (callers->call_stmt != stmt) 
-		callers = callers->next_caller;
-	      else break;
-	    }
-	      
-	  /* substitute call stmt. */
-	  if (callers)
-	    {
-	      tree txn_ce;
-	      txn_ce = build_txn_call_expr (ce, node, txn_handle);
 
-	      if (TREE_CODE (stmt) == CALL_EXPR)
-		{
-		  block_stmt_iterator bsi = bsi_for_stmt (stmt);
-		  bsi_insert_before (&bsi, txn_ce, BSI_SAME_STMT);
-		  bsi_remove (&bsi, true);
-		}
-	      else
-		GIMPLE_STMT_OPERAND (stmt, 1) = txn_ce;
-
-	      cgraph_redirect_edge_callee (callers, node); 	      
-	      if (dump_file)
-		fprintf(dump_file, "redirected edge to %s\n", get_name (node->decl));
-	      redirected = true;
-	    }
-	}
-
-      /* Redirect calls to malloc and related functions to transactional versions if available. */
-#ifdef TANGER
-      if ((DECL_FUNCTION_CODE (fn_decl) == BUILT_IN_MALLOC)
-	  ||(DECL_FUNCTION_CODE (fn_decl) == BUILT_IN_CALLOC)
-	  || (DECL_FUNCTION_CODE (fn_decl) == BUILT_IN_REALLOC)
-	  || (DECL_FUNCTION_CODE (fn_decl) == BUILT_IN_FREE))
-	{
-	  tree txn_ce;
-	  tree new_decl; 
-	  if (DECL_FUNCTION_CODE (fn_decl) == BUILT_IN_MALLOC)
-	    new_decl = built_in_decls[BUILT_IN_GTM_MALLOC];
-	  if (DECL_FUNCTION_CODE (fn_decl) == BUILT_IN_CALLOC)
-	    new_decl = built_in_decls[BUILT_IN_GTM_CALLOC];
-	  if (DECL_FUNCTION_CODE (fn_decl) == BUILT_IN_REALLOC)
-	    new_decl = built_in_decls[BUILT_IN_GTM_REALLOC];
-	  if (DECL_FUNCTION_CODE (fn_decl) == BUILT_IN_FREE)
-	    new_decl = built_in_decls[BUILT_IN_GTM_FREE];
-
-	  tree arglist = CALL_EXPR_ARGS (ce);
-
-	  if (txn_handle)
-	    {
-	      arglist = chainon (arglist, build_tree_list (NULL_TREE, txn_handle));
-	    }
-	  txn_ce = build_function_call_expr (new_decl, arglist);
-	  if (DECL_FUNCTION_CODE (fn_decl) != BUILT_IN_FREE)
-	    txn_ce = build_gimple_modify_stmt (GIMPLE_STMT_OPERAND (stmt, 0), txn_ce);
-	   
-	  block_stmt_iterator bsi = bsi_for_stmt (stmt);
-	  bsi_insert_before (&bsi, txn_ce, BSI_SAME_STMT);
-	  bsi_remove (&bsi, true);
-	   	   
-	}
-#endif
-      /* In case the function call was not redirected and the function not marked as const or tm_pure, 
-	 issue a warning. */
-      /* TODO: handling of calls to irrevocable functions can be expanded here. */
-      if ((!redirected) 
-	  && (TREE_READONLY(node->decl) != 1)
-	  && (DECL_IS_GTM_PURE (node->decl) != 1))
-	{
-	  warning (0, "GTM: irrevocable functions not supported. Call to %qs potentially breaks isolation of transactions.", name);
-	  warning (0, "GTM: No transactional clone found for  %qs.", name);
-	}
-    }      
-  return ;
-}
-
-/* This function expands the stmts within a 
-   transaction so that the corresponding STM 
-   versions of the stmt is called. */
 static void
-replace_txn_stmt (block_stmt_iterator *bsi, enum bsi_iterator_update m, tree txn_handle)
+maybe_transactify_call (gimple stmt)
 {
-  tree stmt = bsi_stmt(*bsi);
-
-  /* TODO redirect call to tm clone use get_call_expr_in */
-  tree ce = get_call_expr_in (stmt);
-  if (ce)
-    replace_call_expr_in_txn (ce, stmt, txn_handle);
-
-  switch TREE_CODE (stmt) {
-      
-    case MODIFY_EXPR:
-    case GIMPLE_MODIFY_STMT:
-      replace_txn_mod_stmt (bsi, m, txn_handle);
-      break;
-      
-    case CALL_EXPR:
-      /* already handled above. */
-      break;
-
-    case GTM_ABORT:
-      expand_gtm_abort (bsi, m, txn_handle);
-      break;
-
-    default:
-      break;
-    }
- 
-  return;
-}
-
-/* Mark recover_bb with a GTM-Return marker
-   which is replaced by variables restoring the 
-   previous state during the checkpoint_gtm-pass. */
-static void
-setup_recover_bb (basic_block bb, tree label) 
-{
-  block_stmt_iterator bsi = bsi_start (bb); 
-  tree stmt =  build1 (LABEL_EXPR, void_type_node, label);
-
-  stmt = unshare_expr (stmt);
-  bsi_insert_before (&bsi, stmt, BSI_SAME_STMT);
-  stmt = make_node (GTM_RETURN);
-  stmt = unshare_expr (stmt);
-  bsi_insert_before (&bsi, stmt, BSI_SAME_STMT);
-
-  return ;
-}
-
-/* Helper function that emits a call to STM 
-   run-time indicating the start of a transaction. */
-static void
-setup_begin_bb (basic_block bb, tree txn_handle, tree jmp_buf)
-{
-  tree txn_begin;
-  tree decl;
-  tree read_only = build_int_cst (integer_type_node, 0);
-  block_stmt_iterator bsi = bsi_start (bb); 
-  
-  decl = built_in_decls[BUILT_IN_GTM_TXN_BEGIN];
-
-  if (txn_handle != NULL_TREE)
-    txn_begin = build_call_expr (decl, 3, txn_handle, 
-				 jmp_buf, build_fold_addr_expr (read_only));
-  else 
-    txn_begin = build_call_expr (decl, 2, jmp_buf, 
-				 build_fold_addr_expr (read_only));
-  txn_begin = unshare_expr (txn_begin);
-  bsi_insert_before (&bsi, txn_begin, BSI_SAME_STMT);
-
-  return ;
-}
-
-/* Helper function that emits call to 
-   abort the transaction in an STM-specific way. */
-static void 
-expand_gtm_abort (block_stmt_iterator *bsi, enum bsi_iterator_update m, tree txn_handle)
-{
-  tree decl;
-  tree call;
-
-  decl = built_in_decls [BUILT_IN_GTM_ABORT];
-  if (txn_handle != NULL_TREE)
-    call = build_call_expr (decl, 1, txn_handle);
-  else 
-    call = build_call_expr (decl, 0);
-  call = unshare_expr (call);
-  bsi_insert_before (bsi, call, m);
-  bsi_remove(bsi, true);
-
-  return ;
-}
-
-#ifdef GTM_EXPL_HANDLE
-/* Insert call to stm_init at beginning of function. */
-static tree
-maybe_insert_stm_new (enum bsi_iterator_update m)
-{
-  basic_block bb;
-
-  FOR_EACH_BB (bb) 
-  {
-    int idx = bb->index;
-    /* TODO find a better place to put this call  (works so far) */
-    if (idx == 2) 
-      {
-	/* Avoid redundant calls to stm_new */ 
-	block_stmt_iterator bsi = bsi_start (bb);
-	tree mod = bsi_stmt (bsi);
-	if (TREE_CODE (mod) == GIMPLE_MODIFY_STMT) 
-	  {
-	    tree ce = GIMPLE_STMT_OPERAND (mod, 1);
-	    if (TREE_CODE (ce) == CALL_EXPR) 
-	      {
-		char *name = get_name (get_callee_fndecl (ce));
-#ifdef TINYSTM_VERSION_0_9_0b1
-		if (strncmp (name, "__builtin_stm_new", 17) == 0)
-#endif
-#ifdef TANGER
-		  if (strncmp (name, "__builtin_tanger_stm_get_tx", 27) == 0)
-#endif
-		    {
-		      return GIMPLE_STMT_OPERAND (mod, 0);
-		    }
-	      }
-	  }
-	
-	/* stm_txn_t *tx;
-	   tx = stm_new (); */
-	tree ptr_void = build_pointer_type (void_type_node);
-	tree txn_handle = create_tmp_var (ptr_void, "txn_handle");
-	tree decl = built_in_decls[BUILT_IN_GTM_NEW];
-	tree call = build_call_expr (decl, 0);
-	tree stmt = build_gimple_modify_stmt (txn_handle, call);
-	stmt = unshare_expr (stmt);
-	bsi_insert_before (&bsi, stmt, m);
-	
-	return txn_handle;
-      }
-  }
-  return NULL_TREE;
-}
-#endif
-
-#ifndef TINYSTM_VERSION_0_9_0b1
-/* Helper function to insert call to stm_init_thread. */
-static void
-insert_stm_init_thread (block_stmt_iterator bsi)
-{
-  tree decl = built_in_decls[BUILT_IN_GTM_INIT_THREAD];
-  tree call = build_call_expr (decl, 0);
-  call = unshare_expr (call);
-  bsi_insert_before (&bsi, call, BSI_SAME_STMT);
-}
-	
-/* Insert call to stm_init_thread at beginning of function. */
-static void
-maybe_insert_stm_init_thread (void)
-{
-  basic_block bb;
-
-  FOR_EACH_BB (bb) 
-  {
-    int idx = bb->index;
-    /* TODO find a better place to put this call  (works so far) */
-    if (idx == 2) 
-      {
-	block_stmt_iterator bsi = bsi_start (bb);
-
-	/* Avoid redundant calls to stm_init_thread */ 
-	tree tmp = bsi_stmt (bsi);
-	if (TREE_CODE (tmp) == CALL_EXPR) 
-	  {
-	    char *name = get_name (get_callee_fndecl (tmp));
-#ifdef TINYSTM_VERSION_0_9_5
-	    if (strncmp (name, "__builtin_stm_init_thread", 25) == 0)
-	      return ;
-#endif
-#ifdef TANGER
-	    if (strncmp (name, "__builtin_tanger_stm_thread_init", 32) == 0)
-	      return ;
-#endif
-	  }
-	insert_stm_init_thread (bsi);
-	return ;
-      }
-  }
-  return ;
-}
-
-/* Helper function inserting calls to stm_exit_thread. */
-static void
-insert_stm_exit_thread (block_stmt_iterator bsi, bool after)
-{ 
-  tree decl = built_in_decls[BUILT_IN_GTM_EXIT_THREAD];
-  tree call = build_call_expr (decl, 0);
-  call = unshare_expr (call);
- 
-  if (after)
-    bsi_insert_after (&bsi, call, BSI_SAME_STMT);
-  else
-    bsi_insert_before (&bsi, call, BSI_SAME_STMT);
-  
-  return ;
-}
-
-/* Helper function inserting calls to stm_exit_thread at RET_EXPR. */
-static void
-insert_stm_exit_thread_ret_expr (block_stmt_iterator bsi_last_bb) 
-{
-  bool after = false;
-
-  gcc_assert (!bsi_end_p (bsi_last_bb));
-  tree ret_expr = bsi_stmt (bsi_last_bb);
-
-  gcc_assert (ret_expr);
-
-  if (TREE_CODE (ret_expr) == RETURN_EXPR) 
-    {
-      if  (!bsi_end_p (bsi_last_bb))
-	{
-	  block_stmt_iterator save = bsi_last_bb;
-	  bsi_prev (&bsi_last_bb);
-	  if (! bsi_end_p (bsi_last_bb))
-	    {
-	      after = true;
-	      tree bef_ret = bsi_stmt (bsi_last_bb);
-	      if (TREE_CODE (bef_ret) == CALL_EXPR) 
-		{
-		  char *name = get_name (get_callee_fndecl (bef_ret));
-#ifdef TINYSTM_VERSION_0_9_5
-		  if (strncmp (name, "__builtin_stm_exit_thread", 25) == 0)
-		    return ;
-#endif
-#ifdef TANGER
-		  if (strncmp (name, "__builtin_tanger_stm_thread_exit", 32) == 0)
-		    return ;
-#endif
-		}
-	    }
-	  else 
-	    {
-	      bsi_last_bb = save;
-	      after = false;
-	    }
-	  insert_stm_exit_thread (bsi_last_bb, after);
-	}
-    }
-  else 
-    {
-      gcc_unreachable();
-    }
-  return ;
-}
+  bool redirected = false;
+  tree fn_decl;
+  struct cgraph_node *node, *orig_node;
+  int flags;
 
-/* Insert call to stm_exit_thread at the end of function. */
-static void
-maybe_insert_stm_exit_thread(void) 
-{
-  basic_block last_bb;
-  block_stmt_iterator bsi_last_bb;
-  edge e;
-  edge_iterator ei;
+  flags = gimple_call_flags (stmt);
+  if (flags & ECF_CONST)
+    return;
 
-  FOR_EACH_EDGE (e, ei, EXIT_BLOCK_PTR->preds)
+  fn_decl = gimple_call_fndecl (stmt);
+  if (!fn_decl)
     {
-      last_bb = e->src;
-      bsi_last_bb = bsi_last (last_bb);
-      insert_stm_exit_thread_ret_expr (bsi_last_bb);
+      warning (0, "Indirect call potentially breaks isolation of transactions");
+      return;
     }
-  return ;
-}
-#endif
-
-/* Expand the begin of an transaction to 
-   set up the transaction in an STM-specific way. */
-static tree
-expand_gtm_txn_marker (struct gtm_region *region, block_stmt_iterator *bsi, enum bsi_iterator_update m, basic_block recover_bb, basic_block begin_bb)
-{
-  tree decl;
-  tree txn_handle;
-  tree sigsetjmp, ssjval;
-  tree mask;
-  tree jmp_buf;
-  tree get;
-  tree stmt;
-  tree list;
-  tree recover_label;
-  tree ptr_void = build_pointer_type (void_type_node);
-
-  /* stm_txn_t *tx;
-     tx = stm_new (); */
-#ifdef GTM_EXPL_HANDLE 
-  txn_handle = maybe_insert_stm_new (m);
-#endif
-  /* TODO check if this condition still holds for other STMs. */
-#ifndef TINYSTM_VERSION_0_9_0b1 
-  insert_stm_init_thread(*bsi);
-  txn_handle = NULL_TREE;
-#endif
-
-  /* jmp_buf *e;
-     e = stm_get_env (tx); */
-  jmp_buf = create_tmp_var (ptr_void, "jmp_buf");
-  decl = built_in_decls[BUILT_IN_GTM_GET_ENV];
-  if (txn_handle != NULL_TREE)
-    get = build_call_expr (decl, 1, txn_handle);
-  else 
-    get = build_call_expr (decl, 0);
-  stmt = build_gimple_modify_stmt (jmp_buf, get);
-  stmt = unshare_expr (stmt);
-  bsi_insert_before (bsi, stmt, m);
-  
-  /* CHECK: if sigsetjmp is called with a non-zero
-     argument it saves the signal mask
-     as part of the environment. 
-     Currently the setjmp call is done manually.
-     TODO: Future work would be to use GCC's EH machinery. */
-  ssjval = create_tmp_var (integer_type_node, "ssj_value");
-  mask = build_int_cst (integer_type_node, 0);
-  list = build_function_type_list (integer_type_node, ptr_type_node, NULL_TREE);
-  decl = build_decl (FUNCTION_DECL, get_identifier ("_setjmp"), list);
-  sigsetjmp = build_call_expr (decl, 1, jmp_buf);
-  stmt = build_gimple_modify_stmt (ssjval, sigsetjmp);
-  stmt = unshare_expr (stmt);
-  bsi_insert_before (bsi, stmt, m);
-  region->setjmp_stmt = stmt;
-
-  recover_label = create_artificial_label ();
-
-  stmt = build3 (COND_EXPR, void_type_node, 
-		 fold_build2 (EQ_EXPR, boolean_type_node, ssjval, integer_zero_node), 
-		 NULL_TREE,
-		 NULL_TREE);
-  stmt = unshare_expr (stmt);
-  bsi_insert_after (bsi, stmt, m);
-  
-  setup_recover_bb (recover_bb, recover_label);
-  setup_begin_bb (begin_bb, txn_handle, jmp_buf);  
-
-  return txn_handle;
-}
-
-/* Helper function that emits call to 
-   commit the transaction in an STM-specific way. */
-static void 
-expand_gtm_return (block_stmt_iterator *bsi, enum bsi_iterator_update m, tree txn_handle, bool end_txn)
-{
-  tree decl;
-  tree call;
-  tree stm_commit_retval;
-  tree stmt;
-
-  decl = built_in_decls[BUILT_IN_GTM_TXN_COMMIT];
-  if (txn_handle != NULL_TREE)
-    call = build_call_expr (decl, 1, txn_handle);
-  else 
-    call = build_call_expr (decl, 0);
-
-  stm_commit_retval  = create_tmp_var (integer_type_node, "stm_commit");
-  add_referenced_var (stm_commit_retval);
-
-  stmt = fold_build2 (GIMPLE_MODIFY_STMT, integer_type_node,
-		      stm_commit_retval, call);
-  stmt = unshare_expr (stmt);
-  bsi_insert_before (bsi, stmt, m);
-
-#ifdef  TINYSTM_VERSION_0_9_5 
-  if (end_txn)
-    maybe_insert_stm_exit_thread(); 
-#endif
-
-#ifdef TANGER 
-  if (end_txn)
-    insert_stm_exit_thread(*bsi, true); 
-#endif
+  if (DECL_IS_GTM_PURE (fn_decl))
+    return;
 
-  return ;
-}
+  orig_node = node = cgraph_node (fn_decl);
 
-/* Insert call to stm_init at beginning of main function. */
-static void
-insert_stm_init(void) 
-{
-  /* TODO allow other functions here, since only C has a mandatory "main" entry point. */
-  char *name = get_name (current_function_decl);
-  if ((strncmp(name, "main", 4) != 0)
-      || (strlen(name) > 4))
-    return ;
-
-  basic_block bb;
-
-  FOR_EACH_BB (bb) 
-  {
-    int idx = bb->index;
-    /* TODO find a better place to put this call  (works so far) */
-    if (idx == 2) 
-      {
-	block_stmt_iterator bsi = bsi_start (bb);
-	tree decl;
-	tree call;
-	
-	decl = built_in_decls[BUILT_IN_GTM_INIT];
-	call = build_call_expr (decl, 0);
-	call = unshare_expr (call);
-
-	bsi_insert_before (&bsi, call, BSI_SAME_STMT);
-	return ;
-      }
-  }
-  
-  gcc_unreachable();
-  return ;
-}
-
-/* Insert call to stm_exit at the end of main function. */
-static void
-insert_stm_exit(void) 
-{
-  /* TODO allow other functions here, since only C has a mandatory "main" entry point. */
-  char *name = get_name (current_function_decl);
-  if ((strlen(name) > 4)
-      || (strncmp(name, "main", 4) != 0))
-    return ;
-
-  tree decl;
-  tree call;
-  
-  basic_block last_bb;
-  block_stmt_iterator bsi_last_bb;
-  
-  edge e;
-  edge_iterator ei;
-  
-  FOR_EACH_EDGE (e, ei, EXIT_BLOCK_PTR->preds)
+  /* Find transactional clone of function.  */
+  while (node && node->next_clone)
     {
-      last_bb = e->src;
-      bsi_last_bb = bsi_last (last_bb);
-      gcc_assert (!bsi_end_p (bsi_last_bb));
-      
-      tree tmp = bsi_stmt (bsi_last_bb);  
-      if (TREE_CODE (tmp) == RETURN_EXPR) 
-	{
-	  decl = built_in_decls[BUILT_IN_GTM_EXIT];
-	  call = build_call_expr (decl, 0);
-	  call = unshare_expr (call);
-	  bsi_insert_before (&bsi_last_bb, call, BSI_SAME_STMT);
-	}
-      else 
-	{
-	  gcc_unreachable();
-	}
+      node = node->next_clone;
+      if (DECL_IS_GTM_CLONE (node->decl))
+	break;
     }
-  return ;
-}
-
-/* Initialize global data structures.*/
-void
-init_label_table (void) 
-{
-  unsigned int i;
-
-  label_index = 0;
-  e_index = 0;
-
-  for (i = 0; i < NUM_BB_TXN; i++)
-    edges_to_instrument[i] = NULL;
-
-  return ;
-}
-
-/* Helper function marking all basic blocks 
-   of a transaction. */
-void
-record_bb_into_table (struct gtm_region *region, basic_block bb)
-{
-  if (dump_file)
-    fprintf (dump_file, "Record TXN Basic block %d\n", bb->index);
-  region->txn_bbs[label_index] = bb->index;
-  label_index++;
-  
-  return ;
-}
-
-/* Helper function that checks whether an edge from a 
-   basic block leaves the scope of a transaction. If 
-   it does the edge is marked for instrumentation. */
-void
-check_and_mark_edges (struct gtm_region *region, basic_block bb) 
-{
-  edge_iterator ei;
-  edge e;
-  unsigned int j;
-  basic_block succ;
-  bool found = false;
 
-  FOR_EACH_EDGE (e, ei, bb->succs)
+  if (DECL_IS_GTM_CLONE (node->decl))
     {
-      succ = e->dest;
+      struct cgraph_edge *callers = orig_node->callers;
 
-      for (j = 0; j < label_index; j++)
+      /* Find appropriate call stmt to redirect */
+      while (callers)
 	{
-	  if (region->txn_bbs[j] == succ->index)
-	    {
-	      if (dump_file)
-		fprintf (dump_file, "found BB index %d in TXN\n", succ->index);
-	      found = true;
-	      break;
-	    }
+	  if (callers->call_stmt == stmt)
+	    break;
+	  callers = callers->next_caller;
 	}
-  
-      if ((!found)
-	  && (succ != ENTRY_BLOCK_PTR)
-	  && (succ != EXIT_BLOCK_PTR))
+
+      /* Substitute call stmt. */
+      if (callers)
 	{
+	  gimple_call_set_fndecl (stmt, node->decl);
+	  cgraph_redirect_edge_callee (callers, node);
 	  if (dump_file)
-	    fprintf (dump_file, "Did _NOT_ find BB index %d in TXN\n", succ->index);
-	  
-	  edges_to_instrument[e_index] = e;
-	  e_index++;
+	    fprintf (dump_file, "redirected edge to %s\n",
+		     get_name (node->decl));
+	  redirected = true;
 	}
     }
 
-  return ;
-}
-
-/* Instrument all previously recorded edges with 
-   a call to stm_commit. */
-void 
-instrument_edges (tree txn_handle)
-{
-  unsigned int j;
-  edge e;
-
-  for (j = 0; j < e_index ; j++)
-    {
-      e = edges_to_instrument[j];
-      gcc_assert (e);
-      
-      basic_block stm_commit_bb = split_edge (e);
-      block_stmt_iterator bsi = bsi_start (stm_commit_bb);
-      expand_gtm_return (&bsi, BSI_SAME_STMT, txn_handle, false);
-      gcc_assert (single_succ_edge (stm_commit_bb)->flags = EDGE_FALLTHRU);
-    }
-
-  return ;
+  /* In case the function call was not redirected and the function
+     not marked as const or tm_pure, issue a warning. */
+  /* ??? Handling of calls to irrevocable functions can be expanded here. */
+  if (!redirected)
+    warning (0, "Call to %qD potentially breaks isolation of transactions.",
+	     fn_decl);
 }
 
-/* Instruments a return expression with a call to stm_commit. */
-void
-instrument_return_expr (block_stmt_iterator *bsi, tree txn_handle)
-{
-  tree stmt = bsi_stmt (*bsi);
-
-  if (TREE_CODE (stmt) == RETURN_EXPR)
-    {
-      expand_gtm_return (bsi, BSI_SAME_STMT, txn_handle, false);
-    }
-  
-  return ;
-}
+/* This function expands the stmts within a transaction so that
+   the corresponding STM versions of the stmt is called. */
 
-/* Instruments transactions with calls to the STM runtime. 
-   Inserts new basic blocks at the beginning of the transaction
-   to allow for variable saving and restoring (checkpointing) 
-   on SSA level. */
-static void
-expand_gtm_txn (struct gtm_region *region)
+static void ATTRIBUTE_UNUSED
+transactify_stmt (gimple_stmt_iterator *gsi)
 {
-  basic_block entry_bb, exit_bb, bb;
-  block_stmt_iterator bsi;
-  
-  tree txn;
-  tree txn_handle;
-  
-  entry_bb = region->entry;
-  exit_bb = region->exit;
-
-  gcc_assert (entry_bb);
-  gcc_assert (exit_bb);
-
-  bsi = bsi_last (entry_bb);
-  txn = bsi_stmt (bsi);
-  
-  gcc_assert (TREE_CODE (txn) == GTM_TXN);
-  init_label_table ();
-
-  /* Split basic blocks and make edges: */
-  /* BB with setjmp (entry_bb) -> BBrestore 
-     BB with setjmp (entry_bb) -> BBtxnbegin
-     BBrestore -> BBtxnbegin
-  */
-  basic_block begin_bb = split_edge (single_succ_edge (entry_bb)); 
-  basic_block recover_bb = split_edge (single_succ_edge (entry_bb));
-
-  /* TODO redirect edge instead of destroy/create */
-  /* Content to the basic blocks is added here. */
-  txn_handle = expand_gtm_txn_marker (region, &bsi, BSI_SAME_STMT, recover_bb, begin_bb);
-  bsi_remove (&bsi, true);
-  remove_edge (single_succ_edge (entry_bb));
-  make_edge (entry_bb, recover_bb, EDGE_FALSE_VALUE);
-  make_edge (entry_bb, begin_bb, EDGE_TRUE_VALUE);
-
-  single_succ_edge (begin_bb)->flags = EDGE_FALLTHRU;
-  remove_edge (single_succ_edge (recover_bb));
-  make_edge (recover_bb, begin_bb, EDGE_FALLTHRU);
-
-  gcc_assert (exit_bb->next_bb);
+  gimple stmt = gsi_stmt (*gsi);
 
-  FOR_BB_BETWEEN (bb, begin_bb, exit_bb->next_bb, next_bb)
+  switch (gimple_code (stmt))
     {
-      if (!bb) 
-	continue;
-
-      record_bb_into_table (region, bb);
+    case GIMPLE_CALL:
+      maybe_transactify_call (stmt);
+      break;
 
-      for (bsi = bsi_start (bb); !bsi_end_p (bsi); bsi_next (&bsi))
-	{
-	  instrument_return_expr (&bsi, txn_handle);
-	  replace_txn_stmt (&bsi, BSI_SAME_STMT, txn_handle);
-	}
-    }
-  
-  FOR_BB_BETWEEN (bb, begin_bb, exit_bb, next_bb)
-    {
-      if (!bb) 
-	continue;
+    case GIMPLE_ASSIGN:
+      /* Only memory reads/writes need to be instrumented.  */
+      if (gimple_assign_single_p (stmt))
+	maybe_transactify_assign (stmt);
+      break;
 
-      check_and_mark_edges (region, bb);
+    default:
+      break;
     }
-
-  instrument_edges (txn_handle);
-
-  bsi = bsi_last (exit_bb);
-  gcc_assert (!bsi_end_p (bsi)
-	      && TREE_CODE (bsi_stmt (bsi)) == GTM_RETURN);
-  
-  expand_gtm_return (&bsi, BSI_SAME_STMT, txn_handle, true);
-  bsi_remove (&bsi, true);
-
-  return;
 }
 
-/* Instrument the GTM region tree rooted at REGION.  
-   We start with the inner regions first. */
-/* TODO adjust for nested transactions! */
-static void
-expand_gtm (struct gtm_region *region)
-{
-  while (region)
-    {
-      /* First, expand the inner regions.  */
-      if (region->inner)
-	expand_gtm (region->inner);
-
-      gcc_assert ((region->type) == GTM_TXN);
-      expand_gtm_txn (region);
-      region = region->next;
-    }
-}
+/* Main entry point for expanding GTM-GIMPLE into runtime calls to the STM. */
 
-/* TM function cloning: helper function that helps to 
-   annotate function body of GTM clone. 
-   Transactions from the original version are removed. */
-static void
-annotate_gtm_function_body (void)
-{
-  tree txn_handle;
-  /* By construction txn_handle is last parameter of the
-     argument list of the function. */
-#ifdef GTM_EXPL_HANDLE
-  txn_handle = tree_last (DECL_ARGUMENTS (current_function_decl));
-#endif
- 
-#ifdef TINYSTM_VERSION_0_9_5
-  txn_handle = NULL_TREE;
-#endif
-
-  basic_block bb;
-  block_stmt_iterator bsi;
-  tree stmt;
-
-  FOR_EACH_BB (bb)
-  {
-    for (bsi = bsi_start (bb); !bsi_end_p (bsi); bsi_next (&bsi))
-      {
-	stmt = bsi_stmt (bsi);
-	if (GTM_DIRECTIVE_P (stmt))
-	  {
-	    bsi_remove (&bsi, true);
-	    if (bsi_end_p (bsi)) break;
-	  }
-	else
-	  replace_txn_stmt (&bsi, BSI_SAME_STMT, txn_handle);
-      }
-  }
-}
-
-/* Main entry point for expanding GTM-GIMPLE 
-   into runtime calls to the STM. */
 static unsigned int
 execute_expand_gtm (void)
 {
-  bool flat_nesting;
-  
-  /* In case we have to instrument 
-     a transactional clone. */
+  /* In case we have to instrument a transactional clone. */
   if (DECL_IS_GTM_CLONE (current_function_decl))
     {
       if (!DECL_IS_GTM_PURE (current_function_decl))
-	annotate_gtm_function_body();
-      else 
+	/* annotate_gtm_function_body () */ ;
+      else
 	{
-	  /* Function with  tm_pure attribute specified. */
+#ifdef ENABLE_CHECKING
+	  /* Function with tm_pure attribute specified.  The front-end
+	     should have generated the appropriate errors and dropped
+	     the transaction trees on the floor.  */
+	  calculate_dominance_info (CDI_DOMINATORS);
 	  build_gtm_regions ();
-	  if (root_gtm_region)
-	    {
-	      /* In case a tm_pure function attribute is combined with 
-		 transactions, we end up here. Issue a warning and 
-		 remove GTM markers. Since there is no standard how to 
-		 treat this case, this may have to be changed. */
-	      warning (0, "GTM: ignored %qs used in function %qs declared as %qs.", 
-		       "#pragma tm atomic", 
-		       get_name (current_function_decl), 
-		       "tm_pure");
-	      collapse_gtm_regions (root_gtm_region);
-	      remove_gtm_stmts (root_gtm_region);
-	      free (root_gtm_region);
-	      root_gtm_region = NULL;
-	    }
+	  gcc_assert (root_gtm_region == NULL);
+	  free_dominance_info (CDI_DOMINATORS);
+#endif
 	}
       return 0;
     }
-  
-  build_gtm_regions ();
-  if (!root_gtm_region)
-    {
-      /* The reason for the following calls is that a 
-	 program maybe transactified without using atomic regions 
-	 inside the main-function. Here calls are inserted to ensure 
-	 the proper initialisation of the STM library. */
-      insert_stm_init();
-      insert_stm_exit(); 
-      return 0;
-    }
- 
-  if (dump_file)
-    {
-      fprintf (dump_file, "\nGTM region tree\n\n");
-      dump_gtm_region (dump_file, root_gtm_region, 0);
-      fprintf (dump_file, "\n");
-    }
-
-  flat_nesting = query_STM_for_flat_nesting();
 
-  if (flat_nesting) 
+  calculate_dominance_info (CDI_DOMINATORS);
+  build_gtm_regions ();
+  if (root_gtm_region)
     {
-      collapse_gtm_regions (root_gtm_region);
-
       if (dump_file)
 	{
-	  fprintf (dump_file, "\nGTM region tree after collapsing regions\n\n");
+	  fprintf (dump_file, "\nGTM region tree\n\n");
 	  dump_gtm_region (dump_file, root_gtm_region, 0);
 	  fprintf (dump_file, "\n");
 	}
-    }
-  
-  expand_gtm (root_gtm_region);  /* instrumentation is done here. */
 
-  insert_stm_init();
-  insert_stm_exit(); 
+      /* expand_gtm (root_gtm_region); */
+      cleanup_tree_cfg ();
+    }
 
   free_dominance_info (CDI_DOMINATORS);
-  
-  cleanup_tree_cfg ();
-
   return 0;
 }
 
-/* GTM expansion -- the default pass, 
-   run before creation of SSA form.  */
+/* GTM expansion -- the default pass, run before creation of SSA form.  */
+
 static bool
 gate_expand_gtm (void)
 {
   return flag_gtm;
 }
 
-struct tree_opt_pass pass_expand_gtm = 
-  {
-    "gtmexp",				/* name */
-    gate_expand_gtm,			/* gate */
-    execute_expand_gtm,			/* execute */
-    NULL,				/* sub */
-    NULL,				/* next */
-    0,					/* static_pass_number */
-    0,					/* tv_id */
-    PROP_gimple_any,			/* properties_required */
-    0,			                /* properties_provided */
-    0,					/* properties_destroyed */
-    TODO_dump_func,			/* todo_flags_start */
-    TODO_cleanup_cfg 
-    | TODO_ggc_collect,		        /* todo_flags_finish */
-    0					/* letter */
-  };
+struct gimple_opt_pass pass_expand_gtm =
+{
+ {
+  GIMPLE_PASS,
+  "gtmexp",				/* name */
+  gate_expand_gtm,			/* gate */
+  execute_expand_gtm,			/* execute */
+  NULL,					/* sub */
+  NULL,					/* next */
+  0,					/* static_pass_number */
+  0,					/* tv_id */
+  PROP_gimple_any,			/* properties_required */
+  0,			                /* properties_provided */
+  0,					/* properties_destroyed */
+  0,					/* todo_flags_start */
+  TODO_dump_func
+  | TODO_cleanup_cfg
+  | TODO_ggc_collect,		        /* todo_flags_finish */
+ }
+};
+
 
-/* Calculate live ranges on SSA. Then checkpoint the 
+#if 0
+/* Calculate live ranges on SSA. Then checkpoint the
    live-in variables to the transaction. */
-void
-checkpoint_live_in_variables (struct gtm_region *region, block_stmt_iterator *bsi_recover, basic_block begin_bb) 
+
+static void
+checkpoint_live_in_variables (struct gtm_region *region,
+			      gimple_stmt_iterator *gsi_recover,
+			      basic_block begin_bb)
 {
   int index = begin_bb->index;
   block_stmt_iterator bsi_save = bsi_for_stmt (region->setjmp_stmt);
@@ -1759,7 +454,7 @@ checkpoint_live_in_variables (struct gtm
   int p;
   tree rep;
   unsigned int i;
-  unsigned int j; 
+  unsigned int j;
   bitmap_iterator bi;
 
   map = init_var_map (num_ssa_names + 1);
@@ -1768,10 +463,10 @@ checkpoint_live_in_variables (struct gtm
   for (j = 0; j < num_ssa_names; j++)
     {
       ssa_var = ssa_name (j);
-      if (!ssa_var) 
+      if (!ssa_var)
 	continue;
 
-      if (TREE_CODE (ssa_var) == SSA_NAME) 
+      if (TREE_CODE (ssa_var) == SSA_NAME)
 	{
 	  register_ssa_partition (map, ssa_var);
 	  p = partition_find (map->var_partition, SSA_NAME_VERSION (ssa_var));
@@ -1782,7 +477,7 @@ checkpoint_live_in_variables (struct gtm
 
   liveinfo = calculate_live_ranges (map);
 
-  /* If variable is live-in at beginning of the 
+  /* If variable is live-in at beginning of the
      transaction checkpoint its value. */
   if (liveinfo->livein)
     {
@@ -1792,20 +487,20 @@ checkpoint_live_in_variables (struct gtm
       EXECUTE_IF_SET_IN_BITMAP (liveinfo->livein[index], 0, i, bi)
 	{
 	  tree var =  partition_to_var (map, i);
-	  
-	  /* TODO check restricts the use of temporaries by the compiler 
+
+	  /* TODO check restricts the use of temporaries by the compiler
 	     may impact other optimisations.
-	     Maybe reordering this part of the checkpointing before introducing 
+	     Maybe reordering this part of the checkpointing before introducing
 	     temporary variables would avoid this check. */
 	  if ((!DECL_ARTIFICIAL (SSA_NAME_VAR (var)))
-	      && (!POINTER_TYPE_P (TREE_TYPE (var)))) 
+	      && (!POINTER_TYPE_P (TREE_TYPE (var))))
 	    {
-	      if (dump_file) 
+	      if (dump_file)
 		{
 		  print_generic_expr (dump_file, var, TDF_SLIM);
 		  fprintf (dump_file, "  ");
 		}
-	      /* Create name for temporary variable 
+	      /* Create name for temporary variable
 		 that checkpoints value of var. */
 	      const char* orig = get_name (SSA_NAME_VAR (var));
 	      int len = strlen (orig);
@@ -1813,13 +508,13 @@ checkpoint_live_in_variables (struct gtm
 	      strncpy (name, "txn_save_", 9);
 	      strncpy (name + 9, orig, len);
 	      *(name + len + 9) = '\0';
-	      
+
 	      /* Create temporary. */
 	      tree type = TREE_TYPE (var);
 	      tree save = create_tmp_var (type, name);
 	      add_referenced_var (save);
 	      tree stmt;
-    	      
+
 	      /* Create gimple statement for saving value of var. */
 	      stmt = fold_build2 (GIMPLE_MODIFY_STMT, type, save, var);
 	      tree real_save = make_ssa_name (save, stmt);
@@ -1839,7 +534,7 @@ checkpoint_live_in_variables (struct gtm
 	      add_phi_arg (phi, new_var, FALLTHRU_EDGE (recover_bb));
 	      add_phi_arg (phi, var, FALLTHRU_EDGE (save_bb));
 	      tree new_var_phi = PHI_RESULT (phi);
-	      
+
 	      free_dominance_info (CDI_DOMINATORS);
 	      calculate_dominance_info (CDI_DOMINATORS);
 
@@ -1862,26 +557,26 @@ checkpoint_live_in_variables (struct gtm
 	}
       if (dump_file)
 	fprintf (dump_file, "\n");
-      
+
     }
   update_ssa(TODO_update_ssa);
 
   return ;
 }
 
-/* Implements the checkpointing of transactions. */ 
-static void 
+/* Implements the checkpointing of transactions. */
+static void
 checkpoint_gtm_txn (struct gtm_region *region)
 {
   basic_block entry_bb = bb_for_stmt (region->setjmp_stmt);
 
   edge branch = BRANCH_EDGE (entry_bb);
   edge fall = FALLTHRU_EDGE (entry_bb);
-  
+
   basic_block begin_bb = fall->dest;
   basic_block recover_bb = branch->dest;
   basic_block next_bb = single_succ (recover_bb);
-  
+
   gcc_assert(begin_bb == next_bb);
   block_stmt_iterator bsi_recover = bsi_start (recover_bb);
   gcc_assert (TREE_CODE (bsi_stmt (bsi_recover)) == LABEL_EXPR);
@@ -1889,13 +584,11 @@ checkpoint_gtm_txn (struct gtm_region *r
   bsi_next (&bsi_recover);
   gcc_assert (TREE_CODE (bsi_stmt (bsi_recover)) == GTM_RETURN);
 
-  checkpoint_live_in_variables (region, &bsi_recover, begin_bb); 
-  /* Remove the previously set GTM_RETURN markers 
-     from the recover basic block. */ 
-  bsi_remove (&bsi_recover, true);  
-
-  return ;
-}	
+  checkpoint_live_in_variables (region, &bsi_recover, begin_bb);
+  /* Remove the previously set GTM_RETURN markers
+     from the recover basic block. */
+  bsi_remove (&bsi_recover, true);
+}
 
 /* Walk the region tree and start checkpointing. */
 static void
@@ -1904,7 +597,7 @@ checkpoint_gtm (struct gtm_region *regio
   while (region)
     {
       /* First, introduce checkpoints for the inner regions.
-	 TODO: testing. Overlapping of inner and outer 
+	 TODO: testing. Overlapping of inner and outer
 	 regions not handled correctly.
 	 Nesting of transactions not implemented correctly.*/
       if (region->inner)
@@ -1914,7 +607,7 @@ checkpoint_gtm (struct gtm_region *regio
       gcc_assert ((region->type) == GTM_TXN);
 
       checkpoint_gtm_txn (region);
-     
+
       region = region->next;
     }
 }
@@ -1925,11 +618,11 @@ execute_checkpoint_gtm (void)
 {
   /* Regions are built during GTM expansion pass. */
   if (!root_gtm_region)
-    return ;
-  
+    return;
+
   /* Checkpointing is done here. */
-  checkpoint_gtm (root_gtm_region);  
-  
+  checkpoint_gtm (root_gtm_region);
+
   if (dump_file)
     {
       fprintf (dump_file, "\nGTM region tree after checkpointing\n\n");
@@ -1940,7 +633,7 @@ execute_checkpoint_gtm (void)
   free_dominance_info (CDI_DOMINATORS);
   cleanup_tree_cfg ();
   free_gtm_regions ();
-  
+
   return;
 }
 
@@ -1951,25 +644,22 @@ gate_checkpoint_gtm (void)
   return flag_gtm;
 }
 
-struct tree_opt_pass pass_checkpoint_gtm = 
-  {
-    "gtmcheckpoint",			/* name */
-    gate_checkpoint_gtm,		/* gate */
-    execute_checkpoint_gtm,		/* execute */
-    NULL,				/* sub */
-    NULL,				/* next */
-    0,					/* static_pass_number */
-    0,					/* tv_id */
-    PROP_ssa | PROP_cfg,		/* properties_required */
-    0,			                /* properties_provided */
-    0,					/* properties_destroyed */
-    0,					/* todo_flags_start */
-    TODO_update_ssa |
-    TODO_verify_ssa |  
-    TODO_dump_func,			/* todo_flags_finish */
-    0					/* letter */
-  };
-
-
-
-
+struct tree_opt_pass pass_checkpoint_gtm =
+{
+  "gtmcheckpoint",			/* name */
+  gate_checkpoint_gtm,		/* gate */
+  execute_checkpoint_gtm,		/* execute */
+  NULL,				/* sub */
+  NULL,				/* next */
+  0,					/* static_pass_number */
+  0,					/* tv_id */
+  PROP_ssa | PROP_cfg,		/* properties_required */
+  0,			                /* properties_provided */
+  0,					/* properties_destroyed */
+  0,					/* todo_flags_start */
+  TODO_update_ssa |
+  TODO_verify_ssa |
+  TODO_dump_func,			/* todo_flags_finish */
+  0					/* letter */
+};
+#endif
--- omp-low.c	(revision 141060)
+++ omp-low.c	(local)
@@ -1622,7 +1622,7 @@ scan_omp_parallel (gimple_stmt_iterator 
   /* Ignore parallel directives with empty bodies, unless there
      are copyin clauses.  */
   if (optimize > 0
-      && empty_body_p (gimple_omp_body (stmt))
+      && empty_body_p (gimple_seq_body (stmt))
       && find_omp_clause (gimple_omp_parallel_clauses (stmt),
 			  OMP_CLAUSE_COPYIN) == NULL)
     {
@@ -1643,7 +1643,7 @@ scan_omp_parallel (gimple_stmt_iterator 
   gimple_omp_parallel_set_child_fn (stmt, ctx->cb.dst_fn);
 
   scan_sharing_clauses (gimple_omp_parallel_clauses (stmt), ctx);
-  scan_omp (gimple_omp_body (stmt), ctx);
+  scan_omp (gimple_seq_body (stmt), ctx);
 
   if (TYPE_FIELDS (ctx->record_type) == NULL)
     ctx->record_type = ctx->receiver_decl = NULL;
@@ -1665,7 +1665,7 @@ scan_omp_task (gimple_stmt_iterator *gsi
 
   /* Ignore task directives with empty bodies.  */
   if (optimize > 0
-      && empty_body_p (gimple_omp_body (stmt)))
+      && empty_body_p (gimple_seq_body (stmt)))
     {
       gsi_replace (gsi, gimple_build_nop (), false);
       return;
@@ -1693,7 +1693,7 @@ scan_omp_task (gimple_stmt_iterator *gsi
       create_omp_child_function (ctx, true);
     }
 
-  scan_omp (gimple_omp_body (stmt), ctx);
+  scan_omp (gimple_seq_body (stmt), ctx);
 
   if (TYPE_FIELDS (ctx->record_type) == NULL)
     {
@@ -1754,7 +1754,7 @@ scan_omp_for (gimple stmt, omp_context *
       scan_omp_op (gimple_omp_for_final_ptr (stmt, i), ctx);
       scan_omp_op (gimple_omp_for_incr_ptr (stmt, i), ctx);
     }
-  scan_omp (gimple_omp_body (stmt), ctx);
+  scan_omp (gimple_seq_body (stmt), ctx);
 }
 
 /* Scan an OpenMP sections directive.  */
@@ -1766,7 +1766,7 @@ scan_omp_sections (gimple stmt, omp_cont
 
   ctx = new_omp_context (stmt, outer_ctx);
   scan_sharing_clauses (gimple_omp_sections_clauses (stmt), ctx);
-  scan_omp (gimple_omp_body (stmt), ctx);
+  scan_omp (gimple_seq_body (stmt), ctx);
 }
 
 /* Scan an OpenMP single directive.  */
@@ -1785,7 +1785,7 @@ scan_omp_single (gimple stmt, omp_contex
   TYPE_NAME (ctx->record_type) = name;
 
   scan_sharing_clauses (gimple_omp_single_clauses (stmt), ctx);
-  scan_omp (gimple_omp_body (stmt), ctx);
+  scan_omp (gimple_seq_body (stmt), ctx);
 
   if (TYPE_FIELDS (ctx->record_type) == NULL)
     ctx->record_type = NULL;
@@ -1981,7 +1981,7 @@ scan_omp_1_stmt (gimple_stmt_iterator *g
     case GIMPLE_OMP_ORDERED:
     case GIMPLE_OMP_CRITICAL:
       ctx = new_omp_context (stmt, ctx);
-      scan_omp (gimple_omp_body (stmt), ctx);
+      scan_omp (gimple_seq_body (stmt), ctx);
       break;
 
     case GIMPLE_BIND:
@@ -5419,11 +5419,11 @@ lower_omp_sections (gimple_stmt_iterator
   lower_rec_input_clauses (gimple_omp_sections_clauses (stmt),
       			   &ilist, &dlist, ctx);
 
-  tgsi = gsi_start (gimple_omp_body (stmt));
+  tgsi = gsi_start (gimple_seq_body (stmt));
   for (len = 0; !gsi_end_p (tgsi); len++, gsi_next (&tgsi))
     continue;
 
-  tgsi = gsi_start (gimple_omp_body (stmt));
+  tgsi = gsi_start (gimple_seq_body (stmt));
   body = NULL;
   for (i = 0; i < len; i++, gsi_next (&tgsi))
     {
@@ -5436,9 +5436,9 @@ lower_omp_sections (gimple_stmt_iterator
 
       gimple_seq_add_stmt (&body, sec_start);
 
-      lower_omp (gimple_omp_body (sec_start), sctx);
-      gimple_seq_add_seq (&body, gimple_omp_body (sec_start));
-      gimple_omp_set_body (sec_start, NULL);
+      lower_omp (gimple_seq_body (sec_start), sctx);
+      gimple_seq_add_seq (&body, gimple_seq_body (sec_start));
+      gimple_seq_set_body (sec_start, NULL);
 
       if (i == len - 1)
 	{
@@ -5489,7 +5489,7 @@ lower_omp_sections (gimple_stmt_iterator
   gimple_seq_add_stmt (&new_body, t);
 
   gimple_bind_set_body (new_stmt, new_body);
-  gimple_omp_set_body (stmt, NULL);
+  gimple_seq_set_body (stmt, NULL);
 
   gsi_replace (gsi_p, new_stmt, true);
 }
@@ -5525,7 +5525,7 @@ lower_omp_single_simple (gimple single_s
 			    tlabel, flabel);
   gimple_seq_add_stmt (pre_p, cond);
   gimple_seq_add_stmt (pre_p, gimple_build_label (tlabel));
-  gimple_seq_add_seq (pre_p, gimple_omp_body (single_stmt));
+  gimple_seq_add_seq (pre_p, gimple_seq_body (single_stmt));
   gimple_seq_add_stmt (pre_p, gimple_build_label (flabel));
 }
 
@@ -5586,7 +5586,7 @@ lower_omp_single_copy (gimple single_stm
 
   gimple_seq_add_stmt (pre_p, gimple_build_label (l0));
 
-  gimple_seq_add_seq (pre_p, gimple_omp_body (single_stmt));
+  gimple_seq_add_seq (pre_p, gimple_seq_body (single_stmt));
 
   copyin_seq = NULL;
   lower_copyprivate_clauses (gimple_omp_single_clauses (single_stmt), pre_p,
@@ -5622,7 +5622,7 @@ lower_omp_single (gimple_stmt_iterator *
   bind_body = NULL;
   lower_rec_input_clauses (gimple_omp_single_clauses (single_stmt),
 			   &bind_body, &dlist, ctx);
-  lower_omp (gimple_omp_body (single_stmt), ctx);
+  lower_omp (gimple_seq_body (single_stmt), ctx);
 
   gimple_seq_add_stmt (&bind_body, single_stmt);
 
@@ -5631,7 +5631,7 @@ lower_omp_single (gimple_stmt_iterator *
   else
     lower_omp_single_simple (single_stmt, &bind_body);
 
-  gimple_omp_set_body (single_stmt, NULL);
+  gimple_seq_set_body (single_stmt, NULL);
 
   gimple_seq_add_seq (&bind_body, dlist);
 
@@ -5678,10 +5678,10 @@ lower_omp_master (gimple_stmt_iterator *
   gimplify_and_add (x, &tseq);
   gimple_bind_add_seq (bind, tseq);
 
-  lower_omp (gimple_omp_body (stmt), ctx);
-  gimple_omp_set_body (stmt, maybe_catch_exception (gimple_omp_body (stmt)));
-  gimple_bind_add_seq (bind, gimple_omp_body (stmt));
-  gimple_omp_set_body (stmt, NULL);
+  lower_omp (gimple_seq_body (stmt), ctx);
+  gimple_seq_set_body (stmt, maybe_catch_exception (gimple_seq_body (stmt)));
+  gimple_bind_add_seq (bind, gimple_seq_body (stmt));
+  gimple_seq_set_body (stmt, NULL);
 
   gimple_bind_add_stmt (bind, gimple_build_label (lab));
 
@@ -5713,10 +5713,10 @@ lower_omp_ordered (gimple_stmt_iterator 
   x = gimple_build_call (built_in_decls[BUILT_IN_GOMP_ORDERED_START], 0);
   gimple_bind_add_stmt (bind, x);
 
-  lower_omp (gimple_omp_body (stmt), ctx);
-  gimple_omp_set_body (stmt, maybe_catch_exception (gimple_omp_body (stmt)));
-  gimple_bind_add_seq (bind, gimple_omp_body (stmt));
-  gimple_omp_set_body (stmt, NULL);
+  lower_omp (gimple_seq_body (stmt), ctx);
+  gimple_seq_set_body (stmt, maybe_catch_exception (gimple_seq_body (stmt)));
+  gimple_bind_add_seq (bind, gimple_seq_body (stmt));
+  gimple_seq_set_body (stmt, NULL);
 
   x = gimple_build_call (built_in_decls[BUILT_IN_GOMP_ORDERED_END], 0);
   gimple_bind_add_stmt (bind, x);
@@ -5805,10 +5805,10 @@ lower_omp_critical (gimple_stmt_iterator
   gimplify_and_add (lock, &tbody);
   gimple_bind_set_body (bind, tbody);
 
-  lower_omp (gimple_omp_body (stmt), ctx);
-  gimple_omp_set_body (stmt, maybe_catch_exception (gimple_omp_body (stmt)));
-  gimple_bind_add_seq (bind, gimple_omp_body (stmt));
-  gimple_omp_set_body (stmt, NULL);
+  lower_omp (gimple_seq_body (stmt), ctx);
+  gimple_seq_set_body (stmt, maybe_catch_exception (gimple_seq_body (stmt)));
+  gimple_bind_add_seq (bind, gimple_seq_body (stmt));
+  gimple_seq_set_body (stmt, NULL);
 
   tbody = gimple_bind_body (bind);
   gimplify_and_add (unlock, &tbody);
@@ -5888,14 +5888,14 @@ lower_omp_for (gimple_stmt_iterator *gsi
   push_gimplify_context (&gctx);
 
   lower_omp (gimple_omp_for_pre_body (stmt), ctx);
-  lower_omp (gimple_omp_body (stmt), ctx);
+  lower_omp (gimple_seq_body (stmt), ctx);
 
   block = make_node (BLOCK);
   new_stmt = gimple_build_bind (NULL, NULL, block);
 
   /* Move declaration of temporaries in the loop body before we make
      it go away.  */
-  omp_for_body = gimple_omp_body (stmt);
+  omp_for_body = gimple_seq_body (stmt);
   if (!gimple_seq_empty_p (omp_for_body)
       && gimple_code (gimple_seq_first_stmt (omp_for_body)) == GIMPLE_BIND)
     {
@@ -5938,7 +5938,7 @@ lower_omp_for (gimple_stmt_iterator *gsi
   lower_omp_for_lastprivate (&fd, &body, &dlist, ctx);
 
   gimple_seq_add_stmt (&body, stmt);
-  gimple_seq_add_seq (&body, gimple_omp_body (stmt));
+  gimple_seq_add_seq (&body, gimple_seq_body (stmt));
 
   gimple_seq_add_stmt (&body, gimple_build_omp_continue (fd.loop.v,
 							 fd.loop.v));
@@ -5960,7 +5960,7 @@ lower_omp_for (gimple_stmt_iterator *gsi
     TREE_USED (block) = 1;
 
   gimple_bind_set_body (new_stmt, body);
-  gimple_omp_set_body (stmt, NULL);
+  gimple_seq_set_body (stmt, NULL);
   gimple_omp_for_set_pre_body (stmt, NULL);
   gsi_replace (gsi_p, new_stmt, true);
 }
@@ -6288,7 +6288,7 @@ lower_omp_taskreg (gimple_stmt_iterator 
   struct gimplify_ctx gctx;
 
   clauses = gimple_omp_taskreg_clauses (stmt);
-  par_bind = gimple_seq_first_stmt (gimple_omp_body (stmt));
+  par_bind = gimple_seq_first_stmt (gimple_seq_body (stmt));
   par_body = gimple_bind_body (par_bind);
   child_fn = ctx->cb.dst_fn;
   if (gimple_code (stmt) == GIMPLE_OMP_PARALLEL
@@ -6335,7 +6335,7 @@ lower_omp_taskreg (gimple_stmt_iterator 
   lower_send_shared_vars (&ilist, &olist, ctx);
 
   /* Once all the expansions are done, sequence all the different
-     fragments inside gimple_omp_body.  */
+     fragments inside gimple_seq_body.  */
 
   new_body = NULL;
 
@@ -6353,7 +6353,7 @@ lower_omp_taskreg (gimple_stmt_iterator 
   gimple_seq_add_seq (&new_body, par_olist);
   new_body = maybe_catch_exception (new_body);
   gimple_seq_add_stmt (&new_body, gimple_build_omp_return (false));
-  gimple_omp_set_body (stmt, new_body);
+  gimple_seq_set_body (stmt, new_body);
 
   bind = gimple_build_bind (NULL, NULL, gimple_bind_block (par_bind));
   gimple_bind_add_stmt (bind, stmt);
@@ -6369,38 +6369,6 @@ lower_omp_taskreg (gimple_stmt_iterator 
   pop_gimplify_context (NULL);
 }
 
-/* Simply introduces a new stmt_list (needed by gimple-low.c).
-   Further add the GTM_RETURN at the end of the TXN.
-   TODO: check for omp constructs in txn! */
-
-static void
-lower_gtm_txn (tree *stmt_p, omp_context *ctx)
-{
-  tree txn_body, txn_bind;
-  tree new_body, t;
-  tree stmt;
-
-  stmt = *stmt_p;
-
-  push_gimplify_context ();
-
-  txn_bind  = GTM_TXN_BODY (stmt);
-
-  txn_body =  BIND_EXPR_BODY (txn_bind);
-  lower_omp (&txn_body, ctx);
-
-  new_body = alloc_stmt_list ();
-
-  append_to_statement_list (txn_bind, &new_body);
-
-  t = make_node (GTM_RETURN);
-  append_to_statement_list (t, &new_body);
-  GTM_TXN_BODY (stmt) = new_body;
-  *stmt_p = stmt;
-
-  pop_gimplify_context (NULL_TREE);
-}
-
 /* Callback for lower_omp_1.  Return non-NULL if *tp needs to be
    regimplified.  If DATA is non-NULL, lower_omp_1 is outside
    of OpenMP context, but with task_shared_vars set.  */
@@ -6684,7 +6652,7 @@ diagnose_sb_1 (gimple_stmt_iterator *gsi
       /* The minimal context here is just the current OMP construct.  */
       inner_context = stmt;
       wi->info = inner_context;
-      walk_gimple_seq (gimple_omp_body (stmt), diagnose_sb_1, NULL, wi);
+      walk_gimple_seq (gimple_seq_body (stmt), diagnose_sb_1, NULL, wi);
       wi->info = context;
       break;
 
@@ -6695,7 +6663,7 @@ diagnose_sb_1 (gimple_stmt_iterator *gsi
 	 walk them.  */
       walk_gimple_seq (gimple_omp_for_pre_body (stmt),
 	  	       diagnose_sb_1, NULL, wi);
-      walk_gimple_seq (gimple_omp_body (stmt), diagnose_sb_1, NULL, wi);
+      walk_gimple_seq (gimple_seq_body (stmt), diagnose_sb_1, NULL, wi);
       wi->info = context;
       break;
 
@@ -6704,10 +6672,6 @@ diagnose_sb_1 (gimple_stmt_iterator *gsi
 			 (splay_tree_value) context);
       break;
 
-    case GTM_TXN:
-      lower_gtm_txn (tp, ctx);
-      break;
-
     default:
       break;
     }
@@ -6741,7 +6705,7 @@ diagnose_sb_2 (gimple_stmt_iterator *gsi
     case GIMPLE_OMP_ORDERED:
     case GIMPLE_OMP_CRITICAL:
       wi->info = stmt;
-      walk_gimple_seq (gimple_omp_body (stmt), diagnose_sb_2, NULL, wi);
+      walk_gimple_seq (gimple_seq_body (stmt), diagnose_sb_2, NULL, wi);
       wi->info = context;
       break;
 
@@ -6751,7 +6715,7 @@ diagnose_sb_2 (gimple_stmt_iterator *gsi
 	 walk them.  */
       walk_gimple_seq (gimple_omp_for_pre_body (stmt),
 	  	       diagnose_sb_2, NULL, wi);
-      walk_gimple_seq (gimple_omp_body (stmt), diagnose_sb_2, NULL, wi);
+      walk_gimple_seq (gimple_seq_body (stmt), diagnose_sb_2, NULL, wi);
       wi->info = context;
       break;
 
--- passes.c	(revision 141060)
+++ passes.c	(local)
@@ -552,7 +552,7 @@ init_optimization_passes (void)
 	{
 	  struct opt_pass **p = &pass_all_early_optimizations.pass.sub;
 	  NEXT_PASS (pass_rebuild_cgraph_edges);
-	  NEXT_PASS (pass_checkpoint_gtm);
+	  /* NEXT_PASS (pass_checkpoint_gtm); */
 	  NEXT_PASS (pass_early_inline);
 	  NEXT_PASS (pass_rename_ssa_copies);
 	  NEXT_PASS (pass_ccp);
--- tree-cfg.c	(revision 141060)
+++ tree-cfg.c	(local)
@@ -614,7 +614,7 @@ make_edges (void)
 	      break;
 
 	    case GIMPLE_GTM_TXN:
-	      cur_gtm_region = new_gtm_region (bb, code, cur_gtm_region);
+	      cur_gtm_region = new_gtm_region (bb, cur_gtm_region);
 	      fallthru = true;
 	      break;
 
@@ -1993,7 +1993,7 @@ remove_useless_stmts_1 (gimple_stmt_iter
         case GIMPLE_OMP_SECTIONS:
         case GIMPLE_OMP_SINGLE:
           {
-            gimple_seq body_seq = gimple_omp_body (stmt);
+            gimple_seq body_seq = gimple_seq_body (stmt);
             gimple_stmt_iterator body_gsi = gsi_start (body_seq);
 
             remove_useless_stmts_1 (&body_gsi, data);
@@ -2007,7 +2007,7 @@ remove_useless_stmts_1 (gimple_stmt_iter
           {
 	    /* Make sure the outermost GIMPLE_BIND isn't removed
 	       as useless.  */
-            gimple_seq body_seq = gimple_omp_body (stmt);
+            gimple_seq body_seq = gimple_seq_body (stmt);
             gimple bind = gimple_seq_first_stmt (body_seq);
             gimple_seq bind_seq = gimple_bind_body (bind);
             gimple_stmt_iterator bind_gsi = gsi_start (bind_seq);
@@ -2586,7 +2586,7 @@ is_ctrl_altering_stmt (gimple t)
     return true;
 
   /* GTM directives alter control flow.  */
-  if (GTM_DIRECTIVE_P (t))
+  if (is_gimple_gtm (t))
     return true;
 
   /* If a statement can throw, it alters control flow.  */
@@ -5599,7 +5599,7 @@ move_stmt_r (gimple_stmt_iterator *gsi_p
       p->remap_decls_p = false;
       *handled_ops_p = true;
 
-      walk_gimple_seq (gimple_omp_body (stmt), move_stmt_r, move_stmt_op, wi);
+      walk_gimple_seq (gimple_seq_body (stmt), move_stmt_r, move_stmt_op, wi);
 
       p->remap_decls_p = save_remap_decls_p;
     }
--- tree-flow.h	(revision 141060)
+++ tree-flow.h	(local)
@@ -675,10 +675,7 @@ extern tree find_omp_clause (tree, enum 
 tree copy_var_decl (tree, tree, tree);
 
 
-/* GTM region information.
-   Concept and parts of the implementation
-   borrowed from OpenMP implementation. */
-#define NUM_BB_TXN 512
+/* GTM region information.  */
 
 struct gtm_region
 {
@@ -697,20 +694,13 @@ struct gtm_region
   /* Block containing the GTM_RETURN as its last stmt.  */
   basic_block exit;
 
-  /* Since the blocks change this is the stmt containing the setjmp after expansion.  */
-  tree setjmp_stmt;
-
-  /* Contains the bb indexes belonging to the transaction.
-     TODO allocate int array dynamically. */
-  int txn_bbs [NUM_BB_TXN];
-
-  enum tree_code type;
+  /* Since the blocks change this is the stmt containing the setjmp
+     after expansion.  */
+  gimple setjmp_stmt;
 };
 
-
 extern struct gtm_region *root_gtm_region;
-extern struct gtm_region *new_gtm_region (basic_block, enum tree_code,
-                                          struct gtm_region *);
+extern struct gtm_region *new_gtm_region (basic_block, struct gtm_region *);
 extern void free_gtm_regions (void);
 
 /*---------------------------------------------------------------------------
--- tree-inline.c	(revision 141060)
+++ tree-inline.c	(local)
@@ -1094,7 +1094,7 @@ remap_gimple_stmt (gimple stmt, copy_bod
 	  break;
 
 	case GIMPLE_OMP_PARALLEL:
-	  s1 = remap_gimple_seq (gimple_omp_body (stmt), id);
+	  s1 = remap_gimple_seq (gimple_seq_body (stmt), id);
 	  copy = gimple_build_omp_parallel
 	           (s1,
 		    gimple_omp_parallel_clauses (stmt),
@@ -1103,7 +1103,7 @@ remap_gimple_stmt (gimple stmt, copy_bod
 	  break;
 
 	case GIMPLE_OMP_TASK:
-	  s1 = remap_gimple_seq (gimple_omp_body (stmt), id);
+	  s1 = remap_gimple_seq (gimple_seq_body (stmt), id);
 	  copy = gimple_build_omp_task
 	           (s1,
 		    gimple_omp_task_clauses (stmt),
@@ -1115,7 +1115,7 @@ remap_gimple_stmt (gimple stmt, copy_bod
 	  break;
 
 	case GIMPLE_OMP_FOR:
-	  s1 = remap_gimple_seq (gimple_omp_body (stmt), id);
+	  s1 = remap_gimple_seq (gimple_seq_body (stmt), id);
 	  s2 = remap_gimple_seq (gimple_omp_for_pre_body (stmt), id);
 	  copy = gimple_build_omp_for (s1, gimple_omp_for_clauses (stmt),
 				       gimple_omp_for_collapse (stmt), s2);
@@ -1138,34 +1138,34 @@ remap_gimple_stmt (gimple stmt, copy_bod
 	  break;
 
 	case GIMPLE_OMP_MASTER:
-	  s1 = remap_gimple_seq (gimple_omp_body (stmt), id);
+	  s1 = remap_gimple_seq (gimple_seq_body (stmt), id);
 	  copy = gimple_build_omp_master (s1);
 	  break;
 
 	case GIMPLE_OMP_ORDERED:
-	  s1 = remap_gimple_seq (gimple_omp_body (stmt), id);
+	  s1 = remap_gimple_seq (gimple_seq_body (stmt), id);
 	  copy = gimple_build_omp_ordered (s1);
 	  break;
 
 	case GIMPLE_OMP_SECTION:
-	  s1 = remap_gimple_seq (gimple_omp_body (stmt), id);
+	  s1 = remap_gimple_seq (gimple_seq_body (stmt), id);
 	  copy = gimple_build_omp_section (s1);
 	  break;
 
 	case GIMPLE_OMP_SECTIONS:
-	  s1 = remap_gimple_seq (gimple_omp_body (stmt), id);
+	  s1 = remap_gimple_seq (gimple_seq_body (stmt), id);
 	  copy = gimple_build_omp_sections
 	           (s1, gimple_omp_sections_clauses (stmt));
 	  break;
 
 	case GIMPLE_OMP_SINGLE:
-	  s1 = remap_gimple_seq (gimple_omp_body (stmt), id);
+	  s1 = remap_gimple_seq (gimple_seq_body (stmt), id);
 	  copy = gimple_build_omp_single
 	           (s1, gimple_omp_single_clauses (stmt));
 	  break;
 
 	case GIMPLE_OMP_CRITICAL:
-	  s1 = remap_gimple_seq (gimple_omp_body (stmt), id);
+	  s1 = remap_gimple_seq (gimple_seq_body (stmt), id);
 	  copy
 	    = gimple_build_omp_critical (s1, gimple_omp_critical_name (stmt));
 	  break;
@@ -2958,7 +2958,7 @@ estimate_num_insns (gimple stmt, eni_wei
 
     case GIMPLE_OMP_FOR:
       return (weights->omp_cost
-              + estimate_num_insns_seq (gimple_omp_body (stmt), weights)
+              + estimate_num_insns_seq (gimple_seq_body (stmt), weights)
               + estimate_num_insns_seq (gimple_omp_for_pre_body (stmt), weights));
 
     case GIMPLE_OMP_PARALLEL:
@@ -2970,17 +2970,17 @@ estimate_num_insns (gimple stmt, eni_wei
     case GIMPLE_OMP_SECTIONS:
     case GIMPLE_OMP_SINGLE:
       return (weights->omp_cost
-              + estimate_num_insns_seq (gimple_omp_body (stmt), weights));
+              + estimate_num_insns_seq (gimple_seq_body (stmt), weights));
 
     /* These GTM directives are cheap enough.  */
-    case GTM_RETURN:
-    case GTM_ABORT:
+    case GIMPLE_GTM_RETURN:
+    case GIMPLE_GTM_ABORT:
       return 0;
 
     /* The entire transaction, however, is expensive.  */
-    case GTM_TXN:
+    case GIMPLE_GTM_TXN:
       return (weights->gtm_txn_cost
-	      + estimate_num_insns_seq (gimple_gtm_txn_body (stmt), weights));
+	      + estimate_num_insns_seq (gimple_seq_body (stmt), weights));
 
     default:
       gcc_unreachable ();
--- tree-nested.c	(revision 141060)
+++ tree-nested.c	(local)
@@ -1154,11 +1154,11 @@ convert_nonlocal_reference_stmt (gimple_
       info->new_local_var_chain = NULL;
 
       walk_body (convert_nonlocal_reference_stmt, convert_nonlocal_reference_op,
-	         info, gimple_omp_body (stmt));
+	         info, gimple_seq_body (stmt));
 
       if (info->new_local_var_chain)
 	declare_vars (info->new_local_var_chain,
-	              gimple_seq_first_stmt (gimple_omp_body (stmt)),
+	              gimple_seq_first_stmt (gimple_seq_body (stmt)),
 		      false);
       info->new_local_var_chain = save_local_var_chain;
       info->suppress_expansion = save_suppress;
@@ -1170,7 +1170,7 @@ convert_nonlocal_reference_stmt (gimple_
       walk_gimple_omp_for (stmt, convert_nonlocal_reference_stmt,
 	  		   convert_nonlocal_reference_op, info);
       walk_body (convert_nonlocal_reference_stmt,
-	  	 convert_nonlocal_reference_op, info, gimple_omp_body (stmt));
+	  	 convert_nonlocal_reference_op, info, gimple_seq_body (stmt));
       info->suppress_expansion = save_suppress;
       break;
 
@@ -1178,7 +1178,7 @@ convert_nonlocal_reference_stmt (gimple_
       save_suppress = info->suppress_expansion;
       convert_nonlocal_omp_clauses (gimple_omp_sections_clauses_ptr (stmt), wi);
       walk_body (convert_nonlocal_reference_stmt, convert_nonlocal_reference_op,
-	         info, gimple_omp_body (stmt));
+	         info, gimple_seq_body (stmt));
       info->suppress_expansion = save_suppress;
       break;
 
@@ -1186,7 +1186,7 @@ convert_nonlocal_reference_stmt (gimple_
       save_suppress = info->suppress_expansion;
       convert_nonlocal_omp_clauses (gimple_omp_single_clauses_ptr (stmt), wi);
       walk_body (convert_nonlocal_reference_stmt, convert_nonlocal_reference_op,
-	         info, gimple_omp_body (stmt));
+	         info, gimple_seq_body (stmt));
       info->suppress_expansion = save_suppress;
       break;
 
@@ -1194,7 +1194,7 @@ convert_nonlocal_reference_stmt (gimple_
     case GIMPLE_OMP_MASTER:
     case GIMPLE_OMP_ORDERED:
       walk_body (convert_nonlocal_reference_stmt, convert_nonlocal_reference_op,
-	         info, gimple_omp_body (stmt));
+	         info, gimple_seq_body (stmt));
       break;
 
     default:
@@ -1549,11 +1549,11 @@ convert_local_reference_stmt (gimple_stm
       info->new_local_var_chain = NULL;
 
       walk_body (convert_local_reference_stmt, convert_local_reference_op, info,
-	         gimple_omp_body (stmt));
+	         gimple_seq_body (stmt));
 
       if (info->new_local_var_chain)
 	declare_vars (info->new_local_var_chain,
-		      gimple_seq_first_stmt (gimple_omp_body (stmt)), false);
+		      gimple_seq_first_stmt (gimple_seq_body (stmt)), false);
       info->new_local_var_chain = save_local_var_chain;
       info->suppress_expansion = save_suppress;
       break;
@@ -1564,7 +1564,7 @@ convert_local_reference_stmt (gimple_stm
       walk_gimple_omp_for (stmt, convert_local_reference_stmt,
 			   convert_local_reference_op, info);
       walk_body (convert_local_reference_stmt, convert_local_reference_op,
-		 info, gimple_omp_body (stmt));
+		 info, gimple_seq_body (stmt));
       info->suppress_expansion = save_suppress;
       break;
 
@@ -1572,7 +1572,7 @@ convert_local_reference_stmt (gimple_stm
       save_suppress = info->suppress_expansion;
       convert_local_omp_clauses (gimple_omp_sections_clauses_ptr (stmt), wi);
       walk_body (convert_local_reference_stmt, convert_local_reference_op,
-		 info, gimple_omp_body (stmt));
+		 info, gimple_seq_body (stmt));
       info->suppress_expansion = save_suppress;
       break;
 
@@ -1580,7 +1580,7 @@ convert_local_reference_stmt (gimple_stm
       save_suppress = info->suppress_expansion;
       convert_local_omp_clauses (gimple_omp_single_clauses_ptr (stmt), wi);
       walk_body (convert_local_reference_stmt, convert_local_reference_op,
-		 info, gimple_omp_body (stmt));
+		 info, gimple_seq_body (stmt));
       info->suppress_expansion = save_suppress;
       break;
 
@@ -1588,7 +1588,7 @@ convert_local_reference_stmt (gimple_stm
     case GIMPLE_OMP_MASTER:
     case GIMPLE_OMP_ORDERED:
       walk_body (convert_local_reference_stmt, convert_local_reference_op,
-		 info, gimple_omp_body (stmt));
+		 info, gimple_seq_body (stmt));
       break;
 
     default:
@@ -1866,7 +1866,7 @@ convert_gimple_call (gimple_stmt_iterato
     case GIMPLE_OMP_TASK:
       save_static_chain_added = info->static_chain_added;
       info->static_chain_added = 0;
-      walk_body (convert_gimple_call, NULL, info, gimple_omp_body (stmt));
+      walk_body (convert_gimple_call, NULL, info, gimple_seq_body (stmt));
       for (i = 0; i < 2; i++)
 	{
 	  tree c, decl;
@@ -1903,7 +1903,7 @@ convert_gimple_call (gimple_stmt_iterato
     case GIMPLE_OMP_MASTER:
     case GIMPLE_OMP_ORDERED:
     case GIMPLE_OMP_CRITICAL:
-      walk_body (convert_gimple_call, NULL, info, gimple_omp_body (stmt));
+      walk_body (convert_gimple_call, NULL, info, gimple_seq_body (stmt));
       break;
 
     default:
--- tree-pretty-print.c	(revision 141060)
+++ tree-pretty-print.c	(local)
@@ -1894,18 +1894,8 @@ dump_generic_node (pretty_printer *buffe
       is_expr = false;
       break;
 
-    case GTM_ABORT:
-      pp_string (buffer, "GTM_ABORT");
-      is_expr = false;
-      break;
-
-    case GTM_RETURN:
-      pp_string (buffer, "GTM_RETURN");
-      is_expr = false;
-      break;
-
     case GTM_TXN:
-      pp_string (buffer, "_Pragma(\"tm atomic\")");
+      pp_string (buffer, "__tm_atomic");
       if (!(flags & TDF_SLIM) && GTM_TXN_BODY (node))
         {
           newline_and_indent (buffer, spc);
@@ -1918,6 +1908,11 @@ dump_generic_node (pretty_printer *buffe
       is_expr = false;
       break;
 
+    case GTM_ABORT:
+      pp_string (buffer, "GTM_ABORT");
+      is_expr = false;
+      break;
+
     case REDUC_MAX_EXPR:
       pp_string (buffer, " REDUC_MAX_EXPR < ");
       dump_generic_node (buffer, TREE_OPERAND (node, 0), spc, flags, false);
--- tree.def	(revision 141060)
+++ tree.def	(local)
@@ -1061,12 +1061,15 @@ DEFTREECODE (OMP_CLAUSE, "omp_clause", t
    Operand 0: GTM_TXN_BODY: contains body of the transaction.*/
 DEFTREECODE (GTM_TXN, "gtm_txn", tcc_statement, 1)
 
-/* Return from an GTM directive.  */
-DEFTREECODE (GTM_RETURN, "gtm_return", tcc_statement, 0)
-
 /* Abort an transaction.  */
 DEFTREECODE (GTM_ABORT, "gtm_abort", tcc_statement, 0)
 
+/* A read protected by a current transaction.  */
+DEFTREECODE (GTM_LOAD, "gtm_load", tcc_expression, 1)
+
+/* A write protected by a current transaction.  */
+DEFTREECODE (GTM_STORE, "gtm_store", tcc_expression, 1)
+
 /* Reduction operations. 
    Operations that take a vector of elements and "reduce" it to a scalar
    result (e.g. summing the elements of the vector, finding the minimum over
--- tree.h	(revision 141060)
+++ tree.h	(local)
@@ -177,12 +177,6 @@ extern const enum tree_code_class tree_c
 
 #define EXPR_P(NODE) IS_EXPR_CODE_CLASS (TREE_CODE_CLASS (TREE_CODE (NODE)))
 
-/* Returns nonzero iff NODE is an GTM directive.  */
-
-#define GTM_DIRECTIVE_P(NODE)                         \
-    (TREE_CODE (NODE) == GTM_TXN                      \
-     || TREE_CODE (NODE) == GTM_RETURN)
-
 /* Number of argument-words in each kind of tree-node.  */
 
 extern const unsigned char tree_code_length[];
@@ -3269,11 +3263,13 @@ struct tree_decl_non_common GTY(())
    of a function - called only from inside transactions.  */
 #define DECL_IS_GTM_CLONE(NODE) (FUNCTION_DECL_CHECK (NODE)->function_decl.gtm_clone_flag)
 
+#if 0
 /* Nonzero in a FUNCTION_DECL means this function should be treated
    as "tm_unknown" function - behaviour of transactions depends
    on STM system  to supports irrevocable calls.  */
 #define DECL_IS_GTM_UNKNOWN(NODE) \
   (FUNCTION_DECL_CHECK (NODE)->function_decl.gtm_unknown_flag)
+#endif
 
 /* Nonzero in a FUNCTION_DECL means this function should be treated
    as "tm_callable" function - function maybe called from within a transaction. */

Index Nav: [Date Index] [Subject Index] [Author Index] [Thread Index]
Message Nav: [Date Prev] [Date Next] [Thread Prev] [Thread Next]