소스 검색

gcc: Split the source into several files.

* gcc-plugin/src/utils.c, gcc-plugin/src/utils.h,
  gcc-plugin/src/warn-unregistered.c,
  gcc-plugin/src/warn-unregistered.h: New files.

* gcc-plugin/src/Makefile.am (starpu_la_SOURCES): Add `utils.c' and
  `warn-unregistered.c'.
  (noinst_HEADERS): New variable.
  (AM_CPPFLAGS): Add `-I$(srcdir)'.
Ludovic Courtès 12 년 전
부모
커밋
a007bb5df7
6개의 변경된 파일411개의 추가작업 그리고 279개의 파일을 삭제
  1. 11 2
      gcc-plugin/src/Makefile.am
  2. 4 277
      gcc-plugin/src/starpu.c
  3. 44 0
      gcc-plugin/src/utils.c
  4. 68 0
      gcc-plugin/src/utils.h
  5. 259 0
      gcc-plugin/src/warn-unregistered.c
  6. 25 0
      gcc-plugin/src/warn-unregistered.h

+ 11 - 2
gcc-plugin/src/Makefile.am

@@ -17,15 +17,24 @@
 # requires a name prefixed by `lib'.
 gccplugin_LTLIBRARIES = starpu.la
 
-starpu_la_SOURCES = starpu.c c-expr.y
+starpu_la_SOURCES =				\
+  c-expr.y					\
+  starpu.c					\
+  utils.c					\
+  warn-unregistered.c
+
+noinst_HEADERS =				\
+  utils.h					\
+  warn-unregistered.h
 
 # Use the Yacc-compatibility mode so that Bison doesn't error out upon
 # reduce/reduce conflicts.
 AM_YFLAGS = -y
 
 AM_CPPFLAGS =						\
+  -I$(srcdir)						\
   -I$(top_srcdir)/include				\
-  -I$(GCC_PLUGIN_INCLUDE_DIR) -Wall -DYYERROR_VERBOSE=1 \
+  -I$(GCC_PLUGIN_INCLUDE_DIR) -Wall -DYYERROR_VERBOSE=1	\
   $(STARPU_CUDA_CPPFLAGS) $(STARPU_OPENCL_CPPFLAGS)
 
 AM_LDFLAGS = -module

+ 4 - 277
gcc-plugin/src/starpu.c

@@ -47,7 +47,6 @@
 #endif
 
 #include <tm.h>
-#include <gimple.h>
 #include <tree-pass.h>
 #include <tree-flow.h>
 #include <cgraph.h>
@@ -57,52 +56,21 @@
 #include <stdio.h>
 #include <sys/mman.h>
 
+/* GCC-StarPU headers.  */
+#include <utils.h>
+#include <warn-unregistered.h>
+
 /* Don't include the dreaded proprietary headers that we don't need anyway.
    In particular, this waives the obligation to reproduce their silly
    disclaimer.  */
 #define STARPU_DONT_INCLUDE_CUDA_HEADERS
 
 
-
-/* GCC 4.7 requires compilation with `g++', and C++ lacks a number of GNU C
-   features, so work around that.  */
-
-#ifdef __cplusplus
-
-/* G++ doesn't implement nested functions, so use C++11 lambdas instead.  */
-
-# include <functional>
-
-# define local_define(ret, name, parms)     auto name = [=]parms
-# define function_parm(ret, name, parms)    std::function<ret parms> name
-
-/* G++ lacks designated initializers.  */
-# define designated_field_init(name, value) value /* XXX: cross fingers */
-
-#else  /* !__cplusplus */
-
-/* GNU C nested functions.  */
-
-# define local_define(ret, name, parms)	    ret name parms
-# define function_parm(ret, name, parms)    ret (*name) parms
-
-/* Designated field initializer.  */
-
-# define designated_field_init(name, value) .name = value
-
-#endif	/* !__cplusplus */
-
-
 /* C expression parser, possibly with C++ linkage.  */
 
 extern int yyparse (location_t, const char *, tree *);
 extern int yydebug;
 
-/* This declaration is from `c-tree.h', but that header doesn't get
-   installed.  */
-
-extern tree xref_tag (enum tree_code, tree);
-
 #ifndef STRINGIFY
 # define STRINGIFY_(x) # x
 # define STRINGIFY(x)  STRINGIFY_ (x)
