Răsfoiți Sursa

ch 5 edits from Andrew

Jeremy G. Siek 2 ani în urmă
părinte
comite
9f6007ae19
1 a modificat fișierele cu 32 adăugiri și 33 ștergeri
  1. 32 33
      book.tex

+ 32 - 33
book.tex

@@ -8580,7 +8580,7 @@ abstract syntax.
 \label{sec:x86-if}
 \index{subject}{x86}
 
-To implement the new logical operations, the
+To implement Booleans, the new logical operations, the
 comparison operations, and the \key{if} expression\python{ and
   statement}, we delve further into the x86
 language. Figures~\ref{fig:x86-1-concrete} and \ref{fig:x86-1} present
@@ -8593,13 +8593,17 @@ comparisons, and \racket{conditional} jumps.
   which we refer to as a \emph{basic block}\index{subject}{basic
     block}.}
 
-One challenge is that x86 does not provide an instruction that
-directly implements logical negation (\code{not} in \LangIf{} and
-\LangCIf{}).  However, the \code{xorq} instruction can be used to
-encode \code{not}.  The \key{xorq} instruction takes two arguments,
-performs a pairwise exclusive-or ($\mathrm{XOR}$) operation on each
-bit of its arguments, and writes the results into its second argument.
-Recall the following truth table for exclusive-or:
+As x86 does not provide direct support for Booleans, we take the usual
+approach of encoding Booleans as integers, with \code{True} as $1$ and
+\code{False} as $0$.
+
+Furthermore, x86 does not provide an instruction that directly
+implements logical negation (\code{not} in \LangIf{} and \LangCIf{}).
+However, the \code{xorq} instruction can be used to encode \code{not}.
+The \key{xorq} instruction takes two arguments, performs a pairwise
+exclusive-or ($\mathrm{XOR}$) operation on each bit of its arguments,
+and writes the results into its second argument.  Recall the following
+truth table for exclusive-or:
 \begin{center}
 \begin{tabular}{l|cc}
    & 0 & 1 \\ \hline
@@ -8763,26 +8767,28 @@ a \key{cmpq} instruction to set the EFLAGS register.
 \section{Shrink the \LangIf{} Language}
 \label{sec:shrink-Lif}
 
-The \LangIf{} language includes several features that are easily
-expressible with other features. For example, \code{and} and \code{or}
-are expressible using \code{if} as follows.
+The \code{shrink} pass translates some of the language features into
+other features, thereby reducing the kinds of expressions in the
+language. For example, the short-circuiting nature of the \code{and}
+and \code{or} logical operators can be expressed using \code{if} as
+follows.
 \begin{align*}
   \CAND{e_1}{e_2} & \quad \Rightarrow \quad \CIF{e_1}{e_2}{\FALSE{}}\\
   \COR{e_1}{e_2} & \quad \Rightarrow \quad \CIF{e_1}{\TRUE{}}{e_2}
 \end{align*}
 By performing these translations in the front end of the compiler,
-subsequent passes of the compiler do not need to deal with these features,
-thus making the passes shorter.
+subsequent passes of the compiler can be shorter.
 
 On the other hand, translations sometimes reduce the efficiency of the
 generated code by increasing the number of instructions. For example,
-expressing subtraction in terms of negation
+expressing subtraction in terms of addition and negation
 \[
 \CBINOP{\key{-}}{e_1}{e_2} \quad \Rightarrow \quad
   \CBINOP{\key{+}}{e_1}{ \CUNIOP{\key{-}}{e_2} }
 \]
 produces code with two x86 instructions (\code{negq} and \code{addq})
-instead of just one (\code{subq}).
+instead of just one (\code{subq}). Thus, we do not recommend
+translating subtraction into addition and negation.
 
 \begin{exercise}\normalfont\normalsize
 %
