ソースを参照

finished draft of loop chapter

Jeremy Siek 4 年 前
コミット
4b3aec7936
1 ファイル変更360 行追加121 行削除
  1. 360 121
      book.tex

+ 360 - 121
book.tex

@@ -1300,7 +1300,7 @@ Figure~\ref{fig:x86-0-concrete} defines the concrete syntax for the subset of
 the x86 assembly language needed for this chapter, which we call x86$_0$.
 %
 An x86 program begins with a \code{main} label followed by a sequence
-of instructions.  In the grammar, elipses such as $\ldots$ are used to
+of instructions.  In the grammar, ellipses such as $\ldots$ are used to
 indicate a sequence of items, e.g., $\Instr \ldots$ is a sequence of
 instructions.\index{instruction}
 %
@@ -1444,7 +1444,7 @@ the top of the stack. The stack grows downward in memory, so we
 increase the size of the stack by subtracting from the stack pointer.
 In the context of a procedure call, the \emph{return
   address}\index{return address} is the instruction after the call
-instruction on the caller side. The function call inststruction,
+instruction on the caller side. The function call instruction,
 \code{callq}, pushes the return address onto the stack.  The register
 \key{rbp} is the \emph{base pointer}\index{base pointer} and is used
 to access variables associated with the current procedure call.  The
@@ -1495,7 +1495,7 @@ Position & Contents \\ \hline
 \end{figure}
 
 Getting back to the program in Figure~\ref{fig:p1-x86}, consider how
-control is transfered from the operating system to the \code{main}
+control is transferred from the operating system to the \code{main}
 function.  The operating system issues a \code{callq main} instruction
 which pushes its return address on the stack and then jumps to
 \code{main}. In x86-64, the stack pointer \code{rsp} must be divisible
@@ -2620,7 +2620,7 @@ approach is to assign a variable to one or more locations in different
 regions of the program.  For example, if a variable is used many times
 in short sequence and then only used again after many other
 instructions, it could be more efficient to assign the variable to a
-register during the intial sequence and then move it to the stack for
+register during the initial sequence and then move it to the stack for
 the rest of its lifetime. We refer the interested reader to
 \citet{Cooper:1998ly} and \citet{Cooper:2011aa} for more information
 about that approach.
@@ -2705,7 +2705,7 @@ accidentally wiped out by the call to \code{read}.  One obvious
 approach is to save all the values in caller-saved registers to the
 stack prior to each function call, and restore them after each
 call. That way, if the register allocator chooses to assign \code{x}
-to a caller-saved register, its value will be preserved accross the
+to a caller-saved register, its value will be preserved across the
 call to \code{read}.  However, the disadvantage of this approach is
 that saving and restoring to the stack is relatively slow. If \code{x}
 is not used many times, it may be better to assign \code{x} to a stack
@@ -3386,7 +3386,7 @@ and \ttm{rsp} because they interfere with $\ttm{t}$.
 \]
 We repeat the process, selecting another maximally saturated
 vertex, which is \code{z}, and color it with the first available
