llcの概要

#下記はすべてllvm-2.8で動作確認しています。

概要

llcは、LLVMのBigCodeを入力として受け取り、
対象アーキテクチャ用のアセンブラファイルを出力する。

オプション

一覧と詳細は、llc --help-hidden | lessするのがよい。

アーキテクチャの指定方法
$ llc -march=arm xxx.bc

サポートするCPUの表示方法
$ llc -march=arm -mcpu=help xxx.bc

ABI指定が必要な場合の例
$ llc -mtriple=x86_64-mingw32
llvm/test 配下を mtriple で grep してみると感じがつかめます。

デバッグ時のオプション
-print-lsr-output
-print-isel-input
-print-machineinstrs

Direct Object File Emission - いわゆる MC と呼ばれてるヤツ


一部のアーキテクチャ・オブジェクトフォーマットでは、安定してオブジェクトファイルを直接吐かせることができます。このへんは鋭意開発中なので、ぜひ最新版で試してみてください。

$ llc -filetype=obj -o foo.o

{i686|x86_64}-{elf|darwin} は十分に安定しています。
{i686|x86_64}-{cygwin|mingw32} いわゆる PECOFF は、あと一息で実用になります。
(実際のところ、chapuni パッチを1つ入れれば clang セルフビルドが可能になるくらい)
arm-{elf|darwin}は(私は試したことがないけど)活発に更新が続いています。

clang から利用する場合 -integrated-as オプションを使います。見事に /usr/bin/as 呼出が省略されます。


最適化オプション

最適化レベル(-O0 -O1 -O2 -O3)による指定
命令スケジューリングの指定
#dynamic programming
#fast
命令スケジューリングの指定
#fast
#source
#instruction level parallel
#register reduction
#register pressure
#latency
#hybrid
レジスタ割り付けの指定
#fast
#linerscan
#pbqp
※以降llvm-2.9
#basic
#greedy

最適化の制御は、下記ファイルで行っている
lib/CodeGen/LLVMTargetMachine.cpp:



入力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;
}

clangでCソースからBitCodeに変換した直後のBitCodeファイル

$ clang -c -emit-llvm -O0 test001.c -o test001.bc
※省略

optで最適化した直後のBitCodeファイル

$ opt -O3 test001.bc -o test001.opt.bc
※max関数はinline展開されるので、以後扱わない。
define i32 @func(i32 %N, i32* nocapture %array) nounwind readonly {
; <label>:0
%1 = icmp sgt i32 %N, 0
 br i1 %1, label %bb.nph, label %._crit_edge

bb.nph: ; preds = %bb.nph, %0
%ret.02 = phi i32 [ %4, %bb.nph ], [ 0, %0 ]
 %i.01 = phi i32 [ %5, %bb.nph ], [ 0, %0 ]
 %scevgep = getelementptr i32* %array, i32 %i.01
 %2 = load i32* %scevgep, align 4
 %3 = icmp sgt i32 %2, %ret.02
 %.0.i = select i1 %3, i32 %2, i32 %ret.02
 %4 = add nsw i32 %.0.i, %ret.02
 %5 = add nsw i32 %i.01, 1
 %exitcond = icmp eq i32 %5, %N
 br i1 %exitcond, label %._crit_edge, label %bb.nph

._crit_edge: ; preds = %bb.nph, %0
%ret.0.lcssa = phi i32 [ 0, %0 ], [ %4, %bb.nph ]
 ret i32 %ret.0.lcssa
}

llc

# 以降は、ARMアーキテクチャ、Coretex-A9を対象にする。
$ llc test001.opt.bc -march=arm -mcpu=coretex-a9

Input

#上記の最適化直後のBitCodeを入力として与える

LoopStrengthReduction

