Hi,

I noticed that sync_lock_release uses lwsync if available but every other
sync_* builtin uses a heavyweight sync. eg:

00000060 <sync_fetch_and_add>:
  60:   7c 00 04 ac     sync    
  64:   7c 69 1b 78     mr      r9,r3
  68:   7c 60 48 28     lwarx   r3,0,r9
  6c:   39 63 00 01     addi    r11,r3,1
  70:   7d 60 49 2d     stwcx.  r11,0,r9
  74:   40 a2 ff f4     bne-    68 <sync_fetch_and_add+0x8>
  78:   4c 00 01 2c     isync
  7c:   4e 80 00 20     blr

Update rs6000_emit_sync, rs6000_split_atomic_op and
rs6000_split_compare_and_swap to use gen_lwsync().

Anton
--

Index: gcc/gcc/config/rs6000/rs6000.c
===================================================================
--- gcc.orig/gcc/config/rs6000/rs6000.c 2008-09-03 02:33:35.000000000 -0400
+++ gcc/gcc/config/rs6000/rs6000.c      2008-09-03 02:44:11.000000000 -0400
@@ -13687,7 +13687,7 @@
   rtx shift = NULL_RTX;
 
   if (sync_p)
-    emit_insn (gen_memory_barrier ());
+    emit_insn (gen_lwsync ());
 
   if (GET_CODE (m) == NOT)
     used_m = XEXP (m, 0);
@@ -13927,7 +13927,7 @@
   enum machine_mode mode = GET_MODE (mem);
   rtx label, x, cond = gen_rtx_REG (CCmode, CR0_REGNO);
 
-  emit_insn (gen_memory_barrier ());
+  emit_insn (gen_lwsync ());
 
   label = gen_label_rtx ();
   emit_label (label);
@@ -13967,7 +13967,7 @@
   enum machine_mode mode = GET_MODE (mem);
   rtx label1, label2, x, cond = gen_rtx_REG (CCmode, CR0_REGNO);
 
-  emit_insn (gen_memory_barrier ());
+  emit_insn (gen_lwsync ());
 
   label1 = gen_rtx_LABEL_REF (VOIDmode, gen_label_rtx ());
   label2 = gen_rtx_LABEL_REF (VOIDmode, gen_label_rtx ());
@@ -14071,7 +14071,7 @@
 {
   rtx label1, label2, x, cond = gen_rtx_REG (CCmode, CR0_REGNO);
 
-  emit_insn (gen_memory_barrier ());
+  emit_insn (gen_lwsync ());
   label1 = gen_rtx_LABEL_REF (VOIDmode, gen_label_rtx ());
   label2 = gen_rtx_LABEL_REF (VOIDmode, gen_label_rtx ());
   emit_label (XEXP (label1, 0));

Reply via email to