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] testsuite, long double, __tm_retry


Today's installment contains the beginnings of a testsuite, adding support for long double, and support for a software-directed transaction retry statement. In the process, a few semantic errors are detected, and a bug in ssa operand update is fixed.


r~
        * builtin-types.def (BT_FN_LDOUBLE_VPTR, BT_FN_VOID_VPTR_LDOUBLE): New.
        * gtm-builtins.def (BUILT_IN_TM_RETRY, BUILT_IN_TM_MEMMOVE): New.
        (BUILT_IN_TM_STORE_LDOUBLE, BUILT_IN_TM_LOAD_LDOUBLE): New.
        * calls.c (special_function_p): Handle them.
        * trans-mem.c (build_tm_load): Handle BUILT_IN_TM_LOAD_LDOUBLE.
        Set call lhs before insertting it.
        (build_tm_store): Handle BUILT_IN_TM_STORE_LDOUBLE.
        (expand_assign_tm): Remove the old stmt before adding the new ones.

        * c-common.c (c_common_reswords): Add __tm_retry.
        * c-common.h (RID_TM_RETRY): New.
        * c-parser.c (struct c_parser): Add in_tm_atomic.
        (c_parser_statement_after_labels): Handle RID_TM_RETRY.
        (c_parser_tm_atomic): Error if !flag_tm; mirror
        c_parser_omp_structured_block for parsing the contained statement.
        (c_parser_tm_abort_retry): Rename from c_parser_tm_abort; error
        if not contained within a __tm_atomic block; handle __tm_retry.
        * c-tree.h (c_begin_tm_atomic): Remove.
        * c-typeck.c (c_begin_tm_atomic): Remove.
        (c_finish_tm_atomic): Don't c_end_compound_stmt.

        * testsuite/gcc.dg/tm: New directory.

