On gcc-3.4.0, unreferenced nested inline functions are not optimized away at -O0 or -O1. This is a regression from gcc-2.95.x and gcc-3.2.2. This breaks building glibc-2.3.2 for sparc64 (see http://sources.redhat.com/ml/libc-alpha/2004-05/msg00066.html) No idea why it doesn't break other architectures. Here's a small test case: void f(void) { inline int g(void) { extern int should_be_optimized_away(void); return should_be_optimized_away(); } } Compile with -S, then examine the .s file; you'll see a reference to should_be_optimized_away that shouldn't be there.
Confirmed, fixed already on the tree-ssa. I do not know if this will get fixed for 3.4.1 at all.
Although the GCC documentation does not specifically say that, in this case, the function should not be emitted, it is certainly suggested by the fact that the documentation says that "static" inline functions are not emitted. A nested inline should be treated like a static inline. Jan, would you please take a look at this problem?
Jan, please investigate this problem. There are a lot of unit-at-a-time related regressions targeted at 3.4.1; please look at all of them and indicate your thoughts.
Subject: Re: [3.4 Regression] [non-unit-at-a-time] unreferenced nested inline functions not optimized away > > ------- Additional Comments From mmitchel at gcc dot gnu dot org 2004-06-12 22:05 ------- > Jan, please investigate this problem. There are a lot of unit-at-a-time related > regressions targeted at 3.4.1; please look at all of them and indicate your > thoughts. I am still offline till day after tomorrow but I will look into that afterwards. The irritating thing about this testcase is that nested functions bypass cgraph code completely on GCC before tree-ssa merge and thus it does not deffer and elliminate it. I am quite surprised that this used to be working on 2.95 and 3.2. To get it back I guess I will need to add some hacks into the frontend to ask the cgraph about the reachability. Honza
I've tried 3 different simple tricks to get this working right, but they've all failed in nasty interference in between trampolines and function ellimination. Given the fact that nested functions are rarely used and ellimination of outline copy of function is not promised anywhere and that mainline already handles this right by unnesting, I would suggest to mark this as WONTFIX. Honza
Fixed in GCC 3.5; won't be fixed in GCC 3.4.x.
*** Bug 16450 has been marked as a duplicate of this bug. ***
This bug is IMHO very severe, it makes GCC 3.4.x totally unusable for glibc builds as it almost doubles the size of the dynamic linker. Can't this decision be reconsidered? It worked just fine until GCC 3.3.x because of the DECL_DEFER_OUTPUT setting in rest_of_compilation (now rest_of_handle_inlining). I have played with: --- gcc/toplev.c.jj 2004-02-20 19:37:45.000000000 +0100 +++ gcc/toplev.c 2004-07-19 15:50:30.985366840 +0200 @@ -2714,9 +2714,13 @@ rest_of_handle_inlining (tree decl) for unreferenced symbols. See g77.f-torture/execute/980520-1.f. But removing this line from the check breaks all languages that use the call graph to output symbols. This hard-coded check is - the least invasive work-around. */ + the least invasive work-around. + C nested functions need to be deferred here too, otherwise + they will be emitted even when never used. */ && (flag_inline_functions - || strcmp (lang_hooks.name, "GNU F77") == 0) + || strcmp (lang_hooks.name, "GNU F77") == 0 + || (strcmp (lang_hooks.name, "GNU C") == 0 + && DECL_CONTEXT (decl))) && ((! TREE_PUBLIC (decl) && ! TREE_ADDRESSABLE (decl) && ! TREE_SYMBOL_REFERENCED (DECL_ASSEMBLER_NAME (decl)) && ! flag_keep_inline_functions) Honza, can you see what problems could this cause?
Subject: Re: [3.4 Regression] [non-unit-at-a-time] unreferenced nested inline functions not optimized away > > ------- Additional Comments From jakub at gcc dot gnu dot org 2004-07-19 14:11 ------- > This bug is IMHO very severe, it makes GCC 3.4.x totally unusable for glibc > builds as it almost doubles the size of the dynamic linker. > Can't this decision be reconsidered? Why exactly does glibc rely on elliminating unused nested functions? > > It worked just fine until GCC 3.3.x because of the DECL_DEFER_OUTPUT setting > in rest_of_compilation (now rest_of_handle_inlining). > > I have played with: > --- gcc/toplev.c.jj 2004-02-20 19:37:45.000000000 +0100 > +++ gcc/toplev.c 2004-07-19 15:50:30.985366840 +0200 > @@ -2714,9 +2714,13 @@ rest_of_handle_inlining (tree decl) > for unreferenced symbols. See g77.f-torture/execute/980520-1.f. > But removing this line from the check breaks all languages that > use the call graph to output symbols. This hard-coded check is > - the least invasive work-around. */ > + the least invasive work-around. > + C nested functions need to be deferred here too, otherwise > + they will be emitted even when never used. */ > && (flag_inline_functions > - || strcmp (lang_hooks.name, "GNU F77") == 0) > + || strcmp (lang_hooks.name, "GNU F77") == 0 > + || (strcmp (lang_hooks.name, "GNU C") == 0 > + && DECL_CONTEXT (decl))) > && ((! TREE_PUBLIC (decl) && ! TREE_ADDRESSABLE (decl) > && ! TREE_SYMBOL_REFERENCED (DECL_ASSEMBLER_NAME (decl)) > && ! flag_keep_inline_functions) > > Honza, can you see what problems could this cause? That might work (using the old deffering code path just didn't occured to me). Instead of relying on the hooks, I think we might simply use cgraph_node (decl)->origin test so we won't mess up for methods (this is why you need the checks for languages, right?) Thanks! Honza > > -- > > > http://gcc.gnu.org/bugzilla/show_bug.cgi?id=15345 > > ------- You are receiving this mail because: ------- > You are on the CC list for the bug, or are watching someone who is.
Subject: Bug 15345 CVSROOT: /cvs/gcc Module name: gcc Branch: gcc-3_4-branch Changes by: jakub@gcc.gnu.org 2004-07-21 07:37:18 Modified files: gcc : ChangeLog tree-optimize.c toplev.c gcc/testsuite : ChangeLog Added files: gcc/testsuite/gcc.dg/torture: nested-fn-1.c Log message: PR middle-end/15345 PR c/16450 * toplev.c (rest_of_handle_inlining): Set DECL_DEFER_OUTPUT on C nested functions as well. * tree-optimize.c (tree_rest_of_compilation): Don't clear decl rtls for deferred nested inlines. * gcc.dg/torture/nested-fn-1.c: New test. Patches: http://gcc.gnu.org/cgi-bin/cvsweb.cgi/gcc/gcc/ChangeLog.diff?cvsroot=gcc&only_with_tag=gcc-3_4-branch&r1=2.2326.2.563&r2=2.2326.2.564 http://gcc.gnu.org/cgi-bin/cvsweb.cgi/gcc/gcc/tree-optimize.c.diff?cvsroot=gcc&only_with_tag=gcc-3_4-branch&r1=2.8.8.5&r2=2.8.8.6 http://gcc.gnu.org/cgi-bin/cvsweb.cgi/gcc/gcc/toplev.c.diff?cvsroot=gcc&only_with_tag=gcc-3_4-branch&r1=1.863.4.10&r2=1.863.4.11 http://gcc.gnu.org/cgi-bin/cvsweb.cgi/gcc/gcc/testsuite/ChangeLog.diff?cvsroot=gcc&only_with_tag=gcc-3_4-branch&r1=1.3389.2.231&r2=1.3389.2.232 http://gcc.gnu.org/cgi-bin/cvsweb.cgi/gcc/gcc/testsuite/gcc.dg/torture/nested-fn-1.c.diff?cvsroot=gcc&only_with_tag=gcc-3_4-branch&r1=NONE&r2=1.1.2.1
Subject: Bug 15345 CVSROOT: /cvs/gcc Module name: gcc Changes by: jakub@gcc.gnu.org 2004-07-21 07:39:09 Modified files: gcc/testsuite : ChangeLog Added files: gcc/testsuite/gcc.dg/torture: nested-fn-1.c Log message: PR middle-end/15345 PR c/16450 * gcc.dg/torture/nested-fn-1.c: New test. Patches: http://gcc.gnu.org/cgi-bin/cvsweb.cgi/gcc/gcc/testsuite/ChangeLog.diff?cvsroot=gcc&r1=1.4029&r2=1.4030 http://gcc.gnu.org/cgi-bin/cvsweb.cgi/gcc/gcc/testsuite/gcc.dg/torture/nested-fn-1.c.diff?cvsroot=gcc&r1=1.1&r2=1.2