Browse Source

gcc: Handle task calls with constants.

* gcc-plugin/src/starpu.c (build_task_submission): Return a `gimple_seq'
  instead of a `gimple'; update caller.
  [local_vars]: New nested function.  Introduce local variables for
  constant arguments, and pass them to INSERT_TASK_FN.

* gcc-plugin/tests/base.c (my_scalar_task): Add `z' parameter.
  (my_scalar_task_cpu, my_scalar_task_opencl): Update accordingly.
  (main): Update accordingly.  Add calls to `my_scalar_task' with
  constant arguments.

* gcc-plugin/tests/scalar-tasks.c (main): Call `my_scalar_task' with
  constants.
Ludovic Courtès 14 years ago
parent
commit
158ab2e66b
3 changed files with 85 additions and 20 deletions
  1. 62 7
      gcc-plugin/src/starpu.c
  2. 22 10
      gcc-plugin/tests/base.c
  3. 1 3
      gcc-plugin/tests/scalar-tasks.c

+ 62 - 7
gcc-plugin/src/starpu.c

@@ -35,6 +35,7 @@ int plugin_is_GPL_compatible;
 #include <tm.h>
 #include <gimple.h>
 #include <tree-pass.h>
+#include <tree-flow.h>
 #include <cgraph.h>
 #include <gimple.h>
 #include <toplev.h>
@@ -935,11 +936,55 @@ handle_pre_genericize (void *gcc_data, void *user_data)
 /* Build a call to `starpu_insert_task' for TASK_DECL, which will replace
    CALL.  */
 
-static gimple
+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
+     variables.  */
+
+  tree local_vars (gimple_seq *body)
+  {
+    size_t n;
+    tree vars = NULL_TREE;
+
+    for (n = 0; n < gimple_call_num_args (call); n++)
+      {
+	tree arg;
+
+	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)
+	  {
+	    /* ARG is a scalar constant.  Introduce a variable to hold it.  */
+	    tree var = create_tmp_var (TREE_TYPE (arg), ".literal-arg");
+
+	    /* Initialize VAR.  */
+	    gimple_seq init = NULL;
+	    tree modify = build2 (MODIFY_EXPR, TREE_TYPE (arg), var, arg);
+	    force_gimple_operand (modify, &init, true, var);
+
+	    gimple_seq_add_seq (body, init);
+
+	    if (vars != NULL_TREE)
+	      chainon (vars, var);
+	    else
+	      vars = var;
+	  }
+      }
+
+    return vars;
+  }
+
   size_t n;
   VEC(tree, heap) *args = NULL;
+  tree vars;
+  gimple_seq body = NULL;
+
+  vars = local_vars (&body);
 
   /* The first argument will be a pointer to the codelet.  */
 
@@ -970,7 +1015,15 @@ build_task_submission (tree task_decl, gimple call)
 	  /* A scalar: the arguments will be:
 	     `STARPU_VALUE, &scalar, sizeof (scalar)'.  */
 
-	  /* XXX: Currently the argument has to be a variable.  */
+	  if (TREE_CODE (arg) != VAR_DECL)
+	    {
+	      gcc_assert (TREE_CONSTANT (arg));
+
+	      /* ARG is a constant, so use the local variable we introduced
+		 to hold it.  */
+	      arg = vars;
+	      vars = TREE_CHAIN (vars);
+	    }
 	  gcc_assert (TREE_CODE (arg) == VAR_DECL);
 
 	  VEC_safe_push (tree, heap, args,
@@ -987,7 +1040,9 @@ build_task_submission (tree task_decl, gimple call)
   VEC_safe_push (tree, heap, args,
 		 build_int_cst (integer_type_node, 0));
 
-  return gimple_build_call_vec (insert_task_fn, args);
+  gimple_seq_add_stmt (&body, gimple_build_call_vec (insert_task_fn, args));
+
+  return body;
 }
 
 static unsigned int
