The Mercury User's Guide

Copyright (C) 1995-1997 The University of Melbourne.

Permission is granted to make and distribute verbatim copies of this manual provided the copyright notice and this permission notice are preserved on all copies.

Permission is granted to copy and distribute modified versions of this manual under the conditions for verbatim copying, provided also that the entire resulting derived work is distributed under the terms of a permission notice identical to this one.

Permission is granted to copy and distribute translations of this manual into another language, under the above conditions for modified versions.

Introduction

This document describes the compilation environment of Mercury. It describes how to use `mmc', the Mercury compiler; how to use `mmake', the "Mercury make" program, a tool built on top of ordinary or GNU make to simplify the handling of Mercury programs; and how to use Prolog to debug Mercury programs.

We strongly recommend that programmers use `mmake' rather than invoking `mmc' directly, because `mmake' is generally easier to use and avoids unnecessary recompilation.

Since the Mercury implementation is essentially a native-code compiler which happens to compile via GNU C, not an interpreter, debugging of compiled Mercury programs would require a dedicated Mercury debugger program - or at least some significant extensions to gdb. It would also require the Mercury compiler to arrange for the object code to contain suitable debugging information. Although it is possible to debug the intermediate C code, this is not productive, since the intermediate C code is extremely low-level and bears little resemblance to the source code. As an alternative, Mercury programmers may wish to use a Prolog system to execute their Mercury programs in order to gain access to this facility. The feasibility of this technique is dependent upon the program being written in the intersection of the Prolog and Mercury languages, which is possible because the two languages have almost the same syntax. The Mercury implementation allows you to run a Mercury program using NU-Prolog or SICStus Prolog (see section Using Prolog).

File naming conventions

Mercury source files should be named `*.m'. Each Mercury source file must contain a single Mercury module whose name should be the same as the filename without the `.m' extension.

