diff options
author | Ben Gamari <ben@smart-cactus.org> | 2022-11-08 11:43:04 -0500 |
---|---|---|
committer | Ben Gamari <ben@smart-cactus.org> | 2022-12-05 18:43:00 -0500 |
commit | 699bf77a1296587dba379052701512952bc25a07 (patch) | |
tree | 5708ac3cdab437bbc716978d8dbbd1b275b43bd1 | |
parent | 251f8c9974325e5d7747f04f569c8cbfdd73ee79 (diff) | |
download | haskell-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.y | 26 |
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 ';' |