商業誌でLLVM本を出します(店頭POPも書きました)

既にもちさんが紹介記事を書いてる通り、「きつねさんでもわかるLLVM」が商業誌で販売されます。
お話を頂いた時は驚いたと同時にこの体裁(主に表紙)や内容で大丈夫なんだろうかと不安にもなりました。
結果としてはオリジナルの(同人誌らしい)部分をそのままに、より良い内容になったと思います。
電子書籍と商業誌版の違いについてはもちさんの記事やサークル公式ページでもまとめてあるのでここでは割愛します。
ちなみに上の画像はジュンク堂書店池袋本店さんで宣伝に使って頂く店頭POPになります。
矢上先生の手書きの絵(レアらしい)が見られるのはジュンク堂だけ!!

本を書くと言うことについて

右も左もわからない状態でコミケに出したところからここまで来たわけですが、
よく周りの人から次の2つのパターンで言われることがあります。

  • 本を書くほどのネタ(技術力?)がない
  • いつかは本を書きたい

似たような面もあるのですが、それぞれについて少し述べたいと思います。

ネタがない

これはほとんどの場合はそんなことは無く、面白いネタを持っていると思います。
何年もエンジニアとして過ごしていればなんらかの知識はたまっていくはずなので知っていることを書けば良いです。

  • わからないことも多い
  • 自分より詳しい人がいっぱいいる
  • 知ってることは当たり前のことだけ

という意見もあるかと思いますが、完璧に理解してる人はほとんどいないですし、その人が本を書くわけでもないです。
当たり前と思ってることは初心者にとっては当たり前ではなく、本として体系的にまとまってあるだけで導入が非常に楽になるはずです。

最近、nginx, fluentd, chefなどを使ったりする関係で調べていましたが、
nginxに関しては日本で結構使われそうに見えるのにドキュメントが死ぬほど少なくて絶望しましたね。特にモジュールの書き方。
fluentdはコミュニティを引っ張って行っている方々が大量のノウハウを残してくれているので幾分楽でしたが、
やはり冗長構成の王道パターンやその設定などで悩むことはありました。(fluentdの本とか需要ありそうな気がする…!)
chefなどの構成管理系は今では必須だと思いますが、最初のハードルが高いと言われています。
今ではchefもpuppetも達人出版会で出ているので少し楽になったと思います。

などなど、やはり新しいものを調査しているともっと情報くれ!と思うことが多々あるわけで、
あなたが持っている当たり前だと思っている情報にも十分価値はあるはずなのです。

本を書きたい

本を書く、というのは一つの目標と言えるかもしれないですが、今では全くそのハードルは高くなくなりました。
コミケKindleは好き勝手出せるので気軽に書くことが出来ます。
あとは今書くだけ!今!

Kindleはまだ出したことがないですが、コミケ達人出版会(電子書籍)、商業出版の3つを比べると気軽に出せる度は以下のようになるでしょう。
コミケ=Kindle >> 達人出版会 >>>>>>>>>>>> 商業出版
コミケは自費出版になるのでお金的な問題はありますが、表現の自由度や内容の正確性についてもかなり緩いです。
Kindleはイメージでしかないですが、初期費用はかからないですが、あまり変な内容で出すとマサカリが飛んできそうです。
達人出版会はレビューの工程などがあり少し面倒なところもあったり、やはり表現に関しては一定の修正が必要になったりします。ただし、内容の正確性について多少許されるところもありそうです(個人的な感想)。
商業出版では表現は相当厳しくなり、内容も間違いがないようにある程度気を使う必要があります。

初めてで気軽に出したいならコミケは非常にお勧めです。
内容もなんでもいいです(売れなくてもいいなら)。
好きなことを書いて出しましょう。

これからについて

出そうと思って始めてから今までで約2年たったわけですが、ずっとやってきたLLVM本シリーズ(?)は一段落したかなと思います。
意外と商業誌が売れている予感がしてまたいろいろ作業が発生しそうだったり、翻訳がうんぬんという話もあったり(チラッ)、まだまだ終われないかもしれませんが。
ひとまずここでLLVMは区切りをつけて次はClangネタで(コミケで)何か出そうという話でもちさんとすすめています。
原稿締め切りまであと一ヶ月ちょっとしか残ってないのに1文字も書いてないので夏コミがかなり危ないですが、
「最低限読み物になるもの」というスタンスを取っているので本当の意味で薄い本にはしたくないところです。
今後ともサークルMotiPizzaをよろしくお願いします。

最後に

LLVMはじめても彼女できませんでした。
(26歳、男性、会社員)

LLVM 3.3 リリースノートの訳

半年に一回がんばる日が来ました。例によってLLVMのリリースノートの訳です。
直訳がほとんどなので気になる人は原文を読みましょう。

大きな変更点としてはLoop Vectorizerの改良やAMD GPUのサポートなどがよく言われているようです。
個人的に訳していて気になったのはLDCで、全力で褒めている感じがしました。

このリリースノートを読んでLLVMが気になった人はぜひきつねさんでもわかるLLVMを読みましょう!

イントロダクション(Instroduction)

このドキュメントはLLVMコンパイラ・インフラストラクチャのリリース3.3に関するリリースノートです。前回のリリースからの大きな改善点, サブプロジェクトの改善点, コードの利用者などを含むLLVMの状況を記しています。LLVMリリースの全てはLLVMリリースサイト からダウンロードできます。

LLVMについての最新情報などの詳細はLLVMメインサイト を参照して下さい。疑問や感想などがありましたらLLVM開発者メーリングリスト に投稿して下さい。

SubversionチェックアウトもしくはメインLLVMウェブページからこのファイルを読んでいるなら、このドキュメントには現在のリリースではなく次のリリースが適用されることに注意して下さい。特定のリリースのリリースノートをみたい場合、リリースページ を見て下さい。

本リリースの包括的では無い変更点リスト(Non-comprehensive list of changes in this release)

  • CellCPUポートが削除されました。古いバージョンには含まれたままです。
  • IRレベルの拡張リンカAPI(ビットコードファイルをアーカイブとしてリンクするためなど)が削除されました。これらの機能を使っている既存クライアントは統合LTOサポートを持つリンカを使用するように移行すべきです。
  • LLVMとClangのドキュメントが記述しやすいreStructuredTextを用いるSphinx ドキュメント生成システムに移行しました。詳細な情報はllvm/docs/README.txtを参照して下さい。
  • TargetTransformInfo(TTI)がIRレベルのパスで命令コストなどのターゲット特有の情報を取得するために使われる新しいインタフェースになります。LSRのような"Lowering"パスとvectorizerのみがTTIインフラを使うことを許可されています。
  • X86とARMのコストモデルを改善しました。
  • Attributesクラスを完全に書き直して拡張しました。列挙型やアラインメントだけでなくコード生成へ情報を渡す際に有用な文字列型属性もサポートしています。詳細はHow To Use Attributes を参照して下さい。
  • instruction selectionパターンのためのTableGenの構文が簡略化されました。レジスタクラスを用いて間接的に型を明示するかわりに、入力パターンの中で直接型を明示すべきです。新しい構文の例としてSparcInstrInfo.tdを参照して下さい。レジスタクラスを使う古い構文は依然動作しますが、未来のLLVMリリースで削除されます。
  • MCJITが例外処理をサポートしました。古いJIT(old jit)でのサポートは3.4リリースで削除されます。
  • コマンドラインオプションが -help の出力で表示されるカテゴリにグループ化できるようになりました。Grouping options into categories を参照してください。
  • LLVMコマンドラインサポートライブラリを使用しているライブラリとリンクすることで継承されている -help でのコマンドラインオプションの見え方が実行時に修正できるようになりました。cl::getRegisteredOptions functionを参照して下さい。
AArch64 target

ARMの64ビットアーキテクチャのAArch64のサポートを追加しました。
開発はまだほとんど初期段階であるが、以下の状況でコンパイルが成功することを期待しています。

  • ClangでC99とC++03の標準規格に準拠するものをコンパイルすること
  • ターゲットプラットフォームとしてLinuxを使用すること
  • コードと静的データが4GBを超えないこと(ヒープに割り当てられるデータには制限はありません)

いくつかの追加機能も実装されています。特に注目なのは、DWARFデバッグGNUスタイルのスレッドローカルストレージそしてインラインアセンブリです。

