Browse Source

proof reading ch 2 complete

Jeremy Siek 4 năm trước cách đây
mục cha
commit
efc906b874
1 tập tin đã thay đổi với 120 bổ sung145 xóa
  1. 120 145
      book.tex

+ 120 - 145
book.tex

@@ -1408,7 +1408,7 @@ suffices for compiling \LangVar{}.
 \label{sec:x86}
 \label{sec:x86}
 \index{x86}
 \index{x86}
 
 
-Figure~\ref{fig:x86-0-concrete} defines the concrete syntax for
+Figure~\ref{fig:x86-int-concrete} defines the concrete syntax for
 \LangXASTInt{}.  We use the AT\&T syntax expected by the GNU
 \LangXASTInt{}.  We use the AT\&T syntax expected by the GNU
 assembler.
 assembler.
 %
 %
@@ -1456,12 +1456,12 @@ integer constant (called \emph{immediate value}\index{immediate
 \end{minipage}
 \end{minipage}
 }
 }
 \caption{The syntax of the \LangXASTInt{} assembly language (AT\&T syntax).}
 \caption{The syntax of the \LangXASTInt{} assembly language (AT\&T syntax).}
-\label{fig:x86-0-concrete}
+\label{fig:x86-int-concrete}
 \end{figure}
 \end{figure}
 
 
 A register is a special kind of variable. Each one holds a 64-bit
 A register is a special kind of variable. Each one holds a 64-bit
 value; there are 16 general-purpose registers in the computer and
 value; there are 16 general-purpose registers in the computer and
-their names are given in Figure~\ref{fig:x86-0-concrete}.  A register
+their names are given in Figure~\ref{fig:x86-int-concrete}.  A register
 is written with a \key{\%} followed by the register name, such as
 is written with a \key{\%} followed by the register name, such as
 \key{\%rax}.
 \key{\%rax}.
 
 
@@ -1633,9 +1633,9 @@ one and adds $8$ to the stack pointer.
 
 
 The compiler needs a convenient representation for manipulating x86
 The compiler needs a convenient representation for manipulating x86
 programs, so we define an abstract syntax for x86 in
 programs, so we define an abstract syntax for x86 in
-Figure~\ref{fig:x86-0-ast}. We refer to this language as
+Figure~\ref{fig:x86-int-ast}. We refer to this language as
 \LangXASTInt{}. The main difference compared to the concrete syntax of
 \LangXASTInt{}. The main difference compared to the concrete syntax of
-\LangXInt{} (Figure~\ref{fig:x86-0-concrete}) is that labels are not
+\LangXInt{} (Figure~\ref{fig:x86-int-concrete}) is that labels are not
 allowed in front of every instructions. Instead instructions are
 allowed in front of every instructions. Instead instructions are
 grouped into \emph{blocks}\index{block}\index{basic block} with a
 grouped into \emph{blocks}\index{block}\index{basic block} with a
 label associated with every block, which is why the \key{X86Program}
 label associated with every block, which is why the \key{X86Program}
@@ -1672,7 +1672,7 @@ of arguments, which is helpful to know during register allocation
 \end{minipage}
 \end{minipage}
 }
 }
 \caption{The abstract syntax of \LangXASTInt{} assembly.}
 \caption{The abstract syntax of \LangXASTInt{} assembly.}
-\label{fig:x86-0-ast}
+\label{fig:x86-int-ast}
 \end{figure}
 \end{figure}
 
 
 \section{Planning the trip to x86 via the \LangCVar{} language}
 \section{Planning the trip to x86 via the \LangCVar{} language}
@@ -2281,24 +2281,25 @@ for conditional expressions in Chapter~\ref{ch:bool-types}.
 In the \code{select-instructions} pass we begin the work of
 In the \code{select-instructions} pass we begin the work of
 translating from \LangCVar{} to \LangXVar{}. The target language of
 translating from \LangCVar{} to \LangXVar{}. The target language of
 this pass is a variant of x86 that still uses variables, so we add an
 this pass is a variant of x86 that still uses variables, so we add an
