Re: [PATCH 2/3][AArch64][PR target/65697] Strengthen barriers for sync-compare-swap builtins.

2015-06-01 Thread James Greenhalgh
On Mon, Jun 01, 2015 at 01:08:15PM +0100, Matthew Wahab wrote:
 On 22/05/15 09:28, Matthew Wahab wrote:
  [Added PR number and updated patches]
 
  This patch changes the code generated for __sync_type_compare_and_swap to
 
  ldxr reg; cmp; bne label; stlxr; cbnz; label: dmb ish; mov .., reg
 
  This removes the acquire-barrier from the load and ends the operation with a
  fence to prevent memory references appearing after the __sync operation from
  being moved ahead of the store-release.
 
  This also strengthens the acquire barrier generated for 
  __sync_lock_test_and_set
  (which, like compare-and-swap, is implemented as a form of atomic exchange):
 
  ldaxr; stxr; cbnz
  becomes
  ldxr; stxr; cbnz; dmb ish
 
 
 Updated patch:
 - Used 'barrier' rather than 'fence' in comments.
 - Simplified the code for the initial load.
 
 Tested with check-gcc for aarch64-none-linux-gnu.
 
 Ok for trunk?
 Matthew
 
 2015-06-01  Matthew Wahab  matthew.wa...@arm.com
 
   PR target/65697
   * config/aarch64/aarch64.c (aarch64_split_compare_and_swap): Check
   for __sync memory models, emit initial loads and final barriers as
   appropriate.
 

OK,

Thanks,
James


 From e1f68896db3b367d43a7ae863339dbe100244360 Mon Sep 17 00:00:00 2001
 From: Matthew Wahab matthew.wa...@arm.com
 Date: Fri, 15 May 2015 09:31:06 +0100
 Subject: [PATCH 2/3] [AArch64] Strengthen barriers for sync-compare-swap
  builtins.
 
 Change-Id: I335771f2f42ea951d227f20f6cb9daa07330614d
 ---
  gcc/config/aarch64/aarch64.c | 18 --
  1 file changed, 16 insertions(+), 2 deletions(-)
 
 diff --git a/gcc/config/aarch64/aarch64.c b/gcc/config/aarch64/aarch64.c
 index b083e12..2db8f4f 100644
 --- a/gcc/config/aarch64/aarch64.c
 +++ b/gcc/config/aarch64/aarch64.c
 @@ -9436,14 +9436,18 @@ aarch64_split_compare_and_swap (rtx operands[])
bool is_weak;
rtx_code_label *label1, *label2;
rtx x, cond;
 +  enum memmodel model;
 +  rtx model_rtx;
  
rval = operands[0];
mem = operands[1];
oldval = operands[2];
newval = operands[3];
is_weak = (operands[4] != const0_rtx);
 +  model_rtx = operands[5];
scratch = operands[7];
mode = GET_MODE (mem);
 +  model = memmodel_from_int (INTVAL (model_rtx));
  
label1 = NULL;
if (!is_weak)
 @@ -9453,7 +9457,13 @@ aarch64_split_compare_and_swap (rtx operands[])
  }
label2 = gen_label_rtx ();
  
 -  aarch64_emit_load_exclusive (mode, rval, mem, operands[5]);
 +  /* The initial load can be relaxed for a __sync operation since a final
 + barrier will be emitted to stop code hoisting.  */
 +  if (is_mm_sync (model))
 +aarch64_emit_load_exclusive (mode, rval, mem,
 +  GEN_INT (MEMMODEL_RELAXED));
 +  else
 +aarch64_emit_load_exclusive (mode, rval, mem, model_rtx);
  
cond = aarch64_gen_compare_reg (NE, rval, oldval);
x = gen_rtx_NE (VOIDmode, cond, const0_rtx);
 @@ -9461,7 +9471,7 @@ aarch64_split_compare_and_swap (rtx operands[])
   gen_rtx_LABEL_REF (Pmode, label2), pc_rtx);
aarch64_emit_unlikely_jump (gen_rtx_SET (pc_rtx, x));
  
 -  aarch64_emit_store_exclusive (mode, scratch, mem, newval, operands[5]);
 +  aarch64_emit_store_exclusive (mode, scratch, mem, newval, model_rtx);
  
if (!is_weak)
  {
 @@ -9478,6 +9488,10 @@ aarch64_split_compare_and_swap (rtx operands[])
  }
  
