Bug 31886 - (different from bug report c/31077 and 29241) C handling of always_inline attribute error and a solution
Summary: (different from bug report c/31077 and 29241) C handling of always_inline att...
Status: RESOLVED FIXED
Alias: None
Product: gcc
Classification: Unclassified
Component: c (show other bugs)
Version: 4.1.0
: P3 normal
Target Milestone: 4.4.0
Assignee: Not yet assigned to anyone
URL:
Keywords:
Depends on:
Blocks:
 
Reported: 2007-05-10 04:06 UTC by Zhouyi Zhou
Modified: 2009-01-13 22:41 UTC (History)
4 users (show)

See Also:
Host: Linux i686 GNU/Linux
Target: Linux i686 GNU/Linux
Build: Linux i686 GNU/Linux
Known to work: 4.4.0
Known to fail: 3.4.6 4.1.2 4.3.2
Last reconfirmed: 2007-05-10 11:04:34


Attachments
Example of kernel file that causes "inlining failed" error (84.71 KB, text/plain)
2007-08-02 17:24 UTC, Rob
Details

Note You need to log in before you can comment on or make changes to this bug.
Description Zhouyi Zhou 2007-05-10 04:06:47 UTC
When compiling following code with no optimize flags given, gcc will complain:
      1 __attribute__((always_inline)) unsigned int
      2 alloc_null_binding1(void)
      3 {
      4  return 1;
      5 }
      6
      7 static inline __attribute__((always_inline)) int ip_nat_initialized1(void)
      8 {
      9
     10    return 2;
     11 }
     12
     13 int ip_nat_rule_find1(void)
     14 {
     15  int ret;
     16  if (!ip_nat_initialized1()){
     17    ret = alloc_null_binding1();
     18   }
     19  return ret;
     20 }
/***************************************************************
****************************************************************
***************************************************************/
[root@zzy inline]gcc -S hello.c
hello.c: In function 'ip_nat_rule_find1':
hello.c:3: sorry, unimplemented: inlining failed in call to 'alloc_null_binding1': function body not available
hello.c:17: sorry, unimplemented: called from here
/***************************************************************
****************************************************************
***************************************************************/
solutions:
Solution 1:
--- gcc-4.1.0/gcc/tree-optimize.c.back  2007-05-09 22:38:58.000000000 -0400
+++ gcc-4.1.0/gcc/tree-optimize.c       2007-05-09 22:38:31.000000000 -0400
@@ -389,9 +389,15 @@
          break;
       if (e)
        {
-         timevar_push (TV_INTEGRATION);
-         optimize_inline_calls (fndecl);
-         timevar_pop (TV_INTEGRATION);
+         for (e = node->callees; e; e = e->next_callee)
+           if (e->inline_failed && !warn_inline)
+             break;
+         if (!e)
+           {
+             timevar_push (TV_INTEGRATION);
+             optimize_inline_calls (fndecl);
+             timevar_pop (TV_INTEGRATION);
+           }
        }
     }
   /* We are not going to maintain the cgraph edges up to date.

/***************************************************************
****************************************************************
***************************************************************/
Solution 2:
--- gcc-4.1.0/gcc/cgraphunit.c.back     2007-05-09 22:41:35.000000000 -0400
+++ gcc-4.1.0/gcc/cgraphunit.c  2007-05-09 22:24:21.000000000 -0400
@@ -1206,7 +1206,7 @@
   if (dump_enabled_p (TDI_tree_all))
     return true;
   if (!cgraph_global_info_ready)
-    return (DECL_INLINE (decl) && !flag_really_no_inline);
+    return ((DECL_INLINE (decl) && !flag_really_no_inline)||lookup_attribute ("always_inline", DECL_ATTRIBUTES (decl)));
   /* Look if there is any clone around.  */
   for (node = cgraph_node (decl); node; node = node->next_clone)
     if (node->global.inlined_to)
--- gcc-4.1.0/gcc/tree-inline.c.back    2007-05-09 22:41:18.000000000 -0400
+++ gcc-4.1.0/gcc/tree-inline.c 2007-05-09 22:35:12.000000000 -0400
@@ -1594,6 +1594,8 @@
     }

   /* Squirrel away the result so that we don't have to check again.  */
+  if (lookup_attribute ("always_inline", DECL_ATTRIBUTES (fn)))
+    inlinable = true;
   DECL_UNINLINABLE (fn) = !inlinable;

   return inlinable;

/***************************************************************
****************************************************************
***************************************************************/

Sincerely yours
Zhouyi Zhou
Comment 1 Andrew Pinski 2007-05-10 04:19:09 UTC
I don't think this is a bug.  The documentation for always inline says:
"For functions declared inline, this attribute inlines the function even if no optimization level was specified."