-AST node of the form $\VAR{\itm{var}}$ to the \LangXASTInt{} abstract
-syntax of Figure~\ref{fig:x86-0-ast}.  We recommend implementing the
-\code{select-instructions} in terms of three auxiliary functions, one
-for each of the non-terminals of \LangCVar{}: $\Atm$, $\Stmt$, and $\Tail$.
+AST node of the form $\VAR{\itm{var}}$ to the \Arg{} non-terminal of
+the \LangXASTInt{} abstract syntax (Figure~\ref{fig:x86-int-ast}).  We
+recommend implementing the \code{select-instructions} with
+three auxiliary functions, one for each of the non-terminals of
+\LangCVar{}: $\Atm$, $\Stmt$, and $\Tail$.
 
 
 The cases for $\Atm$ are straightforward, variables stay
 The cases for $\Atm$ are straightforward, variables stay
 the same and integer constants are changed to immediates:
 the same and integer constants are changed to immediates:
 $\INT{n}$ changes to $\IMM{n}$.
 $\INT{n}$ changes to $\IMM{n}$.
 
 
 Next we consider the cases for $\Stmt$, starting with arithmetic
 Next we consider the cases for $\Stmt$, starting with arithmetic
-operations. For example, in \LangCVar{} an addition operation can take the
-form below, to the left of the $\Rightarrow$.  To translate to x86, we
-need to use the \key{addq} instruction which does an in-place
-update. So we must first move \code{10} to \code{x}. \\
+operations. For example, consider the addition operation below that
+puts the sum of \code{y} and \code{z} into \code{x}. We can use the
+\key{addq} instruction, but it performs an in-place update.  So we
+could move \code{y} to \code{x} and then add \code{z} to \code{x}. \\
 \begin{tabular}{lll}
 \begin{tabular}{lll}
 \begin{minipage}{0.4\textwidth}
 \begin{minipage}{0.4\textwidth}
 \begin{lstlisting}
 \begin{lstlisting}
-x = (+ 10 32);
+x = (+ y z);
 \end{lstlisting}
 \end{lstlisting}
 \end{minipage}
 \end{minipage}
 &
 &
@@ -2306,18 +2307,18 @@ $\Rightarrow$
 &
 &
 \begin{minipage}{0.4\textwidth}
 \begin{minipage}{0.4\textwidth}
 \begin{lstlisting}
 \begin{lstlisting}
-movq $10, x
-addq $32, x
+movq y, x
+addq z, x
 \end{lstlisting}
 \end{lstlisting}
 \end{minipage}
 \end{minipage}
 \end{tabular} \\
 \end{tabular} \\
 %
 %
-There are cases that require special care to avoid generating
-needlessly complicated code. If one of the arguments of the addition
-is the same as the left-hand side of the assignment, then there is no
-need for the extra move instruction.  For example, the following
-assignment statement can be translated into a single \key{addq}
-instruction.\\
+There are also cases that require special care to avoid generating
+needlessly complicated code. For example, if one of the arguments of
+the addition is the same variable as the left-hand side of the
+assignment, then there is no need for the extra move instruction.  The
+following assignment statement can be translated into a single
+\key{addq} instruction.\\
 \begin{tabular}{lll}
 \begin{tabular}{lll}
 \begin{minipage}{0.4\textwidth}
 \begin{minipage}{0.4\textwidth}
 \begin{lstlisting}
 \begin{lstlisting}
@@ -2332,26 +2333,26 @@ $\Rightarrow$
 addq $10, x
 addq $10, x
 \end{lstlisting}
 \end{lstlisting}
 \end{minipage}
 \end{minipage}
-\end{tabular} \\
+\end{tabular}
 
 
 The \key{read} operation does not have a direct counterpart in x86
 The \key{read} operation does not have a direct counterpart in x86
-assembly, so we have instead implemented this functionality in the C
-language~\citep{Kernighan:1988nx}, with the function \code{read\_int}
-in the file \code{runtime.c}. In general, we refer to all of the
-functionality in this file as the \emph{runtime system}\index{runtime system},
-or simply the \emph{runtime} for short. When compiling your generated x86
-assembly code, you need to compile \code{runtime.c} to \code{runtime.o} (an
-``object file'', using \code{gcc} option \code{-c}) and link it into
-the executable. For our purposes of code generation, all you need to
-do is translate an assignment of \key{read} into some variable
-$\itm{lhs}$ (for left-hand side) into a call to the \code{read\_int}
-function followed by a move from \code{rax} to the left-hand side.
-The move from \code{rax} is needed because the return value from
+assembly, so we provide this functionality with the function
+\code{read\_int} in the file \code{runtime.c}, written in
+C~\citep{Kernighan:1988nx}. In general, we refer to all of the
+functionality in this file as the \emph{runtime system}\index{runtime
+  system}, or simply the \emph{runtime} for short. When compiling your
+generated x86 assembly code, you need to compile \code{runtime.c} to
+\code{runtime.o} (an ``object file'', using \code{gcc} option
+\code{-c}) and link it into the executable. For our purposes of code
+generation, all you need to do is translate an assignment of
+\key{read} into a call to the \code{read\_int} function followed by a
+move from \code{rax} to the left-hand-side of the assignment.  The
+move from \code{rax} is needed because the return value from
 \code{read\_int} goes into \code{rax}, as is the case in general.  \\
 \code{read\_int} goes into \code{rax}, as is the case in general.  \\
 \begin{tabular}{lll}
 \begin{tabular}{lll}
 \begin{minipage}{0.3\textwidth}
 \begin{minipage}{0.3\textwidth}
 \begin{lstlisting}
 \begin{lstlisting}
