{"id":16956409,"url":"https://github.com/bgamari/ghc-dump","last_synced_at":"2025-03-22T13:31:55.396Z","repository":{"id":41852926,"uuid":"88437865","full_name":"bgamari/ghc-dump","owner":"bgamari","description":"A GHC plugin and library for analysing GHC Core","archived":false,"fork":false,"pushed_at":"2025-02-04T17:10:17.000Z","size":7941,"stargazers_count":54,"open_issues_count":8,"forks_count":10,"subscribers_count":11,"default_branch":"master","last_synced_at":"2025-03-18T11:48:09.951Z","etag":null,"topics":["ghc","haskell"],"latest_commit_sha":null,"homepage":null,"language":"Haskell","has_issues":true,"has_wiki":null,"has_pages":null,"mirror_url":null,"source_name":null,"license":null,"status":null,"scm":"git","pull_requests_enabled":true,"icon_url":"https://github.com/bgamari.png","metadata":{"files":{"readme":"README.mkd","changelog":null,"contributing":null,"funding":null,"license":null,"code_of_conduct":null,"threat_model":null,"audit":null,"citation":null,"codeowners":null,"security":null,"support":null}},"created_at":"2017-04-16T19:34:55.000Z","updated_at":"2025-01-27T10:29:13.000Z","dependencies_parsed_at":"2023-01-18T11:17:55.427Z","dependency_job_id":null,"html_url":"https://github.com/bgamari/ghc-dump","commit_stats":null,"previous_names":[],"tags_count":3,"template":false,"template_full_name":null,"repository_url":"https://repos.ecosyste.ms/api/v1/hosts/GitHub/repositories/bgamari%2Fghc-dump","tags_url":"https://repos.ecosyste.ms/api/v1/hosts/GitHub/repositories/bgamari%2Fghc-dump/tags","releases_url":"https://repos.ecosyste.ms/api/v1/hosts/GitHub/repositories/bgamari%2Fghc-dump/releases","manifests_url":"https://repos.ecosyste.ms/api/v1/hosts/GitHub/repositories/bgamari%2Fghc-dump/manifests","owner_url":"https://repos.ecosyste.ms/api/v1/hosts/GitHub/owners/bgamari","download_url":"https://codeload.github.com/bgamari/ghc-dump/tar.gz/refs/heads/master","host":{"name":"GitHub","url":"https://github.com","kind":"github","repositories_count":244962912,"owners_count":20539245,"icon_url":"https://github.com/github.png","version":null,"created_at":"2022-05-30T11:31:42.601Z","updated_at":"2022-07-04T15:15:14.044Z","host_url":"https://repos.ecosyste.ms/api/v1/hosts/GitHub","repositories_url":"https://repos.ecosyste.ms/api/v1/hosts/GitHub/repositories","repository_names_url":"https://repos.ecosyste.ms/api/v1/hosts/GitHub/repository_names","owners_url":"https://repos.ecosyste.ms/api/v1/hosts/GitHub/owners"}},"keywords":["ghc","haskell"],"created_at":"2024-10-13T22:14:57.434Z","updated_at":"2025-03-22T13:31:55.135Z","avatar_url":"https://github.com/bgamari.png","language":"Haskell","funding_links":[],"categories":[],"sub_categories":[],"readme":"# ghc-dump: A tool for analysing GHC Core\n\n`ghc-dump` is a library, GHC plugin, and set of tools for recording and\nanalysing GHC's Core representation. The plugin is compatible with GHC 7.10\nthrough 9.0, exporting a consistent (albeit somewhat lossy) representation\nacross these versions. The AST is encoded as CBOR, which is small and easy to\ndeserialise.\n\n## Dumping Core from compilation\n\nThe GHC plugin `GhcDump.Plugin` provides a Core-to-Core plugin which dumps a\nrepresentation of the Core AST to a file after every Core-to-Core pass. To use\nit on a `cabal` package add the following to the relevant stanza of your cabal\nfile (e.g. the `library` stanza in the case of a library):\n```\nbuild-depends: ghc-dump-core\nghc-options: -fplugin GhcDump.Plugin\n```\n\nNow building the project will produce a number of `.cbor` files in the\n`dist-newstyle` directory, one for each step of GHC's Core-to-Core pipeline.\n\n```\n$ cabal build\n$ ls **/*.cbor\ndist-newstyle/build/x86_64-linux/ghc-8.10.4/aeson-1.5.6.0/build/attoparsec-iso8601/src/Data/Attoparsec/Time/Internal.pass-0000.cbor\ndist-newstyle/build/x86_64-linux/ghc-8.10.4/aeson-1.5.6.0/build/attoparsec-iso8601/src/Data/Attoparsec/Time/Internal.pass-0001.cbor\ndist-newstyle/build/x86_64-linux/ghc-8.10.4/aeson-1.5.6.0/build/attoparsec-iso8601/src/Data/Attoparsec/Time/Internal.pass-0002.cbor\ndist-newstyle/build/x86_64-linux/ghc-8.10.4/aeson-1.5.6.0/build/attoparsec-iso8601/src/Data/Attoparsec/Time/Internal.pass-0003.cbor\ndist-newstyle/build/x86_64-linux/ghc-8.10.4/aeson-1.5.6.0/build/attoparsec-iso8601/src/Data/Attoparsec/Time/Internal.pass-0004.cbor\ndist-newstyle/build/x86_64-linux/ghc-8.10.4/aeson-1.5.6.0/build/attoparsec-iso8601/src/Data/Attoparsec/Time/Internal.pass-0005.cbor\n...\n```\n\nHere we see a `pass-N.cbor` file was produced for each Core-to-Core pass.\n\nWe can produce a brief summary of these files using the `summarize` mode of the `ghc-dump`\nCLI tool:\n```\nName                                Terms    Types    Coerc.   Previous phase\nData/Attoparsec/Time/Internal.pass-0000.cbor\n                                    124      63       9        desugar\nData/Attoparsec/Time/Internal.pass-0001.cbor\n                                    138      59       38       Simplifier: Max iterations = 4\n                                                                           SimplMode {Phase = InitialPhase [Gentle],\n                                                                                      inline,\n                                                                                      rules,\n                                                                                      eta-expand,\n                                                                                      no case-of-case}\nData/Attoparsec/Time/Internal.pass-0002.cbor\n                                    138      59       38       Specialise:\nData/Attoparsec/Time/Internal.pass-0003.cbor\n                                    142      59       38       Float out(FOS {Lam = Just 0, Consts = True, OverSatApps = False}):\nData/Attoparsec/Time/Internal.pass-0004.cbor\n                                    118      41       38       Simplifier: Max iterations = 4\n                                                                           SimplMode {Phase = 2 [main],\n                                                                                      inline,\n                                                                                      rules,\n                                                                                      eta-expand,\n                                                                                      case-of-case}\nData/Attoparsec/Time/Internal.pass-0005.cbor\n                                    112      32       38       Simplifier: Max iterations = 4\n                                                                           SimplMode {Phase = 1 [main],\n                                                                                      inline,\n                                                                                      rules,\n                                                                                      eta-expand,\n                                                                                      case-of-case}\n```\nHere we see for each dump file:\n\n * the file name\n * the size of the program measured in terms, types, and coercions\n * the name of the phase that produced the program\n\n## Analysis in GHCi\n\nOne can then load this into `ghci` for analysis,\n```\n$ ghci\nGHCi, version 8.3.20170413: http://www.haskell.org/ghc/  :? for help\nLoaded GHCi configuration from /home/ben/.ghci\nλ\u003e import GhcDump.Repl as Dump\nλ\u003e mod \u003c- readDump \"Test.pass-0.cbor\"\nλ\u003e pretty mod\nmodule Main where\n\nnsoln :: Int-\u003e Int\n{- Core Size{terms=98 types=66 cos=0 vbinds=0 jbinds=0} -}\nnsoln =\n  λ nq →\n    let safe =\n          λ x d ds →\n            case ds of wild {\n              [] → GHC.Types.True\n              : q l →\n                GHC.Classes.\u0026\u0026\n...\n```\n\n## Analysis with CLI tool\n\nAlternatively, the `ghc-dump` utility can be used to render the representation\nin human-readable form. For instance, we can filter the dump to include only\ntop-level binders containing `main` in its name,\n```\n$ ghc-dump show --filter='.*main.*' Test.pass-0.cbor\n```\nYou can conveniently summarize the top-level bindings of the program,\n```\n$ ghc-dump list-bindings --sort=terms Test.pass-0.cbor\nName                 Terms  Types  Coerc. Type\nnsoln                98     66     0      Int-\u003e Int\nmain                 30     28     0      IO ()\n$trModule            5      0      0      Module\nmain                 2      1      0      IO ()\n...\n```\n","project_url":"https://awesome.ecosyste.ms/api/v1/projects/github.com%2Fbgamari%2Fghc-dump","html_url":"https://awesome.ecosyste.ms/projects/github.com%2Fbgamari%2Fghc-dump","lists_url":"https://awesome.ecosyste.ms/api/v1/projects/github.com%2Fbgamari%2Fghc-dump/lists"}