Initial (Large Upload)

This commit is contained in:
2024-04-25 05:02:33 +00:00
parent fcb4151161
commit 114a6c0e30
4519 changed files with 473023 additions and 0 deletions
BIN
View File
Binary file not shown.
+13
View File
@@ -0,0 +1,13 @@
#
# Build all documentation
#
all:
(cd pictures; make)
(cd html; make)
(cd latex; make)
clean:
(cd pictures; make clean)
(cd html; make clean)
(cd latex; make clean)
+16
View File
@@ -0,0 +1,16 @@
You will need the following programs to build the documentation.
1. Perl 5.004 or more recent
2. LaTeX (I use the TeTeX distribution)
3. fig2dev 3.2 (from xfig)
To build the documentation do the following:
1. In this directory, type make
2. cd latex
3. make again
4. make again
5. make again (Three times to make LaTeX stablize on the cross references)
The HTML pages will be in the directory html, starting from html/index.html
The LaTeX documents will be in the directory latex.
Binary file not shown.

After

Width:  |  Height:  |  Size: 29 KiB

Binary file not shown.

After

Width:  |  Height:  |  Size: 11 KiB

Binary file not shown.

After

Width:  |  Height:  |  Size: 16 KiB

Binary file not shown.

After

Width:  |  Height:  |  Size: 41 KiB

Binary file not shown.

After

Width:  |  Height:  |  Size: 13 KiB

Binary file not shown.

After

Width:  |  Height:  |  Size: 10 KiB

Binary file not shown.

After

Width:  |  Height:  |  Size: 38 KiB

Binary file not shown.

After

Width:  |  Height:  |  Size: 14 KiB

Binary file not shown.

After

Width:  |  Height:  |  Size: 38 KiB

Binary file not shown.

After

Width:  |  Height:  |  Size: 3.0 KiB

Binary file not shown.

After

Width:  |  Height:  |  Size: 741 B

Binary file not shown.

After

Width:  |  Height:  |  Size: 2.3 KiB

+86
View File
@@ -0,0 +1,86 @@
#
# This file compiles the documentation
#
HTML= mlrisc.html mltexdoc.html
TEX= ../latex/annotations.tex \
../latex/graphics.tex \
../latex/instructions.tex \
../latex/mltree.tex \
../latex/delayslots.tex \
../latex/cells.tex \
../latex/cluster.tex \
../latex/constants.tex \
../latex/pseudo-ops.tex \
../latex/streams.tex \
../latex/labelexp.tex \
../latex/labels.tex \
../latex/regions.tex \
../latex/regmap.tex \
../latex/graphs.tex \
../latex/mlrisc-ir.tex \
../latex/compiler-graphs.tex \
../latex/SSA.tex \
../latex/VLIW.tex \
../latex/ra.tex \
../latex/ILP.tex \
../latex/mlrisc-arch.tex \
../latex/future-work.tex \
../latex/asm.tex \
../latex/mc.tex \
../latex/span-dep.tex \
../latex/instrsel.tex \
../latex/availability.tex \
../latex/gc.tex \
../latex/mlrisc-gen.tex \
../latex/contributions.tex \
../latex/systems.tex \
../latex/mlrisc-graphics.tex \
../latex/contributors.tex \
../latex/requirements.tex \
../latex/INTRO.tex \
../latex/problem.tex \
../latex/mlrisc-compiler.tex \
../latex/mlrisc-ir-rep.tex \
../latex/backend-opt.tex \
../latex/sys-integration.tex \
../latex/optimizations.tex \
../latex/span-dep.tex \
../latex/mlrisc-md.tex \
../latex/mlrisc-ra.tex \
../latex/line-counts.tex \
../latex/sparc.tex \
../latex/alpha.tex \
../latex/x86.tex \
../latex/ppc.tex \
../latex/mips.tex \
../latex/hppa.tex \
../latex/C6.tex \
../latex/mltree-ext.tex \
../latex/mltree-util.tex
all: pictures $(HTML) makelinks
pictures:
(cd ../pictures; make)
cvsrm:
cvsrm $(HTML)
clean:
/bin/rm -f *.html
makelinks:
@if [ ! -d graphics ]; then ln -f -s ../graphics .; fi
@if [ ! -d pictures ]; then ln -f -s ../pictures .; fi
@if [ ! -f index.html ]; then ln -f -s INTRO.html index.html ; fi
%.html: ../latex/%.tex mltex2html mltex.thm
perl mltex2html ../latex/$(@:.html=.tex)
mlrisc.html: $(TEX)
mltexdoc.html: ../latex/mltex.tex
+116
View File
@@ -0,0 +1,116 @@
###############################################################################
#
# Theme file for MLTeX
#
###############################################################################
#
# Background color for document
#
$BACKGROUND_COLOR="#ffffff"; #white
#
# Default text color for document
#
$TEXT_COLOR="#000020"; #very dark blue
#
# Color of page title
#
$TITLE_COLOR="#aa0000"; #dark red
#
# Color of the abstract title
#
$ABSTRACT_TITLE_COLOR="#486591"; #black
#
# Color of each section title
#
$SECTION_COLOR="#486591";
#
# Color of each subsection title
#
$SUBSECTION_COLOR="#486591";
#
# Color of each subsubsection title
#
$SUBSUBSECTION_COLOR="#486591";
#
# Color of each paragraph title
#
$PARAGRAPH_COLOR="#486591";
#
# Colors for macros \newdef and \newtype
#
$NEWDEF_COLOR="#ff0000"; #red
$NEWTYPE_COLOR="#ff0000"; #red
#
# Colors for html links
#
$LINK_COLOR="navy";
$VLINK_COLOR="gray";
$ALINK_COLOR="maroon";
#
# Colors for SML type variables, keywords and identifiers
#
$SML_TYVAR_COLOR="#00aaaa";
$SML_KEYWORD_COLOR="#6060a0";
$SML_IDENT_COLOR="#9c4040";
#
# Color for emphasis
#
$EMPH_COLOR="#ff0000"; #red
#
# Color for description items
#
$DESC_COLOR="#000070"; #blue
#
# Color for captions
#
$CAPTION_COLOR="#007777"; #green/blue
#
# Color of ML code
#
$CODE_COLOR="#000000"; # black
#
# Background color of table of contents
#
$TOC_BACKGROUND_COLOR="#e6e6e6";
$SECTION_TOC_TEXT_COLOR="#486591";
$MAJORSECTION_TEXT_COLOR="ffffff";
$MAJORSECTION_BACKGROUND_COLOR="#486591";
$SECTION_TOC_BACKGROUND_COLOR="#e6e6e6";
$TOC_FACE="hevetica";
$MAX_LOCAL_TOC_ENTRY_LENGTH=40;
$MAX_GLOBAL_TOC_ENTRY_LENGTH=40;
$GLOBAL_TOC_WIDTH=170;
$SCREEN_WIDTH=700;
$TEXT_WIDTH=600;
$TOC_SIZE=-1;
$X_PIXELS = 1024;
$Y_PIXELS = 768;
$IMAGE_SCALING=0.8;
$PAPER_HEIGHT = "11in";
$PAPER_WIDTH = "8.5in";
@AUTHORS=("Lal George", "Allen Leung");
@EMAILS=('george@research.bell-labs.com','leunga@cs.nyu.edu');
$WWWHOST="www.cs.nyu.edu";
$URLPREFIX="leunga/MLRISC/Doc/html/";
1;
+1441
View File
File diff suppressed because it is too large Load Diff
+3
View File
@@ -0,0 +1,3 @@
\section{The TI C6x Back End}
No documentation yet.
+23
View File
@@ -0,0 +1,23 @@
\section{ILP Optimizations}
\subsection{Introduction}
This section is under construction. A new scheduler framework
for superscalars that ties into the machine description language
is currently being developed.
\subsection{The ILP ToolBox}
\subsubsection{List Scheduler}
\subsubsection{Ranking Algorithms}
Some more complex ranking algorithms (than say critical path) have been
implemented. These are:
\begin{itemize}
\item The algorithm of
\mlrischref{scheduling/PalemSimons.sig}{Palem and Simons}
which appeared in TOPLAS '93. This algorithm
computes the modified deadlines of a set instructions, with
precedence, latency, and deadlines constraints.
\item The algorithm of
\mlrischref{scheduling/LeungPalemPnueli.sig}{Leung, Palem, and Pnueli}
which appeared in PACT '98.
This algorithm computes the modified deadlines of a set of instructions,
with precedence, latency, release-times and deadline constraints.
\end{itemize}
+48
View File
@@ -0,0 +1,48 @@
\section{MLRISC}
\begin{center}
\begin{Bold}
A framework for retargetable and optimizing compiler back ends
\end{Bold}
\end{center}
\begin{center}
\begin{tabular}{cc}
\begin{address}
\href{mailto:george@research.bell-labs.com}{Lal George}
\end{address} &
\begin{address}
\href{mailto:leunga@cs.nyu.edu}{ Allen Leung}
\end{address} \\
Bell Labs & New York University \\
\end{tabular}
\end{center}
\begin{center}
\image{MLRISC logo}{pictures/png/uncol.png}{align="middle"}
\begin{Italics}
\href{contributors.html}{Contributors}
\end{Italics}
\end{center}
Writing native code generators for modern processors is a significant
investment. Unfortunately it is difficult
to reuse this investment for other architectures, and even more
difficult to reuse for other source language compilers. MLRISC is
a customizable optimizing back-end written in
\externhref{http://cm.bell-labs.com/cm/cs/what/smlnj/sml.html}{Standard ML}
and has been successfully retargeted to multiple architectures.
MLRISC deals elegantly with the special requirements imposed by the
execution model of different high-level, typed languages, by allowing
many components of the system to be customized to fit the source language
semantics and runtime system requirements.
The \begin{color}{#aa0000}Overview\end{color} pages on the left provide
an introduction the MLRISC system, mostly from the client's perspective,
while the \begin{color}{#aa0000}System\end{color}
pages give a more detailed look at the
innards, and are of interest to MLRISC hackers. As usual, development of
the system has outpaced the documentation process substantally; thus
the latter part of the document is incomplete but it may still be useful.
These pages are also available in
\href{../latex/mlrisc.ps}{tech report} form.
+35
View File
@@ -0,0 +1,35 @@
#
# This file compiles the documentation
#
TEX= sml.tex mlrisc.tex mltexdoc.tex
PDF= $(TEX:.tex=.pdf)
all: pictures $(PDF)
pictures:
(cd ../pictures; make)
pdf: $(PDF)
%.pdf:
latexmk -bibtex -ps- -pdf $(@:.pdf=.tex)
mlrisc.pdf: annotations.tex graphics.tex instructions.tex mltree.tex \
delayslots.tex cells.tex cluster.tex constants.tex \
pseudo-ops.tex streams.tex labelexp.tex labels.tex regions.tex \
regmap.tex graphs.tex mlrisc-ir.tex compiler-graphs.tex \
SSA.tex VLIW.tex ra.tex ILP.tex mlrisc-arch.tex \
future-work.tex asm.tex mc.tex instrsel.tex \
availability.tex gc.tex mlrisc-gen.tex contributions.tex \
systems.tex mlrisc-graphics.tex contributors.tex \
requirements.tex INTRO.tex problem.tex mlrisc-compiler.tex \
mlrisc-ir-rep.tex backend-opt.tex sys-integration.tex \
optimizations.tex span-dep.tex mlrisc-md.tex line-counts.tex \
sparc.tex alpha.tex x86.tex ppc.tex mips.tex hppa.tex C6.tex \
mltree-ext.tex mltree-util.tex
mltexdoc.pdf: mltex.tex
clean:
rm -f $(PDF) *.aux *.log *.bbl *.blg
+21
View File
@@ -0,0 +1,21 @@
\section{SSA Optimizations}\label{sec:ssa}
All SSA optimization modules satisfy the signature
\mlrischref{SSA/ssa-optimization.sig}{SSA\_OPTIMIZATION},
which is defined as:
\begin{SML}
signature SSA_OPTIMIZATION = sig
structure SSA : SSA
val optimize : SSA.ssa -> SSA.ssa
end
\end{SML}
The following SSA based scalar optimizations have been implemented in MLRISC.
\begin{itemize}
\item \mlrischref{SSA/ssa-dead-code-elim.sml}{Dead code elimination}
\item \mlrischref{SSA/ssa-gvn.sml}{Global value numbering, constant folding, algebraic simplication}
\item \mlrischref{SSA/ssa-gcm.sml}{Global code motion}
\item \mlrischref{SSA/ssa-cond-const-prop.sml}{Conditional constant propagation}
\item \mlrischref{SSA/ssa-op-str-red.sml}{Strength reduction}
\end{itemize}
+21
View File
@@ -0,0 +1,21 @@
\section{Optimizations for VLIW/EPIC Architectures}
\subsection{Overview}
Many newer architectures such as the upcoming IA-64 and the
DSPs such as the C6 are VLIW or so called EPIC machines.
These architectures depends on the compiler to
extract instruction level parallelism (\newdef{ILP})
and data level parallelism (\newdef{DLP}).
Optimizations for these architectures include:
\begin{itemize}
\item Hyperblock construction
\item Predication and predicate analysis
\item Hyperblock scheduling
\item Modulo scheduling
\end{itemize}
\subsection{Hyperblocks}
\subsection{Predicate Analysis}
\subsection{Hyperblock Scheduling}
\subsection{Modulo Scheduling}
+97
View File
@@ -0,0 +1,97 @@
\section{The Alpha Back End}
\subsection{Trap Shadows, Floating Exceptions, and Denormalized Numbers on the DEC Alpha}
\emph{By Andrew W. Appel and Lal George, Nov 28, 1995}
See section 4.7.5.1 of the \emph{Alpha Architecture Reference Manual}.
The Alpha has imprecise exceptions, meaning that if a floating
point instruction raises an IEEE exception, the exception may
not interrupt the processor until several successive instructions have
completed. ML, on the other hand, may want a "precise" model
of floating point exceptions.
Furthermore, the Alpha hardware does not support denormalized numbers
(for ``gradual underflow''). Instead, underflow always rounds to zero.
However, each floating operation (add, mult, etc.) has a trapping
variant that will raise an exception (imprecisely, of course) on
underflow; in that case, the instruction will produce a zero result
AND an exception will occur. In fact, there are several variants
of each instruction; three variants of MULT are:
\begin{description}
\item[MULT s1,s2,d] truncate denormalized result to zero; no exception
\item[MULT/U s1,s2,d] truncate denormalized result to zero; raise UNDERFLOW
\item[MULT/SU s1,s2,d] software completion, producing denormalized result
\end{description}
The hardware treats the \verb|MULT/U| and \verb|MULT/SU|
instructions identically,
truncating a denormalized result to zero and raising the UNDERFLOW
exception. But the operating system, on an UNDERFLOW exception,
examines the faulting instruction to see if it's an \verb|/SU|
form, and if so,
recalculates \verb|s1*s2|, puts the right answer in \verb|d|, and continues,
all without invoking the user's signal handler.
Because most machines compute with denormalized numbers in hardware,
to maximize portability of SML programs, we use the \verb|MULT/SU| form.
(and \verb|ADD/SU|, \verb|SUB/SU|, etc.) But to use this form successfully,
certain rules have to be followed. Basically, d cannot be the same
register as s1 or s2, because the opsys needs to be able to
recalculate the operation using the original contents of s1 and s2,
and the MULT/SU instruction will overwrite d even if it traps.
More generally, we may want to have a sequence of floating-point
instructions. The rules for such a sequence are:
1. The sequence should end with a \verb|TRAPB| (trap barrier) instruction.
(This could be relaxed somewhat, but certainly a \verb|TRAPB| would
be a good idea sometime before the next branch instruction or
update of an ML reference variable, or any other ML side effect.)
2. No instruction in the sequence should destroy any operand of itself
or of any previous instruction in the sequence.
3. No two instructions in the sequence should write the same destination
register.
We can achieve these conditions by the following trick in the
Alpha code generator. Each instruction in the sequence will write
to a different temporary; this is guaranteed by the translation from
ML-RISC. At the beginning of the sequence, we will put a special
pseudo-instruction (we call it \verb|DEFFREG|) that ``defines''
the destination
register of the arithmetic instruction. If there are $K$ arithmetic
instructions in the sequence, then we'll insert $K$
\verb|DEFFREG| instructions
all at the beginning of the sequence.
Then, each arithop will not only ``define'' its destination temporary
but will ``use'' it as well. When all these instructions are fed to
the liveness analyzer, the resulting interference graph will then
have inteference edges satisfying conditions 2 and 3 above.
Of course, \verb|DEFFREG| doesn't actually generate any code. In our model
of the Alpha, every instruction generates exactly 4 bytes of code
except the ``span-dependent'' ones. Therefore, we'll specify \verb|DEFFREG|
as a span-dependent instruction whose minimum and maximum sizes are zero.
At the moment, we do not group arithmetic operations into sequences;
that is, each arithop will be preceded by a single \verb|DEFFREG| and
followed by a \verb|TRAPB|. To avoid the cost of all those \verb|TRAPB|'s,
we should improve this when we have time. Warning: Don't put more
than 31 instructions in the sequence, because they're all required
to write to different destination registers!
What about multiple traps? For example, suppose a sequence of
instructions produces an Overflow and a Divide-by-Zero exception?
ML would like to know only about the earliest trap, but the hardware
will report \emph{BOTH} traps to the operating system. However, as long
as the rules above are followed (and the software-completion versions
of the arithmetic instructions are used), the operating system will
have enough information to know which instruction produced the
trap. It is very probable that the operating system will report \emph{ONLY}
the earlier trap to the user process, but I'm not sure.
For a hint about what the operating system is doing in its own
trap-handler (with software completion), see section 6.3.2 of
``\emph{OpenVMS Alpha Software}'' (Part II of the Alpha Architecture
Manual). This stuff should apply to Unix (OSF1) as well as VMS.
+33
View File
@@ -0,0 +1,33 @@
\section{Annotations}
\subsection{Overview}
A compiler front-end has to be propagate information to
the back-end. An optimization phase may have to leave behind information
at various places of the IR so that other phases can reuse such information.
MLRISC uses the \newdef{annotations}
mechanism for these functions.
Individual instructions, basic blocks, and flow graph edges,
can be attached one or more annotations.
The basic MLRISC system understands many annotations. Some examples are:
\begin{description}
\item[COMMENT]
these can be used to attach comments. If attached to
an instruction, the assemblers will output
them as part of their assembly output.
\item[BRANCH\_PROB]
these can be attached to a branch instruction to indicate
the probability in which is it taken.
\item[EXECUTION\_FREQ]
these can be attached to a basic block to indicate
its expected execution frequency
\end{description}
\subsection{Details}
The primitive annotations datatype is defined
to have this \mlrischref{library/annotations.sig}{signature}.
In addition, MLRISC predefined a few primitive annotations that are
recognized by the core system. This signature is
\mlrischref{instructions/mlriscAnnotations.sig}{MLRISC\_ANNOTATIONS}.
More detailed documentation can be found in this
\href{http://cm.bell-labs.com/cm/cs/what/smlnj/compiler-notes/annotations.ps}{paper}.
+60
View File
@@ -0,0 +1,60 @@
\section{Assemblers}
\subsubsection{Overview}
Assemblers in MLRISC satisfy the signature
\mlrischref{emit/instruction-emitter.sig}{INSTRUCTION\_EMITTER},
which is defined as:
\begin{SML}
signature INSTRUCTION_EMITTER =
sig
structure I : \href{instructions.html}{INSTRUCTIONS}
structure C : \href{cells.html}{CELLS}
structure S : \href{streams.html}{INSTRUCTION_STREAM}
structure P : \href{pseudo-ops.html}{PSEUDO_OPS}
sharing I.C = C
sharing S.P = P
val makeStream : Annotations.annotations ->
((int -> int) -> I.instruction -> unit,
unit,'b,'c,'d,'e) S.stream
end
\end{SML}
The function \sml{makeStream} returns an instruction stream.
By default the output is bound to the stream \sml{AsmStream.asmOutStream}
defined in the structure
\mlrischref{emit/asmStream.sml}{AsmStream} at creation time.
The structure \sml{AsmStream} satisfy the following signature.
\begin{SML}
signature ASM_STREAM = sig
val asmOutStream : TextIO.outstream ref
val withStream : TextIO.outstream -> ('a -> 'b) -> 'a -> 'b
end
\end{SML}
\subsubsection{Redirecting the Output}
It is possible to redirect the output of an instruction stream.
For example, the following statement
\begin{SML}
val asm = makeStream []
\end{SML}
binds the output of \sml{asm} to \sml{AsmStream.asmOutStream}, which
by default is just \sml{TextIO.stdOut}. On the other hand, the
statement
\begin{SML}
val asm = AsmStream.withStream mystream makeStream []
\end{SML}
binds the output of asm to \sml{mystream}.
\subsubsection{More Details}
Assemblers are automatically generated by the
\href{mlrisc-md.html}{MDGen} tool. Some specific generated
assemblers are listed below:
\begin{enumerate}
\item \mlrischref{sparc/emit/sparcAsm.sml}{Sparc}
\item \mlrischref{hppa/emit/hppaAsm.sml}{Hppa}
\item \mlrischref{alpha/emit/alphaAsm.sml}{Alpha}
\item \mlrischref{ppc/emit/ppcAsm.sml}{Power PC}
\item \mlrischref{x86/emit/x86Asm.sml}{X86}
\end{enumerate}
+33
View File
@@ -0,0 +1,33 @@
\section{How to Obtain MLRISC}
There are a few ways to obtain the MLRISC system.
\begin{enumerate}
\item
An old version of MLRISC is available from
\externhref{http://cm.bell-labs.com/cm/cs/what/smlnj/doc/MLRISC/quick-tour/index.html}{this link}.
This version is stable but very out-dated, and does
not contain the most up-to-date features.
\item
New experimental versions are available from the
\externhref{http://cm.bell-labs.com/cm/cs/what/smlnj/software.html}{SML/NJ software page} as part of the SML/NJ compiler releases.
These versions are relative stable, but
do not include the entire MLRISC source tree.
\item \href{mailto:leunga@cs.nyu.edu}{Allen}
keeps an up-to-date version of MLRISC at NYU for private use.
This version includes everything but is under constant changes, so beware!
To access the CVS repository, set your \sml{CVSROOT} environment variable
to
\begin{verbatim}
:pserver:mlrisc@react-ilp.cs.nyu.edu:/home/leunga/mlrisc
\end{verbatim}
and checkout the repository using
\begin{verbatim}
cvs co MLRISC++
\end{verbatim}
The password to use is \sml{mlrisc}.
\item
Generally speaking, you can get the latest version of MLRISC by asking
\href{mailto:george@research.bell-labs.com}{Lal}.
\end{enumerate}
MLRISC is \newdef{free, open source} software, and is released under the
\href{http://cm.bell-labs.com/cm/cs/what/smlnj/license.html}{SML/NJ license}.
+15
View File
@@ -0,0 +1,15 @@
\section{Back End Optimizations}
Once MLRisc trees have been generated, they are passed into a module
that generates a flowgraph of target machine instructions. Again,
this module and all subsequent optimization phases have been
specialized to the front end.
\image{Back end optimizations}{pictures/png/optimization.png}{align=right}
Nearly all
instruction selection modules provided by MLRISC use a simple tree
pattern matching algorithm rather than the more heavy weight BURG
tools --- including the x86 \begin{color}{#580000} It is important to
emphasis that all optimizations are performed on the flowgraph of
target machine instructions and \emph{not} MLRisc
immediate IR. \end{color} There is complete flexibility in the order,
and nature of the optimizations performed.
+146
View File
@@ -0,0 +1,146 @@
\section{Cells}
MLRISC uses
the \mlrischref{instructions/cells.sig}{CELLS}
interface to define all readable/writable resources
in a machine architecture, or \emph{cells}
The types defined herein are:
\begin{itemize}
\item \sml{cellkind} -- different classes of cells are assigned
difference cellkinds. The following cellkinds should be present
\begin{itemize}
\item \sml{GP} -- general purpose registers.
\item \sml{FP} -- floating point registers.
\item \sml{CC} -- condition code registers.
\end{itemize}
In addition, the cellkinds \sml{MEM} and \sml{CTRL}
should also be defined. These are used for representing
memory based data dependence and control dependence.
\begin{itemize}
\item \sml{MEM} -- memory
\item \sml{CTRL} -- control dependence
\end{itemize}
\item \sml{regmap} -- \href{regmap.html}{register map}
\item \sml{cellset} -- a cellset represent a set of cells. This
type can be used to denote live-in/live-out information. Cellsets are
implemented as immutable abstract types.
\end{itemize}
These core definitions are defined in the following signature
\begin{SML}
signature \mlrischref{instructions/cells.sig}{CELLS\_BASIS} =
sig
eqtype cellkind
type cell = int
type regmap = cell Intmap.intmap
exception Cells
val cellkinds : cellkind list
val cellkindToString : cellkind -> string
val firstPseudo : cell
val Reg : cellkind -> int -> cell
val GPReg : int -> cell
val FPReg : int -> cell
val cellRange : cellkind -> {low:int, high:int}
val newCell : cellkind -> 'a -> cell
val cellKind : cell -> cellkind
val updateCellKind : cell * cellkind -> unit
val numCell : cellkind -> unit -> int
val maxCell : unit -> cell
val newReg : 'a -> cell
val newFreg : 'a -> cell
val newVar : cell -> cell
val regmap : unit -> regmap
val lookup : regmap -> cell -> cell
val reset : unit -> unit
end
\end{SML}
\begin{itemize}
\item\sml{cellkinds} -- this is a list of all the cellkinds defined in the
architecture
\item\sml{cellkindToString} -- this function maps a cellkind into its name
\item\sml{firstPseudo} -- MLRISC numbered physical resources
in the architecture from 0 to firstPseudo-1.
This is the first usable virtual register number.
\item\sml{Reg} -- This function maps the $i$th physical
resource of a particular cellkind to its internal encoding used by MLRISC.
Note that all resources in MLRISC are named uniquely.
\item\sml{GPReg} -- abbreviation for \sml{Reg GP}
\item\sml{FPReg} -- abbreviation for \sml{Reg FP}
\item \sml{cellRange} -- this returns a range \sml{{low, high}}
when given a cellkind, with denotes the range of physical resources
\item \sml{newCell} -- This function returns a new virtual register
of a particular cellkind.
\item \sml{newReg} -- abbreviation as \sml{newCell GP}
\item \sml{newFreg} -- abbreviation as \sml{newCell FP}
\item \sml{cellKind} -- When given a cell number, this returns its
cellkind. Note that this feature is not enabled by default.
\item \sml{updateCellKind} -- updates the cellkind of a cell.
\item \sml{numCell} -- returns the number of virtual cells allocated for one cellkind.
\item \sml{maxCell} -- returns the next virtual cell id.
\item \sml{newVar} -- given a cell id, return a new cell id of
the same cellkind.
\item \sml{regmap} -- This function returns a new empty regmap
\item \sml{lookup} -- This converts a regmap into a lookup function.
\item \sml{reset} -- This function resets all counters associated
with all virtual cells.
\end{itemize}
\begin{SML}
signature CELLS = sig
include CELLS_BASIS
val GP : cellkind
val FP : cellkind
val CC : cellkind
val MEM : cellkind
val CTRL : cellkind
val toString : cellkind -> cell -> string
val stackptrR : cell
val asmTmpR : cell
val fasmTmp : cell
val zeroReg : cellkind -> cell option
type cellset
val empty : cellset
val addCell : cellkind -> cell * cellset -> cellset
val rmvCell : cellkind -> cell * cellset -> cellset
val addReg : cell * cellset -> cellset
val rmvReg : cell * cellset -> cellset
val addFreg : cell * cellset -> cellset
val rmvFreg : cell * cellset -> cellset
val getCell : cellkind -> cellset -> cell list
val updateCell : cellkind -> cellset * cell list -> cellset
val cellsetToString : cellset -> string
val cellsetToString' : (cell -> cell) -> cellset -> string
val cellsetToCells : cellset -> cell list
end
\end{SML}
\begin{itemize}
\item \sml{toString} -- convert a cell id of a certain cellkind into
its assembly name.
\item \sml{stackptrR} -- the cell id of the stack pointer register.
\item \sml{asmTmpR} -- the cell id of the assembly temporary
\item \sml{fasmTmp} -- the cell id of the floating point temporary
\item \sml{zeroReg} -- given the cellkind, returns the cell id of the
source that always hold the value of zero, if there is any.
\item \sml{empty} -- an empty cellset
\item \sml{addCell} -- inserts a cell into a cellset
\item \sml{rmvCell} -- remove a cell from a cellset
\item \sml{addReg} -- abbreviation for \sml{addCell GP}
\item \sml{rmvReg} -- abbreviation for \sml{rmvCell GP}
\item \sml{addFreg} -- abbreviation for \sml{addCell FP}
\item \sml{rmvFreg} -- abbreviation for \sml{rmvCell FP}
\item \sml{getCell} -- lookup all cells of a particular cellkind from
the cellset
\item \sml{updateCell} -- replace all cells of a particular cellkind
from the cellset.
\item \sml{cellsetToString} -- pretty print a cellset
\item \sml{cellsetToString'} -- pretty print a cellset, but first
apply a regmap function.
\item \sml{cellsetToCells} -- convert a cellset into list form.
\end{itemize}
+53
View File
@@ -0,0 +1,53 @@
\section{Cluster}
A \newdef{cluster}
represents a compilation unit in linearized form,
and contains information about the control flow, global annotations,
block and edge execution frequencies, and live-in/live-out information.
Its signature is:
\begin{SML}
signature FLOWGRAPH = sig
structure C : \href{cells.html}{CELLS}
structure I : \href{instructions.html}{INSTRUCTIONS}
structure P : \href{pseudo-ops.html}{PSEUDO_OPS}
structure W : \href{freq.html}{FREQ}
sharing I.C = C
datatype block =
PSEUDO of P.pseudo_op
| LABEL of Label.label
| BBLOCK of
\{ blknum : int,
freq : W.freq ref,
annotations : Annotations.annotations ref,
liveIn : C.cellset ref,
liveOut : C.cellset ref,
succ : edge list ref,
pred : edge list ref,
insns : I.instruction list ref
\}
| ENTRY of
\{blknum : int, freq : W.freq ref, succ : edge list ref\}
| EXIT of
\{blknum : int, freq : W.freq ref, pred : edge list ref\}
withtype edge = block * W.freq ref
datatype cluster =
CLUSTER of \{
blocks: block list,
entry : block,
exit : block,
regmap: C.regmap,
blkCounter : int ref,
annotations : Annotations.annotations ref
\}
end
\end{SML}
Clusters are used in
\href{span-dep.html}{span dependency resolution},
\href{delayslots.html}{delay slot filling},
\href{asm.html}{assembly},
and \href{mc.html}{machine code}
output, since these phases require the code laid out in linearized form.
+434
View File
@@ -0,0 +1,434 @@
\section{Basic Compiler Graphs}
\subsection{Introduction}
In this section we describe the set of core compiler specific graphs and
algorithms implemented in MLRISC.
Mostly of these algorithms are parameterized with respect
to the actual intermediate representation, and as such they
do not provide many facilities that are provided by higher abstraction
layers, such as in \href{mlrisc-ir.html}{MLRISC IR},
or in \href{SSA.html}{SSA}.
\subsubsection{Dominator/Post-dominator Trees}
\newdef{Dominance}
is a fundamental concept in compiler optimizations.
Node $A$ $dominates$ $B$
iff all paths from the start node
to $B$ intersects A. A dual notion is the concept of
$post-dominance$:
$A$ \newdef{post-dominates} $B$ iff all paths from $B$ to the stop node
intersects $A$. A (post-)dominator tree can be used
to summarize the dominance/post-dominance relationship.
\begin{SML}
functor \mlrischref{ir/dominator.sml}{DominatorTree}
(GraphImpl : GRAPH_IMPLEMENTATION) : DOMINATOR_TREE
\end{SML}
The functor implements dominator analysis and
creates a dominator/post-dominator tree from a graph $G$. A dominator tree is implemented as a graph
with the following definition:
\begin{SML}
signature \mlrischref{ir/dominator.sig}{DOMINATOR_TREE} = sig
exception Dominator
datatype 'n dom_node =
DOM of \{ node : 'n, level : int, preorder : int, postorder : int \}
type ('n,'e,'g) dom_info
type ('n,'e,'g) dominator_tree = ('n dom_node,unit,('n,'e,'g) dom_info) graph
type ('n,'e,'g) postdominator_tree = ('n dom_node,unit,('n,'e,'g) dom_info) graph
\end{SML}
We annotated each node in
a dominator tree with three extra fields of information, which
is useful for other algorithms:
\begin{itemize}
\item\sml{level} is the nesting level of the tree. The root
node has level 0, children of the root has level 1 and so on.
\item\sml{preorder} is the preorder numbering of a node
\item\sml{preorder} is the postorder numbering of a node.
\end{itemize}
To create a dominator tree and a postdominator tree
from a graph, the following function should be called.
\begin{SML}
val dominator_trees : ('n,'e,'g) graph ->
('n,'e,'g) dominator_tree * ('n,'e,'g) postdominator_tree
\end{SML}
We use the algorithm of Tarjan and Lengauer, which
runs in time $O(|V+E|\alpha(|V+E|))$ where $\alpha$ is the functional
inverse of the Ackermann function.
To perform many common queries on a dominator tree, we first
call the function \sml{methods} to obtain a method object.
\begin{SML}
val methods : ('n,'e,'g) dominator_tree -> dominator_methods
\end{SML}
The methods are packed into the following type:
\begin{SML}
type dominator_methods =
\{ dominates : node_id * node_id -> bool,
immediately_dominates : node_id * node_id -> bool,
strictly_dominates : node_id * node_id -> bool,
postdominates : node_id * node_id -> bool,
immediately_postdominates : node_id * node_id -> bool,
strictly_postdominates : node_id * node_id -> bool,
control_equivalent : node_id * node_id -> bool,
idom : node_id -> node_id, $(* ~1 if none *)$
idoms : node_id -> node_id list,
doms : node_id -> node_id list,
ipdom : node_id -> node_id, $(* ~1 if none *)$
ipdoms : node_id -> node_id list,
pdoms : node_id -> node_id list,
dom_lca : node_id * node_id -> node_id,
pdom_lca : node_id * node_id -> node_id,
dom_level : node_id -> int,
pdom_level : node_id -> int,
control_equivalent_partitions : unit -> node_id list list
\}
\end{SML}
The query methods are as follows:
\begin{methods}
dominates($a,b$) & returns true iff $a$ dominates $b$ \\
immediately\_dominates($a,b$) & returns true iff $a$ immediately dominates $b$ \\
strictly\_dominates($a,b$) & returns true iff $a$ strictly dominates $b$ \\
postdominates($a,b$) & returns true iff $a$ post-dominates $b$ \\
immediately\_postdominates($a,b$) & returns true iff $a$ immediately post-dominates $b$ \\
strictly\_postdominates($a,b$) & returns true iff $a$ strictly post-dominates $b$ \\
control\_equivalent($a,b$) &
returns true iff $a$ dominates $b$ and vice versa \\
idom($a$) & returns the immediate dominator of $a$, or $-1$ if none exists \\
idoms($a$) & returns all nodes that $a$ immediately dominates \\
doms($a$) & returns all nodes that $a$ dominates (including $a$ itself) \\
ipdom($a$) & returns the immediate post-dominator of $a$, or $-1$ if none exists \\
ipdoms($a$) & returns all nodes that $a$ immediately post-dominates \\
pdoms($a$) & returns all nodes that $a$ post-dominates (including $a$ itself) \\
dom\_lca($a,b$) & returns the least common ancestor of $a$ and $b$ in
the dominator tree \\
pdom\_lca($a,b$) & returns the least common ancestor of $a$ and $b$
in the post-dominator tree \\
dom\_level($a$) & returns the nesting level of $a$ in the dominator tree \\
pdom\_level($b$) & returns the nesting level of $a$ in the post-dominator
tree \\
control\_equivalent\_partitions & partitions the graph into
a set of control equivalent nodes.
\end{methods}
The methods \sml{dom_lca}, \sml{pdom_lca} and
\sml{control_equivalent_partitions} executes in $O(n)$ time, where
$n$ is the size of the dominator tree. The other methods run in $O(1)$ time.
\subsubsection{Control Dependence Graph}
Given two nodes $A$ and $B$ in a control flow graph $G$,
we say that $B$ is \newdef{control dependent} on $A$ iff
\begin{itemize}
\item $B$ post-dominates a successor of $A$
\item $B$ does not strictly post-dominates $A$
\end{itemize}
Intuitively, $B$ is control dependent on $A$ means that
some path in the program that goes through $A$ can by-passed $B$,
and furthermore, $A$ is the point in which this divergence can occur.
Control dependence is used to various kinds of analysis and optimizations in
a compiler, such as code motion and global scheduling~\cite{bernstein-rodeh}.
To build a control dependence graph, the functor
\sml{ControlDependenceGraph} can be used:
\begin{SML}
signature \mlrischref{ir/cdg.sig}{CONTROL_DEPENDENCE_GRAPH} = sig
type ('n,'e,'g) cdg = ('n,'e,'g) graph
val control_dependence_graph :
('e -> bool) ->
('n,'e,'g) dominator_tree *
('n,'e,'g) postdominator_tree ->
('n,'e,'g) cdg
end
functor \mlrischref{ir/cdg.sml}{ControlDependenceGraph}
(structure Dom : DOMINATOR_TREE
structure GraphImpl : GRAPH_IMPLEMENTATION
) : CONTROL_DEPENDENCE_GRAPH
\end{SML}
The control depedence graph is a subcomponent of the
program dependence graph commonly used in
modern compiler optimizations.
\subsubsection{Dominance Frontiers}
Many algorithms involving the notion of control dependence or dominance
can be rephrased in terms of \newdef{dominance frontiers}.
A node $A$ is in the dominance frontiers of $B$ iff
$B$ dominates a predecessor of $A$ but $B$ does not strictly-dominate $A$.
We denote this as $A \in DF(B)$.
The dual notion of \newdef{post-dominance frontiers} can be defined
analogously using the post-dominator tree\footnote{Control dependence
can be defined in terms of post-dominance frontiers.}.
\begin{SML}
functor \mlrischref{ir/dominance-frontier.sml}{DominanceFrontiers}(Dom : DOMINATOR_TREE) : DOMINANCE_FRONTIERS
\end{SML}
The functor \sml{DominanceFrontiers} can be used to
compute all the dominance frontiers of all the nodes in a graph.
It has the following signature.
\begin{SML}
signature \mlrischref{ir/dominance-frontier.sig}{DOMINANCE_FRONTIERS} = sig
structure Dom : DOMINATOR_TREE
type dominance_frontiers = node_id list array
val DFs : ('n,'e,'g) Dom.dominator_tree -> dominance_frontiers
end
\end{SML}
\subsubsection{Iterated Dominance Frontiers}
\newdef{Iterated dominance frontiers} (denoted as $DF^+$) are defined
as the least fixed point of iterating the operation $DF$. Formally,
define the dominance frontiers on a set $S$ as follows:
\[
DF(S) \defas \Union_{A \in S} DF(A)
\]
Define iteration of $DF$, denoted as $DF^n$, as follows:
\begin{eqnarray*}
DF^1(S) & \defas & DF(S) \\
DF^{n+1}(S) & \defas & DF(S \union DF^n(S)) \\
\end{eqnarray*}
The iterated dominance frontiers $DF^+(S)$ on a set $S$ are defined as
the limit:
\[
DF^+(S) \defas \lim_{n \to \infty} DF^n(S)
\]
Iterated dominance frontiers of a set $S$ can be computed in
time $O(|S|+|V|+|E|)$ using the
algorithm by Sreedhar and Gao~\cite{linear-time-IDF}\footnote{
In practice it is often sub-linear in $|V|+|E|$.}.
\begin{SML}
functor \mlrischref{ir/djgraph.sml}{DJGraph}(Dom : DOMINATOR_TREE) : DJ_GRAPH
\end{SML}
The functor \sml{DJGraph} implements this algorithm.
It satisfies the signature below:
\begin{SML}
signature \mlrischref{ir/djgraph.sig}{DJ_GRAPH} = sig
structure Dom : DOMINATOR_TREE
type ('n,'e,'g) dj_graph = ('n,'e,'g) Dom.dominator_tree
val dj_graph : ('n,'e,'g) dj_graph ->
\{ DF : node_id -> node_id list,
IDF : node_id -> node_id list,
IDFs : node_id list -> node_id list
\}
end
\end{SML}
The function \sml{dj_graph} takes a dominator tree and returns
three query methods for computing dominance and iterated dominance frontiers.
Method \sml{DF} computes $DF(v)$ for a single node $v$.
Method \sml{IDF} computes the $DF^+(v)$, and method
\sml{IDFs} computes $DF^+(S)$ when given a set of node ids.
The dominator tree must not be updated while these operations
are being performed.
Sreedhar's original algorithm is phrased in terms of the
DJ-graph, which is a fusion of the dominator tree
with its underlying flowgraph. Our variant operates on the
dominator tree and the flowgraph at the same time, without
building an intermediate data structure.
Iterated dominance frontiers are used
in many algorithms that deal with the notion of dominance.
For example, our SSA construction algorithm uses iterated
dominance frontiers to identify confluent points in the program
where $phi$-functions are to be placed.
\subsubsection{Loop Nesting Tree}
A \newdef{natural loop} $L$ in a graph is a maximal
strongly connected component
such that all nodes in $L$ are dominated by a single node $h$, called
the \newdef{loop header}. Loops tend to form good optimization candidates
and consequently \newdef{loop detection} is an essential task in a compiler.
The functor
\begin{SML}
functor \mlrischref{ir/loop-structure.sml}{LoopStructure}
(structure GraphImpl : GRAPH_IMPLEMENTATION
structure Dom : DOMINATOR_TREE
) : LOOP_STRUCTURE
\end{SML}
recognizes all natural loops in a graph and built a
\newdef{loop nesting tree}
that describes the loop nesting relationship between graphs.
\begin{SML}
signature \mlrischref{ir/loop-structure.sig}{LOOP_STRUCTURE} = sig
structure Dom : DOMINATOR_TREE
datatype ('n,'e,'g) loop =
LOOP of \{ nesting : int,
header : node_id,
loop_nodes : node_id list,
backedges : 'e edge list,
exits : 'e edge list
\}
type ('n,'e,'g) loop_info
type ('n,'e,'g) loop_structure = (('n,'e,'g) loop,unit, ('n,'e,'g) loop_info) graph
val loop_structure : ('n,'e,'g) Dom.dominator_tree -> ('n,'e,'g) loop_structure
val nesting_level : ('n,'e,'g) loop_structure -> node_id array
val header : ('n,'e,'g) loop_structure -> node_id array
end
\end{SML}
Our algorithm computes the loop nesting tree in time
$O((|V|+|E|)\alpha(|V|+|E|))$.
Each node in this tree represents a loop in the flowgraph, except the
root of the tree, which represents the entire graph.
Given a flowgraph $G$, the root
of the loop nesting tree is defined to be the sole vertex in
\sml{#entry} $G$. Other nodes in the tree
are indexed by the loop header node ids.
Loop detection classifies each loop and for
each loop $L$, the following information is obtained:
\begin{itemize}
\item An integer \sml{nesting}. The root of the tree has nesting
depth 0. The top level loops have nesting depth 1, etc.
\item The node id of the loop \sml{header} $h$.
\item A set of \sml{loop_nodes}. Loop nodes are
nodes that are in the strongly connected
component $L$, but excluding the header $h$
and all nodes that are part of any nested loops.
Thus all nodes are uniquely partitioned in header nodes and
loop nodes, and loop nodes are further partitioned into different
sets according to which headers they are immediately nested under.
\item A set of \sml{backedges}. A back-edge is an
edge that targets the header $h$ and originates from a loop node
in $L$.
\item A set of loop \sml{exits}. An exit-edge is an edge
that originates from a loop node within $L$
targets a node outside of $L$. Note that this set does not include
any exit-edges contained in loops nested in $L$ but
target a node out of $L$.
\end{itemize}
\subsubsection{Static Single Assignment}
An SSA construction algorithm based on~\cite{SSA,Briggs-SSA,linear-time-IDF}
is implemented in the following functor:
\begin{SML}
functor \mlrischref{ir/ssa.sml}{StaticSingleAssignmentForm}
(Dom : DOMINATOR_TREE) : STATIC_SINGLE_ASSIGNMENT_FORM
\end{SML}
SSA-based optimizations in MLRISC
are actually implemented on top of a
high-level SSA layer described in Section~\ref{sec:ssa}.
So it is not necessary to use this module directly. Nevertheless,
there can be situations in which this module can be specialized in other
ways; for example, in the construction of sparse evaluation graphs.
\begin{SML}
signature \mlrischref{ir/ssa.sig}{STATIC_SINGLE_ASSIGNMENT_FORM} = sig
structure Dom : DOMINATOR_TREE
type var = int
type phi = var * var * var list $(* orig def/def/uses *)$
type renamer = \{defs : var list, uses: var list\} ->
\{defs : var list, uses: var list\}
type copy = \{dst : var list, src: var list\} -> unit
val compute_ssa :
('n,'e,'g) Dom.dominator_tree ->
\{ max_var : var,
defs : 'n node -> var list,
is_live : var * int -> bool,
rename_var : var -> var,
rename_stmt : \{rename:renamer,copy:copy\} -> 'n node -> unit,
insert_phi : \{block : 'n node,
in_edges : 'e edge list,
phis : phi list
\} -> unit
\} -> unit
end
\end{SML}
This module defines the function \sml{compute_ssa}, which
constructs an SSA graph. It requires
the following information from the client:
\begin{itemize}
\item A dominator tree of the flowgraph.
\item \sml{max_var} -- the maximum variable id (integer) that exists
in the flowgraph. All variables are assumed to be indexed by non-negative
integers.
\item \sml{defs}($X$) -- a function that returns $defs(X)$,
i.e.~the set of variable names defined in block $X$.
If a minimal SSA form is desired, this set should include all the definitions
in $X$. If a pruned SSA form is required, this set should
include only the set of names that are live-out in $X$.
\item \sml{is_live}($v,X$) -- a function that determines if
variable $v$ is live-in into block $X$. If not, a $\phi$-function will
not be placed in $X$. For example, to compute
the minimal-SSA form, this function should always return true.
\item \sml{rename_var}($v$) -- a function that returns a new
unique name for variable $v$.
\item \sml{rename_stmt} -- a function of type
\sml{{rename:renamer,copy:copy} -> 'n node -> unit} where
\begin{SML}
type renamer = \{defs : var list, uses: var list\} ->
\{defs : var list, uses: var list\}
type copy = \{dst : var list, src: var list\} -> unit
\end{SML}
Function \sml{rename_stmt} is called for each block
in the flowgraph in the order of the dominator tree, and
is responsible for renaming all the variables in $X$ by
calling the functions \sml{renamer} or \sml{copy}.
Function \sml{renamer} renames all definitions and uses of
a statement, while function \sml{copy} renames
of a set of parallel assignments
\item \sml{insert_phi}($X$,$es$,$phis$) --
a function that inserts a set of
$\phi$-definitions $phis$ in block $X$, where $es$
is the list of control flow edges that merge into block $X$.
\end{itemize}
\subsubsection{IDEFS/IUSE sets}
Reif and Tarjan define the following useful notions for
computing approximate birth-points for expressions, which in turn
can be used to drive other optimizations.
Given a node $X$, let $idom(X)$ denote the immediate dominator of $X$.
Let $def(X)$ ($use(X)$) denote all the definitions (uses) in $X$.
Given a path $p \equiv v_1\ldots v_n$, define $def(p)$ ($use(p)$) as
\begin{eqnarray*}
def(v_1\ldots v_n) & \equiv &\union_{i \in 1 \ldots n} def(v_i) \\
use(v_1\ldots v_n) & \equiv &\union_{i \in 1 \ldots n} use(v_i)
\end{eqnarray*}
Let $P(X)$ denotes all the paths from $idom(X)$ to $X$
that does not cross $idom(X)$ internally. Then define
$idef(X)$ ($iuse(X)$) as:
\begin{eqnarray*}
idef(X) & \equiv & \Union_{idom(X) v_1 \ldots v_n X \in P(X)}
def(v_1\ldots v_n) \\
iuse(X) & \equiv & \Union_{idom(X) v_1 \ldots v_n X \in P(X)}
use(v_1\ldots v_n)
\end{eqnarray*}
The sets $ipostdef(X)$ and $ipostuse(X)$ are defined analogously
using the postdominator tree.
\begin{SML}
signature \mlrischref{ir/idefs2.sig}{IDEFS} = sig
type var = int
val compute_idefs :
\{def_use : 'n Graph.node -> var list * var list,
cfg : ('n,'e,'g) Graph.graph
\} ->
\{ idefuse : unit -> (RegSet.regset * RegSet.regset) Array.array,
ipostdefuse : unit -> (RegSet.regset * RegSet.regset) Array.array
\}
end
structure \mlrischref{ir/idefs2.sml}{IDefs} : IDEFS
\end{SML}
Structure \sml{IDefs} implements the function
\sml{comput_idefs} for computing
the $idef$, $iuse$, $ipostdef$ and $ipostuse$ sets of a control flow
graph. It takes as arguments a flowgraph and a function \sml{def_use}, which
takes a graph node and returns the def/use sets of the node.
It returns two functions \sml{idefuse} and \sml{ipostdefuse} which
compute the $idef/iuse$ and $ipostdef/ipostuse$ sets. These sets
are returned as arrays indexed by node ids.
+36
View File
@@ -0,0 +1,36 @@
\section{Client Defined Constants}
\subsubsection{Introduction}
MLRISC allows the client to inject abstract
\newdef{constants} that are resolved
only at the end of the compilation phase into the instruction stream.
These constants can be used whereever an integer literal is expected.
Typical usage are stack frame offsets for spill locations which are only
known after register allocation,
and garbage collection and exception map which are resolved only
when all address calculation are performed.
\subsubsection{The Details}
Client defined constants should satsify the following signature:
\begin{SML}
signature \mlrischref{instructions/constant.sig}{CONSTANT} = sig
type const
val toString : const -> string
val valueOf : const -> int
val hash : const -> word
val == : const * const -> bool
end
\end{SML}
The methods are:
\begin{methods}
toString & a pretty printing function \\
valueOf & returns the value of the constant \\
hash & returns the hash value of the constant \\
== & compare two constants for identity \\
\end{methods}
The method \sml{toString} should be implemented in all cases.
The method \sml{valueOf} is necessary only if machine code generation
is used. The last two methods, \sml{hash} and \sml{==} are necessary
only if SSA optimizations are used.
+60
View File
@@ -0,0 +1,60 @@
\section{Contributions}
The optimizations provided by MLRISC are at a similar level to
those performed by the Impact compiler; several target back ends
exist (Dec Alpha, HPPA, Sparc, x86, and PPC); but more importantly, the
framework has been demonstrated in \href{systems.html}{real use}
for languages with radically different execution models. These include:
\begin{center}
\begin{tabular}{|c|c|} \hline
Compiler & Association \\ \hline
\begin{color}{#005500}SML/NJ\end{color} & Bell Labs and Princeton\\\hline
\begin{color}{#005500}TIL\end{color} & CMU \\ \hline
\begin{color}{#005500}Tiger\end{color} & Princeton \\ \hline
\begin{color}{#005500}C--\end{color} & OGI \\ \hline
\begin{color}{#005500}SML/Regions\end{color} & DIKU \\ \hline
\begin{color}{#005500}Moby\end{color} & Bell Labs \\ \hline
\end{tabular}
\end{center}
The strength of MLRISC lies in the ability to easily create high
quality code generator for each of these systems. For example:
\begin{description}
\item[Tiger:] Has an execution
model very similar to C with stack allocated activation frames,
and also maintains static and dynamic chains to support lexical
scoping.
\item[TIL:] Is similar to C in its
use of activation frames, however it uses a
\emph{typed intermediate language} that
supports \emph{almost tag-free}
garbage collection. This has severe implications on the
interaction of spilling and garbage collection. The set of live
variables and their locations, be it registers or frame slots,
is recorded in a trace table for a specific program point. When
spilling occurs, it is necessary to adjust some of these trace
tables to reflect the new locations of live variables.
\item[SML/NJ:] Has no runtime
stack, but stores all execution context in a garbage collected
heap. This arrangement imposes special requirements for spilling
registers. SML/NJ also does \emph{dynamic linking} --- that is
to say, no use is made of a conventional linker, but machine
code is generated directly and linked into the interactive
environment, dynamically.
\item[C--:] Is a C-like portable assembly
language used as an intermediate language for high level typed language,
and provides direct compilation support for exceptions and
precise garbage collection. In addition, it allows
interoperability with C function calls.
\end{description}
It is not uncommon for any of these systems to store special global
values in dedicated registers, and use their own parameter passing
and callee-save conventions. In any language that supports garbage
collection, there are also the issues of generating gc type maps,
and gc-safety in aggressive optimizations. MLRISC deals with all these
important issues by allowing customization of many aspects of the system.
+15
View File
@@ -0,0 +1,15 @@
\section{Contributors}
\subsubsection{Past}
\begin{itemize}
\item Florent Guillame (INRIA)
\item George C. Necula (CMU)
\item Ken Cline (CMU)
\item Andrew Bernard (CMU)
\item Dino Oliva (NEC)
\end{itemize}
\subsubsection{Present}
\begin{itemize}
\item Allen Leung (NYU)
\item Fermin Reig (University of Glasgow)
\end{itemize}
+174
View File
@@ -0,0 +1,174 @@
\section{Delay Slot Filling}
\subsection{ Overview }
Superscalar architectures such as the Sparc, MIPS, and PA-RISC
contain delayed branch and/or load instructions.
Delay slot filling is necessary
task of the back end to keep the instruction pipelines busy. To accomodate
the intricate semantics of branch delay slot in various architectures,
MLRISC uses the following very general framework for dealing with
delayed instructions.
\begin{description}
\item[Instruction representation]
To make it easy to deal with instruction with delay slot, MLRISC allow
the following extensions to instruction representations.
\begin{itemize}
\item Instructions with delay slot may have a
\begin{color}{#aa0000}nop\end{color} flag. When this flag is true
the delay slot is assumed to be filled with a NOP instruction.
\item Instructions with delay slots that can be nullified may have a
\begin{color}{#aa0000}nullified\end{color} flag.
When this flag is true the branch delay slot is assumed to be
nullified.
\end{itemize}
\item[Nullification semantics]
Unfortunately, nullification semantics
in architectures vary. In general, MLRISC allows the following
additional nullification characteristics to be specified.
\begin{itemize}
\item Nullification can be specified as illegal; this is needed
because some instructions can not be nullified
\item When nullification is enabled, the semantics of the delay slot
instruction may depend on the direction of the branch, and whether
a conditional test succeeds.
\item Certain class of instructions may be declared to be illegal
to fit into certain class of delay slots.
\end{itemize}
\end{description}
For example, conditional branch instructions on the Sparc are defined
as follows:
\begin{verbatim}
Bicc of {b:branch, a:bool, label:Label.label, nop:bool}
asm: ``b<b><a>\t<label><nop>''
padding: nop = true
nullified: a = true and (case b of I.BA => false | _ => true)
delayslot candidate: false
\end{verbatim}
\noindent where \sml{a} is \emph{annul} flag and \sml{nop} is the nop
flag (see \mlrischref{sparc/sparc.md}{the Sparc machine description}).
A constructor term
\begin{SML}
Bicc\{b=BE, a=true, label=label, nop=true\}
\end{SML}
denotes the instruction sequence
\begin{verbatim}
be,a label
nop
\end{verbatim}
while
\begin{SML}
Bicc\{b=BE, a=false, label=label, nop=false\}
\end{SML}
denotes
\begin{verbatim}
be label
\end{verbatim}
\subsection{The Interface}
Architecture information about how delay slot filling is to be performed
is described in the signature
\mlrischref{backpatch/delaySlotProps.sig}{DELAY\_SLOT\_PROPERTIES}.
\begin{SML}
signature DELAY_SLOT_PROPERTIES =
sig
structure I : INSTRUCTIONS
datatype delay_slot =
D_NONE | D_ERROR | D_ALWAYS
| D_TAKEN | D_FALLTHRU
val delaySlotSize : int
val delaySlot : \{ instr : I.instruction, backward : bool \} ->
\{ n : bool,
nOn : delay_slot,
nOff : delay_slot,
nop : bool
\}
val enableDelaySlot :
\{instr : I.instruction, n:bool, nop:bool\} -> I.instruction
val conflict :
\{regmap:int->int,src:I.instruction,dst:I.instruction\} -> bool
val delaySlotCandidate :
\{ jmp : I.instruction, delaySlot : I.instruction \} -> bool
val setTarget : I.instruction * Label.label -> I.instruction
end
\end{SML}
The components of this signature are:
\begin{description}
\item[delay\_slot] This datatype describes properties related to a
delay slot.
\begin{description}
\item[D\_NONE] This indicates that no delay slot is possible.
\item[D\_ERROR] This indicates that it is an error
\item[D\_ALWAYS] This indicates that the delay slot is always active
\item[D\_TAKEN] This indicates that the
delay slot is only active when branch is taken
\item[D\_FALLTHRU] This indicates that the delay slot
is only active when branch is not taken
\end{description}
\item[delaySlotSize] This is size of delay slot in bytes.
\item[delaySlot] This method takes an instruction \sml{instr}
and a flag indicating whether the branch is \sml{backward},
and returns the delay slot properties of an instruction. The
properties is described by four fields.
\begin{description}
\item[n : bool] This bit is if the nullified bit in the
instruction is currently set.
\item[nOn : delay\_slot] This field indicates the delay slot
type when the instruction is nullified.
\item[nOff : delay\_slot] This field indiciates the delay slot
type when the instruction is not nullified.
\item[nop : bool] This bit indicates whether there is an
implicit padded nop.
\end{description}
\item[enableDelaySlot]
This method set the nullification and nop flags of an instruction.
\item[conflict] This method checks whether there are any conflicts
between instruction \sml{src} and \sml{dst}.
\item[delaySlotCandidate]
This method checks whether instruction \sml{delaySlot} is within the
class of instructions that can fit within the delay slot of
instruction \sml{jmp}.
\item[setTarget]
This method changes the branch target of an instruction.
\end{description}
\subsubsection{Examples}
For example,
\begin{SML}
delaySlot\{instr=instr, backward=true\} =
\{n=true, nOn=D_ERROR, nOff=D_ALWAYS, nop=true\}
\end{SML}
\noindent means that the instruction nullification bit is on, the
the nullification cannot be turned off, delay slot is always active
(when not nullified), and there is currently an implicit padded nop.
\begin{SML}
delaySlot\{instr=instr, backward=false\} =
\{n=false, nOn=D_NONE, nOff=D_TAKEN, nop=false\}
\end{SML}
\noindent means that the nullification bit is off, the delay slot
is inactive when the nullification bit is off, the delay slot is only
active when the (forward) branch is taken when \sml{instr} is
not-nullified, and there
is no implicitly padded nop.
\begin{SML}
delaySlot\{instr=instr, backward=true\} =
\{n=true, nOn=D_TAKEN, nOff=D_ALWAYS, nop=true\}
\end{SML}
\noindent means that the nullification bit is on, the delay slot
is active on a taken (backward) branch when the nullification bit is off,
the delay slot is always active when \sml{instr} is not-nullified,
and there is currently an implicitly padded nop.
+7
View File
@@ -0,0 +1,7 @@
\section{Frequency Driven Compilation}
Most optimizations in MLRISC are driven by execution frequencies
estimates provided by the front-end. These can be in the form of explicit
vertex and edge frequencies, in the form of branch probabilities, or a
combination of the above. Frequency information can be propagated
to the backend via the \href{annotations.html}{annotations} mechanism.
+30
View File
@@ -0,0 +1,30 @@
\section{Future Work}
\subsection{Short Term}
\begin{description}
\item[Detailed user manual:]
A detailed user manual describing the interfaces, algorithms,
and examples on how to put together code generators.
\item[Support for GC:]
There is a strong interaction
with support for GC and global code motion. MLRISC aims at
providing a generic framework for code generators, and finding
the right level of information to support GC and global code
motion is an issue. I think we have several solutions to address
this that need more evaluation.
\item[Other architectures:] There is the need to port
to other architectures like the MIPS, and the IA-64.
\end{description}
\hr
\subsection{Long Term}
\begin{description}
\item[Predicated VLIW compilation:] Currently, the framework
for predicated VLIW architectures compilation
is incomplete, and contain only one back end (C6)
\item[Other compilers:] I would really like to see some
major compiler effort bootstrapped with an MLRISC backend.
\item[Verification] It is extremely difficult to
debug errors in modules that perform aggressive code
reorganizations. Ideas from formal methods such as typed assembly
language (TAL) or Proof Carrying Code (PCC) are worth investigating.
\end{description}
+104
View File
@@ -0,0 +1,104 @@
\section{Garbage Collection Safety}
\subsection{Motivation}
High level languages such as SML make use of garbage collectors
to reclaim unused storage at runtime. For generality, I assume that
a precise, compacting garbage collector is used. In general,
low-level optimizations that reorder instructions
pass \newdef{gc safepoints}, when applied naively,
are not safe. In general, two general classes of safety issues can be identified:
\begin{description}
\item[derived values]
A derived value $x$ is a value that are
dependent on the addresses of one of more heap allocated objects
$a1,a2,a3,\ldots$ and/or the recent branch history.
When these allocated objects $a1,a2,a3,\ldots$
are moved by the garbage collector, $x$
has to be adjusted accordingly.
For example, inductive variable elimination may transformed an array
indexing into a running pointer to the middle of an array object.
Such running pointer is a derived value and is dependent on the
starting address of the array.
The main difficulty in handling a derived value $x$
during garbage collection is that sometimes it is impossible or
counter-productive to recompute from $a1,a2,a3,\ldots$.
For example, when the recent branch history is unknown, or when the
precise relationship between $x$ and $a1,a2,a3,\ldots$ cannot
be inferred from context.
We call these \newdef{unrecoverable} derived values.
\item[incomplete allocation]
If heap allocation is performed inlined, then code motion may
render some allocation incomplete at a gc safepoint. In general, incomplete
allocation has to be completed, or rolled backed and then reexecuted
after garbage collection, when the source language semantics allow it.
\end{description}
Typically, two gc safepoints cannot be separated by an unbounded
number of allocations, which implies that in general, optimizations that move
instructions between basic blocks are unsafe when naively applied,
which greatly limits the class of optimizations in such an environment
to trivial basic block level optimizations.
framework is a necessity.
\subsection{Safety Framework}
MLRISC contains a gc-safety framework
for performing aggressive machine level optimizations, including SSA-based
scalar optimizations, global instruction scheduling, and global
register allocation. Unlike previous work in this area, phases that
perform optimizations and phases that maintain and update
garbage collection information are completely separate, and the optimizer
is constructed in a fully modular manner. In particular,
gc-types and safety constraints
are \emph{parameterizable}
by the source language semantics, the object representation,
and the target architectures.
This framework has the following overall structure:
\begin{description}
\item[Garbage collection invariants annotation]
The front-end client is responsible for annotating each
value in the program with a \newdef{gc type}, which is
used to specify the abstract object representation,
and the constraints on code motion that may be applied to such a value.
The front-end uses an architecture independent \href{mltree.html}{RTL}
language for representing the program, thus this annotation
phase is portable between target architectures.
\item[GC constraints propagation]
After instruction selection, gc constraint are propagated throughout
the machine level program representation. Again, for portability, gc typing
rules are specified in terms of the \href{mltree.html}{ RTL } of
the machine instructions. In this phase, unsafe code motions which
exposes unrecoverable derived values to gc safepoints are automatically
identified. (Pseudo) control dependence and anti-control dependence
constraints are then added the program representation to prohibit all
gc-unsafe code motions.
\item[Machine level optimizations]
After constraints propagation, traditional
machine level optimizations such as
SSA optimizations and/or global scheduling are applied, without regard
to gc information. This is safe because
all gc safety constraints have been translated into the appropriate
code motion constraints.
\item[GC type propagation and gc code generation]
GC type inference is performed when all optimizations
have been performed. GC safepoints are then
identified and the root sets are determined. In addition, compensation
code are inserted at gc points for repairing recoverable derived values.
\end{description}
\subsection{Concurrency Safety}
In the presence of \newdef{concurrency}, i.e. multiple threads
of control that communicate via a shared heap, the above framework
will have to slightly extended. As in before, we assume that
context switching can only occur at well-defined
\emph{safepoints}.
The crucial aspect is that values that are live at safepoints must be
classified as \newdef{local} or \newdef{global}.
Local values are only observable from
the local thread, while global values are potentially observable and mutable
from other threads. The invariants to maintain are as follows:
\begin{itemize}
\item Only local and recoverable derived values may be live at a safepoint,
\item Only local and recoverable allocation may be incomplete at a safepoint
\end{itemize}
+128
View File
@@ -0,0 +1,128 @@
\section{The Graph Visualization Library}
\subsection{Overview}
Visualization is an important aid for debugging graph algorithms.
MLRISC provides a simple facility for displaying graphs that
adheres to the graph interface. Two graph viewer
back-ends are currently supported. (An interface to the \emph{dot}
tool is still available but is unsupported.)
\begin{itemize}
\item \externhref{http://www.cs.uni-sb.de/RW/users/sander/html/gsvcg1.html}{vcg} --
this tool supports the browsing
of hierarchical graphs, zoom in/zoom out functions. It can
handle up to around 5000 nodes in a graph.
\item \externhref{http://www.Informatik.Uni-Bremen.DE/~davinci/}{daVinci} --
this tool supports a separate
``survey'' view from the main view and text searching. This tool is
slower than vcg but it has a nicer interface, and
can handle up to around 500 nodes in a graph.
\end{itemize}
All graph viewing back-ends work in the same manner.
They take a graph whose nodes and edges are annotated with \newdef{layout}
instructions and translate these layout instructions
into the target description language. For vcg, the target description
language is GDL. For daVinci, it is a language based on s-expressions.
\subsection{Graph Layout}
Some basic layout formats are defined structure \sml{GraphLayout} are:
\begin{SML}
structure \mlrischref{visualization/graphLayout.sml}{GraphLayout} = struct
datatype format =
LABEL of string
| COLOR of string
| NODE_COLOR of string
| EDGE_COLOR of string
| TEXT_COLOR of string
| ARROW_COLOR of string
| BACKARROW_COLOR of string
| BORDER_COLOR of string
| BORDERLESS
| SHAPE of string
| ALGORITHM of string
| EDGEPATTERN of string
type ('n,'e,'g) style =
\{ edge : 'e edge -> format list,
node : 'n node -> format list,
graph : 'g -> format list
\}
type layout = (format list, format list, format list) graph
end
\end{SML}
The interpretation of the layout formats are as follows:
\begin{center}
\begin{tabular}{|l|l|} \hline
\sml{LABEL} $l$ & Label a node or an edge with the string $l$ \\
\sml{COLOR} $c$ & Use color $c$ for a node or an edge \\
\sml{NODE_COLOR} $c$ & Use color $c$ for a node \\
\sml{EDGE_COLOR} $c$ & Use color $c$ for an edge \\
\sml{TEXT_COLOR} $c$ & Use color $c$ for the text within a node \\
\sml{ARROW_COLOR} $c$ & Use color $c$ for the arrow of an edge \\
\sml{BACKARROW_COLOR} $c$ & Use color $c$ for the arrow of an edge \\
\sml{BORDER_COLOR} $c$ & Use color $c$ for the border in a node \\
\sml{BORDERLESS} & Disable border for a node \\
\sml{SHAPE} $s$ & Use shape $s$ for a node \\
\sml{ALGORITHM} $a$ & Use algorithm $a$ to layout the graph \\
\sml{EDGEPATTERN} $p$ & Use pattern $p$ to layout an edge \\
\hline
\end{tabular}
\end{center}
Exactly how these formats are interpreted is determined by
the visualization tool that is used. If a feature is unsupported
then the corresponding format will be ignored.
Please see the appropriate reference manuals of vcg and daVinci for details.
\subsection{Layout style}
How a graph is layout is determined by its \newdef{layout style}:
\begin{SML}
type ('n,'e,'g) style =
\{ edge : 'e edge -> format list,
node : 'n node -> format list,
graph : 'g -> format list
\}
\end{SML}
which is simply three functions that convert nodes, edges and graph
info into layout formats.
The function \sml{makeLayout} can be used to convert a
layout style into a layout, which can then be passed to a graph
viewer to be displayed.
\begin{SML}
GraphLayout.makeLayout : ('n,'e,'g) style -> ('n,'e,'g) graph -> layout
\end{SML}
\subsection{Graph Displays}
A \newdef{graph display} is an abstraction for the
interface that converts a layout graph into an external graph
description language. This abstraction is defined in the
signature below.
\begin{SML}
signature \mlrischref{visualization/graphDisplay.sig}{GRAPH_DISPLAY} = sig
val suffix : unit -> string
val program : unit -> string
val visualize : (string -> unit) -> GraphLayout.layout -> unit
end
\end{SML}
\begin{itemize}
\item \sml{suffix} is the common file suffix used for the graph description
language
\item \sml{program} is the common name of the graph visualization tool
\item \sml{visualize} is a function that takes a
string output function and a layout graph $G$ as arguments
and generates a graph description based on $G$
\end{itemize}
\subsection{Graph Viewers}
The graph viewer functor
\mlrischref{visualization/graphViewer.sml}{GraphViewer}
takes a graph display back-end and creates a graph viewer
that can be used to display any layout graph.
\begin{SML}
signature \mlrischref{visualization/graphViewer.sig}{GRAPH_VIEWER} = sig
val view : GraphLayout.layout -> unit
end
functor GraphViewer(D : GRAPH_DISPLAY) : GRAPH_VIEWER
\end{SML}
File diff suppressed because it is too large Load Diff
+3
View File
@@ -0,0 +1,3 @@
\section{The PA RISC Back End}
No documentation yet.
+244
View File
@@ -0,0 +1,244 @@
\section{Instruction Selection} \label{sec:instrsel}
Instruction selection modules are reponsible for translating
\href{mltree.html}{MLTree} statements into a flowgraph consisting
of target machine instructions. MLRISC decomposes this complex task
into \emph{three} components:
\begin{description}
\item[Instruction selection modules] which are responsible for
mapping a sequence of MLTree statements into a sequence target machine code,
\item[Flowgraph builders] which are responsible for constructing
the graph representation of the program from a sequence of target machine
instructions, and
\item[Client Extender] which are responsible for compiling
MLTree extensions (see also Section~\ref{sec:mltree-extension}).
\end{description}
By detaching these components, extra flexiblity is obtained. For example,
the MLRISC system uses two different internal representations. The
first, \href{cluster.html}{cluster}, is a \emph{light-weight} representation
which is suitable for simple compilers without extensive
optimizations; the second, \href{mlrisc-ir.html}{MLRISC IR}, is a
\emph{heavy duty} representation which allows very complex transformations
to be performed. Since the flowgraph builders are detached from the
instruction selection modules, the same instruction selection modules
can be used for both representations.
For consistency, the three components communicate to each other
via the same \href{stream.html}{stream} interface.
\subsection{Interface Definition}
All instruction selection modules satisfy the following signature:
\begin{SML}
signature \mlrischref{mltree/mltreecomp.sig}{MLTREECOMP} =
sig
structure T : \href{mltree.html}{MLTREE}
structure I : \href{instructions.html}{INSTRUCTIONS}
structure C : \href{cells.html}{CELLS}
sharing T.LabelExp = I.\href{labelexp.html}{LabelExp}
sharing I.C = C
type instrStream = (I.instruction,C.regmap,C.cellset) T.stream
type mltreeStream = (T.stm,C.regmap,T.mlrisc list) T.stream
val selectInstructions : instrStream -> mltreeStream
end
\end{SML}
Intuitively, this signature states that
the instruction selection module
returns a function that can transform a stream of MLTree statements
(\newtype{mltreeStream}) into a stream of instructions of the target
machine (\newtype{instrStream}).
\subsubsection{Compiling Client Extensions}
Compilation of client extensions to MLTREE is controlled by the
following signature:
\begin{SML}
signature \mlrischref{mltree/mltreecomp.sig}{MLTREE_EXTENSION_COMP} =
sig
structure T : \href{mltree.html}{MLTREE}
structure I : \href{instructions.html}{INSTRUCTIONS}
structure C : \href{cells.html}{CELLS}
sharing T.LabelExp = I.\href{labelexp.html}{LabelExp}
sharing I.C = C
type reducer =
(I.instruction,C.regmap,C.cellset,I.operand,I.addressing_mode) T.reducer
val compileSext : reducer -> \{stm:T.sext, an:T.an list\} -> unit
val compileRext : reducer -> \{e:T.ty * T.rext, rd:C.cell, an:T.an list\} -> unit
val compileFext : reducer -> \{e:T.ty * T.fext, fd:C.cell, an:T.an list\} -> unit
val compileCCext : reducer -> \{e:T.ty * T.ccext, ccd:C.cell, an:T.an list\} -> unit
end
\end{SML}
Methods \verb|compileSext|, \verb|compileRext|, etc.~are callbacks that
are responsible for compiling MLTREE extensions. The arguments
to these callbacks have the following meaning:
\begin{description}
\item[reducer] The first argument is always the \newtype{reducer},
which contains internal methods for translating MLTree constructs
into machine code. These methods are supplied by the instruction
selection modules.
\item[an] This is a list of annotations that should be attached to the
generated code.
\item[ty, fty] These are the types of the extension construct.
\item[stm, e] This are the extension statement and expression.
\item[rd, fd, cd] These are the target registers of the
expression extension, i.e.~the callback should generate the appropriate
code for the expression and writes the result to this target.
\end{description}
For example, when an instruction selection encounters a
\verb|FOR(|$i,a,b,s$\verb|)| statement extension
defined in Section~\ref{sec:mltree-extension}, the callback
\begin{SML}
compileStm reducer \{ stm=FOR(\(i,a,b,s\)), an=an \}
\end{SML}
\noindent is be involved.
The \newtype{reducer} type is defined
in the signature \mlrischref{mltree/mltree.sig}{MLTREE} and has the
following type:
\begin{SML}
datatype reducer =
REDUCER of
\{ reduceRexp : rexp -> reg,
reduceFexp : fexp -> reg,
reduceCCexp : ccexp -> reg,
reduceStm : stm * an list -> unit,
operand : rexp -> I.operand,
reduceOperand : I.operand -> reg,
addressOf : rexp -> I.addressing_mode,
emit : I.instruction * an list -> unit,
instrStream : (I.instruction,C.regmap,C.cellset) stream,
mltreeStream : (stm,C.regmap,mlrisc list) stream
\}
\end{SML}
The components of the reducer are
\begin{description}
\item[reduceRexp, reduceFexp, reduceCCexp] These functions
take an expression of type integer, floating point and condition code,
translate them into machine code and return the
register that holds the result.
\item[reduceStm] This function takes an MLTree statement and translates
it into machine code. it also takes a second argument, which is the
list of annotations that should be attached to the statement.
\item[operand] This function translates an \sml{rexp} into an
\sml{operand} of the machine architecture.
\item[reduceOperand] This function takes an operand of the machine
architecture and reduces it into an integer register.
\item[addressOf] This function takes an \sml{rexp}, treats
it as an address expression and translates it into the appropriate
\sml{addresssing_mode} of the target architecture.
\item[emit] This function emits an instruction with attached annotations
to the instruction stream
\item[instrStream, mltreeStream] These are the instruction stream
and mltree streams that are currently bound to the extender.
\end{description}
\subsubsection{Extension Example}
Here is an example of how the extender mechanism can be used,
using the \sml{DSP_MLTREE} extensions defined in
Section~\ref{sec:mltree-extension}. We need supply two
new functions, \verb|compileDSPStm| for compiling the \verb|FOR|
construct, and \verb|compileDSPRexp| for compiling the \verb|SUM|,
and saturated arithmetic instructions.
The first function, \sml{compileDSPStm}, is generic and simply
translates the \verb|FOR| loop into the appropriate branches.
Basically, we will translate \verb|FOR(|$i,start,stop,body$\verb|)| into
the following loop in pseudo code:
\begin{SML}
limit = \(stop\)
\(i\) = \(start\)
goto test
loop: \(body\)
\(i\) = \(i\) + 1
test: if \(i\) <= limit goto loop
\end{SML}
This transformation can be implemented as follows:
\begin{SML}
functor DSPMLTreeExtensionComp
(structure I : DSP_INSTRUCTION_SET
structure T : DSP_MLTREE
sharing I.LabelExp = T.LabelExp
) =
struct
structure I = I
structure T = T
structure C = I.C
type reducer =
(I.instruction,C.regmap,C.cellset,I.operand,I.addressing_mode) T.reducer
fun mark(s, []) = s
| mark(s, a::an) = mark(ANNOTATION(s, a), an)
fun compileSext (REDUCER\{reduceStm, ...\})
\{stm=FOR(i, start, stop, body), an\} =
let val limit = C.newReg()
val loop = Label.newLabel ""
val test = Label.newLabel ""
in reduceStm(
SEQ[MV(32, i, start),
MV(32, limit, stop),
JMP([], [LABEL(LabelExp.LABEL test)], []),
LABEL loop,
body,
MV(32, i, ADD(32, REG(32, i), LI 1),
LABEL test,
mark(BCC([],
CMP(32, LE, REG(32, i), REG(32, limit)),
loop),
an),
]
)
end
...
\end{SML}
In this transformation, we have chosen to proprogate the annotation
\verb|an| into the branch constructor.
Assuming the target architecture that we are translated into contains
saturated arithmetic instructions \verb|SADD|, \verb|SSUB|, \verb|SMUL|
and \verb|SDIV|, the DSP extensions
\verb|SUM| and saturated arithmetic expressions can be handled as follows.
\begin{SML}
fun compileRext (REDUCER\{reduceStm, reduceRexp, emit, ...\})
\{ty, e, rd, an\} =
(case (ty,e) of
(_,T.SUM(i, a, b, exp)) =>
reduceStm(SEQ[MV(ty, rd, LI 0),
FOR(i, a, b,
mark(MV(ty, rd, ADD(ty, REG(ty, rd), exp)), an))
]
)
| (32,T.SADD(x,y)) => emit(I.SADD\{r1=reduceRexp x,r2=reduceRexp y,rd=rd\},an)
| (32,T.SSUB(x,y)) => emit(I.SSUB\{r1=reduceRexp x,r2=reduceRexp y,rd=rd\},an)
| (32,T.SMUL(x,y)) => emit(I.SMUL\{r1=reduceRexp x,r2=reduceRexp y,rd=rd\},an)
| (32,T.SDIV(x,y)) => emit(I.SDIV\{r1=reduceRexp x,r2=reduceRexp y,rd=rd\},an)
| ...
)
fun compileFext _ _ = ()
fun compileCCext _ _ = ()
end
\end{SML}
Note that in this example, we have simply chosen to reduce
a \verb|SUM| expression into the high level \verb|FOR| construct.
Clearly, other translation schemes are possible.
\subsection{Instruction Selection Modules}
Here are the actual code for the various back ends:
\begin{enumerate}
\item \mlrischref{sparc/mltree/sparc.sml}{Sparc}
\item \mlrischref{hppa/mltree/hppa.sml}{PA-RISC}
\item \mlrischref{alpha/mltree/alpha.sml}{Alpha}
\item \mlrischref{ppc/mltree/ppc.sml}{Power PC}
\item \mlrischref{x86/mltree/x86.sml}{X86}
\item C6xx
\end{enumerate}
+88
View File
@@ -0,0 +1,88 @@
\section{Instructions}
Instructions in MLRISC are implemented as abstract datatypes and
must satisfy the signature
\mlrischref{instructions/instructions.sig}{INSTRUCTIONS}, defined as follows:
\begin{SML}
signature INSTRUCTIONS =
sig
structure C : \href{cells.html}{CELLS}
structure Constant : \href{constants.html}{CONSTANT}
structure LabelExp : \href{labelexp.html}{LABELEXP}
sharing LabelExp.Constant = Constant
type operand
type ea
type addressing_mode
type instruction
end
\end{SML}
Type \sml{operand} is used to represent ioperands,
\sml{ea} is used to represent effective addresses, type
\sml{addressing_mode} is used to represent the internal addressing mode
used by the architecture. Note that these are all abstract according to
the signature, so the client has complete freedom in choosing the most
convenient representation for these things.
\subsection{Predication}
For architectures that have full \newdef{predication}
built-in, such as the C6xx or IA-64, the instruction set should be
extended to satisfy the signature:
\begin{SML}
signature \mlrischref{instructions/pred-instructions.sig}{PREDICATED_INSTRUCTIONS} =
sig
include INSTRUCTIONS
type predicate
end
\end{SML}
This basically says that the type that is used to represent a predicate
can be implemented however the client wants. This flexibility
is quite important since the predication model may differ substantially
from architecture to architecture.
For example, in the TI C6, there are no seperate predicate register files
and integer registers double as predicate registers, and the predicate
true is any non-zero value. Each instruction can be predicated under a
predicate register or its negation. In contrasts, architectures such as
IA-64 and HP's Playdoh incorporate separate predicate registers into their
architectures. In Playdoh, \newdef{predicate defining} instructions
actually set a pair of complementary predicate registers,
and instructions can only
be predicated under the value of a predicate register, not its negation.
\subsection{VLIW}
VLIW architectures differ from superscalars in that
resource assignments are statically determined at compile time.
We distinguish between two different types of resources, namely
\newdef{functional units} and \newdef{data paths}.
The latter type is particularly
important for clustered architectures.
The following signature
is used to describe VLIW instructions:
\begin{SML}
signature \mlrischref{instructions/vliw-instructions.sig}{VLIW\_INSTRUCTIONS} =
sig
include INSTRUCTIONS
structure FU : \mlrischref{instructions/funits.sig}{FUNITS}
structure DP : \mlrischref{instructions/datapaths.sig}{DATAPATHS}
end
\end{SML}
The signature \sml{FUNITS} is used to describe functional unit
resources, while the signature \sml{DATAPATHS} is used to describe
data paths.
\subsection{Predicated VLIW}
Finally, instructions sets for predicated VLIW/EPIC machines should match
the signature
\begin{SML}
signature \mlrischref{instructions/pred-vliw-instructions.sig}{PREDICATED_VLIW_INSTRUCTIONS} =
sig
include VLIW_INSTRUCTIONS
type predicate
end
\end{SML}
+40
View File
@@ -0,0 +1,40 @@
\section{Label Expressions}
A \newdef{label expression} is a constant
expression defined in terms of labels, or user
defined \href{constants.html}{constants}. MLRISC uses the type
\sml{labexp} to represent label expressions. Label expressions
are defined in the structure
\mlrischref{instructions/labelExp.sml}{LabelExp}.
The datatype \sml{labexp} has the following definition:
\begin{SML}
datatype labexp =
LABEL of Label.label
| CONST of Constant.const
| INT of int
| PLUS of labexp * labexp
| MINUS of labexp * labexp
| MULT of labexp * labexp
| DIV of labexp * labexp
| LSHIFT of labexp * word
| RSHIFT of labexp * word
| AND of labexp * word
| OR of labexp * word
\end{SML}
In addition, the following functions are defined in \sml{labexp}:
\begin{itemize}
\item \sml{valueOf : labexp -> int} -- Returns the value associated with
a label expression
\item \sml{toString : labexp -> string} -- Return the pretty printed representation of an expression
\item \sml{hash : labexp -> word} -- Returns the hash value of an expression
\item \sml{== : labexp * labexp -> bool} -- Tests whether two label expression are lexically identical
\end{itemize}
The type \sml{labexp} is depends on client defined
\href{constants.html}{constants} typed. The functor \sml{LabelExp}
is parameterized as follows.
\begin{SML}
functor \mlrischref{instructions/labelExp.sml}{LabelExp}(Constant : \mlrischref{instructions/constant.sig}{CONSTANT})
\end{SML}
+25
View File
@@ -0,0 +1,25 @@
\section{Labels}
\newdef{Labels} are used as symbolic names for address.
The structure \mlrischref{instructions/labels.sml}{Label}
defines the label datatype. The following operations are defined
on labels:
\begin{itemize}
\item \sml{newLabel : string -> label} -- Generate a new label with
a given name. If the name is \sml{""}, a new name is generated.
\item \sml{nameOf : label -> string} -- Returns the name of
a label
\item \sml{id : label -> int} -- Return the unique id of a label
\item \sml{reset : unit -> unit} -- Return the label id counter to 0.
\end{itemize}
For machine code generation, the following two additional methods are
defined.
\begin{itemize}
\item \sml{addrOf : label -> int} -- Return the address associated with
a label
\item \sml{setAddr : label * int -> unit} -- Set the address associated
with a label
\end{itemize}
See also \href{labelexp.html}{Label Expressions}.
+40
View File
@@ -0,0 +1,40 @@
\section{Line Counts}
\begin{Table}{|l|r|r|}{align=right} \hline
& SML/NJ & MLRISC \\ \hline
\begin{color}{#00aa00}Generic\end{color} & 3,023 & 6,814 \\
\begin{color}{#00aa00}Hppa\end{color} & 725 & 2,285 \\
\begin{color}{#00aa00}Alpha\end{color} & 614 & 2,316 \\ \hline
TOTAL & 4,362 & 11,415 \\ \hline
\end{Table}
The table shows the number of lines involved in a basic MLRISC code
generator for SML/NJ that only does graph coloring register
allocation. The SML/NJ column shows the number of lines specific to
SML/N and the MLRISC column shows the number of lines specific to
MLRISC. The \begin{color}{#00aa00}Generic\end{color} shows the
number of lines that are target independent for both SML/NJ and
MLRISC. The \begin{color}{#00aa00}Hppa\end{color} and
\begin{color}{#00aa00}Alpha\end{color} shows the number of lines that are
target dependent for both the HP Hppa and DEC Alpha targets.
The bulk of the \sml{3,023} generic to SML/NJ is involved in the
generation of MLRisc trees. Once this is done the incremental cost
of adding a target is between \sml{600} to \sml{700} lines.
The MLRISC column shows that the bulk of MLRISC is quite generic and
a client is saved from writing \sml{11,415} lines of code.
\begin{Table}{|l|r|r|}{align=left} \hline
& SML/NJ & MLRISC \\ \hline
\begin{color}{#00aa00}Generic\end{color} & 121 + 3,023 & 15,686 + 6,814\\
\begin{color}{#00aa00}Hppa\end{color} & 32 + 725 & 920 + 2,285 \\
\begin{color}{#00aa00}Alpha\end{color} & 614 & 2,316 \\ \hline
TOTAL & 153 + 4,362 & 16,606 + 11,415 \\ \hline
\end{Table}
If one were to include the preliminary numbers for global acyclic
scheduling in the above table, we find that the incremental cost
required by the client is quite small -- approximately \sml{153}
lines of which \sml{121} are generic. However, the scheduling
infra structure is quite large, a lot of it being quite generic.
\br{left=clear}
+53
View File
@@ -0,0 +1,53 @@
\section{Machine Code Emitters}
\subsubsection{Overview}
MLRISC lets the client to directly emit machine code and bypass the traditional
assembly mechanism.
Machine code emitters in MLRISC satisfy the signature
\mlrischref{emit/instruction-emitter.sig}{INSTRUCTION\_EMITTER},
which is defined as:
\begin{SML}
signature INSTRUCTION_EMITTER =
sig
structure I : \href{instructions.html}{INSTRUCTIONS}
structure C : \href{cells.html}{CELLS}
structure S : \href{streams.html}{INSTRUCTION_STREAM}
structure P : \href{pseudo-ops.html}{PSEUDO_OPS}
sharing I.C = C
sharing S.P = P
val makeStream : Annotations.annotations ->
((int -> int) -> I.instruction -> unit,
unit,'b,'c,'d,'e) S.stream
end
\end{SML}
The function \sml{makeStream} returns an instruction stream.
The output, a stream of bytes, is direct to the client supplied
structure which satisfy the
\mlrischref{emit/code-string.sig}{CODE\_STRING} interface.
This signature is defined as follows:
\begin{SML}
signature CODE_STRING = sig
type code_string
val init : int -> unit
val update : int * Word8.word -> unit
val getCodeString : unit -> code_string
end
\end{SML}
\subsubsection{More Details}
Machine code emitters are automatically generated by the
\href{mlrisc-md.html}{MDGen} tool. Some specific generated
emitters are listed below:
\begin{enumerate}
\item \mlrischref{sparc/emit/sparcMC.sml}{Sparc}
\item \mlrischref{hppa/emit/hppaMC.sml}{Hppa}
\item \mlrischref{alpha/emit/alphaMC.sml}{Alpha}
\item \mlrischref{ppc/emit/ppcMC.sml}{Power PC}
\item \mlrischref{x86/emit/x86MC.sml}{X86}
\end{enumerate}
+444
View File
@@ -0,0 +1,444 @@
\section{The MLRISC Machine Description Language}
\subsection{ Overview }
\newdef{MDGen} is a machine description language
is designed to automate
various mundane and error prone tasks in developing a back-end for
MLRISC. Currently, to target a new
architecture the programmer must provide the following set of modules
written in Standard ML:
\begin{itemize}
\item \codehref{instructions/cells.sig}{CELLS} --
the properties of the register set and (some part of) memory hierarchy.
\item \codehref{instructions/instructions.sig}{INSTRUCTIONS} --
the concrete instruction set representation.
\item \codehref{instructions/insnProps.sig}{INSNS_PROPERTIES} --
properties of the instructions.
\item \codehref{instructions/shuffle.sig}{SHUFFLE} --
methods to emit linearized code from parallel copies.
\item \codehref{emit/instruction-emitter.sig}{ASSEMBLER} --
the assembler
\item \codehref{emit/instruction-emitter.sig}{MC} --
the machine code emitter
\item \codehref{../backpatch/sdi-jumps.sig}{ SDI_JUMPS } --
methods for resolving span-dependent instructions.
\item <a href="../backpatch/delaySlotProps.sig" target=code> DELAY_SLOTS_PROPERTIES
</a> -- machine properties for delay slot filling, if a machine
architecture contains branch delay slots or load delay slots.
\item \codehref{../SSA/ssaProps.sig}{ SSA_PROPERTIES } --
semantics properties for performing optimizations in Static Single
Assignment form.
\end{itemize}
In general, writing a backend is tedious even with
SML's abstraction capabilities.
Furthermore, the machine description is procedural in natural
and must be checked by hand.
\subsection{ What is in MDGen? }
The MDGen tool simplifies the process of developing a new MLRISC backend.
MDGen provides the following:
\begin{itemize}
\item A representation description language for specifying the
machine encoding of the instruction set,
using an extension of ML's algebraic datatype facility.
\item A semantics description language for specifying the abstract semantics
of the instructions.
\end{itemize}
Both sub-languages are based on ML's syntax and semantics, so
they should be readily familiar to all MLRISC users.
A backend developer can specify a new machine architecture using the MDGen
language, and in turn, the MDGen tool generates ML modules that are
required by the MLRISC system.
The basic concepts of MDGen are inspired largely from
Norman Ramsey's <a href="www.cs.virginia.edu/~nr/toolkit">
New Jersey Machine Code Tool Kit </a> and
Ramsey and Davidson's
<a href="http://www.cs.virginia.edu/zephyr/csdl/lrtlindex.html">
Lambda RTL </a>
\subsection{A Sample Description}
Here we present a sample MDGen description, using the Alpha as an example.
We highlight all keywords in the MDGen language
in. A typical machine description
is structured as follows:
\begin{SML}
architecture Alpha =
struct
name "Alpha"
superscalar
little endian
<font color=#FF0000>lowercase assembly</font>
\href{#cells}{Storage cells and locations}
\href{#encoding}{Instruction encoding formats specification}
\href{#instruction}{Instruction definition}
<font color=#FF0000>end</font>
\end{SML}
Here, we declare that the Alpha is a superscalar machine using
little endian encoding. Furthermore, assembly output should be displayed
in lowercase-- this is for personal esthetic reasons only; most assemblers
are case insensitive.
\subsubsection{ <a name="cells">Specifying Storage Cells and Locations </a>}
A <font color="#ff0000">cell</font> is an abstract resource location
for holding data values. On typical machines, the types of
cells include general purpose registers, floating point registers,
and condition code registers.
The \sml{storage} declaration defines different
<font color="#ff0000">cellkinds</font>. MLRISC requires the
cellkinds \sml{GP}, \sml{FP}, \sml{CC} to be defined.
These are the cellkinds for general purpose registers, floating point
registers and condition code registers.
In the following sequence of declarations, a few things are defined:
\begin{itemize}
\item The cellkinds \sml{GP, FP, CC} are defined.
Furthermore, the cellkinds \sml{MEM, CTRL}, which stand
for memory and control (dependence), are also implicitly defined.
\item The \sml{assembly as} clauses specify how a specific cell type is
to be displayed. Here, we specify that register 30, the
stack pointer, should be displayed specially as \sml{$sp}.
\item The \sml{in cellset} clause, when attached, tells MDGen that
the associated cellkind should be part of the
\href{cellset.html}{ cellset }. The clause \sml{in cellset GP}
tells MDGen that the a cell of type \sml{CC} should be treated
the same as a \sml{GP}
\item The \sml{locations} declarations define a few abbreviations:
\sml{stackptrR} is the stack pointer, \sml{asmTmpR} is
the assembly temporary, \sml{fasmTmp} is the floating point
assembly temporary etc.
\end{itemize}
<tt>
\begin{SML}
<font color=#FF0000>storage</font>
GP = 32 <font color=#FF0000>cells <font color=#FF0000>of</font> 64 bits in cellset called</font> "register"
<font color=#FF0000>assembly as</font> (fn 30 => "$sp"
| r => "$"^Int.toString r)
| FP = 32 <font color=#FF0000>cells <font color=#FF0000>of</font> 64 bits in cellset called</font> "floating point register"
<font color=#FF0000>assembly as</font> (fn f => "f"^Int.toString f)
| CC = <font color=#FF0000>cells <font color=#FF0000>of</font> 64 bits in cellset GP called</font> "condition code register"
<font color=#FF0000>assembly as</font> "cc"
<font color=#FF0000>locations</font>
stackptrR = <font color=#008800>$</font>GP[30]
<font color=#FF0000>and</font> asmTmpR = <font color=#008800>$</font>GP[28]
<font color=#FF0000>and</font> fasmTmp = <font color=#008800>$</font>FP[30]
<font color=#FF0000>and</font> GPReg r = <font color=#008800>$</font>GP[r]
<font color=#FF0000>and</font> FPReg f = <font color=#008800>$</font>GP[f]
\end{SML}
<h3> <a name="instruction">
Specifying the Representation of Instructions</a></h3>
\begin{SML}
<font color=#FF0000>structure</font> Instruction =
<font color=#FF0000>struct</font>
<font color=#FF0000>datatype</font> ea =
Direct <font color=#FF0000>of</font> <font color=#008800>$</font>GP
| FDirect <font color=#FF0000>of</font> <font color=#008800>$</font>FP
| Displace <font color=#FF0000>of</font> {base: <font color=#008800>$</font>GP, disp:int}
<font color=#FF0000>datatype</font> operand =
REGop <font color=#FF0000>of</font> <font color=#008800>$</font>GP ``<GP>'' (GP)
| IMMop <font color=#FF0000>of</font> int ``<int>''
| HILABop <font color=#FF0000>of</font> LabelExp.labexp ``hi(<emit_labexp labexp>)''
| LOLABop <font color=#FF0000>of</font> LabelExp.labexp ``lo(<emit_labexp labexp>)''
| LABop <font color=#FF0000>of</font> LabelExp.labexp ``<emit_labexp labexp>''
| CONSTop <font color=#FF0000>of</font> Constant.const ``<emit_const const>''
(*
* When I say ! after the datatype</font> name XXX, it means generate a
* function emit_XXX that converts the constructors into the corresponding
* assembly text. By default, it uses the same name as the constructor,
* but may be modified by the lowercase/uppercase assembly directive.
*
*)
<font color=#FF0000>datatype</font> branch! =
BR 0x30
| BSR 0x34
| BLBC 0x3
| BEQ 0x39 | BLT 0x3a | BLE 0x3b
| BLBS 0x3c | BNE 0x3d | BGE 0x3e
| BGT 0x3f
<font color=#FF0000>datatype</font> fbranch! =
FBEQ 0x31 | FBLT 0x32
| FBLE 0x33 | FBNE 0x35
| FBGE 0x36 | FBGT 0x37
<font color=#FF0000>datatype</font> load! = LDL 0x28 | LDL_L 0x2A | LDQ 0x29 | LDQ_L 0x2B | LDQ_U 0x0B
<font color=#FF0000>datatype</font> store! = STL 0x2C | STQ 0x2D | STQ_U 0x0F
<font color=#FF0000>datatype</font> fload[0x20..0x23]! = LDF | LDG | LDS | LDT
<font color=#FF0000>datatype</font> fstore[0x24..0x27]! = STF | STG | STS | STT
(* non-trapping opcodes *)
<font color=#FF0000>datatype</font> operate! = (* table C-5 *)
ADDL (0wx10,0wx00) | ADDQ (0wx10,0wx20)
| CMPBGE(0wx10,0wx0f) | CMPEQ (0wx10,0wx2d)
| CMPLE (0wx10,0wx6d) | CMPLT (0wx10,0wx4d) | CMPULE (0wx10,0wx3d)
| CMPULT(0wx10,0wx1d) | SUBL (0wx10,0wx09)
| SUBQ (0wx10,0wx29)
| S4ADDL(0wx10,0wx02) | S4ADDQ (0wx10,0wx22) | S4SUBL (0wx10,0wx0b)
| S4SUBQ(0wx10,0wx2b) | S8ADDL (0wx10,0wx12) | S8ADDQ (0wx10,0wx32)
| S8SUBL(0wx10,0wx1b) | S8SUBQ (0wx10,0wx3b)
| AND (0wx11,0wx00) | BIC (0wx11,0wx08) | BIS (0wx11,0wx20)
| CMOVEQ(0wx11,0wx24) | CMOVLBC(0wx11,0wx16) | CMOVLBS(0wx11,0wx14)
| CMOVGE(0wx11,0wx46) | CMOVGT (0wx11,0wx66) | CMOVLE (0wx11,0wx64)
| CMOVLT(0wx11,0wx44) | CMOVNE (0wx11,0wx26) | EQV (0wx11,0wx48)
| ORNOT (0wx11,0wx28) | XOR (0wx11,0wx40)
| EXTBL (0wx12,0wx06) | EXTLH (0wx12,0wx6a) | EXTLL(0wx12,0wx26)
| EXTQH (0wx12,0wx7a) | EXTQL (0wx12,0wx36) | EXTWH(0wx12,0wx5a)
| EXTWL (0wx12,0wx16) | INSBL (0wx12,0wx0b) | INSLH(0wx12,0wx67)
| INSLL (0wx12,0wx2b) | INSQH (0wx12,0wx77) | INSQL(0wx12,0wx3b)
| INSWH (0wx12,0wx57) | INSWL (0wx12,0wx1b) | MSKBL(0wx12,0wx02)
| MSKLH (0wx12,0wx62) | MSKLL (0wx12,0wx22) | MSKQH(0wx12,0wx72)
| MSKQL (0wx12,0wx32) | MSKWH (0wx12,0wx52) | MSKWL(0wx12,0wx12)
| SLL (0wx12,0wx39) | SRA (0wx12,0wx3c) | SRL (0wx12,0wx34)
| ZAP (0wx12,0wx30) | ZAPNOT (0wx12,0wx31)
| MULL (0wx13,0wx00) | MULQ (0wx13,0wx20)
| UMULH (0wx13,0wx30)
| SGNXL "addl" (0wx10,0wx00) (* same as ADDL *)
(* conditional moves *)
<font color=#FF0000>datatype</font> pseudo_op! = DIVL | DIVLU
<font color=#FF0000>datatype</font> operateV! = (* table C-5 opc/func *)
ADDLV (0wx10,0wx40) | ADDQV (0wx10,0wx60)
| SUBLV (0wx10,0wx49) | SUBQV (0wx10,0wx69)
| MULLV (0wx13,0wx00) | MULQV (0wx13,0wx60)
<font color=#FF0000>datatype</font> foperate! = (* table C-6 *)
CPYS (0wx17,0wx20) | CPYSE (0wx17,0wx022) | CPYSN (0wx17,0wx021)
| CVTLQ (0wx17,0wx010) | CVTQL (0wx17,0wx030) | CVTQLSV (0wx17,0wx530)
| CVTQLV (0wx17,0wx130)
| FCMOVEQ (0wx17,0wx02a) | FCMOVEGE (0wx17,0wx02d) | FCMOVEGT (0wx17,0wx02f)
| FCMOVLE (0wx17,0wx02e) | FCMOVELT (0wx17,0wx02c) | FCMOVENE (0wx17,0wx02b)
| MF_FPCR (0wx17,0wx025) | MT_FPCR (0wx17,0wx024)
(* table C-7 *)
| CMPTEQ (0wx16,0wx0a5) | CMPTLT (0wx16,0wx0a6) | CMPTLE (0wx16,0wx0a7)
| CMPTUN (0wx16,0wx0a4)
<font color=#FF0000>datatype</font> foperateV! =
ADDSSUD 0wx5c0
| ADDTSUD 0wx5e0
| CVTQSC 0wx3c
| CVTQTC 0wx3e
| CVTTSC 0wx2c
| CVTTQC 0wx2f
| DIVSSUD 0wx5ec
| DIVTSUD 0wx5c3
| MULSSUD 0wx5c2
| MULTSUD 0wx5e2
| SUBSSUD 0wx5c1
| SUBTSUD 0wx5e1
<font color=#FF0000>datatype</font> osf_user_palcode! =
BPT 0x80 | BUGCHK 0x81 | CALLSYS 0x83
| GENTRAP 0xaa | IMB 0x86 | RDUNIQUE 0x9e | WRUNIQUE 0x9f
end (* Instruction *)
\end{SML}
<h3> <a name="encoding">
Specifying the Instruction Encoding Formats </a></h3>
The Alpha has very simple instruction encoding formats.
<tt>
\begin{SML}
<font color=#FF0000>instruction formats 32 bits</font>
Memory{opc:6, ra:5, rb:GP 5, disp: signed 16} (* p3-9 *)
(* derived from Memory *)
| LoadStore{opc,ra,rb,disp} =
<font color=#FF00000>let val</font> disp =
<font color=#FF00000>case</font> disp <font color=#FF0000>of</font>
I.REGop rb => emit_GP rb
| I.IMMop i => itow i
| I.HILABop le => itow(LabelExp.valueOf le)
| I.LOLABop le => itow(LabelExp.valueOf le)
| I.LABop le => itow(LabelExp.valueOf le)
| I.CONSTop c => itow(Constant.valueOf c)
in Memory{opc,ra,rb,disp}
end
| ILoadStore{opc,r:GP,b,d} = LoadStore{opc,ra=r,rb=b,disp=d}
| FLoadStore{opc,r:FP,b,d} = LoadStore{opc,ra=r,rb=b,disp=d}
| Jump{opc:6,ra:GP 5,rb:GP 5,h:2,disp:int signed 14} (* table C-3 *)
| Memory_fun{opc:6, ra:GP 5, rb:GP 5, func:16} (* p3-9 *)
| Branch{opc:branch 6, ra:GP 5, disp:signed 21} (* p3-10 *)
| Fbranch{opc:fbranch 6, ra:FP 5, disp:signed 21} (* p3-10 *)
(* p3-11 *)
| Operate0{opc:6,ra:GP 5,rb:GP 5,sbz:13..15,_:1=0,func:5..11,rc:GP 5}
(* p3-11 *)
| Operate1{opc:6,ra:GP 5,lit:signed 13..20,_:1=1,func:5..11,rc:GP 5}
| Operate{opc,ra,rb,func,rc} =
(<font color=#FF00000>case</font> rb <font color=#FF0000>of</font>
I.REGop rb => Operate0{opc,ra,rb,func,rc,sbz=0w0}
| I.IMMop i => Operate1{opc,ra,lit=itow i,func,rc}
| I.HILABop le => Operate1{opc,ra,lit=itow(LabelExp.valueOf le),func,rc}
| I.LOLABop le => Operate1{opc,ra,lit=itow(LabelExp.valueOf le),func,rc}
| I.LABop le => Operate1{opc,ra,lit=itow(LabelExp.valueOf le),func,rc}
| I.CONSTop c => Operate1{opc,ra,lit=itow(Constant.valueOf c),func,rc}
)
| Foperate{opc:6,fa:FP 5,fb:FP 5,func:5..15,fc:FP 5}
| Pal{opc:6=0,func:26}
\end{SML}
</tt>
\subsubsection{ Specifying the instruction set }
<tt>
\begin{SML}
<font color=#FF0000>structure</font> MC =
<font color=#FF0000>struct</font>
(* compute displacement address *)
<font color=#FF0000>fun</font> disp lab = itow(Label.addrOf lab - !loc - 4) ~>> 0w2
<font color=#FF0000>end</font>
(*
* The main instruction set definition consists <font color=#FF0000>of</font> the following:
* 1) constructor-like declaration defines the view <font color=#FF0000>of</font> the instruction,
* 2) assembly directive in funny quotes `` '',
* 3) machine encoding expression,
* 4) semantics expression in [[ ]],
* 5) delay slot directives etc (not necessary in this architecture!)
*)
<font color=#FF0000>instruction</font>
DEFFREG <font color=#FF0000>of</font> <font color=#008800>$</font>FP (* define a floating point register *)
``deffreg <FP>''
(* Pseudo instruction for the register allocator *)
(* Load/Store *)
| LDA <font color=#FF0000>of</font> {r: <font color=#008800>$</font>GP, b: <font color=#008800>$</font>GP, d:operand} (* use of REGop is illegal *)
``lda\t<r>, <d>()''
ILoadStore{opc=0w08,r,b,d}
| LDAH <font color=#FF0000>of</font> {r: <font color=#008800>$</font>GP, b: <font color=#008800>$</font>GP, d:operand} (* use of REGop is illegal *)
``ldah\t<r>, <d>()''
ILoadStore{opc=0w09,r,b,d}
| LOAD <font color=#FF0000>of</font> {ldOp:load, r: <font color=#008800>$</font>GP, b: <font color=#008800>$</font>GP, d:operand, mem:Region.region}
``<ldOp>\t<r>, <d>()''
ILoadStore{opc=emit_load ldOp,r,b,d}
| STORE <font color=#FF0000>of</font> {stOp:store, r: <font color=#008800>$</font>GP, b: <font color=#008800>$</font>GP, d:operand, mem:Region.region}
``<stOp>\t<r>, <d>()''
ILoadStore{opc=emit_store stOp,r,b,d}
| FLOAD <font color=#FF0000>of</font> {ldOp:fload, r: <font color=#008800>$</font>FP, b: <font color=#008800>$</font>GP, d:operand, mem:Region.region}
``<ldOp>\t<r>, <d>()''
FLoadStore{opc=emit_fload ldOp,r,b,d}
| FSTORE <font color=#FF0000>of</font> {stOp:fstore, r: <font color=#008800>$</font>FP, b: <font color=#008800>$</font>GP, d:operand, mem:Region.region}
``<stOp>\t<r>, <d>()''
FLoadStore{opc=emit_fstore stOp,r,b,d}
(* Control Instructions *)
| JMPL <font color=#FF0000>of</font> {r: <font color=#008800>$</font>GP, b: <font color=#008800>$</font>GP, d:int} * Label.label list
``jmpl\t<r>, <d>()''
Jump{opc=0wx1a,h=0w0,ra=r,rb=b,disp=d} (* table C-3 *)
| JSR <font color=#FF0000>of</font> {r: <font color=#008800>$</font>GP, b: <font color=#008800>$</font>GP, d:int} * C.cellset * C.cellset
``jsr\t<r>, <d>()''
Jump{opc=0wx1a,h=0w1,ra=r,rb=b,disp=d}
| RET <font color=#FF0000>of</font> {r: <font color=#008800>$</font>GP, b: <font color=#008800>$</font>GP, d:int}
``ret\t<r>, <d>()''
Jump{opc=0wx1a,h=0w2,ra=r,rb=b,disp=d}
| BRANCH <font color=#FF0000>of</font> branch * <font color=#008800>$</font>GP * Label.label
``<branch> <GP>, <label>''
Branch{opc=branch,ra=GP,disp=disp label}
| FBRANCH <font color=#FF0000>of</font> fbranch * <font color=#008800>$</font>FP * Label.label
``<fbranch> <FP>, <label>''
Fbranch{opc=fbranch,ra=FP,disp=disp label}
(* Integer Operate *)
| OPERATE <font color=#FF0000>of</font> {oper:operate, ra: <font color=#008800>$</font>GP, rb:operand, rc: <font color=#008800>$</font>GP}
``<oper>\t<ra>, <rb>, <rc>''
(let val (opc,func) = emit_operate oper
in Operate{opc,func,ra,rb,rc}
end)
| OPERATEV <font color=#FF0000>of</font> {oper:operateV, ra: <font color=#008800>$</font>GP, rb:operand, rc: <font color=#008800>$</font>GP}
``<oper>\t<ra>, <rb>, <rc>''
(let val (opc,func) = emit_operateV oper
in Operate{opc,func,ra,rb,rc}
end)
| PSEUDOARITH <font color=#FF0000>of</font> {oper: pseudo_op, ra: <font color=#008800>$</font>GP, rb:operand, rc: <font color=#008800>$</font>GP,
tmps: C.cellset}
``<oper>\t<ra>, <rb>, <rc>''
(* Copy instructions *)
| COPY <font color=#FF0000>of</font> {dst: <font color=#008800>$</font>GP list, src: <font color=#008800>$</font>GP list,
impl:instruction list option ref, tmp: ea option}
``<app emitInstr (Shuffle.shuffle{regmap,tmp,dst,src})>''
| FCOPY <font color=#FF0000>of</font> {dst: <font color=#008800>$</font>FP list, src: <font color=#008800>$</font>FP list,
impl:instruction list option ref, tmp: ea option}
``<app emitInstr (Shuffle.shufflefp{regmap,tmp,dst,src})>''
(* Floating Point Operate *)
| FOPERATE <font color=#FF0000>of</font> {oper:foperate, fa: <font color=#008800>$</font>FP, fb: <font color=#008800>$</font>FP, fc: <font color=#008800>$</font>FP}
``<oper>\t<fa>, <fb>, <fc>''
(let val (opc,func) = emit_foperate oper
in Foperate{opc,func,fa,fb,fc}
end)
(* Trapping versions <font color=#FF0000>of</font> the above *)
| FOPERATEV <font color=#FF0000>of</font> {oper:foperateV, fa: <font color=#008800>$</font>FP, fb: <font color=#008800>$</font>FP, fc: <font color=#008800>$</font>FP}
``<oper>\t<fa>, <fb>, <fc>''
Foperate{opc=0wx16,func=emit_foperateV oper,fa,fb,fc}
(* Misc *)
| TRAPB (* Trap barrier *)
``trapb''
Memory_fun{opc=0wx18,ra=31,rb=31,func=0wx0}
| CALL_PAL <font color=#FF0000>of</font> {code:osf_user_palcode, def: <font color=#008800>$</font>GP list, use: <font color=#008800>$</font>GP list}
``call_pal <code>''
Pal{func=emit_osf_user_palcode code}
end
\end{SML}
</tt>
\subsection{ 4 Machine Descriptions }
Here are some machine descriptions in varing degree of completion.
\begin{itemize}
\item \codehref{../sparc/sparc.mdl}{ Sparc }
\item \codehref{../hppa/hppa.mdl}{ Hppa }
\item \codehref{../alpha/alpha.mdl}{ Alpha }
\item \codehref{../ppc/ppc.mdl}{ PowerPC }
\item \codehref{../x86/x86.mdl}{ X86 }
\end{itemize}
\subsection{ Syntax Highlighting Macros }
\begin{itemize}
\item \href{md.vim}{ For vim 5.3 }
\end{itemize}
</body>
</html>
+3
View File
@@ -0,0 +1,3 @@
\section{The MIPS Back End}
No documentation yet.
+115
View File
@@ -0,0 +1,115 @@
\section{Architecture of MLRISC}
\subsection{Core Components}
The core components of MLRISC allow the client to quickly construct
an backend for various architectures. These components include:
\begin{itemize}
\item The \href{mltree.html}{MLTREE} language,
which is a RTL-like intermediate language
that is used by the client
to communicate to the MLRISC system. A client is
responsible for writing the module that generates MLTREE from
the source program representation.
\item \href{instrsel.html}{Instruction selection modules},
which generates target machine
instructions from MLTREE.
\item The \href{ra.html}{Register Allocator},
which performs register allocation.
\item \href{asm.html}{Assemblers}, which emits assembly code.
\end{itemize}
For systems that require direct machine code generation, the following
modules are included:
\begin{itemize}
\item \href{span-dep.html}{Span dependency resolution}
modules, which compute addresses
from symbolic addresses,
fill delay slots, and expand instructions that are
\newdef{span dependent}
\item \href{mc.html}{Machine code emitters},
which emit executable machine code into a binary stream.
\end{itemize}
\subsection{Optimization Modules}
In addition, MLRISC has been enhanced to support various types of
machine level optimizations. These include:
\begin{itemize}
\item Core optimizations, which includes
various types of control flow transformation,
and architectural specific peephole optimizations.
\item SSA based scalar optimizations
\item ILP optimizations for superscalars
\item ILP optimizations for VLIW/EPIC architectures
\item GC safety analysis
\end{itemize}
\subsection{Basic Concepts}
Basic concepts in MLRISC are:
\begin{itemize}
\item \href{instructions.html}{Instructions} --
the instruction set of the target architecture.
\item \href{cells.html}{Cells} -- which describes registers,
memory and other mutable resources in the machine.
\item \href{regions.html}{Regions} -- a client defined
abstract type used to represent aliasing information available from
the front-end.
\item \href{constants.html}{Constants} -- a client defined
place holder used to represent constants whose values are unknown
in the front-end.
\item \href{pseudo-ops.html}{Pseudo Ops} -- a client defined
\item \href{annotations.html}{Annotations} -- this is
a generic mechinism for propagating information in the MLRISC sstem.
The client may attach arbitrary annotation of various granularity
to MLRISC's program representation,
which can then be propagated to later phases.
These can be information related to profiling frequency, dependence,
comments, and/or types.
The same mechanism is also used to propagate
analysis information one optimization phase to
another.
\item \href{streams.html}{Instruction Streams} -- an abstraction
for describing a stream of instructions. Instruction streams are
used to connect modules such as instruction selection, assembler,
machine code emitter, and
control flow graph builder.
\item \href{regmap.html}{Regmap} -- a mapping between registers
names. MLRISC register allocators represent the result of register
allocation as a regmap.
\item \href{labels.html}{Labels} -- a type representing
symbolic labels.
\item \href{labelexp.html}{Label Expressions} -- a type representing
constant expressions
involving symbolic labels.
\end{itemize}
\subsection{How Things Are Fit Together}
MLRISC uses two different program representations, clusters and MLRISC IR.
\begin{itemize}
\item \href{cluster.html}{Cluster} is light-weight representation
that is used when only the most basic optimizations are required.
\item \href{mlrisc-ir.html}{MLRISC IR} is more heavy-weight
representation that is built from the
\href{graphs.html}{MLRISC graph library} and the
\href{compiler-graphs.html}{MLRISC compiler graph library}.
MLRISC IR allows more complex transformations and analysis of the
program graph.
\end{itemize}
Conversion modules between the two representations are provided.
In general MLRISC optimization phases are transformations applied on one
of these representations. Optimizations may be chained together to form
a compiler backend. For example, a minimal backend consists of
\begin{itemize}
\item the instruction selection module, which translates
\href{mltree.html}{MLTree} into target instructions,
\item the flowgraph builder, which conversts a stream of target instructions
into a cluster,
\item the register allocator, which performs register allocation, and
\item the assembly code emitter, which generates assembly output
\end{itemize}
+54
View File
@@ -0,0 +1,54 @@
\section{MLRISC Based Compiler}
A traditional compiler will typically consist of a
\begin{color}{#dd0000}lex/yacc\end{color} based front end, an
\begin{color}{#DD0000}optimization\end{color}
phase that is repeatedly invoked
over some intermediate representation, and finally a
\begin{color}{#DD0000}back end\end{color}
code generation phase. The intermediate
representation is usually at a level of detail appropriate to the
optimization being performed, and may be far removed from the
native instructions of the target architecture. The back end
proceeds by translating the intermediate representation into
instructions and registers for an abstract machine that is much
closer to the target architecture. Retargetting is then achieved
by mapping the registers and instructions of the abstract machine
to registers and instructions of the target architecture.
\br{clear=left}
\image{MLRISC based compiler}{pictures/png/compiler-2.png}{align=right}
An MLRISC based compiler, on the other hand, translates the
intermediate representation into MLRISC instructions and it is the
MLRISC instructions that get mapped onto instructions of the target
architecture. Another possibility is to translate the front end
abstract machine instructions instead of the intermediate
representation. Once MLRISC instructions have been generated,
nearly all aspects of high quality code generation come for free. A
long story would be cut short if MLRISC were just another abstract
machine.
\begin{color}{#580000} The key idea behind MLRISC is that there is no
single MLRISC instruction set or intermediate program
representation, \end{color} but the MLRISC intermediate representation
is specialized to the needs of the front end source language being
compiled. The specialization does not stop there, but the:
\begin{itemize}
\item \begin{color}{#005500}target instruction set\end{color},
\item \begin{color}{#005500}flowgraph\end{color}, and
\item \begin{color}{#005500}entire optimization suite\end{color}
\end{itemize}
are specialized to the needs of the front end. The ability to
consistently specialize each of these to create a back end for a
specific language, summarizes the characteristics of MLRISC that
distinguishes it from other retargetable backends.
\begin{color}{#580000} It is important to emphasize that little
optimizations performed on the MLRISC intermediate
representation. \end{color} Most optimizations are done on a flowgraph of
target machine instructions, to enable optimizations that take advantage
of the characteristics of each architectural.
The MLRISC intermediate representation is just used as a stepping
stone to get to the flowgraph.
+60
View File
@@ -0,0 +1,60 @@
\section{MLRisc Generation}
Every compiler will eventually compile down to an abstract machine
that it believes will execute source programs efficiently. The
abstract machine will typically consists of abstract machine
registers and instructions, one or more stacks, and parameter
passing conventions. The hope is that all this will map down
efficiently onto the target machine. Indeed, the abstract machine
should be reasonably close to architectures that are envisioned as
possible targets. Several step need to be followed in the generation
of MLRisc.
\begin{enumerate}
\item The first step in generating target machine code is to define
the MLRisc intermediate representation after it has been
appropriately specialized. The interfaces that describe the
dimensions of specialization are quite simple. Depending on the
compiler, these may be target dependent; for example, in the SML/NJ
compiler, the encoding of registers used to indicate the roots of
garbage collection depend on how the runtime system decodes the
information.
\item The only real connection between the MLRisc intermediate
representation and the target machine is that the first
$0..K-1$ MLRisc registers map onto the first $K$
physical registers on the target machine. Thus some mapping of
dedicated abstract machine registers to physical target registers is
required. It is not always necessary to map abstract machine
registers to physical machine registers. For example, on
architectures like the x86 with few registers, some abstract machine
registers may be mapped to fixed memory locations. Thus an abstract
machine register like the \sml{maskReg} may have something like:
\begin{SML}
LOAD(32, LABEL maskRegLab)
\end{SML}
spliced instead.
\item The unit of compilation is called a
\href{cluster.html}{cluster} which
is the smallest unit for inter-procedural optimizations. A cluster
will typically consist of several entry points that may call each
other, as well as call local functions in the module. For maximum
flexibility, the parameter passing convention for local functions
should be specialized by the \href{mlrisc-ra.html}{register allocator}.
Once the MLRisc trees for a cluster have been built, they must
be converted into target assembly or machine code. This is done by
building up a function (\newdef{codegen}) that
glues together optimizations modules that have been specialized. For
example, the target instruction set must be specialized to hold the
MLRisc constants; the flowgraph must be specialized to carry these
instructions as well as the MLRisc pseudo-ops; the optimization
modules must know about several front end constraints such as how to
spill registers.
\end{enumerate}
If the module that translates the abstract machine instructions
into MLRisc instructions has been appropriately parameterized, then
it can be reused for multiple target architectures. For high level
languages it is better to generate MLRisc instructions from the high
level intermediate form used by the front end of the compiler.
+31
View File
@@ -0,0 +1,31 @@
\section{Graphical Interface}
All the major data structures and intermediate program states can be
viewed graphically using
\externhref{http://www.Informatik.Uni-Bremen.DE/~davinci/}{\begin{color}{red}daVinci\end{color}} and
\externhref{http://www.cs.uni-sb.de/RW/users/sander/html/gsvcg1.html}{\begin{color}{red}vcg\end{color}}
The following screen dumps are intended to represent the range of
possibilities. Graphical tools like these are an indispensible
debugging aid. Each of the dumps below were taken when generating
code for the \begin{color}{red}mandelbrot\end{color} on the HPPA
architecture. It will be necessary to make netscape fill the size of
the screen to view these easily. Even though some of these graphs
look quite complex, daVinci has several \emph{navigational} modes
that allow walking to successors, or predecessors, or navigating
through a scaled down map of the graph. The navigational view is
shown as another window, and the view into the graph that is being
displayed is usually outlined in \begin{color}{blue}blue\end{color}.
\begin{description}
\item[\href{graphics/mandelbrot-opt.gif}{Control Flowgraph after Optimization:}] Each basic block is shown with its dynamic profile and
code before and after a specific optimization. This view
saves having to pour through pages of assembly code listings --
a tedious and frustrating activity.
\item[\href{graphics/mandelbrot-ssa.gif}{SSA form:}]
The generated flow graph is converted to SSA form which
makes many code improvement optimizations easy and efficient.
\item[\href{graphics/mandelbrot-ddg.gif}{Data Dependency Graph}]
A graphical view of the data dependency graph and the various
kinds of dependencies decorating the edges, provides a useful clue to
why instructions got rearranged the way they did. The navigational
view helps to control the complexity in the display.
\end{description}
+158
View File
@@ -0,0 +1,158 @@
\section{MLRISC Intermediate Representation}
The MLRISC intermediate language is called
\newdef{MLTREE} At the lowest level, the core of MLTREE is a
\italics{Register Transfer Language (RTL)}
but represented in tree form. The tree
form makes it convenient to use tree pattern matching tools like
BURG (where appropriate) to do target instruction selection. Thus a
tree such as:
\begin{SML}
MV(32, t,
ADDT(32, MULT(32, REG(32, b), REG(32, b)),
MULT(32, MULT(REG(32, a), LI(4)), REG(32, c))))
\end{SML}
computes \sml{t := b*b + 4*a*c} to 32-bit precision.
The nodes \sml{ADDT} and
\sml{MULT} are the trapping form of addition and multiplication,
and \sml{LI} is used for integer constants. An infinite number
of registers are assumed by the model, however depending on the
target machine the first \sml{0..K} registers map onto the first
\sml{K} registers on the target machine. Everything else is
assumed to be a pseudo-register. The \sml{REG} node is used to
indicate a general purpose register.
The core MLTREE language makes no assumptions about instructions or
calling convections of the target architecture. Trees can be
created and combined in almost any form, with certain meaningless
trees such as \sml{LOAD(32, FLOAD(64, LI 0))} being forbidden by the
MLTREE type structure.
Such pure trees are nice but inadequate in real compilers. One
needs to be able to propagate front end specific information, such
as frame sizes and frame offsets where the actual values are only
available after register allocation and spilling. One could add
support for frames in MLRISC, however this becomes a slippery slope
because some compilers (e.g. SML/NJ) do not have a conventional
notion of frames --- indeed there is no runtime stack in the
execution of SML/NJ. A frame organization for one person may not
meet the needs for another, and so on. In MLRISC, the special
requirements of different compilers is communicated into the MLTREE
language, and subsequently into the optimizations phases, by
specializing the MLTREE data structure with client specific
information. There are currently \emph{five} dimensions over
which one could specialize the MLTREE language.
\begin{description}
\item[Constants] Constants are an
abstraction for integer literals whose value is known after
certain phases of code generation. Frame sizes and offsets are an
example.
\image{MLRISC intermediate representation}{pictures/png/mlrisc-ir.png}{align=right}
\item[Regions] While the data
dependencies between arithmetic operations is implicit in the
instruction, the data dependencies between memory operations is
not. Regions are an abstract view of memory that make this
dependence explicit and is specially useful for instruction
reordering.
\item[Pseudo-ops] Pseudo-ops are
intended to correspond to pseudo-op directives provided by native
assemblers to lay out data, jump tables, and perform alignment.
\item[Annotations]
\href{annotations.html}{Annotations} are used
for injecting semantics and other program information from the front-end
into the backend. For example, a probability annotation can be
attached to a branch instruction. Similarly, line number annotations
can be attached to basic blocks to aid debugging.
In many language implementations function local variables are
spilled to activation frames on the stack. Spill slots contribute
to the size of a function's frame. When an instruction produces a
spill, we may need to update the frame associated to that
instruction (increase the size of its spilling area). The frame
for the current function can be injected in an annotation, which
can be later examined by the spill callback during register allocation.
Annotations are
implemented as an universal type and can be arbitrarily extended.
Individual annotations can be associated
with compiler objects of varying granularity,
from compilation units, to regions, basic blocks, flow edges,
and down to the instructions.
\item[User Defined Extensions]
In the most extreme case, the basic constructors defined in the MLTREE
language may be inadequate for the task at hand.
MLTREE allows the client to arbitrarily extend
the set of statements and expressions to more closely match the
source language and the target architecture(s).
For example, when using MLRISC for the backend of a DSP compiler
it may be useful to extend the set of MLRISC operators to include
fix point and saturated arithmetic.
Similarly, when developing a language for loop parallelization, it may
be useful to extend the MLTREE language with higher-level loop
constructs.
\end{description}
\subsection{Examples}
In the SML/NJ compiler, an encoding of a list of registers
is passed to the garbage collector as the roots of live
variables. This encoding cannot be computed until register
allocation has been performed, therefore the integer literal
encoding is represented as an abstract
\href{constants.html}{constant}.
Again, in the SML/NJ compiler, most stores are for initializing
records in the allocation space, therefore representing every slot in
the allocation space as a unique region allows one to commute
most store instructions. Similarly, most loads are from
\emph{immutable} records, and a simple analysis marks these are
being accesses to \emph{read-only} memory. Read-only memory is
characterized as having multiple \emph{uses} but no
\emph{definitions}.
In the TIL compiler, a \emph{trace table} is generated for
every call site that records the set of live variables, their
location (register or stack offset), and the type associated with
the variable. This table is integrated into the program using the
abstract pseudo-op mechanism. An interesting aspect of these tables
is that they may need adjustment based on the results of register
spilling.
The more convention use of the psuedo-op abstraction is to
propagate function prologue and epilogue information.
The constants abstraction are created by a tree node called
\sml{CONST}. In the SML/NJ compiler, the tree that communicates
garbage collection information looks like:
\begin{verbatim}
MV(32, maskReg, CONST{r110,r200,r300,r400 ...})
\end{verbatim}
where \sml{maskReg} is a dedicated register. On the DEC Alpha,
this would get translated to:
\begin{verbatim}
LDA maskReg, {encode(r110,r200,r300,r400, ...)}
\end{verbatim}
which indicates that the alpha instruction set (and optimization
suite) know about these types of values. Further, after
register allocation, the \sml{LDA} instruction may not be
sufficient as the encoding may result in a value that is too large
as an operand to \sml{LDA}. Two instructions may ultimately be
required to load the encoding into the \sml{maskReg}
register. This expansion is done during
\href{span-dep.html}{span-dependency resolution}.
All these examples are intended to indicate that one
intermediate representation and optimization suite does not fit
all, but that the intermediate representation and optimization
suite needs to be specialized to the needs of the client.
+609
View File
@@ -0,0 +1,609 @@
\section{The MLRISC IR}
\subsection{Introduction}
In this section we will describe the MLRISC intermediate representation.
\subsubsection{Control Flow Graph}
The control flow graph is the main view of the IR.
A control flow graph satisfies the following signature:
\begin{SML}
signature \mlrischref{IR/mlrisc-cfg.sig}{CONTROL_FLOW_GRAPH} = sig
structure I : INSTRUCTIONS
structure P : PSEUDO_OPS
structure C : CELLS
structure W : FIXED_POINT
sharing I.C = C
\italics{definitions}
end
\end{SML}
The following structures nested within a CFG:
\begin{itemize}
\item \sml{I : INSTRUCTIONS} is the instruction structure.
\item \sml{P : PSEUDO_OPS} is the structure with the definition
of pseudo ops.
\item \sml{C : CELLS} is the cells structure describing the
register conventions of the architecture.
\item \sml{W : FIXED_POINT} is a structure that contains
a fixed point type used in execution frequency annotations.
\end{itemize}
The type \sml{weight} below is used in execution frequency annotations:
\begin{SML}
type weight = W.fixed_point
\end{SML}
There are a few different kinds of basic blocks, described
by the type \sml{block_kind} below:
\begin{SML}
datatype block_kind =
START
| STOP
| FUNCTION_ENTRY
| NORMAL
| HYPERBLOCK
\end{SML}
A basic block is defined as the datatype \sml{block}, defined below:
\begin{SML}
and data = LABEL of Label.label
| PSEUDO of P.pseudo_op
and block =
BLOCK of
\{ id : int,
kind : block_kind,
name : B.name,
freq : weight ref,
data : data list ref,
labels : Label.label list ref,
insns : I.instruction list ref,
annotations : Annotations.annotations ref
\}
\end{SML}
Edges in a CFG are annotated with the type \sml{edge_info},
defined below:
\begin{SML}
and edge_kind = ENTRY
| EXIT
| JUMP
| FALLSTHRU
| BRANCH of bool
| SWITCH of int
| SIDEEXIT of int
and edge_info =
EDGE of \{ k : edge_kind,
w : weight ref,
a : Annotations.annotations ref
\}
\end{SML}
Type \sml{cfg} below defines a control flow graph:
\begin{SML}
type edge = edge_info edge
type node = block node
datatype info =
INFO of \{ regmap : C.regmap,
annotations : Annotations.annotations ref,
firstBlock : int ref,
reorder : bool ref
\}
type cfg = (block,edge_info,info) graph
\end{SML}
\subsubsection{Low-level Interface}
The following subsection describes the low-level interface to a CFG.
These functions should be used with care since they do not
always maintain high-level structural invariants imposed on
the representation. In general, higher level interfaces exist
so knowledge of this interface is usually not necessary for customizing
MLRISC.
Various kinds of annotations on basic blocks are defined below:
\begin{SML}
exception LIVEOUT of C.cellset
exception CHANGED of unit -> unit
exception CHANGEDONCE of unit -> unit
\end{SML}
The annotation \sml{LIVEOUT} is used record live-out information
on an escaping block.
The annotations \sml{CHANGED} and \sml{CHANGEDONCE} are used
internally for maintaining views on a CFG. These should not be used
directly.
The following are low-level functions for building new basic blocks.
The functions \sml{new}\emph{XXX} build empty basic blocks of a specific
type. The function \sml{defineLabel} returns a label to a basic block;
and if one does not exist then a new label will be generated automatically.
The functions \sml{emit} and \sml{show_block} are low-level
routines for displaying a basic block.
\begin{SML}
val newBlock : int * B.name -> block
val newStart : int -> block
val newStop : int -> block
val newFunctionEntry : int -> block
val copyBlock : int * block -> block
val defineLabel : block -> Label.label
val emit : C.regmap -> block -> unit
val show_block : C.regmap -> block -> string
\end{SML}
Methods for building a CFG are listed as follows:
\begin{SML}
val cfg : info -> cfg
val new : C.regmap -> cfg
val subgraph : cfg -> cfg
val init : cfg -> unit
val changed : cfg -> unit
val removeEdge : cfg -> edge -> unit
\end{SML}
Again, these methods should be used only with care.
The following functions allow the user to extract low-level information
from a flowgraph. Function \sml{regmap} returns the current register map.
Function \sml{regmap} returns a function that lookups the current register
map. Function \sml{liveOut} returns liveOut information from a block;
it returns the empty cellset if the block is not an escaping block.
Function \sml{fallsThruFrom} takes a node id $v$ and locates the
block $u$ (if any) that flows into $v$ without going through a branch
instruction. Similarly, the function \sml{fallsThruTo} takes
a node id $u$ and locates the block (if any) that $u$ flows into
with going through a branch instruction. If $u$ falls through to
$v$ in any feasible code layout $u$ must preceed $v$.
\begin{SML}
val regmap : cfg -> C.regmap
val reglookup : cfg -> C.register -> C.register
val liveOut : block -> C.cellset
val fallsThruFrom : cfg * node_id -> node_id option
val fallsThruTo : cfg * node_id -> node_id option
\end{SML}
To support graph viewing of a CFG, the following low-level
primitives are provided:
\begin{SML}
val viewStyle : cfg -> (block,edge_info,info) GraphLayout.style
val viewLayout : cfg -> GraphLayout.layout
val headerText : block -> string
val footerText : block -> string
val subgraphLayout : { cfg : cfg, subgraph : cfg } -> GraphLayout.layout
\end{SML}
Finally, a miscellany function for control dependence graph building.
\begin{SML}
val cdgEdge : edge_info -> bool
\end{SML}
\subsubsection{IR}
The MLRISC intermediate representation is a composite
view of various compiler data structures, including the control
flow graph, (post-)dominator trees, control dependence graph, and
loop nesting tree. Basic compiler optimizations in MLRISC
operate on this data structure; advance optimizations
operate on more complex representations which use this
representation as the base layer.
\begin{wrapfigure}{r}{4.5in}
\begin{Boxit}
% \psfig{figure=../pictures/eps/mlrisc-IR.eps,width=4.5in}
\includegraphics[width=4.5in]{../pictures/pdf/mlrisc-IR}
\end{Boxit}
\caption{The MLRISC IR}
\end{wrapfigure}
This IR provides a few additional functionalities:
\begin{itemize}
\item Edge frequencies -- execution frequencies
are maintained on all control flow edges.
\item Extensible annotations -- semantics information can be
represented as annotations on the graph.
\item Multiple facets --
Facets are high-level views that automatically keep themselves
up-to-date. Computed facets are cached and out-of-date facets
are recomputed by demand.
The IR defines a mechanism to attach multiple facets to the IR.
\end{itemize}
The signature of the IR is listed below
\begin{SML}
signature \mlrischref{IR/mlrisc-ir.sig}{MLRISC_IR} = sig
structure I : INSTRUCTIONS
structure CFG : CONTROL_FLOW_GRAPH
structure Dom : DOMINATOR_TREE
structure CDG : CONTROL_DEPENDENCE_GRAPH
structure Loop : LOOP_STRUCTURE
structure Util : CFG_UTIL
sharing Util.CFG = CFG
sharing CFG.I = I
sharing Loop.Dom = CDG.Dom = Dom
type cfg = CFG.cfg
type IR = CFG.cfg
type dom = (CFG.block,CFG.edge_info,CFG.info) Dom.dominator_tree
type pdom = (CFG.block,CFG.edge_info,CFG.info) Dom.postdominator_tree
type cdg = (CFG.block,CFG.edge_info,CFG.info) CDG.cdg
type loop = (CFG.block,CFG.edge_info,CFG.info) Loop.loop_structure
val dom : IR -> dom
val pdom : IR -> pdom
val cdg : IR -> cdg
val loop : IR -> loop
val changed : IR -> unit
val memo : (IR -> 'facet) -> IR -> 'facet
val addLayout : string -> (IR -> GraphLayout.layout) -> unit
val view : string -> IR -> unit
val views : string list -> IR -> unit
val viewSubgraph : IR -> cfg -> unit
end
\end{SML}
The following facets are predefined: dominator, post-dominator tree,
control dependence graph and loop nesting structure.
The functions \sml{dom}, \sml{pdom}, \sml{cdg}, \sml{loop}
are \newdef{facet extraction} methods that
compute up-to-date views of these facets.
The following protocol is used for facets:
\begin{itemize}
\item When the IR is changed,
the function \sml{changed} should be called to
signal that all facets attached to the IR should be updated.
\item To add a new facet of type \sml{F} that is computed by demand,
the programmer has to provide a facet construction
function \sml{f : IR -> F}. Call the function \sml{mem}
to register the new facet. For example, let \sml{val g = memo f}.
Then the function \sml{g} can be used to as a new facet extraction
function for facet \sml{F}.
\item To register a graph viewing function, call
the function \sml{addLayout} and provide an appropriate
graph layout function. For example, we can say
\sml{addLayout "F" layoutF} to register a graph layout function
for a facet called ``F''.
\end{itemize}
To view an IR, the functions \sml{view}, \sml{views} or
\sml{viewSubgraph} can be used. They have the following interpretation:
\begin{itemize}
\item \sml{view} computes a layout for one facet of the IR and displays
it. The predefined facets are called
``dom'', ``pdom'', ``cdg'', ``loop.'' The IR can be
viewed as the facet ``cfg.'' In addition, there is a layout
named ``doms'' which displays the dominator tree and the post-dominator
tree together, with the post-dominator inverted.
\item \sml{views} computes a set of facets and displays it together
in one single picture.
\item \sml{viewSubgraph} layouts a subgraph of the IR.
This creates a picture with the subgraph highlighted and embedded
in the whole IR.
\end{itemize}
\subsubsection{Building a CFG}
There are two basic methods of building a CFG:
\begin{itemize}
\item convert a sequence of machine instructions
into a CFG through the emitter interface, described below, and
\item convert it from a \newdef{cluster}, which is
the basic linearized representation used in the MLRISC system.
\end{itemize}
The first method requires you to perform instruction selection
from a compiler front-end, but allows you to bypass all other
MLRISC phases if desired. The second method allows you
to take advantage of various MLRISC's instruction selection modules
currently available. We describe these methods in this section.
\paragraph{Directly from Instructions}
Signature \sml{CODE_EMITTER} below describes an abstract emitter interface
for accepting a linear stream of instructions from a source
and perform a sequence of actions based on this
stream\footnote{Unlike the signature {\tt EMITTER\_NEW} or
{\tt FLOWGRAPH\_GEN}, it has the advantage that it is not
tied into any form of specific flowgraph representation.}.
\begin{SML}
signature \mlrischref{extensions/code-emitter.sig}{CODE_EMITTER} = sig
structure I : INSTRUCTIONS
structure C : CELLS
structure P : PSEUDO_OPS
sharing I.C = C
type emitter =
\{ defineLabel : Label.label -> unit,
entryLabel : Label.label -> unit,
exitBlock : C.cellset -> unit,
pseudoOp : P.pseudo_op -> unit,
emitInstr : I.instruction -> unit,
comment : string -> unit,
init : int -> unit,
finish : unit -> unit
\}
end
\end{SML}
The code emitter interface has the following informal protocol.
\begin{methods}
init($n$) & Initializes the emitter and signals that
the back-end should
allocate space for $n$ bytes of machine code.
The number is ignored for non-machine code back-ends. \\
defineLabel($l$) & Defines a new label $l$ at the current position.\\
entryLabel($l$) & Defines a new entry label $l$ at the current position.
An entry label defines an entry point into the current flow graph.
Note that multiple entry points are allowed\\
exitBlock($c$) & Defines an exit at the current position.
The cellset $c$ represents the live-out information \\
pseudOp($p$) & Emits an pseudo op $p$ at the current position \\
emitInstr($i$) & Emits an instruction $i$ at the current position \\
blockName($b$) & Changes the block name to $b$ \\
comment($msg$) & Emits a comment $msg$ at the current position \\
finish & Signals that the use of the emitter is finished.
The emitter is free to perform its post-processing functions.
When this is finished the CFG is built.
\end{methods}
The functor \sml{ControlFlowGraphGen} below can be
used to create a CFG builder that uses the \sml{CODE_EMITTER} interface.
\begin{SML}
signature \mlrischref{IR/mlrisc-cfg-gen.sig}{CONTROL_FLOW_GRAPH_GEN} = sig
structure CFG : CONTROL_FLOW_GRAPH
structure Emitter : CODE_EMITTER
sharing Emitter.I = CFG.I
sharing Emitter.P = CFG.P
val emitter : CFG.cfg -> Emitter.emitter
end
functor \mlrischref{IR/mlrisc-cfg-gen.sml}{ControlFlowGraphGen}
(structure CFG : CONTROL_FLOW_GRAPH
structure Emitter : CODE_EMITTER
structure P : INSN_PROPERTIES
sharing CFG.I = Emitter.I = P.I
sharing CFG.P = Emitter.P
sharing CFG.B = Emitter.B
) : CONTROL_FLOW_GRAPH_GEN
\end{SML}
\paragraph{Cluster to CFG}
The core \MLRISC{} system implements many instruction selection
front-ends. The result of an instruction selection module is a linear
code layout block called a cluster. The functor \sml{Cluster2CFG} below
generates a translator that translates a cluster into a CFG:
\begin{SML}
signature \mlrischref{IR/mlrisc-cluster2cfg.sig}{CLUSTER2CFG} = sig
structure CFG : CONTROL_FLOW_GRAPH
structure F : FLOWGRAPH
sharing CFG.I = F.I
sharing CFG.P = F.P
sharing CFG.B = F.B
val cluster2cfg : F.cluster -> CFG.cfg
end
functor \mlrischref{IR/mlrisc-cluster2cfg.sml}{Cluster2CFG}
(structure CFG : CONTROL_FLOW_GRAPH
structure F : FLOWGRAPH
structure P : INSN_PROPERTIES
sharing CFG.I = F.I = P.I
sharing CFG.P = F.P
sharing CFG.B = F.B
) : CLUSTER2CFG
\end{SML}
\paragraph{CFG to Cluster}
The basic \MLRISC{} system also implements many back-end functions
such as register allocation, assembly output and machine code output.
These modules all utilize the cluster representation. The
functor \mlrischref{IR/mlrisc-cfg2cluster.sml}{CFG2Cluster}
below generates a translator
that converts a CFG into a cluster. With the previous functor,
the CFG and the cluster presentation can be freely inter-converted.
\begin{SML}
signature \mlrischref{IR/mlrisc-cfg2cluster.sig}{CFG2CLUSTER} = sig
structure CFG : CONTROL_FLOW_GRAPH
structure F : FLOWGRAPH
sharing CFG.I = F.I
sharing CFG.P = F.P
sharing CFG.B = F.B
val cfg2cluster : { cfg : CFG.cfg, relayout : bool } -> F.cluster
end
functor \mlrischref{IR/mlrisc-cfg2cluster.sml}{CFG2Cluster}
(structure CFG : CONTROL_FLOW_GRAPH
structure F : FLOWGRAPH
sharing CFG.I = F.I
sharing CFG.P = F.P
sharing CFG.B = F.B
val patchBranch : {instr:CFG.I.instruction, backwards:bool} ->
CFG.I.instruction list
) : CFG2CLUSTER
\end{SML}
When a CFG originates from a cluster, we try to preserve
the same code layout through out all optimizations when possible.
The function \sml{cfg2cluster} takes an optional flag
that specifies we should force the recomputation of
the code layout of a control flow graph when translating a CFG
back into a cluster.
\subsubsection{Basic CFG Transformations}
Basic CFG transformations are implemented in the functor
\sml{CFGUtil}. These transformations include splitting edges, merging
edges, removing unreachable code and tail duplication.
\begin{SML}
functor \mlrischref{IR/mlrisc-cfg-util.sml}{CFGUtil}
(structure CFG : CONTROL_FLOW_GRAPH
structure P : INSN_PROPERTIES
sharing P.I = CFG.I
) : CFG_UTIL
\end{SML}
The signature of \sml{CFGUtil} is defined below:
\begin{SML}
signature \mlrischref{IR/mlrisc-cfg-util.sig}{CFG_UTIL} = sig
structure CFG : CONTROL_FLOW_GRAPH
val updateJumpLabel : CFG.cfg -> node_id -> unit
val mergeEdge : CFG.cfg -> CFG.edge -> bool
val eliminateJump : CFG.cfg -> node_id -> bool
val insertJump : CFG.cfg -> node_id -> bool
val splitEdge : CFG.cfg -> { edge : CFG.edge, jump : bool }
-> { edge : CFG.edge, node : CFG.node }
val isMerge : CFG.cfg -> node_id -> bool
val isSplit : CFG.cfg -> node_id -> bool
val hasSideExits : CFG.cfg -> node_id -> bool
val isCriticalEdge : CFG.cfg -> CFG.edge -> bool
val splitAllCriticalEdges : CFG.cfg -> unit
val ceed : CFG.cfg -> node_id * node_id -> bool
val tailDuplicate : CFG.cfg -> \{ subgraph : CFG.cfg, root : node_id \}
-> \{ nodes : CFG.node list,
edges : CFG.edge list \}
val removeUnreachableCode : CFG.cfg -> unit
val mergeAllEdges : CFG.cfg -> unit
end
\end{SML}
These functions have the following meanings:
\begin{itemize}
\item \sml{updateJumpLabel} $G u$. This function
updates the label of the branch instruction in a block $u$
to be consistent with the control flow edges with source $u$.
This is an nop if the CFG is already consistent.
\item \sml{mergeEdge} $G e$. This function merges edge
$e \equiv u \edge{} v$
in the graph $G$ if possible. This is successful only if
there are no other edges flowing into $v$ and no other edges
flowing out from $u$. It returns true if the merge
operation is successful. If successful, the nodes $u$ and $v$
will be coalesced into the block $u$. The jump instruction (if any)
in the node $u$ will also be elided.
\item \sml{eliminateJump} $G u$. This function eliminate the
jump instruction at the end of block $u$ if it is feasible.
\item \sml{insertJump} $G u$. This function inserts a jump
instruction in block $u$ if it is feasible.
\item \sml{splitEdge} $G e$. This function
split the control flow edge $e$, and return a new edge $e'$ and the
new block $u$ as return values. It addition, it takes as
argument a flag \sml{jump}. If this flag is true,
then a jump instruction is always placed in the
split; otherwise, we try to eliminate the jump when feasible.
\item \sml{isMerge} $G u$. This function tests whether block $u$
is a \newdef{merge} node. A merge node is a node that
has two or more incoming flow edges.
\item \sml{isSplit} $G u$. This function tests whether block $u$
is a \newdef{split} node. A split node is a node that
has two or more outgoing flow edges.
\item \sml{hasSideExits} $G u$. This function tests whether
a block has side exits $G$. This assumes that $u$
is a hyperblock.
\item \sml{isCriticalEdge} $G e$. This function tests whether
the edge $e$ is a \newdef{critical} edge. The
edge $e \equiv u \edge{} v$ is critical iff
there are $u$ is merge node and $v$ is a split node.
\item \sml{splitAllCriticalEdges} $G$. This function goes
through the CFG $G$ and splits
all critical edges in the CFG.
This can introduce extra jumps and basic blocks in the program.
\item \sml{mustPreceed} $G (u,v)$. This function
checks whether two blocks $u$ and $v$ are necessarily adjacent.
Blocks $u$ and $v$ must be adjacent iff $u$ must preceed $v$
in any feasible code layout.
\item \sml{tailDuplicate}.
\begin{SML}
val tailDuplicate : CFG.cfg -> \{ subgraph : CFG.cfg, root : node_id \}
-> \{ nodes : CFG.node list,
edges : CFG.edge list \}
\end{SML}
\begin{Figure}
\begin{boxit}
%\cpsfig{figure=../pictures/eps/tail-duplication.eps,width=3in}
\begin{center}
\includegraphics[width=3in]{../pictures/pdf/tail-duplication}
\end{center}%
\end{boxit}
\label{fig:tail-duplication}
\caption{Tail-duplication}
\end{Figure}
This function tail-duplicates the region \sml{subgraph}
until it only has a single entry \sml{root}.
Return the set of new nodes and new edges.
The region is represented as a subgraph view of the CFG.
Figure~\ref{fig:tail-duplication} illustrates
this transformation.
\item \sml{removeUnreachableCode} $G$. This function
removes all unreachable code from the graph.
\item \sml{mergeAllEdges} $G$. This function tries to merge all
the edges in the flowgraph $G$. Merging is performed in the
non-increasing order of edge frequencies.
\end{itemize}
\subsubsection{Dataflow Analysis}
MLRISC provides a simple customizable module for performing
iterative dataflow analysis. A dataflow analyzer
has the following signature:
\begin{SML}
signature \mlrischref{IR/dataflow.sig}{DATAFLOW_ANALYZER} = sig
structure CFG : CONTROL_FLOW_GRAPH
type dataflow_info
val analyze : CFG.cfg * dataflow_info -> dataflow_info
end
\end{SML}
A dataflow problem is described by the signature \sml{DATAFLOW_PROBLEM},
described below:
\begin{SML}
signature \mlrischref{IR/dataflow.sig}{DATAFLOW_PROBLEM} = sig
structure CFG : CONTROL_FLOW_GRAPH
type domain
type dataflow_info
val forward : bool
val bot : domain
val == : domain * domain -> bool
val join : domain list -> domain
val prologue : CFG.cfg * dataflow_info ->
CFG.block node ->
\{ input : domain,
output : domain,
transfer : domain -> domain
\}
val epilogue : CFG.cfg * dataflow_info ->
\{ node : CFG.block node,
input : domain,
output : domain
\} -> unit
end
\end{SML}
This description contains the following items
\begin{itemize}
\item \sml{type domain} is the abstract lattice domain $D$.
\item \sml{type dataflow_info} is where the dataflow information
is stored.
\item \sml{forward} is true iff the dataflow problem is in the
forward direction
\item \sml{bot} is the bottom element of $D$.
\item \sml{==} is the equality function on $D$.
\item \sml{join} is the least-upper-bound function on $D$.
\item \sml{prologue} is a user-supplied function that performs
pre-processing and setup. For each CFG node $X$, this function
computes
\begin{itemize}
\item \sml{input} -- which is the initial input value of $X$
\item \sml{output} -- which is the initial output value of $X$
\item \sml{transfer} -- which is the transfer function on $X$.
\end{itemize}
\item \sml{epilogue} is a function that performs post-processing.
It visits each node $X$ in the flowgraph and return the resulting
\sml{input} and \sml{output} value for $X$.
\end{itemize}
To generate a new dataflow analyzer from a dataflow problem,
the functor \sml{Dataflow} can be used:
\begin{SML}
functor \mlrischref{IR/dataflow.sml}{Dataflow}(P : DATAFLOW_PROBLEM) : DATAFLOW_ANALYZER =
\end{SML}
\subsubsection{Static Branch Prediction}
\subsubsection{Branch Optimizations}
+662
View File
@@ -0,0 +1,662 @@
\section{Machine Description}
\subsection{Overview}
\newdef{MDGen} is a simple tool for generating
various modules in the MLRISC customizable code generator
directly from machine descriptions. These descriptions
contain architectural information such as:
\begin{enumerate}
\item How the the register file(s) are organized.
\item How instructions are encoded in machine code: MLRISC uses
this information to generate machine instructions directly into a byte stream.
Directly machine code generation is used in the SML/NJ compiler.
\item How instructions are pretty printed in assembly: this is used
for debugging and also for assembly output for other non-SML/NJ backends.
\item How instructions are internally represented in MLRISC.
\item Other information needed for performing optimizations, which
include:
\begin{enumerate}
\item The register transfer list (RTL) that defines the
operational semantics of the instruction.
\item Delay slot mechanisms.
\item Information for performing span dependency resolution.
\item Pipeline and reservation table characteristics.
\end{enumerate}
\end{enumerate}
Currently, item 5 is not ready for prime time.
\subsubsection{Why MDGen?}
MLRISC manipulates all instruction sets via a set of abstract
interfaces, which allows the programmer to arbitrarily choose an
instruction representation that is most convenient for a particular
architecture. However, various functions that manipulate
this representation must be provided by the instruction set's programmer.
As the number and complexities of each optimizations grow, and as
the number of architectures increases, the functions
for manipulating the instructions become more numerous and complex.
In order to keep the effort of developing and maintaining
an instruction set manageable,
the MDGen tool is developed to (partially) automate this task.
\subsubsection{Syntax}
MDGen's machine descriptions are written in a syntax that is very
much like that of
\externhref{http://cm.bell-labs.com/cm/cs/what/smlnj/sml.html}{Standard ML}.
Most core SML constructs are recognized.
In addition, new declaration forms specific to MDGen are
used to specify architectural information.
\paragraph{Reserved Words}
All SML keywords are reserved words in MDGen.
In addition, the following keywords are also reserved:
\begin{verbatim}
always architecture assembly at backwards big bits branching called
candidate cell cells cellset debug delayslot dependent endian field
fields formats forwards instruction internal little locations lowercase
name never nodelayslot nullified opcode ordering padded pipeline predicated
register rtl signed span storage superscalar unsigned uppercase
verbatim version vliw when
\end{verbatim}
Two kinds are quotations marks are also reserved:
\begin{SML}
[[ ]]
`` ''
\end{SML}
The first \sml{[[ ]]} is for describing semantics. The
second \sml{`` ''} is for describing assembly syntax.
\paragraph{Syntactic Sugar}
MDGen recognizes the following syntactic sugar.
\begin{description}
\item[Record abbreviations]
Record expressions such as \sml{{x=x,y=y,z=z}}
can be simplified to just \sml{{x,y,z}}.
\item[Binary literals]
Literals in binary can be written with the prefix \sml{0b} (for integer types)
or \sml{0wb} (for word types). For example, \sml{0wb101111} is the same
as \sml{0wx2f} and \sml{0w79}.
\item[Bit slices]
A bit slice, which extracts a range of bits from a word, can be written
using an \sml{at} expression. For example, \sml{w at [16..18]}
means the same thing as \verb|Word32.andb(Word32.>>(w, 0w16),0w7)|, i.e.
it extracts bit 16 to 18 from \sml{w}.
The least significant bit the zeroth bit.
In general, we can write:
\begin{SML}
w at [range1, range2, ..., rangen]
\end{SML}
to extract a sequence of slices from $w$ and concatenate them together.
For example, the expression
\begin{SML}
0wxabcd at [0..3, 4..7, 8..11, 12..15]
\end{SML}
swap the 4 nybbles from the 16-bit word, and evaluates to \sml{0wxdcba}.
\item[Signature]
Signature declarations of the form
\begin{SML}
val x y z : int -> int
\end{SML}
can be used as a shorthand for the more verbose:
\begin{SML}
val x : int -> int
val y : int -> int
val z : int -> int
\end{SML}
\end{description}
\subsubsection{Elaboration Semantics}
Unfortunately, there is no complete formal semantics of how
an MDGen specification elaborates.
But generally speaking, a machine description is a just a structure
(in the SML sense). Different components of this structure describe
different aspects of the architecture.
\paragraph{Syntactic Overloading}
In general, the syntactic overloading are used heavily in MDGen.
There are three types of definitions:
\begin{itemize}
\item Definitions that defines properties of the instruction set.
\item Definitions of functions and terms that are in the RTL meta-language.
The syntax of MDGen's RTL language is borrowed heavily from Lambda-RTL,
which in turns is borrowed heavily from SML.
\item Definitions of functions and types that are to be included in the
output generated by the MDGen tool. These are usually auxiliary
helper functions and definitions.
\end{itemize}
In general, entities of type 2, when appearing in other context, are
properly meta-quoted in the semantics quotations \sml{[[ ]]}.
\subsubsection{Basic Structure of A Machine Description}
The machine description for an architecture are defined via
an \sml{architecture} declaration, which has the following general
form.
\begin{SML}
architecture name =
struct
\Term{architecture type declaration}
\Term{endianess declaration}
\Term{storage class declarations}
\Term{locations declarations}
\Term{assembly case declarations}
\Term{delayslot declaration}
\Term{instruction machine encoding format declarations}
\Term{nested structure declarations}
\Term{instruction definition}
end
\end{SML}
\subsection{Describing the Architecture}
\subsubsection{Architecture type}
Architecture type declaration specifies whether the architecture is
a superscalar or a VLIW/EPIC machine. Currently, this information is
ignored.
\begin{SML}
\Term{architecture type declaration} ::= superscalar | vliw
\end{SML}
\subsubsection{Storage class}
Storage class declarations specify various information about the
registers in the architecture. For example, the Alpha has 32 general
purpose registers and 32 floating point registers. In addition, MLRISC
requires that each architecture specifies a (pseudo) register
type\footnote{Called cellkind in MLRISC.} for
holding condition codes (\sml{CC}).
To specify these information in MDGen, we can say:
\begin{SML}
storage
GP "r" = 32 cells of 64 bits in cellset called "register"
assembly as (fn (30,_) => "$sp"
| (r,_) => "$"^Int.toString r
)
| FP "f" = 32 cells of 64 bits in cellset called "floating point register"
assembly as (fn (f,_) => "$f"^Int.toString f)
| CC "cc" = cells of 64 bits in cellset GP called "condition code register"
assembly as "cc"
\end{SML}
\begin{itemize}
\item There are 32 64-bit general purpose registers,
32 64-bit floating point registers, while \sml{CC} is not a
real register type.
\item Cellsets
are used by MLRISC for annotating liveness information in the program.
The clause \sml{in cellset} states that register type \sml{GP}
and \sml{FP} are allotted their own components in the cellset,
while the register type \sml{CC} are put
in the same cellset component as \sml{GP}.
\item The clause \sml{assembly as} specifies
how each register is to be pretty printed. On the Alpha, general
purpose register are pretty printed with prefix \sml{$}, while
floating point registers are pretty printed with the prefix \sml{$f}.
A special case is made for register 30, which is the stack pointer, and
is pretty printing as \sml{$sp}. Pseudo condition code registers
are pretty printed with the prefix \sml{cc}.
\end{itemize}
\subsubsection{Locations}
Special locations in the register files can be declared using the
\sml{locations} declarations. On the Alpha, GPR
30 is the stack pointer, GPR 28 and floating point register 30
are used as the assembly temporaries. This special constants
can be defined as follows:
\begin{SML}
locations
stackptrR = $GP[30]
and asmTmpR = $GP[28]
and fasmTmp = $FP[30]
\end{SML}
\subsection{Specifying the Machine Encoding}
\subsubsection{Endianess}
The endianess declaration specifies whether the machine is little
endian or big endian so that the correct machine instruction encoding
functions can be generated. The general syntax of this is:
\begin{SML}
\Term{endianess declaration} ::= little endian | big endian
\end{SML}
The Alpha is little endian, so we just say:
\begin{SML}
little endian
\end{SML}
\subsubsection{Defining New Instruction Formats}
How instructions are encoded are specified using
\sml{instruction format} declarations. An instruction format declaration
has the following syntax:
\begin{SML}
\Term{instruction machine encoding format declarations} ::=
instruction formats n bits
\Term{format}1
| \Term{format}2
| \Term{format}3
| ...
| \Term{format}n-1
| \Term{format}n
\end{SML}
Each encoding format can be a primitive format, or a derived format.
\paragraph{Primitive formats}
A primitive format is simply specified by giving it a name and specifying
the position, names and types of its fields. This is usually the same
way it is described in a architectural reference manual.
Here is how we specify some of the (32 bit) primitive instruction formats
used in the Alpha.
\begin{SML}
instruction formats 32 bits
Memory\{opc:6, ra:5, rb:GP 5, disp: signed 16\}
| Jump\{opc:6=0wx1a,ra:GP 5,rb:GP 5,h:2,disp:int signed 14\}
| Memory_fun\{opc:6, ra:GP 5, rb:GP 5, func:16\}
| Branch\{opc:branch 6, ra:GP 5, disp:signed 21\}
| Fbranch\{opc:fbranch 6, ra:FP 5, disp:signed 21\}
| Operate0\{opc:6,ra:GP 5,rb:GP 5,sbz:13..15=0,_:1=0,func:5..11,rc:GP 5\}
| Operate1\{opc:6,ra:GP 5,lit:signed 13..20,_:1=1,func:5..11,rc:GP 5\}
\end{SML}
For example, the format \sml{Memory}
\begin{SML}
Memory\{opc:6, ra:5, rb:GP 5, disp: signed 16\}
\end{SML}
has a 6-bit opcode field, a 5-bit \sml{ra} field, a 5-bit \sml{rb}
field which always hold a general purpose register, and a 16-bit
sign-extended displacement field. The field to the left is positioned
at the most significant bits, while the field to the right is positioned
at the least. The widths of these fields must add up to 32 bits.
Similarly, the format \sml{Jump}
\begin{SML}
Jump{opc:6=0wx1a,ra:GP 5,rb:GP 5,h:2,disp:int signed 14}
\end{SML}
contains a 6-bit opcode field which always hold the constant \sml{0x1a},
two 5-bit fields \sml{ra} and \sml{rb} which are of type \sml{GP},
and a 14-bit sign-extended field of type integer.
Each field in a primitive format has one of 5 forms:
\begin{SML}
\Term{name} : \Term{position}
\Term{name} : \Term{position} = \Term{value}
\Term{name} : \Term{type} \Term{position}
\Term{name} : \Term{type} \Term{position} = \Term{value}
_ : \Term{position} = \Term{value}
\end{SML}
where \Term{position} is either a width, or a bits range
$n$\sml{..}$m$,
with an optional \sml{signed} prefix. The last form, with a wild card
for the field name, can be used to specify an anonymous field that
always has a fixed value.
By default, a field has type \sml{Word32.word}. If a type $T$
is specified, then the function \sml{emit_}$T$ is implicitly called
to convert the type into the appropriate encoding. The function
\sml{emit_}$T$ are generated automatically by MDGen if it is a cellkind
defined by the \sml{storage} class declaration, or if it is a primitive
type such as integer or boolean.
There are also other ways to automatically generate this function
(more on this later.)
For example, the format \sml{Operate1}
\begin{SML}
Operate1\{opc:6,ra:GP 5,lit:signed 13..20,_:1=1,func:5..11,rc:GP 5\}
\end{SML}
states that bits 26 to 31 are allocated to field \sml{opc},
bits 21 to 25 are allocated to field \sml{ra}, which is of type
\sml{GP}, bits 13 to 20 are allocated to field \sml{lit}, bit 12
is a single bit of value 1, etc.
MDGen generates a function for each primitive format declaration of
the same name that can be used for emitting the instruction.
In the case of the Alpha, the following functions are generated:
\begin{SML}
val Memory : \{opc:Word32.word, ra:Word32.word,
rb:int, disp:Word32.word\} -> unit
val Jump : \{ra:int, rb:int, disp:Word32.word\} -> unit
val Operate1 : \{opc:Word32.word, ra:int, lit:Word32.word,
func:Word32.word, rc:int\} -> unit
\end{SML}
\paragraph{Derived formats}
Derived formats are simply instruction formats that are defined
in terms of other formats. On the alpha, we have a \sml{Operate}
format that simplifies to either \sml{Operate0} or \sml{Operate1},
depending on whether the second argument is a literal or a register.
\begin{SML}
Operate\{opc,ra,rb,func,rc\} =
(case rb of
I.REGop rb => Operate0\{opc,ra,rb,func,rc\}
| I.IMMop i => Operate1\{opc,ra,lit=itow i,func,rc\}
| I.HILABop le => Operate1\{opc,ra,lit=High{le=le},func,rc\}
| I.LOLABop le => Operate1\{opc,ra,lit=Low{le=le},func,rc\}
| I.LABop le => Operate1\{opc,ra,lit=itow(LabelExp.valueOf le),func,rc\}
)
\end{SML}
\subsubsection{Generating Encoding Functions}
In MLRISC, we represent an instruction as a set of ML datatypes.
Some of these datatypes represent specific fields or
opcodes of the instructions.
MDGen lets us to associate a machine encoding to each datatype constructor
directly in the specification, and automatically generates an
encoding function for these datatypes.
There are two different ways of specifying an encoding. The first way
is just to write the machine encoding directly next the constructor.
Here's an example directly from the Alpha description:
\begin{SML}
structure Instruction =
struct
datatype branch! = (* table C-2 *)
BR 0x30
| BSR 0x34
| BLBC 0x38
| BEQ 0x39 | BLT 0x3a | BLE 0x3b
| BLBS 0x3c | BNE 0x3d | BGE 0x3e
| BGT 0x3f
datatype fbranch! = (* table C-2 *)
FBEQ 0x31 | FBLT 0x32
| FBLE 0x33 | FBNE 0x35
| FBGE 0x36 | FBGT 0x37
...
end
\end{SML}
The datatypes \sml{branch} and \sml{fbranch} represent specific
branch opcodes for integer branches \sml{BRANCH}, or floating point
branches \sml{FBRANCH}. On the Alpha, instruction \sml{BR} is encoded
with an opcode of \sml{0x30}, instruction \sml{BSR} is encoded
as \sml{0x34} etc. MDGen automatically generates two functions
\begin{SML}
val emit_branch : branch -> Word32.word
val emit_fbranch : branch -> Word32.word
\end{SML}
that perform this encoding.
In the specification for the instruction set, we state that the
\sml{BRANCH} instruction should be encoded using format \sml{Branch},
while the \sml{FBRANCH} instruction should be encoded using
format \sml{Fbranch}.
\begin{SML}
structure MC =
struct
(* Auxiliary function for computing the displacement of a label *)
fun disp ... = ...
...
end
...
instruction
...
| BRANCH of branch * $GP * Label.label
Branch\{opc=branch,ra=GP,disp=disp label\}
| FBRANCH of fbranch * $FP * Label.label
Fbranch\{opc=fbranch,ra=FP,disp=disp label\}
| ...
\end{SML}
Since the primitive instructions formats \sml{Branch} and \sml{FBranch}
are defined with branch and fbranch as the type in the opcode field
\begin{SML}
| Branch\{opc:branch 6, ra:GP 5, disp:signed 21\}
| Fbranch\{opc:fbranch 6, ra:FP 5, disp:signed 21\}
\end{SML}
the functions \sml{emit_branch} and \sml{emit_fbranch} are implicitly
called.
Another way to specify an encoding is to specify a range, as
in the following example:
\begin{SML}
datatype fload[0x20..0x23]! = LDF | LDG | LDS | LDT
datatype fstore[0x24..0x27]! = STF | STG | STS | STT
\end{SML}
This states that \sml{LDF} should be assigned the encoding \sml{0x20},
\sml{LDG} the encoding \sml{0x21} etc. This form is useful for
specifying a consecutive range.
\subsubsection{Encoding Variable Length Instructions}
Most architectures nowadays have fixed length encodings for instructions.
There are some notatable exceptions, however.
The Intel x86 architecture uses a legacy
variable length encoding. Modern RISC machines developed for
embedded systems may utilize space-reduction compression schemes in their
instruction sets. Finally, VLIW machines usually have some form
of NOP compression scheme for compacting issue packets.
\subsection{Specifying the Assembly Formats}
\subsubsection{Assembly Case Declaration}
The assembly case declaration specifies whether the assembly should be
emitted in lower case, upper case, or verbatim. If either lower case
or upper case is specified, all literal strings are converted to the
appropriate case. The general syntax of this declaration is:
\begin{SML}
\Term{assembly case declaration} ::=
lowercase assembly
| uppercase assembly
| verbatim assembly
\end{SML}
\subsubsection{Assembly Annotations}
Assembly output are specified in the assembly meta quotations
\sml{`` ''}, or string quotations \sml{" "}.
For example, here is a fragment from the Alpha description:
\begin{SML}
instruction
...
| LOAD of \{ldOp:load, r: $GP, b: $GP, d:operand, mem:Region.region\}
``<ldOp>\t<r>, <d>()<mem>''
| STORE of \{stOp:store, r: $GP, b: $GP, d:operand, mem:Region.region\}
``<stOp>\t<r>, <d>()<mem>''
| BRANCH of branch * $GP * Label.label
``<branch>\t<GP>, <label>''
| FBRANCH of fbranch * $FP * Label.label
``<fbranch>\t<FP>, <label>''
| CMOVE of \{oper:cmove, ra: $GP, rb:operand, rc: $GP\}
``<oper>\t<ra>, <rb>, <rc>''
| FOPERATE of \{oper:foperate, fa: $FP, fb: $FP, fc: $FP\}
``<oper>\t<fa>, <fb>, <fc>''
| ...
\end{SML}
All characters within the quotations \sml{`` ''} have the same
interpretation as in the string quotation \sml{" "}, except when
they are delimited by the \newdef{backquotes}
\verb|< >|.
Here's how the backquote is interpreted:
\begin{itemize}
\item If it is \verb|<|$x$\verb.>. and $x$ is a variable name of type $t$,
and if an assembly function of type $t$ is defined, then it will be invoked
to convert $x$ to the appropriate text.
\item If it is \verb|<|$x$\verb.>. and $x$ is a variable name of type $t$,
and if an assembly function of type $t$ is NOT defined,
then the function \sml{emit_}$x$ will be called to pretty print $x$.
\item If it is \verb|<|$e$\verb.>. where $e$ is a general expression, then
it will be used directly.
\end{itemize}
\subsubsection{Generating Assembly Functions}
Similar to machine encodings, we can attach assembly annotations to
datatype definitions and let MDGen generate the assembly functions for us.
Annotations take two forms, explicit or implicit.
Explicit annotations are enclosed within assembly quotations \sml{`` ''}.
For example, on the Alpha the datatype \sml{operand} is used to represent
an integer operand. This datatype is defined as follows:
\begin{SML}
datatype operand =
REGop of $GP ``<GP>''
| IMMop of int ``<int>''
| HILABop of LabelExp.labexp ``hi(<labexp>)''
| LOLABop of LabelExp.labexp ``lo(<labexp>)''
| LABop of LabelExp.labexp ``<labexp>''
| CONSTop of Constant.const ``<const>''
\end{SML}
Basicaly this states that \sml{REGop r} should be pretty printed
as \sml{$r}, \sml{IMMop i}
as \sml{i}, \sml{HILABexp le}
as \sml{hi(le)},
etc.
Implicit assembly annotations are specified by simply attaching
an exclamation mark at the end of the datatype name. This states
that the assembly output is the same as the name of the datatype
constructor\footnote{But appropriately modified by the assembly case
declaration.}. For example,
the datatype \sml{operate} is a listing of all integer opcodes
used in MLRISC.
\begin{SML}
datatype operate! = (* table C-5 *)
ADDL (0wx10,0wx00) | ADDQ (0wx10,0wx20)
| CMPBGE(0wx10,0wx0f) | CMPEQ (0wx10,0wx2d)
| CMPLE (0wx10,0wx6d) | CMPLT (0wx10,0wx4d) | CMPULE (0wx10,0wx3d)
| CMPULT(0wx10,0wx1d) | SUBL (0wx10,0wx09)
| SUBQ (0wx10,0wx29)
| S4ADDL(0wx10,0wx02) | S4ADDQ (0wx10,0wx22) | S4SUBL (0wx10,0wx0b)
| S4SUBQ(0wx10,0wx2b) | S8ADDL (0wx10,0wx12) | S8ADDQ (0wx10,0wx32)
| S8SUBL(0wx10,0wx1b) | S8SUBQ (0wx10,0wx3b)
| AND (0wx11,0wx00) | BIC (0wx11,0wx08) | BIS (0wx11,0wx20)
| EQV (0wx11,0wx48)
| ORNOT (0wx11,0wx28) | XOR (0wx11,0wx40)
| EXTBL (0wx12,0wx06) | EXTLH (0wx12,0wx6a) | EXTLL(0wx12,0wx26)
| EXTQH (0wx12,0wx7a) | EXTQL (0wx12,0wx36) | EXTWH(0wx12,0wx5a)
| EXTWL (0wx12,0wx16) | INSBL (0wx12,0wx0b) | INSLH(0wx12,0wx67)
| INSLL (0wx12,0wx2b) | INSQH (0wx12,0wx77) | INSQL(0wx12,0wx3b)
| INSWH (0wx12,0wx57) | INSWL (0wx12,0wx1b) | MSKBL(0wx12,0wx02)
| MSKLH (0wx12,0wx62) | MSKLL (0wx12,0wx22) | MSKQH(0wx12,0wx72)
| MSKQL (0wx12,0wx32) | MSKWH (0wx12,0wx52) | MSKWL(0wx12,0wx12)
| SLL (0wx12,0wx39) | SRA (0wx12,0wx3c) | SRL (0wx12,0wx34)
| ZAP (0wx12,0wx30) | ZAPNOT (0wx12,0wx31)
| MULL (0wx13,0wx00) | MULQ (0wx13,0wx20)
| UMULH (0wx13,0wx30)
| SGNXL "addl" (0wx10,0wx00) (* same as ADDL *)
\end{SML}
This definitions states that \sml{ADDL} should be pretty printed
as \sml{addl}, \sml{ADDQ} as \sml{addq}, etc. However, the opcode
\sml{SGNXL} is pretty printed as \sml{addl} since it has been explicitly
overridden.
\subsection{Defining the Instruction Set}
How the instruction set is represented is declared using the
\sml{instruction} declaration. For example, here's how the Alpha instruction
set is defined:
\begin{SML}
instruction
DEFFREG of $FP
| LDA of \{r: $GP, b: $GP, d:operand\}
| LDAH of \{r: $GP, b: $GP, d:operand\}
| LOAD of \{ldOp:load, r: $GP, b: $GP, d:operand, mem:Region.region\}
| STORE of \{stOp:store, r: $GP, b: $GP, d:operand, mem:Region.region\}
| FLOAD of \{ldOp:fload, r: $FP, b: $GP, d:operand, mem:Region.region\}
| FSTORE of \{stOp:fstore, r: $FP, b: $GP, d:operand, mem:Region.region\}
| JMPL of \{r: $GP, b: $GP, d:int\} * Label.label list
| JSR of \{r: $GP, b: $GP, d:int\} * C.cellset * C.cellset * Region.region
| RET of \{r: $GP, b: $GP, d:int\}
| BRANCH of branch * $GP * Label.label
| FBRANCH of fbranch * $FP * Label.label
| ...
\end{SML}
The \sml{instruction} declaration defines a datatype and specifies
that this datatype is used to represent the instruction set. Generally
speaking, the instruction set's designer has complete freedom in how the
datatype is structured, but there are a few simple rules that she should
follow:
\begin{itemize}
\item If a field represents a register, it should be typed
with the appropriate storage types \sml{$GP},
\sml{$FP}, etc.~instead
of \sml{int}. MDGen will treat its value in the correct manner; for
example, during assembly emission a field declared type \sml{int} is
printed as an integer, while a field declared type \sml{$GP} is displayed
as a general purpose register.
\item MDGen recognizes the following special
types: \sml{label}, \sml{labexp}, \sml{region}, and \sml{cellset}.
\end{itemize}
\subsection{Specifying Instruction Semantics}
MLRISC performs all optimizations at
the granulariy of individual instructions,
specialized to the architecture at hand. Many
optimizations are possible only if the ``semantics'' of the
instructions set to are properly specified. MDGen contains a
\emph{register transfer language} (RTL) sub-language that let us to describe
instruction semantics in a modular and succinct manner.
The semantics of this RTL sub-language has been borrowed heavily from
Norman Ramsey's and Jack Davidson's Lambda RTL. There
are a few main differences, however:
\begin{itemize}
\item The syntax of our RTL language
is closer to that of ML than Lambda RTL.
\item Our RTL language, like that of MDGen, is tied closely to MLRISC.
\end{itemize}
\subsection{How to Run the Tool}
\subsection{Machine Description}
Here are some machine descriptions in varing degree of completion.
\begin{itemize}
\item \mlrischref{sparc/sparc.mdl}{Sparc}
\item \mlrischref{hppa/hppa.mdl}{Hppa}
\item \mlrischref{alpha/alpha.mdl}{Alpha}
\item \mlrischref{ppc/ppc.mdl}{PowerPC}
\item \mlrischref{x86/x86.mdl}{X86}
\end{itemize}
\subsection{ Syntax Highlighting Macros }
\begin{itemize}
\item \href{md.vim}{For vim 5.3}
\end{itemize}
+94
View File
@@ -0,0 +1,94 @@
\section{Register Allocation}
All the optimization modules are written in a generic fashion but
parameterized over architecture and client information. The Standard
ML module system is a central mechanism to the design and
organization of MLRISC. Parameterized modules in Standard ML are
provided by \newdef{functors}, that takes the
specification of input modules and produces a module that matches some
output specification. In particular, SML/NJ modules are
\emph{higher order}, which means that a functor can yield functors as a
result. I will use register allocation as an example.
\image{Back end optimizations}{pictures/png/hof-1.png}{align=left}
The register allocator is written has a higher order functor which
when applied to suitable arguments produces an integer or floating
point register allocator. The figure is simplifed because the output
functor is not restricted to integer and floating point allocators
but could also be other types of allocators, for example, condition
code. The integer and floating point register allocators are
functors that only take \emph{client specific} parameters as
input, whereas the higher-order takes architectural parameters as
input. The client specific parameters include:
\begin{SML}
nFreeRegs : int
dedicated : int list
spill : ..
reload : ..
\end{SML}
where:
\begin{description}
\item[\sml{nFreeRegs}] is the number of free registers or
essentially the number of colors available for coloring the
interference graph.
\item[\sml{dedicated}] is the list of dedicated registers. It
is useful to exclude these from the graph-color process to reduce
the size of the data structures created.
\item[\sml{spill/reload}] are functions that describe how to
spill and reload registers that need to be spilled or reloaded in
an instruction. These two functions are perhaps the most
complicated pieces of information that need to be supplied by a
client of MLRISC.
\end{description}
The architecture specific parameters supplied to the higher-order
functor include:
\begin{SML}
firstPseudoReg : int
maxPseudoR : unit -> int
defUse : instruction -> (int list * int list)
\end{SML}
where:
\begin{description}
\item[\sml{firstPseudoR}] is an integer representing the first
pseudo register. Any register below this value is a physical
register.
\item[\sml{maxPseudoR}] is a function that returns an
integer indicating the number of the highest pseudo-register that
has been used in the program. This number is useful in estimating
the intial size of various tables.
\item[\sml{defUse}] is a function that returns the
registers defined and used by an instruction.
\end{description}
These parameters are largely self explanatory, however, there are
addition architectural parameters that relate to the internal
representation of instructions that would be ugly to explain. For
example there is the need for a module that does liveness analysis
over the register class that is being allocated. This type of
complexity can be shielded from a user. For the DEC Alpha the
situation is as shown in the figure:
\image{Back end optimizations}{pictures/png/hof-2.png}{align=center}
The client only sees the functors on the right, to which only client
specific information need be provided. There is the illusion of a
dedicated DEC Alpha integer and floating point register
allocator. There are several advantages to this:
\begin{itemize}
\item The architectural parameters that are implementation specific
do not need to be explained to a user, and are supplied by someone
that intimately understands the port to the target architecture.
\item The number of parameters that a client supplies is
reduced.
\item The parameters that the client supplies is restricted to
things that concern the front end.
\end{itemize}
File diff suppressed because it is too large Load Diff
+150
View File
@@ -0,0 +1,150 @@
\documentclass{article}
\usepackage{graphicx}
\usepackage{mltex}
\usepackage{wrapfig}
\usepackage{float}
\usepackage{alltt}
%\usepackage{floatfig}
\usepackage{fancyheadings}
%\usepackage{draftcopy}
%\usepackage{bookman}
\usepackage{utopia}
%\usepackage{times}
%\usepackage{ncntrsbk}
%\usepackage{palatino}
\setlength{\textwidth}{6.5in}
\setlength{\evensidemargin}{0in}
\setlength{\oddsidemargin}{0in}
\setlength{\textheight}{8in}
\setlength{\topmargin}{-0.5in}
\pagestyle{fancyplain}
%\addtolength{\headwidth}{\marginparsep}
%\addtolength{\headwidth}{\marginparwidth}
\newcommand{\edge}[1]{\rightarrow_{#1}}
\newcommand{\union}{\cup}
\newcommand{\Union}{\bigcup}
\newcommand{\overrides}{overrides}
\newcommand{\defas}{\stackrel{\rm as}{=}}
\renewcommand{\sectionmark}[1]{\markright{\thesection\ #1}}
\renewcommand{\subsectionmark}[1]{\markright{\thesubsection\ #1}}
\newcommand{\Term}[1]{\mbox{\it #1}}
\lhead[\fancyplain{}{\bfseries\thepage}]%
{\fancyplain{}{\bfseries\rightmark}}
\rhead[\fancyplain{}{\bfseries\leftmark}]%
{\fancyplain{}{\bfseries\thepage}}
\cfoot{}
\newenvironment{Figure}{\begin{figure}[htbp]}{\end{figure}}
\begin{document}
\title{\bf \LARGE MLRISC \\ \large A framework for retargetable and optimizing compiler back ends}
\author{\begin{tabular}{c}
Lal George \\ \\
Bell Laboratories \\
600--700 Mountain Ave. \\
Murray Hill, NJ 07974--0636. \\
{\tt george@research.bell-labs.com}
\end{tabular}
\and
\begin{tabular}{c}
Allen Leung \\ \\
New York University \\
719 Broadway, Rm. 708 \\
New York, NY 10003. \\
{\tt leunga@cs.nyu.edu}
\end{tabular}
}
\date{\today}
\bibliographystyle{alpha}
\maketitle
\begin{abstract}
Writing native code generators for modern processors is a significant
investment. Unfortunately it is difficult
to reuse this investment for other architectures, and even more
difficult to reuse for other source language compilers. MLRISC is
a customizable optimizing back-end written in
\externhref{http://cm.bell-labs.com/cm/cs/what/smlnj/sml.html}{Standard ML}
and has been successfully retargeted to multiple architectures.
MLRISC deals elegantly with the special requirements imposed by the
execution model of different high-level, typed languages, by allowing
many components of the system to be customized to fit the source language
semantics and runtime system requirements.
\end{abstract}
\tableofcontents
\newpage
\majorsection{MLRISC}
\include{INTRO}
\include{contributors}
\include{requirements}
\include{availability}
\majorsection{Overview}
\include{problem}
\include{contributions}
\include{mlrisc-compiler}
\include{mlrisc-ir-rep}
\include{mlrisc-gen}
\include{backend-opt}
\include{mlrisc-ra}
\include{mlrisc-md}
\include{gc}
\include{sys-integration}
\include{optimizations}
\include{mlrisc-graphics}
\include{line-counts}
\include{systems}
\include{future-work}
\majorsection{System}
\include{mlrisc-arch}
\include{mltree}
\include{mltree-ext}
\include{mltree-util}
\include{instrsel}
\include{asm}
\include{mc}
\include{delayslots}
\include{span-dep}
%\include{md}
\include{graphs}
\include{graphics}
\include{compiler-graphs}
\include{mlrisc-ir}
\include{SSA}
\include{ILP}
\include{VLIW}
\include{ra}
\majorsection{Back Ends}
\include{alpha}
\include{hppa}
\include{sparc}
\include{x86}
\include{ppc}
\include{mips}
\include{C6}
\majorsection{Basic Types}
\include{annotations}
\include{cells}
\include{cluster}
\include{constants}
\include{pseudo-ops}
\include{instructions}
\include{streams}
\include{labelexp}
\include{labels}
\include{regions}
\include{regmap}
\bibliography{mlrisc}
\end{document}
+73
View File
@@ -0,0 +1,73 @@
%
% This is derived from alltt.sty
%
\NeedsTeXFormat{LaTeX2e}
\ProvidesPackage{mltex}[2000/2/12 defines mltex environment]
\usepackage{latexsym}
%\usepackage{psfig}
\usepackage{fancyheadings}
\usepackage{sml}
\usepackage{color}
\usepackage{verbatim}
% Sectioning
\newcommand{\Chapter}[1]{\chapter{#1}}
\newcommand{\Section}[1]{\section{#1}}
\newcommand{\Subsection}[1]{\subsection{#1}}
\newcommand{\Subsubsection}[1]{\subsubsection{#1}}
\newcommand{\Paragraph}[1]{\paragraph{#1}}
\newcommand{\majorsection}[1]{}
% Frames
\newsavebox{\savepar}
\newenvironment{boxit}{\begin{lrbox}{\savepar}
\begin{minipage}[b]{\columnwidth}}
{\end{minipage}\end{lrbox}\begin{center}\framebox[\columnwidth]{\usebox{\savepar}}\end{center}}
\newenvironment{Boxit}{\begin{tabular}{|c|}\hline}{\\\hline\end{tabular}}
% Table
\newenvironment{Table}[2]{\begin{tabular}{#1}}{\end{tabular}}
% Images and Figures
\newcommand{\image}[3]{}
%\newcommand{\cpsfig}[1]{\centerline{\psfig{#1}}}
% Formatting
\newenvironment{Bold}{\begingroup\bf}{\endgroup}
\newenvironment{Italics}{\begingroup\it}{\endgroup}
\newenvironment{Emph}{\begingroup\em}{\endgroup}
\newcommand{\italics}[1]{{\it #1}}
\newcommand{\bold}[1]{{\bf #1}}
%\newcommand{\emph}[1]{{\em #1}}
% New definitions
\newcommand{\newdef}[1]{{\em #1}}
\newcommand{\newtype}[1]{{\tt #1}}
% Enviroments
\newenvironment{SML}{\begin{smldisplay}}{\end{smldisplay}}
\newenvironment{methods}{\begin{center}\begin{tabular}{@{\tt}ll}}%
{\end{tabular}\end{center}}
\newenvironment{address}{}{}
% HTML
\newcommand{\href}[2]{#2\footnote{url: \tt #1}}
\newcommand{\externhref}[2]{#2\footnote{url: \tt #1}}
\newcommand{\mlrischref}[2]{\sml{#2}\footnote{{\bf file:} {\tt #1}}}
\newcommand{\br}[1]{}
\newcommand{\hr}{\rule{1em}{\textwidth}}
% Color
\renewenvironment{color}[1]{}{}
% Misc
\newcommand{\MLRISC}{MLRISC}
\newcommand{\MLTeX}{\mbox{$\mbox{MLT}_{\mbox{E}}\mbox{X}$}}
\endinput
+120
View File
@@ -0,0 +1,120 @@
\section{\MLTeX}
\newdef{\MLTeX} is a special \newdef{\LaTeX} package for writing
\MLRISC{} documentation. It is similar to the
\newdef{latex2html}~\cite{latex2html} tool
except that \MLTeX{} has special environments for documenting
Standard ML code. In addition, there is an accompanying tool
called \newdef{mltex2html} for generating HTML pages.
This page, for example, is formatted by \MLTeX.
\subsection{Macros}
Environments defined in \MLTeX{} are:
\begin{description}
\item[SML] This environment is used to display MLRISC code.
For example,
\begin{verbatim}
\begin{SML}
datatype 'a tree =
EMPTY
| LEAF of 'a
| NODE of 'a * 'a tree * 'a tree
\end{SML}
\end{verbatim}
generates:
\begin{SML}
datatype 'a tree =
EMPTY
| LEAF of 'a
| NODE of 'a * 'a tree * 'a tree
\end{SML}
\item[methods] This environment can be used to document a list of
methods to an interface. For example,
\begin{verbatim}
\begin{methods}
\sml{+ : int * int -> int} & addition \\
\sml{- : int * int -> int} & subtraction \\
\sml{* : int * int -> int} & multiplication \\
\sml{/ : int * int -> int} & division \\
\end{methods}
\end{verbatim}
generates:
\begin{methods}
\sml{+ : int * int -> int} & addition \\
\sml{- : int * int -> int} & subtraction \\
\sml{* : int * int -> int} & multiplication \\
\sml{/ : int * int -> int} & division \\
\end{methods}
\end{description}
Macros defined in \MLTeX{} are:
\begin{description}
\item[sml] This macro can be used inline for formating SML code fragment.
For example the fragment
\begin{verbatim}
\begin{quotation}
\begin{tabular}{l}
\sml{val toString : int -> string} \\
\sml{val map : ('a -> 'b) -> 'a list -> 'a list}
\end{tabular}
\end{quotation}
\end{verbatim}
\noindent is formated as:
\begin{quotation}
\begin{tabular}{l}
\sml{val toString : int -> string} \\
\sml{val map : ('a -> 'b) -> 'a list -> 'a list}
\end{tabular}
\end{quotation}
\item[href] This macro generates a html hypertext link to a
page within the same logical document. For example, we can say
\begin{verbatim}
\href{url}{text}
\end{verbatim}
\item[mlrischref] This macro generates a html hypertext link to MLRISC
code. The general syntax is:
\begin{verbatim}
\mlrischref{path}{text}
\end{verbatim}
The \verb|path| parameter is a relative path in the MLRISC hierarchy.
\item[externhref]
This macro generates an external hypertext link to a document outside
of the same logical document. The general syntax is:
\begin{verbatim}
\externhref{url}{text}
\end{verbatim}
\item[newdef] This macro defines a new term. The general syntax is
\begin{verbatim}
\newdef{text}
\end{verbatim}
\end{description}
\subsection{Other Stuff}
In addition to the above, \MLTeX{} understands the following \LaTeX{}
environments and macros, and will translate them into HTML equivalents.
\begin{verbatim}
\begin{itemize} \end{itemize}
\begin{description} \end{description}
\begin{enumerate} \end{enumerate}
\verb
\begin{tabular} \end{tabular}
\begin{figure} \end{figure} \caption
\begin{wrapfigure} \end{wrapfigure}
\section \subsection \subsubsection \paragraph
\ref \label
\noindent \linebreak
\psfig
\end{verbatim}
\subsection{Bugs and Shortcomings}
There are too many to list. But the things to watch for are:
\begin{itemize}
\item A macro and all its arguments must appear in the same line.
\item The tool can get confused if too many macros appear on the same line.
\item Nesting of macros may not be handled correctly.
\item Math mode is not robust.
\end{itemize}
Please send bug fixes and comments to
\href{mailto:leunga@cs.nyu.edu}{Allen Leung}.
+76
View File
@@ -0,0 +1,76 @@
\documentclass{article}
\usepackage{mltex}
\usepackage{wrapfig}
\usepackage{float}
%\usepackage{floatfig}
\usepackage{fancyheadings}
%\usepackage{draftcopy}
%\usepackage{bookman}
\usepackage{utopia}
%\usepackage{times}
%\usepackage{ncntrsbk}
%\usepackage{palatino}
\setlength{\textwidth}{6.5in}
\setlength{\evensidemargin}{0in}
\setlength{\oddsidemargin}{0in}
\setlength{\textheight}{8in}
\setlength{\topmargin}{-0.5in}
\pagestyle{fancyplain}
%\addtolength{\headwidth}{\marginparsep}
%\addtolength{\headwidth}{\marginparwidth}
\newcommand{\edge}[1]{\rightarrow_{#1}}
\newcommand{\union}{\cup}
\newcommand{\Union}{\bigcup}
\newcommand{\overrides}{overrides}
\newcommand{\defas}{\stackrel{\rm as}{=}}
\renewcommand{\sectionmark}[1]{\markright{\thesection\ #1}}
\renewcommand{\subsectionmark}[1]{\markright{\thesubsection\ #1}}
\newcommand{\Term}[1]{\mbox{\it #1}}
\lhead[\fancyplain{}{\bfseries\thepage}]%
{\fancyplain{}{\bfseries\rightmark}}
\rhead[\fancyplain{}{\bfseries\leftmark}]%
{\fancyplain{}{\bfseries\thepage}}
\cfoot{}
\newenvironment{Figure}{\begin{figure}[htbp]}{\end{figure}}
\begin{document}
\title{\bf \LARGE \MLTeX}
\author{\begin{tabular}{c}
Allen Leung \\ \\
New York University \\
719 Broadway, Rm. 714 \\
New York, NY 10003. \\
{\tt leunga@cs.nyu.edu}
\end{tabular}
\and
\begin{tabular}{c}
Lal George \\ \\
Bell Laboratories \\
600--700 Mountain Ave. \\
Murray Hill, NJ 07974--0636. \\
{\tt george@research.bell-labs.com}
\end{tabular}
}
\date{\today}
\bibliographystyle{alpha}
\maketitle
\begin{abstract}
\newdef{\MLTeX} is a special \newdef{\LaTeX} package for writing
\MLRISC{} documentation. It is similar to the \newdef{latex2html}
tool except that \MLTeX{} has special environments for documenting
Standard ML code. In addition, there is an accompanying tool
called \newdef{mltex2html} for generating HTML pages.
\end{abstract}
\include{mltex}
\bibliography{mlrisc}
\end{document}
+283
View File
@@ -0,0 +1,283 @@
\section{MLTree Extensions} \label{sec:mltree-extension}
Pattern matching over the MLTREE intermediate representation
may not be sufficient to provide access to all the registers or
operations provided on a specific architecture. MLTREE extensions is a
method of extending the MLTREE intermediate language so that it is a
better match for the target architecture.
\subsection{Why Extensions}
Pattern matching over the MLTREE intermediate representation
may not be sufficient to provide access to all the registers or
operations provided on a specific architecture. MLTREE extensions is a
method of extending the MLTREE intermediate language so that it is a
better match for the target architecture.
For example there may be special registers to support the
increment-and-test operation on loop indices, or
support for complex mathematical functions such as
square root, or access to hardware specific registers such as the
current register window pointer on the SPARC architecture. It is not
usually possible to write expression trees that would directly
generate these instructions.
Some complex operations can be generated by performing a peephole
optimization over simpler instructions, however this is not always the
most convenient or simple thing to do.
\subsection{Cyclic Dependency}
The easiest way to provide extensions is to parameterize the MLTREE
interface with types that extend the various kinds of trees. Thus if
the type \sml{sext} represented statement extensions, we might define
MLTREE statement trees as :
\begin{SML}
datatype stm
= ...
| SEXT of sext * mlrisc list * stm list
and mlrisc = GPR of rexp | FPR of fexp | CCR of ccexp
\end{SML}
where the constructor \sml{SEXT} applies the extension to a list of
arguments. This approach is unsatisfactory in several ways, for
example, if one wanted to extend MLTREEs with for-loops, then the
following could be generated:
\begin{SML}
SEXT(FORLOOP, [GPR from, GPR to, GPR step], body)
\end{SML}
First, the loop arguments have to be wrapped up in \sml{GPR} and there
is little self documentation on the order of elements that are
arguments to the for-loop. It would be better to be able to write
something like:
\begin{SML}
SEXT(FORLOOP\{from=f, to=t, step=s, body=b\})
\end{SML}
Where \sml{f}, \sml{t}, and \sml{s} are \sml{rexp} trees representing
the loop index start, end, and step size; \sml{b} is a stm list
representing the body of the loop. Unfortunately, there is a cyclic
dependency as MLTREEs are defined in terms of \sml{sext}, and {\tt
sext} is defined in terms of MLTREEs. The usual way to deal with
cyclic dependencies is to use polymorphic type variables.
\subsection{MLTREE EXTENSION}
The statement extension type \sml{sext}, is now a type constructor
with arity four, i.e.
\sml{('s, 'r, 'f, 'c) sx} where \sml{sx} is used instead of {\tt
sext}, and \sml{'s}, \sml{'r}, \sml{'f}, and \sml{'c} represents
MLTREE statement expressions, register expressions, floating point
expressions, and condition code expressions. Thus the for-loop
extension could be declared using something like:
\begin{SML}
datatype ('s,'r,'f,'c) sx
= FORLOOP of \{from: 'r, to: 'r, step: 'r, body: 's\}
\end{SML}
and the MLTREE interface is defined as:
\begin{SML}
signature MLTREE = sig
type ('s, 'r, 'f, 'c) sx
datatype stm =
= ...
| SEXT of sext
withtype sext = (stm, rexp, fexp, cexp) sx
end
\end{SML}
where \sml{sext} is the user defined statement extension but the
type variables have been instantiated to the final form the the MLTREE
\sml{stm}, \sml{rexp}, \sml{fexp}, and \sml{cexp} components.
\subsection{Compilation}
There are dedicated modules that perform pattern matching over MLTREEs
and emit native instructions, and similar modules must be written for
extensions. However, the same kinds of choices used in regular MLTREE
patterns must be repeated for extensions. For example, one may define
an extension for the Intel IA32 of the form:
\begin{SML}
datatype ('s,'r,'f,'c) sx = PUSHL of 'r | POPL of 'r | ...
\end{SML}
that translate directly to the Intel push and pop instructions; the
operands in each case are either memory locations or registers, but
immediates are allowed in the case of \sml{PUSHL}. Considerable effort
has been invested into pattern matching the extensive set of
addressing modes for the Intel architecture, and
one would like to reuse this when compiling extensions. The pattern
matching functions are exposed by a set of functions exported from the
instruction selection module, and provided in the MLTREE
interface. They are:
\begin{SML}
struture I : INSTRUCTIONS
datatype reducer =
REDUCER of \{
reduceRexp : rexp -> reg,
reduceFexp : fexp -> reg,
reduceCCexp : ccexp -> reg,
reduceStm : stm * an list -> unit,
operand : rexp -> I.operand,
reduceOperand : I.operand -> reg,
addressOf : rexp -> I.addressing_mode,
emit : I.instr * an list -> unit,
instrStream : (I.instr, I.regmap, I.cellset) stream,
mltreeStream : (stm, I.regmap, mlrisc list) stream
\}
\end{SML}
where \sml{I} is the native instruction set.
\begin{description}
\item[\tt reduceRexp]: reduces an MLTREE \sml{rexp} to a register, and
similarly for \sml{reduceFexp} and \sml{reduceCCexp}.
\item[\tt reduceStm]: reduces an MLTREE \sml{stm} to a set of instructions
that implement the set of statements.
\item[\tt operand]: reduced an MLTREE \sml{rexp} into an instruction
operand --- usually an immediate or memory address.
\item[\tt operand]: moves a native operand into a register.
\item[\tt addressOf]: reduces an MLTREE \sml{rexp} into a memory address.
\item[\tt emit]: emits an instruction together with an annotation.
\item[\tt instrStream]: is the native instruction output stream, and
\item[\tt mltreeStream]: is the MLTREE output stream.
\end{description}
Each extension must provide a function \sml{compileSext} that compiles
a statement extension into native instructions. In the
\sml{MLTREE_EXTENSION_COMP} interface we have:
\begin{SML}
val compileSext: reducer -> {stm: MLTREE.sexp, an:MLTREE.an list} -> unit
\end{SML}
The use of extensions must follow a special structure.
\begin{enumerate}
\item A module defining the extension type using a type constructor
of arity four. Let us call this structure \sml{ExtTy} and must match
the \sml{MLTREE_EXTENSION} interface.
\item The extension module must be used to specialize MLTREEs.
\item A module that describes how to compile the extension must be
created, and must match the \sml{MLTREE_EXTENSION_COMP} interace.
This module will typically be functorized over the MLTREE interface.
Let us call the result of applying the functor, \sml{ExtComp}.
\item The extension compiler must be passed as a parameter to the
instruction selection module that will invoke it whenever an extension
is seen.
\end{enumerate}
\subsection{Multiple Extensions}
Multiple extensions are handled in a similar fashion, except that the
extension type used to specialize MLTREEs is a tagged union of the
individual extensions. The functor to compile the extension dispatches
to the compilation modules for the individual extensions.
\subsection{Example}
Suppose you are in the process of writing a compiler for a digital
signal processing(\newdef{DSP}) programming language using the MLRISC
framework. This wonderful language that you are developing allows the
programmer to specify high level looping and iteration, and
aggregation constructs that are common in DSP applications.
Furthermore, since saturated and fixed point arithmetic are common
constructs in DSP applications, the language and consequently the
compiler should directly support these operators. For simplicity, we
would like to have a unified intermediate representation that can be
used to directly represent high level constructs in our language, and
low level constructs that are already present in MLTree. Since,
MLTree does not directly support these constructs, it seems that it is
not possible to use MLRISC for such a compiler infrastructure without
substantial rewrite of the core components.
Let us suppose that for illustration that we would like to
implement high level looping and aggregation constructs such as
\begin{verbatim}
for i := lower bound ... upper bound
body
x := sum{i := lower bound ... upper bound} expression
\end{verbatim}
together with saturated arithmetic mentioned above.
Here is a first attempt:
\begin{SML}
structure DSPMLTreeExtension
struct
structure Basis = MLTreeBasis
datatype ('s,'r,'f,'c) sx =
FOR of Basis.var * 'r * 'r * 's
and ('s,'r,'f,'c) rx =
SUM of Basis.var * 'r * 'r * 'r
| SADD of 'r * 'r
| SSUB of 'r * 'r
| SMUL of 'r * 'r
| SDIV of 'r * 'r
type ('s,'r,'f,'c) fx = unit
type ('s,'r,'f,'c) ccx = unit
end
structure DSPMLTree : MLTreeF
(structure Extension = DSPMLTreeExtension
...
)
\end{SML}
In the above signature, we have defined two new datatypes \newtype{sx}
and \newtype{rx} that are used for representing the DSP statement
and integer expression extensions. Integer expression extensions
include the high level sum construct, and the low levels saturated
arithmetic operators. The recursive type definition is
necessary to ``inject'' these new constructors into the basic MLTree
definition.
The following is an example of how these new constructors that we have defined can be used. Suppose the source program in our DSP language is:
\begin{verbatim}
for i := a ... b
{ s := sadd(s, table[i]);
}
\end{verbatim}
\noindent where \verb|sadd| is the saturated add operator.
For simplicity, let us also assume that all operations and addresses
are in 32-bits.
Then the translation of the above into our extended DSP-MLTree could be:
\begin{SML}
EXT(FOR(\(i\), REG(32, \(a\)), REG(32, \(b\)),
MV(32, \(s\), REXT(32, SADD(REG(32, \(s\)),
LOAD(32,
ADD(32, REG(32, \(table\)),
SLL(32, REG(32, \(i\)), LI 2)),
\(region\)))))
))
\end{SML}
One potential short coming of our DSP extension to MLTree is that
the extension does not allow any further extensions. This restriction
may be entirely satisfactory if DSP-MLTree is only used in your compiler
applications and no where else. However, if DSP-MLTree is intended
to be an extension library for MLRISC, then we must build in the flexibility
for extension. This can be done in the same way as in the base MLTree
definition, like this:
\begin{SML}
functor ExtensibleDSPMLTreeExtension
(Extension : \mlrischref{mltree/mltree-extension.sig}{MLTREE_EXTENSION}) =
struct
structure Basis = MLTreeBasis
structure Extension = Extension
datatype ('s,'r,'f,'c) sx =
FOR of Basis.var * 'r * 'r * 's
| EXT of ('s,'r,'f,'c) Extension.sx
and ('s,'r,'f,'c) rx =
SUM of Basis.var * 'r * 'r * 'r
| SADD of 'r * 'r
| SSUB of 'r * 'r
| SMUL of 'r * 'r
| SDIV of 'r * 'r
| REXT of ('s,'r,'f,'c) Extension.rx
withtype
('s,'r,'f,'c) fx = ('s,'r,'f,'c) Extension.fx
and ('s,'r,'f,'c) ccx = ('s,'r,'f,'c) Extension.ccx
end
\end{SML}
As in MLTREE, we provide two new extension
constructors \verb|EXT| and \verb|REXT| in
the definition of \sml{DSP_MLTREE}, which can
be used to further enhance the extended MLTREE language.
+260
View File
@@ -0,0 +1,260 @@
\section{MLTree Utilities}
The \MLRISC{} system contains numerous utilities for working with
MLTree datatypes. Some of the following utilizes are also useful for clients
use:
\begin{description}
\item[MLTreeUtils] implements basic hashing, equality and pretty
printing functions,
\item[MLTreeFold] implements a fold function over the MLTree datatypes,
\item[MLTreeRewrite] implements a generic rewriting engine,
\item[MLTreeSimplify] implements a simplifier that performs algebraic
simplification and constant folding.
\end{description}
\subsubsection{Hashing, Equality, Pretty Printing}
The functor \mlrischref{mltree/mltree-utils.sml}{MLTreeUtils} provides
the basic utilities for hashing an MLTree term, comparing two
MLTree terms for equality and pretty printing. The hashing and comparision
functions are useful for building hash tables using MLTree datatype as keys.
The signature of the functor is:
\begin{SML}
signature \mlrischref{mltree/mltree-utils.sig}{MLTREE_UTILS} =
sig
structure T : MLTREE
(*
* Hashing
*)
val hashStm : T.stm -> word
val hashRexp : T.rexp -> word
val hashFexp : T.fexp -> word
val hashCCexp : T.ccexp -> word
(*
* Equality
*)
val eqStm : T.stm * T.stm -> bool
val eqRexp : T.rexp * T.rexp -> bool
val eqFexp : T.fexp * T.fexp -> bool
val eqCCexp : T.ccexp * T.ccexp -> bool
val eqMlriscs : T.mlrisc list * T.mlrisc list -> bool
(*
* Pretty printing
*)
val show : (string list * string list) -> T.printer
val stmToString : T.stm -> string
val rexpToString : T.rexp -> string
val fexpToString : T.fexp -> string
val ccexpToString : T.ccexp -> string
end
functor \mlrischref{mltree/mltree-utils.sml}{MLTreeUtils}
(structure T : MLTREE
(* Hashing extensions *)
val hashSext : T.hasher -> T.sext -> word
val hashRext : T.hasher -> T.rext -> word
val hashFext : T.hasher -> T.fext -> word
val hashCCext : T.hasher -> T.ccext -> word
(* Equality extensions *)
val eqSext : T.equality -> T.sext * T.sext -> bool
val eqRext : T.equality -> T.rext * T.rext -> bool
val eqFext : T.equality -> T.fext * T.fext -> bool
val eqCCext : T.equality -> T.ccext * T.ccext -> bool
(* Pretty printing extensions *)
val showSext : T.printer -> T.sext -> string
val showRext : T.printer -> T.ty * T.rext -> string
val showFext : T.printer -> T.fty * T.fext -> string
val showCCext : T.printer -> T.ty * T.ccext -> string
) : MLTREE_UTILS =
\end{SML}
The types \sml{hasher}, \sml{equality},
and \sml{printer} represent functions for hashing,
equality and pretty printing. These are defined as:
\begin{SML}
type hasher =
\{stm : T.stm -> word,
rexp : T.rexp -> word,
fexp : T.fexp -> word,
ccexp : T.ccexp -> word
\}
type equality =
\{ stm : T.stm * T.stm -> bool,
rexp : T.rexp * T.rexp -> bool,
fexp : T.fexp * T.fexp -> bool,
ccexp : T.ccexp * T.ccexp -> bool
\}
type printer =
\{ stm : T.stm -> string,
rexp : T.rexp -> string,
fexp : T.fexp -> string,
ccexp : T.ccexp -> string,
dstReg : T.ty * T.var -> string,
srcReg : T.ty * T.var -> string
\}
\end{SML}
For example, to instantiate a \sml{Utils} module for our \sml{DSPMLTree},
we can write:
\begin{SML}
structure U = MLTreeUtils
(structure T = DSPMLTree
fun hashSext \{stm, rexp, fexp, ccexp\} (FOR(i, a, b, s)) =
Word.fromIntX i + rexp a + rexp b + stm s
and hashRext \{stm, rexp, fexp, ccexp\} e =
(case e of
SUM(i,a,b,c) => Word.fromIntX i + rexp a + rexp b + rexp c
| SADD(a,b) => rexp a + rexp b
| SSUB(a,b) => 0w12 + rexp a + rexp b
| SMUL(a,b) => 0w123 + rexp a + rexp b
| SDIV(a,b) => 0w1245 + rexp a + rexp b
)
fun hashFext _ _ = 0w0
fun hashCCext _ _ = 0w0
fun eqSext \{stm, rexp, fexp, ccexp\}
(FOR(i, a, b, s), FOR(i', a', b', s')) =
i=i' andalso rexp(a,a') andalso rexp(b,b') andalso stm(s,s')
fun eqRext \{stm, rexp, fexp, ccexp\} (e,e') =
(case (e,e') of
(SUM(i,a,b,c),SUM(i',a',b',c')) =>
i=i' andalso rexp(a,a') andalso rexp(b,b') andalso stm(c,c')
| (SADD(a,b),SADD(a',b')) => rexp(a,a') andalso rexp(b,b')
| (SSUB(a,b),SSUB(a',b')) => rexp(a,a') andalso rexp(b,b')
| (SMUL(a,b),SMUL(a',b')) => rexp(a,a') andalso rexp(b,b')
| (SDIV(a,b),SDIV(a',b')) => rexp(a,a') andalso rexp(b,b')
| _ => false
)
fun eqFext _ _ = true
fun eqCCext _ _ = true
fun showSext \{stm, rexp, fexp, ccexp, dstReg, srcReg\}
(FOR(i, a, b, s)) =
"for("^dstReg i^":="^rexp a^".."^rexp b^")"^stm s
fun ty t = "."^Int.toString t
fun showRext \{stm, rexp, fexp, ccexp, dstReg, srcReg\} e =
(case (t,e) of
SUM(i,a,b,c) =>
"sum"^ty t^"("^dstReg i^":="^rexp a^".."^rexp b^")"^rexp c
| SADD(a,b) => "sadd"^ty t^"("rexp a^","^rexp b^")"
| SSUB(a,b) => "ssub"^ty t^"("rexp a^","^rexp b^")"
| SMUL(a,b) => "smul"^ty t^"("rexp a^","^rexp b^")"
| SDIV(a,b) => "sdiv"^ty t^"("rexp a^","^rexp b^")"
)
fun showFext _ _ = ""
fun showCCext _ _ = ""
)
\end{SML}
\subsubsection{MLTree Fold}
The functor \mlrischref{mltree/mltree-fold.sml}{MLTreeFold}
provides the basic functionality for implementing various forms of
aggregation function over the MLTree datatypes. Its signature is
\begin{SML}
signature \mlrischref{mltree/mltree-fold.sig}{MLTREE_FOLD} =
sig
structure T : MLTREE
val fold : 'b folder -> 'b folder
end
functor \mlrischref{mltree/mltree-fold.sml}{MLTreeFold}
(structure T : MLTREE
(* Extension mechnism *)
val sext : 'b T.folder -> T.sext * 'b -> 'b
val rext : 'b T.folder -> T.ty * T.rext * 'b -> 'b
val fext : 'b T.folder -> T.fty * T.fext * 'b -> 'b
val ccext : 'b T.folder -> T.ty * T.ccext * 'b -> 'b
) : MLTREE_FOLD =
\end{SML}
The type \newtype{folder} is defined as:
\begin{SML}
type 'b folder =
\{ stm : T.stm * 'b -> 'b,
rexp : T.rexp * 'b -> 'b,
fexp : T.fexp * 'b -> 'b,
ccexp : T.ccexp * 'b -> 'b
\}
\end{SML}
\subsubsection{MLTree Rewriting}
The functor \mlrischref{mltree/mltree-rewrite.sml}{MLTreeRewrite}
implements a generic term rewriting engine which is useful for performing
various transformations on MLTree terms. Its signature is
\begin{SML}
signature \mlrischref{mltree/mltree-rewrite.sig}{MLTREE_REWRITE} =
sig
structure T : MLTREE
val rewrite :
(* User supplied transformations *)
\{ rexp : (T.rexp -> T.rexp) -> (T.rexp -> T.rexp),
fexp : (T.fexp -> T.fexp) -> (T.fexp -> T.fexp),
ccexp : (T.ccexp -> T.ccexp) -> (T.ccexp -> T.ccexp),
stm : (T.stm -> T.stm) -> (T.stm -> T.stm)
\} -> T.rewriters
end
functor \mlrischref{mltre/mltree-rewrite.sml}{MLTreeRewrite}
(structure T : MLTREE
(* Extension *)
val sext : T.rewriter -> T.sext -> T.sext
val rext : T.rewriter -> T.rext -> T.rext
val fext : T.rewriter -> T.fext -> T.fext
val ccext : T.rewriter -> T.ccext -> T.ccext
) : MLTREE_REWRITE =
\end{SML}
The type \newtype{rewriter} is defined in signature
\mlrischref{mltree/mltree.sig}{MLTREE} as:
\begin{SML}
type rewriter =
\{ stm : T.stm -> T.stm,
rexp : T.rexp -> T.rexp,
fexp : T.fexp -> T.fexp,
ccexp : T.ccexp -> T.ccexp
\}
\end{SML}
\subsubsection{MLTree Simplifier}
The functor \mlrischref{mltree/mltree-simplify.sml}{MLTreeSimplify}
implements algebraic simplification and constant folding for MLTree.
Its signature is:
\begin{SML}
signature \mlrischref{mltree/mltree-simplify.sig}{MLTREE_SIMPLIFIER} =
sig
structure T : MLTREE
val simplify :
{ addressWidth : int } -> T.simplifier
end
functor \mlrischref{mltree/mltree-simplify.sml}{MLTreeSimplifier}
(structure T : MLTREE
(* Extension *)
val sext : T.rewriter -> T.sext -> T.sext
val rext : T.rewriter -> T.rext -> T.rext
val fext : T.rewriter -> T.fext -> T.fext
val ccext : T.rewriter -> T.ccext -> T.ccext
) : MLTREE_SIMPLIFIER =
\end{SML}
Where type \newdef{simplifier} is defined in signature
\mlrischref{mltree/mltree.sig}{MLTREE} as:
\begin{SML}
type simplifier =
\{ stm : T.stm -> T.stm,
rexp : T.rexp -> T.rexp,
fexp : T.fexp -> T.fexp,
ccexp : T.ccexp -> T.ccexp
\}
\end{SML}
+659
View File
@@ -0,0 +1,659 @@
\section{The MLTREE Language}
\newdef{MLTree} is the
register transfer language used in the MLRISC system.
It serves two important purposes:
\image{MLTree}{pictures/png/mlrisc-ir.png}{align=right}
\begin{enumerate}
\item As an intermediate representation for a compiler front-end
to talk to the MLRISC system,
\item As specifications for instruction semantics
\end{enumerate}
The latter is needed for optimizations which require precise knowledge of such;
for example, algebraic simplification and constant folding.
MLTree is a low-level \newdef{typed} language:
all operations are typed by its width or precision.
Operations on floating point, integer, and condition code
are also segregated, to prevent accidental misuse.
MLTree is also \emph{tree-oriented} so that it is possible to write efficient
MLTree transformation routines that uses SML pattern matching.
Here are a few examples of MLTree statements.
\begin{SML}
MV(32,t,
ADDT(32,
MULT(32,REG(32,b),REG(32,b)),
MULT(32,
MULT(32,LI(4),REG(32,a)),REG(32,c))))
\end{SML}
computes \sml{t := b*b + 4*a*c}, all in 32-bit precision and overflow
trap enabled; while
\begin{SML}
MV(32,t,
ADD(32,
CVTI2I(32,SIGN_EXTEND,8,
LOAD(8,
ADD(32,REG(32,a),REG(32,i))))))
\end{SML}
loads the byte in address \sml{a+i} and sign extend it to a 32-bit
value.
The statement
\begin{SML}
IF([],CMP(64,GE,REG(64,a),LI 0),
MV(64, t, REG(64, a)),
MV(64, t, NEG(64, REG(64, a)))
)
\end{SML}
in more traditional form means:
\begin{verbatim}
if a >= 0 then
t := a
else
t := -a
\end{verbatim}
This example can be also expressed in a few different ways:
\begin{enumerate}
\item With the conditional move construct described in
Section~\ref{sec:cond-move}:
\begin{SML}
MV(64, t,
COND(CMP(64, GE, REG(64, a)),
REG(64, a),
NEG(64, REG(64, a))))
\end{SML}
\item With explicit branching using the conditional branch
construct \verb|BCC|:
\begin{SML}
MV(64, t, REG(64, a));
BCC([], CMP(64, GE, REG(64, a)), L1);
MV(64, t, NEG(64, REG(64, a)));
DEFINE L1;
\end{SML}
\end{enumerate}
\subsection{The Definitions}
MLTree is defined in the signature \mlrischref{mltree/mltree.sig}{\sml{MLTREE}}
and the functor \mlrischref{mltree/mltree.sml}{\sml{MLTreeF}}
The functor \sml{MLTreeF} is parameterized in terms of
the label expression type, the client supplied region datatype,
the instruction stream type, and the client defined MLTree extensions.
\begin{SML}
functor MLTreeF
(structure LabelExp : \href{labelexp.html}{LABELEXP}
structure Region : \href{regions.html}{REGION}
structure Stream : \href{streams.html}{INSTRUCTION_STREAM}
structure Extension : \mlrischref{mltree/mltree-extension.sig}{MLTREE_EXTENSION}
) : MLTREE
\end{SML}
\subsubsection{Basic Types}
The basic types in MLTree are statements (\newtype{stm})
integer expressions (\newtype{rexp}),
floating point expression (\newtype{fexp}),
and conditional expressions (\newtype{ccexp}).
Statements are evaluated for their effects,
while expressions are evaluated for their value. (Some expressions
could also have trapping effects. The semantics of traps are unspecified.)
These types are parameterized by an extension
type, which we can use to extend the set of MLTree
operators. How this is used is described in Section~\ref{sec:mltree-extension}.
References to registers are represented internally as integers, and are denoted
as the type \sml{reg}. In addition, we use the types \sml{src} and \sml{dst}
as abbreviations for source and destination registers.
\begin{SML}
type reg = int
type src = reg
type dst = reg
\end{SML}
All operators on MLTree are \emph{typed}
by the number of bits that
they work on. For example, 32-bit addition between \sml{a} and \sml{b}
is written as \sml{ADD(32,a,b)}, while 64-bit addition between the same
is written as \sml{ADD(64,a,b)}. Floating point operations are
denoted in the same manner. For example, IEEE single-precision floating
point add is written as \sml{FADD(32,a,b)}, while the same in
double-precision is written as \sml{FADD(64,a,b)}
Note that these types are low level. Higher level distinctions such
as signed and unsigned integer value, are not distinguished by the type.
Instead, operators are usually partitioned into signed and unsigned versions,
and it is legal (and often useful!) to mix signed and unsigned operators in
an expression.
Currently, we don't provide a direct way to specify non-IEEE floating point
together with
IEEE floating point arithmetic. If this distinction is needed then
it can be encoded using the extension mechanism described
in Section~\ref{sec:mltree-extension}.
We use the types \sml{ty} and \sml{fty} to stand for the number of
bits in integer and floating point operations.
\begin{SML}
type ty = int
type fty = int
\end{SML}
\subsubsection{The Basis}
The signature \mlrischref{mltree/mltree-basis.sig}{MLTREE\_BASIS}
defines the basic helper types used in the MLTREE signature.
\begin{SML}
signature MLTREE_BASIS =
sig
datatype cond = LT | LTU | LE | LEU | EQ | NE | GE | GEU | GT | GTU
datatype fcond =
? | !<=> | == | ?= | !<> | !?>= | < | ?< | !>= | !?> |
<= | ?<= | !> | !?<= | > | ?> | !<= | !?< | >= | ?>= |
!< | !?= | <> | != | !? | <=> | ?<>
datatype ext = SIGN_EXTEND | ZERO_EXTEND
datatype rounding_mode = TO_NEAREST | TO_NEGINF | TO_POSINF | TO_ZERO
type ty = int
type fty = int
end
\end{SML}
The most important of these are the
types \newtype{cond} and \newtype{fcond}, which represent the set of integer
and floating point comparisions. These types can be combined with
the comparison constructors \verb|CMP| and \verb|FCMP| to form
integer and floating point comparisions.
\begin{Table}{|c|c|}{align=left} \hline
Operator & Comparison \\ \hline
\sml{LT} & Signed less than \\
\sml{LTU} & Unsigned less than \\
\sml{LE} & Signed less than or equal \\
\sml{LEU} & Unsigned less than or equal \\
\sml{EQ} & Equal \\
\sml{NE} & Not equal \\
\sml{GE} & Signed greater than or equal \\
\sml{GEU} & Unsigned greater than or equal \\
\sml{GT} & Signed greater than \\
\sml{GTU} & Unsigned greater than \\
\hline
\end{Table}
Floating point comparisons can be ``decoded'' as follows.
In IEEE floating point, there are four different basic comparisons
tests that we can performed given two numbers $a$ and $y$:
\begin{description}
\item[$a < b$] Is $a$ less than $b$?
\item[$a = b$] Is $a$ equal to $b$?
\item[$a > b$] Is $a$ greater than to $b$?
\item[$a ? b$] Are $a$ and $b$ unordered (incomparable)?
\end{description}
Comparisons can be joined together. For example,
given two double-precision floating point expressions $a$ and $b$,
the expression \verb|FCMP(64,<=>,a,b)|
asks whether $a$ is less than, equal to or greater than $b$, i.e.~whether
$a$ and $b$ are comparable.
The special symbol \verb|!| negates
the meaning the of comparison. For example, \verb|FCMP(64,!>=,a,b)|
means testing whether $a$ is less than or incomparable with $b$.
\subsection{Integer Expressions}
A reference to the $i$th
integer register with an $n$-bit value is written
as \sml{REG(}$n$,$i$\sml{)}. The operators \sml{LI}, \sml{LI32},
and \sml{LABEL}, \sml{CONST} are used to represent constant expressions
of various forms. The sizes of these constants are inferred from context.
\begin{SML}
REG : ty * reg -> rexp
LI : int -> rexp
LI32 : Word32.word -> rexp
LABEL : LabelExp.labexp -> rexp
CONST : Constant.const -> rexp
\end{SML}
The following figure lists all the basic integer operators and their
intuitive meanings. All operators except \sml{NOTB, NEG, NEGT} are binary
and have the type
\begin{SML}
ty * rexp * rexp -> rexp
\end{SML}
The operators \sml{NOTB, NEG, NEGT} have the type
\begin{SML}
ty * rexp -> rexp
\end{SML}
\begin{tabular}{|l|l|} \hline
\sml{ADD} & Twos complement addition \\
\sml{NEG} & negation \\
\sml{SUB} & Twos complement subtraction \\
\sml{MULS} & Signed multiplication \\
\sml{DIVS} & Signed division, round to zero (nontrapping) \\
\sml{QUOTS} & Signed division, round to negative infinity (nontrapping) \\
\sml{REMS} & Signed remainder (???) \\
\sml{MULU} & Unsigned multiplication \\
\sml{DIVU} & Unsigned division \\
\sml{REMU} & Unsigned remainder \\
\sml{NEGT} & signed negation, trap on overflow \\
\sml{ADDT} & Signed addition, trap on overflow \\
\sml{SUBT} & Signed subtraction, trap on overflow \\
\sml{MULT} & Signed multiplication, trap on overflow \\
\sml{DIVT} & Signed division, round to zero,
trap on overflow or division by zero \\
\sml{QUOTT} & Signed division, round to negative infinity, trap on overflow or division by zero \\
\sml{REMT} & Signed remainder, trap on division by zero \\
\sml{ANDB} & bitwise and \\
\sml{ORB} & bitwise or \\
\sml{XORB} & bitwise exclusive or \\
\sml{NOTB} & ones complement \\
\sml{SRA} & arithmetic right shift \\
\sml{SRL} & logical right shift \\
\sml{SLL} & logical left shift \\
\hline\end{tabular}
\subsubsection{Sign and Zero Extension}
Sign extension and zero extension are written using the operator
\sml{CVTI2I}. \sml{CVTI2I(}$m$,\sml{SIGN_EXTEND},$n$,$e$\sml{)}
sign extends the $n$-bit value $e$ to an $m$-bit value, i.e. the
$n-1$th bit is of $e$ is treated as the sign bit. Similarly,
\sml{CVTI2I(}$m$,\sml{ZERO_EXTEND},$n$,$e$\sml{)}
zero extends an $n$-bit value to an $m$-bit
value. If $m \le n$, then
\sml{CVTI2I(}$m$,\sml{SIGN_EXTEND},$n$,$e$\sml{)} =
\sml{CVTI2I}($m$,\sml{ZERO_EXTEND},$n$,$e$\sml{)}.
\begin{SML}
datatype ext = SIGN_EXTEND | ZERO_EXTEND
CVTI2I : ty * ext * ty * rexp -> rexp
\end{SML}
\subsubsection{Conditional Move} \label{sec:cond-move}
Most new superscalar architectures incorporate conditional move
instructions in their ISAs.
Modern VLIW architectures also directly support full predication.
Since branching (especially with data dependent branches) can
introduce extra latencies in highly pipelined architectures,
condtional moves should be used in place of short branch sequences.
MLTree provide a conditional move instruction \sml{COND},
to make it possible to directly express conditional moves without using
branches.
\begin{SML}
COND : ty * ccexp * rexp * rexp -> rexp
\end{SML}
Semantically, \sml{COND(}\emph{ty},\emph{cc},$a$,$b$\sml{)} means to evaluate
\emph{cc}, and if \emph{cc} evaluates to true then the value of the entire expression is
$a$; otherwise the value is $b$. Note that $a$ and $b$ are allowed to be
\emph{eagerly}
evaluated. In fact, we are allowed to evaluate to \emph{both}
branches, one branch, or neither~\footnote{When possible.}.
Various idioms of the \sml{COND} form are useful for expressing common
constructs in many programming languages. For example, MLTree does not
provide a primitive construct for converting an integer value \sml{x} to a
boolean value (0 or 1). But using \sml{COND}, this is expressible as
\sml{COND(32,CMP(32,NE,x,LI 0),LI 1,LI 0)}. SML/NJ represents
the boolean values true and false as machine integers 3 and 1 respectively.
To convert a boolean condition $e$ into an ML boolean value, we can use
\begin{SML}
COND(32,e,LI 3,LI 1)
\end{SML}
Common C idioms can be easily mapped into the \sml{COND} form. For example,
\begin{itemize}
\item \verb|if (e1) x = y| translates into
\sml{MV(32,x,COND(32,e1,REG(32,y),REG(32,x)))}
\item
\begin{verbatim}
x = e1;
if (e2) x = y
\end{verbatim}
translates into
\sml{MV(32,x,COND(32,e2,REG(32,y),e1))}
\item \verb|x = e1 == e2| translates into
\sml{MV(32,x,COND(32,CMP(32,EQ,e1,e2),LI 1,LI 0)}
\item \verb|x = ! e| translates into
\sml{MV(32,x,COND(32,CMP(32,NE,e,LI 0),LI 1,LI 0)}
\item \verb|x = e ? y : z| translates into
\sml{MV(32,x,COND(32,e,REG(32,y),REG(32,z)))}, and
\item \verb|x = y < z ? y : z| translates into
\begin{alltt}
MV(32,x,
COND(32,
CMP(32,LT,REG(32,y),REG(32,z)),
REG(32,y),REG(32,z)))
\end{alltt}
\end{itemize}
In general, the \sml{COND} form should be used in place of MLTree's branching
constructs whenever possible, since the former is usually highly
optimized in various MLRISC backends.
\subsubsection{Integer Loads}
Integer loads are written using the constructor \verb|LOAD|.
\begin{SML}
LOAD : ty * rexp * Region.region -> rexp
\end{SML}
The client is required to specify a \href{regions.html}{region} that
serves as aliasing information for the load.
\subsubsection{Miscellaneous Integer Operators}
An expression of the \sml{LET}($s$,$e$) evaluates the statement $s$ for
its effect, and then return the value of expression $e$.
\begin{SML}
LET : stm * rexp -> rexp
\end{SML}
Since the order of evaluation is MLTree operators are
\emph{unspecified}
the use of this operator should be severely restricted to only
\emph{side-effect}-free forms.
\subsection{Floating Point Expressions}
Floating registers are referenced using the term \sml{FREG}. The
$i$th floating point register with type $n$ is written
as \sml{FREG(}$n$,$i$\sml{)}.
\begin{SML}
FREG : fty * src -> fexp
\end{SML}
Built-in floating point operations include addition (\sml{FADD}),
subtraction (\sml{FSUB}), multiplication (\sml{FMUL}), division
(\sml{FDIV}), absolute value (\sml{FABS}), negation (\sml{FNEG})
and square root (\sml{FSQRT}).
\begin{SML}
FADD : fty * fexp * fexp -> fexp
FSUB : fty * fexp * fexp -> fexp
FMUL : fty * fexp * fexp -> fexp
FDIV : fty * fexp * fexp -> fexp
FABS : fty * fexp -> fexp
FNEG : fty * fexp -> fexp
FSQRT : fty * fexp -> fexp
\end{SML}
A special operator is provided for manipulating signs.
To combine the sign of $a$ with the magnitude of $b$, we can
write \sml{FCOPYSIGN(}$a$,$b$\sml{)}\footnote{What should
happen if $a$ or $b$ is nan?}.
\begin{SML}
FCOPYSIGN : fty * fexp * fexp -> fexp
\end{SML}
To convert an $n$-bit signed integer $e$ into an $m$-bit floating point value,
we can write \sml{CVTI2F(}$m$,$n$,$e$\sml{)}\footnote{What happen to unsigned integers?}.
\begin{SML}
CVTI2F : fty * ty * rexp -> fexp
\end{SML}
Similarly, to convert an $n$-bit floating point value $e$ to an $m$-bit
floating point value, we can write \sml{CVTF2F(}$m$,$n$,$e$\sml{)}\footnote{
What is the rounding semantics?}.
\begin{SML}
CVTF2F : fty * fty * -> fexp
\end{SML}
\begin{SML}
datatype rounding_mode = TO_NEAREST | TO_NEGINF | TO_POSINF | TO_ZERO
CVTF2I : ty * rounding_mode * fty * fexp -> rexp
\end{SML}
\begin{SML}
FLOAD : fty * rexp * Region.region -> fexp
\end{SML}
\subsection{Condition Expressions}
Unlike languages like C, MLTree makes the distinction between condition
expressions and integer expressions. This distinction is necessary for
two purposes:
\begin{itemize}
\item It clarifies the proper meaning intended in a program, and
\item It makes to possible for a MLRISC backend to map condition
expressions efficiently onto various machine architectures with different
condition code models. For example, architectures like the Intel x86,
Sparc V8, and PowerPC contains dedicated condition code registers, which
are read from and written to by branching and comparison instructions.
On the other hand, architectures such as the Texas Instrument C6, PA RISC,
Sparc V9, and Alpha does not include dedicated condition code registers.
Conditional code registers in these architectures
can be simulated by integer registers.
\end{itemize}
A conditional code register bit can be referenced using the constructors
\sml{CC} and \sml{FCC}. Note that the \emph{condition} must be specified
together with the condition code register.
\begin{SML}
CC : Basis.cond * src -> ccexp
FCC : Basis.fcond * src -> ccexp
\end{SML}
For example, to test the \verb|Z| bit of the \verb|%psr| register on the
Sparc architecture, we can used \sml{CC(EQ,SparcCells.psr)}.
The comparison operators \sml{CMP} and \sml{FCMP} performs integer and
floating point tests. Both of these are \emph{typed} by the precision
in which the test must be performed under.
\begin{SML}
CMP : ty * Basis.cond * rexp * rexp -> ccexp
FCMP : fty * Basis.fcond * fexp * fexp -> ccexp
\end{SML}
Condition code expressions may be combined with the following
logical connectives, which have the obvious meanings.
\begin{SML}
TRUE : ccexp
FALSE : ccexp
NOT : ccexp -> ccexp
AND : ccexp * ccexp -> ccexp
OR : ccexp * ccexp -> ccexp
XOR : ccexp * ccexp -> ccexp
\end{SML}
\subsection{Statements}
Statement forms in MLTree includes assignments, parallel copies,
jumps and condition branches, calls and returns, stores, sequencing,
and annotation.
\subsubsection{Assignments}
Assignments are segregated among the integer, floating point and
conditional code types. In addition, all assignments are \emph{typed}
by the precision of destination register.
\begin{SML}
MV : ty * dst * rexp -> stm
FMV : fty * dst * fexp -> stm
CCMV : dst * ccexp -> stm
\end{SML}
\subsubsection{Parallel Copies}
Special forms are provided for parallel copies for integer and
floating point registers. It is important to emphasize that
the semantics is that all assignments are performed in parallel.
\begin{SML}
COPY : ty * dst list * src list -> stm
FCOPY : fty * dst list * src list -> stm
\end{SML}
\subsubsection{Jumps and Conditional Branches}
Jumps and conditional branches in MLTree take two additional set of
annotations. The first represents the \newdef{control flow} and is denoted
by the type \sml{controlflow}. The second represent
\newdef{control-dependence} and \newdef{anti-control-dependence}
and is denoted by the type \sml{ctrl}.
\begin{SML}
type controlflow = Label.label list
type ctrl = reg list
\end{SML}
Control flow annotation is simply a list of labels, which represents
the set of possible targets of the associated jump. Control dependence
annotations attached to a branch or jump instruction represents the
new definition of \newdef{pseudo control dependence predicates}. These
predicates have no associated dynamic semantics; rather they are used
to constraint the set of potential code motion in an optimizer
(more on this later).
The primitive jumps and conditional branch forms are represented
by the constructors \sml{JMP}, \sml{BCC}.
\begin{SML}
JMP : ctrl * rexp * controlflow -> stm
BCC : ctrl * ccexp * Label.label -> stm
\end{SML}
In addition to \sml{JMP} and \sml{BCC},
there is a \emph{structured} if/then/else statement.
\begin{SML}
IF : ctrl * ccexp * stm * stm -> stm
\end{SML}
Semantically, \sml{IF}($c,x,y,z$) is identical to
\begin{SML}
BCC(\(c\), \(x\), L1)
\(z\)
JMP([], L2)
DEFINE L1
\(y\)
DEFINE L2
\end{SML}
where \verb|L1| and \verb|L2| are new labels, as expected.
Here's an example of how control dependence predicates are used.
Consider the following MLTree statement:
\begin{SML}
IF([p], CMP(32, NE, REG(32, a), LI 0),
MV(32, b, PRED(LOAD(32, m, ...)), p),
MV(32, b, LOAD(32, n, ...)))
\end{SML}
In the first alternative of the \verb|IF|, the \verb|LOAD|
expression is constrainted by the control dependence
predicate \verb|p| defined in the \verb|IF|,
using the predicate constructor \verb|PRED|. These states that
the load is \emph{control dependent} on the test of the branch,
and thus it may not be legally hoisted above the branch without
potentially violating the semantics of the program.
For example,
semantics violation may happen if the value of \verb|m| and \verb|a|
is corrolated, and whenever \verb|a| = 0, the address in \verb|m| is
not a legal address.
Note that on architectures with speculative loads,
the control dependence information can be used to
guide the transformation of control dependent loads into speculative loads.
Now in constrast, the \verb|LOAD| in the second alternative is not
control dependent on the control dependent predicate \verb|p|, and
thus it is safe and legal to hoist the load above the test, as in
\begin{SML}
MV(32, b, LOAD(32, n, ...));
IF([p], CMP(32, NE, REG(32, a), LI 0),
MV(32, b, PRED(LOAD(32, m, ...)), p),
SEQ []
)
\end{SML}
Of course, such transformation is only performed if the optimizer
phases think that it can benefit performance. Thus the control dependence
information does \emph{not} directly specify any transformations, but it
is rather used to indicate when aggressive code motions are legal and safe.
\subsubsection{Calls and Returns}
Calls and returns in MLTree are specified using the constructors
\verb|CALL| and \verb|RET|, which have the following types.
\begin{SML}
CALL : rexp * controlflow * mlrisc * mlrisc *
ctrl * ctrl * Region.region -> stm
RET : ctrl * controlflow -> stm
\end{SML}
The \verb|CALL| form is particularly complex, and require some explanation.
Basically the seven parameters are, in order:
\begin{description}
\item[address] of the called routine.
\item[control flow] annotation for this call. This information
specifies the potential targets of this call instruction. Currently
this information is ignored but will be useful for interprocedural
optimizations in the future.
\item[definition and use] These lists specify the list of
potential definition and uses during the execution of the call.
Definitions and uses are represented as the type \newtype{mlrisc} list.
The contructors for this type is:
\begin{SML}
CCR : ccexp -> mlrisc
GPR : rexp -> mlrisc
FPR : fexp -> mlrisc
\end{SML}
\item[definition of control and anti-control dependence]
These two lists specifies definitions of control and anti-control dependence.
\item[region] annotation for the call, which summarizes
the set of potential memory references during execution of the call.
\end{description}
The matching return statement constructor \verb|RET| has two
arguments. These are:
\begin{description}
\item[anti-control dependence] This parameter represents
the set of anti-control dependence predicates defined by the return
statement.
\item[control flow] This parameter specifies the set of matching
procedure entry points of this return. For example, suppose we have
a procedure with entry points \verb|f| and \verb|f'|.
Then the MLTree statements
\begin{verbatim}
f: ...
JMP L1
f': ...
L1: ...
RET ([], [f, f'])
\end{verbatim}
\noindent can be used to specify that the return is either from
the entries \verb|f| or \verb|f'|.
\end{description}
\subsubsection{Stores}
Stores to integer and floating points are specified using the
constructors \verb|STORE| and \verb|FSTORE|.
\begin{SML}
STORE : ty * rexp * rexp * Region.region -> stm
FSTORE : fty * rexp * fexp * Region.region -> stm
\end{SML}
The general form is
\begin{SML}
STORE(\(width\), \(address\), \(data\), \(region\))
\end{SML}
Stores for condition codes are not provided.
\subsubsection{Miscelleneous Statements}
Other useful statement forms of MLTree are for sequencing (\verb|SEQ|),
defining a local label (\verb|DEFINE|).
\begin{SML}
SEQ : stm list -> stm
DEFINE : Label.label -> stm
\end{SML}
The constructor \sml{DEFINE L} has the same meaning as
executing the method \sml{defineLabel L} in the
\href{stream.html}{stream interface}.
\subsection{Annotations}
\href{annotations.html}{Annotations} are used as the generic mechanism for
exchanging information between different phases of the MLRISC system, and
between a compiler front end and the MLRISC back end.
The following constructors can be used to annotate a MLTree term with
an annotation:
\begin{SML}
MARK : rexp * Annotations.annotation -> rexp
FMARK : fexp * Annotations.annotation -> fexp
CCMARK : ccexp * Annotations.annotation -> ccexp
ANNOTATION : stm * Annotations.annotation -> stm
\end{SML}
+60
View File
@@ -0,0 +1,60 @@
\section{Optimizations}
MLRISC assumes that all high level optimizations (target
independent) have already been performed. This includes things like
inlining, array dependence analysis, and array bounds check
elimination. The target dependent optimizations that remain include
register allocation, scheduling and traditional optimizations to
support scheduling.
\subsection{Register allocation}
MLRISC includes a state-of-the-art graph-coloring based register
allocator that has an aggressive algorithm for copy-propagation. The
latter guarantees to eliminate copy instructions without introducing
spills.
Spills in the register allocator are under the control of the
client via call-backs to the front end. Where to spill registers and
the associated information that must be maintained is client specific
and varies with the compiler.
\subsection{Scheduling for Superscalar Architectures}
Several algorithms for acyclic global scheduling are provided. These
include:
\begin{itemize}
\item Superblock,
\item a variant of Bernstein/Rodeh, and
\item Percolation based scheduling.
\end{itemize}
These algorithms tend to be quite complex and require a large number
of support data structures and analysis. These include data structures
such as:
\begin{itemize}
\item dominator/post dominator trees,
\item loop nesting tree,
\item control dependency graphs, and
\item data dependency graphs.
\end{itemize}
Support analysis and optimization include:
\begin{itemize}
\item constant propagation,
\item global value numbering,
\item global code motion, and
\item loop invariant hoisting.
\end{itemize}
\subsection{VLIW Compilation}
MLRISC also contains a framework for the compilation of
predicated VLIW architectures.
Currently, the following algorithms have been implemented.
\begin{itemize}
\item hyperblock formation
\item hyperblock scheduling
\item modulo scheduling
\end{itemize}
+3
View File
@@ -0,0 +1,3 @@
\section{The PowerPC Back End}
No documentation yet.
+42
View File
@@ -0,0 +1,42 @@
\section{Problem Statement}
Writing a native code generator for any language is a significant
investment, especially for todays modern processors with require extensive
compiler support to achieve high performance. The algorithms that must
be used to generate high quality code are complex, sometimes quite
delicate, and require substantial infrastructure.
\image{Retargeting compiler}{pictures/png/uncol2.png}{align=right}
A specific architecture has a
relatively short life time in relation to the time taken to build
the code generator, and one quickly needs the ability to retarget
to new versions of the architecture, or to different target
architectures. This is by no means an open problem. There are many
compilers today that target multiple architectures, however the
quality of code varies. For example,
\begin{color}{red}\begin{Italics}lcc\end{Italics}\end{color}
by Chris Fraser and David Hansen does
no back end optimizations;
\begin{color}{red}\begin{Italics}gcc\end{Italics}\end{color}
from the Free Software Foundation does extensive peephole and simple
data flow optimizations, and falls short on advanced superscalar
optimizations; and finally the
\begin{color}{red}\begin{Italics}IMPACT\end{Italics}\end{color}
compiler done by the Impact group at the
University of Illinois specializes in more advanced superscalar
and predicated architectures.
\br{clear=right}
\image{UNCOL?}{pictures/png/uncol.png}{align=left} Assuming
the retargeting issue is solved, one would like to use all the
developed infrastructure for multiple source languages. This
problem is far from solved; even though \italics{gcc} has been used
for multiple languages like Ada, Pascal, and Modula III, each of
these have similiar execution models or were forced to adopt C
conventions. \italics{gcc} cannot be used directly for languages
such as Lisp, Smalltalk, Haskell, or ML that have radically
different execution models and special requirements to support
advanced language features.
+39
View File
@@ -0,0 +1,39 @@
\section{Client Defined Pseudo Ops}
\subsection{Introduction}
\newdef{Pseudo ops}
are client defined instruction stream markers. They
can be used to represent assembly directives.
Pseudo ops should satisfy the following signature:
\begin{SML}
signature \mlrischref{instructions/pseudoOps.sig}{PSEUDO_OPS} = sig
type pseudo_op
val toString : pseudo_op -> string
val emitValue : {pOp:pseudo_op, loc:int, emit:Word8.word -> unit} -> unit
val sizeOf : pseudo_op * int -> int
val adjustLabels : pseudo_op * int -> bool
end
\end{SML}
The method that is required is:
\begin{itemize}
\item \sml{toString} -- pretty printing the pseudo in assembly format.
\end{itemize}
When machine code generation is used, we also have to implement
the following methods:
\begin{itemize}
\item \sml{emitValue} --
emit value of pseudo op give current location counter and output
stream. The value emitted should respect the endianness of the
target machine.
\item \sml{sizeOf} --
Size of the pseudo op in bytes given the current location counter
The location counter is provided in case some pseudo ops are
dependent on alignment considerations.
\item \sml{adjustLabels} --
adjust the value of labels in the pseudo op given the current
location counter.
\end{itemize}
These methods are involved during the
\href{span-dep.html}{span dependence resolution} phase to determine
the size and layout of the pseudo ops.
+8
View File
@@ -0,0 +1,8 @@
\section{Register Allocator}
The MLRISC register allocator implements the iterated-coalescing algorithm
described in POPL '96 [George, Appel]. The details are described in these
papers
\begin{enumerate}
\item \externhref{http://cm.bell-labs.com/cm/cs/what/smlnj/compiler-notes/new-ra.ps}{A New MLRISC Register Allocator}
\end{enumerate}
+26
View File
@@ -0,0 +1,26 @@
\section{Regions}
\subsubsection{Overview}
The MLRISC system uses user defined type called
\newdef{regions} to propagate
aliasing information to the backend. This type is
abstract and no constraint is imposed on how it is implemented.
The advantage of this is that the client can optimize the representation
of the region information according to the semantics of the source language.
The downside of this freedom is that the client has to implement
various modules to extract information from the regions datatype
required by various optimization phases.
For clients that do not want to implement their own regions datatype,
there is now a new generic mechanism, called
\newdef{MLRiscRegions}, built on top of
the regions concept, for propagating both:
\begin{itemize}
\item Aliasing information, and
\item Control dependence/anti-control dependence information
\end{itemize}
Both kinds of information are crucial for extracting parallelism
from the target code, and are used in all optimizations that perform code
motion, such as SSA optimizations and all scheduling optimizations.
\subsubsection{MLRisc Regions}
+16
View File
@@ -0,0 +1,16 @@
\section{Regmap}
A \newdef{regmap}
is a mapping from virtual register to virtual or physical
register, and is used by MLRISC register allocators to
represent the current binding of virtual registers. Regmaps are implemented
as \mlrischref{library/intmap.sml}{Intmap}
in MLRISC, and are defined in the
\href{cells.html}{CELLS} interface.
Regmaps are used in phases such as
\href{asm.html}{assembly generation} and
\href{mc.html}{machine code}. MLRISC program representations such
\href{cluster.html}{clusters} and \href{mlrisc-ir.html}{IR}
each contains a global regmap per compilation unit. Representations
such as \href{hyperblock.html}{hyperblock} may contain its own
regmap, which overrides the global regmap.
+3
View File
@@ -0,0 +1,3 @@
\section{Requirements}
The most up-to-date MLRISC system requires
\externhref{http://cm.bell-labs.com/cm/cs/what/smlnj/index.html}{Standard ML of New Jersey} version 110.0.3 or later.
+390
View File
@@ -0,0 +1,390 @@
%
% This is derived from alltt.sty
%
\NeedsTeXFormat{LaTeX2e}
\ProvidesPackage{sml}[1998/12/17 defines sml environment]
%
% Font for typesetting sml code, default is \tt
%
\newcommand{\smlFont}{\verbatim@font}
\newcommand{\smlCommentSize}{\small}
\newcommand{\smlCommentFont}{\it}
\newcommand{\smlNumberFont}{\smlFont}
\newcommand{\smlNumberStyle}[1]{\arabic{#1}}
\newcommand{\sml@font}{\smlFont}
%
% Turn on and off dollar sign
%
\newif\ifsml@dollar
\newcommand{\smlDollarOn}{\sml@dollartrue}
\newcommand{\smlDollarOff}{\sml@dollarfalse}
\smlDollarOff
%
% Font for typesetting sml type variables, default is \it
%
\newcommand{\smlTypeVarFont}{\it}
%
% Commands for typesetting type variables and keywords.
% Can be overridden by user.
%
\newcommand{\makeSmlTypeVar}[1]{'{\smlTypeVarFont#1}}
\newcommand{\makeSmlKeyword}[1]{{\bf#1}}
\newcommand{\BeginSmlComment}{\begingroup\smlCommentSize\smlCommentFont}
\newcommand{\EndSmlComment}{\endgroup}
%
% Command to declare a new type variable translation
% and keywords
%
\newcommand{\smlTypeVar}[2]{
\expandafter\newcommand\csname smltv@#1\endcsname{#2}
}
\newcommand{\smlRemoveTypeVar}[1]{
\expandafter\newcommand\csname smltv@#1\endcsname\relax
}
\newcommand{\smlNewKeyword}[1]{
\expandafter\def\csname smlkw@#1\endcsname{\makeSmlKeyword{#1}}
}
\newcommand{\smlDefineNewKeyword}[2]{
\expandafter\def\csname smlkw@#1\endcsname{#2}
}
\newcommand{\smlRemoveKeyword}[1]{
\expandafter\newcommand\csname smlkw@#1\endcsname\relax
}
%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%
%
%
%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%
\newcommand{\sml@expandtv}[1]{%
\if\csname smltv@#1\endcsname\relax\makeSmlTypeVar{#1}\else%
\csname smltv@#1\endcsname\fi}
\newcommand{\sml@expandkw}[1]{%
\if\csname smlkw@#1\endcsname\relax{#1}\else\csname smlkw@#1\endcsname\fi}
%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%
% This is a lexer that translates type variables and keywords
% #1 is the eof character
% #2 is the current state (actually a macro)
% which can be:
% 0 -- program text
% 1 -- type variable
% 2 -- program text found (
% 3 -- in comment
% 4 -- in comment type variable
% 5 -- in comment found *
% #3 is the current string
% #4 is the next token
%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%
\newcommand{\sml@startlexer}[1]{\sml@lexer{#1}{0}{}}
\newcommand{\sml@lexer}[4]{%
\ifx#4a\let\sml@nexttok=\sml@getletter%
\else\ifx#4b\let\sml@nexttok=\sml@getletter%
\else\ifx#4c\let\sml@nexttok=\sml@getletter%
\else\ifx#4d\let\sml@nexttok=\sml@getletter%
\else\ifx#4e\let\sml@nexttok=\sml@getletter%
\else\ifx#4f\let\sml@nexttok=\sml@getletter%
\else\ifx#4g\let\sml@nexttok=\sml@getletter%
\else\ifx#4h\let\sml@nexttok=\sml@getletter%
\else\ifx#4i\let\sml@nexttok=\sml@getletter%
\else\ifx#4j\let\sml@nexttok=\sml@getletter%
\else\ifx#4k\let\sml@nexttok=\sml@getletter%
\else\ifx#4l\let\sml@nexttok=\sml@getletter%
\else\ifx#4m\let\sml@nexttok=\sml@getletter%
\else\ifx#4n\let\sml@nexttok=\sml@getletter%
\else\ifx#4o\let\sml@nexttok=\sml@getletter%
\else\ifx#4p\let\sml@nexttok=\sml@getletter%
\else\ifx#4q\let\sml@nexttok=\sml@getletter%
\else\ifx#4r\let\sml@nexttok=\sml@getletter%
\else\ifx#4s\let\sml@nexttok=\sml@getletter%
\else\ifx#4t\let\sml@nexttok=\sml@getletter%
\else\ifx#4u\let\sml@nexttok=\sml@getletter%
\else\ifx#4v\let\sml@nexttok=\sml@getletter%
\else\ifx#4w\let\sml@nexttok=\sml@getletter%
\else\ifx#4x\let\sml@nexttok=\sml@getletter%
\else\ifx#4y\let\sml@nexttok=\sml@getletter%
\else\ifx#4z\let\sml@nexttok=\sml@getletter%
\else\ifx#4_\let\sml@nexttok=\sml@getletter%
\else%
\let\sml@nexttok=\sml@transition% is not a letter
\fi\fi\fi\fi\fi\fi\fi\fi\fi\fi\fi\fi\fi\fi\fi\fi\fi\fi\fi\fi\fi\fi\fi\fi\fi\fi\fi%
\sml@nexttok{#1}{#2}{#3}{#4}%
}
\newcommand{\sml@getletter}[4]{\sml@lexer{#1}{#2}{#3#4}} % get more character
%
% Do something according to the lookahead character
%
\newcommand{\sml@transition}[4]{%
%\message{|#3|}%
\if\noexpand#4'%
\let\sml@nextaction=\sml@tokenizetv%
\else\if\noexpand#4#1%
\let\sml@nextaction=\sml@endlexer%
\else\ifx#4(%
\let\sml@nextaction=\sml@lparen%
\else\ifx#4)%
\let\sml@nextaction=\sml@rparen%
\else\ifx#4*%
\let\sml@nextaction=\sml@star%
\else%
\let\sml@nextaction=\sml@tokenizekw%
\fi\fi\fi\fi\fi%
\sml@nextaction{#1}{#2}{#3}{#4}%
}
% 0 -- program text
% 1 -- type variable
% 2 -- program text found (
% 3 -- in comment
% 4 -- in comment type variable
% 5 -- in comment found *
\newcommand{\sml@expand}[2]{%
\ifcase#1\let\sml@process=\sml@expandkw\or%
\let\sml@process=\sml@expandtv\or%
\let\sml@process=\sml@expandkw\or%
\let\sml@process=\sml@expandkw\or%
\let\sml@process=\sml@expandtv\or%
\let\sml@process=\sml@expandkw%
\else\ERROR%
\fi%
\sml@process{#2}%
}
\newcommand{\sml@tokenizekw}[4]{\sml@expand{#2}{#3}#4\sml@lexer{#1}{\sml@deltakw{#2}}{}}
\newcommand{\sml@tokenizetv}[4]{\sml@expand{#2}{#3}\sml@lexer{#1}{\sml@deltatv{#2}}{}}
\newcommand{\sml@endlexer}[4]{\sml@expand{#2}{#3}}
\newcommand{\sml@lparen}[4]{\sml@expand{#2}{#3}%
(\sml@lexer{#1}{\sml@deltal{#2}}{}}
\newcommand{\sml@rparen}[4]{\sml@expand{#2}{#3}%
\sml@closecomment{#2})\sml@lexer{#1}{\sml@deltar{#2}}{}}
\newcommand{\sml@star}[4]{\sml@expand{#2}{#3}*%
\sml@opencomment{#2}\sml@lexer{#1}{\sml@deltas{#2}}{}}
% 0 -- program text
% 1 -- type variable
% 2 -- program text found (
% 3 -- in comment
% 4 -- in comment type variable
% 5 -- in comment found *
\newcommand{\sml@opencomment}[1]{\if2#1\BeginSmlComment\else\fi}
\newcommand{\sml@closecomment}[1]{\if5#1\EndSmlComment\else\fi}
\newcommand{\sml@deltakw}[1]{\ifcase#1 0\or0\or0\or3\or3\or3\else\ERROR\fi}
\newcommand{\sml@deltatv}[1]{\ifcase#1 1\or1\or1\or4\or4\or4\else\ERROR\fi}
\newcommand{\sml@deltal}[1]{\ifcase#1 2\or2\or2\or3\or3\or3\else\ERROR\fi}
\newcommand{\sml@deltas}[1]{\ifcase#1 0\or0\or3\or5\or5\or5\else\ERROR\fi}
\newcommand{\sml@deltar}[1]{\ifcase#1 0\or0\or0\or3\or3\or0\else\ERROR\fi}
%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%
%
% How to process type variables as active character:
%
%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%
\newcommand{\sml@processtypevar}{\sml@lexty{}}
\newcommand{\sml@lexty}[2]{\ifcat\noexpand#2a\let\sml@nextty=\sml@morety\else\let\sml@nextty=\sml@donety\fi\sml@nextty{#1}#2}
\newcommand{\sml@morety}[2]{\sml@lexty{#1#2}}
\newcommand{\sml@donety}[1]{\sml@expandtv{#1}}
\newcommand{\sml@aftertypevar}{}
%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%
%
% Macros for setting up verbatim mode
%
%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%
%
% Set up catcodes for verbatim mode
%
\begingroup
\lccode`\~=`\'
\lowercase{\endgroup
\newcommand{\sml@settick}{\catcode`\'=\active\let~=\sml@processtypevar}
\newcommand{\sml@verbatimmode}{%
\let\sml@origprime=~%
\sml@font%
\@noligs%
\catcode`\^=12%
\catcode`\_=12%
\ifsml@dollar\else\catcode`\$=12\fi%
\catcode`\#=12%
\catcode`\&=12%
\catcode`\~=12%
\catcode`\%=12%
\everymath\expandafter{\the\everymath\sml@mathmode}%
\everydisplay\expandafter{\the\everydisplay\sml@mathmode}%
\everypar\expandafter{\the\everypar\unpenalty}%
\sml@settick%
\frenchspacing\@vobeyspaces% Preserve all spaces
}
%
% Set up catcodes for math mode
%
\newcommand{\sml@mathmode}{
\catcode`\^=7 % Superscript
\catcode`\_=8 % Subscript
\catcode`\'=12 % prime
\let~=\sml@origprime%
}
}
%
% Set up display format
%
\newcommand{\sml@begindisplay}{%
\begingroup
%\trivlist \item
\if@minipage% Insert paragraph break
\else
\vskip\parskip
\fi
\leftskip\@totalleftmargin
\rightskip\z@skip
\parindent\z@
\parfillskip\@flushglue
\parskip\z@skip
\@@par
\@tempswafalse
\def\par{%
\if@tempswa
\leavevmode\null\@@par\penalty\interlinepenalty
\else
\@tempswatrue
\ifhmode\@@par\penalty\interlinepenalty\fi
\fi}
\obeylines % Lines breaks are meaningful
}
%
% End display format
%
%\newcommand{\sml@enddisplay}{\endtrivlist\endgroup}
\newcommand{\sml@enddisplay}{\endgroup}
%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%
%
% The main macros
%
%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%
\newenvironment{smldisplay}{\sml@begindisplay\trivlist\item\sml@verbatimmode}{\endtrivlist\sml@enddisplay}
\newcommand{\sml}{\begingroup\sml@verbatimmode\sml@verb}
\newcommand{\sml@verb}[1]{#1\endgroup}
\newsavebox{\sml@box}
\newenvironment{sml@boxit}{\begin{lrbox}{\sml@box}
\begin{minipage}[b]{\columnwidth}}
{\end{minipage}\end{lrbox}\begin{center}\framebox[\columnwidth]{\usebox{\sml@box}}\end{center}}
\newenvironment{smlboxeddisplay}{\begin{sml@boxit}\begin{smldisplay}}{\end{smldisplay}\end{sml@boxit}}
\newcounter{sml@linecount}
\newcounter{sml@increment}
\newcommand{\sml@setuplineno}[2]{%
\setcounter{sml@linecount}{#1}%
\setcounter{sml@increment}{1}%
\newcommand{\sml@showlinecount}%
{\llap{\smlNumberFont\smlNumberStyle{sml@linecount}\ }}%
\newcommand{\sml@inclineno}{\addtocounter{sml@increment}{-1}%
\ifnum\value{sml@increment}=0\sml@showlinecount\setcounter{sml@increment}{#2}\else \fi%
\addtocounter{sml@linecount}{1}}%
\everypar{\sml@inclineno}%
}
\newenvironment{smllisting}[2]%
{\sml@begindisplay\sml@verbatimmode\sml@setuplineno{#1}{#2}}%
{\sml@enddisplay}
\newenvironment{smlboxedlisting}[2]%
{\begin{sml@boxit}\begin{smllisting}{#1}{#2}}{\end{smllisting}\end{sml@boxit}}
\newenvironment{smldisplay*}[1]{%
\sml@begindisplay
\let\sml@settick=\relax
\sml@verbatimmode
\sml@startlexer{#1}
}{\sml@enddisplay}
\newenvironment{smlboxeddisplay*}[1]%
{\begin{sml@boxit}\begin{smldisplay*}{#1}}{\end{smldisplay*}\end{sml@boxit}}
\begingroup
\catcode`\^^A=12%
\catcode`\<=1%
\catcode`\>=2%
\catcode`\?=0%
\catcode`\{=12%
\catcode`\}=12%
%\catcode`\\=12%
\lowercase<\endgroup%
\def\sml@glob#1\end<\sml@startlexer<^^A>#1^^A\sml@enddisplay\end>%
\def\smldisp<%
\sml@begindisplay%
\let\sml@settick=\relax%
\sml@verbatimmode%
\catcode`\^^A=12%
\sml@glob%
>
\def\endsmldisp<>
>
\begingroup
\catcode`\^^A=12
\lowercase{\endgroup
\newcommand{\Sml}{%
\begingroup%
\let\sml@settick=\relax%
\sml@verbatimmode%
\catcode`\^^A=12%
\long\def\sml@grab##1{\sml@startlexer{^^A}##1^^A\endgroup}%
\sml@grab%
}
}
%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%
%
% Set up the default keywords
%
%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%
\newcommand{\smlSetupAllKeywords}
{ \smlNewKeyword{functor}
\smlNewKeyword{structure}
\smlNewKeyword{signature}
\smlNewKeyword{struct}
\smlNewKeyword{sharing}
\smlNewKeyword{sig}
\smlNewKeyword{include}
\smlNewKeyword{fun}
\smlNewKeyword{val}
\smlNewKeyword{rec}
\smlNewKeyword{type}
\smlNewKeyword{datatype}
\smlNewKeyword{case}
\smlNewKeyword{of}
\smlNewKeyword{and}
\smlNewKeyword{where}
\smlNewKeyword{withtype}
\smlNewKeyword{end}
\smlNewKeyword{let}
\smlNewKeyword{in}
\smlNewKeyword{end}
\smlNewKeyword{handle}
\smlNewKeyword{raise}
\smlNewKeyword{exception}
\smlNewKeyword{local}
\smlNewKeyword{open}
\smlNewKeyword{if}
\smlNewKeyword{then}
\smlNewKeyword{else}
\smlNewKeyword{infix}
\smlNewKeyword{infixr}
\smlNewKeyword{nonfix}
}
\smlSetupAllKeywords
\endinput
+277
View File
@@ -0,0 +1,277 @@
\documentclass{article}
\usepackage{sml}
\title{Package {\tt sml}}
\author{Allen Leung}
\begin{document}
\maketitle
\section{Introduction}
The \verb|sml| package defines a \verb|verbatim|-like environment
called \verb|smldisplay|
for typesetting Standard ML programs.
Like the \verb|alltt| environment,
backslashes `\verb|\|' and the braces \verb|{|
and \verb|}| have their usual meaning in \verb|smldisplay|,
so it is possible to use other
macros and commands within the \verb|smldisplay| environment.
Meta-characters such as \verb|#|, \verb|%|,
\verb|$|, \verb|_| and \verb|^| are disabled and appears verbatim.
To enter math mode, the user can use \verb|\(| \ldots \verb|)| or
\verb|\[| \ldots \verb|\]|. But unlike the \verb|alltt| environment,
the superscripts \verb|^| and subscripts \verb|_| characters
are available inside math mode.
The character \verb|'| is interpreted as the beginning of a ML
type variable. Type variables are typeset
in italics within the \verb|smldisplay| environment. For example,
\begin{verbatim}
\begin{smldisplay}
datatype 'a tree = EMPTY
| NODE of 'a * 'a tree list
\end{smldisplay}
\end{verbatim}
is typeset as follows:
\begin{smldisplay}
datatype 'a tree = EMPTY
| NODE of 'a * 'a tree list
\end{smldisplay}
The environment \verb|smlboxeddisplay| is similar to \verb|smldisplay|
except that a box is also drawn around the displayed program.
For example, if we write:
\begin{verbatim}
\begin{smlboxeddisplay}
datatype 'a tree = EMPTY
| NODE of 'a * 'a tree list
\end{smlboxeddisplay}
\end{verbatim}
we get:
\begin{smlboxeddisplay}
datatype 'a tree = EMPTY
| NODE of 'a * 'a tree list
\end{smlboxeddisplay}
\subsection{Highlighting keywords}
A similar environment, called \verb|smldisp|, can be used to highlight
all SML keywords. However, math mode and other macros are {\em unavailable}
in this environment. For example, in \verb|smldisp| we can write:
\begin{verbatim}
\begin{smldisp}
(* A n-ary tree *)
datatype 'a tree = EMPTY
| NODE of 'a * 'a tree list
(* Flatten a tree as a list in preorder *)
fun flatten(EMPTY) = []
| flatten(NODE(x,children)) = [x] @ List.concat(map flatten children)
\end{smldisp}
\end{verbatim}
and get the following result:
\begin{smldisp}
(* A n-ary tree *)
datatype 'a tree = EMPTY
| NODE of 'a * 'a tree list
(* Flatten a tree as a list in preorder *)
fun flatten(EMPTY) = []
| flatten(NODE(x,children)) = [x] @ List.concat(map flatten children)
\end{smldisp}
Note that the keywords ``datatype'' and ``of'' have been typeset as
\Sml{datatype} and \Sml{of}. Furthermore, comments are typeset
in small italics font.
The following macros control how keywords and comments are typeset
in this environment:
\begin{verbatim}
\newcommand{\makeSmlKeyword}[1]{{\bf #1}}
\newcommand{\smlCommentSize}{\small}
\newcommand{\smlCommentFont}{\it}
\newcommand{\BeginSmlComment}{\begingroup\smlCommentSize\smlCommentFont}
\newcommand{\EndSmlComment}{\endgroup}
\end{verbatim}
These can be redefined by the user if necessary.
\subsection{Type Variable Translations}
It is possible to define type variable translations for
\verb|smldisplay| and \verb|smldisp| environments. For example,
if we write:
\begin{verbatim}
\smlTypeVar{a}{\(\alpha\)}
\smlTypeVar{foo}{\(\underline\beta\)}
\begin{smldisplay}
datatype 'a tree = EMPTY | NODE of 'a * 'a tree list
type 'foo foo = ('foo * 'foo) tree
type 'c seq = 'c list
\end{smldisplay}
\end{verbatim}
we get:
\smlTypeVar{a}{\(\alpha\)}
\smlTypeVar{foo}{\(\underline\beta\)}
\begin{smldisplay}
datatype 'a tree = EMPTY | NODE of 'a * 'a tree list
type 'foo foo = ('foo * 'foo) tree
type 'c seq = 'c list
\end{smldisplay}
Note that all occurrances of \verb|'a| has been translated into
$\alpha$, while all occurrances of \verb|'foo| has been translated
into $\underline\beta$.
A type variable translation declared by \verb|smlTypeVar| is active
in its scope until it is removed by
the macro \verb|\smlRemoveTypeVar|.
For example, we can write:
\begin{verbatim}
\smlRemoveTypeVar{foo}
\end{verbatim}
to remove the translation on type variable \verb|'foo|.
\subsection{{\tt $\backslash${verb}}-like macros}
A \verb|\verb|-like macro called \verb|\sml| is available for typesetting
short SML program fragments within running text.
For example, we can write the following:
\begin{verbatim}
\begin{quotation}
The datatype \sml{'a tree} implements a polymorphic n-ary tree.
The function \sml{val rev : 'a tree -> 'a list} flattens a tree into a list.
\end{quotation}
\end{verbatim}
and obtain:
\begin{quotation}
The datatype \sml{'a tree} implements a polymorphic n-ary tree.
The function \sml{val rev : 'a tree -> 'a list} flattens a tree into a list.
\end{quotation}
The macro \verb|\sml| behaves very much like the \verb|smldisplay|
environment, except that newlines are not interpreted verbatim.
Similarly, there is a \verb|\verb|-like macro called \verb|\Sml| that
behaves like the \verb|smldisp| environment. For example, writing
\begin{verbatim}
\begin{quotation}
The datatype \Sml{'a tree} implements a polymorphic n-ary tree.
The function \Sml{val rev : 'a tree -> 'a list} flattens a tree into a list.
\end{quotation}
\end{verbatim}
we obtain:
\begin{quotation}
The datatype \Sml{'a tree} implements a polymorphic n-ary tree.
The function \Sml{val rev : 'a tree -> 'a list} flattens a tree into a list.
\end{quotation}
\subsection{Changing the Fonts}
The macros \verb|\smlFont| and \verb|\smlTypeVarFont|
define the fonts used for typesetting ML text and type variables.
They are predefined as follows:
\begin{verbatim}
\newcommand{\smlFont}{\verbatim@font}
\newcommand{\smlTypeVarFont}{\it}
\end{verbatim}
Furthermore, the default method of typesetting a type variable
is defined as:
\begin{verbatim}
\newcommand{\makeSmlTypeVar}[1]{'{\smlTypeVarFont #1}}
\end{verbatim}
These can be overridden by the user if desired.
\subsection{Enabling {\tt \$}}
By default, the math shift character \verb|$|
is disabled within the environment \verb|smldisplay|
and the macro \verb|sml|. It is possible to
enable this character by declaring:
\begin{verbatim}
\smlDollarOn
\end{verbatim}
\noindent in the prologue of a document.
For example, we can write:
\begin{verbatim}
\smlDollarOn
\begin{smldisplay}
datatype 'a tree = EMPTY | NODE of 'a * 'a tree list
\textrm{A balanced tree with $n$ nodes has height $O(\log n)$}
\end{smldisplay}
\end{verbatim}
and obtain:
\smlDollarOn
\begin{smldisplay}
datatype 'a tree = EMPTY | NODE of 'a * 'a tree list
\textrm{A balanced tree with $n$ nodes has height $O(\log n)$}
\end{smldisplay}
To turn off the math shift character \verb|$|, we can
write
\begin{verbatim}
\smlDollarOff
\end{verbatim}
\subsection{Numbered Program Listings}
Numbered program listings can be displayed using the
\verb|smllisting| environment, which behaves exactly like
\verb|smldisplay| except that every line is prefixed by a
line number. For example, when we write:
\begin{verbatim}
\smlTypeVar{n}{\(\alpha\)}
\smlTypeVar{e}{\(\beta\)}
\smlTypeVar{g}{\(\gamma\)}
\begin{smllisting}{1}{1}
signature SINGLE_SOURCE_SHORTEST_PATHS =
sig
val single_source_shortest_paths :
\{ weight : 'e Graph.edge -> 'w,
< : 'w * 'w -> bool,
+ : 'w * 'w -> 'w,
zero : 'w,
inf : 'w
\} ->
('n,'e,'g) Graph.graph ->
Graph.node_id ->
\{ dist : 'w Array.array,
pred : Graph.node_id Array.array
\}
end
\end{smllisting}
\end{verbatim}
\noindent we get:
\smlTypeVar{n}{\(\alpha\)}
\smlTypeVar{e}{\(\beta\)}
\smlTypeVar{g}{\(\gamma\)}
\begin{smllisting}{1}{1}
signature SINGLE_SOURCE_SHORTEST_PATHS =
sig
val single_source_shortest_paths :
\{ weight : 'e Graph.edge -> 'w,
< : 'w * 'w -> bool,
+ : 'w * 'w -> 'w,
zero : 'w,
inf : 'w
\} ->
('n,'e,'g) Graph.graph ->
Graph.node_id ->
\{ dist : 'w Array.array,
pred : Graph.node_id Array.array
\}
end
\end{smllisting}
The environment \verb|smllisting| requires two numeric parameters.
The first parameter determines the initial line number of the
listing, while the second parameter determines how often the line
number should be printed. For example, if the second parameter
is 2, then the line number appears every two lines.
The environment \verb|smlboxedlisting| is similar to
\verb|smllisting| except that a box is also drawn around the program
listing.
The following macros control how the numbers are displayed
\begin{verbatim}
\newcommand{\smlNumberFont}{\smlFont}
\newcommand{\smlNumberStyle}[1]{\arabic{#1}}
\end{verbatim}
The first macro \verb|\smlNumberFont| controls the font used
for line numbering, which by default is \verb|\tt|.
The second macro \verb|\smlNumberStyle| displays the line count as
arabic numerals.
\end{document}
+106
View File
@@ -0,0 +1,106 @@
\section{Span Dependency Resolution} \label{sec:span-dep}
The span dependency resolution phase is used to resolve the values of
client defined \href{constants.html}{constants} and \href{labels.html}{labels}
in a program. An instruction whose immediate operand field contains a
constant or \href{labexp.html}{label expression} which
is too large is rewritten into a sequence of instructions to compute
the same result. Similarly, short branches referencing labels that are
too far are rewritten into the long form. For architectures
that require the filling of delay slots, this is performed at the same
time as span depedency resolution, to ensure maximum benefit results.
\subsubsection{The Interface}
The signature \sml{SDI_JUMPS} describes
architectural information about span dependence resolution.
\begin{SML}
signature \mlrischref{backpatch/sdi-jumps.sig}{SDI_JUMPS} = sig
structure I : \href{instructions.html}{INSTRUCTIONS}
structure C : \href{cells.html}{CELLS}
sharing I.C = C
val branchDelayedArch : bool
val isSdi : I.instruction -> bool
val minSize : I.instruction -> int
val maxSize : I.instruction -> int
val sdiSize : I.instruction * (C.cell -> C.cell)
* (Label.label -> int) * int -> int
val expand : I.instruction * int * int -> I.instruction list
end
\end{SML}
The components in this interface are:
\begin{description}
\item[branchDelayedArch] A flag indicating whether the architecture
contains delay slots. For example, this would be true on the MIPS,
Sparc, PA RISC; but would be false on the x86 and on the Alpha.
\item[isSdi] This function returns true if the instruction is
\newdef{span dependent}, i.e.~its size depends either on some unresolved
constants, or on its position in the code stream.
\item[sdiSize] This function takes a span dependent instruction,
a \href{regmap.html}{regmap},
a mapping from labels to code stream position, and
its current code stream position and returns the size of its
expansion in bytes.
\item[expand] This function takes a span dependent instruction,
its size, and its location and return its expansion.
\end{description}
The signature \sml{BBSCHED} is the signature of the phase that performs
span depedennce resolution and code generation.
\begin{SML}
signature \mlrischref{backpatch/bbsched.sig}{BBSCHED} = sig
structure F : \href{cluster.html}{FLOWGRAPH}
val bbsched : F.cluster -> unit
val finish : unit -> unit
val cleanUp : unit -> unit
end
\end{SML}
\subsubsection{The Modules}
Three different functors are present in the \MLRISC{} system for
performing span dependence resolution and code generator.
Functor \sml{BBSched2} is the simplest one, which does not perform
delay slot filling.
\begin{SML}
functor BBSched2
(structure Flowgraph : \mlrischref{cluster/flowgraph.sig}{FLOWGRAPH}
structure Jumps : \mlrischref{backpatch/sdi-jumps.sig}{SDI_JUMPS}
structure Emitter : \href{mc.html}{INSTRUCTION_EMITTER}
sharing Emitter.P = Flowgraph.P
sharing Flowgraph.I = Jumps.I = Emitter.I
): BBSCHED
\end{SML}
Functor \sml{SpanDependencyResolution} performs both span dependence
resolution and delay slot filling at the same time.
\begin{SML}
functor SpanDependencyResolution
(structure Flowgraph : \mlrischref{cluster/flowgraph.sig}{FLOWGRAPH}
structure Emitter : \href{mc.html}{INSTRUCTION_EMITTER}
structure Jumps : \mlrischref{backpatch/sdi-jumps.sig}{SDI_JUMPS}
structure DelaySlot : \href{delayslots.html}{DELAY_SLOT_PROPERTIES}
structure Props : \mlrischref{instructions/insnProps.sig}{INSN_PROPERTIES}
sharing Flowgraph.P = Emitter.P
sharing Flowgraph.I = Jumps.I = DelaySlot.I = Props.I = Emitter.I
) : BBSCHED
\end{SML}
Finally, functor \sml{BackPatch} is a span dependency resolution
module specially written for the \href{x86.html}{x86} architecture.
\begin{SML}
functor BackPatch
(structure CodeString : \mlrischref{emit/code-string.sig}{CODE_STRING}
structure Jumps: \mlrischref{backpatch/sdi-jumps.sig}{SDI_JUMPS}
structure Props : \mlrischref{instructions/insnProps.sig}{INSN_PROPERTIES}
structure Emitter : \mlrischref{backpatch/vlBatchPatch.sig}{MC_EMIT}
structure Flowgraph : \href{cluster.html}{FLOWGRAPH}
structure Asm : \href{asm.html}{INSTRUCTION_EMITTER}
sharing Emitter.I = Jumps.I = Flowgraph.I = Props.I = Asm.I) : BBSCHED
\end{SML}
+56
View File
@@ -0,0 +1,56 @@
\section{The Sparc Back End}
The Sparc back end can function in two different modes:
\begin{description}
\item[Sparc V8] This is V8 instruction set is used. In this mode the processor
behaves like a 32-bit processor. In this mode we assume we
have 16 floating point registers numbered \verb|%f0, %f2, %f4, ..., %f30|.
These are all in IEEE double precision.
\item[Sparc V9] This generates code assuming the V9 instruction set is used.
In this mode the processor functions at 64-bit. In this mode the
floating point processors can number from \verb|%f0, %f2, %f4, ..., %f62|.
These are all in IEEE double precision.
New V9 instructions include the 64-bit extended version of multiplications,
divisions, shifts, and load and store.
\begin{verbatim}
MULX SMULX DIVX SLLX SRLX SRAX LDX STX
\end{verbatim}
Also, V9 includes conditional moves and more general form of branches.
\begin{description}
\item[MOVcc] conditional moves on condition code
\item[FMOVcc] conditional moves on condition code
\item[MOVR] conditional moves on integer condition
\item[BR] branch on integer register with prediction
\item[BP] branch on integer condition with prediction
\end{description}
\end{description}
\subsection{General Setup for V8}
The SPARC architecture has 32 general purpose registers
(\verb|%g0| is always 0)
and 32 single precision floating point registers.
Some Ugliness: double precision floating point registers are
register pairs. There are no double precision moves, negation and absolute
values. These require two single precision operations. I've created
composite instructions \verb|FMOVd|,
\verb|FNEGd| and
\verb|FABSd| to stand for these.
All integer arithmetic instructions can optionally set the condition
code register. We use this to simplify certain comparisons with zero
in the instruction selection process.
Integer multiplication, division and conversion from integer to floating
go thru the pseudo instruction interface, since older sparcs do not
implement these instructions in hardware.
In addition, the trap instruction for detecting overflow is a parameter.
This allows different trap vectors to be used.
\subsection{General Setup for V9}
\subsection{Specializing the Sparc Back End}
+72
View File
@@ -0,0 +1,72 @@
\section{Instruction Streams}
\subsubsection{Overview}
An \newdef{instruction stream}
is an abstraction used by MLRISC to describe linearized instructions.
This abstraction turns out to fit the function of
many MLRISC modules. For example,
a phase such as \href{instrsel.html}{Instruction Selection}
can be viewed as taking an stream of
\href{mltree.html}{MLTREE} statements and return a
stream of \href{instructions.html}{instructions}. Similarly,
phases such as \href{asm.html}{assembly output} and
\href{mc.html}{machine code generation} can be seen
as taking a stream of instructions and
returning a stream of characters and a stream of bytes.
\subsubsection{The Details}
An instruction stream satisfy the following abstract signature:
\begin{SML}
signature \mlrischref{instructions/stream.sig}{INSTRUCTION_STREAM} =
sig
structure P : \href{pseudo-ops.html}{PSEUDO_OPS}
datatype ('a,'b,'c,'d,'e,'f) stream =
STREAM of
\{ beginCluster: int -> 'b,
endCluster : 'c -> unit,
emit : 'a,
pseudoOp : P.pseudo_op -> unit,
defineLabel : Label.label -> unit,
entryLabel : Label.label -> unit,
comment : string -> unit,
annotation : Annotations.annotation -> unit,
exitBlock : 'd -> unit,
alias : 'e -> unit,
phi : 'f -> unit
\}
end
\end{SML}
This type is specialized in other modules as such the
\href{asm.html}{assembler}, the \href{mc.html}{machine code emitter},
and the \href{instrsel.html}{instruction selection modules}.
\subsubsection{The protocol}
All instruction streams, irrespective of their actual types,
follow the following protocol:
\begin{itemize}
\item The method \sml{beginCluster} should be called at the beginning of
the stream to mark the start of a new compilation unit.
The integer passed to this method is the number
of bytes in the stream. This integer is only used for
machine code emitter, which uses it to allocate space for the
code string.
\item The method \sml{endCluster} should be called when the entire
compilation unit has been sent.
\item In between these calls, the following methods can be called in any
order:
\begin{itemize}
\item \sml{emit} -- this method emits an instruction. It takes
a \href{regmap.html}{regmap} as argument.
\item \sml{pseudoOp} -- this method emits a pseudo op.
\item \sml{defineLabel} -- this method defines a \emph{local} label, i.e.
a label that is only referenced within the same compilation unit.
\item \sml{entryLabel} -- this method defines an \emph{enternal} label that
marks an procedure entry, and may be referenced from other
compilation units.
\item \sml{comment} -- this emits a comment string
\item \sml{annotation} -- this function attaches an annotation to
the current basic block.
\item \sml{exitBlock} --
this marks the current block as an procedure exit.
\end{itemize}
\end{itemize}
+43
View File
@@ -0,0 +1,43 @@
\section{System Integration}
In a heavily parameterized system like this, one very quickly ends up
with a large number of modules and dependencies making it very
easy to mix things up in the wrong way.
\image{module dependencies}{pictures/png/sharing1.png}{align=center}
\br{clear=left}
For example, MLRisc is parameterised over pseudo-ops,
constants, and regions. An instruction set must be parameterized
over constants so that instructions that carry immediate operands
can also carry these abstract constants. Instructions must also be
parameterized over regions so that memory operations can be
appropriately annotated. Finally, the flowgraph module must be
parameterized over instructions it carries in basic blocks and
pseudo-ops that describe data layout and alignment constraints.
\image{sharing constraints}{pictures/png/sharing2.png}{align=right}
\br{clear=left}
In integrating a system that involves these modules, it must be the
case that they were created with the same base modules. That is to
say the pseudo-ops in flowgraphs must be the same abstraction that
was used to define the MLRisc intermediate
representation. Alternatively, we want
\begin{color}{#ff0000}sharing constraints\end{color}
that assert that identity of modules used to
specialize other modules. In Standard ML, this is a complete
non-issue. A single line that says exactly that is all that is
needed to maintain consistency, and the module system does the rest
to ensure that the final system is built correctly.
\image{Back end optimizations}{pictures/png/sharing3.png}{align=left}
\br{clear=right}
In certain cases one wants to write a specific module for a
particular architecture. For instance it may be desirable to collapse
trap barriers on the DEC Alpha where it is legal to do so. The
INSTRUCTIONS interface is abstract with no built-in knowledge of
trap barriers as not all architectures have them.
Further the DEC Alpha has fairly unique trap barrier semantics,
that one may want to write an optimization module specific and
dedicated to the Alpha instruction set and architecture, and forget
about writing anything generic. In this case, the Standard ML module
system allows one to say that a specific abstraction actually is or
matches a more detailed interface. That is to say the INSTRUCTION
interface is really the DEC Alpha instruction set.
+17
View File
@@ -0,0 +1,17 @@
\section{Systems Using MLRISC}
Currently these are the systems that are known to be using MLRISC.
\begin{itemize}
\item \externhref{http://cm.bell-labs.com/cm/cs/what/smlnj/index.html}{SML/NJ},
a Standard ML compiler.
\item \externhref{http://www.dcs.gla.ac.uk/~reig/c--/index.html}{C--},
a portable assembly language.
\item \externhref{http://www.cs.bu.edu/groups/church/}{The Church Project}:
compilation with flow types.
\item \externhref{http://compiler.kaist.ac.kr/projects/lgic}{The LGIC Project}:
a compiler for the CHILL language, targeting PowerPC.
\item \externhref{http://www.cs.bell-labs.com/who/jhr/moby/index.html}{The Moby Language}
\end{itemize}
\begin{small}
Please send additions to \href{mailto:leunga@cs.nyu.edu}{Allen Leung}
\end{small}
+3
View File
@@ -0,0 +1,3 @@
\section{The Intel x86 Back End}
No documentation yet.
+74
View File
@@ -0,0 +1,74 @@
EPS= eps/big-pict.eps \
eps/big-pict2.eps \
eps/cfg-rev.eps \
eps/cfg.eps \
eps/compiler-2.eps \
eps/compiler.eps \
eps/compiler2.eps \
eps/hyperblock-formation.eps \
eps/if-conversion.eps \
eps/layers.eps \
eps/mlrisc-ir-archive.eps \
eps/mlrisc-IR.eps \
eps/phg.eps \
eps/region-builder.eps \
eps/subgraph.eps \
eps/tail-dupl.eps \
eps/tail-duplication.eps \
eps/trace.eps \
eps/uncol.eps \
eps/viewer.eps
PDF= pdf/big-pict.pdf \
pdf/big-pict2.pdf \
pdf/cfg-rev.pdf \
pdf/cfg.pdf \
pdf/compiler-2.pdf \
pdf/compiler.pdf \
pdf/compiler2.pdf \
pdf/hyperblock-formation.pdf \
pdf/if-conversion.pdf \
pdf/layers.pdf \
pdf/mlrisc-ir-archive.pdf \
pdf/mlrisc-IR.pdf \
pdf/phg.pdf \
pdf/region-builder.pdf \
pdf/subgraph.pdf \
pdf/tail-dupl.pdf \
pdf/tail-duplication.pdf \
pdf/trace.pdf \
pdf/uncol.pdf \
pdf/viewer.pdf
PNG= png/compiler-1.png \
png/compiler-2.png \
png/hof-1.png \
png/hof-2.png \
png/mlrisc-ir-archive.png \
png/optimization.png \
png/sharing1.png \
png/sharing2.png \
png/sharing3.png \
png/uncol.png \
png/uncol1.png \
png/uncol2.png
all: mkdir $(PNG) $(PDF)
clean:
rm -f $(EPS) $(PNG) $(PDF)
mkdir:
# @if [ ! -d eps ]; then mkdir eps; fi
@if [ ! -d pdf ]; then mkdir pdf; fi
@if [ ! -d png ]; then mkdir png; fi
eps/%.eps: fig/%.fig
fig2dev -L ps $< $@
pdf/%.pdf: fig/%.fig
fig2dev -L pdf $< $@
jpeg/%.jpg: fig/%.fig
fig2dev -L jpeg $< $@
png/%.png: fig/%.fig
fig2dev -L png $< $@
+90
View File
@@ -0,0 +1,90 @@
#FIG 3.2
Landscape
Center
Inches
Letter
100.00
Single
-2
1200 2
6 1800 5775 4125 7275
2 2 0 1 0 30 100 0 -1 0.000 0 0 -1 0 0 5
1800 5775 4094 5775 4094 7275 1800 7275 1800 5775
4 0 0 100 0 18 22 0.0000 4 225 840 2400 6225 Basic\001
4 0 0 100 0 18 22 0.0000 4 285 2040 1875 6750 Optimizations\001
-6
2 2 0 1 0 30 100 0 -1 0.000 0 0 -1 0 0 5
2250 2175 4350 2175 4350 3225 2250 3225 2250 2175
2 2 0 1 0 30 100 0 -1 0.000 0 0 -1 0 0 5
4275 4200 6900 4200 6900 5400 4275 5400 4275 4200
2 2 0 1 0 30 100 0 -1 0.000 0 0 -1 0 0 5
6225 2250 8625 2250 8625 3375 6225 3375 6225 2250
2 2 0 1 0 30 100 0 -1 0.000 0 0 -1 0 0 5
6975 5850 9600 5850 9600 7350 6975 7350 6975 5850
2 1 0 1 0 30 100 0 19 0.000 0 0 -1 1 1 2
1 1 1.00 60.00 120.00
1 1 1.00 60.00 120.00
6375 5400 7875 5850
2 1 0 1 0 30 100 0 19 0.000 0 0 -1 1 1 2
1 1 1.00 60.00 120.00
1 1 1.00 60.00 120.00
4575 5400 2850 5775
2 1 0 1 0 30 100 0 19 0.000 0 0 -1 1 1 2
1 1 1.00 60.00 120.00
1 1 1.00 60.00 120.00
3525 3225 5100 4200
2 1 0 1 0 30 100 0 19 0.000 0 0 -1 1 1 2
1 1 1.00 60.00 120.00
1 1 1.00 60.00 120.00
6900 3375 5625 4200
2 2 0 1 0 30 100 0 -1 0.000 0 0 -1 0 0 5
8925 3975 11475 3975 11475 5400 8925 5400 8925 3975
2 2 0 1 0 30 100 0 -1 0.000 0 0 -1 0 0 5
4650 600 6975 600 6975 1800 4650 1800 4650 600
2 1 0 1 0 30 100 0 19 0.000 0 0 -1 1 1 2
1 1 1.00 60.00 120.00
1 1 1.00 60.00 120.00
5550 1800 5325 4200
2 1 0 1 0 30 100 0 19 0.000 0 0 -1 1 1 2
1 1 1.00 60.00 120.00
1 1 1.00 60.00 120.00
6900 4800 8925 4725
2 2 0 1 0 3 100 0 33 0.000 0 0 -1 0 0 5
2400 8400 3975 8400 3975 9600 2400 9600 2400 8400
2 2 0 1 0 3 100 0 33 0.000 0 0 -1 0 0 5
4950 8400 6525 8400 6525 9600 4950 9600 4950 8400
2 2 0 1 0 3 100 0 33 0.000 0 0 -1 0 0 5
7500 8400 9075 8400 9075 9600 7500 9600 7500 8400
2 2 0 1 0 3 100 0 33 0.000 0 0 -1 0 0 5
9750 7875 11325 7875 11325 9075 9750 9075 9750 7875
2 1 0 1 0 3 100 0 33 0.000 0 0 -1 1 0 2
1 1 1.00 60.00 120.00
3375 8400 3525 8100
2 1 0 1 0 3 100 0 33 0.000 0 0 -1 1 0 2
1 1 1.00 60.00 120.00
6150 8400 6150 8100
2 1 0 1 0 3 100 0 33 0.000 0 0 -1 1 0 2
1 1 1.00 60.00 120.00
8100 8400 7950 8025
2 1 0 1 0 3 100 0 33 0.000 0 0 -1 1 0 2
1 1 1.00 60.00 120.00
10575 7875 10350 7575
3 3 0 1 0 30 100 0 -1 0.000 0 0 0 11
9000 1500 11700 3525 12075 6450 9225 7800 3825 8100 975 7350
1050 5100 1425 2475 3600 750 5250 225 7875 675
-1.000 -1.000 -1.000 -1.000 -1.000 -1.000 -1.000 -1.000
-1.000 -1.000 -1.000
4 0 0 100 0 18 22 0.0000 4 225 1635 4875 4875 MLRISC IR\001
4 0 0 100 0 18 22 0.0000 4 225 645 2625 2775 SSA\001
4 0 0 100 0 18 22 0.0000 4 285 2040 6375 3150 Optimizations\001
4 0 0 100 0 18 22 0.0000 4 285 1770 6450 2850 Superscalar\001
4 0 0 100 0 18 22 0.0000 4 225 750 7350 6300 VLIW\001
4 0 0 100 0 18 22 0.0000 4 285 2040 7350 6690 Optimizations\001
4 0 0 100 0 18 22 0.0000 4 285 1230 9375 4500 Register\001
4 0 0 100 0 18 22 0.0000 4 225 1320 9375 4890 Allocator\001
4 0 0 100 0 18 22 0.0000 4 225 1530 5100 975 Instruction\001
4 0 0 100 0 18 22 0.0000 4 225 1365 5100 1365 Selection\001
4 0 0 100 0 18 22 0.0000 4 285 795 2775 8925 Hppa\001
4 0 0 100 0 18 22 0.0000 4 285 855 5100 8925 Alpha\001
4 0 0 100 0 18 22 0.0000 4 225 525 7875 8925 X86\001
4 0 0 100 0 18 22 0.0000 4 285 870 10050 8400 Sparc\001
+94
View File
@@ -0,0 +1,94 @@
#FIG 3.2
Landscape
Center
Inches
Letter
100.00
Single
-2
1200 2
6 225 150 12750 9600
6 1800 5775 4125 7275
2 2 0 1 0 30 100 0 19 0.000 0 0 -1 0 0 5
1800 5775 4094 5775 4094 7275 1800 7275 1800 5775
4 0 0 100 0 18 22 0.0000 4 225 840 2400 6225 Basic\001
4 0 0 100 0 18 22 0.0000 4 285 2040 1875 6750 Optimizations\001
-6
2 2 0 1 0 30 100 0 19 0.000 0 0 -1 0 0 5
2250 2175 4350 2175 4350 3225 2250 3225 2250 2175
2 2 0 1 0 30 100 0 19 0.000 0 0 -1 0 0 5
4275 4200 6900 4200 6900 5400 4275 5400 4275 4200
2 2 0 1 0 30 100 0 19 0.000 0 0 -1 0 0 5
6225 2250 8625 2250 8625 3375 6225 3375 6225 2250
2 2 0 1 0 30 100 0 19 0.000 0 0 -1 0 0 5
6975 5850 9600 5850 9600 7350 6975 7350 6975 5850
2 1 0 1 0 30 100 0 19 0.000 0 0 -1 1 1 2
1 1 1.00 60.00 120.00
1 1 1.00 60.00 120.00
6375 5400 7875 5850
2 1 0 1 0 30 100 0 19 0.000 0 0 -1 1 1 2
1 1 1.00 60.00 120.00
1 1 1.00 60.00 120.00
4575 5400 2850 5775
2 1 0 1 0 30 100 0 19 0.000 0 0 -1 1 1 2
1 1 1.00 60.00 120.00
1 1 1.00 60.00 120.00
3525 3225 5100 4200
2 1 0 1 0 30 100 0 19 0.000 0 0 -1 1 1 2
1 1 1.00 60.00 120.00
1 1 1.00 60.00 120.00
6900 3375 5625 4200
2 2 0 1 0 30 100 0 19 0.000 0 0 -1 0 0 5
8925 3975 11475 3975 11475 5400 8925 5400 8925 3975
2 2 0 1 0 30 100 0 19 0.000 0 0 -1 0 0 5
4650 600 6975 600 6975 1800 4650 1800 4650 600
2 1 0 1 0 30 100 0 19 0.000 0 0 -1 1 1 2
1 1 1.00 60.00 120.00
1 1 1.00 60.00 120.00
5550 1800 5325 4200
2 1 0 1 0 30 100 0 19 0.000 0 0 -1 1 1 2
1 1 1.00 60.00 120.00
1 1 1.00 60.00 120.00
6900 4800 8925 4725
2 2 0 1 0 3 100 0 33 0.000 0 0 -1 0 0 5
2400 8400 3975 8400 3975 9600 2400 9600 2400 8400
2 2 0 1 0 3 100 0 33 0.000 0 0 -1 0 0 5
4950 8400 6525 8400 6525 9600 4950 9600 4950 8400
2 2 0 1 0 3 100 0 33 0.000 0 0 -1 0 0 5
7500 8400 9075 8400 9075 9600 7500 9600 7500 8400
2 2 0 1 0 3 100 0 33 0.000 0 0 -1 0 0 5
9750 7875 11325 7875 11325 9075 9750 9075 9750 7875
2 1 0 1 0 3 100 0 33 0.000 0 0 -1 1 0 2
1 1 1.00 60.00 120.00
3375 8400 3525 8100
2 1 0 1 0 3 100 0 33 0.000 0 0 -1 1 0 2
1 1 1.00 60.00 120.00
6150 8400 6150 8100
2 1 0 1 0 3 100 0 33 0.000 0 0 -1 1 0 2
1 1 1.00 60.00 120.00
8100 8400 7950 8025
2 1 0 1 0 3 100 0 33 0.000 0 0 -1 1 0 2
1 1 1.00 60.00 120.00
10575 7875 10350 7575
3 3 0 1 0 30 100 0 -1 0.000 0 0 0 11
9000 1500 11700 3525 12075 6450 9225 7800 3825 8100 975 7350
1050 5100 1425 2475 3600 750 5250 225 7875 675
-1.000 -1.000 -1.000 -1.000 -1.000 -1.000 -1.000 -1.000
-1.000 -1.000 -1.000
4 0 0 100 0 18 22 0.0000 4 225 1635 4875 4875 MLRISC IR\001
4 0 0 100 0 18 22 0.0000 4 225 645 2625 2775 SSA\001
4 0 0 100 0 18 22 0.0000 4 285 2040 6375 3150 Optimizations\001
4 0 0 100 0 18 22 0.0000 4 285 1770 6450 2850 Superscalar\001
4 0 0 100 0 18 22 0.0000 4 225 750 7350 6300 VLIW\001
4 0 0 100 0 18 22 0.0000 4 285 2040 7350 6690 Optimizations\001
4 0 0 100 0 18 22 0.0000 4 285 1230 9375 4500 Register\001
4 0 0 100 0 18 22 0.0000 4 225 1320 9375 4890 Allocator\001
4 0 0 100 0 18 22 0.0000 4 225 1530 5100 975 Instruction\001
4 0 0 100 0 18 22 0.0000 4 225 1365 5100 1365 Selection\001
4 0 0 100 0 18 22 0.0000 4 285 795 2775 8925 Hppa\001
4 0 0 100 0 18 22 0.0000 4 285 855 5100 8925 Alpha\001
4 0 0 100 0 18 22 0.0000 4 225 525 7875 8925 X86\001
4 0 0 100 0 18 22 0.0000 4 285 870 10050 8400 Sparc\001
-6
2 2 0 0 0 2 100 0 35 0.000 0 0 -1 0 0 5
600 300 11250 300 11250 9375 600 9375 600 300
+90
View File
@@ -0,0 +1,90 @@
#FIG 3.1
Portrait
Center
Inches
1200 2
2 2 0 1 -1 3 0 0 20 0.000 0 0 -1 0 0 5
2149 3862 3102 3862 3102 4498 2149 4498 2149 3862
2 2 0 1 -1 3 0 0 20 0.000 0 0 -1 0 0 5
1725 7358 3526 7358 3526 8100 1725 8100 1725 7358
2 1 0 1 -1 3 0 0 20 0.000 0 0 -1 1 0 2
1 1 1.00 60.00 120.00
2361 4498 1937 7358
2 2 0 1 -1 3 0 0 20 0.000 0 0 -1 0 0 5
3375 450 5176 450 5176 1192 3375 1192 3375 450
2 1 0 1 -1 3 0 0 20 0.000 0 0 -1 1 0 2
1 1 1.00 60.00 120.00
3975 1200 3339 1729
2 2 0 1 -1 3 0 0 20 0.000 0 0 -1 0 0 5
3900 3825 4854 3825 4854 4461 3900 4461 3900 3825
2 1 0 1 -1 3 0 0 45 0.000 0 0 -1 1 0 2
1 1 1.00 60.00 120.00
3150 2400 2475 3900
2 1 0 1 -1 3 0 0 45 0.000 0 0 -1 1 0 2
1 1 1.00 60.00 120.00
3375 2400 4275 3825
2 2 0 1 -1 3 0 0 20 0.000 0 0 -1 0 0 5
2497 5250 3450 5250 3450 5886 2497 5886 2497 5250
2 1 0 1 -1 3 0 0 45 0.000 0 0 -1 1 0 2
1 1 1.00 60.00 120.00
2550 4500 2700 5250
2 2 0 1 -1 3 0 0 20 0.000 0 0 -1 0 0 5
3750 6375 4703 6375 4703 7011 3750 7011 3750 6375
2 2 0 1 -1 3 0 0 20 0.000 0 0 -1 0 0 5
2400 6300 3354 6300 3354 6936 2400 6936 2400 6300
2 1 0 1 -1 3 0 0 45 0.000 0 0 -1 1 0 2
1 1 1.00 60.00 120.00
2925 5925 2775 6300
2 1 0 1 -1 3 0 0 -1 0.000 0 0 -1 1 0 2
1 1 1.00 60.00 120.00
3225 5925 3975 6375
2 2 0 1 -1 3 0 0 20 0.000 0 0 -1 0 0 5
2797 1689 3750 1689 3750 2325 2797 2325 2797 1689
2 2 0 1 -1 3 0 0 20 0.000 0 0 -1 0 0 5
1071 5175 2025 5175 2025 5811 1071 5811 1071 5175
2 1 0 1 -1 3 0 0 -1 0.000 0 0 -1 1 0 2
1 1 1.00 60.00 120.00
1500 5850 1875 7350
2 1 0 1 -1 3 0 0 -1 0.000 0 0 -1 1 0 2
1 1 1.00 60.00 120.00
2250 4500 1500 5175
2 1 0 1 -1 3 0 0 -1 0.000 0 0 -1 1 0 2
1 1 1.00 60.00 120.00
3300 2325 3225 5250
2 1 0 1 -1 3 0 0 -1 0.000 0 0 -1 1 0 2
1 1 1.00 60.00 120.00
2925 2325 1275 5175
3 2 0 1 -1 3 0 0 -1 0.000 0 1 0 6
1 1 1.00 60.00 120.00
1200 5850 975 6375 525 6225 300 5550 1125 4050 2775 2250
0.00 0.00 1177.04 6178.28 1120.79 6309.53 813.57 6447.49
620.89 6320.89 381.17 6081.17 282.38 5744.08 342.40 5083.03
893.72 4372.32 1372.41 3705.19 1784.91 3255.19 0.00 0.00
3 2 0 1 -1 3 0 0 -1 0.000 0 1 0 5
1 1 1.00 60.00 120.00
4500 1200 5325 3525 5175 6375 4650 7575 3525 7875
0.00 0.00 5055.35 2507.18 5261.60 3088.43 5422.78 4198.39
5330.63 5717.68 5103.57 6676.68 4930.53 7334.12 4462.97 7735.59
4181.72 7810.59 0.00 0.00
4 0 -1 0 0 18 20 0.0000 4 233 212 2467 4286 B\001
4 0 -1 0 0 18 20 0.0000 4 233 191 2679 4921 F\001
4 0 -1 0 0 18 20 0.0000 4 233 657 2361 7782 EXIT\001
4 0 -1 0 0 18 20 0.0000 4 233 996 3782 980 ENTRY\001
4 0 -1 0 0 18 20 0.0000 4 233 191 3495 1435 T\001
4 0 -1 0 0 18 20 0.0000 4 233 212 4206 4286 C\001
4 0 -1 0 0 18 20 0.0000 4 233 212 3102 2145 A\001
4 0 -1 0 0 18 20 0.0000 4 233 212 2785 5686 D\001
4 0 -1 0 0 18 20 0.0000 4 233 191 2790 6780 E\001
4 0 -1 0 0 18 20 0.0000 4 233 191 4106 6780 F\001
4 0 -1 0 0 18 20 0.0000 4 233 191 2577 6246 T\001
4 0 -1 0 0 18 20 0.0000 4 233 191 3725 2900 F\001
4 0 -1 0 0 18 20 0.0000 4 233 191 2948 3275 T\001
4 0 -1 0 0 18 20 0.0000 4 233 233 1444 5567 G\001
4 0 -1 0 0 18 20 0.0000 4 233 191 765 6713 F\001
4 0 -1 0 0 18 20 0.0000 4 233 191 3315 3338 F\001
4 0 -1 0 0 18 20 0.0000 4 233 191 2490 3338 F\001
4 0 -1 0 0 18 20 0.0000 4 233 191 2118 5027 T\001
4 0 -1 0 0 18 20 0.0000 4 233 191 1815 4763 F\001
4 0 -1 0 0 18 20 0.0000 4 233 191 1377 6396 T\001
4 0 -1 0 0 18 20 0.0000 4 233 191 3633 6117 F\001
4 0 -1 0 0 18 20 0.0000 4 233 191 4676 1556 F\001
+85
View File
@@ -0,0 +1,85 @@
#FIG 3.2
Portrait
Center
Inches
Letter
100.00
Single
-2
1200 2
2 1 0 1 -1 3 0 0 20 0.000 0 0 -1 0 1 2
1 1 1.00 60.00 120.00
1200 3525 1650 3900
2 1 0 1 -1 3 0 0 20 0.000 0 0 -1 0 1 2
1 1 1.00 60.00 120.00
2325 3525 1725 3900
2 1 0 1 -1 3 0 0 20 0.000 0 0 -1 0 1 2
1 1 1.00 60.00 120.00
1575 4350 1200 4725
2 1 0 1 -1 3 0 0 20 0.000 0 0 -1 0 1 2
1 1 1.00 60.00 120.00
1800 4350 2325 4725
2 1 0 1 -1 3 0 0 20 0.000 0 0 -1 0 1 2
1 1 1.00 60.00 120.00
1200 5175 1725 5475
2 1 0 1 -1 3 0 0 20 0.000 0 0 -1 0 1 2
1 1 1.00 60.00 120.00
2400 5175 1875 5475
2 1 0 1 -1 3 0 0 20 0.000 0 0 -1 0 1 2
1 1 1.00 60.00 120.00
1800 5925 1575 6825
2 1 0 1 -1 3 0 0 20 0.000 0 0 -1 0 1 2
1 1 1.00 60.00 120.00
1725 2625 1200 3075
2 1 0 1 -1 3 0 0 20 0.000 0 0 -1 0 1 2
1 1 1.00 60.00 120.00
1875 2625 2325 3075
2 1 1 1 -1 3 0 0 -1 4.000 0 0 -1 0 0 1
1425 4800
2 1 0 1 -1 3 0 0 20 0.000 0 0 -1 0 1 2
1 1 1.00 60.00 120.00
1650 1575 1725 2175
2 2 0 1 0 7 100 0 -1 0.000 0 0 7 0 0 5
675 6825 1950 6825 1950 7350 675 7350 675 6825
2 2 0 1 0 7 100 0 -1 0.000 0 0 7 0 0 5
1425 5475 2100 5475 2100 5925 1425 5925 1425 5475
2 2 0 1 0 7 100 0 -1 0.000 0 0 7 0 0 5
1950 4725 2625 4725 2625 5175 1950 5175 1950 4725
2 2 0 1 0 7 100 0 -1 0.000 0 0 7 0 0 5
900 4725 1575 4725 1575 5175 900 5175 900 4725
2 2 0 1 0 7 100 0 -1 0.000 0 0 7 0 0 5
1350 3900 2025 3900 2025 4350 1350 4350 1350 3900
2 2 0 1 0 7 100 0 -1 0.000 0 0 7 0 0 5
900 3075 1575 3075 1575 3525 900 3525 900 3075
2 2 0 1 0 7 100 0 -1 0.000 0 0 7 0 0 5
1950 3075 2625 3075 2625 3525 1950 3525 1950 3075
2 2 0 1 0 7 100 0 -1 0.000 0 0 7 0 0 5
1500 2175 2175 2175 2175 2625 1500 2625 1500 2175
2 2 0 1 0 7 100 0 -1 0.000 0 0 7 0 0 5
975 975 2325 975 2325 1575 975 1575 975 975
3 2 0 1 -1 3 0 0 -1 0.000 0 0 1 4
1 1 1.00 60.00 120.00
1050 3525 600 4350 525 5550 1050 6825
0.000 -1.000 -1.000 0.000
3 2 0 1 -1 3 0 0 -1 0.000 0 0 1 7
1 1 1.00 60.00 120.00
2025 5925 2625 6075 3075 4800 3000 2550 2325 1800 2025 1800
1875 2175
0.000 -1.000 -1.000 -1.000 -1.000 -1.000 0.000
4 0 -1 0 0 18 14 0.0000 4 165 150 1725 2550 A\001
4 0 -1 0 0 18 14 0.0000 4 165 150 1125 3450 B\001
4 0 -1 0 0 18 14 0.0000 4 165 165 2250 3450 C\001
4 0 -1 0 0 18 14 0.0000 4 165 165 1575 4200 D\001
4 0 -1 0 0 18 14 0.0000 4 165 135 1125 5025 E\001
4 0 -1 0 0 18 14 0.0000 4 165 135 2250 5025 F\001
4 0 -1 0 0 18 14 0.0000 4 165 165 1650 5775 G\001
4 0 -1 0 0 18 14 0.0000 4 165 735 1350 1425 ENTRY\001
4 0 -1 0 0 18 14 0.0000 4 165 450 975 7125 EXIT\001
4 0 -1 0 0 18 14 0.0000 4 165 120 1275 2925 T\001
4 0 -1 0 0 18 14 0.0000 4 165 135 2175 2925 F\001
4 0 -1 0 0 18 14 0.0000 4 165 120 750 3825 T\001
4 0 -1 0 0 18 14 0.0000 4 165 135 1275 3825 F\001
4 0 -1 0 0 18 14 0.0000 4 165 120 1200 4575 T\001
4 0 -1 0 0 18 14 0.0000 4 165 135 2175 4575 F\001
4 0 -1 0 0 18 14 0.0000 4 165 120 1575 6300 T\001
4 0 -1 0 0 18 14 0.0000 4 165 135 2100 6225 F\001
+85
View File
@@ -0,0 +1,85 @@
#FIG 3.2
Portrait
Center
Inches
Letter
100.00
Single
-2
1200 2
2 1 0 1 -1 3 0 0 20 0.000 0 0 -1 1 0 2
1 1 1.00 60.00 120.00
1200 3525 1650 3900
2 1 0 1 -1 3 0 0 20 0.000 0 0 -1 1 0 2
1 1 1.00 60.00 120.00
2325 3525 1725 3900
2 1 0 1 -1 3 0 0 20 0.000 0 0 -1 1 0 2
1 1 1.00 60.00 120.00
1575 4350 1200 4725
2 1 0 1 -1 3 0 0 20 0.000 0 0 -1 1 0 2
1 1 1.00 60.00 120.00
1800 4350 2325 4725
2 1 0 1 -1 3 0 0 20 0.000 0 0 -1 1 0 2
1 1 1.00 60.00 120.00
1200 5175 1725 5475
2 1 0 1 -1 3 0 0 20 0.000 0 0 -1 1 0 2
1 1 1.00 60.00 120.00
2400 5175 1875 5475
2 1 0 1 -1 3 0 0 20 0.000 0 0 -1 1 0 2
1 1 1.00 60.00 120.00
1800 5925 1575 6825
2 1 0 1 -1 3 0 0 20 0.000 0 0 -1 1 0 2
1 1 1.00 60.00 120.00
1650 1575 1725 2175
2 2 0 1 -1 3 0 0 -1 0.000 0 0 -1 0 0 5
900 3075 1575 3075 1575 3525 900 3525 900 3075
2 2 0 1 -1 3 0 0 -1 0.000 0 0 -1 0 0 5
1950 3075 2625 3075 2625 3525 1950 3525 1950 3075
2 2 0 1 -1 3 0 0 -1 0.000 0 0 -1 0 0 5
1350 3900 2025 3900 2025 4350 1350 4350 1350 3900
2 2 0 1 -1 3 0 0 -1 0.000 0 0 -1 0 0 5
1950 4725 2625 4725 2625 5175 1950 5175 1950 4725
2 2 0 1 -1 3 0 0 -1 0.000 0 0 -1 0 0 5
1500 2175 2175 2175 2175 2625 1500 2625 1500 2175
2 2 0 1 -1 3 0 0 -1 0.000 0 0 -1 0 0 5
1425 5475 2100 5475 2100 5925 1425 5925 1425 5475
2 1 0 1 -1 3 0 0 20 0.000 0 0 -1 1 0 2
1 1 1.00 60.00 120.00
1725 2625 1200 3075
2 1 0 1 -1 3 0 0 20 0.000 0 0 -1 1 0 2
1 1 1.00 60.00 120.00
1875 2625 2325 3075
2 1 1 1 -1 3 0 0 -1 4.000 0 0 -1 0 0 1
1425 4800
2 2 0 1 -1 3 0 0 -1 0.000 0 0 -1 0 0 5
975 975 2325 975 2325 1575 975 1575 975 975
2 2 0 1 -1 3 0 0 -1 0.000 0 0 -1 0 0 5
675 6825 1950 6825 1950 7350 675 7350 675 6825
2 2 0 1 -1 3 0 0 -1 0.000 0 0 -1 0 0 5
900 4725 1575 4725 1575 5175 900 5175 900 4725
3 2 0 1 -1 3 0 0 -1 0.000 0 1 0 4
1 1 1.00 60.00 120.00
1050 3525 600 4350 525 5550 1050 6825
0.000 -1.000 -1.000 0.000
3 2 0 1 -1 3 0 0 -1 0.000 0 1 0 7
1 1 1.00 60.00 120.00
2025 5925 2625 6075 3075 4800 3000 2550 2325 1800 2025 1800
1875 2175
0.000 -1.000 -1.000 -1.000 -1.000 -1.000 0.000
4 0 -1 0 0 18 14 0.0000 4 165 150 1725 2550 A\001
4 0 -1 0 0 18 14 0.0000 4 165 150 1125 3450 B\001
4 0 -1 0 0 18 14 0.0000 4 165 165 2250 3450 C\001
4 0 -1 0 0 18 14 0.0000 4 165 165 1575 4200 D\001
4 0 -1 0 0 18 14 0.0000 4 165 135 1125 5025 E\001
4 0 -1 0 0 18 14 0.0000 4 165 135 2250 5025 F\001
4 0 -1 0 0 18 14 0.0000 4 165 165 1650 5775 G\001
4 0 -1 0 0 18 14 0.0000 4 165 735 1350 1425 ENTRY\001
4 0 -1 0 0 18 14 0.0000 4 165 450 975 7125 EXIT\001
4 0 -1 0 0 18 14 0.0000 4 165 120 1275 2925 T\001
4 0 -1 0 0 18 14 0.0000 4 165 135 2175 2925 F\001
4 0 -1 0 0 18 14 0.0000 4 165 120 750 3825 T\001
4 0 -1 0 0 18 14 0.0000 4 165 135 1275 3825 F\001
4 0 -1 0 0 18 14 0.0000 4 165 120 1200 4575 T\001
4 0 -1 0 0 18 14 0.0000 4 165 135 2175 4575 F\001
4 0 -1 0 0 18 14 0.0000 4 165 120 1575 6300 T\001
4 0 -1 0 0 18 14 0.0000 4 165 135 2100 6225 F\001
+35
View File
@@ -0,0 +1,35 @@
#FIG 3.2
Portrait
Center
Inches
Letter
100.00
Single
0
1200 2
5 1 0 1 0 7 0 0 -1 0.000 0 1 1 0 8256.137 3282.955 8250 3675 8625 3150 7875 3375
1 1 1.00 60.00 120.00
2 1 0 1 -1 7 0 0 -1 0.000 0 0 -1 0 0 5
4540 4367 5115 4367 5307 3409 4732 3409 4540 4367
2 2 0 1 -1 29 0 0 20 0.000 0 0 -1 0 0 5
8753 3075 9136 3075 9136 5132 8753 5132 8753 3075
2 2 0 2 -1 11 1 0 20 0.000 0 0 -1 0 0 5
7221 3409 8226 3409 8226 4367 7221 4367 7221 3409
2 2 0 2 -1 2 1 0 20 0.000 0 0 -1 0 0 5
5689 3409 6694 3409 6694 4367 5689 4367 5689 3409
2 1 0 1 0 7 0 0 -1 0.000 0 0 -1 1 0 2
1 1 1.00 60.00 120.00
5175 3900 5700 3900
2 1 0 1 0 7 0 0 -1 0.000 0 0 -1 1 0 2
1 1 1.00 60.00 120.00
6675 3900 7200 3900
2 1 0 1 0 7 0 0 -1 0.000 0 0 -1 1 0 2
1 1 1.00 60.00 120.00
8250 3900 8775 3900
4 1 -1 0 0 26 10 0.0000 4 135 574 6120 3936 lex/yacc\001
4 1 -1 0 0 26 9 0.0000 4 106 508 4827 4654 Source\001
4 1 -1 0 0 26 9 0.0000 4 135 622 4827 4826 Program\001
4 1 -1 0 0 26 9 0.0000 4 106 612 8944 5467 Abstract\001
4 1 -1 0 0 26 9 0.0000 4 106 632 8944 5639 machine\001
4 1 -1 0 0 26 9 0.0000 4 95 862 8944 5811 instructions\001
4 0 0 0 0 26 9 0.0000 4 124 632 7461 3936 optimize\001
+73
View File
@@ -0,0 +1,73 @@
#FIG 3.2
Portrait
Center
Inches
Letter
100.00
Single
0
1200 2
5 1 0 1 0 7 0 0 -1 0.000 0 1 1 0 5556.137 4182.955 5550 4575 5925 4050 5175 4275
1 1 1.00 60.00 120.00
6 6825 4200 7125 5475
4 1 0 0 0 2 12 0.0000 4 135 165 6975 4350 M\001
4 1 0 0 0 2 12 0.0000 4 135 120 6975 4575 L\001
4 1 0 0 0 2 12 0.0000 4 135 135 6975 4800 R\001
4 1 0 0 0 2 12 0.0000 4 135 45 6975 5025 i\001
4 1 0 0 0 2 12 0.0000 4 90 90 6975 5250 s\001
4 1 0 0 0 2 12 0.0000 4 90 90 6975 5475 c\001
-6
2 1 0 1 -1 7 0 0 -1 0.000 0 0 -1 0 0 5
1840 5267 2415 5267 2607 4309 2032 4309 1840 5267
2 2 0 2 -1 11 1 0 20 0.000 0 0 -1 0 0 5
4521 4309 5526 4309 5526 5267 4521 5267 4521 4309
2 2 0 2 -1 2 1 0 20 0.000 0 0 -1 0 0 5
2989 4309 3994 4309 3994 5267 2989 5267 2989 4309
2 1 0 1 0 7 0 0 -1 0.000 0 0 -1 1 0 2
1 1 1.00 60.00 120.00
2475 4800 3000 4800
2 1 0 1 0 7 0 0 -1 0.000 0 0 -1 1 0 2
1 1 1.00 60.00 120.00
3975 4800 4500 4800
2 2 0 1 -1 30 0 0 20 0.000 0 0 -1 0 0 5
6053 3975 6436 3975 6436 6032 6053 6032 6053 3975
2 1 0 1 0 7 0 0 -1 0.000 0 0 -1 1 0 2
1 1 1.00 60.00 120.00
5550 4950 6900 5625
2 1 0 1 0 7 0 0 -1 0.000 0 0 -1 1 0 2
1 1 1.00 60.00 120.00
5550 4725 6900 4050
2 1 0 1 4 7 0 0 -1 0.000 0 0 -1 1 0 2
1 1 1.00 60.00 120.00
7125 4875 7425 5025
2 1 0 1 4 7 0 0 -1 0.000 0 0 -1 1 0 2
1 1 1.00 60.00 120.00
7125 4725 7425 4575
2 1 0 1 4 7 0 0 -1 0.000 0 0 -1 1 0 2
1 1 1.00 60.00 120.00
7125 4650 7500 4275
2 1 1 1 0 7 0 0 -1 4.000 0 0 -1 1 0 2
1 1 1.00 60.00 120.00
5550 4800 6075 4800
2 1 0 1 4 7 0 0 -1 0.000 0 0 -1 1 0 2
1 1 1.00 60.00 120.00
7125 4950 7575 5400
2 1 0 1 4 7 0 0 -1 0.000 0 0 -1 1 0 2
1 1 1.00 60.00 120.00
7125 5025 7425 5700
2 1 0 1 4 7 0 0 -1 0.000 0 0 -1 1 0 2
1 1 1.00 60.00 120.00
7125 4500 7350 3975
4 1 -1 0 0 26 10 0.0000 4 150 705 3420 4836 lex/yacc\001
4 1 -1 0 0 26 9 0.0000 4 90 480 2127 5554 Source\001
4 1 -1 0 0 26 9 0.0000 4 120 570 2127 5726 Program\001
4 1 -1 0 0 26 9 0.0000 4 90 525 6244 6367 Abstract\001
4 1 -1 0 0 26 9 0.0000 4 90 585 6244 6539 machine\001
4 1 -1 0 0 26 9 0.0000 4 90 825 6244 6711 instructions\001
4 0 0 0 0 26 9 0.0000 4 120 630 4761 4836 optimize\001
4 0 0 0 0 26 9 0.0000 4 120 390 7380 4247 Alpha\001
4 0 0 0 0 26 9 0.0000 4 120 360 7421 4654 Hppa\001
4 0 0 0 0 26 9 0.0000 4 90 255 7461 5102 X86\001
4 0 0 0 0 26 9 0.0000 4 90 270 7502 5509 PPC\001
4 0 0 0 0 26 9 0.0000 4 120 375 7425 5850 Sparc\001
4 0 0 0 0 26 9 0.0000 4 90 255 7350 3975 C6x\001
+41
View File
@@ -0,0 +1,41 @@
#FIG 3.2
Portrait
Center
Inches
Letter
100.00
Single
0
1200 2
2 1 0 1 -1 7 0 0 -1 0.000 0 0 -1 0 0 5
1800 5100 2700 5100 3000 3600 2100 3600 1800 5100
2 1 0 3 -1 7 0 0 -1 0.000 0 0 -1 1 0 2
0 0 3.00 180.00 360.00
2925 4500 3525 4500
2 1 0 3 -1 7 0 0 -1 0.000 0 0 -1 1 0 2
0 0 3.00 180.00 360.00
5250 4500 5925 4500
2 1 0 3 -1 7 0 0 -1 0.000 0 0 -1 1 0 2
0 0 3.00 180.00 360.00
7650 4500 8325 4500
2 2 0 1 -1 29 0 0 20 0.000 0 0 -1 0 0 5
8400 3075 9000 3075 9000 6300 8400 6300 8400 3075
2 2 0 2 -1 11 1 0 20 0.000 0 0 -1 0 0 5
6000 3600 7575 3600 7575 5100 6000 5100 6000 3600
2 2 0 2 -1 2 1 0 20 0.000 0 0 -1 0 0 5
3600 3600 5175 3600 5175 5100 3600 5100 3600 3600
3 2 0 2 -1 7 0 0 -1 0.000 0 1 0 6
0 0 2.00 120.00 240.00
7575 3900 7800 3600 7800 3300 7425 3150 7125 3300 7125 3600
0.000 -1.000 -1.000 -1.000 -1.000 0.000
4 1 -1 0 0 26 16 0.0000 4 225 1035 4275 4425 lex/yacc\001
4 1 -1 0 0 26 14 0.0000 4 165 795 2250 5550 Source\001
4 1 -1 0 0 26 14 0.0000 4 210 975 2250 5820 Program\001
4 1 -1 0 0 26 14 0.0000 4 165 960 8700 6825 Abstract\001
4 1 -1 0 0 26 14 0.0000 4 165 990 8700 7095 machine\001
4 1 -1 0 0 26 14 0.0000 4 150 1350 8700 7365 instructions\001
4 0 7 0 0 26 16 0.0000 4 225 765 10950 3300 Alpha\001
4 0 7 0 0 26 16 0.0000 4 225 705 11025 4050 Hppa\001
4 0 7 0 0 26 16 0.0000 4 180 480 11100 4875 X86\001
4 0 7 0 0 26 16 0.0000 4 180 585 11175 5625 PPC\001
4 0 0 0 0 26 14 0.0000 4 195 990 6375 4425 optimize\001
+65
View File
@@ -0,0 +1,65 @@
#FIG 3.2
Portrait
Center
Inches
Letter
100.00
Single
-2
1200 2
2 1 0 1 7 7 0 0 -1 0.000 0 0 -1 0 0 5
1800 5100 2700 5100 3000 3600 2100 3600 1800 5100
2 2 0 2 7 7 0 0 20 0.000 0 0 -1 0 0 5
3600 3600 5175 3600 5175 5100 3600 5100 3600 3600
2 2 0 2 7 7 0 0 20 0.000 0 0 -1 0 0 5
6000 3600 7575 3600 7575 5100 6000 5100 6000 3600
2 1 0 3 7 7 0 0 -1 0.000 0 0 -1 1 0 2
0 0 3.00 180.00 360.00
7650 4500 8325 4500
2 1 0 3 7 7 0 0 -1 0.000 0 0 -1 1 0 2
0 0 3.00 180.00 360.00
5250 4500 5925 4500
2 1 0 3 7 7 0 0 -1 0.000 0 0 -1 1 0 2
0 0 3.00 180.00 360.00
2925 4500 3525 4500
2 2 0 1 7 7 0 0 20 0.000 0 0 -1 0 0 5
8400 3075 9000 3075 9000 6300 8400 6300 8400 3075
2 1 0 2 -1 7 0 0 -1 0.000 0 0 -1 1 0 2
0 0 2.00 120.00 240.00
7652 4134 9902 3534
2 1 0 2 0 0 0 0 -1 0.000 0 0 -1 1 0 2
0 0 2.00 120.00 240.00
7671 4748 9921 5648
2 1 0 2 4 7 0 0 -1 0.000 0 0 -1 1 0 2
0 0 2.00 120.00 240.00
10050 4500 11100 3375
2 1 0 2 4 7 0 0 -1 0.000 0 0 -1 1 0 2
0 0 2.00 120.00 240.00
10125 4575 11250 4200
2 1 0 2 4 7 0 0 -1 0.000 0 0 -1 1 0 2
0 0 2.00 120.00 240.00
10125 4800 10950 4800
2 1 0 2 4 7 0 0 -1 0.000 0 0 -1 1 0 2
0 0 2.00 120.00 240.00
10125 5025 11325 5400
3 2 0 2 7 7 0 0 -1 0.000 0 1 0 6
0 0 2.00 120.00 240.00
7575 3900 7800 3600 7800 3300 7425 3150 7125 3300 7125 3600
0.000 -1.000 -1.000 -1.000 -1.000 0.000
4 1 -1 0 0 26 16 0.0000 4 180 240 9900 4050 M\001
4 1 -1 0 0 26 16 0.0000 4 180 180 9900 4335 L\001
4 1 -1 0 0 26 16 0.0000 4 180 210 9900 4620 R\001
4 1 -1 0 0 26 16 0.0000 4 180 90 9900 4905 i\001
4 1 -1 0 0 26 16 0.0000 4 120 120 9900 5190 s\001
4 1 -1 0 0 26 16 0.0000 4 120 135 9900 5475 c\001
4 1 7 0 0 26 14 0.0000 4 210 975 2250 5820 Program\001
4 1 7 0 0 26 14 0.0000 4 165 795 2250 5550 Source\001
4 1 7 0 0 26 16 0.0000 4 225 1035 4275 4425 lex/yacc\001
4 1 7 0 0 26 16 0.0000 4 225 1140 6750 4425 optimize\001
4 1 7 0 0 26 14 0.0000 4 165 960 8700 6825 Abstract\001
4 1 7 0 0 26 14 0.0000 4 165 990 8700 7095 machine\001
4 1 7 0 0 26 14 0.0000 4 150 1350 8700 7365 instructions\001
4 0 0 0 0 26 16 0.0000 4 225 765 10950 3300 Alpha\001
4 0 0 0 0 26 16 0.0000 4 225 705 11025 4050 Hppa\001
4 0 0 0 0 26 16 0.0000 4 180 480 11100 4875 X86\001
4 0 0 0 0 26 16 0.0000 4 180 585 11175 5625 PPC\001
+56
View File
@@ -0,0 +1,56 @@
#FIG 3.1
Portrait
Center
Inches
1200 2
2 2 0 1 -1 3 0 0 20 0.000 0 0 -1 0 0 5
4500 1050 5775 1050 5775 1575 4500 1575 4500 1050
2 2 0 1 -1 3 0 0 20 0.000 0 0 -1 0 0 5
4275 2025 4950 2025 4950 2475 4275 2475 4275 2025
2 2 0 1 -1 3 0 0 20 0.000 0 0 -1 0 0 5
3825 2850 4500 2850 4500 3300 3825 3300 3825 2850
2 2 0 1 -1 3 0 0 20 0.000 0 0 -1 0 0 5
4800 2850 5475 2850 5475 3300 4800 3300 4800 2850
2 2 0 1 -1 3 0 0 20 0.000 0 0 -1 0 0 5
5700 2850 6375 2850 6375 3300 5700 3300 5700 2850
2 2 0 1 -1 3 0 0 20 0.000 0 0 -1 0 0 5
5250 3600 5925 3600 5925 4050 5250 4050 5250 3600
2 2 0 1 -1 3 0 0 20 0.000 0 0 -1 0 0 5
6075 3600 6750 3600 6750 4050 6075 4050 6075 3600
2 2 0 1 -1 3 0 0 20 0.000 0 0 -1 0 0 5
6975 3600 7650 3600 7650 4050 6975 4050 6975 3600
2 2 0 1 -1 3 0 0 20 0.000 0 0 -1 0 0 5
3750 3675 5025 3675 5025 4200 3750 4200 3750 3675
2 1 0 1 -1 3 0 0 20 0.000 0 0 -1 1 0 2
1 1 1.00 60.00 120.00
5025 1575 4650 2025
2 1 0 1 -1 3 0 0 20 0.000 0 0 -1 1 0 2
1 1 1.00 60.00 120.00
4500 2475 4125 2850
2 1 0 1 -1 3 0 0 20 0.000 0 0 -1 1 0 2
1 1 1.00 60.00 120.00
4725 2475 5100 2850
2 1 0 1 -1 3 0 0 20 0.000 0 0 -1 1 0 2
1 1 1.00 60.00 120.00
4875 2475 5925 2850
2 1 0 1 -1 3 0 0 20 0.000 0 0 -1 1 0 2
1 1 1.00 60.00 120.00
5850 3300 5550 3600
2 1 0 1 -1 3 0 0 20 0.000 0 0 -1 1 0 2
1 1 1.00 60.00 120.00
6150 3300 6300 3600
2 1 0 1 -1 3 0 0 20 0.000 0 0 -1 1 0 2
1 1 1.00 60.00 120.00
6300 3300 7275 3600
2 1 0 1 -1 3 0 0 20 0.000 0 0 -1 1 0 2
1 1 1.00 60.00 120.00
4650 2475 4650 3675
4 0 -1 0 0 18 14 0.0000 4 165 705 4800 1425 ENTRY\001
4 0 -1 0 0 18 14 0.0000 4 165 150 4575 2400 A\001
4 0 -1 0 0 18 14 0.0000 4 165 150 4125 3225 B\001
4 0 -1 0 0 18 14 0.0000 4 165 150 5025 3225 C\001
4 0 -1 0 0 18 14 0.0000 4 165 150 5925 3150 D\001
4 0 -1 0 0 18 14 0.0000 4 165 135 5550 3900 E\001
4 0 -1 0 0 18 14 0.0000 4 165 135 6300 3900 F\001
4 0 -1 0 0 18 14 0.0000 4 165 165 7200 3900 G\001
4 0 -1 0 0 18 14 0.0000 4 165 465 4125 4050 EXIT\001
+106
View File
@@ -0,0 +1,106 @@
#FIG 3.2
Portrait
Flush left
Inches
Letter
100.00
Single
0
1200 2
2 2 0 1 0 2 0 0 20 0.000 0 0 -1 0 0 5
790 1189 1492 1189 1492 1891 790 1891 790 1189
2 1 0 2 0 4 0 0 20 0.000 0 0 -1 0 0 2
321 1658 790 1658
2 1 0 2 0 4 0 0 20 0.000 0 0 -1 0 0 2
321 1423 790 1423
2 1 0 2 0 4 0 0 20 0.000 0 0 -1 0 0 2
1492 1423 1960 1423
2 1 0 2 0 4 0 0 20 0.000 0 0 -1 0 0 2
1492 1658 1960 1658
2 2 0 1 0 2 0 0 20 0.000 0 0 -1 0 0 5
3941 2023 4643 2023 4643 2725 3941 2725 3941 2023
2 1 0 2 0 4 0 0 20 0.000 0 0 -1 0 0 2
3473 2491 3941 2491
2 1 0 2 0 4 0 0 20 0.000 0 0 -1 0 0 2
3473 2257 3941 2257
2 1 0 2 0 4 0 0 20 0.000 0 0 -1 0 0 2
4643 2257 5111 2257
2 1 0 2 0 4 0 0 20 0.000 0 0 -1 0 0 2
4643 2491 5111 2491
2 2 0 1 0 2 0 0 20 0.000 0 0 -1 0 0 5
3988 75 4689 75 4689 777 3988 777 3988 75
2 1 0 2 0 4 0 0 20 0.000 0 0 -1 0 0 2
3519 543 3988 543
2 1 0 2 0 4 0 0 20 0.000 0 0 -1 0 0 2
3519 309 3988 309
2 1 0 2 0 4 0 0 20 0.000 0 0 -1 0 0 2
4689 309 5158 309
2 1 0 2 0 4 0 0 20 0.000 0 0 -1 0 0 2
4689 543 5158 543
2 1 0 1 0 4 0 0 20 0.000 0 0 -1 0 0 6
1960 1306 1960 1774 2195 1774 2078 1540 2195 1306 1960 1306
2 1 0 1 0 4 0 0 20 0.000 0 0 -1 0 0 6
5112 2193 5112 2669 5350 2669 5232 2430 5350 2193 5112 2193
2 1 0 1 0 4 0 0 20 0.000 0 0 -1 0 0 6
3472 2148 3472 2623 3234 2623 3352 2385 3234 2148 3472 2148
2 1 0 1 0 4 0 0 20 0.000 0 0 -1 0 0 6
3519 201 3519 677 3280 677 3399 438 3280 201 3519 201
2 1 0 1 0 4 0 0 20 0.000 0 0 -1 0 0 6
5159 201 5159 677 5397 677 5278 438 5397 201 5159 201
2 1 0 1 0 4 0 0 20 0.000 0 0 -1 0 0 6
321 1314 321 1789 82 1789 201 1551 82 1314 321 1314
2 2 0 1 0 2 0 0 20 0.000 0 0 -1 0 0 5
790 1189 1492 1189 1492 1891 790 1891 790 1189
2 1 0 2 0 4 0 0 20 0.000 0 0 -1 0 0 2
321 1658 790 1658
2 1 0 2 0 4 0 0 20 0.000 0 0 -1 0 0 2
321 1423 790 1423
2 1 0 2 0 4 0 0 20 0.000 0 0 -1 0 0 2
1492 1423 1960 1423
2 1 0 2 0 4 0 0 20 0.000 0 0 -1 0 0 2
1492 1658 1960 1658
2 2 0 1 0 2 0 0 20 0.000 0 0 -1 0 0 5
3941 2023 4643 2023 4643 2725 3941 2725 3941 2023
2 1 0 2 0 4 0 0 20 0.000 0 0 -1 0 0 2
3473 2491 3941 2491
2 1 0 2 0 4 0 0 20 0.000 0 0 -1 0 0 2
3473 2257 3941 2257
2 1 0 2 0 4 0 0 20 0.000 0 0 -1 0 0 2
4643 2257 5111 2257
2 1 0 2 0 4 0 0 20 0.000 0 0 -1 0 0 2
4643 2491 5111 2491
2 2 0 1 0 2 0 0 20 0.000 0 0 -1 0 0 5
3988 75 4689 75 4689 777 3988 777 3988 75
2 1 0 2 0 4 0 0 20 0.000 0 0 -1 0 0 2
3519 543 3988 543
2 1 0 2 0 4 0 0 20 0.000 0 0 -1 0 0 2
3519 309 3988 309
2 1 0 2 0 4 0 0 20 0.000 0 0 -1 0 0 2
4689 309 5158 309
2 1 0 2 0 4 0 0 20 0.000 0 0 -1 0 0 2
4689 543 5158 543
2 1 0 1 0 4 0 0 20 0.000 0 0 -1 0 0 6
321 1314 321 1789 82 1789 201 1551 82 1314 321 1314
2 1 0 1 0 24 0 0 20 0.000 0 0 -1 0 0 6
1960 1306 1960 1774 2195 1774 2078 1540 2195 1306 1960 1306
2 1 0 1 0 8 0 0 20 0.000 0 0 -1 0 0 6
3519 201 3519 677 3280 677 3399 438 3280 201 3519 201
2 1 0 1 0 8 0 0 20 0.000 0 0 -1 0 0 6
3472 2148 3472 2623 3234 2623 3352 2385 3234 2148 3472 2148
2 1 0 1 0 21 0 0 20 0.000 0 0 -1 0 0 6
5159 201 5159 677 5397 677 5278 438 5397 201 5159 201
2 1 0 1 0 21 0 0 20 0.000 0 0 -1 0 0 6
5112 2193 5112 2669 5350 2669 5232 2430 5350 2193 5112 2193
2 1 0 1 0 7 0 0 -1 0.000 0 0 -1 1 0 2
2 1 1.00 60.00 120.00
2160 1511 3226 723
2 1 0 1 0 7 0 0 -1 0.000 0 0 -1 1 0 2
2 1 1.00 60.00 120.00
2160 1557 3180 2159
4 0 0 0 0 26 8 0.0000 4 120 1020 4060 1186 Floating Pt RA\001
4 0 0 0 0 26 8 0.0000 4 90 540 4848 3178 Functor\001
4 0 0 0 0 26 8 0.0000 4 90 540 5219 1186 Functor\001
4 0 -1 0 0 26 10 0.0000 4 150 1110 307 2345 Higher Order \001
4 0 0 0 0 26 10 0.0000 4 120 645 956 2484 Functor\001
4 0 -1 0 0 26 10 0.0000 4 150 1500 1445 2335 Register Allocator\001
4 0 0 0 0 26 8 0.0000 4 120 705 4014 3178 Integer RA\001
+119
View File
@@ -0,0 +1,119 @@
#FIG 3.2
Portrait
Center
Inches
Letter
100.00
Single
0
1200 2
2 2 0 1 7 4 0 0 -1 0.000 0 0 -1 0 0 5
10800 600 11100 600 11100 900 10800 900 10800 600
2 2 0 1 7 4 0 0 -1 0.000 0 0 -1 0 0 5
10800 600 11100 600 11100 900 10800 900 10800 600
2 2 0 1 0 2 0 0 20 0.000 0 0 -1 0 0 5
1109 1269 1862 1269 1862 2022 1109 2022 1109 1269
2 1 0 2 0 4 0 0 20 0.000 0 0 -1 0 0 2
609 1771 1109 1771
2 1 0 2 0 4 0 0 20 0.000 0 0 -1 0 0 2
609 1519 1109 1519
2 1 0 2 0 4 0 0 20 0.000 0 0 -1 0 0 2
1862 1519 2364 1519
2 1 0 2 0 4 0 0 20 0.000 0 0 -1 0 0 2
1862 1771 2364 1771
2 2 0 1 0 2 0 0 20 0.000 0 0 -1 0 0 5
4486 2161 5238 2161 5238 2915 4486 2915 4486 2161
2 1 0 2 0 4 0 0 20 0.000 0 0 -1 0 0 2
3984 2664 4486 2664
2 1 0 2 0 4 0 0 20 0.000 0 0 -1 0 0 2
3984 2412 4486 2412
2 1 0 2 0 4 0 0 20 0.000 0 0 -1 0 0 2
5238 2412 5739 2412
2 1 0 2 0 4 0 0 20 0.000 0 0 -1 0 0 2
5238 2664 5739 2664
2 2 0 1 0 2 0 0 20 0.000 0 0 -1 0 0 5
4536 75 5287 75 5287 827 4536 827 4536 75
2 1 0 2 0 4 0 0 20 0.000 0 0 -1 0 0 2
4034 577 4536 577
2 1 0 2 0 4 0 0 20 0.000 0 0 -1 0 0 2
4034 326 4536 326
2 1 0 2 0 4 0 0 20 0.000 0 0 -1 0 0 2
5287 326 5789 326
2 1 0 2 0 4 0 0 20 0.000 0 0 -1 0 0 2
5287 577 5789 577
2 1 0 1 0 4 0 0 20 0.000 0 0 -1 0 0 6
2364 1394 2364 1895 2614 1895 2490 1644 2614 1394 2364 1394
2 1 0 1 0 4 0 0 20 0.000 0 0 -1 0 0 6
5740 2345 5740 2854 5996 2854 5868 2598 5996 2345 5740 2345
2 1 0 1 0 4 0 0 20 0.000 0 0 -1 0 0 6
3983 2295 3983 2804 3728 2804 3854 2549 3728 2295 3983 2295
2 1 0 1 0 4 0 0 20 0.000 0 0 -1 0 0 6
4033 210 4033 721 3777 721 3904 465 3777 210 4033 210
2 1 0 1 0 4 0 0 20 0.000 0 0 -1 0 0 6
5790 210 5790 721 6045 721 5917 465 6045 210 5790 210
2 1 0 1 0 4 0 0 20 0.000 0 0 -1 0 0 6
608 1401 608 1912 352 1912 479 1655 352 1401 608 1401
2 2 0 1 0 2 0 0 20 0.000 0 0 -1 0 0 5
1109 1269 1862 1269 1862 2022 1109 2022 1109 1269
2 1 0 2 0 4 0 0 20 0.000 0 0 -1 0 0 2
609 1771 1109 1771
2 1 0 2 0 4 0 0 20 0.000 0 0 -1 0 0 2
609 1519 1109 1519
2 1 0 2 0 4 0 0 20 0.000 0 0 -1 0 0 2
1862 1519 2364 1519
2 1 0 2 0 4 0 0 20 0.000 0 0 -1 0 0 2
1862 1771 2364 1771
2 2 0 1 0 2 0 0 20 0.000 0 0 -1 0 0 5
4486 2161 5238 2161 5238 2915 4486 2915 4486 2161
2 1 0 2 0 4 0 0 20 0.000 0 0 -1 0 0 2
3984 2664 4486 2664
2 1 0 2 0 4 0 0 20 0.000 0 0 -1 0 0 2
3984 2412 4486 2412
2 1 0 2 0 4 0 0 20 0.000 0 0 -1 0 0 2
5238 2412 5739 2412
2 1 0 2 0 4 0 0 20 0.000 0 0 -1 0 0 2
5238 2664 5739 2664
2 2 0 1 0 2 0 0 20 0.000 0 0 -1 0 0 5
4536 75 5287 75 5287 827 4536 827 4536 75
2 1 0 2 0 4 0 0 20 0.000 0 0 -1 0 0 2
4034 577 4536 577
2 1 0 2 0 4 0 0 20 0.000 0 0 -1 0 0 2
4034 326 4536 326
2 1 0 2 0 4 0 0 20 0.000 0 0 -1 0 0 2
5287 326 5789 326
2 1 0 2 0 4 0 0 20 0.000 0 0 -1 0 0 2
5287 577 5789 577
2 1 0 1 0 4 0 0 20 0.000 0 0 -1 0 0 6
608 1401 608 1912 352 1912 479 1655 352 1401 608 1401
2 1 0 1 0 24 0 0 20 0.000 0 0 -1 0 0 6
2364 1394 2364 1895 2614 1895 2490 1644 2614 1394 2364 1394
2 1 0 1 0 8 0 0 20 0.000 0 0 -1 0 0 6
4033 210 4033 721 3777 721 3904 465 3777 210 4033 210
2 1 0 1 0 8 0 0 20 0.000 0 0 -1 0 0 6
3983 2295 3983 2804 3728 2804 3854 2549 3728 2295 3983 2295
2 1 0 1 0 21 0 0 20 0.000 0 0 -1 0 0 6
5790 210 5790 721 6045 721 5917 465 6045 210 5790 210
2 1 0 1 0 21 0 0 20 0.000 0 0 -1 0 0 6
5740 2345 5740 2854 5996 2854 5868 2598 5996 2345 5740 2345
2 1 0 1 0 7 0 0 -1 0.000 0 0 -1 1 0 2
2 1 1.00 60.00 120.00
2578 1613 3719 770
2 1 0 1 0 7 0 0 -1 0.000 0 0 -1 1 0 2
2 1 1.00 60.00 120.00
2578 1663 3670 2309
2 1 0 1 0 8 0 0 20 0.000 0 0 -1 0 0 6
339 1407 96 1407 96 1912 359 1912 480 1649 359 1407
2 1 0 1 0 7 0 0 -1 0.000 0 0 -1 1 0 2
2 1 1.00 60.00 120.00
543 1018 245 1415
4 0 0 0 0 26 9 0.0000 4 120 1020 4613 1266 Floating Pt RA\001
4 0 0 0 0 26 9 0.0000 4 120 705 4563 3400 Integer RA\001
4 0 0 0 0 26 9 0.0000 4 90 540 5458 3400 Functor\001
4 0 0 0 0 26 9 0.0000 4 90 540 5854 1266 Functor\001
4 0 -1 0 0 26 10 0.0000 4 150 1110 592 2507 Higher Order \001
4 0 0 0 0 26 10 0.0000 4 120 645 1288 2655 Functor\001
4 0 -1 0 0 26 10 0.0000 4 150 1500 1685 2507 Register Allocator\001
4 0 0 0 0 26 10 0.0000 4 150 390 444 969 Spec\001
4 0 4 0 0 26 10 0.0000 4 150 870 245 820 DEC Alpha\001
4 0 4 0 0 26 9 0.0000 4 120 705 4613 1068 DEC Alpha\001
4 0 4 0 0 26 9 0.0000 4 120 705 4563 3202 DEC Alpha\001
@@ -0,0 +1,156 @@
#FIG 3.1
Portrait
Center
Inches
1200 2
2 1 0 1 -1 6 0 0 -1 0.000 0 0 -1 1 0 2
1 1 1.00 60.00 120.00
1350 6075 825 7050
2 1 0 1 -1 6 0 0 -1 0.000 0 0 -1 1 0 2
1 1 1.00 60.00 120.00
525 525 1200 1800
2 1 0 1 -1 6 0 0 -1 0.000 0 0 -1 1 0 2
1 1 1.00 60.00 120.00
4875 450 5550 1725
2 1 0 1 -1 6 0 0 -1 0.000 0 0 -1 1 0 2
1 1 1.00 60.00 120.00
5925 6000 4800 6975
2 2 0 1 -1 6 0 0 20 0.000 0 0 -1 0 0 5
5250 1725 6000 1725 6000 2250 5250 2250 5250 1725
2 2 0 1 -1 6 0 0 20 0.000 0 0 -1 0 0 5
4800 2700 5550 2700 5550 3225 4800 3225 4800 2700
2 2 0 1 -1 6 0 0 20 0.000 0 0 -1 0 0 5
4575 3600 5325 3600 5325 4125 4575 4125 4575 3600
2 1 0 1 -1 6 0 0 20 0.000 0 0 -1 1 0 2
1 1 1.00 60.00 120.00
5550 2250 5100 2700
2 1 0 1 -1 6 0 0 20 0.000 0 0 -1 1 0 2
1 1 1.00 60.00 120.00
5100 3225 4875 3600
2 1 0 1 -1 6 0 0 20 0.000 0 0 -1 1 0 2
1 1 1.00 60.00 120.00
5325 3225 6000 4275
2 1 0 1 -1 6 0 0 20 0.000 0 0 -1 1 0 2
1 1 1.00 60.00 120.00
5175 4125 5925 4275
2 1 0 1 -1 6 0 0 20 0.000 0 0 -1 1 0 2
1 1 1.00 60.00 120.00
4950 4125 4800 4425
2 1 0 1 -1 6 0 0 20 0.000 0 0 -1 1 0 2
1 1 1.00 60.00 120.00
4875 4950 5775 5475
2 1 0 1 -1 6 0 0 20 0.000 0 0 -1 1 0 2
1 1 1.00 60.00 120.00
6150 4800 5850 5475
2 1 0 1 -1 6 0 0 20 0.000 0 0 -1 1 0 2
1 1 1.00 60.00 120.00
5775 2250 6525 2925
2 2 0 1 -1 6 0 0 20 0.000 0 0 -1 0 0 5
5400 5475 6450 5475 6450 6000 5400 6000 5400 5475
2 2 0 1 -1 6 0 0 20 0.000 0 0 -1 0 0 5
5775 4275 6750 4275 6750 4800 5775 4800 5775 4275
2 2 0 1 -1 6 0 0 -1 0.000 0 0 -1 0 0 5
6375 2925 7350 2925 7350 3450 6375 3450 6375 2925
2 2 0 1 -1 6 0 0 20 0.000 0 0 -1 0 0 5
4500 4425 5550 4425 5550 4950 4500 4950 4500 4425
2 2 0 1 -1 6 0 0 -1 0.000 0 0 -1 0 0 5
6900 5475 7950 5475 7950 6000 6900 6000 6900 5475
2 1 0 1 -1 6 0 0 -1 0.000 0 0 -1 1 0 2
1 1 1.00 60.00 120.00
6975 3450 7275 5475
2 1 0 1 -1 6 0 0 -1 0.000 0 0 -1 1 0 2
1 1 1.00 60.00 120.00
7425 6000 4875 6975
2 1 0 5 -1 6 0 0 -1 0.000 0 0 -1 1 0 2
1 1 1.00 300.00 300.00
3000 4125 4050 4125
2 2 0 1 -1 6 0 0 20 0.000 0 0 -1 0 0 5
900 1800 1650 1800 1650 2325 900 2325 900 1800
2 2 0 1 -1 6 0 0 20 0.000 0 0 -1 0 0 5
450 2775 1200 2775 1200 3300 450 3300 450 2775
2 2 0 1 -1 6 0 0 20 0.000 0 0 -1 0 0 5
225 3675 975 3675 975 4200 225 4200 225 3675
2 1 0 1 -1 6 0 0 20 0.000 0 0 -1 1 0 2
1 1 1.00 60.00 120.00
1200 2325 750 2775
2 1 0 1 -1 6 0 0 20 0.000 0 0 -1 1 0 2
1 1 1.00 60.00 120.00
750 3300 525 3675
2 1 0 1 -1 6 0 0 20 0.000 0 0 -1 1 0 2
1 1 1.00 60.00 120.00
975 3300 1650 4350
2 1 0 1 -1 6 0 0 20 0.000 0 0 -1 1 0 2
1 1 1.00 60.00 120.00
825 4200 1575 4350
2 1 0 1 -1 6 0 0 20 0.000 0 0 -1 1 0 2
1 1 1.00 60.00 120.00
600 4200 450 4500
2 1 0 1 -1 6 0 0 20 0.000 0 0 -1 1 0 2
1 1 1.00 60.00 120.00
525 5025 1425 5550
2 1 0 1 -1 6 0 0 20 0.000 0 0 -1 1 0 2
1 1 1.00 60.00 120.00
1800 4875 1500 5550
2 1 0 1 -1 6 0 0 20 0.000 0 0 -1 1 0 2
1 1 1.00 60.00 120.00
1425 2325 2175 3000
2 2 0 1 -1 6 0 0 20 0.000 0 0 -1 0 0 5
1050 5550 2100 5550 2100 6075 1050 6075 1050 5550
2 2 0 1 -1 6 0 0 20 0.000 0 0 -1 0 0 5
1425 4350 2400 4350 2400 4875 1425 4875 1425 4350
2 2 0 1 -1 6 0 0 -1 0.000 0 0 -1 0 0 5
2025 3000 3000 3000 3000 3525 2025 3525 2025 3000
2 2 0 1 -1 6 0 0 20 0.000 0 0 -1 0 0 5
150 4500 1200 4500 1200 5025 150 5025 150 4500
2 1 0 1 -1 6 0 0 -1 0.000 0 0 -1 1 0 3
1 1 1.00 60.00 120.00
2625 3525 2625 5025 1650 5550
3 3 1 1 -1 6 0 0 -1 4.000 0 0 0 13
2100 2325 1575 3150 2100 4050 2775 4350 2475 5850 1650 6450
225 6000 75 5100 225 3150 675 1725 1575 1575 2100 2025
2100 2325
2120.95 2253.06 2031.72 2559.48 1580.82 2848.69 1568.80 3471.04
1902.56 3873.14 2239.98 4175.38 2656.70 4121.44 3019.98 4823.33
2694.05 5508.02 2328.92 6078.06 1938.75 6402.97 1227.01 6518.90
527.64 6348.53 40.22 5787.20 84.34 5311.32 54.97 4647.04
138.94 3594.33 290.76 2810.49 326.47 2027.64 887.80 1540.22
1329.37 1506.56 1761.15 1626.87 2019.64 1850.28 2134.87 2100.80
2120.95 2253.06 2031.72 2559.48
3 3 1 1 -1 6 0 0 -1 4.000 0 0 0 13
6300 2325 5775 3150 6300 4050 6975 4350 6675 5850 5850 6450
4425 6000 4275 5100 4425 3150 4875 1725 5775 1575 6300 2025
6300 2325
6320.95 2253.06 6231.72 2559.48 5780.82 2848.69 5768.80 3471.04
6102.56 3873.14 6439.98 4175.38 6856.70 4121.44 7219.98 4823.33
6894.05 5508.02 6528.92 6078.06 6138.75 6402.97 5427.01 6518.90
4727.64 6348.53 4240.22 5787.20 4284.34 5311.32 4254.97 4647.04
4338.94 3594.33 4490.76 2810.49 4526.47 2027.64 5087.80 1540.22
5529.37 1506.56 5961.15 1626.87 6219.64 1850.28 6334.87 2100.80
6320.95 2253.06 6231.72 2559.48
4 0 -1 0 0 14 16 0.0000 4 195 450 5400 2100 x>0\001
4 0 -1 0 0 14 16 0.0000 4 240 450 4875 3150 y>0\001
4 0 -1 0 0 14 16 0.0000 4 195 450 4725 4050 x=1\001
4 0 -1 0 0 14 16 0.0000 4 195 900 4575 4875 v:=v+1\001
4 0 -1 0 0 14 16 0.0000 4 195 900 5850 4800 v:=v-1\001
4 0 -1 0 0 14 16 0.0000 4 180 900 6450 3375 v:=v*x\001
4 0 -1 0 0 14 16 0.0000 4 225 900 5475 5775 u:=v+y\001
4 0 -1 0 0 18 16 0.0000 4 210 75 6150 2475 f\001
4 0 -1 0 0 18 16 0.0000 4 210 75 5175 2475 t\001
4 0 -1 0 0 14 16 0.0000 4 225 900 6975 5775 u:=v+y\001
4 0 -1 0 0 14 16 0.0000 4 195 450 1050 2175 x>0\001
4 0 -1 0 0 14 16 0.0000 4 240 450 525 3225 y>0\001
4 0 -1 0 0 14 16 0.0000 4 195 450 375 4125 x=1\001
4 0 -1 0 0 14 16 0.0000 4 195 900 225 4950 v:=v+1\001
4 0 -1 0 0 14 16 0.0000 4 195 900 1500 4875 v:=v-1\001
4 0 -1 0 0 14 16 0.0000 4 180 900 2100 3450 v:=v*x\001
4 0 -1 0 0 14 16 0.0000 4 225 900 1125 5850 u:=v+y\001
4 0 -1 0 0 18 16 0.0000 4 210 75 1800 2550 f\001
4 0 -1 0 0 18 16 0.0000 4 210 75 825 2550 t\001
4 0 -1 0 0 18 16 0.0000 4 210 75 525 3600 t\001
4 0 -1 0 0 18 16 0.0000 4 210 75 1200 3600 f\001
4 0 -1 0 0 18 16 0.0000 4 210 75 1200 4275 f\001
4 0 -1 0 0 18 16 0.0000 4 210 75 375 4500 t\001
4 0 -1 0 0 18 16 0.0000 4 210 75 4875 3525 t\001
4 0 -1 0 0 18 16 0.0000 4 210 75 5550 3525 f\001
4 0 -1 0 0 18 16 0.0000 4 210 75 4725 4425 t\001
4 0 -1 0 0 18 16 0.0000 4 210 75 5550 4200 f\001
+79
View File
@@ -0,0 +1,79 @@
#FIG 3.2
Landscape
Center
Inches
Letter
100.00
Single
-2
1200 2
2 2 0 1 0 4 100 0 -1 4.000 0 0 -1 0 0 5
150 2625 2625 2625 2625 7725 150 7725 150 2625
2 2 0 3 0 4 100 0 10 0.000 0 0 -1 0 0 5
1558 5263 2277 5263 2277 5598 1558 5598 1558 5263
2 2 0 3 0 4 100 0 10 0.000 0 0 -1 0 0 5
1079 5886 1798 5886 1798 6221 1079 6221 1079 5886
2 2 0 3 0 4 100 0 10 0.000 0 0 -1 0 0 5
1127 4640 1846 4640 1846 4975 1127 4975 1127 4640
2 2 0 3 0 4 100 0 10 0.000 0 0 -1 0 0 5
648 3969 1367 3969 1367 4304 648 4304 648 3969
2 1 0 3 0 4 100 0 10 0.000 0 0 -1 1 0 2
1 1 4.00 38.33 76.66
983 4304 1415 4640
2 1 0 3 0 4 100 0 10 0.000 0 0 -1 1 0 2
1 1 4.00 38.33 76.66
888 4304 888 5263
2 1 0 3 0 4 100 0 10 0.000 0 0 -1 1 0 2
1 1 4.00 38.33 76.66
1463 4975 983 5263
2 1 0 3 0 4 100 0 10 0.000 0 0 -1 1 0 2
1 1 4.00 38.33 76.66
1463 4975 1846 5215
2 1 0 3 0 4 100 0 10 0.000 0 0 -1 1 0 2
1 1 4.00 38.33 76.66
983 5598 1367 5886
2 1 0 3 0 4 100 0 10 0.000 0 0 -1 1 0 2
1 1 4.00 38.33 76.66
1894 5598 1463 5886
2 1 0 3 0 4 100 0 10 0.000 0 0 -1 1 0 2
1 1 4.00 38.33 76.66
935 3298 935 3969
2 2 0 3 0 4 100 0 -1 0.000 0 0 -1 0 0 5
1127 6796 1894 6796 1894 7227 1127 7227 1127 6796
2 2 0 3 0 4 100 0 -1 0.000 0 0 -1 0 0 5
744 2963 1367 2963 1367 3298 744 3298 744 2963
2 2 0 3 0 4 100 0 -1 0.000 0 0 -1 0 0 5
1654 3394 2229 3394 2229 3730 1654 3730 1654 3394
2 1 0 3 0 4 100 0 -1 0.000 0 0 -1 1 0 2
1 1 4.00 38.33 76.66
2038 3730 1942 5215
2 2 0 3 0 4 100 0 10 0.000 0 0 -1 0 0 5
648 5263 1367 5263 1367 5598 648 5598 648 5263
2 2 0 3 0 4 100 0 10 0.000 0 0 -1 0 0 5
3450 3825 4200 3825 4200 6225 3450 6225 3450 3825
2 2 0 3 0 4 100 0 -1 0.000 0 0 -1 0 0 5
4344 3265 4967 3265 4967 3600 4344 3600 4344 3265
2 2 0 3 0 4 100 0 -1 0.000 0 0 -1 0 0 5
3519 6790 4142 6790 4142 7125 3519 7125 3519 6790
2 2 0 3 0 4 100 0 -1 0.000 0 0 -1 0 0 5
4477 4690 5100 4690 5100 5025 4477 5025 4477 4690
2 2 0 3 0 4 100 0 -1 0.000 0 0 -1 0 0 5
3369 2965 3992 2965 3992 3300 3369 3300 3369 2965
2 1 0 3 0 4 100 0 10 0.000 0 0 -1 1 0 2
1 1 4.00 38.33 76.66
1415 6221 1415 6844
2 1 0 3 0 4 100 0 10 0.000 0 0 -1 1 0 2
1 1 2.00 60.00 120.00
3750 3375 3750 3825
2 1 0 3 0 4 100 0 10 0.000 0 0 -1 1 0 2
1 1 2.00 60.00 120.00
4725 3600 4725 4725
2 1 0 3 0 4 100 0 10 0.000 0 0 -1 1 0 2
1 1 2.00 60.00 120.00
3825 6225 3825 6825
2 1 0 3 0 4 100 0 10 0.000 0 0 -1 1 0 2
1 1 2.00 60.00 120.00
4650 5025 4125 6825
2 1 0 12 15 4 100 0 10 0.000 0 0 -1 1 0 2
1 1 12.00 180.00 90.00
2700 5025 3375 5025
+19
View File
@@ -0,0 +1,19 @@
#FIG 3.2
Landscape
Center
Inches
Letter
100.00
Single
-2
1200 2
2 1 0 1 0 26 100 0 20 0.000 0 0 -1 0 0 4
3375 7275 1275 8100 5400 8100 3375 7275
2 1 0 1 0 22 100 0 20 0.000 0 0 -1 0 0 4
3375 6750 1275 7575 5400 7575 3375 6750
2 1 0 1 0 18 100 0 20 0.000 0 0 -1 0 0 4
3375 6225 1275 7050 5400 7050 3375 6225
2 1 0 1 14 26 100 0 20 0.000 0 0 -1 0 0 4
3375 5700 1275 6525 5400 6525 3375 5700
2 1 0 1 0 10 100 0 20 0.000 0 0 -1 0 0 4
3375 5175 1275 6000 5400 6000 3375 5175
+346
View File
@@ -0,0 +1,346 @@
#FIG 3.2
Landscape
Center
Inches
Letter
100.00
Single
-2
1200 2
6 6698 75 9600 2475
6 7289 840 9097 2301
2 2 0 1 -1 3 0 0 20 0.000 0 0 -1 0 0 5
7636 840 8228 840 8228 1084 7636 1084 7636 840
2 2 0 1 -1 3 0 0 20 0.000 0 0 -1 0 0 5
7532 1292 7845 1292 7845 1501 7532 1501 7532 1292
2 2 0 1 -1 3 0 0 20 0.000 0 0 -1 0 0 5
7324 1675 7636 1675 7636 1884 7324 1884 7324 1675
2 2 0 1 -1 3 0 0 20 0.000 0 0 -1 0 0 5
7776 1675 8089 1675 8089 1884 7776 1884 7776 1675
2 2 0 1 -1 3 0 0 20 0.000 0 0 -1 0 0 5
8193 1675 8505 1675 8505 1884 8193 1884 8193 1675
2 2 0 1 -1 3 0 0 20 0.000 0 0 -1 0 0 5
7985 2023 8297 2023 8297 2232 7985 2232 7985 2023
2 2 0 1 -1 3 0 0 20 0.000 0 0 -1 0 0 5
8367 2023 8680 2023 8680 2232 8367 2232 8367 2023
2 2 0 1 -1 3 0 0 20 0.000 0 0 -1 0 0 5
8784 2023 9097 2023 9097 2232 8784 2232 8784 2023
2 2 0 1 -1 3 0 0 20 0.000 0 0 -1 0 0 5
7289 2058 7880 2058 7880 2301 7289 2301 7289 2058
2 1 0 1 -1 3 0 0 20 0.000 0 0 -1 1 0 2
1 1 1.00 27.82 55.64
7880 1084 7706 1292
2 1 0 1 -1 3 0 0 20 0.000 0 0 -1 1 0 2
1 1 1.00 27.82 55.64
7636 1501 7463 1675
2 1 0 1 -1 3 0 0 20 0.000 0 0 -1 1 0 2
1 1 1.00 27.82 55.64
7741 1501 7915 1675
2 1 0 1 -1 3 0 0 20 0.000 0 0 -1 1 0 2
1 1 1.00 27.82 55.64
7810 1501 8297 1675
2 1 0 1 -1 3 0 0 20 0.000 0 0 -1 1 0 2
1 1 1.00 27.82 55.64
8262 1884 8124 2023
2 1 0 1 -1 3 0 0 20 0.000 0 0 -1 1 0 2
1 1 1.00 27.82 55.64
8402 1884 8471 2023
2 1 0 1 -1 3 0 0 20 0.000 0 0 -1 1 0 2
1 1 1.00 27.82 55.64
8471 1884 8924 2023
2 1 0 1 -1 3 0 0 20 0.000 0 0 -1 1 0 2
1 1 1.00 27.82 55.64
7706 1501 7706 2058
4 0 -1 0 0 18 7 0.0000 4 75 360 7776 1014 ENTRY\001
4 0 -1 0 0 18 7 0.0000 4 75 75 7671 1466 A\001
4 0 -1 0 0 18 7 0.0000 4 75 75 7463 1849 B\001
4 0 -1 0 0 18 7 0.0000 4 75 75 7880 1849 C\001
4 0 -1 0 0 18 7 0.0000 4 75 75 8297 1814 D\001
4 0 -1 0 0 18 7 0.0000 4 75 60 8124 2162 E\001
4 0 -1 0 0 18 7 0.0000 4 75 60 8471 2162 F\001
4 0 -1 0 0 18 7 0.0000 4 75 75 8889 2162 G\001
4 0 -1 0 0 18 7 0.0000 4 75 225 7463 2232 EXIT\001
-6
2 1 0 1 4 4 100 0 -1 0.000 0 0 -1 0 0 4
7950 110 9549 2440 6733 2440 7950 110
-6
6 6525 2543 10275 5325
6 7251 2724 9568 4297
2 2 0 1 -1 3 0 0 20 0.000 0 0 -1 0 0 5
7831 4297 8534 4297 8534 4007 7831 4007 7831 4297
2 2 0 1 -1 3 0 0 20 0.000 0 0 -1 0 0 5
7582 3800 7954 3800 7954 3552 7582 3552 7582 3800
2 2 0 1 -1 3 0 0 20 0.000 0 0 -1 0 0 5
7251 3386 7623 3386 7623 3138 7251 3138 7251 3386
2 2 0 1 -1 3 0 0 20 0.000 0 0 -1 0 0 5
7706 3386 8078 3386 8078 3138 7706 3138 7706 3386
2 2 0 1 -1 3 0 0 20 0.000 0 0 -1 0 0 5
8202 3386 8574 3386 8574 3138 8202 3138 8202 3386
2 2 0 1 -1 3 0 0 20 0.000 0 0 -1 0 0 5
8948 3800 9319 3800 9319 3552 8948 3552 8948 3800
2 2 0 1 -1 3 0 0 20 0.000 0 0 -1 0 0 5
8368 2973 8740 2973 8740 2724 8368 2724 8368 2973
2 1 0 1 -1 3 0 0 20 0.000 0 0 -1 1 0 2
1 1 1.00 33.10 66.20
8160 4007 7789 3800
2 1 0 1 -1 3 0 0 20 0.000 0 0 -1 1 0 2
1 1 1.00 33.10 66.20
8285 4007 9112 3800
2 2 0 1 -1 3 0 0 20 0.000 0 0 -1 0 0 5
8327 3800 8698 3800 8698 3552 8327 3552 8327 3800
2 2 0 1 -1 3 0 0 20 0.000 0 0 -1 0 0 5
8865 3303 9568 3303 9568 3014 8865 3014 8865 3303
2 1 0 1 -1 3 0 0 20 0.000 0 0 -1 1 0 2
1 1 1.00 33.10 66.20
7665 3552 7457 3386
2 1 0 1 -1 3 0 0 20 0.000 0 0 -1 1 0 2
1 1 1.00 33.10 66.20
7747 3552 7871 3386
2 1 0 1 -1 3 0 0 20 0.000 0 0 -1 1 0 2
1 1 1.00 33.10 66.20
7871 3552 8368 3386
2 1 0 1 -1 3 0 0 20 0.000 0 0 -1 1 0 2
1 1 1.00 33.10 66.20
8410 3138 8534 2973
2 1 0 1 -1 3 0 0 20 0.000 0 0 -1 1 0 2
1 1 1.00 33.10 66.20
8244 4007 8492 3800
2 1 0 1 -1 3 0 0 20 0.000 0 0 -1 1 0 2
1 1 1.00 33.10 66.20
8534 3552 9154 3303
4 0 -1 0 0 18 8 0.0000 4 90 75 7416 3303 E\001
4 0 -1 0 0 18 8 0.0000 4 90 75 7871 3303 F\001
4 0 -1 0 0 18 8 0.0000 4 90 90 8327 3303 D\001
4 0 -1 0 0 18 8 0.0000 4 90 90 8492 2890 C\001
4 0 -1 0 0 18 8 0.0000 4 90 450 8989 3180 ENTRY\001
4 0 -1 0 0 18 8 0.0000 4 90 90 9072 3718 B\001
4 0 -1 0 0 18 8 0.0000 4 90 90 8492 3718 A\001
4 0 -1 0 0 18 8 0.0000 4 90 285 8037 4173 EXIT\001
4 0 -1 0 0 18 8 0.0000 4 90 90 7747 3718 G\001
-6
2 1 0 1 4 4 100 0 -1 0.000 0 0 -1 0 0 4
6585 2603 10215 2603 8400 5265 6585 2603
-6
6 2925 225 6225 8100
6 3150 750 6000 7125
2 1 0 1 -1 3 0 0 20 0.000 0 0 -1 1 0 2
1 1 1.00 60.00 120.00
3975 3300 4425 3675
2 1 0 1 -1 3 0 0 20 0.000 0 0 -1 1 0 2
1 1 1.00 60.00 120.00
5100 3300 4500 3675
2 1 0 1 -1 3 0 0 20 0.000 0 0 -1 1 0 2
1 1 1.00 60.00 120.00
4350 4125 3975 4500
2 1 0 1 -1 3 0 0 20 0.000 0 0 -1 1 0 2
1 1 1.00 60.00 120.00
4575 4125 5100 4500
2 1 0 1 -1 3 0 0 20 0.000 0 0 -1 1 0 2
1 1 1.00 60.00 120.00
3975 4950 4500 5250
2 1 0 1 -1 3 0 0 20 0.000 0 0 -1 1 0 2
1 1 1.00 60.00 120.00
5175 4950 4650 5250
2 1 0 1 -1 3 0 0 20 0.000 0 0 -1 1 0 2
1 1 1.00 60.00 120.00
4575 5700 4350 6600
2 1 0 1 -1 3 0 0 20 0.000 0 0 -1 1 0 2
1 1 1.00 60.00 120.00
4425 1350 4500 1950
2 2 0 1 -1 3 0 0 20 0.000 0 0 -1 0 0 5
3675 2850 4350 2850 4350 3300 3675 3300 3675 2850
2 2 0 1 -1 3 0 0 20 0.000 0 0 -1 0 0 5
4725 2850 5400 2850 5400 3300 4725 3300 4725 2850
2 2 0 1 -1 3 0 0 20 0.000 0 0 -1 0 0 5
4125 3675 4800 3675 4800 4125 4125 4125 4125 3675
2 2 0 1 -1 3 0 0 20 0.000 0 0 -1 0 0 5
4725 4500 5400 4500 5400 4950 4725 4950 4725 4500
2 2 0 1 -1 3 0 0 20 0.000 0 0 -1 0 0 5
4275 1950 4950 1950 4950 2400 4275 2400 4275 1950
2 2 0 1 -1 3 0 0 20 0.000 0 0 -1 0 0 5
4200 5250 4875 5250 4875 5700 4200 5700 4200 5250
2 1 0 1 -1 3 0 0 20 0.000 0 0 -1 1 0 2
1 1 1.00 60.00 120.00
4500 2400 3975 2850
2 1 0 1 -1 3 0 0 20 0.000 0 0 -1 1 0 2
1 1 1.00 60.00 120.00
4650 2400 5100 2850
2 1 1 1 -1 3 0 0 -1 4.000 0 0 -1 0 0 1
4200 4575
2 2 0 1 -1 3 0 0 20 0.000 0 0 -1 0 0 5
3750 750 5100 750 5100 1350 3750 1350 3750 750
2 2 0 1 -1 3 0 0 20 0.000 0 0 -1 0 0 5
3450 6600 4725 6600 4725 7125 3450 7125 3450 6600
2 2 0 1 -1 3 0 0 20 0.000 0 0 -1 0 0 5
3675 4500 4350 4500 4350 4950 3675 4950 3675 4500
3 2 0 1 -1 3 0 0 -1 0.000 0 1 0 4
1 1 1.00 60.00 120.00
3825 3300 3375 4125 3300 5325 3825 6600
0.000 -1.000 -1.000 0.000
3 2 0 1 -1 3 0 0 -1 0.000 0 1 0 7
1 1 1.00 60.00 120.00
4800 5700 5400 5850 5850 4575 5775 2325 5100 1575 4800 1575
4650 1950
0.000 -1.000 -1.000 -1.000 -1.000 -1.000 0.000
4 0 -1 0 0 18 14 0.0000 4 165 150 4500 2325 A\001
4 0 -1 0 0 18 14 0.0000 4 165 150 3900 3225 B\001
4 0 -1 0 0 18 14 0.0000 4 165 165 5025 3225 C\001
4 0 -1 0 0 18 14 0.0000 4 165 165 4350 3975 D\001
4 0 -1 0 0 18 14 0.0000 4 165 135 3900 4800 E\001
4 0 -1 0 0 18 14 0.0000 4 165 135 5025 4800 F\001
4 0 -1 0 0 18 14 0.0000 4 165 165 4425 5550 G\001
4 0 -1 0 0 18 14 0.0000 4 165 735 4125 1200 ENTRY\001
4 0 -1 0 0 18 14 0.0000 4 165 450 3750 6900 EXIT\001
4 0 -1 0 0 18 14 0.0000 4 165 120 4050 2700 T\001
4 0 -1 0 0 18 14 0.0000 4 165 135 4950 2700 F\001
4 0 -1 0 0 18 14 0.0000 4 165 120 3525 3600 T\001
4 0 -1 0 0 18 14 0.0000 4 165 135 4050 3600 F\001
4 0 -1 0 0 18 14 0.0000 4 165 120 3975 4350 T\001
4 0 -1 0 0 18 14 0.0000 4 165 135 4950 4350 F\001
4 0 -1 0 0 18 14 0.0000 4 165 120 4350 6075 T\001
4 0 -1 0 0 18 14 0.0000 4 165 135 4875 6000 F\001
-6
3 1 0 5 4 4 100 0 -1 0.000 0 0 0 8
5325 675 6150 2925 6000 6000 4725 8025 3150 7575 3000 3150
3675 300 5025 375
1.000 1.000 1.000 1.000 1.000 1.000 1.000 1.000
-6
6 5475 5025 9750 10050
6 5925 5700 8943 9975
2 2 0 1 -1 3 0 0 20 0.000 0 0 -1 0 0 5
7042 7607 7575 7607 7575 7962 7042 7962 7042 7607
2 2 0 1 -1 3 0 0 20 0.000 0 0 -1 0 0 5
6805 9561 7812 9561 7812 9975 6805 9975 6805 9561
2 1 0 1 -1 3 0 0 20 0.000 0 0 -1 1 0 2
1 1 1.00 33.53 67.06
7160 7962 6924 9561
2 2 0 1 -1 3 0 0 20 0.000 0 0 -1 0 0 5
7727 5700 8734 5700 8734 6114 7727 6114 7727 5700
2 1 0 1 -1 3 0 0 20 0.000 0 0 -1 1 0 2
1 1 1.00 33.53 67.06
8063 6120 7708 6415
2 2 0 1 -1 3 0 0 20 0.000 0 0 -1 0 0 5
8021 7586 8554 7586 8554 7942 8021 7942 8021 7586
2 1 0 1 -1 3 0 0 45 0.000 0 0 -1 1 0 2
1 1 1.00 33.53 67.06
7601 6790 7225 7628
2 1 0 1 -1 3 0 0 45 0.000 0 0 -1 1 0 2
1 1 1.00 33.53 67.06
7727 6790 8231 7586
2 2 0 1 -1 3 0 0 20 0.000 0 0 -1 0 0 5
7237 8382 7769 8382 7769 8738 7237 8738 7237 8382
2 1 0 1 -1 3 0 0 45 0.000 0 0 -1 1 0 2
1 1 1.00 33.53 67.06
7267 7963 7351 8382
2 2 0 1 -1 3 0 0 20 0.000 0 0 -1 0 0 5
7937 9011 8470 9011 8470 9366 7937 9366 7937 9011
2 2 0 1 -1 3 0 0 20 0.000 0 0 -1 0 0 5
7183 8969 7716 8969 7716 9324 7183 9324 7183 8969
2 1 0 1 -1 3 0 0 45 0.000 0 0 -1 1 0 2
1 1 1.00 33.53 67.06
7476 8759 7392 8969
2 1 0 1 -1 3 0 0 -1 0.000 0 0 -1 1 0 2
1 1 1.00 33.53 67.06
7643 8759 8063 9011
2 2 0 1 -1 3 0 0 20 0.000 0 0 -1 0 0 5
7404 6393 7937 6393 7937 6748 7404 6748 7404 6393
2 2 0 1 -1 3 0 0 20 0.000 0 0 -1 0 0 5
6440 8341 6973 8341 6973 8696 6440 8696 6440 8341
2 1 0 1 -1 3 0 0 -1 0.000 0 0 -1 1 0 2
1 1 1.00 33.53 67.06
6679 8717 6889 9555
2 1 0 1 -1 3 0 0 -1 0.000 0 0 -1 1 0 2
1 1 1.00 33.53 67.06
7099 7963 6679 8341
2 1 0 1 -1 3 0 0 -1 0.000 0 0 -1 1 0 2
1 1 1.00 33.53 67.06
7685 6748 7643 8382
2 1 0 1 -1 3 0 0 -1 0.000 0 0 -1 1 0 2
1 1 1.00 33.53 67.06
7476 6748 6553 8341
3 2 0 1 -1 3 0 0 -1 0.000 0 1 0 6
1 1 1.00 33.53 67.06
6511 8717 6386 9011 6135 8927 6009 8550 6470 7712 7392 6706
0.000 -1.000 -1.000 -1.000 -1.000 0.000
3 2 0 1 -1 3 0 0 -1 0.000 0 1 0 5
1 1 1.00 33.53 67.06
8357 6120 8817 7418 8733 9011 8440 9681 7811 9849
0.000 -1.000 -1.000 -1.000 0.000
4 0 -1 0 0 18 11 0.0000 4 120 105 7220 7844 B\001
4 0 -1 0 0 18 11 0.0000 4 120 90 7339 8198 F\001
4 0 -1 0 0 18 11 0.0000 4 120 360 7160 9797 EXIT\001
4 0 -1 0 0 18 11 0.0000 4 120 555 7955 5996 ENTRY\001
4 0 -1 0 0 18 11 0.0000 4 120 105 7795 6251 T\001
4 0 -1 0 0 18 11 0.0000 4 120 120 8192 7844 C\001
4 0 -1 0 0 18 11 0.0000 4 120 120 7575 6647 A\001
4 0 -1 0 0 18 11 0.0000 4 120 105 7398 8626 D\001
4 0 -1 0 0 18 11 0.0000 4 120 90 7400 9237 E\001
4 0 -1 0 0 18 11 0.0000 4 120 90 8136 9237 F\001
4 0 -1 0 0 18 11 0.0000 4 120 105 7281 8939 T\001
4 0 -1 0 0 18 11 0.0000 4 120 90 7923 7069 F\001
4 0 -1 0 0 18 11 0.0000 4 120 105 7488 7279 T\001
4 0 -1 0 0 18 11 0.0000 4 120 120 6648 8560 G\001
4 0 -1 0 0 18 11 0.0000 4 120 90 6268 9200 F\001
4 0 -1 0 0 18 11 0.0000 4 120 90 7694 7314 F\001
4 0 -1 0 0 18 11 0.0000 4 120 90 7233 7314 F\001
4 0 -1 0 0 18 11 0.0000 4 120 105 7025 8257 T\001
4 0 -1 0 0 18 11 0.0000 4 120 90 6856 8110 F\001
4 0 -1 0 0 18 11 0.0000 4 120 105 6611 9023 T\001
4 0 -1 0 0 18 11 0.0000 4 120 90 7872 8867 F\001
4 0 -1 0 0 18 11 0.0000 4 120 90 8454 6318 F\001
-6
3 1 0 1 4 4 100 0 -1 4.000 0 0 0 8
7725 5025 9750 6375 9300 9600 7950 10050 6225 10050 5475 8775
6750 5850 7725 5025
1.000 1.000 1.000 1.000 1.000 1.000 1.000 1.000
-6
6 825 900 2550 3000
2 2 0 1 0 24 100 0 10 4.000 0 0 -1 0 0 5
1050 1200 2250 1200 2250 1725 1050 1725 1050 1200
2 2 0 1 0 24 100 0 10 4.000 0 0 -1 0 0 5
1050 2175 2250 2175 2250 2700 1050 2700 1050 2175
2 1 0 1 0 24 100 0 10 0.000 0 0 -1 1 0 2
1 1 1.00 60.00 120.00
1650 1725 1650 2175
2 2 0 1 4 24 100 0 -1 4.000 0 0 -1 0 0 5
825 900 2550 900 2550 3000 825 3000 825 900
-6
2 1 0 5 8 4 100 0 -1 12.000 0 0 -1 1 1 2
1 1 5.00 60.00 120.00
1 1 5.00 60.00 120.00
5550 6675 6225 6975
2 1 0 5 8 4 100 0 -1 12.000 0 0 -1 1 1 2
1 1 5.00 60.00 120.00
1 1 5.00 60.00 120.00
6075 4725 7650 4275
2 1 0 5 8 4 100 0 -1 12.000 0 0 -1 1 1 2
1 1 5.00 60.00 120.00
1 1 5.00 60.00 120.00
5775 1800 7200 1500
2 1 0 5 8 4 100 0 -1 12.000 0 0 -1 1 1 2
1 1 5.00 60.00 120.00
1 1 5.00 60.00 120.00
1703 2999 3087 3451
2 1 0 5 8 4 100 0 -1 12.000 0 0 -1 1 1 2
1 1 5.00 60.00 120.00
1 1 5.00 60.00 120.00
3187 6131 1950 6900
2 1 0 5 8 4 100 0 -1 12.000 0 0 -1 1 1 2
1 1 5.00 60.00 120.00
1 1 5.00 60.00 120.00
3487 7256 2250 8025
2 1 0 5 8 4 100 0 -1 12.000 0 0 -1 1 1 2
1 1 5.00 60.00 120.00
1 1 5.00 60.00 120.00
3071 5302 1645 5602
3 1 1 1 4 24 100 0 -1 4.000 0 0 0 9
1350 5325 1800 6225 2100 7575 2325 8325 1950 9225 1125 9000
375 7125 375 5025 975 4200
1.000 1.000 1.000 1.000 1.000 1.000 1.000 1.000
1.000
4 0 4 100 0 16 24 0.0000 4 360 690 1050 825 loop\001
4 0 4 100 0 16 24 0.0000 4 285 705 8625 825 dom\001
4 0 4 100 0 16 24 0.0000 4 360 915 9525 4050 pdom\001
4 0 4 100 0 16 24 0.0000 4 285 825 9000 5925 CDG\001
4 0 4 100 0 16 36 0.0000 4 405 1110 5400 675 CFG\001
4 0 4 100 0 16 24 5.0615 4 285 1995 825 6150 Other facets\001
@@ -0,0 +1,27 @@
#FIG 3.2
Portrait
Center
Inches
Letter
100.00
Single
0
1200 2
1 2 0 1 0 14 0 0 20 0.000 1 0.0000 5077 4580 38 50 5039 4596 5113 4564
2 1 0 1 -1 24 0 0 20 0.000 0 0 -1 0 0 9
5039 6644 5039 6644 5016 6836 4892 6836 4892 6900 5212 6900
5212 6836 5113 6836 5089 6644
2 1 0 1 0 12 0 0 20 0.000 0 0 -1 0 0 4
4376 6644 5753 6644 5064 6004 4376 6644
2 1 0 1 0 13 0 0 20 0.000 0 0 -1 0 0 4
4475 6132 5654 6132 5064 5620 4475 6132
2 1 0 1 0 14 0 0 20 0.000 0 0 -1 0 0 4
4572 5748 5556 5748 5064 5236 4572 5748
2 1 0 1 0 2 0 0 20 0.000 0 0 -1 0 0 4
4671 5364 5458 5364 5064 4596 4671 5364
4 0 7 0 0 0 12 0.0000 4 15 45 4050 7350 .\001
4 0 7 0 0 0 12 0.0000 4 15 45 6225 4425 .\001
4 0 8 0 0 26 5 0.0000 4 120 555 5630 6004 Regions\001
4 0 8 0 0 26 5 0.0000 4 90 630 5507 5620 Constants\001
4 0 8 0 0 26 5 0.0000 4 120 765 5433 5108 Pseudo Ops\001
4 0 8 0 0 26 5 0.0000 4 90 630 5605 6388 Core RTL\001

Some files were not shown because too many files have changed in this diff Show More