Explorar o código

gcc: Handle task calls with non-addressable variables.

* gcc-plugin/src/starpu.c (build_task_submission)[local_vars]: Introduce
  local variables for anything that is not addressable; use it.  Mark the
  new variables as addressable.

* gcc-plugin/tests/base.c (my_scalar_task): Change type of `y' to
  `char'.
  (main): Update accordingly.
Ludovic Courtès %!s(int64=14) %!d(string=hai) anos
pai
achega
ba2754dd70
Modificáronse 2 ficheiros con 33 adicións e 25 borrados
  1. 21 14
      gcc-plugin/src/starpu.c
  2. 12 11
      gcc-plugin/tests/base.c

+ 21 - 14
gcc-plugin/src/starpu.c

@@ -940,8 +940,9 @@ static gimple_seq
 build_task_submission (tree task_decl, gimple call)
 {
   /* Return a chain of local variables that need to be introduced.  Variables
-     are introduced for each argument that is not a VAR_DECL, typically
-     scalar constants.  Populate BODY with the initial assignments to these
+     are introduced for each argument that is either a scalar constant or a
+     non-addressable variable---e.g., a `char' variable allocated in a
+     register.  Populate BODY with the initial assignments to these
      variables.  */
 
   tree local_vars (gimple_seq *body)
@@ -963,16 +964,23 @@ build_task_submission (tree task_decl, gimple call)
 
 	arg = gimple_call_arg (call, n);
 
-	if (!POINTER_TYPE_P (TREE_TYPE (arg))
-	    && TREE_CONSTANT (arg)
-	    && TREE_CODE (arg) != VAR_DECL
-	    && TREE_CODE (arg) != ADDR_EXPR)
+	if ((!POINTER_TYPE_P (TREE_TYPE (arg))
+	     && TREE_CONSTANT (arg)
+	     && TREE_CODE (arg) != VAR_DECL
+	     && TREE_CODE (arg) != ADDR_EXPR)
+	    || is_gimple_non_addressable (arg))
 	  {
-	    /* ARG is a scalar constant.  Introduce a variable to hold it.  */
-	    tree var = create_tmp_var (type, ".literal-arg");
-	    tree init_value = fold_convert (type, arg);
+	    /* ARG is a scalar constant or a non-addressable variable.
+	       Introduce a variable to hold it.  */
+	    tree var =
+	      create_tmp_var (type,
+			      is_gimple_non_addressable (arg)
+			      ? ".non-addressable-arg"
+			      : ".literal-arg");
+	    mark_addressable (var);
 
 	    /* Initialize VAR.  */
+	    tree init_value = fold_convert (type, arg);
 	    gimple_seq init = NULL;
 	    tree modify = build2 (MODIFY_EXPR, type, var, init_value);
 	    force_gimple_operand (modify, &init, true, var);
@@ -1025,16 +1033,15 @@ build_task_submission (tree task_decl, gimple call)
 	  /* A scalar: the arguments will be:
 	     `STARPU_VALUE, &scalar, sizeof (scalar)'.  */
 
-	  if (TREE_CODE (arg) != VAR_DECL)
+	  if (is_gimple_non_addressable (arg) || TREE_CONSTANT (arg))
 	    {
-	      gcc_assert (TREE_CONSTANT (arg));
-
-	      /* ARG is a constant, so use the local variable we introduced
-		 to hold it.  */
+	      /* Use the local variable we introduced to hold ARG's
+		 value.  */
 	      arg = vars;
 	      vars = TREE_CHAIN (vars);
 	    }
 	  gcc_assert (TREE_CODE (arg) == VAR_DECL);
+	  gcc_assert (TREE_ADDRESSABLE (arg));
 
 	  VEC_safe_push (tree, heap, args,
 			 build_int_cst (integer_type_node, STARPU_VALUE));

+ 12 - 11
gcc-plugin/tests/base.c

@@ -21,23 +21,23 @@
 
 /* The task under test.  */
 
-static void my_scalar_task (int x, int y, int z) __attribute__ ((task));
+static void my_scalar_task (int x, char y, int z) __attribute__ ((task));
 
-static void my_scalar_task_cpu (int, int, int)
+static void my_scalar_task_cpu (int, char, int)
   __attribute__ ((task_implementation ("cpu", my_scalar_task)));
-static void my_scalar_task_opencl (int, int, int)
+static void my_scalar_task_opencl (int, char, int)
   __attribute__ ((task_implementation ("opencl", my_scalar_task)));
 
 static void
-my_scalar_task_cpu (int x, int y, int z)
+my_scalar_task_cpu (int x, char y, int z)
 {
-  printf ("%s: x = %i, y = %i, z = %i\n", __func__, x, y, z);
+  printf ("%s: x = %i, y = %i, z = %i\n", __func__, x, (int) y, z);
 }
 
 static void
-my_scalar_task_opencl (int x, int y, int z)
+my_scalar_task_opencl (int x, char y, int z)
 {
-  printf ("%s: x = %i, y = %i, z = %i\n", __func__, x, y, z);
+  printf ("%s: x = %i, y = %i, z = %i\n", __func__, x, (int) y, z);
 }
 
 
@@ -46,13 +46,14 @@ main (int argc, char *argv[])
 {
 #pragma starpu hello
 
-  int x = 42, y = 77, z = 99;
+  int x = 42, z = 99;
+  char y = 77;
 
   struct insert_task_argument expected[] =
     {
-      { STARPU_VALUE, &x, sizeof (int) },
-      { STARPU_VALUE, &y, sizeof (int) },
-      { STARPU_VALUE, &z, sizeof (int) },
+      { STARPU_VALUE, &x, sizeof x },
+      { STARPU_VALUE, &y, sizeof y },
+      { STARPU_VALUE, &z, sizeof z },
       { 0, 0, 0 }
     };