Refactor command-line options handling (DynFlags)
At present command-line options are parsed and directly stored into a huge record named
DynFlags. For example, passing
-fspec-constr-recursive=10 will directly set the
specConstrRecursive field of the
DynFlags record to
- some options can be passed per module (cf
- some options can be (un)set interactively in GHCi
- some options can also be read from package environment files
- some options are automatically and dynamically set by the compiler (e.g. with
will soonnow have options per home-unit with the multiple home-units work
- We don't track the provenance of the values stored in DynFlags fields:
- we don't know if it's a default value, a user defined one or an automatically set one
- we don't know how it has been passed by the user (real command line, OPTIONS_GHC pragma, interactively, etc.)
- We do a bad job filtering options that are allowed interactively or not, and in OPTIONS_GHC pragma or not. See #19348.
- We can't easily validate options against others. For example if a user passes
-fasmwe have no way to warn that only the latter will be taken into account.
Add an intermediate AST representation for parsed options:
Options = Seq (Located Option). Use
Locatedto track the provenance of each option. This AST can then be lowered into
cacheOptions :: Options -> DynFlags.
Add support for concatening/appending
Optionswith validation and warning/error reports with location.
Optionsto store parsed
ms_hspp_opts :: Options). Correctly validate options passed this way against the global ones.
Optionvalidation in GHCi. Correctly report options that do nothing. Ideally, make GHCi interpret
Options considering the current state of the interpreter instead of setting some
DynFlagsfields and hoping for no failure.
source :: Optionsfield to
DynFlagswith the invariant that
cacheOptions (source df) == df. [Rename DynFlags into OptionsCache?]
this comment)Project Status (This section added per
Please tick these off as you finish them and list the relevant MR.
Phase 1: Isolation
This is tracked in #17957.
Phase 2: Correctness
Goal of this phase is to add validation to the handshakes between compiler phases. Once
Cmm from Isolation is done,
CmmToLlvm could be picked up by whomever.
Phase 3: Efficiency
Goal of this phase is to use the additions from Correctness to remove runtime checks in guards, since by this point the checks should be held in the type system. And reduce the amount of references carried around that could be redundant, for example if
foo only needs a single field from
PhaseConfig then pass that field rather than the whole config.
This one should be a lot of easy wins but will require lots of perf testing. This one could also be done in parallel after the corresponding checkbox in Correctness is done.