This patch implements a new OpenACC target hook. It is used during
device-specific lowering and allows a backend to indicate whether it needs to
know about a fork/join for a particular axis.
For instance, in PTX we don't care about gang-level fork and join. We also
don't care if the size of that dimension is 1.
The default implementation of the hook never only cares if the oacc_fork and
oacc_join RTL expanders exist (and they don't on the host compiler).
nathan
2015-10-20 Nathan Sidwell <nat...@codesourcery.com>
* target.def (fork_join): New GOACC hook.
* targhooks.h (default_goacc_fork_join): Declare.
* omp-low.c (default_goacc_forkjoin): New.
* doc/tm.texi.in (TARGET_GOACC_FORK_JOIN): Add.
* doc/tm.texi: Regenerate.
* config/nvptx/nvptx.c (nvptx_xform_fork_join): New.
(TARGET_GOACC_FOR_JOIN): Override.
Index: config/nvptx/nvptx.c
===================================================================
--- config/nvptx/nvptx.c (revision 229096)
+++ config/nvptx/nvptx.c (working copy)
@@ -2146,7 +2146,26 @@ nvptx_goacc_validate_dims (tree ARG_UNUS
return changed;
}
-
+
+/* Determine whether fork & joins are needed. */
+
+static bool
+nvptx_xform_fork_join (gcall *call, const int dims[],
+ bool ARG_UNUSED (is_fork))
+{
+ tree arg = gimple_call_arg (call, 1);
+ unsigned axis = TREE_INT_CST_LOW (arg);
+
+ /* We only care about worker and vector partitioning. */
+ if (axis < GOMP_DIM_WORKER)
+ return true;
+
+ /* If the size is 1, there's no partitioning. */
+ if (dims[axis] == 1)
+ return true;
+
+ return false;
+}
#undef TARGET_OPTION_OVERRIDE
#define TARGET_OPTION_OVERRIDE nvptx_option_override
@@ -2236,6 +2255,9 @@ nvptx_goacc_validate_dims (tree ARG_UNUS
#undef TARGET_GOACC_VALIDATE_DIMS
#define TARGET_GOACC_VALIDATE_DIMS nvptx_goacc_validate_dims
+#undef TARGET_GOACC_FORK_JOIN
+#define TARGET_GOACC_FORK_JOIN nvptx_xform_fork_join
+
struct gcc_target targetm = TARGET_INITIALIZER;
#include "gt-nvptx.h"
Index: doc/tm.texi
===================================================================
--- doc/tm.texi (revision 229096)
+++ doc/tm.texi (working copy)
@@ -5748,7 +5748,7 @@ usable. In that case, the smaller the n
to use it.
@end deftypefn
-@deftypefn {Target Hook} bool TARGET_GOACC_VALIDATE_DIMS (tree @var{decl}, int @var{dims[]}, int @var{fn_level})
+@deftypefn {Target Hook} bool TARGET_GOACC_VALIDATE_DIMS (tree @var{decl}, int *@var{dims}, int @var{fn_level})
This hook should check the launch dimensions provided for an OpenACC
compute region, or routine. Defaulted values are represented as -1
and non-constant values as 0. The @var{fn_level} is negative for the
@@ -5760,6 +5760,13 @@ true, if changes have been made. You mu
provide dimensions larger than 1.
@end deftypefn
+@deftypefn {Target Hook} bool TARGET_GOACC_FORK_JOIN (gcall *@var{call}, const int *@var{dims}, bool @var{is_fork})
+This hook should convert IFN_GOACC_FORK and IFN_GOACC_JOIN function
+calls to target-specific gimple. It is executed during the oacc_xform
+pass. It should return true, if the functions should be deleted. The
+default hook returns true, if there are no RTL expanders for them.
+@end deftypefn
+
@node Anchored Addresses
@section Anchored Addresses
@cindex anchored addresses
Index: doc/tm.texi.in
===================================================================
--- doc/tm.texi.in (revision 229096)
+++ doc/tm.texi.in (working copy)
@@ -4249,6 +4249,8 @@ address; but often a machine-dependent
@hook TARGET_GOACC_VALIDATE_DIMS
+@hook TARGET_GOACC_FORK_JOIN
+
@node Anchored Addresses
@section Anchored Addresses
@cindex anchored addresses
Index: omp-low.c
===================================================================
--- omp-low.c (revision 229096)
+++ omp-low.c (working copy)
@@ -17532,6 +17532,29 @@ oacc_validate_dims (tree fn, tree attrs,
return fn_level;
}
+/* Default fork/join early expander. Delete the function calls if
+ there is no RTL expander. */
+
+bool
+default_goacc_fork_join (gcall *ARG_UNUSED (call),
+ const int *ARG_UNUSED (dims), bool is_fork)
+{
+ if (is_fork)
+ {
+#ifndef HAVE_oacc_fork
+ return true;
+#endif
+ }
+ else
+ {
+#ifndef HAVE_oacc_join
+ return true;
+#endif
+ }
+
+ return false;
+}
+
/* Main entry point for oacc transformations which run on the device
compiler after LTO, so we know what the target device is at this
point (including the host fallback). */
Index: target.def
===================================================================
--- target.def (revision 229096)
+++ target.def (working copy)
@@ -1655,9 +1655,19 @@ should fill in anything that needs to de
non-defaults. Diagnostics should be issued as appropriate. Return\n\
true, if changes have been made. You must override this hook to\n\
provide dimensions larger than 1.",
-bool, (tree decl, int dims[], int fn_level),
+bool, (tree decl, int *dims, int fn_level),
default_goacc_validate_dims)
+DEFHOOK
+(fork_join,
+"This hook should convert IFN_UNIQUE calls for IFN_UNIQUE_GOACC_FORK\n\
+and IFN_UNIQUE_GOACC_JOIN to target-specific gimple. It is executed\n\
+during the oacc_device_lower pass. It should return true, if the\n\
+functions should be deleted. The default hook returns true, if there\n\
+are no RTL expanders for these actions.",
+bool, (gcall *call, const int *dims, bool is_fork),
+default_goacc_fork_join)
+
HOOK_VECTOR_END (goacc)
/* Functions relating to vectorization. */
Index: targhooks.h
===================================================================
--- targhooks.h (revision 229096)
+++ targhooks.h (working copy)
@@ -109,6 +109,7 @@ extern void default_destroy_cost_data (v
/* OpenACC hooks. */
extern bool default_goacc_validate_dims (tree, int [], int);
+extern bool default_goacc_fork_join (gcall *, const int [], bool);
/* These are here, and not in hooks.[ch], because not all users of
hooks.h include tm.h, and thus we don't have CUMULATIVE_ARGS. */