This is the mail archive of the gcc-patches@gcc.gnu.org mailing list for the GCC project.


Index Nav: [Date Index] [Subject Index] [Author Index] [Thread Index]
Message Nav: [Date Prev] [Date Next] [Thread Prev] [Thread Next]
Other format: [Raw text]

PATCH: MIPS 74K load/store scheduling tweak (take 2)


The MIPS 74K can't issue loads when stores are in flight. This patch tweaks the instruction scheduling to swap things around in the ready queue to group loads together and stores together, instead of interleaving them.

OK to commit?

-Sandra
2007-08-03  Sandra Loosemore  <sandra@codesourcery.com>
	    David Ung  <davidu@mips.com>

        gcc/
	* config/mips/mips.c (TARGET_SCHED_INIT): Define.
	(mips_maybe_swap_ready): New.
	(mips_last_74k_agen_insn): New.
	(mips_74k_agen_init): New.
	(mips_74k_agen_reorder): New function to group loads and stores
	in the ready queue.
	(mips_sched_init): New.
	(mips_sched_reorder): Call mips_74k_agen_reorder.
	(mips_variable_issue): Call mips_74k_agen_init.
Index: gcc/config/mips/mips.c
===================================================================
*** gcc/config/mips/mips.c	(revision 127140)
--- gcc/config/mips/mips.c	(working copy)
*************** static bool vr4130_true_reg_dependence_p
*** 393,398 ****
--- 393,399 ----
  static bool vr4130_swap_insns_p (rtx, rtx);
  static void vr4130_reorder (rtx *, int);
  static void mips_promote_ready (rtx *, int, int);
+ static void mips_sched_init (FILE *, int, int);
  static int mips_sched_reorder (FILE *, int, rtx *, int *, int);
  static int mips_variable_issue (FILE *, int, rtx, int);
  static int mips_adjust_cost (rtx, rtx, rtx, int);
*************** static const unsigned char mips16e_save_
*** 1225,1230 ****
--- 1226,1233 ----
  #undef TARGET_ASM_FUNCTION_RODATA_SECTION
  #define TARGET_ASM_FUNCTION_RODATA_SECTION mips_function_rodata_section
  
+ #undef TARGET_SCHED_INIT
+ #define TARGET_SCHED_INIT mips_sched_init
  #undef TARGET_SCHED_REORDER
  #define TARGET_SCHED_REORDER mips_sched_reorder
  #undef TARGET_SCHED_VARIABLE_ISSUE
*************** mips_promote_ready (rtx *ready, int lowe
*** 10881,10886 ****
--- 10884,10994 ----
    ready[i] = new_head;
  }
  
+ /* Conditionally swap the instructions at POS1 and POS2 in ready queue
+    READY, also adjusting the priority of the instruction formerly at
+    POS1 when we do so.  */
+ 
+ static void
+ mips_maybe_swap_ready (rtx *ready, int pos1, int pos2)
+ {
+   if (pos1 < pos2
+       && INSN_PRIORITY (ready[pos1]) + 4 >= INSN_PRIORITY (ready[pos2]))
+     {
+       rtx temp;
+       INSN_PRIORITY (ready[pos1]) = INSN_PRIORITY (ready[pos2]);
+       temp = ready[pos1];
+       ready[pos1] = ready[pos2];
+       ready[pos2] = temp;
+     }
+ }
+ 
+ /* Record whether last 74k AGEN instruction was a load or store.  */
+ 
+ static enum attr_type mips_last_74k_agen_insn = TYPE_UNKNOWN;
+ 
+ /* Initialize mips_last_74k_agen_insn from INSN.  A null argument
+    resets to TYPE_UNKNOWN state.  */
+ 
+ static void
+ mips_74k_agen_init (rtx insn)
+ {
+   if (!insn || !NONJUMP_INSN_P (insn))
+     mips_last_74k_agen_insn = TYPE_UNKNOWN;
+   else if (USEFUL_INSN_P (insn))
+     {
+       enum attr_type type = get_attr_type (insn);
+       if (type == TYPE_LOAD || type == TYPE_STORE)
+ 	mips_last_74k_agen_insn = type;
+     }
+ }
+ 
+ /* A TUNE_74K helper function.  The 74K AGEN pipeline likes multiple
+    loads to be grouped together, and multiple stores to be grouped
+    together.  Swap things around in the ready queue to make this happen.  */
+ 
+ static void
+ mips_74k_agen_reorder (rtx *ready, int nready)
+ {
+   int i;
+   int store_pos, load_pos;
+ 
+   store_pos = -1;
+   load_pos = -1;
+ 
+   for (i = nready - 1; i >= 0; i--)
+     {
+       rtx insn = ready[i];
+       if (USEFUL_INSN_P (insn))
+ 	switch (get_attr_type (insn))
+ 	  {
+ 	  case TYPE_STORE:
+ 	    if (store_pos == -1)
+ 	      store_pos = i;
+ 	    break;
+ 	    
+ 	  case TYPE_LOAD:
+ 	    if (load_pos == -1)
+ 	      load_pos = i;
+ 	    break;
+ 	    
+ 	  default:
+ 	    break;
+ 	  }
+     }
+   
+   if (load_pos == -1 || store_pos == -1)
+     return;
+   
+   switch (mips_last_74k_agen_insn)
+     {
+     case TYPE_UNKNOWN:
+       /* Prefer to schedule loads since they have a higher latency.  */
+     case TYPE_LOAD:
+       /* Swap loads to the front of the queue.  */
+       mips_maybe_swap_ready (ready, load_pos, store_pos);
+       break;
+     case TYPE_STORE:
+       /* Swap stores to the front of the queue.  */
+       mips_maybe_swap_ready (ready, store_pos, load_pos);
+       break;
+     default:
+       break;
+     }
+   /* At this point the ready queue may no longer be sorted, but that's
+      OK since 74k can't schedule concurrent load/store on the same
+      cycle.  */
+ }
+ 
+ /* Implement TARGET_SCHED_INIT.  */
+ 
+ static void
+ mips_sched_init (FILE *file ATTRIBUTE_UNUSED, int verbose ATTRIBUTE_UNUSED,
+ 		 int max_ready ATTRIBUTE_UNUSED)
+ {
+   if (TUNE_74K)
+     mips_74k_agen_init (NULL_RTX);
+ }
+ 
  /* Implement TARGET_SCHED_REORDER.  */
  
  static int
*************** mips_sched_reorder (FILE *file ATTRIBUTE
*** 10901,10906 ****
--- 11009,11016 ----
        if (*nreadyp > 1)
  	vr4130_reorder (ready, *nreadyp);
      }
+   if (TUNE_74K)
+     mips_74k_agen_reorder (ready, *nreadyp);
    return mips_issue_rate ();
  }
  
*************** static int
*** 10910,10915 ****
--- 11020,11027 ----
  mips_variable_issue (FILE *file ATTRIBUTE_UNUSED, int verbose ATTRIBUTE_UNUSED,
  		     rtx insn, int more)
  {
+   if (TUNE_74K)
+     mips_74k_agen_init (insn);
    switch (GET_CODE (PATTERN (insn)))
      {
      case USE:

Index Nav: [Date Index] [Subject Index] [Author Index] [Thread Index]
Message Nav: [Date Prev] [Date Next] [Thread Prev] [Thread Next]