Jeremy Siek 6 лет назад
Родитель
Сommit
2eaabcb91a
1 измененных файлов с 80 добавлено и 79 удалено
  1. 80 79
      book.tex

+ 80 - 79
book.tex

@@ -40,7 +40,6 @@
 \else
 \newcommand{\rn}[1]{}
 \newcommand{\margincomment}[1]{}
-% \newcommand{\margincomment}[1]{}
 \fi
 
 \lstset{%
@@ -2155,10 +2154,10 @@ programs.
 
 In Chapter~\ref{ch:int-exp} we simplified the generation of x86
 assembly by placing all variables on the stack. We can improve the
-performance of the generated code considerably if we instead try to
-place as many variables as possible into registers.  The CPU can
-access a register in a single cycle, whereas accessing the stack takes
-many cycles to go to cache or many more to access main memory.
+performance of the generated code considerably if we instead place as
+many variables as possible into registers.  The CPU can access a
+register in a single cycle, whereas accessing the stack takes many
+cycles to go to cache or many more to access main memory.
 Figure~\ref{fig:reg-eg} shows a program with four variables that
 serves as a running example. We show the source program and also the
 output of instruction selection. At that point the program is almost
@@ -2182,20 +2181,23 @@ $R_1$ program:
 \begin{minipage}{0.45\textwidth}
 After instruction selection:
 \begin{lstlisting}
-(program (v w x y z t.1 t.2)
-  (movq (int 1) (var v))
-  (movq (int 46) (var w))
-  (movq (var v) (var x))
-  (addq (int 7) (var x))
-  (movq (var x) (var y))
-  (addq (int 4) (var y))
-  (movq (var x) (var z))
-  (addq (var w) (var z))
-  (movq (var y) (var t.1))
-  (negq (var t.1))
-  (movq (var z) (var t.2))
-  (addq (var t.1) (var t.2))
-  (movq (var t.2) (reg rax)))
+(program
+ ((locals . (v w x y z t.1)))
+ ((start .
+   (block ()
+     (movq (int 1) (var v))
+     (movq (int 46) (var w))
+     (movq (var v) (var x))
+     (addq (int 7) (var x))
+     (movq (var x) (var y))
+     (addq (int 4) (var y))
+     (movq (var x) (var z))
+     (addq (var w) (var z))
+     (movq (var y) (var t.1))
+     (negq (var t.1))
+     (movq (var z) (reg rax))
+     (addq (var t.1) (reg rax))
+     (jmp conclusion)))))
 \end{lstlisting}
 \end{minipage}
 \caption{An example program for register allocation.}
@@ -2315,62 +2317,56 @@ $L_{\mathtt{after}}$ set to make the figure easy to read.
 \hspace{20pt}
 \begin{minipage}{0.45\textwidth}
 \begin{lstlisting}[numbers=left]
-  (program (v w x y z t.1 t.2)
-    (movq (int 1) (var v))
-    (movq (int 46) (var w))
-    (movq (var v) (var x))
-    (addq (int 7) (var x))
-    (movq (var x) (var y))
-    (addq (int 4) (var y))
-    (movq (var x) (var z))
-    (addq (var w) (var z))
-    (movq (var y) (var t.1))
-    (negq (var t.1))
-    (movq (var z) (var t.2))
-    (addq (var t.1) (var t.2))
-    (movq (var t.2) (reg rax)))
+(block ()
+  (movq (int 1) (var v))
+  (movq (int 46) (var w))
+  (movq (var v) (var x))
+  (addq (int 7) (var x))
+  (movq (var x) (var y))
+  (addq (int 4) (var y))
+  (movq (var x) (var z))
+  (addq (var w) (var z))
+  (movq (var y) (var t.1))
+  (negq (var t.1))
+  (movq (var z) (reg rax))
+  (addq (var t.1) (reg rax))
+  (jmp conclusion))
 \end{lstlisting}
 \end{minipage}
 \vrule\hspace{10pt}
 \begin{minipage}{0.45\textwidth}
 \begin{lstlisting}
-
-|$\{ v \}$|
-|$\{ v, w \}$|
-|$\{ w, x \}$|
-|$\{ w, x \}$|
-|$\{ w, x, y\}$|
-|$\{ w, x, y \}$|
-|$\{ w, y, z \}$|
-|$\{ y, z \}$|
-|$\{ t.1, z \}$|
-|$\{ t.1, z \}$|
-|$\{t.1,t.2\}$|
-|$\{t.2\}$|
+|$\{\}$|
+|$\{v \}$|
+|$\{v,w\}$|
+|$\{w,x\}$|
+|$\{w,x\}$|
+|$\{w,x,y\}$|
+|$\{w,x,y\}$|
+|$\{w,y,z\}$|
+|$\{y,z\}$|
+|$\{z,t.1\}$|
+|$\{z,t.1\}$|
+|$\{t.1\}$|
+|$\{\}$|
 |$\{\}$|
 \end{lstlisting}
 \end{minipage}
 
-\caption{An example program annotated with live-after sets.}
+\caption{An example block annotated with live-after sets.}
 \label{fig:live-eg}
 \end{figure}
 
 \begin{exercise}\normalfont
 Implement the compiler pass named \code{uncover-live} that computes
 the live-after sets. We recommend storing the live-after sets (a list
-of lists of variables) in the $\itm{info}$ field of the \key{program}
-node alongside the list of variables as follows.
-\begin{lstlisting}
-   (program (|$\Var^{*}$| |$\itm{live}$-$\itm{afters}$|) |$\Instr^{+}$|)
-\end{lstlisting}
-We recommend organizing your code to use a helper function that takes a
-list of statements and an initial live-after set (typically empty) and
-returns the list of statements and the list of live-after sets.  For
-this chapter, returning the list of statements is unnecessary, as they
-will be unchanged, but in Chapter~\ref{ch:bool-types} we introduce
-\key{if} statements and will need to annotate them with the live-after
-sets of the two branches.
-
+of lists of variables) in the $\itm{info}$ field of the \key{block}
+construct.
+%
+We recommend organizing your code to use a helper function that takes
+a list of instructions and an initial live-after set (typically empty)
+and returns the list of live-after sets.
+%
 We recommend creating helper functions to 1) compute the set of
 variables that appear in an argument (of an instruction), 2) compute
 the variables read by an instruction which corresponds to the $R$
