読者です 読者をやめる 読者になる 読者になる

LLVM 3.1 リリースノートの訳

LLVM

LLVM3.1が予定より一週間ほど遅れてリリースされました。
今回もいろいろなアップデートがあるのでLLVM 3.1 Release Notesを翻訳します。
訳がかなり怪しいところが一部あります。

イントロダクション

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

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

サブプロジェクトの更新状況

LLVM3.1ディストリビューションはLLVMのコアリポジトリ(最適化機構, コード生成器, サポートツールなど)とClangリポジトリで構成されています。更に、LLVMプロジェクトには開発中のサブプロジェクトを含んでいます。ここでは3つのサブプロジェクトの更新を記します。

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

ClangはC,C++,Objective-CのためのLLVMフロントエンドです。Clangはわかりやすい診断メッセージ, 言語標準規格に忠実, 高速かつメモリ使用量の少ないコンパイルという特徴を持ち、
より良いユーザ体験を提供することを目的としています。Clangはx86(32,64ビット),Darwin,ARM環境では、プロダクションで利用できる品質のC,C++,Objective-C,Objective-C++のコンパイラと考えられています。

LLVM3.1ではClangチームが大きな改善を果たしています。以下が主な変更点です。

Clangのリリース3.0からの変更点についての詳細は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.1では主に次のような変更点があります。

  • GCC4.7の部分的なサポート。Adaサポートが不十分だがそれ以外の言語は正しく動作する。
  • ARMプロセッサのサポート。ARM向けにDragonEggをビルドするために必要とされるGCCヘッダのいくつかがGCCによってインストールされないため、動作させるにはGCCソースツリーから必要なヘッダをコピーする必要がある。
  • Fortranの最適化。Fortranのスカラ引数は'restrict'セマンティクスを持つことを利用している。
  • 全言語向けの最適化。type aliasingとtype rangesに関する情報をLLVM最適化機構に渡している。
  • リグレッションテスト(回帰テスト)スイートの追加。
compiler-rt: Compiler Runtime Library

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

3.1ではcompiler-rtは、任意サイズの量に対するatomic操作を許可するatomic操作のヘルパ関数を含んでいる。これらの関数はgccで定義された仕様に従い、clangで利用される。

LLDB: Low Level Debugger

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

libc++: C++ Standard Library

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

  • compiler-rtでできたサポートコードをclangでコンパイル時に、ヘッダが全てのテストが通った。
  • FreeBSDが基盤システムの一部としてlibc++を含んでいる。
  • libc++がSolarisに移植され、libcxxrtとclangの組み合わせが既存コードの大部分で動作している。
VMKit

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

LLVM3.1では、VMKitは実行速度と起動速度の両方で大きな改善を行った。

Polly: Polyhedral Optimizer

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

LLVM3.1では次の見所がある。

  • PollyがLLVMの公式プロジェクトになった。
  • Pollyがclangに直接ロードできるようになった。('-O3 -mllvm -polly'で有効化)
  • 自動スケジュール最適化(Pluto由来の)が統合された。この最適化ではデータ局所性と並列性のためのループ変換を行う。ループ変換に含まれているものとしては、interchange, fusion, fission, skewingそしてtilingなどがあります。

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

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

Crack

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

FAUST

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

Glasgow Haskell Compiler (GHC)

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

Julia

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

LLVM D Compiler

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

Open Shading Language

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

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.54はテストされてLLVM3.1で動作するようになった。また、LLVMリリース2.5以降の古いバージョンでも動作するように開発している。

TTA-based Co-design Environment (TCE)

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

LLVM 3.1の変更点

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

主な新機能

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

LLVM IR(中間表現)とコアの改善点

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

  • 16ビットの半精度浮動小数点の追加。
  • 中間表現がベクタGEPを含むポインタのベクタをサポート。
  • モジュールフラグが導入された。モジュールに関する情報がまとめてLLVMのサブシステムに渡されます。今のところObjective-CのABI情報をエンコードするために利用されています。
  • ロードされる可能性がある値を表現するために、ロードは添付されたメタデータの範囲を持つ。
  • llvm.ctlzとllvm.cttz命令は追加引数を持つようになった。この引数によってゼロ入力のときに命令の振る舞いが未定義になるかどうか決まる。これは0のビットを数えるときに型サイズを返さない命令を持つプラットフォームにおいて更に最適化されたコードを生成するために利用される。
