[pypy-svn] r77918 - pypy/extradoc/talk/pepm2011

leuschel at codespeak.net leuschel at codespeak.net
Thu Oct 14 13:52:46 CEST 2010


Author: leuschel
Date: Thu Oct 14 13:52:42 2010
New Revision: 77918

Modified:
   pypy/extradoc/talk/pepm2011/paper.tex
Log:
some changes to sect. 4


Modified: pypy/extradoc/talk/pepm2011/paper.tex
==============================================================================
--- pypy/extradoc/talk/pepm2011/paper.tex	(original)
+++ pypy/extradoc/talk/pepm2011/paper.tex	Thu Oct 14 13:52:42 2010
@@ -560,15 +560,15 @@
 The main insight to improve the code shown in the last section is that objects
 in category 1 don't survive very long -- they are used only inside the loop and
 nobody else in the program stores a reference to them. The idea for improving
-the code is thus to analyze which objects fall in category 1 and may thus
-not be allocated at all.
+the code is thus to analyze which objects fall in category 1 and thus do
+not have to be allocated at all.
 
 This is a process that is usually called \emph{escape analysis}. In this paper we will
 perform escape analysis by using partial evaluation. The partial evalution is a
-bit peculiar in that there are not actually any constant arguments to the trace,
-but it is only used to optimized operations within a trace.
+bit peculiar in that it receives no static input arguments for the trace,
+but it is only used to optimize operations within a trace.
 
-The partial evaluation works by walking the trace from beginning to end.
+The partial evaluation works by traversing the trace from beginning to end.
 Whenever a \lstinline{new} operation is seen, the operation is removed and a static
 object is constructed and associated with the variable that would have stored
 the result of \lstinline{new}. The static object describes the shape of the
@@ -583,8 +583,9 @@
 as well, because the shape description stores the type and thus the outcome of
 the type check the guard does is statically known.
 
-In the example from last section, the following operations would produce two
-static objects, and be completely removed from the optimized trace:
+In the example from last section, the following operations in the upper half
+of Fig.~\ref{fig:unopt-trace} would produce two
+static objects, and would thus be completely removed from the optimized trace:
 
 \begin{lstlisting}[mathescape,xleftmargin=20pt]
 $p_{5}$ = new(BoxedInteger)
@@ -599,7 +600,8 @@
 one associated with $p_{6}$ would know that it is a \lstinline{BoxedInteger}
 whose \lstinline{intval} field contains the constant -100.
 
-The following operations on $p_{5}$ and $p_{6}$ could then be
+The subsequent operations in Fig.~\ref{fig:unopt-trace},
+ which use $p_{5}$ and $p_{6}$, could then be
 optimized using that knowledge:
 
 \begin{lstlisting}[mathescape,xleftmargin=20pt]
@@ -612,8 +614,8 @@
 $i_{9}$ = int_add($i_{7}$, $i_{8}$)
 \end{lstlisting}
 
-The \lstinline{guard_class} operations can be removed, because the classes of $p_{5}$ and
-$p_{6}$ are known to be \lstinline{BoxedInteger}. The \lstinline{get} operations can be removed
+First, the \lstinline{guard_class} operations can be removed, because the classes of $p_{5}$ and
+$p_{6}$ are known to be \lstinline{BoxedInteger}. Second, the \lstinline{get} operations can be removed
 and $i_{7}$ and $i_{8}$ are just replaced by $i_{4}$ and -100. Thus the only
 remaining operation in the optimized trace would be:
 
@@ -621,24 +623,24 @@
 $i_{9}$ = int_add($i_{4}$, -100)
 \end{lstlisting}
 
-The rest of the trace is optimized similarly.
+The rest of the trace from Fig.~\ref{fig:unopt-trace} is optimized similarly.
 
-So far we have only described what happens when static objects are used in
-operations that read and write their fields and in guards. When the static
-object is used in any other operation, it cannot stay static. For example, when
-a static object is stored in a globally accessible place, the object needs to
-actually be allocated, as it might live longer than one iteration of the loop
+So far we have only described what happens when static objects are used in guards and in
+operations that read and write fields. When the static
+object is used in any other operation, it cannot remain static. For example, when
+a static object is stored in a globally accessible place, the object has to
+be allocated, as it might live longer than one iteration of the loop
 and because the partial evaluator looses track of it. This means that the static
 object needs to be turned into a dynamic one, \ie lifted. This makes it
-necessary to put operations into the residual code that actually allocate the
+necessary to put operations into the residual code that allocate the
 static object at runtime.
 
-This is what happens at the end of the trace in Figure~\ref{fig:unopt-trace}, when the \lstinline{jump} operation
+This is what happens at the end of the trace in Fig.~\ref{fig:unopt-trace}, when the \lstinline{jump} operation
 is hit. The arguments of the jump are at this point static objects. Before the
 jump is emitted, they are \emph{lifted}. This means that the optimizer produces code
 that allocates a new object of the right type and sets its fields to the field
 values that the static object has (if the static object points to other static
-objects, those need to be lifted as well, recursively) This means that instead of the jump,
+objects, those need to be lifted as well, recursively). This means that instead of a simple jump,
 the following operations are emitted:
 
 \begin{lstlisting}[mathescape,xleftmargin=20pt]
@@ -649,10 +651,11 @@
 jump($p_{15}$, $p_{10}$)
 \end{lstlisting}
 
-Note how the operations for creating these two instances have been moved down the
-trace. It looks like for these operations we actually didn't win much, because
-the objects are still allocated at the end. However, the optimization was still
-worthwhile even in this case, because some operations that have been performed
+Observe how the operations for creating these two instances have been moved to later point in the
+trace. 
+At first sight, it may look like for these operations we didn't gain much, as
+the objects are still allocated in the end. However, our optimizations were still
+worthwhile, because some operations that have been performed
 on the lifted static objects have been removed (some \lstinline{get} operations
 and \lstinline{guard_class} operations).
 



More information about the Pypy-commit mailing list