aboutsummaryrefslogtreecommitdiff
diff options
context:
space:
mode:
authorXi Ruoyao <xry111@xry111.site>2025-03-01 11:46:45 +0800
committerLulu Cheng <chenglulu@loongson.cn>2025-08-18 09:09:34 +0800
commit9b55cd0405609474aab6fdd0c621fd738af5800a (patch)
tree67c26625e1dbdcf20eed2225a54bbe036e48dce8
parent91f00a75536a553b5f95ea80694d655c5ddf34af (diff)
downloadgcc-9b55cd0405609474aab6fdd0c621fd738af5800a.zip
gcc-9b55cd0405609474aab6fdd0c621fd738af5800a.tar.gz
gcc-9b55cd0405609474aab6fdd0c621fd738af5800a.tar.bz2
LoongArch: Don't emit overly-restrictive barrier for LL-SC loops
For LL-SC loops, if the atomic operation has succeeded, the SC instruction always imply a full barrier, so the barrier we manually inserted only needs to take the account for the failure memorder, not the success memorder (the barrier is skipped with "b 3f" on success anyway). Note that if we use the AMCAS instructions, we indeed need to consider both the success memorder an the failure memorder deciding if "_db" suffix is needed. Thus the semantics of atomic_cas_value_strong<mode> and atomic_cas_value_strong<mode>_amcas start to be different. To prevent the compiler from being too clever, use a different unspec code for AMCAS instructions. gcc/ChangeLog: * config/loongarch/sync.md (UNSPEC_COMPARE_AND_SWAP_AMCAS): New UNSPEC code. (atomic_cas_value_strong<mode>): NFC, update the comment to note we only need to consider failure memory order. (atomic_cas_value_strong<mode>_amcas): Use UNSPEC_COMPARE_AND_SWAP_AMCAS instead of UNSPEC_COMPARE_AND_SWAP. (atomic_compare_and_swap<mode:GPR>): Pass failure memorder to gen_atomic_cas_value_strong<mode>. (atomic_compare_and_swap<mode:SHORT>): Pass failure memorder to gen_atomic_cas_value_cmp_and_7_si.
-rw-r--r--gcc/config/loongarch/sync.md21
1 files changed, 9 insertions, 12 deletions
diff --git a/gcc/config/loongarch/sync.md b/gcc/config/loongarch/sync.md
index 01346a7..5f894e5 100644
--- a/gcc/config/loongarch/sync.md
+++ b/gcc/config/loongarch/sync.md
@@ -21,6 +21,7 @@
(define_c_enum "unspec" [
UNSPEC_COMPARE_AND_SWAP
+ UNSPEC_COMPARE_AND_SWAP_AMCAS
UNSPEC_COMPARE_AND_SWAP_ADD
UNSPEC_COMPARE_AND_SWAP_SUB
UNSPEC_COMPARE_AND_SWAP_AND
@@ -235,7 +236,7 @@
(set (match_dup 1)
(unspec_volatile:GPR [(match_operand:GPR 2 "reg_or_0_operand" "rJ")
(match_operand:GPR 3 "reg_or_0_operand" "rJ")
- (match_operand:SI 4 "const_int_operand")] ;; mod_s
+ (match_operand:SI 4 "const_int_operand")] ;; mod_f
UNSPEC_COMPARE_AND_SWAP))
(clobber (match_scratch:GPR 5 "=&r"))]
""
@@ -283,8 +284,8 @@
(set (match_dup 1)
(unspec_volatile:QHWD [(match_operand:QHWD 2 "reg_or_0_operand" "rJ")
(match_operand:QHWD 3 "reg_or_0_operand" "rJ")
- (match_operand:SI 4 "const_int_operand")] ;; mod_s
- UNSPEC_COMPARE_AND_SWAP))]
+ (match_operand:SI 4 "const_int_operand")] ;; mod
+ UNSPEC_COMPARE_AND_SWAP_AMCAS))]
"ISA_HAS_LAMCAS"
"ori\t%0,%z2,0\n\tamcas%A4.<size>\t%0,%z3,%1"
[(set (attr "length") (const_int 8))])
@@ -313,16 +314,14 @@
&& is_mm_release (memmodel_base (INTVAL (mod_s))))
mod_s = GEN_INT (MEMMODEL_ACQ_REL);
- operands[6] = mod_s;
-
if (ISA_HAS_LAMCAS)
emit_insn (gen_atomic_cas_value_strong<mode>_amcas (operands[1], operands[2],
operands[3], operands[4],
- operands[6]));
+ mod_s));
else
emit_insn (gen_atomic_cas_value_strong<mode> (operands[1], operands[2],
operands[3], operands[4],
- operands[6]));
+ mod_f));
rtx compare = operands[1];
if (operands[3] != const0_rtx)
@@ -396,7 +395,7 @@
(match_operand:GPR 3 "reg_or_0_operand" "rJ")
(match_operand:GPR 4 "reg_or_0_operand" "rJ")
(match_operand:GPR 5 "reg_or_0_operand" "rJ")
- (match_operand:SI 6 "const_int_operand")] ;; model
+ (match_operand:SI 6 "const_int_operand")] ;; mod_f
UNSPEC_COMPARE_AND_SWAP))
(clobber (match_scratch:GPR 7 "=&r"))]
""
@@ -440,18 +439,16 @@
&& is_mm_release (memmodel_base (INTVAL (mod_s))))
mod_s = GEN_INT (MEMMODEL_ACQ_REL);
- operands[6] = mod_s;
-
if (ISA_HAS_LAMCAS)
emit_insn (gen_atomic_cas_value_strong<mode>_amcas (operands[1], operands[2],
operands[3], operands[4],
- operands[6]));
+ mod_s));
else
{
union loongarch_gen_fn_ptrs generator;
generator.fn_7 = gen_atomic_cas_value_cmp_and_7_si;
loongarch_expand_atomic_qihi (generator, operands[1], operands[2],
- operands[3], operands[4], operands[6]);
+ operands[3], operands[4], mod_f);
}
rtx compare = operands[1];