preprocessor: c++: Support `#pragma GCC target' macros [PR87299]
Checks
Commit Message
`#pragma GCC target' is not currently handled in preprocess-only mode (e.g.,
when running gcc -E or gcc -save-temps). As noted in the PR, this means that
if the target pragma defines any macros, those macros are not effective in
preprocess-only mode. Similarly, such macros are not effective when
compiling with C++ (even when compiling without -save-temps), because C++
does not process the pragma until after all tokens have been obtained from
libcpp, at which point it is too late for macro expansion to take place.
Since r13-1544 and r14-2893, there is a general mechanism to handle pragmas
under these conditions as well, so resolve the PR by using the new "early
pragma" support.
toplev.cc required some changes because the target-specific handlers for
`#pragma GCC target' may call target_reinit(), and toplev.cc was not expecting
that function to be called in preprocess-only mode.
I added some additional testcases from the PR for x86. The other targets
that support `#pragma GCC target' (aarch64, arm, nios2, powerpc, s390)
already had tests verifying that the pragma sets macros as expected; here I
have added -save-temps to some of them, to test that it now works in
preprocess-only mode as well.
gcc/c-family/ChangeLog:
PR preprocessor/87299
* c-pragma.cc (init_pragma): Register `#pragma GCC target' and
related pragmas in preprocess-only mode, and enable early handling.
(c_reset_target_pragmas): New function refactoring code from...
(handle_pragma_reset_options): ...here.
* c-pragma.h (c_reset_target_pragmas): Declare.
gcc/cp/ChangeLog:
PR preprocessor/87299
* parser.cc (cp_lexer_new_main): Call c_reset_target_pragmas ()
after preprocessing is complete, before starting compilation.
gcc/ChangeLog:
PR preprocessor/87299
* toplev.cc (no_backend): New static global.
(finalize): Remove argument no_backend, which is now a
static global.
(process_options): Likewise.
(do_compile): Likewise.
(target_reinit): Don't do anything in preprocess-only mode.
(toplev::main): Adapt to no_backend change.
(toplev::finalize): Likewise.
gcc/testsuite/ChangeLog:
PR preprocessor/87299
* c-c++-common/pragma-target-1.c: New test.
* c-c++-common/pragma-target-2.c: New test.
* g++.target/i386/pr87299-1.C: New test.
* g++.target/i386/pr87299-2.C: New test.
* gcc.target/i386/pr87299-1.c: New test.
* gcc.target/i386/pr87299-2.c: New test.
* gcc.target/s390/target-attribute/tattr-2.c: Add -save-temps to the
options, to test preprocess-only mode as well.
* gcc.target/aarch64/pragma_cpp_predefs_1.c: Likewise.
* gcc.target/arm/pragma_arch_attribute.c: Likewise.
* gcc.target/nios2/custom-fp-2.c: Likewise.
* gcc.target/powerpc/float128-3.c: Likewise.
---
Notes:
Hello-
This patch fixes the PR by enabling early pragma handling for `#pragma GCC
target' and related pragmas such as `#pragma GCC push_options'. I did not
need to touch any target-specific code, however I did need to make a change
to toplev.cc, affecting all targets, to make it safe to call target_reinit()
in preprocess-only mode. (Otherwise, it would be necessary to modify the
implementation of target pragmas in every target, to avoid this code path.)
That was the only complication I ran into.
Regarding testing, I did: (thanks to GCC compile farm for the non-x86
targets)
bootstrap + regtest all languages - x86_64-pc-linux-gnu
bootstrap + regtest c/c++ - powerpc64le-unknown-linux-gnu,
aarch64-unknown-linux-gnu
The following backends also implement this pragma so ought to be tested:
arm
nios2
s390
I am not able to test those directly. I did add coverage to their testsuites
(basically, adding -save-temps to any existing test, causes it to test the
pragma in preprocess-only mode.) Then, I verified on x86_64 with a cross
compiler, that the modified testcases fail before the patch and pass
afterwards. nios2 is an exception, it does not set any libcpp macros when
handling the pragma, so there is nothing to test, but I did verify that
processing the pragma in preprocess-only mode does not cause any problems.
The cross compilers tested were targets arm-unknown-linux-gnueabi,
nios2-unknown-linux, and s390-ibm-linux.
Please let me know if it looks OK? Thanks!
-Lewis
gcc/c-family/c-pragma.cc | 49 ++++++++++++-------
gcc/c-family/c-pragma.h | 2 +-
gcc/cp/parser.cc | 6 +++
gcc/testsuite/c-c++-common/pragma-target-1.c | 19 +++++++
gcc/testsuite/c-c++-common/pragma-target-2.c | 27 ++++++++++
gcc/testsuite/g++.target/i386/pr87299-1.C | 8 +++
gcc/testsuite/g++.target/i386/pr87299-2.C | 8 +++
.../gcc.target/aarch64/pragma_cpp_predefs_1.c | 2 +-
.../gcc.target/arm/pragma_arch_attribute.c | 1 +
gcc/testsuite/gcc.target/i386/pr87299-1.c | 8 +++
gcc/testsuite/gcc.target/i386/pr87299-2.c | 8 +++
gcc/testsuite/gcc.target/nios2/custom-fp-2.c | 2 +-
gcc/testsuite/gcc.target/powerpc/float128-3.c | 2 +-
.../s390/target-attribute/tattr-2.c | 4 +-
gcc/toplev.cc | 21 +++++---
15 files changed, 135 insertions(+), 32 deletions(-)
create mode 100644 gcc/testsuite/c-c++-common/pragma-target-1.c
create mode 100644 gcc/testsuite/c-c++-common/pragma-target-2.c
create mode 100644 gcc/testsuite/g++.target/i386/pr87299-1.C
create mode 100644 gcc/testsuite/g++.target/i386/pr87299-2.C
create mode 100644 gcc/testsuite/gcc.target/i386/pr87299-1.c
create mode 100644 gcc/testsuite/gcc.target/i386/pr87299-2.c
Comments
On Mon, 31 Jul 2023, Lewis Hyatt via Gcc-patches wrote:
> I added some additional testcases from the PR for x86. The other targets
> that support `#pragma GCC target' (aarch64, arm, nios2, powerpc, s390)
> already had tests verifying that the pragma sets macros as expected; here I
> have added -save-temps to some of them, to test that it now works in
> preprocess-only mode as well.
It would seem better to have copies of the tests with and without
-save-temps, to test in both modes, rather than changing what's tested by
an existing test here. Or a test variant that #includes the original test
but uses different options, if the original test isn't doing anything that
would fail to work with that approach.
On 7/31/23 22:22, Lewis Hyatt via Gcc-patches wrote:
> `#pragma GCC target' is not currently handled in preprocess-only mode (e.g.,
> when running gcc -E or gcc -save-temps). As noted in the PR, this means that
> if the target pragma defines any macros, those macros are not effective in
> preprocess-only mode. Similarly, such macros are not effective when
> compiling with C++ (even when compiling without -save-temps), because C++
> does not process the pragma until after all tokens have been obtained from
> libcpp, at which point it is too late for macro expansion to take place.
>
> Since r13-1544 and r14-2893, there is a general mechanism to handle pragmas
> under these conditions as well, so resolve the PR by using the new "early
> pragma" support.
>
> toplev.cc required some changes because the target-specific handlers for
> `#pragma GCC target' may call target_reinit(), and toplev.cc was not expecting
> that function to be called in preprocess-only mode.
>
> I added some additional testcases from the PR for x86. The other targets
> that support `#pragma GCC target' (aarch64, arm, nios2, powerpc, s390)
> already had tests verifying that the pragma sets macros as expected; here I
> have added -save-temps to some of them, to test that it now works in
> preprocess-only mode as well.
>
> gcc/c-family/ChangeLog:
>
> PR preprocessor/87299
> * c-pragma.cc (init_pragma): Register `#pragma GCC target' and
> related pragmas in preprocess-only mode, and enable early handling.
> (c_reset_target_pragmas): New function refactoring code from...
> (handle_pragma_reset_options): ...here.
> * c-pragma.h (c_reset_target_pragmas): Declare.
>
> gcc/cp/ChangeLog:
>
> PR preprocessor/87299
> * parser.cc (cp_lexer_new_main): Call c_reset_target_pragmas ()
> after preprocessing is complete, before starting compilation.
>
> gcc/ChangeLog:
>
> PR preprocessor/87299
> * toplev.cc (no_backend): New static global.
> (finalize): Remove argument no_backend, which is now a
> static global.
> (process_options): Likewise.
> (do_compile): Likewise.
> (target_reinit): Don't do anything in preprocess-only mode.
> (toplev::main): Adapt to no_backend change.
> (toplev::finalize): Likewise.
>
> gcc/testsuite/ChangeLog:
>
> PR preprocessor/87299
> * c-c++-common/pragma-target-1.c: New test.
> * c-c++-common/pragma-target-2.c: New test.
> * g++.target/i386/pr87299-1.C: New test.
> * g++.target/i386/pr87299-2.C: New test.
> * gcc.target/i386/pr87299-1.c: New test.
> * gcc.target/i386/pr87299-2.c: New test.
> * gcc.target/s390/target-attribute/tattr-2.c: Add -save-temps to the
> options, to test preprocess-only mode as well.
> * gcc.target/aarch64/pragma_cpp_predefs_1.c: Likewise.
> * gcc.target/arm/pragma_arch_attribute.c: Likewise.
> * gcc.target/nios2/custom-fp-2.c: Likewise.
> * gcc.target/powerpc/float128-3.c: Likewise.
> ---
>
> Notes:
> Hello-
>
> This patch fixes the PR by enabling early pragma handling for `#pragma GCC
> target' and related pragmas such as `#pragma GCC push_options'. I did not
> need to touch any target-specific code, however I did need to make a change
> to toplev.cc, affecting all targets, to make it safe to call target_reinit()
> in preprocess-only mode. (Otherwise, it would be necessary to modify the
> implementation of target pragmas in every target, to avoid this code path.)
> That was the only complication I ran into.
>
> Regarding testing, I did: (thanks to GCC compile farm for the non-x86
> targets)
>
> bootstrap + regtest all languages - x86_64-pc-linux-gnu
> bootstrap + regtest c/c++ - powerpc64le-unknown-linux-gnu,
> aarch64-unknown-linux-gnu
>
> The following backends also implement this pragma so ought to be tested:
> arm
> nios2
> s390
>
> I am not able to test those directly. I did add coverage to their testsuites
> (basically, adding -save-temps to any existing test, causes it to test the
> pragma in preprocess-only mode.) Then, I verified on x86_64 with a cross
> compiler, that the modified testcases fail before the patch and pass
> afterwards. nios2 is an exception, it does not set any libcpp macros when
> handling the pragma, so there is nothing to test, but I did verify that
> processing the pragma in preprocess-only mode does not cause any problems.
> The cross compilers tested were targets arm-unknown-linux-gnueabi,
> nios2-unknown-linux, and s390-ibm-linux.
>
> Please let me know if it looks OK? Thanks!
The c-family and C++ changes look good. David, any comments on the
toplev changes?
Jason
On Tue, Aug 1, 2023 at 11:01 AM Joseph Myers <joseph@codesourcery.com> wrote:
>
> On Mon, 31 Jul 2023, Lewis Hyatt via Gcc-patches wrote:
>
> > I added some additional testcases from the PR for x86. The other targets
> > that support `#pragma GCC target' (aarch64, arm, nios2, powerpc, s390)
> > already had tests verifying that the pragma sets macros as expected; here I
> > have added -save-temps to some of them, to test that it now works in
> > preprocess-only mode as well.
>
> It would seem better to have copies of the tests with and without
> -save-temps, to test in both modes, rather than changing what's tested by
> an existing test here. Or a test variant that #includes the original test
> but uses different options, if the original test isn't doing anything that
> would fail to work with that approach.
Thank you, I will adjust this.
-Lewis
On Tue, Aug 8, 2023 at 5:53 PM Jason Merrill <jason@redhat.com> wrote:
>
> On 7/31/23 22:22, Lewis Hyatt via Gcc-patches wrote:
> > `#pragma GCC target' is not currently handled in preprocess-only mode (e.g.,
> > when running gcc -E or gcc -save-temps). As noted in the PR, this means that
> > if the target pragma defines any macros, those macros are not effective in
> > preprocess-only mode. Similarly, such macros are not effective when
> > compiling with C++ (even when compiling without -save-temps), because C++
> > does not process the pragma until after all tokens have been obtained from
> > libcpp, at which point it is too late for macro expansion to take place.
> >
> > Since r13-1544 and r14-2893, there is a general mechanism to handle pragmas
> > under these conditions as well, so resolve the PR by using the new "early
> > pragma" support.
> >
> > toplev.cc required some changes because the target-specific handlers for
> > `#pragma GCC target' may call target_reinit(), and toplev.cc was not expecting
> > that function to be called in preprocess-only mode.
> >
> > I added some additional testcases from the PR for x86. The other targets
> > that support `#pragma GCC target' (aarch64, arm, nios2, powerpc, s390)
> > already had tests verifying that the pragma sets macros as expected; here I
> > have added -save-temps to some of them, to test that it now works in
> > preprocess-only mode as well.
> >
> > gcc/c-family/ChangeLog:
> >
> > PR preprocessor/87299
> > * c-pragma.cc (init_pragma): Register `#pragma GCC target' and
> > related pragmas in preprocess-only mode, and enable early handling.
> > (c_reset_target_pragmas): New function refactoring code from...
> > (handle_pragma_reset_options): ...here.
> > * c-pragma.h (c_reset_target_pragmas): Declare.
> >
> > gcc/cp/ChangeLog:
> >
> > PR preprocessor/87299
> > * parser.cc (cp_lexer_new_main): Call c_reset_target_pragmas ()
> > after preprocessing is complete, before starting compilation.
> >
> > gcc/ChangeLog:
> >
> > PR preprocessor/87299
> > * toplev.cc (no_backend): New static global.
> > (finalize): Remove argument no_backend, which is now a
> > static global.
> > (process_options): Likewise.
> > (do_compile): Likewise.
> > (target_reinit): Don't do anything in preprocess-only mode.
> > (toplev::main): Adapt to no_backend change.
> > (toplev::finalize): Likewise.
> >
> > gcc/testsuite/ChangeLog:
> >
> > PR preprocessor/87299
> > * c-c++-common/pragma-target-1.c: New test.
> > * c-c++-common/pragma-target-2.c: New test.
> > * g++.target/i386/pr87299-1.C: New test.
> > * g++.target/i386/pr87299-2.C: New test.
> > * gcc.target/i386/pr87299-1.c: New test.
> > * gcc.target/i386/pr87299-2.c: New test.
> > * gcc.target/s390/target-attribute/tattr-2.c: Add -save-temps to the
> > options, to test preprocess-only mode as well.
> > * gcc.target/aarch64/pragma_cpp_predefs_1.c: Likewise.
> > * gcc.target/arm/pragma_arch_attribute.c: Likewise.
> > * gcc.target/nios2/custom-fp-2.c: Likewise.
> > * gcc.target/powerpc/float128-3.c: Likewise.
> > ---
> >
> > Notes:
> > Hello-
> >
> > This patch fixes the PR by enabling early pragma handling for `#pragma GCC
> > target' and related pragmas such as `#pragma GCC push_options'. I did not
> > need to touch any target-specific code, however I did need to make a change
> > to toplev.cc, affecting all targets, to make it safe to call target_reinit()
> > in preprocess-only mode. (Otherwise, it would be necessary to modify the
> > implementation of target pragmas in every target, to avoid this code path.)
> > That was the only complication I ran into.
> >
> > Regarding testing, I did: (thanks to GCC compile farm for the non-x86
> > targets)
> >
> > bootstrap + regtest all languages - x86_64-pc-linux-gnu
> > bootstrap + regtest c/c++ - powerpc64le-unknown-linux-gnu,
> > aarch64-unknown-linux-gnu
> >
> > The following backends also implement this pragma so ought to be tested:
> > arm
> > nios2
> > s390
> >
> > I am not able to test those directly. I did add coverage to their testsuites
> > (basically, adding -save-temps to any existing test, causes it to test the
> > pragma in preprocess-only mode.) Then, I verified on x86_64 with a cross
> > compiler, that the modified testcases fail before the patch and pass
> > afterwards. nios2 is an exception, it does not set any libcpp macros when
> > handling the pragma, so there is nothing to test, but I did verify that
> > processing the pragma in preprocess-only mode does not cause any problems.
> > The cross compilers tested were targets arm-unknown-linux-gnueabi,
> > nios2-unknown-linux, and s390-ibm-linux.
> >
> > Please let me know if it looks OK? Thanks!
>
> The c-family and C++ changes look good. David, any comments on the
> toplev changes?
>
> Jason
>
Thanks for the review! To be clear, I should continue to wait for
additional feedback on the toplev.cc change, correct?
I have also implemented Joseph's suggestion, to add new testcases
rather than modifying existing ones. That's a pretty minor change just
to the testsuite part so I did not resend the whole patch because of
it, but I can if needed.
-Lewis
@@ -1288,24 +1288,16 @@ handle_pragma_pop_options (cpp_reader *)
current_optimize_pragma = p->optimize_strings;
}
-/* Handle #pragma GCC reset_options to restore the current target and
- optimization options to the original options used on the command line. */
+/* This is mostly a helper for handle_pragma_reset_options () to do the actual
+ work, but the C++ frontend, for example, needs an external interface to
+ perform this operation, since it processes target pragmas twice. (Once for
+ preprocessing purposes, and then again during compilation.) */
-static void
-handle_pragma_reset_options (cpp_reader *)
+void
+c_reset_target_pragmas ()
{
- enum cpp_ttype token;
- tree x = 0;
tree new_optimize = optimization_default_node;
tree new_target = target_option_default_node;
-
- token = pragma_lex (&x);
- if (token != CPP_EOF)
- {
- warning (OPT_Wpragmas, "junk at end of %<#pragma reset_options%>");
- return;
- }
-
if (new_target != target_option_current_node)
{
(void) targetm.target_option.pragma_parse (NULL_TREE, new_target);
@@ -1325,6 +1317,19 @@ handle_pragma_reset_options (cpp_reader *)
current_optimize_pragma = NULL_TREE;
}
+/* Handle #pragma GCC reset_options to restore the current target and
+ optimization options to the original options used on the command line. */
+
+static void
+handle_pragma_reset_options (cpp_reader *)
+{
+ tree x;
+ if (pragma_lex (&x) != CPP_EOF)
+ warning (OPT_Wpragmas, "junk at end of %<#pragma reset_options%>");
+ else
+ c_reset_target_pragmas ();
+}
+
/* Print a plain user-specified message. */
static void
@@ -1839,11 +1844,19 @@ init_pragma (void)
c_register_pragma_with_early_handler ("GCC", "diagnostic",
handle_pragma_diagnostic,
handle_pragma_diagnostic_early);
- c_register_pragma ("GCC", "target", handle_pragma_target);
+ c_register_pragma_with_early_handler ("GCC", "target",
+ handle_pragma_target,
+ handle_pragma_target);
c_register_pragma ("GCC", "optimize", handle_pragma_optimize);
- c_register_pragma ("GCC", "push_options", handle_pragma_push_options);
- c_register_pragma ("GCC", "pop_options", handle_pragma_pop_options);
- c_register_pragma ("GCC", "reset_options", handle_pragma_reset_options);
+ c_register_pragma_with_early_handler ("GCC", "push_options",
+ handle_pragma_push_options,
+ handle_pragma_push_options);
+ c_register_pragma_with_early_handler ("GCC", "pop_options",
+ handle_pragma_pop_options,
+ handle_pragma_pop_options);
+ c_register_pragma_with_early_handler ("GCC", "reset_options",
+ handle_pragma_reset_options,
+ handle_pragma_reset_options);
c_register_pragma (0, "region", handle_pragma_ignore);
c_register_pragma (0, "endregion", handle_pragma_ignore);
@@ -255,7 +255,7 @@ c_register_pragma_with_early_handler (const char *space, const char *name,
pragma_handler_1arg early_handler);
extern void c_invoke_early_pragma_handler (unsigned int);
extern void c_pp_invoke_early_pragma_handler (unsigned int);
-
+extern void c_reset_target_pragmas ();
extern void maybe_apply_pragma_weak (tree);
extern void maybe_apply_pending_pragma_weaks (void);
@@ -761,6 +761,12 @@ cp_lexer_new_main (void)
maybe_check_all_macros (parse_in);
+ /* If we processed any #pragma GCC target directives, we handled them early so
+ any macros they defined would be effective during preprocessing. Now, we
+ need to reset to the default state to begin compilation, and we will
+ process them again at the correct time as needed. */
+ c_reset_target_pragmas ();
+
gcc_assert (!lexer->next_token->purged_p);
return lexer;
}
new file mode 100644
@@ -0,0 +1,19 @@
+/* { dg-do compile { target { i?86-*-* x86_64-*-* } } } */
+/* { dg-options "-mno-avx -O3" } */
+
+void f (double *x)
+{
+ for (int i = 0; i != 8; ++i)
+ x[i] *= 2;
+}
+
+#pragma GCC target("avx")
+
+void g (double *x)
+{
+ for (int i = 0; i != 8; ++i)
+ x[i] *= 2;
+}
+
+/* Make sure the target pragma affected only g() and not also f(). */
+/* { dg-final { scan-assembler-times vzeroupper 1 } } */
new file mode 100644
@@ -0,0 +1,27 @@
+/* { dg-do preprocess { target { i?86-*-* x86_64-*-* } } } */
+/* { dg-options "-mno-avx" } */
+
+#ifdef __AVX__
+#error "__AVX__ should not be defined #1"
+#endif
+
+#pragma GCC target("avx")
+#ifndef __AVX__
+#error "__AVX__ should be defined #1"
+#endif
+
+#pragma GCC reset_options
+#ifdef __AVX__
+#error "__AVX__ should not be defined #2"
+#endif
+
+#pragma GCC push_options
+#pragma GCC target("avx")
+#ifndef __AVX__
+#error "__AVX__ should be defined #2"
+#endif
+
+#pragma GCC pop_options
+#ifdef __AVX__
+#error "__AVX__ should not be defined #3"
+#endif
new file mode 100644
@@ -0,0 +1,8 @@
+/* { dg-do compile } */
+/* { dg-additional-options "-mno-avx" } */
+
+#pragma GCC target("avx")
+const int x1 = __AVX__;
+
+_Pragma("GCC target(\"avx512f\")")
+const int x2 = __AVX512F__;
new file mode 100644
@@ -0,0 +1,8 @@
+/* { dg-do compile } */
+/* { dg-additional-options "-save-temps -mno-avx" } */
+
+#pragma GCC target("avx")
+const int x1 = __AVX__;
+
+_Pragma("GCC target(\"avx512f\")")
+const int x2 = __AVX512F__;
@@ -1,5 +1,5 @@
/* { dg-do compile } */
-/* { dg-options "-O2 -march=armv8-a+crypto" } */
+/* { dg-options "-O2 -march=armv8-a+crypto -save-temps" } */
/* Test that pragma option pushing and popping works.
Also that CPP predefines redefinitions on #pragma works. */
@@ -1,6 +1,7 @@
/* Test for #pragma target macros. */
/* { dg-do compile } */
/* { dg-require-effective-target arm_arch_v8a_ok } */
+/* { dg-additional-options "-save-temps" } */
/* { dg-add-options arm_arch_v8a } */
#include <arm_acle.h>
new file mode 100644
@@ -0,0 +1,8 @@
+/* { dg-do compile } */
+/* { dg-additional-options "-mno-avx" } */
+
+#pragma GCC target("avx")
+const int x1 = __AVX__;
+
+_Pragma("GCC target(\"avx512f\")")
+const int x2 = __AVX512F__;
new file mode 100644
@@ -0,0 +1,8 @@
+/* { dg-do compile } */
+/* { dg-additional-options "-save-temps -mno-avx" } */
+
+#pragma GCC target("avx")
+const int x1 = __AVX__;
+
+_Pragma("GCC target(\"avx512f\")")
+const int x2 = __AVX512F__;
@@ -1,7 +1,7 @@
/* Test specification of custom instructions via pragmas. */
/* { dg-do compile } */
-/* { dg-options "-O1 -ffinite-math-only" } */
+/* { dg-options "-O1 -ffinite-math-only -save-temps" } */
/* -O1 in the options is significant. Without it FP operations may not be
optimized to custom instructions. */
@@ -1,6 +1,6 @@
/* { dg-do compile { target { powerpc*-*-linux* } } } */
/* { dg-require-effective-target powerpc_vsx_ok } */
-/* { dg-options "-O2 -mvsx -mno-float128" } */
+/* { dg-options "-O2 -mvsx -mno-float128 -save-temps" } */
/* Test that we can use #pragma GCC target to enable -mfloat128. */
@@ -1,8 +1,8 @@
/* Functional tests for the "target" attribute and pragma. */
-/* { dg-do compile */
+/* { dg-do compile } */
/* { dg-require-effective-target target_attribute } */
-/* { dg-options "-O3 -march=zEC12 -mno-htm -fno-ipa-icf" } */
+/* { dg-options "-O3 -march=zEC12 -mno-htm -fno-ipa-icf -save-temps" } */
#pragma GCC target("htm")
void p1(void)
@@ -99,7 +99,7 @@ static void general_init (const char *, bool);
static void backend_init (void);
static int lang_dependent_init (const char *);
static void init_asm_output (const char *);
-static void finalize (bool);
+static void finalize ();
static void crash_signal (int) ATTRIBUTE_NORETURN;
static void compile_file (void);
@@ -163,6 +163,7 @@ FILE *aux_info_file;
FILE *callgraph_info_file = NULL;
static bitmap callgraph_info_external_printed;
FILE *stack_usage_file = NULL;
+static bool no_backend = false;
/* The current working directory of a translation. It's generally the
directory from which compilation was initiated, but a preprocessed
@@ -1221,7 +1222,7 @@ parse_alignment_opts (void)
/* Process the options that have been parsed. */
static void
-process_options (bool no_backend)
+process_options ()
{
const char *language_string = lang_hooks.name;
@@ -1871,6 +1872,9 @@ lang_dependent_init (const char *name)
void
target_reinit (void)
{
+ if (no_backend)
+ return;
+
struct rtl_data saved_x_rtl;
rtx *saved_regno_reg_rtx;
tree saved_optimization_current_node;
@@ -1963,7 +1967,7 @@ dump_memory_report (const char *header)
/* Clean up: close opened files, etc. */
static void
-finalize (bool no_backend)
+finalize ()
{
/* Close the dump files. */
if (flag_gen_aux_info)
@@ -2045,7 +2049,7 @@ standard_type_bitsize (int bitsize)
/* Initialize the compiler, and compile the input file. */
static void
-do_compile (bool no_backend)
+do_compile ()
{
/* Don't do any more if an error has already occurred. */
if (!seen_error ())
@@ -2132,7 +2136,7 @@ do_compile (bool no_backend)
timevar_start (TV_PHASE_FINALIZE);
- finalize (no_backend);
+ finalize ();
timevar_stop (TV_PHASE_FINALIZE);
}
@@ -2273,13 +2277,13 @@ toplev::main (int argc, char **argv)
initialization based on the command line options. This hook also
sets the original filename if appropriate (e.g. foo.i -> foo.c)
so we can correctly initialize debug output. */
- bool no_backend = lang_hooks.post_options (&main_input_filename);
+ no_backend = lang_hooks.post_options (&main_input_filename);
- process_options (no_backend);
+ process_options ();
if (m_use_TV_TOTAL)
start_timevars ();
- do_compile (no_backend);
+ do_compile ();
if (flag_self_test && !seen_error ())
{
@@ -2324,6 +2328,7 @@ toplev::main (int argc, char **argv)
void
toplev::finalize (void)
{
+ no_backend = false;
rtl_initialized = false;
this_target_rtl->target_specific_initialized = false;