-|$\itm{var}$| = (read);
+x = (read);
 \end{lstlisting}
 \end{lstlisting}
 \end{minipage}
 \end{minipage}
 &
 &
@@ -2360,26 +2361,25 @@ $\Rightarrow$
 \begin{minipage}{0.3\textwidth}
 \begin{minipage}{0.3\textwidth}
 \begin{lstlisting}
 \begin{lstlisting}
 callq read_int
 callq read_int
-movq %rax, |$\itm{var}$|
+movq %rax, x
 \end{lstlisting}
 \end{lstlisting}
 \end{minipage}
 \end{minipage}
-\end{tabular} \\
+\end{tabular} 
 
 
 There are two cases for the $\Tail$ non-terminal: \key{Return} and
 There are two cases for the $\Tail$ non-terminal: \key{Return} and
 \key{Seq}. Regarding \key{Return}, we recommend treating it as an
 \key{Seq}. Regarding \key{Return}, we recommend treating it as an
 assignment to the \key{rax} register followed by a jump to the
 assignment to the \key{rax} register followed by a jump to the
 conclusion of the program (so the conclusion needs to be labeled).
 conclusion of the program (so the conclusion needs to be labeled).
 For $\SEQ{s}{t}$, you can translate the statement $s$ and tail $t$
 For $\SEQ{s}{t}$, you can translate the statement $s$ and tail $t$
-recursively and append the resulting instructions.
+recursively and then append the resulting instructions.
 
 
 \begin{exercise}
 \begin{exercise}
-\normalfont
-Implement the \key{select-instructions} pass and test it on all of the
-example programs that you created for the previous passes and create
-three new example programs that are designed to exercise all of the
-interesting code in this pass. Use the \key{interp-tests} function
-(Appendix~\ref{appendix:utilities}) from \key{utilities.rkt} to test
-your passes on the example programs.
+\normalfont Implement the \key{select-instructions} pass in
+\code{compiler.rkt}. Create three new example programs that are
+designed to exercise all of the interesting cases in this pass.  In
+the \code{run-tests.rkt} script, uncomment the line for this pass in
+the list of \code{passes} and then run the script to test your
+compiler.
 \end{exercise}
 \end{exercise}
 
 
 
 
@@ -2397,28 +2397,23 @@ mechanics of placing variables on the stack. We study an algorithm for
 placing variables in registers in
 placing variables in registers in
 Chapter~\ref{ch:register-allocation-r1}.
 Chapter~\ref{ch:register-allocation-r1}.
 
 
-Consider again the following \LangVar{} program.
+Consider again the following \LangVar{} program from
+Section~\ref{sec:remove-complex-opera-Rvar}.
 % s0_20.rkt
 % s0_20.rkt
 \begin{lstlisting}
 \begin{lstlisting}
 (let ([a 42])
 (let ([a 42])
   (let ([b a])
   (let ([b a])
     b))
     b))
 \end{lstlisting}
 \end{lstlisting}
-For reference, we repeat the output of \code{select-instructions} on
-the left and show the output of \code{assign-homes} on the right.
-%
-%% Recall that \key{explicate-control} associated the list of
-%% variables with the \code{locals} symbol in the program's $\itm{info}$
-%% field, so \code{assign-homes} has convenient access to the them.
-%
-In this example, we assign variable \code{a} to stack location
-\code{-8(\%rbp)} and variable \code{b} to location
-\code{-16(\%rbp)}.\\
+The output of \code{select-instructions} is shown on the left and the
+output of \code{assign-homes} on the right.  In this example, we
+assign variable \code{a} to stack location \code{-8(\%rbp)} and
+variable \code{b} to location \code{-16(\%rbp)}.\\
 \begin{tabular}{l}
 \begin{tabular}{l}
   \begin{minipage}{0.4\textwidth}
   \begin{minipage}{0.4\textwidth}
 \begin{lstlisting}[basicstyle=\ttfamily\footnotesize]
 \begin{lstlisting}[basicstyle=\ttfamily\footnotesize]
 locals-types:
 locals-types:
