ブロックが動いた
とりあえず、ブロックが動くようになりこんな感じのプログラムがコンパイル・実行できるようになりました。
def times j = 0 while j < self yield j j = j + 1 end 0 end def send_with_block(n) a = 0 n = n + 0 n.times do |i| a = a + i end a end
一見、簡単そうですがかなり面倒です。面倒すぎてどうやったのかすぐ忘れそうなので、ここに詳細を書く予定です。
追記 2008/11/04
ためしに最適化を掛けると動かなくなりました。今の方法だとallocaは呼び出した順番に連続して必ず確保されることを仮定しているので無理があるような気がします。ローカル変数のフレームを構造体でとって順番と存在を保証すればいいと思うのですが速度が落ちるかなって思います。
追記2 2008/11/04
最適化されたコードを見てみました。どうもloadとstoreをvolatile付のものにすればよさそうなのですがつけると速度が落ちそうです。とりあえずvolatile付にして追々データフロー解析をつけようかなって思います。
そもそも、llvmrubyってvolatile付って対応しているのだろうか?
追記3 2008/11/05
llvmrubyにvolatileをつけるオプションが無かったので、強引に作ってvolatileをつけてみました。最適化を掛けるとやっぱり動かなかったです。ローカル変数のフレームを構造体で明示的に指定する必要がありそうです。
volatileをつけるとfibで最適化の効果がなくなりました。やっぱり、volatileをつける場所を限定していかないといけないなと思います。
追記4 2008/11/05
結局、最初の追記の方針どおりローカル変数のフレームを構造体で取るようにしたら最適化を掛けてもOKになりました。ためしにvolatileをつけないようにしてもOKでした。そのため、普通のllvmrubyでも動くようにとりあえずvolatileは無しにします。