Compiler and runtime system ways in GHC
GHC can compile programs in different ways.
For instance, a program might be compiled with profiling enabled (
-prof), or for multithreaded execution (
-threaded), or maybe making some debugging tools available (
-debug, see Debugging/RuntimeSystem for a description).
There are two types of GHC ways, RTS-only ways and full ways.
Runtime system (RTS) ways affect the way that the runtime system is built. As an example,
-threadedis a runtime system way. When you compile a program with
-threaded, it will be linked to a (precompiled) version of the RTS with multithreading enabled.
Obviously, the compiler's RTS must have been built for this way (the threaded RTS is activated by default BTW). In customised builds, an RTS way can be added in the build configuration
mk/build.mk (see mk/build.mk.sample), by adding its short name to the variable
- Full ways
Full compiler ways are ways which affect both the generated code and the runtime system that runs it.
The profiling way
-prof is such a way. The machine code of a program compiled for profiling differs from a normal version's code by all code that gathers the profiling information, and the runtime system has additional functionality to access and report this information. Therefore, all libraries used in a profiling-enabled program need to also have profiling enabled, i.e. a separate library version for profiling needs to be installed to compile the program with
prof. (If the library was installed without this profiling version, the program cannot be linked).
In customised builds, a full way is added in the build configuration
mk/build.mk by adding its tag to the variable
Available ways in a standard GHC
Ways are identified internally by a way name, and enabled by specific compilation flags. In addition, there are short names (tags) for the available ways, mainly used by the build system.
Here is a table of available ways in a standard GHC, as of May 2015.
|Way flag||Way name||Tag||Type||Description|
|-||-||v||Full||(vanilla way) default|
|-threaded||WayThreaded||thr||RTS||multithreaded runtime system|
|-debug||WayDebug||debug||RTS||debugging, enables trace messages and extra checks|
|-prof||WayProf||p||Full||profiling, enables cost centre stacks and profiling reports|
|-eventlog||WayEventLog||l||RTS||Event logging (for ghc-events, threadscope, and EdenTV)|
The standard (vanilla) way of GHC has a name (vanilla), but it could (probably?) even be switched off in a custom build if desired.
Obviously, the libraries would still need to be built in the vanilla way for all RTS-only ways, so one would need
GhcLibWays=v when building any
other RTS-only way.
The code (see below) contains another way, for Glasgow parallel Haskell, which is currently unmaintained (
Ways for parallel execution on clusters and multicores
The parallel Haskell runtime system for Eden (available from http://github.com/jberthold/ghc) defines several RTS-only ways for Eden. All these ways execute the RTS in multiple instances with distributed heaps, they differ in the communication substrate (and consequently in the platform).
|Way flag||Way name||Tag||Type||communication (OS)|
|-parcp||WayParCp||pc||RTS||OS-native shared memory (Windows/Linux)|
|-parms||WayParMSlot||ms||RTS||Windows mail slots (Windows)|
The alert reader might have noticed that combinations like "threaded with dynamic linking" or "profiled with eventlog" are not covered in the table. Some ways can be used together (most prominently, debugging can be used together with any other way), others are mutually excluding each other (like profiling with eventlog).
The allowed combinations are defined inside the compiler, in compiler/GHC/Driver/Session.hs. Which brings us to discussing some of the internals.
When compiling ghc, the available combinations are listed in
mk/config.mk.in; as of 7.10.3:
thr : threaded thr_p : threaded profiled debug : debugging (compile with -g for the C compiler, and -DDEBUG) debug_p : debugging profiled thr_debug : debugging threaded thr_debug_p : debugging threaded profiled l : event logging thr_l : threaded and event logging
For example, to build both the profiling and the debug version of the profiling RTS (
lHSrts_debug_p), you can add
GhcRTSWays += p debug_p
Ways are defined in compiler/GHC/Driver/Session.hs as a Haskell data structure
dynamic_flags defines the actual flag strings for the ghc invocation (like
-threaded), which activate the respective
The short name tags for ways are defined in
wayTag. The tags are used in the suffixes of *.o and *.a files for RTS and libraries, for instance
*.p_o for profiling,
*.l_o for eventlog.
A number of other functions in there customise behaviour depending on the ways.
wayOptc which sets some options for the C compiler, like
-DTRACING for the
However, this is not the full truth. For instance, there is no
-DDEBUG for the debug way here, but the RTS is full of
In mk/ways.mk, we find all the short names and all combinations enumerated, and some more options are defined here (
WAY_*_HC_OPTS). These definitions are for the driver script, and pass on the right (long-name) options to the Haskell compiler to activate what is inside DynFlags (like -prof for WAY_p_HC_OPTS).
Here we find
WAY_debug_HC_OPTS= -static -optc-DDEBUG -ticky -DTICKY_TICKY
so we can learn that ticky profiling is activated by compiling with
(TODO be more precise on where the options from ways.mk are used.)