[Bug middle-end/20408] Unnecessary code generated for empty structs
https://gcc.gnu.org/bugzilla/show_bug.cgi?id=20408 --- Comment #25 from CVS Commits --- The releases/gcc-10 branch has been updated by Jason Merrill : https://gcc.gnu.org/g:031e97207463710797625382baff112b6c3ade51 commit r10-9362-g031e97207463710797625382baff112b6c3ade51 Author: Jason Merrill Date: Mon Feb 8 17:04:03 2021 -0500 c++: generic lambda, fn* conv, empty class [PR98326] Here, in the thunk returned from the captureless lambda conversion to pointer-to-function, we try to pass through invisible reference parameters by reference, without doing a copy. The empty class copy optimization was messing that up. gcc/cp/ChangeLog: PR c++/98326 PR c++/20408 * cp-gimplify.c (simple_empty_class_p): Don't touch an invisiref parm. gcc/testsuite/ChangeLog: PR c++/98326 * g++.dg/cpp1y/lambda-generic-empty1.C: New test.
[Bug middle-end/20408] Unnecessary code generated for empty structs
https://gcc.gnu.org/bugzilla/show_bug.cgi?id=20408 --- Comment #24 from CVS Commits --- The master branch has been updated by Jason Merrill : https://gcc.gnu.org/g:bdbca69e0720fa9062fe71782235141f629ae006 commit r11-7142-gbdbca69e0720fa9062fe71782235141f629ae006 Author: Jason Merrill Date: Mon Feb 8 17:04:03 2021 -0500 c++: generic lambda, fn* conv, empty class [PR98326] Here, in the thunk returned from the captureless lambda conversion to pointer-to-function, we try to pass through invisible reference parameters by reference, without doing a copy. The empty class copy optimization was messing that up. gcc/cp/ChangeLog: PR c++/98326 PR c++/20408 * cp-gimplify.c (simple_empty_class_p): Don't touch an invisiref parm. gcc/testsuite/ChangeLog: PR c++/98326 * g++.dg/cpp1y/lambda-generic-empty1.C: New test.
[Bug middle-end/20408] Unnecessary code generated for empty structs
https://gcc.gnu.org/bugzilla/show_bug.cgi?id=20408 Jason Merrill changed: What|Removed |Added Target Milestone|--- |10.0 Resolution|--- |FIXED Status|ASSIGNED|RESOLVED --- Comment #23 from Jason Merrill --- Fixed in GCC 10.
[Bug middle-end/20408] Unnecessary code generated for empty structs
https://gcc.gnu.org/bugzilla/show_bug.cgi?id=20408 --- Comment #22 from Jason Merrill --- Author: jason Date: Wed May 22 21:39:08 2019 New Revision: 271523 URL: https://gcc.gnu.org/viewcvs?rev=271523=gcc=rev Log: PR c++/20408 - unnecessary code for empty struct. Here initializing the argument from a TARGET_EXPR isn't an empty class copy even though the type is !TREE_ADDRESSABLE, so we should check simple_empty_class_p. * call.c (build_call_a): Use simple_empty_class_p. Added: trunk/gcc/testsuite/g++.dg/tree-ssa/empty-3.C Modified: trunk/gcc/cp/ChangeLog trunk/gcc/cp/call.c trunk/gcc/cp/cp-gimplify.c trunk/gcc/cp/cp-tree.h
[Bug middle-end/20408] Unnecessary code generated for empty structs
https://gcc.gnu.org/bugzilla/show_bug.cgi?id=20408 Jason Merrill changed: What|Removed |Added Status|NEW |ASSIGNED Assignee|unassigned at gcc dot gnu.org |jason at gcc dot gnu.org --- Comment #21 from Jason Merrill --- Created attachment 45900 --> https://gcc.gnu.org/bugzilla/attachment.cgi?id=45900=edit fix Patch waiting for stage 1.
[Bug middle-end/20408] Unnecessary code generated for empty structs
--- Comment #20 from rguenth at gcc dot gnu dot org 2007-11-27 09:40 --- For the testcase in comment #13 we now generate two(!) temporaries: void barc() () { struct Foo D.2027; struct Foo D.2028; D.2027 = {}; D.2028 = {}; bar (D.2028); } via gimplification of ;; Function void barc() (_Z4barcv) ;; enabled by -tree-original cleanup_point Unknown tree: expr_stmt bar (TARGET_EXPR D.2027, {};, Unknown tree: empty_class_expr ;) ; though the generated assembler looks like we cannot do better: _Z4barcv: .LFB3: subq$8, %rsp .LCFI0: movb$0, (%rsp) call_Z3bar3Foo addq$8, %rsp ret _Z4foocv: .LFB2: subq$24, %rsp .LCFI1: leaq23(%rsp), %rdi call_Z3fooRK3Foo addq$24, %rsp ret On the tree level the first simple DSE pass gets rid of the extra temporary and its initialization. -- rguenth at gcc dot gnu dot org changed: What|Removed |Added Status|WAITING |NEW Last reconfirmed|2005-12-09 04:25:06 |2007-11-27 09:40:15 date|| http://gcc.gnu.org/bugzilla/show_bug.cgi?id=20408
[Bug middle-end/20408] Unnecessary code generated for empty structs
--- Comment #19 from steven at gcc dot gnu dot org 2007-11-26 14:17 --- The recent improvements to the dataflow module and ra-conflicts may have fixed this. Richi, you were the last to look at this bug report. Can you check if there still is an issue to fix here? -- steven at gcc dot gnu dot org changed: What|Removed |Added CC||rguenth at gcc dot gnu dot ||org Status|NEW |WAITING http://gcc.gnu.org/bugzilla/show_bug.cgi?id=20408
[Bug middle-end/20408] Unnecessary code generated for empty structs
--- Additional Comments From rguenth at gcc dot gnu dot org 2005-09-05 10:36 --- Pinskias patch fixes one part of the problem. For x86 there remains the issue that we are passing X on the stack and generate _Z8call_foov: .LFB2: subl$26, %esp .LCFI4: pushw %ax .LCFI5: .LCFI6: call_Z3foo1X addl$28, %esp ret which is correct, but I wonder where we figure out to use %ax as source for the tmp X. Also no RTL optimizer sees that the pushw %ax can be safely combined with the stack adjust before because the contents of %ax are unknown and we don't care about what value we pass on the stack. The call expander produces (insn 9 8 10 1 (parallel [ (set (reg/f:SI 7 sp) (plus:SI (reg/f:SI 7 sp) (const_int -2 [0xfffe]))) (clobber (reg:CC 17 flags)) ]) -1 (nil) (nil)) (insn 10 9 11 1 (set (mem/s:QI (pre_modify:SI (reg/f:SI 7 sp) (plus:SI (reg/f:SI 7 sp) (const_int -2 [0xfffe]))) [0 S1 A8]) (reg:QI 58 [ D.1755 ])) -1 (nil) (nil)) (call_insn 11 10 12 1 (call (mem:QI (symbol_ref:SI (_Z3foo1X) [flags 0x41] function_decl 0x40230e00 foo) [0 S1 A8]) (const_int 16 [0x10])) -1 (nil) (nil) (nil)) where it should not use reg 58 as the source to push, but rather the stack slot we assigned to the D.1755 tmp. -- http://gcc.gnu.org/bugzilla/show_bug.cgi?id=20408
[Bug middle-end/20408] Unnecessary code generated for empty structs
--- Additional Comments From rguenth at gcc dot gnu dot org 2005-09-05 10:48 --- Unfortunately we start with D.1755 allocated to a register. This may be solved at the tree level if we fix PR23372. Or we need to be smarter at allocating space for D.1755. -- http://gcc.gnu.org/bugzilla/show_bug.cgi?id=20408
[Bug middle-end/20408] Unnecessary code generated for empty structs
--- Additional Comments From rguenth at gcc dot gnu dot org 2005-09-05 12:38 --- Life analysis should figure out, that for (insn 10 9 11 1 (set (mem/s:QI (pre_modify:SI (reg/f:SI 7 sp) (plus:SI (reg/f:SI 7 sp) (const_int -2 [0xfffe]))) [0 S1 A8]) (reg:QI 58 [ D.1755 ])) -1 (nil) (nil)) where it notes that reg:QI 58 is dead after the instruction, never became life before and so remove the set completely, only preserving the side-effects (pre_modify:SI (reg/f:SI 7 sp) (plus:SI (reg/f:SI 7 sp) (const_int -2 [0xfffe]))) someone familiar with flow.c should be able to hack this into mark_used_reg() in a few minutes :) -- What|Removed |Added AssignedTo|rguenth at gcc dot gnu dot |unassigned at gcc dot gnu |org |dot org Status|ASSIGNED|NEW http://gcc.gnu.org/bugzilla/show_bug.cgi?id=20408
[Bug middle-end/20408] Unnecessary code generated for empty structs
--- Additional Comments From rguenth at gcc dot gnu dot org 2005-09-04 16:25 --- For struct Foo {}; void foo(const Foo); void bar(Foo); void fooc(void) { foo(Foo()); } void barc(void) { bar(Foo()); } we get different initializers for the Foo and the Foo case: void fooc() () { struct Foo D.1594; bb 0: D.1594 = {}; foo (D.1594); return; } void barc() () { struct Foo D.1613; bb 0: D.1613 = 0; bar (D.1613) [tail call]; return; } The former looks correct and does not produce initialization code for the temporary. The latter produces an unneccessary (uninitialized) initialization of the pass-by-value stack slot on x86. -- http://gcc.gnu.org/bugzilla/show_bug.cgi?id=20408
[Bug middle-end/20408] Unnecessary code generated for empty structs
--- Additional Comments From rguenth at gcc dot gnu dot org 2005-09-04 16:37 --- pinskia posted a patch for the =0 bug http://gcc.gnu.org/ml/gcc-patches/2005-03/msg01054.html -- http://gcc.gnu.org/bugzilla/show_bug.cgi?id=20408
[Bug middle-end/20408] Unnecessary code generated for empty structs
--- Additional Comments From rguenth at gcc dot gnu dot org 2005-09-04 17:12 --- I will look at this. Is this by any chance a regression? -- What|Removed |Added AssignedTo|unassigned at gcc dot gnu |rguenth at gcc dot gnu dot |dot org |org Status|NEW |ASSIGNED Last reconfirmed|2005-03-10 15:56:21 |2005-09-04 17:12:03 date|| http://gcc.gnu.org/bugzilla/show_bug.cgi?id=20408
[Bug middle-end/20408] Unnecessary code generated for empty structs
--- Additional Comments From pinskia at gcc dot gnu dot org 2005-03-10 17:30 --- (In reply to comment #10) I think we should produce an empty CONSTRUCTOR (which I am testing right now). That did not fix it, we still get code generated for the empty struct: ;; D.1594 = {} (nil) ;; foo (D.1594) [tail call] (insn 10 8 11 (set (mem:QI (reg/f:SI 56 virtual-outgoing-args) [0 S1 A32]) (reg:QI 58 [ D.1594 ])) -1 (nil) (nil)) (call_insn 11 10 0 (call (mem:QI (symbol_ref:SI (_Z3foo1X) [flags 0x41] function_decl 0x41e9ea6c foo) [0 S1 A8]) (const_int 4 [0x4])) -1 (nil) (nil) (nil)) But on PPC we get: ;; D.1588 = {} (nil) ;; foo (D.1588) [tail call] (insn 10 8 11 0 (set (reg:QI 3 r3) (reg:QI 118 [ D.1588 ])) -1 (nil) (nil)) (call_insn/j 11 10 12 0 (parallel [ (call (mem:SI (symbol_ref:SI (_Z3foo1X) [flags 0x41] function_decl 0x41d9f984 foo) [0 S4 A8]) (const_int 32 [0x20])) (use (const_int 0 [0x0])) (use (reg:SI 119)) (return) ]) -1 (nil) (nil) (expr_list:REG_DEP_TRUE (use (reg:QI 3 r3)) (nil))) See the difference is that we pass on ppc via a register but on x86 we pass via the stack. I don't know a way to fix this with a front-end change. -- What|Removed |Added Component|c++ |middle-end http://gcc.gnu.org/bugzilla/show_bug.cgi?id=20408
[Bug middle-end/20408] Unnecessary code generated for empty structs
--- Additional Comments From pinskia at gcc dot gnu dot org 2005-03-10 17:35 --- The change to cp-gimplifier.c should still happen as it makes not create a INTEGER_CST for an aggregate. -- http://gcc.gnu.org/bugzilla/show_bug.cgi?id=20408