@@ -119,15 +87,11 @@ int plugin_is_GPL_compatible;
 /* The name of this plug-in.  */
 static const char plugin_name[] = "starpu";
 
-/* Whether to enable verbose output.  */
-static bool verbose_output_p = false;
-
 /* Search path for OpenCL source files for the `opencl' pragma, as a
    `TREE_LIST'.  */
 static tree opencl_include_dirs = NULL_TREE;
 
 /* Names of public attributes.  */
-static const char task_attribute_name[] = "task";
 static const char task_implementation_attribute_name[] = "task_implementation";
 static const char output_attribute_name[] = "output";
 static const char heap_allocated_attribute_name[] = "heap_allocated";
@@ -175,7 +139,6 @@ static void define_task (tree task_decl);
 static tree build_pointer_lookup (tree pointer);
 static tree type_decl_for_struct_tag (const char *tag);
 
-static bool task_p (const_tree decl);
 static bool task_implementation_p (const_tree decl);
 static tree task_implementation_task (const_tree task_impl);
 static int task_implementation_where (const_tree task_impl);
@@ -2180,16 +2143,6 @@ task_codelet_declaration (const_tree task_decl)
   return TREE_VALUE (cl_attr);
 }
 
-/* Return true if DECL is a task.  */
-
-static bool
-task_p (const_tree decl)
-{
-  return (TREE_CODE (decl) == FUNCTION_DECL &&
-	  lookup_attribute (task_attribute_name,
-			    DECL_ATTRIBUTES (decl)) != NULL_TREE);
-}
-
 /* Return true if DECL is a task implementation.  */
 
 static bool
@@ -3296,206 +3249,6 @@ validate_task_implementation (tree impl)
       }
 }
 
