前のページ | 次のページ
リスト


〔リスト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)"
前のページ | 次のページ
NEW記事内インデックス    連載インデックスはこちら   Interfaceのトップ
静的単一代入形式による最適化
◆リスト

Copyright 2004 岸 哲夫

Copyright 1997-2004 CQ Publishing Co.,Ltd.