software_development」カテゴリーアーカイブ

LLVM-IR(LLVM中間コード)用コンパイラの作り方 その3

前回の続き

yaccで作成した構文解析ソフトを加工して「骨組み(スケルトン)に肉付け」する形でコンパイラを作っていく。

例えば、文法の一部の、
 行 = 行番号 + 命令群
 命令群 = 命令 + 「:」 + 命令群 または 命令群 = 命令
と言う部分について、
構文を定義したyaccソースコード部分に追加で、その構文に対してどのような処理をするのかを書くことが出来る。

しかし、解釈した構文の処理は、コンパイラが出力すべき命令語の順番になっていない。
上記の例の場合には大きく順番が狂うことはないが、数式の処理の部分だと演算子の優先順位や括弧の処理で大きく順番が狂う。

これを解決するには”構文木”という二分木のツリー構造を使う。
続きを読む

LLVM-IR(LLVM中間コード)用コンパイラの作り方 その1

LLVM-IR(LLVM中間コード)を生成するTiny BASICコンパイラを作ったという話の補足。

コンパイラを作るのは、いくつか作らなければならない部品がある。

主に、「構文解析」と「コード生成」に分けられる。
まずは構文解析について。(追記 – コード生成については「その4」から)

構文解析は、コンパイラの言語の文法のルールに沿って、入力されたソースコードを解読して、解読した結果を出力する。

これがアセンブリ言語のような単純な文法の言語ならば、構文解析のソフトは1から手作りをして作ることができる。
予約語と変数(ラベル)と定数だけで、文法の並び順も単純だからだ。
解読した結果も、基本的には1次元の配列のようなものに順番に入れていけば良い。

BASICみたいな言語の場合、構文解析は少し複雑になるが、手作りで作ることはできる。
再帰下降パーサーという作り方で、文法要素を再帰のソフトで組んでいく方法だ。
中間言語を使う方式のBASICの場合、ソースコードの1行分だけを独立してパーサーに書けて1行分のコード出力を得るというのを、行数分だけ繰り返すという作り方もできる。

C言語やPascalみたいな言語の場合、構文解析はかなり複雑になるので手作りで作るのは困難になる。
そこでyaccやbisonというようなコンパイラコンパイラを用いる。(単純なBASICみたいな言語にも用いることができる)
コンパイラを作るためのメタコンパイラだ。
コンパイラ言語の文法のルールを、それ用の記述方式でソースコードに記述してコンパイラコンパイラに掛けると、構文解析用のパーサーソフトの部分を自動生成してくれるものだ。
解析して解読した結果は構文木というツリー構造のデータに入れるとよい。

コンパイラコンパイラについては、
古い参考書だけど、yaccによるCコンパイラプログラミングという本で自分はマスターした。
コンパイラ「Cm」を改造してみる


続く

LLVMの中間コードアセンブラを試す (Ubuntu編 & Windows編)

最近、LLVM-IR(LLVM中間コード)を生成するコンパイラを趣味で作っている。

これにはLLVMの中間コードアセンブラが必要なので、インストールしなくてはならない。
以前に、Ubuntu上でLLVMのソース一式を自前でビルドしたり、Mac OS X上でパッケージマネージャーでLLVM一式をインストールするのを試したりしていた。
Ubuntuマシンを初期化して中身を消してしまったり、MacについてはMacを使い慣れていないので、長いことコンパイラ作りが捗っていなかった。
やはり使い慣れているWindowsPC上で作業したいと思い、インストール方法を探してみた。
(Windows PC上で作業できるようになってからは、作業が捗ったので1週間ちょっとでコンパイラができた。もっと早くやっておけばよかった。)
続きを読む

NGK2015B(名古屋合同懇親会 2015 忘年会)に行ってきた

