なんか書くネタが無いので、前から書こうと思ってて、ずっときっかけが無くて放置してたGCCバッドノウハウ


gcc-4.0から、-combineとゆーオプションが増えた。
infoによると、

`-combine'
     If you are compiling multiple source files, this option tells the
     driver to pass all the source files to the compiler at once (for
     those languages for which the compiler can handle this).  This
     will allow intermodule analysis (IMA) to be performed by the
     compiler.  Currently the only language for which this is supported
     is C.  If you pass source files for multiple languages to the
     driver, using this option, the driver will invoke the compiler(s)
     that support IMA once each, passing each compiler all the source
     files appropriate for it.  For those languages that do not support
     IMA this option will be ignored, and the compiler will be invoked
     once for each source file in that language.  If you use this
     option in conjunction with `-save-temps', the compiler will
     generate multiple pre-processed files (one for each source file),
     but only one (combined) `.o' or `.s' file.

大体、「複数ファイルをいっぺんにコンパイルするんよ。で、そのとき、各ファイル間でintermodule analysis(IMA)するよ。」と、いうようなことが書いてある。
intermodule analysisっつのがよくわからんけど、名前からして、多分、関数を越える、モジュールレベルでの解析ということだと思う。関数間でレジスタのやりとりをどーのこーのしたりとか、副作用の無い関数の場合は、関数呼び出しを無くしてしまうとか、そういうの。


で、これで一番わかりやすいのは、インライン関数かと思う。

// a.c
#include "comb.h"

int main() 
{
  return inline_func();
}

--------
// b.c
#include "comb.h"

int
inline_func()
{
	return 400;
}
----------
// comb.h
extern inline int inline_func();

こんなふうにしといて、

$ gcc -S -O3 -combine a.c b.c

こんなふうにして実行。そうすると、

	.file	"a.c"
	.text
	.p2align 4,,15
.globl inline_func
	.type	inline_func, @function
inline_func:
	pushl	%ebp
	movl	$400, %eax
	movl	%esp, %ebp
	popl	%ebp
	ret
	.size	inline_func, .-inline_func
	.p2align 4,,15
.globl main
	.type	main, @function
main:
	pushl	%ebp
	movl	$400, %eax
	movl	%esp, %ebp
	subl	$8, %esp
	andl	$-16, %esp
	subl	$16, %esp
	leave
	ret
	.size	main, .-main
	.ident	"GCC: (GNU) 4.0.0"
	.section	.note.GNU-stack,"",@progbits

こういうのができる。a.cにinline_funcが無いけど、mainでは、inline_funcが展開されてるのがそこらへんの影響。


とは言っても、僕はこれまでインライン展開 する/しない が影響するような状況になんてなったこと無いので、役に立つのかどうかは判断できないが。