소스 검색

copy edits for ch 5

Jeremy Siek 3 년 전
부모
커밋
1ae70bcd6f
1개의 변경된 파일125개의 추가작업 그리고 126개의 파일을 삭제
  1. 125 126
      book.tex

+ 125 - 126
book.tex

@@ -9216,11 +9216,10 @@ conclusion:
 \begin{tcolorbox}[colback=white]  
 \begin{tcolorbox}[colback=white]  
 {\if\edition\racketEd
 {\if\edition\racketEd
 \begin{tikzpicture}[baseline=(current  bounding  box.center),scale=0.90]
 \begin{tikzpicture}[baseline=(current  bounding  box.center),scale=0.90]
-\node (Lif) at (0,2)  {\large \LangIf{}};
-\node (Lif-2) at (3,2)  {\large \LangIf{}};
-\node (Lif-3) at (6,2)  {\large \LangIf{}};
-\node (Lif-4) at (9,2)  {\large \LangIf{}};
-\node (Lif-5) at (9,0)  {\large \LangIfANF{}};
+\node (Lif-2) at (0,2)  {\large \LangIf{}};
+\node (Lif-3) at (3,2)  {\large \LangIf{}};
+\node (Lif-4) at (6,2)  {\large \LangIf{}};
+\node (Lif-5) at (10,2)  {\large \LangIfANF{}};
 \node (C1-1) at (0,0)  {\large \LangCIf{}};
 \node (C1-1) at (0,0)  {\large \LangCIf{}};
 
 
 \node (x86-2) at (0,-2)  {\large \LangXIfVar{}};
 \node (x86-2) at (0,-2)  {\large \LangXIfVar{}};
@@ -9230,11 +9229,10 @@ conclusion:
 \node (x86-4) at (8,-2) {\large \LangXIf{}};
 \node (x86-4) at (8,-2) {\large \LangXIf{}};
 \node (x86-5) at (8,-4) {\large \LangXIf{}};
 \node (x86-5) at (8,-4) {\large \LangXIf{}};
 
 
-\path[->,bend left=15] (Lif) edge [above] node {\ttfamily\footnotesize type\_check} (Lif-2);
 \path[->,bend left=15] (Lif-2) edge [above] node {\ttfamily\footnotesize shrink} (Lif-3);
 \path[->,bend left=15] (Lif-2) edge [above] node {\ttfamily\footnotesize shrink} (Lif-3);
 \path[->,bend left=15] (Lif-3) edge [above] node {\ttfamily\footnotesize uniquify} (Lif-4);
 \path[->,bend left=15] (Lif-3) edge [above] node {\ttfamily\footnotesize uniquify} (Lif-4);
-\path[->,bend left=15] (Lif-4) edge [left] node {\ttfamily\footnotesize remove\_complex\_operands} (Lif-5);
-\path[->,bend left=10] (Lif-5) edge [above] node {\ttfamily\footnotesize explicate\_control} (C1-1);
+\path[->,bend left=15] (Lif-4) edge [above] node {\ttfamily\footnotesize remove\_complex\_operands} (Lif-5);
+\path[->,bend left=10] (Lif-5) edge [right] node {\ttfamily\footnotesize explicate\_control} (C1-1);
 \path[->,bend right=15] (C1-1) edge [right] node {\ttfamily\footnotesize select\_instructions} (x86-2);
 \path[->,bend right=15] (C1-1) edge [right] node {\ttfamily\footnotesize select\_instructions} (x86-2);
 \path[->,bend left=15] (x86-2) edge [right] node {\ttfamily\footnotesize uncover\_live} (x86-2-1);
 \path[->,bend left=15] (x86-2) edge [right] node {\ttfamily\footnotesize uncover\_live} (x86-2-1);
 \path[->,bend right=15] (x86-2-1) edge [below] node {\ttfamily\footnotesize build\_interference} (x86-2-2);
 \path[->,bend right=15] (x86-2-1) edge [below] node {\ttfamily\footnotesize build\_interference} (x86-2-2);
@@ -9794,7 +9792,7 @@ and the case-of-case transformation~\citep{PeytonJones:1998}.
 In this chapter we study two features that are the hallmarks of
 In this chapter we study two features that are the hallmarks of
 imperative programming languages: loops and assignments to local
 imperative programming languages: loops and assignments to local
 variables. The following example demonstrates these new features by
 variables. The following example demonstrates these new features by
-computing the sum of the first five positive integers.
+computing the sum of the first five positive integers:
 % similar to loop_test_1.rkt
 % similar to loop_test_1.rkt
 \begin{lstlisting}
 \begin{lstlisting}
 (let ([sum 0])
 (let ([sum 0])
@@ -9807,10 +9805,10 @@ computing the sum of the first five positive integers.
       sum)))
       sum)))
 \end{lstlisting}
 \end{lstlisting}
 The \code{while} loop consists of a condition and a
 The \code{while} loop consists of a condition and a
-body\footnote{The \code{while} loop is not a built-in
+body.\footnote{The \code{while} loop is not a built-in
 feature of the Racket language, but Racket includes many looping
 feature of the Racket language, but Racket includes many looping
 constructs and it is straightforward to define \code{while} as a
 constructs and it is straightforward to define \code{while} as a
-macro.}. The body is evaluated repeatedly so long as the condition
+macro.} The body is evaluated repeatedly so long as the condition
 remains true.
 remains true.
 %
 %
 The \code{set!} consists of a variable and a right-hand side
 The \code{set!} consists of a variable and a right-hand side
@@ -9818,26 +9816,27 @@ expression.  The \code{set!} updates value of the variable to the
 value of the right-hand side.
 value of the right-hand side.
 %
 %
 The primary purpose of both the \code{while} loop and \code{set!} is
 The primary purpose of both the \code{while} loop and \code{set!} is
