As part of the refactorings tracked in #21872 we plan to decouple the Core optimization pipeline from the driver code. In addition to that we aim to make the various Core passes independently usable, which in turn means that we try to avoid shared environments as those tend to accumulate fields which are not used by all passes1. This means as well that we try to avoid the need to setup a monadic environment for the passes.
Changes in this PR
CoreMgot removed from all passes and the CoreToDo interpreter. This leaves Core-to-Core plugins as the sole user of this monad - at least in GHC.Core.Opt - and it was therefore moved to the GHC.Plugins namespace. In order to remove coupling even further all
CoreMuses were removed from GHC.Core.Lint, too. The idea behind this is to make
CoreMthe monad of Core plugins and use more specific monads for other parts of the compiler dealing with Core. The remaining code from GHC.Core.Opt.Monad was moved to GHC.Core.Opt.Utils.
In order to reduce coupling
CoreToDois not used by the Core linter and the Core-to-Stg subsystem.
We a new monad
SimplCountMto GHC.Core.Opt.Stats. This is essentially a writer monad used to accumulate the
SimpleCounts in the CoreToDo interpreter.
A new module GHC.Core.EndPass got split from GHC.Core.Lint. Now, GHC.Core.Lint (still a very large module) is just the domain-layer logic to lint Core, nothing more. Conversely, the endPass logic is application-layer logic using the Core linter, and not actually part of the core linter in any sense. The different endPass and linting functions take configuration record and the respective initialization functions in the driver were added.
All references to the driver code where removed from the Specialise pass and it got a config record. The SpecConstr and CallerCC passes got proper configs too and
specConstrProgramare now pure functions. A new module GHC.Core.Opt.CallerCC.Filter got split from GHC.Core.Opt.CallerCC to avoid hs-boot.
In order to reduce partiality in the CoreToDo interpreter we got rid of the
CoreTidyvariants. These were not "core -> core" passes anyways, and so never belonged there. They were just added because it was previously necessary to have a
CoreToDoto use the "end pass" machinery.
Likewise, we got rid of
The Core interpreter got split in several modules:
runCorePasses-> GHC.Core.Opt and GHC.Driver.Core.Opt
runCorePaseslives in the former module while the entrypoint in the driver (
optimizeCoreHsc) are located in the second one. This way we get a nice separation between code that is responsible for planning (i.e. constructing the Core pipeline along with the configurations of the passes to run) and the one for executing the pipeline.
A new note "The architecture of the Core optimizer" was added to GHC.Driver.Core.Opt that explains the big picture of the aforementioned changes.
Fixes #21611 .