On 01/10/14 09:00, Kugan wrote:
On 01/10/14 01:00, Jiong Wang wrote:
On 27/09/14 22:20, Kugan wrote:
On 23/09/14 01:58, Jiong Wang wrote:
On 22/09/14 16:43, Kugan wrote:

AArch64 has the same issue ARM had where the LR register was not
used in
leaf functions. This was reported in
https://gcc.gnu.org/bugzilla/show_bug.cgi?id=42017. In AArch64, this
test-case need to be added with more live ranges for the need for the
LR_REGNUM. i.e test-case in the PR needs additional loops up to r31 for
the case AArch64 to see this.

The same fix (from the thread
https://gcc.gnu.org/ml/gcc-patches/2011-04/msg02191.html) which went
into ARM should apply to AArch64 as well. Regression tested on qemu for
aarch64-none-linux-gnu with no new regressions. Is this OK for trunk?
This still be a partial fix. LR should be a caller-saved register free
to use in case it's saved properly to across function call.
Indeed. This should be improved from the generic code. Right now, if a
hard register is used in EPILOGUE_USES, it conflicts with all the live
ranges till a call site kills.  I think we should have this patch till
the generic code can be improved.
below is my local patch. LR is treated as free register, and strictly
following AArch64 ABI, frame should always be created, FP maintained
properly if LR clobbered under -fno-omit-frame-pointer.
Thanks Jiong. Sorry I missed your point. As for the additions in your patch:

I am really sorry, just noticed the reply...

    /* ... and any callee saved register that dataflow says is live.  */
    for (regno = R0_REGNUM; regno <= R30_REGNUM; regno++)
      if (df_regs_ever_live_p (regno)
-       && !call_used_regs[regno])
+       && (regno == R30_REGNUM
+           || !call_used_regs[regno]))
        cfun->machine->frame.reg_offset[regno] = SLOT_REQUIRED;

AArch64 CALL_USED_REGISTERS defines R30_REGNUM to be zero. Therefore
shouldn’t this be redundant?

that's because the patch also modified r30 to be caller saved.


-    0, 0, 0, 0,   0, 1, 0, 1,  /* R24 - R30, SP */     \
+    0, 0, 0, 0,   0, 1, 1, 1,  /* R24 - R30, SP */     \

thus, we don't need ad-hoc code in pro/epi to save/restore LR.

on the other hand, we want LR to be a callee-saved register that it could be
used as free register is some scenario.

you can't compile the testcase lr_free_2.c for details.

      }
+  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.  */
+      if (to == STACK_POINTER_REGNUM
+         && flag_omit_leaf_frame_pointer
+         && df_regs_ever_live_p (LR_REGNUM))
+       return false;
+    }

aarch64_frame_pointer_required makes frame pointer needed when
flag_omit_leaf_frame_pointer and df_regs_ever_live_p (LR_REGNUM).
Is this addition still needed?

it's needed.

the problem is the df_reg_ever_live_p (LR_REGNUM) in 
"aarch64_frame_pointer_required"

  if (flag_omit_leaf_frame_pointer
      && (!crtl->is_leaf || df_regs_ever_live_p (LR_REGNUM)))

is invoked before register allocation that it can only catch those LR_REGNUM 
alive scenarios produced
by inline assembly clobber, for example __asm__ ("":::"x30"), written by user 
explicitly in code, while
it can't catch the scenarios that LR_REGNUM allocated by register allocator.

so, we need to add another check in aarch64_can_eliminate which is invoked 
after register allocation to
catch those scenarios where LR allocated by register allocator.

thanks.


Thanks,
Kugan



Reply via email to