[Bug middle-end/20408] Unnecessary code generated for empty structs

2021-02-11 Thread cvs-commit at gcc dot gnu.org via Gcc-bugs
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

2021-02-08 Thread cvs-commit at gcc dot gnu.org via Gcc-bugs
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

2020-12-09 Thread jason at gcc dot gnu.org via Gcc-bugs
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

2019-05-22 Thread jason at gcc dot gnu.org
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

2019-03-05 Thread jason at gcc dot gnu.org
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

2007-11-27 Thread rguenth at gcc dot gnu dot org


--- 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

2007-11-26 Thread steven at gcc dot gnu dot org


--- 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

2005-09-05 Thread rguenth at gcc dot gnu dot org

--- 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

2005-09-05 Thread rguenth at gcc dot gnu dot org

--- 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

2005-09-05 Thread rguenth at gcc dot gnu dot org

--- 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

2005-09-04 Thread rguenth at gcc dot gnu dot org

--- 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

2005-09-04 Thread rguenth at gcc dot gnu dot org

--- 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

2005-09-04 Thread rguenth at gcc dot gnu dot org

--- 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

2005-03-10 Thread pinskia at gcc dot gnu dot org

--- 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

2005-03-10 Thread pinskia at gcc dot gnu dot org

--- 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