ふつパイラ、その後は?

台風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の人達が、何百台、ひょっとしたら何千台と、まとめ買いしてくれるでしょう。 ちょっとロードマップと言うか、営業戦略を考えてみました。参考にしてください。

  1. 2010/03 とーだい地下室にて、初号機3台完成
  2. 2010/04 らくてんで楽天的虫出し
  3. 2010/06 次ロット30台を島根方面とか関係者に配布
  4. 2010/07 某F社あたりに、ACIC化を打診
  5. 2010/08 次ロット300台ぐらいにて、RoRのクラスター実験
  6. 2010/09 ACIC化へGoサイン
  7. 2010/10 Ultra YALV 開発開始
  8. 2010/11 関係雑誌(下記注参照)のお年玉用に納品
  9. 2011/03 ヤマダ電気等へ、販売委託開始
  10. 2011/07 セブンイレブン等のコンビニでも販売開始

(注)、トラ技、インターフェース、日経XXX、SD等のソフトとハードを扱う雑誌

なお、チップだけでは困るので、USBメモリー内に内蔵。USB3.0が流通するようになれば バスバンド幅が、4Gになるし、32000台まで収容できますから、いろいろと面白い事が 出来そう。

たとえば、自動翻訳とか、画像合成とか。

金が余ってるばあさんが、外国へ行って素敵なボーイフレンドを見つけてきた。テレビ電話 したいんだけど、言語がねぇ。そんなの、ググとかの雲にまかせなよ となるかも知れんけど、 ググはいまいち信用ならん。そんな時は、Ultra YALVのチップ入りを、ごっそりと買って きて、そいつにやらせればOK。

あこがれのヨン様と、ドラマ競演したいと言うオバタリアンは、ヤマダから、YARVと素材が セットになったものを買ってくればOK。パソコンのUSB端子にほいほい差し込むだけで、 CGが出来ますです。

どうです、夢が広がりますなあ。

合わせて読みたい、、

上で出てきた coins は、UNIX Magazineの最終号を参考にした。一般書籍では コンパイラの基盤技術と実践―コンパイラ・インフラストラクチャCOINSを用いて があります。(ふつパイラでも、紹介してますね)

ああ、ユニマガ買いに行った時、ATOMの単行本がずらっと棚を占領してたな。映画との コラボが多いな。ATOMの単行本もいいんだけど、普通 ATOMと言ったらこっちでしょう。

初めての人のためのLISP 増補改訂版

この本の最後が

K: あーあ、うっとうしい。(と、言って、突然顔と頭に手をやり、メリッとカツラとゴムマスクに をひっぱがす。と、その下から現れたのは・・・)やっと、清清しちゃった。

他全員: あっ、あなたは!!

はて、増補改訂版で、Kの名前解決はなされるのだろうか? もし、Resolvされるなら、昭和61年 以来の、lazy bind になるな。こりゃ、凄いこった。太古の昔から、蘇るか? 興味津々。