LINUX.ORG.RU

где прочитать про флаги оптимизации gcc?


0

0

Модель процессора такая:

[vilfred@observ vilfred]$ cat /proc/cpuinfo
processor : 0
vendor_id : GenuineIntel
cpu family : 6
model : 11
model name : Intel(R) Celeron(TM) CPU 1300MHz
stepping : 1
cpu MHz : 1302.967
cache size : 256 KB
fdiv_bug : no
hlt_bug : no
f00f_bug : no
coma_bug : no
fpu : yes
fpu_exception : yes
cpuid level : 2
wp : yes
flags : fpu vme de pse tsc msr pae mce cx8 apic sep mtrr pge mca cmov pat pse36 mmx fxsr sse
bogomips : 2601.77

[vilfred@observ vilfred]$

Какие флаги оптимизации GCC давать чтобы прога побыстрее работала или где про это можно прочитать?

thx!!

☆☆

> Какие флаги оптимизации GCC давать чтобы прога побыстрее работала...

Не совсем корректный вопрос. Ответ зависит не только от процессора, но и от проги.

Грубо говоря, разные программы ведут себя различно при одних и тех же оптимизациях.

> ...где про это можно прочитать?

man gcc, однако...

Die-Hard ★★★★★
()
Ответ на: комментарий от Die-Hard

> Не совсем корректный вопрос. Ответ зависит не только от процессора, но и от проги.

делает только элементарные(деление/умножение/вычитание/cложение) арифметические расчеты над массивами массивов.

> man gcc, однако...

заглянул, ух как много читать то надо...

vilfred ☆☆
() автор топика
Ответ на: комментарий от vilfred

>> man gcc, однако...

>заглянул, ух как много читать то надо...

Это в фортунки :)

Novel ★★★★
()
Ответ на: комментарий от vilfred

> заглянул, ух как много читать то надо...

Пи*ц, а ты хочешь посрать и не подуться?

anonymous
()
Ответ на: комментарий от vilfred

vilfred (11.01.2005 3:38:59):

> спасибо за ответы!!!

Ну, ты даешь!

Ты за этот ответ благодаришь:

-march -mcpu -O666

??

Хоть попробуй сначала, как сработает.

ПО существу:

Попробуй -mcpu=pentium3 -O3

и сравни с -mcpu=pentium3 -O2

Если -O2 будет быстрее, то сравни с -mcpu=pentium3 -O2 -funroll-loops

И еще попробуй сравнить с -mcpu=pentium3 -O2 -finline-functions

Попробуй, заодно, -mcpu=pentium4 повставлять вместо -mcpu=pentium3

Die-Hard ★★★★★
()
Ответ на: комментарий от Die-Hard

Да можно сразу ;)

#ARCH     = athlon-mp
#ARCH_EXT = -msse -mmmx -m3dnow -mfpmath=sse,387

ARCH      = pentium4
ARCH_EXT  = -msse2  -msse -mmmx -mfpmath=sse 

ALIGN     = 32
OPTLEVEL  = 3

OPTIMIZE  = -O$(OPTLEVEL) -ffast-math -mcpu=$(ARCH)  -march=$(ARCH) -funroll-loops -fprefetch-loop-arrays -fmove-all-movables -freduce-all-givs\
            -frerun-loop-opt  -frerun-cse-after-loop -fgcse -fschedule-insns2 -fno-strength-reduce -fexpensive-optimizations -fthread-jumps \
            -fcse-follow-jumps -malign-double -falign-loops=$(ALIGN) -falign-jumps=$(ALIGN) -falign-functions=$(ALIGN) -falign-labels=$(ALIGN)\
	    -fcse-skip-blocks  -maccumulate-outgoing-args -fforce-addr -fregmove -fgcse-lm -fgcse-sm $(ARCH_EXT)

------------

а потом info gcc по вышеприведенным ключевым словам ;)

sS ★★★★★
()
Ответ на: комментарий от sS

Еще раз.

Комбинация флагов оптимизации, дающая максимальную скорость выполнения прогораммы, сильно зависит от программы.

Например, -funroll-loops не всегда приведет к ускорению программы.

Единственный способ -- попробовать.

Пробовать надо вокруг между опциями -O2 и -O3, как я писАл примерно. Разгребать все опции оптимизации вручную вряд ли получится, их слишком много.

Die-Hard ★★★★★
()
Ответ на: комментарий от Die-Hard

> Пробовать надо вокруг между опциями -O2 и -O3, как я писАл примерно. Разгребать все опции оптимизации вручную вряд ли получится, их слишком много.

Да имхо и не стоит с этим возиться. Я ради эксперимента как-то добавил -O3 в CFLAGS в /etc/make.conf и пересобрал все порты (FreeBSD), после этого очень много софта отказалось работать, пришлось опять пересобирать с -O2

Novel ★★★★
()
Ответ на: комментарий от Die-Hard

>Ну, ты даешь! Ты за этот ответ благодаришь: -march -mcpu -O666 ??
А что нужно все совсем разжевать ?

cpu
()
Ответ на: комментарий от Novel

Novel (11.01.2005 18:02:32):

> Да имхо и не стоит с этим возиться.

Еще как стОит!

> Я ради эксперимента как-то добавил -O3 в CFLAGS в /etc/make.conf и пересобрал все порты (FreeBSD), ...

А вот этого делать, конечно, не стоило.

Такой пример:

Большой проект, сотни больших файлов. Разумеется, -O3 тормозит немерянно.

Я выделил несколько утилит в отдельный файл и ЭТОТ файл собрал с -O3, а остальное -- с -O2.

Почти в 2 раза быстрее забегало!!

Die-Hard ★★★★★
()
Ответ на: комментарий от Die-Hard

>Большой проект, сотни больших файлов. Разумеется, -O3 тормозит немерянно. Почему тормозит немеренно? Или тормозит компиляция?? При чем здесь количество файлов и скорость работы проги после оптимизации?

ProtecT
()
Ответ на: комментарий от ProtecT

ProtecT (13.01.2005 19:45:05):

> Почему тормозит немеренно?

А я откуда знаю?

-O3 довольно часто тормозит на более-менее сложных программах.

> Или тормозит компиляция??

Нет, именно скорость выполнения получившихся бинарников.

> При чем здесь количество файлов и скорость работы проги после оптимизации?

Ни при чем.

Я хотел только сказать, что иногда бывает полезно компилить НЕКОТОРЫЕ (не все) файлы с -O3

Die-Hard ★★★★★
()
Ответ на: комментарий от Die-Hard

Вобщем, я компилял(с нагугленных) с такими опциями (прога всего одна):

-O9 -g -march=pentium2 -mcpu=pentium2 -pipe -fomit-frame-pointer -mmmx
-msse -mfpmath=sse -fforce-addr -falign-functions=4 -fprefetch-loop-arrays

:)

Сравнивать производительности затрахаешься...

vilfred ☆☆
() автор топика
Ответ на: комментарий от vilfred

vilfred(14.01.2005 0:07:57):

Ну, ты выступил...

> -O9 -g -march=pentium2 -mcpu=pentium2 -pipe -fomit-frame-pointer -mmmx -msse -mfpmath=sse -fforce-addr -falign-functions=4 -fprefetch-loop-arrays

Признайся, это -- стеб?

Die-Hard ★★★★★
()
Ответ на: комментарий от Die-Hard

Вот еще вопрос по теме: зачем автор одной программы (эмулятор спектрума) использует -O20? В мане сказано, что есть -O[0-3] и -Os. 20-то зачем?

gcc -O20 -o glukalka modifed.c Tab.o -I/usr/include/X11 -I/usr/X11/include -L/usr/X11/lib -L/usr/X11/lib -L/usr/X11/lib -lXm -lXt -lXext -lX11 -lXpm -lXxf86vm

K48 ★★★★
()
Ответ на: комментарий от vilfred

я изучал GCC: оптимизацию, какой код выдает и пр. Для этого я написал "программу" на С:

#include <stdlib.h> #include <stdio.h>

int dec(int a); int inc (int a); int inc1 (int a); int inc2 (int a); int inc3 (int a); int dec1 (int a);

int f1(){return 1;}

int f2(int f){return f;}

int f3(int t) { if (t<10)return 0; return 1; }

int f4() { int i; for(i=0;i<5;i++); return i; }

double two(double x){return x*x;}

double cub(double x) { double rez=two(x); return (rez*=x); }

