〔リスト1〕元のCソース(test230.c)
|
//ピープホール最適化をする例
#include <stdio.h>
main()
{
int x = 0;
int y = 0;
x = x + 1;
y = x^2;
printf("%d\n",x);
printf("%d\n",y);
y = y + 0;
y = y + 0;
y = y + 0;
y = y + 0;
y = y + 0;
goto L1;
return;
L1:
return;
printf("%d\n",x);
}
|
|
〔リスト2〕中間言語ソース(test230.c.00.rtl)
|
;; Function main
(note 2 0 5 NOTE_INSN_DELETED)
(insn 5 2 6 (nil) (parallel [
(set (reg/f:SI 7 esp)
(and:SI (reg/f:SI 7 esp)
(const_int -16 [0xfffffff0])))
(clobber (reg:CC 17 flags))
]) -1 (nil)
(nil))
(insn 6 5 7 (nil) (set (reg:SI 59)
(const_int 0 [0x0])) -1 (nil)
(expr_list:REG_EQUAL (const_int 0 [0x0])
(nil)))
(insn 7 6 8 (nil) (parallel [
(set (reg/f:SI 7 esp)
(minus:SI (reg/f:SI 7 esp)
(reg:SI 59)))
(clobber (reg:CC 17 flags))
]) -1 (nil)
(nil))
(insn 8 7 3 (nil) (set (reg/f:SI 60)
(reg/f:SI 55 virtual-stack-dynamic)) -1 (nil)
(nil))
(note 3 8 4 NOTE_INSN_FUNCTION_BEG)
(note 4 3 9 NOTE_INSN_DELETED)
(note 9 4 10 0xf6d75294 NOTE_INSN_BLOCK_BEG)
(note 10 9 12 NOTE_INSN_DELETED)
(insn 12 10 14 (nil) (set (mem/f:SI (plus:SI (reg/f:SI 54
virtual-stack-vars)
(const_int -4 [0xfffffffc])) [0 x+0 S4 A32])
(const_int 0 [0x0])) -1 (nil)
(nil))
(insn 14 12 16 (nil) (set (mem/f:SI (plus:SI (reg/f:SI 54
virtual-stack-vars)
(const_int -8 [0xfffffff8])) [0 y+0 S4 A32])
(const_int 0 [0x0])) -1 (nil)
(nil))
(insn 16 14 18 (nil) (parallel [
(set (mem/f:SI (plus:SI (reg/f:SI 54 virtual-
stack-vars)
(const_int -4 [0xfffffffc]))
[0 x+0 S4 A32])
(plus:SI (mem/f:SI (plus:SI (reg/f:SI 54
virtual-stack-vars)
(const_int -4 [0xfffffffc]))
[0 x+0 S4 A32])
(const_int 1 [0x1])))
(clobber (reg:CC 17 flags))
]) -1 (nil)
(nil))
(insn 18 16 19 (nil) (parallel [
(set (reg:SI 61)
(xor:SI (mem/f:SI (plus:SI (reg/f:SI 54
virtual-stack-vars)
(const_int -4 [0xfffffffc]))
[0 x+0 S4 A32])
(const_int 2 [0x2])))
(clobber (reg:CC 17 flags))
]) -1 (nil)
(nil))
(insn 19 18 21 (nil) (set (mem/f:SI (plus:SI (reg/f:SI 54
virtual-stack-vars)
(const_int -8 [0xfffffff8])) [0 y+0 S4 A32])
(reg:SI 61)) -1 (nil)
(expr_list:REG_EQUAL (xor:SI (mem/f:SI (plus:SI (reg/f:SI
54 virtual-stack-vars)
(const_int -4 [0xfffffffc])) [0 x+0 S4 A32])
(const_int 2 [0x2]))
(nil)))
(insn 21 19 22 (nil) (parallel [
(set (reg/f:SI 7 esp)
(plus:SI (reg/f:SI 7 esp)
(const_int -8 [0xfffffff8])))
(clobber (reg:CC 17 flags))
]) -1 (nil)
(nil))
(insn 22 21 23 (nil) (set (mem/f:SI (pre_dec:SI (reg/f:SI
7 esp)) [0 S4 A32])
(mem/f:SI (plus:SI (reg/f:SI 54 virtual-stack-vars)
(const_int -4 [0xfffffffc]))
[0 x+0 S4 A32])) -1 (nil)
(nil))
(insn 23 22 24 (nil) (set (mem/f:SI (pre_dec:SI
(reg/f:SI 7 esp)) [0 S4 A32])
(symbol_ref/f:SI ("*.LC0"))) -1 (nil)
(nil))
(call_insn 24 23 25 (nil) (set (reg:SI 0 eax)
(call (mem:QI (symbol_ref:SI ("printf")) [0 S1 A8])
(const_int 16 [0x10]))) -1 (nil)
(expr_list:REG_EH_REGION (const_int 0 [0x0])
(nil))
(nil))
(insn 25 24 27 (nil) (parallel [
(set (reg/f:SI 7 esp)
(plus:SI (reg/f:SI 7 esp)
(const_int 16 [0x10])))
(clobber (reg:CC 17 flags))
]) -1 (nil)
(nil))
(insn 27 25 28 (nil) (parallel [
(set (reg/f:SI 7 esp)
(plus:SI (reg/f:SI 7 esp)
(const_int -8 [0xfffffff8])))
(clobber (reg:CC 17 flags))
]) -1 (nil)
(nil))
(insn 28 27 29 (nil) (set (mem/f:SI (pre_dec:SI
(reg/f:SI 7 esp)) [0 S4 A32])
(mem/f:SI (plus:SI (reg/f:SI 54 virtual-stack-vars)
(const_int -8 [0xfffffff8])) [0 y+0 S4 A32]))
-1 (nil)
(nil))
(insn 29 28 30 (nil) (set (mem/f:SI (pre_dec:SI
(reg/f:SI 7 esp)) [0 S4 A32])
(symbol_ref/f:SI ("*.LC0"))) -1 (nil)
(nil))
(call_insn 30 29 31 (nil) (set (reg:SI 0 eax)
(call (mem:QI (symbol_ref:SI ("printf")) [0 S1 A8])
(const_int 16 [0x10]))) -1 (nil)
(expr_list:REG_EH_REGION (const_int 0 [0x0])
(nil))
(nil))
(insn 31 30 38 (nil) (parallel [
(set (reg/f:SI 7 esp)
(plus:SI (reg/f:SI 7 esp)
(const_int 16 [0x10])))
(clobber (reg:CC 17 flags))
]) -1 (nil)
(nil))
(jump_insn 38 31 39 (nil) (set (pc)
(label_ref 45)) -1 (nil)
(nil))
(barrier 39 38 41)
(insn 41 39 42 (nil) (clobber (reg/i:SI 0 eax)) -1 (nil)
(nil))
(insn 42 41 43 (nil) (clobber (reg:SI 58)) -1 (nil)
(nil))
(jump_insn 43 42 44 (nil) (set (pc)
(label_ref 60)) -1 (nil)
(nil))
(barrier 44 43 45)
(code_label 45 44 47 2 ("L1") [0 uses])
(insn 47 45 48 (nil) (clobber (reg/i:SI 0 eax)) -1 (nil)
(nil))
(insn 48 47 49 (nil) (clobber (reg:SI 58)) -1 (nil)
(nil))
(jump_insn 49 48 50 (nil) (set (pc)
(label_ref 60)) -1 (nil)
(nil))
(barrier 50 49 52)
(insn 52 50 53 (nil) (parallel [
(set (reg/f:SI 7 esp)
(plus:SI (reg/f:SI 7 esp)
(const_int -8 [0xfffffff8])))
(clobber (reg:CC 17 flags))
]) -1 (nil)
(nil))
(insn 53 52 54 (nil) (set (mem/f:SI (pre_dec:SI (reg/f:SI 7
esp)) [0 S4 A32])
(mem/f:SI (plus:SI (reg/f:SI 54 virtual-stack-vars)
(const_int -4 [0xfffffffc])) [0 x+0 S4 A32]))
-1 (nil)
(nil))
(insn 54 53 55 (nil) (set (mem/f:SI (pre_dec:SI
(reg/f:SI 7 esp)) [0 S4 A32])
(symbol_ref/f:SI ("*.LC0"))) -1 (nil)
(nil))
(call_insn 55 54 56 (nil) (set (reg:SI 0 eax)
(call (mem:QI (symbol_ref:SI ("printf")) [0 S1 A8])
(const_int 16 [0x10]))) -1 (nil)
(expr_list:REG_EH_REGION (const_int 0 [0x0])
(nil))
(nil))
(insn 56 55 57 (nil) (parallel [
(set (reg/f:SI 7 esp)
(plus:SI (reg/f:SI 7 esp)
(const_int 16 [0x10])))
(clobber (reg:CC 17 flags))
]) -1 (nil)
(nil))
(note 57 56 58 0xf6d75294 NOTE_INSN_BLOCK_END)
(note 58 57 62 NOTE_INSN_FUNCTION_END)
(insn 62 58 63 (nil) (clobber (reg/i:SI 0 eax)) -1 (nil)
(nil))
(insn 63 62 60 (nil) (clobber (reg:SI 58)) -1 (nil)
(nil))
(code_label 60 63 61 1 "" [0 uses])
(insn 61 60 64 (nil) (set (reg/i:SI 0 eax)
(reg:SI 58)) -1 (nil)
(nil))
(insn 64 61 0 (nil) (use (reg/i:SI 0 eax)) -1 (nil)
(nil))
(nil))
(jump_insn 43 42 44 (nil) (set (pc)
(label_ref 60)) -1 (nil)
(nil))
(barrier 44 43 45)
(code_label 45 44 47 2 ("L1") [0 uses])
(insn 47 45 48 (nil) (clobber (reg/i:SI 0 eax)) -1 (nil)
(nil))
(insn 48 47 49 (nil) (clobber (reg:SI 58)) -1 (nil)
(nil))
(jump_insn 49 48 50 (nil) (set (pc)
(label_ref 60)) -1 (nil)
(nil))
(barrier 50 49 52)
(insn 52 50 53 (nil) (parallel [
(set (reg/f:SI 7 esp)
(plus:SI (reg/f:SI 7 esp)
(const_int -8 [0xfffffff8])))
(clobber (reg:CC 17 flags))
]) -1 (nil)
(nil))
(insn 53 52 54 (nil) (set (mem/f:SI (pre_dec:SI (reg/f:SI 7
esp)) [0 S4 A32])
(mem/f:SI (plus:SI (reg/f:SI 54 virtual-stack-vars)
(const_int -4 [0xfffffffc])) [0 x+0 S4 A32]))
-1 (nil)
(nil))
(insn 54 53 55 (nil) (set (mem/f:SI (pre_dec:SI
(reg/f:SI 7 esp)) [0 S4 A32])
(symbol_ref/f:SI ("*.LC0"))) -1 (nil)
(nil))
(call_insn 55 54 56 (nil) (set (reg:SI 0 eax)
(call (mem:QI (symbol_ref:SI ("printf")) [0 S1 A8])
(const_int 16 [0x10]))) -1 (nil)
(expr_list:REG_EH_REGION (const_int 0 [0x0])
(nil))
(nil))
(insn 56 55 57 (nil) (parallel [
(set (reg/f:SI 7 esp)
(plus:SI (reg/f:SI 7 esp)
(const_int 16 [0x10])))
(clobber (reg:CC 17 flags))
]) -1 (nil)
(nil))
(note 57 56 58 0xf6d75294 NOTE_INSN_BLOCK_END)
(note 58 57 62 NOTE_INSN_FUNCTION_END)
(insn 62 58 63 (nil) (clobber (reg/i:SI 0 eax)) -1 (nil)
(nil))
(insn 63 62 60 (nil) (clobber (reg:SI 58)) -1 (nil)
(nil))
(code_label 60 63 61 1 "" [0 uses])
(insn 61 60 64 (nil) (set (reg/i:SI 0 eax)
(reg:SI 58)) -1 (nil)
(nil))
(insn 64 61 0 (nil) (use (reg/i:SI 0 eax)) -1 (nil)
(nil))
|
|
〔リスト3〕アセンブラ・ソース(test230.s)
|
.file "test230.c"
.section .rodata
.LC0:
.string "%d\n"
.text
.globl main
.type main, @function
main:
pushl %ebp
movl %esp, %ebp
subl $8, %esp
andl $-16, %esp
movl $0, %eax
subl %eax, %esp
movl $0, -4(%ebp)
movl $0, -8(%ebp)
leal -4(%ebp), %eax
incl (%eax)
movl -4(%ebp), %eax
xorl $2, %eax
movl %eax, -8(%ebp)
subl $8, %esp
pushl -4(%ebp)
pushl $.LC0
call printf
addl $16, %esp
subl $8, %esp
pushl -8(%ebp)
pushl $.LC0
call printf
addl $16, %esp
.L2:
leave
ret
.size main, .-main
.section .note.GNU-stack,"",@progbits
.ident "GCC: (GNU) 3.3.3 20040412 (Red Hat Linux 3.3.3-7)"
|
|
〔リスト4〕コピー伝播で最適化される
|
main()
{
int a;
int b;
…
…
b = a;
while(…)
{
…
b = a;
}
fopen(…);
…
b = a;
return Foo(b);
}
|
|
〔リスト5〕コピー伝播で最適化されない
|
main()
{
int a;
int b;
…
…
b = a;
return Foo(b);
while(…)
{
…
b = a;
}
fopen(…);
…
b = a;
}
|
|
〔リスト6〕共通部分式除去をする前
|
main()
{
int a;
int b;
int c;
int d;
int e;
…
…
a = b * c; @
d = b; A
e = b * c; B
a = c * d; C
…
}
|
|
〔リスト7〕共通部分式除去をした後
|
main()
{
int a;
int b;
int c;
int d;
int e;
…
…
a = b * c; @
d = b; A
e = a; B
a = a; C
…
}
|
|
〔リスト8〕ループ不変式のループ外追い出し前
|
main()
{
int a;
int b;
…
while(…)
{
a = b;
…
}
…
}
|
|
〔リスト9〕ループ不変式のループ外追い出し後
|
main()
{
int a;
int b;
…
while(…)
{
…
}
a = b;
…
}
|
|
〔リスト10〕元のCソース(test236.c)
|
//中間言語の例
#include <stdio.h>
int main ()
{
int i;
int j;
int k;
i = 1;
j = 1;
k = 0;
i = 2;
i = 3;
i = 4;
while (k < 100)
{
if (j < 20)
{
j = i;
k = k + 1;
}
else
{
j = k;
k = k + 2;
}
}
printf("%d\n",j);
}
|
|
〔リスト11〕最適化なしのアセンブラ・ソース(test236.s)
|
.file "test236.c"
.section .rodata.str1.1,"aMS",@progbits,1
.LC0:
.string "%d\n"
.text
.p2align 2,,3
.globl main
.type main, @function
main:
pushl %ebp
movl %esp, %ebp
subl $8, %esp
andl $-16, %esp
movl $1, %edx
xorl %eax, %eax
.p2align 2,,3
.L7:
cmpl $19, %edx
jg .L5
movl $4, %edx
incl %eax
.L2:
cmpl $99, %eax
jle .L7
subl $8, %esp
pushl %edx
pushl $.LC0
call printf
leave
ret
.p2align 2,,3
.L5:
movl %eax, %edx
leal 2(%eax), %eax
jmp .L2
.size main, .-main
.section .note.GNU-stack,"",@progbits
.ident "GCC: (GNU) 3.3.3 20040412 (Red Hat Linux 3.3.3-7)"
|
|
〔リスト12〕最適化したアセンブラ・ソース(test236a.s)
|
.file "test236.c"
.section .rodata.str1.1,"aMS",@progbits,1
.LC0:
.string "%d\n"
.text
.p2align 2,,3
.globl main
.type main, @function
main:
pushl %ebp
movl %esp, %ebp
pushl %ebx
pushl %eax
andl $-16, %esp
movl $1, %edx
xorl %eax, %eax
.p2align 2,,3
.L7:
cmpl $19, %edx
jg .L5
movl $4, %edx
incl %eax
.L2:
cmpl $99, %eax
jle .L7
subl $8, %esp
pushl %edx
pushl $.LC0
call printf
movl %ebx, %eax
movl -4(%ebp), %ebx
leave
ret
.p2align 2,,3
.L5:
movl %eax, %edx
leal 2(%eax), %eax
jmp .L2
.size main, .-main
.section .note.GNU-stack,"",@progbits
.ident "GCC: (GNU) 3.3.3 20040412 (Red Hat Linux 3.3.3-7)"
|
|
 記事内インデックス 連載インデックスはこちら Interfaceのトップ |
|
|
Copyright 2004 岸 哲夫
Copyright 1997-2004 CQ Publishing Co.,Ltd.
|