[tuples] GIMPLE_OMP_ATOMIC_{LOAD,STORE}

Aldy Hernandez aldyh@redhat.com
Wed Feb 6 15:28:00 GMT 2008


Hi Diego.

This patch adds the final missing piece for high-gimple conversion of
OpenMP.  It converts gimplify_omp_atomic, which in turns needs new
tuples (GIMPLE_OMP_ATOMIC_{LOAD,STORE}).

Diego, could you take a peek at the new tuples, and make sure you agree
with their layout and structure?  I'll wait for your approval before
committing.

Aldy

p.s. I tried to update tuples.tex, but I'm a LaTex idiot, and I can't
figure out which RPM to install to get lgrind.sty (notice I say RPM,
cause I'm definitely not downloading no TeX crap business).

BTW, is lgrind.sty even needed, because the PDF seems to build
regardless, but I'm afraid I'll botch something up.

	* gimple.def: Add GIMPLE_OMP_ATOMIC_{LOAD,STORE} entires.
	* gsstruct.def: Add GSS_OMP_ATOMIC_{LOAD,STORE} entries.
	* gimple-pretty-print.c (dump_gimple_stmt): Add case for
	GIMPLE_OMP_ATOMIC_{LOAD,STORE}.
	* gimplify.c (gimplify_omp_atomic): Enable and convert to tuples.
	* tree.def: Add FIXME notes.
	* gimple.c (gss_for_code): Add cases for
	GIMPLE_OMP_ATOMIC_{LOAD,STORE}.
	(gimple_size): Same.
	(gimple_build_omp_atomic_load): New.
	(gimple_build_omp_atomic_store): New.
	* gimple.h (struct gimple_statement_omp_atomic_{load,store}): New.
	(union gimple_statement_d): Add gimple_omp_atomic_{load,store}.
	(gimple_omp_atomic_store_set_val): New.
	(gimple_omp_atomic_store_val): New.
	(gimple_omp_atomic_load_set_lhs): New.
	(gimple_omp_atomic_load_lhs): New.
	(gimple_omp_atomic_load_set_rhs): New.
	(gimple_omp_atomic_load_rhs): New.
	* tree-cfg.c (verify_types_in_gimple_seq_2): Add cases for
	GIMPLE_OMP_ATOMIC_{LOAD,STORE}.

Index: gimple.def
===================================================================
--- gimple.def	(revision 132144)
+++ gimple.def	(working copy)
@@ -175,6 +175,18 @@ DEFGSCODE(GIMPLE_TRY, "gimple_try")
 /* GIMPLE_NOP represents the "do nothing" statement.  */
 DEFGSCODE(GIMPLE_NOP, "gimple_nop")
 
+/* Tuples used for lowering of OMP_ATOMIC.  Although the form of the OMP_ATOMIC
+   expression is very simple (just in form mem op= expr), various implicit
+   conversions may cause the expression to become more complex, so that it does
+   not fit the gimple grammar very well.  To overcome this problem, OMP_ATOMIC
+   is rewritten as a sequence of two cdoes in gimplification:
+
+   GIMPLE_OMP_LOAD (tmp, mem)
+   val = some computations involving tmp;
+   GIMPLE_OMP_STORE (val).  */
+DEFGSCODE(GIMPLE_OMP_ATOMIC_LOAD, "gimple_omp_atomic_load")
+DEFGSCODE(GIMPLE_OMP_ATOMIC_STORE, "gimple_omp_atomic_store")
+
 /* GIMPLE_OMP_CONTINUE marks the location of the loop or sections
    iteration in partially lowered OpenMP code.  */
 DEFGSCODE(GIMPLE_OMP_CONTINUE, "gimple_omp_continue")
Index: gsstruct.def
===================================================================
--- gsstruct.def	(revision 132144)
+++ gsstruct.def	(working copy)
@@ -43,3 +43,5 @@ DEFGSSTRUCT(GSS_OMP_FOR, "omp_for")
 DEFGSSTRUCT(GSS_OMP_PARALLEL, "omp_parallel")
 DEFGSSTRUCT(GSS_OMP_SECTIONS, "sections")
 DEFGSSTRUCT(GSS_OMP_SINGLE, "single")
+DEFGSSTRUCT(GSS_OMP_ATOMIC_LOAD, "omp_atomic_load")
+DEFGSSTRUCT(GSS_OMP_ATOMIC_STORE, "omp_atomic_store")
Index: gimple-pretty-print.c
===================================================================
--- gimple-pretty-print.c	(revision 132144)
+++ gimple-pretty-print.c	(working copy)
@@ -620,6 +620,26 @@ dump_gimple_stmt (pretty_printer *buffer
       dump_gimple_seq (buffer, gimple_omp_body (gs), spc + 2, flags);
       break;
 
+    case GIMPLE_OMP_ATOMIC_LOAD:
+      pp_string (buffer, "#pragma omp atomic_load");
+      newline_and_indent (buffer, spc + 2);
+      dump_generic_node (buffer, gimple_omp_atomic_load_lhs (gs),
+	  		 spc, flags, false);
+      pp_space (buffer);
+      pp_character (buffer, '=');
+      pp_space (buffer);
+      pp_character (buffer, '*');
+      dump_generic_node (buffer, gimple_omp_atomic_load_rhs (gs),
+	  		 spc, flags, false);
+      break;
+
+    case GIMPLE_OMP_ATOMIC_STORE:
+      pp_string (buffer, "#pragma omp atomic_store (");
+      dump_generic_node (buffer, gimple_omp_atomic_store_val (gs),
+	  		 spc, flags, false);
+      pp_character (buffer, ')');
+      break;
+
     case GIMPLE_OMP_FOR:
       dump_gimple_omp_for (buffer, gs, spc, flags);
       break;
Index: gimplify.c
===================================================================
--- gimplify.c	(revision 132144)
+++ gimplify.c	(working copy)
@@ -5609,7 +5609,7 @@ gimplify_omp_atomic (tree *expr_p, gimpl
   tree addr = TREE_OPERAND (*expr_p, 0);
   tree rhs = TREE_OPERAND (*expr_p, 1);
   tree type = TYPE_MAIN_VARIANT (TREE_TYPE (TREE_TYPE (addr)));
-  tree tmp_load, load, store;
+  tree tmp_load;
 
    tmp_load = create_tmp_var (type, NULL);
    if (goa_stabilize_expr (&rhs, pre_p, addr, tmp_load) < 0)
@@ -5619,21 +5619,16 @@ gimplify_omp_atomic (tree *expr_p, gimpl
        != GS_ALL_DONE)
      return GS_ERROR;
 
-   load = build2 (OMP_ATOMIC_LOAD, void_type_node, tmp_load, addr);
-   /* FIXME tuples.  */
-#if 0
-   append_to_statement_list (load, pre_p);
-#else
-   gimple_unreachable ();
-#endif
+   gimple_seq_add (pre_p,
+		   gimple_build_omp_atomic_load (tmp_load, addr));
    if (gimplify_expr (&rhs, pre_p, NULL, is_gimple_val, fb_rvalue)
        != GS_ALL_DONE)
      return GS_ERROR;
-   store = build1 (OMP_ATOMIC_STORE, void_type_node, rhs);
-   *expr_p = store;
+   gimple_seq_add (pre_p,
+       		   gimple_build_omp_atomic_store (rhs));
+   *expr_p = NULL;
 
    return GS_ALL_DONE;
-
 }
 
 
Index: tree.def
===================================================================
--- tree.def	(revision 132144)
+++ tree.def	(working copy)
@@ -1035,9 +1035,11 @@ DEFTREECODE (OMP_ORDERED, "omp_ordered",
    Operand 1: OMP_CRITICAL_NAME: Identifier for critical section.  */
 DEFTREECODE (OMP_CRITICAL, "omp_critical", tcc_statement, 2)
 
+/* FIXME tuples: Remove; should only exist as tuple.  */
 /* Return from an OpenMP directive.  */
 DEFTREECODE (OMP_RETURN, "omp_return", tcc_statement, 0)
 
+/* FIXME tuples: Remove; should only exist as tuple.  */
 /* OpenMP - An intermediate tree code to mark the location of the
    loop or sections iteration in the partially lowered code.
    The arguments are definition and use of the control variable.  */
@@ -1051,6 +1053,7 @@ DEFTREECODE (OMP_CONTINUE, "omp_continue
 	build_fold_indirect_ref of the address.  */
 DEFTREECODE (OMP_ATOMIC, "omp_atomic", tcc_statement, 2)
 
+/* FIXME tuples: Remove these.  They are now tuples.  */
 /* Codes used for lowering of OMP_ATOMIC.  Although the form of the OMP_ATOMIC
    statement is very simple (just in form mem op= expr), various implicit
    conversions may cause the expression become more complex, so that it does
Index: gimple.c
===================================================================
--- gimple.c	(revision 132144)
+++ gimple.c	(working copy)
@@ -94,6 +94,8 @@ gss_for_code (enum gimple_code code)
     case GIMPLE_OMP_PARALLEL:		return GSS_OMP_PARALLEL;
     case GIMPLE_OMP_SECTIONS:		return GSS_OMP_SECTIONS;
     case GIMPLE_OMP_SINGLE:		return GSS_OMP_SINGLE;
+    case GIMPLE_OMP_ATOMIC_LOAD:	return GSS_OMP_ATOMIC_LOAD;
+    case GIMPLE_OMP_ATOMIC_STORE:	return GSS_OMP_ATOMIC_STORE;
     default:				gcc_unreachable ();
     }
 }
@@ -144,6 +146,10 @@ gimple_size (enum gimple_code code)
       return sizeof (struct gimple_statement_omp_sections);
     case GIMPLE_OMP_SINGLE:
       return sizeof (struct gimple_statement_omp_single);
+    case GIMPLE_OMP_ATOMIC_LOAD:
+      return sizeof (struct gimple_statement_omp_atomic_load);
+    case GIMPLE_OMP_ATOMIC_STORE:
+      return sizeof (struct gimple_statement_omp_atomic_store);
     case GIMPLE_WITH_CLEANUP_EXPR:
       return sizeof (struct gimple_statement_wce);
     default:
@@ -861,6 +867,29 @@ gimple_build_omp_single (gimple_seq body
   return p;
 }
 
+/* Build a GIMPLE_OMP_ATOMIC_LOAD statement.  */
+
+gimple
+gimple_build_omp_atomic_load (tree lhs, tree rhs)
+{
+  gimple p = gimple_alloc (GIMPLE_OMP_ATOMIC_LOAD);
+  gimple_omp_atomic_load_set_lhs (p, lhs);
+  gimple_omp_atomic_load_set_rhs (p, rhs);
+  return p;
+}
+
+/* Build a GIMPLE_OMP_ATOMIC_STORE statement.
+
+   VAL is the value we are storing.  */
+
+gimple
+gimple_build_omp_atomic_store (tree val)
+{
+  gimple p = gimple_alloc (GIMPLE_OMP_ATOMIC_STORE);
+  gimple_omp_atomic_store_set_val (p, val);
+  return p;
+}
+
 /* Return which gimple structure is used by T.  The enums here are defined
    in gsstruct.def.  */
 
Index: gimple.h
===================================================================
--- gimple.h	(revision 132144)
+++ gimple.h	(working copy)
@@ -427,6 +427,24 @@ struct gimple_statement_omp_single GTY((
   tree clauses;
 };
 
+/* GIMPLE_OMP_ATOMIC_LOAD.  
+   Note, this is based on gimple_statement_base, not g_s_omp.  */
+
+struct gimple_statement_omp_atomic_load GTY(())
+{
+  struct gimple_statement_base gsbase;
+  tree rhs, lhs;
+};
+
+/* GIMPLE_OMP_ATOMIC_STORE.
+   Note, this is based on gimple_statement_base, not g_s_omp.  */
+
+struct gimple_statement_omp_atomic_store GTY(())
+{
+  struct gimple_statement_base gsbase;
+  tree val;
+};
+
 enum gimple_statement_structure_enum {
 #define DEFGSSTRUCT(SYM, STRING)	SYM,
 #include "gsstruct.def"
@@ -457,6 +475,8 @@ union gimple_statement_d GTY ((desc ("gi
   struct gimple_statement_omp_parallel GTY ((tag ("GSS_OMP_PARALLEL"))) gimple_omp_parallel;
   struct gimple_statement_omp_sections GTY ((tag ("GSS_OMP_SECTIONS"))) gimple_omp_sections;
   struct gimple_statement_omp_single GTY ((tag ("GSS_OMP_SINGLE"))) gimple_omp_single;
+  struct gimple_statement_omp_atomic_load GTY ((tag ("GSS_OMP_ATOMIC_LOAD"))) gimple_omp_atomic_load;
+  struct gimple_statement_omp_atomic_store GTY ((tag ("GSS_OMP_ATOMIC_STORE"))) gimple_omp_atomic_store;
 };
 
 /* In gimple.c.  */
@@ -492,6 +512,8 @@ gimple gimple_build_omp_return (bool);
 gimple gimple_build_omp_ordered (gimple_seq);
 gimple gimple_build_omp_sections (gimple_seq, tree);
 gimple gimple_build_omp_single (gimple_seq, tree);
+gimple gimple_build_omp_atomic_load (tree, tree);
+gimple gimple_build_omp_atomic_store (tree);
 enum gimple_statement_structure_enum gimple_statement_structure (gimple);
 void gimple_seq_add (gimple_seq, gimple);
 enum gimple_statement_structure_enum gss_for_assign (enum tree_code);
@@ -2430,6 +2452,66 @@ gimple_omp_for_cond (const_gimple gs)
 }
 
 
+/* Set the value being stored in an atomic store.  */
+
+static inline void
+gimple_omp_atomic_store_set_val (gimple g, tree val)
+{
+  GIMPLE_CHECK (g, GIMPLE_OMP_ATOMIC_STORE);
+  g->gimple_omp_atomic_store.val = val;
+}
+
+
+/* Return the value being stored in an atomic store.  */
+
+static inline tree
+gimple_omp_atomic_store_val (const_gimple g)
+{
+  GIMPLE_CHECK (g, GIMPLE_OMP_ATOMIC_STORE);
+  return g->gimple_omp_atomic_store.val;
+}
+
+
+/* Set the LHS of an atomic load.  */
+
+static inline void
+gimple_omp_atomic_load_set_lhs (gimple g, tree lhs)
+{
+  GIMPLE_CHECK (g, GIMPLE_OMP_ATOMIC_LOAD);
+  g->gimple_omp_atomic_load.lhs = lhs;
+}
+
+
+/* Get the LHS of an atomic load.  */
+
+static inline tree
+gimple_omp_atomic_load_lhs (const_gimple g)
+{
+  GIMPLE_CHECK (g, GIMPLE_OMP_ATOMIC_LOAD);
+  return g->gimple_omp_atomic_load.lhs;
+}
+
+
+/* Set the RHS of an atomic set.  */
+
+static inline void
+gimple_omp_atomic_load_set_rhs (gimple g, tree rhs)
+{
+  GIMPLE_CHECK (g, GIMPLE_OMP_ATOMIC_LOAD);
+  g->gimple_omp_atomic_load.rhs = rhs;
+}
+
+
+/* Get the RHS of an atomic set.  */
+
+static inline tree
+gimple_omp_atomic_load_rhs (const_gimple g)
+{
+  GIMPLE_CHECK (g, GIMPLE_OMP_ATOMIC_LOAD);
+  return g->gimple_omp_atomic_load.rhs;
+}
+
+
 /* Return the return value for GIMPLE_RETURN GS.  */
 
 static inline tree
Index: tree-cfg.c
===================================================================
--- tree-cfg.c	(revision 132144)
+++ tree-cfg.c	(working copy)
@@ -3731,6 +3731,8 @@ verify_types_in_gimple_seq_2 (gimple_seq
           case GIMPLE_OMP_PARALLEL:
           case GIMPLE_OMP_SECTIONS:
           case GIMPLE_OMP_SINGLE:
+	  case GIMPLE_OMP_ATOMIC_STORE:
+	  case GIMPLE_OMP_ATOMIC_LOAD:
             break;
 
 	  /* Tuples that do not have trees.  */



More information about the Gcc-patches mailing list