@@ -2443,7 +2439,7 @@ Line 8: $z$ interferes with $w$ and $y$,\\
 Line 9: $z$ interferes with $y$, \\
 Line 10: $t.1$ interferes with $z$, \\
 Line 11: $t.1$ interferes with $z$, \\
-Line 12: $t.2$ interferes with $t.1$, \\
+Line 12: no interference, \\
 Line 13: no interference. \\
 Line 14: no interference.
 \end{quote}
@@ -2457,10 +2453,9 @@ Figure~\ref{fig:interfere}.
 \node (v) at (0,0)   {$v$};
 \node (w) at (2,0)   {$w$};
 \node (x) at (4,0)   {$x$};
-\node (t1) at (6,0)   {$t.1$};
+\node (t1) at (6,-2)   {$t.1$};
 \node (y) at (2,-2)  {$y$};
 \node (z) at (4,-2)  {$z$};
-\node (t2) at (6,-2) {$t.2$};
 
 \draw (v) to (w);
 \foreach \i in {w,x,y}
@@ -2473,7 +2468,6 @@ Figure~\ref{fig:interfere}.
 \draw (z) to (w);
 \draw (z) to (y);
 \draw (t1) to (z);
-\draw (t2) to (t1);
 \end{tikzpicture}
 \]
 \caption{The interference graph of the example program.}
@@ -2481,10 +2475,10 @@ Figure~\ref{fig:interfere}.
 \end{figure}
 
 Our next concern is to choose a data structure for representing the
-interference graph. There are many standard choices for how to
-represent a graph: \emph{adjacency matrix}, \emph{adjacency list}, and
-\emph{edge set}~\citep{Cormen:2001uq}. The right way to choose a data
-structure is to study the algorithm that uses the data structure,
+interference graph. There are many choices for how to represent a
+graph, for example, \emph{adjacency matrix}, \emph{adjacency list},
+and \emph{edge set}~\citep{Cormen:2001uq}. The right way to choose a
+data structure is to study the algorithm that uses the data structure,
 determine what operations need to be performed, and then choose the
 data structure that provide the most efficient implementations of
 those operations. Often times the choice of data structure can have an
@@ -2496,20 +2490,20 @@ correct choice of graph representation is that of an adjacency
 list. There are helper functions in \code{utilities.rkt} for
 representing graphs using the adjacency list representation:
 \code{make-graph}, \code{add-edge}, and \code{adjacent}
-(Appendix~\ref{appendix:utilities}).  In particular, those functions
-use a hash table to map each vertex to the set of adjacent vertices,
-and the sets are represented using Racket's \key{set}, which is also a
-hash table.
+(Appendix~\ref{appendix:utilities}).
+%
+\margincomment{\footnotesize To do: change to use the
+    Racket graph library. \\ --Jeremy}
+%
+In particular, those functions use a hash table to map each vertex to
+the set of adjacent vertices, and the sets are represented using
+Racket's \key{set}, which is also a hash table.
 
 \begin{exercise}\normalfont
 Implement the compiler pass named \code{build-interference} according
-to the algorithm suggested above.  The output of this pass should
-replace the live-after sets with the interference $\itm{graph}$ as
-follows.
-\begin{lstlisting}
-   (program (|$\Var^{*}$| |$\itm{graph}$|) |$\Instr^{+}$|)
-\end{lstlisting}
-
+to the algorithm suggested above.  The output of this pass should be
+stored in the $\itm{info}$ field of the program, under the key
+\code{conflicts}.
 \end{exercise}
 
 \section{Graph Coloring via Sudoku}
@@ -6332,6 +6326,13 @@ $\Rightarrow$
 The top-level function definitions need to be updated as well to take
 an extra closure parameter.
 
+A final concern when implementing closure conversion is that we want
+to maintain efficient tail calls. To preserve the invariant needed for
+tail calls, \code{limit-functions} should be updated to handle
+\code{lambda} (as it happens before \code{convert-to-closures}), as
+well as to reserve an extra spot for the eventual closure parameter
+for all functions.
+
 \section{An Example Translation}
 \label{sec:example-lambda}