Bug 28120

Summary: The option -f[no-]inline-functions is invalid with -O2
Product: gcc Reporter: tanaka
Component: cAssignee: Not yet assigned to anyone <unassigned>
Status: RESOLVED INVALID    
Severity: normal CC: gcc-bugs
Priority: P3    
Version: 4.1.1   
Target Milestone: ---   
Host: i686-pc-linux-gnu Target: i686-pc-linux-gnu
Build: i686-pc-linux-gnu Known to work:
Known to fail: Last reconfirmed:

Description tanaka 2006-06-21 10:26:54 UTC
Compiling C source code(test.c) by

gcc -c --save-temps -O2 -fno-inline-functions test.c -o test.o
gcc -c --save-temps -O2 -finline-functions test.c -o test.o

Both output, function(small()) is integrated into main().

If the option -fno-unit-at-a-time is set additionally, the option -f[no-]inline-functions
becomes effective.

Is it correct?

======== test.c =========
static int small(int a)
{
	return 2*a;
}

int main()
{
	return small(2);
}

======== gcc -v =========
Target: i686-pc-linux-gnu
Configured with: ../gcc-4.1.1/configure --prefix=/work/te/tool/Linux-i686 --enable-languages=c,c++
Thread model: posix
gcc version 4.1.1
----------------
Same result is produced by gcc-3.4.5.
Comment 1 Richard Biener 2006-06-21 11:57:24 UTC
-f[no-]inline is what you are looking for.
Comment 2 tanaka 2006-06-21 12:46:17 UTC
Thanks for your reply.

Originally, my wanting to say is that
When compile a C source code only with an option -O2, 
small function is not inlined.
But it is inlined by gcc-4.1.1.

Small function is not inlined by gcc-3.2.2.

Best regards.
Comment 3 Andrew Pinski 2006-06-21 14:19:02 UTC
Or -fno-inline-functions-called-once for 4.2.0 and above.
Comment 4 Andrew Pinski 2006-06-21 14:19:45 UTC
(In reply to comment #3)
> Or -fno-inline-functions-called-once for 4.2.0 and above.
For this case that is.
Comment 5 tanaka 2006-06-22 03:28:12 UTC
I home to confirm a conclusion.
That is to say, simple function is integrated into their callers when it compiled with a option -O2, after gcc-3.4 isn't it?
Comment 6 tanaka 2006-06-23 09:52:37 UTC
Please answer my question again.

It can not be distinguished between a function, which specified 
__inline__ and an another function, which is not specified __inline__, 
after gcc-3.4.

This is sample.

/************ test.c ****************/
static __inline__ int inl_small( int a)
{
	return 2*a;
}

static int small(int a)
{
	return 2*a;
}

int main()
{
	int i;

	i = inl_small(2);
	i = small(i);
}
############ mk.rc ####################
#!/bin/sh
set -v

BD3_4_5='/work/te/tool/Linux-i686'
GCC3_4_5="$BD3_4_5/bin/gcc"

BD3_3_2='/work/te/tool/Linux-i686-3.3.2'
GCC3_3_2="$BD3_3_2/bin/gcc"

ODP="$BD3_3_2/bin/objdump -C -S --disassemble-zeroes"

$GCC3_4_5 -O2                       -c test.c -o 3_4_5_test_.o
$GCC3_4_5 -O2 -finline-functions    -c test.c -o 3_4_5_test_inf.o
$GCC3_4_5 -O2 -fno-inline-functions -c test.c -o 3_4_5_test_noinf.o
$GCC3_4_5 -O2 -fno-inline           -c test.c -o 3_4_5_test_noin.o

$GCC3_3_2 -O2                       -c test.c -o 3_3_2_test_.o
$GCC3_3_2 -O2 -finline-functions    -c test.c -o 3_3_2_test_inf.o
$GCC3_3_2 -O2 -fno-inline-functions -c test.c -o 3_3_2_test_noinf.o
$GCC3_3_2 -O2 -fno-inline           -c test.c -o 3_3_2_test_noin.o

$ODP 3_4_5_test_.o      > 3_4_5_test_.o.odp
$ODP 3_4_5_test_inf.o   > 3_4_5_test_inf.o.odp
$ODP 3_4_5_test_noinf.o > 3_4_5_test_noinf.o.odp
$ODP 3_4_5_test_noin.o  > 3_4_5_test_noin.o.odp

$ODP 3_3_2_test_.o      > 3_3_2_test_.o.odp
$ODP 3_3_2_test_inf.o   > 3_3_2_test_inf.o.odp
$ODP 3_3_2_test_noinf.o > 3_3_2_test_noinf.o.odp
$ODP 3_3_2_test_noin.o  > 3_3_2_test_noin.o.odp
######################################
Result is
----------------------------------------------------
gcc-3.3.2 -O2 
                        inl_small()     small()
                        inlined.        not inlined.
-finline-functions      inlined.        inlined.
-fno-inline-functions   inlined.        not inlined.
-fno-inline             not inlined.    not inlined.

----------------------------------------------------
gcc-3.4.5 -O2 
                        inl_small       small
                        inlined.        inlined.
-finline-functions      inlined.        inlined.
-fno-inline-functions   inlined.        inlined.
-fno-inline             not inlined.    not inlined.
----------------------------------------------------

It could be controlled to make a function inlined or not inlined,
according to specified __inline__ or not specified __inline__ 
before gcc-3.4.
But it can't after gcc-3.4.


I hope to confirm a conclusion.
That is to say, simple function is always integrated into their 
callers when it compiled with a option -O2, after gcc-3.4 isn't it?

Best regards.
Comment 7 Richard Biener 2006-06-23 10:06:03 UTC
Newer gcc always inline _static_ functions that are used _once_ into their only caller (regardless of being declared inline or not).  You can disable this behavior with -fno-inline-functions-called-once.

All gcc inline small functions regardless of beind declared inline or not, if
-finline-functions is in effect (which it is automatically at -O3).

But... why do you care?  The "inline" keyword is only a hint to the compiler, not
something it has to obey to (or obey to the reverse case, where "inline" is not specified).  So yes, you cannot control what is inlined or what not.  If you need to for correctness, there's two function attributes, __attribute__((noinline)) and __attribute__((always_inline)).