Camil Demetrescu  over 8 years ago

Commit id: 1afbf65a67b1e6883e1e7e1b68581443db7f4f81

deletions | additions      

       

\subsection{A New Approach}  \label{ss:eval-opt-mcvm}  In this section, we present a new approach that combines the flexibility of OSR-based specialization with the efficiency of the JIT-based method, answering an open question raised by Lameed and Hendren~\cite{lameed2013feval}. The key idea is to lift the $f$-to-$f'$ optimization performed by the OSR-based specialization from IR to IIR level. This makes it possible to perform type inference in $f'$, generating a much more efficient code. The main technical challenge of this approach idea  is that the state in $f$ at the OSR point may be incompatible with the state of $f'$ from which execution continues. Indeed, values some variables may be boxed in $f$ and unboxed  in [...] $f'$. Hence, compensation code is needed to adjust the state by performing live variable unboxing during the OSR.  %The main idea for optimizing a function $f$ containing an \feval\ instruction is to dynamically generate a variant $f'$ where the \feval$(g,...)$ is replaced by a direct call of the form $g(...)$. The key to efficiency is the ability to perform type inference on the IIR level, [...]  %capture run-time information  \paragraph{Implementation in McVM.}  We implemented our approach in McVM~\footnote{As McVM\footnote{As  a by-product of our project, we ported the MATLAB McVM virtual machine from the LLVM legacy JIT to the new MCJIT toolkit.}, extending it with four main components: \begin{enumerate}  \item An analysis pass to identify optimization opportunities for \feval\ instructions in the IIR of a function.  \item An extension for the IIR compiler to track the correspondence mapping  between IIR and IR objects at \feval\ sites. \item An OSR  inserter component based on \osrkit\  to insert inject  open OSR points in the IR for IIR locations annotated during the analysis pass. \item An \feval\  optimizer triggered at OSR points, which uses: \begin{enumerate}  \item A a  profile-driven IIR generator to replace \feval\ calls with direct calls calls;  \item A a  helper component to lower the optimized IIR function to IR and construct a state mapping mapping;  \item A a  code caching mechanism to handle the compilation of the continuation functions functions.  \end{enumerate}  \end{enumerate}  \noindent We remark that our implementation heavily depends on \osrkit's ability to handle compensation code.   \paragraph{Analysis Pass.}  We integrated our analysis pass in McVM's analysis manager. In particular, we group \feval\ instructions whose first argument is reached by the same definition, and for each group we mark for instrumentation only those instructions not dominated by others, so that the function can be optimized as early as possible at run-time.   \ifdefined \fullver  The analysis pass is also able to determine whether the value of the argument can change across two executions of the same \feval\ instruction, thus discriminating when a run-time guard must be inserted during the run-time optimization phase. 

The analysis pass also determines whether the value of the argument can change across two executions of the same \feval, and a run-time guard must thus be inserted during the optimization phase.  \fi  \paragraph{IIR Compiler Extension.}  When the IIR compiler processes an annotated \feval\ instruction, it keeps track of the current {\em variable map} between IIR and IR objects, the {\tt llvm::BasicBlock*} created for the \feval, and the {\tt llvm::Value*} object used as its first argument. \paragraph{OSR Inserter.}  The last two elements are then used by the inserter component as basic block and {\tt val} argument in the open-OSR stub that invokes the optimizer component. \newcommand{\gBase}{$g$}  \newcommand{\gOpt}{$g_{opt}$}  \newcommand{\gIIR}{$g^{IIR}$}  \newcommand{\gIR}{$g^{IR}$}  \newcommand{\gOptIIR}{$g^{IIR}_{opt}$}  \newcommand{\gOptIR}{$g^{IR}_{opt}$} \newcommand{\gBase}{$f$}  \newcommand{\gOpt}{$f_{opt}$}  \newcommand{\gIIR}{$f^{IIR}$}  \newcommand{\gIR}{$f^{IR}$}  \newcommand{\gOptIIR}{$f^{IIR}_{opt}$}  \newcommand{\gOptIR}{$f^{IR}_{opt}$}  %%%%%%%%%%%%%%%%%%%%%%%%%%%%%  \paragraph{Generating Optimized Code.}  %\label{sse:optimizing_feval} \paragraph{Optimizer.}  The core of our optimization pipeline is the optimizer module, which is responsible for generating optimized code for the running function \gBase\ using contextual information passed by an open-OSR stub. As a first step, the optimizer inspects {\tt val} to resolve the target $f$ of the \feval\ and checks whether a previously compiled version of \gBase\ optimized for $f$ is available from the cache.  \ifdefined \fullver  If not, a new function \gOpt\ is generated by cloning the IIR representation \gIIR\ of \gBase\ into \gOptIIR\ and replacing all the \feval\ calls in the same group of the instrumented one with direct calls to $f$.