Commit 25651634 by Thomas Schwinge Committed by Thomas Schwinge

Use "oacc kernels" attribute for OpenACC kernels

	gcc/
	* omp-expand.c (expand_omp_target) <GF_OMP_TARGET_KIND_OACC_KERNELS>:
	Set "oacc kernels" attribute.
	* omp-general.c (oacc_set_fn_attrib): Remove is_kernel formal
	parameter.  Adjust all users.
	(oacc_fn_attrib_kernels_p): Remove function.
	* omp-offload.c (execute_oacc_device_lower): Look for "oacc
	kernels" attribute instead of calling oacc_fn_attrib_kernels_p.
	* tree-ssa-loop.c (gate_oacc_kernels): Likewise.
	* tree-parloops.c (create_parallel_loop): If oacc_kernels_p,
	assert "oacc kernels" attribute is set.
	gcc/testsuite/
	* c-c++-common/goacc/classify-kernels-unparallelized.c: Adjust.
	* c-c++-common/goacc/classify-kernels.c: Likewise.
	* c-c++-common/goacc/classify-parallel.c: Likewise.
	* c-c++-common/goacc/classify-routine.c: Likewise.
	* gfortran.dg/goacc/classify-kernels-unparallelized.f95: Likewise.
	* gfortran.dg/goacc/classify-kernels.f95: Likewise.
	* gfortran.dg/goacc/classify-parallel.f95: Likewise.
	* gfortran.dg/goacc/classify-routine.f95: Likewise.

