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))))
max_AST.png

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)))
func_AST.png

出力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
}

max_bitcode_cfg.png

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

func_bitcode_cfg.png

  • 最終更新:2011-02-09 19:55:19

このWIKIを編集するにはパスワード入力が必要です

認証パスワード