-    a : 'Integer, b : 'Integer
+    a : Integer, b : Integer
 start: 
 start: 
     movq $42, a
     movq $42, a
     movq a, b
     movq a, b
@@ -2437,54 +2432,52 @@ start:
     jmp conclusion
     jmp conclusion
 \end{lstlisting}
 \end{lstlisting}
 \end{minipage}
 \end{minipage}
-\end{tabular} \\
+\end{tabular} 
 
 
-There is a entry for \code{locals-types} in the $\itm{info}$ of the
-\code{X86Program} node, which is needed here so that we have the list
-of variables that should be assigned to homes. The support code
-computes the \code{locals-types} entry. In particular,
-\code{type-check-Cvar} installs it in the $\itm{info}$ field of the
-\code{CProgram} node, which should be propagated to the
-\code{X86Program} node. When using \code{interp-tests} or
-\code{compiler-tests} (see Appendix,
-Section~\ref{appendix:utilities}), specify \code{type-check-Cvar} as
-the type checker to use after \code{explicate-control}.
+The \code{locals-types} entry in the $\itm{info}$ of the
+\code{X86Program} node is an alist mapping all the variables in the
+program to their types (for now just \code{Integer}).  The
+\code{assign-homes} pass should replace all uses of those variables
+with stack locations.  As an aside, the \code{locals-types} entry is
+computed by \code{type-check-Cvar} in the support code, which installs
+it in the $\itm{info}$ field of the \code{CProgram} node, which should
+be propagated to the \code{X86Program} node.
 
 
 In the process of assigning variables to stack locations, it is
 In the process of assigning variables to stack locations, it is
 convenient for you to compute and store the size of the frame (in
 convenient for you to compute and store the size of the frame (in
 bytes) in the $\itm{info}$ field of the \key{X86Program} node, with
 bytes) in the $\itm{info}$ field of the \key{X86Program} node, with
 the key \code{stack-space}, which is needed later to generate the
 the key \code{stack-space}, which is needed later to generate the
 conclusion of the \code{main} procedure. The x86-64 standard requires
 conclusion of the \code{main} procedure. The x86-64 standard requires
-the frame size to be a multiple of 16 bytes. \index{frame}
+the frame size to be a multiple of 16 bytes.\index{frame}
 
 
-\begin{exercise}
-\normalfont Implement the \key{assign-homes} pass and test it on all
-of the example programs that you created for the previous passes pass.
-We recommend that \key{assign-homes} take an extra parameter that is a
-mapping of variable names to homes (stack locations for now).  Use the
-\key{interp-tests} function (Appendix~\ref{appendix:utilities}) from
-\key{utilities.rkt} to test your passes on the example programs.
+\begin{exercise}\normalfont
+Implement the \key{assign-homes} pass in \code{compiler.rkt}, defining
+auxiliary functions for the non-terminals \Arg{}, \Instr{}, and
+\Block{}.  We recommend that the auxiliary functions take an extra
+parameter that is an alist mapping variable names to homes (stack
+locations for now).  In the \code{run-tests.rkt} script, uncomment the
+line for this pass in the list of \code{passes} and then run the
+script to test your compiler.
 \end{exercise}
 \end{exercise}
 
 
 
 
 \section{Patch Instructions}
 \section{Patch Instructions}
 \label{sec:patch-s0}
 \label{sec:patch-s0}
 
 
-The \code{patch-instructions} pass compiles \LangXVar{}
-programs to \LangXASTInt{} programs by making sure that each
-instruction adheres to the restrictions of the x86 assembly language.
-In particular, at most one argument of an instruction may be a memory
-reference.
+The \code{patch-instructions} pass compiles from \LangXVar{} to
+\LangXASTInt{} by making sure that each instruction adheres to the
+restriction that at most one argument of an instruction may be a
+memory reference.
 
 
-We return to the following running example.
+We return to the following example.
 % s0_20.rkt
 % s0_20.rkt
 \begin{lstlisting}
 \begin{lstlisting}
    (let ([a 42])
    (let ([a 42])
      (let ([b a])
      (let ([b a])
        b))
        b))
 \end{lstlisting}
 \end{lstlisting}
