regression with 9.6/9.8, observed as heap usage but could be due to behavior change
Summary
The Bluespec Compiler (bsc) is compiled with GHC and we have observed a regression in our testsuite when using GHC 9.6 and 9.8 (including recent 9.8.2), that was not a failure with GHC 9.4 and earlier.
Specifically, in the BSC repo, in directory /testsuite/bsc.bugs/bluespec_inc/b1490/
, there are two tests which exhaust the heap when set with -M256
but execute fine when it is increased with +RTS -M260
and +RTS -M265
. However, with earlier versions of GHC (such as 9.4.8), the heap size can be reduced dramatically and it still executes without exhausting the heap, even down to -M4K
!
Something clearly changed in GHC, but I don't think it's necessarily directly related to heap usage; I would guess that maybe a code optimization has changed the behavior, and it is resulted in BSC using more heap. I say that because BSC is itself a compiler, and the test cases which are now failing are tests that involve a for-loop in the Bluespec design being compiled, and the tests are checking that BSC is able to unroll the loops and properly prune the growing structure so that it doesn't explode. The heap usage could be because BSC is now failing to properly prune, as a result of a behavior change resulting from a change in GHC.
However, I don't know how to diagnose this. Are there RTS flags that can dump information about heap usage, that I can compare between GHC versions? I can use +RTS -s
, but it doesn't show max heap usage, and the info that it does show isn't significantly different between GHC 9.8 and 9.4.
I assume that a binary search of the GHC commits might find the point where the issue was introduced, but each iteration would take a while.
Any advice you can provide on how to investigate this would be appreciated.
Steps to reproduce
BSC is a large program, but if you want to reproduce, you can do this:
git clone --recursive https://github.com/B-Lang-org/bsc
cd bsc
make install-src
cd testsuite/bsc.bugs/bluespec_inc/b1490/
../../../../inst/bin/bsc -verilog Bug1490MyUnion.bsv +RTS -M256M
The result of running BSC in the last line is (when compiled with 9.8 or 9.6):
bsc: Heap exhausted;
bsc: Current maximum heap size is 268435456 bytes (256 MB).
bsc: Use `+RTS -M<size>' to increase it.
Expected behavior
I expect BSC to run to completion and output a message like this (which is what you get with GHC 9.4.8 and earlier version):
Verilog file created: module_arbitrate_myunion.v
In fact, with GHC 9.4.8 (and presumably earlier), the heap can be reduced significantly and BSC still executes fine:
../../../../inst/bin/bsc -verilog Bug1490MyUnion.bsv +RTS -M4K
With GHC 9.6 and 9.8, the heap needs to be increased to around 260 or 265, for it to compile. This difference between essentially nothing (4K) and 260M seems significant, and so I felt it was worth reporting (particularly if the heap is just a sympton and that it's due to a bug in behavior).
Environment
-
GHC versions that fail: 9.8.2, 9.8.1, 9.6.4, 9.6.2
-
GHC versions that work: 9.4.8 (and many earlier versions)
-
Operating System: My results reported here are on macOS 11, but the same failures were seen on GitHub VMs for Ubuntu 22.04 and macOS 12
-
System Architecture: x86_64
We have been using various versions of GHC in our CI over the last few years and had not noticed an issue up through 9.4.x (on various Ubuntu and macOS VMs). We then tested with 9.8.1 (on Ubuntu 22.04 and macOS 12) and saw the error. Today, on my macOS 11 system, I confirmed that 9.8.1 fails and that the recently released 9.8.2 also fails, and I checked 9.6.2 and 9.6.4 and saw that they also failed. So I would guess that the issue was introduced in 9.6. I confirm that we currently do not observe the failure when using 9.4.8 (on Ubuntu 20.04 and 22.04 and macOS 11, 12, and 13).