[Bug c++/85747] suboptimal code without constexpr
https://gcc.gnu.org/bugzilla/show_bug.cgi?id=85747 --- Comment #12 from Andrew Pinski --- *** Bug 89922 has been marked as a duplicate of this bug. ***
[Bug c++/85747] suboptimal code without constexpr
https://gcc.gnu.org/bugzilla/show_bug.cgi?id=85747 Andrew Pinski changed: What|Removed |Added CC||eyalroz1 at gmx dot com --- Comment #11 from Andrew Pinski --- *** Bug 87543 has been marked as a duplicate of this bug. ***
[Bug c++/85747] suboptimal code without constexpr
https://gcc.gnu.org/bugzilla/show_bug.cgi?id=85747 Andrew Pinski changed: What|Removed |Added CC||bmburstein at gmail dot com --- Comment #10 from Andrew Pinski --- *** Bug 97077 has been marked as a duplicate of this bug. ***
[Bug c++/85747] suboptimal code without constexpr
https://gcc.gnu.org/bugzilla/show_bug.cgi?id=85747 Andrew Pinski changed: What|Removed |Added Last reconfirmed||2021-12-27 Severity|normal |enhancement Ever confirmed|0 |1 Status|UNCONFIRMED |NEW --- Comment #9 from Andrew Pinski --- size: 13-3, last_iteration: 13-3 Loop size: 13 Estimated size after unrolling: 40 Not unrolling loop 1: it is not innermost and code would grow. There are a few others like this one. Note LLVM is able even to handle: template constexpr void sort(It first, It last) { for (;first != last; ++first) { auto it = first; ++it; for (; it != last; ++it) { if (*it < *first) { auto tmp = *it; *it = *first; *first = tmp; } } } } static int generate() { int a[] = {0,1,2,3,4,5,6,7,8,9,10,11,12,13,14,15,16,17,18,19,20,21}; a[5] = 55; sort(a + 0, a + 21); return a[0] + a[6] + a[1] + a[2] + a[3] + a[4]; } I suspect the cost estimate it does for the loop is the removal of the load of a[i] knowing that a is fully written to.
[Bug c++/85747] suboptimal code without constexpr
https://gcc.gnu.org/bugzilla/show_bug.cgi?id=85747 Alexander Zaitsev changed: What|Removed |Added CC||zamazan4ik at tut dot by --- Comment #8 from Alexander Zaitsev --- (In reply to Marc Glisse from comment #5) > (In reply to Antony Polukhin from comment #4) > > Does providing some kind of -Oon-the-fly switch solves the issue with JIT > > compile times while still allows more optimizations for the traditional non > > JIT -O2 builds? > > Not sure what you mean by -Oon-the-fly. If you want to JIT compile the code, > you more or less need to embed a compiler in the executable... > > The closest I can think of is -fprofile-values. It is possible to collect > the values of constants during a training run and use them during a second > compilation. But then knowing more constants in one compilation than the > other may change the code in ways that the PGO framework will not like. As I understand Anthony meant here some compiler option which allows to compiler some "aggresive" mode for detecting code which can be calculated at compile-time as much as possible, even if it will increase significantly compilation time. Of course this flag must be disabled by default even with -O3
[Bug c++/85747] suboptimal code without constexpr
https://gcc.gnu.org/bugzilla/show_bug.cgi?id=85747 --- Comment #7 from Antony Polukhin --- (In reply to Jakub Jelinek from comment #6) > IMHO just use constexpr if you care about compile time evaluation > guarantees, that is what it has been added for. Fair point. Overcomplicated logic on the frontend does not seem right. But from my (not experienced) point of view there are some low hanging fruits here. I assume that frontend uses some kind of `__builtin_constant_p` to distinguish between constexpr evaluation or not. Adjusting that function slightly could produce better code out of the box on some optimization levels: static int generate() { int a[7] = {3, 7, 4, 2, 8, 0, 1}; static_assert( __builtin_constant_p(a + 0), "Immediate usage of variable initialized by constant should be a constant expression" ); sort(a + 0, a + 7); // __builtin_constant_p returns `true` => constexpr call static_assert( __builtin_constant_p(a + 0), "Value after constexpr function call should be a constant" ); return a[0] + a[6]; }
[Bug c++/85747] suboptimal code without constexpr
https://gcc.gnu.org/bugzilla/show_bug.cgi?id=85747 Jakub Jelinek changed: What|Removed |Added CC||jakub at gcc dot gnu.org --- Comment #6 from Jakub Jelinek --- IMHO just use constexpr if you care about compile time evaluation guarantees, that is what it has been added for.
[Bug c++/85747] suboptimal code without constexpr
https://gcc.gnu.org/bugzilla/show_bug.cgi?id=85747 --- Comment #5 from Marc Glisse --- (In reply to Antony Polukhin from comment #4) > Does providing some kind of -Oon-the-fly switch solves the issue with JIT > compile times while still allows more optimizations for the traditional non > JIT -O2 builds? Not sure what you mean by -Oon-the-fly. If you want to JIT compile the code, you more or less need to embed a compiler in the executable... The closest I can think of is -fprofile-values. It is possible to collect the values of constants during a training run and use them during a second compilation. But then knowing more constants in one compilation than the other may change the code in ways that the PGO framework will not like.
[Bug c++/85747] suboptimal code without constexpr
https://gcc.gnu.org/bugzilla/show_bug.cgi?id=85747 --- Comment #4 from Antony Polukhin --- (In reply to Marc Glisse from comment #2) > (In reply to Antony Polukhin from comment #0) > > Could the compiler detect that `a[7]` holds values known at compile time and > > force the constexpr on `sort(a + 0, a + 7);`? > > There has to be a limit. If I write a program that computes the trillion's > decimal of pi, this is a constant, do you expect the compiler to evaluate > the whole program and compile it to just return cst? We are moving into a > realm where we would want to mix compilation and execution, sort of JIT. > For smaller functions, some heuristics could be used to try compile-time > evaluation, but sorting an array of size 7 already seems large to me. Does providing some kind of -Oon-the-fly switch solves the issue with JIT compile times while still allows more optimizations for the traditional non JIT -O2 builds?
[Bug c++/85747] suboptimal code without constexpr
https://gcc.gnu.org/bugzilla/show_bug.cgi?id=85747 --- Comment #3 from Antony Polukhin --- (In reply to Richard Biener from comment #1) > What's the reason for writing the code as you pasted it? I've tried to provide a simplified case. In real world `generate()` function will have some arguments and depending on those it could be either constexpr evaluated or not. There's plenty of pre C++14 code that is not well maintained and does not use constexpr a lot, but functions could be treated and evaluated as constexpr in C++14. Main reason for this ticket - is to have some out-of-the-box speedup for such legacy code. Function without arguments seemed to be a good place to start.
[Bug c++/85747] suboptimal code without constexpr
https://gcc.gnu.org/bugzilla/show_bug.cgi?id=85747 --- Comment #2 from Marc Glisse --- (In reply to Antony Polukhin from comment #0) > Could the compiler detect that `a[7]` holds values known at compile time and > force the constexpr on `sort(a + 0, a + 7);`? There has to be a limit. If I write a program that computes the trillion's decimal of pi, this is a constant, do you expect the compiler to evaluate the whole program and compile it to just return cst? We are moving into a realm where we would want to mix compilation and execution, sort of JIT. For smaller functions, some heuristics could be used to try compile-time evaluation, but sorting an array of size 7 already seems large to me. > Could the compiler detect that > the function `generate()` is an `__attribute__((const))` function without > arguments and fully evaluate it's body? If you call the function twice in a row, the compiler removes the second call and reuses the result from the first, so at least it notices that generate is pure.
[Bug c++/85747] suboptimal code without constexpr
https://gcc.gnu.org/bugzilla/show_bug.cgi?id=85747 Richard Biener changed: What|Removed |Added CC||rguenth at gcc dot gnu.org --- Comment #1 from Richard Biener --- Well. Besides of the C++ frontend the compiler has no facility to fully evaluate a part of a program but for cases like this it would rely on inlining then unrolling and then constant propagation. All this work has limits and heuristics and there are just cases where the heuristics need to give up... What's the reason for writing the code as you pasted it? Note that sort isn't a const function since it modifies global memory.