浏览代码

gcc: Add support for `#pragma starpu acquire VAR'.

* gcc-plugin/src/starpu.c (read_pragma_pointer_variable): New function.
  (handle_pragma_register): Use it.
  (handle_pragma_acquire): New function.
  (register_pragmas): Register it.

* gcc-plugin/tests/Makefile.am (gcc_tests): Add `acquire.c' and
  `acquire-errors.c'.

* gcc-plugin/tests/acquire-errors.c, gcc-plugin/tests/acquire.c: New
  files.

* gcc-plugin/tests/lib.h (struct data_acquire_arguments): New struct.
  (data_acquire_calls, expected_acquire_arguments): New variables.
  (starpu_data_acquire): New function.
Ludovic Courtès 14 年之前
父节点
当前提交
de67fc2c78
共有 6 个文件被更改,包括 208 次插入31 次删除
  1. 1 0
      .gitignore
  2. 78 31
      gcc-plugin/src/starpu.c
  3. 2 0
      gcc-plugin/tests/Makefile.am
  4. 47 0
      gcc-plugin/tests/acquire-errors.c
  5. 51 0
      gcc-plugin/tests/acquire.c
  6. 29 0
      gcc-plugin/tests/lib.h

+ 1 - 0
.gitignore

@@ -180,3 +180,4 @@ starpu.log
 /tools/starpu_perfmodel_plot
 /gcc-plugin/tests/run-test
 /gcc-plugin/tests/register-errors
+/gcc-plugin/tests/acquire

+ 78 - 31
gcc-plugin/src/starpu.c

@@ -68,6 +68,8 @@ static const char task_struct_name[] = "starpu_task";
 
 static tree build_codelet_declaration (tree task_decl);
 static tree build_task_body (const_tree task_decl);
+static tree build_pointer_lookup (tree pointer);
+
 
 /* Lookup the StarPU function NAME in the global scope and store the result
    in VAR (this can't be done from `lower_starpu'.)  */
@@ -331,45 +333,53 @@ handle_pragma_wait (struct cpp_reader *reader)
   add_stmt (build_call_expr (fndecl, 0));
 }
 
-/* Process `#pragma starpu register VAR [COUNT]' and emit the corresponding
-   `starpu_vector_data_register' call.  */
+/* Parse a pointer variable for PRAGMA, raising the appropriate error if
+   needed.  Return the pointer variable on success, NULL_TREE otherwise.  */
 
-static void
-handle_pragma_register (struct cpp_reader *reader)
+static tree
+read_pragma_pointer_variable (const char *pragma, location_t loc)
 {
-  tree token;
-  location_t loc;
+  tree token, var = NULL_TREE;
   enum cpp_ttype type;
 
-  loc = cpp_peek_token (reader, 0)->src_loc;
-
   type = pragma_lex (&token);
   if (type == CPP_EOF)
-    {
-      error_at (loc, "unterminated %<starpu register%> pragma");
-      return;
-    }
+    error_at (loc, "unterminated %<starpu %s%> pragma", pragma);
   else if (type != CPP_NAME)
+    error_at (loc, "identifier expected");
+  else
     {
-      error_at (loc, "identifier expected");
-      return;
+      /* Get the variable name.  */
+      tree var_name = token;
+      tree decl = lookup_name (var_name);
+
+      if (decl == NULL_TREE || !DECL_P (decl))
+	error_at (loc, "unbound variable %qE", var_name);
+      else if (!POINTER_TYPE_P (TREE_TYPE (decl))
+	       && TREE_CODE (TREE_TYPE (decl)) != ARRAY_TYPE)
+	error_at (loc, "%qE is neither a pointer nor an array", var_name);
+      else
+	var = decl;
     }
 
-  /* Get the variable name.  */
-  tree var_name = token;
-  tree var = lookup_name (var_name);
-  if (var == NULL_TREE || !DECL_P (var))
-    {
-      error_at (loc, "unbound variable %qE", var_name);
-      return;
-    }
+  return var;
+}
 
