初めに
C言語ソース
unused_var.c
int main() {
int used = 3;
int unused = 10; // 使用されない変数
return used * 2;
}
最適化の設定
最適化なし (-O0)
gcc -S -O0 -masm=intel unused_var.c -o unused_varO0.s
最大最適化 (-O3)
gcc -S -O3 -masm=intel unused_var.c -o unused_varO3.s
最適化しない場合
unused_varO0.s のコード
unused_varO0.s
.file "unused_var.c"
.intel_syntax noprefix
.def ___main; .scl 2; .type 32; .endef
.text
.globl _main
.def _main; .scl 2; .type 32; .endef
_main:
LFB0:
.cfi_startproc
push ebp
.cfi_def_cfa_offset 8
.cfi_offset 5, -8
mov ebp, esp
.cfi_def_cfa_register 5
and esp, -16
sub esp, 16
call ___main
mov DWORD PTR [esp+12], 3
mov DWORD PTR [esp+8], 10
mov eax, DWORD PTR [esp+12]
add eax, eax
leave
.cfi_restore 5
.cfi_def_cfa 4, 4
ret
.cfi_endproc
LFE0:
.ident "GCC: (MinGW.org GCC-6.3.0-1) 6.3.0"
最適化する場合
unused_varO3.s のコード
unused_varO3.s
.file "unused_var.c"
.intel_syntax noprefix
.def ___main; .scl 2; .type 32; .endef
.section .text.startup,"x"
.p2align 4,,15
.globl _main
.def _main; .scl 2; .type 32; .endef
_main:
LFB0:
.cfi_startproc
push ebp
.cfi_def_cfa_offset 8
.cfi_offset 5, -8
mov ebp, esp
.cfi_def_cfa_register 5
and esp, -16
call ___main
mov eax, 6
leave
.cfi_restore 5
.cfi_def_cfa 4, 4
ret
.cfi_endproc
LFE0:
.ident "GCC: (MinGW.org GCC-6.3.0-1) 6.3.0"
分析
未使用変数が消えた。
スタックに詰めてから取り出す処理が無くなった。
used * 2の結果をそのまま返り値eaxレジスタに詰めている。
mov DWORD PTR [esp+12], 3
mov DWORD PTR [esp+8], 10
mov eax, DWORD PTR [esp+12]
add eax, eax
が1行に短縮される。
mov eax, 6
動作環境
windows7 Version6.1.7601
GCC-6.3.0-1
(帰省中につき一時的に昔のパソコンを使用している。windows7が懐かしい。。。)