Re: -fuse-caller-save - Enable for MIPS

2014-04-28 Thread Richard Sandiford
Tom de Vries  writes:
>> If so,
>> should -fuse-caller-save imply -fcaller-saves?
>
> I don't think it's strictly necessary, but I can make a patch if required.

Implying -fcaller-saves seems better to me, since "-O -fuse-caller-save"
looks like it should enable the new optimisation.  It's not my call though.

Thanks,
Richard


Re: -fuse-caller-save - Enable for MIPS

2014-04-28 Thread Richard Sandiford
Tom de Vries  writes:
> On 28-04-14 12:26, Richard Sandiford wrote:
>> Tom de Vries  writes:
>>> On 27-04-14 12:27, Richard Sandiford wrote:
 Tom de Vries  writes:
>mips_emit_call_insn (rtx pattern, rtx orig_addr, rtx addr, bool lazy_p)
>{
>  rtx insn, reg;
>
> -  insn = emit_call_insn (pattern);
> +  emit_call_insn (pattern);
> +  insn = last_call_insn ();
>
>  if (TARGET_MIPS16 && mips_use_pic_fn_addr_reg_p (orig_addr))
>{

 This change isn't necessary; emit_call_insn is defined to return a
 CALL_INSN.

>>>
>>> I dropped this change, as well as the change in the untyped_call expand, I
>>> realized it's unnecessary.
>>
>> Why was the untyped_call part unnecessary?
>>
>
> The define_expand "untyped_call" uses GEN_CALL, which uses
> define_expand "call", which uses mips_expand_call, which uses
> mips_emit_call_insn, which adds the required clobbers.

Ah, yeah.  In that case please keep mips_emit_call_insn static.

OK with that change, although please remove -O1 if the agreement
is that "-O1 -fuse-call-save" should work.

Thanks,
Richard


Re: -fuse-caller-save - Enable for MIPS

2014-04-28 Thread Tom de Vries

On 28-04-14 12:47, Tom de Vries wrote:

Hmm, is that just because -fcaller-saves is -O2 and above?


For -O1, after adding -fcaller-saves the optimization triggers, and the 
test-cases passes.


For -O0, adding -fcaller-saves doesn't make a difference, the optimization 
doesn't trigger.



If so,
should -fuse-caller-save imply -fcaller-saves?


I don't think it's strictly necessary, but I can make a patch if required.

Thanks,
- Tom


Re: -fuse-caller-save - Enable for MIPS

2014-04-28 Thread Tom de Vries

On 28-04-14 12:26, Richard Sandiford wrote:

Tom de Vries  writes:

On 27-04-14 12:27, Richard Sandiford wrote:

Tom de Vries  writes:

   mips_emit_call_insn (rtx pattern, rtx orig_addr, rtx addr, bool lazy_p)
   {
 rtx insn, reg;

-  insn = emit_call_insn (pattern);
+  emit_call_insn (pattern);
+  insn = last_call_insn ();

 if (TARGET_MIPS16 && mips_use_pic_fn_addr_reg_p (orig_addr))
   {


This change isn't necessary; emit_call_insn is defined to return a CALL_INSN.



I dropped this change, as well as the change in the untyped_call expand, I
realized it's unnecessary.


Why was the untyped_call part unnecessary?



The define_expand "untyped_call" uses GEN_CALL, which uses define_expand "call", 
which uses mips_expand_call, which uses mips_emit_call_insn, which adds the 
required clobbers.



I'm a bit surprised that it doesn't work at -O1 for a simple test
like this though.  What goes wrong?



AFAIU now the problem is that the optimization doesn't trigger for -O0
and -01, because the register allocator behaves more conservatively.


Hmm, is that just because -fcaller-saves is -O2 and above?
 If so,
should -fuse-caller-save imply -fcaller-saves?

Thanks,
Richard





Re: -fuse-caller-save - Enable for MIPS

2014-04-28 Thread Richard Sandiford
Tom de Vries  writes:
> On 27-04-14 12:27, Richard Sandiford wrote:
>> Tom de Vries  writes:
>>>   mips_emit_call_insn (rtx pattern, rtx orig_addr, rtx addr, bool lazy_p)
>>>   {
>>> rtx insn, reg;
>>>
>>> -  insn = emit_call_insn (pattern);
>>> +  emit_call_insn (pattern);
>>> +  insn = last_call_insn ();
>>>
>>> if (TARGET_MIPS16 && mips_use_pic_fn_addr_reg_p (orig_addr))
>>>   {
>>
>> This change isn't necessary; emit_call_insn is defined to return a CALL_INSN.
>>
>
> I dropped this change, as well as the change in the untyped_call expand, I 
> realized it's unnecessary.

Why was the untyped_call part unnecessary?

>> I'm a bit surprised that it doesn't work at -O1 for a simple test
>> like this though.  What goes wrong?
>>
>
> AFAIU now the problem is that the optimization doesn't trigger for -O0
> and -01, because the register allocator behaves more conservatively.

Hmm, is that just because -fcaller-saves is -O2 and above?  If so,
should -fuse-caller-save imply -fcaller-saves?

Thanks,
Richard


Re: -fuse-caller-save - Enable for MIPS

2014-04-27 Thread Tom de Vries

On 27-04-14 12:27, Richard Sandiford wrote:

Tom de Vries  writes:

2014-01-12  Radovan Obradovic  
 Tom de Vries  

* config/mips/mips-protos.h (mips_emit_call_insn): Declare.
* config/mips/mips.h (POST_CALL_TMP_REG): Define.
* config/mips/mips.c (mips_emit_call_insn): Remove static.  Use
last_call_insn.  Add POST_CALL_TMP_REG clobber
 (mips_split_call): Use POST_CALL_TMP_REG.
(TARGET_CALL_FUSAGE_CONTAINS_NON_CALLEE_CLOBBERS): Redefine to true.
* config/mips/mips.md (define_expand "untyped_call"): Use
mips_emit_call_insn.

* gcc.target/mips/mips.exp: Add use-caller-save to -ffoo/-fno-foo
options.
* gcc.target/mips/fuse-caller-save.h: New include file.
* gcc.target/mips/fuse-caller-save.c: New test.
* gcc.target/mips/fuse-caller-save-mips16.c: Same.
* gcc.target/mips/fuse-caller-save-micromips.c: Same.


Sorry, a couple of things, but this is looking pretty good:


  mips_emit_call_insn (rtx pattern, rtx orig_addr, rtx addr, bool lazy_p)
  {
rtx insn, reg;

-  insn = emit_call_insn (pattern);
+  emit_call_insn (pattern);
+  insn = last_call_insn ();

if (TARGET_MIPS16 && mips_use_pic_fn_addr_reg_p (orig_addr))
  {


This change isn't necessary; emit_call_insn is defined to return a CALL_INSN.



I dropped this change, as well as the change in the untyped_call expand, I 
realized it's unnecessary.



@@ -2843,6 +2844,16 @@ mips_emit_call_insn (rtx pattern, rtx orig_addr, rtx 
addr, bool lazy_p)
   gen_rtx_REG (Pmode, GOT_VERSION_REGNUM));
emit_insn (gen_update_got_version ());
  }
+
+  if (TARGET_MIPS16
+  && TARGET_EXPLICIT_RELOCS
+  && TARGET_CALL_CLOBBERED_GP
+  && !find_reg_note (insn, REG_NORETURN, 0))
+{
+  rtx post_call_tmp_reg = gen_rtx_REG (word_mode, POST_CALL_TMP_REG);
+  clobber_reg (&CALL_INSN_FUNCTION_USAGE (insn), post_call_tmp_reg);
+}


The REG_NORETURN note won't be around yet, so we might as well drop
that line.  I'm not sure how useful it would be anyway since values
are never live across a noreturn call.



Done.


+/* Temporary register that is used after a call.  $4 and $5 are used for


Might as well make it "...used when restoring $gp after a call", now that
it's not as obvious from context.


+   returning complex double values in soft-float code, so $6 is the first
+   suitable candidate for !TARGET_MIPS16.  For TARGET_MIPS16, we use
+   PIC_OFFSET_TABLE_REGNUM instead.  */


!TARGET_MIPS16 and TARGET_MIPS16 are the wrong way around:

suitable candidate for TARGET_MIPS16.  For !TARGET_MIPS16 we can use
$gp itself as the temporary.  */



Fixed, thanks for catching that.


+/* The scan of the sp-relative saves will fail for -O0 and -O1.
+   For -flto, scans will fail because there's no code in the .s file.  */
+/* { dg-skip-if "" { *-*-* }  { "-O0" "-O1" "-flto"} } */


The -flto thing is handled automatically by the testsuite
(see force_conventional_output_for) so that one should be left out.



Ah, I see. Removed.


I'm a bit surprised that it doesn't work at -O1 for a simple test
like this though.  What goes wrong?



AFAIU now the problem is that the optimization doesn't trigger for -O0 and -01, 
because the register allocator behaves more conservatively.


OK for trunk, if re-testing succeeds?

Thanks,
- Tom

2014-01-12  Radovan Obradovic  
Tom de Vries  

	* config/mips/mips-protos.h (mips_emit_call_insn): Declare.
	* config/mips/mips.h (POST_CALL_TMP_REG): Define.
	* config/mips/mips.c (mips_emit_call_insn): Remove static.  Add
	POST_CALL_TMP_REG clobber.
	(mips_split_call): Use POST_CALL_TMP_REG.
	(TARGET_CALL_FUSAGE_CONTAINS_NON_CALLEE_CLOBBERS): Redefine to true.

	* gcc.target/mips/mips.exp: Add use-caller-save to -ffoo/-fno-foo
	options.
	* gcc.target/mips/fuse-caller-save.h: New include file.
	* gcc.target/mips/fuse-caller-save.c: New test.
	* gcc.target/mips/fuse-caller-save-mips16.c: Same.
	* gcc.target/mips/fuse-caller-save-micromips.c: Same.
---
 gcc/config/mips/mips-protos.h|  1 +
 gcc/config/mips/mips.c   | 20 +++-
 gcc/config/mips/mips.h   |  7 +++
 .../gcc.target/mips/fuse-caller-save-micromips.c | 17 +
 .../gcc.target/mips/fuse-caller-save-mip16.c | 17 +
 gcc/testsuite/gcc.target/mips/fuse-caller-save.c | 17 +
 gcc/testsuite/gcc.target/mips/fuse-caller-save.h | 17 +
 gcc/testsuite/gcc.target/mips/mips.exp   |  1 +
 8 files changed, 92 insertions(+), 5 deletions(-)
 create mode 100644 gcc/testsuite/gcc.target/mips/fuse-caller-save-micromips.c
 create mode 100644 gcc/testsuite/gcc.target/mips/fuse-caller-save-mip16.c
 create mode 100644 gcc/testsuite/gcc.target/mips/fuse-caller-save.c
 create mode 100644 gcc/testsuite/gcc.target/mips/fuse-caller-save.h

diff --git 

Re: -fuse-caller-save - Enable for MIPS

2014-04-27 Thread Richard Sandiford
Tom de Vries  writes:
> 2014-01-12  Radovan Obradovic  
> Tom de Vries  
>
>   * config/mips/mips-protos.h (mips_emit_call_insn): Declare.
>   * config/mips/mips.h (POST_CALL_TMP_REG): Define.
>   * config/mips/mips.c (mips_emit_call_insn): Remove static.  Use
>   last_call_insn.  Add POST_CALL_TMP_REG clobber
>(mips_split_call): Use POST_CALL_TMP_REG.
>   (TARGET_CALL_FUSAGE_CONTAINS_NON_CALLEE_CLOBBERS): Redefine to true.
>   * config/mips/mips.md (define_expand "untyped_call"): Use
>   mips_emit_call_insn.
>
>   * gcc.target/mips/mips.exp: Add use-caller-save to -ffoo/-fno-foo
>   options.
>   * gcc.target/mips/fuse-caller-save.h: New include file.
>   * gcc.target/mips/fuse-caller-save.c: New test.
>   * gcc.target/mips/fuse-caller-save-mips16.c: Same.
>   * gcc.target/mips/fuse-caller-save-micromips.c: Same.

Sorry, a couple of things, but this is looking pretty good:

>  mips_emit_call_insn (rtx pattern, rtx orig_addr, rtx addr, bool lazy_p)
>  {
>rtx insn, reg;
>  
> -  insn = emit_call_insn (pattern);
> +  emit_call_insn (pattern);
> +  insn = last_call_insn ();
>  
>if (TARGET_MIPS16 && mips_use_pic_fn_addr_reg_p (orig_addr))
>  {

This change isn't necessary; emit_call_insn is defined to return a CALL_INSN.

> @@ -2843,6 +2844,16 @@ mips_emit_call_insn (rtx pattern, rtx orig_addr, rtx 
> addr, bool lazy_p)
>  gen_rtx_REG (Pmode, GOT_VERSION_REGNUM));
>emit_insn (gen_update_got_version ());
>  }
> +
> +  if (TARGET_MIPS16
> +  && TARGET_EXPLICIT_RELOCS
> +  && TARGET_CALL_CLOBBERED_GP
> +  && !find_reg_note (insn, REG_NORETURN, 0))
> +{
> +  rtx post_call_tmp_reg = gen_rtx_REG (word_mode, POST_CALL_TMP_REG);
> +  clobber_reg (&CALL_INSN_FUNCTION_USAGE (insn), post_call_tmp_reg);
> +}

The REG_NORETURN note won't be around yet, so we might as well drop
that line.  I'm not sure how useful it would be anyway since values
are never live across a noreturn call.

> +/* Temporary register that is used after a call.  $4 and $5 are used for

Might as well make it "...used when restoring $gp after a call", now that
it's not as obvious from context.

> +   returning complex double values in soft-float code, so $6 is the first
> +   suitable candidate for !TARGET_MIPS16.  For TARGET_MIPS16, we use
> +   PIC_OFFSET_TABLE_REGNUM instead.  */

!TARGET_MIPS16 and TARGET_MIPS16 are the wrong way around:

   suitable candidate for TARGET_MIPS16.  For !TARGET_MIPS16 we can use
   $gp itself as the temporary.  */

> +/* The scan of the sp-relative saves will fail for -O0 and -O1.
> +   For -flto, scans will fail because there's no code in the .s file.  */
> +/* { dg-skip-if "" { *-*-* }  { "-O0" "-O1" "-flto"} } */

The -flto thing is handled automatically by the testsuite
(see force_conventional_output_for) so that one should be left out.

I'm a bit surprised that it doesn't work at -O1 for a simple test
like this though.  What goes wrong?

Thanks,
Richard


Re: -fuse-caller-save - Enable for MIPS

2014-04-26 Thread Tom de Vries

On 25-04-14 15:22, Richard Sandiford wrote:

Tom de Vries  writes:

diff --git a/gcc/config/mips/mips.c b/gcc/config/mips/mips.c
index 45256e9..b61cd44 100644
--- a/gcc/config/mips/mips.c
+++ b/gcc/config/mips/mips.c
@@ -7027,11 +7027,17 @@ mips_expand_call (enum mips_call_type type, rtx result, 
rtx addr,
  {
rtx orig_addr, pattern, insn;
int fp_code;
+  rtx post_call_tmp_reg = gen_rtx_REG (word_mode, POST_CALL_TMP_REG);

fp_code = aux == 0 ? 0 : (int) GET_MODE (aux);
insn = mips16_build_call_stub (result, &addr, args_size, fp_code);
if (insn)
  {
+  if (TARGET_EXPLICIT_RELOCS
+ && TARGET_CALL_CLOBBERED_GP
+ && !find_reg_note (insn, REG_NORETURN, 0))
+   clobber_reg (&CALL_INSN_FUNCTION_USAGE (insn), post_call_tmp_reg);
+


I think this condition should go in mips_emit_call_insn instead,
so that we don't have 4 instances of it.  untyped_call could then
use mips_expand_call as well.



Richard,

Done.


Until now there was no real downside to using $6 for non-MIPS16 code.
Now that there is, it would probably be worth making it:

+#define POST_CALL_TMP_REG \
   (TARGET_MIPS16 ? GP_ARG_FIRST + 2 : PIC_OFFSET_TABLE_REGNUM)

and only adding the clobber for MIPS16.



Done.


diff --git a/gcc/testsuite/gcc.target/mips/fuse-caller-save.c 
b/gcc/testsuite/gcc.target/mips/fuse-caller-save.c
new file mode 100644
index 000..1fd6c7d
--- /dev/null
+++ b/gcc/testsuite/gcc.target/mips/fuse-caller-save.c
@@ -0,0 +1,30 @@
+/* { dg-do compile } */
+/* { dg-options "-fuse-caller-save" } */
+/* { dg-skip-if "" { *-*-* }  { "*" } { "-Os" } } */


I might have asked this before, sorry, but why this skip?  Please add a brief
comment (in the string, if short enough).


I've reduced the amount of skips a bit, and added a comment why they are 
skipped.




+/* Testing -fuse-caller-save optimization option.  */
+
+static int __attribute__((noinline)) NOCOMPRESSION
+bar (int x)
+{
+  return x + 3;
+}
+
+int __attribute__((noinline)) NOCOMPRESSION
+foo (int y)
+{
+  return y + bar (y);
+}
+
+int NOCOMPRESSION
+main (void)
+{
+  return !(foo (5) == 13);
+}
+
+/* Check that there are only 2 stack-saves: r31 in main and foo.  */
+
+/* Check that there only 2 sw/sd.  */
+/* { dg-final { scan-assembler-times "(?n)s\[wd\]\t\\\$.*,.*\\(\\\$sp\\)" 2 } 
} */
+
+/* Check that the first caller-save register is unused.  */
+/* { dg-final { scan-assembler-not "\\\$16" } } */


It'd be good to avoid NOCOMPRESSION because the only case that really
needs the temporary register is MIPS16.  Please try putting the test
in a header file and reusing it for three tests, one each of MIPS16,
microMIPS and uncompressed.



Done, I think, I'm not 100% sure I understood what you wanted me to do here.

build and reg-tested on MIPS.

OK for trunk?

Thanks,
- Tom

2014-01-12  Radovan Obradovic  
Tom de Vries  

	* config/mips/mips-protos.h (mips_emit_call_insn): Declare.
	* config/mips/mips.h (POST_CALL_TMP_REG): Define.
	* config/mips/mips.c (mips_emit_call_insn): Remove static.  Use
	last_call_insn.  Add POST_CALL_TMP_REG clobber
	 (mips_split_call): Use POST_CALL_TMP_REG.
	(TARGET_CALL_FUSAGE_CONTAINS_NON_CALLEE_CLOBBERS): Redefine to true.
	* config/mips/mips.md (define_expand "untyped_call"): Use
	mips_emit_call_insn.

	* gcc.target/mips/mips.exp: Add use-caller-save to -ffoo/-fno-foo
	options.
	* gcc.target/mips/fuse-caller-save.h: New include file.
	* gcc.target/mips/fuse-caller-save.c: New test.
	* gcc.target/mips/fuse-caller-save-mips16.c: Same.
	* gcc.target/mips/fuse-caller-save-micromips.c: Same.
---
 gcc/config/mips/mips-protos.h  |  1 +
 gcc/config/mips/mips.c | 24 --
 gcc/config/mips/mips.h |  7 +++
 gcc/config/mips/mips.md|  4 +++-
 .../gcc.target/mips/fuse-caller-save-micromips.c   | 17 +++
 .../gcc.target/mips/fuse-caller-save-mip16.c   | 17 +++
 gcc/testsuite/gcc.target/mips/fuse-caller-save.c   | 17 +++
 gcc/testsuite/gcc.target/mips/fuse-caller-save.h   | 17 +++
 gcc/testsuite/gcc.target/mips/mips.exp |  1 +
 9 files changed, 98 insertions(+), 7 deletions(-)
 create mode 100644 gcc/testsuite/gcc.target/mips/fuse-caller-save-micromips.c
 create mode 100644 gcc/testsuite/gcc.target/mips/fuse-caller-save-mip16.c
 create mode 100644 gcc/testsuite/gcc.target/mips/fuse-caller-save.c
 create mode 100644 gcc/testsuite/gcc.target/mips/fuse-caller-save.h

diff --git a/gcc/config/mips/mips-protos.h b/gcc/config/mips/mips-protos.h
index 3d59b7b..19ea919 100644
--- a/gcc/config/mips/mips-protos.h
+++ b/gcc/config/mips/mips-protos.h
@@ -232,6 +232,7 @@ extern bool mips_use_pic_fn_addr_reg_p (const_rtx);
 extern rtx mips_expand_call (enum mips_call_type, rtx, rtx, rtx, rtx, bool);
 extern void mips_split_call (rtx, rtx);
 extern bool mips_get_pic_call_symbol (rtx *, int);
+extern rtx mips_emit_call_insn (

Re: -fuse-caller-save - Enable for MIPS

2014-04-25 Thread Richard Sandiford
Tom de Vries  writes:
> diff --git a/gcc/config/mips/mips.c b/gcc/config/mips/mips.c
> index 45256e9..b61cd44 100644
> --- a/gcc/config/mips/mips.c
> +++ b/gcc/config/mips/mips.c
> @@ -7027,11 +7027,17 @@ mips_expand_call (enum mips_call_type type, rtx 
> result, rtx addr,
>  {
>rtx orig_addr, pattern, insn;
>int fp_code;
> +  rtx post_call_tmp_reg = gen_rtx_REG (word_mode, POST_CALL_TMP_REG);
>  
>fp_code = aux == 0 ? 0 : (int) GET_MODE (aux);
>insn = mips16_build_call_stub (result, &addr, args_size, fp_code);
>if (insn)
>  {
> +  if (TARGET_EXPLICIT_RELOCS
> +   && TARGET_CALL_CLOBBERED_GP
> +   && !find_reg_note (insn, REG_NORETURN, 0))
> + clobber_reg (&CALL_INSN_FUNCTION_USAGE (insn), post_call_tmp_reg);
> +

I think this condition should go in mips_emit_call_insn instead,
so that we don't have 4 instances of it.  untyped_call could then
use mips_expand_call as well.

Until now there was no real downside to using $6 for non-MIPS16 code.
Now that there is, it would probably be worth making it:

+#define POST_CALL_TMP_REG \
  (TARGET_MIPS16 ? GP_ARG_FIRST + 2 : PIC_OFFSET_TABLE_REGNUM)

and only adding the clobber for MIPS16.

> diff --git a/gcc/testsuite/gcc.target/mips/fuse-caller-save.c 
> b/gcc/testsuite/gcc.target/mips/fuse-caller-save.c
> new file mode 100644
> index 000..1fd6c7d
> --- /dev/null
> +++ b/gcc/testsuite/gcc.target/mips/fuse-caller-save.c
> @@ -0,0 +1,30 @@
> +/* { dg-do compile } */
> +/* { dg-options "-fuse-caller-save" } */
> +/* { dg-skip-if "" { *-*-* }  { "*" } { "-Os" } } */

I might have asked this before, sorry, but why this skip?  Please add a brief
comment (in the string, if short enough).

> +/* Testing -fuse-caller-save optimization option.  */
> +
> +static int __attribute__((noinline)) NOCOMPRESSION
> +bar (int x)
> +{
> +  return x + 3;
> +}
> +
> +int __attribute__((noinline)) NOCOMPRESSION
> +foo (int y)
> +{
> +  return y + bar (y);
> +}
> +
> +int NOCOMPRESSION
> +main (void)
> +{
> +  return !(foo (5) == 13);
> +}
> +
> +/* Check that there are only 2 stack-saves: r31 in main and foo.  */
> +
> +/* Check that there only 2 sw/sd.  */
> +/* { dg-final { scan-assembler-times "(?n)s\[wd\]\t\\\$.*,.*\\(\\\$sp\\)" 2 
> } } */
> +
> +/* Check that the first caller-save register is unused.  */
> +/* { dg-final { scan-assembler-not "\\\$16" } } */

It'd be good to avoid NOCOMPRESSION because the only case that really
needs the temporary register is MIPS16.  Please try putting the test
in a header file and reusing it for three tests, one each of MIPS16,
microMIPS and uncompressed.

Thanks,
Richard