15345 – [3.4 Regression] [non-unit-at-a-time] unreferenced nested inline functions not optimized away (original) (raw)
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 Drea 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 Drea 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, otherwisethey 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, otherwisethey 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.