From mboxrd@z Thu Jan 1 00:00:00 1970 Return-Path: Received: (qmail 24192 invoked by alias); 9 Nov 2006 16:30:00 -0000 Received: (qmail 24159 invoked by uid 48); 9 Nov 2006 16:29:46 -0000 Date: Thu, 09 Nov 2006 16:30:00 -0000 Subject: [Bug c/29782] New: Incorrect inlining failure X-Bugzilla-Reason: CC Message-ID: Reply-To: gcc-bugzilla@gcc.gnu.org To: gcc-bugs@gcc.gnu.org From: "takis at issaris dot org" Mailing-List: contact gcc-bugs-help@gcc.gnu.org; run by ezmlm Precedence: bulk List-Archive: List-Post: List-Help: Sender: gcc-bugs-owner@gcc.gnu.org X-SW-Source: 2006-11/txt/msg00760.txt.bz2 List-Id: GCC sometimes does not inline code claiming the function has grown to large, while inlining it would have _decreased_ the codesize. For example, the following block of code, will result in read_time being inlined: #include static inline long long read_time(void) { long long l; asm volatile( "rdtsc\n\t" : "=A" (l) ); return l; } int main() { long long l = read_time(); printf("%Ld\n", l); } The following block will not inline read_time: #include static __attribute__ ((noinline)) long long read_time(void) { long long l; asm volatile( "rdtsc\n\t" : "=A" (l) ); return l; } int main() { long long l = read_time(); printf("%Ld\n", l); } As read_time is really small, its codesize will always be smaller if it gets inlined. Nonetheless, in some cases the compiler gives a warning that the code has grown to large, and that it will _disable_ inlining because of this: "warning: inlining failed in call to ‘read_time’: --param large-function-growth limit reached" This seems wrong to me as the non-inlined code would be larger then the inlined code. Compiling it with: gcc -c -I. -fomit-frame-pointer -g -Wdeclaration-after-statement -Wall -Wno-switch -Wdisabled-optimization -Wpointer-arith -Wredundant-decls -Winline -O3 rdtsc.c Shows that the inlined version is indeed smaller: size inlinerdtsc.o text data bss dec hex filename 51 0 0 51 33 inlinerdtsc.o size rdtsc.o text data bss dec hex filename 68 0 0 68 44 rdtsc.o I do not think it is specific to this short block of code, as the generated assembly shows rdtsc being only 2 bytes long, while the call instruction by itself already occupies 5 bytes: Not inlined: 00000000 : 0: 0f 31 rdtsc 2: c3 ret 3: 8d b6 00 00 00 00 lea 0x0(%esi),%esi 9: 8d bc 27 00 00 00 00 lea 0x0(%edi),%edi 00000010
: 10: 8d 4c 24 04 lea 0x4(%esp),%ecx 14: 83 e4 f0 and $0xfffffff0,%esp 17: ff 71 fc pushl 0xfffffffc(%ecx) 1a: 51 push %ecx 1b: 83 ec 18 sub $0x18,%esp 1e: e8 dd ff ff ff call 0 23: c7 04 24 00 00 00 00 movl $0x0,(%esp) 2a: 89 44 24 04 mov %eax,0x4(%esp) 2e: 89 54 24 08 mov %edx,0x8(%esp) 32: e8 fc ff ff ff call 33 37: 83 c4 18 add $0x18,%esp 3a: 31 c0 xor %eax,%eax 3c: 59 pop %ecx 3d: 8d 61 fc lea 0xfffffffc(%ecx),%esp 40: c3 ret Inlined: 00000000
: 0: 8d 4c 24 04 lea 0x4(%esp),%ecx 4: 83 e4 f0 and $0xfffffff0,%esp 7: ff 71 fc pushl 0xfffffffc(%ecx) a: 51 push %ecx b: 83 ec 18 sub $0x18,%esp e: 0f 31 rdtsc 10: 89 44 24 04 mov %eax,0x4(%esp) 14: 89 54 24 08 mov %edx,0x8(%esp) 18: c7 04 24 00 00 00 00 movl $0x0,(%esp) 1f: e8 fc ff ff ff call 20 24: 83 c4 18 add $0x18,%esp 27: 31 c0 xor %eax,%eax 29: 59 pop %ecx 2a: 8d 61 fc lea 0xfffffffc(%ecx),%esp 2d: c3 ret Does GCC just disable all inlining as soon as a certain limit in codesize is reached? Or does it actually try to determine whether inlining will increase or decrease the codesize? If so, is an heuristic used or an exact calculation (if possible)? If an heuristic is used, what is the heuristic? Thanks for any reply! :) System info: * Ubuntu Edgy Eft 6.10 * Linux issaris 2.6.17-10-generic #2 SMP Fri Oct 13 18:45:35 UTC 2006 i686 GNU/Linux * Intel(R) Pentium(R) 4 CPU 3.20GHz * Compiler: Using built-in specs. Target: i486-linux-gnu Configured with: ../src/configure -v --enable-languages=c,c++,fortran,objc,obj-c++,treelang --prefix=/usr --enable-shared --with-system-zlib --libexecdir=/usr/lib --without-included-gettext --enable-threads=posix --enable-nls --program-suffix=-4.1 --enable-__cxa_atexit --enable-clocale=gnu --enable-libstdcxx-debug --enable-mpfr --enable-checking=release i486-linux-gnu Thread model: posix gcc version 4.1.2 20060928 (prerelease) (Ubuntu 4.1.1-13ubuntu5) With friendly regards, Takis -- Summary: Incorrect inlining failure Product: gcc Version: 4.1.2 Status: UNCONFIRMED Severity: minor Priority: P3 Component: c AssignedTo: unassigned at gcc dot gnu dot org ReportedBy: takis at issaris dot org GCC build triplet: i486-linux-gnu GCC host triplet: i486-linux-gnu GCC target triplet: i486-linux-gnu http://gcc.gnu.org/bugzilla/show_bug.cgi?id=29782