-to cause side effects, so they do not have a meaningful result
-value. Instead their result is the \code{\#<void>} value.  The
+to cause side effects, so they do not give a meaningful result
+value. Instead, their result is the \code{\#<void>} value.  The
 expression \code{(void)} is an explicit way to create the
 expression \code{(void)} is an explicit way to create the
-\code{\#<void>} value and it has type \code{Void}.  The
+\code{\#<void>} value, and it has type \code{Void}.  The
 \code{\#<void>} value can be passed around just like other values
 \code{\#<void>} value can be passed around just like other values
-inside an \LangLoop{} program and it can be compared for equality with
+inside an \LangLoop{} program, and it can be compared for equality with
 another \code{\#<void>} value. However, there are no other operations
 another \code{\#<void>} value. However, there are no other operations
-specific to the the \code{\#<void>} value in \LangLoop{}. In contrast,
+specific to the \code{\#<void>} value in \LangLoop{}. In contrast,
 Racket defines the \code{void?}  predicate that returns \code{\#t}
 Racket defines the \code{void?}  predicate that returns \code{\#t}
 when applied to \code{\#<void>} and \code{\#f} otherwise.%
 when applied to \code{\#<void>} and \code{\#f} otherwise.%
 %
 %
 \footnote{Racket's \code{Void} type corresponds to what is often
 \footnote{Racket's \code{Void} type corresponds to what is often
   called the \code{Unit} type. Racket's \code{Void} type is inhabited
   called the \code{Unit} type. Racket's \code{Void} type is inhabited
-  by a single value \code{\#<void>} which corresponds to \code{unit}
-  or \code{()} in the literature~\citep{Pierce:2002hj}.}.
+  by a single value \code{\#<void>}, which corresponds to \code{unit}
+  or \code{()} in the literature~\citep{Pierce:2002hj}.}
 %
 %
-With the addition of side-effecting features such as \code{while} loop
-and \code{set!}, it is helpful to also include in a language feature
-for sequencing side effects: the \code{begin} expression. It consists
-of one or more subexpressions that are evaluated left-to-right.
+With the addition of side effect-producing features such as
+\code{while} loop and \code{set!}, it is helpful to include a language
+feature for sequencing side effects: the \code{begin} expression. It
+consists of one or more subexpressions that are evaluated
+left to right.
 %
 %
 \fi}
 \fi}
 
 
@@ -9966,9 +9965,9 @@ the condition remains true.
 \label{fig:Lwhile-syntax}
 \label{fig:Lwhile-syntax}
 \end{figure}
 \end{figure}
 
 
-The concrete syntax of \LangLoop{} is defined in
-figure~\ref{fig:Lwhile-concrete-syntax} and its abstract syntax is defined
-in figure~\ref{fig:Lwhile-syntax}.
+Figure~\ref{fig:Lwhile-concrete-syntax} shows the definition of the
+concrete syntax of \LangLoop{}, and figure~\ref{fig:Lwhile-syntax}
+shows the definition of its abstract syntax.
 %
 %
 The definitional interpreter for \LangLoop{} is shown in
 The definitional interpreter for \LangLoop{} is shown in
 figure~\ref{fig:interp-Lwhile}.
 figure~\ref{fig:interp-Lwhile}.
@@ -9976,20 +9975,20 @@ figure~\ref{fig:interp-Lwhile}.
 {\if\edition\racketEd    
 {\if\edition\racketEd    
 %
 %
 We add new cases for \code{SetBang}, \code{WhileLoop}, \code{Begin},
 We add new cases for \code{SetBang}, \code{WhileLoop}, \code{Begin},
-and \code{Void} and we make changes to the cases for \code{Var} and
+and \code{Void}, and we make changes to the cases for \code{Var} and
 \code{Let} regarding variables. To support assignment to variables and
 \code{Let} regarding variables. To support assignment to variables and
 to make their lifetimes indefinite (see the second example in
 to make their lifetimes indefinite (see the second example in
 section~\ref{sec:assignment-scoping}), we box the value that is bound
 section~\ref{sec:assignment-scoping}), we box the value that is bound
 to each variable (in \code{Let}). The case for \code{Var} unboxes the
 to each variable (in \code{Let}). The case for \code{Var} unboxes the
 value.
 value.
 %
 %
-Now to discuss the new cases. For \code{SetBang}, we find the
-variable in the environment to obtain a boxed value and then we change
+Now we discuss the new cases. For \code{SetBang}, we find the
+variable in the environment to obtain a boxed value, and then we change
 it using \code{set-box!} to the result of evaluating the right-hand
 it using \code{set-box!} to the result of evaluating the right-hand
 side.  The result value of a \code{SetBang} is \code{\#<void>}.
 side.  The result value of a \code{SetBang} is \code{\#<void>}.
 %
 %
-For the \code{WhileLoop}, we repeatedly 1) evaluate the condition, and
-if the result is true, 2) evaluate the body.
+For the \code{WhileLoop}, we repeatedly (1) evaluate the condition, and
+if the result is true, (2) evaluate the body.
 The result value of a \code{while} loop is also \code{\#<void>}.
 The result value of a \code{while} loop is also \code{\#<void>}.
 %
 %
 The $\BEGIN{\itm{es}}{\itm{body}}$ expression evaluates the
 The $\BEGIN{\itm{es}}{\itm{body}}$ expression evaluates the
@@ -10062,7 +10061,7 @@ class InterpLwhile(InterpLif):
 \label{fig:interp-Lwhile}
 \label{fig:interp-Lwhile}
 \end{figure}
 \end{figure}
 
 
-The type checker for \LangLoop{} is defined in
+The definition of the type checker for \LangLoop{} is shown in
 figure~\ref{fig:type-check-Lwhile}.
 figure~\ref{fig:type-check-Lwhile}.
 %
 %
 {\if\edition\racketEd    
 {\if\edition\racketEd    
@@ -10146,9 +10145,9 @@ class TypeCheckLwhile(TypeCheckLif):
 %  
 %  
 At first glance, the translation of these language features to x86
 At first glance, the translation of these language features to x86
 seems straightforward because the \LangCIf{} intermediate language
 seems straightforward because the \LangCIf{} intermediate language
-already supports all of the ingredients that we need: assignment,
+already supports all the ingredients that we need: assignment,
 \code{goto}, conditional branching, and sequencing. However, there are
 \code{goto}, conditional branching, and sequencing. However, there are
-complications that arise which we discuss in the next section. After
+complications that arise, which we discuss in the next section. After
 that we introduce the changes necessary to the existing passes.
 that we introduce the changes necessary to the existing passes.
 %
 %
 \fi}
 \fi}
@@ -10166,16 +10165,16 @@ that we introduce the changes necessary to the existing passes.
 \section{Cyclic Control Flow and Dataflow Analysis}
 \section{Cyclic Control Flow and Dataflow Analysis}
 \label{sec:dataflow-analysis}
 \label{sec:dataflow-analysis}
 
 
-Up until this point the programs generated in
+Up until this point, the programs generated in
 \code{explicate\_control} were guaranteed to be acyclic. However, each
 \code{explicate\_control} were guaranteed to be acyclic. However, each
-\code{while} loop introduces a cycle. But does that matter?
+\code{while} loop introduces a cycle. Does that matter?
 %
 %
-Indeed it does.  Recall that for register allocation, the compiler
+Indeed, it does.  Recall that for register allocation, the compiler
 performs liveness analysis to determine which variables can share the
 performs liveness analysis to determine which variables can share the
-same register.  To accomplish this we analyzed the control-flow graph
+same register.  To accomplish this, we analyzed the control-flow graph
 in reverse topological order
 in reverse topological order
 (section~\ref{sec:liveness-analysis-Lif}), but topological order is
 (section~\ref{sec:liveness-analysis-Lif}), but topological order is
-only well-defined for acyclic graphs.
+well defined only for acyclic graphs.
 
 
 Let us return to the example of computing the sum of the first five
 Let us return to the example of computing the sum of the first five
 positive integers. Here is the program after instruction selection but
 positive integers. Here is the program after instruction selection but
@@ -10242,10 +10241,10 @@ block8:
   \end{minipage}
   \end{minipage}
 \fi}
 \fi}
 \end{center}
 \end{center}
-Recall that liveness analysis works backwards, starting at the end
+Recall that liveness analysis works backward, starting at the end
 of each function. For this example we could start with \code{block8}
 of each function. For this example we could start with \code{block8}
-because we know what is live at the beginning of the conclusion,
-just \code{rax} and \code{rsp}. So the live-before set
+because we know what is live at the beginning of the conclusion:
+only \code{rax} and \code{rsp}. So the live-before set
 for \code{block8} is \code{\{rsp,sum\}}.
 for \code{block8} is \code{\{rsp,sum\}}.
 %
 %
 Next we might try to analyze \code{block5} or \code{block7}, but
 Next we might try to analyze \code{block5} or \code{block7}, but
@@ -10253,26 +10252,26 @@ Next we might try to analyze \code{block5} or \code{block7}, but
 we are stuck.
 we are stuck.
 
 
 The way out of this impasse is to realize that we can compute an
 The way out of this impasse is to realize that we can compute an
-under-approximation of each live-before set by starting with empty
-live-after sets.  By \emph{under-approximation}, we mean that the set
-only contains variables that are live for some execution of the
+underapproximation of each live-before set by starting with empty
+live-after sets.  By \emph{underapproximation}, we mean that the set
+contains only variables that are live for some execution of the
 program, but the set may be missing some variables that are live.
 program, but the set may be missing some variables that are live.
-Next, the under-approximations for each block can be improved by 1)
+Next, the underapproximations for each block can be improved by (1)
 updating the live-after set for each block using the approximate
 updating the live-after set for each block using the approximate
-live-before sets from the other blocks and 2) perform liveness
+live-before sets from the other blocks, and (2) performing liveness
 analysis again on each block.  In fact, by iterating this process, the
 analysis again on each block.  In fact, by iterating this process, the
-under-approximations eventually become the correct solutions!
+underapproximations eventually become the correct solutions!
 %
 %
 This approach of iteratively analyzing a control-flow graph is
 This approach of iteratively analyzing a control-flow graph is
 applicable to many static analysis problems and goes by the name
 applicable to many static analysis problems and goes by the name
 \emph{dataflow analysis}\index{subject}{dataflow analysis}.  It was invented by
 \emph{dataflow analysis}\index{subject}{dataflow analysis}.  It was invented by
-\citet{Kildall:1973vn} in his Ph.D. thesis at the University of
+\citet{Kildall:1973vn} in his PhD thesis at the University of
 Washington.
 Washington.
 
 
-Let us apply this approach to the above example. We use the empty set
-for the initial live-before set for each block. Let $m_0$ be the
-following mapping from label names to sets of locations (variables and
-registers).
+Let us apply this approach to the previously presented example. We use
+the empty set for the initial live-before set for each block. Let
+$m_0$ be the following mapping from label names to sets of locations
+(variables and registers):
 \begin{center}
 \begin{center}
 \begin{lstlisting}
 \begin{lstlisting}
 mainstart: {}, block5: {}, block7: {}, block8: {}
 mainstart: {}, block5: {}, block7: {}, block8: {}
@@ -10289,8 +10288,8 @@ mainstart: {}, block5: {i}, block7: {i, sum}, block8: {rsp, sum}
 \end{center}
 \end{center}
 
 
 For the second round, the live-after for \code{mainstart} is the
 For the second round, the live-after for \code{mainstart} is the
-current live-before for \code{block5}, which is \code{\{i\}}.  So the
-liveness analysis for \code{mainstart} computes the empty set. The
+current live-before for \code{block5}, which is \code{\{i\}}.  Therefore
+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
 live-after for \code{block5} is the union of the live-before sets for
 \code{block7} and \code{block8}, which is \code{\{i , rsp, sum\}}.
 \code{block7} and \code{block8}, which is \code{\{i , rsp, sum\}}.
 So the liveness analysis for \code{block5} computes \code{\{i , rsp,
 So the liveness analysis for \code{block5} computes \code{\{i , rsp,
@@ -10298,7 +10297,7 @@ So the liveness analysis for \code{block5} computes \code{\{i , rsp,
 \code{block5} (from the previous iteration), which is \code{\{i\}}.
 \code{block5} (from the previous iteration), which is \code{\{i\}}.
 So the liveness analysis for \code{block7} remains \code{\{i,
 So the liveness analysis for \code{block7} remains \code{\{i,
   sum\}}.  Together these yield the following approximation $m_2$ of
   sum\}}.  Together these yield the following approximation $m_2$ of
-the live-before sets.
+the live-before sets:
 \begin{center}
 \begin{center}
   \begin{lstlisting}
   \begin{lstlisting}
 mainstart: {}, block5: {i, rsp, sum}, block7: {i, sum}, block8: {rsp, sum}
 mainstart: {}, block5: {i, rsp, sum}, block7: {i, sum}, block8: {rsp, sum}
@@ -10308,7 +10307,7 @@ In the preceding iteration, only \code{block5} changed, so we can
 limit our attention to \code{mainstart} and \code{block7}, the two
 limit our attention to \code{mainstart} and \code{block7}, the two
 blocks that jump to \code{block5}.  As a result, the live-before sets
 blocks that jump to \code{block5}.  As a result, the live-before sets
 for \code{mainstart} and \code{block7} are updated to include
 for \code{mainstart} and \code{block7} are updated to include
-\code{rsp}, yielding the following approximation $m_3$.
+\code{rsp}, yielding the following approximation $m_3$:
 \begin{center}
 \begin{center}
   \begin{lstlisting}
   \begin{lstlisting}
 mainstart: {rsp}, block5: {i,rsp,sum}, block7: {i,rsp,sum}, block8: {rsp,sum}
 mainstart: {rsp}, block5: {i,rsp,sum}, block7: {i,rsp,sum}, block8: {rsp,sum}
@@ -10319,20 +10318,21 @@ its live-before set remains \code{\{i,rsp,sum\}}.  At this point
 our approximations have converged, so $m_3$ is the solution.
 our approximations have converged, so $m_3$ is the solution.
 
 
 This iteration process is guaranteed to converge to a solution by the
 This iteration process is guaranteed to converge to a solution by the
-Kleene Fixed-Point Theorem, a general theorem about functions on
+Kleene fixed-point theorem, a general theorem about functions on
 lattices~\citep{Kleene:1952aa}. Roughly speaking, a \emph{lattice} is
 lattices~\citep{Kleene:1952aa}. Roughly speaking, a \emph{lattice} is
 any collection that comes with a partial ordering $\sqsubseteq$ on its
 any collection that comes with a partial ordering $\sqsubseteq$ on its
-elements, a least element $\bot$ (pronounced bottom), and a join
-operator $\sqcup$.\index{subject}{lattice}\index{subject}{bottom}\index{subject}{partial
-  ordering}\index{subject}{join}\footnote{Technically speaking, we will be
-  working with join semi-lattices.} When two elements are ordered $m_i
-\sqsubseteq m_j$, it means that $m_j$ contains at least as much
-information as $m_i$, so we can think of $m_j$ as a better-or-equal
-approximation than $m_i$.  The bottom element $\bot$ represents the
-complete lack of information, i.e., the worst approximation.  The join
-operator takes two lattice elements and combines their information,
-i.e., it produces the least upper bound of the two.\index{subject}{least upper
-  bound}
+elements, a least element $\bot$ (pronounced \emph{bottom}), and a
+join operator
+$\sqcup$.\index{subject}{lattice}\index{subject}{bottom}\index{subject}{partial
+  ordering}\index{subject}{join}\footnote{Technically speaking, we
+  will be working with join semilattices.} When two elements are
+ordered $m_i \sqsubseteq m_j$, it means that $m_j$ contains at least
+as much information as $m_i$, so we can think of $m_j$ as a
+better-than-or-equal-to approximation in relation to $m_i$.  The
+bottom element $\bot$ represents the complete lack of information,
+that is, the worst approximation.  The join operator takes two lattice
+elements and combines their information; that is, it produces the
+least upper bound of the two.\index{subject}{least upper bound}
 
 
 A dataflow analysis typically 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
 represent abstract states and another lattice that aggregates the
@@ -10344,11 +10344,11 @@ set, and the join operator to be set union.
 %
 %
 We form a second lattice $M$ by taking its elements to be mappings
 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
 from the block labels to sets of locations (elements of $L$).  We
-order the mappings point-wise, 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)
 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
 \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
 bottom element of $M$ is the mapping $\bot_M$ that sends every label
-to the empty set, i.e., $\bot_M(\ell) = \emptyset$.
+to the empty set; that is, $\bot_M(\ell) = \emptyset$.
 
 
 We can think of one iteration of liveness analysis applied to the
 We can think of one iteration of liveness analysis applied to the
 whole program as being a function $f$ on the lattice $M$. It takes a
 whole program as being a function $f$ on the lattice $M$. It takes a
@@ -10363,20 +10363,20 @@ solution should be a \emph{fixed point} of the function $f$.\index{subject}{fixe
 \[
 \[
    f(m_s) = m_s
    f(m_s) = m_s
 \]
 \]
-Furthermore, the solution should only include locations that are
+Furthermore, the solution should include only locations that are
 forced to be there by performing liveness analysis on the program, so
 forced to be there by performing liveness analysis on the program, so
 the solution should be the \emph{least} fixed point.\index{subject}{least fixed point}
 the solution should be the \emph{least} fixed point.\index{subject}{least fixed point}
 
 
-The Kleene Fixed-Point Theorem states that if a function $f$ is
+The Kleene fixed-point theorem states that if a function $f$ is
 monotone (better inputs produce better outputs), then the least fixed
 monotone (better inputs produce better outputs), then the least fixed
 point of $f$ is the least upper bound of the \emph{ascending Kleene
 point of $f$ is the least upper bound of the \emph{ascending Kleene
-  chain} obtained by starting at $\bot$ and iterating $f$ as
-follows.\index{subject}{Kleene Fixed-Point Theorem}
+  chain} obtained by starting at $\bot$ and iterating $f$, as
+follows:\index{subject}{Kleene Fixed-Point Theorem}
 \[
 \[
 \bot \sqsubseteq f(\bot) \sqsubseteq f(f(\bot)) \sqsubseteq \cdots
 \bot \sqsubseteq f(\bot) \sqsubseteq f(f(\bot)) \sqsubseteq \cdots
   \sqsubseteq f^n(\bot) \sqsubseteq \cdots
   \sqsubseteq f^n(\bot) \sqsubseteq \cdots
 \]
 \]
-When a lattice contains only finitely-long ascending chains, then
+When a lattice contains only finitely long ascending chains, then
 every Kleene chain tops out at some fixed point after some number of
 every Kleene chain tops out at some fixed point after some number of
 iterations of $f$.
 iterations of $f$.
 \[
 \[
@@ -10385,7 +10385,7 @@ iterations of $f$.
 \]
 \]
 
 
 The liveness analysis is indeed a monotone function and the lattice
 The liveness analysis is indeed a monotone function and the lattice
-$M$ only has finitely-long ascending chains because there are only a
+$M$ has finitely long ascending chains because there are only a
 finite number of variables and blocks in the program. Thus we are
 finite number of variables and blocks in the program. Thus we are
 guaranteed that iteratively applying liveness analysis to all blocks
 guaranteed that iteratively applying liveness analysis to all blocks
 in the program will eventually produce the least fixed point solution.
 in the program will eventually produce the least fixed point solution.
@@ -10394,17 +10394,17 @@ Next let us consider dataflow analysis in general and discuss the
 generic work list algorithm (figure~\ref{fig:generic-dataflow}). 
 generic work list algorithm (figure~\ref{fig:generic-dataflow}). 
 %
 %
 The algorithm has four parameters: the control-flow graph \code{G}, a
 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
+function \code{transfer} that applies the analysis to one block, and the
+\code{bottom} and \code{join} operators for the lattice of abstract
 states. The \code{analyze\_dataflow} function is formulated as a
 states. The \code{analyze\_dataflow} function is formulated as a
-\emph{forward} dataflow analysis, that is, the inputs to the transfer
+\emph{forward} dataflow analysis; that is, the inputs to the transfer
 function come from the predecessor nodes in the control-flow
 function come from the predecessor nodes in the control-flow
 graph. However, liveness analysis is a \emph{backward} dataflow
 graph. However, liveness analysis is a \emph{backward} dataflow
 analysis, so in that case one must supply the \code{analyze\_dataflow}
 analysis, so in that case one must supply the \code{analyze\_dataflow}
 function with the transpose of the control-flow graph.
 function with the transpose of the control-flow graph.
 
 
 The algorithm begins by creating the bottom mapping, represented by a
 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
+hash table.  It then pushes all the nodes in the control-flow graph
 onto the work list (a queue). The algorithm repeats the \code{while}
 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
 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 \code{input} for
 node is popped from the work list and processed. The \code{input} for
@@ -10414,7 +10414,6 @@ obtain the \code{output} abstract state. If the output differs from
 the previous state for this block, the mapping for this block is
 the previous state for this block, the mapping for this block is
 updated and its successor nodes are pushed onto the work list.
 updated and its successor nodes are pushed onto the work list.
 
 
-
 \begin{figure}[tb]
 \begin{figure}[tb]
 \begin{tcolorbox}[colback=white]  
 \begin{tcolorbox}[colback=white]  
 {\if\edition\racketEd    
 {\if\edition\racketEd    
@@ -10468,7 +10467,7 @@ def analyze_dataflow(G, transfer, bottom, join):
 There is a subtle interaction between the
 There is a subtle interaction between the
 \code{remove\_complex\_operands} pass, the addition of \code{set!},
 \code{remove\_complex\_operands} pass, the addition of \code{set!},
 and the left-to-right order of evaluation of Racket. Consider the
 and the left-to-right order of evaluation of Racket. Consider the
-following example.
+following example:
 \begin{lstlisting}
 \begin{lstlisting}
 (let ([x 2])
 (let ([x 2])
   (+ x (begin (set! x 40) x)))
   (+ x (begin (set! x 40) x)))
@@ -10482,7 +10481,7 @@ example we obtain the following program whose result is \code{80}!
   (let ([tmp (begin (set! x 40) x)])
   (let ([tmp (begin (set! x 40) x)])
     (+ x tmp)))
     (+ x tmp)))
 \end{lstlisting}
 \end{lstlisting}
-The problem is that, with mutable variables, the ordering between
+The problem is that with mutable variables, the ordering between
 reads and writes is important, and the
 reads and writes is important, and the
 \code{remove\_complex\_operands} pass moved the \code{set!} to happen
 \code{remove\_complex\_operands} pass moved the \code{set!} to happen
 before the first read of \code{x}.
 before the first read of \code{x}.
@@ -10493,16 +10492,16 @@ side of a \code{set!}. We mark each read from a mutable variable with
 the form \code{get!} (\code{GetBang} in abstract syntax) to indicate
 the form \code{get!} (\code{GetBang} in abstract syntax) to indicate
 that the read operation is effectful in that it can produce different
 that the read operation is effectful in that it can produce different
 results at different points in time. Let's apply this idea to the
 results at different points in time. Let's apply this idea to the
-following variation that also involves a variable that is not mutated.
+following variation that also involves a variable that is not mutated:
 % loop_test_24.rkt
 % loop_test_24.rkt
 \begin{lstlisting}
 \begin{lstlisting}
 (let ([x 2])
 (let ([x 2])
   (let ([y 0])
   (let ([y 0])
     (+ y (+ x (begin (set! x 40) x)))))
     (+ y (+ x (begin (set! x 40) x)))))
 \end{lstlisting}
 \end{lstlisting}
-We first analyze the above program to discover that variable \code{x}
+We first analyze this program to discover that variable \code{x}
 is mutable but \code{y} is not. We then transform the program as
 is mutable but \code{y} is not. We then transform the program as
-follows, replacing each occurrence of \code{x} with \code{(get! x)}.
+follows, replacing each occurrence of \code{x} with \code{(get! x)}:
 \begin{lstlisting}
 \begin{lstlisting}
 (let ([x 2])
 (let ([x 2])
   (let ([y 0])
   (let ([y 0])
@@ -10513,7 +10512,7 @@ immutable variables, we can apply the \code{remove\_complex\_operands}
 pass, where reads from immutable variables are still classified as
 pass, where reads from immutable variables are still classified as
 atomic expressions but reads from mutable variables are classified as
 atomic expressions but reads from mutable variables are classified as
 complex.  Thus, \code{remove\_complex\_operands} yields the following
 complex.  Thus, \code{remove\_complex\_operands} yields the following
-program.\\
+program:\\
 \begin{minipage}{\textwidth}
 \begin{minipage}{\textwidth}
 \begin{lstlisting}
 \begin{lstlisting}
 (let ([x 2])
 (let ([x 2])
@@ -10533,7 +10532,7 @@ variables, making it more likely for some of them to be spilled.  The
 result of this program is \code{42}, the same as the result prior to
 result of this program is \code{42}, the same as the result prior to
 \code{remove\_complex\_operands}.
 \code{remove\_complex\_operands}.
 
 
-The approach that we've sketched above requires only a small
+The approach that we've sketched requires only a small
 modification to \code{remove\_complex\_operands} to handle
 modification to \code{remove\_complex\_operands} to handle
 \code{get!}. However, it requires a new pass, called
 \code{get!}. However, it requires a new pass, called
 \code{uncover-get!}, that we discuss in
 \code{uncover-get!}, that we discuss in
@@ -10563,10 +10562,10 @@ passes.
 \section{Uncover \texttt{get!}}
 \section{Uncover \texttt{get!}}
 \label{sec:uncover-get-bang}
 \label{sec:uncover-get-bang}
 
 
-The goal of this pass it to mark uses of mutable variables so that
+The goal of this pass is to mark uses of mutable variables so that
 \code{remove\_complex\_operands} can treat them as complex expressions
 \code{remove\_complex\_operands} can treat them as complex expressions
-and thereby preserve their ordering relative to the side-effects in
-other operands. So the first step is to collect all the mutable
+and thereby preserve their ordering relative to the side effects in
+other operands. So, the first step is to collect all the mutable
 variables. We recommend creating an auxiliary function for this,
 variables. We recommend creating an auxiliary function for this,
 named \code{collect-set!}, that recursively traverses expressions,
 named \code{collect-set!}, that recursively traverses expressions,
 returning the set of all variables that occur on the left-hand side of a
 returning the set of all variables that occur on the left-hand side of a
@@ -10587,14 +10586,14 @@ returning the set of all variables that occur on the left-hand side of a
 \end{minipage}
 \end{minipage}
 \end{center}
 \end{center}
 By placing this pass after \code{uniquify}, we need not worry about
 By placing this pass after \code{uniquify}, we need not worry about
-variable shadowing and our logic for \code{Let} can remain simple, as
-in the excerpt above.
+variable shadowing, and our logic for \code{Let} can remain simple, as
+in this excerpt.
 
 
 The second step is to mark the occurrences of the mutable variables
 The second step is to mark the occurrences of the mutable variables
 with the new \code{GetBang} AST node (\code{get!} in concrete
 with the new \code{GetBang} AST node (\code{get!} in concrete
 syntax). The following is an excerpt of the \code{uncover-get!-exp}
 syntax). The following is an excerpt of the \code{uncover-get!-exp}
 function, which takes two parameters: the set of mutable variables
 function, which takes two parameters: the set of mutable variables
-\code{set!-vars}, and the expression \code{e} to be processed. The
+\code{set!-vars} and the expression \code{e} to be processed. The
 case for \code{(Var x)} replaces it with \code{(GetBang x)} if it is a
 case for \code{(Var x)} replaces it with \code{(GetBang x)} if it is a
 mutable variable or leaves it alone if not.
 mutable variable or leaves it alone if not.
 \begin{center}
 \begin{center}
@@ -10710,7 +10709,7 @@ must introduce a temporary variable and bind it to the complex
 expression.  This approach applies, unchanged, to handle the new
 expression.  This approach applies, unchanged, to handle the new
 language forms.  For example, in the following code there are two
 language forms.  For example, in the following code there are two
 \code{begin} expressions appearing as arguments to the \code{+}
 \code{begin} expressions appearing as arguments to the \code{+}
-operator.  The output of \code{rco\_exp} is shown below, in which the
+operator.  The output of \code{rco\_exp} is then shown, in which the
 \code{begin} expressions have been bound to temporary
 \code{begin} expressions have been bound to temporary
 variables. Recall that \code{let} expressions in \LangLoopANF{} are
 variables. Recall that \code{let} expressions in \LangLoopANF{} are
 allowed to have arbitrary expressions in their right-hand side
 allowed to have arbitrary expressions in their right-hand side
@@ -10768,7 +10767,7 @@ $\Rightarrow$
 
 
 Recall that in the \code{explicate\_control} pass we define one helper
 Recall that in the \code{explicate\_control} pass we define one helper
 function for each kind of position in the program.  For the \LangVar{}
 function for each kind of position in the program.  For the \LangVar{}
-language of integers and variables we needed assignment and tail
+language of integers and variables, we needed assignment and tail
 positions. The \code{if} expressions of \LangIf{} introduced predicate
 positions. The \code{if} expressions of \LangIf{} introduced predicate
 positions. For \LangLoop{}, the \code{begin} expression introduces yet
 positions. For \LangLoop{}, the \code{begin} expression introduces yet
 another kind of position: effect position. Except for the last
 another kind of position: effect position. Except for the last
@@ -10778,11 +10777,11 @@ generate better code by taking this fact into account.
 
 
 The output language of \code{explicate\_control} is \LangCLoop{}
 The output language of \code{explicate\_control} is \LangCLoop{}
 (figure~\ref{fig:c7-syntax}), which is nearly identical to
 (figure~\ref{fig:c7-syntax}), which is nearly identical to
-\LangCIf{}. The only syntactic difference is the addition of \VOID{}
+\LangCIf{}. The only syntactic differences are the addition of \VOID{}
 and that \code{read} may appear as a statement.  The most significant
 and that \code{read} may appear as a statement.  The most significant
 difference between the programs generated by \code{explicate\_control}
 difference between the programs generated by \code{explicate\_control}
 in chapter~\ref{ch:Lif} versus \code{explicate\_control} in this
 in chapter~\ref{ch:Lif} versus \code{explicate\_control} in this
-chapter is that the control-flow graphs of the later may contain
+chapter is that the control-flow graphs of the latter may contain
 cycles.
 cycles.
 
 
 \begin{figure}[tp]
 \begin{figure}[tp]
@@ -10813,7 +10812,7 @@ causes side effects, then the expression can be removed, so the result
 is just the continuation.
 is just the continuation.
 %
 %
 The case for $\WHILE{\itm{cnd}}{\itm{body}}$ expressions is
 The case for $\WHILE{\itm{cnd}}{\itm{body}}$ expressions is
-interesting; the generated code is depicted in the following diagram.
+interesting; the generated code is depicted in the following diagram:
 \begin{center}
 \begin{center}
   \begin{minipage}{0.3\textwidth}
   \begin{minipage}{0.3\textwidth}
 \xymatrix{
 \xymatrix{
@@ -10828,8 +10827,8 @@ We start by creating a fresh label $\itm{loop}$ for the top of the
 loop.  Next, recursively process the \itm{body} (in effect position)
 loop.  Next, recursively process the \itm{body} (in effect position)
 with a \code{goto} to $\itm{loop}$ as the continuation, producing
 with a \code{goto} to $\itm{loop}$ as the continuation, producing
 \itm{body'}. Process the \itm{cnd} (in predicate position) with
 \itm{body'}. 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 dictionary of
+\itm{body'} as the \emph{then} branch and the continuation block as the
+\emph{else} branch. The result should be added to the dictionary of
 \code{basic-blocks} with the label \itm{loop}. The result for the
 \code{basic-blocks} with the label \itm{loop}. The result for the
 whole \code{while} loop is a \code{goto} to the \itm{loop} label.
 whole \code{while} loop is a \code{goto} to the \itm{loop} label.
 
 
@@ -10862,8 +10861,8 @@ the condition expression.
 Only two small additions are needed in the \code{select\_instructions}
 Only two small additions are needed in the \code{select\_instructions}
 pass to handle the changes to \LangCLoop{}. First, to handle the
 pass to handle the changes to \LangCLoop{}. First, to handle the
 addition of \VOID{} we simply translate it to \code{0}.  Second,
 addition of \VOID{} we simply translate it to \code{0}.  Second,
-\code{read} may appear as a stand-alone statement instead of only
-appearing on the right-hand side of an assignment statement. The code
+\code{read} may appear as a stand-alone statement instead of 
+appearing only on the right-hand side of an assignment statement. The code
 generation is nearly identical to the one for assignment; just leave
 generation is nearly identical to the one for assignment; just leave
 off the instruction for moving the result into the left-hand side.
 off the instruction for moving the result into the left-hand side.
 
 
@@ -10883,7 +10882,7 @@ perform liveness analysis, replacing the code in
 \code{uncover\_live} that processed the basic blocks in topological
 \code{uncover\_live} that processed the basic blocks in topological
 order (section~\ref{sec:liveness-analysis-Lif}).
 order (section~\ref{sec:liveness-analysis-Lif}).
 
 
-The \code{analyze\_dataflow} function has four parameters.
+The \code{analyze\_dataflow} function has the following four parameters.
 \begin{enumerate}
 \begin{enumerate}
 \item The first parameter \code{G} should be passed the transpose
 \item The first parameter \code{G} should be passed the transpose
   of the control-flow graph.
   of the control-flow graph.
@@ -10893,7 +10892,7 @@ The \code{analyze\_dataflow} function has four parameters.
   set for that block.  The transfer function should return the
   set for that block.  The transfer function should return the
   live-before set for the block.
   live-before set for the block.
   %
   %
-  \racket{Also, as a side-effect, it should update the block's
+  \racket{Also, as a side effect, it should update the block's
     $\itm{info}$ with the liveness information for each instruction.}
     $\itm{info}$ with the liveness information for each instruction.}
   %
   %
   \python{Also, as a side-effect, it should update the live-before and
   \python{Also, as a side-effect, it should update the live-before and
@@ -10903,14 +10902,14 @@ The \code{analyze\_dataflow} function has four parameters.
   reuse the code you already have for analyzing basic blocks.
   reuse the code you already have for analyzing basic blocks.
 \item The third and fourth parameters of \code{analyze\_dataflow} are
 \item The third and fourth parameters of \code{analyze\_dataflow} are
   \code{bottom} and \code{join} for the lattice of abstract states,
   \code{bottom} and \code{join} for the lattice of abstract states,
-  i.e.  sets of locations. For liveness analysis, the bottom of the
-  lattice is the empty set and the join operator is set union.
+  that is, sets of locations. For liveness analysis, the bottom of the
+  lattice is the empty set, and the join operator is set union.
 \end{enumerate}
 \end{enumerate}
 
 
 
 
 \begin{figure}[p]
 \begin{figure}[p]
 \begin{tcolorbox}[colback=white]      
 \begin{tcolorbox}[colback=white]      
-\begin{tikzpicture}[baseline=(current  bounding  box.center)]
+\begin{tikzpicture}[baseline=(current  bounding  box.center),scale=0.90]
 \node (Lfun) at (0,2)  {\large \LangLoop{}};
 \node (Lfun) at (0,2)  {\large \LangLoop{}};
 \node (Lfun-2) at (3,2)  {\large \LangLoop{}};
 \node (Lfun-2) at (3,2)  {\large \LangLoop{}};
 %\node (Lfun-3) at (6,2)  {\large \LangLoop{}};
 %\node (Lfun-3) at (6,2)  {\large \LangLoop{}};
@@ -10921,14 +10920,14 @@ The \code{analyze\_dataflow} function has four parameters.
 \node (F1-4) at (6,2)  {\large \LangLoop{}};
 \node (F1-4) at (6,2)  {\large \LangLoop{}};
 \node (F1-5) at (9,2)  {\large \LangLoop{}};
 \node (F1-5) at (9,2)  {\large \LangLoop{}};
 \node (F1-6) at (9,0)  {\large \LangLoopANF{}};
 \node (F1-6) at (9,0)  {\large \LangLoopANF{}};
-\node (C3-2) at (3,0)  {\large \racket{\LangCLoop{}}\python{\LangCIf{}}};
+\node (C3-2) at (0,0)  {\large \racket{\LangCLoop{}}\python{\LangCIf{}}};
 
 
-\node (x86-2) at (3,-2)  {\large \LangXIfVar{}};
-\node (x86-2-1) at (3,-4)  {\large \LangXIfVar{}};
-\node (x86-2-2) at (6,-4)  {\large \LangXIfVar{}};
-\node (x86-3) at (6,-2)  {\large \LangXIfVar{}};
-\node (x86-4) at (9,-2) {\large \LangXIf{}};
-\node (x86-5) at (9,-4) {\large \LangXIf{}};
+\node (x86-2) at (0,-2)  {\large \LangXIfVar{}};
+\node (x86-2-1) at (0,-4)  {\large \LangXIfVar{}};
+\node (x86-2-2) at (4,-4)  {\large \LangXIfVar{}};
+\node (x86-3) at (4,-2)  {\large \LangXIfVar{}};
+\node (x86-4) at (8,-2) {\large \LangXIf{}};
+\node (x86-5) at (8,-4) {\large \LangXIf{}};
 
 
 
 
 %% \path[->,bend left=15] (Lfun) edge [above] node
 %% \path[->,bend left=15] (Lfun) edge [above] node
@@ -10949,22 +10948,22 @@ The \code{analyze\_dataflow} function has four parameters.
 %%      {\ttfamily\footnotesize expose-alloc.} (F1-4);
 %%      {\ttfamily\footnotesize expose-alloc.} (F1-4);
 \path[->,bend left=15] (F1-4) edge [above] node
 \path[->,bend left=15] (F1-4) edge [above] node
      {\ttfamily\footnotesize uncover\_get!} (F1-5);
      {\ttfamily\footnotesize uncover\_get!} (F1-5);
-\path[->,bend left=15] (F1-5) edge [right] node
-     {\ttfamily\footnotesize remove\_complex.} (F1-6);
-\path[->,bend right=15] (F1-6) edge [above] node
+\path[->,bend left=15] (F1-5) edge [left] node
+     {\ttfamily\footnotesize remove\_complex\_operands} (F1-6);
+\path[->,bend left=10] (F1-6) edge [above] node
      {\ttfamily\footnotesize explicate\_control} (C3-2);
      {\ttfamily\footnotesize explicate\_control} (C3-2);
-\path[->,bend left=15] (C3-2) edge [left] node
-     {\ttfamily\footnotesize select\_instr.} (x86-2);
-\path[->,bend right=15] (x86-2) edge [left] node
+\path[->,bend left=15] (C3-2) edge [right] node
+     {\ttfamily\footnotesize select\_instructions} (x86-2);
+\path[->,bend right=15] (x86-2) edge [right] node
      {\ttfamily\footnotesize uncover\_live} (x86-2-1);
      {\ttfamily\footnotesize uncover\_live} (x86-2-1);
 \path[->,bend right=15] (x86-2-1) edge [below] node 
 \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);
+     {\ttfamily\footnotesize build\_interference} (x86-2-2);
+\path[->,bend right=15] (x86-2-2) edge [right] node
+     {\ttfamily\footnotesize allocate\_registers} (x86-3);
 \path[->,bend left=15] (x86-3) edge [above] node
 \path[->,bend left=15] (x86-3) edge [above] node
-     {\ttfamily\footnotesize patch\_instr.} (x86-4);
+     {\ttfamily\footnotesize patch\_instructions} (x86-4);
 \path[->,bend left=15] (x86-4) edge [right] node
 \path[->,bend left=15] (x86-4) edge [right] node
-     {\ttfamily\footnotesize pre.\_and\_concl.} (x86-5);
+     {\ttfamily\footnotesize prelude\_and\_conclusion} (x86-5);
 \end{tikzpicture}
 \end{tikzpicture}
 \end{tcolorbox}
 \end{tcolorbox}