-
Notifications
You must be signed in to change notification settings - Fork 11
Commit
This commit does not belong to any branch on this repository, and may belong to a fork outside of the repository.
GHC DevX biweekly update 2023-02-09 (#30)
* Starts next biweekly update * Fix date * biweekly: jeff: add CI discussion * jeff: add eDSL and release notes blurbs * jeff: add work on HoH * Update 2023-02-09-ghc-update-2023-02-09.md * Update 2023-02-09-ghc-update-2023-02-09.md * Update 2023-02-09-ghc-update-2023-02-09.md * Update 2023-02-09-ghc-update-2023-02-09.md * Update 2023-02-09-ghc-update-2023-02-09.md * add item about GHCi bytecode size limits * Update 2023-02-09-ghc-update-2023-02-09.md * Update 2023-02-09-ghc-update-2023-02-09.md * Update 2023-02-09-ghc-update-2023-02-09.md * Update 2023-02-09-ghc-update-2023-02-09.md * Update 2023-02-09-ghc-update-2023-02-09.md * Update 2023-02-09-ghc-update-2023-02-09.md * Update 2023-02-09-ghc-update-2023-02-09.md * add section about exceptions and improve the ones about ghci bytecode and temp files * Update 2023-02-09-ghc-update-2023-02-09.md * Update 2023-02-09-ghc-update-2023-02-09.md * Update 2023-02-09-ghc-update-2023-02-09.md * Update 2023-02-09-ghc-update-2023-02-09.md --------- Co-authored-by: doyougnu <jeffrey.young@iohk.io> Co-authored-by: Luite Stegeman <stegeman@gmail.com> Co-authored-by: Josh Meredith <joshmeredith2008@gmail.com>
- Loading branch information
1 parent
561caf5
commit 15f0338
Showing
1 changed file
with
233 additions
and
0 deletions.
There are no files selected for viewing
This file contains bidirectional Unicode text that may be interpreted or compiled differently than what appears below. To review, open the file in an editor that reveals hidden Unicode characters.
Learn more about bidirectional Unicode characters
Original file line number | Diff line number | Diff line change |
---|---|---|
@@ -0,0 +1,233 @@ | ||
--- | ||
slug: 2023-02-09-ghc-update | ||
title: "IOG GHC Update #3 (2023-02-09)" | ||
authors: [sylvain,doyougnu,luite,josh] | ||
tags: [ghc,ghc-update] | ||
--- | ||
|
||
Biweekly update from the GHC DevX team at IOG. | ||
|
||
Previous updates can be found [here](https://engineering.iog.io/tags/ghc-update). | ||
|
||
## JavaScript backend | ||
|
||
### Template Haskell | ||
|
||
Luite: fixed the support for one-shot mode (GHC's `-c` command-line flag) | ||
in the TH JS linker. | ||
|
||
Luite: Investigated a warning about the temporary directory not being removed | ||
after running Template Haskell with the JavaScript backend. It turned out | ||
that GHC's `GHC.Utils.TmpFs.newTempDir`, which is used by the Template Haskell | ||
linker, does not allow the newly created directory to be removed | ||
(see [#22952](https://gitlab.haskell.org/ghc/ghc/-/issues/22952)). | ||
|
||
Sylvain: cleaned up the [merge request](https://gitlab.haskell.org/ghc/ghc/-/merge_requests/9779), | ||
removing unnecessary changes and adding documentation. | ||
|
||
### JavaScript backend CI | ||
|
||
Jeff: JavaScript backend CI was [finally | ||
merged](https://gitlab.haskell.org/ghc/ghc/-/merge_requests/9552)! Now that we | ||
have CI we are unblocked on several fronts, such as, implementing [faster | ||
arithmetic](https://gitlab.haskell.org/ghc/ghc/-/merge_requests/9825) and fixing | ||
some [async | ||
exceptions](https://gitlab.haskell.org/ghc/ghc/-/merge_requests/9879). In | ||
general, we can now have confidence that our work is progressing the JavaScript | ||
backend to a better state. | ||
|
||
Sylvain: fixed a spurious failure on JS CI due to some test _passing_ on fast runners | ||
while it was expected to fail (see [!9934](https://gitlab.haskell.org/ghc/ghc/-/merge_requests/9934)). | ||
|
||
Josh: fixed some inaccurate test predicates [!9939](https://gitlab.haskell.org/ghc/ghc/-/merge_requests/9939) | ||
|
||
### FileStat | ||
|
||
Josh: rebased and merged [!9755](https://gitlab.haskell.org/ghc/ghc/-/merge_requests/9755). | ||
This patch changes the representation of the JavaScript equivalent of the C `struct stat` | ||
to make its field offsets match the C ones: some Haskell codes directly access fields of | ||
this structure using `hsc2hs` to get the field offsets from the C headers. | ||
|
||
This patch also adds fields to the JavaScript file stat that were previously not | ||
included, such as modification and access times. | ||
|
||
### JavaScript RTS refactor | ||
|
||
Josh: rebased [!9794](https://gitlab.haskell.org/ghc/ghc/-/merge_requests/9794) which consists | ||
in the refactor of the module generating some part of the RTS. The new JS CI job found a bug in the patch that | ||
caused ~50 tests to time out, so waiting for CI to be set up before merging this MR was judicious. | ||
|
||
This MR also became an opportunity to revisit some arbitrary cache sizes in the RTS code generator. | ||
This is still ongoing work. | ||
|
||
### Warnings | ||
|
||
Luite: We accidently removed the check for the "javascript" calling convention on | ||
foreign imports, allowing this convention to be wrongly used on native platform. | ||
Fixed in [!9880](https://gitlab.haskell.org/ghc/ghc/-/merge_requests/9880). | ||
|
||
### Fix for asynchronous exceptions | ||
|
||
Luite: Fixed an issue in the garbage collector for the JavaScript backend: | ||
A thread that posts an asynchronous exception (`throwTo`) to another thread | ||
is temporarily suspended until the exception has been delivered. The | ||
garbage collector did not correctly follow the list of threads suspended in | ||
this way, potentially considering them unreachable and cleaning up data | ||
referenced by them. See [#22836](https://gitlab.haskell.org/ghc/ghc/-/issues/22836) and | ||
[!9879](https://gitlab.haskell.org/ghc/ghc/-/merge_requests/9879). | ||
|
||
### Integer performance | ||
|
||
Evaluating the following expression is very slow in general but especially with | ||
the JS backend: | ||
|
||
```haskell | ||
1 `shiftL` (1 `shiftL` 20) :: Integer | ||
``` | ||
|
||
We've had to mark a test computing this as broken on CI because it triggers a | ||
timeout error. Luckily the identification of slow operations is easy with | ||
JavaScript profiling tools (see graphs in | ||
https://gitlab.haskell.org/ghc/ghc/-/issues/22835) and we know that `Word32` | ||
primops are the culprit in this case. | ||
|
||
Sylvain started replacing the uses of JavaScript's `BigInt` in the | ||
implementation of these primops with usual JavaScript `numbers`. | ||
See [!9825](https://gitlab.haskell.org/ghc/ghc/-/merge_requests/9825). | ||
|
||
### JavaScript EDSL | ||
|
||
Jeff: JavaScript eDSL based on | ||
[sunroof](https://github.com/ku-fpg/sunroof-compiler) close to MR, see | ||
[#22736](https://gitlab.haskell.org/ghc/ghc/-/issues/22736) for background. | ||
Compiler is complete. Major items left are: the interpreter to translate to | ||
`JStat`, filling in documentation, and testing now that CI has been merged. | ||
|
||
### Documentation | ||
|
||
Jeff: Wrote the JavaScript backend release notes. Notes pending | ||
[approval](https://gitlab.haskell.org/ghc/ghc/-/merge_requests/9828). We cite | ||
the [JavaScript | ||
backend](https://gitlab.haskell.org/ghc/ghc/-/wikis/javascript-backend) wiki | ||
page in the release notes. So Jeff and Sylvain heavily edited the wiki pages to | ||
make them suitable for external customers. | ||
|
||
### Change from `js` to `javascript` architecture | ||
|
||
In [#22740](https://gitlab.haskell.org/ghc/ghc/-/issues/22740) it was noticed that | ||
`hackage-server` would prevent the upload of the upcoming `base` package bundled with GHC 9.6. | ||
The reason is that `hackage-server` relies on the `cabal --check` feature which filters | ||
out perfectly valid packages (it happened before, for example with [ghc-api-compat](https://gitlab.haskell.org/haskell/ghc-api-compat/-/issues/1)). | ||
|
||
In our case, the package was rejected because the `js` architecture wasn't recognized | ||
as a built-in one, but luckily we could fall back to the existing `javascript` built-in | ||
architecture defined for GHCJS (if it wasn't a JS backend, we would have had to fix Cabal, | ||
update `hackage-server` dependencies, and redeploy `hackage-server`...). | ||
|
||
Sylvain completed Ben's MR in [!9814](https://gitlab.haskell.org/ghc/ghc/-/merge_requests/9814). | ||
|
||
For early users of the JS backend the change means that from now on: | ||
- `configure` command is: `emconfigure ./configure --target=javascript-unknown-ghcjs` | ||
- Cabal condition is: `arch(javascript)` | ||
- CPP condition is: `#if defined(javascript_HOST_ARCH)` | ||
|
||
## Compiler performance | ||
|
||
### More-strict `break` | ||
|
||
Josh: opened an MR to add a strict `break'` version to `base` - however, this would require a CLC proposal. | ||
|
||
https://gitlab.haskell.org/ghc/ghc/-/issues/22865 | ||
https://gitlab.haskell.org/ghc/ghc/-/merge_requests/9868 | ||
|
||
Further analysis was done using ticky profiles on a simple test program that benchmarks GHC's startup code. | ||
This has found an example where a more-strict break is an improvement in GHC, which will provide motivation | ||
for the CLC proposal. | ||
|
||
### Unboxed CodeBuffers | ||
|
||
Josh: implemented changes to GHC's text encoding buffers to use unboxed tuples on handle encoders/decoders. | ||
The buffers pass around and repeatedly pack/unpack a tuple in an `IO` inner loop, which causes a significant | ||
number of unnecessary allocations. By replacing this with an unboxed tuple, and replacing the `IO` with | ||
manually passing around a `State# RealWorld` in the same tuple, we're able to reduce allocations by nearly 50% | ||
in a pathological example (non-allocating loop printing characters). | ||
|
||
https://gitlab.haskell.org/ghc/ghc/-/issues/22946 | ||
https://gitlab.haskell.org/ghc/ghc/-/merge_requests/9948 | ||
|
||
### Optimization Handbook | ||
|
||
Jeff: opened IT ticket to move the [Optimization | ||
Handbook](https://github.com/input-output-hk/hs-opt-handbook.github.io) to Haskell Foundation's repository. | ||
IT stated they need to check with legal, of course. | ||
|
||
Jeff: almost finished the [lambda | ||
lifting](https://input-output-hk.github.io/hs-opt-handbook.github.io/src/Optimizations/GHC_opt/lambda_lifting.html) | ||
chapter; major remaining items are adding some glossary terms and describing the | ||
interaction between lambda lifting and calling conventions. | ||
|
||
|
||
### Constant folding for division operations | ||
|
||
While looking into his old merge requests still opened, Sylvain nerd-snipped | ||
himself into fixing constant folding rules for division operations (see | ||
[#22152](https://gitlab.haskell.org/ghc/ghc/-/issues/22152)). | ||
|
||
MR [!8956](https://gitlab.haskell.org/ghc/ghc/-/merge_requests/8956) adds the | ||
following rewrite rules: | ||
|
||
``` | ||
case quotRemInt# x y of | ||
(# q, _ #) -> body | ||
====> | ||
case quotInt# x y of | ||
q -> body | ||
case quotRemInt# x y of | ||
(# _, r #) -> body | ||
====> | ||
case remInt# x y of | ||
r -> body | ||
For all primitive numerical types: | ||
(x `quot` l1) `quot` l2 | ||
| l1 /= 0 | ||
| l2 /= 0 | ||
| l1*l2 doesn't overflow/underflow | ||
====> | ||
x `quot` (l1 * l2) | ||
``` | ||
|
||
It also makes some division primops (Word64/Int64 Quot/Rem, WordQuotRem2Op) | ||
ok-for-speculation when the divisor is known to be non-zero, similarly to other | ||
division primops. Otherwise the last rule wasn't firing in the added test | ||
because we got the following Core (simplified for the presentation): | ||
|
||
```haskell | ||
case quotWord64# x# 10#Word64 of | ||
ds1 -> case quotWord64# ds1 20#Word64 of | ||
ds2 -> ... | ||
``` | ||
|
||
and not: | ||
|
||
```haskell | ||
case quotWord64# (quotWord64# x# 10#Word64) 20#Word64 of | ||
ds2 -> ... | ||
``` | ||
|
||
## GHCi | ||
|
||
Luite: A test run of GHC 9.6 with the `-fbyte-code-and-object-code` flag | ||
on [head.hackage](https://ghc.gitlab.haskell.org/head.hackage/) revealed | ||
([issue #22888](https://gitlab.haskell.org/ghc/ghc/-/issues/22888)) with bytecode | ||
size limits. Many bytecode instructions have `Word16` operands, which | ||
is not always enough to run programs generated from optimized core. The solution | ||
is to enable large operands for all the bytecode instructions that deal with | ||
stack offsets. | ||
|
||
https://gitlab.haskell.org/ghc/ghc/-/issues/22888 | ||
https://gitlab.haskell.org/ghc/ghc/-/merge_requests/9957 |