Hexagon Target

今は使われていない古いhexagonv2およびhexagonv3プロセッサアーキテクチャのサポートを廃止しました。現在サポートしているアーキテクチャはhexagonv4とhexagonv5です。

Mips target

新しい機能と改善点は以下の通りです。

  • Clangドライバ
    • Sourcery CodeBench Mips toolchain directories treeのサポート
    • 次の新しいコマンドラインオプションをサポート
      • -mxgot / -mno-xgot
      • -EL /-EB
      • -mmic romips / -mno-micromips
      • -msingle-float / -mdouble-float
      • -mabi=32 (o32 abi) と -mabi=64 (n64 abi)
    • 以前は-mips16, -mmicromips, -mdsp そして -mdspr2 のようなオプションはアセンブラには渡されなかったが、この問題は修正されました。
  • DSP-ASEコード生成の品質を改善するためにいくつかの変更が行われました。
    • 乗算命令と積和演算命令が4つのアキュムレータ全てを使うようになりました。
    • DSP命令がビルトインを使う必要無く出力されるようにInstruction selectionパターンが追加されました。
  • 遅延スロットを埋める命令のために遅延スロットフィルタパスが後続ブロックを検索できるようになりました。(-disable-mips-df-succbb-search=false オプションを使って下さい)
PowerPC Target

新しい機能と改善点は以下の通りです。

  • PowerPCアセンブリパーサをサポートしました。
  • スレッドローカルストレートのサポートが追加されました。 64ビットELFサブターゲットのみです。
  • mediumとlargeのコードモデル(-mcmodel=medium,large)のサポートが追加されました。現在はmediumコードモデルがデフォルトです。64ビットELFサブターゲットのみです。
  • レジスタ割り当て(より少ない予約レジスタ)を改善しました。
  • 64ビットのアトミックなロートとストアがサポートされました。
  • スカラ型のアラインされていないメモリアクセスのためのコード生成を改善しました。
  • -ffast-mathを利用した場合の浮動小数点数型の除算と平方根命令の性能を改善しました。
  • predicated returnをサポートしました。
  • 比較のためのコード生成を改善しました。
  • インラインのsetjmpとlongjmpのサポートが追加されました。
  • PowerISA 2.04, 2.05 そして 2.06 で導入された多くの命令のサポートが追加されました。
  • ベクトル型レジスタのためのスピルコードを改善しました。
  • -mno-altivecのサポートを追加しました。
  • 複素数型パラメータ, 128ビット整数型パラメータ, そしてvarargs関数のためのABI互換性が修正されました。 64ビットELFサブターゲットのみです。
Loop Vectorizer

ループベクトル化(Loop Vectorizer)の開発を続けています。ループベクトル化は現在次の機能を持っています。

  • 未知の繰り返し回数(trip count)のループ
  • ポインタの実行時チェック
  • リダクションとインダクション
  • 整数型のMin/Maxリダクション
  • If変換
  • ポインタ帰納変数
  • リバースイテレータ
  • 混合型のベクトル化
  • 関数呼び出しのベクトル化
  • ベクトル化の部分的アンローリング

ループベクトル化は-O3でデフォルトで有効化されます。

SLP Vectorizer

現在LLVMは新しくSLPベクトル化を持っています。この新しいSLPベクトル化はデフォルトでは有効になりませんが、clangのフラグとして-fslp-vectorizeを利用することで有効になります。BBベクトル化はコマンドラインフラグの-fslp-vectorize-aggressiveを利用することで有効になります。。

R600 Backend

R600バックエンドがこのリリースで追加されました。これはAMD GPU(HD2XXX-HD7XXX)をサポートします。このバックエンドはMesa3D プロジェクトの一部として開発されているAMDオープンソースグラフィック/コンピュートドライバの中で使われています。

SystemZ/s390x Backend

LLVMとclangはIBMの z/Architectreをサポートします。現在、このサポートはGNU/Linux(GNU triplet s390x-linux-gnu)に限定され、z10かそれ以上を必要とします。

Sub-project Status Update

コアとなるLLVM 3.3のプロダクション品質のコンパイラ・インフラストラクチャのディストリビューションに加えて、LLVMプロジェクトはLLVMコアを利用し同じライセンス共有するをサブプロジェクトを含みます。このセクションではこれらのサブプロジェクトの変更点を提供します。

DragonEgg: GCC front-ends, LLVM back-end

DragonEggGCCの最適化機構とコード生成をLLVMのものと置き換えたGCCプラグイン です。gcc-4.5, 4.6, 4.7そして4.8で動作し、x86-32/x86-64とARMプロセッサファミリーをターゲットにできます。Darwin, FreeBSD, KFreeBSD, LinuxそしてOpenBSDプラットフォームで使われています。Ada, C, C++そしてFortranを完全にサポートしています。Go, Java, Obj-CそしてObj-C++は部分的サポートです。gcc-4.6が最もサポートされたバージョンであり、特にgcc-4.7以降ではAdaがうまく動作しないことを注意しておきます。

3.3のリリース は次の注目すべき変更点があります。

  • gcc-4.8(gcc-4.8.1以降が必要)のサポート
  • オブジェクトファイルをLLVMの統合アセンブラで直接書き換えることが可能
  • より健全な(saner)デバッグ情報の生成
  • ビットフィールドが任意のスカラ型を含むことができます(Adaで有用)
LLDB: Low Level Debugger

LLDB はコマンドラインデバッガそしてスクリプトと他のアプリケーションか利用できるデバッガAPIのゼロから実装です。
LLDBは最新の言語機能とターゲットサポートのためにLLVMコアディストリビューションの次のコンポーネントを利用します。

3.3のリリース は次の注目すべき変更点があります。

Linuxでの機能

Linuxでの改善点

  • マルチスレッドプログラムのデバッグ
  • i386プログラムのデバッグ
  • プロセスリスト、アタッチ、フォーク
  • 式評価

External Open Source Projects Using LLVM 3.3

LLVMの興味深い点は多くの他の言語やツールプロジェクトのためのイネーブル技術として使われることです。このセクションではLLVM3.3で動作するよう更新されたいくつかのプロジェクトをリストアップします。

Portable Computing Language (pocl)

容易にポータブルなオープンソースOpenCL実装を生成することに加えて、pocl のもう一つの主な目的はコンパイラの最適化を利用したOpenCLプログラムの性能ポータビリティを改善することとターゲット依存の手動最適化の必要性を減らすことです。poclの重要な部分は、ワークグループバリアの存在の中でさえカーネルコンパイラを用いて静的に多数のワークアイテムを並列化するLLVMパスの∩であることです。これによって複数の方法でワークグループの静的な細流度並列化が可能になる。

TTA-based Co-design Environment (TCE)

TCE はTransport triggered architecture(TTA)基にした新しいプロセッサを設計するためのツールセットです。これはC/C++プログラムから合成可能なVHDL/Verilogそして並列プログラムバイナリまでの完全な協調設計フローを提供する。プロセッサの設定可能な項目としてはレジスタファイル、機能ユニット、サポート操作、そして相互接続ネットワークが含まれる。

TCEはC/C++/OpenCL Cの言語サポート、ターゲット非依存の最適化、そして一部のコード生成のためにClangとLLVMを利用する。これはコンパイラツールチェインの大部分をターゲット毎に再コンパイルすることを避けるために、デザインされたTTAプロセッサ向けの新しいLLVMベースのコード生成器を"オンザフライ"で生成し、それらを実行時ライブラリとしてコンパイラバックエンドにロードする。

Just-in-time Adaptive Decoder Engine (Jade)

Jade(Just-in-time Adaptive Decoder Engine)はビデオデコーダ設定のJITコンパイルのためにLLVMを利用した汎用的なビデオデコーダエンジンです。それらの設定はMPEG Reconfigurable Video Coding(RVC)委員会によって設計されている。MPEG RVCスタンダードはデコーダのストリームベースのデータフロー表現に基づいている。それはRVC-CAL言語で書かれたコーディングツールの標準ライブラリとデコーダのデータフロー設定(ブロック図)から構成される。

JadeプロジェクトはOpen RVC-CAL Compiler(Orcc)の一部としてホストされ、ビデオコーディングツールのRVC-CAL標準ライブラリをLLVMアセンブリコードへ変換することを要求する。

LDC - the LLVM-based D compiler

