|
@@ -1548,15 +1548,19 @@ a subscript $0$ because later we introduce extended versions of this
|
|
assembly language. The main difference compared to the concrete syntax
|
|
assembly language. The main difference compared to the concrete syntax
|
|
of x86 (Figure~\ref{fig:x86-0-concrete}) is that it does not allow
|
|
of x86 (Figure~\ref{fig:x86-0-concrete}) is that it does not allow
|
|
labeled instructions to appear anywhere, but instead organizes
|
|
labeled instructions to appear anywhere, but instead organizes
|
|
-instructions into a group called a \emph{block}\index{block}\index{basic block}
|
|
|
|
-and associates a label with every block, which is why the \key{CFG} struct
|
|
|
|
-(for control-flow graph) includes an alist mapping labels to
|
|
|
|
-blocks. The reason for this organization becomes apparent in
|
|
|
|
-Chapter~\ref{ch:bool-types} when we introduce conditional
|
|
|
|
-branching. The \code{Block} structure includes an $\itm{info}$ field
|
|
|
|
-that is not needed for this chapter, but will become useful in
|
|
|
|
-Chapter~\ref{ch:register-allocation-r1}. For now, the $\itm{info}$
|
|
|
|
-field should just contain an empty list.
|
|
|
|
|
|
+instructions into a group called a
|
|
|
|
+\emph{block}\index{block}\index{basic block} and associates a label
|
|
|
|
+with every block, which is why the \key{CFG} struct (for control-flow
|
|
|
|
+graph) includes an alist mapping labels to blocks. The reason for this
|
|
|
|
+organization becomes apparent in Chapter~\ref{ch:bool-types} when we
|
|
|
|
+introduce conditional branching. The \code{Block} structure includes
|
|
|
|
+an $\itm{info}$ field that is not needed for this chapter, but will
|
|
|
|
+become useful in Chapter~\ref{ch:register-allocation-r1}. For now,
|
|
|
|
+the $\itm{info}$ field should just contain an empty list. Also,
|
|
|
|
+regarding the abstract syntax for \code{callq}, the \code{Callq}
|
|
|
|
+struct includes an integer for representing the arity of the function,
|
|
|
|
+i.e., the number of arguments, which is helpful to know during
|
|
|
|
+register allocation (Chapter~\ref{ch:register-allocation-r1}).
|
|
|
|
|
|
\begin{figure}[tp]
|
|
\begin{figure}[tp]
|
|
\fbox{
|
|
\fbox{
|
|
@@ -1732,7 +1736,6 @@ approach and used all of the registers for variables.
|
|
\path[->,bend left=15] (R1) edge [above] node {\ttfamily\footnotesize uniquify} (R1-2);
|
|
\path[->,bend left=15] (R1) edge [above] node {\ttfamily\footnotesize uniquify} (R1-2);
|
|
\path[->,bend left=15] (R1-2) edge [above] node {\ttfamily\footnotesize remove-complex.} (R1-3);
|
|
\path[->,bend left=15] (R1-2) edge [above] node {\ttfamily\footnotesize remove-complex.} (R1-3);
|
|
\path[->,bend left=15] (R1-3) edge [right] node {\ttfamily\footnotesize explicate-control} (C0-2);
|
|
\path[->,bend left=15] (R1-3) edge [right] node {\ttfamily\footnotesize explicate-control} (C0-2);
|
|
-%\path[->,bend right=15] (C0-1) edge [above] node {\ttfamily\footnotesize uncover-locals} (C0-2);
|
|
|
|
\path[->,bend right=15] (C0-2) edge [left] node {\ttfamily\footnotesize select-instr.} (x86-2);
|
|
\path[->,bend right=15] (C0-2) edge [left] node {\ttfamily\footnotesize select-instr.} (x86-2);
|
|
\path[->,bend left=15] (x86-2) edge [above] node {\ttfamily\footnotesize assign-homes} (x86-3);
|
|
\path[->,bend left=15] (x86-2) edge [above] node {\ttfamily\footnotesize assign-homes} (x86-3);
|
|
\path[->,bend left=15] (x86-3) edge [above] node {\ttfamily\footnotesize patch-instr.} (x86-4);
|
|
\path[->,bend left=15] (x86-3) edge [above] node {\ttfamily\footnotesize patch-instr.} (x86-4);
|
|
@@ -2347,7 +2350,7 @@ start:
|
|
In the output of \code{select-instructions}, there is a entry for
|
|
In the output of \code{select-instructions}, there is a entry for
|
|
\code{locals-types} in the $\itm{info}$ of the \code{Program} node,
|
|
\code{locals-types} in the $\itm{info}$ of the \code{Program} node,
|
|
which is needed here so that we have the list of variables that should
|
|
which is needed here so that we have the list of variables that should
|
|
-be assigned to homes. The the support code computes the
|
|
|
|
|
|
+be assigned to homes. The support code computes the
|
|
\code{locals-types} entry. In particular, \code{type-check-C0}
|
|
\code{locals-types} entry. In particular, \code{type-check-C0}
|
|
installs it in the $\itm{info}$ field of the \code{Program} node.
|
|
installs it in the $\itm{info}$ field of the \code{Program} node.
|
|
When using \code{interp-tests} or \code{compiler-tests} (see Appendix,
|
|
When using \code{interp-tests} or \code{compiler-tests} (see Appendix,
|
|
@@ -5709,19 +5712,13 @@ the \code{void?} predicate that returns \code{\#t} when applied to
|
|
\end{figure}
|
|
\end{figure}
|
|
|
|
|
|
Figure~\ref{fig:type-check-R3} shows the type checker for $R_3$, which
|
|
Figure~\ref{fig:type-check-R3} shows the type checker for $R_3$, which
|
|
-deserves some explanation. As we see in Section~\ref{sec:GC}, we
|
|
|
|
-need to know which variables contain pointers into the heap, that is,
|
|
|
|
-which variables contain vectors. Also, when allocating a vector, we
|
|
|
|
-need to know which elements of the vector are pointers. We can obtain
|
|
|
|
-this information during type checking. The type checker in
|
|
|
|
|
|
+deserves some explanation. When allocating a vector, we need to know
|
|
|
|
+which elements of the vector are pointers (i.e. are also vectors). We
|
|
|
|
+can obtain this information during type checking. The type checker in
|
|
Figure~\ref{fig:type-check-R3} not only computes the type of an
|
|
Figure~\ref{fig:type-check-R3} not only computes the type of an
|
|
-expression, it also wraps every sub-expression $e$ with the form
|
|
|
|
-$(\key{HasType}~e~T)$, where $T$ is $e$'s type.
|
|
|
|
-Subsequently, in the \code{uncover-locals} pass
|
|
|
|
-(Section~\ref{sec:uncover-locals-r3}) this type information is
|
|
|
|
-propagated to all variables (including the temporaries generated by
|
|
|
|
-\code{remove-complex-opera*}).
|
|
|
|
-
|
|
|
|
|
|
+expression, it also wraps every \key{vector} creation with the form
|
|
|
|
+$(\key{HasType}~e~T)$, where $T$ is the vector's type.
|
|
|
|
+%
|
|
To create the s-expression for the \code{Vector} type in
|
|
To create the s-expression for the \code{Vector} type in
|
|
Figure~\ref{fig:type-check-R3}, we use the
|
|
Figure~\ref{fig:type-check-R3}, we use the
|
|
\href{https://docs.racket-lang.org/reference/quasiquote.html}{unquote-splicing
|
|
\href{https://docs.racket-lang.org/reference/quasiquote.html}{unquote-splicing
|
|
@@ -5730,13 +5727,13 @@ start and end parentheses. \index{unquote-slicing}
|
|
|
|
|
|
|
|
|
|
\begin{figure}[tp]
|
|
\begin{figure}[tp]
|
|
-\begin{lstlisting}[basicstyle=\ttfamily\footnotesize]
|
|
|
|
|
|
+\begin{lstlisting}[basicstyle=\ttfamily\scriptsize]
|
|
(define (type-check-exp env)
|
|
(define (type-check-exp env)
|
|
(lambda (e)
|
|
(lambda (e)
|
|
(define recur (type-check-exp env))
|
|
(define recur (type-check-exp env))
|
|
(match e
|
|
(match e
|
|
...
|
|
...
|
|
- [(Void) (values (HasType (Void) 'Void) 'Void)]
|
|
|
|
|
|
+ [(Void) (values (Void) 'Void)]
|
|
[(Prim 'vector es)
|
|
[(Prim 'vector es)
|
|
(define-values (e* t*) (for/lists (e* t*) ([e es]) (recur e)))
|
|
(define-values (e* t*) (for/lists (e* t*) ([e es]) (recur e)))
|
|
(let ([t `(Vector ,@t*)])
|
|
(let ([t `(Vector ,@t*)])
|
|
@@ -5748,27 +5745,22 @@ start and end parentheses. \index{unquote-slicing}
|
|
(unless (and (exact-nonnegative-integer? i) (< i (length ts)))
|
|
(unless (and (exact-nonnegative-integer? i) (< i (length ts)))
|
|
(error 'type-check-exp "invalid index ~a" i))
|
|
(error 'type-check-exp "invalid index ~a" i))
|
|
(let ([t (list-ref ts i)])
|
|
(let ([t (list-ref ts i)])
|
|
- (values
|
|
|
|
- (HasType (Prim 'vector-ref
|
|
|
|
- (list e^ (HasType (Int i) 'Integer)))
|
|
|
|
- t)
|
|
|
|
- t))]
|
|
|
|
- [else (error "expected a vector in vector-ref, not" t)])]
|
|
|
|
|
|
+ (values (Prim 'vector-ref (list e^ (Int i))) t))]
|
|
|
|
+ [else (error 'type-check-exp
|
|
|
|
+ "expected a vector in vector-ref, not ~a" t)])]
|
|
[(Prim 'vector-set! (list e (Int i) arg) )
|
|
[(Prim 'vector-set! (list e (Int i) arg) )
|
|
(define-values (e-vec t-vec) (recur e))
|
|
(define-values (e-vec t-vec) (recur e))
|
|
(define-values (e-arg^ t-arg) (recur arg))
|
|
(define-values (e-arg^ t-arg) (recur arg))
|
|
(match t-vec
|
|
(match t-vec
|
|
[`(Vector ,ts ...)
|
|
[`(Vector ,ts ...)
|
|
- (unless (and (exact-nonnegative-integer? i)
|
|
|
|
- (i . < . (length ts)))
|
|
|
|
|
|
+ (unless (and (exact-nonnegative-integer? i) (i . < . (length ts)))
|
|
(error 'type-check-exp "invalid index ~a" i))
|
|
(error 'type-check-exp "invalid index ~a" i))
|
|
(unless (type-equal? (list-ref ts i) t-arg)
|
|
(unless (type-equal? (list-ref ts i) t-arg)
|
|
(error 'type-check-exp "type mismatch in vector-set! ~a ~a"
|
|
(error 'type-check-exp "type mismatch in vector-set! ~a ~a"
|
|
(list-ref ts i) t-arg))
|
|
(list-ref ts i) t-arg))
|
|
(values (Prim 'vector-set! (list e-vec (Int i) e-arg^)) 'Void)]
|
|
(values (Prim 'vector-set! (list e-vec (Int i) e-arg^)) 'Void)]
|
|
[else (error 'type-check-exp
|
|
[else (error 'type-check-exp
|
|
- "expected a vector in vector-set!, not ~a"
|
|
|
|
- t-vec)])]
|
|
|
|
|
|
+ "expected a vector in vector-set!, not ~a" t-vec)])]
|
|
[(Prim 'vector-length (list e))
|
|
[(Prim 'vector-length (list e))
|
|
(define-values (e^ t) (recur e))
|
|
(define-values (e^ t) (recur e))
|
|
(match t
|
|
(match t
|
|
@@ -5776,14 +5768,25 @@ start and end parentheses. \index{unquote-slicing}
|
|
(values (Prim 'vector-length (list e^)) 'Integer)]
|
|
(values (Prim 'vector-length (list e^)) 'Integer)]
|
|
[else (error 'type-check-exp
|
|
[else (error 'type-check-exp
|
|
"expected a vector in vector-lenfth, not ~a" t)])]
|
|
"expected a vector in vector-lenfth, not ~a" t)])]
|
|
- [(Prim 'eq? (list e1 e2))
|
|
|
|
- (define-values (e1^ T1) (recur e1))
|
|
|
|
- (define-values (e2^ T2) (recur e2))
|
|
|
|
- (unless (equal? T1 T2)
|
|
|
|
- (error "arguments of eq? must have the same type, but are not"
|
|
|
|
- (list T1 T2)))
|
|
|
|
- (values (HasType (Prim 'eq? (list e1^ e2^)) 'Boolean) 'Boolean)]
|
|
|
|
|
|
+ [(Prim 'eq? (list arg1 arg2))
|
|
|
|
+ (define-values (e1 t1) (recur arg1))
|
|
|
|
+ (define-values (e2 t2) (recur arg2))
|
|
|
|
+ (match* (t1 t2)
|
|
|
|
+ [(`(Vector ,ts1 ...) `(Vector ,ts2 ...)) (void)]
|
|
|
|
+ [(other wise)
|
|
|
|
+ (unless (type-equal? t1 t2)
|
|
|
|
+ (error 'type-check-exp
|
|
|
|
+ "type error: different argument types of eq?: ~a != ~a" t1 t2))])
|
|
|
|
+ (values (Prim 'eq? (list e1 e2)) 'Boolean)]
|
|
|
|
+ [(HasType (Prim 'vector es) t)
|
|
|
|
+ ((type-check-exp env) (Prim 'vector es))]
|
|
|
|
+ [(HasType e t)
|
|
|
|
+ (define-values (e^ t^) (recur e))
|
|
|
|
+ (unless (type-equal? t t^)
|
|
|
|
+ (error 'type-check-exp "type mismatch in HasType" t t^))
|
|
|
|
+ (values (HasType e^ t) t)]
|
|
...
|
|
...
|
|
|
|
+ [else (error 'type-check-exp "R3/unmatched ~a" e)]
|
|
)))
|
|
)))
|
|
\end{lstlisting}
|
|
\end{lstlisting}
|
|
\caption{Type checker for the $R_3$ language.}
|
|
\caption{Type checker for the $R_3$ language.}
|
|
@@ -6085,8 +6088,8 @@ succeed.
|
|
%% \label{sec:code-generation-gc}
|
|
%% \label{sec:code-generation-gc}
|
|
|
|
|
|
The introduction of garbage collection has a non-trivial impact on our
|
|
The introduction of garbage collection has a non-trivial impact on our
|
|
-compiler passes. We introduce two new compiler passes named
|
|
|
|
-\code{expose-allocation} and \code{uncover-locals}. We make
|
|
|
|
|
|
+compiler passes. We introduce a new compiler pass named
|
|
|
|
+\code{expose-allocation}. We make
|
|
significant changes to \code{select-instructions},
|
|
significant changes to \code{select-instructions},
|
|
\code{build-interference}, \code{allocate-registers}, and
|
|
\code{build-interference}, \code{allocate-registers}, and
|
|
\code{print-x86} and make minor changes in severl more passes. The
|
|
\code{print-x86} and make minor changes in severl more passes. The
|
|
@@ -6292,77 +6295,6 @@ the \key{allocate}, \key{vector-ref}, and \key{vector-set!}, and
|
|
other forms.
|
|
other forms.
|
|
|
|
|
|
|
|
|
|
-\section{Uncover Locals}
|
|
|
|
-\label{sec:uncover-locals-r3}
|
|
|
|
-
|
|
|
|
-Recall that the \code{explicate-control} function collects all of the
|
|
|
|
-local variables so that it can store them in the $\itm{info}$ field of
|
|
|
|
-the \code{Program} structure. Also recall that we need to know the
|
|
|
|
-types of all the local variables for purposes of identifying the root
|
|
|
|
-set for the garbage collector. Thus, we create a pass named
|
|
|
|
-\code{uncover-locals} to collect not just the variables but the
|
|
|
|
-variables and their types in the form of an alist. Thanks to the
|
|
|
|
-\code{HasType} nodes, the types are readily available at every
|
|
|
|
-assignment to a variable. We recommend storing the resulting alist in
|
|
|
|
-the $\itm{info}$ field of the program, associated with the
|
|
|
|
-\code{locals} key. Figure~\ref{fig:uncover-locals-r3} lists the output
|
|
|
|
-of the \code{uncover-locals} pass on the running example.
|
|
|
|
-
|
|
|
|
-\begin{figure}[tbp]
|
|
|
|
-% tests/s2_17.rkt
|
|
|
|
-\begin{lstlisting}
|
|
|
|
-locals:
|
|
|
|
- vecinit7976 : '(Vector Integer), tmp7980 : 'Integer,
|
|
|
|
- alloc7975 : '(Vector (Vector Integer)), tmp7983 : 'Integer,
|
|
|
|
- collectret7974 : 'Void, initret7977 : 'Void,
|
|
|
|
- collectret7978 : 'Void, tmp7985 : '(Vector Integer),
|
|
|
|
- tmp7984 : 'Integer, tmp7979 : 'Integer, tmp7982 : 'Integer,
|
|
|
|
- alloc7971 : '(Vector Integer), tmp7981 : 'Integer,
|
|
|
|
- vecinit7972 : 'Integer, initret7973 : 'Void,
|
|
|
|
-block91:
|
|
|
|
- (collect 16)
|
|
|
|
- goto block89;
|
|
|
|
-block90:
|
|
|
|
- collectret7974 = (void);
|
|
|
|
- goto block89;
|
|
|
|
-block89:
|
|
|
|
- alloc7971 = (allocate 1 (Vector Integer));
|
|
|
|
- initret7973 = (vector-set! alloc7971 0 vecinit7972);
|
|
|
|
- vecinit7976 = alloc7971;
|
|
|
|
- tmp7982 = (global-value free_ptr);
|
|
|
|
- tmp7983 = (+ tmp7982 16);
|
|
|
|
- tmp7984 = (global-value fromspace_end);
|
|
|
|
- if (< tmp7983 tmp7984) then
|
|
|
|
- goto block87;
|
|
|
|
- else
|
|
|
|
- goto block88;
|
|
|
|
-block88:
|
|
|
|
- (collect 16)
|
|
|
|
- goto block86;
|
|
|
|
-block87:
|
|
|
|
- collectret7978 = (void);
|
|
|
|
- goto block86;
|
|
|
|
-block86:
|
|
|
|
- alloc7975 = (allocate 1 (Vector (Vector Integer)));
|
|
|
|
- initret7977 = (vector-set! alloc7975 0 vecinit7976);
|
|
|
|
- tmp7985 = (vector-ref alloc7975 0);
|
|
|
|
- return (vector-ref tmp7985 0);
|
|
|
|
-start:
|
|
|
|
- vecinit7972 = 42;
|
|
|
|
- tmp7979 = (global-value free_ptr);
|
|
|
|
- tmp7980 = (+ tmp7979 16);
|
|
|
|
- tmp7981 = (global-value fromspace_end);
|
|
|
|
- if (< tmp7980 tmp7981) then
|
|
|
|
- goto block90;
|
|
|
|
- else
|
|
|
|
- goto block91;
|
|
|
|
-\end{lstlisting}
|
|
|
|
-\caption{Output of \code{uncover-locals} for the running example.}
|
|
|
|
-\label{fig:uncover-locals-r3}
|
|
|
|
-\end{figure}
|
|
|
|
-
|
|
|
|
-\clearpage
|
|
|
|
-
|
|
|
|
\section{Select Instructions and the x86$_2$ Language}
|
|
\section{Select Instructions and the x86$_2$ Language}
|
|
\label{sec:select-instructions-gc}
|
|
\label{sec:select-instructions-gc}
|
|
\index{instruction selection}
|
|
\index{instruction selection}
|
|
@@ -6738,7 +6670,6 @@ conclusion:
|
|
\node (R3-5) at (9,0) {\large $R'_3$};
|
|
\node (R3-5) at (9,0) {\large $R'_3$};
|
|
\node (R3-6) at (6,0) {\large $R'_3$};
|
|
\node (R3-6) at (6,0) {\large $R'_3$};
|
|
\node (C2-4) at (3,-2) {\large $C_2$};
|
|
\node (C2-4) at (3,-2) {\large $C_2$};
|
|
-\node (C2-3) at (0,-2) {\large $C_2$};
|
|
|
|
|
|
|
|
\node (x86-2) at (3,-4) {\large $\text{x86}^{*}_2$};
|
|
\node (x86-2) at (3,-4) {\large $\text{x86}^{*}_2$};
|
|
\node (x86-3) at (6,-4) {\large $\text{x86}^{*}_2$};
|
|
\node (x86-3) at (6,-4) {\large $\text{x86}^{*}_2$};
|
|
@@ -6753,8 +6684,7 @@ conclusion:
|
|
\path[->,bend left=15] (R3-3) edge [above] node {\ttfamily\footnotesize uniquify} (R3-4);
|
|
\path[->,bend left=15] (R3-3) edge [above] node {\ttfamily\footnotesize uniquify} (R3-4);
|
|
\path[->,bend left=15] (R3-4) edge [right] node {\ttfamily\footnotesize\color{red} expose-alloc.} (R3-5);
|
|
\path[->,bend left=15] (R3-4) edge [right] node {\ttfamily\footnotesize\color{red} expose-alloc.} (R3-5);
|
|
\path[->,bend left=15] (R3-5) edge [below] node {\ttfamily\footnotesize remove-complex.} (R3-6);
|
|
\path[->,bend left=15] (R3-5) edge [below] node {\ttfamily\footnotesize remove-complex.} (R3-6);
|
|
-\path[->,bend right=20] (R3-6) edge [left] node {\ttfamily\footnotesize explicate-control} (C2-3);
|
|
|
|
-\path[->,bend right=15] (C2-3) edge [below] node {\ttfamily\footnotesize\color{red} uncover-locals} (C2-4);
|
|
|
|
|
|
+\path[->,bend right=20] (R3-6) edge [left] node {\ttfamily\footnotesize explicate-control} (C2-4);
|
|
\path[->,bend left=15] (C2-4) edge [right] node {\ttfamily\footnotesize\color{red} select-instr.} (x86-2);
|
|
\path[->,bend left=15] (C2-4) edge [right] node {\ttfamily\footnotesize\color{red} select-instr.} (x86-2);
|
|
\path[->,bend right=15] (x86-2) edge [left] node {\ttfamily\footnotesize uncover-live} (x86-2-1);
|
|
\path[->,bend right=15] (x86-2) edge [left] node {\ttfamily\footnotesize uncover-live} (x86-2-1);
|
|
\path[->,bend right=15] (x86-2-1) edge [below] node {\ttfamily\footnotesize\color{red} build-inter.} (x86-2-2);
|
|
\path[->,bend right=15] (x86-2-1) edge [below] node {\ttfamily\footnotesize\color{red} build-inter.} (x86-2-2);
|
|
@@ -7576,19 +7506,19 @@ apply this new function to all the function definitions.
|
|
\Atm &::=& \gray{ \Int \mid \Var \mid \key{\#t} \mid \key{\#f} }
|
|
\Atm &::=& \gray{ \Int \mid \Var \mid \key{\#t} \mid \key{\#f} }
|
|
\\
|
|
\\
|
|
\itm{cmp} &::= & \gray{ \key{eq?} \mid \key{<} } \\
|
|
\itm{cmp} &::= & \gray{ \key{eq?} \mid \key{<} } \\
|
|
-\Exp &::= & \gray{ \Atm \mid (\key{read}) \mid (\key{-}\;\Atm) \mid (\key{+} \; \Atm\;\Atm)
|
|
|
|
- \mid (\key{not}\;\Atm) \mid (\itm{cmp}\;\Atm\;\Atm) } \\
|
|
|
|
- &\mid& \gray{ (\key{allocate}\,\Int\,\Type)
|
|
|
|
- \mid (\key{vector-ref}\, \Atm\, \Int) } \\
|
|
|
|
- &\mid& \gray{ (\key{vector-set!}\,\Atm\,\Int\,\Atm) \mid (\key{global-value} \,\itm{name}) \mid (\key{void}) } \\
|
|
|
|
- &\mid& (\key{fun-ref}~\itm{label}) \mid (\key{call} \,\Atm\,\Atm\ldots) \\
|
|
|
|
|
|
+\Exp &::= & \gray{ \Atm \mid \LP\key{read}\RP \mid \LP\key{-}\;\Atm\RP \mid \LP\key{+} \; \Atm\;\Atm\RP
|
|
|
|
+ \mid \LP\key{not}\;\Atm\RP \mid \LP\itm{cmp}\;\Atm\;\Atm\RP } \\
|
|
|
|
+ &\mid& \gray{ \LP\key{allocate}\,\Int\,\Type\RP
|
|
|
|
+ \mid \LP\key{vector-ref}\, \Atm\, \Int\RP } \\
|
|
|
|
+ &\mid& \gray{ \LP\key{vector-set!}\,\Atm\,\Int\,\Atm\RP \mid \LP\key{global-value} \,\itm{name}\RP \mid \LP\key{void}\RP } \\
|
|
|
|
+ &\mid& \LP\key{fun-ref}~\itm{label}\RP \mid \LP\key{call} \,\Atm\,\Atm\ldots\RP \\
|
|
\Stmt &::=& \gray{ \ASSIGN{\Var}{\Exp} \mid \RETURN{\Exp}
|
|
\Stmt &::=& \gray{ \ASSIGN{\Var}{\Exp} \mid \RETURN{\Exp}
|
|
- \mid (\key{collect} \,\itm{int}) }\\
|
|
|
|
-\Tail &::= & \gray{\RETURN{\Exp} \mid (\key{seq}\;\Stmt\;\Tail)} \\
|
|
|
|
- &\mid& \gray{(\key{goto}\,\itm{label})
|
|
|
|
- \mid \IF{(\itm{cmp}\, \Atm\,\Atm)}{(\key{goto}\,\itm{label})}{(\key{goto}\,\itm{label})}} \\
|
|
|
|
- &\mid& (\key{tail-call}\,\Atm\,\Atm\ldots) \\
|
|
|
|
- \Def &::=& (\key{define}\; (\itm{label} \; [\Var \key{:} \Type]\ldots) \key{:} \Type \; ((\itm{label}\,\key{.}\,\Tail)\ldots)) \\
|
|
|
|
|
|
+ \mid \LP\key{collect} \,\itm{int}\RP }\\
|
|
|
|
+\Tail &::= & \gray{\RETURN{\Exp} \mid \LP\key{seq}\;\Stmt\;\Tail\RP} \\
|
|
|
|
+ &\mid& \gray{\LP\key{goto}\,\itm{label}\RP
|
|
|
|
+ \mid \IF{\LP\itm{cmp}\, \Atm\,\Atm\RP}{\LP\key{goto}\,\itm{label}\RP}{\LP\key{goto}\,\itm{label}\RP}} \\
|
|
|
|
+ &\mid& \LP\key{tail-call}\,\Atm\,\Atm\ldots\RP \\
|
|
|
|
+ \Def &::=& \LP\key{define}\; \LP\itm{label} \; [\Var \key{:} \Type]\ldots\RP \key{:} \Type \; \LP\LP\itm{label}\,\key{.}\,\Tail\RP\ldots\RP\RP \\
|
|
C_3 & ::= & \Def\ldots
|
|
C_3 & ::= & \Def\ldots
|
|
\end{array}
|
|
\end{array}
|
|
\]
|
|
\]
|
|
@@ -7613,7 +7543,7 @@ C_3 & ::= & \Def\ldots
|
|
&\mid& \gray{ \BINOP{\key{'vector-ref}}{\Atm}{\INT{\Int}} }\\
|
|
&\mid& \gray{ \BINOP{\key{'vector-ref}}{\Atm}{\INT{\Int}} }\\
|
|
&\mid& \gray{ (\key{Prim}~\key{'vector-set!}\,(\key{list}\,\Atm\,\INT{\Int}\,\Atm)) }\\
|
|
&\mid& \gray{ (\key{Prim}~\key{'vector-set!}\,(\key{list}\,\Atm\,\INT{\Int}\,\Atm)) }\\
|
|
&\mid& \gray{ (\key{GlobalValue} \,\Var) \mid (\key{Void}) }\\
|
|
&\mid& \gray{ (\key{GlobalValue} \,\Var) \mid (\key{Void}) }\\
|
|
- &\mid& \FUNREF{\itm{label}} \mid \CALL{\Atm}{\Atm\ldots} \\
|
|
|
|
|
|
+ &\mid& \FUNREF{\itm{label}} \mid \CALL{\Atm}{\LP\Atm\ldots\RP} \\
|
|
\Stmt &::=& \gray{ \ASSIGN{\VAR{\Var}}{\Exp}
|
|
\Stmt &::=& \gray{ \ASSIGN{\VAR{\Var}}{\Exp}
|
|
\mid (\key{Collect} \,\itm{int}) } \\
|
|
\mid (\key{Collect} \,\itm{int}) } \\
|
|
\Tail &::= & \gray{ \RETURN{\Exp} \mid \SEQ{\Stmt}{\Tail}
|
|
\Tail &::= & \gray{ \RETURN{\Exp} \mid \SEQ{\Stmt}{\Tail}
|
|
@@ -7630,14 +7560,6 @@ C_3 & ::= & \PROGRAMDEFS{\itm{info}}{(\Def\ldots)}
|
|
\label{fig:c3-syntax}
|
|
\label{fig:c3-syntax}
|
|
\end{figure}
|
|
\end{figure}
|
|
|
|
|
|
-\section{Uncover Locals}
|
|
|
|
-\label{sec:uncover-locals-r4}
|
|
|
|
-
|
|
|
|
-The function for processing $\Tail$ should be updated with a case for
|
|
|
|
-\code{TailCall}. We also recommend creating a new function for
|
|
|
|
-processing function definitions. Each function definition in $C_3$ has
|
|
|
|
-its own set of local variables, so the code for function definitions
|
|
|
|
-should be similar to the case for the \code{Program} form in $C_2$.
|
|
|
|
|
|
|
|
\section{Select Instructions and the x86$_3$ Language}
|
|
\section{Select Instructions and the x86$_3$ Language}
|
|
\label{sec:select-r4}
|
|
\label{sec:select-r4}
|
|
@@ -7891,7 +7813,6 @@ of your previously created test programs.
|
|
\node (F1-2) at (9,0) {\large $F_1$};
|
|
\node (F1-2) at (9,0) {\large $F_1$};
|
|
\node (F1-3) at (6,0) {\large $F_1$};
|
|
\node (F1-3) at (6,0) {\large $F_1$};
|
|
\node (F1-4) at (3,0) {\large $F_1$};
|
|
\node (F1-4) at (3,0) {\large $F_1$};
|
|
-\node (C3-1) at (6,-2) {\large $C_3$};
|
|
|
|
\node (C3-2) at (3,-2) {\large $C_3$};
|
|
\node (C3-2) at (3,-2) {\large $C_3$};
|
|
|
|
|
|
\node (x86-2) at (3,-4) {\large $\text{x86}^{*}_3$};
|
|
\node (x86-2) at (3,-4) {\large $\text{x86}^{*}_3$};
|
|
@@ -7915,9 +7836,7 @@ of your previously created test programs.
|
|
\path[->,bend right=15] (F1-3) edge [above] node
|
|
\path[->,bend right=15] (F1-3) edge [above] node
|
|
{\ttfamily\footnotesize\color{red} remove-complex.} (F1-4);
|
|
{\ttfamily\footnotesize\color{red} remove-complex.} (F1-4);
|
|
\path[->,bend left=15] (F1-4) edge [right] node
|
|
\path[->,bend left=15] (F1-4) edge [right] node
|
|
- {\ttfamily\footnotesize\color{red} explicate-control} (C3-1);
|
|
|
|
-\path[->,bend left=15] (C3-1) edge [below] node
|
|
|
|
- {\ttfamily\footnotesize\color{red} uncover-locals} (C3-2);
|
|
|
|
|
|
+ {\ttfamily\footnotesize\color{red} explicate-control} (C3-2);
|
|
\path[->,bend right=15] (C3-2) edge [left] node
|
|
\path[->,bend right=15] (C3-2) edge [left] node
|
|
{\ttfamily\footnotesize\color{red} select-instr.} (x86-2);
|
|
{\ttfamily\footnotesize\color{red} select-instr.} (x86-2);
|
|
\path[->,bend left=15] (x86-2) edge [left] node
|
|
\path[->,bend left=15] (x86-2) edge [left] node
|
|
@@ -8448,7 +8367,6 @@ $\Downarrow$
|
|
\node (F1-3) at (6,0) {\large $F_1$};
|
|
\node (F1-3) at (6,0) {\large $F_1$};
|
|
\node (F1-4) at (3,0) {\large $F_1$};
|
|
\node (F1-4) at (3,0) {\large $F_1$};
|
|
\node (F1-5) at (0,0) {\large $F_1$};
|
|
\node (F1-5) at (0,0) {\large $F_1$};
|
|
-\node (C3-1) at (6,-2) {\large $C_3$};
|
|
|
|
\node (C3-2) at (3,-2) {\large $C_3$};
|
|
\node (C3-2) at (3,-2) {\large $C_3$};
|
|
|
|
|
|
\node (x86-2) at (3,-4) {\large $\text{x86}^{*}_3$};
|
|
\node (x86-2) at (3,-4) {\large $\text{x86}^{*}_3$};
|
|
@@ -8474,9 +8392,7 @@ $\Downarrow$
|
|
\path[->,bend right=15] (F1-4) edge [above] node
|
|
\path[->,bend right=15] (F1-4) edge [above] node
|
|
{\ttfamily\footnotesize remove-complex.} (F1-5);
|
|
{\ttfamily\footnotesize remove-complex.} (F1-5);
|
|
\path[->] (F1-5) edge [left] node
|
|
\path[->] (F1-5) edge [left] node
|
|
- {\ttfamily\footnotesize explicate-control} (C3-1);
|
|
|
|
-\path[->,bend left=15] (C3-1) edge [below] node
|
|
|
|
- {\ttfamily\footnotesize uncover-locals} (C3-2);
|
|
|
|
|
|
+ {\ttfamily\footnotesize explicate-control} (C3-2);
|
|
\path[->,bend right=15] (C3-2) edge [left] node
|
|
\path[->,bend right=15] (C3-2) edge [left] node
|
|
{\ttfamily\footnotesize select-instr.} (x86-2);
|
|
{\ttfamily\footnotesize select-instr.} (x86-2);
|
|
\path[->,bend left=15] (x86-2) edge [left] node
|
|
\path[->,bend left=15] (x86-2) edge [left] node
|