This is a continuation of Strands SICL (SICL implements Common
Lisp). Although most of the compiler can itself be written in Common
Lisp to be a compliant Compiler it must eventually compile to
machine code. Today this is done by the SBCL compiler. To make the
compiler work standalone this will need to be implemented and thus I have drafted this
proposal. It is criteria that the compiler need to be fast and good. A speed
goal for the generated code would be to be within a factor of 3 of a C compiler. The
compiler itself must compile fast similarly to the SBCL compiler today or
better. As SICL itself it is written in Common lisp.This is a preliminary draft of my
ideas of how this can be accomplished, subject approval by Dr Strand.
By the time the code gets to the compiler the macro-expander has already run and all that
is left are the 25 special forms that need to be compiled.
block
let*
return-from
catch
load-time-value
setq
eval-when
locally
symbol-macrolet
flet
macrolet
tagbody
function
multiple-value-call
the
go
multiple-value-prog1
throw
if
progn
unwind-protect
labels
progv
let
quote
Structure
Optimization
The IR language
Mind you a SSA form (single static assignment) mentioned in the above
paper should be replaced with a CPS form (continuation passing style) for CL
peephole optimizations
Null sequences – Delete useless operations.
Combine operations – Replace several operations with one equivalent.
Algebraic laws – Use algebraic laws to simplify or reorder instructions.
Special case instructions – Use instructions designed for special operand cases.
Address mode operations – Use address modes to simplify code.
…
typecheck optimization
Remove unnecessary type checks. Move type checks out of loops.
Invariant lifter
Lifts invariants (also called constant expressions) out of loops.
loop unrolling
Unrolls loops giving more opportunity of for parallelism. See Instruction Fusion below.
Machine code translation
More than just translating the Universal Assembly to machine code there are also
architecture specific optimizations.
Register optimization
I suggest Linear scan for speed.
Linear Scan is a algorithm suggested by Poletto in 1999. I this
approach the code is not turned into a graph. Instead, all the
variables are linearly scanned to determine the live range,
represented as a interval. Once all the live ranges have been
determined, the intervals are traversed chronologically. Although this
traversal could help identifying which variables whose live ranges
interfere, no graph is being built and the variable are allocate din
a greedy way.
Instruction fusion
Instruction fusion is the process of grouping arithmetic instructions together to form
vector instructions.
jmp elimination
The assembly of then include instructions for things like conditional add which don’t require
jumping. Substitute there if possible.
Runtime
Finally the compiler has finished ad the binary blob is passed to the run-time for
execution. A dialog is also necessary to find variables, functions and like referenced from
the expression being evaluated.