ひでみのアイデア帳

くだらないことなんだけど、忘れないために・・・

LLVM環境の構築

LLVMはどんな中間言語を吐くか気になったので・・・

% tar xJvf llvm-3.5.0.src.tar.xz

% tar xJvf cfe-3.5.0.src.tar.xz

% tar xJvf compiler-rt-3.5.0.src.tar.xz

% cd llvm-3.5.0.src

% mv ../cfe-3.5.0.src ./tools/clang

% mv ../compiler-rt-3.5.0.src ./projects/compiler-rt

% mkdir /usr/local/llvm

% make

インストール後はパスを通す。

export PATH=$PATH:/usr/local/llvm/bin

ubuntuの場合llvmはgcc 4.7以上が必要になる。

ubuntuでgccが古い場合は下記のようにデフォルトのgccを4.8などにする。

sudo apt-get install gcc-4.8

sudo update-alternatives --set gcc /usr/bin/gcc-4.8

サンプルソース// test.c

include <stdio.h>

int main()

{

    int i = 0;

    for (i = 0; i < 99; i++) printf("hello, world %d\n", i),

    return 0;

}

コンパイル$ clang test.c -v

clang version 3.5.0 (tags/RELEASE_350/final)

Target: x86_64-unknown-linux-gnu

Thread model: posix

Found candidate GCC installation: /usr/lib/gcc/i686-linux-gnu/4.8

Found candidate GCC installation: /usr/lib/gcc/i686-linux-gnu/4.8.2

Found candidate GCC installation: /usr/lib/gcc/i686-linux-gnu/4.9

Found candidate GCC installation: /usr/lib/gcc/i686-linux-gnu/4.9.1

Found candidate GCC installation: /usr/lib/gcc/x86_64-linux-gnu/4.4

Found candidate GCC installation: /usr/lib/gcc/x86_64-linux-gnu/4.4.7

Found candidate GCC installation: /usr/lib/gcc/x86_64-linux-gnu/4.5

Found candidate GCC installation: /usr/lib/gcc/x86_64-linux-gnu/4.5.3

Found candidate GCC installation: /usr/lib/gcc/x86_64-linux-gnu/4.6

Found candidate GCC installation: /usr/lib/gcc/x86_64-linux-gnu/4.6.4

Found candidate GCC installation: /usr/lib/gcc/x86_64-linux-gnu/4.8

Found candidate GCC installation: /usr/lib/gcc/x86_64-linux-gnu/4.8.2

Found candidate GCC installation: /usr/lib/gcc/x86_64-linux-gnu/4.9

Found candidate GCC installation: /usr/lib/gcc/x86_64-linux-gnu/4.9.1

Selected GCC installation: /usr/lib/gcc/x86_64-linux-gnu/4.8

Candidate multilib: .;@m64

Candidate multilib: 32;@m32

Candidate multilib: x32;@mx32

Selected multilib: .;@m64

 "/usr/local/llvm/bin/clang" -cc1 -triple x86_64-unknown-linux-gnu -emit-obj -mrelax-all -disable-free -main-file-name test.c -mrelocation-model static -mdisable-fp-elim -fmath-errno -masm-verbose -mconstructor-aliases -munwind-tables -fuse-init-array -target-cpu x86-64 -target-linker-version 2.24 -v -dwarf-column-info -resource-dir /usr/local/llvm/bin/../lib/clang/3.5.0 -internal-isystem /usr/local/include -internal-isystem /usr/local/llvm/bin/../lib/clang/3.5.0/include -internal-externc-isystem /usr/include/x86_64-linux-gnu -internal-externc-isystem /include -internal-externc-isystem /usr/include -fdebug-compilation-dir /home/h-ishihara/workspace/llvm -ferror-limit 19 -fmessage-length 80 -mstackrealign -fobjc-runtime=gcc -fdiagnostics-show-option -fcolor-diagnostics -o /tmp/test-717d05.o -x c test.c

clang -cc1 version 3.5.0 based upon LLVM 3.5.0 default target x86_64-unknown-linux-gnu

ignoring nonexistent directory "/include"

include "..." search starts here:

include <...> search starts here:

 /usr/local/include

 /usr/local/llvm/bin/../lib/clang/3.5.0/include

 /usr/include/x86_64-linux-gnu

 /usr/include