@@ -1027,16 +1082,16 @@ lower_starpu (void)
 	{
 	  printf ("%s:     callee is a task\n", __func__);
 
-	  gimple call_site, submission;
+	  gimple call_site;
+	  gimple_seq submission;
 	  gimple_stmt_iterator gsi;
 
 	  call_site = callee->call_stmt;
 	  gsi = gsi_for_stmt (call_site);
 
 	  submission = build_task_submission (callee_decl, call_site);
-	  gsi_replace (&gsi, submission, true);
-
-	  gimple_set_block (submission, gimple_block (call_site));
+	  gsi_remove (&gsi, true);
+	  gsi_insert_seq_before (&gsi, submission, GSI_SAME_STMT);
 
 	  rebuild_cgraph_edges ();
 	}

+ 22 - 10
gcc-plugin/tests/base.c

@@ -21,23 +21,23 @@
 
 /* The task under test.  */
 
-static void my_scalar_task (int x, int y) __attribute__ ((task));
+static void my_scalar_task (int x, int y, int z) __attribute__ ((task));
 
-static void my_scalar_task_cpu (int, int)
+static void my_scalar_task_cpu (int, int, int)
   __attribute__ ((task_implementation ("cpu", my_scalar_task)));
-static void my_scalar_task_opencl (int, int)
+static void my_scalar_task_opencl (int, int, int)
   __attribute__ ((task_implementation ("opencl", my_scalar_task)));
 
 static void
-my_scalar_task_cpu (int x, int y)
+my_scalar_task_cpu (int x, int y, int z)
 {
-  printf ("%s: x = %i, y = %i\n", __func__, x, y);
+  printf ("%s: x = %i, y = %i, z = %i\n", __func__, x, y, z);
 }
 
 static void
-my_scalar_task_opencl (int x, int y)
+my_scalar_task_opencl (int x, int y, int z)
 {
-  printf ("%s: x = %i, y = %i\n", __func__, x, y);
+  printf ("%s: x = %i, y = %i, z = %i\n", __func__, x, y, z);
 }
 
 
@@ -46,12 +46,13 @@ main (int argc, char *argv[])
 {
 #pragma starpu hello
 
-  int x = 42, y = 77;
+  int x = 42, y = 77, z = 99;
 
   struct insert_task_argument expected[] =
     {
       { STARPU_VALUE, &x, sizeof (int) },
       { STARPU_VALUE, &y, sizeof (int) },
+      { STARPU_VALUE, &z, sizeof (int) },
       { 0, 0, 0 }
     };
 
@@ -59,9 +60,20 @@ main (int argc, char *argv[])
 
   /* Invoke the task, which should make sure it gets called with
      EXPECTED.  */
-  my_scalar_task (x, y);
+  my_scalar_task (x, y, z);
 
-  assert (tasks_submitted == 1);
+  /* Invoke the task using literal constants instead of variables.  */
+  my_scalar_task (42, y, z);
+  my_scalar_task (x, 77, z);
+  my_scalar_task (x, y, 99);
+
+  my_scalar_task (42, 77, z);
+  my_scalar_task (x, 77, 99);
+  my_scalar_task (42, y, 99);
+
+  my_scalar_task (42, 77, 99);
+
+  assert (tasks_submitted == 8);
 
   return EXIT_SUCCESS;
 }

+ 1 - 3
gcc-plugin/tests/scalar-tasks.c

@@ -51,8 +51,6 @@ my_scalar_task_opencl (int x, int y)
 int
 main (int argc, char *argv[])
 {
-  int x = 42, y = 77;
-
   /* FIXME: Eventually remove calls to libstarpu and use pragmas or generated
      code.  */
 
@@ -60,7 +58,7 @@ main (int argc, char *argv[])
 
   /* Invoke the task, which should make sure it gets called with
      EXPECTED.  */
-  my_scalar_task (x, y);
+  my_scalar_task (42, 77);
 
 #pragma starpu wait