D はCライクの構文と静的型付きを持つ言語です。これは効率、制御、そしてモデリング力を安全性とプログラマの生産性に実際的に結びつける。D言語はコンパイル時関数実行(CTFE)とテンプレートメタプログラミングのような強力なコンセプトをサポートし、そして並列性への革新的なアプローチと多くの古典的なパラダイムを提供する。

効率的なネイティブコードを生成するために、LLVMと結合したリファレンスコンパイラをバックエンドとして、LDC はそのフロントエンドを使用する。LDCLinuxOS X、そしてWindowsのようなx86/x86_64システムとLinux/PPC64をターゲットとする。ARMのような他のアーテキテクチャへのポートは進行中です。

Additional Information

LLVMウェブページ 、特にドキュメントでは様々な追加情報が利用できます。ウェブページにはSubversionにあるソースコードにあわせて更新されているAPIドキュメントもあります。LLVMツリーの "llvm/docs" ディレクトリに行くと特定のリリースに対するドキュメントが取得可能です。

LLVMに関する質問やコメント等がありましたらメーリングリスト を通してお気軽にご連絡下さい。

Heroku,Sinatra,Twitter Bootstrapを使ってみました

無事達人出版会様よりきつねさんでもわかるLLVMを公開できました。
それと同時公開を目標に作成したMotiPizzaのサークル公式ページを作成したのでその方法をまとめてみます。
後半の部分の手順忘れてしまったので適当になってますが。

今回のポイントとしてはタイトルの通りデプロイ先としてHerokuを利用し, フレームワークとしてSinatra(ruby), そしてデザイン(CSS)としてTwitter Bottstrapを使ったことです。
Rubyを含めすべて初めて使ったのでそのあたりもついでにまとめておきます。
参考にしたサイトは最後にまとめてあります。

今回作成したページのソースはGitHubにあります。

Rubyの開発環境

Rubyは一度も使ったことなかったので、今回作成するにあたりRuby使おうというのはすぐ決めました。
よくわからないけどちらちら見る単語から判断するにrbenvでRuby本体のバージョン切り替えを行ってGemでパッケージ管理するまで理解しました。

rbenvのインストール方法はいろいろなところを参考にしましたがapt-getでさくっといれました。(debian sidにしかないっぽいです。普通はgithubからいれるみたい)
ruby-buildはrbenvでRubyをインストールするために必要?

$ sudo apt-get install rbenv ruby-build

rbenvを使うためにbashrcやzshrcなどに設定を入れておく必要があるようです。設定後にはログインしなおすなりして設定を有効にしてください。

## zshの場合は.zshrcに以下を追加
eval "$(rbenv init - zsh)"
## bashの場合は.bashrcに以下を追加(?)
eval "$(rbenv init -)"

rbenv入れた後に実際にrubyをインストールしますが、インストールできるrubyのバージョンは以下のコマンドで確認できます。

$ rbenv install

1.9系で一番新しそうなの入れたかったので1.9.3-p194をいれました

$ rbenv install 1.9.3-p194

インストールしたrubyをシステム全体で使う場合にはglobalにバージョン指定します。

$ rbenv global 1.9.3-p194
$ rbenv global
1.9.3-p194

これで好きなバージョンのrubyが使えるようになりましたが、gemを入れるたびにrbenv rehashしないとgemが有効にならないようで、この作業を自動化してくれるgemを入れます。(gem自体のインストール方法は忘れた)

$ sudo gem i rbenv-rehash

Bundler

Bundlerはプロジェクト単位でgemを管理するもので、別の開発環境でも同じ構成を簡単に構築することができるようになります。
特にHerokuではこれを使ってデプロイしてるようです。

bundlerをgemでインストールします。この場合はsudoつけたら違う場所にインストールするからだめ?

$ gem install bundler
$ bundle -v
Bundler version 1.2.3
$ which bundle
/home/sabo/.rbenv/versions/1.9.3-p194/bin/bundle

プロジェクトで使うgemをGemfileで指定します。今回作成したGemfileは以下のようなものです。

source :rubygems
gem 'sinatra', '1.1.0'
gem 'haml'
gem 'thin'

これをプロジェクトのトップディレクトリに置いた状態で以下のコマンドを実行することで自動的にgemがインストールされます。
特にpathを指定することが重要で、指定path以下にgemがインストールされ、プロジェクトではそこにあるgemしか使わなくなります。

$ bundle install --path vendor/bundler

コマンド実行後に新しいファイルが3つできます。Gemfile.lock以外はコミットしないようにします。

  • .bundle/
    • bundleの設定を保存する場所
    • コミットしない. gitignoreする.
  • Gemfile.lock
    • Gemfileの依存関係により自動的にインストールされるgemの設定もすべて含めたファイル
    • コミットする.
    • Gemfileだけでは依存関係やバージョンが変わる可能性があるため
  • vendor/
    • 実際にgemがインストールされる場所
    • コミットしない. gitignoreする.
    • Gemfile.lockで指定していれば同じ環境ができるはずなので

SinatraHamlを使った開発

RubyフレームワークといえばRailsですがほぼ静的なページ構成になりますし、軽量フレームワークとして有名なSinatraを使うことにしました。
HamlはHTML記述のためのテンプレートです。個人的にはかなり気に入りました。PHPでも欲しいです。

Sinatraの詳しい使い方は公式ページなどを見ると良いですが、簡単なことなら直感的に使い方がわかります。
公式サンプルのコピペですが、これだけで / にアクセスするとindex.hamlを表示するものができます。

require 'sinatra'

get '/' do
  haml :index
end

sinatraの仕様としてhamlなどのテンプレートファイルはviewsディレクトリの中に置く必要があります。
./views/index.haml に以下のように記述したファイルを置きます。

-# coding: UTF-8
!!!
%html
  %head
    %title< MotiPizza
  %body
    HelloWorld!!

hamlではPythonのようにインデントが階層を意味しているのでシンプルな見た目になります。
%divのようにタグは%をつけて記述し、最後に<や>をつけるとHTML生成時の改行を制御できます。
以下のように{}でタグの属性も追加できます。もちろん#{var}のようにrubyの変数をhaml内でも使えます。

%a{:href=>"http://motipizza.com"}< MotiPizza公式ページ

画像やCSSファイル、JavaScriptファイルなどの公開ファイルはpublicディレクトリにおく必要があります。
/public/img/moti.jpg に画像をおいた場合は/img/moti.jpgでアクセスできます。

%img{"src" => "/img/moti.jpg", "alt" => "もち画像"}

hamlで共通部分(レイアウト)を記述するためにはlayout.hamlを置けば良いです。
タイトルやフッターなどは共通で後は個別に異なるという場合に、layout.hamlを使えば共通部分(レイアウト)を記述できます。

%html
  %head
    %title< MotiPizza
  %body
    %div
      =yield
    %footer
      Copyright 2013 MotiPizza

以上のように =yield と書いたところにhamlが展開されるので、index.hamlなどには%div以下だけを書けば良いです。

上記の方法では一番外側しか共通化できないですが、他のhamlファイルをincludeすることで共通の構造を生成できます。
index.hamlなどに以下のように追加します

%div
  = haml :hello

hello.hamlを作成し以下のように記述します。

%p< HelloWorld!!

これで:helloにhello.hamlの内容が展開されます。
今回はtwitterはてブなどのソーシャルボタンをまとめるためにこれを使いました。

foremanを使って動作確認

よくわかってないですがforemanはProcfileに従ってプロセスを起動するものらしいです。
HerokuではProcfileを使うようなのでProcfileを使った状態で動作確認するのが良いでしょう。
もちろんforemanを使わなくても以下のようにコマンドを実行すればSinatraを起動できます。

$ bundle exec ruby web.rb -p 5000

これでSinatraを使って記述した web.rb をポート5000番で起動します。

まずforemanを別途インストールします。

$ gem install foreman

次にProcfileを書きます。Procfileは1行に"アプリケーション名:コマンド"という形式で書きます。アプリケーション名は何でもいいです。
$PORTには5000が入り2行目以降は+100されていくとかなんとか。

web: bundle exec ruby web.rb -p $PORT

Procfileを記述したら以下のコマンドを実行することでforemanによりアプリケーションを実行できます。

$ forman start

TwitterBootstrap

