This is the mail archive of the
gcc-patches@gcc.gnu.org
mailing list for the GCC project.
[PATCH] MIPS: Optimize atomic memory operations for TARGET_OCTEON.
- From: David Daney <ddaney at caviumnetworks dot com>
- To: GCC Patches <gcc-patches at gcc dot gnu dot org>
- Date: Tue, 29 Sep 2009 10:13:44 -0700
- Subject: [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:");