NGK2015B(名古屋合同懇親会 2015 忘年会)に行ってきた。
名古屋のIT系勉強会によるコミュニティ合同の忘年会的なイベントだ。
20151205_132829
参加者は各勉強会の主催者や関係者が多かった。
自分は勉強会関係者というわけではないが、幾つかの勉強会に割と参加していたりする。
昼の部はLT大会ということで、自分も先週作ったばかりの発表をした。
LLVM-IR(LLVM中間コード)を生成するTiny BASICコンパイラを作ってみた
続きを読む

LLVM-IR(LLVM中間コード)を生成するTiny BASICコンパイラを作ってみた

LLVM中間コードを生成するTiny BASICコンパイラを作ってみた
(元の記事はこちらに書いていたものをblogに書き直ししている)

以前、CIL(MSIL)中間コードを生成するTiny BASICコンパイラというのを作ってみた。(2012-09-01)
それを元にJavaバイトコードを生成するTiny BASICコンパイラを作ってみた。(2013-03-01)
今回、これらをベースにLLVM中間コード(LLVM-IR)を生成するTiny BASICコンパイラを作ってみた。(2015-12-04)

1. つくってみたもの

 Tiny Basic Compiler (LLVM中間コード版)

 [ Tiny Basic Compiler 実行ファイル+ソースコード tinybas_llvm-ir_01.zip (download) ]

 特徴
 ・整数型の小型なBASIC
 ・シンプルな言語仕様なのでソースコードも短く、コンパイラの仕組みを学習するサンプルとして活用できる

2. 使い方

 BASICのソースコードをコンパイルし、出力される.llファイルをllvm-asというLLVM-IR用のアセンブラを使ってアセンブルして.bcファイルを生成する。
 lliを使ってビットコードファイルをインタープリタ実行することができる。

 順番に手順を説明すると以下のとおり。

 サンプルのソースコードは例えば次のようになる。(example1.bas)

10 INPUT X
20 Y= x*x + 6*x + 9
30 PRINT Y

 コマンドラインで、次のようにコマンド入力してコンパイルする。
 % tinybas example1.bas

 結果、example1.ll が得られる。
 この.ll ファイルはllvm-as用のアセンブリーソースコードである。
 llvm-asを使って.bcファイルを作る。
 % llvm-as example1.ll
 で、example1.bcが作られる。

 実行するには、次のようにする。
 % lli example1.bc

 ちなみにアセンブリーソースコード(example1.llファイル)は、以下のように生成される。

;============================================================
;	Compiler: Tiny Basic Compiler Ver 0.1
;	Source: example1.bas
;	Object: example1.ll
;============================================================

@.1 = private unnamed_addr constant [4 x i8] c"%d\0A\00", align 1
@.2 = private unnamed_addr constant [3 x i8] c"?\0A\00", align 1
@buf = common global [1024 x i8] zeroinitializer, align 1
declare i32 @printf(i8*, ...) nounwind
declare i8* @gets(i8*) nounwind
declare i32 @atoi(i8*) nounwind

define i32 @main() {
;------------------------------------
	%acc = alloca i32 , align 4
	br label %_L10

_L10:
	%_V0 = alloca i32 , align 4
	%1 = call i32(i8*,...)* @printf(i8* getelementptr inbounds([3 x i8]* @.2, i32 0, i32 0)) nounwind
	%2 = call i8* @gets(i8* getelementptr inbounds ([1024 x i8]* @buf, i32 0, i32 0)) nounwind
	%3 = call i32 @atoi(i8* getelementptr inbounds ([1024 x i8]* @buf, i32 0, i32 0)) nounwind
	store i32 %3, i32* %_V0 ,align 4
	br label %_L20

_L20:
	%_V1 = alloca i32 , align 4
	%4 = load i32* %_V0, align 4
	store i32 %4, i32* %acc
	%5 = load i32* %acc, align 4
	%6 = load i32* %_V0, align 4
	store i32 %6, i32* %acc
	%7 = load i32* %acc, align 4
	%8 = mul nsw i32 %5, %7
	store i32 %8, i32* %acc
	%9 = load i32* %acc, align 4
	store i32 6 , i32* %acc, align 4
	%10 = load i32* %acc, align 4
	%11 = load i32* %_V0, align 4
	store i32 %11, i32* %acc
	%12 = load i32* %acc, align 4
	%13 = mul nsw i32 %10, %12
	store i32 %13, i32* %acc
	%14 = load i32* %acc, align 4
	%15 = add nsw i32 %9, %14
	store i32 %15, i32* %acc
	%16 = load i32* %acc, align 4
	store i32 9 , i32* %acc, align 4
	%17 = load i32* %acc, align 4
	%18 = add nsw i32 %16, %17
	store i32 %18, i32* %acc
	%19 = load i32* %acc, align 4
	store i32 %19, i32* %_V1 ,align 4
	br label %_L30

_L30:
	%20 = load i32* %_V1, align 4
	store i32 %20, i32* %acc
	%21 = load i32* %acc, align 4
	%22 = call i32(i8*,...)* @printf(i8* getelementptr inbounds([4 x i8]* @.1, i32 0, i32 0), i32 %21) nounwind
	br label %_END

_END:
;------------------------------------
	ret i32 0
}

