ihp
ihp copied to clipboard
Compiling IHP app with optimizations - Simplifier ticks exhausted error
Just ran into this GHC error while compiling two of the controller modules in a project with 256 modules (including generated ones) and about 14,000 lines of code:
<no location info>: error:
Simplifier ticks exhausted
When trying UnfoldingDone $fFillParams[]record_$cfill
To increase the limit, use -fsimpl-tick-factor=N (default 100).
In addition try adjusting -funfolding-case-threshold=N and
-funfolding-case-scaling=N for the module in question.
Using threshold=1 and scaling=5 should break most inlining loops.
If you need to increase the tick factor substantially, while also
adjusting unfolding parameters please file a bug report and
indicate the factor you needed.
If GHC was unable to complete compilation even with a very large factor
(a thousand or more), please consult the "Known bugs or infelicities"
section in the Users Guide before filing a report. There are a
few situations unlikely to occur in practical programs for which
simplifier non-termination has been judged acceptable.
To see detailed counts use -ddump-simpl-stats
Total ticks: 167124
<no location info>: error:
Simplifier ticks exhausted
When trying UnfoldingDone $dFillParams_sKXb
To increase the limit, use -fsimpl-tick-factor=N (default 100).
In addition try adjusting -funfolding-case-threshold=N and
-funfolding-case-scaling=N for the module in question.
Using threshold=1 and scaling=5 should break most inlining loops.
If you need to increase the tick factor substantially, while also
adjusting unfolding parameters please file a bug report and
indicate the factor you needed.
If GHC was unable to complete compilation even with a very large factor
(a thousand or more), please consult the "Known bugs or infelicities"
section in the Users Guide before filing a report. There are a
few situations unlikely to occur in practical programs for which
simplifier non-termination has been judged acceptable.
To see detailed counts use -ddump-simpl-stats
Total ticks: 176447
This is being reported in two controller modules with only about 100-200 lines of code each, and nothing particularly "weird" in the code. I haven't seen this before until just now.
Works fine when compiling the unoptimized version, but compiling the optimized version causes this error. Any ideas how I can go about fixing this? Or what might be causing it?
Update: as it says in the error, setting the -fsimpl-tick-factor
to a higher number appears to have fixed it. In this case, I had to increase it tenfold from the default of 100, to 1000. To do so, I added the following to my Makefile
:
PROD_GHC_OPTIONS+= -fsimpl-tick-factor=1000
This feels... wrong: increasing a value to tenfold of its default value, without fully understanding the implications of doing so. So I would love suggestions on how to fix this properly, or what might be causing it. It feels especially weird since I don't think we've done anything particularly strange in the module. I would post it, but it is not an open-source project unfortunately.
One of the modules compiled after increasing it to 200, the other was stubborn and didn't work with 300 or 500, but 1000 seems to have worked.
Edit: it's still compiling after about 15-20 minutes and is using over 24gb of RAM in the process. Clearly something is wrong! Is there a way to find out what's triggering this? Will compile without optimizations for now.
I've seen this error before. It's caused by a |> fill @[..]
call with a lot of arguments passed to fill
. One workaround in the past was to identify the fill
call causing this and then splitting it into multiple calls:
-- before
|> fill @["a", "b", "c", "d"]
-- after
|> fill @["a", "b"]
|> fill @["c", "d"]
If you can make a small reproducer, maybe we can report this issue upstream to GHC
Ah, yep, we do have a fill
with a long list in those modules, thank you! It's a relief to know what it is. It was certainly bugging me not knowing and being worried other stuff might break. I'll use that workaround for now thanks! And try to come up with a minimal example. Should we come up with a minimal IHP example or can we get it down to one file for instance?
Minimum IHP example might be enough 👍
I guess I just wondered if there was a way to provide them with a minimal example that doesn't carry with it all the "weight" of having a full-blown IHP app. Like just a simple cabal project for instance.
Yes if that's easy to do that would be even better than an minimum IHP example
Actually fixed via https://github.com/digitallyinduced/ihp/commit/9dc3b9f07186d612e994447dc050613af4b4c1aa
:sunglasses:
Turns out the we three redundant recursion steps (3 different case branches to
fill
). By removing the redundant code
What was the redundant code - it's unclear to me from looking at the code?
If you remove some of the noise around the previous code you can see it calls fill
from each branch of the case statement:
fill record = do
case ... of
Right ... -> fill @rest ...
Left ... -> fill @rest ...
Left ... -> fill @rest ...
Now with the new code, we only call fill
once at the end instead from those 3 branches