Twitter Bootstrapはボタン、フォーム、ナビゲーションなどのテンプレート集みたいなものです。
これを使えばCSSの知識がなくてもそれっぽいデザインができるんじゃないかと思いました。
が、そんなことはぜんぜんないです!
微妙な位置調整やそもそもうまく配置できないときにはCSSさんの出番が来てしまうので、一定の知識は要求されますね。
でもやはり簡単に作れますし、Hamlとも相性が良く記述しやすいので、非常に便利なものだと思いました。

公式のサンプルが結構いろいろ書いてあって参考になるのですが、ちょっと変えようと思うとどうやればいいのかわからないので他のTwitterBootstrapを使ってるところのソースを見てひたすらコピペする作業でした。
FireBugとか使って他人のページをCSS変更したりとか楽しいです。

TwitterBootstrapを使うにはCSSとJSをダウンロードして配置すれば良いですが、
CDNで配信してるところもあるのでそれを使う手もあります。
よくわかってないですが、CDNだと全部入りしかないかもしれません。

.containerを使えばセンタリングされるというのをいろんなところで見るのですが、ほとんどの場合されなくて困りました。
諦めてCSSで位置調整するか、.span4.offset1 などでオフセット指定で調整したりしてます。
あとは、レスポンシブデザインにすると画面サイズ小さくしたときの挙動がよくわからなくて、レイアウトが崩れるので諦めました。

Heroku

HerokuはRuby以外にもJavaなども実行できるホスティングサービスですが、Rubyが一番有名じゃないでしょうか。
実質Railsみたいな印象がありましたが、ちゃんとSinatraも実行できるようです。

詳細はここでは書かないですが、基本的には無料でaddonを使わなければクレジットカードなども登録しなくていいです。
無料のaddon使う場合にもカード登録しないといけないとかなんとか。
あと、1時間(?)アクセスがないとインスタンスが休止するようで次回アクセス時に起動時間が数十秒かかるのが面倒です。
addonで休止しないようにできるみたいです。

細かいHerokuの操作は忘れましたが、Herokuへのデプロイはgitでpushするだけになります。
gitでpush時に必要に応じてテストが行われてProcfile通りにプロセスが実行されます。
既にforemanで動作確認まで済んでいるので、git pushするだけで開発環境と同じ動作が期待できます。
逆に動作が異なるときはgitで管理されている以外のものを使っている状態です。

LLVM 3.2 リリースノートの訳

ようやくLLVM 3.2がでました。今回はスケジュールよりもそれほど遅れませんでした。
前回に引き続き、リリースノートを訳しました。
SROA周りとか訳がぶっこわれているところがありますが、気になる人は原文を読みましょう。
branchを見ながら訳したので抜けているところがあったらすみません。

変更の注目点としてはLLVM本体としては、ループベクトル化,SROAの新実装, NVPTX(旧PTX)バックエンド追加などがあります。
MIPSPowerPCの変更点の多さは注目です。(個人的にMIPSをずっと見てたので変更量は本当にすごいです)
Clangを含めスレッドローカルストレージ周りの追加や
サブプロジェクトとしてClang Static Analyzerという項目が追加されていたり、
外部のオープンソースプロジェクトとしてEmbToolkitが追加されていたりします。

LLVM狐本もよろしくおねがいします!

追記
思ったより参照頂いているようでありがたい限りです。
訳についてコメントを頂いたので反映させて頂きました。ありがとうございます。
専門用語の対訳がわからなかったり、直訳かつ単語をスキップして訳していたりもするので、どうしても気になる場合はコメント頂けるとうれしいです。
翻訳は読むだけと違ったスキルが必要で自分にはまだまだ力が及ばないところもありますが、日本語なら読むという方に参考になれば幸いです。

イントロダクション(Instroduction)

このドキュメントはLLVMコンパイラ・インフラストラクチャのリリース3.2に関するリリースノートです。
前回のリリースからの大きな改善点, サブプロジェクトの改善点, コードの利用者などを含むLLVMの状況を記しています。
LLVMリリースの全てはLLVMリリースサイト からダウンロードできます。

LLVMについての最新情報などの詳細はLLVMメインサイト を参照して下さい。
疑問や感想などがありましたらLLVM開発者メーリングリスト に投稿して下さい。

サブプロジェクトの更新状況(Sub-project Status Update)

LLVM3.2ディストリビューションはLLVMのコアリポジトリ(オプティマイザ, コード生成器, サポートツールなど)と
Clang, DragonEgg, compiler-rtサブプロジェクトリポジトリから成る高品質のコードで構成されています。
更に、LLVMプロジェクトには開発中のサブプロジェクトを含んでいます。
これらのコードに加えて、LLVMプロジェクトは開発中のサブプロジェクトを含みます。
ここでは3つのサブプロジェクトの更新を記します。

Clang: C/C++/Objective-C Frontend Toolkit

Clang はC,C++,Objective-CのためのLLVMフロントエンドです。
Clangはわかりやすい診断メッセージ(コンパイルエラー・警告を明快にするためのわかりやすい情報), 言語標準規格に忠実, 高速かつメモリ使用量の少ないコンパイルという特徴を持ち、
より良いユーザ体験を提供することを目指しています。
ClangはLLVMのようにモジュール化されたライブラリを元として作られており、開発ツールを作成したり(開発ツールに)統合したりするのに適しています。

LLVM3.2のリリースにあわせて、Clangチームは大きな改善を果たしています。以下が主な変更点です。

  • Clangの診断(diagnostics)の改善
  • tls_model(Thread Local Storage)アーキテクチャのサポート
  • 型安全属性

Clangのリリース3.1からの変更点についての詳細はClangリリースノート を参照して下さい。
もしClangで通らないコードが他のコンパイラで通る場合、
それが意図していないものか既知のものであるかを確認するために、言語互換性ガイド を参照して下さい。

DragonEgg: GCC front-ends, LLVM back-end

DragonEggGCCオプティマイザとコード生成器をLLVMのものに置き換えるGCCプラグイン です。
GCC4.5, GCC4.6(部分的にGCC4.7)で動作し、Darwin, FreeBSD, KFreeBSD, LinuxそしてOpenBSD上で利用実績があります。
x86-32/x86-64とARMプロセッサファミリーをターゲットとして利用できます。
Ada, C, C++そしてFortranを完全にサポートし、Go, Java, Obj-CそしてObj-C++は部分的なサポートをしています。

リリース3.2では主に次のような変更点があります。

  • PollyのようなLLVMプラグインをロードできるようになった
  • スレッドローカルストレージモデルのサポート
  • variable lifetimeの知識をLLVMオプティマイザに渡す
  • LTOサポート付きでビルドされたGCCはもはや不要
compiler-rt: Compiler Runtime Library

compiler-rt プロジェクトは、コード生成器や他の実行時コンポーネントで必要とされる低レベルでターゲット特有のフックの実装を提供する単純なライブラリです。
例えば、32ビットターゲット向けにコンパイル時に、double型から64ビット符号無し整数への変換は"__fixunsdfdi"関数の実行時呼び出しへコンパイルされる。
compiler-rtライブラリは高度に最適化されたこれらの実装および他の低レベルルーチン(libgccより3倍速いものもある)を提供する。

3.2のリリースでは次のような主な変更点がある。

  • ThreadSanitizer(TSan) : C/C++用データ競合検知ランタイムライブラリの追加
  • AddressSanitizer の改善 : より良いポータビリティ(OSX, Android NDK), cmakeベースのビルドのサポート, エラー報告の強化, 多くのバグfix
  • A6 'Swift' CPUのサポートの追加
  • ハードウェアで符号無し除算が可能な場合にdivsi3関数でそれを活用するように改善
LLDB: Low Level Debugger

LLDB はコマンドラインデバッガの基礎からの実装であり、他のアプリケーションから利用されるデバッガAPIです。
LLDBは(特にC++向けの)忠実な式解析(expression parsing)を提供するためにClangのパーサを利用しており、ターゲットサポートのためにLLVM JITを利用している。

3.2のリリースでは次のような主な変更点がある。

  • Clang向けのLinuxビルドfix(Building LLDB を参照)
  • いくつかのLinuxの安定性, 利便性の改善
  • Linux上で式評価で(古いJITから)MCJitを使うように変更
libc++: C++ Standard Library

