* target.def (goacc.dim_limit): New hook.
authornathan <nathan@138bc75d-0d04-0410-961f-82ee72b054a4>
Thu, 5 Nov 2015 13:50:13 +0000 (13:50 +0000)
committernathan <nathan@138bc75d-0d04-0410-961f-82ee72b054a4>
Thu, 5 Nov 2015 13:50:13 +0000 (13:50 +0000)
* targhooks.h (default_goacc_dim_limit): Declare.
* doc/tm.texi.in (TARGET_GOACC_DIM_LIMIT): Add.
* doc/tm.texi: Rebuilt.
* omp-low.h (get_oacc_fn_dim_size, get_oacc_ifn_dim_arg): Declare.
* omp-low.c (get_oacc_fn_dim_size, get_oacc_ifn_dim_arg): New.
(default_goacc_dim_limit): New.
* config/nvptx/nvptx.c (PTX_VECTOR_LENGTH, PTX_WORKER_LENGTH): New.
(nvptx_goacc_dim_limit) New.
(TARGET_GOACC_DIM_LIMIT): Override.
* tree-vrp.c: Include omp-low.h, target.h.
(extract_range_basic): Add handling for IFN_GOACC_DIM_SIZE &
IFN_GOACC_DIM_POS.

git-svn-id: svn+ssh://gcc.gnu.org/svn/gcc/trunk@229809 138bc75d-0d04-0410-961f-82ee72b054a4

gcc/ChangeLog
gcc/config/nvptx/nvptx.c
gcc/doc/tm.texi
gcc/doc/tm.texi.in
gcc/omp-low.c
gcc/omp-low.h
gcc/target.def
gcc/targhooks.h
gcc/tree-vrp.c

index c7b238b..44e71f4 100644 (file)
@@ -1,3 +1,19 @@
+2015-11-05  Nathan Sidwell  <nathan@codesourcery.com>
+
+       * target.def (goacc.dim_limit): New hook.
+       * targhooks.h (default_goacc_dim_limit): Declare.
+       * doc/tm.texi.in (TARGET_GOACC_DIM_LIMIT): Add.
+       * doc/tm.texi: Rebuilt.
+       * omp-low.h (get_oacc_fn_dim_size, get_oacc_ifn_dim_arg): Declare.
+       * omp-low.c (get_oacc_fn_dim_size, get_oacc_ifn_dim_arg): New.
+       (default_goacc_dim_limit): New.
+       * config/nvptx/nvptx.c (PTX_VECTOR_LENGTH, PTX_WORKER_LENGTH): New.
+       (nvptx_goacc_dim_limit) New.
+       (TARGET_GOACC_DIM_LIMIT): Override.
+       * tree-vrp.c: Include omp-low.h, target.h.
+       (extract_range_basic): Add handling for IFN_GOACC_DIM_SIZE &
+       IFN_GOACC_DIM_POS.
+
 2015-11-05  Ilya Enkovich  <enkovich.gnu@gmail.com>
 
        * tree-vect-generic.c (do_compare): Use -1 for true
index dafb695..0204ad3 100644 (file)
@@ -3499,6 +3499,25 @@ nvptx_goacc_validate_dims (tree ARG_UNUSED (decl), int *ARG_UNUSED (dims),
   return changed;
 }
 
+/* Return maximum dimension size, or zero for unbounded.  */
+
+static int
+nvptx_dim_limit (int axis)
+{
+  switch (axis)
+    {
+    case GOMP_DIM_WORKER:
+      return PTX_WORKER_LENGTH;
+
+    case GOMP_DIM_VECTOR:
+      return PTX_VECTOR_LENGTH;
+
+    default:
+      break;
+    }
+  return 0;
+}
+
 /* Determine whether fork & joins are needed.  */
 
 static bool
@@ -4016,6 +4035,9 @@ nvptx_goacc_reduction (gcall *call)
 #undef TARGET_GOACC_VALIDATE_DIMS
 #define TARGET_GOACC_VALIDATE_DIMS nvptx_goacc_validate_dims
 
+#undef TARGET_GOACC_DIM_LIMIT
+#define TARGET_GOACC_DIM_LIMIT nvptx_dim_limit
+
 #undef TARGET_GOACC_FORK_JOIN
 #define TARGET_GOACC_FORK_JOIN nvptx_goacc_fork_join
 
index 1e6baa0..f394db7 100644 (file)
@@ -5777,6 +5777,11 @@ true, if changes have been made.  You must override this hook to
 provide dimensions larger than 1.
 @end deftypefn
 
+@deftypefn {Target Hook} int TARGET_GOACC_DIM_LIMIT (int @var{axis})
+This hook should return the maximum size of a particular dimension,
+or zero if unbounded.
+@end deftypefn
+
 @deftypefn {Target Hook} bool TARGET_GOACC_FORK_JOIN (gcall *@var{call}, const int *@var{dims}, bool @var{is_fork})
 This hook can be used to convert IFN_GOACC_FORK and IFN_GOACC_JOIN
 function calls to target-specific gimple, or indicate whether they
index 0529011..d188c57 100644 (file)
@@ -4262,6 +4262,8 @@ address;  but often a machine-dependent strategy can generate better code.
 
 @hook TARGET_GOACC_VALIDATE_DIMS
 
+@hook TARGET_GOACC_DIM_LIMIT
+
 @hook TARGET_GOACC_FORK_JOIN
 
 @hook TARGET_GOACC_REDUCTION
index ac88fa5..b72c3dd 100644 (file)
@@ -12096,6 +12096,41 @@ get_oacc_fn_attrib (tree fn)
   return lookup_attribute (OACC_FN_ATTRIB, DECL_ATTRIBUTES (fn));
 }
 
