This is another old patch teaches the omp expansion pass how to propagate the acc loop independent clause to the later stages throughout compilation. Unfortunately, it didn't include any test cases. I'm not sure how effective this will be with the existing kernel parloops pass. But as I noted in my Cauldron talk, we would like to convert acc kernels regions to acc parallel regions, and this patch could help in that regard.
Chung-Lin, do you have anymore state on this patch? Anyway, I bootstrapped and regtested it for x86_64 Linux with nvptx offloading and it didn't introduce any regressions. We do have a couple of other standalone kernels patches in og8, but those depend on other patches. Thanks, Cesar
[OpenACC] Propagate independent clause for OpenACC kernels pass 2018-XX-YY Chung-Lin Tang <clt...@codesourcery.com> Cesar Philippidis <ce...@codesourcery.com> gcc/ * cfgloop.h (struct loop): Add 'bool marked_independent' field. * omp-expand.c (struct omp_region): Add 'int kind' and 'bool independent' fields. (expand_omp_for): Set 'marked_independent' field for loop corresponding to region. (find_omp_for_region_data): New function. (build_omp_regions_1): Set kind field. Call find_omp_for_region_data for GIMPLE_OMP_FOR statements. (cherry picked from gomp-4_0-branch r225759) --- gcc/cfgloop.h | 4 ++++ gcc/omp-expand.c | 46 ++++++++++++++++++++++++++++++++++++++++++++-- 2 files changed, 48 insertions(+), 2 deletions(-) diff --git a/gcc/cfgloop.h b/gcc/cfgloop.h index 80a31c416ca..7928681b514 100644 --- a/gcc/cfgloop.h +++ b/gcc/cfgloop.h @@ -221,6 +221,10 @@ struct GTY ((chain_next ("%h.next"))) loop { /* True if the loop is part of an oacc kernels region. */ unsigned in_oacc_kernels_region : 1; + /* True if loop is tagged as having independent iterations by user, + e.g. the OpenACC independent clause. */ + bool marked_independent; + /* The number of times to unroll the loop. 0 means no information given, just do what we always do. A value of 1 means do not unroll the loop. A value of USHRT_MAX means unroll with no specific unrolling factor. diff --git a/gcc/omp-expand.c b/gcc/omp-expand.c index 9b03f62e065..427f329d35f 100644 --- a/gcc/omp-expand.c +++ b/gcc/omp-expand.c @@ -107,6 +107,12 @@ struct omp_region /* True if this is nested inside an OpenACC kernels construct. */ bool inside_kernels_p; + + /* Records a generic kind field. */ + int kind; + + /* For an OpenACC loop directive, true if has the 'independent' clause. */ + bool independent; }; static struct omp_region *root_omp_region; @@ -5705,8 +5711,15 @@ expand_omp_for (struct omp_region *region, gimple *inner_stmt) loops_state_set (LOOPS_NEED_FIXUP); if (region->inside_kernels_p) - expand_omp_for_generic (region, &fd, BUILT_IN_NONE, BUILT_IN_NONE, - inner_stmt); + { + expand_omp_for_generic (region, &fd, BUILT_IN_NONE, BUILT_IN_NONE, + inner_stmt); + if (region->independent && region->cont->loop_father) + { + struct loop *loop = region->cont->loop_father; + loop->marked_independent = true; + } + } else if (gimple_omp_for_kind (fd.for_stmt) & GF_OMP_FOR_SIMD) expand_omp_simd (region, &fd); else if (gimple_omp_for_kind (fd.for_stmt) == GF_OMP_FOR_KIND_OACC_LOOP) @@ -7887,6 +7900,31 @@ expand_omp (struct omp_region *region) } } +/* Fill in additional data for a region REGION associated with an + OMP_FOR STMT. */ + +static void +find_omp_for_region_data (struct omp_region *region, gomp_for *stmt) +{ + region->kind = gimple_omp_for_kind (stmt); + + if (region->kind == GF_OMP_FOR_KIND_OACC_LOOP) + { + struct omp_region *target_region = region->outer; + while (target_region + && target_region->type != GIMPLE_OMP_TARGET) + target_region = target_region->outer; + if (!target_region) + return; + + tree clauses = gimple_omp_for_clauses (stmt); + + if (target_region->kind == GF_OMP_TARGET_KIND_OACC_KERNELS + && omp_find_clause (clauses, OMP_CLAUSE_INDEPENDENT)) + region->independent = true; + } +} + /* Helper for build_omp_regions. Scan the dominator tree starting at block BB. PARENT is the region that contains BB. If SINGLE_TREE is true, the function ends once a single tree is built (otherwise, whole @@ -7953,6 +7991,8 @@ build_omp_regions_1 (basic_block bb, struct omp_region *parent, case GF_OMP_TARGET_KIND_OACC_KERNELS: case GF_OMP_TARGET_KIND_OACC_DATA: case GF_OMP_TARGET_KIND_OACC_HOST_DATA: + if (is_gimple_omp_oacc (stmt)) + region->kind = gimple_omp_target_kind (stmt); break; case GF_OMP_TARGET_KIND_UPDATE: case GF_OMP_TARGET_KIND_ENTER_DATA: @@ -7974,6 +8014,8 @@ build_omp_regions_1 (basic_block bb, struct omp_region *parent, /* #pragma omp ordered depend is also just a stand-alone directive. */ region = NULL; + else if (code == GIMPLE_OMP_FOR) + find_omp_for_region_data (region, as_a <gomp_for *> (stmt)); /* ..., this directive becomes the parent for a new region. */ if (region) parent = region; -- 2.17.1