-/* Return true if there exists a `starpu_vector_data_register' call for VAR
-   before GSI in its basic block.  */
-
-static bool
-registration_in_bb_p (gimple_stmt_iterator gsi, tree var)
-{
-  gcc_assert (SSA_VAR_P (var));
-
-  tree register_fn_name;
-
-  register_fn_name = get_identifier ("starpu_vector_data_register");
-
-  local_define (bool, registration_function_p, (const_tree obj))
-  {
-    /* TODO: Compare against the real fndecl.  */
-    return (obj != NULL_TREE
-	    && TREE_CODE (obj) == FUNCTION_DECL
-	    && DECL_NAME (obj) == register_fn_name);
-  };
-
-  bool found;
-
-  for (found = false;
-       !gsi_end_p (gsi) && !found;
-       gsi_prev (&gsi))
-    {
-      gimple stmt;
-
-      stmt = gsi_stmt (gsi);
-      if (is_gimple_call (stmt))
-	{
-	  tree fn = gimple_call_fndecl (stmt);
-	  if (registration_function_p (fn))
-	    {
-	      tree arg = gimple_call_arg (stmt, 2);
-	      if (is_gimple_address (arg))
-	      	arg = TREE_OPERAND (arg, 0);
-
-	      if (((TREE_CODE (arg) == VAR_DECL
-		    || TREE_CODE (arg) == VAR_DECL)
-		   && refs_may_alias_p (arg, var))
-
-		  /* Both VAR and ARG should be SSA names, otherwise, if ARG
-		     is a VAR_DECL, `ptr_derefs_may_alias_p' will
-		     conservatively assume that they may alias.  */
-		  || (TREE_CODE (var) == SSA_NAME
-		      && TREE_CODE (arg) != VAR_DECL
-		      && ptr_derefs_may_alias_p (arg, var)))
-		{
-		  if (verbose_output_p)
-		    {
-		      var = TREE_CODE (var) == SSA_NAME ? SSA_NAME_VAR (var) : var;
-		      inform (gimple_location (stmt),
-			      "found registration of variable %qE",
-			      DECL_NAME (var));
-		    }
-		  found = true;
-		}
-	    }
-	}
-    }
-
-  return found;
-}
-
-/* Return true if BB is dominated by a registration of VAR.  */
-
-static bool
-dominated_by_registration (gimple_stmt_iterator gsi, tree var)
-{
-  /* Is there a registration call for VAR in GSI's basic block?  */
-  if (registration_in_bb_p (gsi, var))
-    return true;
-
-  edge e;
-  edge_iterator ei;
-  bool found = false;
-
-  /* If every incoming edge is dominated by a registration, then we're
-     fine.
-
-     FIXME: This triggers false positives when registration is done in a
-     loop, because there's always an edge through which no registration
-     happens--the edge corresponding to the case where the loop is not
-     entered.  */
-
-  FOR_EACH_EDGE (e, ei, gsi_bb (gsi)->preds)
-    {
-      if (!dominated_by_registration (gsi_last_bb (e->src), var))
-	return false;
-      else
-	found = true;
-    }
-
-  return found;
-}
-
-/* Return true if NAME aliases a global variable or a PARM_DECL.  Note that,
-   for the former, `ptr_deref_may_alias_global_p' is way too conservative,
-   hence this approach.  */
-
-static bool
-ssa_name_aliases_global_or_parm_p (const_tree name)
-{
-  gcc_assert (TREE_CODE (name) == SSA_NAME);
-
-  if (TREE_CODE (SSA_NAME_VAR (name)) == PARM_DECL)
-    return true;
-  else
-    {
-      gimple def_stmt;
-
-      def_stmt = SSA_NAME_DEF_STMT (name);
-      if (is_gimple_assign (def_stmt))
-	{
-	  tree rhs = gimple_assign_rhs1 (def_stmt);
-
-	  if (TREE_CODE (rhs) == VAR_DECL
-	      && (DECL_EXTERNAL (rhs) || TREE_STATIC (rhs)))
-	    return true;
-	}
-    }
-
-  return false;
-}
-
-
-/* Validate the arguments passed to tasks in FN's body.  */
-
-static void
-validate_task_invocations (tree fn)
-{
-  gcc_assert (TREE_CODE (fn) == FUNCTION_DECL);
-
-  const struct cgraph_node *cgraph;
-  const struct cgraph_edge *callee;
-
-  cgraph = cgraph_get_node (fn);
-
-  /* When a definition of IMPL is available, check its callees.  */
-  if (cgraph != NULL)
-    for (callee = cgraph->callees;
-	 callee != NULL;
-	 callee = callee->next_callee)
-      {
-	if (task_p (callee->callee->decl))
-	  {
-	    unsigned i;
-	    gimple call_stmt = callee->call_stmt;
-
-	    for (i = 0; i < gimple_call_num_args (call_stmt); i++)
-	      {
-		tree arg = gimple_call_arg (call_stmt, i);
-
-		if (TREE_CODE (arg) == ADDR_EXPR
-		    && TREE_CODE (TREE_OPERAND (arg, 0)) == VAR_DECL
-		    && (TREE_CODE (TREE_TYPE (TREE_OPERAND (arg, 0)))
-			== ARRAY_TYPE))
-		  /* This is a "pointer-to-array" of a variable, so what we
-		     really care about is the variable itself.  */
-		  arg = TREE_OPERAND (arg, 0);
-
-		if ((POINTER_TYPE_P (TREE_TYPE (arg))
-		     || (TREE_CODE (TREE_TYPE (arg)) == ARRAY_TYPE))
-		    && ((TREE_CODE (arg) == VAR_DECL
-			 && !TREE_STATIC (arg)
-			 && !DECL_EXTERNAL (arg)
-			 && !TREE_NO_WARNING (arg))
-			|| (TREE_CODE (arg) == SSA_NAME
-			    && !ssa_name_aliases_global_or_parm_p (arg))))
-		  {
-		    if (!dominated_by_registration (gsi_for_stmt (call_stmt),
-						    arg))
-		      {
-			if (TREE_CODE (arg) == SSA_NAME)
-			  {
-			    tree var = SSA_NAME_VAR (arg);
-			    if (DECL_NAME (var) != NULL)
-			      arg = var;
-
-			    /* TODO: Check whether we can get the original
-			       variable name via ARG's DEF_STMT.  */
-			  }
-
-			if (TREE_CODE (arg) == VAR_DECL
-			    && DECL_NAME (arg) != NULL_TREE)
-			  warning_at (gimple_location (call_stmt), 0,
-				      "variable %qE may be used unregistered",
-				      DECL_NAME (arg));
-			else
-			  warning_at (gimple_location (call_stmt), 0,
-				      "argument %i may be used unregistered",
-				      i);
-		      }
-		  }
-	      }
-	  }
-      }
-}
-
 static unsigned int
 lower_starpu (void)
 {
@@ -3591,22 +3344,6 @@ lower_starpu (void)
   return 0;
 }
 