-After the \key{assign-homes} pass, the above program has been translated to
-the following. \\
+The \key{assign-homes} pass produces the following output
+for this program. \\
 \begin{minipage}{0.5\textwidth}
 \begin{minipage}{0.5\textwidth}
 \begin{lstlisting}
 \begin{lstlisting}
 stack-space: 16
 stack-space: 16
@@ -2505,13 +2498,12 @@ from \key{rax} to the destination location, as follows.
 \end{lstlisting}
 \end{lstlisting}
 
 
 \begin{exercise}
 \begin{exercise}
-\normalfont
-Implement the \key{patch-instructions} pass and test it on all of the
-example programs that you created for the previous passes and create
-three new example programs that are designed to exercise all of the
-interesting code in this pass. Use the \key{interp-tests} function
-(Appendix~\ref{appendix:utilities}) from \key{utilities.rkt} to test
-your passes on the example programs.
+\normalfont Implement the \key{patch-instructions} pass in
+\code{compiler.rkt}. Create three new example programs that are
+designed to exercise all of the interesting cases in this pass.  In
+the \code{run-tests.rkt} script, uncomment the line for this pass in
+the list of \code{passes} and then run the script to test your
+compiler.
 \end{exercise}
 \end{exercise}
 
 
 
 
@@ -2519,52 +2511,31 @@ your passes on the example programs.
 \label{sec:print-x86}
 \label{sec:print-x86}
 
 
 The last step of the compiler from \LangVar{} to x86 is to convert the
 The last step of the compiler from \LangVar{} to x86 is to convert the