int fac(int n){return (n<2)?1:n*fac(n-1);}

long C(unsigned int m, unsigned int n) { if (m==n) return 1; if (!m) return 1; return C(m,n-1)+C(m-1,n-1); } /******************************************************************************/ int inc(int a) { return dec(a+1); }

int dec(int a) { return (a>1) ? inc(a-2) : a; } /******************************************************************************/

int inc1 (int a) { return inc2(a+1); }

int inc2 (int a) { return inc3(a+2); }

int inc3 (int a) { return dec1(a+3); }

int dec1 (int a) { return (a < 8) ? a : inc1(a-7); } /*****************************************************************************/ int main() { int d=f1(); d=f2(9*7+d); d=f3(17); d=f4(); d=fac(f1()+f3(11)+f3(15+f3(14+f3(f2(13))))); long g=C(1,2); double f=cub(two(2.0)); int k=inc(1); int l=dec1(8); printf("%d %f %lld %d %d",d,f,g,k,l); }

ruslan_pisarev_
()
Ответ на: комментарий от vilfred

Когда откомпилил командой gcc -S <имя.c> -o <имя.S>, я получил следующий код:

.file "test1.c" .text .globl f1 .type f1, @function f1: pushl %ebp movl %esp, %ebp movl $1, %eax popl %ebp ret .size f1, .-f1 .globl f2 .type f2, @function f2: pushl %ebp movl %esp, %ebp movl 8(%ebp), %eax popl %ebp ret .size f2, .-f2 .globl f3 .type f3, @function f3: pushl %ebp movl %esp, %ebp subl $4, %esp cmpl $9, 8(%ebp) jg .L4 movl $0, -4(%ebp) jmp .L3 .L4: movl $1, -4(%ebp) .L3: movl -4(%ebp), %eax leave ret .size f3, .-f3 .globl f4 .type f4, @function f4: pushl %ebp movl %esp, %ebp subl $4, %esp movl $0, -4(%ebp) .L6: cmpl $4, -4(%ebp) jg .L7 leal -4(%ebp), %eax incl (%eax) jmp .L6 .L7: movl -4(%ebp), %eax leave ret .size f4, .-f4 .globl two .type two, @function two: pushl %ebp movl %esp, %ebp subl $8, %esp fldl 8(%ebp) fstpl -8(%ebp) fldl -8(%ebp) fmull -8(%ebp) leave ret .size two, .-two .globl cub .type cub, @function cub: pushl %ebp movl %esp, %ebp subl $24, %esp fldl 8(%ebp) fstpl -8(%ebp) fldl -8(%ebp) fstpl (%esp) call two fstpl -16(%ebp) fldl -16(%ebp) fmull -8(%ebp) fstl -16(%ebp) leave ret .size cub, .-cub .globl fac .type fac, @function fac: pushl %ebp movl %esp, %ebp subl $8, %esp cmpl $1, 8(%ebp) jle .L12 movl 8(%ebp), %eax decl %eax movl %eax, (%esp) call fac movl %eax, -4(%ebp) movl -4(%ebp), %eax imull 8(%ebp), %eax movl %eax, -4(%ebp) jmp .L13 .L12: movl $1, -4(%ebp) .L13: movl -4(%ebp), %eax leave ret .size fac, .-fac .globl C .type C, @function C: pushl %ebp movl %esp, %ebp pushl %ebx subl $12, %esp movl 8(%ebp), %eax cmpl 12(%ebp), %eax jne .L15 movl $1, -8(%ebp) jmp .L14 .L15: cmpl $0, 8(%ebp) jne .L16 movl $1, -8(%ebp) jmp .L14 .L16: movl 12(%ebp), %eax decl %eax movl %eax, 4(%esp) movl 8(%ebp), %eax movl %eax, (%esp) call C movl %eax, %ebx movl 12(%ebp), %eax decl %eax movl %eax, 4(%esp) movl 8(%ebp), %eax decl %eax movl %eax, (%esp) call C addl %eax, %ebx movl %ebx, -8(%ebp) .L14: movl -8(%ebp), %eax addl $12, %esp popl %ebx popl %ebp ret .size C, .-C .globl inc .type inc, @function inc: pushl %ebp movl %esp, %ebp subl $8, %esp movl 8(%ebp), %eax incl %eax movl %eax, (%esp) call dec leave ret .size inc, .-inc .globl dec .type dec, @function dec: pushl %ebp movl %esp, %ebp subl $8, %esp cmpl $1, 8(%ebp) jle .L19 movl 8(%ebp), %eax subl $2, %eax movl %eax, (%esp) call inc movl %eax, -4(%ebp) jmp .L20 .L19: movl 8(%ebp), %eax movl %eax, -4(%ebp) .L20: movl -4(%ebp), %eax leave ret .size dec, .-dec .globl inc1 .type inc1, @function inc1: pushl %ebp movl %esp, %ebp subl $8, %esp movl 8(%ebp), %eax incl %eax movl %eax, (%esp) call inc2 leave ret .size inc1, .-inc1 .globl inc2 .type inc2, @function inc2: pushl %ebp movl %esp, %ebp subl $8, %esp movl 8(%ebp), %eax addl $2, %eax movl %eax, (%esp) call inc3 leave ret .size inc2, .-inc2 .globl int3 .type int3, @function int3: pushl %ebp movl %esp, %ebp subl $8, %esp movl 8(%ebp), %eax addl $3, %eax movl %eax, (%esp) call dec1 leave ret .size int3, .-int3 .globl dec1 .type dec1, @function dec1: pushl %ebp movl %esp, %ebp subl $8, %esp cmpl $7, 8(%ebp) jle .L25 movl 8(%ebp), %eax subl $7, %eax movl %eax, (%esp) call inc1 movl %eax, -4(%ebp) jmp .L26 .L25: movl 8(%ebp), %eax movl %eax, -4(%ebp) .L26: movl -4(%ebp), %eax leave ret .size dec1, .-dec1 .section .rodata .LC3: .string "%d %f %lld %d %d" .align 8 .LC2: .long 0 .long 1073741824 .text .globl main .type main, @function main: pushl %ebp movl %esp, %ebp pushl %ebx subl $68, %esp andl $-16, %esp movl $0, %eax addl $15, %eax addl $15, %eax shrl $4, %eax sall $4, %eax subl %eax, %esp call f1 movl %eax, -12(%ebp) movl -12(%ebp), %eax addl $63, %eax movl %eax, (%esp) call f2 movl %eax, -12(%ebp) movl $17, (%esp) call f3 movl %eax, -12(%ebp) call f4 movl %eax, -12(%ebp) call f1 movl %eax, %ebx movl $11, (%esp) call f3 addl %eax, %ebx movl $13, (%esp) call f2 movl %eax, (%esp) call f3 addl $14, %eax movl %eax, (%esp) call f3 addl $15, %eax movl %eax, (%esp) call f3 leal (%ebx,%eax), %eax movl %eax, (%esp) call fac movl %eax, -12(%ebp) movl $2, 4(%esp) movl $1, (%esp) call C movl %eax, -16(%ebp) fldl .LC2 fstpl (%esp) call two fstpl (%esp) call cub fstpl -24(%ebp) movl $1, (%esp) call inc movl %eax, -28(%ebp) movl $8, (%esp) call dec1 movl %eax, -32(%ebp) movl -32(%ebp), %eax movl %eax, 24(%esp) movl -28(%ebp), %eax movl %eax, 20(%esp) movl -16(%ebp), %eax movl %eax, 16(%esp) fldl -24(%ebp) fstpl 8(%esp) movl -12(%ebp), %eax movl %eax, 4(%esp) movl $.LC3, (%esp) call printf movl -4(%ebp), %ebx leave ret .size main, .-main .section .note.GNU-stack,"",@progbits .ident "GCC: (GNU) 3.4.0"

Поэтому я сделал вывод, что без оптимизации компилятор выдает дословный перевод: сказано сохранить в переменной -- сохраняет, сказано вызвать функцию, пусть даже простейшую, -- вызывает. В общем при такой компиляции код, мягко говоря, генериться не очень эффективный, хотя простые выражения он вычисляет.

ruslan_pisarev_
()
Ответ на: комментарий от vilfred

Идем дальше... gcc -S -O2 <имя.c> -o <имя.S>:

	.file	"test1.c"
	.text
	.p2align 4,,15
