* [PATCH][GCC][ARM] New helper functions to check atomicity requirements
@ 2018-09-24 9:58 Matthew Malcomson
2018-09-25 16:43 ` Richard Earnshaw (lists)
0 siblings, 1 reply; 2+ messages in thread
From: Matthew Malcomson @ 2018-09-24 9:58 UTC (permalink / raw)
To: gcc-patches
Cc: Kyrylo.Tkachov, Richard.Earnshaw, nickc, nd, Ramana.Radhakrishnan
[-- Attachment #1: Type: text/plain, Size: 7312 bytes --]
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 <matthew.malcomson@arm.com>
* config/arm/arm.c (arm_split_compare_and_swap, arm_split_atomic_op):
Use new helper functions.
* config/arm/sync.md (atomic_load<mode>, atomic_store<mode>):
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.
############### 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<sync_sfx>\\t%0, %1\";
+ return "lda<sync_sfx>\t%0, %1";
else
- return \"ldr<sync_sfx>%?\\t%0, %1\";
+ return "lda<sync_sfx>%?\t%0, %1";
}
else
{
if (TARGET_THUMB1)
- return \"lda<sync_sfx>\\t%0, %1\";
+ return "ldr<sync_sfx>\t%0, %1";
else
- return \"lda<sync_sfx>%?\\t%0, %1\";
+ return "ldr<sync_sfx>%?\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<sync_sfx>\t%1, %0\";
+ return "stl<sync_sfx>\t%1, %0";
else
- return \"str<sync_sfx>%?\t%1, %0\";
+ return "stl<sync_sfx>%?\t%1, %0";
}
else
{
if (TARGET_THUMB1)
- return \"stl<sync_sfx>\t%1, %0\";
+ return "str<sync_sfx>\t%1, %0";
else
- return \"stl<sync_sfx>%?\t%1, %0\";
+ return "str<sync_sfx>%?\t%1, %0";
}
}
[(set_attr "arch" "32,v8mb,any")
[-- Attachment #2: helper-functions.patch --]
[-- Type: text/plain, Size: 6048 bytes --]
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<sync_sfx>\\t%0, %1\";
+ return "lda<sync_sfx>\t%0, %1";
else
- return \"ldr<sync_sfx>%?\\t%0, %1\";
+ return "lda<sync_sfx>%?\t%0, %1";
}
else
{
if (TARGET_THUMB1)
- return \"lda<sync_sfx>\\t%0, %1\";
+ return "ldr<sync_sfx>\t%0, %1";
else
- return \"lda<sync_sfx>%?\\t%0, %1\";
+ return "ldr<sync_sfx>%?\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<sync_sfx>\t%1, %0\";
+ return "stl<sync_sfx>\t%1, %0";
else
- return \"str<sync_sfx>%?\t%1, %0\";
+ return "stl<sync_sfx>%?\t%1, %0";
}
else
{
if (TARGET_THUMB1)
- return \"stl<sync_sfx>\t%1, %0\";
+ return "str<sync_sfx>\t%1, %0";
else
- return \"stl<sync_sfx>%?\t%1, %0\";
+ return "str<sync_sfx>%?\t%1, %0";
}
}
[(set_attr "arch" "32,v8mb,any")
^ permalink raw reply [flat|nested] 2+ messages in thread
* Re: [PATCH][GCC][ARM] New helper functions to check atomicity requirements
2018-09-24 9:58 [PATCH][GCC][ARM] New helper functions to check atomicity requirements Matthew Malcomson
@ 2018-09-25 16:43 ` Richard Earnshaw (lists)
0 siblings, 0 replies; 2+ messages in thread
From: Richard Earnshaw (lists) @ 2018-09-25 16:43 UTC (permalink / raw)
To: Matthew Malcomson, gcc-patches
Cc: Kyrylo.Tkachov, nickc, nd, Ramana.Radhakrishnan
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 <matthew.malcomson@arm.com>
>
> * config/arm/arm.c (arm_split_compare_and_swap, arm_split_atomic_op):
> Use new helper functions.
> * config/arm/sync.md (atomic_load<mode>, atomic_store<mode>):
> 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<sync_sfx>\\t%0, %1\";
> + return "lda<sync_sfx>\t%0, %1";
> else
> - return \"ldr<sync_sfx>%?\\t%0, %1\";
> + return "lda<sync_sfx>%?\t%0, %1";
> }
> else
> {
> if (TARGET_THUMB1)
> - return \"lda<sync_sfx>\\t%0, %1\";
> + return "ldr<sync_sfx>\t%0, %1";
> else
> - return \"lda<sync_sfx>%?\\t%0, %1\";
> + return "ldr<sync_sfx>%?\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<sync_sfx>\t%1, %0\";
> + return "stl<sync_sfx>\t%1, %0";
> else
> - return \"str<sync_sfx>%?\t%1, %0\";
> + return "stl<sync_sfx>%?\t%1, %0";
> }
> else
> {
> if (TARGET_THUMB1)
> - return \"stl<sync_sfx>\t%1, %0\";
> + return "str<sync_sfx>\t%1, %0";
> else
> - return \"stl<sync_sfx>%?\t%1, %0\";
> + return "str<sync_sfx>%?\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<sync_sfx>\\t%0, %1\";
> + return "lda<sync_sfx>\t%0, %1";
> else
> - return \"ldr<sync_sfx>%?\\t%0, %1\";
> + return "lda<sync_sfx>%?\t%0, %1";
> }
> else
> {
> if (TARGET_THUMB1)
> - return \"lda<sync_sfx>\\t%0, %1\";
> + return "ldr<sync_sfx>\t%0, %1";
> else
> - return \"lda<sync_sfx>%?\\t%0, %1\";
> + return "ldr<sync_sfx>%?\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<sync_sfx>\t%1, %0\";
> + return "stl<sync_sfx>\t%1, %0";
> else
> - return \"str<sync_sfx>%?\t%1, %0\";
> + return "stl<sync_sfx>%?\t%1, %0";
> }
> else
> {
> if (TARGET_THUMB1)
> - return \"stl<sync_sfx>\t%1, %0\";
> + return "str<sync_sfx>\t%1, %0";
> else
> - return \"stl<sync_sfx>%?\t%1, %0\";
> + return "str<sync_sfx>%?\t%1, %0";
> }
> }
> [(set_attr "arch" "32,v8mb,any")
>
^ permalink raw reply [flat|nested] 2+ messages in thread
end of thread, other threads:[~2018-09-25 16:13 UTC | newest]
Thread overview: 2+ messages (download: mbox.gz / follow: Atom feed)
-- links below jump to the message on this page --
2018-09-24 9:58 [PATCH][GCC][ARM] New helper functions to check atomicity requirements Matthew Malcomson
2018-09-25 16:43 ` Richard Earnshaw (lists)
This is a public inbox, see mirroring instructions
for how to clone and mirror all data and code used for this inbox;
as well as URLs for read-only IMAP folder(s) and NNTP newsgroup(s).