emit_label (label2);
 +
 +  /* Emit any final barrier needed for a __sync operation.  */
 +  if (is_mm_sync (model))
 +aarch64_emit_post_barrier (model);
  }
  
  /* Split an atomic operation.  */
 -- 
 1.9.1
 



Re: [PATCH 2/3][AArch64][PR target/65697] Strengthen barriers for sync-compare-swap builtins.

2015-06-01 Thread Matthew Wahab

On 22/05/15 09:28, Matthew Wahab wrote:

[Added PR number and updated patches]

This patch changes the code generated for __sync_type_compare_and_swap to

ldxr reg; cmp; bne label; stlxr; cbnz; label: dmb ish; mov .., reg

This removes the acquire-barrier from the load and ends the operation with a
fence to prevent memory references appearing after the __sync operation from
being moved ahead of the store-release.

This also strengthens the acquire barrier generated for __sync_lock_test_and_set
(which, like compare-and-swap, is implemented as a form of atomic exchange):

ldaxr; stxr; cbnz
becomes
ldxr; stxr; cbnz; dmb ish



Updated patch:
- Used 'barrier' rather than 'fence' in comments.
- Simplified the code for the initial load.

Tested with check-gcc for aarch64-none-linux-gnu.

Ok for trunk?
Matthew

2015-06-01  Matthew Wahab  matthew.wa...@arm.com

PR target/65697
* config/aarch64/aarch64.c (aarch64_split_compare_and_swap): Check
for __sync memory models, emit initial loads and final barriers as
appropriate.

From e1f68896db3b367d43a7ae863339dbe100244360 Mon Sep 17 00:00:00 2001
From: Matthew Wahab matthew.wa...@arm.com
Date: Fri, 15 May 2015 09:31:06 +0100
Subject: [PATCH 2/3] [AArch64] Strengthen barriers for sync-compare-swap
 builtins.

Change-Id: I335771f2f42ea951d227f20f6cb9daa07330614d
---
 gcc/config/aarch64/aarch64.c | 18 --
 1 file changed, 16 insertions(+), 2 deletions(-)

diff --git a/gcc/config/aarch64/aarch64.c b/gcc/config/aarch64/aarch64.c
index b083e12..2db8f4f 100644
--- a/gcc/config/aarch64/aarch64.c
+++ b/gcc/config/aarch64/aarch64.c
@@ -9436,14 +9436,18 @@ aarch64_split_compare_and_swap (rtx operands[])
   bool is_weak;
   rtx_code_label *label1, *label2;
   rtx x, cond;
+  enum memmodel model;
+  rtx model_rtx;
 
   rval = operands[0];
   mem = operands[1];
   oldval = operands[2];
   newval = operands[3];
   is_weak = (operands[4] != const0_rtx);
+  model_rtx = operands[5];
   scratch = operands[7];
   mode = GET_MODE (mem);
+  model = memmodel_from_int (INTVAL (model_rtx));
 
   label1 = NULL;
   if (!is_weak)
@@ -9453,7 +9457,13 @@ aarch64_split_compare_and_swap (rtx operands[])
 }
   label2 = gen_label_rtx ();
 
-  aarch64_emit_load_exclusive (mode, rval, mem, operands[5]);
+  /* The initial load can be relaxed for a __sync operation since a final
+ barrier will be emitted to stop code hoisting.  */
+  if (is_mm_sync (model))
+aarch64_emit_load_exclusive (mode, rval, mem,
+ GEN_INT (MEMMODEL_RELAXED));
+  else
+aarch64_emit_load_exclusive (mode, rval, mem, model_rtx);
 
   cond = aarch64_gen_compare_reg (NE, rval, oldval);
   x = gen_rtx_NE (VOIDmode, cond, const0_rtx);
@@ -9461,7 +9471,7 @@ aarch64_split_compare_and_swap (rtx operands[])
 			gen_rtx_LABEL_REF (Pmode, label2), pc_rtx);
   aarch64_emit_unlikely_jump (gen_rtx_SET (pc_rtx, x));
 
-  aarch64_emit_store_exclusive (mode, scratch, mem, newval, operands[5]);
+  aarch64_emit_store_exclusive (mode, scratch, mem, newval, model_rtx);
 
   if (!is_weak)
 {
@@ -9478,6 +9488,10 @@ aarch64_split_compare_and_swap (rtx operands[])
 }
 
   emit_label (label2);
