Plugins are a new feature in GHC 7.2.1 that allows users to write compiler passes (for things like optimizations) over GHC's internal intermediate language, Core.
GHC understands the -fplugin and -fplugin-arg options. You essentially install plugins for GHC by cabal installing them, as they expose a module implementing an interface, and then calling GHC in the form of:
Warning: this can fail with non obvious error messages if in the same directory as the Some.Plugin.Module source; seems GHC tries to use the source instead of the installed package.
Some.Plugin.Module should export a symbol named 'plugin' - see the following repositories for examples that do Common Subexpression Elimination, turn Haskell into a strict language, and implement a loop unroller:
We can think of CoreToDo as being a type synonym for (Core -> Core) - that is, the install function just inserts its own CoreToDo into the list of compiler passes. For example, the CSE pass actually couples a simplification pass, followed by CSE itself into the front of the compilation pipeline:
More specifically, a CoreToDo describes some sort of particular pass over a Core program that can be invoked as many times as you like. For reference, defaultGentlSimplToDo is constructed using CoreDoSimplify. In this case, cse_pass is constructed using CoreDoPluginsPass, which takes a name and a function of type ModGuts -> CoreM ModGuts - ModGuts is a type that represents the 1 module GHC is compiling at any time. You normally want to manipulate the field mg_binds of a ModGuts, which contains all the top-level bindings for the module.
bindsOnlyPass is a function that merely lifts a function over binders to a function over ModGuts. It's the simple case where nothing else from the ModGuts is needed.
More details on plugins for end-users can be found in the users guide.
Plugins for Cmm
Aside from manipulating the core language, we would also like to manipulate the C-- representation GHC generates for modules too.