]> git.ipfire.org Git - thirdparty/gcc.git/commitdiff
OpenMP: Add OMP_STRUCTURED_BLOCK and GIMPLE_OMP_STRUCTURED_BLOCK.
authorSandra Loosemore <sandra@codesourcery.com>
Thu, 24 Aug 2023 17:34:59 +0000 (17:34 +0000)
committerSandra Loosemore <sandra@codesourcery.com>
Fri, 25 Aug 2023 19:42:50 +0000 (19:42 +0000)
In order to detect invalid jumps in and out of intervening code in
imperfectly-nested loops, the front ends need to insert some sort of
marker to identify the structured block sequences that they push into
the inner body of the loop.  The error checking happens in the
diagnose_omp_blocks pass, between gimplification and OMP lowering, so
we need both GENERIC and GIMPLE representations of these markers.
They are removed in OMP lowering so no subsequent passes need to know
about them.

This patch doesn't include any front-end changes to generate the new
data structures.

gcc/cp/ChangeLog
* constexpr.cc (cxx_eval_constant_expression): Handle
OMP_STRUCTURED_BLOCK.
* pt.cc (tsubst_expr): Likewise.

gcc/ChangeLog
* doc/generic.texi (OpenMP): Document OMP_STRUCTURED_BLOCK.
* doc/gimple.texi (GIMPLE instruction set): Add
GIMPLE_OMP_STRUCTURED_BLOCK.
(GIMPLE_OMP_STRUCTURED_BLOCK): New subsection.
* gimple-low.cc (lower_stmt): Error on GIMPLE_OMP_STRUCTURED_BLOCK.
* gimple-pretty-print.cc (dump_gimple_omp_block): Handle
GIMPLE_OMP_STRUCTURED_BLOCK.
(pp_gimple_stmt_1): Likewise.
* gimple-walk.cc (walk_gimple_stmt): Likewise.
* gimple.cc (gimple_build_omp_structured_block): New.
* gimple.def (GIMPLE_OMP_STRUCTURED_BLOCK): New.
* gimple.h (gimple_build_omp_structured_block): Declare.
(gimple_has_substatements): Handle GIMPLE_OMP_STRUCTURED_BLOCK.
(CASE_GIMPLE_OMP): Likewise.
* gimplify.cc (is_gimple_stmt): Handle OMP_STRUCTURED_BLOCK.
(gimplify_expr): Likewise.
* omp-expand.cc (GIMPLE_OMP_STRUCTURED_BLOCK): Error on
GIMPLE_OMP_STRUCTURED_BLOCK.
* omp-low.cc (scan_omp_1_stmt): Handle GIMPLE_OMP_STRUCTURED_BLOCK.
(lower_omp_1): Likewise.
(diagnose_sb_1): Likewise.
(diagnose_sb_2): Likewise.
* tree-inline.cc (remap_gimple_stmt): Handle
GIMPLE_OMP_STRUCTURED_BLOCK.
(estimate_num_insns): Likewise.
* tree-nested.cc (convert_nonlocal_reference_stmt): Likewise.
(convert_local_reference_stmt): Likewise.
(convert_gimple_call): Likewise.
* tree-pretty-print.cc (dump_generic_node): Handle
OMP_STRUCTURED_BLOCK.
* tree.def (OMP_STRUCTURED_BLOCK): New.
* tree.h (OMP_STRUCTURED_BLOCK_BODY): New.

18 files changed:
gcc/cp/constexpr.cc
gcc/cp/pt.cc
gcc/doc/generic.texi
gcc/doc/gimple.texi
gcc/gimple-low.cc
gcc/gimple-pretty-print.cc
gcc/gimple-walk.cc
gcc/gimple.cc
gcc/gimple.def
gcc/gimple.h
gcc/gimplify.cc
gcc/omp-expand.cc
gcc/omp-low.cc
gcc/tree-inline.cc
gcc/tree-nested.cc
gcc/tree-pretty-print.cc
gcc/tree.def
gcc/tree.h

