public inbox for gcc-patches@gcc.gnu.org
 help / color / mirror / Atom feed
* [PATCH][AArch64] LR register not used in leaf functions
@ 2014-09-22 15:43 Kugan
  2014-09-22 15:58 ` Jiong Wang
  0 siblings, 1 reply; 12+ messages in thread
From: Kugan @ 2014-09-22 15:43 UTC (permalink / raw)
  To: gcc-patches; +Cc: Marcus Shawcroft, Richard Earnshaw

[-- Attachment #1: Type: text/plain, Size: 780 bytes --]

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?

Thanks,
Kugan


gcc/ChangeLog:

2014-09-23  Kugan Vivekanandarajah  <kuganv@linaro.org>

	* config/aarch64/aarch64.h (EPILOGUE_USES): Return true only after
	epilogue_completed is true.

[-- Attachment #2: p.txt --]
[-- Type: text/plain, Size: 549 bytes --]

diff --git a/gcc/config/aarch64/aarch64.h b/gcc/config/aarch64/aarch64.h
index db950da..b3e4585 100644
--- a/gcc/config/aarch64/aarch64.h
+++ b/gcc/config/aarch64/aarch64.h
@@ -309,7 +309,7 @@ extern unsigned long aarch64_tune_flags;
    considered live at the start of the called function.  */
 
 #define EPILOGUE_USES(REGNO) \
-  ((REGNO) == LR_REGNUM)
+  (epilogue_completed && (REGNO) == LR_REGNUM)
 
 /* EXIT_IGNORE_STACK should be nonzero if, when returning from a function,
    the stack pointer does not matter.  The value is tested only in

^ permalink raw reply	[flat|nested] 12+ messages in thread

* Re: [PATCH][AArch64] LR register not used in leaf functions
  2014-09-22 15:43 [PATCH][AArch64] LR register not used in leaf functions Kugan
@ 2014-09-22 15:58 ` Jiong Wang
  2014-09-27 21:20   ` Kugan
  0 siblings, 1 reply; 12+ messages in thread
From: Jiong Wang @ 2014-09-22 15:58 UTC (permalink / raw)
  To: Kugan, gcc-patches; +Cc: Marcus Shawcroft, Richard Earnshaw

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.

I had a very similar patch to this sitting in my local tree and under
various benchmark analysis.

-- Jiong
>
> Thanks,
> Kugan
>
>
> gcc/ChangeLog:
>
> 2014-09-23  Kugan Vivekanandarajah  <kuganv@linaro.org>
>
> 	* config/aarch64/aarch64.h (EPILOGUE_USES): Return true only after
> 	epilogue_completed is true.
>


^ permalink raw reply	[flat|nested] 12+ messages in thread

* Re: [PATCH][AArch64] LR register not used in leaf functions
  2014-09-22 15:58 ` Jiong Wang
@ 2014-09-27 21:20   ` Kugan
  2014-09-30 15:00     ` Jiong Wang
  0 siblings, 1 reply; 12+ messages in thread
From: Kugan @ 2014-09-27 21:20 UTC (permalink / raw)
  To: Jiong Wang, gcc-patches; +Cc: Marcus Shawcroft, Richard Earnshaw



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.

Thanks,
Kugan

> 
> I had a very similar patch to this sitting in my local tree and under
> various benchmark analysis.
> 
> -- Jiong
>>
>> Thanks,
>> Kugan
>>
>>
>> gcc/ChangeLog:
>>
>> 2014-09-23  Kugan Vivekanandarajah  <kuganv@linaro.org>
>>
>>     * config/aarch64/aarch64.h (EPILOGUE_USES): Return true only after
>>     epilogue_completed is true.
>>
> 
> 

^ permalink raw reply	[flat|nested] 12+ messages in thread

* Re: [PATCH][AArch64] LR register not used in leaf functions
  2014-09-27 21:20   ` Kugan
@ 2014-09-30 15:00     ` Jiong Wang
  2014-10-01  8:00       ` Kugan
                         ` (2 more replies)
  0 siblings, 3 replies; 12+ messages in thread
From: Jiong Wang @ 2014-09-30 15:00 UTC (permalink / raw)
  To: Kugan, gcc-patches; +Cc: Marcus Shawcroft, Richard Earnshaw

[-- Attachment #1: Type: text/plain, Size: 1823 bytes --]

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.


gcc/
   * config/aarch64/aarch64.h (CALL_USED_REGISTERS): Mark LR as caller-save.
   (EPILOGUE_USES): Guard the check by epilogue_completed.
   * config/aarch64/aarch64.c (aarch64_layout_frame): Explictly check for LR.
   (aarch64_can_eliminate): Check LR_REGNUM liveness.

gcc/testsuite/
   * gcc.target/aarch64/lr_free_1.c: New testcase for -fomit-frame-pointer.
   * gcc.target/aarch64/lr_free_2.c: New testcase for leaf -fno-omit-frame-pointer.

[-- Warning: decoded text below may be mangled, UTF-8 assumed --]
[-- Attachment #2: new-fix.patch --]
[-- Type: text/x-patch; name=new-fix.patch, Size: 4866 bytes --]

diff --git a/gcc/config/aarch64/aarch64.h b/gcc/config/aarch64/aarch64.h
index db950da..892b310 100644
--- a/gcc/config/aarch64/aarch64.h
+++ b/gcc/config/aarch64/aarch64.h
@@ -250,7 +250,7 @@ extern unsigned long aarch64_tune_flags;
     1, 1, 1, 1,   1, 1, 1, 1,	/* R0 - R7 */		\
     1, 1, 1, 1,   1, 1, 1, 1,	/* R8 - R15 */		\
     1, 1, 1, 0,   0, 0, 0, 0,	/* R16 - R23 */		\
-    0, 0, 0, 0,   0, 1, 0, 1,	/* R24 - R30, SP */	\
+    0, 0, 0, 0,   0, 1, 1, 1,	/* R24 - R30, SP */	\
     1, 1, 1, 1,   1, 1, 1, 1,	/* V0 - V7 */		\
     0, 0, 0, 0,   0, 0, 0, 0,	/* V8 - V15 */		\
     1, 1, 1, 1,   1, 1, 1, 1,   /* V16 - V23 */         \
@@ -309,7 +309,7 @@ extern unsigned long aarch64_tune_flags;
    considered live at the start of the called function.  */
 
 #define EPILOGUE_USES(REGNO) \
-  ((REGNO) == LR_REGNUM)
+  (epilogue_completed && (REGNO) == LR_REGNUM)
 
 /* EXIT_IGNORE_STACK should be nonzero if, when returning from a function,
    the stack pointer does not matter.  The value is tested only in
diff --git a/gcc/config/aarch64/aarch64.c b/gcc/config/aarch64/aarch64.c
index 15c7be6..8b39b2a 100644
--- a/gcc/config/aarch64/aarch64.c
+++ b/gcc/config/aarch64/aarch64.c
@@ -1864,7 +1864,8 @@ aarch64_layout_frame (void)
   /* ... 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;
 
   for (regno = V0_REGNUM; regno <= V31_REGNUM; regno++)
@@ -4313,6 +4314,16 @@ aarch64_can_eliminate (const int from, const int to)
 
       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.  */
+      if (to == STACK_POINTER_REGNUM
+	  && flag_omit_leaf_frame_pointer
+	  && df_regs_ever_live_p (LR_REGNUM))
+	return false;
+    }
 
   return true;
 }