Files ending in `.int', `.int2' and `.int3' are interface files; these are generated automatically by the compiler, using the `--make-interface' (or `--make-int') and `--make-short-interface' (or `--make-short-int') options. Files ending in `.opt' are interface files used in inter-module optimization, and are created using the `--make-optimization-interface' (or `--make-opt-int') option.

Since the interface of a module changes less often than its implementation, the `.int', `.int2', `.int3', and `.opt' files will remain unchanged on many compilations. To avoid unnecessary recompilations of the clients of the module, the timestamps on the these files are updated only if their contents change. `.date', `.date3' and `.optdate' files associated with the module are used as date stamps; they are used when deciding whether the interface files need to be regenerated.

Files ending in `.d' are automatically-generated Makefile fragments which contain the dependencies for a module. Files ending in `.dep' are automatically-generated Makefile fragments which contain the rules for an entire program.

In the source code for the Mercury runtime library, we use a few files ending in `.mod'; these are preprocessed using the perl script `mod2c' to produce C files. (Originally the Mercury compiler also produced `.mod' files, but now we compile directly to C.)

As usual, `.c' files are C source code, `.h' files are C header files, `.o' files are object code, `.no' files are NU-Prolog object code, and `.ql' files are SICStus Prolog object code. In addition, `.pic_o' files are object code files that contain position-independent code (PIC).

Using the Mercury compiler

Following a long Unix tradition, the Mercury compiler is called `mmc' (for "Melbourne Mercury Compiler"). Some of its options (e.g. `-c', `-o', and `-I') have a similar meaning to that in other Unix compilers.

Arguments to `mmc' that name Mercury source files may omit the `.m' suffix.

To compile a program which consists of just a single module, use the command

mmc module.m

Unlike traditional Unix compilers, however, `mmc' will put the executable into a file called `module', not `a.out'.

For programs that consist of more than one module, we strongly recommend that you use Mmake (see section Using Mmake). Mmake will perform all the steps listed below, using automatic dependency analysis to ensure that things are done in the right order, and that steps are not repeated unnecessarily.

To compile a module to object code without creating an executable, use the command

mmc -c module.m

`mmc' will put the object code into a file called `module.o'. It also will leave the intermediate C code in a file called `module.c'.

Before you can compile a module, you must make the interface files for the modules that it imports (directly or indirectly). You can create the interface files for one or more modules using the commands

mmc --make-short-int module1.m module2.m ...
mmc --make-int module1.m module2.m ...

If you are going to compile with `--intermodule-optimization' enabled, then you also need to create the optimization interface files.

mmc --make-opt-int module1.m module2.m ...

Given that you have made all the interface files, one way to create an executable for a multi-module program is to compile all the modules at the same time using the command

mmc module1.m module2.m ...

This will by default put the resulting executable in `module1', but you can use the `-o filename' option to specify a different name for the output file, if you so desire.

The other way to create an executable for a multi-module program is to compile each module separately using `mmc -c', and then link the resulting object files together. The linking is a two stage process.

First, you must create and compile an initialization file, which is a C source file containing calls to automatically generated initialization functions contained in the C code of the modules of the program:

c2init module1.c module2.c ... > main_module_init.c,
mgnuc -c main_module_init.c

The `c2init' command line must contain the name of the C file of every module in the program. The order of the arguments is not important. The `mgnuc' command is the Mercury GNU C compiler; it is a shell script that invokes the GNU C compiler `gcc' with the options appropriate for compiling the C programs generated by Mercury.

You then link the object code of each module with the object code of the initialization file to yield the executable:

ml -o main_module module1.o module2.o ... main_module_init.o

`ml', the Mercury linker, is another shell script that invokes a C compiler with options appropriate for Mercury, this time for linking. `ml' also pipes any error messages from the linker through `mdemangle', the Mercury symbol demangler, so that error messages refer to predicate and function names from the Mercury source code rather than to the names used in the intermediate C code.

The above command puts the executable in the file `main_module'. The same command line without the `-o' option would put the executable into the file `a.out'.

`mmc' and `ml' both accept a `-v' (verbose) option. You can use that option to see what is actually going on. For the full set of options of `mmc', see section Invocation.

Running programs

Once you have created an executable for a Mercury program, you can go ahead and execute it. You may however wish to specify certain options to the Mercury runtime system. The Mercury runtime accepts options via the `MERCURY_OPTIONS' environment variable. Setting `MERCURY_OPTIONS' to `-h' will list the available options. The most useful of these are the options that set the size of the stacks.

The det stack and the nondet stack are allocated fixed sizes at program start-up. The default size is 512k for the det stack and 128k for the nondet stack, but these can be overridden with the `-sd' and `-sn' options, whose arguments are the desired sizes of the det and nondet stacks respectively, in units of kilobytes. On operating systems that provide the appropriate support, the Mercury runtime will ensure that stack overflow is trapped by the virtual memory system.

With conservative garbage collection (the default), the heap will start out with a zero size, and will be dynamically expanded as needed, When not using conservative garbage collection, the heap has a fixed size like the stacks. The default size is 4 Mb, but this can be overridden with the `-sh' option.

Using Prolog

Since the current Mercury implementation does not yet provide any useful support for debugging, we recommend that you use a Prolog system for debugging your Mercury programs. However, there is no point in using a Prolog debugger to track down a bug that can be detected statically by the Mercury compiler. The command

mmc -e module1.m ...

causes the Mercury compiler to perform all its syntactic and semantic checks on the named modules, but not to generate any code.

In our experience, omitting that step is not wise. If you do omit it, you often waste a lot of time debugging problems that the compiler could have detected for you.

Using NU-Prolog

You can compile a Mercury source module using NU-Prolog via the command

mnc module1.m ...

`mnc' is the Mercury variant of `nc', the NU-Prolog compiler. It adapts nc to compile Mercury programs, e.g. by defining do-nothing predicates for the various Mercury declarations (which are executed by nc).

Some invocations of `mnc' will result in warnings such as

Warning: main is a system predicate.
It shouldn't be used as a non-terminal.

Such warnings should be ignored.

`mnc' compiles the modules it is given into NU-Prolog bytecode, stored in files with a `.no' suffix. You can link these together using the command

mnl -o main_module module1.no ...

Ignore any warnings such as

Warning: main/2 redefined
Warning: solutions/2 redefined
Warning: !/0 redefined

`mnl', the Mercury NU-Prolog linker, will put the executable (actually a shell script invoking a save file) into the file `main_module.nu'. This can be executed normally using

./main_module.nu arguments

Alternatively, one can execute such programs using `mnp', the Mercury version of np, the NU-Prolog interpreter. The command

mnp

will start up the Mercury NU-Prolog interpreter. Inside the interpreter, you can load your source files with a normal consulting command such as

['module.m'].

You can also use the `--debug' option to `mnl' when linking. This will produce an executable whose entry point is the NU-Prolog interpreter, rather than main/2 in your program.

In both cases, you can start executing your program by typing

r("program-name arguments").

at the prompt of the NU-Prolog interpreter.

All the NU-Prolog debugging commands work as usual. The most useful ones are the trace and spy commands at the main prompt to turn on complete or selective tracing respectively, and the l (leap), s (skip), and r (redo) commands of the tracer. For more information, see the NU-Prolog documentation.

By default the debugger only displays the top levels of terms; you can use the `|' command to enter an interactive term browser. (Within the term browser, type `h.' for help.) Also note that in the debugger, we use a version of error/1 which fails rather than aborting after printing the "Software Error:" message. This makes debugging easier, but will of course change the behaviour after an error occurs.

Using SICStus Prolog

Using SICStus Prolog is similar to using NU-Prolog, except that the commands to use are `msc', `msl', and `msp' rather than `mnc', `mnl', and `mnp'.

Due to shortcomings in SICStus Prolog (in particular, the lack of backslash escapes in character strings), you need to use `sicstus_conv' to convert Mercury `.m' files to the `.pl' files that SICStus Prolog expects before you can load them into the interpreter. The command to use is just

sicstus_conv module.m

By default, `msc' compiles files to machine code using SICStus Prolog's `fastcode' mode. If space is more important than speed, you can use the `--mode compactcode' option, which instructs msc to use SICStus Prolog's `compactcode' mode, which compiles files to a bytecode format.

Hazards of using Prolog

There are some Mercury programs which are not valid Prolog programs. In particular, Mercury programs that use functions will generally not be valid Prolog programs (with the exception that the basic arithmetic functions such as `+', `-', etc., will work fine if you use Prolog's `is' predicate).

Also, Mercury will always reorder goals to ensure that they are mode-correct (or report a mode error if it cannot do so), but Prolog systems will not always do so, and will sometimes just silently give the wrong result. For example, in Mercury the following predicate will usually succeed, whereas in Prolog it will always fail.

:- pred p(list(int)::in, list(int)::out) is semidet.
p(L0, L) :-
        L \= [],
        q(L0, L).

:- pred q(list(int)::in, list(int)::out) is det.

The reason is that in Mercury, the test `L \= []' is reordered to after the call to q/2, but in Prolog, it executes even though L is not bound, and consequently the test always fails.

NU-Prolog has logical alternatives to the non-logical Prolog operations, and since Mercury supports both syntaxes, you can use NU-Prolog's logical alternatives to avoid this problem. However, during the development of the Mercury compiler we had to abandon their use for efficiency reasons.

Another hazard is that NU-Prolog does not have a garbage collector.

Using Mmake

Mmake, short for "Mercury Make", is a tool for building Mercury programs that is built on top of ordinary or GNU Make (1). With Mmake, building even a complicated Mercury program consisting of a number of modules is as simple as

mmake main-module.depend
mmake main-module

Mmake only recompiles those files that need to be recompiled, based on automatically generated dependency information. Most of the dependencies are stored in `.d' files that are automatically recomputed every time you recompile, so they are never out-of-date. A little bit of the dependency information is stored in `.dep' files which are more expensive to recompute. The `mmake main-module.depend' command which recreates the `main-module.dep' file needs to be repeated only when you add or remove a module from your program, and there is no danger of getting an inconsistent executable if you forget this step -- instead you will get a compile or link error.

`mmake' allows you to build more than one program in the same directory. Each program must have its own `.dep' file, and therefore you must run `mmake program.depend' for each program.

If there is a file called `Mmake' or `Mmakefile' in the current directory, Mmake will include that file in its automatically-generated Makefile. The `Mmake' file can override the default values of various variables used by Mmake's builtin rules, or it can add additional rules, dependencies, and actions.

Mmake's builtin rules are defined by the file `prefix/lib/mercury/mmake/Mmake.rules' (where prefix is `/usr/local/mercury-version' by default, and version is the version number, e.g. `0.6'), as well as the rules in the automatically-generated `.dep' files. These rules define the following targets:

`main-module.depend'
Creates the file `main-module.dep' from `main-module.m' and the modules it imports. This step must be performed first.
`main-module.ints'
Ensure that the interface files for main-module and its imported modules are up-to-date. (If the underlying `make' program does not handle transitive dependencies, this step may be necessary before attempting to make `main-module' or `main-module.check'; if the underlying `make' is GNU Make, this step should not be necessary.)
`main-module.check'
Perform semantic checking on main-module and its imported modules. Error messages are placed in `.err' files.
`main-module'
Compiles and links main-module using the Mercury compiler. Error messages are placed in `.err' files.
`main-module.split'
Compiles and links main-module using the Mercury compiler, with the Mercury compiler's `--split-c-files' option enabled. See section Output-level (LLDS -> C) optimization options for more information about `--split-c-files'.
`main-module.nu'
Compiles and links main-module using NU-Prolog.
`main-module.nu.debug'
Compiles and links main-module using NU-Prolog. The resulting executable will start up in the NU-Prolog interpreter rather than calling main/2.
`main-module.sicstus'
Compiles and links main-module using SICStus Prolog.
`main-module.sicstus.debug'
Compiles and links main-module using SICStus Prolog. The resulting executable will start up in the SICStus Prolog interpreter rather than calling main/2.
`libmain-module'
Builds a library whose top-level module is main-module. This will build a static object library, a shared object library (for platforms that support it), and the necessary interface files. See section Libraries for more information.
`main-module.clean'
Removes the automatically generated files that contain the compiled code of the program and the error messages produced by the compiler. Specifically, this will remove all the `.c', `.s', `.o', `.no', `.ql', and `.err' files belonging to the named main-module or its imported modules.
`main-module.change_clean'
Removes files that need updating when changing garbage collection method or when enabling inter-module optimization. Specifically, this will remove all the `.c', `.s', `.o', `.dep' and executable files belonging to the named main-module or its imported modules.
`main-module.realclean'
Removes all the automatically generated files. In addition to the files removed by main-module.clean, this removes the `.date', `.int', `.int2', `.int3', `.opt', `.optdate', `.date3', `.d', and `.dep' belonging to one of the modules of the program, and also the various possible executables for the program --- `main-module', `main-module.nu', `main-module.nu.save', `main-module.nu.debug', `main-module.nu.debug.save', `main-module.sicstus', and `main-module.sicstus.debug'.
`clean'
This makes `main-module.clean' for every main-module for which there is a `main-module.dep' file in the current directory.
`realclean'
This makes `main-module.realclean' for every main-module for which there is a `main-module.dep' file in the current directory.

The variables used by the builtin rules (and their default values) are defined in the file `prefix/lib/mercury/mmake/Mmake.vars', however these may be overridden by user `Mmake' files. Some of the more useful variables are:

MAIN_TARGET
The name of the default target to create if `mmake' is invoked with any target explicitly named on the command line.
MC
The executable that invokes the Mercury compiler.
MCFLAGS and EXTRA_MCFLAGS
Flags to pass to the Mercury compiler.
MGNUC
The executable that invokes the C compiler.
MGNUCFLAGS and EXTRA_MGNUCFLAGS
Flags to pass to the C compiler.
ML
The executable that invokes the linker.
MLFLAGS and EXTRA_MLFLAGS
Flags to pass to the linker.

Other variables also exist - see `prefix/lib/mercury/mmake/Mmake.vars' for a complete list.

If you wish to temporarily change the flags passed to an executable, rather than setting the various `FLAGS' variables directly, one can supply a `EXTRA_' variable. When defining a `FLAGS' option directly (in your own `Mmake' file), it is recommended you include the `EXTRA_' version at the end. This is particularly intended for use where a shell script needs to call mmake and add an extra parameter, without interfering with the flag settings in the `Mmake' file.

MCFLAGS = -O6 $(EXTRA_MCFLAGS)

Note that since Mmake is built on top of Make or GNU Make, you can make use of the features supported by the underlying Make. In particular, GNU Make has support for running jobs in parallel, which is very useful if you have a machine with more than one CPU.

Libraries

Often you will want to use a particular set of Mercury modules in more than one program. The Mercury implementation includes support for developing libraries, i.e. sets of Mercury modules intended for reuse. It allows separate compilation of libraries and, on many platforms, it supports shared object libraries.

Writing libraries

A Mercury library is identified by a top-level module, which must directly or indirectly use (import) all of the modules in that library. It may be as simple as this `mypackage.m' file:

:- module mypackage.
:- import_module foo, bar, baz.

Building libraries

Generally Mmake will do most of the work of building libraries automatically. Here's a sample Mmakefile for creating a library.

MAIN_TARGET = libmypackage
depend: mypackage.depend

The Mmake target `libfoo' is a built-in target for creating a library whose top-level module is `foo.m'. The automatically generated Make rules for the target `libfoo' will create all the files needed to use the library.

Mmake will create static (non-shared) object libraries and, on most platforms, shared object libraries; however, we do not yet support the creation of dynamic link libraries (DLLs) on Windows. Static libraries are created using the standard tools `ar' and `ranlib'. Shared libraries are created using the `--make-shared-lib' option to `ml'. The automatically-generated Make rules for `libmypackage' will look something like this:

libmypackage: libmypackage.a libmypackage.so \
		$(mypackage.ints) $(mypackage.opts) mypackage.init

libmypackage.a: $(mypackage.os)
	rm -f libmypackage.a
	$(AR) $(ARFLAGS) libmypackage.a $(mypackage.os)
	$(RANLIB) $(RANLIBFLAGS) mypackage.a

libmypackage.so: $(mypackage.pic_os)
	$(ML) $(MLFLAGS) --make-shared-lib -o libmypackage.so \
		$(mypackage.pic_os) $(MLLIBS)

libmypackage.init:
	...

clean:
	rm -f libmypackage.a libmypackage.so

If necessary, you can override the default definitions of the variables such as `ML', `MLFLAGS', and `MLLIBS' to customize the way shared libraries are built. Similarly `AR', `ARFLAGS', `RANLIB', and `RANLIBFLAGS' control the way static libraries are built.

Note that to use a library, as well as the shared or static object library, you also need the interface files. That's why the `libmypackage' target builds `$(mypackage.ints)'. Also, if the people using the library are going to use intermodule optimization, you need the intermodule optimization interfaces. That's why the `libmypackage' target builds `$(mypackage.opts)'. In addition, with certain compilation grades, programs will need to execute some startup code to initialize the library; the `mypackage.init' file contains information about initialization code for the library.

On some platforms, shared objects must be created using position independent code (PIC), which requires passing some special options to the C compiler. On these platforms, Mmake will create `.pic_o' files, and `$(mypackage.pic_os)' will contain a list of the `.pic_o' files for the library whose top-level module is `mypackage'. On other platforms, position independent code is the default, and `$(mypackage.pic_os)' will just be the same as `$(mypackage.os)', which contains a list of the `.o' files for that module.

Installing libraries

If you want, once you have built a library, you could then install (i.e. copy) the shared object library, the static object library, the interface files and the initialization file into a different directory, or into several different directories, for that matter -- though it is probably easiest for the users of the library if you keep them in a single directory. Or alternatively, you could package them up into a `tar', `shar', or `zip' archive and ship them to the people who will use the library.

Using libraries

To use a library, you need to set the Mmake variables `VPATH', `MCFLAGS', `MLFLAGS', `MLLIBS', and `C2INITFLAGS' to specify the name and location of the library or libraries that you wish to use. For example, if you want to link in the libraries `mypackage' and `myotherlib', which were built in the directories `/some/directory/mypackage' and `/some/directory/myotherlib' respectively, you could use the following settings:

# Specify the location of the `mypackage' and `myotherlib' directories
MYPACKAGE_DIR = /some/directory/mypackage
MYOTHERLIB_DIR = /some/directory/myotherlib

# The following stuff tells Mmake to use the two libraries
VPATH = $(MYPACKAGE_DIR):$(MYOTHERLIB_DIR):$(MMAKE_VPATH)
MCFLAGS = -I$(MYPACKAGE_DIR) -I$(MYOTHERLIB_DIR) $(EXTRA_MCFLAGS)
MLFLAGS = -R$(MYPACKAGE_DIR) -R$(MYOTHERLIB_DIR) $(EXTRA_MLFLAGS) \
          -L$(MYPACKAGE_DIR) -L$(MYOTHERLIB_DIR)
MLLIBS = -lmypackage -lmyotherlib $(EXTRA_MLLIBS)
C2INITFLAGS = $(MYPACKAGE_DIR)/mypackage.init \
              $(MYOTHERLIB_DIR)/myotherlib.init

Here `VPATH' is a colon-separated list of path names specifying directories that Mmake will search for interface files. The `-I' options in `MCFLAGS' tell `mmc' where to find the interface files. The `-R' options in `MLFLAGS' tell the loader where to find shared libraries, and the `-L' options tell the linker where to find libraries. (Note that the `-R' options must precede the `-L' options.) The `-l' options tell the linker which libraries to link with. The extras arguments to `c2init' specified in the `C2INITLFLAGS' variable tell `c2init' where to find the `.init' files for the libraries, so that it can generate appropriate initialization code.

The example above assumes that the static object library, shared object library, interface files and initialization file are for each Mercury library being used all put in a single directory, which is probably the simplest way of organizing things, but the Mercury implementation does not require that.

Profiling

Introduction

The Mercury profiler `mprof' is a tool which can be used to analyze a Mercury program's performance, so that the programmer can determine which predicates or functions are taking up a disproportionate amount of the execution time.

To obtain the best trade-off between productivity and efficiency, programmers should not spend too much time optimizing their code until they know which parts of the code are really taking up most of the time. Only once the code has been profiled should the programmer consider making optimizations that would improve efficiency at the expense of readability or ease of maintenance.

A good profiler is a tool that should be part of every software engineer's toolkit.

Building profiled applications

To enable profiling, your program must be built in a `.prof' grade. For example, if the default grade on your system is `asm_fast.gc', then to compile with profiling enabled, use grade `asm_fast.gc.prof'. You can do this by setting the `GRADE' variable in your Mmake file, e.g. by adding the line `GRADE=asm_fast.gc.prof'. See section Compilation model options for more information about the different grades.

Enabling profiling has several effects. Firstly, it causes the compiler to generate slightly modified code which counts the number of times each predicate or function is called, and for every call, records the caller and callee. Secondly, your program will be linked with versions of the library and runtime that were compiled with profiling enabled. (It also has the effect for each source file the compiler generates the static call graph for that file in `module.prof'.)

Creating the profile

The next step is to run your program. The profiling version of your program will collect profiling information during execution, and save this information in the files `Prof.Counts', `Prof.Decls', and `Prof.CallPair'. (`Prof.Decl' contains the names of the procedures and their associated addresses, `Prof.CallPair' records the number of times each procedure was called by each different caller, and `Prof.Counts' records the number of times that execution was in each procedure when a profiling interrupt occurred.)

It is also possible to combine profiling results from multiple runs of your program. You can do by running your program several times, and typing `mprof_merge_counts' after each run.

Due to a known timing-related bug in our code, you may occasionally get segmentation violations when running your program with time profiling enabled. If this happens, just run it again -- the problem occurs only very rarely.

Displaying the profile

To display the profile, just type `mprof'. This will read the `Prof.*' files and display the flat profile in a nice human-readable format. If you also want to see the call graph profile, which takes a lot longer to generate, type `mprof -c'.

Note that `mprof' can take quite a while to execute, and will usually produce quite a lot of output, so you will usually want to redirect the output into a file with a command such as `mprof > mprof.out'.

Analysis of results

The profile output consists of three major sections. These are named the call graph profile, the flat profile and the alphabetic listing.

The call graph profile presents the local call graph of each procedure. For each procedure it shows the parents (callers) and children (callees) of that procedure, and shows the execution time and call counts for each parent and child. It is sorted on the total amount of time spent in the procedure and all of its descendents (i.e. all of the procedures that it calls, directly or indirectly.)

The flat profile presents the just execution time spent in each procedure. It does not count the time spent in descendents of a procedure.

The alphabetic listing just lists the procedures in alphabetical order, along with their index number in the call graph profile, so that you can quickly find the entry for a particular procedure in the call graph profile.

The profiler works by interrupting the program at frequent intervals, and each time recording the currently active procedure and its caller. It uses these counts to determine the proportion of the total time spent in each procedure. This means that the figures calculated for these times are only a statistical approximation to the real values, and so they should be treated with some caution.

The time spent in a procedure and its descendents is calculated by propagating the times up the call graph, assuming that each call to a procedure from a particular caller takes the same amount of time. This assumption is usually reasonable, but again the results should be treated with caution.

Note that any time spent in a C function (e.g. time spent in `GC_malloc()', which does memory allocation and garbage collection) is credited to the Mercury procedure that called that C function.

Here is a small portion of the call graph profile from an example program.

                                  called/total       parents
index  %time    self descendents  called+self    name           index
                                  called/total       children

                                                     <spontaneous>
[1]    100.0    0.00        0.75       0         call_engine_label [1] 
                0.00        0.75       1/1           do_interpreter [3]

-----------------------------------------------

                0.00        0.75       1/1           do_interpreter [3]
[2]    100.0    0.00        0.75       1         io__run/0(0) [2] 
                0.00        0.00       1/1           io__init_state/2(0) [11]
                0.00        0.74       1/1           main/2(0) [4]

-----------------------------------------------

                0.00        0.75       1/1           call_engine_label [1]
[3]    100.0    0.00        0.75       1         do_interpreter [3] 
                0.00        0.75       1/1           io__run/0(0) [2]

-----------------------------------------------

                0.00        0.74       1/1           io__run/0(0) [2]
[4]     99.9    0.00        0.74       1         main/2(0) [4] 
                0.00        0.74       1/1           sort/2(0) [5]
                0.00        0.00       1/1           print_list/3(0) [16]
                0.00        0.00       1/10          io__write_string/3(0) [18]

-----------------------------------------------

                0.00        0.74       1/1           main/2(0) [4]
[5]     99.9    0.00        0.74       1         sort/2(0) [5] 
                0.05        0.65       1/1           list__perm/2(0) [6]
                0.00        0.09   40320/40320       sorted/1(0) [10]

-----------------------------------------------

                                       8             list__perm/2(0) [6]
                0.05        0.65       1/1           sort/2(0) [5]
[6]     86.6    0.05        0.65       1+8      list__perm/2(0) [6] 
                0.00        0.60    5914/5914        list__insert/3(2) [7]
                                       8             list__perm/2(0) [6]

-----------------------------------------------

                0.00        0.60    5914/5914        list__perm/2(0) [6]
[7]     80.0    0.00        0.60    5914         list__insert/3(2) [7] 
                0.60        0.60    5914/5914        list__delete/3(3) [8]

-----------------------------------------------

                                   40319             list__delete/3(3) [8]
                0.60        0.60    5914/5914        list__insert/3(2) [7]
[8]     80.0    0.60        0.60    5914+40319  list__delete/3(3) [8] 
                                   40319             list__delete/3(3) [8]

-----------------------------------------------

                0.00        0.00       3/69283       tree234__set/4(0) [15]
                0.09        0.09   69280/69283       sorted/1(0) [10]
[9]     13.3    0.10        0.10   69283         compare/3(0) [9] 
                0.00        0.00       3/3           __Compare___io__stream/0(0) [20]
                0.00        0.00   69280/69280       builtin_compare_int/3(0) [27]

-----------------------------------------------

                0.00        0.09   40320/40320       sort/2(0) [5]
[10]    13.3    0.00        0.09   40320         sorted/1(0) [10] 
                0.09        0.09   69280/69283       compare/3(0) [9]

-----------------------------------------------

The first entry is `call_engine_label' and its parent is `<spontaneous>', meaning that it is the root of the call graph. (The first three entries, `call_engine_label', `do_interpreter', and `io__run/0' are all part of the Mercury runtime; `main/2' is the entry point to the user's program.)

Each entry of the call graph profile consists of three sections, the parent procedures, the current procedure and the children procedures.

Reading across from the left, for the current procedure the fields are:

The predicate or function names are not just followed by their arity but also by their mode in brackets. A mode of zero corresponds to the first mode declaration of that predicate in the source code. For example, `list__delete/3(3)' corresponds to the `(out, out, in)' mode of `list__delete/3'.

Now for the parent and child procedures the self and descendent time have slightly different meanings. For the parent procedures the self and descendent time represent the proportion of the current procedure's self and descendent time due to that parent. These times are obtained using the assumption that each call contributes equally to the total time of the current procedure.

Invocation

This section contains a brief description of all the options available for `mmc', the Mercury compiler. Sometimes this list is a little out-of-date; use `mmc --help' to get the most up-to-date list.

Invocation overview

mmc is invoked as

mmc [options] modules

For module names, the trailing `.m' is optional.

Options are either short (single-letter) options preceded by a single `-', or long options preceded by `--'. Options are case-sensitive. We call options that do not take arguments flags. Single-letter flags may be grouped with a single `-', e.g. `-vVc'. Single-letter flags may be negated by appending another trailing `-', e.g. `-v-'. Long flags may be negated by preceding them with `no-', e.g. `--no-verbose'.

Warning options

-w
--inhibit-warnings
Disable all warning messages.

--halt-at-warn.
This option causes the compiler to treat all warnings as if they were errors. This means that if any warning is issued, the compiler will not generate code -- instead, it will return a non-zero exit status.

--halt-at-syntax-error.
This option causes the compiler to halt immediately after syntax checking and not do any semantic checking if it finds any syntax errors in the program.

--no-warn-singleton-variables
Don't warn about variables which only occur once.

--no-warn-missing-det-decls
For predicates that are local to a module (those that are not exported), don't issue a warning if the `pred' or `mode' declaration does not have a determinism annotation. Use this option if you want the compiler to perform automatic determinism inference for non-exported predicates.

--no-warn-det-decls-too-lax
Don't warn about determinism declarations which could have been stricter.

--no-warn-nothing-exported
Don't warn about modules whose interface sections have no exported predicates, functions, insts, modes or types.

--warn-unused-args
Warn about predicate or function arguments which are not used.

--warn-interface-imports
Warn about modules imported in the interface which are not used in the interface.

--warn-missing-opt-files
Warn about `.opt' files that cannot be opened.

--warn-non-stratification
Warn about possible non-stratification of the predicates/functions in the module. Non-stratification occurs when a predicate/function can call itself negatively through some path along its call graph.

--no-warn-simple-code
Disable warnings about constructs which are so simple that they are likely to be programming errors.

--warn-duplicate-calls
Warn about multiple calls to a predicate with the same input arguments.

Verbosity options

-v
--verbose
Output progress messages at each stage in the compilation.

-V
--very-verbose
Output very verbose progress messages.

-E
--verbose-error-messages
Explain error messages. Asks the compiler to give you a more detailed explanation of any errors it finds in your program.

-S
--statistics
Output messages about the compiler's time/space usage. At the moment this option implies `--no-trad-passes', so you get information at the boundaries between phases of the compiler.

-T
--debug-types
Output detailed debugging traces of the type checking.

-N
--debug-modes
Output detailed debugging traces of the mode checking.

--debug-det, --debug-determinism
Output detailed debugging traces of determinism analysis.

--debug-opt
Output detailed debugging traces of the optimization process.

--debug-vn <n>
Output detailed debugging traces of the value numbering optimization pass. The different bits in the number argument of this option control the printing of different types of tracing messages.

Output options

These options are mutually exclusive. If more than one of these options is specified, only the first in this list will apply. If none of these options are specified, the default action is to compile and link the modules named on the command line to produce an executable.

-M
--generate-dependencies
Output "Make"-style dependencies for the module and all of its dependencies to `module.dep'.
--generate-module-order
Output the strongly connected components of the module dependency graph in top-down order to `module.order'. Implies `--generate-dependencies'.

-i
--make-int
--make-interface
Write the module interface to `module.int'. Also write the short interface to `module.int2'.

--make-short-int
--make-short-interface
Write the unqualified version of the short interface to `module.int3'.

--make-opt-int
--make-optimization-interface
Write information used for inter-module optimization to `module.opt'.

-G
--convert-to-goedel
Convert the Mercury code to Goedel. Output to file `module.loc'. The translation is not perfect; some Mercury constructs cannot be easily translated into Goedel.

-P
--pretty-print
--convert-to-mercury
Convert to Mercury. Output to file `module.ugly'. This option acts as a Mercury ugly-printer. (It would be a pretty-printer, except that comments are stripped and nested if-then-elses are indented too much -- so the result is rather ugly.)

--typecheck-only
Just check the syntax and type-correctness of the code. Don't invoke the mode analysis and later passes of the compiler. When converting Prolog code to Mercury, it can sometimes be useful to get the types right first and worry about modes second; this option supports that approach.

-e
--errorcheck-only
Check the module for errors, but do not generate any code.

-C
--compile-to-c
--compile-to-C
Generate C code in `module.c', but not object code.

-c
--compile-only
Generate C code in `module.c' and object code in `module.o' but do not attempt to link the named modules.

Auxiliary output options

--no-assume-gmake
When generating `.dep' files, generate Makefile fragments that use only the features of standard make; do not assume the availability of GNU Make extensions. This makes these files significantly larger.
--generate-trace
Include code to generate an execution trace in the C code output by the compiler.
--generate-bytecode
Output a bytecode form of the module for use by an experimental debugger.
--generate-prolog
Convert the program to Prolog. Output to file `module.pl' or `module.nl' (depending the the dialect).
--prolog-dialect dialect
Target the named dialect if generating Prolog code. The dialect should be one of `sicstus', `nu'.
--auto-comments
Output comments in the `module.c' file. This is primarily useful for trying to understand how the generated C code relates to the source code, e.g. in order to debug the compiler. The code may be easier to understand if you also use the `--no-llds-optimize' option.

-n
--line-numbers
Output source line numbers in the generated code. This option only works in conjunction with the `--convert-to-goedel' and `--convert-to-mercury' options.

--show-dependency-graph
Write out the dependency graph to module.dependency_graph.

-d stage
--dump-hlds stage
Dump the HLDS (intermediate representation) after the specified stage number or stage name to `module.hlds_dump.num-name'. Stage numbers range from 1 to 99; not all stage numbers are valid. The special stage name `all' causes the dumping of all stages. Multiple dump options accumulate.

-D fields
--verbose-dump-hlds fields
With `--dump-hlds', include extra detail in the dump. Each type of detail is included in the dump if its corresponding letter occurs in the option argument. These details are: a - argument modes in unifications, b - builtin flags on calls, c - contexts of goals and types, d - determinism of goals, f - follow_vars sets of goals, i - instmap deltas of goals, l - pred/mode ids and unify contexts of called predicates, n - nonlocal variables of goals, p - pre-birth, post-birth, pre-death and post-death sets of goals, r - resume points of goals, s - store maps of goals, t - results of termination analysis, u - unification categories, v - variable numbers in variable names. The special argument value "all" will cause the printing of all these fields.

Language semantics options

See the Mercury language reference manual for detailed explanations of these options.

--no-reorder-conj
Execute conjunctions left-to-right except where the modes imply that reordering is unavoidable.

--no-reorder-disj
Execute disjunctions strictly left-to-right.

--fully-strict
Don't optimize away loops or calls to error/1.

--infer-types
If there is no type declaration for a predicate or function, try to infer the type, rather than just reporting an error.

--infer-modes
If there is no mode declaration for a predicate, try to infer the modes, rather than just reporting an error.

--no-infer-det, --no-infer-determinism
If there is no determinism declaration for a procedure, don't try to infer the determinism, just report an error.

Compilation model options

The following compilation options affect the generated code in such a way that the entire program must be compiled with the same setting of these options, and it must be linked to a version of the Mercury library which has been compiled with the same setting. (Attempting to link object files compiled with different settings of these options will generally result in an error at link time, typically of the form `undefined symbol MR_grade_...' or `symbol MR_runtime_grade multiply defined'.)

The options below must be passed to `mgnuc' and `ml' as well as to `mmc'.

-s grade
--grade grade
Select the compilation model. The grade should be a base grade with zero or more grade modifiers appended. The base grades are `none', `reg', `jump', `asm_jump', `fast', and `asm_fast'. The grade modifiers are `.gc', `.prof', `.proftime', `.profcalls', `.tr', and `.debug'. The `.prof', `.proftime', and `.profcalls' grade modifiers are mutually exclusive; only one of those three may be specified. If a grade includes more than one grade modifier, the grade modifiers must be given in the same order as the order they are listed here. The default grade is system-dependent; it is chosen at installation time by `configure', the auto-configuration script, but can be overridden with the `MERCURY_DEFAULT_GRADE' environment variable if desired. Depending on your particular installation, only a subset of these possible grades will have been installed. Attempting to use a grade which has not been installed will result in an error at link time. (The error message will typically be something like `ld: can't find library for -lmercury'.) The tables below show the options that are selected by each base grade and grade modifier; they are followed by descriptions of those options.
Grade
Options implied.
`none'
None.
`reg'
--gcc-global-registers.
`jump'
--gcc-nonlocal-gotos.
`fast'
--gcc-global-registers --gcc-nonlocal-gotos.
`asm_jump'
--gcc-nonlocal-gotos --asm-labels.
`asm_fast'
--gcc-global-registers --gcc-nonlocal_gotos --asm-labels.
Grade modifier
Options implied.
`.gc'
--gc conservative.
`.prof'
--profiling.
`.proftime'
--profile-time.
`.profcalls'
--profile-calls.
`.tr'
--use-trail.
`.debug'
--debug.

--gcc-global-registers (grades: reg, fast, asm_fast)
--no-gcc-global-registers (grades: none, jump, asm_jump)
Specify whether or not to use GNU C's global register variables extension.

--gcc-non-local-gotos (grades: jump, fast, asm_jump, asm_fast)
--no-gcc-non-local-gotos (grades: none, reg)
Specify whether or not to use GNU C's "labels as values" extension.

--asm-labels (grades: asm_jump, asm_fast)
--no-asm-labels (grades: none, reg, jump, fast)
Specify whether or not to use GNU C's asm extensions for inline assembler labels.

--gc {none, conservative, accurate}
--garbage-collection {none, conservative, accurate}
Specify which method of garbage collection to use. Grades containing `.gc' use `--gc conservative', other grades use `--gc none'. `accurate' is not yet implemented.

--tags {none, low, high}
(This option is not intended for general use.) Specify whether to use the low bits or the high bits of each word as tag bits (default: low).

--num-tag-bits n
(This option is not intended for general use.) Use n tag bits. This option is required if you specify `--tags high'. With `--tags low', the default number of tag bits to use is determined by the auto-configuration script.

--profiling (grades: any grade containing `.prof')
Enable profiling. Insert profiling hooks in the generated code, and also output some profiling information (the static call graph) to the file `module.prof'. See section Profiling.

--profile-calls (grades: any grade containing `.profcalls')
Similar to `--profiling', except that this option only gathers call counts, not timing information. Useful on systems where time profiling is not supported (e.g. MS Windows).

--profile-time (grades: any grade containing `.proftime')
Similar to `--profiling', except that this option only gathers timing information, not call counts. For the results to be useful, call counts for an identical run of your program need to be gathered using `--profiling' or `--profile-calls'. The only advantage of using `--profile-time' and `--profile-calls' to gather timing information and call counts in seperate runs, rather than just using `--profiling' to gather them both at once, is that the former method can give slightly more accurate timing results. because with the latter method the code inserted to record call counts has a small effect on the execution speed.

--debug (grades: any grade containing `.debug')
Enable debugging. Pass the `-g' flag to the C compiler, instead of `-DSPEED', to enable debugging of the generated C code. This option also implies `--no-c-optimize'. Debugging support is currently extremely primitive - this option is probably not useful to anyone except the Mercury implementors. We recommend that you use instead use `mnp' or `msp'. See section Using Prolog for details.

--args {old, compact}
--arg-convention {old, compact}
(This option is not intended for general use.) Use the specified argument passing convention in the generated low-level C code. With the `simple' convention, the nth argument is passed in or out using register rn. With the `compact' convention, the nth input argument is passed using register rn and the nth output argument is returned using register rn. The `compact' convention, which is the default, generally leads to more efficient code.

--no-type-layout
(This option is not intended for general use.) Don't output base_type_layout structures or references to them. This option will generate smaller executables, but will not allow the use of code that uses the layout information (e.g. `functor', `arg'). Using such code will result in undefined behaviour at runtime. The C code also needs to be compiled with `-DNO_TYPE_LAYOUT'.

--pic-reg (grades: any grade containing `.pic_reg')
[For Unix with intel x86 architecture only.] Select a register usage convention that is compatible with position-independent code (gcc's `-fpic' option). This is necessary when using shared libraries on Intel x86 systems running Unix. On other systems it has no effect.

Code generation options

--no-trad-passes
The default `--trad-passes' completely processes each predicate before going on to the next predicate. This option tells the compiler to complete each phase of code generation on all predicates before going on the next phase on all predicates.

--no-reclaim-heap-on-nondet-failure
Don't reclaim heap on backtracking in nondet code.

--no-reclaim-heap-on-semidet-failure
Don't reclaim heap on backtracking in semidet code.

--cc compiler-name
Specify which C compiler to use.

--c-include-directory dir
Specify the directory containing the Mercury C header files.

--cflags options
Specify options to be passed to the C compiler.

--fact-table-max-array-size size
Specify the maximum number of elements in a single `pragma fact_table' data array (default: 1024). The data for fact tables is placed into multiple C arrays, each with a maximum size given by this option. The reason for doing this is that most C compilers have trouble compiling very large arrays.

--fact-table-hash-percent-full percentage
Specify how full the `pragma fact_table' hash tables should be allowed to get. Given as an integer percentage (valid range: 1 to 100, default: 90). A lower value means that the compiler will use larger tables, but there will generally be less hash collisions, so it may result in faster lookups.

--have-delay-slot
(This option is not intended for general use.) Assume that branch instructions have a delay slot.

--num-real-r-regs n
(This option is not intended for general use.) Assume r1 up to rn are real general purpose registers.

--num-real-f-regs n
(This option is not intended for general use.) Assume f1 up to fn are real floating point registers.

--num-real-r-temps n
(This option is not intended for general use.) Assume that n non-float temporaries will fit into real machine registers.

--num-real-f-temps n
(This option is not intended for general use.) Assume that n float temporaries will fit into real machine registers.

Optimization options

Overall optimization options

-O n
--opt-level n
--optimization-level n
Set optimization level to n. Optimization levels range from -1 to 6. Optimization level -1 disables all optimizations, while optimization level 6 enables all optimizations except for the cross-module optimizations listed below. In general, there is a trade-off between compilation speed and the speed of the generated code. When developing, you should normally use optimization level 0, which aims to minimize compilation time. It enables only those optimizations that in fact usually reduce compilation time. The default optimization level is level 2, which delivers reasonably good optimization in reasonable time. Optimization levels higher than that give better optimization, but take longer, and are subject to the law of diminishing returns. The difference in the quality of the generated code between optimization level 5 and optimization level 6 is very small, but using level 6 may increase compiation time and memory requirements dramatically. Note that if you want the compiler to perform cross-module optimizations, then you must enable them separately; the cross-module optimizations are not enabled by any `-O' level, because they affect the compilation process in ways that require special treatment by `mmake'.

--opt-space
--optimize-space
Turn on optimizations that reduce code size and turn off optimizations that significantly increase code size.

--intermodule-optimization
Perform inlining and higher-order specialization of the code for predicates or functions imported from other modules.

--enable-termination
--enable-term
Enable termination analysis. Termination analysis analyses each mode of each predicate to see whether it terminates. `pragma terminates', `pragma does_not_terminate' and `pragma check_termination' pragmas have no effect unless termination analysis is enabled. When using termination, `--intermodule-optimization' should be enabled, as it greatly improves the accuracy of the analysis.

--check-termination
--check-term
--chk-term
Enable termination analysis, and emit warnings for some predicates or functions that cannot be proved to terminate. In many cases the compiler is unable to prove termination the problem is either a lack of information about the termination properties of other predicates, or because the program used language constructs (such as higher order calls) which could not be analysed. In these cases the compiler does not emit a warning of non-termination, as it is likely to be spurious.

--verbose-check-termination
--verb-check-term
--verb-chk-term
Enable termination analysis, and emit warnings for all predicates or functions that cannot be proved to terminate.

--split-c-files
Generate each C function in its own C file, so that the linker will optimize away unused code. This has the same effect as `--optimize-dead-procs', except that it works globally at link time, rather than over a single module, so it does a much better job of eliminating unused procedures. This option significantly increases compilation time, link time, and intermediate disk space requirements, but in return reduces the size of the final executable, typically by about 10-20%. This option is only useful with `--procs-per-c-function 1'. N.B. When using `mmake', the `--split-c-files' option should not be placed in the `MCFLAGS' variable. Instead, use the `MODULE.split' target, i.e. type `mmake foo.split' rather than `mmake foo'.

High-level (HLDS -> HLDS) optimization options

These optimizations are high-level transformations on our HLDS (high-level data structure).

--no-inlining
Disable all forms of inlining.
--no-inline-simple
Disable the inlining of simple procedures.
--no-inline-single-use
Disable the inlining of procedures called only once.
--inline-compound-threshold threshold
Inline a procedure if its size (measured roughly in terms of the number of connectives in its internal form), multiplied by the number of times it is called, is below the given threshold.
--inline-simple-threshold threshold
Inline a procedure if its size is less than the given threshold.
--intermod-inline-simple-threshold threshold
Similar to --inline-simple-threshold, except used to determine which predicates should be included in `.opt' files. Note that changing this between writing the `.opt' file and compiling to C may cause link errors, and too high a value may result in reduced performance.

--no-common-struct
Disable optimization of common term structures.

--no-common-goal
Disable optimization of common goals. At the moment this optimization detects only common deconstruction unifications. Disabling this optimization reduces the class of predicates that the compiler considers to be deterministic.

--no-follow-code
Don't migrate builtin goals into branched goals.

--optimize-unused-args
Remove unused predicate arguments. The compiler will generate more efficient code for polymorphic predicates.

--intermod-unused-args
Perform unused argument removal across module boundaries. This option implies `--optimize-unused-args' and `--intermodule-optimization'.

--optimize-higher-order
Specialize calls to higher-order predicates where the higher-order arguments are known.

--optimize-constant-propagation
Evaluate constant expressions at compile time.

--optimize-constructor-last-call
Enable the optimization of "last" calls that are followed by constructor application.

--optimize-dead-procs.
Enable dead predicate elimination.

--excess-assign
Remove excess assignment unifications.

--optimize-duplicate-calls
Optimize away multiple calls to a predicate with the same input arguments.

--optimize-saved-vars
Reorder goals to minimize the number of variables that have to be saved across calls.

Medium-level (HLDS -> LLDS) optimization options

These optimizations are applied during the process of generating low-level intermediate code from our high-level data structure.

--no-static-ground-terms
Disable the optimization of constructing constant ground terms at compile time and storing them as static constants.

--no-smart-indexing
Generate switches as a simple if-then-else chains; disable string hashing and integer table-lookup indexing.

--dense-switch-req-density percentage
The jump table generated for an atomic switch must have at least this percentage of full slots (default: 25).

--dense-switch-size size
The jump table generated for an atomic switch must have at least this many entries (default: 4).

--lookup-switch-req-density percentage
The lookup tables generated for an atomic switch in which all the outputs are constant terms must have at least this percentage of full slots (default: 25).

--lookup-switch-size size
The lookup tables generated for an atomic switch in which all the outputs are constant terms must have at least this many entries (default: 4).

--string-switch-size size
The hash table generated for a string switch must have at least this many entries (default: 8).

--tag-switch-size size
The number of alternatives in a tag switch must be at least this number (default: 3).

--try-switch-size size
The number of alternatives in a try-chain switch must be at least this number (default: 3).

--no-middle-rec
Disable the middle recursion optimization.

--no-simple-neg
Don't generate simplified code for simple negations.

--no-follow-vars
Don't optimize the assignment of registers in branched goals.

Low-level (LLDS -> LLDS) optimization options

These optimizations are transformations that are applied to our low-level intermediate code before emitting C code.

--no-llds-optimize
Disable the low-level optimization passes.

--no-optimize-peep
Disable local peephole optimizations.

--no-optimize-jumps
Disable elimination of jumps to jumps.

--no-optimize-fulljumps
Disable elimination of jumps to ordinary code.

--no-optimize-labels
Disable elimination of dead labels and code.

--optimize-dups
Enable elimination of duplicate code.

--optimize-value-number
Perform value numbering on extended basic blocks.

--pred-value-number
Extend value numbering to whole procedures, rather than just basic blocks.

--no-optimize-frames
Disable stack frame optimizations.

--no-optimize-delay-slot
Disable branch delay slot optimizations.

--optimize-repeat n
Iterate most optimizations at most n times (default: 3).

--optimize-vnrepeat n
Iterate value numbering at most n times (default: 1).

Output-level (LLDS -> C) optimization options

These optimizations are applied during the process of generating C intermediate code from our low-level data structure.

--no-emit-c-loops
Use only gotos -- don't emit C loop constructs.

--use-macro-for-redo-fail
Emit the fail or redo macro instead of a branch to the fail or redo code in the runtime system.

--procs-per-c-function n
Don't put the code for more than n Mercury procedures in a single C function. The default value of n is one. Increasing n can produce slightly more efficient code, but makes compilation slower. Setting n to the special value zero has the effect of putting all the procedures in a single function, which produces the most efficient code but tends to severely stress the C compiler.

Object-level (C -> object code) optimization options

These optimizations are applied during the process of compiling the generated C code to machine code object files.

If you are using Mmake, you need to pass these options to `mgnuc' rather than to `mmc'.

--no-c-optimize
Don't enable the C compiler's optimizations.

--inline-alloc
Inline calls to `GC_malloc()'. This can improve performance a fair bit, but may significantly increase code size. This option has no effect if `--gc conservative' is not set or if the C compiler is not GNU C.

Miscellaneous options

-I dir
--search-directory dir
Append dir to the list of directories to be searched for imported modules.
--intermod-directory dir
Append dir to the list of directories to be searched for `.opt' files.
--use-search-directories-for-intermod
Append the arguments of all -I options to the list of directories to be searched for `.opt' files.

-?
-h
--help
Print a usage message.

Link options

-o filename
--output-file filename
Specify the name of the final executable. (The default executable name is the same as the name of the first module on the command line, but without the `.m' extension.)

--link-flags options
Specify options to be passed to `ml', the Mercury linker.

-L directory
--library-directory directory
Append dir to the list of directories in which to search for libraries.
-l library
--library library
Link with the specified library.
--link-object object
Link with the specified object file.

Environment variables

The shell scripts in the Mercury compilation environment will use the following environment variables if they are set. There should be little need to use these, because the default values will generally work fine.

MERCURY_DEFAULT_GRADE
The default grade to use if no `--grade' option is specified.

MERCURY_OPTIONS
A list of options for the Mercury runtime that gets linked into every Mercury program. Options are available to set the size of the different memory areas, and to enable various debugging traces. Set `MERCURY_OPTIONS' to `-h' for help.

MERCURY_C_INCL_DIR
Directory for the Mercury C header files (`*.h').

MERCURY_INT_DIR
Directory for the Mercury library interface files (`*.int', `*.int2', `*.int3' and `*.opt').

MERCURY_NC_BUILTIN
Filename of the Mercury `nc'-compatibility file (nc_builtin.nl).

MERCURY_C_LIB_DIR
Base directory containing the Mercury libraries (`libmer.a' and possibly `libmer.so') for each configuration and grade. The libraries for each configuration and grade should be in the subdirectory config/grade of $MERCURY_C_LIB_DIR.

MERCURY_NONSHARED_LIB_DIR
For IRIX 5, this environment variable can be used to specify a directory containing a version of libgcc.a which has been compiled with `-mno-abicalls'. See the file `README.IRIX-5' in the Mercury source distribution.

MERCURY_MOD_LIB_DIR
The directory containing the .init files in the Mercury library. They are used to create the initialization file `*_init.c'.

MERCURY_MOD_LIB_MODS
The names of the .init files in the Mercury library.

MERCURY_NU_LIB_DIR
Directory for the NU-Prolog object files (`*.no') for the NU-Prolog Mercury library.

MERCURY_NU_LIB_OBJS
List of the NU-Prolog object files (`*.no') for the Mercury library.

MERCURY_NU_OVERRIDING_LIB_OBJS
List of the NU-Prolog object files (`*.no') for the Mercury library which override definitions given in `MERCURY_NU_LIB_OBJS'.

MERCURY_SP_LIB_DIR
Directory for the Sicstus-Prolog object files (`*.ql') for the Sicstus-Prolog Mercury library.

MERCURY_SP_LIB_OBJS
List of the Sicstus-Prolog object files (`*.ql') for the Mercury library.

MERCURY_SP_OVERRIDING_LIB_OBJS
List of the Sicstus-Prolog object files (`*.ql') for the Mercury library which override definitions given in `MERCURY_SP_LIB_OBJS'.

MERCURY_COMPILER
Filename of the Mercury Compiler.

MERCURY_INTERPRETER
Filename of the Mercury Interpreter.

MERCURY_MKINIT
Filename of the program to create the `*_init.c' file.

Using a different C compiler

The Mercury compiler takes special advantage of certain extensions provided by GNU C to generate much more efficient code. We therefore recommend that you use GNU C for compiling Mercury programs. However, if for some reason you wish to use another compiler, it is possible to do so. Here's what you need to do.