@@ -1,3 +1,11 @@
+2014-03-21 Marcus Shawcroft <marcus.shawcroft@arm.com>
+
+ PR target/60580
+ * config/aarch64/aarch64.c (faked_omit_frame_pointer): Remove.
+ (aarch64_frame_pointer_required): Adjust logic.
+ (aarch64_can_eliminate): Adjust logic.
+ (aarch64_override_options_after_change): Adjust logic.
+
2014-03-19 Venkataramanan Kumar <venkataramanan.kumar@linaro.org>
* config/aarch64/aarch64.md (stack_protect_set, stack_protect_test)
@@ -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,
@@ -1730,17 +1726,15 @@ aarch64_frame_pointer_required (void)
if (cfun->calls_alloca)
return true;
- /* We may have turned flag_omit_frame_pointer on in order to have this
- function called; if we did, we also set the 'faked_omit_frame_pointer' flag
- and we'll check it here.
- If we really did set flag_omit_frame_pointer normally, then we return false
- (no frame pointer required) in all cases. */
+ /* In aarch64_override_options_after_change
+ flag_omit_leaf_frame_pointer turns off the frame pointer by
+ default. Turn it back on now if we've not got a leaf
+ function. */
+ if (flag_omit_leaf_frame_pointer
+ && (!crtl->is_leaf || df_regs_ever_live_p (LR_REGNUM)))
+ return true;
- if (flag_omit_frame_pointer && !faked_omit_frame_pointer)
- return false;
- else if (flag_omit_leaf_frame_pointer)
- return !crtl->is_leaf || df_regs_ever_live_p (LR_REGNUM);
- return true;
+ return false;
}
/* Mark the registers that need to be saved by the callee and calculate
@@ -4168,23 +4162,8 @@ aarch64_can_eliminate (const int from, const int to)
return true;
if (from == FRAME_POINTER_REGNUM && to == HARD_FRAME_POINTER_REGNUM)
return true;
- return false;
- }
- else
- {
- /* If we decided that we didn't need a leaf frame pointer but then used
- LR in the function, then we'll want a frame pointer after all, so
- prevent this elimination to ensure a frame pointer is used.
-
- NOTE: the original value of flag_omit_frame_pointer gets trashed
- IFF flag_omit_leaf_frame_pointer is true, so we check the value
- of faked_omit_frame_pointer here (which is true when we always
- wish to keep non-leaf frame pointers but only wish to keep leaf frame
- pointers when LR is clobbered). */
- if (to == STACK_POINTER_REGNUM
- && df_regs_ever_live_p (LR_REGNUM)
- && faked_omit_frame_pointer)
- return false;
+
+ return false;
}
return true;
@@ -5314,17 +5293,10 @@ aarch64_override_options (void)
static void
aarch64_override_options_after_change (void)
{
- 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
- whether flag_omit_frame_pointer was turned on normally or just faked. */
-
- if (flag_omit_leaf_frame_pointer && !flag_omit_frame_pointer)
- {
- flag_omit_frame_pointer = true;
- faked_omit_frame_pointer = true;
- }
+ if (flag_omit_frame_pointer)
+ flag_omit_leaf_frame_pointer = false;
+ else if (flag_omit_leaf_frame_pointer)
+ flag_omit_frame_pointer = true;
}
static struct machine_function *
@@ -1,3 +1,10 @@
+2014-03-21 Marcus Shawcroft <marcus.shawcroft@arm.com>
+
+ PR target/60580
+ * gcc.target/aarch64/pr60580_1.c: New.
+ * gcc.target/aarch64/test_fp_attribute_1.c: New.
+ * gcc.target/aarch64/test_fp_attribute_2.c: New.
+
2014-03-14 Alex Velenko <Alex.Velenko@arm.com>
* gcc.target/aarch64/vdup_lane_1.c: New testcase.
new file mode 100644
@@ -0,0 +1,45 @@
+/* { dg-do compile } */
+/* { dg-options "-O0 -fomit-frame-pointer -fno-inline --save-temps" } */
+
+void
+func_leaf (void)
+{
+ int a = 0;
+}
+
+void
+func_no_leaf (void)
+{
+ int a = 0;
+ func_leaf ();
+}
+
+void
+func1 (void)
+{
+ int a = 0;
+ func_no_leaf ();
+}
+
+/*
+ * This function calls XXX(), which modifies SP. This is incompatible to
+ * -fomit-frame-pointer generated code as SP is used to access the frame.
+ */
+__attribute__ ((optimize("no-omit-frame-pointer")))
+void
+func2 (void)
+{
+ int a = 0;
+ func_no_leaf ();
+}
+
+void
+func3 (void)
+{
+ int a = 0;
+ func_no_leaf ();
+}
+
+/* { dg-final { scan-assembler-times "stp\tx29, x30, \\\[sp, -\[0-9\]+\\\]!" 1 } } */
+
+/* { dg-final { cleanup-saved-temps } } */
new file mode 100644
@@ -0,0 +1,26 @@
+/* { dg-do compile } */
+/* { dg-options "-O0 -fno-omit-frame-pointer -fno-inline --save-temps" } */
+
+void
+leaf (void)
+{
+ int a = 0;
+}
+
+__attribute__ ((optimize("omit-frame-pointer")))
+void
+non_leaf_1 (void)
+{
+ leaf ();
+}
+
+__attribute__ ((optimize("omit-frame-pointer")))
+void
+non_leaf_2 (void)
+{
+ leaf ();
+}
+
+/* { dg-final { scan-assembler-times "str\tx30, \\\[sp\\\]" 2 } } */
+
+/* { dg-final { cleanup-saved-temps } } */
new file mode 100644
@@ -0,0 +1,26 @@
+/* { dg-do compile } */
+/* { dg-options "-O0 -fomit-frame-pointer -fno-inline --save-temps" } */
+
+void
+leaf (void)
+{
+ int a = 0;
+}
+
+__attribute__ ((optimize("no-omit-frame-pointer")))
+void
+non_leaf_1 (void)
+{
+ leaf ();
+}
+
+__attribute__ ((optimize("no-omit-frame-pointer")))
+void
+non_leaf_2 (void)
+{
+ leaf ();
+}
+
+/* { dg-final { scan-assembler-times "stp\tx29, x30, \\\[sp, -\[0-9\]+\\\]!" 2 } } */
+
+/* { dg-final { cleanup-saved-temps } } */