On Fri, Dec 10, 2021 at 05:33:25PM +0000, Kwok Cheung Yeung wrote:
> 2021-12-10  Kwok Cheung Yeung  <k...@codesourcery.com>
> 
>       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 <gomp_metadirective *>::test): New.
>       (is_a_helper <gomp_metadirective_variant *>::test): New.
>       (is_a_helper <const gomp_metadirective *>::test): New.
>       (is_a_helper <const gomp_metadirective_variant *>::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
      gimple_seq variant_seq = gimple_omp_metadirective_variants (gs);
      gimple_stmt_iterator gsi = gsi_start (variant_seq);
and in the loop
          gimple *variant = gsi_stmt (gsi);
and gsi_next (&gsi); at the end.  Similarly for all other spots that walk
gimple_omp_metadirective_variants.


> +    case GIMPLE_OMP_METADIRECTIVE:
> +      {
> +     gimple *variant = gimple_omp_metadirective_variants (stmt);
> +
> +     while (variant)
> +       {
> +         ret = walk_gimple_op (gimple_omp_body (variant), callback_op, wi);
> +         if (ret)
> +           return ret;
> +
> +         variant = variant->next;
> +       }

So here too...

> +      }
> +      break;
> +
>      case GIMPLE_TRANSACTION:
>        {
>       gtransaction *txn = as_a <gtransaction *> (stmt);
> @@ -700,6 +715,22 @@ walk_gimple_stmt (gimple_stmt_iterator *gsi, 
> walk_stmt_fn callback_stmt,
>       return wi->callback_result;
>        break;
>  
> +    case GIMPLE_OMP_METADIRECTIVE:
> +      {
> +     gimple *variant = gimple_omp_metadirective_variants (stmt);
> +
> +     while (variant)
> +       {
> +         ret = walk_gimple_seq_mod (gimple_omp_body_ptr (variant),
> +                                    callback_stmt, callback_op, wi);
> +         if (ret)
> +           return wi->callback_result;
> +
> +         variant = variant->next;
> +       }

and here etc.
> --- a/gcc/omp-expand.c
> +++ b/gcc/omp-expand.c
> @@ -10418,6 +10418,10 @@ build_omp_regions_1 (basic_block bb, struct 
> omp_region *parent,
>         /* GIMPLE_OMP_SECTIONS_SWITCH is part of
>            GIMPLE_OMP_SECTIONS, and we do nothing for it.  */
>       }
> +      else if (code == GIMPLE_OMP_METADIRECTIVE)
> +     {
> +       /* Do nothing for metadirectives.  */
> +     }

No {}s around the comment, just /* ...  */;

> --- a/gcc/tree-cfg.c
> +++ b/gcc/tree-cfg.c
> @@ -1670,6 +1670,18 @@ cleanup_dead_labels (void)
>         }
>         break;
>  
> +     case GIMPLE_OMP_METADIRECTIVE:
> +       {
> +         for (unsigned i = 0; i < gimple_num_ops (stmt); i++)
> +           {
> +             label = gimple_omp_metadirective_label (stmt, i);
> +             new_label = main_block_label (label, label_for_bb);
> +             if (new_label != label)
> +               gimple_omp_metadirective_set_label (stmt, i, new_label);
> +           }
> +       }
> +       break;

Why the {} around the for?

> @@ -6147,6 +6159,18 @@ gimple_redirect_edge_and_branch (edge e, basic_block 
> dest)
>                                          gimple_block_label (dest));
>        break;
>  
> +    case GIMPLE_OMP_METADIRECTIVE:
> +      {
> +     for (unsigned i = 0; i < gimple_num_ops (stmt); i++)
> +       {
> +         tree label = gimple_omp_metadirective_label (stmt, i);
> +         if (label_to_block (cfun, label) == e->dest)
> +           gimple_omp_metadirective_set_label (stmt, i,
> +                                               gimple_block_label (dest));
> +       }
> +      }
> +      break;

Likewise.

> --- a/gcc/tree-ssa-operands.c
> +++ b/gcc/tree-ssa-operands.c
> @@ -973,6 +973,33 @@ operands_scanner::parse_ssa_operands ()
>        append_vuse (gimple_vop (fn));
>        goto do_default;
>  
> +    case GIMPLE_OMP_METADIRECTIVE:
> +      n = gimple_num_ops (stmt);
> +      for (i = start; i < n; i++)
> +     {

Why the {}s around the inner for?

> +       for (tree selector = gimple_op (stmt, i);
> +            selector != NULL;
> +            selector = TREE_CHAIN (selector))
> +         {

Why the {}s around the if ?

> +           if (TREE_PURPOSE (selector) == get_identifier ("user"))
> +             {
> +               for (tree property = TREE_VALUE (selector);
> +                    property != NULL;
> +                    property = TREE_CHAIN (property))
> +                 if (TREE_PURPOSE (property)
> +                     == get_identifier ("condition"))
> +                   {
> +                     for (tree condition = TREE_VALUE (property);
> +                          condition != NULL;
> +                          condition = TREE_CHAIN (condition))
> +                       get_expr_operands (&TREE_VALUE (condition),
> +                                          opf_use);
> +                   }
> +             }
> +         }
> +     }
> +      break;
> +

Also, I wonder how does LTO saving/restoring handle the
GIMPLE_OMP_METADIRECTIVE statements.

Otherwise LGTM.

        Jakub

Reply via email to