@@ -8942,11 +8948,9 @@ condition must be a comparison.
 As a motivating example, consider the following program that has an
 \key{if} expression nested in the condition of another \key{if}:%
 \python{\footnote{Programmers rarely write nested \code{if}
-  expressions, but it is not uncommon for the condition of an
-  \code{if} statement to be a call of a function that also contains an
-  \code{if} statement.  When such a function is inlined, the result is
-  a nested \code{if} that requires the techniques discussed in this
-  section.}}
+    expressions, but they do write nested expressions involving
+    logical \code{and}, which, as we have seen, translates to
+    \code{if}.}}
 % cond_test_41.rkt, if_lt_eq.py
 \begin{center}
 \begin{minipage}{0.96\textwidth}
@@ -9266,7 +9270,6 @@ def explicate_effect(e, cont, basic_blocks):
             ...
         case _:
             ...
-
 def explicate_assign(rhs, lhs, cont, basic_blocks):
     match rhs:
         case IfExp(test, body, orelse):
@@ -9275,7 +9278,6 @@ def explicate_assign(rhs, lhs, cont, basic_blocks):
             ...
         case _:
             return [Assign([lhs], rhs)] + cont
-
 def explicate_pred(cnd, thn, els, basic_blocks):
     match cnd:
         case Compare(left, [op], [right]):
@@ -9296,7 +9298,6 @@ def explicate_pred(cnd, thn, els, basic_blocks):
             return [If(Compare(cnd, [Eq()], [Constant(False)]),
                        create_block(els, basic_blocks),
                        create_block(thn, basic_blocks))]
-
 def explicate_stmt(s, cont, basic_blocks):
     match s:
         case Assign([lhs], rhs):
@@ -9305,7 +9306,6 @@ def explicate_stmt(s, cont, basic_blocks):
             return explicate_effect(value, cont, basic_blocks)
         case If(test, body, orelse):
             ...
-
 def explicate_control(p):
     match p:
         case Module(body):
@@ -9757,7 +9757,7 @@ The \code{select\_instructions} pass translates \LangCIf{} to
 \racket{For $\Atm$, we have new cases for the Booleans.}
 %
 \python{We begin with the Boolean constants.}
-We take the usual approach of encoding them as integers.
+As previously discussed, we encode them as integers.
 \[
 \TRUE{} \quad\Rightarrow\quad \key{1}
 \qquad\qquad
@@ -9846,7 +9846,7 @@ but use different condition codes for the conditional jump instruction.
 
 \python{Regarding the \key{return} statement, we recommend treating it
   as an assignment to the \key{rax} register followed by a jump to the
-  conclusion of the \code{main} function.}
+  conclusion of the \code{main} function. (See section~\ref{sec:prelude-conclusion-cond} for more about the conclusion of \code{main}.)}
 
 \begin{exercise}\normalfont\normalsize
 Expand your \code{select\_instructions} pass to handle the new
@@ -9953,11 +9953,9 @@ this instruction is particularly interesting because during
 compilation, we do not know which way a conditional jump will go. Thus
 we do not know whether to use the live-before set for the block
 associated with the $\itm{label}$ or the live-before set for the
-following instruction.  However, there is no harm to the correctness
-of the generated code if we classify more locations as live than the
-ones that are truly live during one particular execution of the
-instruction. Thus, we can take the union of the live-before sets from
-the following instruction and from the mapping for $\itm{label}$ in
+following instruction. So we use both, by taking the union of the
+live-before sets from the following instruction and from the mapping
+for $\itm{label}$ in
 \racket{\code{label->live}}\python{\code{live\_before\_block}}.
 
 The auxiliary functions for computing the variables in an
@@ -10029,8 +10027,9 @@ pass.
 The second argument of the \key{cmpq} instruction must not be an
 immediate value (such as an integer). So, if you are comparing two
 immediates, we recommend inserting a \key{movq} instruction to put the
-second argument in \key{rax}. As usual, \key{cmpq} may have at most
-one memory reference.
+second argument in \key{rax}.
+%
+As usual, \key{cmpq} may have at most one memory reference.
 %
 The second argument of the \key{movzbq} must be a register.