compiler-rtと同様、libc++は更に寛容的に利用できるようにMITとUIUCのデュアルライセンスを採用している。
LLVM3.2では次の主な変更点がある。

  • C++11 shared_ptr アトミックアクセスAPI(20.7.2.5)が実装された
  • ライブラリを通してnoexceptとconstexprを適用した
  • associative container emplace(良い訳求む!)におけるC++11への適合性の改善
  • std::rotate アルゴリズムとI/Oの性能改善
  • new/deleteオペレータと例外型のためのtype_infosをlibc++からlibc++abiへ移動した
  • バグfix. , vector アルゴリズム, , , , , , ,
VMKit

VMKitプロジェクト は静的もしくはjust-in-timeコンパイラとしてLLVM利用する、Java Virtual Machine(Java VM or JVM)の実装です。

LLVM3.2では次の主な変更点がある。

  • バグfixのみ。 機能の変更無し。
Polly: Polyhedral Optimizer

Polly はデータ局所性と並列性のための実験的なオプティマイザです。
現在、高レベルなループ最適化と(OpenMPランタイムを利用した)自動並列化を提供している。
自動SIMD化とアクセラレータコード生成のあたりはまだ始まったばかりです。

LLVM3.2では次の主な変更点がある。

  • Pollyに利用されているisl(integer set library)がMITライセンスとして再度ライセンス化された
  • islベースコード生成
  • LGPLV2だったCLooGをMITライセンスのものに入れ替え
  • 細粒度オプション(Fine grained option)の取り扱い(コアと計算の分離, コントロールオーバーヘッドvsコードサイズ)
  • FORTRANとDragonEGGのサポート
  • OpenMPコード生成のfix
Clang Static Analyzer

Clang Static Analyzer は潜在的なバグを発見するための高度な解析を実行する、Clangと統合された高度なソースコード解析ツールです。

LLVM3.2のリリースでは、static analyzerは多くの部分で重要な改善をしており、次のような変更点があります。

  • Translation Unit(詳細は以下)内で手続き間解析の改善。これはパーサがバグを発見する能力を大きく拡大させる。
  • "well-known" APIをモデル化するための新しいインフラ。これは、それらの関数呼び出しをモデル化するときにパーサがより良い仕事を実行できるようにする。
  • checker APIで関数/メソッド呼び出しを表現するより統一された方法を用いたことによるstatic analyzer checkersを書くためのAPIの重要な改善。詳細はBuilding a Checker in 24 hoursを見てください。

リリースでは特にObjective-C解析向けの次のような変更点を含む。

  • Objective-Cメソッド向けの手続き間解析
  • "blocks"の呼び出しの手続き間解析
  • dispatch_onceやfriendsのようなGCD APIの正確なモデリング
  • arrayやdictionaryリテラルのような最近追加されたObjective-C constructs(訳注:コンテナ?)向けのサポートの改善

リリースでは特にC++解析向けの次のような改善を含む。

  • C++メソッド(Translation Unit内)向けの手続き間解析
  • C++イニシャライザとデストラクタのより正確なモデリング

最後に、このリリースはscan-build(コマンドラインもしくは統合システムから分析を起動するために使われる)のための多くの小さな改善を含む。
これはディレクトリ横断的な問題を含む。これはいくつかのケースで潜在的なセキュリティ問題を引き起こす可能性がある。
この問題を報告するために、我々はTim Brown氏(Portcullis Computer Security Ltd)に承認を求めている。

LLVM3.2を利用している外部のオープンソースプロジェクト

LLVMの興味深い点として、多くの言語やツールのプロジェクトで何かを実現する(実現技術)ために使われていることです。
この節ではLLVM3.2とともに動作するように既に更新されているプロジェクトの一部を挙げる。

Crack

Crack はコンパイル言語のパフォーマンスをもつ、スクリプト言語のように開発が容易なものを提供することを目的とする。
この言語はC++, Java, Pythonからコンセプトを得て、オブジェクト指向や演算子オーバーロード,強い型付けを取り入れたものです。

EmbToolkit

EmbToolkit はLinuxのクロスコンパイラ toolchain/SDK (GCC/binutils/Cライブラリ(uclibc,glibc,musl))、パッケージのクロスコンパイルのためのビルドシステムそしてオプションとして様々なルートファイルシステムを提供する。
ARMとMIPSをサポートする。
現在3.2リリースに向けたclang+llvm環境を提供するために準備中。

FAUST

FAUST はリアルタイム音声信号処理のためのコンパイル言語です。
FAUSTはFunctional AUdio STreamを表す。
プログラミングモデルは関数型プログラミングとブロック図構成(block diagram composition)の2つのアプローチを結合させたものです。
FaustコンパイラはC, C++, Java, JavaScriptの出力形式に加えて、LLVMビットコードを生成可能で、LLVM2.7から3.2で動作する。

Glasgow Haskell Compiler (GHC)

GHC は遅延評価関数型プログラミング言語であるHaskellのオープンソースのコンパイラおよびプログラミングスイートです。
様々なプラットフォーム向けに最適化されたコードを生成する静的コンパイラや開発時用のインタラクティブなシステムを含んでいる。
GHC7.0以降はLLVM2.8以降をサポートしたLLVMコード生成器を含んでいる。

Julia

Julia は技術計算向け高レベル高性能の動的言語です。
洗練されたコンパイラ、分散並列処理、数値精度、豊富な数値演算ライブラリを提供する。
コンパイラでは型推論を用いて型宣言無しで高速なコードを生成しており、LLVMの最適化パスやJITコンパイラも利用している。
Julia言語 は複数ディスパッチやプログラムに大幅な柔軟性を与えるように設計されている。
Juliaは既に多くの問題に利用可能です。

LLVM D Compiler

LLVM D Compiler(LDC)はD言語用のコンパイラです。
DMDフロントエンドに基づいてLLVMをバックエンドとして利用している。

Open Shading Language

Open Shading Language(OSL)はプログラマブルなシェーディング向けの小さいが高機能な言語です。
先進的な大域照明レンダラや他のアプリケーションで利用され、マテリアル, 光源, 転移, パターン生成の表現に適している。
実行時に複雑なシェーダネットワークをx86コードにJITするためにLLVMを利用している。

OSLはSony Pictures Imageworksによって開発され、フィルムアニメーションとビジュアル効果に特化して使われる社内のレンダラーと使われる。
New BSDライセンスのオープンソースソフトウェアとして配布される。
これはアメイジングスパイダーマン, メン・イン・ブラック3, モンスター・ホテルや現在作成中の他の映画、CM、そしてBlender, VRay, Autodesk Beastのようないくつかのオープンソースレンダリング製品において全てのシェーディングで使われている。

Portable OpenCL (pocl)

簡単で移植性のあるオープンソースのOpenCL実装の実現に加えて、pocl のもう1つの主な目的は、
コンパイラの最適化を利用しターゲットに依存した手動最適化の必要性を減らすことで、
OpenCLプログラムの性能の移植性を改善することです。
poclの重要な部分は、カーネルコンパイラを用いて静的に複数の仕事に並列化させるために使われるLLVMパスの集合です。
これによって複数の方法(SIMD, VLIW, superscalarなど)でワークグループの静的な細流度並列化が可能になる。

Pure

Pure はterm rewritingを基にした代数/関数型プログラミング言語です。
プログラムはsymbolic fashionで式を評価するのに利用される方程式の集合です。
インタプリタはPureプログラムを高速なネイティブコードにJITコンパイルするためにLLVMをバックエンドとして利用している。
Pureは動的型付け, 先行評価と遅延評価, レキシカルクロージャ, 衛生的なマクロシステム(term rewritingを基にしたもの), 組み込みのリストと行列のサポート
そしてCや他のプログラミング言語への使いやすいインタフェース
(LLVMビットコードモジュールのロードや対応するLLVMコンパイラが利用可能であればPureプログラム内にC, C++, Fortran, Faustコードのインライン記述が可能)

Pureバージョン0.56はテストされてLLVM3.2で動作するようになった。また、LLVMリリース2.5以降の古いバージョンでも動作するように開発している。

TTA-based Co-design Environment (TCE)

TCE はTransport triggered architecture(TTA)を基にしたアプリケーション特有のプロセッサ(ASP)をデザインするためのツールセットです。
このツールセットでは上はC/C++プログラムから下は合成可能なVHDL/Verilogや並列プログラムのバイナリまでの完全な共創(co-design)フローを提供する。
プロセッサの設定可能な項目としてはレジスタファイルや機能ユニット, サポート操作, 相互接続ネットワークが含まれる。

