Hi!
modules.cc has apparently support for extensions and attempts to ensure
that if a module is compiled with those extensions enabled, sources which
use the module are compiled with the same extensions.
The only extension supported is SE_OPENMP right now.
And the use of the extension is keyed on streaming out or in OMP_CLAUSE
tree.
This is undesirable for several reasons.
OMP_CLAUSE is the only tree which can appear in the IL even without
-fopenmp/-fopenmp-simd/-fopenacc (when simd ("notinbranch") or
simd ("inbranch") attributes are used), and it can appear also in all
the 3 modes mentioned above. On the other side, with the exception of
arguments of attributes added e.g. for declare simd where no harm should
be done if -fopenmp/-fopenmp-simd isn't enabled later on, OMP_CLAUSE appears
in OMP_*_CLAUSES of OpenMP/OpenACC construct trees. And those construct
trees often have no clauses at all, so keying the extension on OMP_CLAUSE
doesn't catch many cases that should be caught.
Furthermore, for OpenMP we have 2 modes, -fopenmp-simd which parses some
OpenMP but constructs from that mostly OMP_SIMD and a few other cases,
and -fopenmp which includes that and far more on top of that; and there is
also -fopenacc.
So, this patch stops setting/requesting the extension on OMP_CLAUSE,
introduces 3 extensions rather than one (SE_OPENMP_SIMD, SE_OPENMP and
SE_OPENACC) and keyes those on OpenMP constructs from the -fopenmp-simd
subset, other OpenMP constructs and OpenACC constructs.
2025-03-05 Jakub Jelinek <[email protected]>
PR c++/119102
gcc/cp/
* module.cc (enum streamed_extensions): Add SE_OPENMP_SIMD
and SE_OPENACC, change value of SE_OPENMP and SE_BITS.
(CASE_OMP_SIMD_CODE, CASE_OMP_CODE, CASE_OACC_CODE): Define.
(trees_out::start): Don't set SE_OPENMP extension for OMP_CLAUSE.
Set SE_OPENMP_SIMD extension for CASE_OMP_SIMD_CODE, SE_OPENMP
for CASE_OMP_CODE and SE_OPENACC for CASE_OACC_CODE.
(trees_in::start): Don't fail for OMP_CLAUSE with missing
SE_OPENMP extension. Do fail for CASE_OMP_SIMD_CODE and missing
SE_OPENMP_SIMD extension, or CASE_OMP_CODE and missing SE_OPENMP
extension, or CASE_OACC_CODE and missing SE_OPENACC extension.
(module_state::write_readme): Write all of SE_OPENMP_SIMD, SE_OPENMP
and SE_OPENACC extensions.
(module_state::read_config): Diagnose missing -fopenmp, -fopenmp-simd
and/or -fopenacc depending on extensions used.
gcc/testsuite/
* g++.dg/modules/pr119102_a.H: New test.
* g++.dg/modules/pr119102_b.C: New test.
* g++.dg/modules/omp-3_a.C: New test.
* g++.dg/modules/omp-3_b.C: New test.
* g++.dg/modules/omp-3_c.C: New test.
* g++.dg/modules/omp-3_d.C: New test.
* g++.dg/modules/oacc-1_a.C: New test.
* g++.dg/modules/oacc-1_b.C: New test.
* g++.dg/modules/oacc-1_c.C: New test.
--- gcc/cp/module.cc.jj 2025-03-03 17:36:37.263748933 +0100
+++ gcc/cp/module.cc 2025-03-04 17:52:16.439987517 +0100
@@ -3613,8 +3613,10 @@ void slurping::release_macros ()
/* Flags for extensions that end up being streamed. */
enum streamed_extensions {
- SE_OPENMP = 1 << 0,
- SE_BITS = 1
+ SE_OPENMP_SIMD = 1 << 0,
+ SE_OPENMP = 1 << 1,
+ SE_OPENACC = 1 << 2,
+ SE_BITS = 3
};
/* Counter indices. */
@@ -5276,6 +5278,53 @@ trees_in::tree_list (bool has_purpose)
return res;
}
+
+#define CASE_OMP_SIMD_CODE \
+ case OMP_SIMD: \
+ case OMP_STRUCTURED_BLOCK: \
+ case OMP_LOOP: \
+ case OMP_ORDERED: \
+ case OMP_TILE: \
+ case OMP_UNROLL
+#define CASE_OMP_CODE \
+ case OMP_PARALLEL: \
+ case OMP_TASK: \
+ case OMP_FOR: \
+ case OMP_DISTRIBUTE: \
+ case OMP_TASKLOOP: \
+ case OMP_TEAMS: \
+ case OMP_TARGET_DATA: \
+ case OMP_TARGET: \
+ case OMP_SECTIONS: \
+ case OMP_CRITICAL: \
+ case OMP_SINGLE: \
+ case OMP_SCOPE: \
+ case OMP_TASKGROUP: \
+ case OMP_MASKED: \
+ case OMP_DISPATCH: \
+ case OMP_INTEROP: \
+ case OMP_MASTER: \
+ case OMP_TARGET_UPDATE: \
+ case OMP_TARGET_ENTER_DATA: \
+ case OMP_TARGET_EXIT_DATA: \
+ case OMP_METADIRECTIVE: \
+ case OMP_ATOMIC: \
+ case OMP_ATOMIC_READ: \
+ case OMP_ATOMIC_CAPTURE_OLD: \
+ case OMP_ATOMIC_CAPTURE_NEW
+#define CASE_OACC_CODE \
+ case OACC_PARALLEL: \
+ case OACC_KERNELS: \
+ case OACC_SERIAL: \
+ case OACC_DATA: \
+ case OACC_HOST_DATA: \
+ case OACC_LOOP: \
+ case OACC_CACHE: \
+ case OACC_DECLARE: \
+ case OACC_ENTER_DATA: \
+ case OACC_EXIT_DATA: \
+ case OACC_UPDATE
+
/* Start tree write. Write information to allocate the receiving
node. */
@@ -5311,10 +5360,21 @@ trees_out::start (tree t, bool code_stre
break;
case OMP_CLAUSE:
- state->extensions |= SE_OPENMP;
u (OMP_CLAUSE_CODE (t));
break;
+ CASE_OMP_SIMD_CODE:
+ state->extensions |= SE_OPENMP_SIMD;
+ break;
+
+ CASE_OMP_CODE:
+ state->extensions |= SE_OPENMP;
+ break;
+
+ CASE_OACC_CODE:
+ state->extensions |= SE_OPENACC;
+ break;
+
case STRING_CST:
str (TREE_STRING_POINTER (t), TREE_STRING_LENGTH (t));
break;
@@ -5383,13 +5443,25 @@ trees_in::start (unsigned code)
break;
case OMP_CLAUSE:
- {
- if (!(state->extensions & SE_OPENMP))
- goto fail;
+ t = build_omp_clause (UNKNOWN_LOCATION, omp_clause_code (u ()));
+ break;
- unsigned omp_code = u ();
- t = build_omp_clause (UNKNOWN_LOCATION, omp_clause_code (omp_code));
- }
+ CASE_OMP_SIMD_CODE:
+ if (!(state->extensions & SE_OPENMP_SIMD))
+ goto fail;
+ t = make_node (tree_code (code));
+ break;
+
+ CASE_OMP_CODE:
+ if (!(state->extensions & SE_OPENMP))
+ goto fail;
+ t = make_node (tree_code (code));
+ break;
+
+ CASE_OACC_CODE:
+ if (!(state->extensions & SE_OPENACC))
+ goto fail;
+ t = make_node (tree_code (code));
break;
case STRING_CST:
@@ -15402,8 +15474,13 @@ module_state::write_readme (elf_out *to,
readme.printf ("source: %s", main_input_filename);
readme.printf ("dialect: %s", dialect);
if (extensions)
- readme.printf ("extensions: %s",
- extensions & SE_OPENMP ? "-fopenmp" : "");
+ readme.printf ("extensions: %s%s%s",
+ extensions & SE_OPENMP ? "-fopenmp"
+ : extensions & SE_OPENMP_SIMD ? "-fopenmp-simd" : "",
+ (extensions & SE_OPENACC)
+ && (extensions & (SE_OPENMP | SE_OPENMP_SIMD))
+ ? " " : "",
+ extensions & SE_OPENACC ? "-fopenacc" : "");
/* The following fields could be expected to change between
otherwise identical compilations. Consider a distributed build
@@ -19166,12 +19243,22 @@ module_state::read_config (module_state_
too. */
{
unsigned ext = cfg.u ();
- unsigned allowed = (flag_openmp ? SE_OPENMP : 0);
+ unsigned allowed = (flag_openmp ? SE_OPENMP | SE_OPENMP_SIMD : 0);
+ if (flag_openmp_simd)
+ allowed |= SE_OPENMP_SIMD;
+ if (flag_openacc)
+ allowed |= SE_OPENACC;
if (unsigned bad = ext & ~allowed)
{
if (bad & SE_OPENMP)
error_at (loc, "module contains OpenMP, use %<-fopenmp%> to enable");
+ else if (bad & SE_OPENMP_SIMD)
+ error_at (loc, "module contains OpenMP, use %<-fopenmp%> or "
+ "%<-fopenmp-simd%> to enable");
+ if (bad & SE_OPENACC)
+ error_at (loc, "module contains OpenACC, use %<-fopenacc%> to "
+ "enable");
cfg.set_overrun ();
goto done;
}
--- gcc/testsuite/g++.dg/modules/pr119102_a.H.jj 2025-03-04
17:58:56.669389212 +0100
+++ gcc/testsuite/g++.dg/modules/pr119102_a.H 2025-03-04 17:58:48.221507257
+0100
@@ -0,0 +1,9 @@
+// PR c++/119102
+// { dg-additional-options "-fmodule-header" }
+// { dg-module-cmi {} }
+
+int foo (int)
+#if defined __x86_64__ || defined __aarch64__
+__attribute__((simd ("notinbranch")))
+#endif
+;
--- gcc/testsuite/g++.dg/modules/pr119102_b.C.jj 2025-03-04
17:59:31.234906196 +0100
+++ gcc/testsuite/g++.dg/modules/pr119102_b.C 2025-03-04 17:59:26.480972633
+0100
@@ -0,0 +1,9 @@
+// PR c++/119102
+// { dg-additional-options "-fmodules-ts" }
+
+import "pr119102_a.H";
+
+int
+main ()
+{
+}
--- gcc/testsuite/g++.dg/modules/omp-3_a.C.jj 2025-03-04 18:28:22.694702204
+0100
+++ gcc/testsuite/g++.dg/modules/omp-3_a.C 2025-03-04 18:29:13.524991414
+0100
@@ -0,0 +1,14 @@
+// { dg-additional-options "-fmodules-ts -fopenmp-simd" }
+// { dg-require-effective-target pthread }
+
+export module foo;
+// { dg-module-cmi foo { target pthread } }
+
+export inline void frob (unsigned (&ary)[64])
+{
+ int sum = 0;
+
+#pragma omp simd safelen(16) aligned (ary : 16)
+ for (unsigned ix = 0; ix < 64; ix++)
+ ary[ix] *= 2;
+}
--- gcc/testsuite/g++.dg/modules/omp-3_b.C.jj 2025-03-04 18:28:26.447649726
+0100
+++ gcc/testsuite/g++.dg/modules/omp-3_b.C 2025-03-04 18:29:36.630668318
+0100
@@ -0,0 +1,11 @@
+// { dg-additional-options "-fmodules-ts -fopenmp-simd" }
+// { dg-require-effective-target pthread }
+
+import foo;
+
+unsigned ary[64];
+
+int main ()
+{
+ frob (ary);
+}
--- gcc/testsuite/g++.dg/modules/omp-3_c.C.jj 2025-03-04 18:28:30.428594057
+0100
+++ gcc/testsuite/g++.dg/modules/omp-3_c.C 2025-03-04 18:43:53.955666435
+0100
@@ -0,0 +1,11 @@
+// { dg-additional-options "-fmodules-ts -fopenmp" }
+// { dg-require-effective-target pthread }
+
+import foo;
+
+unsigned ary[64];
+
+int main ()
+{
+ frob (ary);
+}
--- gcc/testsuite/g++.dg/modules/omp-3_d.C.jj 2025-03-04 18:43:59.424589869
+0100
+++ gcc/testsuite/g++.dg/modules/omp-3_d.C 2025-03-04 18:44:37.401058197
+0100
@@ -0,0 +1,9 @@
+// { dg-additional-options "-fmodules-ts" }
+// { dg-require-effective-target pthread }
+
+import foo;
+
+// { dg-regexp "In module imported at \[^\n]*omp-3_d.C:4:1:\nfoo: error:
module contains OpenMP, use '-fopenmp' or '-fopenmp-simd' to enable\n" }
+// { dg-prune-output "failed to read" }
+// { dg-prune-output "fatal error:" }
+// { dg-prune-output "compilation terminated" }
--- gcc/testsuite/g++.dg/modules/oacc-1_a.C.jj 2025-03-04 18:45:22.097432445
+0100
+++ gcc/testsuite/g++.dg/modules/oacc-1_a.C 2025-03-04 18:50:18.536284123
+0100
@@ -0,0 +1,15 @@
+// { dg-additional-options "-fmodules-ts -fopenacc" }
+// { dg-require-effective-target pthread }
+
+export module foo;
+// { dg-module-cmi foo { target pthread } }
+
+export inline void frob (unsigned (&ary)[64])
+{
+ int sum, i;
+#pragma acc parallel
+#pragma acc loop gang worker vector reduction (+:sum)
+ for (i = 0; i < 64; i++)
+ sum += ary[i];
+ ary[0] += sum;
+}
--- gcc/testsuite/g++.dg/modules/oacc-1_b.C.jj 2025-03-04 18:48:24.387880885
+0100
+++ gcc/testsuite/g++.dg/modules/oacc-1_b.C 2025-03-04 18:48:38.816679049
+0100
@@ -0,0 +1,11 @@
+// { dg-additional-options "-fmodules-ts -fopenacc" }
+// { dg-require-effective-target pthread }
+
+import foo;
+
+unsigned ary[64];
+
+int main ()
+{
+ frob (ary);
+}
--- gcc/testsuite/g++.dg/modules/oacc-1_c.C.jj 2025-03-04 18:48:44.342601750
+0100
+++ gcc/testsuite/g++.dg/modules/oacc-1_c.C 2025-03-04 18:49:01.724358608
+0100
@@ -0,0 +1,9 @@
+// { dg-additional-options "-fmodules-ts" }
+// { dg-require-effective-target pthread }
+
+import foo;
+
+// { dg-regexp "In module imported at \[^\n]*oacc-1_c.C:4:1:\nfoo: error:
module contains OpenACC, use '-fopenacc' to enable\n" }
+// { dg-prune-output "failed to read" }
+// { dg-prune-output "fatal error:" }
+// { dg-prune-output "compilation terminated" }
Jakub