That quote is from:
http://gcc.gnu.org/onlinedocs/gcc-4.1.2/gcc/Function-Attributes.html
And it is also in:
http://gcc.gnu.org/onlinedocs/gcc-4.0.2/gcc/Function-Attributes.html


alloc_null_binding is not declared inline so how do you think GCC will inline this function?
Comment 2 zhouzhouyi@ercist.iscas.ac.cn 2007-05-10 04:41:05 UTC
Subject: Re:  (different from bug report c/31077 and 29241) C
 handling of always_inline attribute error and a solution

Dear pinskia,
  If you lookup my solution current handling of conditions 
for optimize_inline_calls in tree_rest_of_compilation is obvious
not good.
Sincerely yours
Zhouyi Zhou
On 10 May 2007 03:19:10 -0000
"pinskia at gcc dot gnu dot org" <gcc-bugzilla@gcc.gnu.org> wrote:

> 
> 
> ------- Comment #1 from pinskia at gcc dot gnu dot org  2007-05-10 04:19 -------
> I don't think this is a bug.  The documentation for always inline says:
> "For functions declared inline, this attribute inlines the function even if no
> optimization level was specified."
> 
> That quote is from:
> http://gcc.gnu.org/onlinedocs/gcc-4.1.2/gcc/Function-Attributes.html
> And it is also in:
> http://gcc.gnu.org/onlinedocs/gcc-4.0.2/gcc/Function-Attributes.html
> 
> 
> alloc_null_binding is not declared inline so how do you think GCC will inline
> this function?
> 
> 
> -- 
> 
> pinskia at gcc dot gnu dot org changed:
> 
>            What    |Removed                     |Added
> ----------------------------------------------------------------------------
>              Status|UNCONFIRMED                 |WAITING
>             Summary|(different from bug report  |(different from bug report
>                    |c/31077 and 29241) C        |c/31077 and 29241) C
>                    |handling of always_inline   |handling of always_inline
>                    |attribute error and a       |attribute error and a
>                    |solution                    |solution
> 
> 
> http://gcc.gnu.org/bugzilla/show_bug.cgi?id=31886
> 
> ------- You are receiving this mail because: -------
> You reported the bug, or are watching the reporter.
> 
Comment 3 zhouzhouyi@ercist.iscas.ac.cn 2007-05-10 04:43:44 UTC
Subject: Re:  (different from bug report c/31077 and 29241) C
 handling of always_inline attribute error and a solution

heh, pinkia, take a look at my solution1
On 10 May 2007 03:41:06 -0000
"zhouzhouyi at ercist dot iscas dot ac dot cn" <gcc-bugzilla@gcc.gnu.org> wrote:

> 
> 
> ------- Comment #2 from zhouzhouyi at ercist dot iscas dot ac dot cn  2007-05-10 04:41 -------
> Subject: Re:  (different from bug report c/31077 and 29241) C
>  handling of always_inline attribute error and a solution
> 
> Dear pinskia,
>   If you lookup my solution current handling of conditions 
> for optimize_inline_calls in tree_rest_of_compilation is obvious
> not good.
> Sincerely yours
> Zhouyi Zhou
> On 10 May 2007 03:19:10 -0000
> "pinskia at gcc dot gnu dot org" <gcc-bugzilla@gcc.gnu.org> wrote:
> 
> > 
> > 
> > ------- Comment #1 from pinskia at gcc dot gnu dot org  2007-05-10 04:19 -------
> > I don't think this is a bug.  The documentation for always inline says:
> > "For functions declared inline, this attribute inlines the function even if no
> > optimization level was specified."
> > 
> > That quote is from:
> > http://gcc.gnu.org/onlinedocs/gcc-4.1.2/gcc/Function-Attributes.html
> > And it is also in:
> > http://gcc.gnu.org/onlinedocs/gcc-4.0.2/gcc/Function-Attributes.html
> > 
> > 
> > alloc_null_binding is not declared inline so how do you think GCC will inline
> > this function?
> > 
> > 
> > -- 
> > 
> > pinskia at gcc dot gnu dot org changed:
> > 
> >            What    |Removed                     |Added
> > ----------------------------------------------------------------------------
> >              Status|UNCONFIRMED                 |WAITING
> >             Summary|(different from bug report  |(different from bug report
> >                    |c/31077 and 29241) C        |c/31077 and 29241) C
> >                    |handling of always_inline   |handling of always_inline
> >                    |attribute error and a       |attribute error and a
> >                    |solution                    |solution
> > 
> > 
> > http://gcc.gnu.org/bugzilla/show_bug.cgi?id=31886
> > 
> > ------- You are receiving this mail because: -------
> > You reported the bug, or are watching the reporter.
> > 
> 
> 
> -- 
> 
> 
> http://gcc.gnu.org/bugzilla/show_bug.cgi?id=31886
> 
> ------- You are receiving this mail because: -------
> You reported the bug, or are watching the reporter.
> 
Comment 4 Zhouyi Zhou 2007-05-10 05:33:23 UTC
Dear Pinsky
 In addition,
