diff paper/chapter3.tex @ 17:3afb4bfe1100

fix
author Kaito Tokumori <e105711@ie.u-ryukyu.ac.jp>
date Mon, 15 Feb 2016 07:30:44 +0900
parents 7161b80a7e19
children
line wrap: on
line diff
--- a/paper/chapter3.tex	Sun Feb 14 20:07:43 2016 +0900
+++ b/paper/chapter3.tex	Mon Feb 15 07:30:44 2016 +0900
@@ -1,5 +1,5 @@
 \chapter{LLVM clang 上での CbC の実装}
-第 \ref{chapter:CbC}, \ref{chapter:LLVM/clang} 章をもとに LLVM, clang への CbC コンパイル機能の実装を行う. コードセグメントの解釈, 軽量継続などいくつかの機能は過去の研究によって実装されたが, 本研究での実装に繋がるので説明する.
+第 \ref{chapter:CbC}, \ref{chapter:LLVM/clang} 章をもとに LLVM, clang への CbC コンパイル機能の実装を行う. コードセグメントの解釈, 軽量継続などいくつかの機能は過去の研究によって実装されたが, 本研究での実装に繋がるのでここでも説明する.
 
 以降に示される LLVM, clang のファイルパスについて, \$(CLANG) を clang のソースコードを展開したディレクトリのパス, \$(LLVM) を LLVM のソースコードを展開したディレクトリのパスとする.
 \section{code segment}
@@ -331,8 +331,51 @@
 \end{lstlisting}
 
 \section{フレームポインタ操作最適化}
-フレームポインタ操作の最適化は omit leaf frame pointer を強制することで行う. この最適化は \ref{sec:olfp} 節でしたとおり leaf function に対して行われるが, 継続を続ける code segment は何もせずとも leaf function の条件を満たしているので内部で有効化するだけで良い.
+フレームポインタ操作の最適化は omit leaf frame pointer を強制することで行う. この最適化は関数呼び出しの際に行われるフレームポインタ操作に関わる最適化である. 通常関数呼び出しを行う際にはフレームポインタの値をスタックに積み, return 直前に戻すという作業を行う. omit leaf frame pointer はこの操作を leaf function を呼び出す際に行わないようにする最適化である.
+leaf function とはコールツリーの終端の位置する関数のことを指し, この関数が関数を呼び出さないことを意味する. 軽量継続を続ける code segment は何もせずとも leaf function の条件を満たしているので内部で有効化するだけで良い.
+
+以下のリスト \ref{loptno}, \ref{lopt} はどちらもリスト \ref{leaf} をコンパイルして得られるアセンブリコードから関数 caller の部分を抜き出したものであり, 前者が omit leaf frame pointer 無し, 後者が omit leaf frame pointer ありのコードである. push, pop 命令によるフレームポインタの操作がリスト \ref{lopt} ではなくなっていることがわかる.
 
+\begin{lstlisting}[frame=lrbt, label=leaf, caption={関数 caller}]
+void caller(int a, int b, int c){
+  B(a, b, c, 40);
+  return;
+}
+\end{lstlisting}
+\begin{lstlisting}[frame=lrbt, label=loptno, caption={関数 caller (omit leaf frame pointer 無し)}]
+_caller:                                ## @caller
+  .cfi_startproc
+## BB#0:
+  pushq  %rbp
+Ltmp0:
+  .cfi_def_cfa_offset 16
+Ltmp1:
+  .cfi_offset %rbp, -16
+  movq   %rsp, %rbp
+Ltmp2:
+  .cfi_def_cfa_register %rbp
+  movl   %edi, -4(%rbp)
+  movl   %esi, -8(%rbp)
+  movl   -4(%rbp), %esi
+  addl   -8(%rbp), %esi
+  movl   %esi, %eax
+  popq   %rbp
+  retq
+  .cfi_endproc
+\end{lstlisting}
+\begin{lstlisting}[frame=lrbt, label=lopt, caption={関数 caller (omit leaf frame pointer 有り)}]
+_caller:                                ## @caller
+  .cfi_startproc
+## BB#0:
+  movl   %edi, -4(%rbp)
+  movl   %esi, -8(%rbp)
+  movl   -4(%rbp), %esi
+  addl   -8(%rbp), %esi
+  movl   %esi, %eax
+  retq
+  .cfi_endproc
+\end{lstlisting}
+  
 omit leaf frame pointer は clang 内部では CodeGenOpts.OmitLeafFramePointer として表現されている. clang は CodeGen で LLVM IR の function を生成する際にこのフラグが立っているかどうかを確認し, 立っている場合には関数の no-frame-pointer-elim という attribute を false にする. それにより最適化が当該関数に作用するようになる. この, LLVM IR function への attribute 設定を行っているのは \$(CLANG)/lib/CodeGen/CGCall.cpp である. ここをリスト \ref{olfp} のように変更した. 通常は OmitLeafFramePointer のみを確認する部分を HasCodeSegment によって code segment の有無も確認するように変更している. これにより, code segment を含むコードのコンパイル, 即ち CbC のコードのコンパイルの際には自動的に omit leaf frame pointer が有効化されるようになった.
 
 \begin{lstlisting}[frame=lrbt,label=olfp,caption={omit leaf frame pointer 有効化}]