TCEはCC/C++言語サポート,ターゲット非依存の最適化そして一部のコード生成のためにlangとLLVMを利用する。
これはコンパイラチェインの大部分をターゲット毎に再コンパイルするのを避けるために、
デザインされたTTAプロセッサのために"オンザフライ"で新しいLLVMベースのコード生成器を生成し、
ランタイムライブラリとしてコンパイラバックエンドへそれらをロードする。

LLVM 3.2の変更点

このリリースには大量のバグフィックス、性能修正そして細かい改善点を含んでいます。
この節ではいくつかの主な改善点と新機能を挙げています。

主な新機能(Majro New Features)

LLVM3.2はいくつかの主な変更点と大きな新機能があります。

  • ループベクトル化(Loop Vectorizer)
  • SROA(Scalar Replacement Of Aggregates)の新実装
  • NVIDIAのソースをベースとしたNVPTXバックエンド(既存のPTXバックエンドの置き換え)
LLVM IRとコアの改善点(LLVM IR and Core Improvements)

LLVM IRは新しいターゲットのより良いサポートのためにいくつかの新機能があり、それによって新たな最適化が可能になります。

  • スレッドローカル変数は特定のTLSモデルを持つことができる。 Language Reference Manualを参照。
  • 古い関数属性向けの'TYPE_CODE_FUNCTION_OLD' タイプコードとautoupgradeコードが削除された
  • Attributeクラスの内部表現は、LLVMContextオブジェクトに格納される一意化されたopaqueオブジェクトへのポインタへと変換される。 よって、Attributesクラスはこのopaqueオブジェクトのただのラッパーとなった。
オプティマイザの改善点(Optimizer Improvements)

多くの細かい性能修正とバグフィックスに加えて、このリリースではオプティマイザに対する細かい強化と追加が少し含まれている。

Loop Vectorizer。我々はループベクトル化を追加し現在では小さなループをベクトル化することができるようになった。
ループ最適化はデフォルトで無効化されており、-mllvm-vectorize-loopsフラグにより有効化できる。
SIMD vector widthは-mllvm-force-vector-width=4フラグで明示される。
そのデフォルト値は0であり、自動選択を意味する。
我々は次のような関数をベクトル化可能である。

unsigned sum_arrays(int *A, int *B, int start, int end) {
  unsigned sum = 0;
  for (int i = start; i < end; ++i)
    sum += A[i] + B[i] + i;

  return sum;
}

我々は次のようなループ下でベクトル化可能である。

  • 最も内側のループは必ず1つのBasic Blockを持つ必要がある
  • イテレーション回数がループの実行開始以前に既知である
  • ループカウンタは1つずつインクリメントされる
  • ループトリップカウントは変数になれる
  • ループはゼロから始まる必要はない
  • 帰納変数(インデックス変数, 誘導変数)をループ内で使うことが可能
  • Loop reductionがサポートされている
  • アフィンアクセスパターンを伴う配列は'noalias'としてマークされる必要はなく、実行時にチェックされる

SROA。 我々はよりパワフルに、そして残りの最適化パイプラインにより親切なコードを生成するためにSROAを書き直した。
以前はこのパスは比較的な小さな集合のみを操作する必要があるというスケール問題があり、間違えてスカラSSA値にするために大きな集合を1つの大きな整数に置き換えるという問題があった。
小さなスタックバッファを表すi1024やi2048型の大きな数字が結果となった。
これらは今度は次の多くの最適化パスを遅くする。

新しいSROAパスは現在使用中の集合の一部のみをスカラに昇格させる異なるアルゴリズムを使っている。
このため閾値を必要としない。スカラ値を集合の特定のLLVM型ではなく集合の使用から推定する。
これらの特徴はパスとコードの最適化を結合するだけでなく多くの関数のコンパイル時間を劇的に改善する。

  • Branch weightメタデータは多くのオプティマイザを通して保護される
MCレベルの改善点(MC Level Improvements)

LLVMマシンコード(MC)サブシステムはアセンブリ, ディスアセンブリ, オブジェクトファイルフォーマットの扱いなどや
CPUの命令セットレベルのツールに関連する数多くの問題を解決するため作られた。
詳細な情報はIntro to the LLVM MC Project Blog Postを参照してください。

  • 次のようなアセンブラディレクティブのサポートの追加: .ifb, .ifnb, .ifc, .ifnc, .purgem, .rept そして .version (ELF) Darwin用の .pushsection, .popsection, .previous .
  • .lcommディレクティブのハンドリング強化
  • MSスタイルインラインアセンブラ: offsetとTYPEオペレータの実装の追加
  • ターゲットはNOPパディングのための最小限のサポートされたNOPサイズを明示することができる
  • ELF改善: Windows上でELFオブジェクトの生成をサポート
  • MachO改善: symbol-difference 変数はN_ABSとしてマークされ、data-in-codeマーカーのためのdirect-to-object属性が追加された
  • x86とarmターゲット向けの注釈付きディスアセンブリ出力のサポート
  • ARM TARGET2 relocationのサポート追加とARMスタイルの "$d.*"ラベルのハンドリング修正 によりARMサポートが改善された
  • PowerPCにおけるlocal-exec TLSの実装
ターゲット独自のコード生成器の改善点(Target Independent COde Genereator Improvements)

Stack Coloring。コードの離れた領域で別個に使われているスタックオブジェクトを共有させるために新しい最適化パスを実装した。
この最適化は、オプティマイザにとってスタックスロットが共有されていないことが明白なケースでは、必要とされるスタックスペースを大幅に減らす。
各alloca について、それがひとつのリージョン内で使われていることをコードジェネレータに伝えるためにlifetimeマーカーを使用している。

連続したload/storeはマージされる。

コード生成基盤に非常に多くの仕事を取り入れた。
これらは積極的なアルゴリズムを実装可能にし、コード生成を早くすることができる。

Very Long Instruction Word(VLIW)アーキテクチャのためのバンドリングをサポートするために新しいTableGen基盤を追加した。
TalbeGenはVLIWターゲットのスケジュール記述からDFA(決定性有限オートマトン)を自動的に生成することができる。
この記述ではバンドル内で命令の正当なグルーピングを決定するために問い合わされる(queried)ことができる。

機械命令バンドルにグルーピングするためにをDFA基盤をベースとした新しいターゲット非依存のVLIW packetizerを追加した。

我々は命令間の関係づけのために新しいTableGen基盤を追加した。
この機能によりTableGenは自動的に関連テーブルのセットと様々な形式の命令間を切り替えるために使われるクエリ関数を構築できる。
詳細な情報はHow To Use Instruction Mappings を参照して下さい。

基本ブロック配置(Basic Block Placement)

確率を基にしたブロック配置とコードレイアウトアルゴリズムがLLVMのコード生成器に追加された。
レイアウトパスは__builtin_expectのようなソースコードアノテーションと同様の静的ヒューリスティックスから算出される確率をサポートする。

X86-32とX86-64ターゲットの改善点(X86-32 and X86-64 Target Improvements)

X86ターゲットにおける新しい特徴と主な変更点は以下の通りです。

  • 特にAVX2向けの小さなコード生成最適化
ARMターゲットの改善点(ARM Target Improvements)

ARMターゲットの新機能は以下の通りです。

  • A6 'Swift' CPU向けのサポートと性能改善
ARM統合アセンブラ(ARM Integrated Assembler)

Clang向けの直接オブジェクト化モジュールを含む、ARMターゲットのフル機能のマクロアセンブラが対応された。
アセンブラはDarwinでのみデフォルトで有効化されており、Linuxではテストやプラットフォーム特有の追加サポートが未解決です(訳自信無し)。

Thumb1, Thumb2とARMモードが完全サポートされており、サブターゲットと特定CPU拡張としてはVFP2, VFP3とNEONがサポートされている。

アセンブラはUnified Syntax(詳細はARM Architecural Reference Manualを参照)のみが使える。
いくつか発展途上のサポートされているpre-unfied(divided) syntaxあるが、未だサポートと大きな差がある。

MIPSターゲットの改善点(MIPS Target Improvements)

