From mboxrd@z Thu Jan 1 00:00:00 1970 Return-Path: Received: (qmail 34965 invoked by alias); 25 Sep 2018 16:13:23 -0000 Mailing-List: contact gcc-patches-help@gcc.gnu.org; run by ezmlm Precedence: bulk List-Id: List-Archive: List-Post: List-Help: Sender: gcc-patches-owner@gcc.gnu.org Received: (qmail 34943 invoked by uid 89); 25 Sep 2018 16:13:23 -0000 Authentication-Results: sourceware.org; auth=none X-Spam-SWARE-Status: No, score=-26.7 required=5.0 tests=BAYES_00,GIT_PATCH_0,GIT_PATCH_1,GIT_PATCH_2,GIT_PATCH_3,KAM_LOTSOFHASH,SPF_PASS autolearn=ham version=3.3.2 spammy=2306, lda X-HELO: foss.arm.com Received: from foss.arm.com (HELO foss.arm.com) (217.140.101.70) by sourceware.org (qpsmtpd/0.93/v0.84-503-g423c35a) with ESMTP; Tue, 25 Sep 2018 16:13:20 +0000 Received: from usa-sjc-imap-foss1.foss.arm.com (unknown [10.72.51.249]) by usa-sjc-mx-foss1.foss.arm.com (Postfix) with ESMTP id 1310A7A9; Tue, 25 Sep 2018 09:13:19 -0700 (PDT) Received: from e120077-lin.cambridge.arm.com (e120077-lin.cambridge.arm.com [10.2.206.194]) by usa-sjc-imap-foss1.foss.arm.com (Postfix) with ESMTPSA id A735E3F5BD; Tue, 25 Sep 2018 09:13:17 -0700 (PDT) Subject: Re: [PATCH][GCC][ARM] New helper functions to check atomicity requirements To: Matthew Malcomson , gcc-patches@gcc.gnu.org Cc: Kyrylo.Tkachov@arm.com, nickc@redhat.com, nd@arm.com, Ramana.Radhakrishnan@arm.com References: From: "Richard Earnshaw (lists)" Openpgp: preference=signencrypt Message-ID: <6f4a0038-694a-3165-c78a-884376ed8a54@arm.com> Date: Tue, 25 Sep 2018 16:43:00 -0000 User-Agent: Mozilla/5.0 (X11; Linux x86_64; rv:52.0) Gecko/20100101 Thunderbird/52.9.1 MIME-Version: 1.0 In-Reply-To: Content-Type: text/plain; charset=us-ascii Content-Transfer-Encoding: 7bit X-SW-Source: 2018-09/txt/msg01461.txt.bz2 On 24/09/18 10:22, Matthew Malcomson wrote: > A few places in the arm and aarch64 backends check whether an atomic > operation needs acquire or release semantics. > This is generally done with a check like > > (is_mm_relaxed (model) > || is_mm_consume (model) > || is_mm_release (model)) > > In this patch we introduce two helper functions to make things a little > tidier. > > There are a few places in the arm/ backend that check whether an > operation needs memory model semantics with an idiom that can now be > replaced with the new aarch_mm_needs_* functions, so we make that > replacement. > > There is also some backslash removal to make things a little tidier. > > Full bootstrap and regression test plus cross-compilation regression tests done on arm-none-linux-gnueabihf. > Ok for trunk? > > gcc/ChangeLog: > > 2018-09-24 Matthew Malcomson > > * config/arm/arm.c (arm_split_compare_and_swap, arm_split_atomic_op): > Use new helper functions. > * config/arm/sync.md (atomic_load, atomic_store): > Use new helper functions. > * config/arm/aarch-common-protos.h (aarch_mm_needs_acquire, > aarch_mm_needs_release): New declarations. > * config/arm/aarch-common.c (aarch_mm_needs_acquire, > aarch_mm_needs_release): New. > OK R. > > ############### Attachment also inlined for ease of reply ############### > > > diff --git a/gcc/config/arm/aarch-common-protos.h b/gcc/config/arm/aarch-common-protos.h > index 6204482bbb91fc64dbe37f892559d02a6cdf42da..b9a9b0438f6dddb7468e2b3581dcd3202b85b898 100644 > --- a/gcc/config/arm/aarch-common-protos.h > +++ b/gcc/config/arm/aarch-common-protos.h > @@ -28,6 +28,8 @@ extern int aarch_crypto_can_dual_issue (rtx_insn *, rtx_insn *); > extern bool aarch_rev16_p (rtx); > extern bool aarch_rev16_shleft_mask_imm_p (rtx, machine_mode); > extern bool aarch_rev16_shright_mask_imm_p (rtx, machine_mode); > +extern bool aarch_mm_needs_acquire (rtx); > +extern bool aarch_mm_needs_release (rtx); > extern int arm_early_load_addr_dep (rtx, rtx); > extern int arm_early_load_addr_dep_ptr (rtx, rtx); > extern int arm_early_store_addr_dep (rtx, rtx); > diff --git a/gcc/config/arm/aarch-common.c b/gcc/config/arm/aarch-common.c > index f0675a339f9a1c20ed7206de10359e4798e48ec5..14eb49575480c392a4d872da9ea92633f6f8ca8f 100644 > --- a/gcc/config/arm/aarch-common.c > +++ b/gcc/config/arm/aarch-common.c > @@ -29,6 +29,7 @@ > #include "tm.h" > #include "rtl.h" > #include "rtl-iter.h" > +#include "memmodel.h" > > /* In ARMv8-A there's a general expectation that AESE/AESMC > and AESD/AESIMC sequences of the form: > @@ -230,6 +231,28 @@ aarch_rev16_p (rtx x) > return is_rev; > } > > +/* Return non-zero if the RTX representing a memory model is a memory model > + that needs acquire semantics. */ > +bool > +aarch_mm_needs_acquire (rtx const_int) > +{ > + enum memmodel model = memmodel_from_int (INTVAL (const_int)); > + return !(is_mm_relaxed (model) > + || is_mm_consume (model) > + || is_mm_release (model)); > +} > + > +/* Return non-zero if the RTX representing a memory model is a memory model > + that needs release semantics. */ > +bool > +aarch_mm_needs_release (rtx const_int) > +{ > + enum memmodel model = memmodel_from_int (INTVAL (const_int)); > + return !(is_mm_relaxed (model) > + || is_mm_consume (model) > + || is_mm_acquire (model)); > +} > + > /* Return nonzero if the CONSUMER instruction (a load) does need > PRODUCER's value to calculate the address. */ > int > diff --git a/gcc/config/arm/arm.c b/gcc/config/arm/arm.c > index 6332e68df0506bb980cf55e05e7293b4a44d1e91..c7e6bf7f13467893c409d031a17a86594a2d160b 100644 > --- a/gcc/config/arm/arm.c > +++ b/gcc/config/arm/arm.c > @@ -28626,7 +28626,7 @@ arm_expand_compare_and_swap (rtx operands[]) > void > arm_split_compare_and_swap (rtx operands[]) > { > - rtx rval, mem, oldval, newval, neg_bval; > + rtx rval, mem, oldval, newval, neg_bval, mod_s_rtx; > machine_mode mode; > enum memmodel mod_s, mod_f; > bool is_weak; > @@ -28638,20 +28638,16 @@ arm_split_compare_and_swap (rtx operands[]) > oldval = operands[3]; > newval = operands[4]; > is_weak = (operands[5] != const0_rtx); > - mod_s = memmodel_from_int (INTVAL (operands[6])); > + mod_s_rtx = operands[6]; > + mod_s = memmodel_from_int (INTVAL (mod_s_rtx)); > mod_f = memmodel_from_int (INTVAL (operands[7])); > neg_bval = TARGET_THUMB1 ? operands[0] : operands[8]; > mode = GET_MODE (mem); > > bool is_armv8_sync = arm_arch8 && is_mm_sync (mod_s); > > - bool use_acquire = TARGET_HAVE_LDACQ > - && !(is_mm_relaxed (mod_s) || is_mm_consume (mod_s) > - || is_mm_release (mod_s)); > - > - bool use_release = TARGET_HAVE_LDACQ > - && !(is_mm_relaxed (mod_s) || is_mm_consume (mod_s) > - || is_mm_acquire (mod_s)); > + bool use_acquire = TARGET_HAVE_LDACQ && aarch_mm_needs_acquire (mod_s_rtx); > + bool use_release = TARGET_HAVE_LDACQ && aarch_mm_needs_release (mod_s_rtx); > > /* For ARMv8, the load-acquire is too weak for __sync memory orders. Instead, > a full barrier is emitted after the store-release. */ > @@ -28746,13 +28742,8 @@ arm_split_atomic_op (enum rtx_code code, rtx old_out, rtx new_out, rtx mem, > > bool is_armv8_sync = arm_arch8 && is_mm_sync (model); > > - bool use_acquire = TARGET_HAVE_LDACQ > - && !(is_mm_relaxed (model) || is_mm_consume (model) > - || is_mm_release (model)); > - > - bool use_release = TARGET_HAVE_LDACQ > - && !(is_mm_relaxed (model) || is_mm_consume (model) > - || is_mm_acquire (model)); > + bool use_acquire = TARGET_HAVE_LDACQ && aarch_mm_needs_acquire (model_rtx); > + bool use_release = TARGET_HAVE_LDACQ && aarch_mm_needs_release (model_rtx); > > /* For ARMv8, a load-acquire is too weak for __sync memory orders. Instead, > a full barrier is emitted after the store-release. */ > diff --git a/gcc/config/arm/sync.md b/gcc/config/arm/sync.md > index 7141c76bef511e7869e7e6c1d1bc00674c67c3d0..08fc5d1a8ab4a07cd8aa2f3c9826af8e3326f9b1 100644 > --- a/gcc/config/arm/sync.md > +++ b/gcc/config/arm/sync.md > @@ -70,20 +70,19 @@ > VUNSPEC_LDA))] > "TARGET_HAVE_LDACQ" > { > - enum memmodel model = memmodel_from_int (INTVAL (operands[2])); > - if (is_mm_relaxed (model) || is_mm_consume (model) || is_mm_release (model)) > + if (aarch_mm_needs_acquire (operands[2])) > { > if (TARGET_THUMB1) > - return \"ldr\\t%0, %1\"; > + return "lda\t%0, %1"; > else > - return \"ldr%?\\t%0, %1\"; > + return "lda%?\t%0, %1"; > } > else > { > if (TARGET_THUMB1) > - return \"lda\\t%0, %1\"; > + return "ldr\t%0, %1"; > else > - return \"lda%?\\t%0, %1\"; > + return "ldr%?\t%0, %1"; > } > } > [(set_attr "arch" "32,v8mb,any") > @@ -97,20 +96,19 @@ > VUNSPEC_STL))] > "TARGET_HAVE_LDACQ" > { > - enum memmodel model = memmodel_from_int (INTVAL (operands[2])); > - if (is_mm_relaxed (model) || is_mm_consume (model) || is_mm_acquire (model)) > + if (aarch_mm_needs_release (operands[2])) > { > if (TARGET_THUMB1) > - return \"str\t%1, %0\"; > + return "stl\t%1, %0"; > else > - return \"str%?\t%1, %0\"; > + return "stl%?\t%1, %0"; > } > else > { > if (TARGET_THUMB1) > - return \"stl\t%1, %0\"; > + return "str\t%1, %0"; > else > - return \"stl%?\t%1, %0\"; > + return "str%?\t%1, %0"; > } > } > [(set_attr "arch" "32,v8mb,any") > > > helper-functions.patch > > > diff --git a/gcc/config/arm/aarch-common-protos.h b/gcc/config/arm/aarch-common-protos.h > index 6204482bbb91fc64dbe37f892559d02a6cdf42da..b9a9b0438f6dddb7468e2b3581dcd3202b85b898 100644 > --- a/gcc/config/arm/aarch-common-protos.h > +++ b/gcc/config/arm/aarch-common-protos.h > @@ -28,6 +28,8 @@ extern int aarch_crypto_can_dual_issue (rtx_insn *, rtx_insn *); > extern bool aarch_rev16_p (rtx); > extern bool aarch_rev16_shleft_mask_imm_p (rtx, machine_mode); > extern bool aarch_rev16_shright_mask_imm_p (rtx, machine_mode); > +extern bool aarch_mm_needs_acquire (rtx); > +extern bool aarch_mm_needs_release (rtx); > extern int arm_early_load_addr_dep (rtx, rtx); > extern int arm_early_load_addr_dep_ptr (rtx, rtx); > extern int arm_early_store_addr_dep (rtx, rtx); > diff --git a/gcc/config/arm/aarch-common.c b/gcc/config/arm/aarch-common.c > index f0675a339f9a1c20ed7206de10359e4798e48ec5..14eb49575480c392a4d872da9ea92633f6f8ca8f 100644 > --- a/gcc/config/arm/aarch-common.c > +++ b/gcc/config/arm/aarch-common.c > @@ -29,6 +29,7 @@ > #include "tm.h" > #include "rtl.h" > #include "rtl-iter.h" > +#include "memmodel.h" > > /* In ARMv8-A there's a general expectation that AESE/AESMC > and AESD/AESIMC sequences of the form: > @@ -230,6 +231,28 @@ aarch_rev16_p (rtx x) > return is_rev; > } > > +/* Return non-zero if the RTX representing a memory model is a memory model > + that needs acquire semantics. */ > +bool > +aarch_mm_needs_acquire (rtx const_int) > +{ > + enum memmodel model = memmodel_from_int (INTVAL (const_int)); > + return !(is_mm_relaxed (model) > + || is_mm_consume (model) > + || is_mm_release (model)); > +} > + > +/* Return non-zero if the RTX representing a memory model is a memory model > + that needs release semantics. */ > +bool > +aarch_mm_needs_release (rtx const_int) > +{ > + enum memmodel model = memmodel_from_int (INTVAL (const_int)); > + return !(is_mm_relaxed (model) > + || is_mm_consume (model) > + || is_mm_acquire (model)); > +} > + > /* Return nonzero if the CONSUMER instruction (a load) does need > PRODUCER's value to calculate the address. */ > int > diff --git a/gcc/config/arm/arm.c b/gcc/config/arm/arm.c > index 6332e68df0506bb980cf55e05e7293b4a44d1e91..c7e6bf7f13467893c409d031a17a86594a2d160b 100644 > --- a/gcc/config/arm/arm.c > +++ b/gcc/config/arm/arm.c > @@ -28626,7 +28626,7 @@ arm_expand_compare_and_swap (rtx operands[]) > void > arm_split_compare_and_swap (rtx operands[]) > { > - rtx rval, mem, oldval, newval, neg_bval; > + rtx rval, mem, oldval, newval, neg_bval, mod_s_rtx; > machine_mode mode; > enum memmodel mod_s, mod_f; > bool is_weak; > @@ -28638,20 +28638,16 @@ arm_split_compare_and_swap (rtx operands[]) > oldval = operands[3]; > newval = operands[4]; > is_weak = (operands[5] != const0_rtx); > - mod_s = memmodel_from_int (INTVAL (operands[6])); > + mod_s_rtx = operands[6]; > + mod_s = memmodel_from_int (INTVAL (mod_s_rtx)); > mod_f = memmodel_from_int (INTVAL (operands[7])); > neg_bval = TARGET_THUMB1 ? operands[0] : operands[8]; > mode = GET_MODE (mem); > > bool is_armv8_sync = arm_arch8 && is_mm_sync (mod_s); > > - bool use_acquire = TARGET_HAVE_LDACQ > - && !(is_mm_relaxed (mod_s) || is_mm_consume (mod_s) > - || is_mm_release (mod_s)); > - > - bool use_release = TARGET_HAVE_LDACQ > - && !(is_mm_relaxed (mod_s) || is_mm_consume (mod_s) > - || is_mm_acquire (mod_s)); > + bool use_acquire = TARGET_HAVE_LDACQ && aarch_mm_needs_acquire (mod_s_rtx); > + bool use_release = TARGET_HAVE_LDACQ && aarch_mm_needs_release (mod_s_rtx); > > /* For ARMv8, the load-acquire is too weak for __sync memory orders. Instead, > a full barrier is emitted after the store-release. */ > @@ -28746,13 +28742,8 @@ arm_split_atomic_op (enum rtx_code code, rtx old_out, rtx new_out, rtx mem, > > bool is_armv8_sync = arm_arch8 && is_mm_sync (model); > > - bool use_acquire = TARGET_HAVE_LDACQ > - && !(is_mm_relaxed (model) || is_mm_consume (model) > - || is_mm_release (model)); > - > - bool use_release = TARGET_HAVE_LDACQ > - && !(is_mm_relaxed (model) || is_mm_consume (model) > - || is_mm_acquire (model)); > + bool use_acquire = TARGET_HAVE_LDACQ && aarch_mm_needs_acquire (model_rtx); > + bool use_release = TARGET_HAVE_LDACQ && aarch_mm_needs_release (model_rtx); > > /* For ARMv8, a load-acquire is too weak for __sync memory orders. Instead, > a full barrier is emitted after the store-release. */ > diff --git a/gcc/config/arm/sync.md b/gcc/config/arm/sync.md > index 7141c76bef511e7869e7e6c1d1bc00674c67c3d0..08fc5d1a8ab4a07cd8aa2f3c9826af8e3326f9b1 100644 > --- a/gcc/config/arm/sync.md > +++ b/gcc/config/arm/sync.md > @@ -70,20 +70,19 @@ > VUNSPEC_LDA))] > "TARGET_HAVE_LDACQ" > { > - enum memmodel model = memmodel_from_int (INTVAL (operands[2])); > - if (is_mm_relaxed (model) || is_mm_consume (model) || is_mm_release (model)) > + if (aarch_mm_needs_acquire (operands[2])) > { > if (TARGET_THUMB1) > - return \"ldr\\t%0, %1\"; > + return "lda\t%0, %1"; > else > - return \"ldr%?\\t%0, %1\"; > + return "lda%?\t%0, %1"; > } > else > { > if (TARGET_THUMB1) > - return \"lda\\t%0, %1\"; > + return "ldr\t%0, %1"; > else > - return \"lda%?\\t%0, %1\"; > + return "ldr%?\t%0, %1"; > } > } > [(set_attr "arch" "32,v8mb,any") > @@ -97,20 +96,19 @@ > VUNSPEC_STL))] > "TARGET_HAVE_LDACQ" > { > - enum memmodel model = memmodel_from_int (INTVAL (operands[2])); > - if (is_mm_relaxed (model) || is_mm_consume (model) || is_mm_acquire (model)) > + if (aarch_mm_needs_release (operands[2])) > { > if (TARGET_THUMB1) > - return \"str\t%1, %0\"; > + return "stl\t%1, %0"; > else > - return \"str%?\t%1, %0\"; > + return "stl%?\t%1, %0"; > } > else > { > if (TARGET_THUMB1) > - return \"stl\t%1, %0\"; > + return "str\t%1, %0"; > else > - return \"stl%?\t%1, %0\"; > + return "str%?\t%1, %0"; > } > } > [(set_attr "arch" "32,v8mb,any") >