http://gcc.gnu.org/bugzilla/show_bug.cgi?id=60580
Jakub Jelinek <jakub at gcc dot gnu.org> changed: What |Removed |Added ---------------------------------------------------------------------------- CC| |jakub at gcc dot gnu.org, | |jsm28 at gcc dot gnu.org, | |uros at gcc dot gnu.org --- Comment #1 from Jakub Jelinek <jakub at gcc dot gnu.org> --- This is a complete mess, what aarch64 backend does is completely incompatible with optimize attribute. I've tried to fix this up: --- gcc/config/aarch64/aarch64.opt.jj 2014-01-20 14:50:22.000000000 +0100 +++ gcc/config/aarch64/aarch64.opt 2014-03-19 11:52:29.963772607 +0100 @@ -59,6 +59,11 @@ const char *aarch64_cpu_string Variable const char *aarch64_tune_string +; Did we set flag_omit_frame_pointer just so aarch64_frame_pointer_required +; would be called? +Variable +bool faked_omit_frame_pointer + mbig-endian Target Report RejectNegative Mask(BIG_END) Assume target CPU is configured as big endian --- gcc/config/aarch64/aarch64.c.jj 2014-03-18 12:26:13.000000000 +0100 +++ gcc/config/aarch64/aarch64.c 2014-03-19 12:20:19.471504562 +0100 @@ -315,10 +315,6 @@ static GTY(()) int gty_dummy; #define AARCH64_NUM_BITMASKS 5334 static unsigned HOST_WIDE_INT aarch64_bitmasks[AARCH64_NUM_BITMASKS]; -/* Did we set flag_omit_frame_pointer just so - aarch64_frame_pointer_required would be called? */ -static bool faked_omit_frame_pointer; - typedef enum aarch64_cond_code { AARCH64_EQ = 0, AARCH64_NE, AARCH64_CS, AARCH64_CC, AARCH64_MI, AARCH64_PL, @@ -5278,7 +5274,11 @@ aarch64_override_options (void) static void aarch64_override_options_after_change (void) { - faked_omit_frame_pointer = false; + if (global_options_set.x_flag_omit_frame_pointer) + { + faked_omit_frame_pointer = false; + global_options_set.x_faked_omit_frame_pointer = false; + } /* To omit leaf frame pointers, we need to turn flag_omit_frame_pointer on so that aarch64_frame_pointer_required will be called. We need to remember @@ -5288,6 +5288,9 @@ aarch64_override_options_after_change (v { flag_omit_frame_pointer = true; faked_omit_frame_pointer = true; + global_options_set.x_faked_omit_frame_pointer + = global_options_set.x_flag_omit_frame_pointer; + global_options_set.x_flag_omit_frame_pointer = false; } } but while that fixes some of the cases, it doesn't fix everything, the problem is that the non-TargetVariable Variables aren't actually Saved. Now, i386 backend seems to handle it differently, instead of adding a faked_omit_frame_pointer variable (which, as this PR suggests would need to be handled as an Optimization Saved variable, but supposedly the opts framework doesn't allow it yet), it clears omit_leaf_frame_pointer flag if flag_omit_frame_pointer is true: /* Keep nonleaf frame pointers. */ if (opts->x_flag_omit_frame_pointer) opts->x_target_flags &= ~MASK_OMIT_LEAF_FRAME_POINTER; else if (TARGET_OMIT_LEAF_FRAME_POINTER_P (opts->x_target_flags)) opts->x_flag_omit_frame_pointer = 1; but does that only in in override_options hook. That means that say for -fomit-frame-pointer -momit-leaf-frame-pointer on the command line supposedly that turns off TARGET_OMIT_LEAF_FRAME_POINTER and when some function has __attribute__((optimize ("no-omit-frame-pointer"))) and is leaf, frame pointer will not be omitted there. But for -fno-omit-frame-pointer -momit-leaf-frame-pointer on the command line and __attribute__((optimize ("no-omit-frame-pointer"))) supposedly it will not have frame pointer if it is leaf. The primary issue is that flag_omit_frame_pointer is Optimization Save flag, while omit-leaf-frame-pointer is typcially Target Save, the former optimize attribute thing, the latter target attribute thing. Not sure what is the best way out of this, but I guess doing in aarch64 what i386 does would be significant progress.