GHC can dump its optimized intermediate code (said to be in “Core” format) to a file as a side-effect of compilation. Core files, which are given the suffix .hcr, can be read and processed by non-GHC back-end tools. The Core format is formally described in An External Representation for the GHC Core Language, and sample tools (in Haskell) for manipulating Core files are available in the GHC source distribution directory /fptools/ghc/utils/ext-core. Note that the format of .hcr files is different (though similar) to the Core output format generated for debugging purposes (Section 4.18).
The Core format natively supports notes which you can add to your source code using the CORE pragma (see Section 7.7).
Generate .hcr files.
GHC can also read in External Core files as source; just give the .hcr file on the command line, instead of the .hs or .lhs Haskell source. A current infelicity is that you need to give teh -fglasgow-exts flag too, because ordinary Haskell 98, when translated to External Core, uses things like rank-2 types.