.globl f1
	.type	f1, @function
f1:
	pushl	%ebp
	movl	$1, %eax
	movl	%esp, %ebp
	popl	%ebp
	ret
	.size	f1, .-f1
	.p2align 4,,15
.globl f2
	.type	f2, @function
f2:
	pushl	%ebp
	movl	%esp, %ebp
	movl	8(%ebp), %eax
	popl	%ebp
	ret
	.size	f2, .-f2
	.p2align 4,,15
.globl f3
	.type	f3, @function
f3:
	pushl	%ebp
	xorl	%eax, %eax
	movl	%esp, %ebp
	cmpl	$9, 8(%ebp)
	popl	%ebp
	setg	%al
	ret
	.size	f3, .-f3
	.p2align 4,,15
.globl f4
	.type	f4, @function
f4:
	pushl	%ebp
	movl	$4, %eax
	movl	%esp, %ebp
	.p2align 4,,15
.L9:
	decl	%eax
	jns	.L9
	popl	%ebp
	movl	$5, %eax
	ret
	.size	f4, .-f4
	.p2align 4,,15
.globl two
	.type	two, @function
two:
	pushl	%ebp
	movl	%esp, %ebp
	fldl	8(%ebp)
	popl	%ebp
	fmul	%st(0), %st
	ret
	.size	two, .-two
	.p2align 4,,15
.globl cub
	.type	cub, @function
cub:
	pushl	%ebp
	movl	%esp, %ebp
	subl	$32, %esp
	fldl	8(%ebp)
	fstl	(%esp)
	fstpl	-24(%ebp)
	call	two
	fldl	-24(%ebp)
	leave
	fmulp	%st, %st(1)
	ret
	.size	cub, .-cub
	.p2align 4,,15
.globl fac
	.type	fac, @function
fac:
	pushl	%ebp
	movl	$1, %eax
	movl	%esp, %ebp
	pushl	%ebx
	subl	$4, %esp
	movl	8(%ebp), %ebx
	cmpl	$1, %ebx
	jg	.L19
	popl	%edx
	popl	%ebx
	popl	%ebp
	ret
	.p2align 4,,7
.L19:
	leal	-1(%ebx), %eax
	movl	%eax, (%esp)
	call	fac
	popl	%edx
	imull	%ebx, %eax
	popl	%ebx
	popl	%ebp
	ret
	.size	fac, .-fac
	.p2align 4,,15
.globl C
	.type	C, @function
C:
	pushl	%ebp
	movl	$1, %eax
	movl	%esp, %ebp
	subl	$20, %esp
	movl	12(%ebp), %edx
	movl	%edi, -4(%ebp)
	movl	8(%ebp), %edi
	movl	%ebx, -12(%ebp)
	movl	%esi, -8(%ebp)
	cmpl	%edx, %edi
	je	.L20
	testl	%edi, %edi
	jne	.L24
.L20:
	movl	-12(%ebp), %ebx
	movl	-8(%ebp), %esi
	movl	-4(%ebp), %edi
	movl	%ebp, %esp
	popl	%ebp
	ret
	.p2align 4,,7
.L24:
	movl	%edi, (%esp)
	leal	-1(%edx), %ebx
	movl	%ebx, 4(%esp)
	call	C
	movl	%ebx, 4(%esp)
	movl	%eax, %esi
	leal	-1(%edi), %eax
	movl	%eax, (%esp)
	call	C
	leal	(%esi,%eax), %eax
	movl	-12(%ebp), %ebx
	movl	-8(%ebp), %esi
	movl	-4(%ebp), %edi
	movl	%ebp, %esp
	popl	%ebp
	ret
	.size	C, .-C
	.p2align 4,,15
.globl inc
	.type	inc, @function
inc:
	pushl	%ebp
	movl	%esp, %ebp
	incl	8(%ebp)
	popl	%ebp
	jmp	dec
	.size	inc, .-inc
	.p2align 4,,15
.globl dec
	.type	dec, @function
dec:
	pushl	%ebp
	movl	%esp, %ebp
	movl	8(%ebp), %eax
	cmpl	$1, %eax
	jg	.L28
	popl	%ebp
	ret
	.p2align 4,,7
.L28:
	subl	$2, %eax
	movl	%eax, 8(%ebp)
	popl	%ebp
	jmp	inc
	.size	dec, .-dec
	.p2align 4,,15
.globl inc2
	.type	inc2, @function
inc2:
	pushl	%ebp
	movl	%esp, %ebp
	addl	$2, 8(%ebp)
	popl	%ebp
	jmp	inc3
	.size	inc2, .-inc2
	.p2align 4,,15
.globl inc1
	.type	inc1, @function
inc1:
	pushl	%ebp
	movl	%esp, %ebp
	incl	8(%ebp)
	popl	%ebp
	jmp	inc2
	.size	inc1, .-inc1
	.p2align 4,,15
.globl dec1
	.type	dec1, @function
dec1:
	pushl	%ebp
	movl	%esp, %ebp
	movl	8(%ebp), %eax
	cmpl	$7, %eax
	jg	.L33
	popl	%ebp
	ret
	.p2align 4,,7
.L33:
	subl	$7, %eax
	movl	%eax, 8(%ebp)
	popl	%ebp
	jmp	inc1
	.size	dec1, .-dec1
	.p2align 4,,15
.globl int3
	.type	int3, @function
int3:
	pushl	%ebp
	movl	%esp, %ebp
	addl	$3, 8(%ebp)
	popl	%ebp
	jmp	dec1
	.size	int3, .-int3
	.section	.rodata
.LC3:
	.string	"%d %f %lld %d %d"
	.text
	.p2align 4,,15
.globl main
	.type	main, @function
main:
	pushl	%ebp
	movl	%esp, %ebp
	pushl	%edi
	pushl	%esi
	pushl	%ebx
	subl	$44, %esp
	andl	$-16, %esp
	subl	$16, %esp
	call	f1
	movl	%eax, %ebx
	call	f4
	movl	$11, (%esp)
	call	f3
	movl	$13, (%esp)
	addl	%eax, %ebx
	call	f2
	movl	%eax, (%esp)
	call	f3
	addl	$14, %eax
	movl	%eax, (%esp)
	call	f3
	addl	$15, %eax
	movl	%eax, (%esp)
	call	f3
	leal	(%ebx,%eax), %eax
	movl	$2, %ebx
	movl	%eax, (%esp)
	call	fac
	movl	%ebx, 4(%esp)
	movl	%eax, %edi
	movl	$1, (%esp)
	call	C
	movl	$0, (%esp)
	movl	$1073741824, %ecx
	movl	%eax, %esi
	movl	%ecx, 4(%esp)
	call	two
	fstpl	(%esp)
	call	cub
	movl	$1, (%esp)
	fstpl	-24(%ebp)
	call	inc
	movl	$8, (%esp)
	movl	%eax, %ebx
	call	dec1
	fldl	-24(%ebp)
	movl	%ebx, 20(%esp)
	movl	%esi, 16(%esp)
	movl	%edi, 4(%esp)
	movl	%eax, 24(%esp)
	fstpl	8(%esp)
	movl	$.LC3, (%esp)
	call	printf
	leal	-12(%ebp), %esp
	popl	%ebx
	popl	%esi
	popl	%edi
	popl	%ebp
	ret
	.size	main, .-main
	.section	.note.GNU-stack,"",@progbits
	.ident	"GCC: (GNU) 3.4.0"

ruslan_pisarev_
()
Ответ на: комментарий от vilfred

Прошу модератора удалить предыдущие сообщения -- неудачно размещенны

ruslan_pisarev_
()
Ответ на: комментарий от vilfred

я изучал GCC: оптимизацию, какой код выдает и пр.
Для этого я написал "программу" на С:

#include <stdlib.h>
#include <stdio.h>

int dec(int a);
int inc (int a);
int inc1 (int a);
int inc2 (int a);
int inc3 (int a);
int dec1 (int a);

int f1(){return 1;}

int f2(int f){return f;}

int f3(int t)
{
    if (t<10)return 0;
    return 1;
}

int f4()
{
    int i;
    for(i=0;i<5;i++);
    return i;
}


double two(double x){return x*x;}

double cub(double x)
{
    double rez=two(x);
    return (rez*=x);
}

int fac(int n){return (n<2)?1:n*fac(n-1);}