+/* Extract an oacc execution dimension from FN.  FN must be an
+   offloaded function or routine that has already had its execution
+   dimensions lowered to the target-specific values.  */
+
+int
+get_oacc_fn_dim_size (tree fn, int axis)
+{
+  tree attrs = get_oacc_fn_attrib (fn);
+  
+  gcc_assert (axis < GOMP_DIM_MAX);
+
+  tree dims = TREE_VALUE (attrs);
+  while (axis--)
+    dims = TREE_CHAIN (dims);
+
+  int size = TREE_INT_CST_LOW (TREE_VALUE (dims));
+
+  return size;
+}
+
+/* Extract the dimension axis from an IFN_GOACC_DIM_POS or
+   IFN_GOACC_DIM_SIZE call.  */
+
+int
+get_oacc_ifn_dim_arg (const gimple *stmt)
+{
+  gcc_checking_assert (gimple_call_internal_fn (stmt) == IFN_GOACC_DIM_SIZE
+                      || gimple_call_internal_fn (stmt) == IFN_GOACC_DIM_POS);
+  tree arg = gimple_call_arg (stmt, 0);
+  HOST_WIDE_INT axis = TREE_INT_CST_LOW (arg);
+
+  gcc_checking_assert (axis >= 0 && axis < GOMP_DIM_MAX);
+  return (int) axis;
+}
+
 /* Expand the GIMPLE_OMP_TARGET starting at REGION.  */
 
 static void
@@ -19015,6 +19050,18 @@ default_goacc_validate_dims (tree ARG_UNUSED (decl), int *dims,
   return changed;
 }
 
+/* Default dimension bound is unknown on accelerator and 1 on host. */
+
+int
+default_goacc_dim_limit (int ARG_UNUSED (axis))
+{
+#ifdef ACCEL_COMPILER
+  return 0;
+#else
+  return 1;
+#endif
+}
+
 namespace {
 
 const pass_data pass_data_oacc_device_lower =
index 2fb2028..ee0f8ac 100644 (file)
@@ -31,6 +31,8 @@ extern bool make_gimple_omp_edges (basic_block, struct omp_region **, int *);
 extern void omp_finish_file (void);
 extern tree omp_member_access_dummy_var (tree);
 extern tree get_oacc_fn_attrib (tree);
+extern int get_oacc_ifn_dim_arg (const gimple *);
+extern int get_oacc_fn_dim_size (tree, int);
 
 extern GTY(()) vec<tree, va_gc> *offload_funcs;
 extern GTY(()) vec<tree, va_gc> *offload_vars;
index 461af6b..c7ec292 100644 (file)
@@ -1659,6 +1659,13 @@ bool, (tree decl, int *dims, int fn_level),
 default_goacc_validate_dims)
 
 DEFHOOK
+(dim_limit,
+"This hook should return the maximum size of a particular dimension,\n\
+or zero if unbounded.",
+int, (int axis),
+default_goacc_dim_limit)
+
+DEFHOOK
 (fork_join,
 "This hook can be used to convert IFN_GOACC_FORK and IFN_GOACC_JOIN\n\
 function calls to target-specific gimple, or indicate whether they\n\
index c34e4ae..a8e7ebb 100644 (file)
@@ -110,6 +110,7 @@ extern void default_destroy_cost_data (void *);
 
 /* OpenACC hooks.  */
 extern bool default_goacc_validate_dims (tree, int [], int);
+extern int default_goacc_dim_limit (int);
 extern bool default_goacc_fork_join (gcall *, const int [], bool);
 extern void default_goacc_reduction (gcall *);
 
index 807c6ec..c0b6cfc 100644 (file)
@@ -55,8 +55,8 @@ along with GCC; see the file COPYING3.  If not see
 #include "tree-ssa-threadupdate.h"
 #include "tree-ssa-scopedtables.h"
 #include "tree-ssa-threadedge.h"
-
-
+#include "omp-low.h"
+#include "target.h"
 
 /* Range of values that can be associated with an SSA_NAME after VRP
    has executed.  */
@@ -3973,7 +3973,9 @@ extract_range_basic (value_range *vr, gimple *stmt)
   else if (is_gimple_call (stmt) && gimple_call_internal_p (stmt))
     {
       enum tree_code subcode = ERROR_MARK;
-      switch (gimple_call_internal_fn (stmt))
+      unsigned ifn_code = gimple_call_internal_fn (stmt);
+
+      switch (ifn_code)
        {
        case IFN_UBSAN_CHECK_ADD:
          subcode = PLUS_EXPR;
@@ -3984,6 +3986,28 @@ extract_range_basic (value_range *vr, gimple *stmt)
        case IFN_UBSAN_CHECK_MUL:
          subcode = MULT_EXPR;
          break;
+       case IFN_GOACC_DIM_SIZE:
+       case IFN_GOACC_DIM_POS:
+         /* Optimizing these two internal functions helps the loop
+            optimizer eliminate outer comparisons.  Size is [1,N]
+            and pos is [0,N-1].  */
+         {
+           bool is_pos = ifn_code == IFN_GOACC_DIM_POS;
+           int axis = get_oacc_ifn_dim_arg (stmt);
+           int size = get_oacc_fn_dim_size (current_function_decl, axis);
+
+           if (!size)
+             /* If it's dynamic, the backend might know a hardware
+                limitation.  */
+             size = targetm.goacc.dim_limit (axis);
+
+           tree type = TREE_TYPE (gimple_call_lhs (stmt));
+           set_value_range (vr, VR_RANGE,
+                            build_int_cst (type, is_pos ? 0 : 1),
+                            size ? build_int_cst (type, size - is_pos)
+                                 : vrp_val_max (type), NULL);
+         }
+         return;
        default:
          break;
        }