From patchwork Mon May 11 12:38:44 2015 Content-Type: text/plain; charset="utf-8" MIME-Version: 1.0 Content-Transfer-Encoding: 7bit X-Patchwork-Submitter: sameera X-Patchwork-Id: 470745 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 8C56514016A for ; Mon, 11 May 2015 22:39:28 +1000 (AEST) Authentication-Results: ozlabs.org; dkim=pass (1024-bit key; unprotected) header.d=gcc.gnu.org header.i=@gcc.gnu.org header.b=ktgzhMys; dkim-atps=neutral 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=I0S+1zAVb/XPiYHWx WJfiFhHQrWPnVgTOBVqBffBHk2argWO1WfhW98PYJwGIvICy49AbAohPFEq73E4w yejGulG6uDhxZNNilpaEHPzJ8qRgftBKyT0wWsy27Jwk73c5r91hhXCVDGRyyV9G YXTo6xu/hvleotA7nEzRx+Qyvs= 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=FMuAe9nl8lenzSqfvNPuDcf 6+qU=; b=ktgzhMysVz26qDnQJMDTH9fHeeJqrNoeagD/b9nYwvfqStvtv1oPP8n 7nmOCzl9V1WpDrIdUbOXjhJS3IyNtcv65NJAhAxOnRmkCFBAQ/9vgR/ZynfUlj0j x7MrjkatJhaIQFNCu7HQPxdnzj/A+SvAW6xuvOZ0Xi4AiDnw80JA= Received: (qmail 5109 invoked by alias); 11 May 2015 12:39:20 -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 5096 invoked by uid 89); 11 May 2015 12:39:19 -0000 Authentication-Results: sourceware.org; auth=none X-Virus-Found: No X-Spam-SWARE-Status: No, score=-1.0 required=5.0 tests=AWL, BAYES_00, SPF_PASS, T_RP_MATCHES_RCVD autolearn=ham version=3.3.2 X-HELO: mailapp01.imgtec.com Received: from mailapp01.imgtec.com (HELO mailapp01.imgtec.com) (195.59.15.196) by sourceware.org (qpsmtpd/0.93/v0.84-503-g423c35a) with ESMTP; Mon, 11 May 2015 12:39:17 +0000 Received: from KLMAIL01.kl.imgtec.org (unknown [192.168.5.35]) by Websense Email Security Gateway with ESMTPS id EB27D70BD0C0; Mon, 11 May 2015 13:39:10 +0100 (IST) Received: from PUMAIL01.pu.imgtec.org (192.168.91.250) by KLMAIL01.kl.imgtec.org (192.168.5.35) with Microsoft SMTP Server (TLS) id 14.3.195.1; Mon, 11 May 2015 13:38:10 +0100 Received: from [192.168.93.25] (192.168.93.25) by PUMAIL01.pu.imgtec.org (192.168.91.250) with Microsoft SMTP Server (TLS) id 14.3.123.3; Mon, 11 May 2015 18:07:57 +0530 Message-ID: <5550A2D4.8090808@imgtec.com> Date: Mon, 11 May 2015 18:08:44 +0530 From: sameera User-Agent: Mozilla/5.0 (X11; Linux x86_64; rv:31.0) Gecko/20100101 Thunderbird/31.6.0 MIME-Version: 1.0 To: Matthew Fortune , "clm@codesourcery.com" , Mike Stump CC: Richard Sandiford , "gcc-patches@gcc.gnu.org" , "echristo@gmail.com" Subject: Re: [PATCH][MIPS] Enable load-load/store-store bonding References: <38C8F1E431EDD94A82971C543A11B4FEE0A588@PUMAIL01.pu.imgtec.org> <8761ju8c2k.fsf@talisman.default> <38C8F1E431EDD94A82971C543A11B4FEE0C46D@PUMAIL01.pu.imgtec.org> <5519336F.4020609@imgtec.com> <55348A22.5050704@imgtec.com> <6D39441BF12EF246A7ABCE6654B023532103246C@LEMAIL01.le.imgtec.org> <55508D02.4050007@imgtec.com> <6D39441BF12EF246A7ABCE6654B0235321051D54@LEMAIL01.le.imgtec.org> In-Reply-To: <6D39441BF12EF246A7ABCE6654B0235321051D54@LEMAIL01.le.imgtec.org> X-IsSubscribed: yes On Monday 11 May 2015 05:43 PM, Matthew Fortune wrote: > Hi Sameera, > > Sameera Deshpande writes: >> Changelog: >> gcc/ >> * config/mips/mips.md (JOIN_MODE): New mode iterator. >> (join2_load_Store): New pattern. >> (join2_loadhi): Likewise. >> (define_peehole2): Add peephole2 patterns to join 2 >> HI/SI/SF/DF-mode >> load-load and store-stores. >> * config/mips/mips.opt (mload-store-pairs): New option. >> (TARGET_LOAD_STORE_PAIRS): New macro. >> * config/mips/mips.h (ENABLE_LD_ST_PAIRS): Likewise. >> * config/mips/mips-protos.h (mips_load_store_bonding_p): New >> prototype. >> * config/mips/mips.c (mips_load_store_bonding_p): New function. >> >> gcc/testsuite/ >> * gcc.target/mips/p5600-bonding.c : New testcase to test >> bonding. > > Just 'New file.' is fine for the changelog. > >> diff --git a/gcc/testsuite/gcc.target/mips/p5600-bonding.c b/gcc/testsuite/gcc.target/mips/p5600-bonding.c >> new file mode 100644 >> index 0000000..122b9f8 >> --- /dev/null >> +++ b/gcc/testsuite/gcc.target/mips/p5600-bonding.c >> @@ -0,0 +1,19 @@ >> +/* { dg-do compile } */ >> +/* { dg-options "-dp -mtune=p5600 -mno-micromips -mno-mips16" } */ >> +/* { dg-skip-if "Bonding needs peephole optimization." { *-*-* } { "-O0" "-O1" } { "" } } */ >> +typedef int VINT32 __attribute__ ((vector_size((16)))); >> + >> +void memory_operation_fun2_si(void * __restrict src, void * __restrict dest, int num) > > Code style applies for testcases too, return type on line above, space > after function name, line length. > >> +{ >> + VINT32 *vsrc = (VINT32 *)src; > > Indentation. > >> + VINT32 *vdest = (VINT32 *)dest; >> + int i; >> + >> + for (i = 0; i < num - 1; i+=2) >> + { > > Indentation > >> + vdest[i] = (vdest[i] + vsrc[i]); > > Unnecessary brackets. > >> + vdest[i + 1] = vdest[i + 1] + vsrc[i + 1]; >> + } >> +} >> +/* { dg-final { scan-assembler "join2_" } } */ >> + > > OK with those changes. > > Thanks, > Matthew > Hi Matthew, Thanks for the comments. Please find attached updated patch. I do not have permissions to apply the patch in GCC. Can you please submit the patch for me? Changelog: gcc/ * config/mips/mips.md (JOIN_MODE): New mode iterator. (join2_load_Store): New pattern. (join2_loadhi): Likewise. (define_peehole2): Add peephole2 patterns to join 2 HI/SI/SF/DF-mode load-load and store-stores. * config/mips/mips.opt (mload-store-pairs): New option. (TARGET_LOAD_STORE_PAIRS): New macro. * config/mips/mips.h (ENABLE_LD_ST_PAIRS): Likewise. * config/mips/mips-protos.h (mips_load_store_bonding_p): New prototype. * config/mips/mips.c (mips_load_store_bonding_p): New function. gcc/testsuite/ * gcc.target/mips/p5600-bonding.c : New file. diff --git a/gcc/config/mips/mips-protos.h b/gcc/config/mips/mips-protos.h index b48e04f..244eb8d 100644 --- a/gcc/config/mips/mips-protos.h +++ b/gcc/config/mips/mips-protos.h @@ -360,6 +360,7 @@ extern bool mips_epilogue_uses (unsigned int); extern void mips_final_prescan_insn (rtx_insn *, rtx *, int); extern int mips_trampoline_code_size (void); extern void mips_function_profiler (FILE *); +extern bool mips_load_store_bonding_p (rtx *, machine_mode, bool); typedef rtx (*mulsidi3_gen_fn) (rtx, rtx, rtx); #ifdef RTX_CODE diff --git a/gcc/config/mips/mips.c b/gcc/config/mips/mips.c index bf69850..4fc15c4 100644 --- a/gcc/config/mips/mips.c +++ b/gcc/config/mips/mips.c @@ -18241,6 +18241,66 @@ umips_load_store_pair_p_1 (bool load_p, bool swap_p, return true; } +bool +mips_load_store_bonding_p (rtx *operands, machine_mode mode, bool load_p) +{ + rtx reg1, reg2, mem1, mem2, base1, base2; + enum reg_class rc1, rc2; + HOST_WIDE_INT offset1, offset2; + + if (load_p) + { + reg1 = operands[0]; + reg2 = operands[2]; + mem1 = operands[1]; + mem2 = operands[3]; + } + else + { + reg1 = operands[1]; + reg2 = operands[3]; + mem1 = operands[0]; + mem2 = operands[2]; + } + + if (mips_address_insns (XEXP (mem1, 0), mode, false) == 0 + || mips_address_insns (XEXP (mem2, 0), mode, false) == 0) + return false; + + mips_split_plus (XEXP (mem1, 0), &base1, &offset1); + mips_split_plus (XEXP (mem2, 0), &base2, &offset2); + + /* Base regs do not match. */ + if (!REG_P (base1) || !rtx_equal_p (base1, base2)) + return false; + + /* Either of the loads is clobbering base register. It is legitimate to bond + loads if second load clobbers base register. However, hardware does not + support such bonding. */ + if (load_p + && (REGNO (reg1) == REGNO (base1) + || (REGNO (reg2) == REGNO (base1)))) + return false; + + /* Loading in same registers. */ + if (load_p + && REGNO (reg1) == REGNO (reg2)) + return false; + + /* The loads/stores are not of same type. */ + rc1 = REGNO_REG_CLASS (REGNO (reg1)); + rc2 = REGNO_REG_CLASS (REGNO (reg2)); + if (rc1 != rc2 + && !reg_class_subset_p (rc1, rc2) + && !reg_class_subset_p (rc2, rc1)) + return false; + + if (abs (offset1 - offset2) != GET_MODE_SIZE (mode)) + return false; + + return true; +} + /* OPERANDS describes the operands to a pair of SETs, in the order dest1, src1, dest2, src2. Return true if the operands can be used in an LWP or SWP instruction; LOAD_P says which. */ diff --git a/gcc/config/mips/mips.h b/gcc/config/mips/mips.h index 4bd83f5..c9accd1 100644 --- a/gcc/config/mips/mips.h +++ b/gcc/config/mips/mips.h @@ -3162,3 +3162,10 @@ extern GTY(()) struct target_globals *mips16_globals; #define STANDARD_STARTFILE_PREFIX_1 "/lib64/" #define STANDARD_STARTFILE_PREFIX_2 "/usr/lib64/" #endif + +/* Load store bonding is not supported by micromips and fix_24k. The + performance can be degraded for those targets. Hence, do not bond for + micromips or fix_24k. */ +#define ENABLE_LD_ST_PAIRS \ + (TARGET_LOAD_STORE_PAIRS && TUNE_P5600 \ + && !TARGET_MICROMIPS && !TARGET_FIX_24K) diff --git a/gcc/config/mips/mips.md b/gcc/config/mips/mips.md index ed4c0ba..0e2b172 100644 --- a/gcc/config/mips/mips.md +++ b/gcc/config/mips/mips.md @@ -754,6 +754,11 @@ (define_mode_iterator MOVEP1 [SI SF]) (define_mode_iterator MOVEP2 [SI SF]) +(define_mode_iterator JOIN_MODE [HI + SI + (SF "TARGET_HARD_FLOAT") + (DF "TARGET_HARD_FLOAT + && TARGET_DOUBLE_FLOAT")]) ;; This mode iterator allows :HILO to be used as the mode of the ;; concatenated HI and LO registers. @@ -7407,6 +7412,112 @@ { return MIPS_CALL ("jal", operands, 0, -1); } [(set_attr "type" "call") (set_attr "insn_count" "3")]) + +;; Match paired HI/SI/SF/DFmode load/stores. +(define_insn "*join2_load_store" + [(set (match_operand:JOIN_MODE 0 "nonimmediate_operand" "=d,f,m,m") + (match_operand:JOIN_MODE 1 "nonimmediate_operand" "m,m,d,f")) + (set (match_operand:JOIN_MODE 2 "nonimmediate_operand" "=d,f,m,m") + (match_operand:JOIN_MODE 3 "nonimmediate_operand" "m,m,d,f"))] + "ENABLE_LD_ST_PAIRS && reload_completed" + { + bool load_p = (which_alternative == 0 || which_alternative == 1); + /* Reg-renaming pass reuses base register if it is dead after bonded loads. + Hardware does not bond those loads, even when they are consecutive. + However, order of the loads need to be checked for correctness. */ + if (!load_p || !reg_overlap_mentioned_p (operands[0], operands[1])) + { + output_asm_insn (mips_output_move (operands[0], operands[1]), + operands); + output_asm_insn (mips_output_move (operands[2], operands[3]), + &operands[2]); + } + else + { + output_asm_insn (mips_output_move (operands[2], operands[3]), + &operands[2]); + output_asm_insn (mips_output_move (operands[0], operands[1]), + operands); + } + return ""; + } + [(set_attr "move_type" "load,fpload,store,fpstore") + (set_attr "insn_count" "2,2,2,2")]) + +;; 2 HI/SI/SF/DF loads are joined. +;; P5600 does not support bonding of two LBs, hence QI mode is not included. +;; The loads must be non-volatile as they might be reordered at the time of asm +;; generation. +(define_peephole2 + [(set (match_operand:JOIN_MODE 0 "register_operand") + (match_operand:JOIN_MODE 1 "non_volatile_mem_operand")) + (set (match_operand:JOIN_MODE 2 "register_operand") + (match_operand:JOIN_MODE 3 "non_volatile_mem_operand"))] + "ENABLE_LD_ST_PAIRS + && mips_load_store_bonding_p (operands, mode, true)" + [(parallel [(set (match_dup 0) + (match_dup 1)) + (set (match_dup 2) + (match_dup 3))])] + "") + +;; 2 HI/SI/SF/DF stores are joined. +;; P5600 does not support bonding of two SBs, hence QI mode is not included. +(define_peephole2 + [(set (match_operand:JOIN_MODE 0 "memory_operand") + (match_operand:JOIN_MODE 1 "register_operand")) + (set (match_operand:JOIN_MODE 2 "memory_operand") + (match_operand:JOIN_MODE 3 "register_operand"))] + "ENABLE_LD_ST_PAIRS + && mips_load_store_bonding_p (operands, mode, false)" + [(parallel [(set (match_dup 0) + (match_dup 1)) + (set (match_dup 2) + (match_dup 3))])] + "") + +;; Match paired HImode loads. +(define_insn "*join2_loadhi" + [(set (match_operand:SI 0 "register_operand" "=r") + (any_extend:SI (match_operand:HI 1 "non_volatile_mem_operand" "m"))) + (set (match_operand:SI 2 "register_operand" "=r") + (any_extend:SI (match_operand:HI 3 "non_volatile_mem_operand" "m")))] + "ENABLE_LD_ST_PAIRS && reload_completed" + { + /* Reg-renaming pass reuses base register if it is dead after bonded loads. + Hardware does not bond those loads, even when they are consecutive. + However, order of the loads need to be checked for correctness. */ + if (!reg_overlap_mentioned_p (operands[0], operands[1])) + { + output_asm_insn ("lh\t%0,%1", operands); + output_asm_insn ("lh\t%2,%3", operands); + } + else + { + output_asm_insn ("lh\t%2,%3", operands); + output_asm_insn ("lh\t%0,%1", operands); + } + + return ""; + } + [(set_attr "move_type" "load") + (set_attr "insn_count" "2")]) + + +;; 2 HI loads are joined. +(define_peephole2 + [(set (match_operand:SI 0 "register_operand") + (any_extend:SI (match_operand:HI 1 "non_volatile_mem_operand"))) + (set (match_operand:SI 2 "register_operand") + (any_extend:SI (match_operand:HI 3 "non_volatile_mem_operand")))] + "ENABLE_LD_ST_PAIRS + && mips_load_store_bonding_p (operands, HImode, true)" + [(parallel [(set (match_dup 0) + (any_extend:SI (match_dup 1))) + (set (match_dup 2) + (any_extend:SI (match_dup 3)))])] + "") + ;; Synchronization instructions. diff --git a/gcc/config/mips/mips.opt b/gcc/config/mips/mips.opt index 9e89aa9..a9baebe 100644 --- a/gcc/config/mips/mips.opt +++ b/gcc/config/mips/mips.opt @@ -418,3 +418,7 @@ Enable use of odd-numbered single-precision registers noasmopt Driver + +mload-store-pairs +Target Report Var(TARGET_LOAD_STORE_PAIRS) Init(1) +Enable load/store bonding. diff --git a/gcc/testsuite/gcc.target/mips/p5600-bonding.c b/gcc/testsuite/gcc.target/mips/p5600-bonding.c new file mode 100644 index 0000000..0890ffa --- /dev/null +++ b/gcc/testsuite/gcc.target/mips/p5600-bonding.c @@ -0,0 +1,20 @@ +/* { dg-do compile } */ +/* { dg-options "-dp -mtune=p5600 -mno-micromips -mno-mips16" } */ +/* { dg-skip-if "Bonding needs peephole optimization." { *-*-* } { "-O0" "-O1" } { "" } } */ +typedef int VINT32 __attribute__ ((vector_size((16)))); + +void +memory_operation (void * __restrict src, void * __restrict dest, int num) +{ + VINT32 *vsrc = (VINT32 *) src; + VINT32 *vdest = (VINT32 *) dest; + int i; + + for (i = 0; i < num - 1; i += 2) + { + vdest[i] = vdest[i] + vsrc[i]; + vdest[i + 1] = vdest[i + 1] + vsrc[i + 1]; + } +} +/* { dg-final { scan-assembler "join2_" } } */ +