target.def (goacc.dim_limit): New hook.
* 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. From-SVN: r229809
This commit is contained in:
parent
337d2167cc
commit
bd75197575
@ -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
|
||||
|
@ -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
|
||||
|
||||
|
@ -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
|
||||
|
@ -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
|
||||
|
@ -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 =
|
||||
|
@ -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;
|
||||
|
@ -1658,6 +1658,13 @@ provide dimensions larger than 1.",
|
||||
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\
|
||||
|
@ -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 *);
|
||||
|
||||
|
@ -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;
|
||||
}
|
||||
|
Loading…
Reference in New Issue
Block a user