long C(unsigned int m, unsigned int n)
{
    if (m==n) return 1;
    if (!m) return 1;
    return C(m,n-1)+C(m-1,n-1);
}
/******************************************************************************/

int inc(int a)
{
    return dec(a+1);
}

int dec(int a)
{
    return (a>1) ? inc(a-2) : a;
}
/******************************************************************************/


int inc1 (int a)
{
    return inc2(a+1);
}

int inc2 (int a)
{
    return inc3(a+2);
}

int inc3 (int a)
{
    return dec1(a+3);
}

int dec1 (int a)
{
    return (a < 8) ? a : inc1(a-7);
}
/*****************************************************************************/

int main()
{
    int d=f1();
    d=f2(9*7+d);
    d=f3(17);
    d=f4();
    d=fac(f1()+f3(11)+f3(15+f3(14+f3(f2(13)))));
    long g=C(1,2);
    double f=cub(two(2.0));
    int k=inc(1);
    int l=dec1(8);
    printf("%d %f %lld %d %d",d,f,g,k,l);
}

ruslan_pisarev_
()
Ответ на: комментарий от vilfred

Когда откомпилил командой gcc -S <имя.c> -o <имя.S>, я получил следующий код:

	.file	"test1.c"
	.text
.globl f1
	.type	f1, @function
f1:
	pushl	%ebp
	movl	%esp, %ebp
	movl	$1, %eax
	popl	%ebp
	ret
	.size	f1, .-f1
.globl f2
	.type	f2, @function
f2:
	pushl	%ebp
	movl	%esp, %ebp
	movl	8(%ebp), %eax
	popl	%ebp
	ret
	.size	f2, .-f2
.globl f3
	.type	f3, @function
f3:
	pushl	%ebp
	movl	%esp, %ebp
	subl	$4, %esp
	cmpl	$9, 8(%ebp)
	jg	.L4
	movl	$0, -4(%ebp)
	jmp	.L3
.L4:
	movl	$1, -4(%ebp)
.L3:
	movl	-4(%ebp), %eax
	leave
	ret
	.size	f3, .-f3
.globl f4
	.type	f4, @function
f4:
	pushl	%ebp
	movl	%esp, %ebp
	subl	$4, %esp
	movl	$0, -4(%ebp)
.L6:
	cmpl	$4, -4(%ebp)
	jg	.L7
	leal	-4(%ebp), %eax
	incl	(%eax)
	jmp	.L6
.L7:
	movl	-4(%ebp), %eax
	leave
	ret
	.size	f4, .-f4
.globl two
	.type	two, @function
two:
	pushl	%ebp
	movl	%esp, %ebp
	subl	$8, %esp
	fldl	8(%ebp)
	fstpl	-8(%ebp)
	fldl	-8(%ebp)
	fmull	-8(%ebp)
	leave
	ret
	.size	two, .-two
.globl cub
	.type	cub, @function
cub:
	pushl	%ebp
	movl	%esp, %ebp
	subl	$24, %esp
	fldl	8(%ebp)
	fstpl	-8(%ebp)
	fldl	-8(%ebp)
	fstpl	(%esp)
	call	two
	fstpl	-16(%ebp)
	fldl	-16(%ebp)
	fmull	-8(%ebp)
	fstl	-16(%ebp)
	leave
	ret
	.size	cub, .-cub
.globl fac
	.type	fac, @function
fac:
	pushl	%ebp
	movl	%esp, %ebp
	subl	$8, %esp
	cmpl	$1, 8(%ebp)
	jle	.L12
	movl	8(%ebp), %eax
	decl	%eax
	movl	%eax, (%esp)
	call	fac
	movl	%eax, -4(%ebp)
	movl	-4(%ebp), %eax
	imull	8(%ebp), %eax
	movl	%eax, -4(%ebp)
	jmp	.L13
.L12:
	movl	$1, -4(%ebp)
.L13:
	movl	-4(%ebp), %eax
	leave
	ret
	.size	fac, .-fac
.globl C
	.type	C, @function
C:
	pushl	%ebp
	movl	%esp, %ebp
	pushl	%ebx
	subl	$12, %esp
	movl	8(%ebp), %eax
	cmpl	12(%ebp), %eax
	jne	.L15
	movl	$1, -8(%ebp)
	jmp	.L14
.L15:
	cmpl	$0, 8(%ebp)
	jne	.L16
	movl	$1, -8(%ebp)
	jmp	.L14
.L16:
	movl	12(%ebp), %eax
	decl	%eax
	movl	%eax, 4(%esp)
	movl	8(%ebp), %eax
	movl	%eax, (%esp)
	call	C
	movl	%eax, %ebx
	movl	12(%ebp), %eax
	decl	%eax
	movl	%eax, 4(%esp)
	movl	8(%ebp), %eax
	decl	%eax
	movl	%eax, (%esp)
	call	C
	addl	%eax, %ebx
	movl	%ebx, -8(%ebp)
.L14:
	movl	-8(%ebp), %eax
	addl	$12, %esp
	popl	%ebx
	popl	%ebp
	ret
	.size	C, .-C
.globl inc
	.type	inc, @function
inc:
	pushl	%ebp
	movl	%esp, %ebp
	subl	$8, %esp
	movl	8(%ebp), %eax
	incl	%eax
	movl	%eax, (%esp)
	call	dec
	leave
	ret
	.size	inc, .-inc
.globl dec
	.type	dec, @function
dec:
	pushl	%ebp
	movl	%esp, %ebp
	subl	$8, %esp
	cmpl	$1, 8(%ebp)
	jle	.L19
	movl	8(%ebp), %eax
	subl	$2, %eax
	movl	%eax, (%esp)
	call	inc
	movl	%eax, -4(%ebp)
	jmp	.L20
.L19:
	movl	8(%ebp), %eax
	movl	%eax, -4(%ebp)
.L20:
	movl	-4(%ebp), %eax
	leave
	ret
	.size	dec, .-dec
.globl inc1
	.type	inc1, @function
inc1:
	pushl	%ebp
	movl	%esp, %ebp
	subl	$8, %esp
	movl	8(%ebp), %eax
	incl	%eax
	movl	%eax, (%esp)
	call	inc2
	leave
	ret
	.size	inc1, .-inc1
.globl inc2
	.type	inc2, @function
inc2:
	pushl	%ebp
	movl	%esp, %ebp
	subl	$8, %esp
	movl	8(%ebp), %eax
	addl	$2, %eax
	movl	%eax, (%esp)
	call	inc3
	leave
	ret
	.size	inc2, .-inc2
.globl int3
	.type	int3, @function
int3:
	pushl	%ebp
	movl	%esp, %ebp
	subl	$8, %esp
	movl	8(%ebp), %eax
	addl	$3, %eax
	movl	%eax, (%esp)
	call	dec1
	leave
	ret
	.size	int3, .-int3
.globl dec1
	.type	dec1, @function
dec1:
	pushl	%ebp
	movl	%esp, %ebp
	subl	$8, %esp
	cmpl	$7, 8(%ebp)
	jle	.L25
	movl	8(%ebp), %eax
	subl	$7, %eax
	movl	%eax, (%esp)
	call	inc1
	movl	%eax, -4(%ebp)
	jmp	.L26
.L25:
	movl	8(%ebp), %eax
	movl	%eax, -4(%ebp)
.L26:
	movl	-4(%ebp), %eax
	leave
	ret
	.size	dec1, .-dec1
	.section	.rodata
.LC3:
	.string	"%d %f %lld %d %d"
	.align 8
.LC2:
	.long	0
	.long	1073741824
	.text
.globl main
	.type	main, @function
