소스 검색

gcc: Check the return value of `starpu_data_lookup'.

* gcc-plugin/src/starpu.c (data_lookup_fn): New declaration.
  (build_error_statements): Add support for ERROR_VAR == NULL_TREE;
  (handle_task_attribute): Initialize DATA_LOOKUP_FN.
  (handle_pre_genericize): Set CURRENT_FUNCTION_DECL to TASK around
  `define_task' call.
  (build_pointer_lookup): Introduce a `TARGET_EXPR' that checks whether
  the returned handled is NULL.

* gcc-plugin/tests/output-pointer.c (main): Register X.
* gcc-plugin/tests/pointers.c (main): Register X and Y.
Ludovic Courtès 13 년 전
부모
커밋
1d33afe3cb
3개의 변경된 파일101개의 추가작업 그리고 30개의 파일을 삭제
  1. 74 28
      gcc-plugin/src/starpu.c
  2. 11 1
      gcc-plugin/tests/output-pointer.c
  3. 16 1
      gcc-plugin/tests/pointers.c

+ 74 - 28
gcc-plugin/src/starpu.c

@@ -86,7 +86,7 @@ static const char heap_allocated_orig_type_attribute_name[] =
 static const char codelet_struct_name[] = "starpu_codelet_gcc";
 
 /* Cached function declarations.  */
-static tree unpack_fn;
+static tree unpack_fn, data_lookup_fn;
 
 
 /* Forward declarations.  */
@@ -329,14 +329,9 @@ static tree build_error_statements (location_t, tree, const char *, ...)
 static tree
 build_error_statements (location_t loc, tree error_var, const char *fmt, ...)
 {
-  gcc_assert (TREE_CODE (error_var) == VAR_DECL
-	      && TREE_TYPE (error_var) == integer_type_node);
-
-  static tree strerror_fn;
-  LOOKUP_STARPU_FUNCTION (strerror_fn, "strerror");
-
   expanded_location xloc = expand_location (loc);
 
+  tree print;
   char *str, *fmt_long;
   va_list args;
 
@@ -346,18 +341,44 @@ build_error_statements (location_t loc, tree error_var, const char *fmt, ...)
      to be done in two steps.  */
 
   vasprintf (&str, fmt, args);
-  asprintf (&fmt_long, "%s:%d: error: %s: %%s\n",
-	    xloc.file, xloc.line, str);
 
-  tree error_code =
-    build1 (NEGATE_EXPR, TREE_TYPE (error_var), error_var);
-  tree print =
-    build_call_expr (built_in_decls[BUILT_IN_PRINTF], 2,
-		     build_string_literal (strlen (fmt_long) + 1, fmt_long),
-		     build_call_expr (strerror_fn, 1, error_code));
+  if (error_var != NULL_TREE)
+    {
+      /* ERROR_VAR is an error code.  */
+
+      static tree strerror_fn;
+      LOOKUP_STARPU_FUNCTION (strerror_fn, "strerror");
+
+      gcc_assert (TREE_CODE (error_var) == VAR_DECL
+		  && TREE_TYPE (error_var) == integer_type_node);
+
+      asprintf (&fmt_long, "%s:%d: error: %s: %%s\n",
+		xloc.file, xloc.line, str);
+
+      tree error_code =
+	build1 (NEGATE_EXPR, TREE_TYPE (error_var), error_var);
+      print =
+	build_call_expr (built_in_decls[BUILT_IN_PRINTF], 2,
+			 build_string_literal (strlen (fmt_long) + 1,
+					       fmt_long),
+			 build_call_expr (strerror_fn, 1, error_code));
+    }
+  else
+    {
+      /* No error code provided.  */
+
+      asprintf (&fmt_long, "%s:%d: error: %s\n",
+		xloc.file, xloc.line, str);
+
+      print =
+	build_call_expr (built_in_decls[BUILT_IN_PUTS], 1,
+			 build_string_literal (strlen (fmt_long) + 1,
+					       fmt_long));
+    }
 
   free (fmt_long);
   free (str);
+  va_end (args);
 
   tree stmts = NULL;
   append_to_statement_list (print, &stmts);
@@ -969,6 +990,7 @@ handle_task_attribute (tree *node, tree name, tree args,
 
   /* Lookup & cache function declarations for later reuse.  */
   LOOKUP_STARPU_FUNCTION (unpack_fn, "starpu_codelet_unpack_args");
+  LOOKUP_STARPU_FUNCTION (data_lookup_fn, "starpu_data_lookup");
 
   return NULL_TREE;
 }
@@ -1930,7 +1952,9 @@ handle_pre_genericize (void *gcc_data, void *user_data)
 			      TYPE_ARG_TYPES (TREE_TYPE (task))));
 
 	  /* Build its body.  */
+	  current_function_decl = task;
 	  define_task (task);
+	  current_function_decl = fn;
 
 	  /* Compile TASK's body.  */
 	  rest_of_decl_compilation (task, true, 0);
@@ -1947,23 +1971,45 @@ handle_pre_genericize (void *gcc_data, void *user_data)
 static tree
 build_pointer_lookup (tree pointer)
 {
-#if 0
-  gimple emit_error_message (void)
-  {
-    static const char msg[] =
-      "starpu: task called with unregistered pointer, aborting\n";
+  /* Make sure DATA_LOOKUP_FN is valid.  */
+  LOOKUP_STARPU_FUNCTION (data_lookup_fn, "starpu_data_lookup");
 
-    return gimple_build_call (built_in_decls[BUILT_IN_PUTS], 1,
-			      build_string_literal (strlen (msg) + 1, msg));
-  }
-#endif
+  location_t loc;
 
-  static tree data_lookup_fn;
-  LOOKUP_STARPU_FUNCTION (data_lookup_fn, "starpu_data_lookup");
+  if (DECL_P (pointer))
+    loc = DECL_SOURCE_LOCATION (pointer);
+  else
+    loc = UNKNOWN_LOCATION;
+
+  /* Introduce a local variable to hold the handle.  */
+
+  tree result_var = build_decl (loc, VAR_DECL,
+  				create_tmp_var_name (".data_lookup_result"),
+  				ptr_type_node);
+  DECL_CONTEXT (result_var) = current_function_decl;
+  DECL_ARTIFICIAL (result_var) = true;
+  DECL_SOURCE_LOCATION (result_var) = loc;
 
-  return build_call_expr (data_lookup_fn, 1, pointer);
+  tree call = build_call_expr (data_lookup_fn, 1, pointer);
+  tree assignment = build2 (INIT_EXPR, TREE_TYPE (result_var),
+  			    result_var, call);
+
+  /* Build `if (RESULT_VAR == NULL) error ();'.  */
+
+  tree cond = build3 (COND_EXPR, void_type_node,
+		      build2 (EQ_EXPR, boolean_type_node,
+			      result_var, null_pointer_node),
+		      build_error_statements (loc, NULL_TREE,
+					      "attempt to use unregistered "
+					      "pointer"),
+		      NULL_TREE);
+
+  tree stmts = NULL;
+  append_to_statement_list (assignment, &stmts);
+  append_to_statement_list (cond, &stmts);
+  append_to_statement_list (result_var, &stmts);
 
