diff options
author | Ben Gamari <ben@smart-cactus.org> | 2022-11-08 11:43:04 -0500 |
---|---|---|
committer | Matthew Pickering <matthewtpickering@gmail.com> | 2022-12-15 09:50:46 +0000 |
commit | 32497a141fd1415c166451730bb5adc7b16882b3 (patch) | |
tree | b6c445af053db046a7d2e16345dfca17b7c9ef85 | |
parent | 3208e037b5723a7d52c2054cb563abfc1a8aa373 (diff) | |
download | haskell-32497a141fd1415c166451730bb5adc7b16882b3.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.
(cherry picked from commit 748490d2ff51d6c6fa44aad587908b271c801fa9)
-rw-r--r-- | compiler/GHC/Cmm/Parser.y | 26 |
1 files changed, 23 insertions, 3 deletions
diff --git a/compiler/GHC/Cmm/Parser.y b/compiler/GHC/Cmm/Parser.y index 6288393d3a..afced69a72 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. ----------------------------------------------------------------------------- -} @@ -650,6 +657,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 ';' |