main:
	pushl	%ebp
	movl	%esp, %ebp
	pushl	%ebx
	subl	$68, %esp
	andl	$-16, %esp
	movl	$0, %eax
	addl	$15, %eax
	addl	$15, %eax
	shrl	$4, %eax
	sall	$4, %eax
	subl	%eax, %esp
	call	f1
	movl	%eax, -12(%ebp)
	movl	-12(%ebp), %eax
	addl	$63, %eax
	movl	%eax, (%esp)
	call	f2
	movl	%eax, -12(%ebp)
	movl	$17, (%esp)
	call	f3
	movl	%eax, -12(%ebp)
	call	f4
	movl	%eax, -12(%ebp)
	call	f1
	movl	%eax, %ebx
	movl	$11, (%esp)
	call	f3
	addl	%eax, %ebx
	movl	$13, (%esp)
	call	f2
	movl	%eax, (%esp)
	call	f3
	addl	$14, %eax
	movl	%eax, (%esp)
	call	f3
	addl	$15, %eax
	movl	%eax, (%esp)
	call	f3
	leal	(%ebx,%eax), %eax
	movl	%eax, (%esp)
	call	fac
	movl	%eax, -12(%ebp)
	movl	$2, 4(%esp)
	movl	$1, (%esp)
	call	C
	movl	%eax, -16(%ebp)
	fldl	.LC2
	fstpl	(%esp)
	call	two
	fstpl	(%esp)
	call	cub
	fstpl	-24(%ebp)
	movl	$1, (%esp)
	call	inc
	movl	%eax, -28(%ebp)
	movl	$8, (%esp)
	call	dec1
	movl	%eax, -32(%ebp)
	movl	-32(%ebp), %eax
	movl	%eax, 24(%esp)
	movl	-28(%ebp), %eax
	movl	%eax, 20(%esp)
	movl	-16(%ebp), %eax
	movl	%eax, 16(%esp)
	fldl	-24(%ebp)
	fstpl	8(%esp)
	movl	-12(%ebp), %eax
	movl	%eax, 4(%esp)
	movl	$.LC3, (%esp)
	call	printf
	movl	-4(%ebp), %ebx
	leave
	ret
	.size	main, .-main
	.section	.note.GNU-stack,"",@progbits
	.ident	"GCC: (GNU) 3.4.0"

Поэтому я сделал вывод, что без оптимизации компилятор выдает дословный перевод:
сказано сохранить в переменной -- сохраняет, сказано вызвать функцию,
пусть даже простейшую, -- вызывает. В общем при такой компиляции код, мягко
говоря, генериться не очень эффективный, хотя простые выражения он вычисляет.

ruslan_pisarev_
()
Ответ на: комментарий от vilfred

Далее, я решил посмотреть оптимизацию: gcc -S -O1 <имя.c> -o <имя.S>:

	.file	"test1.c"
	.text
.globl f1
	.type	f1, @function
f1:
	pushl	%ebp
	movl	%esp, %ebp
	movl	$1, %eax
	popl	%ebp
	ret
	.size	f1, .-f1
.globl f2
	.type	f2, @function
f2:
	pushl	%ebp
	movl	%esp, %ebp
	movl	8(%ebp), %eax
	popl	%ebp
	ret
	.size	f2, .-f2
.globl f3
	.type	f3, @function
f3:
	pushl	%ebp
	movl	%esp, %ebp
	cmpl	$9, 8(%ebp)
	setg	%al
	movzbl	%al, %eax
	popl	%ebp
	ret
	.size	f3, .-f3
.globl f4
	.type	f4, @function
f4:
	pushl	%ebp
	movl	%esp, %ebp
	movl	$0, %eax
.L9:
	incl	%eax
	cmpl	$4, %eax
	jle	.L9
	popl	%ebp
	ret
	.size	f4, .-f4
.globl two
	.type	two, @function
two:
	pushl	%ebp
	movl	%esp, %ebp
	fldl	8(%ebp)
	fmul	%st(0), %st
	popl	%ebp
	ret
	.size	two, .-two
.globl cub
	.type	cub, @function
cub:
	pushl	%ebp
	movl	%esp, %ebp
	subl	$8, %esp
	fldl	8(%ebp)
	fstpl	(%esp)
	call	two
	fmull	8(%ebp)
	leave
	ret
	.size	cub, .-cub
.globl fac
	.type	fac, @function
fac:
	pushl	%ebp
	movl	%esp, %ebp
	pushl	%ebx
	subl	$4, %esp
	movl	8(%ebp), %ebx
	movl	$1, %eax
	cmpl	$1, %ebx
	jle	.L16
	leal	-1(%ebx), %eax
	movl	%eax, (%esp)
	call	fac
	imull	%ebx, %eax
.L16:
	addl	$4, %esp
	popl	%ebx
	popl	%ebp
	ret
	.size	fac, .-fac
.globl C
	.type	C, @function
C:
	pushl	%ebp
	movl	%esp, %ebp
	subl	$20, %esp
	movl	%ebx, -12(%ebp)
	movl	%esi, -8(%ebp)
	movl	%edi, -4(%ebp)
	movl	8(%ebp), %edi
	movl	12(%ebp), %edx
	movl	$1, %eax
	cmpl	%edx, %edi
	je	.L17
	movl	$1, %eax
	testl	%edi, %edi
	je	.L17
	leal	-1(%edx), %ebx
	movl	%ebx, 4(%esp)
	movl	%edi, (%esp)
	call	C
	movl	%eax, %esi
	movl	%ebx, 4(%esp)
	leal	-1(%edi), %eax
	movl	%eax, (%esp)
	call	C
	leal	(%esi,%eax), %eax
.L17:
	movl	-12(%ebp), %ebx
	movl	-8(%ebp), %esi
	movl	-4(%ebp), %edi
	movl	%ebp, %esp
	popl	%ebp
	ret
	.size	C, .-C
.globl inc
	.type	inc, @function
inc:
	pushl	%ebp
	movl	%esp, %ebp
	subl	$8, %esp
	movl	8(%ebp), %eax
	incl	%eax
	movl	%eax, (%esp)
	call	dec
	leave
	ret
	.size	inc, .-inc
.globl dec
	.type	dec, @function
dec:
	pushl	%ebp
	movl	%esp, %ebp
	subl	$8, %esp
	movl	8(%ebp), %eax
	movl	%eax, %edx
	cmpl	$1, %eax
	jle	.L21
	subl	$2, %eax
	movl	%eax, (%esp)
	call	inc
	movl	%eax, %edx
.L21:
	movl	%edx, %eax
	leave
	ret
	.size	dec, .-dec
.globl inc1
	.type	inc1, @function
inc1:
	pushl	%ebp
	movl	%esp, %ebp
	subl	$8, %esp
	movl	8(%ebp), %eax
	incl	%eax
	movl	%eax, (%esp)
	call	inc2
	leave
	ret
	.size	inc1, .-inc1
.globl inc2
	.type	inc2, @function
inc2:
	pushl	%ebp
	movl	%esp, %ebp
	subl	$8, %esp
	movl	8(%ebp), %eax
	addl	$2, %eax
	movl	%eax, (%esp)
	call	inc3
	leave
	ret
	.size	inc2, .-inc2
.globl int3
	.type	int3, @function
int3:
	pushl	%ebp
	movl	%esp, %ebp
	subl	$8, %esp
	movl	8(%ebp), %eax
	addl	$3, %eax
	movl	%eax, (%esp)
	call	dec1
	leave
	ret
	.size	int3, .-int3
.globl dec1
	.type	dec1, @function
dec1:
	pushl	%ebp
	movl	%esp, %ebp
	subl	$8, %esp
	movl	8(%ebp), %eax
	movl	%eax, %edx
	cmpl	$7, %eax
	jle	.L26
	subl	$7, %eax
	movl	%eax, (%esp)
	call	inc1
	movl	%eax, %edx
.L26:
	movl	%edx, %eax
	leave
	ret
	.size	dec1, .-dec1
	.section	.rodata
.LC3:
	.string	"%d %f %lld %d %d"
	.text
.globl main
	.type	main, @function
main:
	pushl	%ebp
	movl	%esp, %ebp
	pushl	%edi
	pushl	%esi
	pushl	%ebx
	subl	$44, %esp
	andl	$-16, %esp
	subl	$16, %esp
	call	f1
	movl	%eax, %ebx
	call	f4
	movl	$11, (%esp)
	call	f3
	addl	%eax, %ebx
	movl	$13, (%esp)
	call	f2
	movl	%eax, (%esp)
	call	f3
	addl	$14, %eax
	movl	%eax, (%esp)
	call	f3
	addl	$15, %eax
	movl	%eax, (%esp)
	call	f3
	leal	(%ebx,%eax), %eax
	movl	%eax, (%esp)
	call	fac
	movl	%eax, %edi
	movl	$2, 4(%esp)
	movl	$1, (%esp)
	call	C
	movl	%eax, %esi
	movl	$0, (%esp)
	movl	$1073741824, 4(%esp)
	call	two
	fstpl	(%esp)
	call	cub
	fstpl	-24(%ebp)
	movl	$1, (%esp)
	call	inc
	movl	%eax, %ebx
	movl	$8, (%esp)
	call	dec1
	movl	%eax, 24(%esp)
	movl	%ebx, 20(%esp)
	movl	%esi, 16(%esp)
	fldl	-24(%ebp)
	fstpl	8(%esp)
	movl	%edi, 4(%esp)
	movl	$.LC3, (%esp)
	call	printf
	leal	-12(%ebp), %esp
	popl	%ebx
	popl	%esi
	popl	%edi
	popl	%ebp
	ret
	.size	main, .-main
	.section	.note.GNU-stack,"",@progbits
	.ident	"GCC: (GNU) 3.4.0"

