Преглед на файлове

removing uncover locals

Jeremy Siek преди 4 години
родител
ревизия
dc63f7ceec
променени са 1 файла, в които са добавени 63 реда и са изтрити 147 реда
  1. 63 147
      book.tex

+ 63 - 147
book.tex

@@ -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
 of x86 (Figure~\ref{fig:x86-0-concrete}) is that it does not allow
 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]
 \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-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 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 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);
@@ -2347,7 +2350,7 @@ start:
 In the output of \code{select-instructions}, there is a entry for
 \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
-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}
 installs it in the $\itm{info}$ field of the \code{Program} node.
 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}
 
 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
-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
 Figure~\ref{fig:type-check-R3}, we use the
 \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{lstlisting}[basicstyle=\ttfamily\footnotesize]
+\begin{lstlisting}[basicstyle=\ttfamily\scriptsize]
 (define (type-check-exp env)
   (lambda (e)
     (define recur (type-check-exp env))
     (match e
       ...
-      [(Void) (values (HasType (Void) 'Void) 'Void)]
+      [(Void) (values (Void) 'Void)]
       [(Prim 'vector es)
        (define-values (e* t*) (for/lists (e* t*) ([e es]) (recur e)))
        (let ([t `(Vector ,@t*)])
@@ -5748,27 +5745,22 @@ start and end parentheses.  \index{unquote-slicing}
           (unless (and (exact-nonnegative-integer? i) (< i (length ts)))
             (error 'type-check-exp "invalid index ~a" 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) )
        (define-values (e-vec t-vec) (recur e))
        (define-values (e-arg^ t-arg) (recur arg))
        (match t-vec
          [`(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))
           (unless (type-equal? (list-ref ts i) t-arg)
             (error 'type-check-exp "type mismatch in vector-set! ~a ~a" 
                    (list-ref ts i) t-arg))
           (values (Prim 'vector-set! (list e-vec (Int i) e-arg^))  'Void)]
          [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))
        (define-values (e^ t) (recur e))
        (match t
@@ -5776,14 +5768,25 @@ start and end parentheses.  \index{unquote-slicing}
           (values (Prim 'vector-length (list e^))  'Integer)]
          [else (error 'type-check-exp
                       "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}
 \caption{Type checker for the $R_3$ language.}
@@ -6085,8 +6088,8 @@ succeed.
 %% \label{sec:code-generation-gc}
 
 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},
 \code{build-interference}, \code{allocate-registers}, and
 \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.
 
 
-\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}
 \label{sec:select-instructions-gc}
 \index{instruction selection}
@@ -6738,7 +6670,6 @@ conclusion:
 \node (R3-5) at (9,0)  {\large $R'_3$};
 \node (R3-6) at (6,0)  {\large $R'_3$};
 \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-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-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 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 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);
@@ -7576,19 +7506,19 @@ apply this new function to all the function definitions.
 \Atm &::=& \gray{ \Int \mid \Var \mid \key{\#t} \mid \key{\#f} }
   \\
 \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} 
-       \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
 \end{array}
 \]
@@ -7613,7 +7543,7 @@ C_3 & ::= & \Def\ldots
    &\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{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} 
        \mid (\key{Collect} \,\itm{int}) } \\
 \Tail &::= & \gray{ \RETURN{\Exp} \mid \SEQ{\Stmt}{\Tail} 
@@ -7630,14 +7560,6 @@ C_3 & ::= & \PROGRAMDEFS{\itm{info}}{(\Def\ldots)}
 \label{fig:c3-syntax}
 \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}
 \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-3) at (6,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 (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
      {\ttfamily\footnotesize\color{red} remove-complex.} (F1-4);
 \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
      {\ttfamily\footnotesize\color{red} select-instr.} (x86-2);
 \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-4) at (3,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 (x86-2) at (3,-4)  {\large $\text{x86}^{*}_3$};
@@ -8474,9 +8392,7 @@ $\Downarrow$
 \path[->,bend right=15] (F1-4) edge [above] node
      {\ttfamily\footnotesize remove-complex.} (F1-5);
 \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
      {\ttfamily\footnotesize select-instr.} (x86-2);
 \path[->,bend left=15] (x86-2) edge [left] node