The
compiler performs a number of optimizations on
the intermediate Foam code.
Further optimizations may be performed downstream by a C or Lisp compiler,
depending on the environment.
The criterion for deciding which Foam optimizations to include in
the
compiler has been to select those optimizations
which have maximum payoff but cannot be expected from a downstream
compiler.
These optimizations are:
Program specialization is used to exploit specific
instances of generic type constructors.
For example, if the generic constructor SPMquotComplex" is used as
SPMquotComplex(DoubleFloat)", then specialized versions
of the complex arithmetic operations are produced at compile-time.
On the other hand, if the constructor is used as SPMquotComplex(R)",
where SPMquotR" is a parameter, then code is generated which
binds the operations from SPMquotR" and SPMquotComplex(R)" at run-time.
Procedural integration (or inlining) is used to eliminate function calls. This is particularly effective where many exported operations are simple combinations of other functions. The compiler performs cross-file procedural integration by extracting code bursts from other compiled files. This optimization is only performed when a client of a package declares that it is willing to depend on the package's implementation.
Data structure elimination converts heap-allocated structures to collections of temporaries, when possible. This optimization often eliminates the need to heap-allocate temporary results. For example, arithmetic operations on rational or complex number structures are converted into sequences of component operations. This optimization allows efficient code without complicated explicit reference accounting on the part of the programmer.
Dataflow analysis of condition variables eliminates computed branches which arise from inlining generators. The analysis identifies generator control nodes and splits them to form reducible flow graphs. This allows programs to use the high-level control abstractions without a performance penalty.
Some other optimizations that would be expected of any downstream concrete-code generator are performed on Foam as prerequisites of other optimizations. These include: copy propagation, dead variable elimination, dead code elimination, constant folding (including big integer arithmetic), and various peep-hole optimizations.
Together these optimizations seem quite effective. In particular, the combination of cross-file inlining and data structure elimination produces significant gains for the style of programming encouraged by the language.
While we have not performed a careful comparison, certain high-level examples generate code which is comparable in performance to optimized hand-written C.