Commit f8393eb0 by Nathan Sidwell Committed by Nathan Sidwell

omp-low.h (oacc_fn_attrib_kernels_p): Declare.

	* omp-low.h (oacc_fn_attrib_kernels_p): Declare.
	(set_oacc_fn_attrib): Add IS_KERNEL arg.
	* omp-low.c (set_oacc_fn_attrib): Add IS_KERNEL arg.
	(oacc_fn_attrib_kernels_p, oacc_fn_attrib_level): New.
	(expand_omp_target): Pass is_kernel to set_oacc_fn_attrib.
	(oacc_validate_dims): Add LEVEL arg, don't return level.
	(new_oacc_loop_routine): Use oacc_fn_attrib_level, not
	oacc_validate_dims.
	(execute_oacc_device_lower): Adjust, add more dump output.
	* tree-ssa-loop.c (gate_oacc_kernels): Use
	oacc_fn_attrib_kernels_p.
	* tree-parloops.c (create_parallel_loop): Adjust
	set_oacc_fn_attrib call.

From-SVN: r232830
parent b0b35f86
2016-01-26 Nathan Sidwell <nathan@acm.org>
* omp-low.h (oacc_fn_attrib_kernels_p): Declare.
(set_oacc_fn_attrib): Add IS_KERNEL arg.
* omp-low.c (set_oacc_fn_attrib): Add IS_KERNEL arg.
(oacc_fn_attrib_kernels_p, oacc_fn_attrib_level): New.
(expand_omp_target): Pass is_kernel to set_oacc_fn_attrib.
(oacc_validate_dims): Add LEVEL arg, don't return level.
(new_oacc_loop_routine): Use oacc_fn_attrib_level, not
oacc_validate_dims.
(execute_oacc_device_lower): Adjust, add more dump output.
* tree-ssa-loop.c (gate_oacc_kernels): Use
oacc_fn_attrib_kernels_p.
* tree-parloops.c (create_parallel_loop): Adjust
set_oacc_fn_attrib call.
2016-01-26 Jakub Jelinek <jakub@redhat.com> 2016-01-26 Jakub Jelinek <jakub@redhat.com>
PR lto/69254 PR lto/69254
......
...@@ -12487,10 +12487,11 @@ replace_oacc_fn_attrib (tree fn, tree dims) ...@@ -12487,10 +12487,11 @@ replace_oacc_fn_attrib (tree fn, tree dims)
/* Scan CLAUSES for launch dimensions and attach them to the oacc /* Scan CLAUSES for launch dimensions and attach them to the oacc
function attribute. Push any that are non-constant onto the ARGS function attribute. Push any that are non-constant onto the ARGS
list, along with an appropriate GOMP_LAUNCH_DIM tag. */ list, along with an appropriate GOMP_LAUNCH_DIM tag. IS_KERNEL is
true, if these are for a kernels region offload function. */
void void
set_oacc_fn_attrib (tree fn, tree clauses, vec<tree> *args) set_oacc_fn_attrib (tree fn, tree clauses, bool is_kernel, vec<tree> *args)
{ {
/* Must match GOMP_DIM ordering. */ /* Must match GOMP_DIM ordering. */
static const omp_clause_code ids[] static const omp_clause_code ids[]
...@@ -12515,6 +12516,9 @@ set_oacc_fn_attrib (tree fn, tree clauses, vec<tree> *args) ...@@ -12515,6 +12516,9 @@ set_oacc_fn_attrib (tree fn, tree clauses, vec<tree> *args)
non_const |= GOMP_DIM_MASK (ix); non_const |= GOMP_DIM_MASK (ix);
} }
attr = tree_cons (NULL_TREE, dim, attr); attr = tree_cons (NULL_TREE, dim, attr);
/* Note kernelness with TREE_PUBLIC. */
if (is_kernel)
TREE_PUBLIC (attr) = 1;
} }
replace_oacc_fn_attrib (fn, attr); replace_oacc_fn_attrib (fn, attr);
...@@ -12583,6 +12587,36 @@ get_oacc_fn_attrib (tree fn) ...@@ -12583,6 +12587,36 @@ get_oacc_fn_attrib (tree fn)
return lookup_attribute (OACC_FN_ATTRIB, DECL_ATTRIBUTES (fn)); return lookup_attribute (OACC_FN_ATTRIB, DECL_ATTRIBUTES (fn));
} }
/* Return true if this oacc fn attrib is for a kernels offload
region. We use the TREE_PUBLIC flag of each dimension -- only
need to check the first one. */
bool
oacc_fn_attrib_kernels_p (tree attr)
{
return TREE_PUBLIC (TREE_VALUE (attr));
}
/* Return level at which oacc routine may spawn a partitioned loop, or
-1 if it is not a routine (i.e. is an offload fn). */
static int
oacc_fn_attrib_level (tree attr)
{
tree pos = TREE_VALUE (attr);
if (!TREE_PURPOSE (pos))
return -1;
int ix = 0;
for (ix = 0; ix != GOMP_DIM_MAX;
ix++, pos = TREE_CHAIN (pos))
if (!integer_zerop (TREE_PURPOSE (pos)))
break;
return ix;
}
/* Extract an oacc execution dimension from FN. FN must be an /* Extract an oacc execution dimension from FN. FN must be an
offloaded function or routine that has already had its execution offloaded function or routine that has already had its execution
dimensions lowered to the target-specific values. */ dimensions lowered to the target-specific values. */
...@@ -13125,6 +13159,7 @@ expand_omp_target (struct omp_region *region) ...@@ -13125,6 +13159,7 @@ expand_omp_target (struct omp_region *region)
enum built_in_function start_ix; enum built_in_function start_ix;
location_t clause_loc; location_t clause_loc;
unsigned int flags_i = 0; unsigned int flags_i = 0;
bool oacc_kernels_p = false;
switch (gimple_omp_target_kind (entry_stmt)) switch (gimple_omp_target_kind (entry_stmt))
{ {
...@@ -13144,8 +13179,10 @@ expand_omp_target (struct omp_region *region) ...@@ -13144,8 +13179,10 @@ expand_omp_target (struct omp_region *region)
start_ix = BUILT_IN_GOMP_TARGET_ENTER_EXIT_DATA; start_ix = BUILT_IN_GOMP_TARGET_ENTER_EXIT_DATA;
flags_i |= GOMP_TARGET_FLAG_EXIT_DATA; flags_i |= GOMP_TARGET_FLAG_EXIT_DATA;
break; break;
case GF_OMP_TARGET_KIND_OACC_PARALLEL:
case GF_OMP_TARGET_KIND_OACC_KERNELS: case GF_OMP_TARGET_KIND_OACC_KERNELS:
oacc_kernels_p = true;
/* FALLTHROUGH */
case GF_OMP_TARGET_KIND_OACC_PARALLEL:
start_ix = BUILT_IN_GOACC_PARALLEL; start_ix = BUILT_IN_GOACC_PARALLEL;
break; break;
case GF_OMP_TARGET_KIND_OACC_DATA: case GF_OMP_TARGET_KIND_OACC_DATA:
...@@ -13304,7 +13341,7 @@ expand_omp_target (struct omp_region *region) ...@@ -13304,7 +13341,7 @@ expand_omp_target (struct omp_region *region)
break; break;
case BUILT_IN_GOACC_PARALLEL: case BUILT_IN_GOACC_PARALLEL:
{ {
set_oacc_fn_attrib (child_fn, clauses, &args); set_oacc_fn_attrib (child_fn, clauses, oacc_kernels_p, &args);
tagging = true; tagging = true;
} }
/* FALLTHRU */ /* FALLTHRU */
...@@ -20202,17 +20239,17 @@ oacc_xform_loop (gcall *call) ...@@ -20202,17 +20239,17 @@ oacc_xform_loop (gcall *call)
} }
/* Validate and update the dimensions for offloaded FN. ATTRS is the /* Validate and update the dimensions for offloaded FN. ATTRS is the
raw attribute. DIMS is an array of dimensions, which is returned. raw attribute. DIMS is an array of dimensions, which is filled in.
Returns the function level dimensionality -- the level at which an LEVEL is the partitioning level of a routine, or -1 for an offload
offload routine wishes to partition a loop. */ region itself. */
static int static void
oacc_validate_dims (tree fn, tree attrs, int *dims) oacc_validate_dims (tree fn, tree attrs, int *dims, int level)
{ {
tree purpose[GOMP_DIM_MAX]; tree purpose[GOMP_DIM_MAX];
unsigned ix; unsigned ix;
tree pos = TREE_VALUE (attrs); tree pos = TREE_VALUE (attrs);
int fn_level = -1; bool is_kernel = oacc_fn_attrib_kernels_p (attrs);
/* Make sure the attribute creator attached the dimension /* Make sure the attribute creator attached the dimension
information. */ information. */
...@@ -20221,21 +20258,12 @@ oacc_validate_dims (tree fn, tree attrs, int *dims) ...@@ -20221,21 +20258,12 @@ oacc_validate_dims (tree fn, tree attrs, int *dims)
for (ix = 0; ix != GOMP_DIM_MAX; ix++) for (ix = 0; ix != GOMP_DIM_MAX; ix++)
{ {
purpose[ix] = TREE_PURPOSE (pos); purpose[ix] = TREE_PURPOSE (pos);
if (purpose[ix])
{
if (integer_zerop (purpose[ix]))
fn_level = ix + 1;
else if (fn_level < 0)
fn_level = ix;
}
tree val = TREE_VALUE (pos); tree val = TREE_VALUE (pos);
dims[ix] = val ? TREE_INT_CST_LOW (val) : -1; dims[ix] = val ? TREE_INT_CST_LOW (val) : -1;
pos = TREE_CHAIN (pos); pos = TREE_CHAIN (pos);
} }
bool changed = targetm.goacc.validate_dims (fn, dims, fn_level); bool changed = targetm.goacc.validate_dims (fn, dims, level);
/* Default anything left to 1. */ /* Default anything left to 1. */
for (ix = 0; ix != GOMP_DIM_MAX; ix++) for (ix = 0; ix != GOMP_DIM_MAX; ix++)
...@@ -20250,13 +20278,15 @@ oacc_validate_dims (tree fn, tree attrs, int *dims) ...@@ -20250,13 +20278,15 @@ oacc_validate_dims (tree fn, tree attrs, int *dims)
/* Replace the attribute with new values. */ /* Replace the attribute with new values. */
pos = NULL_TREE; pos = NULL_TREE;
for (ix = GOMP_DIM_MAX; ix--;) for (ix = GOMP_DIM_MAX; ix--;)
{
pos = tree_cons (purpose[ix], pos = tree_cons (purpose[ix],
build_int_cst (integer_type_node, dims[ix]), build_int_cst (integer_type_node, dims[ix]),
pos); pos);
if (is_kernel)
TREE_PUBLIC (pos) = 1;
}
replace_oacc_fn_attrib (fn, pos); replace_oacc_fn_attrib (fn, pos);
} }
return fn_level;
} }
/* Create an empty OpenACC loop structure at LOC. */ /* Create an empty OpenACC loop structure at LOC. */
...@@ -20327,8 +20357,7 @@ static void ...@@ -20327,8 +20357,7 @@ static void
new_oacc_loop_routine (oacc_loop *parent, gcall *call, tree decl, tree attrs) new_oacc_loop_routine (oacc_loop *parent, gcall *call, tree decl, tree attrs)
{ {
oacc_loop *loop = new_oacc_loop_raw (parent, gimple_location (call)); oacc_loop *loop = new_oacc_loop_raw (parent, gimple_location (call));
int dims[GOMP_DIM_MAX]; int level = oacc_fn_attrib_level (attrs);
int level = oacc_validate_dims (decl, attrs, dims);
gcc_assert (level >= 0); gcc_assert (level >= 0);
...@@ -20924,18 +20953,35 @@ static unsigned int ...@@ -20924,18 +20953,35 @@ static unsigned int
execute_oacc_device_lower () execute_oacc_device_lower ()
{ {
tree attrs = get_oacc_fn_attrib (current_function_decl); tree attrs = get_oacc_fn_attrib (current_function_decl);
int dims[GOMP_DIM_MAX];
if (!attrs) if (!attrs)
/* Not an offloaded function. */ /* Not an offloaded function. */
return 0; return 0;
int fn_level = oacc_validate_dims (current_function_decl, attrs, dims);
/* Discover, partition and process the loops. */ /* Discover, partition and process the loops. */
oacc_loop *loops = oacc_loop_discovery (); oacc_loop *loops = oacc_loop_discovery ();
int fn_level = oacc_fn_attrib_level (attrs);
if (dump_file)
fprintf (dump_file, oacc_fn_attrib_kernels_p (attrs)
? "Function is kernels offload\n"
: fn_level < 0 ? "Function is parallel offload\n"
: "Function is routine level %d\n", fn_level);
unsigned outer_mask = fn_level >= 0 ? GOMP_DIM_MASK (fn_level) - 1 : 0; unsigned outer_mask = fn_level >= 0 ? GOMP_DIM_MASK (fn_level) - 1 : 0;
oacc_loop_partition (loops, outer_mask); oacc_loop_partition (loops, outer_mask);
int dims[GOMP_DIM_MAX];
oacc_validate_dims (current_function_decl, attrs, dims, fn_level);
if (dump_file)
{
const char *comma = "Compute dimensions [";
for (int ix = 0; ix != GOMP_DIM_MAX; ix++, comma = ", ")
fprintf (dump_file, "%s%d", comma, dims[ix]);
fprintf (dump_file, "]\n");
}
oacc_loop_process (loops); oacc_loop_process (loops);
if (dump_file) if (dump_file)
{ {
......
...@@ -33,7 +33,8 @@ extern tree omp_member_access_dummy_var (tree); ...@@ -33,7 +33,8 @@ extern tree omp_member_access_dummy_var (tree);
extern void replace_oacc_fn_attrib (tree, tree); extern void replace_oacc_fn_attrib (tree, tree);
extern tree build_oacc_routine_dims (tree); extern tree build_oacc_routine_dims (tree);
extern tree get_oacc_fn_attrib (tree); extern tree get_oacc_fn_attrib (tree);
extern void set_oacc_fn_attrib (tree, tree, vec<tree> *); extern void set_oacc_fn_attrib (tree, tree, bool, vec<tree> *);
extern bool oacc_fn_attrib_kernels_p (tree);
extern int get_oacc_ifn_dim_arg (const gimple *); extern int get_oacc_ifn_dim_arg (const gimple *);
extern int get_oacc_fn_dim_size (tree, int); extern int get_oacc_fn_dim_size (tree, int);
......
...@@ -2041,7 +2041,7 @@ create_parallel_loop (struct loop *loop, tree loop_fn, tree data, ...@@ -2041,7 +2041,7 @@ create_parallel_loop (struct loop *loop, tree loop_fn, tree data,
tree clause = build_omp_clause (loc, OMP_CLAUSE_NUM_GANGS); tree clause = build_omp_clause (loc, OMP_CLAUSE_NUM_GANGS);
OMP_CLAUSE_NUM_GANGS_EXPR (clause) OMP_CLAUSE_NUM_GANGS_EXPR (clause)
= build_int_cst (integer_type_node, n_threads); = build_int_cst (integer_type_node, n_threads);
set_oacc_fn_attrib (cfun->decl, clause, NULL); set_oacc_fn_attrib (cfun->decl, clause, true, NULL);
} }
else else
{ {
......
...@@ -154,12 +154,7 @@ gate_oacc_kernels (function *fn) ...@@ -154,12 +154,7 @@ gate_oacc_kernels (function *fn)
tree oacc_function_attr = get_oacc_fn_attrib (fn->decl); tree oacc_function_attr = get_oacc_fn_attrib (fn->decl);
if (oacc_function_attr == NULL_TREE) if (oacc_function_attr == NULL_TREE)
return false; return false;
if (!oacc_fn_attrib_kernels_p (oacc_function_attr))
tree val = TREE_VALUE (oacc_function_attr);
while (val != NULL_TREE && TREE_VALUE (val) == NULL_TREE)
val = TREE_CHAIN (val);
if (val != NULL_TREE)
return false; return false;
struct loop *loop; struct loop *loop;
......
Markdown is supported
0% or
You are about to add 0 people to the discussion. Proceed with caution.
Finish editing this message first!
Please register or to comment