MIPSターゲットにおける新機能と主な変更点は以下の通りです。

  • 統合アセンブラサポート: MIPS32がPICとstaticで動作する、既知の制限としてPR14456においてR_MIPS_GPREL16リロケーションが間違った加数(addend)で生成される。 MIPS64サポートは不完全である。例えば例外ハンドリングが動作しない。
  • fast calling convetionがサポート
  • Android MIPSツールチェインがClangドライバに追加された
  • "-mabi=n32"オプションを通したMIPS N32 ABI向けのClangドライバサポートの追加
  • MIPS32とMIPS64のディスアセンブラが実装された
  • llcの"-mxgot"オプションを通した大きなGOT(64KBを超える)を含んだプログラムのコンパイルをサポート
  • MIPS32 DSP intrinsicsの実験的なサポート
  • MIPS16の実験的なサポート。次のような制限を持つ: soft floatのみをサポート, C++例外はサポートされない, 大きなスタックフレーム(> 32000 Bytes)はサポートされない, .sでは直接オブジェクトコード出力がサポートされない。
  • スタンドアロンアセンブラ(llvm-mc): 実装は進行中であり実験的である
  • リトルエンディアンとビッグエンディアンのMIPS32プラットフォームにおける古典的なJITとMCJITの全てのテストがパス
  • インラインアセンブラサポート: 全ての共通の制約(constraints)とオペランド修正(modifiers)が実装された
  • 末尾最適化(tail call optimization)のサポート。llcの"-enable-mips-tail-calls"オプションを使うかもしくはClangの"-mllvm-enable-mips-tail-calls"オプションを使うことで有効化できる
  • $fp, $gp, $ra, $atレジスタを予約レジスタから削除することによるレジスタ割り当ての改善
  • 長い分岐展開(Long branch expansion)パスが実装された。これは16-bitフィールドに入らないoffsetを持つ分岐命令を展開する。
  • Cavium Octeon IIボードがテストビルドに使われる(llvm-mips-linux builder)
PowerPCターゲットの改善点(PowerPC Target Improvements)

64-bit PowerPC ELF ABI準拠のため、GCCとの相互運用性のため、そして全般的な64-bit PowerPCサポートのため、多くの修正と変更がLLVMに(そしてClangにも)なされている。
いくつかの主な変更は以下の通りです。

  • MCJITサポートの追加
  • PPC64リロケーションサポートと(Small code model) TOCハンドリングの追加
  • パラメータ渡しと戻り値のfix(アライメント問題, パディング, varargsサポート, 適切なレジスタ使用, 奇数サイズの構造体サポート, 浮動小数点数サポート, i32戻り値のための戻り値拡張)
  • ベクタレジスタのためのspill/reloadコードの修正
  • C++例外ハンドリングの有効化
  • GCCの挙動に関連するdouble-rounding互換性問題を修正するための変更
  • Darwin ppc64 ABIサポートからppc64-elf-linux ABIを独立させる(disentangle)ためのリファクタリング
  • 新しいテストケースの分類、およびテストケースの修正(エンディアンやwordサイズ問題)を分類した
  • ビッグエンディアンコード生成バグ, 命令エンコーディングや命令制約のfix,
  • Clang統合アセンブラ(-integrated-as)の実装
  • Altivec compare命令の追加サポート
  • IBM long doubleサポート

更に32bit,64bitコード向けのコード生成の改善を含む。
Freescale e500mcとe5500コア向けの命令スケジューリングサポートの追加

PTX/NVPTXターゲットの改善点(PTX/NVPTX Target Improvements)

PTXバックエンドはNVPTXバックエンドにより置き換えられた。
NVPTXバックエンドはNVIDIAによるCUDA(nvcc)とOpenCLコンパイラで使われているLLVMバックエンドをベースとしている。
いくつかの主な変更点は以下の通りです。

  • PTX3.1とSM3.4の互換性
  • NVIDIA Compiler SDKで定義されているでNVVM intrinsics向けのサポート
  • より多くのLLVm IRをカバーした古いPTXバックエンドとの完全な互換性

バックエンドのいかなるバグもLLVM Bugzillaに投稿するようにお願いします。

他のターゲット特有の改善点(Other Target Specific Improvements)
  • TargetLibraryInfoにおけるライブラリ関数のためのカスタム名のサポート追加
主な変更点と削除された機能(Major Changes and Removed Features)

ここでは以前のリリースからアップグレードしようとして陥るかもしれない"落とし穴"を挙げていきます

  • llvm-ldとllvm-stubは削除された。llvm-ldの機能は一部についてはllvm-link, opt, llc, ldに置き換えられ、Clangにより完全に置き換えられた。
  • MCJIT: インラインアセンブリのサポート(asm parserが必要), lliの'-remote-mcjit'のための疑似リモートターゲット実行の追加
内部APIの変更点(Internal API Changes)

多くのAPIがこのリリースで変更されている。
いくつかの主なLLVM APIの変更点は以下の通りである。

(CodeGenパスからだけではなく)IRレベルパスでターゲット特有の情報にアクセスを可能にするための新しいインターフェイスを追加した。
"TargetTransformInfo" と呼ばれる新しいIRレベルパスでは、いくつかの低レベルインタフェースを提供する。
LSRとLowerInvokeは既にこのインターフェイスを使っている。

構造体TargetDataはDataLayoutという名前に変更され、さらに(Targetに依存しないようにするために、Targetから)VMCoreに移動しました。

ツールの変更点(Tools Changes)

いくつかのツールがこのリリースで変更されました。変更点の一部は以下の通りです。

  • opt: '-mtriple'オプションのサポート追加
  • llvm-mc: '-show-inst'と-show-encoding'オプションのための'-disassemble'オプションのサポート, X86とARMターゲット向け注釈付きディスアセンブリ出力生成のための'-edis'オプションの追加
  • libprofile: プロファイルデータファイル名がLLVMPROF_OUTPUT環境変数により明示できるようにした
  • llvm-objdump: 利用可能なターゲットを表示するように変更した, '-arch'オプションでx86とx86-64が有効なarch名として認識されるようになった
  • llcとopt: '-enable-excess-fp-precision'オプションもしくは'-enable-unsafe-fp-math'オプションにより有効化される FADD + FMUL もしくは FSUB + FMULのペアーからFMA構成の追加
  • llc: llcからのオブジェクトファイル出力はもはや実験的とは思われていない。
  • gold プラグイン: Position Independent Executables (PIE)のサポート

既知の問題点

LLVMはプロダクション品質のコンパイラであり、幅広いアプリケーションで使われて多くの製品を輩出しています。
とは言え、全てのサブシステムが総体として成熟しているとは言えません(特にマイナーなターゲットにおいては)。
もし問題に遭遇した場合は、LLVMバグデータベース をチェックし、既知でない場合はバグを提出するかLLVM開発者ML で質問してください。

既知の問題点としては以下の通りです。

  • CellSPU, MSP430そしてXCoreバックエンドは実験的な段階です。 CellSPUバックエンドはLLVM 3.3で削除される予定です。
  • 統合アセンブラ, ディスアセンブラそしてJITはいくつかのターゲットではサポートされていません。統合アセンブラがサポートされていない場合、システムアセンブラが必要とされています。詳細はTarget Features Matrixを参照して下さい。

追加情報

LLVMウェブページ 、特にドキュメント では様々な追加情報が利用できます。
ウェブページにはSubversionにあるソースコードにあわせて更新されているAPIドキュメントもあります。
LLVMツリーの"llvm/branches/releases"のdocsディレクトリに行くと特定のリリースに対するドキュメントが取得可能です。

LLVMに関する質問やコメント等がありましたらメーリングリスト を通してお気軽にご連絡下さい。

きつねさんとおぼえるLLVM (LLVM解説本) をC83で出します


前回の「3日で出来るLLVM」にひきつづきLLVM解説本をC83で出します。
タイトルは表紙のきつねさんが特徴の「きつねさんとおぼえるLLVM」です。 LLVM狐本で覚えて下さい!
フロントエンド,ミドルエンドは柏木餅子(id:motipizza, @)、バックエンドは私が担当しました。
表紙は引き続き矢上さん(blog,tumblr)に書いて頂きました。
(前回同様タイトルと内容があっているとは限りません!!)

