summaryrefslogtreecommitdiff
diff options
context:
space:
mode:
authorBen Gamari <ben@smart-cactus.org>2022-11-08 11:43:04 -0500
committerBen Gamari <ben@smart-cactus.org>2022-12-05 18:43:00 -0500
commit699bf77a1296587dba379052701512952bc25a07 (patch)
tree5708ac3cdab437bbc716978d8dbbd1b275b43bd1
parent251f8c9974325e5d7747f04f569c8cbfdd73ee79 (diff)
downloadhaskell-699bf77a1296587dba379052701512952bc25a07.tar.gz
cmm/Parser: Atomic load syntax
Originally I had thought I would just use the `prim` call syntax instead of introducing new syntax for atomic loads. However, it turns out that `prim` call syntax tends to make things quite unreadable. This new syntax seems quite natural.
-rw-r--r--compiler/GHC/Cmm/Parser.y26
1 files changed, 23 insertions, 3 deletions
diff --git a/compiler/GHC/Cmm/Parser.y b/compiler/GHC/Cmm/Parser.y
index 480a3436c1..dbb2e47030 100644
--- a/compiler/GHC/Cmm/Parser.y
+++ b/compiler/GHC/Cmm/Parser.y
@@ -205,9 +205,16 @@ memory ordering guarantees. These are supported in Cmm syntax as follows:
%relaxed W_[ptr] = ...; // an atomic store with relaxed ordering semantics
%release W_[ptr] = ...; // an atomic store with release ordering semantics
- x = W_(ptr); // a non-atomic load
- (x) = prim %load_relaxed64(ptr); // a 64-bit atomic load with relaxed ordering
- (x) = prim %load_acquire64(ptr); // a 64-bit atomic load with acquire ordering
+ x = W_(ptr); // a non-atomic load
+ x = %relaxed W_[ptr]; // an atomic load with relaxed ordering
+ x = %acquire W_[ptr]; // an atomic load with acquire ordering
+ // or equivalently...
+ x = prim %load_acquire64(ptr);
+
+Here we used W_ as an example but these operations can be used on all Cmm
+types.
+
+See Note [Heap memory barriers] in SMP.h for details.
----------------------------------------------------------------------------- -}
@@ -645,6 +652,19 @@ stmt :: { CmmParse () }
| lreg '=' expr ';'
{ do reg <- $1; e <- $3; withSourceNote $2 $4 (emitAssign reg e) }
+
+ -- Use lreg instead of local_reg to avoid ambiguity
+ | lreg '=' mem_ordering type '[' expr ']' ';'
+ { do reg <- $1;
+ let lreg = case reg of
+ { CmmLocal r -> r
+ ; other -> pprPanic "CmmParse:" (ppr reg <> text "not a local register")
+ } ;
+ mord <- $3;
+ let { ty = $4; w = typeWidth ty };
+ e <- $6;
+ let op = MO_AtomicRead w mord;
+ withSourceNote $2 $7 $ code (emitPrimCall [lreg] op [e]) }
| mem_ordering type '[' expr ']' '=' expr ';'
{ do mord <- $1; withSourceNote $3 $8 (doStore (Just mord) $2 $4 $7) }
| type '[' expr ']' '=' expr ';'