Он по-прежнему работает с памятью, но теперь он поумнел -- он удаляет(по крайней
мере частично) фрагменты избыточного кода: функции f2 и f3 не вызываются, т.е.
теперь видны следы оптимизации и компилятор может создать более быструю програм-
му. Но и сейчас GCC не смог упростить выражения с большим числом функций, нет
даже попыток "вычислить" результат выражений с рекурсивными функциями.

ruslan_pisarev_
()
Ответ на: комментарий от vilfred

Далее, я решил посмотреть оптимизацию: gcc -S -O1 <имя.c> -o <имя.S>:

	.file	"test1.c"
	.text
.globl f1
	.type	f1, @function
f1:
	pushl	%ebp
	movl	%esp, %ebp
	movl	$1, %eax
	popl	%ebp
	ret
	.size	f1, .-f1
.globl f2
	.type	f2, @function
f2:
	pushl	%ebp
	movl	%esp, %ebp
	movl	8(%ebp), %eax
	popl	%ebp
	ret
	.size	f2, .-f2
.globl f3
	.type	f3, @function
f3:
	pushl	%ebp
	movl	%esp, %ebp
	cmpl	$9, 8(%ebp)
	setg	%al
	movzbl	%al, %eax
	popl	%ebp
	ret
	.size	f3, .-f3
.globl f4
	.type	f4, @function
f4:
	pushl	%ebp
	movl	%esp, %ebp
	movl	$0, %eax
.L9:
	incl	%eax
	cmpl	$4, %eax
	jle	.L9
	popl	%ebp
	ret
	.size	f4, .-f4
.globl two
	.type	two, @function
two:
	pushl	%ebp
	movl	%esp, %ebp
	fldl	8(%ebp)
	fmul	%st(0), %st
	popl	%ebp
	ret
	.size	two, .-two
.globl cub
	.type	cub, @function
cub:
	pushl	%ebp
	movl	%esp, %ebp
	subl	$8, %esp
	fldl	8(%ebp)
	fstpl	(%esp)
	call	two
	fmull	8(%ebp)
	leave
	ret
	.size	cub, .-cub
.globl fac
	.type	fac, @function
fac:
	pushl	%ebp
	movl	%esp, %ebp
	pushl	%ebx
	subl	$4, %esp
	movl	8(%ebp), %ebx
	movl	$1, %eax
	cmpl	$1, %ebx
	jle	.L16
	leal	-1(%ebx), %eax
	movl	%eax, (%esp)
	call	fac
	imull	%ebx, %eax
.L16:
	addl	$4, %esp
	popl	%ebx
	popl	%ebp
	ret
	.size	fac, .-fac
.globl C
	.type	C, @function
C:
	pushl	%ebp
	movl	%esp, %ebp
	subl	$20, %esp
	movl	%ebx, -12(%ebp)
	movl	%esi, -8(%ebp)
	movl	%edi, -4(%ebp)
	movl	8(%ebp), %edi
	movl	12(%ebp), %edx
	movl	$1, %eax
	cmpl	%edx, %edi
	je	.L17
	movl	$1, %eax
	testl	%edi, %edi
	je	.L17
	leal	-1(%edx), %ebx
	movl	%ebx, 4(%esp)
	movl	%edi, (%esp)
	call	C
	movl	%eax, %esi
	movl	%ebx, 4(%esp)
	leal	-1(%edi), %eax
	movl	%eax, (%esp)
	call	C
	leal	(%esi,%eax), %eax
.L17:
	movl	-12(%ebp), %ebx
	movl	-8(%ebp), %esi
	movl	-4(%ebp), %edi
	movl	%ebp, %esp
	popl	%ebp
	ret
	.size	C, .-C
.globl inc
	.type	inc, @function
inc:
	pushl	%ebp
	movl	%esp, %ebp
	subl	$8, %esp
	movl	8(%ebp), %eax
	incl	%eax
	movl	%eax, (%esp)
	call	dec
	leave
	ret
	.size	inc, .-inc
.globl dec
	.type	dec, @function
dec:
	pushl	%ebp
	movl	%esp, %ebp
	subl	$8, %esp
	movl	8(%ebp), %eax
	movl	%eax, %edx
	cmpl	$1, %eax
	jle	.L21
	subl	$2, %eax
	movl	%eax, (%esp)
	call	inc
	movl	%eax, %edx
.L21:
	movl	%edx, %eax
	leave
	ret
	.size	dec, .-dec
.globl inc1
	.type	inc1, @function
inc1:
	pushl	%ebp
	movl	%esp, %ebp
	subl	$8, %esp
	movl	8(%ebp), %eax
	incl	%eax
	movl	%eax, (%esp)
	call	inc2
	leave
	ret
	.size	inc1, .-inc1
.globl inc2
	.type	inc2, @function
inc2:
	pushl	%ebp
	movl	%esp, %ebp
	subl	$8, %esp
	movl	8(%ebp), %eax
	addl	$2, %eax
	movl	%eax, (%esp)
	call	inc3
	leave
	ret
	.size	inc2, .-inc2
.globl int3
	.type	int3, @function
int3:
	pushl	%ebp
	movl	%esp, %ebp
	subl	$8, %esp
	movl	8(%ebp), %eax
	addl	$3, %eax
	movl	%eax, (%esp)
	call	dec1
	leave
	ret
	.size	int3, .-int3
.globl dec1
	.type	dec1, @function
dec1:
	pushl	%ebp
	movl	%esp, %ebp
	subl	$8, %esp
	movl	8(%ebp), %eax
	movl	%eax, %edx
	cmpl	$7, %eax
	jle	.L26
	subl	$7, %eax
	movl	%eax, (%esp)
	call	inc1
	movl	%eax, %edx
.L26:
	movl	%edx, %eax
	leave
	ret
	.size	dec1, .-dec1
	.section	.rodata
.LC3:
	.string	"%d %f %lld %d %d"
	.text
.globl main
	.type	main, @function
main:
	pushl	%ebp
	movl	%esp, %ebp
	pushl	%edi
	pushl	%esi
	pushl	%ebx
	subl	$44, %esp
	andl	$-16, %esp
	subl	$16, %esp
	call	f1
	movl	%eax, %ebx
	call	f4
	movl	$11, (%esp)
	call	f3
	addl	%eax, %ebx
	movl	$13, (%esp)
	call	f2
	movl	%eax, (%esp)
	call	f3
	addl	$14, %eax
	movl	%eax, (%esp)
	call	f3
	addl	$15, %eax
	movl	%eax, (%esp)
	call	f3
	leal	(%ebx,%eax), %eax
	movl	%eax, (%esp)
	call	fac
	movl	%eax, %edi
	movl	$2, 4(%esp)
	movl	$1, (%esp)
	call	C
	movl	%eax, %esi
	movl	$0, (%esp)
	movl	$1073741824, 4(%esp)
	call	two
	fstpl	(%esp)
	call	cub
	fstpl	-24(%ebp)
	movl	$1, (%esp)
	call	inc
	movl	%eax, %ebx
	movl	$8, (%esp)
	call	dec1
	movl	%eax, 24(%esp)
	movl	%ebx, 20(%esp)
	movl	%esi, 16(%esp)
	fldl	-24(%ebp)
	fstpl	8(%esp)
	movl	%edi, 4(%esp)
	movl	$.LC3, (%esp)
	call	printf
	leal	-12(%ebp), %esp
	popl	%ebx
	popl	%esi
	popl	%edi
	popl	%ebp
	ret
	.size	main, .-main
	.section	.note.GNU-stack,"",@progbits
	.ident	"GCC: (GNU) 3.4.0"

