public inbox for gcc-bugs@sourceware.org help / color / mirror / Atom feed
* [Bug c++/53792] New: [C++11][constexpr] improving compiler-time constexpr evaluation @ 2012-06-28 6:59 vincenzo.innocente at cern dot ch 2012-06-28 9:34 ` [Bug c++/53792] " rguenth at gcc dot gnu.org ` (7 more replies) 0 siblings, 8 replies; 9+ messages in thread From: vincenzo.innocente at cern dot ch @ 2012-06-28 6:59 UTC (permalink / raw) To: gcc-bugs http://gcc.gnu.org/bugzilla/show_bug.cgi?id=53792 Bug #: 53792 Summary: [C++11][constexpr] improving compiler-time constexpr evaluation Classification: Unclassified Product: gcc Version: 4.8.0 Status: UNCONFIRMED Severity: enhancement Priority: P3 Component: c++ AssignedTo: unassigned@gcc.gnu.org ReportedBy: vincenzo.innocente@cern.ch Filed under c++ even if it is most probably an optimization issue. At the moment it looks like that constexpr are evaluated at compile time only if explicitly assigned to a constexpr constant. There are cases though where the compiler can infer that the expression can still be evaluated at compile time even if used in a run-time context. Take the following quite realistic example of a consexpr "indexing table" used to access a non-const array using string literals though an inline function. In principle foo and bar are equivalent. At the moment gcc evaluates "getIndex" at compile time for bar (where the marco expansion explicitly instantiates a constexpr int, while it generates runtime code for foo that uses the inlined function getV. Would the compiler be able to transform getV in something like the code in the macro? constexpr entry theMap[] = { {"a", 0}, {"b", 1}, {nullptr,2} }; // filled at run time double v[3]; constexpr bool same(char const *x, char const *y) { return !*x && !*y ? true : (*x == *y && same(x+1, y+1)); } constexpr int getIndex(char const *label, entry const *entries) { return !entries->label ? entries->index : same(entries->label, label) ? entries->index : getIndex(label, entries+1); } inline double __attribute__((always_inline)) getV(const char * name ) { return v[getIndex(name,theMap)]; } #define SetV(X,NAME) \ constexpr int i_##X = getIndex(NAME, theMap);\ const double X = v[i_##X] int foo() { const double a = getV("a"); const double b = getV("b"); if (a==b) return 1; return 0; } int bar() { SetV(a,"a"); SetV(b,"b"); if (a==b) return 1; return 0; } ^ permalink raw reply [flat|nested] 9+ messages in thread
* [Bug c++/53792] [C++11][constexpr] improving compiler-time constexpr evaluation 2012-06-28 6:59 [Bug c++/53792] New: [C++11][constexpr] improving compiler-time constexpr evaluation vincenzo.innocente at cern dot ch @ 2012-06-28 9:34 ` rguenth at gcc dot gnu.org 2012-06-28 11:08 ` vincenzo.innocente at cern dot ch ` (6 subsequent siblings) 7 siblings, 0 replies; 9+ messages in thread From: rguenth at gcc dot gnu.org @ 2012-06-28 9:34 UTC (permalink / raw) To: gcc-bugs http://gcc.gnu.org/bugzilla/show_bug.cgi?id=53792 Richard Guenther <rguenth at gcc dot gnu.org> changed: What |Removed |Added ---------------------------------------------------------------------------- Status|UNCONFIRMED |NEW Last reconfirmed| |2012-06-28 Ever Confirmed|0 |1 --- Comment #1 from Richard Guenther <rguenth at gcc dot gnu.org> 2012-06-28 09:34:20 UTC --- Does the C++ standard require getIndex to be evaluated to a constant in getV? Or is 'constexpr' only telling you that it is required in a context where evaluation to a constant is required (and thus arguments to a constexpr function are constrained)? ^ permalink raw reply [flat|nested] 9+ messages in thread
* [Bug c++/53792] [C++11][constexpr] improving compiler-time constexpr evaluation 2012-06-28 6:59 [Bug c++/53792] New: [C++11][constexpr] improving compiler-time constexpr evaluation vincenzo.innocente at cern dot ch 2012-06-28 9:34 ` [Bug c++/53792] " rguenth at gcc dot gnu.org @ 2012-06-28 11:08 ` vincenzo.innocente at cern dot ch 2012-07-19 14:28 ` jason at gcc dot gnu.org ` (5 subsequent siblings) 7 siblings, 0 replies; 9+ messages in thread From: vincenzo.innocente at cern dot ch @ 2012-06-28 11:08 UTC (permalink / raw) To: gcc-bugs http://gcc.gnu.org/bugzilla/show_bug.cgi?id=53792 --- Comment #2 from vincenzo Innocente <vincenzo.innocente at cern dot ch> 2012-06-28 11:08:38 UTC --- On 28 Jun, 2012, at 11:34 AM, rguenth at gcc dot gnu.org wrote: > http://gcc.gnu.org/bugzilla/show_bug.cgi?id=53792 > > Richard Guenther <rguenth at gcc dot gnu.org> changed: > > What |Removed |Added > ---------------------------------------------------------------------------- > Status|UNCONFIRMED |NEW > Last reconfirmed| |2012-06-28 > Ever Confirmed|0 |1 > > --- Comment #1 from Richard Guenther <rguenth at gcc dot gnu.org> 2012-06-28 09:34:20 UTC --- > Does the C++ standard require getIndex to be evaluated to a constant in getV? No, a constexpr function can be used as a "normal" function. For instance if getV was not inlined the correct behaviour is what we observe > Or is 'constexpr' only telling you that it is required ina context where > evaluation to a constant is required (and thus arguments to a constexpr > function are constrained)? I would say yes (a constant needs to be evaluated using a constexpr function. see page 148-150 (166-168 of my pdf) of the standard (7.1.5 point 3 and following) > My point is that the compiler does not identify that "getIndex" is a constant expression in the context of foo nor in context of the following foo2 that indeed produce (as it should) identical code to foo int foo2() { const double a = v[getIndex("a",theMap)]; const double b = v[getIndex("b",theMap)]; if (a==b) return 1; return 0; } ^ permalink raw reply [flat|nested] 9+ messages in thread
* [Bug c++/53792] [C++11][constexpr] improving compiler-time constexpr evaluation 2012-06-28 6:59 [Bug c++/53792] New: [C++11][constexpr] improving compiler-time constexpr evaluation vincenzo.innocente at cern dot ch 2012-06-28 9:34 ` [Bug c++/53792] " rguenth at gcc dot gnu.org 2012-06-28 11:08 ` vincenzo.innocente at cern dot ch @ 2012-07-19 14:28 ` jason at gcc dot gnu.org 2012-07-27 10:48 ` vincenzo.innocente at cern dot ch ` (4 subsequent siblings) 7 siblings, 0 replies; 9+ messages in thread From: jason at gcc dot gnu.org @ 2012-07-19 14:28 UTC (permalink / raw) To: gcc-bugs http://gcc.gnu.org/bugzilla/show_bug.cgi?id=53792 Jason Merrill <jason at gcc dot gnu.org> changed: What |Removed |Added ---------------------------------------------------------------------------- CC| |jason at gcc dot gnu.org --- Comment #3 from Jason Merrill <jason at gcc dot gnu.org> 2012-07-19 14:27:49 UTC --- Since getV is not constexpr, constexpr doesn't help with optimization of foo, so it relies on inlining. constexpr should help with foo2, however. ^ permalink raw reply [flat|nested] 9+ messages in thread
* [Bug c++/53792] [C++11][constexpr] improving compiler-time constexpr evaluation 2012-06-28 6:59 [Bug c++/53792] New: [C++11][constexpr] improving compiler-time constexpr evaluation vincenzo.innocente at cern dot ch ` (2 preceding siblings ...) 2012-07-19 14:28 ` jason at gcc dot gnu.org @ 2012-07-27 10:48 ` vincenzo.innocente at cern dot ch 2012-07-27 15:06 ` jason at redhat dot com ` (3 subsequent siblings) 7 siblings, 0 replies; 9+ messages in thread From: vincenzo.innocente at cern dot ch @ 2012-07-27 10:48 UTC (permalink / raw) To: gcc-bugs http://gcc.gnu.org/bugzilla/show_bug.cgi?id=53792 --- Comment #4 from vincenzo Innocente <vincenzo.innocente at cern dot ch> 2012-07-27 10:47:49 UTC --- is "__attribute__((always_inline)) " not making foo to transform in foo2 in a very early compiler's stage? I can make getV a macro if helps: I do not like SetV due to its "not natural" syntax ^ permalink raw reply [flat|nested] 9+ messages in thread
* [Bug c++/53792] [C++11][constexpr] improving compiler-time constexpr evaluation 2012-06-28 6:59 [Bug c++/53792] New: [C++11][constexpr] improving compiler-time constexpr evaluation vincenzo.innocente at cern dot ch ` (3 preceding siblings ...) 2012-07-27 10:48 ` vincenzo.innocente at cern dot ch @ 2012-07-27 15:06 ` jason at redhat dot com 2012-08-08 11:18 ` giulio.eulisse at cern dot ch ` (2 subsequent siblings) 7 siblings, 0 replies; 9+ messages in thread From: jason at redhat dot com @ 2012-07-27 15:06 UTC (permalink / raw) To: gcc-bugs http://gcc.gnu.org/bugzilla/show_bug.cgi?id=53792 --- Comment #5 from Jason Merrill <jason at redhat dot com> 2012-07-27 15:06:31 UTC --- On 07/27/2012 06:47 AM, vincenzo.innocente at cern dot ch wrote: > is "__attribute__((always_inline)) " not making foo to transform in foo2 in a > very early compiler's stage? Fairly early, but not as early as constant expression folding. Jason ^ permalink raw reply [flat|nested] 9+ messages in thread
* [Bug c++/53792] [C++11][constexpr] improving compiler-time constexpr evaluation 2012-06-28 6:59 [Bug c++/53792] New: [C++11][constexpr] improving compiler-time constexpr evaluation vincenzo.innocente at cern dot ch ` (4 preceding siblings ...) 2012-07-27 15:06 ` jason at redhat dot com @ 2012-08-08 11:18 ` giulio.eulisse at cern dot ch 2012-08-08 18:19 ` paolo.carlini at oracle dot com 2015-05-06 15:03 ` [Bug c++/53792] [C++11] " balakrishnan.erode at gmail dot com 7 siblings, 0 replies; 9+ messages in thread From: giulio.eulisse at cern dot ch @ 2012-08-08 11:18 UTC (permalink / raw) To: gcc-bugs http://gcc.gnu.org/bugzilla/show_bug.cgi?id=53792 Giulio Eulisse <giulio.eulisse at cern dot ch> changed: What |Removed |Added ---------------------------------------------------------------------------- CC| |giulio.eulisse at cern dot | |ch --- Comment #6 from Giulio Eulisse <giulio.eulisse at cern dot ch> 2012-08-08 11:17:58 UTC --- A simpler testcase for the underlying problem is the following. struct entry { char const* label; int value; }; constexpr bool same(char const *x, char const *y) { return !*x && !*y ? true : /* default */ (*x == *y && same(x+1, y+1)); } constexpr int keyToValue(char const *label, entry const *entries) { return !entries->label ? entries->value : same(entries->label, label) ? entries->value : /*default*/ keyToValue(label, entries+1); } constexpr entry foo[] = {{"Foo", 0}, {"Bar", 1}, {"FooBar", 2}, {0, -1}}; int bar() { /* constexpr */ int result = keyToValue("Foo", foo); // Uncomment constexpr for optimized version. return result; } Without the constexpr the code is fully expanded as if the arguments were generic: 0000000000000000 <_Z3barv>: 0: 53 push %rbx 1: bf 00 00 00 00 mov $0x0,%edi 6: bb 00 00 00 00 mov $0x0,%ebx b: eb 0f jmp 1c <_Z3barv+0x1c> d: 0f 1f 00 nopl (%rax) 10: 48 83 c3 10 add $0x10,%rbx 14: 48 8b 3b mov (%rbx),%rdi 17: 48 85 ff test %rdi,%rdi 1a: 74 1d je 39 <_Z3barv+0x39> 1c: 80 3f 46 cmpb $0x46,(%rdi) 1f: 75 ef jne 10 <_Z3barv+0x10> 21: 80 7f 01 6f cmpb $0x6f,0x1(%rdi) 25: 75 e9 jne 10 <_Z3barv+0x10> 27: 48 83 c7 02 add $0x2,%rdi 2b: be 00 00 00 00 mov $0x0,%esi 30: e8 00 00 00 00 callq 35 <_Z3barv+0x35> 35: 84 c0 test %al,%al 37: 74 d7 je 10 <_Z3barv+0x10> 39: 8b 43 08 mov 0x8(%rbx),%eax 3c: 5b pop %rbx 3d: c3 retq Disassembly of section .text._Z4samePKcS0_: 0000000000000000 <_Z4samePKcS0_>: 0: 0f b6 17 movzbl (%rdi),%edx 3: 84 d2 test %dl,%dl 5: 75 09 jne 10 <_Z4samePKcS0_+0x10> 7: 80 3e 00 cmpb $0x0,(%rsi) a: 0f 94 c0 sete %al d: c3 retq e: 66 90 xchg %ax,%ax 10: 31 c0 xor %eax,%eax 12: 3a 16 cmp (%rsi),%dl 14: 74 0a je 20 <_Z4samePKcS0_+0x20> 16: c3 retq 17: 66 0f 1f 84 00 00 00 nopw 0x0(%rax,%rax,1) 1e: 00 00 20: 0f b6 47 01 movzbl 0x1(%rdi),%eax 24: 84 c0 test %al,%al 26: 75 10 jne 38 <_Z4samePKcS0_+0x38> 28: 80 7e 01 00 cmpb $0x0,0x1(%rsi) 2c: b8 01 00 00 00 mov $0x1,%eax 31: 75 0a jne 3d <_Z4samePKcS0_+0x3d> 33: f3 c3 repz retq 35: 0f 1f 00 nopl (%rax) 38: 3a 46 01 cmp 0x1(%rsi),%al 3b: 74 0b je 48 <_Z4samePKcS0_+0x48> 3d: 31 c0 xor %eax,%eax 3f: 90 nop 40: c3 retq 41: 0f 1f 80 00 00 00 00 nopl 0x0(%rax) 48: 48 83 ec 08 sub $0x8,%rsp 4c: 48 83 c6 02 add $0x2,%rsi 50: 48 83 c7 02 add $0x2,%rdi 54: e8 00 00 00 00 callq 59 <_Z4samePKcS0_+0x59> 59: 84 c0 test %al,%al 5b: 74 10 je 6d <_Z4samePKcS0_+0x6d> 5d: b8 01 00 00 00 mov $0x1,%eax 62: 66 0f 1f 44 00 00 nopw 0x0(%rax,%rax,1) 68: 48 83 c4 08 add $0x8,%rsp 6c: c3 retq 6d: 31 c0 xor %eax,%eax 6f: eb f7 jmp 68 <_Z4samePKcS0_+0x68> while with constexpr on results everything is optimized out: 0000000000000000 <_Z3barv>: 0: 31 c0 xor %eax,%eax 2: c3 retq ^ permalink raw reply [flat|nested] 9+ messages in thread
* [Bug c++/53792] [C++11][constexpr] improving compiler-time constexpr evaluation 2012-06-28 6:59 [Bug c++/53792] New: [C++11][constexpr] improving compiler-time constexpr evaluation vincenzo.innocente at cern dot ch ` (5 preceding siblings ...) 2012-08-08 11:18 ` giulio.eulisse at cern dot ch @ 2012-08-08 18:19 ` paolo.carlini at oracle dot com 2015-05-06 15:03 ` [Bug c++/53792] [C++11] " balakrishnan.erode at gmail dot com 7 siblings, 0 replies; 9+ messages in thread From: paolo.carlini at oracle dot com @ 2012-08-08 18:19 UTC (permalink / raw) To: gcc-bugs http://gcc.gnu.org/bugzilla/show_bug.cgi?id=53792 --- Comment #7 from Paolo Carlini <paolo.carlini at oracle dot com> 2012-08-08 18:18:51 UTC --- Thanks Giulio! ^ permalink raw reply [flat|nested] 9+ messages in thread
* [Bug c++/53792] [C++11] improving compiler-time constexpr evaluation 2012-06-28 6:59 [Bug c++/53792] New: [C++11][constexpr] improving compiler-time constexpr evaluation vincenzo.innocente at cern dot ch ` (6 preceding siblings ...) 2012-08-08 18:19 ` paolo.carlini at oracle dot com @ 2015-05-06 15:03 ` balakrishnan.erode at gmail dot com 7 siblings, 0 replies; 9+ messages in thread From: balakrishnan.erode at gmail dot com @ 2015-05-06 15:03 UTC (permalink / raw) To: gcc-bugs https://gcc.gnu.org/bugzilla/show_bug.cgi?id=53792 Balakrishnan B <balakrishnan.erode at gmail dot com> changed: What |Removed |Added ---------------------------------------------------------------------------- CC| |balakrishnan.erode at gmail dot co | |m --- Comment #8 from Balakrishnan B <balakrishnan.erode at gmail dot com> --- Another testcase with c++14 extended constexpr (i.e supports loops and more than one statement). Code: template<class T> void sink(T); constexpr unsigned foo(){ unsigned i = 1; while((i<<1) > i){ i = i<<1; } return i; } template<unsigned i> struct Foo { }; void bar(){ sink(foo()); sink(Foo<foo()>{}); } Assembly for bar: clang3.5.1 -O3 -std=c++14 bar(): # @bar() pushq %rax movl $-2147483648, %edi # imm = 0xFFFFFFFF80000000 callq void sink<unsigned int>(unsigned int) popq %rax jmp void sink<Foo<2147483648u> >(Foo<2147483648u>) # TAILCALL gcc5.1.0 -O3 -std=c++14 bar(): movl $32, %eax movl $1, %edi jmp .L2 .L3: movl %edx, %edi .L2: subl $1, %eax leal (%rdi,%rdi), %edx jne .L3 subq $8, %rsp call void sink<unsigned int>(unsigned int) subq $8, %rsp pushq $0 call void sink<Foo<2147483648u> >(Foo<2147483648u>) addq $24, %rsp ret Live demo: http://goo.gl/b56Q5k ^ permalink raw reply [flat|nested] 9+ messages in thread
end of thread, other threads:[~2015-05-06 15:03 UTC | newest] Thread overview: 9+ messages (download: mbox.gz / follow: Atom feed) -- links below jump to the message on this page -- 2012-06-28 6:59 [Bug c++/53792] New: [C++11][constexpr] improving compiler-time constexpr evaluation vincenzo.innocente at cern dot ch 2012-06-28 9:34 ` [Bug c++/53792] " rguenth at gcc dot gnu.org 2012-06-28 11:08 ` vincenzo.innocente at cern dot ch 2012-07-19 14:28 ` jason at gcc dot gnu.org 2012-07-27 10:48 ` vincenzo.innocente at cern dot ch 2012-07-27 15:06 ` jason at redhat dot com 2012-08-08 11:18 ` giulio.eulisse at cern dot ch 2012-08-08 18:19 ` paolo.carlini at oracle dot com 2015-05-06 15:03 ` [Bug c++/53792] [C++11] " balakrishnan.erode at gmail dot com
This is a public inbox, see mirroring instructions for how to clone and mirror all data and code used for this inbox; as well as URLs for read-only IMAP folder(s) and NNTP newsgroup(s).