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 >