Tru64 UNIXで遊ぼう!(inline編)
Tru64 UNIXでlibarchiveをコンパイル出来るように試行錯誤していたところ、面白いものを見つけました。
どうやら、Tru64 UNIXの場合は関数指定子inlineを__inlineと定義しているようです。
どういうことなの?
せっかくなのでアセンブラを出力させてみました。
まずは普通のinline版
$ more inline.c static inline int max(int i1, int i2) { return (i1 > i2) ? i1:i2; } int main(int argc, char *argv[]) { return max(1,5); }
$ cc -V Compaq C V6.5-303 (dtk) on HP Tru64 UNIX V5.1B (Rev. 2650) Compiler Driver V6.5-302 (dtk) cc Driver
$ cc -S inline.c $ more inline.s .set noat .set noreorder .text .arch generic .align 4 .file 1 "inline.c" .loc 1 1 # 1 static inline int .ent $$1$max .loc 1 1 .loc 1 2 # 2 max(int i1, int i2) { $$1$max: # 000002 .frame $sp, 0, $26 .prologue 0 .context full sextl $17, $17 sextl $16, $0 .loc 1 3 # 3 return (i1 > i2) ? i1:i2; cmplt $0, $17, $1 # 000003 cmovne $1, $17, $0 .loc 1 4 # 4 } ret ($26) # 000004 .end $$1$max unop unop unop .loc 1 1 .loc 1 6 # 5 # 6 int .globl main .ent main .loc 1 6 .loc 1 7 # 7 main(int argc, char *argv[]) main: # 000007 .frame $sp, 0, $26 .prologue 0 .loc 1 9 # 8 { # 9 return max(1,5); .context full mov 5, $17 # 000009 mov 1, $16 br $$1$max .end main .loc 1 6
おおう、普通にmaxを呼び出してますね...
では待望の__inline版
$ more __inline.c static __inline int max(int i1, int i2) { return (i1 > i2) ? i1:i2; } int main(int argc, char *argv[]) { return max(1,5); }
$ cc -S __inline.c
$ more __inline.s
.set noat
.set noreorder
.text
.arch generic
.align 4
.file 1 "__inline.c"
.loc 1 6
# 6 int
.globl main
.ent main
.loc 1 6
.loc 1 7
# 7 main(int argc, char *argv[])
main: # 000007
.frame $sp, 0, $26
.prologue 0
.loc 1 3
.context full
mov 5, $0 # 000003
.loc 1 10
# 8 {
# 9 return max(1,5);
# 10 }
ret ($26) # 000010
.end main
.loc 1 6
おーっ!インライン展開されています!
というわけで、Compaq C Compilerの場合、関数指定子inlineを__inlineと定義すれば、最適化をかけなくてもインライン展開されるということがわかりました〜
(もちろん普通?のinlineの場合でも最適化をかけるとインライン展開される)
ちなみにコンパイラにgccを使った場合は、関数指定子inline、__inlineどちらを使っても結果は変わりませんでした〜
(もちろん最適化をかけると、どちらもインライン展開される)
$ gcc -v Using built-in specs. Target: alphaev68-dec-osf5.1b Configured with: ./configure --enable-languages=c,c++ --enable-threads=posix --disable-nls --without-gnu-ld --with-ld=/usr/ccs/bin/ld --without-gnu-as --with-as=/usr/bin/as --disable-libssp Thread model: posix gcc version 4.4.7 (GCC)
$ /usr/local/bin/gcc -S __inline.c $ more __inline.s .file 1 "__inline.c" .verstamp 3 11 .set noreorder .set volatile .set noat .arch ev6 .text .align 2 .ent max $max..ng: max: .frame $15,32,$26,0 .mask 0x4008000,-32 lda $30,-32($30) stq $26,0($30) stq $15,8($30) bis $31,$30,$15 .prologue 0 bis $31,$16,$2 bis $31,$17,$1 stl $2,16($15) stl $1,20($15) ldl $2,20($15) ldl $1,16($15) cmple $2,$1,$3 cmoveq $3,$2,$1 addl $31,$1,$1 bis $31,$1,$0 bis $31,$15,$30 ldq $26,0($30) ldq $15,8($30) lda $30,32($30) ret $31,($26),1 .end max .align 2 .globl main .ent main main: .frame $15,32,$26,0 .mask 0x4008000,-32 ldgp $29,0($27) $main..ng: lda $30,-32($30) stq $26,0($30) stq $15,8($30) bis $31,$30,$15 .prologue 1 bis $31,$16,$1 stq $17,24($15) stl $1,16($15) lda $16,1($31) lda $17,5($31) bsr $26,$max..ng bis $31,$0,$1 bis $31,$1,$0 bis $31,$15,$30 ldq $26,0($30) ldq $15,8($30) lda $30,32($30) ret $31,($26),1 .end main
うーむ、libarchiveにこの修正を突っ込んだ人はどこで発見したんですかね?
有名な話なのかな?