-  if (!POINTER_TYPE_P (TREE_TYPE (var))
-      && TREE_CODE (TREE_TYPE (var)) != ARRAY_TYPE)
-    {
-      error_at (loc, "%qE is neither a pointer nor an array", var_name);
-      return;
-    }
+/* Process `#pragma starpu register VAR [COUNT]' and emit the corresponding
+   `starpu_vector_data_register' call.  */
+
+static void
+handle_pragma_register (struct cpp_reader *reader)
+{
+  tree token, var;
+  location_t loc;
+  enum cpp_ttype type;
+
+  loc = cpp_peek_token (reader, 0)->src_loc;
+
+  var = read_pragma_pointer_variable ("register", loc);
+  if (var == NULL_TREE)
+    return;
 
   if (TREE_CODE (TREE_TYPE (var)) == ARRAY_TYPE
       && !DECL_EXTERNAL (var)
@@ -407,7 +417,7 @@ handle_pragma_register (struct cpp_reader *reader)
 	 size was determined.  */
       if (count == NULL_TREE)
 	{
-	  error_at (loc, "cannot determine size of array %qE", var_name);
+	  error_at (loc, "cannot determine size of array %qE", DECL_NAME (var));
 	  return;
 	}
     }
@@ -441,7 +451,7 @@ handle_pragma_register (struct cpp_reader *reader)
 	  /* The number of elements of this array was already determined.  */
 	  inform (loc,
 		  "element count can be omitted for bounded array %qE",
-		  var_name);
+		  DECL_NAME (var));
 
 	  if (count_arg != NULL_TREE)
 	    {
@@ -449,7 +459,8 @@ handle_pragma_register (struct cpp_reader *reader)
 		{
 		  if (!tree_int_cst_equal (count, count_arg))
 		    error_at (loc, "specified element count differs "
-			      "from actual size of array %qE", var_name);
+			      "from actual size of array %qE",
+			      DECL_NAME (var));
 		}
 	      else
 		/* Using a variable to determine the array size whereas the
@@ -490,6 +501,40 @@ handle_pragma_register (struct cpp_reader *reader)
   add_stmt (call);
 }
 
+/* Process `#pragma starpu acquire VAR' and emit the corresponding
+   `starpu_data_acquire' call.  */
+
+static void
+handle_pragma_acquire (struct cpp_reader *reader)
+{
+  static tree acquire_fn;
+  LOOKUP_STARPU_FUNCTION (acquire_fn, "starpu_data_acquire");
+
+  tree token, var;
+  location_t loc;
+
+  loc = cpp_peek_token (reader, 0)->src_loc;
+
+  var = read_pragma_pointer_variable ("register", loc);
+  if (var == NULL_TREE)
+    return;
+
+  if (pragma_lex (&token) != CPP_EOF)
+    error_at (loc, "junk after %<starpu acquire%> pragma");
+
+  /* If VAR is an array, take its address.  */
+  tree pointer =
+    POINTER_TYPE_P (TREE_TYPE (var))
+    ? var
+    : build_addr (var, current_function_decl);
+
+  /* Call `starpu_data_acquire (starpu_data_lookup (ptr), STARPU_RW)'.
+     TODO: Support modes other than RW.  */
+  add_stmt (build_call_expr (acquire_fn, 2,
+			     build_pointer_lookup (pointer),
+			     build_int_cst (integer_type_node, STARPU_RW)));
+}
+
 static void
 register_pragmas (void *gcc_data, void *user_data)
 {
@@ -501,6 +546,8 @@ register_pragmas (void *gcc_data, void *user_data)
 		     handle_pragma_wait);
   c_register_pragma_with_expansion (STARPU_PRAGMA_NAME_SPACE, "register",
 				    handle_pragma_register);
+  c_register_pragma_with_expansion (STARPU_PRAGMA_NAME_SPACE, "acquire",
+				    handle_pragma_acquire);
 }
 
 

+ 2 - 0
gcc-plugin/tests/Makefile.am