内容としては前回からの加筆修正版となっており、主な追加要素としてはJITコンパイルの方法, Passの書き方, バックエンドではオブジェクト生成の方法などがあります。
前回購入された方でも十分満足できる内容が追加されているのではないかと思います。
特に餅さんが担当したJITコンパイルのところは非常に面白い話になっています。
私が担当したバックエンドも構成を見直して全体的に書き直したのでわかりやすくなったと思います。
餅さんからは「やっとよめる日本語になった」とひどいありがたいお言葉を頂きました。
全体で224ページあり、前回から70ページ増加しています。もちろん追加部分以外の修正も多く含んでいます。

今回が初めてという方向けとして改めて本書についてご紹介します。
LLVMというコンパイラ基盤に興味があるけどわからない,遊んでみたいという方向けにLLVMを使ったコンパイラを実際に作りながら紹介するという本になっています。
フロントエンド(中間表現出力まで)、ミドルエンド(最適化)、バックエンド(オブジェクト生成)と幅広く解説していますので多くの方に有用な内容を含んでいるのではないかと思います。
ただし、本書の内容が全て正しいという保証はありません。
著者二人が趣味で遊んでいて、知っていることをまとめた程度だと思って頂いて構いません。
本書のボリュームからわかる通り非常に多くの内容を詰め込んでいますので、
それらを参考に改めて確認して頂ければ一から学習するよりも理解が早くなると思います。

以下、頒布場所の詳細になります。部数制限もないので知り合いの方に頼むなどして10部20部100部でも買って下さい!
コミックマーケット83
場所:東京ビッグサイト
サークル名:MotiPizza
日程:3日目 (12月31日)
スペース番号:東Y03a
値段: 1部 1200円
部数制限: 無し

追記
取り置きも可能になりました。
取り置き希望の方はこちらにコメントをお願いします。
今回は前回よりも多めに刷っていますので14時くらいまでは残っていると思いますが、
どうしてもという方はぜひご利用下さい。

以下、章構成

  • はじめに
    • 本書の構成
    • この本で何ができるようになるの?
    • 本書の目的とターゲット層
    • 本書を読むにあたって必要となるもの
    • 本書内の記載について
    • お断り
  • コンパイラとLLVM
  • 環境構築
    • 本章の概要と構成
    • 環境
    • インストール
    • ツールの種類と確認
  • LLVM IR
    • 本章の概要と目的
    • LLVM IRの特徴
    • LLVM IR の構成
    • LLVM の型とLLVM アセンブリの主な命令
    • 基本的なLLVMの中間表現
    • 条件文
    • ループ文
    • アグリゲート型へのアクセス
    • Metadata
  • フロントエンドを作る
    • 本章の概要
    • 構文規則の定義
    • 目標の設定
    • 字句解析
    • 構文解析
    • 意味解析
    • コード生成
    • main の作成
    • コンパイルと動作確認
    • mem2reg の適用と組込み関数の導入
    • JITをやってみる
    • Metadata を埋め込みたい場合
    • CommandLine ライブラリ
  • Passについて
    • Passの概念
    • Passの種類
    • その他のPass に実装すべきもの
    • 簡単なPass を実装してみる
    • 適用されるPass を確認する
  • バックエンドを作る
    • LLVMのバックエンドを学ぶ前に
    • LLVMのバックエンドって何するの?
    • バックエンドの流れ
    • 目標を決める
    • ターゲットの仕様を決める
    • TableGen
    • ターゲットのクラス構成
    • TableGenの記述(Sample.td)
    • 共通クラスの実装
    • SelectionDAGISelの実装
    • AsmPrinterの実装
    • フレーム処理の実装
    • Disassemblerの実装
    • その他の実装
    • コンパイルしよう!
    • バックエンドを作ってみて
  • あとがき
  • 索引
  • 参考資料

verilogをflymake

適当にさくっと作ってみた。

;; flymake settings for verilog mode
(defun flymake-verilog-init ()
  (let* ((temp (flymake-init-create-temp-buffer-copy 'flymake-create-temp-inplace))
         (local (file-relative-name temp (file-name-directory buffer-file-name))))
    (list "iverilog" (list "-tnull" local))))

;; iverilog error pattern
(add-to-list 'flymake-err-line-patterns
             '("\\(.*?\\):\\([0-9]+\\): \\(.*\\)$" 1 2 nil 3))

(add-hook 'verilog-mode-hook (lambda () (flymake-mode 1)))
(push '("\\.[v]\\'" flymake-verilog-init) flymake-allowed-file-name-masks)

llcで実行されるPass

llcを実行したときにどんなPassが実行されるか(PassManagerに追加されるか)が気になったのでざざっとしらべた。
ほぼ自分用のメモです。
createXXX はPassを生成する関数. XXXIDはIDからPassを生成?. どちらもその後PassManagerに追加.
最適化オプションによっては実行されないものや増えたりするものもあるので参考程度に。

PassManager::add()でPass名表示するようにしたみたけどだいたいあってそう。
最後に紹介する-debug-passの表示とはあってるのかよくわからない。

llc

  • main (tools/llc/llc.cpp)
    • LLVMTargetMachine::addPassesToEmitFile() (LLVMTargetMachine.cpp)
      • addPassesToGenerateCode
        • TargetPassConfig追加
        • TargetPassConfig::addIRPasses() (Pases.cpp)
          • createTypeBasedAliasAnalysisPass
          • createBasicAliasAnalysisPas
          • createLoopStrengthReducePass
          • createGCLoweringPass
          • createUnreachableBlockEliminationPass
        • addPassesToHandleExceptions() (LLVMTargetMachine.cpp)
        • TargetPassConfig::addISelPrepare() (Passes.cpp)
          • createCodeGenPreparePass
          • createStackProtectorPass
          • addPreISel() (Target毎に実装)
        • MachineModuleInfo追加
        • MachineFunctionAnalysis追加
        • addInstSelector() (Target毎に実装)
          • createXXXISelDag (XXXはTarget名)
        • TargetPassConfig::addMachinePasses (Passes.cpp)
          • ExpandISelPseudosID
          • TargetPassConfig::addMachineSSAOptimization (Passes.cpp)
            • OptimizePHIsID
            • LocalStackSlotAllocationID
            • DeadMachineInstructionElimID
            • MachineLICMID
            • MachineCSEID
            • MachineSinkingID
            • PeepholeOptimizerID
          • TargetPassConfig::addOptimizedRegAlloc (Passes.cpp)
            • LiveVariablesID
            • MachineLoopInfoID
            • PHIEliminationID
            • TwoAddressInstructionPassID
            • ProcessImplicitDefsID
            • RegisterCoalescerID
            • MachineSchedulerID
            • createRegAllocPass
            • addFinalizeRegAlloc()
            • StackSlotColoringID
            • PostRAMachineLICMID
          • addPostRegAlloc()
          • PrologEpilogCodeInserterID
          • TargetPassConfig::addMachineLateOptimization (Passes.cpp)
            • BranchFolderPassID
            • TailDuplicateID
            • MachineCopyPropagationID
          • ExpandPostRAPseudosID
          • addPreSched2() (Target毎に実装)
          • PostRASchedulerID
          • GCMachineCodeAnalysisID
          • TargetPassConfig::addBlockPlacement (Passes.cpp)
            • MachineBlockPlacementID
            • MachineBlockPlacementStatsID
          • addPreEmitPass() (Target毎に実装)
      • (End of addPassesToGenerateCode)
      • createAsmPrinter
      • createGCInfoDeleter

AsmPrinter

出力によって使用するMCStreamerが異なる.

  • アセンブリの場合
    • createAsmStreamer()
    • TargetRegistry::RegisterAsmStreamer()で登録しなければデフォルトのllvm::createAsmStreamer() (MCAsmStreamer.cpp)が使われる
    • MCAsmAstremaerクラス
  • オブジェクトの場合
    • createMCObjectStreamer()
    • TargetRegistry::RegisterMCObjectStreamer()で登録した関数

オプション

optやllcにオプションとして-debug-passを追加するとパスの情報を表示できる。(helpででてこないけどこれは便利)

  • debug-passで指定できるものは以下の通り。
  • None (デバッグ表示を無効化,デフォルト)
  • Arguments (optに渡される引数、つまり実行されるパスを表示)
  • Structure (パス情報をrun()の前に表示)
  • Executions (実行前にパス名を表示)
  • Details (実行中に詳細を表示)

下に行くほど詳細で、下のオプションを指定すればそれより上のオプションは全て有効になる。