Version 41 (modified by thoughtpolice, 6 years ago) (diff)


New Plugins work

Plugins are a new feature in GHC 7.2.1 that will allow 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:

$ ghc -fplugin=Some.Plugin.Module -fplugin-opt=Some.Plugin.Module:no-fizzbuzz a.hs

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:

Basic overview of the plugins API for Core

Modules can be loaded by GHC as compiler plugins by exposing a declaration called 'plugin' of type 'GhcPlugins.Plugin', which is an ADT containing a function that installs a pass into the Core pipeline.

module Some.Plugin.Module (plugin) where
import GhcPlugins

plugin :: Plugin
plugin = defaultPlugin {
  installCoreToDos = install

-- type CommandLineOption = String

install :: [CommandLineOption] -> [CoreToDo] -> CoreM [CoreToDo]
install _options passes = do

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:

module CSE.Plugin where


install :: [CommandLineOption] -> [CoreToDo] -> CoreM [CoreToDo]
install _ xs = return $ CoreDoPasses [defaultGentleSimplToDo, cse] : xs
  where cse = CoreDoPluginPass "Common Subexpression Elimination" (bindsOnlyPass cseProgram)

cseProgram :: [CoreBind] -> CoreM [CoreBind]
cseProgram binds = do

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.

The Future

Plugins for Cmm

Aside from manipulating the core language, we would also like to manipulate the C-- representation GHC generates for modules too.

TODO fixme

Rough API possibilities

TODO fixme