The problem will still exists even add a inline to line 1 of the program, unless you add a static to line 1.
Sincerely yours 
Zhouyi Zhou
Comment 5 Richard Biener 2007-05-10 11:04:34 UTC
Confirmed.  Either we should not accept always_inline on a function not declared inline (or warn in that case), or a function marked always_inline should be considered for inlining always.  Second, the

t.i:3: sorry, unimplemented: inlining failed in call to 'alloc_null_binding1': function body not available

is fixed in 4.1.2.

Which leaves us with

t.i:3: sorry, unimplemented: inlining failed in call to 'alloc_null_binding1': function not inlinable

with the function not marked inline (but only for -O0, not -O).  I guess we
want to make that behavior at least consistent.  Note with -O0 -finline we get

t.i:3: sorry, unimplemented: inlining failed in call to 'alloc_null_binding1': function body not available

again ;)
Comment 6 Rob 2007-08-02 17:18:39 UTC
I can confirm this too. Here is the bug report I was to post - but I searched to see if this was already reported ;) - Here are my notes:

tree-inline.c - sorry, unimplemented: inlining failed ... function body not available

When compiling the kernel with GCC version 4.3.0 20070630 or 20070716 it seems to remove (optimize away) functions which are needed. When GCC later discovers it needs the function afterall it crys "function body not available" and terminates the build with an error. 

