5.4. Modes of operation

GHC's behaviour is firstly controlled by a mode flag. Only one of these flags may be given, but it does not necessarily need to be the first option on the command-line. The available modes are:

ghc --interactive

Interactive mode, which is also available as ghci. Interactive mode is described in more detail in Chapter 3, Using GHCi.

ghc --make

In this mode, GHC will build a multi-module Haskell program automatically, figuring out dependencies for itself. If you have a straightforward Haskell program, this is likely to be much easier, and faster, than using make. Make mode is described in Section 5.4.1, “Using ghc ––make.

ghc -e expr

Expression-evaluation mode. This is very similar to interactive mode, except that there is a single expression to evaluate (expr) which is given on the command line. See Section 5.4.2, “Expression evaluation mode” for more details.

ghc -E
ghc -c
ghc -S
ghc -c

This is the traditional batch-compiler mode, in which GHC can compile source files one at a time, or link objects together into an executable. This mode also applies if there is no other mode flag specified on the command line, in which case it means that the specified files should be compiled and then linked to form a program. See Section 5.4.3, “Batch compiler mode”.

ghc -M

Dependency-generation mode. In this mode, GHC can be used to generate dependency information suitable for use in a Makefile. See Section 5.6.11, “Dependency generation”.

ghc --mk-dll

DLL-creation mode (Windows only). See Section 12.6.1, “Creating a DLL”.

ghc --help
ghc -?

Cause GHC to spew a long usage message to standard output and then exit.

ghc --show-iface file

Read the interface in file and dump it as text to stdout. For example ghc --show-iface M.hi.

ghc --supported-languages

Print the supported language extensions.

ghc --info

Print information about the compiler.

ghc --version
ghc -V

Print a one-line string including GHC's version number.

ghc --numeric-version

Print GHC's numeric version number only.

ghc --print-libdir

Print the path to GHC's library directory. This is the top of the directory tree containing GHC's libraries, interfaces, and include files (usually something like /usr/local/lib/ghc-5.04 on Unix). This is the value of $libdir in the package configuration file (see Section 5.8, “ Packages ”).

5.4.1. Using ghc ––make

When given the ––make option, GHC will build a multi-module Haskell program by following dependencies from one or more root modules (usually just Main). For example, if your Main module is in a file called Main.hs, you could compile and link the program like this:

ghc ––make Main.hs

The command line may contain any number of source file names or module names; GHC will figure out all the modules in the program by following the imports from these initial modules. It will then attempt to compile each module which is out of date, and finally, if there is a Main module, the program will also be linked into an executable.

The main advantages to using ghc ––make over traditional Makefiles are:

  • GHC doesn't have to be restarted for each compilation, which means it can cache information between compilations. Compiling a multi-module program with ghc ––make can be up to twice as fast as running ghc individually on each source file.

  • You don't have to write a Makefile.

  • GHC re-calculates the dependencies each time it ismas">Section 8.12.5, “INLINE and NOINLINE pragmas”. The INLINE pragma affects the specialised version of the function (only), and applies even if the function is recursive. The motivating example is this:

    -- A GADT for arrays with type-indexed representation
    data Arr e where
      ArrInt :: !Int -> ByteArray# -> Arr Int
      ArrPair :: !Int -> Arr e1 -> Arr e2 -> Arr (e1, e2)
    
    (!:) :: Arr e -> Int -> e
    {-# SPECIALISE INLINE (!:) :: Arr Int -> Int -> Int #-}
    {-# SPECIALISE INLINE (!:) :: Arr (a, b) -> Int -> (a, b) #-}
    (ArrInt _ ba)     !: (I# i) = I# (indexIntArray# ba i)
    (ArrPair _ a1 a2) !: i      = (a1 !: i, a2 !: i)
    

    Here, (!:) is a recursive function that indexes arrays of type Arr e. Consider a call to (!:) at type (Int,Int). The second specialisation will fire, and the specialised function will be inlined. It has two calls to (!:), both at type Int. Both these calls fire the first specialisation, whose body is also inlined. The result is a type-based unrolling of the indexing function.

    Warning: you can make GHC diverge by using SPECIALISE INLINE on an ordinarily-recursive function.

    Note: In earlier versions of GHC, it was possible to provide your own specialised function for a given type:

    {-# SPECIALIZE hammeredLookup :: [(Int, value)] -> Int -> value = intLookup #-}
    

    This feature has been removed, as it is now subsumed by the RULES pragma (see Section 8.13.4, “Specialisation ”).

8.12.9. SPECIALIZE instance pragma

Same idea, except for instance declarations. For example:

instance (Eq a) => Eq (Foo a) where { 
   {-# SPECIALIZE instance Eq (Foo [(Int, Bar)]) #-}
   ... usual stuff ...
 }

The pragma must occur inside the where part of the instance declaration.

Compatible with HBC, by the way, except perhaps in the placement of the pragma.

8.12.10. UNPACK pragma

The UNPACK indicates to the compiler that it should unpack the contents of a constructor field into the constructor itself, removing a level of indirection. For example:

data T = T {-# UNPACK #-} !Float
           {-# UNPACK #-} !Float

will create a constructor T containing two unboxed floats. This may not always be an optimisation: if the T constructor is scrutinised and the floats passed to a non-strict function for example, they will have to be reboxed (this is done automatically by the compiler).

Unpacking constructor fields should only be used in conjunction with -O, in order to expose unfoldings to the compiler so the reboxing can be removed as often as possible. For example:

f :: T -> Float
f (T f1 f2) = f1 + f2

The compiler will avoid reboxing f1 and f2 by inlining + on floats, but only when -O is on.

Any single-constructor data is eligible for unpacking; for example

data T = T {-# UNPACK #-} !(Int,Int)

will store the two Ints directly in the T constructor, by flattening the pair. Multi-level unpacking is also supported:

data T = T {-# UNPACK #-} !S
data S = S {-# UNPACK #-} !Int {-# UNPACK #-} !Int

will store two unboxed Int#s directly in the T constructor. The unpacker can see through newtypes, too.

If a field cannot be unpacked, you will not get a warning, so it might be an idea to check the generated code with -ddump-simpl.

See also the -funbox-strict-fields flag, which essentially has the effect of adding {-# UNPACK #-} to every strict constructor field.

./usr/share/doc/ghc6-doc/users_guide/modes.html0000644000000000000000000004230511315435727020312 0ustar rootroot5.4. Modes of operation

5.4. Modes of operation