Many backends need to override optimization options after we have processed all optimization options. It is done in OVERRIDE_OPTIONS. But it is only called once for a given input. We do have OPTIMIZATION_OPTIONS, which is executed when the optimization options are changed via "pragma GCC optimize" or by using the "optimize" attribute. But OPTIMIZATION_OPTIONS isn't enough. On Linux/x86-64, it gives [hjl@gnu-6 gcc]$ cat /tmp/x.i void foo (void) __attribute__ ((__optimize__(2,"omit-frame-pointer"))); void foo (void) { } [hjl@gnu-6 gcc]$ ./xgcc -B./ -S /tmp/x.i -mno-accumulate-outgoing-args -fomit-frame-pointer /tmp/x.i:1: warning: unwind tables currently require either a frame pointer or -maccumulate-outgoing-args for correctness [hjl@gnu-6 gcc]$ ./xgcc -B./ -S /tmp/x.i -mno-accumulate-outgoing-args [hjl@gnu-6 gcc]$ That means we may silently generate wrong codes. To properly support "pragma GCC optimize" and the "optimize" attribute, we need a way for a backend to override the optimization options whenever they are changed.
This is a target bug as the warning happens in the back-end.
Here is one approach to add OVERRIDE_OPTIMIZATION_OPTIONS so that a backend can have a chance to override optimization options. --- gcc/config/i386/i386.h.override 2008-09-11 16:48:39.000000000 -0700 +++ gcc/config/i386/i386.h 2008-09-17 13:02:45.000000000 -0700 @@ -482,6 +482,8 @@ enum calling_abi #define OVERRIDE_OPTIONS override_options (true) +#define OVERRIDE_OPTIMIZATION_OPTIONS override_options (false) + /* Define this to change the optimizations performed by default. */ #define OPTIMIZATION_OPTIONS(LEVEL, SIZE) \ optimization_options ((LEVEL), (SIZE)) --- gcc/opts.c.override 2008-09-15 08:44:27.000000000 -0700 +++ gcc/opts.c 2008-09-17 13:00:58.000000000 -0700 @@ -1105,8 +1105,14 @@ decode_options (unsigned int argc, const } #endif +#ifndef OVERRIDE_OPTIMIZATION_OPTIONS +#define OVERRIDE_OPTIMIZATION_OPTIONS do { } while (0) +#endif + /* Save the current optimization options if this is the first call. */ - if (first_time_p) + if (!first_time_p) + OVERRIDE_OPTIMIZATION_OPTIONS; + else { optimization_default_node = build_optimization_node (); optimization_current_node = optimization_default_node;
(In reply to comment #1) > This is a target bug as the warning happens in the back-end. > But there is no chance for a backend to do anything about it. It can happen to any backends which check flag_XXX in OVERRIDE_OPTIONS.
(In reply to comment #3) > (In reply to comment #1) > > This is a target bug as the warning happens in the back-end. > > > > But there is no chance for a backend to do anything about it. > It can happen to any backends which check flag_XXX in > OVERRIDE_OPTIONS. But what does C front-end have to do it then? Nothing.
If the __optimize__ attribute is handled properly, we may be able to fold the __target__ attribute into the __optimize__ attribute and all backends can support function specific -mXXX options like void foo (void) __attribute__ ((__optimize__(2,"omit-frame-pointer,-mtune=core2")));
Then lets say it is a middle-end issue. Still nowhere has you touched the C front-end.
This also causes the failure of gcc.dg/pr37106-1.c on ia64-*-* targets.
I think we need to break OVERRIDE_OPTIONS into 2 parts: 1. Execute only once for a given input. 2. Execute every time after all optimization options are processed. with things like OVERRIDE_OPTIONS_ONCE and OVERRIDE_OPTIONS_ALWAYS. Then OVERRIDE_OPTIONS can be defined as #define OVERRIDE_OPTIONS \ OVERRIDE_OPTIONS_ALWAYS; \ OVERRIDE_OPTIONS_ONCE
Subject: Bug 37565 Author: sje Date: Thu Oct 29 16:44:02 2009 New Revision: 153714 URL: http://gcc.gnu.org/viewcvs?root=gcc&view=rev&rev=153714 Log: 2009-10-29 Steve Ellcey <sje@cup.hp.com> PR middle-end/37565 PR target/38018 * doc/tm.texi (OVERRIDE_OPTIONS): Update. (TARGET_OVERRIDE_OPTIONS_AFTER_CHANGE): New. * optc-gen.awk (cl_target_option_restore): Include call to targetm.override_options_after_change. * target-def.h (TARGET_OVERRIDE_OPTIONS_AFTER_CHANGE): New. * target.h (override_options_after_change): New. * c-common.c (parse_optimize_options): Call targetm.override_options_after_change. * config/ia64/ia64.c (TARGET_OVERRIDE_OPTIONS_AFTER_CHANGE): New. (ia64_override_options_after_change): New. (ia64_override_options) Add call to above. Modified: trunk/gcc/ChangeLog trunk/gcc/c-common.c trunk/gcc/config/ia64/ia64.c trunk/gcc/doc/tm.texi trunk/gcc/optc-gen.awk trunk/gcc/target-def.h trunk/gcc/target.h
The patch I checked in provides the infrastructure to fix this problem and I have fixed the IA64 instance of it but other targets (like x86) will need to define TARGET_OVERRIDE_OPTIONS_AFTER_CHANGE as well to completely resolve this defect.
Fixed in GCC 4.9.0 by r0-125571-gc7f36d55a63c3 https://gcc.gnu.org/pipermail/gcc-patches/2013-October/371339.html