--- builtin-types.def	(revision 141453)
+++ builtin-types.def	(local)
@@ -481,6 +481,7 @@ DEF_FUNCTION_TYPE_1 (BT_FN_I4_VPTR, BT_I
 DEF_FUNCTION_TYPE_1 (BT_FN_I8_VPTR, BT_I8, BT_VOLATILE_PTR)
 DEF_FUNCTION_TYPE_1 (BT_FN_FLOAT_VPTR, BT_FLOAT, BT_VOLATILE_PTR)
 DEF_FUNCTION_TYPE_1 (BT_FN_DOUBLE_VPTR, BT_DOUBLE, BT_VOLATILE_PTR)
+DEF_FUNCTION_TYPE_1 (BT_FN_LDOUBLE_VPTR, BT_LONGDOUBLE, BT_VOLATILE_PTR)
 
 DEF_FUNCTION_TYPE_2 (BT_FN_VOID_VPTR_I1, BT_VOID, BT_VOLATILE_PTR, BT_I1)
 DEF_FUNCTION_TYPE_2 (BT_FN_VOID_VPTR_I2, BT_VOID, BT_VOLATILE_PTR, BT_I2)
@@ -489,3 +490,5 @@ DEF_FUNCTION_TYPE_2 (BT_FN_VOID_VPTR_I8,
 DEF_FUNCTION_TYPE_2 (BT_FN_VOID_VPTR_FLOAT, BT_VOID, BT_VOLATILE_PTR, BT_FLOAT)
 DEF_FUNCTION_TYPE_2 (BT_FN_VOID_VPTR_DOUBLE, BT_VOID, 
                      BT_VOLATILE_PTR, BT_DOUBLE)
+DEF_FUNCTION_TYPE_2 (BT_FN_VOID_VPTR_LDOUBLE, BT_VOID,
+		     BT_VOLATILE_PTR, BT_LONGDOUBLE)
--- c-common.c	(revision 141453)
+++ c-common.c	(local)
@@ -657,6 +657,7 @@ const struct c_common_resword c_common_r
   { "__thread",		RID_THREAD,	0 },
   { "__tm_abort",	RID_TM_ABORT,	0 },
   { "__tm_atomic",	RID_TM_ATOMIC,	0 },
+  { "__tm_retry",	RID_TM_RETRY,   0 },
   { "__typeof",		RID_TYPEOF,	0 },
   { "__typeof__",	RID_TYPEOF,	0 },
   { "__volatile",	RID_VOLATILE,	0 },
--- c-common.h	(revision 141453)
+++ c-common.h	(local)
@@ -79,7 +79,7 @@ enum rid
   RID_CXX_COMPAT_WARN,
 
   /* GNU transactional memory extension */
-  RID_TM_ATOMIC, RID_TM_ABORT,
+  RID_TM_ATOMIC, RID_TM_ABORT, RID_TM_RETRY,
 
   /* Too many ways of getting the name of a function as a string */
   RID_FUNCTION_NAME, RID_PRETTY_FUNCTION_NAME, RID_C99_FUNCTION_NAME,
--- c-parser.c	(revision 141453)
+++ c-parser.c	(local)
@@ -182,6 +182,8 @@ typedef struct c_parser GTY(())
      undesirable to bind an identifier to an Objective-C class, even
      if a class with that name exists.  */
   BOOL_BITFIELD objc_need_raw_identifier : 1;
+  /* True if we're processing a __tm_atomic statement.  */
+  BOOL_BITFIELD in_tm_atomic : 1;
 } c_parser;
 
 
@@ -914,7 +916,7 @@ static struct c_expr c_parser_postfix_ex
 static struct c_expr c_parser_postfix_expression_after_primary (c_parser *,
 								struct c_expr);
 static tree c_parser_tm_atomic (c_parser *);
-static tree c_parser_tm_abort (c_parser *);
+static tree c_parser_tm_abort_retry (c_parser *);
 static struct c_expr c_parser_expression (c_parser *);
 static struct c_expr c_parser_expression_conv (c_parser *);
 static tree c_parser_expr_list (c_parser *, bool);
@@ -3735,7 +3737,8 @@ c_parser_statement_after_labels (c_parse
 	  stmt = c_parser_tm_atomic (parser);
 	  break;
 	case RID_TM_ABORT:
-	  stmt = c_parser_tm_abort (parser);
+	case RID_TM_RETRY:
+	  stmt = c_parser_tm_abort_retry (parser);
 	  goto expect_semicolon;
 	case RID_THROW:
 	  gcc_assert (c_dialect_objc ());
@@ -8230,32 +8233,65 @@ c_parser_omp_threadprivate (c_parser *pa
 static tree
 c_parser_tm_atomic (c_parser *parser)
 {
-  tree block;
+  bool old_in_atomic = parser->in_tm_atomic;
+  tree stmt;
 
   gcc_assert (c_parser_next_token_is_keyword (parser, RID_TM_ATOMIC));
+
+  if (!flag_tm)
+    error_at (c_parser_peek_token (parser)->location,
+	      "%<__tm_atomic%> without transactional memory support enabled");
+
   c_parser_consume_token (parser);
 
-  block = c_begin_tm_atomic ();
+  parser->in_tm_atomic = true;
+
+  stmt = push_stmt_list ();
   c_parser_statement (parser);
-  return c_finish_tm_atomic (block);
+  stmt = pop_stmt_list (stmt);
+
+  if (flag_tm)
+    stmt = c_finish_tm_atomic (stmt);
+
+  parser->in_tm_atomic = old_in_atomic;
+
+  return stmt;
 }
 
-/* Parse a __tm_abort statement (GCC Extension).
+/* Parse a __tm_abort or __tm_retry statement (GCC Extension).
 
    tm-atomic-statement:
      __tm_atomic;
+   tm-retry-statement:
+     __tm_retry;
 */
 
 static tree
-c_parser_tm_abort (c_parser *parser)
+c_parser_tm_abort_retry (c_parser *parser)
 {
-  gcc_assert (c_parser_next_token_is_keyword (parser, RID_TM_ABORT));
-  c_parser_consume_token (parser);
+  enum built_in_function code;
 
-  /* ??? Verify that __tm_abort is contained within the
-     lexical scope of a __tm_atomic.  */
+  if (c_parser_next_token_is_keyword (parser, RID_TM_ABORT))
+    code = BUILT_IN_TM_ABORT;
+  else if (c_parser_next_token_is_keyword (parser, RID_TM_RETRY))
+    code = BUILT_IN_TM_RETRY;
+  else
+    gcc_unreachable ();
+
+  if (!parser->in_tm_atomic)
+    {
+      location_t here = c_parser_peek_token (parser)->location;
+      if (code == BUILT_IN_TM_ABORT)
+        error_at (here, "%<__tm_abort%> not within %<__tm_atomic%>");
+      else
+        error_at (here, "%<__tm_retry%> not within %<__tm_atomic%>");
+      c_parser_consume_token (parser);
+      return error_mark_node;
+    }
+
+  c_parser_consume_token (parser);
 
-  return add_stmt (build_call_expr (built_in_decls[BUILT_IN_TM_ABORT], 0));
+  return add_stmt (build_call_expr (built_in_decls[code], 0));
 }
 
 /* Parse a single source file.  */
--- c-tree.h	(revision 141453)
+++ c-tree.h	(local)
@@ -602,7 +602,6 @@ extern tree c_finish_omp_parallel (tree,
 extern tree c_begin_omp_task (void);
 extern tree c_finish_omp_task (tree, tree);
 extern tree c_finish_omp_clauses (tree);
-extern tree c_begin_tm_atomic (void);
 extern tree c_finish_tm_atomic (tree);
 
 /* Set to 0 at beginning of a function definition, set to 1 if
--- c-typeck.c	(revision 141453)
+++ c-typeck.c	(local)
@@ -8867,19 +8867,6 @@ c_finish_omp_clauses (tree clauses)
   return clauses;
 }
 
-/* Similar to c_begin_omp_parallel. */
-
-tree
-c_begin_tm_atomic (void)
-{
-  tree block;
-
-  keep_next_level ();
-  block = c_begin_compound_stmt (true);
-
-  return block;
-}
-
 /* Create a transaction node.  */
 
 tree
@@ -8887,8 +8874,6 @@ c_finish_tm_atomic (tree block)
 {
   tree stmt;
 
-  block = c_end_compound_stmt (block, true);
-
   stmt = make_node (TM_ATOMIC);
   TREE_TYPE (stmt) = void_type_node;
   TM_ATOMIC_BODY (stmt) = block;
--- calls.c	(revision 141453)
+++ calls.c	(local)
@@ -482,22 +482,26 @@ special_function_p (const_tree fndecl, i
     {
       switch (DECL_FUNCTION_CODE (fndecl))
 	{
-	case BUILT_IN_TM_ABORT:
 	case BUILT_IN_TM_COMMIT:
+	case BUILT_IN_TM_ABORT:
+	case BUILT_IN_TM_RETRY:
 	case BUILT_IN_TM_IRREVOKABLE:
 	case BUILT_IN_TM_MEMCPY:
+	case BUILT_IN_TM_MEMMOVE:
 	case BUILT_IN_TM_STORE_1:
 	case BUILT_IN_TM_STORE_2:
 	case BUILT_IN_TM_STORE_4:
 	case BUILT_IN_TM_STORE_8:
 	case BUILT_IN_TM_STORE_FLOAT:
 	case BUILT_IN_TM_STORE_DOUBLE:
+	case BUILT_IN_TM_STORE_LDOUBLE:
 	case BUILT_IN_TM_LOAD_1:
 	case BUILT_IN_TM_LOAD_2:
 	case BUILT_IN_TM_LOAD_4:
 	case BUILT_IN_TM_LOAD_8:
 	case BUILT_IN_TM_LOAD_FLOAT:
 	case BUILT_IN_TM_LOAD_DOUBLE:
+	case BUILT_IN_TM_LOAD_LDOUBLE:
 	  flags |= ECF_TM_OPS;
 	  break;
 	default:
--- gtm-builtins.def	(revision 141453)
+++ gtm-builtins.def	(local)
@@ -5,11 +5,15 @@ DEF_TM_BUILTIN (BUILT_IN_TM_COMMIT, "__g
 		BT_FN_VOID, ATTR_NOTHROW_LIST)
 DEF_TM_BUILTIN (BUILT_IN_TM_ABORT, "__gtm_abort",
 		BT_FN_VOID, ATTR_NORETURN_NOTHROW_LIST)
+DEF_TM_BUILTIN (BUILT_IN_TM_RETRY, "__gtm_retry",
+		BT_FN_VOID, ATTR_NORETURN_NOTHROW_LIST)
 DEF_TM_BUILTIN (BUILT_IN_TM_IRREVOKABLE, "__gtm_irrevokable",
 		BT_FN_VOID, ATTR_NOTHROW_LIST)
 
 DEF_TM_BUILTIN (BUILT_IN_TM_MEMCPY, "__gtm_memcpy",
 		BT_FN_PTR_PTR_CONST_PTR_SIZE, ATTR_NOTHROW_NONNULL)
+DEF_TM_BUILTIN (BUILT_IN_TM_MEMMOVE, "__gtm_memmove",
+		BT_FN_PTR_PTR_CONST_PTR_SIZE, ATTR_NOTHROW_NONNULL)
 
 DEF_TM_BUILTIN (BUILT_IN_TM_STORE_1, "__gtm_store8",
 		BT_FN_VOID_VPTR_I1, ATTR_NOTHROW_LIST)
@@ -23,6 +27,8 @@ DEF_TM_BUILTIN (BUILT_IN_TM_STORE_FLOAT,
 		BT_FN_VOID_VPTR_FLOAT, ATTR_NOTHROW_LIST)
 DEF_TM_BUILTIN (BUILT_IN_TM_STORE_DOUBLE, "__gtm_store_double",
 		BT_FN_VOID_VPTR_DOUBLE, ATTR_NOTHROW_LIST)
+DEF_TM_BUILTIN (BUILT_IN_TM_STORE_LDOUBLE, "__gtm_store_ldouble",
+		BT_FN_VOID_VPTR_LDOUBLE, ATTR_NOTHROW_LIST)
 
 DEF_TM_BUILTIN (BUILT_IN_TM_LOAD_1, "__gtm_load8",
 		BT_FN_I1_VPTR, ATTR_PURE_NOTHROW_LIST)
@@ -36,3 +42,5 @@ DEF_TM_BUILTIN (BUILT_IN_TM_LOAD_FLOAT, 
 		BT_FN_FLOAT_VPTR, ATTR_PURE_NOTHROW_LIST)
 DEF_TM_BUILTIN (BUILT_IN_TM_LOAD_DOUBLE, "__gtm_load_double",
 		BT_FN_DOUBLE_VPTR, ATTR_PURE_NOTHROW_LIST)
+DEF_TM_BUILTIN (BUILT_IN_TM_LOAD_LDOUBLE, "__gtm_load_ldouble",
+		BT_FN_LDOUBLE_VPTR, ATTR_PURE_NOTHROW_LIST)
=== testsuite/gcc.dg/tm	(new directory)
==================================================================
--- testsuite/gcc.dg/tm/abort-1.c	(revision 141453)
+++ testsuite/gcc.dg/tm/abort-1.c	(local)
@@ -0,0 +1,11 @@
+/* { dg-do compile } */
+
+void f(void)
+{
+  __tm_abort;		/* { dg-error "not within" } */
+}
+
+void g(void)
+{
+  __tm_retry;		/* { dg-error "not within" } */
+}
--- testsuite/gcc.dg/tm/abort-2.c	(revision 141453)
+++ testsuite/gcc.dg/tm/abort-2.c	(local)
@@ -0,0 +1,13 @@
+/* { dg-do compile } */
+/* { dg-options "-fgnu-tm" } */
+
+int g;
+void f(void)
+{
+  __tm_atomic {
+    if (g == 0)
+      __tm_abort;
+    if (g == 1)
+      __tm_retry;
+  }
+}
--- testsuite/gcc.dg/tm/atomic-1.c	(revision 141453)
+++ testsuite/gcc.dg/tm/atomic-1.c	(local)
@@ -0,0 +1,9 @@
+/* { dg-do compile } */
+
+int g;
+void f(void)
+{
+  __tm_atomic {		/* { dg-error "without transactional memory" } */
+    g++;
+  }
+}
--- testsuite/gcc.dg/tm/atomic-2.c	(revision 141453)
+++ testsuite/gcc.dg/tm/atomic-2.c	(local)
@@ -0,0 +1,10 @@
+/* { dg-do compile } */
+/* { dg-options "-fgnu-tm" } */
+
+int g;
+void f(void)
+{
+  __tm_atomic {
+    g++;
+  }
+}
--- testsuite/gcc.dg/tm/data-1.c	(revision 141453)
+++ testsuite/gcc.dg/tm/data-1.c	(local)
@@ -0,0 +1,48 @@
+/* { dg-do compile } */
+/* { dg-options "-fgnu-tm" } */
+/* Test read and write on all basic types.  */
+
+static char gc;
+static signed char gsc;
+static unsigned char guc;
+
+static short gs;
+static unsigned short gus;
+
+static int gi;
+static unsigned int gui;
+
+static long gl;
+static unsigned long gul;
+
+static long long gll;
+static unsigned long long gull;
+
+static float gf;
+static double gd;
+static long double gld;
+
+void f(void)
+{
+  __tm_atomic {
+    gc++;
+    gsc++;
+    guc++;
+
+    gs++;
+    gus++;
+
+    gi++;
+    gui++;
+
+    gl++;
+    gul++;
+
+    gll++;
+    gull++;
+
+    gf++;
+    gd++;
+    gld++;
+  }
+}
--- testsuite/gcc.dg/tm/tm.exp	(revision 141453)
+++ testsuite/gcc.dg/tm/tm.exp	(local)
@@ -0,0 +1,36 @@
+#   Copyright (C) 2002, 2005, 2007 Free Software Foundation, Inc.
+
+# This program is free software; you can redistribute it and/or modify
+# it under the terms of the GNU General Public License as published by
+# the Free Software Foundation; either version 3 of the License, or
+# (at your option) any later version.
+# 
+# This program is distributed in the hope that it will be useful,
+# but WITHOUT ANY WARRANTY; without even the implied warranty of
+# MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE.  See the
+# GNU General Public License for more details.
+# 
+# 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/>.
+
+# GCC testsuite that uses the `dg.exp' driver.
+
+# Load support procs.
+load_lib gcc-dg.exp
+
+# If a testcase doesn't have special options, use these.
+global DEFAULT_CFLAGS
+if ![info exists DEFAULT_CFLAGS] then {
+    set DEFAULT_CFLAGS " -ansi -pedantic-errors"
+}
+
+# Initialize `dg'.
+dg-init
+
+# Main loop.
+dg-runtest [lsort [glob -nocomplain $srcdir/$subdir/*.\[cS\]]] \
+        "" $DEFAULT_CFLAGS
+
+# All done.
+dg-finish
--- trans-mem.c	(revision 141453)
+++ trans-mem.c	(local)
@@ -601,6 +601,8 @@ build_tm_load (tree lhs, tree rhs, gimpl
     code = BUILT_IN_TM_LOAD_FLOAT;
   else if (type == double_type_node)
     code = BUILT_IN_TM_LOAD_DOUBLE;
+  else if (type == long_double_type_node)
+    code = BUILT_IN_TM_LOAD_LDOUBLE;
   else if (TYPE_SIZE_UNIT (type) != NULL
 	   && host_integerp (TYPE_SIZE_UNIT (type), 1))
     {
@@ -631,11 +633,13 @@ build_tm_load (tree lhs, tree rhs, gimpl
   gcc_assert (is_gimple_operand (t));
 
   gcall = gimple_build_call (built_in_decls[code], 1, t);
-  gsi_insert_before (gsi, gcall, GSI_SAME_STMT);
 
   t = TREE_TYPE (TREE_TYPE (built_in_decls[code]));
   if (useless_type_conversion_p (type, t))
-    gimple_call_set_lhs (gcall, lhs);
+    {
+      gimple_call_set_lhs (gcall, lhs);
+      gsi_insert_before (gsi, gcall, GSI_SAME_STMT);
+    }
   else
     {
       gimple g;
@@ -643,6 +647,7 @@ build_tm_load (tree lhs, tree rhs, gimpl
 
       temp = make_rename_temp (t, NULL);
       gimple_call_set_lhs (gcall, temp);
+      gsi_insert_before (gsi, gcall, GSI_SAME_STMT);
 
       t = fold_build1 (VIEW_CONVERT_EXPR, type, temp);
       g = gimple_build_assign (lhs, t);
@@ -666,6 +671,8 @@ build_tm_store (tree lhs, tree rhs, gimp
     code = BUILT_IN_TM_STORE_FLOAT;
   else if (type == double_type_node)
     code = BUILT_IN_TM_STORE_DOUBLE;
+  else if (type == long_double_type_node)
+    code = BUILT_IN_TM_STORE_LDOUBLE;
   else if (TYPE_SIZE_UNIT (type) != NULL
 	   && host_integerp (TYPE_SIZE_UNIT (type), 1))
     {
@@ -728,6 +735,9 @@ expand_assign_tm (struct tm_region *regi
   bool load_p = requires_barrier (rhs);
   gimple gcall;
 
+  mark_vops_in_stmt (stmt);
+  gsi_remove (gsi, true);
+
   if (load_p && store_p)
     {
       tm_atomic_subcode_ior (region, GTMA_HAVE_LOAD | GTMA_HAVE_STORE);
@@ -752,8 +762,6 @@ expand_assign_tm (struct tm_region *regi
     return;
 
   add_stmt_to_tm_region  (region, gcall);
-  mark_vops_in_stmt (stmt);
-  gsi_remove (gsi, true);
 }
 
 

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