[Next] [Previous] [Up] [Top]

2 Building Your Program

2.3 Controlling the compiler configuration

Vortex's behavior is controlled by configuration parameters and options; the primary distinction between them is that options are set and queried by a regular set of commands, while manipulation of configuration parameters is currently more ad hoc. This section describes configuration parameters and a few important options. Section 2.4 describes options and how to set or display them in more detail.

Vortex displays its configuration upon startup; you can also request it with the config command. The configuration is part of the compiler state saved in a checkpoint.

Current program. At each moment, Vortex works with a single program. If the program consists of one file, this file is the current program. If the program consists of multiple files, the current program is the file from which the others are included, possibly indirectly. The current program is set by any of the make commands, for example,

No current program is assumed upon Vortex startup. See Section 2.2.3 for a detailed description of make.

Vortex can compile multiple languages. Cecil is the most stable input language, but Java, C++, Modula-3, and ParcPlace Smalltalk front-ends are also available, with an IBM Smalltalk front-end under development. To set the language being compiled, use the lang command:

Regardless of the current language, the set of compiler commands and options remains the same. Only Cecil expressions are recognized by the evaluator (since they are evaluated in the context of the Vortex compiler's implementation, which is written in Cecil). Filename extensions have no influence on the current language, nor is any specific extension enforced, although each individual language has its own default extension.

Generated language. Vortex generates either C++ or assembly code. By default, it produces code appropriate for the architecture/OS combination on which it is being run.

The gen commands can be used to enable cross-compilation. For example, to use a sun4 vortex executable to produce an executable that would run on an alpha, one would issue a gen C_64 command, followed by a make1 command at the Vortex> prompt. Phase two compilation could then be done on an alpha using either make or pm. pm takes an optional -arch <archname> command line argument that overrides its default assumption of compiling for the architecture/OS on which it is invoked.

Cecil standard library. The Cecil language includes no built-in data or control structures. When compiling a Cecil program, Vortex can automatically include the standard library, a selection of standard data and control structures (e.g. numbers, loops, arrays) plus the Cecil evaluator, which facilitates debugging the program. Alternately, you may select a subset of the standard library, or no library at all.

There are four levels of incorporating the Cecil standard library (described in more detail in a separate document), depending on the top library file that is included in the program (including a file causes other files referenced in it to be included, too). The levels are determined by compiler commands as follows:

These commands are processed in addition to any files included by the Cecil program. Choosing nostdlib and explicitly including prelude.cecil from one of the files comprising a program is equivalent to choosing stdlib when compiling that program (even if it contains no explicit includes).

(When compiling Java, the file stdlib.rtl is included as the default standard library; nostdlib can be used to disable this default library. Other languages have no standard libraries.)

Optimization level. When debugging code, it is convenient to compile it without optimizations both to reduce turnaround time and to make it easier to use the Cecil evaluator and debugger (discussed in sections 3 and 4). We typically make some source changes, do a series of incremental, non-optimizing compilations while debugging, and finally perform an optimizing compilation once things seem to work. Optimization speeds up applications by roughly an order of magnitude, so it generally is a good idea to optimize a program before running it on a large input set.

Which optimizations are performed depends on the value of the integer option optimization_level; larger values of optimization_level correspond to more aggressive combinations of optimizations. Its default value is 0 (perform no optimizations). It may be set using the following commands:

Commands

Value of optimization_level

Impact

o0 or no_optimize

0

Perform no optimizations

o1 or

optimize

1

Only perform a few highly profitable optimizations (class analysis, splitting, class hierarchy analysis, class prediction, closure delaying, and inlining)

o2 or

full_optimize

2

Augment o1 with useful, but smaller-impact optimizations such as CSE

Since separately compiled libraries (such as the precompiled standard library that comes with the distribution) are compiled with no optimization, you need to disable separate compilation (i.e., enable whole-program optimization) to achieve higher performance. This is controlled by the option use_shared_libraries.

Be prepared for a long compilation time when you first set use_shared_libraries to false, since all the library files will need to be recompiled. You may want to switch to a smaller standard library before specializing library code.

In a large program, often only a few files are being debugged at a time. In such a case, it is reasonable to optimize the other files. This is achieved by first compiling everything with optimization ( Vortex> set use_shared_libraries false; o2; make) and then turning optimization off ( Vortex> o0). After these actions, every file that is modified will be recompiled without optimization (thus making debugging easier and reducing turnaround time). The command Vortex> makeo2 will then recompile unoptimized files with optimization, bringing the current program up to full optimization. makeo1 and makeo2 set the optimization_level option for only the immediately succeeding compile. It is reasonable to keep optimization_level set to 0, but periodically use makeo1 or makeo2 to bring things up to full speed.