clang+llvmã§ããããªããããã³ã¼ããçæããã¦ãã話ã
å
æ¥llvm 3.3ããªãªã¼ã¹ããã¾ãããaarch64(arm 64bit)ã®ã³ã¼ããçæã§ããããã«ãªã£ãã¨ãããã¨ãªã®ã§ãã½ã¼ã¹ãããã«ããã¦éãã§ããã®ã§ãããããããªãåãæé©åãããã³ã¼ããçæããã¦ããã®ã«æ°ãã¤ãã¾ãããaarch64ã ã¨ä»ã¯å®è¡ãã¦ç¢ºèªã§ããç°å¢ãæå
ã«ç¡ãã®ã§ãæ®éã®armv7-aã§åããã¨ã試ãã¾ããã
ããã§ä½¿ã£ãã³ã¼ãã¨ãã®çµæã¯gistã«è²¼ãã¾ããã
https://gist.github.com/tetsu-koba/5835724
ã½ã¼ã¹ã³ã¼ã
int sum(int x) { int sum = 0; int i; for (i = 1; i <= x; i++) { sum += i; } return sum; }
1ããnã¾ã§ã®ç·åãæ±ããé¢æ°ã§ãã1ãã100ã¾ã§ã®ç·åã5050ãªã®ã¯ガウス少年の逸話ã§æåã§ããã
gcc 4.8.1ã§ã®çæã³ã¼ã
sum: cmp r0, #0 ble .L4 adds r2, r0, #1 movs r3, #1 movs r0, #0 .L3: add r0, r0, r3 adds r3, r3, #1 cmp r3, r2 bne .L3 bx lr .L4: movs r0, #0 bx lr
æé©å -Oãã¤ãã¦ã³ã³ãã¤ã«ãã¦ãã¾ãã(-O3ã«ãã¦ãç¹ã«å¤åã¯ããã¾ãããï¼
ã½ã¼ã¹ã³ã¼ãã«å¿ å®ã«ã«ã¼ããåãã¦ãã¾ãããããæ®éã®ã³ã¼ãã ã¨æã£ã¦ãã¾ãããllvmã®ã³ã¼ããè¦ãã¾ã§ã¯ã
clang+llvm 3.3 ã§ã®çæã³ã¼ã
sum: mov r1, #0 cmp r0, #1 blt .LBB0_2 sub r1, r0, #2 sub r2, r0, #1 umull r1, r2, r2, r1 and r2, r2, #1 lsrs r2, r2, #1 rrx r1, r1 add r0, r1, r0, lsl #1 sub r1, r0, #1 .LBB0_2: mov r0, r1 bx lr
ããï¼umullã¯ä¹ç®å½ä»¤ããªãããè¦ãã¨ã«ã¼ããã¦ãªããï¼
1ããnã®ç·åã¯nåå ç®ããªãã¦ãã1/2 * n * (n + 1) ã§æ±ãããããã¨ã¯ç¥èã¨ãã¦ã¯ç¥ã£ã¦ãã¾ãããllvmã¯ããã¨ä¼¼ããããªãã¨ããã¦ãã¾ãããããå¾®å¦ã«éãããããæ£ããã®ãã©ããã±ã£ã¨ã¿ã¦å¤æãã¤ãã¾ãããï¼æ£ãããã¨ã確èªãã¾ãããclang+llvmでさりげなくすごいコードが生成されていた話の補足。 - 組み込みの人。ï¼
é«éåã®ããã«å
ã®ã½ã¼ã¹ãæã§ã¢ã»ã³ãã©åããã¨ãã¦ãããã¾ã§ã®ã³ã¼ãã¯å³åº§ã«ã¯æ¸ãã¾ããããç§ãªãã³ã³ãã¤ã©ã«ãä»»ããã¾ãã
ããã«ä»¥ä¸ã®ã³ã¼ãã追å ãã¦ã¿ã¾ããã
#include <stdio.h> int main() { int n; n = 100; printf("sum(%d) = %d\n", n, sum(n)); }
ããã¦ããã®é¨åã®çæã³ã¼ãã¯
main: push {r11, lr} movw r0, :lower16:.L.str mov r1, #100 movt r0, :upper16:.L.str movw r2, #5050 mov r11, sp bl printf mov r0, #0 pop {r11, pc}
ããã¯ä¸æ¬åãããï¼
sum(100)=5050ãªã®ã¯ã³ã³ãã¤ã«ããæç¹ã§ããã£ã¦ããã®ã§ãããsumé¢æ°ãå¼ã°ãã«å®æ°ã§5050ãprintfã«æ¸¡ãã¦ãã¾ãã
ã¡ãªã¿ã«gcc 4.8.1ã ã¨
main: movs r3, #1 movs r2, #0 .L9: add r2, r2, r3 adds r3, r3, #1 cmp r3, #101 bne .L9 movw r0, #:lower16:.LC0 movs r1, #100 movt r0, #:upper16:.LC0 b printf
sumé¢æ°ãããã«ã¤ã³ã©ã¤ã³å±éããã¦ãå®æ°100ãåãè¾¼ã¾ãã¦ãã¾ããããããã¨ãã¦100åã«ã¼ããã¦ãã¾ãã
(2013.6.24追è¨ï¼
èªåã§ãã«ãããgccã§ã¯ãã¡ã§ããããUbuntu 12.04LTSã§apt-get installããarm-linux-gnueabihf-gcc ã§ã¯ -O2ãã¤ããã¨clangã¨åæ§ã«sumé¢æ°ãå¼ã°ãã«å®æ°ã§5050ãprintfã«æ¸¡ããããªã³ã¼ããçæãã¾ãã
æå
ã®ããã¤ãã®ãã¼ã¸ã§ã³ã®gccã§è©¦ããã¨ããã§ã¯ã4.6, 4.7ã§ã¯ããã®ã§ããã4.8ã§ãã¡ã«ãªã£ãããã§ãããªã°ã¬ãã·ã§ã³ããªï¼
(追è¨ããã¾ã§ã)
ã¾ã¨ã
ãã®é¢æ°ã®ä¸ä¾ã«ã¤ãã¦è¨ãã°ãgccã®æé©åã ã¨ã«ã¼ãã®åæ°ã¯å¤ããã¾ããããclang+llvmã§ã¯å¾¹åºçã®ã«ã¼ããé¤å»ãããã¨ãã¾ããã«ã¼ãã®åæ°ã大ãããªãã¨ãã®å®è¡æéã®å·®ã¯å¦å®ã«ç¾ããã¯ãã§ããllvmããããï¼ãªãããã®æé©åãllvm 3.3ãããªã®ãããã以åãããããªã®ãã¯èª¿ã¹ã¦ãã¾ãããï¼
ç§èªèº«ã¯ã³ã³ãã¤ã©ã®ä¸èº«ã«ã¤ãã¦ãããªãã«ç¥èãããã®ã§ããã®ãããªæé©åãå¯è½ã§ãããã¨ã¯ç¥ã£ã¦ããã®ã§ãããç¾ç¶ã®clang + llvmã§ã³ã³ãã¤ã«ãªãã·ã§ã³ã«-Oãã²ã¨ã¤è¿½å ããã ãã§ããã¾ã§ãã£ã¦ãããã¨ã¯é©ãã§ããã
ããã«æã£ããã¨
llvmã§ãã®ãããªæé©åãã§ããã®ã¯ããã®sumé¢æ°ããç´ç²ãªé¢æ°ãã§ãããä¸ããããå¼æ°ã«ãã£ã¦ã®ã¿é¢æ°å¤ãè¨ç®ã§ãããã以å¤ã®å¯ä½ç¨ã®å½±é¿ãåããªããä¸ããªãããã§ããCè¨èªã§ã¯ãã£ããããã¨å¯ä½ç¨ã®ããã³ã¼ããæ··ãã¦ãã¾ããã¨ãç°¡åã«ã§ãã¦ãã¾ããï¼ä¾ãã°ãã«ã¼ãã®ä¸ã§ã°ãã¼ãã«å¤æ°ããã¤ã³ã¿ãåç
§ãããªã©ãï¼ããããã¨æé©åãå¹ããªããªã£ã¦ãã¾ãã¾ãã
ããããã®ã³ã¼ããæ¸ãè
ã®æéã¨ãã¦ãã©ãæ¸ãã¨ã©ãæé©åãå¹ãããããã«æé©åãéªéããªãããã«ã³ã¼ããæ¸ããã¨ãããã¨ãåãããã®ããªã¨æãã¾ããããããã¯ãã³ã³ãã¤ã©ã®æé©åãéªéãã«ãããããªè¨èªä»æ§ã®è¨èªãç¿å¾ãã¦ããã使ãããã³ã³ãã¤ã©ã®æé©åãéªéãã«ããè¨èªã®ã²ã¨ã¤ã¨ãã¦ã¯é¢æ°åè¨èªãããã¾ããã