-\LangXASTInt{} AST (defined in Figure~\ref{fig:x86-0-ast}) to the
-string representation (defined in Figure~\ref{fig:x86-0-concrete}). The Racket
-\key{format} and \key{string-append} functions are useful in this
-regard. The main work that this step needs to perform is to create the
-\key{main} function and the standard instructions for its prelude and
-conclusion, as shown in Figure~\ref{fig:p1-x86} of
-Section~\ref{sec:x86}. You need to know the number of stack-allocated
-variables, so we suggest computing it in the \key{assign-homes} pass
-(Section~\ref{sec:assign-r1}) and storing it in the $\itm{info}$ field
-of the \key{program} node.
-
-%% Your compiled code should print the result of the program's execution
-%% by using the \code{print\_int} function provided in
-%% \code{runtime.c}. If your compiler has been implemented correctly so
-%% far, this final result should be stored in the \key{rax} register.
-%% We'll talk more about how to perform function calls with arguments in
-%% general later on, but for now, place the following after the compiled
-%% code for the \LangVar{} program but before the conclusion:
-
-%% \begin{lstlisting}
-%%     movq %rax, %rdi
-%%     callq print_int
-%% \end{lstlisting}
-
-%% These lines move the value in \key{rax} into the \key{rdi} register, which
-%% stores the first argument to be passed into \key{print\_int}.
-
-If you want your program to run on Mac OS X, your code needs to
-determine whether or not it is running on a Mac, and prefix
-underscores to labels like \key{main}.  You can determine the platform
-with the Racket call \code{(system-type 'os)}, which returns
-\code{'macosx}, \code{'unix}, or \code{'windows}.  
-%% In addition to
-%% placing underscores on \key{main}, you need to put them in front of
-%% \key{callq} labels (so \code{callq print\_int} becomes \code{callq
-%%   \_print\_int}).
+\LangXASTInt{} AST (defined in Figure~\ref{fig:x86-int-ast}) to the
+string representation (defined in
+Figure~\ref{fig:x86-int-concrete}). The Racket \key{format} and
+\key{string-append} functions are useful in this regard. The main work
+that this step needs to perform is to create the \key{main} function
+and the standard instructions for its prelude and conclusion, as shown
+in Figure~\ref{fig:p1-x86} of Section~\ref{sec:x86}. You will need to
+know the amount of space needed for the stack frame, which you can
+obtain from the \code{stack-space} entry in the $\itm{info}$ field of
+the \key{X86Program} node.
+
+When running on Mac OS X, you compiler should prefix an underscore to
+labels like \key{main}. The Racket call \code{(system-type 'os)} is
+useful for determining which operating system the compiler is running
+on. It returns \code{'macosx}, \code{'unix}, or \code{'windows}.
 
 
 \begin{exercise}
 \begin{exercise}
-\normalfont Implement the \key{print-x86} pass and test it on all of
-the example programs that you created for the previous passes. Use the
-\key{compiler-tests} function (Appendix~\ref{appendix:utilities}) from
-\key{utilities.rkt} to test your complete compiler on the example
-programs.  See the \key{run-tests.rkt} script in the student support
-code for an example of how to use \key{compiler-tests}. Also, remember
-to compile the provided \key{runtime.c} file to \key{runtime.o} using
-\key{gcc}.
+  \normalfont Implement the \key{print-x86} pass in
+  \code{compiler.rkt}. Uncomment the line for this pass in the list of
+  \code{passes} in the \code{run-tests.rkt} script. Also uncomment the
+  call to the \key{compiler-tests} function
+  (Appendix~\ref{appendix:utilities}), which tests your complete
+  compiler by executing the generated x86 code. Compile the provided
+  \key{runtime.c} file to \key{runtime.o} using \key{gcc}. Run the
+  script to test your compiler.
 \end{exercise}
 \end{exercise}
 
 
 
 
@@ -2602,7 +2573,11 @@ arithmetic. For example, your partial evaluator should translate
 \]
 \]
 To accomplish this, the \code{pe-exp} function should produce output
 To accomplish this, the \code{pe-exp} function should produce output
 in the form of the $\itm{residual}$ non-terminal of the following
 in the form of the $\itm{residual}$ non-terminal of the following
-grammar.
+grammar. The idea is that when processing an addition expression, we
+can always produce either 1) an integer constant, 2) and addition
+expression with an integer constant on the left-hand side but not the
+right-hand side, or 3) or an addition expression in which neither
+subexpression is a constant.
 \[
 \[
 \begin{array}{lcl}
 \begin{array}{lcl}
 \itm{inert} &::=& \Var \mid \LP\key{read}\RP \mid \LP\key{-} \;\Var\RP
 \itm{inert} &::=& \Var \mid \LP\key{read}\RP \mid \LP\key{-} \;\Var\RP
@@ -2612,11 +2587,11 @@ grammar.
 \itm{residual} &::=& \Int \mid \LP\key{+}\; \Int\; \itm{inert}\RP \mid \itm{inert} 
 \itm{residual} &::=& \Int \mid \LP\key{+}\; \Int\; \itm{inert}\RP \mid \itm{inert} 
 \end{array}
 \end{array}
 \]
 \]
-The \code{pe-add} and \code{pe-neg} functions may therefore assume
-that their inputs are $\itm{residual}$ expressions and they should
-return $\itm{residual}$ expressions.  Once the improvements are
-complete, make sure that your compiler still passes all of the tests.
-After all, fast code is useless if it produces incorrect results!
+The \code{pe-add} and \code{pe-neg} functions may assume that their
+inputs are $\itm{residual}$ expressions and they should return
+$\itm{residual}$ expressions.  Once the improvements are complete,
+make sure that your compiler still passes all of the tests.  After
+all, fast code is useless if it produces incorrect results!
 \end{exercise}
 \end{exercise}
 
 
 
 
@@ -4677,7 +4652,7 @@ the first argument:
 \]
 \]
 \end{minipage}
 \end{minipage}
 }
 }
-\caption{The concrete syntax of \LangXIf{}  (extends \LangXASTInt{} of Figure~\ref{fig:x86-0-concrete}).}
+\caption{The concrete syntax of \LangXIf{}  (extends \LangXASTInt{} of Figure~\ref{fig:x86-int-concrete}).}
 \label{fig:x86-1-concrete}
 \label{fig:x86-1-concrete}
 \end{figure}
 \end{figure}
 
 
@@ -4709,7 +4684,7 @@ the first argument:
 \]
 \]
 \end{minipage}
 \end{minipage}
 }
 }
-\caption{The abstract syntax of \LangXASTIf{} (extends \LangXASTInt{} of Figure~\ref{fig:x86-0-ast}).}
+\caption{The abstract syntax of \LangXASTIf{} (extends \LangXASTInt{} of Figure~\ref{fig:x86-int-ast}).}
 \label{fig:x86-1}
 \label{fig:x86-1}
 \end{figure}
 \end{figure}