# HG changeset patch # User Takahiro SHIMIZU # Date 1526379742 -32400 # Node ID 8c7be076e6e6f40614a28a8e77d3f3ad02706edb # Parent fc5259b6167ec3a9a8cb215f77b447d982c2ee24 auto-Update generated slides by script diff -r fc5259b6167e -r 8c7be076e6e6 lib/template.md --- a/lib/template.md Mon May 14 15:36:32 2018 +0900 +++ b/lib/template.md Tue May 15 19:22:22 2018 +0900 @@ -1,4 +1,4 @@ -title: 近況報告 +title: CbCによるMoarVMの改良 author: Takahiro Shimizu profile: lang: Japanese diff -r fc5259b6167e -r 8c7be076e6e6 slides/2018/05/14/memo.txt --- a/slides/2018/05/14/memo.txt Mon May 14 15:36:32 2018 +0900 +++ b/slides/2018/05/14/memo.txt Tue May 15 19:22:22 2018 +0900 @@ -1,3 +1,40 @@ 今日の進捗 +# MoarVMのJIT +* [Docs](https://github.com/MoarVM/MoarVM/tree/master/docs)を見る +# Lego +* MoarMVのJITはLegoと呼ばれているらしい + +# DynASM +* Dynamic Assemler + * http://luajit.org/dynasm.html +* [luajit](http://luajit.org/)プロジェクトで作られているもの +* MoarVMには `3rdparty`ディレクトリ以下に展開されている +* x86アーキテクチャのJITコンパイル用のアセンブラのようなものらしい + * luaが`dasc`と呼ばれるCに近いアセンブラをCを出力する前に実行 + * Cのヘッダーの `#include` している部分を機械語にランタイムで翻訳 +* [GitHubのcommit](https://github.com/MoarVM/MoarVM/commit/372d0582ab90d4ddfc43553bbebe4e553a42278d) + +# DynASM + + +- To get you started, here is a simple code snippet to be pre-processed. The lines starting with '|' (the pipe symbol) are for DynASM: + +``` + if (ptr != NULL) { + | mov eax, foo+17 + | mov edx, [eax+esi*2+0x20] + | add ebx, [ecx+bar(ptr, 9)] + } +``` + +- After pre-processing you get: + +``` + if (ptr != NULL) { + dasm_put(Dst, 123, foo+17, bar(ptr, 9)); + } +``` + + diff -r fc5259b6167e -r 8c7be076e6e6 slides/2018/05/14/zip.txt --- /dev/null Thu Jan 01 00:00:00 1970 +0000 +++ b/slides/2018/05/14/zip.txt Tue May 15 19:22:22 2018 +0900 @@ -0,0 +1,50 @@ +2018-05-08---- +今日の進捗 + +- MoarVMの資料を読み解く +- CbCで実装するべき場所を考察する + +---------- +2018-05-14---- +今日の進捗 + +# MoarVMのJIT +* [Docs](https://github.com/MoarVM/MoarVM/tree/master/docs)を見る + +# Lego +* MoarMVのJITはLegoと呼ばれているらしい + +# DynASM +* Dynamic Assemler + * http://luajit.org/dynasm.html +* [luajit](http://luajit.org/)プロジェクトで作られているもの +* MoarVMには `3rdparty`ディレクトリ以下に展開されている +* x86アーキテクチャのJITコンパイル用のアセンブラのようなものらしい + * luaが`dasc`と呼ばれるCに近いアセンブラをCを出力する前に実行 + * Cのヘッダーの `#include` している部分を機械語にランタイムで翻訳 +* [GitHubのcommit](https://github.com/MoarVM/MoarVM/commit/372d0582ab90d4ddfc43553bbebe4e553a42278d) + +# DynASM + + +- To get you started, here is a simple code snippet to be pre-processed. The lines starting with '|' (the pipe symbol) are for DynASM: + +``` + if (ptr != NULL) { + | mov eax, foo+17 + | mov edx, [eax+esi*2+0x20] + | add ebx, [ecx+bar(ptr, 9)] + } +``` + +- After pre-processing you get: + +``` + if (ptr != NULL) { + dasm_put(Dst, 123, foo+17, bar(ptr, 9)); + } +``` + + + +---------- diff -r fc5259b6167e -r 8c7be076e6e6 slides/2018/05/15/memo.txt --- /dev/null Thu Jan 01 00:00:00 1970 +0000 +++ b/slides/2018/05/15/memo.txt Tue May 15 19:22:22 2018 +0900 @@ -0,0 +1,33 @@ +# ゼミ + +- 論文自体は昔のもの +- MoarVMどこが遅いのか? JITがアレ? +- 直接バイナリを吐かない理由は? + +- Comon Lisp Cに変換して生成したオブジェクトを作る + - その他の最適化はCコンパイラに投げる + - 京都で開発された 京都CommonLisp + - Lisp中でread evalループを持っていた + - interpretするルーチンがLISPで書かれている + - -->普段はCコンパイラが呼ばれない + - stack をlistの管理で行う + +- JITが遅いならCbCの入る場所がなさそう + +- 直接アセンブラを書いても良さそう + - MoarVMからCbCを吐く + +- 帯域脱出が問題 + - スタックの管理ならCbCでいけるかもしれない + - MoarVMの + +- 行き先を渡す +- 厳しいなら構造体にいれてあげる + - diコンテナ + - 見かけ上関数呼び出しっぽく書ける + +- Cの再実装 + - 比較して見る + - 頻度の高いif文を先に持っていって再構築 + +- CbC側を書き換えるのをどうするか diff -r fc5259b6167e -r 8c7be076e6e6 slides/2018/05/15/slide.md --- /dev/null Thu Jan 01 00:00:00 1970 +0000 +++ b/slides/2018/05/15/slide.md Tue May 15 19:22:22 2018 +0900 @@ -0,0 +1,150 @@ +title: CbCによるMoarVMの改良 +author: Takahiro Shimizu +profile: +lang: Japanese + + +# 研究目的 +- Perl5の後継言語として開発されているPerl6はMoarVMと呼ばれるVMを搭載している. +- Perl6はMoarVM,JVM,JavaScript上で動くRakudoと呼ばれる実装と,コンパイラ開発者用のサブセットであるNQPが主な実装となっている. +- 現在Perl6及びMoarVMは全体的な速度がPerl5と比較し低下しており,実務として利用できるレベルに達していない. +- さらにPerl6の実装自体巨大なcase-switch文など見通しが悪くなっている. +- この問題を解決するために現在当研究室で開発している継続を中心にしたContinuation based Cを用いて改良を行う +- CbCの設計理念からVMの実装と親和性が高い事も推測できる為,実際にCbCを用いてどのようにVMが実装できるかを検証する + +# 今週の進捗 + +- MoarVMのJITのドキュメントを読み始めました + +# MoarVMのJIT +* [Docs](https://github.com/MoarVM/MoarVM/tree/master/docs)を見る +* JitCompiler overview +* Expression 'Tree' Intermedite Representation +* Runtime Configuration +* JIT Todo + + +# Lego +* MoarMVのJITはLegoと呼ばれているらしい + +# DynASM +* Dynamic Assemler + * http://luajit.org/dynasm.html + * [luajit](http://luajit.org/)プロジェクトで作られているもの + * MoarVMには `3rdparty`ディレクトリ以下に展開されている + * x86アーキテクチャのJITコンパイル用のアセンブラのようなものらしい + * luaが`dasc`と呼ばれるCに近いアセンブラをCを出力する前に実行 + * Cのヘッダーの `#include` している部分を機械語にランタイムで翻訳 + * [GitHubのcommit](https://github.com/MoarVM/MoarVM/commit/372d0582ab90d4ddfc43553bbebe4e553a42278d) + + +# DynASM + + + - To get you started, here is a simple code snippet to be pre-processed. The lines starting with '|' (the pipe symbol) are for DynASM: + + ``` + if (ptr != NULL) { + | mov eax, foo+17 + | mov edx, [eax+esi*2+0x20] + | add ebx, [ecx+bar(ptr, 9)] + } +``` + +- After pre-processing you get: + +``` + if (ptr != NULL) { + dasm_put(Dst, 123, foo+17, bar(ptr, 9)); + } +``` + +# Expression Tree + +- まだ翻訳出来てない... + +## syntax +- `(` と`)`で括っていくLISPスタイル +- wordはPerlの正規表現 `[^\s\(\)#:"']`で表現されるもの +- keywordは `:` が途中につく +- 先頭に`$`が来るとリファレンスであり,MoarVMのオペランドもしくは宣言済みの変数 +- `^`が先頭に来るとマクロであり,`macro:`で宣言可能 +- 先頭に`&`だと関数のマクロ + +``` +(template: sp_p6oget_o + (let: (($val (load (add (^p6obody $1) $2) ptr_sz))) + (if (nz $val) $val (^vmnull)))) +``` + +# Instruction Selection + +* シーケンスを実際にx86に変換する部分 +* [Aho etal](https://dl.acm.org/citation.cfm?id=75700)の論文が基本となっているらしい + + +# 書き換え + +- `spesh/facts.c`を書き換えていこうかなとしています +- case文で分岐した後の返り値をstackにどうやって積むかが問題 +- 遷移を担当するテーブルの設計 + +# 書き換え地点 + +``` + case MVM_OP_const_i64_32: + case MVM_OP_const_i64_16: + case MVM_OP_const_s: + literal_facts(tc, g, ins); + //XXX 書き換え + goto literal_facts_cbc(tc,g,ins,__return); + goto literal_facts(tc, g, ins); + break; +``` + +# target + +``` +__code literal_facts_cbc(MVMThreadContext *tc, MVMSpeshGraph *g, MVMSpeshIns *ins,__code(*exit)()) { + MVMSpeshFacts *tgt_facts = &g->facts[ins->operands[0].reg.orig][ins->operands[0].reg.i]; + switch (ins->info->opcode) { + case MVM_OP_const_i64: + tgt_facts->value.i = ins->operands[1].lit_i64; + break; + case MVM_OP_const_i32: + tgt_facts->value.i = ins->operands[1].lit_i32; + break; + case MVM_OP_const_i16: + tgt_facts->value.i = ins->operands[1].lit_i16; + break; + case MVM_OP_const_i8: + tgt_facts->value.i = ins->operands[1].lit_i8; + break; + case MVM_OP_const_n32: + tgt_facts->value.n = ins->operands[1].lit_n32; + break; + case MVM_OP_const_n64: + tgt_facts->value.n = ins->operands[1].lit_n64; + break; + case MVM_OP_const_i64_32: + tgt_facts->value.i = ins->operands[1].lit_i32; + break; + case MVM_OP_const_i64_16: + tgt_facts->value.i = ins->operands[1].lit_i16; + break; + case MVM_OP_const_s: + tgt_facts->value.s = MVM_cu_string(tc, g->sf->body.cu, + ins->operands[1].lit_str_idx); + break; + default: + return; + } + tgt_facts->flags |= MVM_SPESH_FACT_KNOWN_VALUE; + goto (*exit1)(); +} +``` + +# 来週の予定 + +* JITもう少し読む +* JITから書き換える?