-number, which is $1$. We add $1$ to the saturations for the
+number, which is $1$. We add $1$ to the saturation for the
 neighboring vertices \code{t}, \code{y}, \code{w}, and \code{rsp}.
 \[
 \begin{tikzpicture}[baseline=(current  bounding  box.center)]
@@ -3638,7 +3638,7 @@ notify the priority queue when their saturation changes.
   \item[$\LP\code{pqueue-pop!}\,\itm{queue}\RP$] returns the item with
     the lowest priority.
   \item[$\LP\code{pqueue-decrease-key!}\,\itm{queue}\,\itm{handle}\RP$]
-    notifices the queue the the priority has decreased for the item
+    notifies the queue that the priority has decreased for the item
     associated with the given handle.
   \end{description}
 \end{tcolorbox}
@@ -4019,7 +4019,7 @@ stack, we have limited the register allocator to use just two
 registers: \code{rbx} and \code{rcx}.  In the prelude of the
 \code{main} function, we push \code{rbx} onto the stack because it is
 a callee-saved register and it was assigned to variable by the
-register allocator.  We substract \code{8} from the \code{rsp} at the
+register allocator.  We subtract \code{8} from the \code{rsp} at the
 end of the prelude to reserve space for the one spilled variable.
 After that subtraction, the \code{rsp} is aligned to 16 bytes.
 
@@ -4374,7 +4374,7 @@ variable \code{x}, it can find its type in the environment.
 \end{figure}
 
 
-Figure~\ref{fig:type-check-aux-R2} defines three auxilliary functions
+Figure~\ref{fig:type-check-aux-R2} defines three auxiliary functions
 that are used in the type checker. The \code{operator-types} function
 defines a dictionary that maps the operator names to their parameter
 and return types. The \code{type-equal?} function determines whether
@@ -4414,7 +4414,7 @@ result is the return type of the operator.
     [else
      (error 'type-check-op "unrecognized operator ~a" op)]))
 \end{lstlisting}
-\caption{Auxilliary functions for type checking.}
+\caption{Auxiliary functions for type checking.}
 \label{fig:type-check-aux-R2}
 \end{figure}
 
@@ -4671,7 +4671,7 @@ C_1 & ::= & \gray{\PROGRAM{\itm{info}}{\CFG{\key{(}\itm{label}\,\key{.}\,\Tail\k
 \]
 \end{minipage}
 }
-\caption{The abstract syntax of $C_1$, an extention of $C_0$
+\caption{The abstract syntax of $C_1$, an extension of $C_0$
   (Figure~\ref{fig:c0-syntax}).}
 \label{fig:c1-syntax}
 \end{figure}
@@ -5071,7 +5071,7 @@ following program.
     42)  
 \end{lstlisting}
 The \code{and} operation should transform into something that the
-\code{explicat-pred} function can still analyze and descend through to
+\code{explicate-pred} function can still analyze and descend through to
 reach the underlying \code{eq?} conditions. Ideally, your
 \code{explicate-control} pass should generate code similar to the
 following for the above program.
@@ -5222,20 +5222,22 @@ algorithm itself does not change.
 Recall that for $R_1$ we implemented liveness analysis for a single
 basic block (Section~\ref{sec:liveness-analysis-r1}). With the
 addition of \key{if} expressions to $R_2$, \code{explicate-control}
-produces many basic blocks arranged in a control-flow graph. The first
-question we need to consider is: what order should we process the
-basic blocks? To perform liveness analysis on a basic block, we need
-to know its live-after set. If a basic block has no successor blocks
-(i.e. no out-edges in the control flow graph), then it has an empty
-live-after set and we can immediately apply liveness analysis to
-it. If a basic block has some successors, then we need to complete
-liveness analysis on those blocks first. Thankfully, the control flow
-graph does not contain any cycles because $R_2$ does not include loops
-%
-\footnote{If we were to add loops to the language, then the CFG could
-  contain cycles and we would need to use an iterative worklist
-  algorithm for computing the fixed point of the liveness
-  analysis~\citep{Aho:1986qf}.}.
+produces many basic blocks arranged in a control-flow graph.  We
+recommend that you create a new auxiliary function named
+\code{uncover-live-CFG} that applies liveness analysis to a
+control-flow graph.
+
+The first question we need to consider is: what order should we
+process the basic blocks in the control-flow graph? To perform
+liveness analysis on a basic block, we need to know its live-after
+set. If a basic block has no successor blocks (i.e. no out-edges in
+the control flow graph), then it has an empty live-after set and we
+can immediately apply liveness analysis to it. If a basic block has
+some successors, then we need to complete liveness analysis on those
+blocks first. Thankfully, the control flow graph does not contain any
+cycles because $R_2$ does not include loops.  (In
+Chapter~\ref{ch:loop} we add loops and study how to handle cycles in
+the control-flow graph.)
 %
 Returning to the question of what order should we process the basic
 blocks, the answer is reverse topological order. We recommend using
@@ -5571,7 +5573,7 @@ example of Figure~\ref{fig:if-example-x86}. The \code{start} block end
 with a jump to \code{block7953} and there are no other jumps to
 \code{block7953} in the rest of the program. In this situation we can
 avoid the runtime overhead of this jump by merging \code{block7953}
-into the preceeding block, in this case the \code{start} block.
+into the preceding block, in this case the \code{start} block.
 Figure~\ref{fig:remove-jumps} shows the output of
 \code{select-instructions} on the left and the result of this
 optimization on the right.
@@ -5618,8 +5620,8 @@ block7952:
 
 \begin{exercise}\normalfont
   Implement a pass named \code{remove-jumps} that merges basic blocks
-  into their preceeding basic block, when there is only one preceeding
-  block. The pass should translate from psuedo $x86_1$ to pseudo
+  into their preceding basic block, when there is only one preceding
+  block. The pass should translate from pseudo $x86_1$ to pseudo
   $x86_1$ and it should come immediately after
   \code{select-instructions}.  Check that \code{remove-jumps}
   accomplishes the goal of merging basic blocks on several test
@@ -5905,7 +5907,7 @@ start and end parentheses.  \index{unquote-slicing}
          [`(Vector ,ts ...)
           (values (Prim 'vector-length (list e^))  'Integer)]
          [else (error 'type-check-exp
-                      "expected a vector in vector-lenfth, not ~a" t)])]
+                      "expected a vector in vector-length, not ~a" t)])]
       [(Prim 'eq? (list arg1 arg2))
        (define-values (e1 t1) (recur arg1))
        (define-values (e2 t2) (recur arg2))
@@ -6230,7 +6232,7 @@ 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
+\code{print-x86} and make minor changes in several more passes.  The
 following program will serve as our running example.  It creates two
 tuples, one nested inside the other. Both tuples have length one. The
 program accesses the element in the inner tuple tuple via two vector
@@ -6358,12 +6360,40 @@ Figure~\ref{fig:expose-alloc-output} shows the output of the
 \label{sec:remove-complex-opera-R3}
 
 The new forms \code{collect}, \code{allocate}, and \code{global-value}
-should all be treated as complex operands. A new case for
-\code{HasType} is needed and the case for \code{Prim} needs to be
-handled carefully to prevent the \code{Prim} node from being separated
-from its enclosing \code{HasType}.
+should all be treated as complex operands.
+%% A new case for
+%% \code{HasType} is needed and the case for \code{Prim} needs to be
+%% handled carefully to prevent the \code{Prim} node from being separated
+%% from its enclosing \code{HasType}.
+Figure~\ref{fig:r3-anf-syntax}
+shows the grammar for the output language $R_3^{\dagger}$ of this
+pass, which is $R_3$ in administrative normal form.
 
-TODO: add the grammar for the output language
+\begin{figure}[tp]
+\centering
+\fbox{
+\begin{minipage}{0.96\textwidth}
+\small
+\[
+\begin{array}{rcl}
+  \Atm &::=& \gray{ \INT{\Int} \mid \VAR{\Var} \mid \BOOL{\itm{bool}} }
+       \mid \VOID{} \\
+\Exp &::=& \gray{ \Atm \mid \READ{} } \\
+   &\mid& \gray{ \NEG{\Atm} \mid \ADD{\Atm}{\Atm} } \\
+   &\mid& \gray{ \LET{\Var}{\Exp}{\Exp} } \\
+   &\mid& \gray{ \UNIOP{\key{'not}}{\Atm} } \\
+   &\mid& \gray{ \BINOP{\itm{cmp}}{\Atm}{\Atm} \mid \IF{\Exp}{\Exp}{\Exp} }\\
+   &\mid& \LP\key{Collect}~\Int\RP \mid \LP\key{Allocate}~\Int~\Type\RP
+   \mid \LP\key{GlobalValue}~\Var\RP\\
+%  &\mid& \LP\key{HasType}~\Exp~\Type\RP \\
+R^{\dagger}_3  &::=& \gray{ \PROGRAM{\code{'()}}{\Exp} }
+\end{array}
+\]
+\end{minipage}
+}
+\caption{$R_3^{\dagger}$ is $R_3$ in administrative normal form (ANF).}
+\label{fig:r3-anf-syntax}
+\end{figure}
 
 
 \section{Explicate Control and the $C_2$ language}
@@ -6905,8 +6935,8 @@ instances.
 \end{center}
 Similarly, to write to a field of a structure, use its set function,
 whose name starts with \code{set-}, followed by the structure name,
-then a dash, then the field name, and conclused with an exclamation
-mark. The folowing example uses \code{set-point-x!} to change the
+then a dash, then the field name, and concluded with an exclamation
+mark. The following example uses \code{set-point-x!} to change the
 \code{x} field from \code{7} to \code{42}.
 \begin{center}
   \begin{lstlisting}
@@ -6934,7 +6964,7 @@ allocated data is more likely to become garbage then data that has
 survived one or more previous calls to \code{collect}. This insight
 motivated the creation of \emph{generational garbage collectors}
 \index{generational garbage collector} that
-1) segragates data according to its age into two or more generations,
+1) segregates data according to its age into two or more generations,
 2) allocates less space for younger generations, so collecting them is
 faster, and more space for the older generations, and 3) performs
 collection on the younger generations more frequently then for older
@@ -7520,22 +7550,7 @@ The concrete syntax for a function reference is $\CFUNREF{f}$.
 \begin{minipage}{0.96\textwidth}
 \[
 \begin{array}{lcl}
-\Exp &::=& \gray{ \INT{\Int} \mid \READ{} \mid \NEG{\Exp} } \\
-     &\mid& \gray{ \ADD{\Exp}{\Exp} 
-      \mid \BINOP{\code{'-}}{\Exp}{\Exp} } \\
-     &\mid& \gray{ \VAR{\Var} \mid \LET{\Var}{\Exp}{\Exp} } \\
-     &\mid& \gray{ \BOOL{\itm{bool}} 
-      \mid \AND{\Exp}{\Exp} }\\
-     &\mid& \gray{ \OR{\Exp}{\Exp}
-      \mid \NOT{\Exp} } \\
-     &\mid& \gray{ \BINOP{\itm{cmp}}{\Exp}{\Exp}
-      \mid \IF{\Exp}{\Exp}{\Exp} } \\
-     &\mid& \gray{ \VECTOR{\Exp} } \\
-     &\mid& \gray{ \VECREF{\Exp}{\INT{\Int}} }\\
-     &\mid& \gray{ \VECSET{\Exp}{\INT{\Int}}{\Exp}} \\
-     &\mid& \gray{ \VOID{} \mid \LP\key{HasType}~\Exp~\Type \RP 
-     \mid \APPLY{\Exp}{\Exp\ldots} }\\
-     &\mid& \FUNREF{\Var}\\
+\Exp &::=& \ldots \mid \FUNREF{\Var}\\
  \Def &::=& \gray{ \FUNDEF{\Var}{([\Var \code{:} \Type]\ldots)}{\Type}{\code{'()}}{\Exp} }\\
   F_1 &::=& \PROGRAMDEFS{\code{'()}}{\LP \Def\ldots \RP}
 \end{array}
@@ -7580,7 +7595,7 @@ follows.
   (Def |$f$| ([|$x_1$|:|$T_1$|] |$\ldots$| [|$x_5$|:|$T_5$|] [vec : (Vector |$T_6 \ldots T_n$|)]) |$T_r$| |$\itm{info}$| |$\itm{body}'$|) 
 \end{lstlisting}
 where the $\itm{body}$ is transformed into $\itm{body}'$ by replacing
-the occurences of the later parameters with vector references.
+the occurrences of the later parameters with vector references.
 \begin{lstlisting}
   (Var |$x_i$|) |$\Rightarrow$| (Prim 'vector-ref (list vec (Int |$(i - 6)$|)))
 \end{lstlisting}
@@ -7609,19 +7624,48 @@ $\Rightarrow$
 \label{sec:rco-r4}
 
 The primary decisions to make for this pass is whether to classify
-\code{FunRef} and \code{Apply} as either simple or complex
+\code{FunRef} and \code{Apply} as either atomic or complex
 expressions. Recall that a simple expression will eventually end up as
-just an ``immediate'' argument of an x86 instruction. Function
+just an immediate argument of an x86 instruction. Function
 application will be translated to a sequence of instructions, so
-\code{Apply} must be classified as complex expression. Regarding
-\code{FunRef}, as discussed above, the function label needs to
-be converted to an address using the \code{leaq} instruction. Thus,
+\code{Apply} must be classified as complex expression.
+On the other hand, the arguments of \code{Apply} should be
+atomic expressions.
+%
+Regarding \code{FunRef}, as discussed above, the function label needs
+to be converted to an address using the \code{leaq} instruction. Thus,
 even though \code{FunRef} seems rather simple, it needs to be
 classified as a complex expression so that we generate an assignment
 statement with a left-hand side that can serve as the target of the
-\code{leaq}.
+\code{leaq}. Figure~\ref{fig:r4-anf-syntax} defines the
+output language $R_4^{\dagger}$ of this pass.
 
-TODO: add the output grammar
+\begin{figure}[tp]
+\centering
+\fbox{
+\begin{minipage}{0.96\textwidth}
+\small
+\[
+\begin{array}{rcl}
+  \Atm &::=& \gray{ \INT{\Int} \mid \VAR{\Var} \mid \BOOL{\itm{bool}} 
+       \mid \VOID{} } \\
+\Exp &::=& \gray{ \Atm \mid \READ{} } \\
+   &\mid& \gray{ \NEG{\Atm} \mid \ADD{\Atm}{\Atm} } \\
+   &\mid& \gray{ \LET{\Var}{\Exp}{\Exp} } \\
+   &\mid& \gray{ \UNIOP{\key{'not}}{\Atm} } \\
+   &\mid& \gray{ \BINOP{\itm{cmp}}{\Atm}{\Atm} \mid \IF{\Exp}{\Exp}{\Exp} }\\
+   &\mid& \gray{ \LP\key{Collect}~\Int\RP \mid \LP\key{Allocate}~\Int~\Type\RP
+  \mid \LP\key{GlobalValue}~\Var\RP }\\
+   &\mid& \FUNREF{\Var} \mid \APPLY{\Atm}{\Atm\ldots}\\
+ \Def &::=& \gray{ \FUNDEF{\Var}{([\Var \code{:} \Type]\ldots)}{\Type}{\code{'()}}{\Exp} }\\
+R^{\dagger}_4  &::=& \gray{ \PROGRAMDEFS{\code{'()}}{\Def} }
+\end{array}
+\]
+\end{minipage}
+}
+\caption{$R_4^{\dagger}$ is $R_4$ in administrative normal form (ANF).}
+\label{fig:r4-anf-syntax}
+\end{figure}
 
 
 \section{Explicate Control and the $C_3$ language}
@@ -7644,6 +7688,7 @@ apply this new function to all the function definitions.
 \begin{figure}[tp]
 \fbox{
 \begin{minipage}{0.96\textwidth}
+\small
 \[
 \begin{array}{lcl}
 \Atm &::=& \gray{ \Int \mid \Var \mid \key{\#t} \mid \key{\#f} }
@@ -7674,7 +7719,7 @@ C_3 & ::= & \Def\ldots
 \begin{figure}[tp]
 \fbox{
 \begin{minipage}{0.96\textwidth}
-    \small
+\small
 \[
 \begin{array}{lcl}
 \Atm &::=& \gray{ \INT{\Int} \mid \VAR{\Var} \mid \BOOL{\itm{bool}} }\\
@@ -7682,19 +7727,19 @@ C_3 & ::= & \Def\ldots
 \Exp &::= & \gray{ \Atm \mid \READ{} } \\
    &\mid& \gray{ \NEG{\Atm} \mid \ADD{\Atm}{\Atm} }\\
    &\mid& \gray{ \UNIOP{\key{not}}{\Atm} \mid \BINOP{\itm{cmp}}{\Atm}{\Atm}  } \\
-   &\mid& \gray{ (\key{Allocate} \,\itm{int}\,\itm{type}) } \\
+   &\mid& \gray{ \LP\key{Allocate} \,\itm{int}\,\itm{type}\RP } \\
    &\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& \gray{ \LP\key{Prim}~\key{'vector-set!}\,\LP\key{list}\,\Atm\,\INT{\Int}\,\Atm\RP\RP }\\
+   &\mid& \gray{ \LP\key{GlobalValue} \,\Var\RP \mid \LP\key{Void}\RP }\\
    &\mid& \FUNREF{\itm{label}} \mid \CALL{\Atm}{\LP\Atm\ldots\RP} \\
 \Stmt &::=& \gray{ \ASSIGN{\VAR{\Var}}{\Exp} 
-       \mid (\key{Collect} \,\itm{int}) } \\
+       \mid \LP\key{Collect} \,\itm{int}\RP } \\
 \Tail &::= & \gray{ \RETURN{\Exp} \mid \SEQ{\Stmt}{\Tail} 
        \mid \GOTO{\itm{label}} } \\
     &\mid& \gray{ \IFSTMT{\BINOP{\itm{cmp}}{\Atm}{\Atm}}{\GOTO{\itm{label}}}{\GOTO{\itm{label}}}  }\\
     &\mid& \TAILCALL{\Atm}{\Atm\ldots} \\
-\Def &::=& \DEF{\itm{label}}{([\Var\key{:}\Type]\ldots)}{\Type}{\itm{info}}{((\itm{label}\,\key{.}\,\Tail)\ldots)}\\
-C_3 & ::= & \PROGRAMDEFS{\itm{info}}{(\Def\ldots)} 
+\Def &::=& \DEF{\itm{label}}{\LP[\Var\key{:}\Type]\ldots\RP}{\Type}{\itm{info}}{\LP\LP\itm{label}\,\key{.}\,\Tail\RP\ldots\RP}\\
+C_3 & ::= & \PROGRAMDEFS{\itm{info}}{\LP\Def\ldots\RP} 
 \end{array}
 \]
 \end{minipage}
@@ -8566,7 +8611,7 @@ $\Downarrow$
 \begin{tikzpicture}[baseline=(current  bounding  box.center)]
 \node (R4) at (0,2)  {\large $R_4$};
 \node (R4-2) at (3,2)  {\large $R_4$};
-%\node (R4-3) at (6,2)  {\large $R_4$};
+\node (R4-3) at (6,2)  {\large $R_4$};
 \node (F1-1) at (12,0)  {\large $F_1$};
 \node (F1-2) at (9,0)  {\large $F_1$};
 \node (F1-3) at (6,0)  {\large $F_1$};
@@ -8582,25 +8627,25 @@ $\Downarrow$
 \node (x86-2-1) at (3,-6)  {\large $\text{x86}^{*}_3$};
 \node (x86-2-2) at (6,-6)  {\large $\text{x86}^{*}_3$};
 
-%% \path[->,bend left=15] (R4) edge [above] node
-%%      {\ttfamily\footnotesize\color{red} type-check} (R4-2);
 \path[->,bend left=15] (R4) edge [above] node
-     {\ttfamily\footnotesize uniquify} (R4-2);
-\path[->,bend left=15] (R4-2) edge [right] node
+     {\ttfamily\footnotesize shrink} (R4-2);
+\path[->,bend left=15] (R4-2) edge [above] node
+     {\ttfamily\footnotesize uniquify} (R4-3);
+\path[->,bend left=15] (R4-3) edge [right] node
      {\ttfamily\footnotesize reveal-functions} (F1-1);
 \path[->,bend left=15] (F1-1) edge [below] node
      {\ttfamily\footnotesize\color{red} convert-to-clos.} (F1-2);
 \path[->,bend right=15] (F1-2) edge [above] node
-     {\ttfamily\footnotesize limit-functions} (F1-3);
+     {\ttfamily\footnotesize limit-fun.} (F1-3);
 \path[->,bend right=15] (F1-3) edge [above] node
      {\ttfamily\footnotesize expose-alloc.} (F1-4);
 \path[->,bend right=15] (F1-4) edge [above] node
      {\ttfamily\footnotesize remove-complex.} (F1-5);
-\path[->] (F1-5) edge [left] node
+\path[->,bend right=15] (F1-5) edge [right] node
      {\ttfamily\footnotesize explicate-control} (C3-2);
-\path[->,bend right=15] (C3-2) edge [left] node
+\path[->,bend left=15] (C3-2) edge [left] node
      {\ttfamily\footnotesize select-instr.} (x86-2);
-\path[->,bend left=15] (x86-2) edge [left] node
+\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 build-inter.} (x86-2-2);
@@ -8608,7 +8653,8 @@ $\Downarrow$
      {\ttfamily\footnotesize allocate-reg.} (x86-3);
 \path[->,bend left=15] (x86-3) edge [above] node
      {\ttfamily\footnotesize patch-instr.} (x86-4);
-\path[->,bend right=15] (x86-4) edge [left] node {\ttfamily\footnotesize print-x86} (x86-5);
+\path[->,bend left=15] (x86-4) edge [right] node
+     {\ttfamily\footnotesize print-x86} (x86-5);
 \end{tikzpicture}
   \caption{Diagram of the passes for $R_5$, a language with lexically-scoped
   functions.}
@@ -8702,7 +8748,7 @@ operator in a direct call, then we say that the function
 need to perform closure conversion on the function.
 
 \begin{exercise}\normalfont
-  Implement an auxilliary function for detecting which global
+  Implement an auxiliary function for detecting which global
   functions escape. Using that function, implement an improved version
   of closure conversion that does not apply closure conversion to
   global functions that do not escape but instead compiles them as
@@ -8852,7 +8898,7 @@ in Figure~\ref{fig:r8-syntax}.
      &\mid& \gray{ \VOID{} \mid \LP\key{HasType}~\Exp~\Type \RP 
      \mid \APPLY{\Exp}{\Exp\ldots} }\\
   &\mid& \gray{ \LAMBDA{\LP\LS\Var\code{:}\Type\RS\ldots\RP}{\Type}{\Exp} }\\
-  &\mid& \SETBANG{\Var}{\Exp} \mid \BEGIN{\Exp\ldots}{\Exp}
+  &\mid& \SETBANG{\Var}{\Exp} \mid \BEGIN{\LP\Exp\ldots\RP}{\Exp}
    \mid \WHILE{\Exp}{\Exp} \\
  \Def &::=& \gray{ \FUNDEF{\Var}{\LP\LS\Var \code{:} \Type\RS\ldots\RP}{\Type}{\code{'()}}{\Exp} }\\
   R_5 &::=& \gray{ \PROGRAMDEFSEXP{\code{'()}}{\LP\Def\ldots\RP}{\Exp} }
@@ -8865,6 +8911,9 @@ in Figure~\ref{fig:r8-syntax}.
 \end{figure}
 
 
+% TODO: type checker and interpreter for $R_8$.
+
+  
 At first glance, the translation of these language features to x86
 seems to be trivial because the $C_3$ intermediate language already
 supports all of the ingredients that we need: assignment, \code{goto},
@@ -8900,7 +8949,7 @@ closure. Thus, if we naively add support for assignment to our current
 compiler, the output of this program would be \code{32}.
 
 A first attempt at solving this problem would be to save a pointer to
-\code{x} in the closure and change the occurences of \code{x} inside
+\code{x} in the closure and change the occurrences of \code{x} inside
 the lambda to dereference the pointer. Of course, this would require
 assigning \code{x} to the stack and not to a register. However, the
 problem goes a bit deeper. Consider the following example in which we
@@ -8998,8 +9047,8 @@ Next we might try to analyze \code{block5} or \code{block7}, but
 \code{block5} jumps to \code{block7} and vice versa, so it seems that
 we are stuck.
 
-The way out of this impass comes from the realization that one can
-perfom liveness analysis starting with an empty live-after set to
+The way out of this impasse comes from the realization that one can
+perform liveness analysis starting with an empty live-after set to
 compute an under-approximation of the live-before set.  By
 \emph{under-approximation}, we mean that the set only contains
 variables that are really live, but it may be missing some.  Next, the
@@ -9041,16 +9090,16 @@ block8: {rsp, sum1}
 \end{center}
 
 For the second round, the live-after for \code{mainstart} is the
-current live-before for \code{block5}, which is \code{\{i2\}}.  So
-the liveness analysis for \code{mainstart} computes the empty set. The
-live-after for \code{block5} is the union of the live-before's for
+current live-before for \code{block5}, which is \code{\{i2\}}.  So the
+liveness analysis for \code{mainstart} computes the empty set. The
+live-after for \code{block5} is the union of the live-before sets for
 \code{block7} and \code{block8}, which is \code{\{i2 , rsp, sum1\}}.
 So the liveness analysis for \code{block5} computes \code{\{i2 , rsp,
   sum1\}}.  The live-after for \code{block7} is the live-before for
 \code{block5} (from the previous iteration), which is \code{\{i2\}}.
-So the liveness analysis for \code{block7} remains \code{\{i2, sum1\}}.
-Together these yield the following approximation $m_2$ of the
-live-before sets.
+So the liveness analysis for \code{block7} remains \code{\{i2,
+  sum1\}}.  Together these yield the following approximation $m_2$ of
+the live-before sets.
 \begin{center}
   \begin{lstlisting}
 mainstart: {}
@@ -9059,7 +9108,7 @@ block7: {i2, sum1}
 block8: {rsp, sum1}
 \end{lstlisting}
 \end{center}
-In the preceeding iteration, only \code{block5} changed, so we can
+In the preceding iteration, only \code{block5} changed, so we can
 limit our attention to \code{mainstart} and \code{block7}, the two
 blocks that jump to \code{block5}.  As a result, the live-before sets
 for \code{mainstart} and \code{block7} are updated to include
@@ -9092,7 +9141,7 @@ operator takes two lattice elements and combines their information,
 i.e., it produces the least upper bound of the two.\index{least upper
   bound}
 
-A dataflow analysis typicaly involves two lattices: one lattice to
+A dataflow analysis typically involves two lattices: one lattice to
 represent abstract states and another lattice that aggregates the
 abstract states of all the blocks in the control-flow graph.  For
 liveness analysis, an abstract state is a set of locations.  We form
@@ -9102,11 +9151,11 @@ set, and the join operator to be set union.
 %
 We form a second lattice $M$ by taking its elements to be mappings
 from the block labels to sets of locations (elements of $L$).  We
-order the mappings pointwise, using the ordering of $L$. So given any
+order the mappings point-wise, using the ordering of $L$. So given any
 two mappings $m_i$ and $m_j$, $m_i \sqsubseteq_M m_j$ when $m_i(\ell)
 \subseteq m_j(\ell)$ for every block label $\ell$ in the program.  The
 bottom element of $M$ is the mapping $\bot_M$ that sends every label
-to the emptyset, i.e., $\bot_M(\ell) = \emptyset$.
+to the empty set, i.e., $\bot_M(\ell) = \emptyset$.
 
 We can think of one iteration of liveness analysis as being a function
 $f$ on the lattice $M$. It takes a mapping as input and computes a new
@@ -9154,8 +9203,8 @@ generic work list algorithm (Figure~\ref{fig:generic-dataflow}).
 The algorithm has four parameters: the control-flow graph \code{G}, a
 function \code{transfer} that applies the analysis to one block, the
 \code{bottom} and \code{join} operator for the lattice of abstract
-staties.  The algorithm begins by creating the bottom mapping,
-represented by hashtable.  It then pushes all of the nodes in the
+states.  The algorithm begins by creating the bottom mapping,
+represented by a hash table.  It then pushes all of the nodes in the
 control-flow graph onto the work list (a queue). The algorithm repeats
 the \code{while} loop as long as there are items in the work list. In
 each iteration, a node is popped from the work list and processed. The
@@ -9242,11 +9291,11 @@ example is as follows.
 
 \paragraph{Assigned \& Free}
 
-We recommend defining an auxilliary function named
+We recommend defining an auxiliary function named
 \code{assigned\&free} that takes an expression and simultaneously
 computes 1) a set of assigned variables $A$, 2) a set $F$ of variables
 that occur free within lambda's, and 3) a new version of the
-expression that records which bound variables occured in the
+expression that records which bound variables occurred in the
 intersection of $A$ and $F$. You can use the struct
 \code{AssignedFree} to do this. Consider the case for
 $\LET{x}{\itm{rhs}}{\itm{body}}$.  Suppose the the recursive call on
@@ -9360,54 +9409,237 @@ function \code{f}.
 \section{Remove Complex Operands}
 \label{sec:rco-loop}
 
+The three new language forms, \code{while}, \code{set!}, and
+\code{begin} need to be categorized as atomic or complex expressions,
+as do their subexpressions. They are all complex and their
+subexpressions are all allowed to be complex.
+Figure~\ref{fig:r4-anf-syntax} defines the output language
+$R_4^{\dagger}$ of this pass.
 
-TODO: define the output grammar
+\begin{figure}[tp]
+\centering
+\fbox{
+\begin{minipage}{0.96\textwidth}
+\small
+\[
+\begin{array}{rcl}
+\Atm &::=& \gray{ \INT{\Int} \mid \VAR{\Var} \mid \BOOL{\itm{bool}}
+       \mid \VOID{} } \\
+\Exp &::=& \ldots \mid \gray{ \LET{\Var}{\Exp}{\Exp} } \\
+    &\mid& \WHILE{\Exp}{\Exp} \mid \SETBANG{\Var}{\Exp}
+   \mid \BEGIN{\LP\Exp\ldots\RP}{\Exp} \\
+\Def &::=& \gray{ \FUNDEF{\Var}{([\Var \code{:} \Type]\ldots)}{\Type}{\code{'()}}{\Exp} }\\
+R^{\dagger}_8  &::=& \gray{ \PROGRAMDEFS{\code{'()}}{\Def} }
+\end{array}
+\]
+\end{minipage}
+}
+\caption{$R_8^{\dagger}$ is $R_8$ in administrative normal form (ANF).}
+\label{fig:r8-anf-syntax}
+\end{figure}
 
+As usual, when a complex expression appears in a grammar position that
+needs to be atomic, such as the argument of a primitive operator, we
+must introduce a temporary variable and bind it to the complex
+expression.  This approach applies, unchanged, to handle the new
+language forms.  For example, in the following code there are two
+\code{begin} expressions appearing as arguments to \code{+}.  The
+output of \code{rco-exp} is shown below, in which the \code{begin}
+expression have been bound to temporary variables. Recall that
+\code{let} expressions in $R_8^{\dagger}$ are allowed to have
+arbitrary expressions in their right-hand-side expression, so it is
+fine to place \code{begin} there.
 
 \begin{lstlisting}
 (let ([x0 10])
   (let ([y1 0])
     (+ (+ (begin (set! y1 (read)) x0)
-          (begin (set! x0 (read)) y1))
+           (begin (set! x0 (read)) y1))
        x0)))
 |$\Rightarrow$|
-(define (main) : Integer
-  (let ([x0 10])
-    (let ([y1 0])
-      (let ([tmp2 (begin 
-                    (set! y1 (read))
-                    x0)])
-        (let ([tmp3 (begin 
-                      (set! x0 (read))
-                      y1)])
-          (let ([tmp4 (+ tmp2 tmp3)])
-            (+ tmp4 x0)))))))
+(let ([x0 10])
+  (let ([y1 0])
+    (let ([tmp2 (begin (set! y1 (read)) x0)])
+      (let ([tmp3 (begin (set! x0 (read)) y1)])
+        (let ([tmp4 (+ tmp2 tmp3)])
+          (+ tmp4 x0))))))
 \end{lstlisting}
 
+\section{Explicate Control}
+\label{sec:explicate-loop}
 
+Recall that in the \code{explicate-control} pass we define one helper
+function for each kind of position in the program.  For the $R_1$
+language of integers and variables we needed kinds of positions:
+assignment and tail. The \code{if} expressions of $R_2$ introduced
+predicate positions. For $R_8$, the \code{begin} expression introduces
+yet another kind of position: effect position. Except for the last
+subexpression, the subexpressions inside a \code{begin} are evaluated
+only for their effect. Their result values are discarded. We can
+generate better code by taking this fact into account.
+
+The output language of \code{explicate-control} is $C_7$
+(Figure~\ref{fig:c7-syntax}), which is nearly identical to $C_3$. The
+only difference is that \code{Call}, \code{vector-set!}, and
+\code{read} may also appear as statements.
 
+\begin{figure}[tp]
+\fbox{
+\begin{minipage}{0.96\textwidth}
+\small
+\[
+\begin{array}{lcl}
+\Stmt &::=& \gray{ \ASSIGN{\VAR{\Var}}{\Exp} 
+       \mid \LP\key{Collect} \,\itm{int}\RP } \\
+     &\mid& \CALL{\Atm}{\LP\Atm\ldots\RP} \mid \READ{}\\
+     &\mid& \LP\key{Prim}~\key{'vector-set!}\,\LP\key{list}\,\Atm\,\INT{\Int}\,\Atm\RP\RP \\
+\Def &::=& \DEF{\itm{label}}{\LP\LS\Var\key{:}\Type\RS\ldots\RP}{\Type}{\itm{info}}{\LP\LP\itm{label}\,\key{.}\,\Tail\RP\ldots\RP}\\
+C_3 & ::= & \PROGRAMDEFS{\itm{info}}{\LP\Def\ldots\RP} 
+\end{array}
+\]
+\end{minipage}
+}
+\caption{The abstract syntax of $C_7$, extending $C_3$ (Figure~\ref{fig:c3-syntax}).}
+\label{fig:c7-syntax}
+\end{figure}
 
+The new auxiliary function \code{explicate-effect} takes an expression
+(in an effect position) and a promise of a continuation block. The
+function returns a promise for a $\Tail$ that includes the generated
+code for the input expression followed by the continuation block.  If
+the expression is obviously pure, that is, never causes side effects,
+then the expression can be removed, so the result is just the
+continuation block.
+%
+The $\WHILE{\itm{cnd}}{\itm{body}}$ loop is the most interesting case.
+First, you will need a fresh label $\itm{loop}$ for the top of the
+loop.  Recursively process the \itm{body} (in effect position) with
+the a \code{goto} to $\itm{loop}$ as the continuation, producing
+\itm{body'}. Next, process the \itm{cnd} (in predicate position) with
+\itm{body'} as the then-branch and the continuation block as the
+else-branch. The result should be added to the control-flow graph with
+the label \itm{loop}. The result for the whole \code{while} loop is a
+\code{goto} to the \itm{loop} label. Note that the loop should only be
+added to the control-flow graph if the loop is indeed used, which can
+be accomplished using \code{delay}.
+
+The auxiliary functions for tail, assignment, and predicate positions
+need to be updated. The three new language forms, \code{while},
+\code{set!}, and \code{begin}, can appear in assignment and tail
+positions.  Only \code{begin} may appear in predicate positions; the
+other two have result type \code{Void}.
 
-\section{Explicate Control}
-\label{sec:explicate-loop}
+\section{Select Instructions}
+\label{sec:select-instructions-loop}
 
+Only three small additions are needed in the
+\code{select-instructions} pass to handle the changes to $C_7$.  That
+is, \code{Call}, \code{read}, and \code{vector-set!} may now appear as
+stand-alone statements instead of only appearing on the right-hand
+side of an assignment statement. The code generation is nearly
+identical; just leave off the instruction for moving the result into
+the left-hand side.
 
 \section{Register Allocation}
 \label{sec:register-allocation-loop}
 
+As discussed in Section~\ref{sec:dataflow-analysis}, the presence of
+loops in $R_8$ means that the control-flow graphs may contain cycles,
+which complicates the liveness analysis needed for register
+allocation.
 
-%\section{Remove Jumps}
-%\label{sec:remove-jumps-loop}
+\subsection{Liveness Analysis}
+\label{sec:liveness-analysis-r8}
 
+We recommend using the generic \code{analyze-dataflow} function that
+was presented at the end of Section~\ref{sec:dataflow-analysis} to
+perform liveness analysis, replacing the code in
+\code{uncover-live-CFG} that processed the basic blocks in topological
+order (Section~\ref{sec:liveness-analysis-r2}).
 
-\section{Select Instructions}
-\label{sec:select-instructions-loop}
+The \code{analyze-dataflow} function has four parameters.
+\begin{enumerate}
+\item The first parameter \code{G} should be a directed graph from the
+  \code{racket/graph} package (see the sidebar in
+  Section~\ref{sec:build-interference}) that represents the
+  control-flow graph.
+\item The second parameter \code{transfer} is a function that applies
+  liveness analysis to a basic block. It takes two parameters: the
+  label for the block to analyze and the live-after set for that
+  block.  The transfer function should return the live-before set for
+  the block.  Also, as a side-effect, it should update the block's
+  $\itm{info}$ with the liveness information for each instruction. To
+  implement the \code{transfer} function, you should be able to reuse
+  the code you already have for analyzing basic blocks.
+\item The third and fourth parameters of \code{analyze-dataflow} are
+  \code{bottom} and \code{join} for the lattice of abstract states,
+  i.e.  sets of locations. The bottom of the lattice is the empty set
+  \code{(set)} and the join operator is \code{set-union}.
+\end{enumerate}
 
 
+\begin{figure}[p]
+\begin{tikzpicture}[baseline=(current  bounding  box.center)]
+\node (R4) at (0,2)  {\large $R_8$};
+\node (R4-2) at (3,2)  {\large $R_8$};
+\node (R4-3) at (6,2)  {\large $R_8$};
+\node (R4-4) at (9,2)  {\large $R_8$};
+\node (F1-1) at (12,0)  {\large $F_1$};
+\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 (F1-5) at (0,0)  {\large $F_1$};
+\node (C3-2) at (3,-2)  {\large $C_3$};
+
+\node (x86-2) at (3,-4)  {\large $\text{x86}^{*}_3$};
+\node (x86-3) at (6,-4)  {\large $\text{x86}^{*}_3$};
+\node (x86-4) at (9,-4) {\large $\text{x86}^{*}_3$};
+\node (x86-5) at (9,-6) {\large $\text{x86}^{\dagger}_3$};
 
+\node (x86-2-1) at (3,-6)  {\large $\text{x86}^{*}_3$};
+\node (x86-2-2) at (6,-6)  {\large $\text{x86}^{*}_3$};
+
+%% \path[->,bend left=15] (R4) edge [above] node
+%%      {\ttfamily\footnotesize\color{red} type-check} (R4-2);
+\path[->,bend left=15] (R4) edge [above] node
+     {\ttfamily\footnotesize shrink} (R4-2);
+\path[->,bend left=15] (R4-2) edge [above] node
+     {\ttfamily\footnotesize uniquify} (R4-3);
+\path[->,bend left=15] (R4-3) edge [above] node
+     {\ttfamily\footnotesize\color{red} convert-assignments} (R4-4);
+\path[->,bend left=15] (R4-4) edge [left] node
+     {\ttfamily\footnotesize reveal-functions} (F1-1);
+\path[->,bend left=15] (F1-1) edge [below] node
+     {\ttfamily\footnotesize convert-to-clos.} (F1-2);
+\path[->,bend right=15] (F1-2) edge [above] node
+     {\ttfamily\footnotesize limit-fun.} (F1-3);
+\path[->,bend right=15] (F1-3) edge [above] node
+     {\ttfamily\footnotesize expose-alloc.} (F1-4);
+\path[->,bend right=15] (F1-4) edge [above] node
+     {\ttfamily\footnotesize\color{red} remove-complex.} (F1-5);
+\path[->,bend right=15] (F1-5) edge [right] node
+     {\ttfamily\footnotesize\color{red} explicate-control} (C3-2);
+\path[->,bend left=15] (C3-2) edge [left] node
+     {\ttfamily\footnotesize\color{red} select-instr.} (x86-2);
+\path[->,bend right=15] (x86-2) edge [left] node
+     {\ttfamily\footnotesize\color{red} uncover-live} (x86-2-1);
+\path[->,bend right=15] (x86-2-1) edge [below] node 
+     {\ttfamily\footnotesize build-inter.} (x86-2-2);
+\path[->,bend right=15] (x86-2-2) edge [left] node
+     {\ttfamily\footnotesize allocate-reg.} (x86-3);
+\path[->,bend left=15] (x86-3) edge [above] node
+     {\ttfamily\footnotesize patch-instr.} (x86-4);
+\path[->,bend left=15] (x86-4) edge [right] node {\ttfamily\footnotesize print-x86} (x86-5);
+\end{tikzpicture}
+  \caption{Diagram of the passes for $R_8$ (loops and assignment).}
+\label{fig:R8-passes}
+\end{figure}
 
+Figure~\ref{fig:R8-passes} provides an overview of all the passes needed
+for the compilation of $R_8$.
 
 
+% TODO: challenge assignment
 
 %%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%
 \chapter{Dynamic Typing}
@@ -10434,11 +10666,11 @@ registers.
 %%  LocalWords:  Sarkar lcl Matz aa representable Chez Ph Dan's nano
 %%  LocalWords:  fk bh Siek plt uq Felleisen Bor Yuh ASTs AST Naur eq
 %%  LocalWords:  BNF fixnum datatype arith prog backquote quasiquote
-%%  LocalWords:  ast Reynold's reynolds interp cond fx evaluator
+%%  LocalWords:  ast Reynold's reynolds interp cond fx evaluator jane
 %%  LocalWords:  quasiquotes pe nullary unary rcl env lookup gcc rax
 %%  LocalWords:  addq movq callq rsp rbp rbx rcx rdx rsi rdi subq nx
 %%  LocalWords:  negq pushq popq retq globl Kernighan uniquify lll ve
-%%  LocalWords:  allocator gensym env subdirectory scm rkt tmp lhs
+%%  LocalWords:  allocator gensym env subdirectory scm rkt tmp lhs Tt
 %%  LocalWords:  runtime Liveness liveness undirected Balakrishnan je
 %%  LocalWords:  Rosen DSATUR SDO Gebremedhin Omari morekeywords cnd
 %%  LocalWords:  fullflexible vertices Booleans Listof Pairof thn els
@@ -10461,4 +10693,11 @@ registers.
 % LocalWords:  mainconclusion Cardelli bodyT fvs clos fvts subtype uj
 % LocalWords:  polymorphism untyped elts tys tagof Vectorof tyeq orq
 % LocalWords:  andq untagged Shao inlining ebp jge setle setg setge
-% LocalWords:  struct symtab
+% LocalWords:  struct symtab Friedman's MacOS Nystrom alist sam kate
+% LocalWords:  alists arity github unordered pqueue exprs ret param
+% LocalWords:  tyerr bytereg dh dl JmpIf HasType Osterlund Jacek TODO
+% LocalWords:  Gamari GlobalValue ProgramDefsExp prm ProgramDefs vn
+% LocalWords:  FunRef TailCall tailjmp IndirectCallq TailJmp Gilray
+% LocalWords:  dereference unbox Dataflow versa dataflow Kildall rhs
+% LocalWords:  Kleene enqueue dequeue AssignedFree FV cnvt SetBang tg
+% LocalWords:  ValueOf typechecker