+
+  /* Emit any final barrier needed for a __sync operation.  */
+  if (is_mm_sync (model))
+aarch64_emit_post_barrier (model);
 }
 
 /* Split an atomic operation.  */
-- 
1.9.1



Re: [PATCH 2/3][AArch64][PR target/65697] Strengthen barriers for sync-compare-swap builtins.

2015-05-22 Thread Matthew Wahab

[Added PR number and updated patches]

This patch changes the code generated for __sync_type_compare_and_swap to

  ldxr reg; cmp; bne label; stlxr; cbnz; label: dmb ish; mov .., reg

This removes the acquire-barrier from the load and ends the operation with a
fence to prevent memory references appearing after the __sync operation from
being moved ahead of the store-release.

This also strengthens the acquire barrier generated for __sync_lock_test_and_set
(which, like compare-and-swap, is implemented as a form of atomic exchange):

  ldaxr; stxr; cbnz
becomes
  ldxr; stxr; cbnz; dmb ish


Tested with check-gcc for aarch64-none-linux-gnu.

Ok for trunk?
Matthew

2015-05-22  Matthew Wahab  matthew.wa...@arm.com

PR target/65697
* config/aarch64/aarch64.c (aarch64_split_compare_and_swap): Check
for __sync memory models, emit appropriate initial and final
barriers.

From 1e5cda95944e7176b8934296b1bb1ec4c9fb1362 Mon Sep 17 00:00:00 2001
From: Matthew Wahab matthew.wa...@arm.com
Date: Fri, 15 May 2015 09:31:06 +0100
Subject: [PATCH 2/3] [AArch64] Strengthen barriers for sync-compare-swap
 builtins.

Change-Id: I335771f2f42ea951d227f20f6cb9daa07330614d
---
 gcc/config/aarch64/aarch64.c | 19 +--
 1 file changed, 17 insertions(+), 2 deletions(-)

diff --git a/gcc/config/aarch64/aarch64.c b/gcc/config/aarch64/aarch64.c
index 182dbad..5b9feee 100644
--- a/gcc/config/aarch64/aarch64.c
+++ b/gcc/config/aarch64/aarch64.c
@@ -9433,14 +9433,19 @@ aarch64_split_compare_and_swap (rtx operands[])
   bool is_weak;
   rtx_code_label *label1, *label2;
   rtx x, cond;
+  enum memmodel model;
+  rtx model_rtx;
+  rtx load_model_rtx;
 
   rval = operands[0];
   mem = operands[1];
   oldval = operands[2];
   newval = operands[3];
   is_weak = (operands[4] != const0_rtx);
+  model_rtx = operands[5];
   scratch = operands[7];
   mode = GET_MODE (mem);
+  model = memmodel_from_int (INTVAL (model_rtx));
 
   label1 = NULL;
   if (!is_weak)
@@ -9450,7 +9455,13 @@ aarch64_split_compare_and_swap (rtx operands[])
 }
   label2 = gen_label_rtx ();
 
-  aarch64_emit_load_exclusive (mode, rval, mem, operands[5]);
+  /* A __sync operation will end with a fence so the load can be relaxed.  */
+  if (is_mm_sync (model))
+load_model_rtx = GEN_INT (MEMMODEL_RELAXED);
+  else
+load_model_rtx = model_rtx;
+
+  aarch64_emit_load_exclusive (mode, rval, mem, load_model_rtx);
 
   cond = aarch64_gen_compare_reg (NE, rval, oldval);
   x = gen_rtx_NE (VOIDmode, cond, const0_rtx);
@@ -9458,7 +9469,7 @@ aarch64_split_compare_and_swap (rtx operands[])
 			gen_rtx_LABEL_REF (Pmode, label2), pc_rtx);
   aarch64_emit_unlikely_jump (gen_rtx_SET (pc_rtx, x));
 
-  aarch64_emit_store_exclusive (mode, scratch, mem, newval, operands[5]);
+  aarch64_emit_store_exclusive (mode, scratch, mem, newval, model_rtx);
 
   if (!is_weak)
 {
@@ -9475,6 +9486,10 @@ aarch64_split_compare_and_swap (rtx operands[])
 }
 
   emit_label (label2);
+
+  /* A __sync operation may need a final fence.  */
+  if (is_mm_sync (model))
+aarch64_emit_post_barrier (model);
 }
 
 /* Split an atomic operation.  */
-- 
1.9.1