From-SVN: r247955
parent ee58b02f
2017-05-12 Thomas Schwinge <thomas@codesourcery.com>
* omp-expand.c (expand_omp_target) <GF_OMP_TARGET_KIND_OACC_KERNELS>:
Set "oacc kernels" attribute.
* omp-general.c (oacc_set_fn_attrib): Remove is_kernel formal
parameter. Adjust all users.
(oacc_fn_attrib_kernels_p): Remove function.
* omp-offload.c (execute_oacc_device_lower): Look for "oacc
kernels" attribute instead of calling oacc_fn_attrib_kernels_p.
* tree-ssa-loop.c (gate_oacc_kernels): Likewise.
* tree-parloops.c (create_parallel_loop): If oacc_kernels_p,
assert "oacc kernels" attribute is set.
2017-05-11 Carl Love <cel@us.ibm.com>
* config/rs6000/rs6000-c: Add support for built-in functions
......
......@@ -7083,7 +7083,16 @@ expand_omp_target (struct omp_region *region)
exit_bb = region->exit;
if (gimple_omp_target_kind (entry_stmt) == GF_OMP_TARGET_KIND_OACC_KERNELS)
mark_loops_in_oacc_kernels_region (region->entry, region->exit);
{
mark_loops_in_oacc_kernels_region (region->entry, region->exit);
/* Further down, both OpenACC kernels and OpenACC parallel constructs
will be mappted to BUILT_IN_GOACC_PARALLEL, and to distinguish the
two, there is an "oacc kernels" attribute set for OpenACC kernels. */
DECL_ATTRIBUTES (child_fn)
= tree_cons (get_identifier ("oacc kernels"),
NULL_TREE, DECL_ATTRIBUTES (child_fn));
}
if (offloaded)
{
......@@ -7266,7 +7275,6 @@ expand_omp_target (struct omp_region *region)
enum built_in_function start_ix;
location_t clause_loc;
unsigned int flags_i = 0;
bool oacc_kernels_p = false;
switch (gimple_omp_target_kind (entry_stmt))
{
......@@ -7287,8 +7295,6 @@ expand_omp_target (struct omp_region *region)
flags_i |= GOMP_TARGET_FLAG_EXIT_DATA;
break;
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;
break;
......@@ -7450,10 +7456,8 @@ expand_omp_target (struct omp_region *region)
args.quick_push (get_target_arguments (&gsi, entry_stmt));
break;
case BUILT_IN_GOACC_PARALLEL:
{
oacc_set_fn_attrib (child_fn, clauses, oacc_kernels_p, &args);
tagging = true;
}
oacc_set_fn_attrib (child_fn, clauses, &args);
tagging = true;
/* FALLTHRU */
case BUILT_IN_GOACC_ENTER_EXIT_DATA:
case BUILT_IN_GOACC_UPDATE:
......
......@@ -515,11 +515,10 @@ oacc_replace_fn_attrib (tree fn, tree dims)
/* Scan CLAUSES for launch dimensions and attach them to the oacc
function attribute. Push any that are non-constant onto the ARGS
list, along with an appropriate GOMP_LAUNCH_DIM tag. IS_KERNEL is
true, if these are for a kernels region offload function. */
list, along with an appropriate GOMP_LAUNCH_DIM tag. */
void
oacc_set_fn_attrib (tree fn, tree clauses, bool is_kernel, vec<tree> *args)
oacc_set_fn_attrib (tree fn, tree clauses, vec<tree> *args)
{
/* Must match GOMP_DIM ordering. */
static const omp_clause_code ids[]
......@@ -545,9 +544,6 @@ oacc_set_fn_attrib (tree fn, tree clauses, bool is_kernel, vec<tree> *args)
non_const |= GOMP_DIM_MASK (ix);
}
attr = tree_cons (NULL_TREE, dim, attr);
/* Note kernelness with TREE_PUBLIC. */
if (is_kernel)
TREE_PUBLIC (attr) = 1;
}
oacc_replace_fn_attrib (fn, attr);
......@@ -616,16 +612,6 @@ oacc_get_fn_attrib (tree 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));
}
/* 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. */
......
......@@ -82,11 +82,9 @@ extern int omp_max_vf (void);
extern int omp_max_simt_vf (void);
extern tree oacc_launch_pack (unsigned code, tree device, unsigned op);
extern void oacc_replace_fn_attrib (tree fn, tree dims);
extern void oacc_set_fn_attrib (tree fn, tree clauses, bool is_kernel,
vec<tree> *args);
extern void oacc_set_fn_attrib (tree fn, tree clauses, vec<tree> *args);
extern tree oacc_build_routine_dims (tree clauses);
extern tree oacc_get_fn_attrib (tree fn);
extern bool oacc_fn_attrib_kernels_p (tree attr);
extern int oacc_get_fn_dim_size (tree fn, int axis);
extern int oacc_get_ifn_dim_arg (const gimple *stmt);
......
......@@ -619,7 +619,6 @@ oacc_validate_dims (tree fn, tree attrs, int *dims, int level, unsigned used)
tree purpose[GOMP_DIM_MAX];
unsigned ix;
tree pos = TREE_VALUE (attrs);
bool is_kernel = oacc_fn_attrib_kernels_p (attrs);
/* Make sure the attribute creator attached the dimension
information. */
......@@ -666,13 +665,8 @@ oacc_validate_dims (tree fn, tree attrs, int *dims, int level, unsigned used)
/* Replace the attribute with new values. */
pos = NULL_TREE;
for (ix = GOMP_DIM_MAX; ix--;)
{
pos = tree_cons (purpose[ix],
build_int_cst (integer_type_node, dims[ix]),
pos);
if (is_kernel)
TREE_PUBLIC (pos) = 1;
}
pos = tree_cons (purpose[ix],
build_int_cst (integer_type_node, dims[ix]), pos);
oacc_replace_fn_attrib (fn, pos);
}
}
......@@ -1455,10 +1449,16 @@ execute_oacc_device_lower ()
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);
{
if (fn_level >= 0)
fprintf (dump_file, "Function is OpenACC routine level %d\n",
fn_level);
else if (lookup_attribute ("oacc kernels",
DECL_ATTRIBUTES (current_function_decl)))
fprintf (dump_file, "Function is OpenACC kernels offload\n");
else
fprintf (dump_file, "Function is OpenACC parallel offload\n");
}
unsigned outer_mask = fn_level >= 0 ? GOMP_DIM_MASK (fn_level) - 1 : 0;
unsigned used_mask = oacc_loop_partition (loops, outer_mask);
......
2017-05-12 Thomas Schwinge <thomas@codesourcery.com>
* c-c++-common/goacc/classify-kernels-unparallelized.c: Adjust.
* c-c++-common/goacc/classify-kernels.c: Likewise.
* c-c++-common/goacc/classify-parallel.c: Likewise.
* c-c++-common/goacc/classify-routine.c: Likewise.
* gfortran.dg/goacc/classify-kernels-unparallelized.f95: Likewise.
* gfortran.dg/goacc/classify-kernels.f95: Likewise.
* gfortran.dg/goacc/classify-parallel.f95: Likewise.
* gfortran.dg/goacc/classify-routine.f95: Likewise.
* c-c++-common/goacc/classify-kernels-unparallelized.c: New file.
* c-c++-common/goacc/classify-kernels.c: Likewise.
* c-c++-common/goacc/classify-parallel.c: Likewise.
......
......@@ -24,16 +24,16 @@ void KERNELS ()
}
/* Check the offloaded function's attributes.
{ dg-final { scan-tree-dump-times "(?n)__attribute__\\(\\(omp target entrypoint\\)\\)" 1 "ompexp" } } */
{ dg-final { scan-tree-dump-times "(?n)__attribute__\\(\\(oacc kernels, omp target entrypoint\\)\\)" 1 "ompexp" } } */
/* Check that exactly one OpenACC kernels construct is analyzed, and that it
can't be parallelized.
{ dg-final { scan-tree-dump-times "FAILED:" 1 "parloops1" } }
{ dg-final { scan-tree-dump-times "(?n)__attribute__\\(\\(oacc function \\(, , \\), omp target entrypoint\\)\\)" 1 "parloops1" } }
{ dg-final { scan-tree-dump-times "(?n)__attribute__\\(\\(oacc function \\(, , \\), oacc kernels, omp target entrypoint\\)\\)" 1 "parloops1" } }
{ dg-final { scan-tree-dump-not "SUCCESS: may be parallelized" "parloops1" } } */
/* Check the offloaded function's classification and compute dimensions (will
always be 1 x 1 x 1 for non-offloading compilation).
{ dg-final { scan-tree-dump-times "(?n)Function is kernels offload" 1 "oaccdevlow" } }
{ dg-final { scan-tree-dump-times "(?n)Function is OpenACC kernels offload" 1 "oaccdevlow" } }
{ dg-final { scan-tree-dump-times "(?n)Compute dimensions \\\[1, 1, 1\\\]" 1 "oaccdevlow" } }
{ dg-final { scan-tree-dump-times "(?n)__attribute__\\(\\(oacc function \\(1, 1, 1\\), omp target entrypoint\\)\\)" 1 "oaccdevlow" } } */
{ dg-final { scan-tree-dump-times "(?n)__attribute__\\(\\(oacc function \\(1, 1, 1\\), oacc kernels, omp target entrypoint\\)\\)" 1 "oaccdevlow" } } */
......@@ -20,16 +20,16 @@ void KERNELS ()
}
/* Check the offloaded function's attributes.
{ dg-final { scan-tree-dump-times "(?n)__attribute__\\(\\(omp target entrypoint\\)\\)" 1 "ompexp" } } */
{ dg-final { scan-tree-dump-times "(?n)__attribute__\\(\\(oacc kernels, omp target entrypoint\\)\\)" 1 "ompexp" } } */
/* Check that exactly one OpenACC kernels construct is analyzed, and that it
can be parallelized.
{ dg-final { scan-tree-dump-times "SUCCESS: may be parallelized" 1 "parloops1" } }
{ dg-final { scan-tree-dump-times "(?n)__attribute__\\(\\(oacc function \\(0, , \\), omp target entrypoint\\)\\)" 1 "parloops1" } }
{ dg-final { scan-tree-dump-times "(?n)__attribute__\\(\\(oacc function \\(0, , \\), oacc kernels, omp target entrypoint\\)\\)" 1 "parloops1" } }
{ dg-final { scan-tree-dump-not "FAILED:" "parloops1" } } */
/* Check the offloaded function's classification and compute dimensions (will
always be 1 x 1 x 1 for non-offloading compilation).
{ dg-final { scan-tree-dump-times "(?n)Function is kernels offload" 1 "oaccdevlow" } }
{ dg-final { scan-tree-dump-times "(?n)Function is OpenACC kernels offload" 1 "oaccdevlow" } }
{ dg-final { scan-tree-dump-times "(?n)Compute dimensions \\\[1, 1, 1\\\]" 1 "oaccdevlow" } }
{ dg-final { scan-tree-dump-times "(?n)__attribute__\\(\\(oacc function \\(1, 1, 1\\), omp target entrypoint\\)\\)" 1 "oaccdevlow" } } */
{ dg-final { scan-tree-dump-times "(?n)__attribute__\\(\\(oacc function \\(1, 1, 1\\), oacc kernels, omp target entrypoint\\)\\)" 1 "oaccdevlow" } } */
......@@ -23,6 +23,6 @@ void PARALLEL ()
/* Check the offloaded function's classification and compute dimensions (will
always be 1 x 1 x 1 for non-offloading compilation).
{ dg-final { scan-tree-dump-times "(?n)Function is parallel offload" 1 "oaccdevlow" } }
{ dg-final { scan-tree-dump-times "(?n)Function is OpenACC parallel offload" 1 "oaccdevlow" } }
{ dg-final { scan-tree-dump-times "(?n)Compute dimensions \\\[1, 1, 1\\\]" 1 "oaccdevlow" } }
{ dg-final { scan-tree-dump-times "(?n)__attribute__\\(\\(oacc function \\(1, 1, 1\\), omp target entrypoint\\)\\)" 1 "oaccdevlow" } } */
......@@ -25,6 +25,6 @@ void ROUTINE ()
/* Check the offloaded function's classification and compute dimensions (will
always be 1 x 1 x 1 for non-offloading compilation).
{ dg-final { scan-tree-dump-times "(?n)Function is routine level 1" 1 "oaccdevlow" } }
{ dg-final { scan-tree-dump-times "(?n)Function is OpenACC routine level 1" 1 "oaccdevlow" } }
{ dg-final { scan-tree-dump-times "(?n)Compute dimensions \\\[1, 1, 1\\\]" 1 "oaccdevlow" } }
{ dg-final { scan-tree-dump-times "(?n)__attribute__\\(\\(oacc function \\(0 1, 1 1, 1 1\\), omp declare target, oacc function \\(0 1, 1 0, 1 0\\)\\)\\)" 1 "oaccdevlow" } } */
......@@ -26,16 +26,16 @@ program main
end program main
! Check the offloaded function's attributes.
! { dg-final { scan-tree-dump-times "(?n)__attribute__\\(\\(omp target entrypoint\\)\\)" 1 "ompexp" } }
! { dg-final { scan-tree-dump-times "(?n)__attribute__\\(\\(oacc kernels, omp target entrypoint\\)\\)" 1 "ompexp" } }
! Check that exactly one OpenACC kernels construct is analyzed, and that it
! can't be parallelized.
! { dg-final { scan-tree-dump-times "FAILED:" 1 "parloops1" } }
! { dg-final { scan-tree-dump-times "(?n)__attribute__\\(\\(oacc function \\(, , \\), omp target entrypoint\\)\\)" 1 "parloops1" } }
! { dg-final { scan-tree-dump-times "(?n)__attribute__\\(\\(oacc function \\(, , \\), oacc kernels, omp target entrypoint\\)\\)" 1 "parloops1" } }
! { dg-final { scan-tree-dump-not "SUCCESS: may be parallelized" "parloops1" } }
! Check the offloaded function's classification and compute dimensions (will
! always be 1 x 1 x 1 for non-offloading compilation).
! { dg-final { scan-tree-dump-times "(?n)Function is kernels offload" 1 "oaccdevlow" } }
! { dg-final { scan-tree-dump-times "(?n)Function is OpenACC kernels offload" 1 "oaccdevlow" } }
! { dg-final { scan-tree-dump-times "(?n)Compute dimensions \\\[1, 1, 1\\\]" 1 "oaccdevlow" } }
! { dg-final { scan-tree-dump-times "(?n)__attribute__\\(\\(oacc function \\(1, 1, 1\\), omp target entrypoint\\)\\)" 1 "oaccdevlow" } }
! { dg-final { scan-tree-dump-times "(?n)__attribute__\\(\\(oacc function \\(1, 1, 1\\), oacc kernels, omp target entrypoint\\)\\)" 1 "oaccdevlow" } }
......@@ -22,16 +22,16 @@ program main
end program main
! Check the offloaded function's attributes.
! { dg-final { scan-tree-dump-times "(?n)__attribute__\\(\\(omp target entrypoint\\)\\)" 1 "ompexp" } }
! { dg-final { scan-tree-dump-times "(?n)__attribute__\\(\\(oacc kernels, omp target entrypoint\\)\\)" 1 "ompexp" } }
! Check that exactly one OpenACC kernels construct is analyzed, and that it
! can be parallelized.
! { dg-final { scan-tree-dump-times "SUCCESS: may be parallelized" 1 "parloops1" } }
! { dg-final { scan-tree-dump-times "(?n)__attribute__\\(\\(oacc function \\(0, , \\), omp target entrypoint\\)\\)" 1 "parloops1" } }
! { dg-final { scan-tree-dump-times "(?n)__attribute__\\(\\(oacc function \\(0, , \\), oacc kernels, omp target entrypoint\\)\\)" 1 "parloops1" } }
! { dg-final { scan-tree-dump-not "FAILED:" "parloops1" } }
! Check the offloaded function's classification and compute dimensions (will
! always be 1 x 1 x 1 for non-offloading compilation).
! { dg-final { scan-tree-dump-times "(?n)Function is kernels offload" 1 "oaccdevlow" } }
! { dg-final { scan-tree-dump-times "(?n)Function is OpenACC kernels offload" 1 "oaccdevlow" } }
! { dg-final { scan-tree-dump-times "(?n)Compute dimensions \\\[1, 1, 1\\\]" 1 "oaccdevlow" } }
! { dg-final { scan-tree-dump-times "(?n)__attribute__\\(\\(oacc function \\(1, 1, 1\\), omp target entrypoint\\)\\)" 1 "oaccdevlow" } }
! { dg-final { scan-tree-dump-times "(?n)__attribute__\\(\\(oacc function \\(1, 1, 1\\), oacc kernels, omp target entrypoint\\)\\)" 1 "oaccdevlow" } }
......@@ -25,6 +25,6 @@ end program main
! Check the offloaded function's classification and compute dimensions (will
! always be 1 x 1 x 1 for non-offloading compilation).
! { dg-final { scan-tree-dump-times "(?n)Function is parallel offload" 1 "oaccdevlow" } }
! { dg-final { scan-tree-dump-times "(?n)Function is OpenACC parallel offload" 1 "oaccdevlow" } }
! { dg-final { scan-tree-dump-times "(?n)Compute dimensions \\\[1, 1, 1\\\]" 1 "oaccdevlow" } }
! { dg-final { scan-tree-dump-times "(?n)__attribute__\\(\\(oacc function \\(1, 1, 1\\), omp target entrypoint\\)\\)" 1 "oaccdevlow" } }
......@@ -24,6 +24,6 @@ end subroutine ROUTINE
! Check the offloaded function's classification and compute dimensions (will
! always be 1 x 1 x 1 for non-offloading compilation).
! { dg-final { scan-tree-dump-times "(?n)Function is routine level 1" 1 "oaccdevlow" } }
! { dg-final { scan-tree-dump-times "(?n)Function is OpenACC routine level 1" 1 "oaccdevlow" } }
! { dg-final { scan-tree-dump-times "(?n)Compute dimensions \\\[1, 1, 1\\\]" 1 "oaccdevlow" } }
! { dg-final { scan-tree-dump-times "(?n)__attribute__\\(\\(oacc function \\(0 1, 1 1, 1 1\\), omp declare target, oacc function \\(0 0, 1 0, 1 0\\)\\)\\)" 1 "oaccdevlow" } }
......@@ -2043,10 +2043,13 @@ create_parallel_loop (struct loop *loop, tree loop_fn, tree data,
/* Prepare the GIMPLE_OMP_PARALLEL statement. */
if (oacc_kernels_p)
{
gcc_checking_assert (lookup_attribute ("oacc kernels",
DECL_ATTRIBUTES (cfun->decl)));
tree clause = build_omp_clause (loc, OMP_CLAUSE_NUM_GANGS);
OMP_CLAUSE_NUM_GANGS_EXPR (clause)
= build_int_cst (integer_type_node, n_threads);
oacc_set_fn_attrib (cfun->decl, clause, true, NULL);
oacc_set_fn_attrib (cfun->decl, clause, NULL);
}
else
{
......
......@@ -152,10 +152,7 @@ gate_oacc_kernels (function *fn)
if (!flag_openacc)
return false;
tree oacc_function_attr = oacc_get_fn_attrib (fn->decl);
if (oacc_function_attr == NULL_TREE)
return false;
if (!oacc_fn_attrib_kernels_p (oacc_function_attr))
if (!lookup_attribute ("oacc kernels", DECL_ATTRIBUTES (fn->decl)))
return false;
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