One of the micro-optimizations that may be done inside the tree optimizer involves disregarding V_MAY_DEF/V_MUST_DEF operands for read-only globals. So, if a symbol is marked read-only and the operand scanner requests a V_MAY_DEF or V_MUST_DEF operand for it, we replace it with a VUSE. This works fine, except that I was having comparison errors with SPEC2000's eon. I tracked it down to the C++ FE emitting an assignment instruction for a global const variable. The source code declares const double ggPi = 3.14159265358979323846; double const divPi = 1 / ggPi; And since divPi is initialized to an expression, I guess it needs to compute it at runtime, so it emits an initialization function: void __static_initialization_and_destruction_0(int, int) (__initialize_p, __priority) { ... if (D.55019) { ggPi.319 = ggPi; D.55021 = 1.0e+0 / ggPi.319; divPi = D.55021; } ... } So, we now have an assignment for divPi in the IL stream. This throws a monkey wrench into this micro-optimization because it shouldn't really have ignored that V_MUST_DEF (the tree optimizers end up removing the assignment). This optimization is currently disabled because of this. If the C++ FE is fixed to address this problem, the following patch will re-enable the optimization: --- tree-ssa-operands.c 9 Apr 2005 01:37:24 -0000 2.75 +++ tree-ssa-operands.c 9 Apr 2005 01:51:02 -0000 @@ -1803,14 +1803,8 @@ add_stmt_operand (tree *var_p, stmt_ann_ it into a VUSE. This happens when read-only variables are marked call-clobbered and/or aliased to writeable variables. So we only check that this only happens on stores, and not writes to GIMPLE - registers. - - FIXME: The C++ FE is emitting assignments in the IL stream for - read-only globals. This is wrong, but for the time being disable - this transformation on V_MUST_DEF operands (otherwise, we - mis-optimize SPEC2000's eon). */ + registers. */ if ((flags & opf_is_def) - && !(flags & opf_kill_def) && unmodifiable_var_p (var)) { gcc_assert (!is_real_op);
Confirmed.
(In reply to comment #0) I guess I misunderstand the problem, as given: const double ggPi = 3.14159265358979323846; double const divPi = 1 / ggPi; It would seem that neither ggPi or divPI should be designated "unchanging" at the tree/rtl level, as neither are global static const objects, although: 3.14159265358979323846 is, if stored as a value; as opposed to being inlined in the code as an immediate. ggPi and divPi are simply variables which are initialized with values at runtime; where the fact that they're "const" has prevented an assignment (other than an initializing one) being accepted as valid during semantic analysis. Where post semantic analysis, they're just variables just like any others which happen to have no assignments specified post initialization (as enforced by the front end); so should not be marked READONLY/unchanging to begin with, it would seem?
Simple code which shows we now have a missed optimization: static const double a = 1.0; static const double b = a+1.0; double c() { return b; } See PR 21089.
(In reply to comment #3) > Simple code which shows we now have a missed optimization: > static const double a = 1.0; > static const double b = a+1.0; > > double c() > { > return b; > } > > See PR 21089. I believe the optimization necessitates the variable's declaration be changed (either explicitly, or by implication): static const double b = a+1.0; => const double b = a+1.0; If it's static-const value can't be pre-computed at compile time. (as opposed to allowing a non-const-literal value to initialize a global static const object).
I wonder if this is the recent regression in eon again.
Created attachment 9973 [details] Proposed patch
I believe the patch attached will fix the problem. Diego, will this allow you to reactivate your optimization? And, if so, what kind of code will be improved?
Subject: Re: C++ FE emitting assignments to read-only global symbols On Tuesday 11 October 2005 17:07, mmitchel at gcc dot gnu dot org wrote: > Diego, will this allow you to reactivate your optimization? And, if so, > what kind of code will be improved? > Thanks Mark. The underlying code has shifted in the interim. There was another bug that would cause us to ICE with code that specifically casted away constness. We now should get this micro-optimization on the cases we cared for (call-clobbering situations, mostly).
Subject: Re: C++ FE emitting assignments to read-only global symbols dnovillo at redhat dot com wrote: > Thanks Mark. The underlying code has shifted in the interim. There was > another bug that would cause us to ICE with code that specifically casted > away constness. We now should get this micro-optimization on the cases we > cared for (call-clobbering situations, mostly). OK, so my patch is no longer directly useful then? (It still seems like it would be an improvement in the abstract, in that assigning to TREE_READONLY variables is evil, but if it won't have any immediate tangible benefit, I'll leave this for 4.2.)
Subject: Re: C++ FE emitting assignments to read-only global symbols On Wednesday 12 October 2005 10:55, mark at codesourcery dot com wrote: > OK, so my patch is no longer directly useful then? (It still seems like > it would be an improvement in the abstract, in that assigning to > TREE_READONLY variables is evil, but if it won't have any immediate > tangible benefit, I'll leave this for 4.2.) > Leaving it for 4.2 should be fine. It is only a micro-optimization and I only noticed it by chance because we were being too aggressive with it. Yes, it's nice to stop the FE from generating stores to TREE_READONLY, but it's not the end of the world for 4.1. Thanks.
Right now after fixing this and PR 23777 should become fixed.
Mark was going to leave this for GCC 4.2, but hasn't fixed this for GCC 4.2 yet, either. What's going to happen with this bug?
Subject: Re: C++ FE emitting assignments to read-only global symbols steven at gcc dot gnu dot org wrote: > Mark was going to leave this for GCC 4.2, but hasn't fixed this for GCC 4.2 > yet, either. What's going to happen with this bug? After Diego's comments, it didn't sound like it was still important to fix it. Does the patch in Comment #6 still apply? It looks like to me as if it would (at least in principle; the code affected still looks the same). If so, it's OK to apply to mainline, assuming test results go OK. Would you like to test it? If that fix will also fix PR 23777, then the same fix is also OK for 4.2. If not, then is there any compelling reason to apply it to 4.2? Thanks,
I don't think there is a compelling reason to have the patch in GCC 4.2. But it would still be nice to get this out of the way, to reduce the number of VOPs a bit further. I have updated the patch of comment #6 and I'll test it (on x86_64/i686) somewhen later this week.
Closing as DONTCARE, by request from Diego :-)
Reopen ...
... to mark as WONTFIX.
Subject: Re: C++ FE emitting assignments to read-only global symbols for 4.3? > From: rguenth at gcc dot gnu dot org <gcc-bugzilla@gcc.gnu.org> > Reply-To: <gcc-bugzilla@gcc.gnu.org> > Date: 5 Feb 2007 22:51:25 -0000 > To: <schlie@comcast.net> > Subject: [Bug c++/20912] C++ FE emitting assignments to read-only global > symbols > > > > ------- Comment #17 from rguenth at gcc dot gnu dot org 2007-02-05 22:51 > ------- > ... to mark as WONTFIX. > > > -- > > rguenth at gcc dot gnu dot org changed: > > What |Removed |Added > ---------------------------------------------------------------------------- > Status|REOPENED |RESOLVED > Resolution| |WONTFIX > > > http://gcc.gnu.org/bugzilla/show_bug.cgi?id=20912 > > ------- You are receiving this mail because: ------- > You are on the CC list for the bug, or are watching someone who is.
One more case where C++ front-end is doing this still is located in PR 31809.