Он по-прежнему работает с памятью, но теперь он поумнел -- он удаляет(по крайней
мере частично) фрагменты избыточного кода: функции f2 и f3 не вызываются, т.е.
теперь видны следы оптимизации и компилятор может создать более быструю програм-
му. Но и сейчас GCC не смог упростить выражения с большим числом функций, нет
даже попыток "вычислить" результат выражений с рекурсивными функциями.

ruslan_pisarev_
()
Ответ на: комментарий от vilfred

Ну и gcc -S -O3 <имя.c> -o <имя.S>:

	.file	"test1.c"
	.text
	.p2align 4,,15
.globl f1
	.type	f1, @function
f1:
	pushl	%ebp
	movl	$1, %eax
	movl	%esp, %ebp
	popl	%ebp
	ret
	.size	f1, .-f1
	.p2align 4,,15
.globl f2
	.type	f2, @function
f2:
	pushl	%ebp
	movl	%esp, %ebp
	movl	8(%ebp), %eax
	popl	%ebp
	ret
	.size	f2, .-f2
	.p2align 4,,15
.globl f3
	.type	f3, @function
f3:
	pushl	%ebp
	xorl	%eax, %eax
	movl	%esp, %ebp
	cmpl	$9, 8(%ebp)
	popl	%ebp
	setg	%al
	ret
	.size	f3, .-f3
	.p2align 4,,15
.globl f4
	.type	f4, @function
f4:
	pushl	%ebp
	movl	$4, %eax
	movl	%esp, %ebp
	.p2align 4,,15
.L9:
	decl	%eax
	jns	.L9
	popl	%ebp
	movl	$5, %eax
	ret
	.size	f4, .-f4
	.p2align 4,,15
.globl two
	.type	two, @function
two:
	pushl	%ebp
	movl	%esp, %ebp
	fldl	8(%ebp)
	popl	%ebp
	fmul	%st(0), %st
	ret
	.size	two, .-two
	.p2align 4,,15
.globl cub
	.type	cub, @function
cub:
	pushl	%ebp
	movl	%esp, %ebp
	fldl	8(%ebp)
	popl	%ebp
	fld	%st(0)
	fmul	%st(1), %st
	fmulp	%st, %st(1)
	ret
	.size	cub, .-cub
	.p2align 4,,15
.globl fac
	.type	fac, @function
fac:
	pushl	%ebp
	movl	$1, %eax
	movl	%esp, %ebp
	pushl	%ebx
	subl	$4, %esp
	movl	8(%ebp), %ebx
	cmpl	$1, %ebx
	jg	.L22
	popl	%edx
	popl	%ebx
	popl	%ebp
	ret
	.p2align 4,,7
.L22:
	leal	-1(%ebx), %eax
	movl	%eax, (%esp)
	call	fac
	popl	%edx
	imull	%ebx, %eax
	popl	%ebx
	popl	%ebp
	ret
	.size	fac, .-fac
	.p2align 4,,15
.globl C
	.type	C, @function
C:
	pushl	%ebp
	movl	$1, %eax
	movl	%esp, %ebp
	subl	$20, %esp
	movl	12(%ebp), %edx
	movl	%edi, -4(%ebp)
	movl	8(%ebp), %edi
	movl	%ebx, -12(%ebp)
	movl	%esi, -8(%ebp)
	cmpl	%edx, %edi
	je	.L23
	testl	%edi, %edi
	jne	.L27
.L23:
	movl	-12(%ebp), %ebx
	movl	-8(%ebp), %esi
	movl	-4(%ebp), %edi
	movl	%ebp, %esp
	popl	%ebp
	ret
	.p2align 4,,7
.L27:
	movl	%edi, (%esp)
	leal	-1(%edx), %ebx
	movl	%ebx, 4(%esp)
	call	C
	movl	%ebx, 4(%esp)
	movl	%eax, %esi
	leal	-1(%edi), %eax
	movl	%eax, (%esp)
	call	C
	leal	(%esi,%eax), %eax
	movl	-12(%ebp), %ebx
	movl	-8(%ebp), %esi
	movl	-4(%ebp), %edi
	movl	%ebp, %esp
	popl	%ebp
	ret
	.size	C, .-C
	.p2align 4,,15
.globl inc
	.type	inc, @function
inc:
	pushl	%ebp
	movl	%esp, %ebp
	subl	$4, %esp
	movl	8(%ebp), %edx
	leal	1(%edx), %eax
	cmpl	$1, %eax
	jg	.L33
	leave
	ret
	.p2align 4,,7
.L33:
	leal	-1(%edx), %eax
	movl	%eax, (%esp)
	call	inc
	leave
	ret
	.size	inc, .-inc
	.p2align 4,,15
.globl dec
	.type	dec, @function
dec:
	pushl	%ebp
	movl	%esp, %ebp
	movl	8(%ebp), %eax
	cmpl	$1, %eax
	jg	.L36
	popl	%ebp
	ret
	.p2align 4,,7
.L36:
	subl	$2, %eax
	movl	%eax, 8(%ebp)
	popl	%ebp
	jmp	inc
	.size	dec, .-dec
	.p2align 4,,15
.globl inc2
	.type	inc2, @function
inc2:
	pushl	%ebp
	movl	%esp, %ebp
	addl	$2, 8(%ebp)
	popl	%ebp
	jmp	inc3
	.size	inc2, .-inc2
	.p2align 4,,15
.globl inc1
	.type	inc1, @function
inc1:
	pushl	%ebp
	movl	%esp, %ebp
	addl	$3, 8(%ebp)
	popl	%ebp
	jmp	inc3
	.size	inc1, .-inc1
	.p2align 4,,15
.globl dec1
	.type	dec1, @function
dec1:
	pushl	%ebp
	movl	%esp, %ebp
	subl	$8, %esp
	movl	8(%ebp), %eax
	cmpl	$7, %eax
	movl	%eax, %edx
	jg	.L45
	leave
	movl	%edx, %eax
	ret
	.p2align 4,,7
.L45:
	subl	$4, %eax
	movl	%eax, (%esp)
	call	inc3
	leave
	movl	%eax, %edx
	movl	%edx, %eax
	ret
	.size	dec1, .-dec1
	.p2align 4,,15
.globl int3
	.type	int3, @function
int3:
	pushl	%ebp
	movl	%esp, %ebp
	subl	$8, %esp
	movl	8(%ebp), %edx
	leal	3(%edx), %eax
	cmpl	$7, %eax
	jg	.L52
	leave
	ret
	.p2align 4,,7
.L52:
	leal	-1(%edx), %eax
	movl	%eax, (%esp)
	call	inc3
	leave
	ret
	.size	int3, .-int3
	.section	.rodata
.LC3:
	.string	"%d %f %lld %d %d"
	.align 8
.LC6:
	.long	0
	.long	1078984704
	.text
	.p2align 4,,15
.globl main
	.type	main, @function
main:
	pushl	%ebp
	movl	$4, %eax
	movl	%esp, %ebp
	pushl	%edi
	pushl	%esi
	pushl	%ebx
	subl	$28, %esp
	andl	$-16, %esp
	subl	$16, %esp
	.p2align 4,,15
.L61:
	decl	%eax
	jns	.L61
	movl	$2, (%esp)
	call	fac
	movl	$1, (%esp)
	imull	$3, %eax, %edi
	movl	$1, %eax
	movl	%eax, 4(%esp)
	call	C
	movl	$0, (%esp)
	movl	$1, %ecx
	movl	%eax, %ebx
	movl	%ecx, 4(%esp)
	call	C
	movl	$0, (%esp)
	leal	(%ebx,%eax), %esi
	call	inc
	movl	$4, (%esp)
	movl	%eax, %ebx
	call	inc3
	fldl	.LC6
	movl	%ebx, 20(%esp)
	movl	%esi, 16(%esp)
	movl	%edi, 4(%esp)
	movl	%eax, 24(%esp)
	fstpl	8(%esp)
	movl	$.LC3, (%esp)
	call	printf
	leal	-12(%ebp), %esp
	popl	%ebx
	popl	%esi
	popl	%edi
	popl	%ebp
	ret
	.size	main, .-main
	.section	.note.GNU-stack,"",@progbits
	.ident	"GCC: (GNU) 3.4.0"

