ããæ¥ãå®å
šã«ç°ãªãç¬èªã®ã¢ãŒããã¯ãã£ã®ããã»ããµã®ã¢ã€ãã¢ãæãã€ãããã®ã¢ã€ãã¢ããããŒããŠã§ã¢ã§ãå®è£
ããããšèãããšæ³åããŠãã ããã 幞ããªããšã«ãããã¯äžå¯èœã§ã¯ãããŸããã å°ãæ€èšŒããããã§ããªãã®ã¢ã€ãã¢ãå®çŸããŸãã Intelãç Žç£ããããšã«ã€ããŠã®çŽ æŽããã倢ããã§ã«ãããMicrosoftã¯ã¢ãŒããã¯ãã£çšã«Windowsãæ¥ãã§æžãæããŠããŸããLinuxã³ãã¥ããã£ã¯ãéåžžã«éå±ãªå£çŽãåãããã€ã¯ãããã»ããµçšã®ã·ã¹ãã ã®æ°ããããŒãžã§ã³ããã§ã«äœæããŠããŸãã
ãã ããããããã¹ãŠã®ããã«ãã³ã³ãã€ã©ãŒãšããå°ããªãã®ã1ã€æ¬ ããŠããŸãã
ã¯ããå€ãã®äººãã³ã³ãã€ã©ãéèŠãªãã®ãšèŠãªããŠããªãããšãç¥ã£ãŠããŸãã誰ããå³å¯ã«ã¢ã»ã³ãã©ã§ããã°ã©ãã³ã°ããã¹ãã ãšä¿¡ããŠããŸãã ããªããããæããªããç§ã¯ããªããšè°è«ããªãã§ãã ããããã èªãã§ããªãã§ãã ããã
å
ã®ã¢ãŒããã¯ãã£ã§å°ãªããšãCèšèªã䜿çšã§ããããã«ããå Žåã¯ãcatã䜿çšããŠãã ããã
ãã®èšäºã§ã¯ãLLVMã³ã³ãã€ã©ã€ã³ãã©ã¹ãã©ã¯ãã£ã䜿çšããŠãããã«åºã¥ããã«ã¹ã¿ã ãœãªã¥ãŒã·ã§ã³ãæ§ç¯ããæ¹æ³ã«ã€ããŠèª¬æããŸãã
LLVMã®ç¯å²ã¯ãæ°ããããã»ããµãŒçšã®ã³ã³ãã€ã©ãŒã®éçºã«éå®ãããŸãã.LLVMã³ã³ãã€ã©ãŒã€ã³ãã©ã¹ãã©ã¯ãã£ã¯ãæ°ããããã°ã©ãã³ã°èšèªãæ°ããæé©åã¢ã«ãŽãªãºã ãããã°ã©ã ã³ãŒãã®éçåæïŒãšã©ãŒã®æ€çŽ¢ãçµ±èšã®åéãªã©ïŒçšã®ã³ã³ãã€ã©ãŒã®éçºã«ã䜿çšã§ããŸãã
ããšãã°ãããã€ãã®æšæºããã»ããµïŒããšãã°ARMïŒãç¹æ®ãªã³ããã»ããµïŒããšãã°ãããªãã¯ã¹FPUïŒãšçµã¿åãããŠäœ¿çšââã§ããŸãããã®å ŽåãFPUçšã®ã³ãŒããçæã§ããããã«ãæ¢åã®ARMã³ã³ãã€ã©ãå€æŽããå¿
èŠããããŸãã
ãŸããLLVMã®èå³æ·±ãã¢ããªã±ãŒã·ã§ã³ã¯ãé«ã¬ãã«èšèªã§ã®ãœãŒã¹ããã¹ãã®çæïŒããèšèªããå¥ã®èšèªãžã®ã翻蚳ãïŒã§ãã ããšãã°ãCã®ãœãŒã¹ã³ãŒãã䜿çšããŠVerilogã³ãŒããžã§ãã¬ãŒã¿ãŒãèšè¿°ã§ããŸãã
KDPV
ãªãLLVMãªã®ãïŒ
çŸåšãç¬èªã®ã¢ãŒããã¯ãã£çšã®ã³ã³ãã€ã©ãéçºããçŸå®çãªæ¹æ³ã¯ãGCCã䜿çšãããLLVMã䜿çšãã2ã€ã ãã§ãã ä»ã®ãªãŒãã³ãœãŒã¹ã³ã³ãã€ã©ãããžã§ã¯ãã¯ãGCCãLLVMãªã©ã®éçºã¬ãã«ã«éããŠããªãããæ代é
ãã§éçºãåæ¢ããŠãããæé©åã¢ã«ãŽãªãºã ãéçºããŠããããCèšèªæšæºãšã®å®å
šãªäºææ§ãæäŸããŠããªãå ŽåããããŸããããã°ã©ãã³ã°èšèªã ç¬èªã®ã³ã³ãã€ã©ãããŒããããéçºããããšã¯éåžžã«éåççãªæ¹æ³ã§ããæ¢åã®ãªãŒãã³ãœãŒã¹ãœãªã¥ãŒã·ã§ã³ã¯ãå€ãã®éåžžã«éèŠãªæé©åã¢ã«ãŽãªãºã ãåããã³ã³ãã€ã©ããã³ããšã³ããæ¢ã«å®è£
ããŠããããã§ãã
ããã2ã€ã®ãªãŒãã³ãœãŒã¹ãããžã§ã¯ãã®ãã¡ãã³ã³ãã€ã©ã®ããŒã¹ãšããŠéžæãã¹ããã®ã¯ã©ãã§ããïŒ GCCïŒGNU Compiler CollectionïŒã¯å€ããããžã§ã¯ãã§ãæåã®ãªãªãŒã¹ã¯1987幎ã«è¡ãããŸããããã®èè
ã¯ããªãŒãã³ãœãŒã¹éåã§æåãªRichard Stallmanã§ã[4]ã CãC ++ãObjective-CãFortranãJavaãAdaãGoãªã©ã®å€ãã®ããã°ã©ãã³ã°èšèªããµããŒãããŠããŸãã ã¡ã€ã³ã¢ã»ã³ããªã«å«ãŸããŠããªãä»ã®å€ãã®ããã°ã©ãã³ã°èšèªã®ããã³ããšã³ãããããŸãã GCCã³ã³ãã€ã©ã¯ãå€æ°ã®ããã»ããµã¢ãŒããã¯ãã£ãšãªãã¬ãŒãã£ã³ã°ã·ã¹ãã ããµããŒãããŠãããçŸåšæãäžè¬çãªã³ã³ãã€ã©ã§ãã GCCèªäœã¯Cã§èšè¿°ãããŠããŸãïŒã³ã¡ã³ãã§ã¯ãã»ãšãã©ãC ++ã§ãã§ã«æžãçŽãããŠããããšãä¿®æ£ãããŸããïŒã
LLVMã¯ã¯ããã«ãè¥ããã2003幎ã«æåã®ãªãªãŒã¹ãè¡ãããããæ£ç¢ºã«ã¯Clangããã³ããšã³ããCãC ++ãObjective-Cããã³Objective-C ++ããã°ã©ãã³ã°èšèªããµããŒãããCommon LispãActionScriptãAdaã®èšèªã®ããã³ããšã³ããåããŠããŸããDãFortranãOpenGLã·ã§ãŒãã£ã³ã°èšèªãGoãHaskellãJavaãã€ãã³ãŒããJuliaãSwiftãPythonãRubyãRustãScalaãCïŒãããã³Luaã ç±³åœã€ãªãã€å€§åŠã§éçºãããOS Xãªãã¬ãŒãã£ã³ã°ã·ã¹ãã ã§ã®éçºçšã®äž»èŠã³ã³ãã€ã©ã§ãããLLVMã¯C ++ïŒææ°ãªãªãŒã¹ã§ã¯C ++ 11ïŒã§èšè¿°ãããŠããŸã[5]ã
LLVMã®çžå¯Ÿçãªãè¥ããã¯æ¬ é¥ã§ã¯ãªããé倧ãªãã°ãçºçããªãã»ã©ååã«æçããŠããã ãã§ãªããGCCã®ãããªæ代é
ãã®ã¢ãŒããã¯ãã£ãœãªã¥ãŒã·ã§ã³ã®å€§ããªè² æ
ãè² ããŸããã ã³ã³ãã€ã©ã®ã¢ãžã¥ãŒã«æ§é ã«ãããLLCCïŒLLVMããã¯ãšã³ãïŒã«ãã£ãŠã¿ãŒã²ãããã©ãããã©ãŒã ã³ãŒãã®çæãå®è¡ãããäžæ¹ã§ãLLCC-GCCããã³ããšã³ãã䜿çšããŠGCCæšæºãå®å
šã«ãµããŒãã§ããŸãã ãªãªãžãã«ã®LLVMããã³ããšã³ãã§ããClangã䜿çšããããšãã§ããŸãã
LLVMã¯ååã«ææžåãããŠãããå€ãã®ã³ãŒãäŸããããŸãã
ã¢ãžã¥ã©ãŒã³ã³ãã€ã©ã¢ãŒããã¯ãã£
LLVMã³ã³ãã€ã©ã€ã³ãã©ã¹ãã©ã¯ãã£ã¯ããŸããŸãªããŒã«ã§æ§æãããŠããŸãããããããã¹ãŠããã®èšäºã®ãã¬ãŒã ã¯ãŒã¯å
ã§èæ
®ããããšã¯æå³ããããŸããã ã³ã³ãã€ã©èªäœãæ§æããã¡ã€ã³ããŒã«ã«éå®ããŸãã
LLVMã³ã³ãã€ã©ã¯ãä»ã®ããã€ãã®ã³ã³ãã€ã©ãšåæ§ã«ãããã³ããšã³ãããªããã£ãã€ã¶ãŒïŒããã«ã©ã³ãïŒãããã³ããã¯ãšã³ãã§æ§æãããŠããŸãã ãã®æ§é ã«ãããæ°ããããã°ã©ãã³ã°èšèªçšã®ã³ã³ãã€ã©ãŒã®éçºãæé©åã¡ãœããã®éçºãããã³ç¹å®ã®ããã»ããµãŒçšã®ã³ãŒããžã§ãã¬ãŒã¿ãŒã®éçºãåé¢ã§ããŸãïŒãã®ãããªã³ã³ãã€ã©ãŒã¯ããªã¿ãŒã²ããå¯èœããããªã¿ãŒã²ããå¯èœããšåŒã°ããŸãïŒã
ãããã®éã®ãªã³ã¯ã¯ããä»®æ³ãã·ã³ãã®ã¢ã»ã³ãã©ãŒã§ããäžéèšèªLLVMã§ãã ããã³ããšã³ãïŒClangãªã©ïŒã¯ãé«ã¬ãã«èšèªã®ããã°ã©ã ã®ããã¹ããäžéèšèªã®ããã¹ãã«å€æãããªããã£ãã€ã¶ãŒïŒoptïŒã¯ããŸããŸãªæé©åãå®è¡ããããã¯ãšã³ãïŒllcïŒã¯ã¿ãŒã²ããããã»ããµã®ã³ãŒããçæããŸãïŒã¢ã»ã³ãã©ãŒã§ããŸãã¯ãã€ããªãã¡ã€ã«ãšããŠçŽæ¥ïŒã ããã«ãããã°ã©ã ã®å®è¡äžã«ã³ã³ãã€ã«ãçŽæ¥è¡ãããå ŽåãLLVMã¯JITïŒãžã£ã¹ãã€ã³ã¿ã€ã ïŒã³ã³ãã€ã«ã¢ãŒãã§åäœã§ããŸãã
ããã°ã©ã ã®äžéè¡šçŸã¯ãLLVMã¢ã»ã³ãã©ãŒèšèªã®ããã¹ããã¡ã€ã«ã®åœ¢åŒããŸãã¯ãã€ããªåœ¢åŒã®ããããã³ãŒãã圢åŒã®ããããã§ãã ããã©ã«ãã§ã¯ãclangã¯ãããã³ãŒãïŒ.bcãã¡ã€ã«ïŒãçæããŸãããLLVMã®ãããã°ãšåŠç¿ã®ããã«ãLLVMã¢ã»ã³ãã©ãŒã§ããã¹ãäžéè¡šçŸãçæããå¿
èŠããããŸãïŒäžéè¡šçŸãäžéè¡šçŸãšããèšèããIRã³ãŒããšãåŒã°ããŸãïŒã
å³ 1.ã³ã³ãã€ã©ã®ã¢ãžã¥ãŒã«ã¢ãŒããã¯ãã£
äžèšã®ããã°ã©ã ã«å ããŠãLLVMã«ã¯ä»ã®ãŠãŒãã£ãªãã£ãå«ãŸããŠããŸã[6]ã
ããã§ã¯ãCã§æãåçŽãªããã°ã©ã ãæžããŸãããã
int foo(int x, int y) { return x + y; }
ãããŠãããã³ã³ãã€ã«ããŸãïŒ
clang-3.5 -c add.c -O0 --target=xcore -emit-llvm -S -o add_o0.ll
ããã€ãã®èª¬æïŒ
-c add.c-å
¥åãã¡ã€ã«ã
-O0-æé©åã¬ãã«0ãæé©åãªãã
--target = xcore-xcoreããã»ããµã®ã³ã¢ã¯ãIRã³ãŒãã«ã³ã³ãã€ã«ãããšãã«è€éãªæ©èœãæããªããããç 究ã«çæ³çãªãªããžã§ã¯ãã§ãã ãã®ã«ãŒãã«ã®å®¹éã¯32ã§ãclangã¯ãã¹ãŠã®å€æ°ã32ãããã¯ãŒãã®å¢çã«åãããŸãã
-emit-llvm -S-ïŒã¢ã»ã³ãã©ãŒLLVMã§ïŒããã¹ã圢åŒã§llvmãã¡ã€ã«ãçæããããã«clangã«æ瀺ããŸãã
-o add_o0.ll-åºåãã¡ã€ã«
çµæãèŠãŠã¿ãŸãããïŒ
; ModuleID = 'add.c'
target datalayout = "em:ep:32:32-i1:8:32-i8:8:32-i16:16:32-i64:32-f64:32-a:0:32-n32"
target triple = "xcore"
; Function Attrs: nounwind
define i32 @foo(i32 %x, i32 %y) #0 {
%1 = alloca i32, align 4
%2 = alloca i32, align 4
store i32 %x, i32* %1, align 4
store i32 %y, i32* %2, align 4
%3 = load i32* %1, align 4
%4 = load i32* %2, align 4
%5 = add nsw i32 %3, %4
ret i32 %5
}
attributes #0 = { nounwind "less-precise-fpmad"="false" "no-frame-pointer-elim"="false" "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}
!xcore.typestrings = !{!1}
!0 = metadata !{metadata !"Ubuntu clang version 3.5.0-4ubuntu2~trusty2 (tags/RELEASE_350/final) (based on LLVM 3.5.0)"}
!1 = metadata !{i32 (i32, i32)* @foo, metadata !"f{si}(si,si)"}
ããªãè€éã«èŠããŸãããïŒ ãã ããããã«äœãæžãããŠããããç解ããŸãããã ã ããïŒ
ã¿ãŒã²ããdatalayout = "emïŒepïŒ32ïŒ32-i1ïŒ8ïŒ32-i8ïŒ8ïŒ32-i16ïŒ16ïŒ32-i64ïŒ32-f64ïŒ32-aïŒ0ïŒ32-n32"
å€æ°ã®ããã深床ãšã¢ãŒããã¯ãã£ã®æãåºæ¬çãªæ©èœã®èª¬æã e-ãªãã«ãšã³ãã£ã¢ã³ã¢ãŒããã¯ãã£ã ããã°ãšã³ãã£ã¢ã³ã®å ŽåãEïŒmïŒe-ãã³ã°ãªã³ã°ãåœåèŠåã«ãªããŸãã ãŸã å¿
èŠãããŸããã pïŒ32ïŒ32-ãã€ã³ã¿ãŒã¯32ãããã§ã32ãããã¯ãŒãã®å¢çã«é
眮ãããŸãã i1ïŒ8ïŒ32-ããŒã«å€æ°ïŒi1ïŒã¯8ãããå€ã§è¡šçŸããã32ãããã¯ãŒãã®å¢çã«æŽåãããŸãã ããã«ãæŽæ°å€æ°i8-i64ïŒãããã8ã64ãããïŒãããã³å粟床ã®å®å€æ°ã®f64ã§ãåæ§ã§ãã aïŒ0ïŒ32-éçŽå€æ°ïŒã€ãŸããé
åãšæ§é äœïŒã¯32ãããã®ã¢ã©ã€ã¡ã³ããæã¡ãŸããn32-ããã»ããµALUã«ãã£ãŠåŠçãããæ°å€ã®ããã深床ïŒãã€ãã£ãæŽæ°å¹
ïŒã
ã¿ãŒã²ããïŒã¿ãŒã²ããããã»ããµïŒã®ååã¯æ¬¡ã®ãšããã§ãïŒtarget triple =â xcoreâã IRã³ãŒãã¯ãã°ãã°ããã·ã³ã«äŸåããªãããšåŒã°ããŸãããå®éã«ã¯ããã§ã¯ãããŸããã ã¿ãŒã²ããã¢ãŒããã¯ãã£ã®ããã€ãã®æ©èœãåæ ããŠããŸãã ããããããã¯ãšã³ãã ãã§ãªãããã³ããšã³ãã«ãã¿ãŒã²ããã¢ãŒããã¯ãã£ãæå®ããå¿
èŠãããçç±ã®1ã€ã§ãã
fooã®æ©èœã³ãŒãã¯æ¬¡ã®ãšããã§ãã
define i32 @foo(i32 %x, i32 %y) #0 {
%1 = alloca i32, align 4
%2 = alloca i32, align 4
store i32 %x, i32* %1, align 4
store i32 %y, i32* %2, align 4
%3 = load i32* %1, align 4
%4 = load i32* %2, align 4
%5 = add nsw i32 %3, %4
ret i32 %5
}
å
ã®é¢æ°ã¯éåžžã«åçŽã§ãããã³ãŒãã¯ããªãé¢åã§ãã ããã圌ã®ä»äºã§ãã
LLVMå
ã®ãã¹ãŠã®å€æ°åã«ã¯ãïŒ
ïŒããŒã«ã«å€æ°ã®å ŽåïŒãŸãã¯@ã®ã°ããŒãã«ã®æ¥é èŸãä»ããŠããããšã«æ³šæããŠãã ããã ãã®äŸã§ã¯ããã¹ãŠã®å€æ°ã¯ããŒã«ã«ã§ãã
ïŒ
1 = alloca i32ãalign 4-ã¹ã¿ãã¯äžã®å€æ°ã«4ãã€ããå²ãåœãŠãŸãããã®é åãžã®ãã€ã³ã¿ãŒã¯ãã€ã³ã¿ãŒïŒ
1ã§ãã
store i32ïŒ
xãi32 *ïŒ
1ãalign 4-é¢æ°ã®åŒæ°ã®1ã€ïŒïŒ
xïŒãéžæããé åã«ã³ããŒããŸãã
ïŒ
3 = i32 *ïŒ
1ãload 4ãããŒã-å€æ°ã®å€ãååŸããŸãïŒ
3ã ïŒ
3ã¯ãïŒ
xã®ããŒã«ã«ã³ããŒãä¿åããããã«ãªããŸããã
ïŒ
yåŒæ°ã«ã€ããŠãåãããšãè¡ããŸã
ïŒ
5 = nsw i32ïŒ
3ãïŒ
4ãè¿œå -ïŒ
xãšïŒ
yã®ããŒã«ã«ã³ããŒãè¿œå ããçµæãïŒ
5ã«å
¥ããŸãã nswå±æ§ããããŸããããŸã éèŠã§ã¯ãããŸããã
å€ïŒ
5ãè¿ããŸãã
äžèšã®äŸãããããããã«ãæé©åã¬ãã«0ã§ã¯ãclangã¯ãœãŒã¹ã³ãŒãã«æåéãåŸãã³ãŒããçæãããã¹ãŠã®åŒæ°ã®ããŒã«ã«ã³ããŒãäœæããåé·ãªã³ãã³ããåé€ããããšããŸããã ããã¯æªãã³ã³ãã€ã©ããããã£ã®ããã«æãããããããŸããããããã°ã©ã ããããã°ãããšããããã³ã³ã³ãã€ã©èªäœã®ã³ãŒãããããã°ãããšããå®éã«ã¯éåžžã«äŸ¿å©ãªæ©èœã§ãã
æé©åã¬ãã«ãO1ã«å€æŽãããšã©ããªããèŠãŠã¿ãŸãããã
define i32 @foo(i32 %x, i32 %y) #0 {
%1 = add nsw i32 %y, %x
ret i32 %1
}
äœåãªããŒã ã¯1ã€ãæ®ã£ãŠããŸããã ããã§ãããã°ã©ã ã¯é¢æ°ã®åŒæ°ãçŽæ¥è¿œå ããçµæãè¿ããŸãã
ããé«ãã¬ãã«ã®æé©åããããŸããããã®ç¹å®ã®ã±ãŒã¹ã§ã¯ãããè¯ãçµæã¯åŸãããŸããã æé©åã®æ倧ã¬ãã«ã¯ãã§ã«éæãããŠããŸãã
LLVMã³ãŒãã®æ®ãã®éšåïŒå±æ§ãã¡ã¿ããŒã¿ïŒã¯ããµãŒãã¹æ
å ±ãããèªäœã«äŒããŸãããããã¯ä»ã®ãšããèå³æ·±ããã®ã§ã¯ãããŸããã
LLVMã³ãŒãæ§é
LLVMã³ãŒãæ§é ã¯éåžžã«åçŽã§ãã ããã°ã©ã ã³ãŒãã¯ã¢ãžã¥ãŒã«ã§æ§æãããã³ã³ãã€ã©ã¯äžåºŠã«1ã€ã®ã¢ãžã¥ãŒã«ãåŠçããŸãã ã¢ãžã¥ãŒã«ã«ã¯ãã°ããŒãã«å®£èšïŒå€æ°ãå®æ°ãããã³ä»ã®ã¢ãžã¥ãŒã«ã«ããé¢æ°ããããŒã®å®£èšïŒãšé¢æ°ããããŸãã é¢æ°ã«ã¯åŒæ°ãšæ»ãå€ã®åããããŸãã é¢æ°ã¯ããŒã¹ãããã¯ã§æ§æãããŸãã ããŒã¹ãŠãããã¯ã1ã€ã®ãšã³ããªãã€ã³ããš1ã€ã®åºå£ãã€ã³ããæã€LLVMã¢ã»ã³ãã©ãŒåœä»€ã·ãŒã±ã³ã¹ã§ãã ããŒã¹ãããã¯ã«ã¯åå²ãšã«ãŒãã¯å«ãŸãããæåããæåŸãŸã§å³å¯ã«é£ç¶ããŠå®è¡ãããçµäºã³ãã³ãïŒé¢æ°ããæ»ããå¥ã®ãããã¯ã«åãæ¿ããïŒã§çµäºããå¿
èŠããããŸãã
æåŸã«ãããŒã¹ãŠãããã¯ã¢ã»ã³ãã©ã³ãã³ãã§æ§æãããŸãã ã³ãã³ãã®ãªã¹ãã¯ãLLVMã®ããã¥ã¡ã³ã[7]ã«èšèŒãããŠããŸãã
ãã®ãããããŒã¹ãŠãããã«ã¯ã©ãã«ã§ããŒã¯ããããšã³ããªãã€ã³ãã1ã€ãããå¿
ãç¡æ¡ä»¶ã®ãžã£ã³ãã³ãã³ãbrãŸãã¯ãªã¿ãŒã³ã³ãã³ãretã§çµäºããå¿
èŠããããŸãã ãããã®åã«æ¡ä»¶åå²ã³ãã³ããããå ŽåããããŸãããã®å Žåãçµäºã³ãã³ãã®çŽåã§ãªããã°ãªããŸããã ããŒã¹ãŠãããã«ã¯ãåä»»è
ã®ãªã¹ãïŒå¶åŸ¡ãååŸã§ããããŒã¹ãŠãããïŒãšåŸç¶ã®ãªã¹ãïŒå¶åŸ¡ã転éã§ããããŒã¹ãŠãããïŒããããŸãã ãã®æ
å ±ã«åºã¥ããŠãCFGãæ§ç¯ãããŸã-å¶åŸ¡ãããŒã°ã©ããå¶åŸ¡ãããŒã°ã©ããã³ã³ãã€ã©ã§ããã°ã©ã ãè¡šãæãéèŠãªæ§é ã
Cã®ãã¹ãäŸãèããŠã¿ãŸãããã
èšèªCã®ãœãŒã¹ã³ãŒãã«ãµã€ã¯ã«ãæãããŸãã
CFGã®åœ¢åŒã¯æ¬¡ã®ãšããã§ãã
LLVMã®å¥ã®ã¿ã€ãã®ã°ã©ãã¯ãDAG-æåéå·¡åã°ã©ããåºæ¬åäœã§ããæåéå·¡åã°ã©ãã§ãã
ã¢ã»ã³ãã©ãŒã³ãã³ããšãããã®éã®äŸåé¢ä¿ãè¡šããŸãã 次ã®å³ã¯ãããŒã¹ãŠãããã®DAGã瀺ããŠããŸããããã¯ãäžèšã®äŸã®ã«ãŒãã®æ¬äœãè¡šããæé©åã¬ãã«ã¯-O1ã§ãã
SSAãã©ãŒã
é«æ°Žæºèšèªãšåºå¥ããIRã³ãŒãã®äž»èŠãªæ©èœã¯ãããããSSA圢åŒïŒéçåäžå²ãåœãŠåœ¢åŒïŒã§è¡šç€ºãããããšã§ãã ãã®æ©èœã¯ãLLVMãã©ãããã©ãŒã ã§ã³ã³ãã€ã©ãŒãéçºããéã«ç解ããããã«éåžžã«éèŠã§ããããã泚æãæããŸãã èŠããã«ãSSA圢åŒã§ã¯ãåå€æ°ã«ã¯ããã°ã©ã ã®1ã€ã®ãã€ã³ãã§ã®ã¿1åã ãå€ãå²ãåœãŠãããŸãã IRã³ãŒãã®æé©åããã³å€æã¢ã«ãŽãªãºã ã¯ãã¹ãŠããã®ãã©ãŒã ã§ã®ã¿æ©èœããŸãã
ããããéåžžã®é«çŽèšèªããã°ã©ã ããã®åœ¢åŒã«å€æããæ¹æ³ã¯ïŒ å®éãéåžžã®ããã°ã©ãã³ã°èšèªã§ã¯ãå€æ°ã®å€ã¯ãããã°ã©ã ã®ããŸããŸãªå ŽæããŸãã¯ã«ãŒããªã©ã§è€æ°åå²ãåœãŠãããšãã§ããŸãã
ãã®ããã°ã©ã ã®åäœãå®è£
ããã«ã¯ã2ã€ã®æ¹æ³ã®ããããã䜿çšããŸãã æåã®ããªãã¯ã¯ãäžèšã®ã³ãŒãã®ããã«ãããŒã/ã¹ãã¢ã³ãã³ãã®ãã¢ã䜿çšããããšã§ãã å¯äžã®å²ãåœãŠå¶éã¯ãLLVMååä»ãå€æ°ã«ã®ã¿é©çšããããã€ã³ã¿ãŒã«ãã£ãŠåç
§ãããã¡ã¢ãªã®å Žæã«ã¯é©çšãããŸããã ã€ãŸããstoreã³ãã³ãã䜿çšããŠã¡ã¢ãªã»ã«ã«ç¡å¶éã®åæ°æžã蟌ãããšãã§ãããã®ã»ã«ãžã®ãã€ã³ã¿ã¯å€æŽãããªããããæ£åŒãªSSAã«ãŒã«ãéµå®ãããŸãã ãã®ã¡ãœããã¯éåžžã-O0ã®æé©åã¬ãã«ã§äœ¿çšãããŸãã詳现ã«ã€ããŠã¯èª¬æããŸããã 2çªç®ã®ããªãã¯ã§ã¯ãIRã³ãŒãã®ãã1ã€ã®èå³æ·±ãæŠå¿µã§ããÏé¢æ°ã䜿çšããŸãã
SSAã³ãŒãïŒããŒã/ã¹ãã¢
åã®ã»ã¯ã·ã§ã³ã®ãã¹ãã±ãŒã¹ã䜿çšããŸãã
æé©åã¬ãã«-O0ã§ã³ã³ãã€ã«ããŸãã
define i32 @for_loop(i32* %x) #0 {
%1 = alloca i32*, align 4
%sum = alloca i32, align 4
%i = alloca i32, align 4
store i32* %x, i32** %1, align 4
store i32 0, i32* %sum, align 4
store i32 0, i32* %i, align 4
br label %2
; :2 ; preds = %12, %0
%3 = load i32* %i, align 4
%4 = icmp slt i32 %3, 10
br i1 %4, label %5, label %15
; :5 ; preds = %2
%6 = load i32* %i, align 4
%7 = load i32** %1, align 4
%8 = getelementptr inbounds i32* %7, i32 %6
%9 = load i32* %8, align 4
%10 = load i32* %sum, align 4
%11 = add nsw i32 %10, %9
store i32 %11, i32* %sum, align 4
br label %12
; :12 ; preds = %5
%13 = load i32* %i, align 4
%14 = add nsw i32 %13, 1
store i32 %14, i32* %i, align 4
br label %2
; :15 ; preds = %2
%16 = load i32* %sum, align 4
ret i32 %16
}
ããã§ãäžèšã®å
容ãããããŸããã«ãŒãå€æ°ã¯ãïŒ
iãã€ã³ã¿ãŒã«ãã£ãŠåç
§ãããåãªãã¡ã¢ãªã»ã«ã§ãã
SSAã³ãŒãïŒÏé¢æ°
O1æé©åã¬ãã«ãè©ŠããŠã¿ãŸãããã
define i32 @for_loop(i32* nocapture readonly %x) #0 {
br label %1
; :1 ; preds = %1, %0
%i.02 = phi i32 [ 0, %0 ], [ %5, %1 ]
%sum.01 = phi i32 [ 0, %0 ], [ %4, %1 ]
%2 = getelementptr inbounds i32* %x, i32 %i.02
%3 = load i32* %2, align 4, !tbaa !2
%4 = add nsw i32 %3, %sum.01
%5 = add nsw i32 %i.02, 1
%exitcond = icmp eq i32 %5, 10
br i1 %exitcond, label %6, label %1
; :6 ; preds = %1
ret i32 %4
}
ããã§ãã«ãŒãå€æ°ã¯ïŒ
i.02ïŒLLVMã®å€æ°åã«ã¯ããªãªããå«ããããšãã§ããŸãïŒã§ãããããã¯ãã€ã³ã¿ãŒã§ã¯ãªãéåžžã®32ãããå€æ°ã§ãããå€ã¯phi i32é¢æ°[0ãïŒ
0]ã䜿çšããŠå²ãåœãŠãããŸãã [ïŒ
5ãïŒ
1]ã ããã¯ãããŒã¹ãããã¯ïŒ
0ïŒé¢æ°ã®æåã®ããŒã¹ãããã¯ïŒããé·ç§»ãçºçããå Žåãé¢æ°ã¯å€0ãåããããŒã¹ãããã¯ïŒ
1ïŒåãããŒã¹ã®åºåãã€ã³ãããé·ç§»ãçºçããå Žåãå€æ°ïŒ
5ã®å€ãããã¯ïŒã ãããã£ãŠãIRã³ãŒããžã§ãã¬ãŒã¿ãŒã¯ãå³å¯ã«æ£åŒãªSSAã«ãŒã«ã«åŸã£ãŠã2ã€ã®å€æ°ã®å²ãåœãŠãåãé€ããŸããã ããã«ãåæ§ã®æ¹æ³ã§variableïŒ
sum.01ãžã®å²ãåœãŠãçºçããããšãããããŸãã
ãã®ãããÏé¢æ°ã®æå³ã¯ããã®å€ãã©ã®åºæ¬åäœããé·ç§»ãããã«äŸåãããšããããšã§ãã Ïé¢æ°ã¯ãããŒã¹ãŠãããã®å
é ã§ã®ã¿èŠã€ããããšãã§ããŸãã è€æ°ããå Žåã¯ãããŒã¹ãŠãããã®æåã®åœä»€ããé£ç¶ããŠå®è¡ããå¿
èŠããããŸãã
ã¢ã¢æé©åïŒ
æé©åã¬ãã«-O2ã§ã¯ã©ããªããŸããïŒ
define i32 @for_loop(i32* nocapture readonly %x) #0 {
%1 = load i32* %x, align 4, !tbaa !2
%2 = getelementptr inbounds i32* %x, i32 1
%3 = load i32* %2, align 4, !tbaa !2
%4 = add nsw i32 %3, %1
%5 = getelementptr inbounds i32* %x, i32 2
%6 = load i32* %5, align 4, !tbaa !2
%7 = add nsw i32 %6, %4
%8 = getelementptr inbounds i32* %x, i32 3
%9 = load i32* %8, align 4, !tbaa !2
%10 = add nsw i32 %9, %7
%11 = getelementptr inbounds i32* %x, i32 4
%12 = load i32* %11, align 4, !tbaa !2
%13 = add nsw i32 %12, %10
%14 = getelementptr inbounds i32* %x, i32 5
%15 = load i32* %14, align 4, !tbaa !2
%16 = add nsw i32 %15, %13
%17 = getelementptr inbounds i32* %x, i32 6
%18 = load i32* %17, align 4, !tbaa !2
%19 = add nsw i32 %18, %16
%20 = getelementptr inbounds i32* %x, i32 7
%21 = load i32* %20, align 4, !tbaa !2
%22 = add nsw i32 %21, %19
%23 = getelementptr inbounds i32* %x, i32 8
%24 = load i32* %23, align 4, !tbaa !2
%25 = add nsw i32 %24, %22
%26 = getelementptr inbounds i32* %x, i32 9
%27 = load i32* %26, align 4, !tbaa !2
%28 = add nsw i32 %27, %25
ret i32 %28
}
ãªããã£ãã€ã¶ãŒã¯ã«ãŒããéå§ããŸããã äžè¬ã«ãLLVM IRã³ãŒããªããã£ãã€ã¶ãŒã¯éåžžã«ã€ã³ããªãžã§ã³ãã§ããã«ãŒããå±éããã ãã§ãªããã³ãŒãã«æ瀺çã«ååšããªãå Žåã§ããéèŠãªæ§æãåçŽåããå®æ°å€ãèšç®ããä»ã®è€éãªã³ãŒãå€æãå®è¡ã§ããŸãã
IRã³ãŒãã®ã¬ã€ã¢ãŠã
å®éã®ããã°ã©ã ã¯1ã€ã®ã¢ãžã¥ãŒã«ã§æ§æãããŠããŸããã åŸæ¥ã®ã³ã³ãã€ã©ã¯ãã¢ãžã¥ãŒã«ãåå¥ã«ã³ã³ãã€ã«ãããªããžã§ã¯ããã¡ã€ã«ã«å€æããŠãããªã³ã«ãŒïŒãªã³ã«ãŒïŒã«æž¡ããŸãããªã³ã«ãŒã¯ãããã1ã€ã®å®è¡å¯èœãã¡ã€ã«ã«çµåããŸãã LLVMã§ããããè¡ãããšãã§ããŸãã
ãã ããLLVMã«ã¯IRã³ãŒããäœæããæ©èœããããŸãã ãããæ€èšããæãç°¡åãªæ¹æ³ã¯ãäŸã䜿çšããããšã§ãã foo.cãšbar.cã®2ã€ã®ãœãŒã¹ã¢ãžã¥ãŒã«ããããšããŸãã
ããã°ã©ã ããåŸæ¥ã®ãæ¹æ³ã§ã³ã³ãã€ã«ãããŠããå Žåããªããã£ãã€ã¶ãŒã¯ã»ãšãã©äœãã§ããŸãããfoo.cãã³ã³ãã€ã«ãããšããã³ã³ãã€ã©ãŒã¯baré¢æ°å
ã«äœãããããç¥ãããbarïŒïŒåŒã³åºããæ¿å
¥ããå¯äžã®æçœãªæ¹æ³ãå®è¡ã§ããŸãã
ããããIRã³ãŒããäœæãããšã1ã€ã®ã¢ãžã¥ãŒã«ãåŸãããŸãã-O2ã¬ãã«ã§æé©åãããšã次ã®ããã«ãªããŸãïŒããããããããããã«ãã¢ãžã¥ãŒã«ããããŒãšã¡ã¿ããŒã¿ã¯çç¥ãããŸãïŒã
define i32 @foo(i32 %x, i32 %y) #0 {
%1 = shl i32 %x, 1
%2 = mul i32 %1, %x
%3 = mul i32 %y, 3
%4 = mul i32 %3, %y
%5 = add nsw i32 %4, %2
ret i32 %5
}
; Function Attrs: nounwind readnone
define i32 @bar(i32 %x, i32 %k) #0 {
%1 = mul nsw i32 %x, %x
%2 = mul nsw i32 %1, %k
ret i32 %2
}
fooé¢æ°ã§åŒã³åºããè¡ããããã³ã³ãã€ã©ãŒãbarïŒïŒã®å
容ãå®å
šã«è»¢éããŠãéäžã§kã®å®æ°å€ã眮ãæããŠããããšãããããŸãã barïŒïŒé¢æ°ã¯ã¢ãžã¥ãŒã«å
ã«æ®ããŸãããããã°ã©ã å
ã®ä»ã®å Žæã§åŒã³åºãããªãéããå®è¡å¯èœãã¡ã€ã«ã®ã³ã³ãã€ã«æã«é€å€ãããŸãã
GCCã«ã¯ãäžéã³ãŒãããªã³ã¯ããã³æé©åããæ©èœïŒLTOããªã³ã¯ææé©åïŒãããããšã«æ³šæããŠãã ãã[6]ã
ãã¡ãããLLVMã§ã®æé©åã¯IRã³ãŒãã®æé©åã«éå®ãããŸããã ããã¯ãšã³ãå
éšã§ã¯ãIRã³ãŒãããã·ã³è¡šçŸã«å€æããããŸããŸãªæ®µéã§ããŸããŸãªæé©åãè¡ãããŸãã LLVMã¯ãããã®æé©åã®äžéšãç¬èªã«å®è¡ããŸãããããã¯ãšã³ãéçºè
ã¯ãããã»ããµã¢ãŒããã¯ãã£ã®æ©èœãå®å
šã«äœ¿çšã§ããããã«ããç¬èªã®æé©åã¢ã«ãŽãªãºã ãéçºã§ããŸãïŒãŸããéçºããå¿
èŠããããŸãïŒã
ã¿ãŒã²ãããã©ãããã©ãŒã ã®ã³ãŒãçæ
å
ã®ããã»ããµã¢ãŒããã¯ãã£çšã®ã³ã³ãã€ã©ã®éçºãããã¯äž»ã«ããã¯ãšã³ãã®éçºã§ãã ååãšããŠãããã³ããšã³ãã¢ã«ãŽãªãºã ãžã®ä»å
¥ã¯äžèŠã§ãããããã«ããŠããéåžžã«æ£åœãªçç±ãå¿
èŠã§ãã Clangã®ãœãŒã¹ã³ãŒããåæãããšãã»ãšãã©ã®ãç¹å¥ãªãã¢ã«ãŽãªãºã ããéæšæºåœ¢åŒã®å®æ°ãæã€x86ããã³PowerPCããã»ããµã«åœãŠã¯ãŸãããšãããããŸãã ä»ã®ã»ãšãã©ã®ããã»ããµã§ã¯ãåºæ¬åã®ãµã€ãºãšãšã³ãã£ã¢ã³ïŒããã°ãšã³ãã£ã¢ã³ãŸãã¯ãªãã«ãšã³ãã£ã¢ã³ïŒã®ã¿ãæå®ããå¿
èŠããããŸãã ã»ãšãã©ã®å ŽåããµããŒããããŠããå€ãã®ããã»ããµã®äžããïŒããã深床ã«é¢ããŠïŒåæ§ã®ããã»ããµãç°¡åã«èŠã€ããããšãã§ããŸãã
ã¿ãŒã²ãããã©ãããã©ãŒã ã®ã³ãŒãçæã¯ãLLVMãLLCããã¯ãšã³ãã§è¡ãããŸãã LLCã¯å€ãã®ç°ãªãããã»ããµããµããŒãããŠãããããã«åºã¥ããŠç¬èªã®ãªãªãžãã«ããã»ããµçšã®ã³ãŒããžã§ãã¬ãŒã¿ãäœæã§ããŸãã ãŸãããã®ã¿ã¹ã¯ã¯ããµããŒããããŠããåã¢ãŒããã¯ãã£ã®ã¢ãžã¥ãŒã«ãå«ããã¹ãŠã®ãœãŒã¹ã³ãŒããå®å
šã«ãªãŒãã³ã§ããã調æ»ã«å©çšã§ãããããç°¡çŽ åãããŠããŸãã
ã¿ãŒã²ãããã©ãããã©ãŒã ïŒã¿ãŒã²ããïŒã®ã³ãŒããžã§ãã¬ãŒã¿ãŒã¯ãLLVMã€ã³ãã©ã¹ãã©ã¯ãã£ã«åºã¥ããŠã³ã³ãã€ã©ãŒãéçºãããšãã«æãæéã®ãããã¿ã¹ã¯ã§ãã ã¿ãŒã²ããããã»ããµã®ã¢ãŒããã¯ãã£ã«å€§ããäŸåããŠãããããããã§ã¯ããã¯ãšã³ãå®è£
ã®æ©èœã«ãã ãããªãããšã«ããŸããã ãã ããå°æ¬ãããHabrã®èŠèŽè
ããã®ãããã¯ã«èå³ãæã£ãŠããå Žåã¯ã次ã®èšäºã§ããã¯ãšã³ããéçºããéã®éèŠãªãã€ã³ãã説æããæºåãã§ããŠããŸãã
ãããã«
çãèšäºã§ã¯ãLLVMã¢ãŒããã¯ãã£ãLLVM IRæ§æãããã¯ãšã³ãéçºããã»ã¹ã®ãããã«ã€ããŠã詳现ã«æ€èšããããšã¯ã§ããŸããã ãã ãããããã®åé¡ã«ã€ããŠã¯ããã¥ã¡ã³ãã§è©³ãã説æããŠããŸãã èè
ã¯ãããLLVMã³ã³ãã€ã©ã€ã³ãã©ã¹ãã©ã¯ãã£ã®äžè¬çãªã¢ã€ãã¢ãäžããããšããŸããããã®ãã©ãããã©ãŒã ã¯ãã¢ãã³ã§åŒ·åã§ãæ®éçã§ãããå
¥åèšèªãŸãã¯ã¿ãŒã²ããããã»ããµã¢ãŒããã¯ãã£ããç¬ç«ããŠãããããéçºè
ã®èŠæ±ã«å¿ããŠäž¡æ¹ãå®è£
ã§ããŸãã
ã¬ãã¥ãŒæžã¿ã®ãã®ã«å ããŠãLLVMã«ã¯ä»ã®ãŠãŒãã£ãªãã£ãå«ãŸããŠããŸããããããã®èæ
®äºé
ã¯èšäºã®ç¯å²ãè¶
ããŠããŸãã
LLVMã䜿çšãããšããã€ãã©ã€ã³ã¢ãŒããã¯ãã£ãå«ãããããã¢ãŒããã¯ãã£ïŒæ³šãåç
§ïŒã«ããã¯ãšã³ããå®è£
ã§ããŸããã³ãã³ãã®äžŠå€ããå®è¡ãããŸããŸãªäžŠååãªãã·ã§ã³ãVLIWãã¯ã©ã·ãã¯ã¢ãŒããã¯ãã£ããã³ã¹ã¿ãã¯ã¢ãŒããã¯ãã£ãäžè¬ã«ä»»æã®ãªãã·ã§ã³ã
éæšæºãœãªã¥ãŒã·ã§ã³ãããã»ããµã¢ãŒããã¯ãã£ã®äžå¿ã«ãããã©ããã«é¢ä¿ãªããå€ããå°ãªããã³ãŒããèšè¿°ããã ãã§ãã
ã¡ã¢çç±ã®ç¯å²å
ã®èª°ã§ãã 次ã®ããã«ã4ãããã¢ãŒããã¯ãã£çšã®Cèšèªã³ã³ãã€ã©ãå®è£
ããããšã¯ã»ãšãã©äžå¯èœã§ãã èšèªæšæºã§ã¯ãå°ãªããšã8ã®ããã深床ãæ瀺çã«å¿
èŠã§ãã
æåŠ
ã³ã³ãã€ã©ãŒ[1]
ãã©ãŽã³ããã¯[2] Wirth N.ãã«ãã³ã³ãã€ã©
Gcc[3]
gcc.gnu.org -GCCãããžã§ã¯ããµã€ã
[4]ãªãã£ãŒãM.ã¹ããŒã«ãã³ãšGCCéçºè
ã³ãã¥ããã£ã GNUã³ã³ãã€ã©ã³ã¬ã¯ã·ã§ã³ã®å
éš
LLVM[5]
http://llvm.org/-LLVMãããžã§ã¯ããµã€ã
[6]
http://llvm.org/docs/GettingStarted.html LLVMã·ã¹ãã å
¥é
[7]
http://llvm.org/docs/LangRef.html LLVMèšèªãªãã¡ã¬ã³ã¹ããã¥ã¢ã«
[8]
http://llvm.org/docs/WritingAnLLVMBackend.html LLVMããã¯ãšã³ãã®äœæ
[9]
http://llvm.org/docs/WritingAnLLVMPass.html LLVMãã¹ã®äœæ
[10] Chen Chung-Shuã Cpu0ã¢ãŒããã¯ãã£çšã®LLVMããã¯ãšã³ãã®äœæ
[11] Mayur PandeyãSuyog Sardaã LLVMã¯ãã¯ããã¯
[12]ãã«ãŒãã»ã«ã«ããŒãŸã»ããã¹ã LLVMã³ã¢ã©ã€ãã©ãªå
¥é
[13] Suyog SardaãããŠãŒã«ãã³ãã£ã LLVM Essentials
èè
ã¯ãã³ã¡ã³ããšPMã§ããªãã®è³ªåã«åãã§çããŸãã
PMã§éç¥ããããã¹ãŠã®ã¿ã€ããã¹ã«ã€ããŠéç¥ããèŠæ±ã äºåã«æè¬ããŸãã