Re: [PATCH 2/7] openmp: Add middle-end support for metadirectives

2022-05-30 Thread Jakub Jelinek via Gcc-patches
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

2021-12-10 Thread Kwok Cheung Yeung
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