-  /* FIXME: Add `if (VAR == NULL) abort ();'.  */
+  return build4 (TARGET_EXPR, ptr_type_node, result_var, stmts, NULL_TREE, NULL_TREE);
 }
 
 /* Build the body of TASK_DECL, which will call `starpu_insert_task'.  */

+ 11 - 1
gcc-plugin/tests/output-pointer.c

@@ -1,5 +1,5 @@
 /* GCC-StarPU
-   Copyright (C) 2011 Institut National de Recherche en Informatique et Automatique
+   Copyright (C) 2011, 2012 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
@@ -74,6 +74,16 @@ main (int argc, char *argv[])
   size_t size = 42;
   int x[size];
 
+  /* Register X (don't use the pragma, to avoid mixing concerns in this
+     test.)  */
+
+  starpu_data_handle_t handle;
+
+  expected_register_arguments.pointer = x;
+  expected_register_arguments.elements = 42;
+  expected_register_arguments.element_size = sizeof x[0];
+  starpu_vector_data_register (&handle, 0, (uintptr_t) x, 42, sizeof x[0]);
+
   struct insert_task_argument expected[] =
     {
       { STARPU_VALUE, &size, sizeof size },

+ 16 - 1
gcc-plugin/tests/pointers.c

@@ -1,5 +1,5 @@
 /* GCC-StarPU
-   Copyright (C) 2011 Institut National de Recherche en Informatique et Automatique
+   Copyright (C) 2011, 2012 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
@@ -75,6 +75,21 @@ main (int argc, char *argv[])
   y = malloc (sizeof *y);
   *y = 77;
 
+  /* Register X and Y (don't use the pragma, to avoid mixing concerns in this
+     test.)  */
+
+  starpu_data_handle_t handle;
+
+  expected_register_arguments.pointer = x;
+  expected_register_arguments.elements = 1;
+  expected_register_arguments.element_size = sizeof x[0];
+  starpu_vector_data_register (&handle, 0, (uintptr_t) x, 1, sizeof x[0]);
+
+  expected_register_arguments.pointer = y;
+  expected_register_arguments.elements = 1;
+  expected_register_arguments.element_size = sizeof *y;
+  starpu_vector_data_register (&handle, 0, (uintptr_t) y, 1, sizeof *y);
+
   struct insert_task_argument expected_pointer_task[] =
     {
       { STARPU_R,  x },