This does not occur if I add "-O0" on the end of the command line. :(

I also do not have this problem when using GCC version 4.2.1 20070628 .


http://www.kernel.org/pub/linux/kernel/v2.6/testing/linux-2.6.22-rc2.tar.bz2

make V=1 vmlinux

...
/usr/test/bin/gcc -Wp,-MD,kernel/.futex.o.d  -nostdinc -isystem /usr/test/lib/gcc/i686-pc-linux-gnu/4.3.0/include -D__KERNEL__ -Iinclude -Iinclude2 -Ilinux-2.6.22-rc2-source/include -include include/linux/autoconf.h -Ilinux-2.6.22-rc2-source/kernel -Ikernel -Wall -Wundef -Wstrict-prototypes -Wno-trigraphs -fno-strict-aliasing -fno-common -O2 -fprofile-arcs -ftest-coverage -D__arch_um__ -DSUBARCH=\"i386\" -Ilinux-2.6.22-rc2-source/arch/um/include -Iarch/um/include  -Ilinux-2.6.22-rc2-source/arch/um/include  -Ilinux-2.6.22-rc2-source/arch/um/include/skas -Dvmap=kernel_vmap -Din6addr_loopback=kernel_in6addr_loopback -march=k8 -mpreferred-stack-boundary=2 -ffreestanding -D_LARGEFILE64_SOURCE -Derrno=kernel_errno -Dsigprocmask=kernel_sigprocmask -Dmktime=kernel_mktime -U__i386__ -Ui386 -fno-unit-at-a-time -fno-omit-frame-pointer -fno-optimize-sibling-calls -g -fno-stack-protector -Wdeclaration-after-statement -Wno-pointer-sign  -D"KBUILD_STR(s)=#s" -D"KBUILD_BASENAME=KBUILD_STR(futex)"  
-D"KBUILD_MODNAME=KBUILD_STR(futex)" -c -o kernel/.tmp_futex.o linux-2.6.22-rc2-source/kernel/futex.c

linux-2.6.22-rc2-source/kernel/futex.c: In function 'futex_requeue_pi':
linux-2.6.22-rc2-source/kernel/futex.c:272: sorry, unimplemented: inlining failed in call to 'get_futex_key_refs': function body not available
linux-2.6.22-rc2-source/kernel/futex.c:908: sorry, unimplemented: called from here
make[2]: *** [kernel/futex.o] Error 1
make[1]: *** [kernel] Error 2
make: *** [vmlinux] Error 2
make: Leaving directory `linux-2.6.22-rc2-source'


The message comes from this file: gcc-4_3-trunk/gcc/tree-inline.c , line 2443:

          sorry ("inlining failed in call to %q+F: %s", fn, reason);
          sorry ("called from here");

and from here, /opt/gcc-4_3-trunk/gcc/diagnostic.def :
DEFINE_DIAGNOSTIC_KIND (DK_SORRY, "sorry, unimplemented: ")


The same problem occurs when compiling these files:
linux-2.6.22-rc2-source/mm/filemap.c
linux-2.6.22-rc2-source/fs/buffer.c
linux-2.6.22-rc2-source/fs/bio.c
linux-2.6.22-rc2-source/fs/block_dev.c
linux-2.6.22-rc2-source/fs/reiserfs/do_balan.c
linux-2.6.22-rc2-source/fs/reiserfs/namei.c
linux-2.6.22-rc2-source/fs/reiserfs/stree.c
linux-2.6.22-rc2-source/block/elevator.c
linux-2.6.22-rc2-source/block/ll_rw_blk.c
linux-2.6.22-rc2-source/net/ipv4/ip_output.c
linux-2.6.22-rc2-source/net/ipv4/igmp.c and linux-2.6.22-rc2-source/include/net/dst.h
linux-2.6.22-rc2-source/net/ipv4/xfrm4_output.c and linux-2.6.22-rc2-source/include/net/dst.h
linux-2.6.22-rc2-source/fs/udf/partition.c
linux-2.6.22-rc2-source/net/ipv4/ipvs/ip_vs_xmit.c
linux-2.6.22-rc2-source/net/ipv4/netfilter/nf_nat_rule.c
linux-2.6.22-rc2-source/net/ipv6/ip6_output.c
linux-2.6.22-rc2-source/net/ipv6/ip6_input.c
linux-2.6.22-rc2-source/net/ipv6/ndisc.c
linux-2.6.22-rc2-source/net/ipv6/mcast.c


I tried this line in the kernel Makefile but still got the same error message:
CFLAGS_futex.o += $(call cc-ifversion, -ge, 0403, -fno-inline)

I would have preferred if that had worked rather than resorting to "-O0" since
there are so many files affected by this issue.


I worked around this problem by editing "linux-2.6.22-rc2-source/kernel/Makefile" (and all the other makefiles) by adding this sort of line near the top of the Makefile:

CFLAGS_futex.o += $(call cc-ifversion, -ge, 0403, -O0)


That allows the kernel to build with GCC 4.3 but does not "fix" GCC itself.


Here is the minimum command line to trigger the problem:

gcc -O1 -fno-unit-at-a-time -c -o futex.o futex.i 
linux-2.6.22-rc2-source/kernel/futex.c: In function 'futex_requeue_pi':
linux-2.6.22-rc2-source/kernel/futex.c:272: sorry, unimplemented: inlining failed in call to 'get_futex_key_refs': function body not available
linux-2.6.22-rc2-source/kernel/futex.c:908: sorry, unimplemented: called from here

If I use "-O0" or leave off "-fno-unit-at-a-time" I don't get the error. These
options are what are present in the kernel's makefile (not my preferences). The
kernel's makefiles are written in a particular way to allow various other features
to work (so a full overhaul of the all makefiles is out (for me)). If this is
not a problem with GCC 4.3 but instead an issue with the way Linux was written
then we can't expect to be compiling Linux with GCC 4.3 any time soon.


The kernel's makefile options do work with 4.2.1 and (recent) earlier versions of GCC.


I will enclose the ".i" file.
Comment 7 Rob 2007-08-02 17:24:00 UTC
Created attachment 14010 [details]
Example of kernel file that causes "inlining failed" error
Comment 8 Rob 2007-08-06 06:44:57 UTC
GCC 4.2.2 20070804 is able to compile newer kernels as is 4.2.1 20070628. I guess 4.3 and 4.1 are the only series lacking this ability. 

I am not allowed to change the "Summary:" to add "[4.3 Regression]" to the begining since I did not create this report. 

If we desire to compile the Linux kernel with GCC 4.3 (and apparently, but not tested by me, GCC 4.1 also) we will need to fix this.
Comment 9 Zhouyi Zhou 2007-08-06 08:40:50 UTC
(In reply to comment #8)
I try to compile my giving C program using gcc-4.2.1, the problem still exists.
As my solution 1 suggests:
a caller function is inlinable only if all of its callee functions are 
inlinable. while this is not the case in original tree-optimize.c (including that in CVS), which says a caller function should be inlined if one of its function is inlinable. 

Comment 10 Richard Biener 2007-08-20 07:58:04 UTC
Honza, can you look into this pls?
Comment 11 Rob 2009-01-13 22:10:37 UTC
ping
Comment 12 Richard Biener 2009-01-13 22:41:30 UTC
Fixed for GCC 4.4 (with unit-at-a-time being always on).