clangの概要
# 下記はすべてllvm-2.8
Clangは、各種ソースファイル(C/C++/Obj-C)をコンパイルすることができる。
Clangは細かくモジュール化されており、各モジュールをDriverが制御する。
※例えば、-O4でコンパイルした場合、LLVMのモジュールやgccをDriverが呼び出し、
※実行ファイル生成まで行う。
一般的なコンパイルの流れは下記フェーズからなる
- c -emit-llvmの場合
字句解析・構文解析・意味解析
C/C++/Obj-Cソースコードを読み込む
ASTに変換する
AST(Abstract Syntax Tree)の生成
ASTをファイルに出力する
ASTをファイルから読み込む
Analyzer
ASTを解析する
結果を出力する
CodeGen(BitCodeの生成)
ASTをBitCodeに変換する
最適化オプション
-O3 optの-std-compile-optsと同様の最適化を行う。 -O4 LinkTimeOptimizeを行う。上記に加えて、-std-link-optsを行う。 (記憶が正しければ -O4 -c と -O3 -emit-llvm はほぼ等価)
デバッグ用のオプション
-Xclang -ast-dump -Xclang -std-view -Xclang -dump-raw-tokens -Xclang -dump-tokens -Xclang -print-stats -Xclang -ftime-report
--analyze -Xanalyzer -cfg-view -Xanalyzer -cfg-dump
入力Cソースファイル
int max(int x, int y) {
if (x > y) return x; else return y;
}
int func(int N, int array[]) {
int i; int ret=0; for (i=0; i<N; i++) { ret += max(array[i], ret); } return ret;
}
中間生成のASTファイル
int max(int x, int y) (CompoundStmt 0xbe02620 <test001.c:2:23, line:5:1>
(IfStmt 0xbe02600 <line:3:3, line:4:15> <<<NULL>>> (BinaryOperator 0xbe02570 <line:3:7, col:11> 'int' '>' (DeclRefExpr 0xbe02530 <col:7> 'int' ParmVar='x' 0xbe02420) (DeclRefExpr 0xbe02550 <col:11> 'int' ParmVar='y' 0xbe02460)) (ReturnStmt 0xbe025b0 <col:14, col:21> (DeclRefExpr 0xbe0258c <col:21> 'int' ParmVar='x' 0xbe02420)) (ReturnStmt 0xbe025e8 <line:4:8, col:15> (DeclRefExpr 0xbe025c4 <col:15> 'int' ParmVar='y' 0xbe02460))))
int func(int N, int array[]) (CompoundStmt 0xbe02b28 <test001.c:7:30, line:14:1>
(DeclStmt 0xbe027c0 <line:8:3, col:8> 0xbe02790 "int i") (DeclStmt 0xbe02840 <line:9:3, col:12> 0xbe027f0 "int ret = (IntegerLiteral 0xbe02820 <col:11> 'int' 0)") (ForStmt 0xbe02ac8 <line:10:3, line:12:3> (BinaryOperator 0xbe02898 <line:10:8, col:10> 'int' '=' (DeclRefExpr 0xbe02854 <col:8> 'int' Var='i' 0xbe02790) (IntegerLiteral 0xbe02878 <col:10> 'int' 0)) <<<NULL>>> (BinaryOperator 0xbe02908 <col:13, col:15> 'int' '<' (DeclRefExpr 0xbe028c8 <col:13> 'int' Var='i' 0xbe02790) (DeclRefExpr 0xbe028e8 <col:15> 'int' ParmVar='N' 0xbe02650)) (UnaryOperator 0xbe02948 <col:18, col:19> 'int' postfix '++' (DeclRefExpr 0xbe02924 <col:18> 'int' Var='i' 0xbe02790)) (CompoundStmt 0xbe02aa8 <col:23, line:12:3> (CompoundAssignOperator 0xbe02a80 <line:11:5, col:29> 'int' '+=' ComputeLHSTy='int' ComputeResultTy='int' (DeclRefExpr 0xbe02960 <col:5> 'int' Var='ret' 0xbe027f0) (CallExpr 0xbe02a50 <col:12, col:29> 'int' (ImplicitCastExpr 0xbe02a38 <col:12> 'int (*)(int, int)' <FunctionToPointerDecay> (DeclRefExpr 0xbe02980 <col:12> 'int (int, int)' FunctionDecl='max' 0xbe024d0)) (ArraySubscriptExpr 0xbe029e0 <col:16, col:23> 'int' (DeclRefExpr 0xbe029a0 <col:16> 'int *' ParmVar='array' 0xbe026b0) (DeclRefExpr 0xbe029c0 <col:22> 'int' Var='i' 0xbe02790)) (DeclRefExpr 0xbe029fc <col:26> 'int' Var='ret' 0xbe027f0))))) (ReturnStmt 0xbe02b10 <line:13:3, col:10> (DeclRefExpr 0xbe02af0 <col:10> 'int' Var='ret' 0xbe027f0)))
出力BitCodeファイル
; ModuleID = 'test001.bc'
target datalayout = "e-p:32:32:32-i1:8:8-i8:8:8-i16:16:16-i32:32:32-i64:32:64-f32:32:32-f64:32:64-v64:64:64-v128:128:128-a0:0:64-f80:32:32-n8:16:32"
target triple = "i386-pc-linux-gnu"
define i32 @max(i32 %x, i32 %y) nounwind {
entry:
%retval = alloca i32, align 4 %x.addr = alloca i32, align 4 %y.addr = alloca i32, align 4 store i32 %x, i32* %x.addr, align 4 store i32 %y, i32* %y.addr, align 4 %tmp = load i32* %x.addr, align 4 %tmp1 = load i32* %y.addr, align 4 %cmp = icmp sgt i32 %tmp, %tmp1 br i1 %cmp, label %if.then, label %if.else
if.then: ; preds = %entry
%tmp2 = load i32* %x.addr, align 4 store i32 %tmp2, i32* %retval br label %return
if.else: ; preds = %entry
%tmp3 = load i32* %y.addr, align 4 store i32 %tmp3, i32* %retval br label %return
return: ; preds = %if.else, %if.then
%0 = load i32* %retval ret i32 %0
}
define i32 @func(i32 %N, i32* %array) nounwind {
entry:
%N.addr = alloca i32, align 4 %array.addr = alloca i32*, align 4 %i = alloca i32, align 4 %ret = alloca i32, align 4 store i32 %N, i32* %N.addr, align 4 store i32* %array, i32** %array.addr, align 4 store i32 0, i32* %ret, align 4 store i32 0, i32* %i, align 4 br label %for.cond
for.cond: ; preds = %for.inc, %entry
%tmp = load i32* %i, align 4 %tmp1 = load i32* %N.addr, align 4 %cmp = icmp slt i32 %tmp, %tmp1 br i1 %cmp, label %for.body, label %for.end
for.body: ; preds = %for.cond
%tmp2 = load i32* %i, align 4 %tmp3 = load i32** %array.addr, align 4 %arrayidx = getelementptr inbounds i32* %tmp3, i32 %tmp2 %tmp4 = load i32* %arrayidx %tmp5 = load i32* %ret, align 4 %call = call i32 @max(i32 %tmp4, i32 %tmp5) %tmp6 = load i32* %ret, align 4 %add = add nsw i32 %tmp6, %call store i32 %add, i32* %ret, align 4 br label %for.inc
for.inc: ; preds = %for.body
%tmp7 = load i32* %i, align 4 %inc = add nsw i32 %tmp7, 1 store i32 %inc, i32* %i, align 4 br label %for.cond
- 最終更新:2011-02-09 19:55:19