This is the mail archive of the gcc@gcc.gnu.org mailing list for the GCC project.


Index Nav: [Date Index] [Subject Index] [Author Index] [Thread Index]
Message Nav: [Date Prev] [Date Next] [Thread Prev] [Thread Next]

Re: Some optimization thoughts (and thanks!)


Carlo Wood <carlo@alinoe.com> wrote (May 1, 2001, 12:15:46EDT):
>The compiler can't know how often a function is called, only the linker
>can.  This would be possible for static functions, but I'd be highly
>surpriced when static functions with one caller aren't already inlined :/

1) The -fprofile-arcs option generates a program flow graph, so gcc
_can_ determine if a function has a single call point (this need not be
done at the level of the linker).

2) gcc (2.96, at least) does not inline _static_ functions that are only
called from one location.

Here is some test code that demonstrates this failing:
/* inline_test.c */
/* a test of inlining single call point functions */

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

static int file_local_variable;

static void do_that(void)
{
int temp;
int count;
int limit;
temp = 0;

/* random number between 0 and 255 */
limit = rand() & 0xff;

for (count = 0; count < limit; count++)
{
temp += (count & 0xf1);
}

if (temp > 4096)
{
temp = temp/512;

for (count = 0; count < limit; count++)
{
temp += (count & 0x22);
}
if (temp > 4096)
{
file_local_variable = 0;
}
else
{
file_local_variable = 512;
}
}
else
{
temp = temp*16;

for (count = 0; count < limit; count++)
{
temp += (count & 0x1f);
}
if (temp > 4096)
{
file_local_variable = 4;
}
else
{
temp *= 4;
for (count = 0; count < limit; count++)
{
temp += (count & 0xf2);
}
if (temp > 4096)
{
file_local_variable = 8;
}
else
{
file_local_variable = 16;
}
}
}
}

void do_this (void)
{
do_that();
if (file_local_variable==0)
{
printf("This is done.");
}
else
{
printf("Ooops!");
}
}

/* END */

And here is the assembly resulting from 'gcc -O3 -S inline_test.c':

.file "inline_test.c"
.version "01.01"
gcc2_compiled.:
.text
.align 4
.type do_that,@function
do_that:
pushl %ebp
movl %esp, %ebp
pushl %ebx
pushl %eax
call rand
xorl %ebx, %ebx
movzbl %al,%ecx
xorl %edx, %edx
cmpl %ecx, %ebx
jge .L62
.p2align 2
.L36:
movl %edx, %eax
andl $241, %eax
incl %edx
addl %eax, %ebx
cmpl %ecx, %edx
jl .L36
.L62:
cmpl $4096, %ebx
jle .L38
testl %ebx, %ebx
movl %ebx, %eax
jns .L39
leal 511(%ebx), %eax
.L39:
movl %eax, %ebx
xorl %edx, %edx
sarl $9, %ebx
cmpl %ecx, %edx
jge .L63
.p2align 2
.L43:
movl %edx, %eax
andl $34, %eax
incl %edx
addl %eax, %ebx
cmpl %ecx, %edx
jl .L43
.L63:
xorl %eax, %eax
cmpl $4097, %ebx
setl %al
decl %eax
andl $-512, %eax
addl $512, %eax
jmp .L66
.p2align 2
.L38:
xorl %edx, %edx
sall $4, %ebx
cmpl %ecx, %edx
jge .L64
.p2align 2
.L51:
movl %edx, %eax
andl $31, %eax
incl %edx
addl %eax, %ebx
cmpl %ecx, %edx
jl .L51
.L64:
cmpl $4096, %ebx
jle .L53
movl $4, file_local_variable
jmp .L47
.p2align 2
.L53:
xorl %edx, %edx
sall $2, %ebx
cmpl %ecx, %edx
jge .L65
.p2align 2
.L58:
movl %edx, %eax
andl $242, %eax
incl %edx
addl %eax, %ebx
cmpl %ecx, %edx
jl .L58
.L65:
xorl %eax, %eax
cmpl $4097, %ebx
setl %al
leal 8(,%eax,8), %eax
.L66:
movl %eax, file_local_variable
.L47:
movl -4(%ebp), %ebx
leave
ret
.Lfe1:
.size do_that,.Lfe1-do_that
.section .rodata
.LC0:
.string "This is done."
.LC1:
.string "Ooops!"
.local file_local_variable
.comm file_local_variable,4,4
.text
.align 4
.globl do_this
.type do_this,@function
do_this:
pushl %ebp
movl %esp, %ebp
subl $8, %esp
call do_that
movl file_local_variable, %edx
testl %edx, %edx
jne .L68
subl $12, %esp
pushl $.LC0
jmp .L70
.p2align 2
.L68:
subl $12, %esp
pushl $.LC1
.L70:
call printf
addl $16, %esp
leave
ret
.Lfe2:
.size do_this,.Lfe2-do_this
.ident "GCC: (GNU) 2.96 20000731 (Red Hat Linux 7.0)"

p.s., I am not a gcc developer and only a hobbyist user.  I wish gcc to be
the best in the world because it is Open Source.  

Index Nav: [Date Index] [Subject Index] [Author Index] [Thread Index]
Message Nav: [Date Prev] [Date Next] [Thread Prev] [Thread Next]