public inbox for gcc-patches@gcc.gnu.org
 help / color / mirror / Atom feed
From: Sameera Deshpande <Sameera.Deshpande@imgtec.com>
To: "rdsandiford@googlemail.com" <rdsandiford@googlemail.com>
Cc: Matthew Fortune <Matthew.Fortune@imgtec.com>,
	"gcc-patches@gcc.gnu.org"	<gcc-patches@gcc.gnu.org>
Subject: [PATCH][MIPS] Enable load-load/store-store bonding
Date: Thu, 19 Jun 2014 09:41:00 -0000	[thread overview]
Message-ID: <38C8F1E431EDD94A82971C543A11B4FEE0A5C8@PUMAIL01.pu.imgtec.org> (raw)

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

Hi Richard,

Please find attached the patch implementing load-load/store-store bonding supported by P5600.

In P5600, 2 consecutive loads/stores of same type which access contiguous memory locations are bonded together by instruction issue unit to dispatch single load/store instruction which accesses both locations. This allows 2X improvement in memory intensive code. This optimization can be performed for LH, SH, LW, SW, LWC, SWC, LDC, SDC instructions.

This patch adds peephole2 patterns to identify such loads/stores, and put them in parallel, so that the scheduler will not split it - thereby guarantying h/w level load/store bonding.

The patch is tested with dejagnu for correctness.
Local testing on hardware for perf is  currently going on.
Ok for trunk? 

Changelog:
gcc/
	* config/mips/mips.md (JOINLDST1): New mode iterator.
	(insn_type): New mode attribute.
	(reg): Update mode attribute.
	(join2_load_Store<JOINLDST1:mode>): New pattern.
	(join2_loadhi): Likewise.
	(join2_storehi): Likewise.
	(define_peehole2): Add peephole2 patterns to join 2 HI/SI/SF/DF-mode
	load-load and store-stores.
	* config/mips/mips.opt (mld-st-pairing): New option.
	* config/mips/mips.c (mips_option_override): New exception.
	*config/mips/mips.h (ENABLE_LD_ST_PAIRING): New macro.

- Thanks and regards,
   Sameera D.