-/* A pass to warn about possibly unregistered task arguments.  */
-
-static unsigned int
-warn_starpu_unregistered (void)
-{
-  tree fndecl;
-
-  fndecl = current_function_decl;
-  gcc_assert (TREE_CODE (fndecl) == FUNCTION_DECL);
-
-  if (!task_p (fndecl))
-    validate_task_invocations (fndecl);
-
-  return 0;
-}
-
 static struct opt_pass pass_lower_starpu =
   {
     designated_field_init (type, GIMPLE_PASS),
@@ -3617,16 +3354,6 @@ static struct opt_pass pass_lower_starpu =
     /* The rest is zeroed.  */
   };
 
-static struct opt_pass pass_warn_starpu_unregistered =
-  {
-    designated_field_init (type, GIMPLE_PASS),
-    designated_field_init (name, "warn_starpu_unregistered"),
-    designated_field_init (gate, NULL),
-    designated_field_init (execute, warn_starpu_unregistered),
-
-    /* The rest is zeroed.  */
-  };
-
 
 /* Initialization.  */
 

+ 44 - 0
gcc-plugin/src/utils.c

@@ -0,0 +1,44 @@
+/* GCC-StarPU
+   Copyright (C) 2012 Inria
+
+   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/>.  */
+
+#include <starpu-gcc-config.h>
+
+#include <gcc-plugin.h>
+#include <plugin-version.h>
+
+#include <plugin.h>
+#include <cpplib.h>
+#include <tree.h>
+#include <gimple.h>
+
+#include <utils.h>
+
+
+/* Whether to enable verbose output.  */
+bool verbose_output_p = false;
+
+/* Name of the `task' attribute.  */
+const char task_attribute_name[] = "task";
+
+/* Return true if DECL is a task.  */
+
+bool
+task_p (const_tree decl)
+{
+  return (TREE_CODE (decl) == FUNCTION_DECL &&
+	  lookup_attribute (task_attribute_name,
+			    DECL_ATTRIBUTES (decl)) != NULL_TREE);
+}

+ 68 - 0
gcc-plugin/src/utils.h

@@ -0,0 +1,68 @@
+/* GCC-StarPU
+   Copyright (C) 2012 Inria
+
+   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/>.  */
+
+/* Various utilities.  */
+
+#pragma once
+
+/* GCC 4.7 requires compilation with `g++', and C++ lacks a number of GNU C
+   features, so work around that.  */
+
+#ifdef __cplusplus
+
+/* G++ doesn't implement nested functions, so use C++11 lambdas instead.  */
+
+# include <functional>
+
+# define local_define(ret, name, parms)     auto name = [=]parms
+# define function_parm(ret, name, parms)    std::function<ret parms> name
+
+/* G++ lacks designated initializers.  */
+# define designated_field_init(name, value) value /* XXX: cross fingers */
+
+#else  /* !__cplusplus */
+
+/* GNU C nested functions.  */
+
+# define local_define(ret, name, parms)	    ret name parms
+# define function_parm(ret, name, parms)    ret (*name) parms
+
+/* Designated field initializer.  */
+
+# define designated_field_init(name, value) .name = value
+
+#endif /* !__cplusplus */
+
+
+extern bool verbose_output_p;
+extern const char task_attribute_name[];
+extern bool task_p (const_tree decl);
+
+
+#include <tree.h>
+
+/* This declaration is from `c-tree.h', but that header doesn't get
+   installed.  */
+
+extern tree xref_tag (enum tree_code, tree);
+
+
+/* Don't warn about the unused `gcc_version' variable, from
+   <plugin-version.h>.  */
+
+static const struct plugin_gcc_version *starpu_gcc_version
+  __attribute__ ((__unused__));
+static const struct plugin_gcc_version *starpu_gcc_version = &gcc_version;

+ 259 - 0
gcc-plugin/src/warn-unregistered.c

