Bug 15345 - [3.4 Regression] [non-unit-at-a-time] unreferenced nested inline functions not optimized away
Summary: [3.4 Regression] [non-unit-at-a-time] unreferenced nested inline functions no...
Status: RESOLVED FIXED
Alias: None
Product: gcc
Classification: Unclassified
Component: middle-end (show other bugs)
Version: 3.4.0
: P2 normal
Target Milestone: 3.4.2
Assignee: Not yet assigned to anyone
URL:
Keywords: missed-optimization
: 16450 (view as bug list)
Depends on:
Blocks:
 
Reported: 2004-05-09 17:26 UTC by dank
Modified: 2004-10-30 21:11 UTC (History)
3 users (show)

See Also:
Host:
Target:
Build:
Known to work: tree-ssa 3.3.3 4.0.0 3.4.2
Known to fail: 3.4.0 4.0.0
Last reconfirmed: 2004-05-09 18:59:11


Attachments

Note You need to log in before you can comment on or make changes to this bug.
Description dank 2004-05-09 17:26:07 UTC
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.
Comment 1 Andrew Pinski 2004-05-09 18:59:10 UTC
Confirmed, fixed already on the tree-ssa.  I do not know if this will get fixed for 3.4.1 at all.
Comment 2 Mark Mitchell 2004-05-31 22:14:11 UTC
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?
Comment 3 Mark Mitchell 2004-06-12 22:05:25 UTC
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.
Comment 4 Jan Hubicka 2004-06-13 14:13:02 UTC
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
Comment 5 Jan Hubicka 2004-06-21 17:47:24 UTC
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
Comment 6 Mark Mitchell 2004-06-21 21:22:46 UTC
Fixed in GCC 3.5; won't be fixed in GCC 3.4.x.
Comment 7 Andrew Pinski 2004-07-09 16:48:27 UTC
*** Bug 16450 has been marked as a duplicate of this bug. ***
Comment 8 Jakub Jelinek 2004-07-19 14:11:46 UTC
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?
Comment 9 Jan Hubicka 2004-07-19 15:43:56 UTC
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.
Comment 10 CVS Commits 2004-07-21 07:37:22 UTC
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

Comment 11 CVS Commits 2004-07-21 07:39:13 UTC
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