diff --git a/gcc/testsuite/gcc.target/aarch64/lr_free_1.c b/gcc/testsuite/gcc.target/aarch64/lr_free_1.c
new file mode 100644
index 0000000..4c530a2
--- /dev/null
+++ b/gcc/testsuite/gcc.target/aarch64/lr_free_1.c
@@ -0,0 +1,38 @@
+/* { dg-do run } */
+/* { dg-options "-fno-inline -O2 -fomit-frame-pointer -ffixed-x2 -ffixed-x3 -ffixed-x4 -ffixed-x5 -ffixed-x6 -ffixed-x7 -ffixed-x8 -ffixed-x9 -ffixed-x10 -ffixed-x11 -ffixed-x12 -ffixed-x13 -ffixed-x14 -ffixed-x15 -ffixed-x16 -ffixed-x17 -ffixed-x18 -ffixed-x19 -ffixed-x20 -ffixed-x21 -ffixed-x22 -ffixed-x23 -ffixed-x24 -ffixed-x25 -ffixed-x26 -ffixed-x27 -ffixed-28 -ffixed-29 --save-temps -mgeneral-regs-only -fno-ipa-cp" } */
+
+extern void abort ();
+
+int
+dec (int a, int b)
+{
+  return a + b;
+}
+
+int
+cal (int a, int b)
+{
+  int sum1 = a * b;
+  int sum2 = a / b;
+  int sum = dec (sum1, sum2);
+  return a + b + sum + sum1 + sum2;
+}
+
+int
+main (int argc, char **argv)
+{
+  int ret = cal (2, 1);
+
+  if (ret != 11)
+    abort ();
+
+  return 0;
+}
+
+/* { dg-final { scan-assembler-times "str\tx30, \\\[sp, -\[0-9\]+\\\]!" 2 } } */
+/* { dg-final { scan-assembler "str\tw30, \\\[sp, \[0-9\]+\\\]" } } */
+
+/* { dg-final { scan-assembler "ldr\tw30, \\\[sp, \[0-9\]+\\\]" } } */
+/* { dg-final { scan-assembler-times "ldr\tx30, \\\[sp\\\], \[0-9\]+" 2 } } */
+
+/* { dg-final { cleanup-saved-temps } } */
diff --git a/gcc/testsuite/gcc.target/aarch64/lr_free_2.c b/gcc/testsuite/gcc.target/aarch64/lr_free_2.c
new file mode 100644
index 0000000..2bfb6ad
--- /dev/null
+++ b/gcc/testsuite/gcc.target/aarch64/lr_free_2.c
@@ -0,0 +1,29 @@
+/* { dg-do run } */
+/* { dg-options "-fno-inline -O2 -ffixed-x2 -ffixed-x3 -ffixed-x4 -ffixed-x5 -ffixed-x6 -ffixed-x7 -ffixed-x8 -ffixed-x9 -ffixed-x10 -ffixed-x11 -ffixed-x12 -ffixed-x13 -ffixed-x14 -ffixed-x15 -ffixed-x16 -ffixed-x17 -ffixed-x18 -ffixed-x19 -ffixed-x20 -ffixed-x21 -ffixed-x22 -ffixed-x23 -ffixed-x24 -ffixed-x25 -ffixed-x26 -ffixed-x27 -ffixed-x28 --save-temps -mgeneral-regs-only -fno-ipa-cp -fdump-rtl-ira" } */
+
+extern void abort ();
+
+int
+cal (int a, int b)
+{
+  /* { dg-final { scan-assembler-times "stp\tx29, x30, \\\[sp, -\[0-9\]+\\\]!" 2 } } */
+  int sum = a + b;
+  int sum1 = a * b;
+  /* { dg-final { scan-assembler-times "ldr\tx29, x30, \\\[sp\\\], \[0-9\]+" 2 } } */
+  /* { dg-final { scan-rtl-dump "assign reg 30" "ira" } } */
+  return (a + b + sum + sum1);
+}
+
+int
+main (int argc, char **argv)
+{
+  int ret = cal (1, 2);
+
+  if (ret != 8)
+    abort ();
+
+  return 0;
+}
+
+/* { dg-final { cleanup-saved-temps } } */
+/* { dg-final { cleanup-rtl-dump "ira" } } */

^ permalink raw reply	[flat|nested] 12+ messages in thread

* Re: [PATCH][AArch64] LR register not used in leaf functions
  2014-09-30 15:00     ` Jiong Wang
@ 2014-10-01  8:00       ` Kugan
  2014-11-04 10:56         ` Jiong Wang
  2014-11-11 14:52       ` Marcus Shawcroft
  2014-11-15  0:52       ` Andrew Pinski
  2 siblings, 1 reply; 12+ messages in thread
From: Kugan @ 2014-10-01  8:00 UTC (permalink / raw)
  To: Jiong Wang, gcc-patches; +Cc: Marcus Shawcroft, Richard Earnshaw


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:


   /* ... 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?


   for (regno = V0_REGNUM; regno <= V31_REGNUM; regno++)
@@ -4313,6 +4314,16 @@ aarch64_can_eliminate (const int from, const int to)

       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.  */
+      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?

Thanks,
Kugan

^ permalink raw reply	[flat|nested] 12+ messages in thread

* Re: [PATCH][AArch64] LR register not used in leaf functions
  2014-10-01  8:00       ` Kugan
@ 2014-11-04 10:56         ` Jiong Wang
  0 siblings, 0 replies; 12+ messages in thread
From: Jiong Wang @ 2014-11-04 10:56 UTC (permalink / raw)
  To: Kugan, gcc-patches; +Cc: Marcus Shawcroft, Richard Earnshaw


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
>


^ permalink raw reply	[flat|nested] 12+ messages in thread

* Re: [PATCH][AArch64] LR register not used in leaf functions
  2014-09-30 15:00     ` Jiong Wang
  2014-10-01  8:00       ` Kugan
@ 2014-11-11 14:52       ` Marcus Shawcroft
  2014-11-15  0:52       ` Andrew Pinski
  2 siblings, 0 replies; 12+ messages in thread
From: Marcus Shawcroft @ 2014-11-11 14:52 UTC (permalink / raw)
  To: Jiong Wang; +Cc: Kugan, gcc-patches

On 30 September 2014 16:00, Jiong Wang <jiong.wang@arm.com> wrote:

> gcc/
>   * config/aarch64/aarch64.h (CALL_USED_REGISTERS): Mark LR as caller-save.
>   (EPILOGUE_USES): Guard the check by epilogue_completed.
>   * config/aarch64/aarch64.c (aarch64_layout_frame): Explictly check for LR.
>   (aarch64_can_eliminate): Check LR_REGNUM liveness.
>
> gcc/testsuite/
>   * gcc.target/aarch64/lr_free_1.c: New testcase for -fomit-frame-pointer.
>   * gcc.target/aarch64/lr_free_2.c: New testcase for leaf
> -fno-omit-frame-pointer.

OK /Marcus

^ permalink raw reply	[flat|nested] 12+ messages in thread

* Re: [PATCH][AArch64] LR register not used in leaf functions
  2014-09-30 15:00     ` Jiong Wang
  2014-10-01  8:00       ` Kugan
  2014-11-11 14:52       ` Marcus Shawcroft
@ 2014-11-15  0:52       ` Andrew Pinski
  2014-11-15 15:27         ` Jiong Wang
  2 siblings, 1 reply; 12+ messages in thread
From: Andrew Pinski @ 2014-11-15  0:52 UTC (permalink / raw)
  To: Jiong Wang; +Cc: Kugan, gcc-patches, Marcus Shawcroft, Richard Earnshaw

On Tue, Sep 30, 2014 at 8:00 AM, Jiong Wang <jiong.wang@arm.com> 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.
>
>
> gcc/
>   * config/aarch64/aarch64.h (CALL_USED_REGISTERS): Mark LR as caller-save.
>   (EPILOGUE_USES): Guard the check by epilogue_completed.
>   * config/aarch64/aarch64.c (aarch64_layout_frame): Explictly check for LR.
>   (aarch64_can_eliminate): Check LR_REGNUM liveness.
>
> gcc/testsuite/
>   * gcc.target/aarch64/lr_free_1.c: New testcase for -fomit-frame-pointer.
>   * gcc.target/aarch64/lr_free_2.c: New testcase for leaf
> -fno-omit-frame-pointer.

