Bug 20912 - C++ FE emitting assignments to read-only global symbols
Summary: C++ FE emitting assignments to read-only global symbols
Status: RESOLVED WONTFIX
Alias: None
Product: gcc
Classification: Unclassified
Component: c++ (show other bugs)
Version: 4.1.0
: P2 normal
Target Milestone: ---
Assignee: Mark Mitchell
URL:
Keywords: missed-optimization, wrong-code
Depends on: 21089
Blocks: 23777 31809
  Show dependency treegraph
 
Reported: 2005-04-09 01:51 UTC by Diego Novillo
Modified: 2007-05-04 01:30 UTC (History)
5 users (show)

See Also:
Host:
Target:
Build:
Known to work:
Known to fail:
Last reconfirmed: 2005-09-12 15:26:37


Attachments
Proposed patch (676 bytes, patch)
2005-10-11 21:06 UTC, Mark Mitchell
Details | Diff

Note You need to log in before you can comment on or make changes to this bug.
Description Diego Novillo 2005-04-09 01:51:43 UTC
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);
Comment 1 Andrew Pinski 2005-04-09 12:48:41 UTC
Confirmed.
Comment 2 Paul Schlie 2005-04-14 21:28:55 UTC
(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?
Comment 3 Andrew Pinski 2005-04-18 17:56:33 UTC
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.
Comment 4 Paul Schlie 2005-04-18 19:29:02 UTC
(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).
Comment 5 Andrew Pinski 2005-07-18 01:37:49 UTC
I wonder if this is the recent regression in eon again.
Comment 6 Mark Mitchell 2005-10-11 21:06:39 UTC
Created attachment 9973 [details]
Proposed patch
Comment 7 Mark Mitchell 2005-10-11 21:07:17 UTC
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?
Comment 8 Diego Novillo 2005-10-12 14:16:44 UTC
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).
Comment 9 Mark Mitchell 2005-10-12 14:55:43 UTC
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.)

Comment 10 Diego Novillo 2005-10-12 15:00:14 UTC
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.
Comment 11 Andrew Pinski 2005-10-28 18:25:05 UTC
Right now after fixing this and PR 23777 should become fixed.
Comment 12 Steven Bosscher 2007-02-03 18:35:58 UTC
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?
Comment 13 Mark Mitchell 2007-02-05 03:18:45 UTC
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,

Comment 14 Steven Bosscher 2007-02-05 22:30:10 UTC
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.
Comment 15 Steven Bosscher 2007-02-05 22:46:01 UTC
Closing as DONTCARE, by request from Diego :-)
Comment 16 Richard Biener 2007-02-05 22:51:05 UTC
Reopen ...
Comment 17 Richard Biener 2007-02-05 22:51:25 UTC
... to mark as WONTFIX.
Comment 18 Paul Schlie 2007-02-07 00:56:20 UTC
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.


Comment 19 Andrew Pinski 2007-05-04 01:30:22 UTC
One more case where C++ front-end is doing this still is located in PR 31809.