Features of Vortex
Vortex is a language-independent optimizing compiler infrastructure
for object-oriented and other high-level languages, written entirely in
Cecil. It primarily operates as a whole-program
optimizer, performing aggressive analyses and optimizations given the whole
program. It has front-ends for Cecil, Diesel, Smalltalk, Java, C++, and Modula-3.
These front-ends translate into the Vortex RTL intermediate language. Vortex
produces either portable C++ code or SPARC assembly code. A release
of Vortex is available; here are some other resources.
Vortex includes the following optimizations and other features:
Vortex performs static intraprocedural iterative class analysis, tracking
the possible classes of expressions within a procedure. Static class information
enables dynamically dispatched messages to be statically bound as regular
procedure calls (if static class information proves that only one method
can be called), and allows run-time class or subclass tests (such as Java's
instanceof construct) to be constant-folded (if static class information
proves the test is always true or false).
Vortex performs automatic inlining, optimizing statically bound procedure
calls. Inlining is interleaved with class analysis so that class analysis
can track the flow of classes into and out of inlined methods.
Vortex includes class hierarchy analysis, which augments intraprocedural
analysis with information about the program's whole class hierarchy. Information
from automatic class hierarchy analysis is strictly better than information
about final methods or classes in Java and non-virtual member functions
Vortex includes a wide range of interprocedural class analysis algorithms,
ranging from quick linear-time algorithms to precise context-sensitive
algorithms. Intraprocedural class analysis and optimization exploits information
gathered from interprocedural class analysis. In addition, several other
analyses rely on the call graph computed as a side-effect of interprocedural
class analysis, including interprocedural constant propagation, interprocedural
side-effect analysis, interprocedural escape analysis (to identify which
closures may be stack-allocated), and interprocedural exception analysis
(to identify which procedures never raise exceptions).
Vortex exploits dynamic profile information about the relative frequencies
of different classes at each call site to optimize dynamically dispatched
messages. If one or a few receiver classes are most common at a site, then
class tests are inserted in-line before the message, with each test leading
to a branch where the message has been statically bound to the appropriate
receiver. Even in the absence of peaked frequencies, if only a few methods
can be called by a message site, Vortex can insert a few subclass tests
in-line to statically bind to each of the possible methods.
Vortex combines dynamic class profile information and static class hierarchy
information to drive a selective procedure specialization algorithm.
Vortex includes an intraprocedural optimization, splitting, which can eliminate
conditional branches in procedures if earlier merges lost the information
tested by the branch. This optimization is particularly useful to optimize
repeated class tests.
Vortex includes optimizations to reduce the cost of closures (first-class
functions), including inlining invocations of statically known closures,
delaying closure creations to those branches where the closures are needed
(a kind of partial dead code elimination applied to closure creations),
"shrinkwrapping" of environment creation code to the subset of the program's
control flow graph where the environment is needed, and stack-allocating
closures where possible.
Vortex includes several traditional optimizations, including constant propagation
and folding (including of conditional branches and switches), common subexpression
elimination, and dead assignment elimination. When producing assembly code,
global register allocation and simple instruction scheduling are performed.
Vortex includes a must-alias and side-effect analysis which is used to
identify and eliminate redundant loads (CSE of loads, in essense) and stores
and dead stores. By interleaving the elimination of redundant loads with
other analyses including class analysis and constant propagation, class
and constant information can be tracked through stores and subsequent loads
of memory locations. Consider an example where a callee function allocates
& initializes a data structure to hold its results values, which the
caller merely takes apart: if the callee function is inlined, then Vortex's
optimizations can eliminate the stores into and loads from the result data
structure and then eliminate the data structure allocation entirely if
no more references remain to the result data structure. Other idioms using
short-lived intermediate data structures can similarly be optimized.
Vortex supports symbolic analysis of comparison outcomes, enabling it to
eliminate conditional tests whose outcome is implied by some earlier test.
This optimization is particularly useful to eliminate unnecessary array
Vortex includes a framework for implementing iterative data flow analyses.
A client writes a collection of analysis flow functions (dispatching on
the different kinds of intermediate nodes), each of which specifies either
a particular local flow graph transformation to perform as an optimization,
or the updated data flow information to continue propagating. The framework
automatically manages invoking flow functions in either a forward or backward
traversal order, performing iterative approximations, applying transformations
when iteration has reached fixpoint and only simulating transformations
before reaching fixpoint. Clients also can specify that several analyses
should be composed; the framework automatically interleaves the analyses,
allowing each to benefit from the optimization and analysis effects of
the others, in an optimistic manner. Vortex's interprocedural analyses
are also supported by a framework that makes it easy to extend any intraprocedural
analysis to an interprocedural version, with a client-specified context-sensitivity
Vortex includes support for selective recompilation after programming changes,
to make its whole-program optimization approach practical even in a normal
incremental program development environment.
Some resources for Vortex