ふつパイラ、その後は?
台風18号が駆け足でやってきて、行ってしまった。去年ぐらいから、台風に愛称?を 付けるんじゃなかったっけ? 愛称が出てこないってのは、昔、誰かさんが流行らせようとして失速してしまった「E電」と 一緒ですかい。嫌われ者は、2009-18 ぐらいの無味乾燥なの方がいいと思うぞ。
で、その2009-18 による被害だが、ちと稲が倒れていました。一杯、チャリやらバイクが倒れて いました。おまわりさんが、被害状況確認で、倒れた台数を数えていました。
私が見た範囲で、一番の被害は、ラーメン屋の看板を支える鉄の支柱数本が、グニャと 曲がって、駐車場側に倒れていた事です。既に、業者さんが来て、どうやって修復しようか 検討中でした。支柱の根元はアスファルトで舗装されてるから、大変だろうなー。
修復支援のために、久しぶりにラーメンでも食べに行きますか。この地より被害の大きかった 地域や亡くなった方がおられるようで、お見舞い申し上げます。
cbcをもうちょっと
前回、「 次は、cbcの何処かを改造して、sedでも挟んでやるか。まてまて、var名とぶつかったら どうする? うかつに出来ないよ。あれ? stdout って、予約語? 疑問が一杯。」と、あらぬ 事を口ばしってしまった。今は反省している。
stdin,stdout,stderrの3つ組は、POSIXだかANSI で、要求してるんじゃなかったっけ? 教えて えらい人。
var名とかと、ぶつかるかもと言うのは、やってみた方が早そう。
[sakae@fb ~/cbc-1.0/test]$ cat ansi.cb import stdio; int main(void) { int stdin = 3; return stderr(stdin, 10); } int stderr(int stdin, int stdout) { return stdin + stdout; } [sakae@fb ~/cbc-1.0/test]$ ../bin/cbc ansi.cb [sakae@fb ~/cbc-1.0/test]$
無事に、コンパイル出来たよ。で、アセンブリ出力はどうなったかと言うと、
.file "ansi.cb" .text .globl main .type main,@function main: pushl %ebp movl %esp, %ebp subl $8, %esp movl $3, %eax movl %eax, -4(%ebp) movl $10, %eax pushl %eax movl -4(%ebp), %eax pushl %eax call stderr addl $8, %esp movl %eax, -8(%ebp) movl -8(%ebp), %eax jmp .L0 .L0: movl %ebp, %esp popl %ebp ret .size main,.-main .globl stderr .type stderr,@function stderr: pushl %ebp movl %esp, %ebp movl 8(%ebp), %eax movl 12(%ebp), %ecx addl %ecx, %eax jmp .L1 .L1: movl %ebp, %esp popl %ebp ret .size stderr,.-stderr
残っているのは、関数名にした、stderrだけか。そもそも、前回のエラーは、アセンブリ段階で 名前解決出来なくて、リンクフェーズまで解決を持ち越された為、基盤の部分とマッチング しないと言う事だった。そして、解決時のヒントが、stdio.hb に書いてあるんだった。*.hbと 言う名前に惑わされていたけど、これらのファイルが、cbcと外界をつなぐパイプだった訳だ。
それで次は、どうやってFreeBSD界に居ついてもらうかだが、ちとソースを眺めてみないと 改造箇所が分からないな。楽に閲覧出来るようにしちゃえ。
[sakae@fb ~/cbc-1.0/test]$ cd ../net/loveruby/cflat/ [sakae@fb ~/cbc-1.0/net/loveruby/cflat]$ ls asm/ compiler/ exception/ parser/ type/ ast/ entity/ ir/ sysdep/ utils/ [sakae@fb ~/cbc-1.0/net/loveruby/cflat]$ gtags [sakae@fb ~/cbc-1.0/net/loveruby/cflat]$ htags -sanohITvt 'Welcome to CBC tour' [sakae@fb ~/cbc-1.0/net/loveruby/cflat]$ w3m HTML/index.html
さあ、ツアー開始。compiler/Compiler.java にある、mainあたりから、潜って行けば いいですね。 buildの中にある、assemble関数の中にでも、sedを忍ばせればいいかと思ったら、こやつは gasを呼び出しているだけだった。(ああ、今まで sed さんへ外注しようと考えていたけど、java内 できっと出来るはずだよね。正規表現のクラスがあるだろうから。)よって、もうちょっと手前だな。そう、compile関数の中が よさそう。駆け足ツアーみたいで、generateAssemblyかと思ったら、違ったみたいで、まだ まだ引き回されています。歳のせいか、足腰が弱って、Javaにはなかなか着いていけませんです。
そんな訳なんで、HTMLの下を晒して、若い者にでも調べてきてもらおうと思ったら、
[sakae@fb ~/cbc-1.0/net/loveruby/cflat]$ du -sh HTML 7.9M HTML
もあって、晒すにはちとつらいです。10000行ぐらいのソースなんですが、ツアー用に仕立てると 肥大しますなぁ。
そんな訳で、ちと趣を変える事にします。
ふつパイラを読んだ後に、やるのは ==> LLVM
前回ちょっと出てきた、LLVM clang です。今まで cコンパイラーと 言えば、gccが当たり前でしたが、ライセンスの関係とかで、使うのやだと言い出す人達がいて 精力的に開発されているようです。やだやだの筆頭応援団は、apple。
で、コンパイラーの世界もバーチャルマシンです。ローレベルな機械(LLVM)を定義して、それ用に コンパイラーを作ろうって事。Javaでは、JVMと言う仮想機械を定義しておいて、それ用の コンパイラーが、javac 。JVMは、いろいろなリアルCPU(x86,aparc,...)で動くようにして おけば、どこでもJavaアプリが動く。この要領ですね。
筆頭応援団は、MacRubyもLLVM採用、とまらないLLVM人気 と言う事を始めたようです。
FreeBSDでも
llvm-gcc is the LLVM C front end. It is a modified version of gcc that compiles C/C++/ObjC programs into native objects, LLVM bitcode or LLVM assembly language, depending upon the options. By default, llvm-gcc compiles to native objects just like GCC does. If the -emit-llvm option is given then it will generate LLVM bitcode files instead. If -S (assembly) is also given, then it will generate LLVM assembly. Being derived from the GNU Compiler Collection, llvm-gcc has many of gcc's features and accepts most of gcc's options. It handles a number of gcc's extensions to the C programming language.
こんな具合に、準備が始まっています。(ports/lang/llvm-gcc4)
昔どこかで読んだ資料では、rmsはGNUの看板であるgccを、なるべく解析されないように わざと難しく作ったとか。 嘘か真か分かりませんが、hackしようにも、とてつもなく 暗黒な世界だそうです。
そういうのに嫌気を差した人達が、始めたんでしょうか? そう言えば、日の丸コンパイラ も、健闘してますね。
次にやるのは、coins だ。
coinsは、Javaで書かれた、コンパイラです。 簡単に言ってしまうと、cbcの兄貴分にあたります。コンパイラを作る上での設備(部品)が いろいろ用意されているので、これを叩き台にして、自分用に発展させてくださいって事です。
coinsの利用例を見ると
舞田純一, 佐藤聡, 中井央: Ruby と拡張可能構文解析器生成系による COINS を用いたコンパイラの自動生成, FIT2006 第 5 回情報科学技術フォーラム講演論文集(1), pp. 35-36 (2006).
こういう例もあるようですから、見てみたいですな。
使い方は簡単です。頂いてきた coins-1.4.4.3-ja.jar (ja版は、解説書同梱済み)を unzip するだけです。ああ、cygin上かlinux上で試します。 コマンド行が長いので、簡単なスクリプト(jcc)を書いておきました。(ちょっと、インチキっぽいですが)
#!/bin/sh if [ -n "$3" ]; then opt="$1 $2" src=$3 elif [ -z "$3" ]; then opt=$1 src=$2 else opt='-O2' src=$1 fi java -cp coins-1.4.4.3-ja/classes coins.driver.Driver $opt \ -coins:target=x86,assembler=as $src
配置は、こんな具合で、実験台にする fact.c もちょっと見てみます。
sakae@debian:~/tmp$ ls META-INF/ coins-1.4.4.3-ja/ fact.c jcc* sakae@debian:~/tmp$ cat fact.c #include <stdio.h> long fact(long n){ if (n == 0){ return 1; } else { return n * fact(n - 1); } } main(){ printf("%ld\n", fact(10L)); }
それでは、早速コンパイラの試運転
sakae@debian:~/tmp$ ./jcc fact.c sakae@debian:~/tmp$ ./a.out 3628800 sakae@debian:~/tmp$ ./jcc -S fact.c sakae@debian:~/tmp$ lv fact.s .ident "Coins Compiler version: coins-1.4.4.3 + BackEnd-1.0" /* JavaCG for target:x86 convention:standard */ .section .text .align 4 .global fact fact: pushl %ebp movl %esp,%ebp pushl %ebx movl 8(%ebp),%ebx cmpl $0,%ebx jne .L5 .L4: movl $1,%ebx jmp .L6 .L5: leal -1(%ebx),%eax pushl %eax call fact leal 4(%esp),%esp imull %eax,%ebx .L6: movl %ebx,%eax popl %ebx leave ret .align 1 string.6: .byte 37 .byte 108 .byte 100 .byte 10 .byte 0 .align 4 .global main main: pushl %ebp movl %esp,%ebp pushl $10 call fact leal 4(%esp),%esp pushl %eax pushl $string.6 call printf leal 8(%esp),%esp .L9: leave ret
それでは、最適化してみます。
sakae@debian:~/tmp$ ./jcc -S -O3 fact.c sakae@debian:~/tmp$ cat fact.s : main: pushl %ebp movl %esp,%ebp pushl $10 call fact leal 4(%esp),%esp pushl %eax pushl $string.8 call printf leal 8(%esp),%esp .L14: leave ret
(g)ccを使って、最適化すると、凄い事になっちゃいます。
sakae@debian:~/tmp$ cc -S -O3 fact.c sakae@debian:~/tmp$ cat fact.s .file "fact.c" .text .p2align 4,,15 .globl fact .type fact, @function fact: pushl %ebp movl $1, %eax movl %esp, %ebp movl 8(%ebp), %edx testl %edx, %edx je .L3 .p2align 4,,7 .p2align 3 .L4: imull %edx, %eax subl $1, %edx jne .L4 .L3: popl %ebp ret .size fact, .-fact .section .rodata.str1.1,"aMS",@progbits,1 .LC0: .string "%ld\n" .text .p2align 4,,15 .globl main .type main, @function main: leal 4(%esp), %ecx andl $-16, %esp pushl -4(%ecx) pushl %ebp movl %esp, %ebp pushl %ecx subl $20, %esp movl $3628800, 4(%esp) movl $.LC0, (%esp) call printf addl $20, %esp popl %ecx popl %ebp leal -4(%ecx), %esp ret .size main, .-main .ident "GCC: (Debian 4.3.2-1.1) 4.3.2" .section .note.GNU-stack,"",@progbits
答えがmainに即値で書き込んであるよ。factの末尾再帰が除去がされてるよ。老獪だな。後発組 頑張ってください。
それでは、折角なので、coinsを作ってみる。
sakae@debian:~/tmp/coins-1.4.4.3-ja$ sh build.sh cd tools && make all make[1]: ディレクトリ `/home/sakae/tmp/coins-1.4.4.3-ja/src/coins/backend/tools' に入ります make[1]: `all' に対して行うべき事はありません. make[1]: ディレクトリ `/home/sakae/tmp/coins-1.4.4.3-ja/src/coins/backend/tools' から出ます cd gen && make all make[1]: ディレクトリ `/home/sakae/tmp/coins-1.4.4.3-ja/src/coins/backend/gen' に入ります java -classpath ../../../../classes coins.backend.tools.Tmd2Java \ -p ../tools/tmd.java.proto x86sse2.tmd make[1]: ディレクトリ `/home/sakae/tmp/coins-1.4.4.3-ja/src/coins/backend/gen' から出ます if [ -d tmd ] && cd tmd ; then make all; make -f Makeparam; fi Buildfile: build.xml compile: [depend] Deleted 5 out of date files in 16 seconds [javac] Compiling 1 source file to /home/sakae/tmp/coins-1.4.4.3-ja/classes [javac] Compiling 1 source file to /home/sakae/tmp/coins-1.4.4.3-ja/classes [javac] 注:/home/sakae/tmp/coins-1.4.4.3-ja/src/coins/backend/gen/CodeGenerator_x86sse2.java の操作は、未チェックまたは安全ではありません。 [javac] 注:詳細については、-Xlint:unchecked オプションを指定して再コンパイルしてください。 copy: buildall: BUILD SUCCESSFUL Total time: 1 minute 8 seconds
x86sse2用(i686)のさわり部分が出来たっぽい。他にどんなマシンに対応してるかと言うと
sakae@debian:~/tmp/coins-1.4.4.3-ja/src/coins/backend/gen$ ls -l *tmd -rw-r--r-- 1 sakae sakae 39503 2008-05-10 16:09 alpha.tmd -rw-r--r-- 1 sakae sakae 58174 2008-09-19 04:05 arm.tmd -rw-r--r-- 1 sakae sakae 1061 2008-05-10 16:09 common.tmd -rw-r--r-- 1 sakae sakae 37310 2008-05-10 16:09 mb.tmd -rw-r--r-- 1 sakae sakae 67315 2008-07-13 19:38 mips.tmd -rw-r--r-- 1 sakae sakae 143555 2008-05-10 16:09 ppc.tmd -rw-r--r-- 1 sakae sakae 2405 2008-05-10 16:09 sample.tmd -rw-r--r-- 1 sakae sakae 111227 2008-05-10 16:09 sh4.tmd -rw-r--r-- 1 sakae sakae 53604 2008-12-11 10:14 sparc.tmd -rw-r--r-- 1 sakae sakae 48004 2008-05-10 16:09 thumb.tmd -rw-r--r-- 1 sakae sakae 64752 2008-05-10 16:09 x86.tmd -rw-r--r-- 1 sakae sakae 87340 2008-06-20 14:44 x86_64.tmd -rw-r--r-- 1 sakae sakae 71174 2009-05-15 15:30 x86sse2.tmd
sh4ってのが、日本的だなあ。それにしても、Javaは得意じゃありませんですよ。 折角のソースを目の前にして残念ですが、これ以上の深入りはやめる事にします。
とーだいのCPU実験
東大名物 CPU実験が始まったようです。C# やるんですか。 JAVAと親戚ですかね。それとも、縁を切っちゃったんでしょうか?
どうせやるなら、C#なんて止めて、YARVの実マシンを焼きつけませんか。世の中、かそーかそー じゃ、ツマラナイじゃないですか。とーだい製のリアルマシンを是非作ってくださいな。
何なら、だいびるから、あの人を拉致して、本郷の地下室へ半年程監禁してもかまいませんよ。 Lispの神様に許可を頂いておきますから。神様も昔は、TAOで道楽(もとえ、開発)されたはずですから、きっと 日本の将来のため、ご許可くださるでしょう。
後は、島根方面から、アプリを載せる名目であの人を召還し、名PMとして、あの人も。 あわよく完成したら、筐体にみんなのサインを入れて、東大製Rubyマシンとして売り出せば いいです。大学も自分で稼げと言うご時世ですから、是非どうぞ。
きっと、世界のRubyファンが、一人1台は買ってくれるでしょう。ああ、そうそう、1台だけ 買って満足するように作っちゃだめですよ。何台でも買って合体したら、台数分だけ パワーアップするようにしてください。きっと、パワーが欲しくて欲しくてしょうがない Ruby on Railsの人達が、何百台、ひょっとしたら何千台と、まとめ買いしてくれるでしょう。 ちょっとロードマップと言うか、営業戦略を考えてみました。参考にしてください。
- 2010/03 とーだい地下室にて、初号機3台完成
- 2010/04 らくてんで楽天的虫出し
- 2010/06 次ロット30台を島根方面とか関係者に配布
- 2010/07 某F社あたりに、ACIC化を打診
- 2010/08 次ロット300台ぐらいにて、RoRのクラスター実験
- 2010/09 ACIC化へGoサイン
- 2010/10 Ultra YALV 開発開始
- 2010/11 関係雑誌(下記注参照)のお年玉用に納品
- 2011/03 ヤマダ電気等へ、販売委託開始
- 2011/07 セブンイレブン等のコンビニでも販売開始
(注)、トラ技、インターフェース、日経XXX、SD等のソフトとハードを扱う雑誌
なお、チップだけでは困るので、USBメモリー内に内蔵。USB3.0が流通するようになれば バスバンド幅が、4Gになるし、32000台まで収容できますから、いろいろと面白い事が 出来そう。
たとえば、自動翻訳とか、画像合成とか。
金が余ってるばあさんが、外国へ行って素敵なボーイフレンドを見つけてきた。テレビ電話 したいんだけど、言語がねぇ。そんなの、ググとかの雲にまかせなよ となるかも知れんけど、 ググはいまいち信用ならん。そんな時は、Ultra YALVのチップ入りを、ごっそりと買って きて、そいつにやらせればOK。
あこがれのヨン様と、ドラマ競演したいと言うオバタリアンは、ヤマダから、YARVと素材が セットになったものを買ってくればOK。パソコンのUSB端子にほいほい差し込むだけで、 CGが出来ますです。
どうです、夢が広がりますなあ。
合わせて読みたい、、
上で出てきた coins は、UNIX Magazineの最終号を参考にした。一般書籍では コンパイラの基盤技術と実践―コンパイラ・インフラストラクチャCOINSを用いて があります。(ふつパイラでも、紹介してますね)
ああ、ユニマガ買いに行った時、ATOMの単行本がずらっと棚を占領してたな。映画との コラボが多いな。ATOMの単行本もいいんだけど、普通 ATOMと言ったらこっちでしょう。
この本の最後が
K: あーあ、うっとうしい。(と、言って、突然顔と頭に手をやり、メリッとカツラとゴムマスクに をひっぱがす。と、その下から現れたのは・・・)やっと、清清しちゃった。
他全員: あっ、あなたは!!
はて、増補改訂版で、Kの名前解決はなされるのだろうか? もし、Resolvされるなら、昭和61年 以来の、lazy bind になるな。こりゃ、凄いこった。太古の昔から、蘇るか? 興味津々。