Skip to content
New issue

Have a question about this project? Sign up for a free GitHub account to open an issue and contact its maintainers and the community.

By clicking “Sign up for GitHub”, you agree to our terms of service and privacy statement. We’ll occasionally send you account related emails.

Already on GitHub? Sign in to your account

Serialize Core #2813

Merged
merged 11 commits into from
Jun 19, 2022
Merged

Serialize Core #2813

merged 11 commits into from
Jun 19, 2022

Conversation

wz1000
Copy link
Collaborator

@wz1000 wz1000 commented Apr 1, 2022

Serialize core to core files

Add a .hi.core file format to which we serialize out compiled core after generating it.
This core is then read back in on subsequent runs and compiled to bytecode.

This greatly speeds up startup times when we need compilation, as we can simply read bytecode
off the disk instead of having to recompile a lot of modules

This is based off Fat Interface files in GHC: https://gitlab.haskell.org/ghc/ghc/-/merge_requests/7502

@wz1000
Copy link
Collaborator Author

wz1000 commented Apr 1, 2022

Some benchmarks here: https://well-typed.com/blog/2022/04/hls-performance/

(this is the serialize-core set of commits)

@wz1000 wz1000 force-pushed the wip/th-core-file-3 branch 3 times, most recently from 749c2f8 to 214971e Compare April 2, 2022 09:34
Copy link
Collaborator

@pepeiborra pepeiborra left a comment

Choose a reason for hiding this comment

The reason will be displayed to describe this comment to others. Learn more.

This looks awesome, I just got some questions on the handling of interface files and core files timestamps.

ghcide/src/Development/IDE/Core/Rules.hs Show resolved Hide resolved
ghcide/src/Development/IDE/Core/Compile.hs Outdated Show resolved Hide resolved
ghcide/src/Development/IDE/GHC/CoreFile.hs Outdated Show resolved Hide resolved
@wz1000 wz1000 force-pushed the wip/th-core-file-3 branch 14 times, most recently from 566b90c to 2141259 Compare June 8, 2022 12:33
@wz1000
Copy link
Collaborator Author

wz1000 commented Jun 8, 2022

I've added the on demand bytecode generation commit to this as well as its a major simplification of the patch, and deletes a bunch of code added by the first commit, along with fixing a few bugs. If required I can split it into multiple PRs but I think it is better to review all the changes at once.

See the commit message for a description of the changes.

@wz1000 wz1000 force-pushed the wip/th-core-file-3 branch 4 times, most recently from 460f287 to 0e60634 Compare June 13, 2022 09:55
Add a `.hi.core` file format to which we serialize out compiled core after generating it.
This core is then read back in on subsequent runs and compiled to bytecode.

This greatly speeds up startup times when we need compilation, as we can simply read bytecode
off the disk instead of having to recompile a lot of modules

This is based off Fat Interface files in GHC: https://gitlab.haskell.org/ghc/ghc/-/merge_requests/7502

- Also add --verify-core-file to do roundtrip testing of core-files

- Use closed world assumption for core and .hie files
Adds a new rule `GetLinkable` which is called on demand by
hscCompileCoreExprHook whenever a linkable is required for a splice.

Adds a MonadUnliftIO instance for Action to faciliate the above

We write Core Files whenever a linkable could potentially be required for a file
(i.e it is in the transitive closure of a module that uses TH/compile time code
execution)

However, we only generate byte/object code when such a linkable is
really required by a splice (i.e. the module is in the transitive closure
of any symbol called from a splice).

No linkables are stored in `HiFileResult`. If a linkable is required, then
it must be obtained via a call to `GetLinkable`.

Also use hashes to do fine grained recompilation checking for TH instead of
mod times. This simplifies recompilation checking quite a bit.
Copy link
Collaborator

@pepeiborra pepeiborra left a comment

Choose a reason for hiding this comment

The reason will be displayed to describe this comment to others. Learn more.

Do you expect any perf regressions in non TH projects?

ghcide/src/Development/IDE/Core/Compile.hs Outdated Show resolved Hide resolved
-- | Find the runtime dependencies by looking at the annotations
-- serialized in the iface
parseRuntimeDeps :: [ModIfaceAnnotation] -> ModuleEnv UTCTime
parseRuntimeDeps :: [ModIfaceAnnotation] -> ModuleEnv BS.ByteString
Copy link
Collaborator

Choose a reason for hiding this comment

The reason will be displayed to describe this comment to others. Learn more.

This now collects hashes instead of timestamps, right?
Maybe worth an extended comment.

Copy link
Collaborator Author

Choose a reason for hiding this comment

The reason will be displayed to describe this comment to others. Learn more.

I've added a line here and also a bit in Note [Recompilation avoidance in the presence of TH]

@wz1000
Copy link
Collaborator Author

wz1000 commented Jun 19, 2022

Do you expect any perf regressions in non TH projects?