Java版TinyBasicやMSIL版TinyBasicに比べると、冗長なコードが多い。
LLVM-IRのコード生成はSSA(静的単一代入形式)などの仕組みが少し難しく、うまいコード生成が作れなかった。

このページの上記の説明では説明不足なので、blogで補足を書き足していく予定。

上記のページに書いただけでは説明不足なので、こちらのblogで補足説明を書いていく予定。(週1くらいで)

全天球撮影用カメラ「THETA」用のサムネイル画像をアニメーションGIFで生成する

全天球撮影用カメラ「THETA」用のサムネイル画像をアニメーションGIFで生成する。
(元の記事はこちらに書いていたものをblogに書き直ししている)

TiltShiftの画像処理&アニメーションGIF生成のソフトを自作してみた。
[ Theta-Thumbnail version 0.1 ソースコード付き (download) ]

OpenCVのバージョン2.4を使用しており、ビルドにはOpenCVが必要。
GIFファイル操作のため、imgctl.dllというライブラリを使用している。
imgctl.dllとOpenCVを使ってGIFアニメーションを出力するコードを書いてみた

ビルドしなくても、実行ファイル(.exe)を起動して使うことができる。
Visual Studioを持っていない場合、実行ファイルを動かすのにVCのRuntimeをインストールしないといけないかもしれない。

THETAで撮影した画像ファイルをPCに取り出して、このソフトで処理すると、サムネイルサイズのアニメーションGIF画像ファイルが出力される。

生成されたアニメーションGIFファイルは以下のようになる。

このソフトを使うには、THETAで天地を正しく撮影したJPEG画像ファイルでないといけない。
リコー公式のWindows/Mac版のTHETA用ビューワーを使って天頂補正書き出しをすることで天地を補正した画像が得られるので、それを使えばよい。
全天球カメラRICOH THETA用アプリ更新。JPG保存や Google+ / Google マップ公開に対応


参考Link

THETA公式 http://theta360.com/ja/
リコー、全天球撮影カメラ「THETA」発売 ワンショットで上から下まで360度キャプチャ – ITmedia ニュース
360度全天球写真カメラ『THETA』で世界をぐるぐる回してみた
全天球撮影用カメラ「THETA」を使ってみる – 釣竿で空中撮影

Oculus Rift勉強会 関西#02に行ってきた

Oculus Rift勉強会 関西#02に行ってきた。
20151101_140059
内容はこんな感じだった。
・アーティフィスのVR/AR開発の話
Oculus Rift入門まとめ
猫でも分かるOculus警察撃退法
THETAでモバイルVRコンテンツ開発
・VRはどれくらいあなたの身近にやってくる?
・Unity-chan CRSをGear VRで60FPS動作するために行った事
・LT Gear VRを10倍楽しむ方法
・LT GoPro以外で、360videoを撮ってみる方法
・LT Bullet TrainとOculus Touchの衝撃
・LT WindowsとBluetoothLEマイコンでコントローラーを作ってみよう
続きを読む