From patchwork Sun Apr 27 23:38:22 2014 Content-Type: text/plain; charset="utf-8" MIME-Version: 1.0 Content-Transfer-Encoding: 7bit X-Patchwork-Submitter: Tom de Vries X-Patchwork-Id: 343198 Return-Path: X-Original-To: incoming@patchwork.ozlabs.org Delivered-To: patchwork-incoming@bilbo.ozlabs.org Received: from sourceware.org (server1.sourceware.org [209.132.180.131]) (using TLSv1.2 with cipher ECDHE-RSA-AES256-GCM-SHA384 (256/256 bits)) (No client certificate requested) by ozlabs.org (Postfix) with ESMTPS id 545061400A6 for ; Mon, 28 Apr 2014 09:38:41 +1000 (EST) DomainKey-Signature: a=rsa-sha1; c=nofws; d=gcc.gnu.org; h=list-id :list-unsubscribe:list-archive:list-post:list-help:sender :message-id:date:from:mime-version:to:cc:subject:references :in-reply-to:content-type; q=dns; s=default; b=qvPVQL+qH2Ervm6ba mMvCyXhe6FV2i2Tg1IW7btd4uUXQL2XZYYaFBItd7wVhFefWcTxqYu7YeTsnv7hX ZssUHM+pWLNiGJKpKhp+XlNs2RjjI9OnbF61ZMU0RY3oY1Qt1wWPoVnXPsv1t92y swk1eS0V483pzXoR+tu60PQDGk= DKIM-Signature: v=1; a=rsa-sha1; c=relaxed; d=gcc.gnu.org; h=list-id :list-unsubscribe:list-archive:list-post:list-help:sender :message-id:date:from:mime-version:to:cc:subject:references :in-reply-to:content-type; s=default; bh=9klKCxoY3/bUk3iGZ5QGJne gJPU=; b=TUq3u95+MQVgHDXpy+xbqKL+KITAaGJZeBDfsxHNvjCFIeBlfyWOPqX nLaA9MSbN7OOV07GENtpyOaT31QAJJpSJvd7rxbomrlhRygWUmdMy/6Tfhz7N7DY vsLQdkvSIQEedW3ryOrv7RELyOV4UpPtkxdS/2PxLiwGqp8K+zQg= Received: (qmail 30074 invoked by alias); 27 Apr 2014 23:38:33 -0000 Mailing-List: contact gcc-patches-help@gcc.gnu.org; run by ezmlm Precedence: bulk List-Id: List-Unsubscribe: List-Archive: List-Post: List-Help: Sender: gcc-patches-owner@gcc.gnu.org Delivered-To: mailing list gcc-patches@gcc.gnu.org Received: (qmail 30057 invoked by uid 89); 27 Apr 2014 23:38:32 -0000 Authentication-Results: sourceware.org; auth=none X-Virus-Found: No X-Spam-SWARE-Status: No, score=-1.9 required=5.0 tests=AWL, BAYES_00 autolearn=ham version=3.3.2 X-HELO: relay1.mentorg.com Received: from relay1.mentorg.com (HELO relay1.mentorg.com) (192.94.38.131) by sourceware.org (qpsmtpd/0.93/v0.84-503-g423c35a) with ESMTP; Sun, 27 Apr 2014 23:38:30 +0000 Received: from svr-orw-fem-01.mgc.mentorg.com ([147.34.98.93]) by relay1.mentorg.com with esmtp id 1WeYeQ-0000QU-OZ from Tom_deVries@mentor.com ; Sun, 27 Apr 2014 16:38:26 -0700 Received: from SVR-IES-FEM-01.mgc.mentorg.com ([137.202.0.104]) by svr-orw-fem-01.mgc.mentorg.com over TLS secured channel with Microsoft SMTPSVC(6.0.3790.4675); Sun, 27 Apr 2014 16:38:26 -0700 Received: from [127.0.0.1] (137.202.0.76) by SVR-IES-FEM-01.mgc.mentorg.com (137.202.0.104) with Microsoft SMTP Server id 14.2.247.3; Mon, 28 Apr 2014 00:38:23 +0100 Message-ID: <535D94EE.6080704@mentor.com> Date: Mon, 28 Apr 2014 01:38:22 +0200 From: Tom de Vries User-Agent: Mozilla/5.0 (X11; Linux x86_64; rv:24.0) Gecko/20100101 Thunderbird/24.4.0 MIME-Version: 1.0 To: CC: "gcc-patches@gcc.gnu.org" Subject: Re: -fuse-caller-save - Enable for MIPS References: <534ED7BC.50300@mentor.com> <534FF0F9.60404@redhat.com> <87lhv4ug7f.fsf@sandifor-thinkpad.stglab.manchester.uk.ibm.com> <53500628.2090802@redhat.com> <5356853D.8050905@mentor.com> <535A5A8F.30901@mentor.com> <8761lxr1ay.fsf@sandifor-thinkpad.stglab.manchester.uk.ibm.com> <535BA119.8090504@mentor.com> <8761lvcbjo.fsf@talisman.default> In-Reply-To: <8761lvcbjo.fsf@talisman.default> 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 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 (rtx, rtx, rtx, bool); extern void mips_expand_fcc_reload (rtx, rtx, rtx); extern void mips_set_return_address (rtx, rtx); extern bool mips_move_by_pieces_p (unsigned HOST_WIDE_INT, unsigned int); diff --git a/gcc/config/mips/mips.c b/gcc/config/mips/mips.c index 45256e9..b80c1b4 100644 --- a/gcc/config/mips/mips.c +++ b/gcc/config/mips/mips.c @@ -2814,7 +2814,7 @@ mips_force_temporary (rtx dest, rtx value) ADDR is the legitimized form, and LAZY_P is true if the call address is lazily-bound. */ -static rtx +rtx mips_emit_call_insn (rtx pattern, rtx orig_addr, rtx addr, bool lazy_p) { rtx insn, reg; @@ -2843,6 +2843,15 @@ 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) + { + 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); + } + return insn; } @@ -7099,10 +7108,8 @@ mips_split_call (rtx insn, rtx call_pattern) { emit_call_insn (call_pattern); if (!find_reg_note (insn, REG_NORETURN, 0)) - /* Pick a temporary register that is suitable for both MIPS16 and - non-MIPS16 code. $4 and $5 are used for returning complex double - values in soft-float code, so $6 is the first suitable candidate. */ - mips_restore_gp_from_cprestore_slot (gen_rtx_REG (Pmode, GP_ARG_FIRST + 2)); + mips_restore_gp_from_cprestore_slot (gen_rtx_REG (Pmode, + POST_CALL_TMP_REG)); } /* Return true if a call to DECL may need to use JALX. */ @@ -19134,6 +19141,9 @@ mips_atomic_assign_expand_fenv (tree *hold, tree *clear, tree *update) #undef TARGET_ATOMIC_ASSIGN_EXPAND_FENV #define TARGET_ATOMIC_ASSIGN_EXPAND_FENV mips_atomic_assign_expand_fenv +#undef TARGET_CALL_FUSAGE_CONTAINS_NON_CALLEE_CLOBBERS +#define TARGET_CALL_FUSAGE_CONTAINS_NON_CALLEE_CLOBBERS true + struct gcc_target targetm = TARGET_INITIALIZER; #include "gt-mips.h" diff --git a/gcc/config/mips/mips.h b/gcc/config/mips/mips.h index b25865b..14fa8fd 100644 --- a/gcc/config/mips/mips.h +++ b/gcc/config/mips/mips.h @@ -2212,6 +2212,13 @@ enum reg_class #define FP_ARG_FIRST (FP_REG_FIRST + 12) #define FP_ARG_LAST (FP_ARG_FIRST + MAX_ARGS_IN_REGISTERS - 1) +/* Temporary register that is used when restoring $gp after a call. $4 and $5 + are used for returning complex double values in soft-float code, so $6 is the + first suitable candidate for TARGET_MIPS16. For !TARGET_MIPS16 we can use + $gp itself as the temporary. */ +#define POST_CALL_TMP_REG \ + (TARGET_MIPS16 ? GP_ARG_FIRST + 2 : PIC_OFFSET_TABLE_REGNUM) + /* 1 if N is a possible register number for function argument passing. We have no FP argument registers when soft-float. When FP registers are 32 bits, we can't directly reference the odd numbered ones. */ diff --git a/gcc/testsuite/gcc.target/mips/fuse-caller-save-micromips.c b/gcc/testsuite/gcc.target/mips/fuse-caller-save-micromips.c new file mode 100644 index 0000000..6ad01c7 --- /dev/null +++ b/gcc/testsuite/gcc.target/mips/fuse-caller-save-micromips.c @@ -0,0 +1,17 @@ +/* { dg-do compile } */ +/* { dg-options "-fuse-caller-save (-mmicromips)" } */ +/* At -O0 and -O1, the register allocator behaves more conservatively, and + the fuse-caller-save optimization doesnt' trigger. */ +/* { dg-skip-if "" { *-*-* } { "-O0" "-O1" } } */ +/* Testing -fuse-caller-save optimization option. */ + +#define ATTRIBUTE MICROMIPS +#include "fuse-caller-save.h" + +/* 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" } } */ diff --git a/gcc/testsuite/gcc.target/mips/fuse-caller-save-mip16.c b/gcc/testsuite/gcc.target/mips/fuse-caller-save-mip16.c new file mode 100644 index 0000000..a7c6cf4 --- /dev/null +++ b/gcc/testsuite/gcc.target/mips/fuse-caller-save-mip16.c @@ -0,0 +1,17 @@ +/* { dg-do compile } */ +/* { dg-options "-fuse-caller-save (-mips16)" } */ +/* At -O0 and -O1, the register allocator behaves more conservatively, and + the fuse-caller-save optimization doesnt' trigger. */ +/* { dg-skip-if "" { *-*-* } { "-O0" "-O1" } } */ +/* Testing -fuse-caller-save optimization option. */ + +#define ATTRIBUTE MIPS16 +#include "fuse-caller-save.h" + +/* 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" } } */ 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 0000000..72c08fe --- /dev/null +++ b/gcc/testsuite/gcc.target/mips/fuse-caller-save.c @@ -0,0 +1,17 @@ +/* { dg-do compile } */ +/* { dg-options "-fuse-caller-save" } */ +/* At -O0 and -O1, the register allocator behaves more conservatively, and + the fuse-caller-save optimization doesnt' trigger. */ +/* { dg-skip-if "" { *-*-* } { "-O0" "-O1" } } */ +/* Testing -fuse-caller-save optimization option. */ + +#define ATTRIBUTE NOCOMPRESSION +#include "fuse-caller-save.h" + +/* 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" } } */ diff --git a/gcc/testsuite/gcc.target/mips/fuse-caller-save.h b/gcc/testsuite/gcc.target/mips/fuse-caller-save.h new file mode 100644 index 0000000..edf6039 --- /dev/null +++ b/gcc/testsuite/gcc.target/mips/fuse-caller-save.h @@ -0,0 +1,17 @@ +static int __attribute__((noinline)) ATTRIBUTE +bar (int x) +{ + return x + 3; +} + +int __attribute__((noinline)) ATTRIBUTE +foo (int y) +{ + return y + bar (y); +} + +int ATTRIBUTE +main (void) +{ + return !(foo (5) == 13); +} diff --git a/gcc/testsuite/gcc.target/mips/mips.exp b/gcc/testsuite/gcc.target/mips/mips.exp index 8c72cff..6ad8160 100644 --- a/gcc/testsuite/gcc.target/mips/mips.exp +++ b/gcc/testsuite/gcc.target/mips/mips.exp @@ -305,6 +305,7 @@ foreach option { tree-vectorize unroll-all-loops unroll-loops + use-caller-save } { lappend mips_option_groups $option "-f(no-|)$option" } -- 1.8.3.2