No, but there could be perf regressions in projects that use TH and unboxed things on GHC <9.2 (which forces us to use object code), as now we have the overhead of serializing the core file in addition to writing out object code. I don't think this is worth any added complexity to fix.

For non TH use cases, I don't think any of the new code paths introduced by this patch should be invoked.

@wz1000
Copy link
Collaborator Author

wz1000 commented Jun 19, 2022

lsp-types benchmarks from CI show a nice reduction in number of rebuilds:

version    name                             userTime             delayedTime             firstBuildTime        averageTimePerResponse   totalTime            ghcRebuilds   maxResidency   allocatedBytes
upstream   edit                             68.34383137499997    10.323516597999998      10.334371703          0.6970121766224486       78.67693306000001    95            301MB          55698MB
HEAD       edit                             72.96970079299999    2.556725e-2             5.532733985           0.6881369898673468       73.00332802          52            276MB          50770MB
upstream   hover                            13.180079563000007   0.3166564680000001      12.829332708          4.152855428571494e-3     13.507315229000001   46            251MB          9263MB
HEAD       hover                            5.209367877999997    0.196952351             4.999792951000001     2.452743602040775e-3     5.411812424000001    3             219MB          3990MB
upstream   hover after edit                 16.226807561999998   72.62041956800002       11.032502892          5.360594148979589e-2     88.85325952100001    101           290MB          63126MB
HEAD       hover after edit                 9.012798             70.83114584299999       5.323865788           3.765507356122449e-2     79.850448532         52            257MB          56876MB
upstream   getDefinition                    11.708442747000001   0.434386321             11.421054226          3.2380240816326624e-3    12.155265844         46            252MB          9371MB
HEAD       getDefinition                    5.441150572000004    0.23985461200000002     5.112820338000001     3.5576397244898358e-3    5.686483675000001    3             218MB          3985MB
upstream   getDefinition after edit         16.72425692399999    63.91054510700001       11.093108735          5.8071333642857055e-2    80.640507521         109           297MB          56701MB
HEAD       getDefinition after edit         10.927045198999998   65.46247111600002       5.377242325           5.740327070408162e-2     76.395617709         53            260MB          51959MB
upstream   completions                      16.024376701999998   0.12638918500000001     14.459607334          1.5972830255102016e-2    16.160324949         46            282MB          12134MB
HEAD       completions                      7.743020277000001    3.7383337e-2            6.252399412           1.5214895551020418e-2    7.786593106000001    3             250MB          7065MB
upstream   completions after edit           21.830183619         63.994075509999995      12.162668197          9.86556277653061e-2      85.83132011500001    106           339MB          60462MB
HEAD       completions after edit           13.18969144          61.474015296            6.1228598750000005    7.211571085714286e-2     74.670201526         52            313MB          52776MB
upstream   code actions                     2.3720257100000004   4.6412799000000005e-2   0.31173037400000003   2.1030310540816333e-2    2.42527778           45            291MB          10190MB
HEAD       code actions                     1.712576749          5.1093743e-2            0.33512016            1.4060921306122447e-2    1.7733261720000002   2             245MB          4876MB
upstream   code actions after edit          65.72750791100002    11.642961312000002      11.943436961000002    0.6673076584285715       77.377336811         94            324MB          54960MB
HEAD       code actions after edit          68.587991455         4.694555815             4.960643374           0.6967999784693877       73.29235393100001    51            293MB          49519MB
upstream   code actions after cradle edit   256.286724468        3.9071791e-2            5.564788900000001     2.5583938700510203       256.333212442        95            482MB          158010MB
HEAD       code actions after cradle edit   250.82462046499998   4.5853073000000015e-2   5.85507109            2.4996945527959182       250.876928326        52            467MB          152667MB
upstream   documentSymbols after edit       13.074759930000003   12.107352305999994      11.55576718           0.12925116065306125      25.192915388000003   48            303MB          18172MB
HEAD       documentSymbols after edit       12.817890320000002   5.993950903             5.242964592           0.1275457322857143       18.833141979         6             261MB          13719MB
upstream   hole fit suggestions             250.11240799599997   3.1923236e-2            17.055141456          2.3781396769285714       250.15273281         95            330MB          206578MB
HEAD       hole fit suggestions             233.84543248400004   2.9465238000000005e-2   9.63315947            2.287884959316327        233.88360630000003   52            306MB          197949MB

@wz1000 wz1000 merged commit dc45afc into master Jun 19, 2022
@michaelpj
Copy link
Collaborator

Is this ultimately going to get into GHC? Or are we going to be on the hook for maintaining this indefinitely?

@wz1000
Copy link
Collaborator Author

wz1000 commented Jun 20, 2022

Is this ultimately going to get into GHC? Or are we going to be on the hook for maintaining this indefinitely?

Fat interface files are likely to be in GHC 9.6

Sign up for free to join this conversation on GitHub. Already have an account? Sign in to comment
Labels
None yet
Projects
None yet
Development

Successfully merging this pull request may close these issues.

None yet

3 participants