【お知らせ】プログラミング記事の投稿はQiitaに移行しました。

コンパイラを作ってみて

コンパイラ開発(id:n7shi:20090310)を通して物の見方がどう変わったかについて書いてみます。一般的な見解(と私が認識しているもの)、私の見解(過去・現在)などの視点が入り乱れるため、箇条書きを中心に記述します。何かを主張しようとしているわけではないので、特に結論のようなものはないことを、あらかじめ断っておきます。

【追記】私が作成したコンパイラSilverlight上で動作確認できます。 ⇒ id:n7shi:20090727

アセンブラ

アセンブラをいじることに対する一般的な見解(と私が認識しているもの)

  1. コンピュータの動作についてよりよく理解するため。
  2. カリカリにチューニングするため。

これらに対して以下のような意見があります。

  • CPU内部で更にマイクロコードに分解されるのだから、アセンブリだけ見ていてもパイプラインの動作などは分からないし、不十分

これはその通りなのですが、だからどうするかとなると、二極化するように思われます。

  1. 低レイヤはブラックボックスとして扱って、高級言語のノウハウに注力するべき。
  2. CPUごとの特性を調べて、最適なパフォーマンスが得られるようにするべき。
過去の自分の見解
現在の自分の見解
  • レイヤを厳密に切り分けないで、必要に応じて降りていける程度のノウハウはあった方が良い。
  • アセンブラが露出してしまうケースは依然として存在する。完全に隠蔽するのは無理ではないか。

アセンブラのノウハウ 1

ノウハウだけでは抽象的過ぎるので、もう少し詳しく説明します。

たとえば高級言語で開発していてどうしても期待通りの動きをしないときに、それがアルゴリズムというような大域的な問題ではなく、局所的な言語仕様の理解不足が原因だということがあります。言語仕様から探そうとしても具体例として演繹する必要があるため、かなり苦労します。

こういうときに該当箇所のアセンブリを出力するのも、解決の糸口を探る方法の一つとして使えます。もちろんそれで全部が解決するわけではありません。あくまで一つの方法です。これはある種のカンニングだと言えます。

ただし『ある程度のノウハウ』がないと、そもそも出力されたアセンブリを解読することができません。具体的には後述します。

インタプリタ言語ではそもそもアセンブリに出力できないため、この方法は使えません。インタプリタについては後述します。

過去の自分の見解
  • 高級言語では不可能なチューニングをするためのもの。
  • そこまでの高速動作を要求するような開発はしないので、自分には関係ない。
現在の自分の見解
  • 言語の実装をカンニングするためのもの。
  • 楽をするためのノウハウ。

インタプリタ

インタプリタ言語を調査しようとしてもアセンブリに落とせないため、インタプリタの実装を読むことになります。その際に以下の壁があります。

この関係に着目すれば、以下のように解釈できます。

関係として相似でも、アセンブリ排除という視点を入れると、見方が複雑になります。

【注】話を単純化するため、アセンブリで実装された昔のBASICのような言語や、JITでネイティブコードとして実行される言語は除外しています。JITは単純なインタプリタよりも更に読むのが難しいです。

過去の自分の見解
現在の自分の見解

アセンブラのノウハウ 2

コンパイラの出力するアセンブリを読むために必要な『ある程度のノウハウ』について書きます。これは現在の私の考え方です。コンパイラを書く前には考えたことがありませんでしたし、一般論(こうすればコンパイラの出力したアセンブリが読めます、等)としても見たことがありません。

まず、アセンブラの用途については以下のような見解が一般的だと思います。

それに対して、私がここで取り上げようとしているものは異なります。

  • 対象とするアセンブリの範囲は高級言語が出力するものに限定。
  • 特権命令は対象外。
  • 最適化は対象外。

まとめると以下のようになります。

  • OSを作るのにもチューニングするのにも役に立たない範囲のアセンブラのノウハウ。
  • フルアセンブラで手書きするのとも異なる。
    • 最適化を除外すると、コンパイラが出力するアセンブリは定型句の組み合わせで冗長。
    • ケースバイケースで柔軟に対処する手書きとは性質が異なる。

これが自分でコンパイラを作ったり、コンパイラの出力するアセンブリを読んだりするのに最低限必要なノウハウです。コンパイラを作って初めてこういうアセンブリとの接し方があるということに気付きましたが、実際に役に立っているかどうかは自分でもよく分かりません。