End of search list.

 "/usr/bin/ld" -z relro --hash-style=gnu --build-id --eh-frame-hdr -m elf_x86_64 -dynamic-linker /lib64/ld-linux-x86-64.so.2 -o a.out /usr/lib/gcc/x86_64-linux-gnu/4.8/../../../x86_64-linux-gnu/crt1.o /usr/lib/gcc/x86_64-linux-gnu/4.8/../../../x86_64-linux-gnu/crti.o /usr/lib/gcc/x86_64-linux-gnu/4.8/crtbegin.o -L/usr/lib/gcc/x86_64-linux-gnu/4.8 -L/usr/lib/gcc/x86_64-linux-gnu/4.8/../../../x86_64-linux-gnu -L/lib/x86_64-linux-gnu -L/lib/../lib64 -L/usr/lib/x86_64-linux-gnu -L/usr/lib/gcc/x86_64-linux-gnu/4.8/../../.. -L/usr/local/llvm/bin/../lib -L/lib -L/usr/lib /tmp/test-717d05.o -lgcc --as-needed -lgcc_s --no-as-needed -lc -lgcc --as-needed -lgcc_s --no-as-needed /usr/lib/gcc/x86_64-linux-gnu/4.8/crtend.o /usr/lib/gcc/x86_64-linux-gnu/4.8/../../../x86_64-linux-gnu/crtn.o

他いろいろclang -emit-llvm -S test.c

-> test.ll

lli test.ll

llvm-as test.ll

-> test.bc

llc test.ll

-> test.s

やっと中間コードtest.llは次のように出力される。

; ModuleID = ''test.c''

target datalayout = "e-m:e-i64:64-f80:128-n8:16:32:64-S128"

target triple = "x86_64-unknown-linux-gnu"

@.str = private unnamed_addr constant [17 x i8] c"hello, world %d\0A\00", align 1

; Function Attrs: nounwind uwtable

define i32 @main() #0 {

entry:

  %retval = alloca i32, align 4

  %i = alloca i32, align 4

  store i32 0, i32* %retval

  store i32 0, i32* %i, align 4

  br label %for.cond

for.cond:                                         ; preds = %for.inc, %entry

  %0 = load i32* %i, align 4

  %cmp = icmp slt i32 %0, 99

  br i1 %cmp, label %for.body, label %for.end

for.body:                                         ; preds = %for.cond

  %1 = load i32* %i, align 4

  %call = call i32 (i8, ...) @printf(i8 getelementptr inbounds ([17 x i8] @.str, i32 0, i32 0), i32 %1)

  br label %for.inc

for.inc:                                          ; preds = %for.body

  %2 = load i32* %i, align 4

  %inc = add nsw i32 %2, 1

  store i32 %inc, i32* %i, align 4

  br label %for.cond

for.end:                                          ; preds = %for.cond

  ret i32 0

}

declare i32 @printf(i8*, ...) #1

attributes #0 = { nounwind uwtable "less-precise-fpmad"="false" "no-frame-pointer-elim"="true" "no-frame-pointer-elim-non-leaf" "no-infs-fp-math"="false" "no-nans-fp-math"="false" "stack-protector-buffer-size"="8" "unsafe-fp-math"="false" "use-soft-float"="false" }

attributes #1 = { "less-precise-fpmad"="false" "no-frame-pointer-elim"="true" "no-frame-pointer-elim-non-leaf" "no-infs-fp-math"="false" "no-nans-fp-math"="false" "stack-protector-buffer-size"="8" "unsafe-fp-math"="false" "use-soft-float"="false" }

!llvm.ident = !{!0}

!0 = metadata !{metadata !"clang version 3.5.0 (tags/RELEASE_350/final)"}

まとめtest.llは非常にソースコードを展開しただけなので、厳密なことは言えないが、forラベルの括りで処理すればパイプラインでH/W化が可能なのが見て分かる。

CソースコードをH/Wするには、処理形態はプロセッサーに似たような作りになってしまうのは仕方がないことである。

どこまで並列性、パイプライン性を持たせることができるかで処理性能が決まるといって過言ではない。

おまけ(備忘録)ELLCC

http://ellcc.org/

Clang+LLVMで組み込み向けクロスコンパイラの作成

MicroBlazeのコンパイルをサポートしているらしい。

fairy

https://gitorious.org/fairy/llvm-fairy

これが何者かが分からないがMicroBlazeのコンパイラで引っかかった。

Writing an LLVM Backend

http://llvm.org/docs/WritingAnLLVMBackend.html

LLVM language Reference Manual

LLVMをするにあたって、これも読まなければいけない。

http://llvm.org/docs/LangRef.html

DCPU-16用LLVMバックエンド

https://news.ycombinator.com/item?id=3813302

Legup

http://legup.eecg.utoronto.ca/

MIPS+H/Wアクセラレーション

Alteraが中心でAvalonバスを使用する。