|
@@ -7596,6 +7596,24 @@ particularly important to \textbf{not} replace its condition with a
|
|
|
temporary variable because that would interfere with the generation of
|
|
|
high-quality output in the \code{explicate\_control} pass.
|
|
|
|
|
|
+
|
|
|
+\newcommand{\LifASTMonadPython}{
|
|
|
+\begin{array}{rcl}
|
|
|
+%% \itm{binaryop} &::=& \code{Add()} \MID \code{Sub()} \\
|
|
|
+%% \itm{cmp} &::= & \code{Eq()} \MID \code{NotEq()} \MID \code{Lt()} \MID \code{LtE()} \MID \code{Gt()} \MID \code{GtE()} \\
|
|
|
+%% \itm{unaryop} &::=& \code{USub()} \MID \code{Not()} \\
|
|
|
+%% \itm{bool} &::=& \code{True} \MID \code{False} \\
|
|
|
+\Atm &::=& \INT{\Int} \MID \VAR{\Var} \MID \BOOL{\itm{bool}}\\
|
|
|
+\Exp &::=& \Atm \MID \READ{} \\
|
|
|
+ &\MID& \BINOP{\itm{binaryop}}{\Atm}{\Atm} \MID \UNIOP{\key{unaryop}}{\Atm} \\
|
|
|
+ &\MID& \CMP{\Atm}{\itm{cmp}}{\Atm} \MID \IF{\Exp}{\Exp}{\Exp} \\
|
|
|
+ &\MID& \LET{\Var}{\Exp}{\Exp}\\
|
|
|
+\Stmt{} &::=& \PRINT{\Atm} \MID \EXPR{\Exp} \\
|
|
|
+ &\MID& \ASSIGN{\VAR{\Var}}{\Exp} \MID \IFSTMT{\Exp}{\Stmt^{*}}{\Stmt^{*}}\\
|
|
|
+\LangIfANF &::=& \PROGRAM{\code{()}}{\Stmt^{*}}
|
|
|
+\end{array}
|
|
|
+}
|
|
|
+
|
|
|
\begin{figure}[tp]
|
|
|
\centering
|
|
|
\fbox{
|
|
@@ -7603,7 +7621,7 @@ high-quality output in the \code{explicate\_control} pass.
|
|
|
{\if\edition\racketEd
|
|
|
\[
|
|
|
\begin{array}{rcl}
|
|
|
-\Atm &::=& \gray{ \INT{\Int} \MID \VAR{\Var} } \MID \BOOL{\itm{bool}}\\
|
|
|
+Atm &::=& \gray{ \INT{\Int} \MID \VAR{\Var} } \MID \BOOL{\itm{bool}}\\
|
|
|
\Exp &::=& \gray{ \Atm \MID \READ{} } \\
|
|
|
&\MID& \gray{ \NEG{\Atm} \MID \ADD{\Atm}{\Atm} } \\
|
|
|
&\MID& \gray{ \LET{\Var}{\Exp}{\Exp} } \\
|
|
@@ -7615,19 +7633,11 @@ high-quality output in the \code{explicate\_control} pass.
|
|
|
\fi}
|
|
|
{\if\edition\pythonEd
|
|
|
\[
|
|
|
-\begin{array}{rcl}
|
|
|
-\itm{binaryop} &::=& \code{Add()} \MID \code{Sub()} \\
|
|
|
-\itm{cmp} &::= & \code{Eq()} \MID \code{NotEq()} \MID \code{Lt()} \MID \code{LtE()} \MID \code{Gt()} \MID \code{GtE()} \\
|
|
|
-\itm{unaryop} &::=& \code{USub()} \MID \code{Not()} \\
|
|
|
-\itm{bool} &::=& \code{True} \MID \code{False} \\
|
|
|
-\Atm &::=& \INT{\Int} \MID \VAR{\Var} \MID \BOOL{\itm{bool}}\\
|
|
|
-\Exp &::=& \Atm \MID \READ{} \\
|
|
|
- &\MID& \BINOP{\itm{binaryop}}{\Atm}{\Atm} \MID \UNIOP{\key{unaryop}}{\Atm} \\
|
|
|
- &\MID& \CMP{\Atm}{\itm{cmp}}{\Atm} \MID \IF{\Exp}{\Exp}{\Exp} \\
|
|
|
- &\MID& \LET{\Var}{\Exp}{\Exp}\\
|
|
|
-\Stmt{} &::=& \PRINT{\Atm} \MID \EXPR{\Exp} \\
|
|
|
- &\MID& \ASSIGN{\VAR{\Var}}{\Exp} \MID \IFSTMT{\Exp}{\Stmt^{*}}{\Stmt^{*}}\\
|
|
|
-\LangIfANF &::=& \PROGRAM{\code{()}}{\Stmt^{*}}
|
|
|
+\begin{array}{l}
|
|
|
+ \LifASTMonadPython \\
|
|
|
+ \begin{array}{rcl}
|
|
|
+ \LangIfANF &::=& \PROGRAM{\code{()}}{\Stmt^{*}}
|
|
|
+ \end{array}
|
|
|
\end{array}
|
|
|
\]
|
|
|
\fi}
|
|
@@ -11652,6 +11662,14 @@ pass, which is \LangAlloc{} in monadic normal form.
|
|
|
\section{Explicate Control and the \LangCVec{} language}
|
|
|
\label{sec:explicate-control-r3}
|
|
|
|
|
|
+\newcommand{\CtupASTPython}{
|
|
|
+\begin{array}{lcl}
|
|
|
+\Exp &::= & \GET{\Atm}{\Atm}\MID \ALLOCATE{\Int}{\Type} \\
|
|
|
+ &\MID& \GLOBALVALUE{\Var}\RP \MID \LEN{\Atm} \\
|
|
|
+\Stmt &::=& \COLLECT{\Int} \\
|
|
|
+ &\MID& \ASSIGN{\PUT{\Atm}{\Atm}}{\Atm}
|
|
|
+\end{array}
|
|
|
+}
|
|
|
|
|
|
\begin{figure}[tp]
|
|
|
\fbox{
|
|
@@ -11680,23 +11698,12 @@ pass, which is \LangAlloc{} in monadic normal form.
|
|
|
\fi}
|
|
|
{\if\edition\pythonEd
|
|
|
\[
|
|
|
+\begin{array}{l}
|
|
|
+ \gray{\CifASTPython} \\ \hline
|
|
|
+ \CtupASTPython \\
|
|
|
\begin{array}{lcl}
|
|
|
-\Atm &::=& \INT{\Int} \MID \VAR{\Var} \MID \BOOL{\itm{bool}} \\
|
|
|
-\Exp &::= & \Atm \MID \READ{} \\
|
|
|
- &\MID& \BINOP{\Atm}{\itm{binaryop}}{\Atm}
|
|
|
- \MID \UNIOP{\itm{unaryop}}{\Atm} \\
|
|
|
- &\MID& \CMP{\Atm}{\itm{cmp}}{\Atm}
|
|
|
- \MID \BOOLOP{\itm{boolop}}{\Atm}{\Atm} \\
|
|
|
- &\MID& \GET{\Atm}{\Atm}
|
|
|
- \MID \ALLOCATE{\Int}{\Type} \MID \GLOBALVALUE{\Var}\RP\\
|
|
|
- &\MID& \LEN{\Atm} \\
|
|
|
-\Stmt &::=& \PRINT{\Exp} \MID \EXPR{\Exp} \\
|
|
|
- &\MID& \ASSIGN{\VAR{\Var}}{\Exp}
|
|
|
- \MID \RETURN{\Exp} \MID \GOTO{\itm{label}} \\
|
|
|
- &\MID& \IFSTMT{\CMP{\Atm}{\itm{cmp}}{\Atm}}{\LS\GOTO{\itm{label}}\RS}{\LS\GOTO{\itm{label}}\RS} \\
|
|
|
- &\MID& \COLLECT{\Int} \\
|
|
|
- &\MID& \ASSIGN{\PUT{\Atm}{\Atm}}{\Atm} \\
|
|
|
-\LangCVecM{} & ::= & \CPROGRAM{\itm{info}}{\LC\itm{label}\,\key{:}\,\Stmt^{*}, \ldots \RC}
|
|
|
+\LangCVecM{} & ::= & \CPROGRAM{\itm{info}}{\LC\itm{label}\key{:}\,\Stmt^{*}, \ldots \RC}
|
|
|
+\end{array}
|
|
|
\end{array}
|
|
|
\]
|
|
|
\fi}
|
|
@@ -11826,6 +11833,10 @@ tag is organized.
|
|
|
\code{bitwise-ior} and \code{arithmetic-shift} to compute the tag
|
|
|
during compilation.}
|
|
|
%
|
|
|
+\python{We recommend using the bitwise-or operator \code{|} and the
|
|
|
+ shift-left operator \code{<<} to compute the tag during
|
|
|
+ compilation.}
|
|
|
+%
|
|
|
The type annotation in the \code{allocate} form is used to determine
|
|
|
the pointer mask region of the tag.
|
|
|
%
|
|
@@ -12807,13 +12818,15 @@ nested inside each other.
|
|
|
\begin{array}{lcl}
|
|
|
\Type &::=& \key{Callable}\LS \LS \Type \key{,} \ldots \RS \key{, } \Type \RS \\
|
|
|
\Exp &::=& \CAPPLY{\Exp}{\Exp\code{,} \ldots} \\
|
|
|
+ \Stmt &::=& \CRETURN{\Exp} \\
|
|
|
\Def &::=& \CDEF{\Var}{\Var \key{:} \Type\key{,} \ldots}{\Type}{\Stmt^{+}}
|
|
|
\end{array}
|
|
|
}
|
|
|
\newcommand{\LfunASTPython}{
|
|
|
\begin{array}{lcl}
|
|
|
\Type &::=& \key{FunctionType}\LP \Type^{*} \key{, } \Type \RP \\
|
|
|
- \Exp &::& \CALL{\Exp}{\Exp^{*}}\\
|
|
|
+ \Exp &::=& \CALL{\Exp}{\Exp^{*}}\\
|
|
|
+ \Stmt &::=& \RETURN{\Exp} \\
|
|
|
\Def &::=& \FUNDEF{\Var}{\LS \LP \Var \key{, } \Type \RP \key{, } \ldots \RS}{\Type}{}{\Stmt^{+}}
|
|
|
\end{array}
|
|
|
}
|
|
@@ -13524,8 +13537,8 @@ defined in Figure~\ref{fig:f1-syntax}.
|
|
|
{\if\edition\pythonEd
|
|
|
\[
|
|
|
\begin{array}{lcl}
|
|
|
-\Exp &::=& \ldots \MID \FUNREF{\Var}\\
|
|
|
- \LangFunM{} &::=& \PROGRAM{}{\LS \Def \ldots \RS}
|
|
|
+\Exp &::=& \FUNREF{\Var}\\
|
|
|
+ \LangFunM{} &::=& \PROGRAM{}{\LS \Def \code{,} \ldots \RS}
|
|
|
\end{array}
|
|
|
\]
|
|
|
\fi}
|
|
@@ -13648,9 +13661,13 @@ 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}.
|
|
|
|
|
|
-The output of this pass, \LangFunANF{}, extends \LangAllocANF{} with
|
|
|
-\code{FunRef} and \racket{\code{Apply}}\python{\code{Call}} in the
|
|
|
-grammar for expressions.
|
|
|
+The output of this pass, \LangFunANF{}, extends \LangAllocANF{}
|
|
|
+(Figure~\ref{fig:Lvec-anf-syntax}) with \code{FunRef}
|
|
|
+and \racket{\code{Apply}}\python{\code{Call}} in the grammar for expressions.
|
|
|
+%
|
|
|
+\python{Also, \LangFunANF{} adds \code{Return} to the grammar for statements.}
|
|
|
+
|
|
|
+% TODO: Return?
|
|
|
|
|
|
|
|
|
%% Figure~\ref{fig:Rfun-anf-syntax} defines the output language
|
|
@@ -13693,24 +13710,50 @@ output of \code{explicate\_control}.
|
|
|
\racket{(The concrete syntax is given in
|
|
|
Figure~\ref{fig:c3-concrete-syntax} of the Appendix.)}
|
|
|
%
|
|
|
-The auxiliary functions for assignment and tail contexts should be
|
|
|
-updated with cases for \racket{\code{Apply}}\python{\code{Call}} and
|
|
|
-\code{FunRef} and the function for predicate context should be updated
|
|
|
-for \racket{\code{Apply}}\python{\code{Call}} but not \code{FunRef}.
|
|
|
-(A \code{FunRef} can't be a Boolean.) In assignment and predicate
|
|
|
-contexts, \code{Apply} becomes \code{Call}, whereas in tail position
|
|
|
-\code{Apply} becomes \code{TailCall}. We recommend defining a new
|
|
|
+The auxiliary functions for assignment\racket{and tail contexts} should
|
|
|
+be updated with cases for
|
|
|
+\racket{\code{Apply}}\python{\code{Call}} and \code{FunRef} and the
|
|
|
+function for predicate context should be updated for
|
|
|
+\racket{\code{Apply}}\python{\code{Call}} but not \code{FunRef}. (A
|
|
|
+\code{FunRef} can't be a Boolean.) In assignment and predicate
|
|
|
+contexts, \code{Apply} becomes \code{Call}\racket{, whereas in tail position
|
|
|
+\code{Apply} becomes \code{TailCall}}. We recommend defining a new
|
|
|
auxiliary function for processing function definitions. This code is
|
|
|
similar to the case for \code{Program} in \LangVec{}. The top-level
|
|
|
\code{explicate\_control} function that handles the \code{ProgramDefs}
|
|
|
form of \LangFun{} can then apply this new function to all the
|
|
|
function definitions.
|
|
|
|
|
|
+{\if\edition\pythonEd
|
|
|
+
|
|
|
+The translation of \code{Return} statements requires a new auxiliary
|
|
|
+function to handle expressions in tail context, called
|
|
|
+\code{explicate\_tail}. The function should take an expression and the
|
|
|
+dictionary of basic blocks and produce a list of statements in the
|
|
|
+\LangCFun{} language. The \code{explicate\_tail} function should
|
|
|
+include cases for \code{Begin}, \code{IfExp}, \code{Let}, \code{Call},
|
|
|
+and a default case for other kinds of expressions. The default case
|
|
|
+should produce a \code{Return} statement. The case for \code{Call}
|
|
|
+should change it into \code{TailCall}. The other cases should
|
|
|
+recursively process their subexpressions and statements, choosing the
|
|
|
+appropriate explicate functions for the various contexts.
|
|
|
+
|
|
|
+\fi}
|
|
|
+
|
|
|
+
|
|
|
+\newcommand{\CfunASTPython}{
|
|
|
+\begin{array}{lcl}
|
|
|
+\Exp &::= & \FUNREF{\itm{label}} \MID \CALL{\Atm}{\LS\Atm\code{,}\ldots\RS} \\
|
|
|
+\Stmt &::= & \TAILCALL{\Atm}{\LS\Atm\code{,}\ldots\RS} \\
|
|
|
+\Def &::=& \DEF{\itm{label}}{\LS\LP\Var\key{,}\Type\RP\code{,}\ldots\RS}{\LC\itm{label}\key{:}\Stmt^{*}\code{,}\ldots\RC}{\_}{\Type}{\_}
|
|
|
+\end{array}
|
|
|
+}
|
|
|
|
|
|
\begin{figure}[tp]
|
|
|
\fbox{
|
|
|
\begin{minipage}{0.96\textwidth}
|
|
|
\small
|
|
|
+{\if\edition\racketEd
|
|
|
\[
|
|
|
\begin{array}{lcl}
|
|
|
\Atm &::=& \gray{ \INT{\Int} \MID \VAR{\Var} \MID \BOOL{\itm{bool}} }\\
|
|
@@ -13733,6 +13776,19 @@ function definitions.
|
|
|
\LangCFunM{} & ::= & \PROGRAMDEFS{\itm{info}}{\LP\Def\ldots\RP}
|
|
|
\end{array}
|
|
|
\]
|
|
|
+\fi}
|
|
|
+{\if\edition\pythonEd
|
|
|
+\[
|
|
|
+ \begin{array}{l}
|
|
|
+ \gray{\CifASTPython} \\ \hline
|
|
|
+ \gray{\CtupASTPython} \\ \hline
|
|
|
+ \CfunASTPython \\
|
|
|
+ \begin{array}{lcl}
|
|
|
+ \LangCFunM{} & ::= & \CPROGRAMDEFS{\LS\Def\code{,}\ldots\RS}
|
|
|
+ \end{array}
|
|
|
+ \end{array}
|
|
|
+\]
|
|
|
+\fi}
|
|
|
\end{minipage}
|
|
|
}
|
|
|
\caption{The abstract syntax of \LangCFun{}, extending \LangCVec{} (Figure~\ref{fig:c2-syntax}).}
|
|
@@ -13754,8 +13810,7 @@ language, whose syntax is defined in Figure~\ref{fig:x86-3}.
|
|
|
\small
|
|
|
\[
|
|
|
\begin{array}{lcl}
|
|
|
- \Arg &::=& \gray{ \key{\$}\Int \MID \key{\%}\Reg \MID \Int\key{(}\key{\%}\Reg\key{)} \MID \key{\%}\itm{bytereg} } \MID \Var \key{(\%rip)}
|
|
|
- \MID \LP\key{fun-ref}\; \itm{label}\RP\\
|
|
|
+ \Arg &::=& \gray{ \key{\$}\Int \MID \key{\%}\Reg \MID \Int\key{(}\key{\%}\Reg\key{)} \MID \key{\%}\itm{bytereg} } \MID \Var \key{(\%rip)} \\
|
|
|
\itm{cc} & ::= & \gray{ \key{e} \MID \key{l} \MID \key{le} \MID \key{g} \MID \key{ge} } \\
|
|
|
\Instr &::=& \ldots
|
|
|
\MID \key{callq}\;\key{*}\Arg \MID \key{tailjmp}\;\Arg
|
|
@@ -13775,11 +13830,12 @@ language, whose syntax is defined in Figure~\ref{fig:x86-3}.
|
|
|
\fbox{
|
|
|
\begin{minipage}{0.96\textwidth}
|
|
|
\small
|
|
|
+{\if\edition\racketEd
|
|
|
\[
|
|
|
\begin{array}{lcl}
|
|
|
\Arg &::=& \gray{ \INT{\Int} \MID \REG{\Reg} \MID \DEREF{\Reg}{\Int}
|
|
|
\MID \BYTEREG{\Reg} } \\
|
|
|
- &\MID& \gray{ (\key{Global}~\Var) } \MID \FUNREF{\itm{label}} \\
|
|
|
+ &\MID& \gray{ \GLOBAL{\Var} } \MID \FUNREF{\itm{label}} \\
|
|
|
\Instr &::=& \ldots \MID \INDCALLQ{\Arg}{\itm{int}}
|
|
|
\MID \TAILJMP{\Arg}{\itm{int}}\\
|
|
|
&\MID& \BININSTR{\code{'leaq}}{\Arg}{\REG{\Reg}}\\
|
|
@@ -13788,6 +13844,21 @@ language, whose syntax is defined in Figure~\ref{fig:x86-3}.
|
|
|
\LangXIndCallM{} &::= & \PROGRAMDEFS{\itm{info}}{\LP\Def\ldots\RP}
|
|
|
\end{array}
|
|
|
\]
|
|
|
+\fi}
|
|
|
+{\if\edition\pythonEd
|
|
|
+\[
|
|
|
+\begin{array}{lcl}
|
|
|
+ \Arg &::=& \gray{ \INT{\Int} \MID \REG{\Reg} \MID \DEREF{\Reg}{\Int}
|
|
|
+ \MID \BYTEREG{\Reg} } \\
|
|
|
+ &\MID& \gray{ \GLOBAL{\Var} } \MID \FUNREF{\itm{label}} \\
|
|
|
+ \Instr &::=& \ldots \MID \INDCALLQ{\Arg}{\itm{int}}
|
|
|
+ \MID \TAILJMP{\Arg}{\itm{int}}\\
|
|
|
+ &\MID& \BININSTR{\code{leaq}}{\Arg}{\REG{\Reg}}\\
|
|
|
+ \Def &::= & \DEF{\itm{label}}{\LS\RS}{\LC\itm{label}\key{:}\,\Instr^{*}\code{,}\ldots\RC}{\_}{\Type}{\_} \\
|
|
|
+\LangXIndCallM{} &::= & \XPROGRAMDEFS{\LS\Def\code{,}\ldots\RS}
|
|
|
+\end{array}
|
|
|
+\]
|
|
|
+\fi}
|
|
|
\end{minipage}
|
|
|
}
|
|
|
\caption{The abstract syntax of \LangXIndCall{} (extends
|
|
@@ -13822,21 +13893,30 @@ Section~\ref{sec:fun-x86}. That is, the arguments are passed in
|
|
|
registers. We recommend turning the parameters into local variables
|
|
|
and generating instructions at the beginning of the function to move
|
|
|
from the argument passing registers to these local variables.
|
|
|
+{\if\edition\racketEd
|
|
|
+\begin{lstlisting}
|
|
|
+ (Def |$f$| '([|$x_1$| : |$T_1$|] [|$x_2$| : |$T_2$|] |$\ldots$| ) |$T_r$| |$\itm{info}$| |$B$|)
|
|
|
+ |$\Rightarrow$|
|
|
|
+ (Def |$f$| '() 'Integer |$\itm{info}'$| |$B'$|)
|
|
|
+\end{lstlisting}
|
|
|
+\fi}
|
|
|
+{\if\edition\pythonEd
|
|
|
\begin{lstlisting}
|
|
|
- (Def |$f$| '([|$x_1$| : |$T_1$|] [|$x_2$| : |$T_2$|] |$\ldots$| ) |$T_r$| |$\itm{info}$| |$G$|)
|
|
|
+ FunctionDef(|$f$|, [|$(x_1,T_1),\ldots$|], |$B$|, _, |$T_r$|, _)
|
|
|
|$\Rightarrow$|
|
|
|
- (Def |$f$| '() 'Integer |$\itm{info}'$| |$G'$|)
|
|
|
+ FunctionDef(|$f$|, [], |$B'$|, _, int, _)
|
|
|
\end{lstlisting}
|
|
|
-The $G'$ control-flow graph is the same as $G$ except that the
|
|
|
+\fi}
|
|
|
+The basic blocks $B'$ are the same as $B$ except that the
|
|
|
\code{start} block is modified to add the instructions for moving from
|
|
|
the argument registers to the parameter variables. So the \code{start}
|
|
|
-block of $G$ shown on the left is changed to the code on the right.
|
|
|
+block of $B$ shown on the left is changed to the code on the right.
|
|
|
\begin{center}
|
|
|
\begin{minipage}{0.3\textwidth}
|
|
|
\begin{lstlisting}
|
|
|
start:
|
|
|
|$\itm{instr}_1$|
|
|
|
- |$\vdots$|
|
|
|
+ |$\cdots$|
|
|
|
|$\itm{instr}_n$|
|
|
|
\end{lstlisting}
|
|
|
\end{minipage}
|
|
@@ -13845,10 +13925,9 @@ $\Rightarrow$
|
|
|
\begin{lstlisting}
|
|
|
start:
|
|
|
movq %rdi, |$x_1$|
|
|
|
- movq %rsi, |$x_2$|
|
|
|
- |$\vdots$|
|
|
|
+ |$\cdots$|
|
|
|
|$\itm{instr}_1$|
|
|
|
- |$\vdots$|
|
|
|
+ |$\cdots$|
|
|
|
|$\itm{instr}_n$|
|
|
|
\end{lstlisting}
|
|
|
\end{minipage}
|
|
@@ -13877,7 +13956,7 @@ itself is performed with an indirect function call. The return value
|
|
|
from the function is stored in \code{rax}, so it needs to be moved
|
|
|
into the \itm{lhs}.
|
|
|
\begin{lstlisting}
|
|
|
- |\itm{lhs}| = (call |\itm{fun}| |$\itm{arg}_1~\itm{arg}_2\ldots$|));
|
|
|
+ |\itm{lhs}| = |$\CALL{\itm{fun}}{\itm{arg}_1\ldots}$|
|
|
|
|$\Rightarrow$|
|
|
|
movq |$\itm{arg}_1$|, %rdi
|
|
|
movq |$\itm{arg}_2$|, %rsi
|
|
@@ -13887,7 +13966,7 @@ into the \itm{lhs}.
|
|
|
\end{lstlisting}
|
|
|
The \code{IndirectCallq} AST node includes an integer for the arity of
|
|
|
the function, i.e., the number of parameters. That information is
|
|
|
-useful in the \code{uncover-live} pass for determining which
|
|
|
+useful in the \code{uncover\_live} pass for determining which
|
|
|
argument-passing registers are potentially read during the call.
|
|
|
|
|
|
For tail calls, the parameter passing is the same as non-tail calls:
|
|
@@ -13901,18 +13980,15 @@ means ``pop the frame and then do an indirect jump'', which we name
|
|
|
argument that specifies where to jump and an integer that represents
|
|
|
the arity of the function being called.
|
|
|
|
|
|
-Recall that in Section~\ref{sec:explicate-control-Lvar} we recommended
|
|
|
-using the label \code{start} for the initial block of a program, and
|
|
|
-in Section~\ref{sec:select-Lvar} we recommended labeling the conclusion
|
|
|
-of the program with \code{conclusion}, so that $(\key{Return}\;\Arg)$
|
|
|
-can be compiled to an assignment to \code{rax} followed by a jump to
|
|
|
-\code{conclusion}. With the addition of function definitions, we will
|
|
|
-have a starting block and conclusion for each function, but their
|
|
|
-labels need to be unique. We recommend prepending the function's name
|
|
|
-to \code{start} and \code{conclusion}, respectively, to obtain unique
|
|
|
-labels. (Alternatively, one could \code{gensym} labels for the start
|
|
|
-and conclusion and store them in the $\itm{info}$ field of the
|
|
|
-function definition.)
|
|
|
+Recall that we use the label \code{start} for the initial block of a
|
|
|
+program, and in Section~\ref{sec:select-Lvar} we recommended labeling
|
|
|
+the conclusion of the program with \code{conclusion}, so that
|
|
|
+$\RETURN{Arg}$ can be compiled to an assignment to \code{rax} followed
|
|
|
+by a jump to \code{conclusion}. With the addition of function
|
|
|
+definitions, there is a start block and conclusion for each function,
|
|
|
+but their labels need to be unique. We recommend prepending the
|
|
|
+function's name to \code{start} and \code{conclusion}, respectively,
|
|
|
+to obtain unique labels.
|
|
|
|
|
|
|
|
|
\section{Register Allocation}
|
|
@@ -13978,31 +14054,33 @@ register. Additionally, you should ensure that the argument of
|
|
|
code generation more convenient, because we trample many registers
|
|
|
before the tail call (as explained in the next section).
|
|
|
|
|
|
-\section{Print x86}
|
|
|
+\section{Prelude and Conclusion}
|
|
|
|
|
|
-For the \code{print\_x86} pass, the cases for \code{FunRef} and
|
|
|
-\code{IndirectCallq} are straightforward: output their concrete
|
|
|
-syntax.
|
|
|
-\begin{lstlisting}
|
|
|
- (FunRef |\itm{label}|) |$\Rightarrow$| |\itm{label}|(%rip)
|
|
|
- (IndirectCallq |\itm{arg}| |\itm{int}|) |$\Rightarrow$| callq *|\itm{arg}'|
|
|
|
-\end{lstlisting}
|
|
|
+%% For the \code{print\_x86} pass, the cases for \code{FunRef} and
|
|
|
+%% \code{IndirectCallq} are straightforward: output their concrete
|
|
|
+%% syntax.
|
|
|
+%% \begin{lstlisting}
|
|
|
+%% (FunRef |\itm{label}|) |$\Rightarrow$| |\itm{label}|(%rip)
|
|
|
+%% (IndirectCallq |\itm{arg}| |\itm{int}|) |$\Rightarrow$| callq *|\itm{arg}'|
|
|
|
+%% \end{lstlisting}
|
|
|
|
|
|
-The \code{TailJmp} node requires a bit work. A straightforward
|
|
|
-translation of \code{TailJmp} would be \code{jmp *$\itm{arg}$}, but
|
|
|
-before the jump we need to pop the current frame. This sequence of
|
|
|
-instructions is the same as the code for the conclusion of a function,
|
|
|
-except the \code{retq} is replaced with \code{jmp *$\itm{arg}$}.
|
|
|
+Now that register allocation is complete, we can translate the
|
|
|
+\code{TailJmp} into a sequence of instructions. A straightforward
|
|
|
+translation of \code{TailJmp} would simply be \code{jmp *$\itm{arg}$}.
|
|
|
+However, before the jump we need to pop the current frame. This
|
|
|
+sequence of instructions is the same as the code for the conclusion of
|
|
|
+a function, except the \code{retq} is replaced with \code{jmp *$\itm{arg}$}.
|
|
|
|
|
|
-Regarding function definitions, you will need to generate a prelude
|
|
|
+Regarding function definitions, you need to generate a prelude
|
|
|
and conclusion for each one. This code is similar to the prelude and
|
|
|
conclusion that you generated for the \code{main} function in
|
|
|
Chapter~\ref{ch:Lvec}. To review, the prelude of every function
|
|
|
should carry out the following steps.
|
|
|
+% TODO: .align the functions!
|
|
|
\begin{enumerate}
|
|
|
-\item Start with \code{.global} and \code{.align} directives followed
|
|
|
- by the label for the function. (See Figure~\ref{fig:add-fun} for an
|
|
|
- example.)
|
|
|
+%% \item Start with \code{.global} and \code{.align} directives followed
|
|
|
+%% by the label for the function. (See Figure~\ref{fig:add-fun} for an
|
|
|
+ %% example.)
|
|
|
\item Push \code{rbp} to the stack and set \code{rbp} to current stack
|
|
|
pointer.
|
|
|
\item Push to the stack all of the callee-saved registers that were
|
|
@@ -14108,13 +14186,24 @@ function in \LangFun{} to x86. The figure also includes the results of the
|
|
|
\begin{tabular}{ll}
|
|
|
\begin{minipage}{0.5\textwidth}
|
|
|
% s3_2.rkt
|
|
|
+{\if\edition\racketEd
|
|
|
\begin{lstlisting}[basicstyle=\ttfamily\scriptsize]
|
|
|
(define (add [x : Integer] [y : Integer])
|
|
|
: Integer
|
|
|
(+ x y))
|
|
|
(add 40 2)
|
|
|
\end{lstlisting}
|
|
|
+\fi}
|
|
|
+{\if\edition\pythonEd
|
|
|
+\begin{lstlisting}[basicstyle=\ttfamily\scriptsize]
|
|
|
+def add(x:int, y:int) -> int:
|
|
|
+ return x + y
|
|
|
+
|
|
|
+print(add(40, 2))
|
|
|
+\end{lstlisting}
|
|
|
+\fi}
|
|
|
$\Downarrow$
|
|
|
+{\if\edition\racketEd
|
|
|
\begin{lstlisting}[basicstyle=\ttfamily\scriptsize]
|
|
|
(define (add86 [x87 : Integer]
|
|
|
[y88 : Integer]) : Integer
|
|
@@ -14127,10 +14216,26 @@ $\Downarrow$
|
|
|
(tail-call tmp89 40 2)
|
|
|
)
|
|
|
\end{lstlisting}
|
|
|
+\fi}
|
|
|
+{\if\edition\pythonEd
|
|
|
+\begin{lstlisting}[basicstyle=\ttfamily\scriptsize]
|
|
|
+def add(x:int, y:int) -> int:
|
|
|
+ addstart:
|
|
|
+ return x + y
|
|
|
+
|
|
|
+def main() -> int:
|
|
|
+ mainstart:
|
|
|
+ fun.0 = add
|
|
|
+ tmp.1 = fun.0(40, 2)
|
|
|
+ print(tmp.1)
|
|
|
+ return 0
|
|
|
+\end{lstlisting}
|
|
|
+\fi}
|
|
|
\end{minipage}
|
|
|
&
|
|
|
$\Rightarrow$
|
|
|
\begin{minipage}{0.5\textwidth}
|
|
|
+{\if\edition\racketEd
|
|
|
\begin{lstlisting}[basicstyle=\ttfamily\scriptsize]
|
|
|
(define (add86) : Integer
|
|
|
add86start:
|
|
@@ -14148,11 +14253,36 @@ $\Rightarrow$
|
|
|
tail-jmp tmp89
|
|
|
)
|
|
|
\end{lstlisting}
|
|
|
+\fi}
|
|
|
+{\if\edition\pythonEd
|
|
|
+\begin{lstlisting}[basicstyle=\ttfamily\scriptsize]
|
|
|
+def add() -> int:
|
|
|
+ addstart:
|
|
|
+ movq %rdi, x
|
|
|
+ movq %rsi, y
|
|
|
+ movq x, %rax
|
|
|
+ addq y, %rax
|
|
|
+ jmp addconclusion
|
|
|
+
|
|
|
+def main() -> int:
|
|
|
+ mainstart:
|
|
|
+ leaq add, fun.0
|
|
|
+ movq $40, %rdi
|
|
|
+ movq $2, %rsi
|
|
|
+ callq *fun.0
|
|
|
+ movq %rax, tmp.1
|
|
|
+ movq tmp.1, %rdi
|
|
|
+ callq print_int
|
|
|
+ movq $0, %rax
|
|
|
+ jmp mainconclusion
|
|
|
+\end{lstlisting}
|
|
|
+\fi}
|
|
|
$\Downarrow$
|
|
|
\end{minipage}
|
|
|
\end{tabular}
|
|
|
\begin{tabular}{ll}
|
|
|
\begin{minipage}{0.3\textwidth}
|
|
|
+{\if\edition\racketEd
|
|
|
\begin{lstlisting}[basicstyle=\ttfamily\scriptsize]
|
|
|
.globl add86
|
|
|
.align 16
|
|
@@ -14168,9 +14298,32 @@ add86conclusion:
|
|
|
popq %rbp
|
|
|
retq
|
|
|
\end{lstlisting}
|
|
|
+\fi}
|
|
|
+{\if\edition\pythonEd
|
|
|
+\begin{lstlisting}[basicstyle=\ttfamily\scriptsize]
|
|
|
+ .align 16
|
|
|
+add:
|
|
|
+ pushq %rbp
|
|
|
+ movq %rsp, %rbp
|
|
|
+ subq $0, %rsp
|
|
|
+ jmp addstart
|
|
|
+addstart:
|
|
|
+ movq %rdi, %rdx
|
|
|
+ movq %rsi, %rcx
|
|
|
+ movq %rdx, %rax
|
|
|
+ addq %rcx, %rax
|
|
|
+ jmp addconclusion
|
|
|
+addconclusion:
|
|
|
+ subq $0, %r15
|
|
|
+ addq $0, %rsp
|
|
|
+ popq %rbp
|
|
|
+ retq
|
|
|
+\end{lstlisting}
|
|
|
+\fi}
|
|
|
\end{minipage}
|
|
|
&
|
|
|
\begin{minipage}{0.5\textwidth}
|
|
|
+{\if\edition\racketEd
|
|
|
\begin{lstlisting}[basicstyle=\ttfamily\scriptsize]
|
|
|
.globl main
|
|
|
.align 16
|
|
@@ -14193,6 +14346,37 @@ mainconclusion:
|
|
|
popq %rbp
|
|
|
retq
|
|
|
\end{lstlisting}
|
|
|
+\fi}
|
|
|
+{\if\edition\pythonEd
|
|
|
+\begin{lstlisting}[basicstyle=\ttfamily\scriptsize]
|
|
|
+ .globl main
|
|
|
+ .align 16
|
|
|
+main:
|
|
|
+ pushq %rbp
|
|
|
+ movq %rsp, %rbp
|
|
|
+ subq $0, %rsp
|
|
|
+ movq $65536, %rdi
|
|
|
+ movq $65536, %rsi
|
|
|
+ callq initialize
|
|
|
+ movq rootstack_begin(%rip), %r15
|
|
|
+ jmp mainstart
|
|
|
+mainstart:
|
|
|
+ leaq add(%rip), %rcx
|
|
|
+ movq $40, %rdi
|
|
|
+ movq $2, %rsi
|
|
|
+ callq *%rcx
|
|
|
+ movq %rax, %rcx
|
|
|
+ movq %rcx, %rdi
|
|
|
+ callq print_int
|
|
|
+ movq $0, %rax
|
|
|
+ jmp mainconclusion
|
|
|
+mainconclusion:
|
|
|
+ subq $0, %r15
|
|
|
+ addq $0, %rsp
|
|
|
+ popq %rbp
|
|
|
+ retq
|
|
|
+\end{lstlisting}
|
|
|
+\fi}
|
|
|
\end{minipage}
|
|
|
\end{tabular}
|
|
|
\caption{Example compilation of a simple function to x86.}
|