GHC issueshttps://gitlab.haskell.org/ghc/ghc/-/issues2024-03-20T09:18:31Zhttps://gitlab.haskell.org/ghc/ghc/-/issues/24539Improve memory efficiency of `UnlinkedBCO`2024-03-20T09:18:31ZHannes SiebenhandlImprove memory efficiency of `UnlinkedBCO`There are quite a number of `UnlinkedBCO`s alive during a GHCi session. For example, loading agda into GHCi, there are around `360050` instances of `UnlinkedBCO`.
Currently `UnlinkedBCO` is defined like this:
```haskell
data UnlinkedBC...There are quite a number of `UnlinkedBCO`s alive during a GHCi session. For example, loading agda into GHCi, there are around `360050` instances of `UnlinkedBCO`.
Currently `UnlinkedBCO` is defined like this:
```haskell
data UnlinkedBCO
= UnlinkedBCO {
unlinkedBCOName :: !Name,
unlinkedBCOArity :: {-# UNPACK #-} !Int,
unlinkedBCOInstrs :: !(UArray Int Word16), -- insns
unlinkedBCOBitmap :: !(UArray Int Word64), -- bitmap
unlinkedBCOLits :: !(SizedSeq BCONPtr), -- non-ptrs
unlinkedBCOPtrs :: !(SizedSeq BCOPtr) -- ptrs
}
```
Saving a couple of Words per `UnlinkedBCO` can quickly accumulate to tens of megabytes.
This issue discusses two improvements that are relatively non-invasive.
### Unpack `UArray Int`
The PR !12142 implements this improvement
The `UArray` of `unlinkedBCOInstrs` and `unlinkedBCOBitmap` is never used, only its packing of `Word16`'s and `Word64`'s is required.
Thus, we can replace `UArray Int Word*` with a wrapper around the underlying `ByteArray#` allowing us to save 6 Ints per `UnlinkedBCO`.
In the example of agda, this saves us roughly `360050 * 6 Ints ~= 17282400 ~ 17MB`. I am unsure whether an `UnliftedNewtype` removes even one more indirection, which would reduce the memory `7MB`.
### Flatten `SizedSeq`
The PR !12170 implements this improvement.
`SizedSeq a` is a simple wrapper around `[a]` that keeps track of the number of elements and supports efficient appending (by keeping the list in reverse).
However, as such, the size is only needed once, and the trivial case of `SizedSeq 0 []` isn't shared. To add insult to injury, lists are quite inefficient, and the `unlinkedBCOLits` and `unlinkedBCOPtrs` are only ever traversed and not filtered or iteratively consumed / constructed.
We show the size distributions of all `SizedSeq`'s, which we obtained using `ghc-debug` scripts:
```
# Length of SizedSeq
283147 0
198237 1
126478 2
69233 3
26596 4
5587 5
3903 6
2943 7
```
The majority of cases is the empty list, singleton and tuple, so this lack of sharing is noticeable. We cut off the end of the table, there are rarely larger lists. I am including the full list for completeness: [unlinkedbco-sseq](/uploads/301ae49a1a2bb3d20e528a6d1b7f0a9d/unlinkedbco-sseq)
Note, not all `SizedSeq`'s are utilised by `UnlinkedBCO`, but most of them:
```
ghc-9.9-inplace:GHC.ByteCode.Types:UnlinkedBCO[ghc-9.9-inplace:GHC.Types.Name:Name,ARR_WORDS,ARR_WORDS,ghc-boot-9.9-inplace:GHC.Data.SizedSeq:SizedSeq,ghc-boot-9.9-inplace:GHC.Data.SizedSeq:SizedSeq]:25923600:360050:72:72.0
ghc-boot-9.9-inplace:GHC.Data.SizedSeq:SizedSeq[ghc-prim:GHC.Types::]:17478120:436953:40:40.0
ghc-boot-9.9-inplace:GHC.Data.SizedSeq:SizedSeq[ghc-prim:GHC.Types:[]]:11325920:283148:40:40.0
```
This says that there are `436953 + 283148 = 720101` SizedSeqs, and `360050 * 2 = 720100` are retained by `UnlinkedBCO`.
Thus, we propose to introduce a new data type that is specialised for this payload, called `FlatBag` which efficiently stores elements and where the empty case can be shared.Hannes SiebenhandlHannes Siebenhandlhttps://gitlab.haskell.org/ghc/ghc/-/issues/24538Windows binary distributions ship with empty package database2024-03-19T19:22:46ZBen GamariWindows binary distributions ship with empty package databaseThe `ghcup` validation job for my most recent 9.10.1-alpha1 candidate (https://gitlab.haskell.org/ghc/ghcup-ci/-/jobs/1807133) reveals that Windows binary distributions are unserviceable, failing to find any of the boot packages during c...The `ghcup` validation job for my most recent 9.10.1-alpha1 candidate (https://gitlab.haskell.org/ghc/ghcup-ci/-/jobs/1807133) reveals that Windows binary distributions are unserviceable, failing to find any of the boot packages during compilation due to all of the package registration files being empty:
```
Unpacking to acme-box-0.0.0.0\
+ cd acme-box-0.0.0.0/
+ ghc Setup.hs
[1 of 2] Compiling Main ( Setup.hs, Setup.o )
Setup.hs:1:1: error: [GHC-87110]
Could not find module `Prelude'.
Use -v to see a list of the files searched for.
|
1 | import Distribution.Simple
| ^
Setup.hs:1:1: error: [GHC-87110]
Could not find module `Distribution.Simple'.
Use -v to see a list of the files searched for.
|
1 | import Distribution.Simple
| ^^^^^^^^^^^^^^^^^^^^^^^^^^
```Ben GamariBen Gamarihttps://gitlab.haskell.org/ghc/ghc/-/issues/24537template-haskell's RecordWildCards support2024-03-25T11:11:54ZLiam Goodacretemplate-haskell's RecordWildCards support## Summary
RecordWildCards syntax `Con {..}` doesn't appear to be represented in template-haskell.
Suppose we have a data type:
```hs
data G = H { field0 :: Int, field1 :: String }
deriving stock Show
```
Using `[e|H {..}|]` yields...## Summary
RecordWildCards syntax `Con {..}` doesn't appear to be represented in template-haskell.
Suppose we have a data type:
```hs
data G = H { field0 :: Int, field1 :: String }
deriving stock Show
```
Using `[e|H {..}|]` yields `RecConE Main.H []`.
But this is indistinguishable from `[e|H {}|]`.
However, using `H {}` in place of `H {..}` won't compile if `H` has fields.
## Expected behavior
Have `RecConE` support wildcards.
### (Solutionising)
Perhaps something like:
```hs
data RecWild = NoRecWildCard | RecWildCard
data Exp ...
| RecConE Name [FieldExp] RecWild
data Pat ...
| RecP Name [FieldPat] RecWild
```
Supporting both `H {..}` and `H {field1=42, ..}`.
Maybe `.Lib` could keep its existing `recConE` & `recP` but add `recConWildE` & `recWildP`? (if that's desirable)
```
recConE :: Quote m => Name -> [m (Name, Exp)] -> m Exp
recConE c fs = do { flds <- sequenceA fs; pure (RecConE c flds NoRecWildCard) }
recConWildE :: Quote m => Name -> [m (Name, Exp)] -> m Exp
recConWildE c fs = do { flds <- sequenceA fs; pure (RecConE c flds RecWildCard) }
```
## Environment
* GHC version used: 9.8.2 and below.https://gitlab.haskell.org/ghc/ghc/-/issues/24536`configure --disable-tables-next-to-code` + `default+debug_info` = linking er...2024-03-12T16:14:55Zdoyougnujmy6342@gmail.com`configure --disable-tables-next-to-code` + `default+debug_info` = linking errorsIf I run:
```
./boot
./configure --disable-tables-next-to-code
hadrian/build --flavour=default+debug_info
```
I get:
```
/tmp/ghc452698_0/ghc_3.s: Assembler messages:
/tmp/ghc452698_0/ghc_3.s:193:0: error:
Error: symbol `.Lck_end...If I run:
```
./boot
./configure --disable-tables-next-to-code
hadrian/build --flavour=default+debug_info
```
I get:
```
/tmp/ghc452698_0/ghc_3.s: Assembler messages:
/tmp/ghc452698_0/ghc_3.s:193:0: error:
Error: symbol `.Lck_end' is already defined
|
193 | .Lck_end:
| ^
/tmp/ghc452698_0/ghc_3.s:194:0: error:
Error: symbol `.Lck_proc_end' is already defined
|
194 | .Lck_proc_end:
| ^
`cc' failed in phase `Assembler'. (Exit code: 1)
Command failed
Build failed.
```
Whereas I expect a compiler with DWARF enabled and no tables next to code. Why does this matter? Because I was trying to re-assess the performance of TNTC and I want DWARF symbols so that in perf I can gen annotated assembly.
...or...is this just expected behavior?https://gitlab.haskell.org/ghc/ghc/-/issues/24534Allow foreign imports to return ST actions2024-03-12T15:14:13ZOleg GrenrusAllow foreign imports to return ST actionsSome FFI usage is "pure" in the sense of ST, say you allocate some buffer (`MutableByteArray# s`) and pass it to the C function. I cannot use
```haskell
foreign import ccall "initMyStruct" c_initMyStruct :: MutableByteArray# s -> ST s (...Some FFI usage is "pure" in the sense of ST, say you allocate some buffer (`MutableByteArray# s`) and pass it to the C function. I cannot use
```haskell
foreign import ccall "initMyStruct" c_initMyStruct :: MutableByteArray# s -> ST s ()
```
which is a pity.https://gitlab.haskell.org/ghc/ghc/-/issues/245339.10.1-alpha1 regression: certain comments missing from AST2024-03-25T19:13:15Zamesgen9.10.1-alpha1 regression: certain comments missing from AST## Summary
In GHC 9.10.1-alpha1, certain comments do no longer occur in the AST compared to previous GHCs.
I noticed this while upgrading the Ormolu code formatter to GHC 9.10.1-alpha1 (for early integration) as it relies on this.
## ...## Summary
In GHC 9.10.1-alpha1, certain comments do no longer occur in the AST compared to previous GHCs.
I noticed this while upgrading the Ormolu code formatter to GHC 9.10.1-alpha1 (for early integration) as it relies on this.
## Steps to reproduce
Compile eg this code with `-ddump-parsed-ast -dkeep-comments`
```haskell
instance
( Read a, -- Weird
Read b
) =>
Read (a, b)
```
with GHC 9.10.1-alpha1, and note that the substring `Weird` does not occur in the output, in contrast to previous GHCs.
## Expected behavior
The pre-9.10.1-alpha1 behavior should be restored.
## Additional information
Bisecting points to !11716 introducing this. cc @alanz
## Environment
* GHC version used: 9.10.1-alpha19.10.1Alan ZimmermanAlan Zimmermanhttps://gitlab.haskell.org/ghc/ghc/-/issues/24532ghc -M fails to account for TemplateHaskell dependencies2024-03-12T15:17:25ZBen Gamarighc -M fails to account for TemplateHaskell dependenciesIn !12220 I found that `time`'s new dependency on `TemplateHaskell` results in Hadrian build failures. The reason appears to be that the implicit dependency on `Language.Haskell.TH.Lib.Internal` when `TemplateHaskell` is used is not acco...In !12220 I found that `time`'s new dependency on `TemplateHaskell` results in Hadrian build failures. The reason appears to be that the implicit dependency on `Language.Haskell.TH.Lib.Internal` when `TemplateHaskell` is used is not accounted for in `ghc -M` output.https://gitlab.haskell.org/ghc/ghc/-/issues/24531Runtime failure on windows with zlib-0.7.0.0 when missing zlib library2024-03-12T15:28:23ZHannes SiebenhandlRuntime failure on windows with zlib-0.7.0.0 when missing zlib libraryFirst reported by https://github.com/haskell/zlib/issues/65
GHC doesn't fail compilation of a binary depending on `zlib-0.7.0.0`, although the linking of the zlib system depedency failed. The issue exists at least on GHC 9.2.8 through G...First reported by https://github.com/haskell/zlib/issues/65
GHC doesn't fail compilation of a binary depending on `zlib-0.7.0.0`, although the linking of the zlib system depedency failed. The issue exists at least on GHC 9.2.8 through GHC 9.6.
There is no message when running `cabal build`, but opening a repl session fails with the message:
```
ghc-9.4.8.exe: Could not load `zlib1.dll'. Reason: addDLL: zlib1.dll or dependencies not loaded. (Win32 error 126)
```
I was able to reproduce the issue on Win 10, GHC 9.4.8 and cabal 3.10.2.1, but was unable to reproduce the issue on any windows GitHub CI runners.
I briefly investigated, the main change seems to be that zlib haskell library switched to using `extra-libraries` on windows, which should alwasy exist as GHC ships with zlib on windows. Likewise, I verified the library exists, too.Ben GamariBen Gamarihttps://gitlab.haskell.org/ghc/ghc/-/issues/24530Remove duplication of `IfaceTyConInfo` when writing bytecode to .hi files2024-03-20T09:09:08ZHannes SiebenhandlRemove duplication of `IfaceTyConInfo` when writing bytecode to .hi filesIn heap analysis, we noticed there is a high amount of duplication of `IfaceTyConInfo` constructors when we persist `mi_extra_decls` to the respective `ModIface`. Note, this duplication only occurs when you write `mi_extra_decls` to the ...In heap analysis, we noticed there is a high amount of duplication of `IfaceTyConInfo` constructors when we persist `mi_extra_decls` to the respective `ModIface`. Note, this duplication only occurs when you write `mi_extra_decls` to the interface files.
On the agda codebase, with a ghc compiled with `--flavour=perf+ipe`, we gathered the following numbers with ghc-debug (census2LevelClosureType):
```
key; total; count; max; avg
ghc-9.9-inplace:GHC.Iface.Type:IfaceTyCon[ghc-9.9-inplace:GHC.Types.Name:Name,ghc-9.9-inplace:GHC.Iface.Type:IfaceTyConInfo]:206635176:8609799:24:24.0
ghc-9.9-inplace:GHC.Iface.Type:IfaceTyConInfo[ghc-9.9-inplace:Language.Haskell.Syntax.Type:NotPromoted,ghc-9.9-inplace:GHC.Iface.Type:IfaceNormalTyCon];141466584;5894441;24;24.0
ghc-9.9-inplace:GHC.Iface.Type:IfaceTyConInfo[ghc-9.9-inplace:Language.Haskell.Syntax.Type:IsPromoted,ghc-9.9-inplace:GHC.Iface.Type:IfaceNormalTyCon];64949568;2706232;24;24.0
```
We omitted several other lines to focus on the duplication of `IfaceTyConInfo`.
There are 5894441 occurrences of `IfaceTyConInfo NotPromoted IfaceNormalTyCon` and 2706232 instances of `IfaceTyConInfo IsPromoted IfaceNormalTyCon`, resulting in an 200MB overhead.
Note, this duplication does not occur if the `mi_extra_decls` are read from `ModIface`. However, in #24516, we identify a different issue with `IfaceTyConInfo`.Hannes SiebenhandlHannes Siebenhandlhttps://gitlab.haskell.org/ghc/ghc/-/issues/24529Binary distribution build on Windows fails2024-03-25T17:40:32ZBen GamariBinary distribution build on Windows failsIt appears that the `reloc-binary-dist` target is broken in at least some situations on Windows. Specifically, the `configure` invocation performed by `Rules.BinaryDist.installTo` fails to find the in-place mingw toolchain, causing `ghc-...It appears that the `reloc-binary-dist` target is broken in at least some situations on Windows. Specifically, the `configure` invocation performed by `Rules.BinaryDist.installTo` fails to find the in-place mingw toolchain, causing `ghc-toolchain` to conclude that there is no valid object merging tool available:
```
[Error {errorMessage = "Neither a object-merging tool (e.g. ld -r) nor an ar that supports -L is available", errorLogContexts = []}]
```
What is perplexing is that this appears to work in CI: the build system manages to produce a binary distribution, albeit a broken one for unrelated reasons (#24525).https://gitlab.haskell.org/ghc/ghc/-/issues/24528Bump time to 1.142024-03-27T13:44:44ZAshley YakeleyBump time to 1.14I've just released time-1.14 to Hackage. The corresponding git commit is the ghc branch, which always points to the commit that I intend for GHC (and matches the latest release in Hackage).I've just released time-1.14 to Hackage. The corresponding git commit is the ghc branch, which always points to the commit that I intend for GHC (and matches the latest release in Hackage).9.10.1Ben GamariBen Gamarihttps://gitlab.haskell.org/ghc/ghc/-/issues/245279.10.1-alpha1 is missing -src.tar.lz2024-03-12T15:29:10Zjwaldmann9.10.1-alpha1 is missing -src.tar.lzin directory https://downloads.haskell.org/ghc/9.10.0.20240310/ , there is ghc-9.10.0.20240310-src.tar.xz but I was also expecting .lz (e.g., 9.8.2 has both)in directory https://downloads.haskell.org/ghc/9.10.0.20240310/ , there is ghc-9.10.0.20240310-src.tar.xz but I was also expecting .lz (e.g., 9.8.2 has both)https://gitlab.haskell.org/ghc/ghc/-/issues/24526read "500." :: Double fails2024-03-10T23:26:32ZDavid Foxread "500." :: Double fails## Summary
A common rendering of floating point numbers is not recognized by the Read instance.
## Steps to reproduce
```plaintext
Prelude> read "500.0" :: Double
500.0
Prelude> read "500" :: Double
500.0
Prelude> read "500." :: Doubl...## Summary
A common rendering of floating point numbers is not recognized by the Read instance.
## Steps to reproduce
```plaintext
Prelude> read "500.0" :: Double
500.0
Prelude> read "500" :: Double
500.0
Prelude> read "500." :: Double
*** Exception: Prelude.read: no parse
```
## Expected behavior
```plaintext
Prelude> read "500." :: Double
500.0
```
## Environment
* GHC version used: 8.6.5https://gitlab.haskell.org/ghc/ghc/-/issues/24525Windows bindists are quite broken2024-03-20T10:46:50ZBen GamariWindows bindists are quite brokenmingw32 binary distributions are currently quite broken:
```bash
$ wget https://gitlab.haskell.org/ghc/ghc/-/jobs/1805153/artifacts/raw/ghc-x86_64-windows-release.tar.xz
$ tar -xf ../ghc-x86_64-windows-release.tar.xz
$ cd ghc-9.10.0.2024...mingw32 binary distributions are currently quite broken:
```bash
$ wget https://gitlab.haskell.org/ghc/ghc/-/jobs/1805153/artifacts/raw/ghc-x86_64-windows-release.tar.xz
$ tar -xf ../ghc-x86_64-windows-release.tar.xz
$ cd ghc-9.10.0.20240310-x86_64-unknown-mingw32/
$ bin/ghc --info
ghc-9.10.0.20240310.exe: could not detect mingw toolchain in the following paths: ["C:\\msys64\\home\\ben\\tmp\\ghc-9.10.0.20240310-x86_64-unknown-mingw32\\lib\\..\\mingw","C:\\msys64\\home\\ben\\tmp\\ghc-9.10.0.20240310-x86_64-unknown-mingw32\\lib\\..\\..\\mingw","C:\\msys64\\home\\ben\\tmp\\ghc-9.10.0.20240310-x86_64-unknown-mingw32\\lib\\..\\..\\..\\mingw"]
```
It appears that many things that should be in the root of the binary distribution are instead now in `lib` (including `mingw/`):
```bash
$ ls lib/
a.exe config.guess config.status default.host.target.in doc ghc-usage.txt install-sh llvm-targets mk README x86_64-windows-ghc-9.10.0.20240310
bin config.log config.sub default.target docs-utils html latex Makefile package.conf.d settings
build.mk config.mk configure default.target.ghc-toolchain ghc-interp.js include lib manpage post-link.mjs template-hsc.h
completion config.mk.in default.host.target default.target.in ghci-usage.txt INSTALL llvm-passes mingw prelude.js wrappers
```
Moving `lib/mingw` to the root of the distribution appears to be sufficient to make the compiler functional.9.10.1https://gitlab.haskell.org/ghc/ghc/-/issues/24524ghc-heap doesn't allow containers 0.72024-03-12T14:43:09ZDavid Feuerghc-heap doesn't allow containers 0.7## Summary
We can't run the `containers` tests with the `containers` version set to 0.7 because `ghc-heap` imposes an upper bound below that.
Optional:
* Operating System:
* System Architecture:## Summary
We can't run the `containers` tests with the `containers` version set to 0.7 because `ghc-heap` imposes an upper bound below that.
Optional:
* Operating System:
* System Architecture:Ben GamariBen Gamarihttps://gitlab.haskell.org/ghc/ghc/-/issues/24523`rts-1.0.2.conf` (or earlier) specifies `rts.haddock` but no such file ships ...2024-03-12T14:44:58ZMike Pilgrem`rts-1.0.2.conf` (or earlier) specifies `rts.haddock` but no such file ships with GHC## Summary
Since GHC 9.0.1 (at least, on Windows*), the `rts-1.0.2.conf` file (or its equivalent) has specified a `rts.haddock` file (in key `haddock-interfaces`) but no such file is provided with GHC. Before GHC 9.0.1, the `rts.conf` f...## Summary
Since GHC 9.0.1 (at least, on Windows*), the `rts-1.0.2.conf` file (or its equivalent) has specified a `rts.haddock` file (in key `haddock-interfaces`) but no such file is provided with GHC. Before GHC 9.0.1, the `rts.conf` file did not specify a `*.haddock` file.
*I also looked inside the `*.tar.xz` file for GHC 9.8.2/x86_64/Alpine Linux 3.12 (dynamically linked). I think the same is true for Linux.
## Expected behavior
Either the `*.conf` file does not specify a `*.haddock` file or that the specified `rts.haddock` file is provided with GHC.
## Environment
* GHC version used: 9.0.1 to 9.8.2.
Optional:
* Operating System: Windows
* System Architecture: x86_64ZubinZubinhttps://gitlab.haskell.org/ghc/ghc/-/issues/24522Incomplete inferred types showed for type holes since GHC 9.82024-03-11T09:00:52ZJan HrčekIncomplete inferred types showed for type holes since GHC 9.8## Summary
Since ghc 9.8 the inferred types of wildcards (sometimes?) don't contains type class constraints.
## Steps to reproduce
Consider this code:
```
$ cat A.hs
f :: _
f x y = x + y
```
When compiled with GHC 9.6, I get this err...## Summary
Since ghc 9.8 the inferred types of wildcards (sometimes?) don't contains type class constraints.
## Steps to reproduce
Consider this code:
```
$ cat A.hs
f :: _
f x y = x + y
```
When compiled with GHC 9.6, I get this error:
```
A.hs:1:6: error: [GHC-88464]
• Found type wildcard ‘_’
standing for ‘Integer -> Integer -> Integer’
To use the inferred type, enable PartialTypeSignatures
• In the type signature: f :: _
|
1 | f :: _
| ^
```
But when compiled with GHC 9.8.2 I get this (notice the inferred type doesn't contain Num a constraint):
```
A.hs:1:6: error: [GHC-88464]
• Found type wildcard ‘_’ standing for ‘a -> a -> a’
Where: ‘a’ is a rigid type variable bound by
the inferred type of f :: a -> a -> a
at A.hs:2:1-13
To use the inferred type, enable PartialTypeSignatures
• In the type signature: f :: _
|
1 | f :: _
| ^
A.hs:2:11: error: [GHC-39999]
• No instance for ‘Num a’ arising from a use of ‘+’
Possible fix:
add (Num a) to the context of the inferred type of f :: a -> a -> a
• In the expression: x + y
In an equation for ‘f’: f x y = x + y
|
2 | f x y = x + y
| ^
```
## Expected behavior
I would expect that if I use the inferred type, I will get code that type checks (e.g. `Num a => a -> a -> a` or `Integer -> Integer -> Integer`).
This is breaking haskell-language-server functionality, which uses the type displayed in the warning (`a -> a -> a`) in that it leads it to creation of code actions (small popups you can use to locally "fix" your code) that break user's code as in this example:
![Screenshot_from_2024-03-09_14-47-41](/uploads/e333c4313f2c558260e9958b4462d4fa/Screenshot_from_2024-03-09_14-47-41.png)
See this "broken" test case for illustration: https://github.com/haskell/haskell-language-server/blob/c50a0e118b8570b2bd405de6ff5be6a54926aa5d/plugins/hls-refactor-plugin/test/Main.hs#L665-L673
## Environment
* GHC version used: 9.8.2
Optional:
* Operating System: Fedora Linux 39
* System Architecture: x86_64https://gitlab.haskell.org/ghc/ghc/-/issues/24521Some Addr#, (Mutable)ByteArray# primops do not note mutability expectations2024-03-14T21:44:21ZBen OrchardSome Addr#, (Mutable)ByteArray# primops do not note mutability expectationsOne group of primops exported by GHC.Exts are the `index<primty>OffAddr# :: Addr# -> Int# -> <primty>` functions.
Their type signatures were somewhat surprising to me-- how are we to read from an address without some sort of state tracki...One group of primops exported by GHC.Exts are the `index<primty>OffAddr# :: Addr# -> Int# -> <primty>` functions.
Their type signatures were somewhat surprising to me-- how are we to read from an address without some sort of state tracking?
The Haddock docstrings state "Read a (pretty type description); offset in (type size in bytes) words."
This docstring is shared with the associated `read<primty>OffAddr# :: Addr# -> Int# -> State# d -> (# State# d, <primty> #)` function.
These primops are for reading from immutable non-GC-managed addresses. I eventually gathered so from some documentation in GHC.Prim,
which explains what the index, read and write primops do in the context of `ByteArray#`s. On a closer look, there are notes on whether a given primop works with immutable or mutable memory, but these are inconsistently applied, and no `Addr#` primops make any reference.
I think primops that access the contents of some pointer (`Addr#`, `MutableByteArray#` or `ByteArray#`) should note the mutability of the memory they're accessing. This is potentially "obvious" for the latter two, but easily confusing for `Addr#` access primops which aren't explained purely by their type signatures.
This is fairly easily accomplished by editing some `desc` fields in `utils/genprimopcode/AccessOps.hs`.https://gitlab.haskell.org/ghc/ghc/-/issues/24519CmmToAsm/x86: Poor unrolling for unaligned memcpy2024-03-20T14:58:37ZMatthew Cravenclyring@gmail.comCmmToAsm/x86: Poor unrolling for unaligned memcpyCompile the following module, and look at the generated assembly:
```haskell
module Memcpy where
import Foreign
import Data.Word
fun :: Ptr Word8 -> Ptr Word8 -> IO ()
fun p q = copyBytes p q 16
```
When I compile with `ghc-9.8.2 -O ...Compile the following module, and look at the generated assembly:
```haskell
module Memcpy where
import Foreign
import Data.Word
fun :: Ptr Word8 -> Ptr Word8 -> IO ()
fun p q = copyBytes p q 16
```
When I compile with `ghc-9.8.2 -O -dno-typeable-binds Memcpy.hs -S` on my x86-64 machine, this is what I see:
<details>
```asm
.section .text
.align 8
.align 8
.quad 12884901903
.quad 0
.long 14
.long 0
.globl Memcpy_fun1_info
.type Memcpy_fun1_info, @function
Memcpy_fun1_info:
.LcRu:
leaq -16(%rbp),%rax
cmpq %r15,%rax
jb .LcRy
.LcRz:
movq $.LcRr_info,-16(%rbp)
movq %r14,%rbx
movq %rsi,-8(%rbp)
addq $-16,%rbp
testb $7,%bl
jne .LcRr
.LcRs:
jmp *(%rbx)
.align 8
.quad 1
.long 30
.long 0
.LcRr_info:
.LcRr:
movq $.LcRx_info,(%rbp)
movq 7(%rbx),%rax
movq 8(%rbp),%rbx
movq %rax,8(%rbp)
testb $7,%bl
jne .LcRx
.LcRB:
jmp *(%rbx)
.align 8
.quad 65
.long 30
.long 0
.LcRx_info:
.LcRx:
movq 8(%rbp),%rax
movq 7(%rbx),%rbx
;; !!!
movb 0(%rbx),%cl
movb %cl,0(%rax)
movb 1(%rbx),%cl
movb %cl,1(%rax)
movb 2(%rbx),%cl
movb %cl,2(%rax)
movb 3(%rbx),%cl
movb %cl,3(%rax)
movb 4(%rbx),%cl
movb %cl,4(%rax)
movb 5(%rbx),%cl
movb %cl,5(%rax)
movb 6(%rbx),%cl
movb %cl,6(%rax)
movb 7(%rbx),%cl
movb %cl,7(%rax)
movb 8(%rbx),%cl
movb %cl,8(%rax)
movb 9(%rbx),%cl
movb %cl,9(%rax)
movb 10(%rbx),%cl
movb %cl,10(%rax)
movb 11(%rbx),%cl
movb %cl,11(%rax)
movb 12(%rbx),%cl
movb %cl,12(%rax)
movb 13(%rbx),%cl
movb %cl,13(%rax)
movb 14(%rbx),%cl
movb %cl,14(%rax)
movb 15(%rbx),%bl
movb %bl,15(%rax)
leaq ghczmprim_GHCziTupleziPrim_Z0T_closure+1(%rip),%rbx
addq $16,%rbp
jmp *(%rbp)
.LcRy:
leaq Memcpy_fun1_closure(%rip),%rbx
jmp *-8(%r13)
.size Memcpy_fun1_info, .-Memcpy_fun1_info
.section .data
.align 8
.align 1
.globl Memcpy_fun1_closure
.type Memcpy_fun1_closure, @object
Memcpy_fun1_closure:
.quad Memcpy_fun1_info
.section .text
.align 8
.align 8
.quad 12884901903
.quad 0
.long 14
.long 0
.globl Memcpy_fun_info
.type Memcpy_fun_info, @function
Memcpy_fun_info:
.LcRU:
jmp Memcpy_fun1_info
.size Memcpy_fun_info, .-Memcpy_fun_info
.section .data
.align 8
.align 1
.globl Memcpy_fun_closure
.type Memcpy_fun_closure, @object
Memcpy_fun_closure:
.quad Memcpy_fun_info
.section .note.GNU-stack,"",@progbits
.ident "GHC 9.8.2"
```
</details>
Notice the 32 single-byte `movb` instructions used to implement the copy. (I have marked this with `!!!`.)
We are probably using single-byte move instructions because the given `Ptr`s can have arbitrary alignment. But on x86-64, the penalty for an unaligned `movq` is typically at most a few cycles. It would be much better for both speed and code size to emit four eight-byte move instructions or even two unaligned 16-byte move instructions. (There are a few of the latter in SSE and SSE2, which we assume are available on every x86-64 machine.) And indeed I see the latter if I also add `-fllvm`.
I haven't checked, but would not be surprised if there were similar opportunities for improvement available on other platforms.https://gitlab.haskell.org/ghc/ghc/-/issues/24518Update Cabal to version 3.10.3.0 for GHC-9.6 and GHC-9.82024-03-21T13:19:34ZTrevis ElserUpdate Cabal to version 3.10.3.0 for GHC-9.6 and GHC-9.8## Summary
At the most user facing level, plugins appear to not work correctly with 9.6/9.8 when using `stack`. The issue on that side is tracked https://github.com/commercialhaskell/stack/issues/6251. However, it would appear that the ...## Summary
At the most user facing level, plugins appear to not work correctly with 9.6/9.8 when using `stack`. The issue on that side is tracked https://github.com/commercialhaskell/stack/issues/6251. However, it would appear that the underlying issue is with the `Cabal` library. The issue for `Cabal` is at https://github.com/haskell/cabal/issues/9375. The fix for this is included in `cabal-3.10.3.0`~~, which ghc-9.10 appears to be ahead of~~.
So if I'm understanding the various moving parts all correctly bumping the included `Cabal` version for the next 9.6 and 9.8 series releases will fix the issue. As it stands, this is holding some users on 9.4.x.
## Steps to reproduce
From the cabal issue, reproducing would appear to be as simple as having a plugin module Foo and then running:
```
ghc-9.6.3 --abi-hash -fplugin=Foo
```
Which would result in:
```
<command line>: Could not find module ‘Foo’
Use -v (or `:set -v` in ghci) to see a list of the files searched for.
```
## Expected behavior
The expectation would be to have a hash from the above.
@mpickering I'm tagging you because you commented here: https://github.com/haskell/cabal/issues/9375#issuecomment-1789748616 and almost certainly have more context/understanding than I do on the internal implications of this.9.6.5ZubinZubin