Удален почти весь избыточный код -- за исключением функции f4 (c циклом), а если
количество итераций <4 то происходит "разворот" цикла и эта функция также удаля-
ется. Выражение с большим числом функций легко вычисляется, а в месте вызова
fac помещается ее внутренность(к сожалению с сохраненим рекурсивности). То же
происходит и с C -- она (даже ее тривиальный вызов: C(0,1) ) не вычисляется до
конца ;( Далее, взаимно рекурсивные функции -- пара и четверка -- превращаются
в рекурсивную и сопровождающие функции, которые могут ее вызывать.

ruslan_pisarev_
()
Ответ на: комментарий от vilfred

Идем дальше... gcc -S -O2 <имя.c> -o <имя.S>:

	.file	"test1.c"
	.text
	.p2align 4,,15
.globl f1
	.type	f1, @function
f1:
	pushl	%ebp
	movl	$1, %eax
	movl	%esp, %ebp
	popl	%ebp
	ret
	.size	f1, .-f1
	.p2align 4,,15
.globl f2
	.type	f2, @function
f2:
	pushl	%ebp
	movl	%esp, %ebp
	movl	8(%ebp), %eax
	popl	%ebp
	ret
	.size	f2, .-f2
	.p2align 4,,15
.globl f3
	.type	f3, @function
f3:
	pushl	%ebp
	xorl	%eax, %eax
	movl	%esp, %ebp
	cmpl	$9, 8(%ebp)
	popl	%ebp
	setg	%al
	ret
	.size	f3, .-f3
	.p2align 4,,15
.globl f4
	.type	f4, @function
f4:
	pushl	%ebp
	movl	$4, %eax
	movl	%esp, %ebp
	.p2align 4,,15
.L9:
	decl	%eax
	jns	.L9
	popl	%ebp
	movl	$5, %eax
	ret
	.size	f4, .-f4
	.p2align 4,,15
.globl two
	.type	two, @function
two:
	pushl	%ebp
	movl	%esp, %ebp
	fldl	8(%ebp)
	popl	%ebp
	fmul	%st(0), %st
	ret
	.size	two, .-two
	.p2align 4,,15
.globl cub
	.type	cub, @function
cub:
	pushl	%ebp
	movl	%esp, %ebp
	subl	$32, %esp
	fldl	8(%ebp)
	fstl	(%esp)
	fstpl	-24(%ebp)
	call	two
	fldl	-24(%ebp)
	leave
	fmulp	%st, %st(1)
	ret
	.size	cub, .-cub
	.p2align 4,,15
.globl fac
	.type	fac, @function
fac:
	pushl	%ebp
	movl	$1, %eax
	movl	%esp, %ebp
	pushl	%ebx
	subl	$4, %esp
	movl	8(%ebp), %ebx
	cmpl	$1, %ebx
	jg	.L19
	popl	%edx
	popl	%ebx
	popl	%ebp
	ret
	.p2align 4,,7
.L19:
	leal	-1(%ebx), %eax
	movl	%eax, (%esp)
	call	fac
	popl	%edx
	imull	%ebx, %eax
	popl	%ebx
	popl	%ebp
	ret
	.size	fac, .-fac
	.p2align 4,,15
.globl C
	.type	C, @function
C:
	pushl	%ebp
	movl	$1, %eax
	movl	%esp, %ebp
	subl	$20, %esp
	movl	12(%ebp), %edx
	movl	%edi, -4(%ebp)
	movl	8(%ebp), %edi
	movl	%ebx, -12(%ebp)
	movl	%esi, -8(%ebp)
	cmpl	%edx, %edi
	je	.L20
	testl	%edi, %edi
	jne	.L24
.L20:
	movl	-12(%ebp), %ebx
	movl	-8(%ebp), %esi
	movl	-4(%ebp), %edi
	movl	%ebp, %esp
	popl	%ebp
	ret
	.p2align 4,,7
.L24:
	movl	%edi, (%esp)
	leal	-1(%edx), %ebx
	movl	%ebx, 4(%esp)
	call	C
	movl	%ebx, 4(%esp)
	movl	%eax, %esi
	leal	-1(%edi), %eax
	movl	%eax, (%esp)
	call	C
	leal	(%esi,%eax), %eax
	movl	-12(%ebp), %ebx
	movl	-8(%ebp), %esi
	movl	-4(%ebp), %edi
	movl	%ebp, %esp
	popl	%ebp
	ret
	.size	C, .-C
	.p2align 4,,15
.globl inc
	.type	inc, @function
inc:
	pushl	%ebp
	movl	%esp, %ebp
	incl	8(%ebp)
	popl	%ebp
	jmp	dec
	.size	inc, .-inc
	.p2align 4,,15
.globl dec
	.type	dec, @function
dec:
	pushl	%ebp
	movl	%esp, %ebp
	movl	8(%ebp), %eax
	cmpl	$1, %eax
	jg	.L28
	popl	%ebp
	ret
	.p2align 4,,7
.L28:
	subl	$2, %eax
	movl	%eax, 8(%ebp)
	popl	%ebp
	jmp	inc
	.size	dec, .-dec
	.p2align 4,,15
.globl inc2
	.type	inc2, @function
inc2:
	pushl	%ebp
	movl	%esp, %ebp
	addl	$2, 8(%ebp)
	popl	%ebp
	jmp	inc3
	.size	inc2, .-inc2
	.p2align 4,,15
.globl inc1
	.type	inc1, @function
inc1:
	pushl	%ebp
	movl	%esp, %ebp
	incl	8(%ebp)
	popl	%ebp
	jmp	inc2
	.size	inc1, .-inc1
	.p2align 4,,15
.globl dec1
	.type	dec1, @function
dec1:
	pushl	%ebp
	movl	%esp, %ebp
	movl	8(%ebp), %eax
	cmpl	$7, %eax
	jg	.L33
	popl	%ebp
	ret
	.p2align 4,,7
.L33:
	subl	$7, %eax
	movl	%eax, 8(%ebp)
	popl	%ebp
	jmp	inc1
	.size	dec1, .-dec1
	.p2align 4,,15
.globl int3
	.type	int3, @function
int3:
	pushl	%ebp
	movl	%esp, %ebp
	addl	$3, 8(%ebp)
	popl	%ebp
	jmp	dec1
	.size	int3, .-int3
	.section	.rodata
.LC3:
	.string	"%d %f %lld %d %d"
	.text
	.p2align 4,,15
.globl main
	.type	main, @function
main:
	pushl	%ebp
	movl	%esp, %ebp
	pushl	%edi
	pushl	%esi
	pushl	%ebx
	subl	$44, %esp
	andl	$-16, %esp
	subl	$16, %esp
	call	f1
	movl	%eax, %ebx
	call	f4
	movl	$11, (%esp)
	call	f3
	movl	$13, (%esp)
	addl	%eax, %ebx
	call	f2
	movl	%eax, (%esp)
	call	f3
	addl	$14, %eax
	movl	%eax, (%esp)
	call	f3
	addl	$15, %eax
	movl	%eax, (%esp)
	call	f3
	leal	(%ebx,%eax), %eax
	movl	$2, %ebx
	movl	%eax, (%esp)
	call	fac
	movl	%ebx, 4(%esp)
	movl	%eax, %edi
	movl	$1, (%esp)
	call	C
	movl	$0, (%esp)
	movl	$1073741824, %ecx
	movl	%eax, %esi
	movl	%ecx, 4(%esp)
	call	two
	fstpl	(%esp)
	call	cub
	movl	$1, (%esp)
	fstpl	-24(%ebp)
	call	inc
	movl	$8, (%esp)
	movl	%eax, %ebx
	call	dec1
	fldl	-24(%ebp)
	movl	%ebx, 20(%esp)
	movl	%esi, 16(%esp)
	movl	%edi, 4(%esp)
	movl	%eax, 24(%esp)
	fstpl	8(%esp)
	movl	$.LC3, (%esp)
	call	printf
	leal	-12(%ebp), %esp
	popl	%ebx
	popl	%esi
	popl	%edi
	popl	%ebp
	ret
	.size	main, .-main
	.section	.note.GNU-stack,"",@progbits
	.ident	"GCC: (GNU) 3.4.0"

Ну что можно сказать? Код теперь генериться с учетом суперскалярной архитектуры:
2 конвейера, но на этом все :<

ruslan_pisarev_
()
Ответ на: комментарий от ruslan_pisarev_

Ух ты, спасибо большое за такой детальный ответ!!! Буду рабираться!... хех!

vilfred ☆☆
() автор топика
Вы не можете добавлять комментарии в эту тему. Тема перемещена в архив.