Mercurial > hg > Papers > 2016 > kaito-master
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 有効化}]