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: Optimize atomic memory operations for TARGET_OCTEON.


This is a follow up to an uncommitted patch I send over a month ago. For the Octeon processor, we can use the SYNCW instruction instead of SYNC in some situations for increased performance.

On Octeon the combination SYNCW ... other instructions ... SC functions as a full memory barrier and is faster than the same sequence written with a SYNC.

After Richard's rewrite of the atomic memory RTL expanders, this patch becomes almost trivial, we gate the use of SYNCW on TARGET_OCTEON.

Other places we emit SYNC are not followed by SC, so the optimization does not apply there.


Tested on mips64-unknown-linux-gnu all default languages and RUNTESTFLAGS="--target_board=unix/\{,-mabi=64\}" with no regressions.


OK to commit?

2009-09-29 David Daney <ddaney@caviumnetworks.com>

	* gcc/config/mips/mips.c (mips_process_sync_loop) Emit syncw
	instructions for TARGET_OCTEON.
Index: gcc/config/mips/mips.c
===================================================================
--- gcc/config/mips/mips.c	(revision 152057)
+++ gcc/config/mips/mips.c	(working copy)
@@ -11455,7 +11455,22 @@ mips_process_sync_loop (rtx insn, rtx *o
 
   /* Output the release side of the memory barrier.  */
   if (get_attr_sync_release_barrier (insn) == SYNC_RELEASE_BARRIER_YES)
-    mips_multi_add_insn ("sync", NULL);
+    {
+      if (TARGET_OCTEON)
+	{
+	  /* Octeon doesn't reorder reads, so a full barrier can be
+	     created by using SYNCW to order writes combined with the
+	     write from the following SC.  When the SC successfully
+	     completes, we know that all preceding writes are also
+	     committed to the coherent memory system.  It is possible
+	     for a single SYNCW to fail, but a pair of them will never
+	     fail, so we use two.  */
+	  mips_multi_add_insn ("syncw", NULL);
+	  mips_multi_add_insn ("syncw", NULL);
+	}
+      else
+	mips_multi_add_insn ("sync", NULL);
+    }
 
   /* Output the branch-back label.  */
   mips_multi_add_label ("1:");

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