最適化機構の改善点

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

  • ループアンロールパスで実行時にループ回数をカウントしながらループをアンロール可能に。この機能はデフォルトで無効化されており、-unroll-runtimeフラグで有効化できる。
  • 基本ブロック自動ベクトル化パスが利用可能に。このパスを実行するには、-vectorizeオプションを関連するpost-vectorization cleanupパスとともに渡すこと。詳細な情報はEuroLLVM2012のスライド(Autovectorization with LLVM)を参照して下さい。
  • インラインのコストヒューリスティックが完全に整備され、関数呼び出しを通した定数伝播や自明なデッドコードコストの無視、そしてC++ STLのイテレータパターンの厳密なモデル化が可能に。
MCレベルの改善点

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

  • アセンブリファイル(.s)をアセンブル時に統合アセンブラがオプションでデバッグ情報を出力できるようになった。これはllvm-mcに-gオプションを渡すことで有効化できる。
ターゲット独自のコード生成器の改善点

Type Legalizerがベクタを認証する方法を変更した。今後はType Legalizerは整数要素を昇格しようとする。これによりvector-selectの実装が可能になった。更に、charやshortのベクタを使うような場面では、SIMD命令が有効な32ビット型として昇格されるため、性能が大きく改善されたことを確認した。浮動小数点型は従来通り拡張される。

コード生成器の基盤に著しい改良を行った。その結果、更に積極的なアルゴリズムの実装が可能になり、速度が向上した。

  • TableGenは、制約の組み合わせを表すためだけに使われるレジスタクラスを命令とサブレジスタから合成することができるようになった。合成レジスタクラスは直近のユーザ定義の親クラスから性質を継承するようになった。
  • MachineRegisterInfoは、レジスタ割り当ての開始時に予約レジスタの固定をできるようにした。
  • MachineOperandの新しい種類は命令呼び出しで破壊されるレジスタ(clobber)の一覧をコンパクトな表現で提供する。レジスタマスクオペランドは保存されたレジスタのビットマスクで参照し、それ以外は破壊されている。
  • name accelerator tables DWARF extensionのためのデータ出力がサポートされた。これは名前参照の高速化のためにLLDBで使われている。

Very Long Instruction Word(VLIW)アーキテクチャ用のビルドをサポートするためにTableGen基盤を追加した。TableGenは、命令群を束にできるかどうかを定義したVLIWターゲットのスケジュール記述から決定性有限オートマトン(DFA)を自動生成する。

マシン命令をまとめるためのDFA基盤を基にしたターゲット非依存の新しいVLIW packetizer(パケット化)を追加した。

基本ブロック配置

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

X86-32とX86-64ターゲットの改善点

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

  • AVX2サポートの大きな改善
  • AVX1の改善と大量のバグ修正
  • FMA4とXOP命令セット拡張のサポート
  • 高速なコンパイルと異なる呼び出し規約サポートのためにCall命令はレジスタマスクオペランドを利用する
  • DW2例外ハンドリングがCygwinとMinGWで有効化
  • MSVCランタイムで使われる暗黙的TLSモデルのサポート
ARMターゲットの改善点

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

  • constant islandパスは基本ブロックとconstant pool entryの4バイト以上のアラインメントをサポート
  • DarwinにおいてARMターゲットのフル機能の統合アセンブラが対応
ARM統合アセンブラ

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

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

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

MIPSターゲットの改善点

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

  • MIPS32リトルエンディアンの直接オブジェクトコード出力が実用的に
  • long double型(f128)の例外ハンドリング付きのアセンブリ出力(assembly printing)モードにおいて、N64 ABI向けのMIPS64リトルエンディアンのコード生成器がかなり実用的に
  • 新命令に対するサポートが追加。swap-bytes命令(WSBHとDSBH)、浮動小数点のmultiply-add/subtractと負数のmultiply-add/subtract命令、レジスタ+レジスタアドレッシング付きの浮動小数点load/store命令(LWXC1)など。
  • 性能を改善するいくつかの修正
  • Post-RAスケジューリングが-O3オプションで有効化
  • soft-floatのコード生成のサポートが追加
  • MIPS64ビットターゲット向けのclangドライバがサポート
  • clangにおけるMIPS浮動小数点ABIオプションのサポート
