aboutsummaryrefslogtreecommitdiff
diff options
context:
space:
mode:
authorJakub Jelinek <jakub@redhat.com>2015-11-06 07:06:25 +0000
committerJakub Jelinek <jakub@redhat.com>2015-11-06 07:06:25 +0000
commitad4bcd3232c39bb9a4b6efc84c1f4b7be70cd725 (patch)
tree61285831707b929d60cb82c794e77927fcab7a76
parentf047c2fee058a7d6feed99b8e8f89cd0823cd41a (diff)
parentec2c4ed734a21fb7a1595c9c568f2477375bac46 (diff)
svn merge -r229795:229809 svn+ssh://gcc.gnu.org/svn/gcc/trunk
git-svn-id: https://gcc.gnu.org/svn/gcc/branches/gomp-4_5-branch@229833 138bc75d-0d04-0410-961f-82ee72b054a4
-rw-r--r--gcc/ChangeLog21
-rw-r--r--gcc/config/nvptx/nvptx.c22
-rw-r--r--gcc/doc/tm.texi5
-rw-r--r--gcc/doc/tm.texi.in2
-rw-r--r--gcc/omp-low.c47
-rw-r--r--gcc/omp-low.h2
-rw-r--r--gcc/target.def7
-rw-r--r--gcc/targhooks.h1
-rw-r--r--gcc/tree-vect-generic.c8
-rw-r--r--gcc/tree-vrp.c30
10 files changed, 141 insertions, 4 deletions
diff --git a/gcc/ChangeLog b/gcc/ChangeLog
index 60ad78a2170..44e71f48d15 100644
--- a/gcc/ChangeLog
+++ b/gcc/ChangeLog
@@ -1,3 +1,24 @@
+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
+ result instead of 1.
+
2015-11-05 Ramana Radhakrishnan <ramana.radhakrishnan@arm.com>
* config/aarch64/aarch64.c
diff --git a/gcc/config/nvptx/nvptx.c b/gcc/config/nvptx/nvptx.c
index dafb6954690..0204ad3383e 100644
--- a/gcc/config/nvptx/nvptx.c
+++ b/gcc/config/nvptx/nvptx.c
@@ -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
diff --git a/gcc/doc/tm.texi b/gcc/doc/tm.texi
index 1e6baa0a080..f394db7d0a6 100644
--- a/gcc/doc/tm.texi
+++ b/gcc/doc/tm.texi
@@ -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
diff --git a/gcc/doc/tm.texi.in b/gcc/doc/tm.texi.in
index 0529011cb61..d188c57b75c 100644
--- a/gcc/doc/tm.texi.in
+++ b/gcc/doc/tm.texi.in
@@ -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
diff --git a/gcc/omp-low.c b/gcc/omp-low.c
index dec72491b18..86cc65500af 100644
--- a/gcc/omp-low.c
+++ b/gcc/omp-low.c
@@ -12279,6 +12279,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
@@ -19353,6 +19388,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 =
diff --git a/gcc/omp-low.h b/gcc/omp-low.h
index 2fb2028f6cf..ee0f8ac1ad5 100644
--- a/gcc/omp-low.h
+++ b/gcc/omp-low.h
@@ -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;
diff --git a/gcc/target.def b/gcc/target.def
index 461af6b14d8..c7ec2929714 100644
--- a/gcc/target.def
+++ b/gcc/target.def
@@ -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\
diff --git a/gcc/targhooks.h b/gcc/targhooks.h
index c34e4ae052c..a8e7ebbd8ca 100644
--- a/gcc/targhooks.h
+++ b/gcc/targhooks.h
@@ -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 *);
diff --git a/gcc/tree-vect-generic.c b/gcc/tree-vect-generic.c
index 4e96e87d02d..c64fdc4d46a 100644
--- a/gcc/tree-vect-generic.c
+++ b/gcc/tree-vect-generic.c
@@ -154,10 +154,16 @@ static tree
do_compare (gimple_stmt_iterator *gsi, tree inner_type, tree a, tree b,
tree bitpos, tree bitsize, enum tree_code code, tree type)
{
+ tree stype = TREE_TYPE (type);
+ tree cst_false = build_zero_cst (stype);
+ tree cst_true = build_all_ones_cst (stype);
+ tree cmp;
+
a = tree_vec_extract (gsi, inner_type, a, bitsize, bitpos);
b = tree_vec_extract (gsi, inner_type, b, bitsize, bitpos);
- return gimplify_build2 (gsi, code, TREE_TYPE (type), a, b);
+ cmp = build2 (code, boolean_type_node, a, b);
+ return gimplify_build3 (gsi, COND_EXPR, stype, cmp, cst_true, cst_false);
}
/* Expand vector addition to scalars. This does bit twiddling
diff --git a/gcc/tree-vrp.c b/gcc/tree-vrp.c
index 807c6ecc804..c0b6cfc1444 100644
--- a/gcc/tree-vrp.c
+++ b/gcc/tree-vrp.c
@@ -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;
}