+      /* 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;

This breaks my build on aarch64-elf (with some local modifications) as
aarch64_frame_pointer_required returns true but then we use LR but now
aarch64_can_eliminate and aarch64_frame_pointer_required are
inconsitant which is not a valid thing for LRA (and reload).

This was mentioned in https://gcc.gnu.org/ml/gcc-patches/2013-12/msg00151.html :
" IRA calls hook frame_pointer_required and it returns false. After
that LRA calls can_eliminate hook and it returns false which means
that fp can not be used for allocation and we should spill all pseudos
assigned to it."

Can you revert your patch until you can figure out how to get LRA (and
reload) to play nicely with what you want to do?

Thanks,
Andrew Pinski

^ permalink raw reply	[flat|nested] 12+ messages in thread

* Re: [PATCH][AArch64] LR register not used in leaf functions
  2014-11-15  0:52       ` Andrew Pinski
@ 2014-11-15 15:27         ` Jiong Wang
  2014-11-15 15:49           ` Andrew Pinski
  0 siblings, 1 reply; 12+ messages in thread
From: Jiong Wang @ 2014-11-15 15:27 UTC (permalink / raw)
  To: Andrew Pinski
  Cc: Jiong Wang, Kugan, gcc-patches, Marcus Shawcroft, Richard Earnshaw

2014-11-15 0:15 GMT+00:00 Andrew Pinski <pinskia@gmail.com>:
> On Tue, Sep 30, 2014 at 8:00 AM, Jiong Wang <jiong.wang@arm.com> wrote:
>> On 27/09/14 22:20, Kugan wrote:
>>>
>>>
>>> On 23/09/14 01:58, Jiong Wang wrote:
>
> +      /* 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;
>
> This breaks my build on aarch64-elf (with some local modifications)

Hi Andrew,

  then what's your local modification?
  I think the problem is we need to figure out why there is an ICE
after your local modification?
  can you please send me your local modification and testcase if possible.


> aarch64_frame_pointer_required returns true but then we use LR but now
> aarch64_can_eliminate and aarch64_frame_pointer_required are
> inconsitant which is not a valid thing for LRA (and reload).
>
> This was mentioned in https://gcc.gnu.org/ml/gcc-patches/2013-12/msg00151.html :
> " IRA calls hook frame_pointer_required and it returns false. After
> that LRA calls can_eliminate hook and it returns false which means
> that fp can not be used for allocation and we should spill all pseudos
> assigned to it."
>
> Thanks,
> Andrew Pinski

^ permalink raw reply	[flat|nested] 12+ messages in thread

* Re: [PATCH][AArch64] LR register not used in leaf functions
  2014-11-15 15:27         ` Jiong Wang
@ 2014-11-15 15:49           ` Andrew Pinski
  2014-11-15 16:37             ` Andrew Pinski
  0 siblings, 1 reply; 12+ messages in thread
From: Andrew Pinski @ 2014-11-15 15:49 UTC (permalink / raw)
  To: Jiong Wang
  Cc: Jiong Wang, Kugan, gcc-patches, Marcus Shawcroft, Richard Earnshaw

On Sat, Nov 15, 2014 at 6:08 AM, Jiong Wang
<wong.kwongyuan.tools@gmail.com> wrote:
> 2014-11-15 0:15 GMT+00:00 Andrew Pinski <pinskia@gmail.com>:
>> On Tue, Sep 30, 2014 at 8:00 AM, Jiong Wang <jiong.wang@arm.com> wrote:
>>> On 27/09/14 22:20, Kugan wrote:
>>>>
>>>>
>>>> On 23/09/14 01:58, Jiong Wang wrote:
>>
>> +      /* 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;
>>
>> This breaks my build on aarch64-elf (with some local modifications)
>
> Hi Andrew,
>
>   then what's your local modification?
>   I think the problem is we need to figure out why there is an ICE
> after your local modification?
>   can you please send me your local modification and testcase if possible.

My local modifications can be found in the gcc git at
apinski/thunderx-cost.  Note I reverted this patch so I can continue
working.  The testcase is compiling newlib.  Let me try to get it
again.
I was configuring a combined build with:
--disable-fixed-point --without-ppl --without-python --disable-werror
--enable-plugins --enable-checking --disable-sim --with-newlib
--disable-tls --with-cpu=thunderx --with-multilib-list=lp64,ilp32
--target=aarch64-thunderx-elf --enable-languages=c,c++

Thanks,
Andrew Pinski

>
>
>> aarch64_frame_pointer_required returns true but then we use LR but now
>> aarch64_can_eliminate and aarch64_frame_pointer_required are
>> inconsitant which is not a valid thing for LRA (and reload).
>>
>> This was mentioned in https://gcc.gnu.org/ml/gcc-patches/2013-12/msg00151.html :
>> " IRA calls hook frame_pointer_required and it returns false. After
>> that LRA calls can_eliminate hook and it returns false which means
>> that fp can not be used for allocation and we should spill all pseudos
>> assigned to it."
>>
>> Thanks,
>> Andrew Pinski

^ permalink raw reply	[flat|nested] 12+ messages in thread

* Re: [PATCH][AArch64] LR register not used in leaf functions
  2014-11-15 15:49           ` Andrew Pinski
@ 2014-11-15 16:37             ` Andrew Pinski
  2014-11-15 20:29               ` Jiong Wang
  0 siblings, 1 reply; 12+ messages in thread
From: Andrew Pinski @ 2014-11-15 16:37 UTC (permalink / raw)
  To: Jiong Wang
  Cc: Jiong Wang, Kugan, gcc-patches, Marcus Shawcroft, Richard Earnshaw

[-- Attachment #1: Type: text/plain, Size: 2317 bytes --]

On Sat, Nov 15, 2014 at 7:21 AM, Andrew Pinski <pinskia@gmail.com> wrote:
> On Sat, Nov 15, 2014 at 6:08 AM, Jiong Wang
> <wong.kwongyuan.tools@gmail.com> wrote:
>> 2014-11-15 0:15 GMT+00:00 Andrew Pinski <pinskia@gmail.com>:
>>> On Tue, Sep 30, 2014 at 8:00 AM, Jiong Wang <jiong.wang@arm.com> wrote:
>>>> On 27/09/14 22:20, Kugan wrote:
>>>>>
>>>>>
>>>>> On 23/09/14 01:58, Jiong Wang wrote:
>>>
>>> +      /* 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;
>>>
>>> This breaks my build on aarch64-elf (with some local modifications)
>>
>> Hi Andrew,
>>
>>   then what's your local modification?
>>   I think the problem is we need to figure out why there is an ICE
>> after your local modification?
>>   can you please send me your local modification and testcase if possible.
>
> My local modifications can be found in the gcc git at
> apinski/thunderx-cost.  Note I reverted this patch so I can continue
> working.  The testcase is compiling newlib.  Let me try to get it
> again.
> I was configuring a combined build with:
> --disable-fixed-point --without-ppl --without-python --disable-werror
> --enable-plugins --enable-checking --disable-sim --with-newlib
> --disable-tls --with-cpu=thunderx --with-multilib-list=lp64,ilp32
> --target=aarch64-thunderx-elf --enable-languages=c,c++

Attached is the preprocessed source.
cc1 strtol.i -mabi=ilp32 -O2
is enough to reproduce the ICE.

Thanks,
Andrew

>
> Thanks,
> Andrew Pinski
>
>>
>>
>>> aarch64_frame_pointer_required returns true but then we use LR but now
>>> aarch64_can_eliminate and aarch64_frame_pointer_required are
>>> inconsitant which is not a valid thing for LRA (and reload).
>>>
>>> This was mentioned in https://gcc.gnu.org/ml/gcc-patches/2013-12/msg00151.html :
>>> " IRA calls hook frame_pointer_required and it returns false. After
>>> that LRA calls can_eliminate hook and it returns false which means
>>> that fp can not be used for allocation and we should spill all pseudos
>>> assigned to it."
>>>
>>> Thanks,
>>> Andrew Pinski

[-- Attachment #2: strtol.i --]
[-- Type: application/octet-stream, Size: 28916 bytes --]

# 1 "/data1/src/gcc-cavium/toolchain-thunder/scripts/../src/newlib/libc/stdlib/strtol.c"
# 1 "/home/apinski/src/gcc-cavium/toolchain-thunder/build-aarch64-thunderx-elf/aarch64-thunderx-elf/ilp32/newlib//"
# 1 "<built-in>"
# 1 "<command-line>"
# 1 "/data1/src/gcc-cavium/toolchain-thunder/scripts/../src/newlib/libc/stdlib/strtol.c"
# 120 "/data1/src/gcc-cavium/toolchain-thunder/scripts/../src/newlib/libc/stdlib/strtol.c"
# 1 "/data1/src/gcc-cavium/toolchain-thunder/src/newlib/libc/include/_ansi.h" 1 3 4
# 15 "/data1/src/gcc-cavium/toolchain-thunder/src/newlib/libc/include/_ansi.h" 3 4
# 1 "./newlib.h" 1 3 4
# 16 "/data1/src/gcc-cavium/toolchain-thunder/src/newlib/libc/include/_ansi.h" 2 3 4
# 1 "/data1/src/gcc-cavium/toolchain-thunder/src/newlib/libc/include/sys/config.h" 1 3 4



# 1 "/data1/src/gcc-cavium/toolchain-thunder/src/newlib/libc/include/machine/ieeefp.h" 1 3 4
# 5 "/data1/src/gcc-cavium/toolchain-thunder/src/newlib/libc/include/sys/config.h" 2 3 4
# 1 "/data1/src/gcc-cavium/toolchain-thunder/src/newlib/libc/include/sys/features.h" 1 3 4
# 6 "/data1/src/gcc-cavium/toolchain-thunder/src/newlib/libc/include/sys/config.h" 2 3 4
# 17 "/data1/src/gcc-cavium/toolchain-thunder/src/newlib/libc/include/_ansi.h" 2 3 4
# 121 "/data1/src/gcc-cavium/toolchain-thunder/scripts/../src/newlib/libc/stdlib/strtol.c" 2
# 1 "/data1/src/gcc-cavium/toolchain-thunder/build-aarch64-thunderx-elf/gcc/include-fixed/limits.h" 1 3 4
# 34 "/data1/src/gcc-cavium/toolchain-thunder/build-aarch64-thunderx-elf/gcc/include-fixed/limits.h" 3 4
# 1 "/data1/src/gcc-cavium/toolchain-thunder/build-aarch64-thunderx-elf/gcc/include-fixed/syslimits.h" 1 3 4






# 1 "/data1/src/gcc-cavium/toolchain-thunder/build-aarch64-thunderx-elf/gcc/include-fixed/limits.h" 1 3 4
# 168 "/data1/src/gcc-cavium/toolchain-thunder/build-aarch64-thunderx-elf/gcc/include-fixed/limits.h" 3 4
# 1 "/data1/src/gcc-cavium/toolchain-thunder/src/newlib/libc/include/limits.h" 1 3 4
# 169 "/data1/src/gcc-cavium/toolchain-thunder/build-aarch64-thunderx-elf/gcc/include-fixed/limits.h" 2 3 4
# 8 "/data1/src/gcc-cavium/toolchain-thunder/build-aarch64-thunderx-elf/gcc/include-fixed/syslimits.h" 2 3 4
# 35 "/data1/src/gcc-cavium/toolchain-thunder/build-aarch64-thunderx-elf/gcc/include-fixed/limits.h" 2 3 4
# 122 "/data1/src/gcc-cavium/toolchain-thunder/scripts/../src/newlib/libc/stdlib/strtol.c" 2
# 1 "/data1/src/gcc-cavium/toolchain-thunder/src/newlib/libc/include/ctype.h" 1 3 4



# 1 "/data1/src/gcc-cavium/toolchain-thunder/src/newlib/libc/include/_ansi.h" 1 3 4
# 5 "/data1/src/gcc-cavium/toolchain-thunder/src/newlib/libc/include/ctype.h" 2 3 4




# 8 "/data1/src/gcc-cavium/toolchain-thunder/src/newlib/libc/include/ctype.h" 3 4
int isalnum (int __c);
int isalpha (int __c);
int iscntrl (int __c);
int isdigit (int __c);
int isgraph (int __c);
int islower (int __c);
int isprint (int __c);
int ispunct (int __c);
int isspace (int __c);
int isupper (int __c);
int isxdigit (int __c);
int tolower (int __c);
int toupper (int __c);


int isblank (int __c);



int isascii (int __c);
int toascii (int __c);
# 43 "/data1/src/gcc-cavium/toolchain-thunder/src/newlib/libc/include/ctype.h" 3 4
const

extern char *__ctype_ptr__;
# 109 "/data1/src/gcc-cavium/toolchain-thunder/src/newlib/libc/include/ctype.h" 3 4
extern const char _ctype_[];


# 123 "/data1/src/gcc-cavium/toolchain-thunder/scripts/../src/newlib/libc/stdlib/strtol.c" 2
# 1 "/data1/src/gcc-cavium/toolchain-thunder/src/newlib/libc/include/errno.h" 1 3 4




typedef int error_t;



# 1 "/data1/src/gcc-cavium/toolchain-thunder/src/newlib/libc/include/sys/errno.h" 1 3 4
# 11 "/data1/src/gcc-cavium/toolchain-thunder/src/newlib/libc/include/sys/errno.h" 3 4
# 1 "/data1/src/gcc-cavium/toolchain-thunder/src/newlib/libc/include/sys/reent.h" 1 3 4
# 14 "/data1/src/gcc-cavium/toolchain-thunder/src/newlib/libc/include/sys/reent.h" 3 4
# 1 "/data1/src/gcc-cavium/toolchain-thunder/build-aarch64-thunderx-elf/gcc/include/stddef.h" 1 3 4
# 149 "/data1/src/gcc-cavium/toolchain-thunder/build-aarch64-thunderx-elf/gcc/include/stddef.h" 3 4
typedef long int ptrdiff_t;
# 216 "/data1/src/gcc-cavium/toolchain-thunder/build-aarch64-thunderx-elf/gcc/include/stddef.h" 3 4
typedef long unsigned int size_t;
# 328 "/data1/src/gcc-cavium/toolchain-thunder/build-aarch64-thunderx-elf/gcc/include/stddef.h" 3 4
typedef unsigned int wchar_t;
# 426 "/data1/src/gcc-cavium/toolchain-thunder/build-aarch64-thunderx-elf/gcc/include/stddef.h" 3 4
typedef struct {
  long long __max_align_ll __attribute__((__aligned__(__alignof__(long long))));
  long double __max_align_ld __attribute__((__aligned__(__alignof__(long double))));
} max_align_t;
# 15 "/data1/src/gcc-cavium/toolchain-thunder/src/newlib/libc/include/sys/reent.h" 2 3 4
# 1 "/data1/src/gcc-cavium/toolchain-thunder/src/newlib/libc/include/sys/_types.h" 1 3 4
# 12 "/data1/src/gcc-cavium/toolchain-thunder/src/newlib/libc/include/sys/_types.h" 3 4
# 1 "/data1/src/gcc-cavium/toolchain-thunder/build-aarch64-thunderx-elf/aarch64-thunderx-elf/ilp32/newlib/targ-include/machine/_types.h" 1 3 4
# 32 "/data1/src/gcc-cavium/toolchain-thunder/build-aarch64-thunderx-elf/aarch64-thunderx-elf/ilp32/newlib/targ-include/machine/_types.h" 3 4
# 1 "/data1/src/gcc-cavium/toolchain-thunder/src/newlib/libc/include/machine/_default_types.h" 1 3 4
# 27 "/data1/src/gcc-cavium/toolchain-thunder/src/newlib/libc/include/machine/_default_types.h" 3 4
typedef signed char __int8_t;

typedef unsigned char __uint8_t;
# 41 "/data1/src/gcc-cavium/toolchain-thunder/src/newlib/libc/include/machine/_default_types.h" 3 4
typedef short int __int16_t;

typedef short unsigned int __uint16_t;
# 63 "/data1/src/gcc-cavium/toolchain-thunder/src/newlib/libc/include/machine/_default_types.h" 3 4
typedef long int __int32_t;

typedef long unsigned int __uint32_t;
# 89 "/data1/src/gcc-cavium/toolchain-thunder/src/newlib/libc/include/machine/_default_types.h" 3 4
typedef long long int __int64_t;

typedef long long unsigned int __uint64_t;
# 120 "/data1/src/gcc-cavium/toolchain-thunder/src/newlib/libc/include/machine/_default_types.h" 3 4
typedef signed char __int_least8_t;

typedef unsigned char __uint_least8_t;
# 146 "/data1/src/gcc-cavium/toolchain-thunder/src/newlib/libc/include/machine/_default_types.h" 3 4
typedef short int __int_least16_t;

typedef short unsigned int __uint_least16_t;
# 168 "/data1/src/gcc-cavium/toolchain-thunder/src/newlib/libc/include/machine/_default_types.h" 3 4
typedef long int __int_least32_t;

typedef long unsigned int __uint_least32_t;
# 186 "/data1/src/gcc-cavium/toolchain-thunder/src/newlib/libc/include/machine/_default_types.h" 3 4
typedef long long int __int_least64_t;

typedef long long unsigned int __uint_least64_t;
# 200 "/data1/src/gcc-cavium/toolchain-thunder/src/newlib/libc/include/machine/_default_types.h" 3 4
typedef long int __intptr_t;

typedef long unsigned int __uintptr_t;
# 33 "/data1/src/gcc-cavium/toolchain-thunder/build-aarch64-thunderx-elf/aarch64-thunderx-elf/ilp32/newlib/targ-include/machine/_types.h" 2 3 4


typedef long signed int _ssize_t;
# 13 "/data1/src/gcc-cavium/toolchain-thunder/src/newlib/libc/include/sys/_types.h" 2 3 4
# 1 "/data1/src/gcc-cavium/toolchain-thunder/src/newlib/libc/include/sys/lock.h" 1 3 4





typedef int _LOCK_T;
typedef int _LOCK_RECURSIVE_T;
# 14 "/data1/src/gcc-cavium/toolchain-thunder/src/newlib/libc/include/sys/_types.h" 2 3 4


typedef long _off_t;



typedef short __dev_t;



typedef unsigned short __uid_t;


typedef unsigned short __gid_t;



__extension__ typedef long long _off64_t;







typedef long _fpos_t;
# 67 "/data1/src/gcc-cavium/toolchain-thunder/src/newlib/libc/include/sys/_types.h" 3 4
# 1 "/data1/src/gcc-cavium/toolchain-thunder/build-aarch64-thunderx-elf/gcc/include/stddef.h" 1 3 4
# 357 "/data1/src/gcc-cavium/toolchain-thunder/build-aarch64-thunderx-elf/gcc/include/stddef.h" 3 4
typedef unsigned int wint_t;
# 68 "/data1/src/gcc-cavium/toolchain-thunder/src/newlib/libc/include/sys/_types.h" 2 3 4



typedef struct
{
  int __count;
  union
  {
    wint_t __wch;
    unsigned char __wchb[4];
  } __value;
} _mbstate_t;



typedef _LOCK_RECURSIVE_T _flock_t;




typedef void *_iconv_t;
# 16 "/data1/src/gcc-cavium/toolchain-thunder/src/newlib/libc/include/sys/reent.h" 2 3 4






typedef unsigned long __ULong;
# 38 "/data1/src/gcc-cavium/toolchain-thunder/src/newlib/libc/include/sys/reent.h" 3 4
struct _reent;






struct _Bigint
{
  struct _Bigint *_next;
  int _k, _maxwds, _sign, _wds;
  __ULong _x[1];
};


struct __tm
{
  int __tm_sec;
  int __tm_min;
  int __tm_hour;
  int __tm_mday;
  int __tm_mon;
  int __tm_year;
  int __tm_wday;
  int __tm_yday;
  int __tm_isdst;
};







struct _on_exit_args {
 void * _fnargs[32];
 void * _dso_handle[32];

 __ULong _fntypes;


 __ULong _is_cxa;
};
# 91 "/data1/src/gcc-cavium/toolchain-thunder/src/newlib/libc/include/sys/reent.h" 3 4
struct _atexit {
 struct _atexit *_next;
 int _ind;

 void (*_fns[32])(void);
        struct _on_exit_args _on_exit_args;
};
# 115 "/data1/src/gcc-cavium/toolchain-thunder/src/newlib/libc/include/sys/reent.h" 3 4
struct __sbuf {
 unsigned char *_base;
 int _size;
};
# 179 "/data1/src/gcc-cavium/toolchain-thunder/src/newlib/libc/include/sys/reent.h" 3 4
struct __sFILE {
  unsigned char *_p;
  int _r;
  int _w;
  short _flags;
  short _file;
  struct __sbuf _bf;
  int _lbfsize;






  void * _cookie;

  int (* _read) (struct _reent *, void *, char *, int)
                                          ;
  int (* _write) (struct _reent *, void *, const char *, int)

                                   ;
  _fpos_t (* _seek) (struct _reent *, void *, _fpos_t, int);
  int (* _close) (struct _reent *, void *);


  struct __sbuf _ub;
  unsigned char *_up;
  int _ur;


  unsigned char _ubuf[3];
  unsigned char _nbuf[1];


  struct __sbuf _lb;


  int _blksize;
  _off_t _offset;


  struct _reent *_data;



  _flock_t _lock;

  _mbstate_t _mbstate;
  int _flags2;
};
# 285 "/data1/src/gcc-cavium/toolchain-thunder/src/newlib/libc/include/sys/reent.h" 3 4
typedef struct __sFILE __FILE;



struct _glue
{
  struct _glue *_next;
  int _niobs;
  __FILE *_iobs;
};
# 317 "/data1/src/gcc-cavium/toolchain-thunder/src/newlib/libc/include/sys/reent.h" 3 4
struct _rand48 {
  unsigned short _seed[3];
  unsigned short _mult[3];
  unsigned short _add;




};
# 569 "/data1/src/gcc-cavium/toolchain-thunder/src/newlib/libc/include/sys/reent.h" 3 4
struct _reent
{
  int _errno;




  __FILE *_stdin, *_stdout, *_stderr;

  int _inc;
  char _emergency[25];

  int _current_category;
  const char *_current_locale;

  int __sdidinit;

  void (* __cleanup) (struct _reent *);


  struct _Bigint *_result;
  int _result_k;
  struct _Bigint *_p5s;
  struct _Bigint **_freelist;


  int _cvtlen;
  char *_cvtbuf;

  union
    {
      struct
        {
          unsigned int _unused_rand;
          char * _strtok_last;
          char _asctime_buf[26];
          struct __tm _localtime_buf;
          int _gamma_signgam;
          __extension__ unsigned long long _rand_next;
          struct _rand48 _r48;
          _mbstate_t _mblen_state;
          _mbstate_t _mbtowc_state;
          _mbstate_t _wctomb_state;
          char _l64a_buf[8];
          char _signal_buf[24];
          int _getdate_err;
          _mbstate_t _mbrlen_state;
          _mbstate_t _mbrtowc_state;
          _mbstate_t _mbsrtowcs_state;
          _mbstate_t _wcrtomb_state;
          _mbstate_t _wcsrtombs_state;
   int _h_errno;
        } _reent;



      struct
        {

          unsigned char * _nextf[30];
          unsigned int _nmalloc[30];
        } _unused;
    } _new;



  struct _atexit *_atexit;
  struct _atexit _atexit0;



  void (**(_sig_func))(int);




  struct _glue __sglue;
  __FILE __sf[3];
};
# 762 "/data1/src/gcc-cavium/toolchain-thunder/src/newlib/libc/include/sys/reent.h" 3 4
extern struct _reent *_impure_ptr ;
extern struct _reent *const _global_impure_ptr ;

void _reclaim_reent (struct _reent *);
# 12 "/data1/src/gcc-cavium/toolchain-thunder/src/newlib/libc/include/sys/errno.h" 2 3 4



extern int *__errno (void);




extern const char * const _sys_errlist[];
extern int _sys_nerr;
# 10 "/data1/src/gcc-cavium/toolchain-thunder/src/newlib/libc/include/errno.h" 2 3 4
# 124 "/data1/src/gcc-cavium/toolchain-thunder/scripts/../src/newlib/libc/stdlib/strtol.c" 2
# 1 "/data1/src/gcc-cavium/toolchain-thunder/src/newlib/libc/include/stdlib.h" 1 3 4
# 10 "/data1/src/gcc-cavium/toolchain-thunder/src/newlib/libc/include/stdlib.h" 3 4
# 1 "/data1/src/gcc-cavium/toolchain-thunder/src/newlib/libc/include/machine/ieeefp.h" 1 3 4
# 11 "/data1/src/gcc-cavium/toolchain-thunder/src/newlib/libc/include/stdlib.h" 2 3 4





# 1 "/data1/src/gcc-cavium/toolchain-thunder/build-aarch64-thunderx-elf/gcc/include/stddef.h" 1 3 4
# 17 "/data1/src/gcc-cavium/toolchain-thunder/src/newlib/libc/include/stdlib.h" 2 3 4


# 1 "/data1/src/gcc-cavium/toolchain-thunder/src/newlib/libc/include/machine/stdlib.h" 1 3 4
# 20 "/data1/src/gcc-cavium/toolchain-thunder/src/newlib/libc/include/stdlib.h" 2 3 4

# 1 "/data1/src/gcc-cavium/toolchain-thunder/src/newlib/libc/include/alloca.h" 1 3 4
# 22 "/data1/src/gcc-cavium/toolchain-thunder/src/newlib/libc/include/stdlib.h" 2 3 4








typedef struct
{
  int quot;
  int rem;
} div_t;

typedef struct
{
  long quot;
  long rem;
} ldiv_t;




typedef struct
{
  long long int quot;
  long long int rem;
} lldiv_t;




typedef int (*__compar_fn_t) (const void *, const void *);







int __locale_mb_cur_max (void);



void abort (void) __attribute__ ((__noreturn__));
int abs (int);
int atexit (void (*__func)(void));
double atof (const char *__nptr);

float atoff (const char *__nptr);

int atoi (const char *__nptr);
int _atoi_r (struct _reent *, const char *__nptr);
long atol (const char *__nptr);
long _atol_r (struct _reent *, const char *__nptr);
void * bsearch (const void * __key, const void * __base, size_t __nmemb, size_t __size, __compar_fn_t _compar)



                                ;
void * calloc (size_t __nmemb, size_t __size) ;
div_t div (int __numer, int __denom);
void exit (int __status) __attribute__ ((__noreturn__));
void free (void *) ;
char * getenv (const char *__string);
char * _getenv_r (struct _reent *, const char *__string);
char * _findenv (const char *, int *);
char * _findenv_r (struct _reent *, const char *, int *);

extern char *suboptarg;
int getsubopt (char **, char * const *, char **);

long labs (long);
ldiv_t ldiv (long __numer, long __denom);
void * malloc (size_t __size) ;
int mblen (const char *, size_t);
int _mblen_r (struct _reent *, const char *, size_t, _mbstate_t *);
int mbtowc (wchar_t *__restrict, const char *__restrict, size_t);
int _mbtowc_r (struct _reent *, wchar_t *__restrict, const char *__restrict, size_t, _mbstate_t *);
int wctomb (char *, wchar_t);
int _wctomb_r (struct _reent *, char *, wchar_t, _mbstate_t *);
size_t mbstowcs (wchar_t *__restrict, const char *__restrict, size_t);
size_t _mbstowcs_r (struct _reent *, wchar_t *__restrict, const char *__restrict, size_t, _mbstate_t *);
size_t wcstombs (char *__restrict, const wchar_t *__restrict, size_t);
size_t _wcstombs_r (struct _reent *, char *__restrict, const wchar_t *__restrict, size_t, _mbstate_t *);


char * mkdtemp (char *);
int mkostemp (char *, int);
int mkostemps (char *, int, int);
int mkstemp (char *);
int mkstemps (char *, int);
char * mktemp (char *) __attribute__ ((__warning__ ("the use of `mktemp' is dangerous; use `mkstemp' instead")));

char * _mkdtemp_r (struct _reent *, char *);
int _mkostemp_r (struct _reent *, char *, int);
int _mkostemps_r (struct _reent *, char *, int, int);
int _mkstemp_r (struct _reent *, char *);
int _mkstemps_r (struct _reent *, char *, int);
char * _mktemp_r (struct _reent *, char *) __attribute__ ((__warning__ ("the use of `mktemp' is dangerous; use `mkstemp' instead")));

void qsort (void * __base, size_t __nmemb, size_t __size, __compar_fn_t _compar);
int rand (void);
void * realloc (void * __r, size_t __size) ;

void * reallocf (void * __r, size_t __size);
char * realpath (const char *__restrict path, char *__restrict resolved_path);

void srand (unsigned __seed);
double strtod (const char *__restrict __n, char **__restrict __end_PTR);
double _strtod_r (struct _reent *,const char *__restrict __n, char **__restrict __end_PTR);

float strtof (const char *__restrict __n, char **__restrict __end_PTR);







long strtol (const char *__restrict __n, char **__restrict __end_PTR, int __base);
long _strtol_r (struct _reent *,const char *__restrict __n, char **__restrict __end_PTR, int __base);
unsigned long strtoul (const char *__restrict __n, char **__restrict __end_PTR, int __base);
unsigned long _strtoul_r (struct _reent *,const char *__restrict __n, char **__restrict __end_PTR, int __base);

int system (const char *__string);


long a64l (const char *__input);
char * l64a (long __input);
char * _l64a_r (struct _reent *,long __input);
int on_exit (void (*__func)(int, void *),void * __arg);
void _Exit (int __status) __attribute__ ((__noreturn__));
int putenv (char *__string);
int _putenv_r (struct _reent *, char *__string);
void * _reallocf_r (struct _reent *, void *, size_t);
int setenv (const char *__string, const char *__value, int __overwrite);
int _setenv_r (struct _reent *, const char *__string, const char *__value, int __overwrite);

char * gcvt (double,int,char *);
char * gcvtf (float,int,char *);
char * fcvt (double,int,int *,int *);
char * fcvtf (float,int,int *,int *);
char * ecvt (double,int,int *,int *);
char * ecvtbuf (double, int, int*, int*, char *);
char * fcvtbuf (double, int, int*, int*, char *);
char * ecvtf (float,int,int *,int *);
char * dtoa (double, int, int, int *, int*, char**);
int rand_r (unsigned *__seed);

double drand48 (void);
double _drand48_r (struct _reent *);
double erand48 (unsigned short [3]);
double _erand48_r (struct _reent *, unsigned short [3]);
long jrand48 (unsigned short [3]);
long _jrand48_r (struct _reent *, unsigned short [3]);
void lcong48 (unsigned short [7]);
void _lcong48_r (struct _reent *, unsigned short [7]);
long lrand48 (void);
long _lrand48_r (struct _reent *);
long mrand48 (void);
long _mrand48_r (struct _reent *);
long nrand48 (unsigned short [3]);
long _nrand48_r (struct _reent *, unsigned short [3]);
unsigned short *
       seed48 (unsigned short [3]);
unsigned short *
       _seed48_r (struct _reent *, unsigned short [3]);
void srand48 (long);
void _srand48_r (struct _reent *, long);
long long atoll (const char *__nptr);
long long _atoll_r (struct _reent *, const char *__nptr);
long long llabs (long long);
lldiv_t lldiv (long long __numer, long long __denom);


long long strtoll (const char *__restrict __n, char **__restrict __end_PTR, int __base);


long long _strtoll_r (struct _reent *, const char *__restrict __n, char **__restrict __end_PTR, int __base);


unsigned long long strtoull (const char *__restrict __n, char **__restrict __end_PTR, int __base);


unsigned long long _strtoull_r (struct _reent *, const char *__restrict __n, char **__restrict __end_PTR, int __base);


void cfree (void *);
int unsetenv (const char *__string);
int _unsetenv_r (struct _reent *, const char *__string);
# 221 "/data1/src/gcc-cavium/toolchain-thunder/src/newlib/libc/include/stdlib.h" 3 4
char * _dtoa_r (struct _reent *, double, int, int, int *, int*, char**);

void * _malloc_r (struct _reent *, size_t) ;
void * _calloc_r (struct _reent *, size_t, size_t) ;
void _free_r (struct _reent *, void *) ;
void * _realloc_r (struct _reent *, void *, size_t) ;
void _mstats_r (struct _reent *, char *);

int _system_r (struct _reent *, const char *);

void __eprintf (const char *, const char *, unsigned int, const char *);




extern long double strtold (const char *__restrict, char **__restrict);




# 125 "/data1/src/gcc-cavium/toolchain-thunder/scripts/../src/newlib/libc/stdlib/strtol.c" 2
# 1 "/data1/src/gcc-cavium/toolchain-thunder/src/newlib/libc/include/reent.h" 1 3 4
# 95 "/data1/src/gcc-cavium/toolchain-thunder/src/newlib/libc/include/reent.h" 3 4
# 1 "/data1/src/gcc-cavium/toolchain-thunder/src/newlib/libc/include/machine/types.h" 1 3 4
# 19 "/data1/src/gcc-cavium/toolchain-thunder/src/newlib/libc/include/machine/types.h" 3 4
typedef long int __off_t;
typedef int __pid_t;

__extension__ typedef long long int __loff_t;
# 96 "/data1/src/gcc-cavium/toolchain-thunder/src/newlib/libc/include/reent.h" 2 3 4



# 1 "/data1/src/gcc-cavium/toolchain-thunder/build-aarch64-thunderx-elf/gcc/include/stddef.h" 1 3 4
# 100 "/data1/src/gcc-cavium/toolchain-thunder/src/newlib/libc/include/reent.h" 2 3 4


struct stat;
struct tms;
struct timeval;
struct timezone;
# 140 "/data1/src/gcc-cavium/toolchain-thunder/src/newlib/libc/include/reent.h" 3 4
extern int _close_r (struct _reent *, int);
extern int _execve_r (struct _reent *, const char *, char *const *, char *const *);
extern int _fcntl_r (struct _reent *, int, int, int);
extern int _fork_r (struct _reent *);
extern int _fstat_r (struct _reent *, int, struct stat *);
extern int _getpid_r (struct _reent *);
extern int _isatty_r (struct _reent *, int);
extern int _kill_r (struct _reent *, int, int);
extern int _link_r (struct _reent *, const char *, const char *);
extern _off_t _lseek_r (struct _reent *, int, _off_t, int);
extern int _mkdir_r (struct _reent *, const char *, int);
extern int _open_r (struct _reent *, const char *, int, int);
extern _ssize_t _read_r (struct _reent *, int, void *, size_t);
extern int _rename_r (struct _reent *, const char *, const char *);
extern void *_sbrk_r (struct _reent *, ptrdiff_t);
extern int _stat_r (struct _reent *, const char *, struct stat *);
extern unsigned long _times_r (struct _reent *, struct tms *);
extern int _unlink_r (struct _reent *, const char *);
extern int _wait_r (struct _reent *, int *);
extern _ssize_t _write_r (struct _reent *, int, const void *, size_t);


extern int _gettimeofday_r (struct _reent *, struct timeval *__tp, void *__tzp);
# 126 "/data1/src/gcc-cavium/toolchain-thunder/scripts/../src/newlib/libc/stdlib/strtol.c" 2








# 133 "/data1/src/gcc-cavium/toolchain-thunder/scripts/../src/newlib/libc/stdlib/strtol.c"
long
_strtol_r
# 134 "/data1/src/gcc-cavium/toolchain-thunder/scripts/../src/newlib/libc/stdlib/strtol.c" 3 4
(
# 134 "/data1/src/gcc-cavium/toolchain-thunder/scripts/../src/newlib/libc/stdlib/strtol.c"
struct _reent *rptr 
# 134 "/data1/src/gcc-cavium/toolchain-thunder/scripts/../src/newlib/libc/stdlib/strtol.c" 3 4
, const 
# 134 "/data1/src/gcc-cavium/toolchain-thunder/scripts/../src/newlib/libc/stdlib/strtol.c"
char *__restrict nptr 
# 134 "/data1/src/gcc-cavium/toolchain-thunder/scripts/../src/newlib/libc/stdlib/strtol.c" 3 4
, 
# 134 "/data1/src/gcc-cavium/toolchain-thunder/scripts/../src/newlib/libc/stdlib/strtol.c"
char **__restrict endptr 
# 134 "/data1/src/gcc-cavium/toolchain-thunder/scripts/../src/newlib/libc/stdlib/strtol.c" 3 4
, 
# 134 "/data1/src/gcc-cavium/toolchain-thunder/scripts/../src/newlib/libc/stdlib/strtol.c"
int base
# 134 "/data1/src/gcc-cavium/toolchain-thunder/scripts/../src/newlib/libc/stdlib/strtol.c" 3 4
)





# 139 "/data1/src/gcc-cavium/toolchain-thunder/scripts/../src/newlib/libc/stdlib/strtol.c"
{
 register const unsigned char *s = (const unsigned char *)nptr;
 register unsigned long acc;
 register int c;
 register unsigned long cutoff;
 register int neg = 0, any, cutlim;






 do {
  c = *s++;
 } while (
# 153 "/data1/src/gcc-cavium/toolchain-thunder/scripts/../src/newlib/libc/stdlib/strtol.c" 3 4
         (((__ctype_ptr__+sizeof(""[
# 153 "/data1/src/gcc-cavium/toolchain-thunder/scripts/../src/newlib/libc/stdlib/strtol.c"
         c
# 153 "/data1/src/gcc-cavium/toolchain-thunder/scripts/../src/newlib/libc/stdlib/strtol.c" 3 4
         ]))[(int)(
# 153 "/data1/src/gcc-cavium/toolchain-thunder/scripts/../src/newlib/libc/stdlib/strtol.c"
         c
# 153 "/data1/src/gcc-cavium/toolchain-thunder/scripts/../src/newlib/libc/stdlib/strtol.c" 3 4
         )])&010)
# 153 "/data1/src/gcc-cavium/toolchain-thunder/scripts/../src/newlib/libc/stdlib/strtol.c"
                   );
 if (c == '-') {
  neg = 1;
  c = *s++;
 } else if (c == '+')
  c = *s++;
 if ((base == 0 || base == 16) &&
     c == '0' && (*s == 'x' || *s == 'X')) {
  c = s[1];
  s += 2;
  base = 16;
 }
 if (base == 0)
  base = c == '0' ? 8 : 10;
# 185 "/data1/src/gcc-cavium/toolchain-thunder/scripts/../src/newlib/libc/stdlib/strtol.c"
 cutoff = neg ? -(unsigned long)
# 185 "/data1/src/gcc-cavium/toolchain-thunder/scripts/../src/newlib/libc/stdlib/strtol.c" 3 4
                               (-0x7fffffffL - 1L) 
# 185 "/data1/src/gcc-cavium/toolchain-thunder/scripts/../src/newlib/libc/stdlib/strtol.c"
                                        : 0x7fffffffL;
 cutlim = cutoff % (unsigned long)base;
 cutoff /= (unsigned long)base;
 for (acc = 0, any = 0;; c = *s++) {
  if (
# 189 "/data1/src/gcc-cavium/toolchain-thunder/scripts/../src/newlib/libc/stdlib/strtol.c" 3 4
     (((__ctype_ptr__+sizeof(""[
# 189 "/data1/src/gcc-cavium/toolchain-thunder/scripts/../src/newlib/libc/stdlib/strtol.c"
     c
# 189 "/data1/src/gcc-cavium/toolchain-thunder/scripts/../src/newlib/libc/stdlib/strtol.c" 3 4
     ]))[(int)(
# 189 "/data1/src/gcc-cavium/toolchain-thunder/scripts/../src/newlib/libc/stdlib/strtol.c"
     c
# 189 "/data1/src/gcc-cavium/toolchain-thunder/scripts/../src/newlib/libc/stdlib/strtol.c" 3 4
     )])&04)
# 189 "/data1/src/gcc-cavium/toolchain-thunder/scripts/../src/newlib/libc/stdlib/strtol.c"
               )
   c -= '0';
  else if (
# 191 "/data1/src/gcc-cavium/toolchain-thunder/scripts/../src/newlib/libc/stdlib/strtol.c" 3 4
          (((__ctype_ptr__+sizeof(""[
# 191 "/data1/src/gcc-cavium/toolchain-thunder/scripts/../src/newlib/libc/stdlib/strtol.c"
          c
# 191 "/data1/src/gcc-cavium/toolchain-thunder/scripts/../src/newlib/libc/stdlib/strtol.c" 3 4
          ]))[(int)(
# 191 "/data1/src/gcc-cavium/toolchain-thunder/scripts/../src/newlib/libc/stdlib/strtol.c"
          c
# 191 "/data1/src/gcc-cavium/toolchain-thunder/scripts/../src/newlib/libc/stdlib/strtol.c" 3 4
          )])&(01|02))
# 191 "/data1/src/gcc-cavium/toolchain-thunder/scripts/../src/newlib/libc/stdlib/strtol.c"
                    )
   c -= 
# 192 "/data1/src/gcc-cavium/toolchain-thunder/scripts/../src/newlib/libc/stdlib/strtol.c" 3 4
       ((((__ctype_ptr__+sizeof(""[
# 192 "/data1/src/gcc-cavium/toolchain-thunder/scripts/../src/newlib/libc/stdlib/strtol.c"
       c
# 192 "/data1/src/gcc-cavium/toolchain-thunder/scripts/../src/newlib/libc/stdlib/strtol.c" 3 4
       ]))[(int)(
# 192 "/data1/src/gcc-cavium/toolchain-thunder/scripts/../src/newlib/libc/stdlib/strtol.c"
       c
# 192 "/data1/src/gcc-cavium/toolchain-thunder/scripts/../src/newlib/libc/stdlib/strtol.c" 3 4
       )])&(01|02))==01) 
# 192 "/data1/src/gcc-cavium/toolchain-thunder/scripts/../src/newlib/libc/stdlib/strtol.c"
                  ? 'A' - 10 : 'a' - 10;
  else
   break;
  if (c >= base)
   break;
               if (any < 0 || acc > cutoff || (acc == cutoff && c > cutlim))
   any = -1;
  else {
   any = 1;
   acc *= base;
   acc += c;
  }
 }
 if (any < 0) {
  acc = neg ? 
# 206 "/data1/src/gcc-cavium/toolchain-thunder/scripts/../src/newlib/libc/stdlib/strtol.c" 3 4
             (-0x7fffffffL - 1L) 
# 206 "/data1/src/gcc-cavium/toolchain-thunder/scripts/../src/newlib/libc/stdlib/strtol.c"
                      : 0x7fffffffL;
  rptr->_errno = 
# 207 "/data1/src/gcc-cavium/toolchain-thunder/scripts/../src/newlib/libc/stdlib/strtol.c" 3 4
                34
# 207 "/data1/src/gcc-cavium/toolchain-thunder/scripts/../src/newlib/libc/stdlib/strtol.c"
                      ;
 } else if (neg)
  acc = -acc;
 if (endptr != 0)
  *endptr = (char *) (any ? (char *)s - 1 : nptr);
 return (acc);
}



long
strtol
# 218 "/data1/src/gcc-cavium/toolchain-thunder/scripts/../src/newlib/libc/stdlib/strtol.c" 3 4
(const 
# 218 "/data1/src/gcc-cavium/toolchain-thunder/scripts/../src/newlib/libc/stdlib/strtol.c"
char *__restrict s 
# 218 "/data1/src/gcc-cavium/toolchain-thunder/scripts/../src/newlib/libc/stdlib/strtol.c" 3 4
, 
# 218 "/data1/src/gcc-cavium/toolchain-thunder/scripts/../src/newlib/libc/stdlib/strtol.c"
char **__restrict ptr 
# 218 "/data1/src/gcc-cavium/toolchain-thunder/scripts/../src/newlib/libc/stdlib/strtol.c" 3 4
, 
# 218 "/data1/src/gcc-cavium/toolchain-thunder/scripts/../src/newlib/libc/stdlib/strtol.c"
int base
# 218 "/data1/src/gcc-cavium/toolchain-thunder/scripts/../src/newlib/libc/stdlib/strtol.c" 3 4
)




# 222 "/data1/src/gcc-cavium/toolchain-thunder/scripts/../src/newlib/libc/stdlib/strtol.c"
{
 return _strtol_r (
# 223 "/data1/src/gcc-cavium/toolchain-thunder/scripts/../src/newlib/libc/stdlib/strtol.c" 3 4
                  _impure_ptr
# 223 "/data1/src/gcc-cavium/toolchain-thunder/scripts/../src/newlib/libc/stdlib/strtol.c"
                        , s, ptr, base);
}

^ permalink raw reply	[flat|nested] 12+ messages in thread

* Re: [PATCH][AArch64] LR register not used in leaf functions
  2014-11-15 16:37             ` Andrew Pinski
@ 2014-11-15 20:29               ` Jiong Wang
  0 siblings, 0 replies; 12+ messages in thread
From: Jiong Wang @ 2014-11-15 20:29 UTC (permalink / raw)
  To: Andrew Pinski
  Cc: Jiong Wang, Kugan, gcc-patches, Marcus Shawcroft,
	Richard Earnshaw, vmakarov

2014-11-15 15:49 GMT+00:00 Andrew Pinski <pinskia@gmail.com>:
>> My local modifications can be found in the gcc git at
>> apinski/thunderx-cost.  Note I reverted this patch so I can continue
>> working.  The testcase is compiling newlib.  Let me try to get it
>> again.
>> I was configuring a combined build with:
>> --disable-fixed-point --without-ppl --without-python --disable-werror
>> --enable-plugins --enable-checking --disable-sim --with-newlib
>> --disable-tls --with-cpu=thunderx --with-multilib-list=lp64,ilp32
>> --target=aarch64-thunderx-elf --enable-languages=c,c++
>
> Attached is the preprocessed source.
> cc1 strtol.i -mabi=ilp32 -O2
> is enough to reproduce the ICE.

thanks. I can reproduce this ICE under -mabi=ilp32 on your code base.

and it's strange LR marked as alive while the final assembly don't have it.
the reason of this is the following pattern

define_insn "*tb<optab><mode>1"
define_insn "*cb<optab><mode>1"

always declare to clobber some register while they don't always use them
in code generation, so sub-optimal code generated, some registers are wasted.

you can see before my patch x19 is allocated for that clobber, thus there
is an unnecessary save of x19 to stack, while after my patch, x30 is allocated
for that clobber, so aarch64_can_eliminate invoked after this will
think this function
require frame pointer according to our ABI, so there are unncessary frame setup
instruction.

basically, it's not inconsistent between aarch64_require_frame_p and
aarch64_can_eliminate.  it's inconsistent between
aarch64_can_eliminate
invoked before assign_by_spills and after that.

and my first impression is that the gcc_assert in lra-eliminate.c is
to strong and need to be relaxed in some situation.

>
> Thanks,
> Andrew
>

^ permalink raw reply	[flat|nested] 12+ messages in thread

end of thread, other threads:[~2014-11-15 19:53 UTC | newest]

Thread overview: 12+ messages (download: mbox.gz / follow: Atom feed)
-- links below jump to the message on this page --
2014-09-22 15:43 [PATCH][AArch64] LR register not used in leaf functions Kugan
2014-09-22 15:58 ` Jiong Wang
2014-09-27 21:20   ` Kugan
2014-09-30 15:00     ` Jiong Wang
2014-10-01  8:00       ` Kugan
2014-11-04 10:56         ` Jiong Wang
2014-11-11 14:52       ` Marcus Shawcroft
2014-11-15  0:52       ` Andrew Pinski
2014-11-15 15:27         ` Jiong Wang
2014-11-15 15:49           ` Andrew Pinski
2014-11-15 16:37             ` Andrew Pinski
2014-11-15 20:29               ` Jiong Wang

This is a public inbox, see mirroring instructions
for how to clone and mirror all data and code used for this inbox;
as well as URLs for read-only IMAP folder(s) and NNTP newsgroup(s).