PTXターゲットの改善点

極めて目立った条件的逆転(conditional inversion)のバグ修正がこのリリースに含まれています。

注意: LLVM3.1は現時点のものをPTXバックエンドの最後のリリースとしている。PTXバックエンドは現在NVPTXバックエンドに置き換えられている途中であり、SVNにある。

他のターゲット特有の改善点
  • QualcommのHexagon VLIWプロセッサのサポートが追加
主な変更点と削除された機能

あなたが既にLLVM3.1の変更点の一部を利用しているLLVMのユーザか開発者なら、この節ではいくつか既知の情報を挙げている。

  • LLVMのビルドシステムはビルド時にpython2インタプリタを必要とする。Perlインタプリタはもはや必要とされない。
  • Cバックエンドは削除された。いくつかの重要なプログラムがコンパイルできないという問題点があったためです。
  • Alpha, Blackfin, SystemZターゲットがメンテナンスが不十分なため削除されました。
  • LLVM3.1はLLVM2.9のビットコードファイルを読み込みのサポートを削除しました。将来はLLVMの未来の全てのバージョン向けに、LLVM3.0以降で生成されたビットコードファイルと.llファイルを読むことを目指す。
  • unwind命令が無くなりました。LLVM3.0では新しい例外ハンドリングシステムの命令があるため、unwind命令は廃止されました。
  • LLVM3.0とそれ以前は名前に応じてsetjmpのような関数に対してreturns_twiceを自動的に追加していました。この機能は3.1では削除されました。-ffreestandingオプションが使われると有効になります。
内部APIの変更点

多くのAPIがこのリリースで変更されました。以下がLLVM APIの主な変更点の一部です。

  • 新しいTargetOptionsクラスではターゲット特有のオプションがグローバル変数からメンバ変数に移動されました。結果として、関連するフラグがclangの-mllvmオプションによって対応されなくなりました。
    • llvm::PrintMachineCode
    • llvm::NoFramePointerElim
    • llvm::NoFramePointerElimNonLeaf
    • llvm::DisableFramePointerElim(const MachineFunction &)
    • llvm::LessPreciseFPMADOption
    • llvm::LessPrecideFPMAD()
    • llvm::NoExcessFPPrecision
    • llvm::UnsafeFPMath
    • llvm::NoInfsFPMath
    • llvm::NoNaNsFPMath
    • llvm::HonorSignDependentRoundingFPMathOption
    • llvm::HonorSignDependentRoundingFPMath()
    • llvm::UseSoftFloat
    • llvm::FloatABIType
    • llvm::NoZerosInBSS
    • llvm::JITExceptionHandling
    • llvm::JITEmitDebugInfo
    • llvm::JITEmitDebugInfoToDisk
    • llvm::GuaranteedTailCallOpt
    • llvm::StackAlignmentOverride
    • llvm::RealignStack
    • llvm::DisableJumpTables
    • llvm::EnableFastISel
    • llvm::getTrapFunctionName()
    • llvm::EnableSegmentedStacks
  • MDBuilderクラスがメタデータの生成を簡易化するために追加されました。
ツールの変更点

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

  • llvm-stressは異なるLLVMコンポーネントを覆うためにランダムで.llファイルを生成するためのコマンドラインツールです。
  • llvm-ldツールが削除されました。clangドライバが複数のビットコードファイルをバイナリに変換するためのより信頼できる方法を提供します。ビットコードファイルをマージするにはllvm-linkが利用できます。
Pythonバインディング

公式にサポートされたPythonバインディングが追加されました。完全な機能のサポートはまだまだです。現在のバインディングでサポートしているインタフェースは以下の通りです。

  • オブジェクトファイルインタフェース
  • ディスアセンブラ

オブジェクトファイルインタフェースを使うことで、バイナリオブジェクトファイルを検査することができます。readelfやllvm-objdumpのpython版だと思って下さい。

追加機能のサポートはコミュニティ貢献者によって現在開発中です。Pythonバインディングの方向性に興味がある方は、IRCか開発者MLで意志を表明して下さい。

既知の問題点

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

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

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

追加情報

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

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