[-- Attachment #2: load-store-pairing.patch --]
[-- Type: application/octet-stream, Size: 8218 bytes --]

diff --git a/gcc/config/mips/mips.c b/gcc/config/mips/mips.c
index b5b5ba7..9804ef2 100644
--- a/gcc/config/mips/mips.c
+++ b/gcc/config/mips/mips.c
@@ -18813,6 +18813,9 @@ mips_option_override (void)
   if (TARGET_MICROMIPS && TARGET_MIPS16)
     error ("unsupported combination: %s", "-mips16 -mmicromips");
 
+  if (TARGET_FIX_24K && TUNE_P5600)
+    error ("unsupported combination: %s", "-mtune=p5600 -mfix-24k");
+
   /* Save the base compression state and process flags as though we
      were generating uncompressed code.  */
   mips_base_compression_flags = TARGET_COMPRESSION;
diff --git a/gcc/config/mips/mips.h b/gcc/config/mips/mips.h
index 86ca419..4478f81e 100644
--- a/gcc/config/mips/mips.h
+++ b/gcc/config/mips/mips.h
@@ -3184,3 +3184,6 @@ extern GTY(()) struct target_globals *mips16_globals;
    with arguments ARGS.  */
 #define PMODE_INSN(NAME, ARGS) \
   (Pmode == SImode ? NAME ## _si ARGS : NAME ## _di ARGS)
+
+#define ENABLE_LD_ST_PAIRING \
+  (TARGET_ENABLE_LD_ST_PAIRING && TUNE_P5600)
diff --git a/gcc/config/mips/mips.md b/gcc/config/mips/mips.md
index 7229e8f..05605c5 100644
--- a/gcc/config/mips/mips.md
+++ b/gcc/config/mips/mips.md
@@ -780,6 +780,7 @@
 
 (define_mode_iterator MOVEP1 [SI SF])
 (define_mode_iterator MOVEP2 [SI SF])
+(define_mode_iterator JOINLDST1 [SI SF DF])
 
 ;; This mode iterator allows :HILO to be used as the mode of the
 ;; concatenated HI and LO registers.
@@ -883,6 +884,8 @@
 (define_mode_attr loadx [(SF "lwxc1") (DF "ldxc1") (V2SF "ldxc1")])
 (define_mode_attr storex [(SF "swxc1") (DF "sdxc1") (V2SF "sdxc1")])
 
+(define_mode_attr insn_type [(SI "") (SF "fp") (DF "fp")])
+
 ;; The unextended ranges of the MIPS16 addiu and daddiu instructions
 ;; are different.  Some forms of unextended addiu have an 8-bit immediate
 ;; field but the equivalent daddiu has only a 5-bit field.
@@ -890,7 +893,7 @@
 
 ;; This attribute gives the best constraint to use for registers of
 ;; a given mode.
-(define_mode_attr reg [(SI "d") (DI "d") (CC "z") (CCF "f")])
+(define_mode_attr reg [(SI "d") (DI "d") (CC "z") (CCF "f") (SF "f") (DF "f")])
 
 ;; This attribute gives the format suffix for floating-point operations.
 (define_mode_attr fmt [(SF "s") (DF "d") (V2SF "ps")])
@@ -7442,6 +7445,153 @@
   { return MIPS_CALL ("jal", operands, 0, -1); }
   [(set_attr "type" "call")
    (set_attr "insn_count" "3")])
+
+(define_insn "*join2_load_store<JOINLDST1:mode>"
+  [(parallel
+    [(set (match_operand:JOINLDST1 0 "nonimmediate_operand" "=<reg>,m")
+	  (match_operand:JOINLDST1 1 "nonimmediate_operand" "m,<reg>"))
+     (set (match_operand:JOINLDST1 2 "nonimmediate_operand" "=<reg>,m")
+	  (match_operand:JOINLDST1 3 "nonimmediate_operand" "m,<reg>"))])]
+  "ENABLE_LD_ST_PAIRING && reload_completed"
+  {
+    output_asm_insn (mips_output_move (operands[0], operands[1]), operands);
+    output_asm_insn (mips_output_move (operands[2], operands[3]), &operands[2]);
+    return "";
+  }
+  [(set_attr "move_type" "<insn_type>load,<insn_type>store")
+   (set_attr_alternative "insn_count"
+	[(mult (symbol_ref "mips_load_store_insns (operands[1], insn)")
+	       (const_int 2))
+	 (mult (symbol_ref "mips_load_store_insns (operands[0], insn)")
+	       (const_int 2))])])
+
+;;2 SI/SF/DF loads are joined.
+(define_peephole2
+  [(set (match_operand:JOINLDST1 0 "register_operand")
+	(mem:JOINLDST1 (plus:SI (match_operand:SI 1 "register_operand")
+				(match_operand:SI 2 "const_int_operand"))))
+   (set (match_operand:JOINLDST1 3 "register_operand")
+	(mem:JOINLDST1 (plus:SI (match_dup 1)
+				(match_operand:SI 4 "const_int_operand"))))]
+  "ENABLE_LD_ST_PAIRING &&
+   REGNO_REG_CLASS (REGNO (operands[0]))
+	== REGNO_REG_CLASS (REGNO (operands[3])) &&
+   (abs (INTVAL (operands[2]) - INTVAL (operands[4]))
+	== GET_MODE_SIZE (<JOINLDST1:MODE>mode))"
+
+  [(parallel [(set (match_dup 0)
+		   (match_dup 2))
+	      (set (match_dup 3)
+		   (match_dup 4))])]
+  {
+    operands[4] = SET_SRC (PATTERN (next_active_insn (curr_insn)));
+    operands[2] = SET_SRC (PATTERN (curr_insn));
+  })
+
+;; 2 SI/SF/DF stores are joined.
+(define_peephole2
+  [(set (mem:JOINLDST1 (plus:SI (match_operand:SI 0 "register_operand")
+				(match_operand:SI 1 "const_int_operand")))
+	(match_operand:JOINLDST1 2 "register_operand"))
+   (set (mem:JOINLDST1 (plus:SI (match_dup 0)
+				(match_operand:SI 3 "const_int_operand")))
+	(match_operand:JOINLDST1 4 "register_operand"))]
+  "ENABLE_LD_ST_PAIRING &&
+   REGNO_REG_CLASS (REGNO (operands[2]))
+	== REGNO_REG_CLASS (REGNO (operands[4])) &&
+   (abs (INTVAL (operands[1]) - INTVAL (operands[3]))
+	== GET_MODE_SIZE (<JOINLDST1:MODE>mode))"
+  [(parallel [(set (match_dup 1)
+		   (match_dup 2))
+	      (set (match_dup 3)
+		   (match_dup 4))])]
+  {
+    operands[3] = SET_DEST (PATTERN (next_active_insn (curr_insn)));
+    operands[1] = SET_DEST (PATTERN (curr_insn));
+  })
+
+(define_insn "*join2_storehi"
+  [(parallel
+    [(set (match_operand:HI 0 "memory_operand" "=m")
+	  (match_operand:HI 1 "register_operand" "r"))
+     (set (match_operand:HI 2 "memory_operand" "=m")
+	  (match_operand:HI 3 "register_operand" "r"))])]
+  "ENABLE_LD_ST_PAIRING && reload_completed"
+  {
+    output_asm_insn (mips_output_move (operands[0], operands[1]), operands);
+    output_asm_insn (mips_output_move (operands[2], operands[3]), &operands[2]);
+    return "";
+  }
+  [(set_attr "move_type" "store")
+   (set_attr_alternative "insn_count"
+	[(mult	(symbol_ref "mips_load_store_insns (operands[0], insn)")
+		(const_int 2))])])
+
+(define_insn "*join2_loadhi"
+  [(parallel
+    [(set (match_operand:SI 0 "register_operand" "=r")
+	  (any_extend:SI (match_operand:HI 1 "memory_operand" "m")))
+     (set (match_operand:SI 2 "register_operand" "=r")
+	  (any_extend:SI (match_operand:HI 3 "memory_operand" "m")))])]
+  "ENABLE_LD_ST_PAIRING && reload_completed"
+  {
+    output_asm_insn ("lh<u>\t%0,%1", operands);
+    output_asm_insn ("lh<u>\t%2,%3", operands);
+    return "";
+  }
+  [(set_attr "move_type" "load")
+   (set_attr_alternative "insn_count"
+	[(mult	(symbol_ref "mips_load_store_insns (operands[1], insn)")
+		(const_int 2))])])
+
+
+;; 2 16 bit integer loads are joined.
+(define_peephole2
+  [(set (match_operand:SI 0 "register_operand")
+	(any_extend:SI (mem:HI (plus:SI
+				  (match_operand:SI 1 "register_operand")
+				  (match_operand:SI 2 "const_int_operand")))))
+   (set (match_operand:SI 3 "register_operand")
+	(any_extend:SI (mem:HI (plus:SI
+				  (match_dup 1)
+				  (match_operand:SI 4 "const_int_operand")))))]
+  "ENABLE_LD_ST_PAIRING &&
+   REGNO_REG_CLASS (REGNO (operands[0]))
+	== REGNO_REG_CLASS (REGNO (operands[3])) &&
+   (abs (INTVAL (operands[2]) - INTVAL (operands[4]))
+	== GET_MODE_SIZE (HImode))"
+
+  [(parallel [(set (match_dup 0)
+		   (match_dup 2))
+	      (set (match_dup 3)
+		   (match_dup 4))])]
+  {
+    operands[4] = SET_SRC (PATTERN (next_active_insn (curr_insn)));
+    operands[2] = SET_SRC (PATTERN (curr_insn));
+  })
+
+;; 2 16 bit integer stores are joined.
+(define_peephole2
+  [(set (mem:HI (plus:SI (match_operand:SI 0 "register_operand")
+			 (match_operand:SI 1 "const_int_operand")))
+	(match_operand:HI 2 "register_operand"))
+   (set (mem:HI (plus:SI (match_dup 0)
+			 (match_operand:SI 3 "const_int_operand")))
+	(match_operand:HI 4 "register_operand"))]
+  "ENABLE_LD_ST_PAIRING &&
+   REGNO_REG_CLASS (REGNO (operands[2]))
+	== REGNO_REG_CLASS (REGNO (operands[4])) &&
+   (abs (INTVAL (operands[1]) - INTVAL (operands[3]))
+	== GET_MODE_SIZE (HImode))"
+  [(parallel [(set (match_dup 1)
+		   (match_dup 2))
+	      (set (match_dup 3)
+		   (match_dup 4))])]
+  {
+    operands[3] = SET_DEST (PATTERN (next_active_insn (curr_insn)));
+    operands[1] = SET_DEST (PATTERN (curr_insn));
+  })
+
 \f
 ;; Synchronization instructions.
 
diff --git a/gcc/config/mips/mips.opt b/gcc/config/mips/mips.opt
index b9cfd62..d4135cf 100644
--- a/gcc/config/mips/mips.opt
+++ b/gcc/config/mips/mips.opt
@@ -445,3 +445,7 @@ Enum(mips_lib_setting) String(tiny) Value(MIPS_LIB_TINY)
 
 msched-weight
 Target Report Var(TARGET_SCHED_WEIGHT) Undocumented
+
+mld-st-pairing
+Target Report Var(TARGET_ENABLE_LD_ST_PAIRING)
+Enable load/store pairing

             reply	other threads:[~2014-06-19  9:41 UTC|newest]

Thread overview: 15+ messages / expand[flat|nested]  mbox.gz  Atom feed  top
2014-06-19  9:41 Sameera Deshpande [this message]
     [not found] <38C8F1E431EDD94A82971C543A11B4FEE0A588@PUMAIL01.pu.imgtec.org>
2014-06-21 16:25 ` Richard Sandiford
2014-06-23  9:18   ` Sameera Deshpande
2014-06-23  9:41     ` Richard Sandiford
2014-06-24 10:42   ` Sameera Deshpande
2015-03-30 11:28     ` sameera
2015-04-20  5:09       ` sameera
2015-04-20 18:30         ` Mike Stump
2015-04-20 19:09         ` Matthew Fortune
2015-04-20 22:01           ` Moore, Catherine
2015-05-11 11:05           ` sameera
2015-05-11 12:13             ` Matthew Fortune
2015-05-11 12:39               ` sameera
2015-05-11 16:40             ` Mike Stump
2015-05-13  7:39               ` sameera

Reply instructions:

You may reply publicly to this message via plain-text email
using any one of the following methods:

* Save the following mbox file, import it into your mail client,
  and reply-to-all from there: mbox

  Avoid top-posting and favor interleaved quoting:
  https://en.wikipedia.org/wiki/Posting_style#Interleaved_style

* Reply using the --to, --cc, and --in-reply-to
  switches of git-send-email(1):

  git send-email \
    --in-reply-to=38C8F1E431EDD94A82971C543A11B4FEE0A5C8@PUMAIL01.pu.imgtec.org \
    --to=sameera.deshpande@imgtec.com \
    --cc=Matthew.Fortune@imgtec.com \
    --cc=gcc-patches@gcc.gnu.org \
    --cc=rdsandiford@googlemail.com \
    /path/to/YOUR_REPLY

  https://kernel.org/pub/software/scm/git/docs/git-send-email.html

* If your mail client supports setting the In-Reply-To header
  via mailto: links, try the mailto: link
Be sure your reply has a Subject: header at the top and a blank line before the message body.
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).