Skip to content

Increase compiler modularity

(See also the wiki page https://gitlab.haskell.org/ghc/ghc/-/wikis/Make-GHC-codebase-more-modular)

This is a meta-ticket about the avoidance of direct access to compiler state (DynFlags, HscEnv, etc.). Many functions implicitly access DynFlags to query command line options, package state, linker state, etc. making the code not modular.

As a stronger motivation: I want to fix #14335 (support for compiler plugins with cross-compilation). It should have been pretty straightforward to use two package states instead of one (one for the host compiler and another for the target code). Sadly this isn't currently possible because the package state stored in DynFlags is accessed very indirectly (e.g. to get the effective wired-in unit ids on disk when pretty-printing messages for the user, etc.). There are a lot of other examples of this kind.

All the work done in this direction will be beneficial to make GHC multi-target, multi-session and to improve cross-compilation support (cf https://github.com/hsyl20/ghc-cross-compilation for what we would like to improve).

Three different but related goals regarding DynFlags:

  1. Make it clearer which bits of DynFlags are used where. Eg pass smaller record to SDoc. Ameliorates the symptoms of not having (2); and is generally a good idea.
  2. Stop making DynFlags depend on TcM etc. It should just be an abstract syntax tree. Move mutable state, caches &c, to Session (= HscEnv).
  3. Remove mutable state from DynFlags, and keep it somewhere else. But where? HscEnv?

Old Tasks:

  • Remove DynFlags from pretty-print SDocContext: #10143 (closed)
  • Remove unsafeGlobalDynFlags #14597
  • Add SDocContext instead of directly accessing DynFlags in SDoc
  • Don't access the (target) package state when pretty-printing UnitId, Module, etc.
  • Use Platform instead of DynFlags in code generators
  • Fix handling of -dppr-debug
  • Remove Outputable instances for things that need some context to be printed
  • Fix binary blob handling (GHC.CmmToAsm.Ppr.pprBytes)
  • Don't store state into DynFlags. Use HscEnv or another env instead.
  • Remove DumpFlags from Logger (c.f. logHasDumpFlag). They must be passed in each subsystem configuration explicitly instead. [Sylvain: it was easier to keep DumpFlags into the Logger to untangle Logger and the rest of DynFlags first. But now we should complete this.]

Current tasks, making subsystems not use DynFlags and HscEnv:

A crude test is

git grep -l -E '(Driver.Session|DynFlags|dflags|HscEnv|hsc_env)' ':(exclude)compiler/GHC/Driver' compiler/

to find module in need of being fixed up.

Isolate DynFlags module by module, phase by phase in the compiler. we'll try to proceed in this ordering (deepest part of the compiler up) based on the log file in @doyougnu's previous comments in #20730.

C-- & STG

Core optimizations

core-opt-modulegraph

Green modules

Purple modules

Can do punting on the monad, perhaps:

The monad issue:

Better to do after:

Misc

Linker modules except for GHC.Linker.Loader seem like perhaps good "leaf" modules to tackle.

  • GHC.Linker
  • GHC.Linker.Dynamic
  • GHC.Linker.ExtraObj
  • GHC.Linker.Loader Probably best to skip
  • GHC.Linker.MacOS
  • GHC.Linker.Static
  • GHC.Linker.Static.Utils
  • GHC.Linker.Types
  • GHC.Linker.Unit: !8370 (closed)
  • GHC.Linker.Windows
  • GHC.SysTools.Process: !11437 (closed)
Edited by jeffrey young
To upload designs, you'll need to enable LFS and have an admin enable hashed storage. More information