@@ -0,0 +1,259 @@
+/* GCC-StarPU
+   Copyright (C) 2012 Inria
+
+   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/>.  */
+
+/* Use extensions of the GNU C Library.  */
+#define _GNU_SOURCE 1
+
+#include <starpu-gcc-config.h>
+
+#include <gcc-plugin.h>
+#include <plugin-version.h>
+
+#include <plugin.h>
+#include <cpplib.h>
+#include <tree.h>
+#include <tree-pass.h>
+#include <gimple.h>
+#include <diagnostic.h>
+#include <cgraph.h>
+
+#include <utils.h>
+
+/* Return true if there exists a `starpu_vector_data_register' call for VAR
+   before GSI in its basic block.  */
+
+static bool
+registration_in_bb_p (gimple_stmt_iterator gsi, tree var)
+{
+  gcc_assert (SSA_VAR_P (var));
+
+  tree register_fn_name;
+
+  register_fn_name = get_identifier ("starpu_vector_data_register");
+
+  local_define (bool, registration_function_p, (const_tree obj))
+  {
+    /* TODO: Compare against the real fndecl.  */
+    return (obj != NULL_TREE
+	    && TREE_CODE (obj) == FUNCTION_DECL
+	    && DECL_NAME (obj) == register_fn_name);
+  };
+
+  bool found;
+
+  for (found = false;
+       !gsi_end_p (gsi) && !found;
+       gsi_prev (&gsi))
+    {
+      gimple stmt;
+
+      stmt = gsi_stmt (gsi);
+      if (is_gimple_call (stmt))
+	{
+	  tree fn = gimple_call_fndecl (stmt);
+	  if (registration_function_p (fn))
+	    {
+	      tree arg = gimple_call_arg (stmt, 2);
+	      if (is_gimple_address (arg))
+	      	arg = TREE_OPERAND (arg, 0);
+
+	      if (((TREE_CODE (arg) == VAR_DECL
+		    || TREE_CODE (arg) == VAR_DECL)
+		   && refs_may_alias_p (arg, var))
+
+		  /* Both VAR and ARG should be SSA names, otherwise, if ARG
+		     is a VAR_DECL, `ptr_derefs_may_alias_p' will
+		     conservatively assume that they may alias.  */
+		  || (TREE_CODE (var) == SSA_NAME
+		      && TREE_CODE (arg) != VAR_DECL
+		      && ptr_derefs_may_alias_p (arg, var)))
+		{
+		  if (verbose_output_p)
+		    {
+		      var = TREE_CODE (var) == SSA_NAME ? SSA_NAME_VAR (var) : var;
+		      inform (gimple_location (stmt),
+			      "found registration of variable %qE",
+			      DECL_NAME (var));
+		    }
+		  found = true;
+		}
+	    }
+	}
+    }
+
+  return found;
+}
+
+/* Return true if BB is dominated by a registration of VAR.  */
+
+static bool
+dominated_by_registration (gimple_stmt_iterator gsi, tree var)
+{
+  /* Is there a registration call for VAR in GSI's basic block?  */
+  if (registration_in_bb_p (gsi, var))
+    return true;
+
+  edge e;
+  edge_iterator ei;
+  bool found = false;
+
+  /* If every incoming edge is dominated by a registration, then we're
+     fine.
+
+     FIXME: This triggers false positives when registration is done in a
+     loop, because there's always an edge through which no registration
+     happens--the edge corresponding to the case where the loop is not
+     entered.  */
+
+  FOR_EACH_EDGE (e, ei, gsi_bb (gsi)->preds)
+    {
+      if (!dominated_by_registration (gsi_last_bb (e->src), var))
+	return false;
+      else
+	found = true;
+    }
+
+  return found;
+}
+
+/* Return true if NAME aliases a global variable or a PARM_DECL.  Note that,
+   for the former, `ptr_deref_may_alias_global_p' is way too conservative,
+   hence this approach.  */
+
+static bool
+ssa_name_aliases_global_or_parm_p (const_tree name)
+{
+  gcc_assert (TREE_CODE (name) == SSA_NAME);
+
+  if (TREE_CODE (SSA_NAME_VAR (name)) == PARM_DECL)
+    return true;
+  else
+    {
+      gimple def_stmt;
+
+      def_stmt = SSA_NAME_DEF_STMT (name);
+      if (is_gimple_assign (def_stmt))
+	{
+	  tree rhs = gimple_assign_rhs1 (def_stmt);
+
+	  if (TREE_CODE (rhs) == VAR_DECL
+	      && (DECL_EXTERNAL (rhs) || TREE_STATIC (rhs)))
+	    return true;
+	}
+    }
+
+  return false;
+}
+
+
+/* Validate the arguments passed to tasks in FN's body.  */
+
+static void
+validate_task_invocations (tree fn)
+{
+  gcc_assert (TREE_CODE (fn) == FUNCTION_DECL);
+
+  const struct cgraph_node *cgraph;
+  const struct cgraph_edge *callee;
+
+  cgraph = cgraph_get_node (fn);
+
+  /* When a definition of IMPL is available, check its callees.  */
+  if (cgraph != NULL)
+    for (callee = cgraph->callees;
+	 callee != NULL;
+	 callee = callee->next_callee)
+      {
+	if (task_p (callee->callee->decl))
+	  {
+	    unsigned i;
+	    gimple call_stmt = callee->call_stmt;
+
+	    for (i = 0; i < gimple_call_num_args (call_stmt); i++)
+	      {
+		tree arg = gimple_call_arg (call_stmt, i);
+
+		if (TREE_CODE (arg) == ADDR_EXPR
+		    && TREE_CODE (TREE_OPERAND (arg, 0)) == VAR_DECL
+		    && (TREE_CODE (TREE_TYPE (TREE_OPERAND (arg, 0)))
+			== ARRAY_TYPE))
+		  /* This is a "pointer-to-array" of a variable, so what we
+		     really care about is the variable itself.  */
+		  arg = TREE_OPERAND (arg, 0);
+
+		if ((POINTER_TYPE_P (TREE_TYPE (arg))
+		     || (TREE_CODE (TREE_TYPE (arg)) == ARRAY_TYPE))
+		    && ((TREE_CODE (arg) == VAR_DECL
+			 && !TREE_STATIC (arg)
+			 && !DECL_EXTERNAL (arg)
+			 && !TREE_NO_WARNING (arg))
+			|| (TREE_CODE (arg) == SSA_NAME
+			    && !ssa_name_aliases_global_or_parm_p (arg))))
+		  {
+		    if (!dominated_by_registration (gsi_for_stmt (call_stmt),
+						    arg))
+		      {
+			if (TREE_CODE (arg) == SSA_NAME)
+			  {
+			    tree var = SSA_NAME_VAR (arg);
+			    if (DECL_NAME (var) != NULL)
+			      arg = var;
+
+			    /* TODO: Check whether we can get the original
+			       variable name via ARG's DEF_STMT.  */
+			  }
+
+			if (TREE_CODE (arg) == VAR_DECL
+			    && DECL_NAME (arg) != NULL_TREE)
+			  warning_at (gimple_location (call_stmt), 0,
+				      "variable %qE may be used unregistered",
+				      DECL_NAME (arg));
+			else
+			  warning_at (gimple_location (call_stmt), 0,
+				      "argument %i may be used unregistered",
+				      i);
+		      }
+		  }
+	      }
+	  }
+      }
+}
+
+/* A pass to warn about possibly unregistered task arguments.  */
+
+static unsigned int
+warn_starpu_unregistered (void)
+{
+  tree fndecl;
+
+  fndecl = current_function_decl;
+  gcc_assert (TREE_CODE (fndecl) == FUNCTION_DECL);
+
+  if (!task_p (fndecl))
+    validate_task_invocations (fndecl);
+
+  return 0;
+}
+
+struct opt_pass pass_warn_starpu_unregistered =
+  {
+    designated_field_init (type, GIMPLE_PASS),
+    designated_field_init (name, "warn_starpu_unregistered"),
+    designated_field_init (gate, NULL),
+    designated_field_init (execute, warn_starpu_unregistered),
+
+    /* The rest is zeroed.  */
+  };

+ 25 - 0
gcc-plugin/src/warn-unregistered.h

@@ -0,0 +1,25 @@
+/* GCC-StarPU
+   Copyright (C) 2012 Inria
+
+   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/>.  */
+
+/* Buffer registration warning pass.  */
+
+#pragma once
+
+#include <tree-pass.h>
+
+/* A pass that warns about use of possibly unregistered buffers.  */
+
+extern struct opt_pass pass_warn_starpu_unregistered;