$ llc -print-lsr-output
*** Code after LSR *** [#zcaf67b7]

define i32 @func(i32 %N, i32* %array) nounwind readonly {
entry:
%cmp1 = icmp sgt i32 %N, 0
 br i1 %cmp1, label %for.body.preheader, label %for.end

for.body.preheader: ; preds = %entry
br label %for.body

for.body: ; preds = %for.body.preheader, %for.body
%lsr.iv1 = phi i32* [ %array, %for.body.preheader ], [ %scevgep, %for.body ]
 %lsr.iv = phi i32 [ %N, %for.body.preheader ], [ %lsr.iv.next, %for.body ]
 %ret.02 = phi i32 [ %add, %for.body ], [ 0, %for.body.preheader ]
 %tmp4 = load i32* %lsr.iv1, align 4
 %cmp.i = icmp sgt i32 %tmp4, %ret.02
 %storemerge.i = select i1 %cmp.i, i32 %tmp4, i32 %ret.02
 %add = add nsw i32 %storemerge.i, %ret.02
 %lsr.iv.next = add i32 %lsr.iv, -1
 %scevgep = getelementptr i32* %lsr.iv1, i32 1
 %exitcond = icmp eq i32 %lsr.iv.next, 0
 br i1 %exitcond, label %for.end.loopexit, label %for.body

for.end.loopexit: ; preds = %for.body
br label %for.end

for.end: ; preds = %for.end.loopexit, %entry
%ret.0.lcssa = phi i32 [ 0, %entry ], [ %add, %for.end.loopexit ]
 ret i32 %ret.0.lcssa
}

Preparation

$ llc -print-isel-input
*** Final LLVM Code input to ISel *** [#yaa83e03]

define i32 @func(i32 %N, i32* %array) nounwind readonly {
entry:
%cmp1 = icmp sgt i32 %N, 0
 br i1 %cmp1, label %entry.for.body_crit_edge, label %entry.for.end_crit_edge

entry.for.end_crit_edge: ; preds = %entry
br label %for.end

entry.for.body_crit_edge: ; preds = %entry
br label %for.body

for.body: ; preds = %entry.for.body_crit_edge, %for.body
%lsr.iv1 = phi i32* [ %scevgep, %for.body ], [ %array, %entry.for.body_crit_edge ]
 %lsr.iv = phi i32 [ %lsr.iv.next, %for.body ], [ %N, %entry.for.body_crit_edge ]
 %ret.02 = phi i32 [ %add, %for.body ], [ 0, %entry.for.body_crit_edge ]
 %tmp4 = load i32* %lsr.iv1, align 4
 %cmp.i = icmp sgt i32 %tmp4, %ret.02
 %storemerge.i = select i1 %cmp.i, i32 %tmp4, i32 %ret.02
 %add = add nsw i32 %storemerge.i, %ret.02
 %lsr.iv.next = add i32 %lsr.iv, -1
 %scevgep = getelementptr i32* %lsr.iv1, i32 1
 %exitcond = icmp eq i32 %lsr.iv.next, 0
 br i1 %exitcond, label %for.body.for.end_crit_edge, label %for.body

for.body.for.end_crit_edge: ; preds = %for.body
br label %for.end

for.end: ; preds = %for.body.for.end_crit_edge, %entry.for.end_crit_edge
%ret.0.lcssa = phi i32 [ 0, %entry.for.end_crit_edge ], [ %add, %for.body.for.end_crit_edge ]
 ret i32 %ret.0.lcssa
}

SelectionDAG


SelectionDAG->MachineInstrへ変換

# After Instruction Selection:
# Machine code for function func:
Function Live Ins: %R0 in reg%16393, %R1 in reg%16394
Function Live Outs: %R0

BB#0: derived from LLVM BB %entry
  Live Ins: %R0 %R1
       %reg16394<def> = COPY %R1; GPR:%reg16394
       %reg16393<def> = COPY %R0; GPR:%reg16393
       %reg16385<def> = COPY %reg16394; GPR:%reg16385,16394
       %reg16384<def> = COPY %reg16393; GPR:%reg16384,16393
       CMPri %reg16393, 0, pred:14, pred:%reg0, %CPSR<imp-def>; GPR:%reg16393
       Bcc <BB#2>, pred:12, pred:%CPSR
   Successors according to CFG: BB#2 BB#1

BB#1: derived from LLVM BB %entry.for.end_crit_edge
  Predecessors according to CFG: BB#0
       %reg16395<def> = MOVi 0, pred:14, pred:%reg0, opt:%reg0; GPR:%reg16395
       B <BB#5>
   Successors according to CFG: BB#5

BB#2: derived from LLVM BB %entry.for.body_crit_edge
  Predecessors according to CFG: BB#0
       %reg16396<def> = MOVi 0, pred:14, pred:%reg0, opt:%reg0; GPR:%reg16396
   Successors according to CFG: BB#3

BB#3: derived from LLVM BB %for.body
  Predecessors according to CFG: BB#2 BB#3
       %reg16386<def> = PHI %reg16385, <BB#2>, %reg16391, <BB#3>; GPR:%reg16386,16385,16391
       %reg16387<def> = PHI %reg16384, <BB#2>, %reg16390, <BB#3>; GPR:%reg16387,16384,16390
       %reg16388<def> = PHI %reg16396, <BB#2>, %reg16389, <BB#3>; GPR:%reg16388,16396,16389
       %reg16397<def>, %reg16391<def> = LDR_POST %reg16386, %reg0, 4, pred:14, pred:%reg0; GPR:%reg16397,16391,16386
       CMPrr %reg16397, %reg16388, pred:14, pred:%reg0, %CPSR<imp-def>; GPR:%reg16397,16388
       %reg16398<def> = MOVCCr %reg16388, %reg16397, pred:12, pred:%CPSR; GPR:%reg16398,16388,16397
       %reg16389<def> = ADDrr %reg16398<kill>, %reg16388, pred:14, pred:%reg0, opt:%reg0; GPR:%reg16389,16398,16388
       %reg16390<def> = SUBri %reg16387, 1, pred:14, pred:%reg0, opt:%reg0; GPR:%reg16390,16387
       CMPzri %reg16390, 0, pred:14, pred:%reg0, %CPSR<imp-def>; GPR:%reg16390
       Bcc <BB#3>, pred:1, pred:%CPSR
   Successors according to CFG: BB#4 BB#3

BB#4: derived from LLVM BB %for.body.for.end_crit_edge
  Predecessors according to CFG: BB#3
   Successors according to CFG: BB#5

BB#5: derived from LLVM BB %for.end
  Predecessors according to CFG: BB#1 BB#4
       %reg16392<def> = PHI %reg16395, <BB#1>, %reg16389, <BB#4>; GPR:%reg16392,16395,16389
       %R0<def> = COPY %reg16392; GPR:%reg16392
       MOVPCLR pred:14, pred:%reg0

# End machine code for function func.

SSA-Based Machine Code Optimizations[#o265f88f]

Optimiza machine instructin PHIs

Local Stack Slot Alloction

Remove dead machine instructions

Tail Duplication

# After Pre-RegAlloc TailDuplicate:
# Machine code for function func:
Function Live Ins: %R0 in reg%16393, %R1 in reg%16394
Function Live Outs: %R0

BB#0: derived from LLVM BB %entry
  Live Ins: %R0 %R1
       %reg16394<def> = COPY %R1; GPR:%reg16394
       %reg16393<def> = COPY %R0; GPR:%reg16393
       CMPri %reg16393, 0, pred:14, pred:%reg0, %CPSR<imp-def>; GPR:%reg16393
       Bcc <BB#2>, pred:12, pred:%CPSR
   Successors according to CFG: BB#2 BB#1

BB#1: derived from LLVM BB %entry.for.end_crit_edge
  Predecessors according to CFG: BB#0
       %reg16395<def> = MOVi 0, pred:14, pred:%reg0, opt:%reg0; GPR:%reg16395
       B <BB#5>
   Successors according to CFG: BB#5

BB#2: derived from LLVM BB %entry.for.body_crit_edge
  Predecessors according to CFG: BB#0
       %reg16385<def> = COPY %reg16394; GPR:%reg16385,16394
       %reg16384<def> = COPY %reg16393; GPR:%reg16384,16393
       %reg16396<def> = MOVi 0, pred:14, pred:%reg0, opt:%reg0; GPR:%reg16396
   Successors according to CFG: BB#3

BB#3: derived from LLVM BB %for.body
  Predecessors according to CFG: BB#2 BB#3
       %reg16386<def> = PHI %reg16385, <BB#2>, %reg16391, <BB#3>; GPR:%reg16386,16385,16391
       %reg16387<def> = PHI %reg16384, <BB#2>, %reg16390, <BB#3>; GPR:%reg16387,16384,16390
       %reg16388<def> = PHI %reg16396, <BB#2>, %reg16389, <BB#3>; GPR:%reg16388,16396,16389
       %reg16397<def>, %reg16391<def> = LDR_POST %reg16386, %reg0, 4, pred:14, pred:%reg0; GPR:%reg16397,16391,16386
       CMPrr %reg16397, %reg16388, pred:14, pred:%reg0, %CPSR<imp-def>; GPR:%reg16397,16388
       %reg16398<def> = MOVCCr %reg16388, %reg16397, pred:12, pred:%CPSR; GPR:%reg16398,16388,16397
       %reg16389<def> = ADDrr %reg16398<kill>, %reg16388, pred:14, pred:%reg0, opt:%reg0; GPR:%reg16389,16398,16388
       %reg16390<def> = SUBri %reg16387, 1, pred:14, pred:%reg0, opt:%CPSR<imp-def>; GPR:%reg16390,16387
       Bcc <BB#3>, pred:1, pred:%CPSR
   Successors according to CFG: BB#4 BB#3

BB#4: derived from LLVM BB %for.body.for.end_crit_edge
  Predecessors according to CFG: BB#3
   Successors according to CFG: BB#5

BB#5: derived from LLVM BB %for.end
  Predecessors according to CFG: BB#1 BB#4
       %reg16392<def> = PHI %reg16395, <BB#1>, %reg16389, <BB#4>; GPR:%reg16392,16395,16389
       %R0<def> = COPY %reg16392; GPR:%reg16392
       MOVPCLR pred:14, pred:%reg0

# End machine code for function func.

ARM pre register alloction load/store optimization

# After PreRegAlloc passes:
# Machine code for function func:
Function Live Ins: %R0 in reg%16393, %R1 in reg%16394
Function Live Outs: %R0

BB#0: derived from LLVM BB %entry
  Live Ins: %R0 %R1
       %reg16394<def> = COPY %R1; GPR:%reg16394
       %reg16393<def> = COPY %R0; GPR:%reg16393
       CMPri %reg16393, 0, pred:14, pred:%reg0, %CPSR<imp-def>; GPR:%reg16393
       Bcc <BB#2>, pred:12, pred:%CPSR
   Successors according to CFG: BB#2 BB#1

BB#1: derived from LLVM BB %entry.for.end_crit_edge
  Predecessors according to CFG: BB#0
       %reg16395<def> = MOVi 0, pred:14, pred:%reg0, opt:%reg0; GPR:%reg16395
       B <BB#5>
   Successors according to CFG: BB#5

BB#2: derived from LLVM BB %entry.for.body_crit_edge
  Predecessors according to CFG: BB#0
       %reg16385<def> = COPY %reg16394; GPR:%reg16385,16394
       %reg16384<def> = COPY %reg16393; GPR:%reg16384,16393
       %reg16396<def> = MOVi 0, pred:14, pred:%reg0, opt:%reg0; GPR:%reg16396
   Successors according to CFG: BB#3

BB#3: derived from LLVM BB %for.body
  Predecessors according to CFG: BB#2 BB#3
       %reg16386<def> = PHI %reg16385, <BB#2>, %reg16391, <BB#3>; GPR:%reg16386,16385,16391
       %reg16387<def> = PHI %reg16384, <BB#2>, %reg16390, <BB#3>; GPR:%reg16387,16384,16390
       %reg16388<def> = PHI %reg16396, <BB#2>, %reg16389, <BB#3>; GPR:%reg16388,16396,16389
       %reg16397<def>, %reg16391<def> = LDR_POST %reg16386, %reg0, 4, pred:14, pred:%reg0; GPR:%reg16397,16391,16386
       CMPrr %reg16397, %reg16388, pred:14, pred:%reg0, %CPSR<imp-def>; GPR:%reg16397,16388
       %reg16398<def> = MOVCCr %reg16388, %reg16397, pred:12, pred:%CPSR; GPR:%reg16398,16388,16397
       %reg16389<def> = ADDrr %reg16398<kill>, %reg16388, pred:14, pred:%reg0, opt:%reg0; GPR:%reg16389,16398,16388
       %reg16390<def> = SUBri %reg16387, 1, pred:14, pred:%reg0, opt:%CPSR<imp-def>; GPR:%reg16390,16387
       Bcc <BB#3>, pred:1, pred:%CPSR
   Successors according to CFG: BB#4 BB#3

BB#4: derived from LLVM BB %for.body.for.end_crit_edge
  Predecessors according to CFG: BB#3
   Successors according to CFG: BB#5

BB#5: derived from LLVM BB %for.end
  Predecessors according to CFG: BB#1 BB#4
       %reg16392<def> = PHI %reg16395, <BB#1>, %reg16389, <BB#4>; GPR:%reg16392,16395,16389
       %R0<def> = COPY %reg16392; GPR:%reg16392
       MOVPCLR pred:14, pred:%reg0

# End machine code for function func.

Register Allocation

Live Variable Analysis

Eliminate PHI nodes

Two-Address instruction

Process Implicit Definitions

Slot index numbering

Live Interval Analysis

Simple Register Coalescing

Calculate spill weights

Live Stack Slot Analysis

Virtual Register Map

Linear Scan Register Allocator

# After Register Allocation:
# Machine code for function func:
Function Live Ins: %R0 in reg%16393, %R1 in reg%16394
Function Live Outs: %R0

BB#0: derived from LLVM BB %entry
  Live Ins: %R0 %R1
       CMPri %R0, 0, pred:14, pred:%reg0, %CPSR<imp-def>
       Bcc <BB#2>, pred:12, pred:%CPSR<kill>
   Successors according to CFG: BB#2 BB#1

BB#1: derived from LLVM BB %entry.for.end_crit_edge
  Predecessors according to CFG: BB#0
       %R2<def> = MOVi 0, pred:14, pred:%reg0, opt:%reg0
       B <BB#5>
   Successors according to CFG: BB#5

BB#2: derived from LLVM BB %entry.for.body_crit_edge
  Live Ins: %R1 %R0 %R0 %R1
   Predecessors according to CFG: BB#0
       %R2<def> = MOVi 0, pred:14, pred:%reg0, opt:%reg0
   Successors according to CFG: BB#3

BB#3: derived from LLVM BB %for.body
  Live Ins: %R1 %R0 %R0 %R2 %R1
   Predecessors according to CFG: BB#2 BB#3
       %R3<def>, %R1<def> = LDR_POST %R1, %reg0, 4, pred:14, pred:%reg0
       CMPrr %R3, %R2, pred:14, pred:%reg0, %CPSR<imp-def>
       %R12<def> = COPY %R2
       %R12<def> = MOVCCr %R12, %R3<kill>, pred:12, pred:%CPSR<kill>
       %R2<def> = ADDrr %R12<kill>, %R2<kill>, pred:14, pred:%reg0, opt:%reg0
       %R0<def> = SUBri %R0<kill>, 1, pred:14, pred:%reg0, opt:%CPSR<imp-def>
       Bcc <BB#3>, pred:1, pred:%CPSR<kill>
   Successors according to CFG: BB#4 BB#3

BB#4: derived from LLVM BB %for.body.for.end_crit_edge
  Live Ins: %R2
   Predecessors according to CFG: BB#3
   Successors according to CFG: BB#5

BB#5: derived from LLVM BB %for.end
  Live Ins: %R2
   Predecessors according to CFG: BB#1 BB#4
       %R0<def> = COPY %R2<kill>
       MOVPCLR pred:14, pred:%reg0, %R0<imp-use,kill>

# End machine code for function func.

after regalloc code optimization

Stack Slot Coloring

Machine Instruction LICM

Subregister lowering instruction

# After LowerSubregs:
# Machine code for function func:
Function Live Ins: %R0 in reg%16393, %R1 in reg%16394
Function Live Outs: %R0

BB#0: derived from LLVM BB %entry
  Live Ins: %R0 %R1
       CMPri %R0, 0, pred:14, pred:%reg0, %CPSR<imp-def>
       Bcc <BB#2>, pred:12, pred:%CPSR<kill>
   Successors according to CFG: BB#2 BB#1

BB#1: derived from LLVM BB %entry.for.end_crit_edge
  Predecessors according to CFG: BB#0
       %R2<def> = MOVi 0, pred:14, pred:%reg0, opt:%reg0
       B <BB#5>
   Successors according to CFG: BB#5

BB#2: derived from LLVM BB %entry.for.body_crit_edge
  Live Ins: %R1 %R0 %R0 %R1
   Predecessors according to CFG: BB#0
       %R2<def> = MOVi 0, pred:14, pred:%reg0, opt:%reg0
   Successors according to CFG: BB#3

BB#3: derived from LLVM BB %for.body
  Live Ins: %R1 %R0 %R0 %R2 %R1
   Predecessors according to CFG: BB#2 BB#3
       %R3<def>, %R1<def> = LDR_POST %R1, %reg0, 4, pred:14, pred:%reg0
       CMPrr %R3, %R2, pred:14, pred:%reg0, %CPSR<imp-def>
       %R12<def> = MOVr %R2, pred:14, pred:%reg0, opt:%reg0
       %R12<def> = MOVCCr %R12, %R3<kill>, pred:12, pred:%CPSR<kill>
       %R2<def> = ADDrr %R12<kill>, %R2<kill>, pred:14, pred:%reg0, opt:%reg0
       %R0<def> = SUBri %R0<kill>, 1, pred:14, pred:%reg0, opt:%CPSR<imp-def>
       Bcc <BB#3>, pred:1, pred:%CPSR<kill>
   Successors according to CFG: BB#4 BB#3

BB#4: derived from LLVM BB %for.body.for.end_crit_edge
  Live Ins: %R2
   Predecessors according to CFG: BB#3
   Successors according to CFG: BB#5

BB#5: derived from LLVM BB %for.end
  Live Ins: %R2
   Predecessors according to CFG: BB#1 BB#4
       %R0<def> = MOVr %R2<kill>, pred:14, pred:%reg0, opt:%reg0
       MOVPCLR pred:14, pred:%reg0, %R0<imp-use,kill>

# End machine code for function func.

Prolog/Epilog Code Insertion

# After PrologEpilogCodeInserter:
# Machine code for function func:
Function Live Ins: %R0 in reg%16393, %R1 in reg%16394
Function Live Outs: %R0

BB#0: derived from LLVM BB %entry
  Live Ins: %R0 %R1
       CMPri %R0, 0, pred:14, pred:%reg0, %CPSR<imp-def>
       Bcc <BB#2>, pred:12, pred:%CPSR<kill>
   Successors according to CFG: BB#2 BB#1

BB#1: derived from LLVM BB %entry.for.end_crit_edge
  Predecessors according to CFG: BB#0
       %R2<def> = MOVi 0, pred:14, pred:%reg0, opt:%reg0
       B <BB#5>
   Successors according to CFG: BB#5

BB#2: derived from LLVM BB %entry.for.body_crit_edge
  Live Ins: %R1 %R0 %R0 %R1
   Predecessors according to CFG: BB#0
       %R2<def> = MOVi 0, pred:14, pred:%reg0, opt:%reg0
   Successors according to CFG: BB#3

BB#3: derived from LLVM BB %for.body
  Live Ins: %R1 %R0 %R0 %R2 %R1
   Predecessors according to CFG: BB#2 BB#3
       %R3<def>, %R1<def> = LDR_POST %R1, %reg0, 4, pred:14, pred:%reg0
       CMPrr %R3, %R2, pred:14, pred:%reg0, %CPSR<imp-def>
       %R12<def> = MOVr %R2, pred:14, pred:%reg0, opt:%reg0
       %R12<def> = MOVCCr %R12, %R3<kill>, pred:12, pred:%CPSR<kill>
       %R2<def> = ADDrr %R12<kill>, %R2<kill>, pred:14, pred:%reg0, opt:%reg0
       %R0<def> = SUBri %R0<kill>, 1, pred:14, pred:%reg0, opt:%CPSR<imp-def>
       Bcc <BB#3>, pred:1, pred:%CPSR<kill>
   Successors according to CFG: BB#4 BB#3

BB#4: derived from LLVM BB %for.body.for.end_crit_edge
  Live Ins: %R2
   Predecessors according to CFG: BB#3
   Successors according to CFG: BB#5

BB#5: derived from LLVM BB %for.end
  Live Ins: %R2
   Predecessors according to CFG: BB#1 BB#4
       %R0<def> = MOVr %R2<kill>, pred:14, pred:%reg0, opt:%reg0
       MOVPCLR pred:14, pred:%reg0, %R0<imp-use,kill>

# End machine code for function func.


Late Machine Code Optimization

ARM load/store optimization

ARM psude instruction expansion

If Converter

# After PreSched2 passes:
# Machine code for function func:
Function Live Ins: %R0 in reg%16393, %R1 in reg%16394
Function Live Outs: %R0

BB#0: derived from LLVM BB %entry
  Live Ins: %R0 %R1
       CMPri %R0, 0, pred:14, pred:%reg0, %CPSR<imp-def>
       Bcc <BB#2>, pred:12, pred:%CPSR<kill>
   Successors according to CFG: BB#2 BB#1

BB#1: derived from LLVM BB %entry.for.end_crit_edge
  Predecessors according to CFG: BB#0
       %R2<def> = MOVi 0, pred:14, pred:%reg0, opt:%reg0
       B <BB#4>
   Successors according to CFG: BB#4

BB#2: derived from LLVM BB %entry.for.body_crit_edge
  Live Ins: %R1 %R0 %R0 %R1
   Predecessors according to CFG: BB#0
       %R2<def> = MOVi 0, pred:14, pred:%reg0, opt:%reg0
   Successors according to CFG: BB#3

BB#3: derived from LLVM BB %for.body
  Live Ins: %R1 %R0 %R0 %R2 %R1
   Predecessors according to CFG: BB#2 BB#3
       %R3<def>, %R1<def> = LDR_POST %R1, %reg0, 4, pred:14, pred:%reg0
       CMPrr %R3, %R2, pred:14, pred:%reg0, %CPSR<imp-def>
       %R12<def> = MOVr %R2, pred:14, pred:%reg0, opt:%reg0
       %R12<def> = MOVCCr %R12, %R3<kill>, pred:12, pred:%CPSR<kill>
       %R2<def> = ADDrr %R12<kill>, %R2<kill>, pred:14, pred:%reg0, opt:%reg0
       %R0<def> = SUBri %R0<kill>, 1, pred:14, pred:%reg0, opt:%CPSR<imp-def>
       Bcc <BB#3>, pred:1, pred:%CPSR<kill>
   Successors according to CFG: BB#3 BB#4

BB#4: derived from LLVM BB %for.end
  Live Ins: %R2
   Predecessors according to CFG: BB#1 BB#3
       %R0<def> = MOVr %R2<kill>, pred:14, pred:%reg0, opt:%reg0
       MOVPCLR pred:14, pred:%reg0, %R0<imp-use,kill>

# End machine code for function func.

PostRAScheduler

# After PostRAScheduler:
# Machine code for function func:
Function Live Ins: %R0 in reg%16393, %R1 in reg%16394
Function Live Outs: %R0

BB#0: derived from LLVM BB %entry
  Live Ins: %R0 %R1
       CMPri %R0, 0, pred:14, pred:%reg0, %CPSR<imp-def>
       Bcc <BB#2>, pred:12, pred:%CPSR<kill>
   Successors according to CFG: BB#2 BB#1

BB#1: derived from LLVM BB %entry.for.end_crit_edge
  Predecessors according to CFG: BB#0
       %R2<def> = MOVi 0, pred:14, pred:%reg0, opt:%reg0
       B <BB#4>
   Successors according to CFG: BB#4

BB#2: derived from LLVM BB %entry.for.body_crit_edge
  Live Ins: %R1 %R0 %R0 %R1
   Predecessors according to CFG: BB#0
       %R2<def> = MOVi 0, pred:14, pred:%reg0, opt:%reg0
   Successors according to CFG: BB#3

BB#3: derived from LLVM BB %for.body
  Live Ins: %R1 %R0 %R0 %R2 %R1
   Predecessors according to CFG: BB#2 BB#3
       %R3<def>, %R1<def> = LDR_POST %R1, %reg0, 4, pred:14, pred:%reg0
       %R12<def> = MOVr %R2, pred:14, pred:%reg0, opt:%reg0
       CMPrr %R3, %R2, pred:14, pred:%reg0, %CPSR<imp-def>
       %R12<def> = MOVCCr %R12, %R3<kill>, pred:12, pred:%CPSR<kill>
       %R0<def> = SUBri %R0<kill>, 1, pred:14, pred:%reg0, opt:%CPSR<imp-def>
       %R2<def> = ADDrr %R12<kill>, %R2<kill>, pred:14, pred:%reg0, opt:%reg0
       Bcc <BB#3>, pred:1, pred:%CPSR<kill>
   Successors according to CFG: BB#3 BB#4

BB#4: derived from LLVM BB %for.end
  Live Ins: %R2
   Predecessors according to CFG: BB#1 BB#3
       %R0<def> = MOVr %R2<kill>, pred:14, pred:%reg0, opt:%reg0
       MOVPCLR pred:14, pred:%reg0, %R0<imp-use>

# End machine code for function func.

Late Machine Code Optimization 2

Control Flow Optimizer

Tail Duplication

Code Placement Optimization

ARM constant island placement and branch shortening

Pre Code Emission[#s2f80334]

# After PreEmit passes:
# Machine code for function func:
Function Live Ins: %R0 in reg%16393, %R1 in reg%16394
Function Live Outs: %R0

BB#0: derived from LLVM BB %entry
  Live Ins: %R0 %R1
       CMPri %R0, 0, pred:14, pred:%reg0, %CPSR<imp-def>
       Bcc <BB#2>, pred:12, pred:%CPSR<kill>
   Successors according to CFG: BB#2 BB#1

BB#1: derived from LLVM BB %entry.for.end_crit_edge
  Predecessors according to CFG: BB#0
       %R2<def> = MOVi 0, pred:14, pred:%reg0, opt:%reg0
       %R0<def> = MOVr %R2<kill>, pred:14, pred:%reg0, opt:%reg0
       MOVPCLR pred:14, pred:%reg0, %R0<imp-use>

BB#2: derived from LLVM BB %entry.for.body_crit_edge
  Live Ins: %R1 %R0 %R0 %R1
   Predecessors according to CFG: BB#0
       %R2<def> = MOVi 0, pred:14, pred:%reg0, opt:%reg0
   Successors according to CFG: BB#3

BB#3: derived from LLVM BB %for.body
  Live Ins: %R1 %R0 %R0 %R2 %R1
   Predecessors according to CFG: BB#2 BB#3
       %R3<def>, %R1<def> = LDR_POST %R1, %reg0, 4, pred:14, pred:%reg0
       %R12<def> = MOVr %R2, pred:14, pred:%reg0, opt:%reg0
       CMPrr %R3, %R2, pred:14, pred:%reg0, %CPSR<imp-def>
       %R12<def> = MOVCCr %R12, %R3<kill>, pred:12, pred:%CPSR<kill>
       %R0<def> = SUBri %R0<kill>, 1, pred:14, pred:%reg0, opt:%CPSR<imp-def>
       %R2<def> = ADDrr %R12<kill>, %R2<kill>, pred:14, pred:%reg0, opt:%reg0
       Bcc <BB#3>, pred:1, pred:%CPSR<kill>
   Successors according to CFG: BB#3 BB#4

BB#4: derived from LLVM BB %for.end
  Live Ins: %R2
   Predecessors according to CFG: BB#3
       %R0<def> = MOVr %R2<kill>, pred:14, pred:%reg0, opt:%reg0
       MOVPCLR pred:14, pred:%reg0, %R0<imp-use>

# End machine code for function func.

Emit assembler

      .syntax unified
       .cpu coretex-a9
       .eabi_attribute 20, 1
       .eabi_attribute 21, 1
       .eabi_attribute 23, 3
       .eabi_attribute 24, 1
       .eabi_attribute 25, 1
       .file   "test001.opt.bc"
       .text
       .globl  max
       .align  2
       .type   max,%function
max: @ @max
@ BB#0:
      cmp     r0, r1
       movgt   r1, r0
       mov     r0, r1
       mov     pc, lr
.Ltmp0:
      .size   max, .Ltmp0-max

      .globl  func
       .align  2
       .type   func,%function
func: @ @func
@ BB#0:
      cmp     r0, #0
       bgt     .LBB1_2
@ BB#1: @ %.._crit_edge_crit_edge
      mov     r2, #0
       mov     r0, r2
       mov     pc, lr
.LBB1_2: @ %.bb.nph_crit_edge
      mov     r2, #0
.LBB1_3: @ %bb.nph
                                      @ =>This Inner Loop Header: Depth=1
       ldr     r3, [r1], #4
       mov     r12, r2
       cmp     r3, r2
       movgt   r12, r3
       subs    r0, r0, #1
       add     r2, r12, r2
       bne     .LBB1_3
@ BB#4: @ %._crit_edge
      mov     r0, r2
       mov     pc, lr
.Ltmp1:
      .size   func, .Ltmp1-func


参考資料

LLVM Developers Meeting

2008 CodeGen Overview and Focus on SelectionDAGs

2008 LLVM Register Allocation

2009 Future Works in LLVM Register Allocation


LLVM Subsystem Documentation

Writing an LLVM Backend

The LLVM Target-Independent Code Generator

TableGen Fundamentals


  • 最終更新:2011-02-09 20:29:49

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

認証パスワード