Re: [PATCH 2/7] openmp: Add middle-end support for metadirectives
On Fri, Dec 10, 2021 at 05:33:25PM +, Kwok Cheung Yeung wrote: > 2021-12-10 Kwok Cheung Yeung > > gcc/ > * gimple-low.c (lower_omp_metadirective): New. > (lower_stmt): Handle GIMPLE_OMP_METADIRECTIVE. > * gimple-pretty-print.c (dump_gimple_omp_metadirective): New. > (pp_gimple_stmt_1): Handle GIMPLE_OMP_METADIRECTIVE. > * gimple-walk.c (walk_gimple_op): Handle GIMPLE_OMP_METADIRECTIVE. > (walk_gimple_stmt): Likewise. > * gimple.c (gimple_alloc_omp_metadirective): New. > (gimple_build_omp_metadirective): New. > (gimple_build_omp_metadirective_variant): New. > * gimple.def (GIMPLE_OMP_METADIRECTIVE): New. > (GIMPLE_OMP_METADIRECTIVE_VARIANT): New. > * gimple.h (gomp_metadirective_variant): New. > (gomp_metadirective): New. > (is_a_helper ::test): New. > (is_a_helper ::test): New. > (is_a_helper ::test): New. > (is_a_helper ::test): New. > (gimple_alloc_omp_metadirective): New prototype. > (gimple_build_omp_metadirective): New prototype. > (gimple_build_omp_metadirective_variant): New prototype. > (gimple_has_substatements): Add GIMPLE_OMP_METADIRECTIVE case. > (gimple_has_ops): Add GIMPLE_OMP_METADIRECTIVE. > (gimple_omp_metadirective_label): New. > (gimple_omp_metadirective_set_label): New. > (gimple_omp_metadirective_variants): New. > (gimple_omp_metadirective_set_variants): New. > (CASE_GIMPLE_OMP): Add GIMPLE_OMP_METADIRECTIVE. > * gimplify.c (is_gimple_stmt): Add OMP_METADIRECTIVE. > (expand_omp_metadirective): New. > (gimplify_omp_metadirective): New. > (gimplify_expr): Add case for OMP_METADIRECTIVE. > * gsstruct.def (GSS_OMP_METADIRECTIVE): New. > (GSS_OMP_METADIRECTIVE_VARIANT): New. > * omp-expand.c (build_omp_regions_1): Handle GIMPLE_OMP_METADIRECTIVE. > (omp_make_gimple_edges): Likewise. > * omp-low.c (struct omp_context): Add next_clone field. > (new_omp_context): Initialize next_clone field. > (clone_omp_context): New. > (delete_omp_context): Delete clone contexts. > (scan_omp_metadirective): New. > (scan_omp_1_stmt): Handle GIMPLE_OMP_METADIRECTIVE. > (lower_omp_metadirective): New. > (lower_omp_1): Handle GIMPLE_OMP_METADIRECTIVE. > * tree-cfg.c (cleanup_dead_labels): Handle GIMPLE_OMP_METADIRECTIVE. > (gimple_redirect_edge_and_branch): Likewise. > * tree-inline.c (remap_gimple_stmt): Handle GIMPLE_OMP_METADIRECTIVE. > (estimate_num_insns): Likewise. > * tree-pretty-print.c (dump_generic_node): Handle OMP_METADIRECTIVE. > * tree-ssa-operands.c (parse_ssa_operands): Handle > GIMPLE_OMP_METADIRECTIVE. > --- a/gcc/gimple-pretty-print.c > +++ b/gcc/gimple-pretty-print.c > @@ -2051,6 +2051,63 @@ dump_gimple_omp_return (pretty_printer *buffer, const > gimple *gs, int spc, > } > } > > +/* Dump a GIMPLE_OMP_METADIRECTIVE tuple on the pretty_printer BUFFER. */ > + > +static void > +dump_gimple_omp_metadirective (pretty_printer *buffer, const gimple *gs, > +int spc, dump_flags_t flags) > +{ > + if (flags & TDF_RAW) > +{ > + dump_gimple_fmt (buffer, spc, flags, "%G <%+BODY <%S> >", gs, > +gimple_omp_body (gs)); > +} No need for {}s around a single statement. > + else > +{ > + pp_string (buffer, "#pragma omp metadirective"); > + newline_and_indent (buffer, spc + 2); > + > + gimple *variant = gimple_omp_metadirective_variants (gs); > + > + for (unsigned i = 0; i < gimple_num_ops (gs); i++) > + { > + tree selector = gimple_op (gs, i); > + > + if (selector == NULL_TREE) > + pp_string (buffer, "default:"); > + else > + { > + pp_string (buffer, "when ("); > + dump_generic_node (buffer, selector, spc, flags, false); > + pp_string (buffer, "):"); > + } > + > + if (variant != NULL) > + { > + newline_and_indent (buffer, spc + 4); > + pp_left_brace (buffer); > + pp_newline (buffer); > + dump_gimple_seq (buffer, gimple_omp_body (variant), spc + 6, > +flags); > + newline_and_indent (buffer, spc + 4); > + pp_right_brace (buffer); > + > + variant = variant->next; > + } > + else > + { > + tree label = gimple_omp_metadirective_label (gs, i); > + > + pp_string (buffer, " "); > + dump_generic_node (buffer, label, spc, flags, false); > + } > + > + if (i != gimple_num_ops (gs) - 1) > + newline_and_indent (buffer, spc + 2); I think better would be to use a gimple_stmt_iterator to walk the variants, so no variant->next etc., but gimple_omp_metadirective_variants returning a gimple_seq instead of gimple * (it is the same thing under the hood), then
[PATCH 2/7] openmp: Add middle-end support for metadirectives
This patch contains the required support for metadirectives in the middle-end. The tree metadirective representation is gimplified into the high Gimple representation, which is structured like this: #pragma omp metadirective when (): goto body_label|end_label when (>: goto body_label|end_label default: goto body_label|end_label body_label: end_label: Each variant ends with an explicit goto to either the shared standalone body (if the variant uses it) or to the point after the body (if it does not). When lowered to low Gimple, the directive bodies move outside of the metadirective statement, retaining only the labels to the bodies, so it looks like this instead: #pragma omp metadirective when (): goto body1_label when (>: goto body2_label default: goto default_label body1_label: goto body_label|end_label body2_label: goto body_label|end_label default_label: goto body_label|end_label body_label: end_label: When scanning the OpenMP regions in the ompexp pass, we create a 'clone' of the surrounding context when recursively scanning the directive variants. If the same outer context was used for all variants, then it would appear as if all the variants were inside the region at the same time (only one variant of the metadirective is ever active at a time), which can lead to spurious errors. The rest of the code is the plumbing required to allow the Gimple metadirective statement to pass through the middle-end. GCC will emit an ICE if it makes it through to the back-end though, as the metadirective is supposed to be eliminated before it gets that far. KwokFrom 1a2fcbb2191fd1dd694ea5730e54fab19d6465b4 Mon Sep 17 00:00:00 2001 From: Kwok Cheung Yeung Date: Mon, 6 Dec 2021 22:29:34 + Subject: [PATCH 2/7] openmp: Add middle-end support for metadirectives This adds a new Gimple statement type GIMPLE_OMP_METADIRECTIVE, which represents the metadirective in Gimple. In high Gimple, the statement contains the body of the directive variants, whereas in low Gimple, it only contains labels to the bodies. This patch adds support for converting metadirectives from tree to Gimple form, and handling of the Gimple form (Gimple lowering, OpenMP lowering and expansion, inlining, SSA handling etc). Metadirectives should be resolved before they reach the back-end, otherwise the compiler will crash as GCC does not know how to convert metadirective Gimple statements to RTX. 2021-12-10 Kwok Cheung Yeung gcc/ * gimple-low.c (lower_omp_metadirective): New. (lower_stmt): Handle GIMPLE_OMP_METADIRECTIVE. * gimple-pretty-print.c (dump_gimple_omp_metadirective): New. (pp_gimple_stmt_1): Handle GIMPLE_OMP_METADIRECTIVE. * gimple-walk.c (walk_gimple_op): Handle GIMPLE_OMP_METADIRECTIVE. (walk_gimple_stmt): Likewise. * gimple.c (gimple_alloc_omp_metadirective): New. (gimple_build_omp_metadirective): New. (gimple_build_omp_metadirective_variant): New. * gimple.def (GIMPLE_OMP_METADIRECTIVE): New. (GIMPLE_OMP_METADIRECTIVE_VARIANT): New. * gimple.h (gomp_metadirective_variant): New. (gomp_metadirective): New. (is_a_helper ::test): New. (is_a_helper ::test): New. (is_a_helper ::test): New. (is_a_helper ::test): New. (gimple_alloc_omp_metadirective): New prototype. (gimple_build_omp_metadirective): New prototype. (gimple_build_omp_metadirective_variant): New prototype. (gimple_has_substatements): Add GIMPLE_OMP_METADIRECTIVE case. (gimple_has_ops): Add GIMPLE_OMP_METADIRECTIVE. (gimple_omp_metadirective_label): New. (gimple_omp_metadirective_set_label): New. (gimple_omp_metadirective_variants): New. (gimple_omp_metadirective_set_variants): New. (CASE_GIMPLE_OMP): Add GIMPLE_OMP_METADIRECTIVE. * gimplify.c (is_gimple_stmt): Add OMP_METADIRECTIVE. (expand_omp_metadirective): New. (gimplify_omp_metadirective): New. (gimplify_expr): Add case for OMP_METADIRECTIVE. * gsstruct.def (GSS_OMP_METADIRECTIVE): New. (GSS_OMP_METADIRECTIVE_VARIANT): New. * omp-expand.c (build_omp_regions_1): Handle GIMPLE_OMP_METADIRECTIVE. (omp_make_gimple_edges): Likewise. * omp-low.c (struct omp_context): Add next_clone field. (new_omp_context): Initialize next_clone field. (clone_omp_context): New. (delete_omp_context): Delete clone contexts. (scan_omp_metadirective): New. (scan_omp_1_stmt): Handle GIMPLE_OMP_METADIRECTIVE. (lower_omp_metadirective): New. (lower_omp_1): Handle GIMPLE_OMP_METADIRECTIVE. * tree-cfg.c (cleanup_dead_labels): Handle GIMPLE_OMP_METADIRECTIVE. (gimple_redirect_edge_and_branch): Likewise. * tree-inline.c (remap_gimple_stmt): Handle GIMPLE_OMP_METADIR