再帰関数の展開
4.3.0の最適化は凄いらしい。
http://d.hatena.ne.jp/toge/20080229#1204238423
with ada.integer_text_io; procedure test is function f(x : integer) return integer is begin if x <= 0 then return 1; else return x * f(x - 1); end if; end f; begin ada.integer_text_io.put(f(10)); end test;
gcc -O3 -S
.file "test.adb" .text .p2align 4,,15 .def _test__f.437; .scl 3; .type 32; .endef _test__f.437: LFB11: pushl %ebp LCFI0: movl %esp, %ebp LCFI1: subl $36, %esp LCFI2: movl %ebx, -12(%ebp) LCFI3: movl %eax, %ebx movl $1, %eax testl %ebx, %ebx movl %esi, -8(%ebp) LCFI4: movl %edi, -4(%ebp) LCFI5: jle L3 movl %ebx, %esi movl $1, %eax subl $1, %esi je L5 movl %ebx, %edi movl $1, %eax subl $2, %edi je L7 movl %ebx, %edx movl $1, %eax subl $3, %edx movl %edx, -36(%ebp) je L9 movl %ebx, %edx movl $1, %eax subl $4, %edx movl %edx, -32(%ebp) je L11 movl %ebx, %edx movl $1, %eax subl $5, %edx movl %edx, -28(%ebp) je L13 movl %ebx, %edx movl $1, %eax subl $6, %edx movl %edx, -24(%ebp) je L15 movl %ebx, %edx movl $1, %eax subl $7, %edx movl %edx, -20(%ebp) je L17 movl %ebx, %edx movl $1, %eax subl $8, %edx movl %edx, -16(%ebp) je L19 leal -9(%ebx), %eax call _test__f.437 imull -16(%ebp), %eax L19: imull -20(%ebp), %eax L17: imull -24(%ebp), %eax L15: imull -28(%ebp), %eax L13: imull -32(%ebp), %eax L11: imull -36(%ebp), %eax L9: imull %edi, %eax L7: imull %esi, %eax L5: imull %ebx, %eax L3: movl -12(%ebp), %ebx movl -8(%ebp), %esi movl -4(%ebp), %edi movl %ebp, %esp popl %ebp ret LFE11: .p2align 4,,15 .globl __ada_test .def __ada_test; .scl 2; .type 32; .endef __ada_test: LFB10: pushl %ebp LCFI6: movl $8, %eax movl %esp, %ebp LCFI7: subl $24, %esp LCFI8: leal -8(%ebp), %ecx movl %ebx, -8(%ebp) LCFI9: movl _ada__integer_text_io__default_base, %ebx movl %esi, -4(%ebp) LCFI10: movl _ada__integer_text_io__default_width, %esi call _test__f.437 movl %ebx, 8(%esp) movl %esi, 4(%esp) leal (%eax,%eax,8), %eax leal (%eax,%eax,4), %eax addl %eax, %eax movl %eax, (%esp) call _ada__integer_text_io__put__2 movl -8(%ebp), %ebx movl -4(%ebp), %esi movl %ebp, %esp popl %ebp ret LFE10: .section .eh_frame,"dr" Lframe1: .long LECIE1-LSCIE1 LSCIE1: .long 0x0 .byte 0x1 .def ___gnat_eh_personality; .scl 2; .type 32; .endef .ascii "zP\0" .uleb128 0x1 .sleb128 -4 .byte 0x8 .uleb128 0x5 .byte 0x0 .long ___gnat_eh_personality .byte 0xc .uleb128 0x4 .uleb128 0x4 .byte 0x88 .uleb128 0x1 .align 4 LECIE1: LSFDE1: .long LEFDE1-LASFDE1 LASFDE1: .long LASFDE1-Lframe1 .long LFB11 .long LFE11-LFB11 .uleb128 0x0 .byte 0x4 .long LCFI0-LFB11 .byte 0xe .uleb128 0x8 .byte 0x85 .uleb128 0x2 .byte 0x4 .long LCFI1-LCFI0 .byte 0xd .uleb128 0x5 .byte 0x4 .long LCFI3-LCFI1 .byte 0x83 .uleb128 0x5 .byte 0x4 .long LCFI5-LCFI3 .byte 0x87 .uleb128 0x3 .byte 0x86 .uleb128 0x4 .align 4 LEFDE1: LSFDE3: .long LEFDE3-LASFDE3 LASFDE3: .long LASFDE3-Lframe1 .long LFB10 .long LFE10-LFB10 .uleb128 0x0 .byte 0x4 .long LCFI6-LFB10 .byte 0xe .uleb128 0x8 .byte 0x85 .uleb128 0x2 .byte 0x4 .long LCFI7-LCFI6 .byte 0xd .uleb128 0x5 .byte 0x4 .long LCFI9-LCFI7 .byte 0x83 .uleb128 0x4 .byte 0x4 .long LCFI10-LCFI9 .byte 0x86 .uleb128 0x3 .align 4 LEFDE3: .def _ada__integer_text_io__put__2; .scl 2; .type 32; .endef
展開はされますけど、定数までたたみこんでくれません……。分岐も残ってます。
例外情報のラベルが除去できないとかそんなでしょうか。C++だとどうなんでしょ。