Bug 50087 - [C++0x] Weird optimization anomaly with constexpr
Summary: [C++0x] Weird optimization anomaly with constexpr
Status: NEW
Alias: None
Product: gcc
Classification: Unclassified
Component: c++ (show other bugs)
Version: 4.6.1
: P3 normal
Target Milestone: ---
Assignee: Not yet assigned to anyone
URL:
Keywords: missed-optimization
Depends on:
Blocks: constexpr
  Show dependency treegraph
 
Reported: 2011-08-15 12:48 UTC by eric-gcc
Modified: 2024-08-19 15:20 UTC (History)
3 users (show)

See Also:
Host:
Target:
Build:
Known to work:
Known to fail:
Last reconfirmed: 2011-08-16 00:00:00


Attachments
runs_too_long runs in a very short period of time (141 bytes, text/plain)
2011-08-15 12:48 UTC, eric-gcc
Details
The function 'runs_too_long' takes basically forever (123 bytes, text/plain)
2011-08-15 12:49 UTC, eric-gcc
Details

Note You need to log in before you can comment on or make changes to this bug.
Description eric-gcc 2011-08-15 12:48:17 UTC
Created attachment 25014 [details]
runs_too_long runs in a very short period of time

I have two nearly identical programs. In one (small.joe.cpp), a function called 'runs_too_long' does not run too long. It is compiled down to returning a constant value.

In another, very slightly different program (small-nojoe.cpp), the function 'runs_too_long' does indeed run too long. It, in fact will not complete in any reasonable length of time.
Comment 1 eric-gcc 2011-08-15 12:49:16 UTC
Created attachment 25015 [details]
The function 'runs_too_long' takes basically forever
Comment 2 Paolo Carlini 2011-08-15 13:36:33 UTC
I can't reproduce this. Maybe Jason wants to double check.
Comment 3 Jason Merrill 2011-08-16 21:38:01 UTC
This is more or less expected behavior.  Since a const variable declaration has different semantics depending on whether or not the initializer is a constant-expression, a compiler needs to find a constant value if there is one.  So we do, and joe is initialized with that constant value.

But in the second testcase, there is no semantic constraint on whether or not the call fib(92) is a constant-expression, so we don't try to reduce it to a constant, assuming that normal optimization can do just as well.

But for whatever reason, in this case normal optimization isn't doing as well as constexpr evaluation can.
Comment 4 Paolo Carlini 2011-08-16 21:48:59 UTC
(for the record: I somehow wrongly understood long, "forever" *compile*-time)
Comment 5 eric-bugs 2011-09-02 20:57:45 UTC
I thought that perhaps it was expected behavior. I still think it's a missed optimization opportunity. A call of a constexpr function can clearly, in all cases, be reduced to a constant expression if the arguments are also constant expressions. So it seems like the optimizer should do this if it can.

But it isn't a 'bug' exactly, just more of a 'it could do this better'.
Comment 6 Jason Merrill 2011-09-03 00:48:25 UTC
(In reply to comment #5)
> I still think it's a missed optimization opportunity.

Yes, it definitely is.  I'm just not sure whether it should be fixed by doing constexpr expansion in non-constant expression contexts in some cases, or improving normal optimization to handle this case.
Comment 7 eric-gcc 2011-09-13 22:15:16 UTC
(In reply to comment #6)
> (In reply to comment #5)
> > I still think it's a missed optimization opportunity.
> 
> Yes, it definitely is.  I'm just not sure whether it should be fixed by doing
> constexpr expansion in non-constant expression contexts in some cases, or
> improving normal optimization to handle this case.

That's an interesting question. I think improving normal optimization to handle this case might prove to be rather tricky. It would basically require detecting that a function could be constexpr even if it wasn't declared that way. Otherwise, a deep recursion case like this is really a pain to deal with at optimization time.

I can think of cases where I have created templates for finding GCDs (using Euclid's algorithm), integer logarithms and integer exponents at compile time that are not toy problems. GCDs in particular are at least is tricky as the silly bad recursive Fibonacci number generator.

Of course, I'm only guessing. Compilers and optimizers are not my thing. It just seems like using the constexpr logic in some cases would be a lot easier.