index da2c31168105ead1d2079c743132074c21b960ed..8bd5c4a47f818bdbc5b0271ade649ad5005d6c1f 100644 (file)
@@ -8155,6 +8155,7 @@ cxx_eval_constant_expression (const constexpr_ctx *ctx, tree t,
     case OMP_SCAN:
     case OMP_SCOPE:
     case OMP_SECTION:
+    case OMP_STRUCTURED_BLOCK:
     case OMP_MASTER:
     case OMP_MASKED:
     case OMP_TASKGROUP:
index c017591f235b30ff202748c8dc954437452ecf3d..2223594539c155a16e3c78af962543500812cc43 100644 (file)
@@ -19747,6 +19747,7 @@ tsubst_expr (tree t, tree args, tsubst_flags_t complain, tree in_decl)
       break;
 
     case OMP_MASTER:
+    case OMP_STRUCTURED_BLOCK:
       omp_parallel_combined_clauses = NULL;
       /* FALLTHRU */
     case OMP_SECTION:
index 3f9bddd7eae3c6dd9e665044d07a792bf68cde58..c8d6ef062f64ae5d8cf0e07394470ea364dacf9b 100644 (file)
@@ -2488,6 +2488,20 @@ In some cases, @code{OMP_CONTINUE} is placed right before
 occur right after the looping body, it will be emitted between
 @code{OMP_CONTINUE} and @code{OMP_RETURN}.
 
+@item OMP_STRUCTURED_BLOCK
+
+This is another statement that doesn't correspond to an OpenMP directive.
+It is used to mark sections of code in another directive that must
+be structured block sequences, in particular for sequences of intervening code
+in the body of an @code{OMP_FOR}.  It is not necessary to use this when the
+entire body of a directive is required to be a structured block sequence,
+since that is implicit in the representation of the corresponding node.
+
+This tree node is used only to allow error checking transfers of control
+in/out of the structured block sequence after gimplification.
+It has a single operand (@code{OMP_STRUCTURED_BLOCK_BODY}) that is
+the code within the structured block sequence.
+
 @item OMP_ATOMIC
 
 Represents @code{#pragma omp atomic}.
index 322c7609cf3159f5f908400440a21287c622c9fa..a3ade15afc9b4d6afc3d5d1fff0e297f62a862e3 100644 (file)
@@ -468,6 +468,7 @@ The following table briefly describes the GIMPLE instruction set.
 @item @code{GIMPLE_OMP_SECTIONS_SWITCH}        @tab x                  @tab x
 @item @code{GIMPLE_OMP_SINGLE}         @tab x                  @tab x
 @item @code{GIMPLE_PHI}                        @tab                    @tab x
+@item @code{GIMPLE_OMP_STRUCTURED_BLOCK} @tab x                        @tab
 @item @code{GIMPLE_RESX}               @tab                    @tab x
 @item @code{GIMPLE_RETURN}             @tab x                  @tab x
 @item @code{GIMPLE_SWITCH}             @tab x                  @tab x
@@ -1040,6 +1041,7 @@ Return a deep copy of statement @code{STMT}.
 * @code{GIMPLE_OMP_SECTION}::
 * @code{GIMPLE_OMP_SECTIONS}::
 * @code{GIMPLE_OMP_SINGLE}::
+* @code{GIMPLE_OMP_STRUCTURED_BLOCK}::
 * @code{GIMPLE_PHI}::
 * @code{GIMPLE_RESX}::
 * @code{GIMPLE_RETURN}::
@@ -2160,6 +2162,23 @@ Set @code{CLAUSES} to be the clauses associated with @code{OMP_SINGLE} @code{G}.
 @end deftypefn
 
 
+@node @code{GIMPLE_OMP_STRUCTURED_BLOCK}
+@subsection @code{GIMPLE_OMP_STRUCTURED_BLOCK}
+@cindex @code{GIMPLE_OMP_STRUCTURED_BLOCK}
+
+Like the GENERIC equivalent @code{OMP_STRUCTURED_BLOCK}, this GIMPLE
+statement does not correspond directly to an OpenMP directive, and
+exists only to permit error checking of transfers of control
+in/out of structured block sequences (the @code{diagnose_omp_blocks} pass
+in @file{omp-low.cc}).  All @code{GIMPLE_OMP_STRUCTURED_BLOCK}
+nodes are eliminated during OpenMP lowering.
+
+@deftypefn {GIMPLE function} gimple gimple_build_omp_structured_block (gimple_seq body)
+Build a @code{GIMPLE_OMP_STRUCTURED_BLOCK} statement.
+@code{BODY} is the sequence of statements in the structured block sequence.
+@end deftypefn
+
+
 @node @code{GIMPLE_PHI}
 @subsection @code{GIMPLE_PHI}
 @cindex @code{GIMPLE_PHI}
index e6f04f234dfa335546317960120fca5a24e3df02..6abc286d2160e5d313d05daa4065371e857a0be7 100644 (file)
@@ -717,6 +717,10 @@ lower_stmt (gimple_stmt_iterator *gsi, struct lower_data *data)
        gsi_next (gsi);
       return;
 
+    case GIMPLE_OMP_STRUCTURED_BLOCK:
+      /* These are supposed to be removed already in OMP lowering.  */
+      gcc_unreachable ();
+
     case GIMPLE_NOP:
     case GIMPLE_ASM:
     case GIMPLE_ASSIGN:
index 8db221f65fe7e2fc1ce25685240f11516af87fe6..82017b92e89ef18b9e7517649d66a3979c0901e0 100644 (file)
@@ -1896,7 +1896,7 @@ dump_gimple_omp_sections (pretty_printer *buffer, const gomp_sections *gs,
     }
 }
 
-/* Dump a GIMPLE_OMP_{MASTER,ORDERED,SECTION} tuple on the
+/* Dump a GIMPLE_OMP_{MASTER,ORDERED,SECTION,STRUCTURED_BLOCK} tuple on the
    pretty_printer BUFFER.  */
 
 static void
@@ -1916,6 +1916,9 @@ dump_gimple_omp_block (pretty_printer *buffer, const gimple *gs, int spc,
        case GIMPLE_OMP_SECTION:
          pp_string (buffer, "#pragma omp section");
          break;
+       case GIMPLE_OMP_STRUCTURED_BLOCK:
+         pp_string (buffer, "#pragma omp __structured_block");
+         break;
        default:
          gcc_unreachable ();
        }
@@ -2801,6 +2804,7 @@ pp_gimple_stmt_1 (pretty_printer *buffer, const gimple *gs, int spc,
 
     case GIMPLE_OMP_MASTER:
     case GIMPLE_OMP_SECTION:
+    case GIMPLE_OMP_STRUCTURED_BLOCK:
       dump_gimple_omp_block (buffer, gs, spc, flags);
       break;
 
index a019515438c91c2501417396dd306be9b3bfad4a..9516d61ffa9991a51e12e3ef62468dcc44ef8f06 100644 (file)
@@ -693,6 +693,7 @@ walk_gimple_stmt (gimple_stmt_iterator *gsi, walk_stmt_fn callback_stmt,
     case GIMPLE_OMP_ORDERED:
     case GIMPLE_OMP_SCAN:
     case GIMPLE_OMP_SECTION:
+    case GIMPLE_OMP_STRUCTURED_BLOCK:
     case GIMPLE_OMP_PARALLEL:
     case GIMPLE_OMP_TASK:
     case GIMPLE_OMP_SCOPE:
index f3b941e56c811caaed6f6b5a21a9a2449291337c..d5a4f634416c1d0984e1e3afd62997e5ff1ab78c 100644 (file)
@@ -1038,6 +1038,21 @@ gimple_build_omp_section (gimple_seq body)
 }
 
 
+/* Build a GIMPLE_OMP_STRUCTURED_BLOCK statement.
+
+   BODY is the structured block sequence.  */
+
+gimple *
+gimple_build_omp_structured_block (gimple_seq body)
+{
+  gimple *p = gimple_alloc (GIMPLE_OMP_STRUCTURED_BLOCK, 0);
+  if (body)
+    gimple_omp_set_body (p, body);
+
+  return p;
+}
+
+
 /* Build a GIMPLE_OMP_MASTER statement.
 
    BODY is the sequence of statements to be executed by just the master.  */
index 274350d9534ebf2510d9587b670dd29185f6c16e..b164a8b847a2fd93368b5a7135f81f98bb0bcb5e 100644 (file)
@@ -275,6 +275,11 @@ DEFGSCODE(GIMPLE_OMP_CRITICAL, "gimple_omp_critical", GSS_OMP_CRITICAL)
    unspecified by the standards.  */
 DEFGSCODE(GIMPLE_OMP_FOR, "gimple_omp_for", GSS_OMP_FOR)
 
+/* GIMPLE_STRUCTURED_BLOCK <BODY> is an internal construct used to assert
+   that BODY is a structured block sequence, with no other semantics.  It is
+   used to allow error-checking of intervening code in OMP_FOR constructs.  */
+DEFGSCODE(GIMPLE_OMP_STRUCTURED_BLOCK, "gimple_omp_structured_block", GSS_OMP)
+
 /* GIMPLE_OMP_MASTER <BODY> represents #pragma omp master.
    BODY is the sequence of statements to execute in the master section.  */
 DEFGSCODE(GIMPLE_OMP_MASTER, "gimple_omp_master", GSS_OMP)
index d3750f95d7936ef987464d4f38d701187b617031..2d0ac103636d077bac1015a6bca0910b4c9db891 100644 (file)
@@ -1591,6 +1591,7 @@ gomp_parallel *gimple_build_omp_parallel (gimple_seq, tree, tree, tree);
 gomp_task *gimple_build_omp_task (gimple_seq, tree, tree, tree, tree,
                                       tree, tree);
 gimple *gimple_build_omp_section (gimple_seq);
+gimple *gimple_build_omp_structured_block (gimple_seq);
 gimple *gimple_build_omp_scope (gimple_seq, tree);
 gimple *gimple_build_omp_master (gimple_seq);
 gimple *gimple_build_omp_masked (gimple_seq, tree);
@@ -1879,6 +1880,7 @@ gimple_has_substatements (gimple *g)
     case GIMPLE_OMP_TASKGROUP:
     case GIMPLE_OMP_ORDERED:
     case GIMPLE_OMP_SECTION:
+    case GIMPLE_OMP_STRUCTURED_BLOCK:
     case GIMPLE_OMP_PARALLEL:
     case GIMPLE_OMP_TASK:
     case GIMPLE_OMP_SCOPE:
@@ -6746,6 +6748,7 @@ gimple_return_set_retval (greturn *gs, tree retval)
     case GIMPLE_OMP_TEAMS:                     \
     case GIMPLE_OMP_SCOPE:                     \
     case GIMPLE_OMP_SECTION:                   \
+    case GIMPLE_OMP_STRUCTURED_BLOCK:          \
     case GIMPLE_OMP_MASTER:                    \
     case GIMPLE_OMP_MASKED:                    \
     case GIMPLE_OMP_TASKGROUP:                 \
index 1e90daad990f0aa28515ac970c8446458e253def..a49b50bc857a397f8733c03f31840f88b6b58b11 100644 (file)
@@ -5980,6 +5980,7 @@ is_gimple_stmt (tree t)
     case OMP_SCOPE:
     case OMP_SECTIONS:
     case OMP_SECTION:
+    case OMP_STRUCTURED_BLOCK:
     case OMP_SINGLE:
     case OMP_MASTER:
     case OMP_MASKED:
@@ -17037,6 +17038,7 @@ gimplify_expr (tree *expr_p, gimple_seq *pre_p, gimple_seq *post_p,
          break;
 
        case OMP_SECTION:
+       case OMP_STRUCTURED_BLOCK:
        case OMP_MASTER:
        case OMP_MASKED:
        case OMP_ORDERED:
@@ -17055,6 +17057,9 @@ gimplify_expr (tree *expr_p, gimple_seq *pre_p, gimple_seq *post_p,
              case OMP_SECTION:
                g = gimple_build_omp_section (body);
                break;
+             case OMP_STRUCTURED_BLOCK:
+               g = gimple_build_omp_structured_block (body);
+               break;
              case OMP_MASTER:
                g = gimple_build_omp_master (body);
                break;
@@ -17455,6 +17460,7 @@ gimplify_expr (tree *expr_p, gimple_seq *pre_p, gimple_seq *post_p,
                  && code != OMP_SCAN
                  && code != OMP_SECTIONS
                  && code != OMP_SECTION
+                 && code != OMP_STRUCTURED_BLOCK
                  && code != OMP_SINGLE
                  && code != OMP_SCOPE);
     }
index 1a4d625fea3075989f47c8dd23966039f42142b3..6172839c719375239b79676091b25335a6d443f7 100644 (file)
@@ -10593,6 +10593,10 @@ expand_omp (struct omp_region *region)
             parent GIMPLE_OMP_SECTIONS region.  */
          break;
 
+       case GIMPLE_OMP_STRUCTURED_BLOCK:
+         /* We should have gotten rid of these in gimple lowering.  */
+         gcc_unreachable ();
+
        case GIMPLE_OMP_SINGLE:
        case GIMPLE_OMP_SCOPE:
          expand_omp_single (region);
index b882df048ef20df77c785b35ee8f2fffe3224e2f..00e6fb07cb60345900d0aa636954ef2855adff49 100644 (file)
@@ -4300,6 +4300,7 @@ scan_omp_1_stmt (gimple_stmt_iterator *gsi, bool *handled_ops_p,
        }
       /* FALLTHRU */
     case GIMPLE_OMP_SECTION:
+    case GIMPLE_OMP_STRUCTURED_BLOCK:
     case GIMPLE_OMP_MASTER:
     case GIMPLE_OMP_ORDERED:
     case GIMPLE_OMP_CRITICAL:
@@ -14499,6 +14500,14 @@ lower_omp_1 (gimple_stmt_iterator *gsi_p, omp_context *ctx)
       gcc_assert (ctx);
       lower_omp_single (gsi_p, ctx);
       break;
+    case GIMPLE_OMP_STRUCTURED_BLOCK:
+      /* We have already done error checking at this point, so these nodes
+        can be completely removed and replaced with their body.  */
+      ctx = maybe_lookup_ctx (stmt);
+      gcc_assert (ctx);
+      lower_omp (gimple_omp_body_ptr (stmt), ctx);
+      gsi_replace_with_seq (gsi_p, gimple_omp_body (stmt), true);
+      break;
     case GIMPLE_OMP_MASTER:
     case GIMPLE_OMP_MASKED:
       ctx = maybe_lookup_ctx (stmt);
@@ -14886,6 +14895,7 @@ diagnose_sb_1 (gimple_stmt_iterator *gsi_p, bool *handled_ops_p,
     case GIMPLE_OMP_SECTIONS:
     case GIMPLE_OMP_SINGLE:
     case GIMPLE_OMP_SECTION:
+    case GIMPLE_OMP_STRUCTURED_BLOCK:
     case GIMPLE_OMP_MASTER:
     case GIMPLE_OMP_MASKED:
     case GIMPLE_OMP_ORDERED:
@@ -14949,6 +14959,7 @@ diagnose_sb_2 (gimple_stmt_iterator *gsi_p, bool *handled_ops_p,
     case GIMPLE_OMP_SECTIONS:
     case GIMPLE_OMP_SINGLE:
     case GIMPLE_OMP_SECTION:
+    case GIMPLE_OMP_STRUCTURED_BLOCK:
     case GIMPLE_OMP_MASTER:
     case GIMPLE_OMP_MASKED:
     case GIMPLE_OMP_ORDERED:
index 1d98d96df710744c1e86d69659a8aecdcab70449..d63060c9429c456f769649afc075a4fec450678d 100644 (file)
@@ -1708,6 +1708,11 @@ remap_gimple_stmt (gimple *stmt, copy_body_data *id)
                   (s1, gimple_omp_sections_clauses (stmt));
          break;
 
+       case GIMPLE_OMP_STRUCTURED_BLOCK:
+         s1 = remap_gimple_seq (gimple_omp_body (stmt), id);
+         copy = gimple_build_omp_structured_block (s1);
+         break;
+
        case GIMPLE_OMP_SINGLE:
          s1 = remap_gimple_seq (gimple_omp_body (stmt), id);
          copy = gimple_build_omp_single
@@ -4562,6 +4567,7 @@ estimate_num_insns (gimple *stmt, eni_weights *weights)
     case GIMPLE_OMP_SCAN:
     case GIMPLE_OMP_SECTION:
     case GIMPLE_OMP_SECTIONS:
+    case GIMPLE_OMP_STRUCTURED_BLOCK:
     case GIMPLE_OMP_SINGLE:
     case GIMPLE_OMP_TARGET:
     case GIMPLE_OMP_TEAMS:
index ae7d1f1f6a8424fe352715c3d57945052feac15c..31c7b6001bd4f56df5c96c047d87f1fb6479e2f7 100644 (file)
@@ -1795,6 +1795,7 @@ convert_nonlocal_reference_stmt (gimple_stmt_iterator *gsi, bool *handled_ops_p,
       break;
 
     case GIMPLE_OMP_SECTION:
+    case GIMPLE_OMP_STRUCTURED_BLOCK:
     case GIMPLE_OMP_MASTER:
     case GIMPLE_OMP_MASKED:
     case GIMPLE_OMP_ORDERED:
@@ -2540,6 +2541,7 @@ convert_local_reference_stmt (gimple_stmt_iterator *gsi, bool *handled_ops_p,
       break;
 
     case GIMPLE_OMP_SECTION:
+    case GIMPLE_OMP_STRUCTURED_BLOCK:
     case GIMPLE_OMP_MASTER:
     case GIMPLE_OMP_MASKED:
     case GIMPLE_OMP_ORDERED:
@@ -3050,6 +3052,7 @@ convert_gimple_call (gimple_stmt_iterator *gsi, bool *handled_ops_p,
       /* FALLTHRU */
     case GIMPLE_OMP_SECTIONS:
     case GIMPLE_OMP_SECTION:
+    case GIMPLE_OMP_STRUCTURED_BLOCK:
     case GIMPLE_OMP_SINGLE:
     case GIMPLE_OMP_SCOPE:
     case GIMPLE_OMP_MASTER:
index e6fbf94793f8c1c47e1eab1c9fd5b4b98922bf4b..4491176a126df82f59d7b3ea9091cbbebf2d8e02 100644 (file)
@@ -3748,6 +3748,10 @@ dump_generic_node (pretty_printer *pp, tree node, int spc, dump_flags_t flags,
       pp_string (pp, "#pragma omp section");
       goto dump_omp_body;
 
+    case OMP_STRUCTURED_BLOCK:
+      pp_string (pp, "#pragma omp __structured_block");
+      goto dump_omp_body;
+
     case OMP_SCAN:
       if (OMP_SCAN_CLAUSES (node))
        {
index be94b7ece0a727903b2fe06240e74e6a8dcf8427..abba3d764ae4ad8a319cc2056fcf6b80a8498d71 100644 (file)
@@ -1287,6 +1287,15 @@ DEFTREECODE (OMP_SCAN, "omp_scan", tcc_statement, 2)
    Operand 0: OMP_SECTION_BODY: Section body.  */
 DEFTREECODE (OMP_SECTION, "omp_section", tcc_statement, 1)
 
+/* OpenMP structured block sequences that don't correspond to the body
+   another directive.  This is used for code fragments within the body
+   of a directive that are separately required to be structured block
+   sequence; in particular, for intervening code sequences in
+   imperfectly-nested loops.
+   Operand 0: BODY: contains the statement(s) within the structured block
+   sequence.  */
+DEFTREECODE (OMP_STRUCTURED_BLOCK, "omp_structured_block", tcc_statement, 1)
+
 /* OpenMP - #pragma omp master
    Operand 0: OMP_MASTER_BODY: Master section body.  */
 DEFTREECODE (OMP_MASTER, "omp_master", tcc_statement, 1)
index 4c04245e2b1bc16d723704201bd3a2897743dd4f..75bda3fba2f61502265c70a7d9cf75fd3763216c 100644 (file)
@@ -1530,6 +1530,9 @@ class auto_suppress_location_wrappers
 
 #define OMP_SECTION_BODY(NODE)    TREE_OPERAND (OMP_SECTION_CHECK (NODE), 0)
 
+#define OMP_STRUCTURED_BLOCK_BODY(NODE) \
+  TREE_OPERAND (OMP_STRUCTURED_BLOCK_CHECK (NODE), 0)
+
 #define OMP_SINGLE_BODY(NODE)     TREE_OPERAND (OMP_SINGLE_CHECK (NODE), 0)
 #define OMP_SINGLE_CLAUSES(NODE)   TREE_OPERAND (OMP_SINGLE_CHECK (NODE), 1)