@@ -19,6 +19,8 @@ gcc_tests =					\
   pointers.c					\
   register.c					\
   register-errors.c				\
+  acquire.c					\
+  acquire-errors.c				\
   task-errors.c					\
   scalar-tasks.c				\
   pointer-tasks.c				\

+ 47 - 0
gcc-plugin/tests/acquire-errors.c

@@ -0,0 +1,47 @@
+/* GCC-StarPU
+   Copyright (C) 2011 Institut National de Recherche en Informatique et Automatique
+
+   GCC-StarPU 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.
+
+   GCC-StarPU 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-StarPU.  If not, see <http://www.gnu.org/licenses/>.  */
+
+extern float *y;
+
+static const double a[123];
+
+int
+main (int argc, char *argv[])
+{
+#pragma starpu initialize
+
+  int x[123] __attribute__ ((unused));
+  static char z[345] __attribute__ ((unused));
+
+#pragma starpu register x
+
+#pragma starpu acquire /* (error "unterminated") */
+#pragma starpu acquire 123 /* (error "identifier expected") */
+#pragma starpu acquire does_not_exit /* (error "unbound variable") */
+
+#pragma starpu acquire argc /* (error "neither a pointer nor an array") */
+#pragma starpu acquire y
+#pragma starpu acquire x
+
+  /* XXX: Uncomment below when this is supported.  */
+#if 0
+#pragma starpu acquire z /* error "not registered" */
+#pragma starpu acquire a /* error "not registered" */
+#pragma starpu acquire argv /* error "not registered" */
+#endif
+
+  return 1;
+}

+ 51 - 0
gcc-plugin/tests/acquire.c

@@ -0,0 +1,51 @@
+/* GCC-StarPU
+   Copyright (C) 2011 Institut National de Recherche en Informatique et Automatique
+
+   GCC-StarPU 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.
+
+   GCC-StarPU 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-StarPU.  If not, see <http://www.gnu.org/licenses/>.  */
+
+/* Test whether `#pragma starpu acquire ...' generates the right code.  */
+
+#undef NDEBUG
+
+#include <lib.h>
+
+int
+main (int argc, char *argv[])
+{
+#pragma starpu initialize
+
+  int x[123];
+  static char z[345];
+
+  expected_register_arguments.pointer = x;
+  expected_register_arguments.elements = 123;
+  expected_register_arguments.element_size = sizeof x[0];
+#pragma starpu register x
+
+  expected_acquire_arguments.pointer = x;
+#pragma starpu acquire x
+
+  expected_register_arguments.pointer = z;
+  expected_register_arguments.elements = sizeof z;
+  expected_register_arguments.element_size = sizeof z[0];
+#pragma starpu register z
+
+  expected_acquire_arguments.pointer = z;
+#pragma starpu acquire z
+
+  assert (data_register_calls == 2);
+  assert (data_acquire_calls == 2);
+
+  return EXIT_SUCCESS;
+}

+ 29 - 0
gcc-plugin/tests/lib.h

@@ -220,6 +220,35 @@ starpu_vector_data_register (starpu_data_handle *handle,
 }
 
 
+/* Data acquisition.  */
+
+struct data_acquire_arguments
+{
+  /* Pointer to the data being acquired.  */
+  void *pointer;
+};
+
+/* Number of `starpu_vector_data_acquire' calls.  */
+static unsigned int data_acquire_calls;
+
+/* Variable describing the expected `starpu_vector_data_acquire'
+   arguments.  */
+struct data_acquire_arguments expected_acquire_arguments;
+
+int
+starpu_data_acquire (starpu_data_handle handle, starpu_access_mode mode)
+{
+  /* XXX: Currently only `STARPU_RW'.  */
+  assert (mode == STARPU_RW);
+
+  assert (dummy_handle_to_pointer (handle)
+	  == expected_acquire_arguments.pointer);
+  data_acquire_calls++;
+
+  return 0;
+}
+
+
 /* Initialization.  */
 
 static int initialized;