public inbox for gcc-bugs@sourceware.org
help / color / mirror / Atom feed
* [Bug c++/19661] New: many redundant atexit calls emitted into the executable for static objects with empty destructors
@ 2005-01-27 22:24 yuri at tsoft dot com
  2005-01-28  1:08 ` [Bug c++/19661] unnecessary atexit calls emitted " bangerth at dealii dot org
                   ` (7 more replies)
  0 siblings, 8 replies; 22+ messages in thread
From: yuri at tsoft dot com @ 2005-01-27 22:24 UTC (permalink / raw)
  To: gcc-bugs

When some object having empty destructor is declared as static in the local
context of some function g++ still inserts <atexit> call with the empty handler
like <__tcf_0> below.

It may seem like minor issue but redundant instructions increase chances for
I-cache misses and worthen processor pipeline.

Yuri


08048800 <__tcf_0>:
 8048800:       55                      push   %ebp
 8048801:       89 e5                   mov    %esp,%ebp
 8048803:       5d                      pop    %ebp
 8048804:       c3                      ret


--testcase--
begin 644 case-empty-atexit.tgz
M'XL(`.1G^4$``^V6VVJ#0!"&O=ZG&-*;))!D/:Q>)!1"GV31:2.83=`U&$KZ
M[!U-BI)#<U%)"YT/85?\]Z#C/[.Q+G""ZZW=3[3%*K4SIW>D#&2D%+5*JLBG
M5DHW4$U[PG&E&X5>Z(>^YTC7#X/(`=7_5BXI"ZMS`&=?YNEWN@1WF&VVC]C2
M(XDOXE]-7WI>0[I2AD%P,_X4^:_XUW\`Z0//"QV0/>_C*O\\_D(\I2;.R@1A
M4$U7`R&PLI@;V&W2!,H"AZ.Y$/2-;!K#$C3=B+5.S7`$[P(@WI06%@L8H*%1
M@[J+)LGF].@TMJ/)4.^PHSF(WWY[YIK_5SVO<<__7NM_GZ2-_U7$_G\$'?\O
MTDUA<]3K9U$6J7D#H]=8;'6,4-BDR0)Y&5O*`K7SEW4&:+V]I*XY"C!I/0X'
MDC:IY-6<#Z`$<:[\.,XZ&W=D"5Y..YZ1_##G_/%CKOA_0H'I]0QPM_Y+U=;_
M*"*]HHO]_PANE?]CJ6\/`8WGN\<``#VM/<UEG&$8AF$8AF$8AF$8AF$8AF$8
-AF'^#)_;GM5=`"@`````
`
end

-- 
           Summary: many redundant atexit calls emitted into the executable
                    for static objects with empty destructors
           Product: gcc
           Version: 3.4.2
            Status: UNCONFIRMED
          Severity: normal
          Priority: P2
         Component: c++
        AssignedTo: unassigned at gcc dot gnu dot org
        ReportedBy: yuri at tsoft dot com
                CC: gcc-bugs at gcc dot gnu dot org
 GCC build triplet: n/a
GCC target triplet: n/a


http://gcc.gnu.org/bugzilla/show_bug.cgi?id=19661


^ permalink raw reply	[flat|nested] 22+ messages in thread

* [Bug c++/19661] unnecessary atexit calls emitted for static objects with empty destructors
  2005-01-27 22:24 [Bug c++/19661] New: many redundant atexit calls emitted into the executable for static objects with empty destructors yuri at tsoft dot com
@ 2005-01-28  1:08 ` bangerth at dealii dot org
  2005-01-28  1:22 ` [Bug middle-end/19661] " pinskia at gcc dot gnu dot org
                   ` (6 subsequent siblings)
  7 siblings, 0 replies; 22+ messages in thread
From: bangerth at dealii dot org @ 2005-01-28  1:08 UTC (permalink / raw)
  To: gcc-bugs


------- Additional Comments From bangerth at dealii dot org  2005-01-28 01:08 -------
Confirmed, although I consider this to be a rather minor point since 
the code is actually run only once. Here's a small test: 
-------------------- 
struct A { 
    A(); 
    ~A() {} 
}; 
 
void foo () { 
  static A a; 
} 
------------------------- 
 
g/x> /home/bangerth/bin/gcc-4.0-pre/bin/c++ -S -O3 x.cc 
g/x> cat x.s | c++filt > x.ss 
 
.... 
foo(): 
.LFB5: 
	pushl	%ebp 
.LCFI2: 
	movl	%esp, %ebp 
.LCFI3: 
	pushl	%ebx 
.LCFI4: 
	subl	$20, %esp 
.LCFI5: 
	cmpb	$0, guard variable for foo()::a 
	je	.L12 
.L9: 
	addl	$20, %esp 
	popl	%ebx 
	popl	%ebp 
	ret 
	.p2align 4,,7 
.L12: 
	movl	guard variable for foo()::a, (%esp) 
	call	__cxa_guard_acquire 
	testl	%eax, %eax 
	je	.L9 
	movl	foo()::a, (%esp) 
.LEHB0: 
	call	A::A() 
.LEHE0: 
	movl	guard variable for foo()::a, (%esp) 
	call	__cxa_guard_release 
	movl	$__tcf_0, (%esp) 
	call	atexit 
	addl	$20, %esp 
	popl	%ebx 
	popl	%ebp 
	ret 
... 
 
W. 

-- 
           What    |Removed                     |Added
----------------------------------------------------------------------------
           Severity|normal                      |enhancement
             Status|UNCONFIRMED                 |NEW
     Ever Confirmed|                            |1
   Last reconfirmed|0000-00-00 00:00:00         |2005-01-28 01:08:27
               date|                            |
            Summary|many redundant atexit calls |unnecessary atexit calls
                   |emitted into the executable |emitted for static objects
                   |for static objects with     |with empty destructors
                   |empty destructors           |


http://gcc.gnu.org/bugzilla/show_bug.cgi?id=19661


^ permalink raw reply	[flat|nested] 22+ messages in thread

* [Bug middle-end/19661] unnecessary atexit calls emitted for static objects with empty destructors
  2005-01-27 22:24 [Bug c++/19661] New: many redundant atexit calls emitted into the executable for static objects with empty destructors yuri at tsoft dot com
  2005-01-28  1:08 ` [Bug c++/19661] unnecessary atexit calls emitted " bangerth at dealii dot org
@ 2005-01-28  1:22 ` pinskia at gcc dot gnu dot org
  2005-01-28  1:26 ` [Bug c++/19661] " yuri at tsoft dot com
                   ` (5 subsequent siblings)
  7 siblings, 0 replies; 22+ messages in thread
From: pinskia at gcc dot gnu dot org @ 2005-01-28  1:22 UTC (permalink / raw)
  To: gcc-bugs


------- Additional Comments From pinskia at gcc dot gnu dot org  2005-01-28 01:22 -------
This is related to PR 17736 which is for empty global variables with empty constructors.

-- 
           What    |Removed                     |Added
----------------------------------------------------------------------------
          Component|c++                         |middle-end
           Keywords|                            |missed-optimization


http://gcc.gnu.org/bugzilla/show_bug.cgi?id=19661


^ permalink raw reply	[flat|nested] 22+ messages in thread

* [Bug c++/19661] unnecessary atexit calls emitted for static objects with empty destructors
  2005-01-27 22:24 [Bug c++/19661] New: many redundant atexit calls emitted into the executable for static objects with empty destructors yuri at tsoft dot com
  2005-01-28  1:08 ` [Bug c++/19661] unnecessary atexit calls emitted " bangerth at dealii dot org
  2005-01-28  1:22 ` [Bug middle-end/19661] " pinskia at gcc dot gnu dot org
@ 2005-01-28  1:26 ` yuri at tsoft dot com
  2005-01-28  1:46 ` [Bug middle-end/19661] " pinskia at gcc dot gnu dot org
                   ` (4 subsequent siblings)
  7 siblings, 0 replies; 22+ messages in thread
From: yuri at tsoft dot com @ 2005-01-28  1:26 UTC (permalink / raw)
  To: gcc-bugs


------- Additional Comments From yuri at tsoft dot com  2005-01-28 01:26 -------
(In reply to comment #1)
> Confirmed, although I consider this to be a rather minor point since 
> the code is actually run only once. Here's a small test: 

I agree, but it bloats the code, therefore reducing potential for inlining and
pipeline trashing.

-- 
           What    |Removed                     |Added
----------------------------------------------------------------------------
           Severity|enhancement                 |normal
          Component|middle-end                  |c++


http://gcc.gnu.org/bugzilla/show_bug.cgi?id=19661


^ permalink raw reply	[flat|nested] 22+ messages in thread

* [Bug middle-end/19661] unnecessary atexit calls emitted for static objects with empty destructors
  2005-01-27 22:24 [Bug c++/19661] New: many redundant atexit calls emitted into the executable for static objects with empty destructors yuri at tsoft dot com
                   ` (2 preceding siblings ...)
  2005-01-28  1:26 ` [Bug c++/19661] " yuri at tsoft dot com
@ 2005-01-28  1:46 ` pinskia at gcc dot gnu dot org
  2005-01-28 17:02 ` [Bug c++/19661] " bangerth at dealii dot org
                   ` (3 subsequent siblings)
  7 siblings, 0 replies; 22+ messages in thread
From: pinskia at gcc dot gnu dot org @ 2005-01-28  1:46 UTC (permalink / raw)
  To: gcc-bugs


------- Additional Comments From pinskia at gcc dot gnu dot org  2005-01-28 01:45 -------
But it is still an enhancement because any missed optimization that does not happen before is.
Also this is a middle-end bug since the middle-end and not the front-end figure out that the function 
is empty and remove the call to atexit.

-- 
           What    |Removed                     |Added
----------------------------------------------------------------------------
           Severity|normal                      |enhancement
          Component|c++                         |middle-end


http://gcc.gnu.org/bugzilla/show_bug.cgi?id=19661


^ permalink raw reply	[flat|nested] 22+ messages in thread

* [Bug c++/19661] unnecessary atexit calls emitted for static objects with empty destructors
  2005-01-27 22:24 [Bug c++/19661] New: many redundant atexit calls emitted into the executable for static objects with empty destructors yuri at tsoft dot com
                   ` (3 preceding siblings ...)
  2005-01-28  1:46 ` [Bug middle-end/19661] " pinskia at gcc dot gnu dot org
@ 2005-01-28 17:02 ` bangerth at dealii dot org
  2005-01-28 18:53 ` [Bug middle-end/19661] " pinskia at gcc dot gnu dot org
                   ` (2 subsequent siblings)
  7 siblings, 0 replies; 22+ messages in thread
From: bangerth at dealii dot org @ 2005-01-28 17:02 UTC (permalink / raw)
  To: gcc-bugs


------- Additional Comments From bangerth at dealii dot org  2005-01-28 17:01 -------
atexit only takes a pointer to a function to be run on exit of the 
program. The fact that this is an empty function is unbeknownst to 
it, and probably the code in the middle-end that has to deal with 
that. I therefore believe that the front-end has to take care of the 
fact that we have may run an empty function; it would also logically 
make sense to guard the call to atexit with a check whether the 
destructor is empty or not. 
 
I'll move this bug back to the C++ component. 
 
W. 

-- 
           What    |Removed                     |Added
----------------------------------------------------------------------------
          Component|middle-end                  |c++


http://gcc.gnu.org/bugzilla/show_bug.cgi?id=19661


^ permalink raw reply	[flat|nested] 22+ messages in thread

* [Bug middle-end/19661] unnecessary atexit calls emitted for static objects with empty destructors
  2005-01-27 22:24 [Bug c++/19661] New: many redundant atexit calls emitted into the executable for static objects with empty destructors yuri at tsoft dot com
                   ` (4 preceding siblings ...)
  2005-01-28 17:02 ` [Bug c++/19661] " bangerth at dealii dot org
@ 2005-01-28 18:53 ` pinskia at gcc dot gnu dot org
  2005-01-28 19:11 ` bangerth at dealii dot org
  2005-09-24 17:43 ` [Bug tree-optimization/19661] " pinskia at gcc dot gnu dot org
  7 siblings, 0 replies; 22+ messages in thread
From: pinskia at gcc dot gnu dot org @ 2005-01-28 18:53 UTC (permalink / raw)
  To: gcc-bugs


------- Additional Comments From pinskia at gcc dot gnu dot org  2005-01-28 18:53 -------
(In reply to comment #5)
> I'll move this bug back to the C++ component. 
Consider the following C++ code:
struct Foo { ~Foo() {} int i; };
struct A { Foo foo[2]; };
void foo () { 
  static A a; 
} 

We don't know the deconstructor for A is empty until we remove the empry loop and do optimizations 
on it.  So this is again a job for the midde-end/tree-optimizations.  We can then mark the function as 
empty and then have a pass (or really fold or something like that) remove calls to atexit (and similar 
functions) which just references empty functions.  This is the correct way of doing this.

-- 
           What    |Removed                     |Added
----------------------------------------------------------------------------
          Component|c++                         |middle-end
  GCC build triplet|n/a                         |
 GCC target triplet|n/a                         |


http://gcc.gnu.org/bugzilla/show_bug.cgi?id=19661


^ permalink raw reply	[flat|nested] 22+ messages in thread

* [Bug middle-end/19661] unnecessary atexit calls emitted for static objects with empty destructors
  2005-01-27 22:24 [Bug c++/19661] New: many redundant atexit calls emitted into the executable for static objects with empty destructors yuri at tsoft dot com
                   ` (5 preceding siblings ...)
  2005-01-28 18:53 ` [Bug middle-end/19661] " pinskia at gcc dot gnu dot org
@ 2005-01-28 19:11 ` bangerth at dealii dot org
  2005-09-24 17:43 ` [Bug tree-optimization/19661] " pinskia at gcc dot gnu dot org
  7 siblings, 0 replies; 22+ messages in thread
From: bangerth at dealii dot org @ 2005-01-28 19:11 UTC (permalink / raw)
  To: gcc-bugs


------- Additional Comments From bangerth at dealii dot org  2005-01-28 19:11 -------
Why do you think the front-end doesn't know that the destructor is empty? 
It sees its definition, and it knows about potential destructors of 
member objects and base classes, so it should have all the information. 
That being said, I don't consider this to be such an important case as 
to pour a lot of passion into this discussion :-) 
 
W. 

-- 


http://gcc.gnu.org/bugzilla/show_bug.cgi?id=19661


^ permalink raw reply	[flat|nested] 22+ messages in thread

* [Bug tree-optimization/19661] unnecessary atexit calls emitted for static objects with empty destructors
  2005-01-27 22:24 [Bug c++/19661] New: many redundant atexit calls emitted into the executable for static objects with empty destructors yuri at tsoft dot com
                   ` (6 preceding siblings ...)
  2005-01-28 19:11 ` bangerth at dealii dot org
@ 2005-09-24 17:43 ` pinskia at gcc dot gnu dot org
  7 siblings, 0 replies; 22+ messages in thread
From: pinskia at gcc dot gnu dot org @ 2005-09-24 17:43 UTC (permalink / raw)
  To: gcc-bugs


------- Additional Comments From pinskia at gcc dot gnu dot org  2005-09-24 17:42 -------
Hmm, the easy way to to have a pass which finds all the atexit calls and sees if the function which is 
passed is a const function and if it is, then just remove the atexit call.

-- 
           What    |Removed                     |Added
----------------------------------------------------------------------------
          Component|middle-end                  |tree-optimization


http://gcc.gnu.org/bugzilla/show_bug.cgi?id=19661


^ permalink raw reply	[flat|nested] 22+ messages in thread

* [Bug tree-optimization/19661] unnecessary atexit calls emitted for static objects with empty destructors
       [not found] <bug-19661-4@http.gcc.gnu.org/bugzilla/>
                   ` (10 preceding siblings ...)
  2024-05-07 21:47 ` cvs-commit at gcc dot gnu.org
@ 2024-05-07 21:47 ` pinskia at gcc dot gnu.org
  11 siblings, 0 replies; 22+ messages in thread
From: pinskia at gcc dot gnu.org @ 2024-05-07 21:47 UTC (permalink / raw)
  To: gcc-bugs

https://gcc.gnu.org/bugzilla/show_bug.cgi?id=19661

Andrew Pinski <pinskia at gcc dot gnu.org> changed:

           What    |Removed                     |Added
----------------------------------------------------------------------------
             Status|ASSIGNED                    |RESOLVED
   Target Milestone|---                         |15.0
         Resolution|---                         |FIXED

--- Comment #21 from Andrew Pinski <pinskia at gcc dot gnu.org> ---
Fixed.

^ permalink raw reply	[flat|nested] 22+ messages in thread

* [Bug tree-optimization/19661] unnecessary atexit calls emitted for static objects with empty destructors
       [not found] <bug-19661-4@http.gcc.gnu.org/bugzilla/>
                   ` (9 preceding siblings ...)
  2024-04-19  0:59 ` pinskia at gcc dot gnu.org
@ 2024-05-07 21:47 ` cvs-commit at gcc dot gnu.org
  2024-05-07 21:47 ` pinskia at gcc dot gnu.org
  11 siblings, 0 replies; 22+ messages in thread
From: cvs-commit at gcc dot gnu.org @ 2024-05-07 21:47 UTC (permalink / raw)
  To: gcc-bugs

https://gcc.gnu.org/bugzilla/show_bug.cgi?id=19661

--- Comment #20 from GCC Commits <cvs-commit at gcc dot gnu.org> ---
The trunk branch has been updated by Andrew Pinski <pinskia@gcc.gnu.org>:

https://gcc.gnu.org/g:c9dd853680b12d9c9def5de61abde5d057c526ba

commit r15-308-gc9dd853680b12d9c9def5de61abde5d057c526ba
Author: Andrew Pinski <quic_apinski@quicinc.com>
Date:   Fri Mar 15 16:34:22 2024 -0700

    DCE __cxa_atexit calls where the function is pure/const [PR19661]

    In C++ sometimes you have a deconstructor function which is "empty", like
for an
    example with unions or with arrays.  The front-end might not know it is
empty either
    so this should be done on during optimization.o
    To implement it I added it to DCE where we mark if a statement is necessary
or not.

    Bootstrapped and tested on x86_64-linux-gnu with no regressions.

    Changes since v1:
      * v2: Add support for __aeabi_atexit for arm-*eabi. Add extra comments.
            Add cxa_atexit-5.C testcase for -fPIC case.
      * v3: Fix testcases for the __aeabi_atexit (forgot to do in the v2).

            PR tree-optimization/19661

    gcc/ChangeLog:

            * tree-ssa-dce.cc (is_cxa_atexit): New function.
            (is_removable_cxa_atexit_call): New function.
            (mark_stmt_if_obviously_necessary): Don't mark removable
            cxa_at_exit calls.
            (mark_all_reaching_defs_necessary_1): Likewise.
            (propagate_necessity): Likewise.

    gcc/testsuite/ChangeLog:

            * g++.dg/tree-ssa/cxa_atexit-1.C: New test.
            * g++.dg/tree-ssa/cxa_atexit-2.C: New test.
            * g++.dg/tree-ssa/cxa_atexit-3.C: New test.
            * g++.dg/tree-ssa/cxa_atexit-4.C: New test.
            * g++.dg/tree-ssa/cxa_atexit-5.C: New test.
            * g++.dg/tree-ssa/cxa_atexit-6.C: New test.

    Signed-off-by: Andrew Pinski <quic_apinski@quicinc.com>

^ permalink raw reply	[flat|nested] 22+ messages in thread

* [Bug tree-optimization/19661] unnecessary atexit calls emitted for static objects with empty destructors
       [not found] <bug-19661-4@http.gcc.gnu.org/bugzilla/>
                   ` (8 preceding siblings ...)
  2024-04-19  0:39 ` pinskia at gcc dot gnu.org
@ 2024-04-19  0:59 ` pinskia at gcc dot gnu.org
  2024-05-07 21:47 ` cvs-commit at gcc dot gnu.org
  2024-05-07 21:47 ` pinskia at gcc dot gnu.org
  11 siblings, 0 replies; 22+ messages in thread
From: pinskia at gcc dot gnu.org @ 2024-04-19  0:59 UTC (permalink / raw)
  To: gcc-bugs

https://gcc.gnu.org/bugzilla/show_bug.cgi?id=19661

--- Comment #19 from Andrew Pinski <pinskia at gcc dot gnu.org> ---
(In reply to Andrew Pinski from comment #18)
> Created attachment 57987 [details]
> Patch which I will be submitting once GCC 15 stage 1 opens up

I forgot to add the testcase from comment #12. the patch which I am going to
submit will have it.

^ permalink raw reply	[flat|nested] 22+ messages in thread

* [Bug tree-optimization/19661] unnecessary atexit calls emitted for static objects with empty destructors
       [not found] <bug-19661-4@http.gcc.gnu.org/bugzilla/>
                   ` (7 preceding siblings ...)
  2024-03-16 22:47 ` i at maskray dot me
@ 2024-04-19  0:39 ` pinskia at gcc dot gnu.org
  2024-04-19  0:59 ` pinskia at gcc dot gnu.org
                   ` (2 subsequent siblings)
  11 siblings, 0 replies; 22+ messages in thread
From: pinskia at gcc dot gnu.org @ 2024-04-19  0:39 UTC (permalink / raw)
  To: gcc-bugs

https://gcc.gnu.org/bugzilla/show_bug.cgi?id=19661

--- Comment #18 from Andrew Pinski <pinskia at gcc dot gnu.org> ---
Created attachment 57987
  --> https://gcc.gnu.org/bugzilla/attachment.cgi?id=57987&action=edit
Patch which I will be submitting once GCC 15 stage 1 opens up

^ permalink raw reply	[flat|nested] 22+ messages in thread

* [Bug tree-optimization/19661] unnecessary atexit calls emitted for static objects with empty destructors
       [not found] <bug-19661-4@http.gcc.gnu.org/bugzilla/>
                   ` (6 preceding siblings ...)
  2024-03-16  2:17 ` pinskia at gcc dot gnu.org
@ 2024-03-16 22:47 ` i at maskray dot me
  2024-04-19  0:39 ` pinskia at gcc dot gnu.org
                   ` (3 subsequent siblings)
  11 siblings, 0 replies; 22+ messages in thread
From: i at maskray dot me @ 2024-03-16 22:47 UTC (permalink / raw)
  To: gcc-bugs

https://gcc.gnu.org/bugzilla/show_bug.cgi?id=19661

Fangrui Song <i at maskray dot me> changed:

           What    |Removed                     |Added
----------------------------------------------------------------------------
                 CC|                            |i at maskray dot me

--- Comment #17 from Fangrui Song <i at maskray dot me> ---
(In reply to Andrew Pinski from comment #16)
> So what is interesting is the way LLVM implements this as an IPO pass as how
> I described in comment #8, 6 years after I wrote that. Well they used
> "empty" rather than const . Note using it as an IPO pass I think is not
> wrong just having a specialized pass here where this is the same as DCE so
> just have DCE handle it instead seems better; plus with the availability of
> having pure/const flags with LTO and not having to load in the function
> seems much better really.

Yes, LLVM recognizes __cxa_atexit as a library function and removes it in
GlobalOpt (part of IPO) since 2011
(https://github.com/llvm/llvm-project/commit/ee6bc70d2f1c2434ca9ca8092216bdeab322c7e5),
likely because
GlobalOpt is already doing global variable optimizations (e.g. removal if dead,
constant folding). Technically __cxa_atexit removal can be moved elsewhere.

There are two GlobalOpt passes in the optimization pipeline (see -mllvm
-print-changed=cdiff output), one before the inliner and one after.

  SROA
  ...
  GlobalOpt
  ...
  buildInlinerPipeline
  ...
  GlobalOpt

For empty functions like `~constant_init() {}`, SROA deletes unneeded IR
instructions (spill of the "this" pointer) and actually makes the IR function
empty. Then GlobalOpt removes __cxa_atexit call sites.

For `static void empty() {} ~constant_init() { empty(); }`, the inliner removes
the `empty()` and makes the IR function empty. Then GlobalOpt removes
__cxa_atexit call sites.

^ permalink raw reply	[flat|nested] 22+ messages in thread

* [Bug tree-optimization/19661] unnecessary atexit calls emitted for static objects with empty destructors
       [not found] <bug-19661-4@http.gcc.gnu.org/bugzilla/>
                   ` (5 preceding siblings ...)
  2024-03-15 23:40 ` pinskia at gcc dot gnu.org
@ 2024-03-16  2:17 ` pinskia at gcc dot gnu.org
  2024-03-16 22:47 ` i at maskray dot me
                   ` (4 subsequent siblings)
  11 siblings, 0 replies; 22+ messages in thread
From: pinskia at gcc dot gnu.org @ 2024-03-16  2:17 UTC (permalink / raw)
  To: gcc-bugs

https://gcc.gnu.org/bugzilla/show_bug.cgi?id=19661

--- Comment #16 from Andrew Pinski <pinskia at gcc dot gnu.org> ---
So what is interesting is the way LLVM implements this as an IPO pass as how I
described in comment #8, 6 years after I wrote that. Well they used "empty"
rather than const . Note using it as an IPO pass I think is not wrong just
having a specialized pass here where this is the same as DCE so just have DCE
handle it instead seems better; plus with the availability of having pure/const
flags with LTO and not having to load in the function seems much better really.

^ permalink raw reply	[flat|nested] 22+ messages in thread

* [Bug tree-optimization/19661] unnecessary atexit calls emitted for static objects with empty destructors
       [not found] <bug-19661-4@http.gcc.gnu.org/bugzilla/>
                   ` (4 preceding siblings ...)
  2024-03-15 22:56 ` pinskia at gcc dot gnu.org
@ 2024-03-15 23:40 ` pinskia at gcc dot gnu.org
  2024-03-16  2:17 ` pinskia at gcc dot gnu.org
                   ` (5 subsequent siblings)
  11 siblings, 0 replies; 22+ messages in thread
From: pinskia at gcc dot gnu.org @ 2024-03-15 23:40 UTC (permalink / raw)
  To: gcc-bugs

https://gcc.gnu.org/bugzilla/show_bug.cgi?id=19661

--- Comment #15 from Andrew Pinski <pinskia at gcc dot gnu.org> ---
The patch is able to handle all 3 testcases here even:
For the libstdc++ one:
t3.cc.123t.dce2:Deleting : __cxxabiv1::__cxa_atexit (__dt_comp , &global,
&__dso_handle);

^ permalink raw reply	[flat|nested] 22+ messages in thread

* [Bug tree-optimization/19661] unnecessary atexit calls emitted for static objects with empty destructors
       [not found] <bug-19661-4@http.gcc.gnu.org/bugzilla/>
                   ` (3 preceding siblings ...)
  2022-11-02 17:16 ` redi at gcc dot gnu.org
@ 2024-03-15 22:56 ` pinskia at gcc dot gnu.org
  2024-03-15 23:40 ` pinskia at gcc dot gnu.org
                   ` (6 subsequent siblings)
  11 siblings, 0 replies; 22+ messages in thread
From: pinskia at gcc dot gnu.org @ 2024-03-15 22:56 UTC (permalink / raw)
  To: gcc-bugs

https://gcc.gnu.org/bugzilla/show_bug.cgi?id=19661

Andrew Pinski <pinskia at gcc dot gnu.org> changed:

           What    |Removed                     |Added
----------------------------------------------------------------------------
             Status|NEW                         |ASSIGNED
           Assignee|unassigned at gcc dot gnu.org      |pinskia at gcc dot gnu.org

--- Comment #14 from Andrew Pinski <pinskia at gcc dot gnu.org> ---
I am testing a (small) patch for this. Basically DCE can remove the calls to
__cxa_atexit .

^ permalink raw reply	[flat|nested] 22+ messages in thread

* [Bug tree-optimization/19661] unnecessary atexit calls emitted for static objects with empty destructors
       [not found] <bug-19661-4@http.gcc.gnu.org/bugzilla/>
                   ` (2 preceding siblings ...)
  2022-11-02 15:53 ` redi at gcc dot gnu.org
@ 2022-11-02 17:16 ` redi at gcc dot gnu.org
  2024-03-15 22:56 ` pinskia at gcc dot gnu.org
                   ` (7 subsequent siblings)
  11 siblings, 0 replies; 22+ messages in thread
From: redi at gcc dot gnu.org @ 2022-11-02 17:16 UTC (permalink / raw)
  To: gcc-bugs

https://gcc.gnu.org/bugzilla/show_bug.cgi?id=19661

--- Comment #13 from Jonathan Wakely <redi at gcc dot gnu.org> ---
*** Bug 107500 has been marked as a duplicate of this bug. ***

^ permalink raw reply	[flat|nested] 22+ messages in thread

* [Bug tree-optimization/19661] unnecessary atexit calls emitted for static objects with empty destructors
       [not found] <bug-19661-4@http.gcc.gnu.org/bugzilla/>
  2021-09-24  7:41 ` antoshkka at gmail dot com
  2022-11-02 15:47 ` pinskia at gcc dot gnu.org
@ 2022-11-02 15:53 ` redi at gcc dot gnu.org
  2022-11-02 17:16 ` redi at gcc dot gnu.org
                   ` (8 subsequent siblings)
  11 siblings, 0 replies; 22+ messages in thread
From: redi at gcc dot gnu.org @ 2022-11-02 15:53 UTC (permalink / raw)
  To: gcc-bugs

https://gcc.gnu.org/bugzilla/show_bug.cgi?id=19661

Jonathan Wakely <redi at gcc dot gnu.org> changed:

           What    |Removed                     |Added
----------------------------------------------------------------------------
   Last reconfirmed|2006-02-05 21:10:26         |2022-11-2

--- Comment #12 from Jonathan Wakely <redi at gcc dot gnu.org> ---
Reduced from the code in libstdc++:

extern "C" int puts(const char*);

struct A
{
  constexpr A()  { }
  ~A() { puts("bye"); }
};

namespace
{
  struct constant_init
  {
    union {
      A obj;
    };
    constexpr constant_init() : obj() { }

    ~constant_init() { /* do nothing, union member is not destroyed */ }
  };


  // Single-threaded fallback buffer.
  constinit constant_init global;
}

extern "C" A* get() { return &global.obj; }

With -std=c++20 -Os GCC emits a call to atexit:

(anonymous namespace)::constant_init::~constant_init() [base object
destructor]:
        ret
get:
        mov     eax, OFFSET FLAT:_ZN12_GLOBAL__N_16globalE
        ret
_GLOBAL__sub_I_get:
        mov     edx, OFFSET FLAT:__dso_handle
        mov     esi, OFFSET FLAT:_ZN12_GLOBAL__N_16globalE
        mov     edi, OFFSET FLAT:_ZN12_GLOBAL__N_113constant_initD1Ev
        jmp     __cxa_atexit


With the same options, Clang doesn't:

get:                                    # @get
        lea     rax, [rip + (anonymous namespace)::global]
        ret

^ permalink raw reply	[flat|nested] 22+ messages in thread

* [Bug tree-optimization/19661] unnecessary atexit calls emitted for static objects with empty destructors
       [not found] <bug-19661-4@http.gcc.gnu.org/bugzilla/>
  2021-09-24  7:41 ` antoshkka at gmail dot com
@ 2022-11-02 15:47 ` pinskia at gcc dot gnu.org
  2022-11-02 15:53 ` redi at gcc dot gnu.org
                   ` (9 subsequent siblings)
  11 siblings, 0 replies; 22+ messages in thread
From: pinskia at gcc dot gnu.org @ 2022-11-02 15:47 UTC (permalink / raw)
  To: gcc-bugs

https://gcc.gnu.org/bugzilla/show_bug.cgi?id=19661

Andrew Pinski <pinskia at gcc dot gnu.org> changed:

           What    |Removed                     |Added
----------------------------------------------------------------------------
                 CC|                            |rdiezmail-gcc at yahoo dot de

--- Comment #11 from Andrew Pinski <pinskia at gcc dot gnu.org> ---
*** Bug 107500 has been marked as a duplicate of this bug. ***

^ permalink raw reply	[flat|nested] 22+ messages in thread

* [Bug tree-optimization/19661] unnecessary atexit calls emitted for static objects with empty destructors
       [not found] <bug-19661-4@http.gcc.gnu.org/bugzilla/>
@ 2021-09-24  7:41 ` antoshkka at gmail dot com
  2022-11-02 15:47 ` pinskia at gcc dot gnu.org
                   ` (10 subsequent siblings)
  11 siblings, 0 replies; 22+ messages in thread
From: antoshkka at gmail dot com @ 2021-09-24  7:41 UTC (permalink / raw)
  To: gcc-bugs

https://gcc.gnu.org/bugzilla/show_bug.cgi?id=19661

--- Comment #10 from Antony Polukhin <antoshkka at gmail dot com> ---
Any progress?

Multiple compilers already eliminate the atexit call. Moreover, some of the
compilers even eliminate the guard variable after that 
https://godbolt.org/z/dbdfMrroa

Note that the atexit elimination would benefit the libstdc++, as the latter now
uses a bunch of constant_init instances that have empty destructor
in libstdc++-v3/src/c++17/memory_resource.cc and
libstdc++-v3/src/c++11/system_error.cc . It would be possible to eliminate the
atexit calls for those cases and speedup startup times
https://godbolt.org/z/MKaWKevzq

^ permalink raw reply	[flat|nested] 22+ messages in thread

* [Bug tree-optimization/19661] unnecessary atexit calls emitted for static objects with empty destructors
       [not found] <bug-19661-6649@http.gcc.gnu.org/bugzilla/>
@ 2008-02-20 21:53 ` pinskia at gcc dot gnu dot org
  0 siblings, 0 replies; 22+ messages in thread
From: pinskia at gcc dot gnu dot org @ 2008-02-20 21:53 UTC (permalink / raw)
  To: gcc-bugs



------- Comment #9 from pinskia at gcc dot gnu dot org  2008-02-20 21:52 -------
(In reply to comment #7)
> Why do you think the front-end doesn't know that the destructor is empty? 

Because it is non trivial.  Try it with a more complex case where you have
multiple layer destructors and inlining, you will see that the front-end does
not know if it is empty until way after inlining.

-- Pinski


-- 


http://gcc.gnu.org/bugzilla/show_bug.cgi?id=19661


^ permalink raw reply	[flat|nested] 22+ messages in thread

end of thread, other threads:[~2024-05-07 21:47 UTC | newest]

Thread overview: 22+ messages (download: mbox.gz / follow: Atom feed)
-- links below jump to the message on this page --
2005-01-27 22:24 [Bug c++/19661] New: many redundant atexit calls emitted into the executable for static objects with empty destructors yuri at tsoft dot com
2005-01-28  1:08 ` [Bug c++/19661] unnecessary atexit calls emitted " bangerth at dealii dot org
2005-01-28  1:22 ` [Bug middle-end/19661] " pinskia at gcc dot gnu dot org
2005-01-28  1:26 ` [Bug c++/19661] " yuri at tsoft dot com
2005-01-28  1:46 ` [Bug middle-end/19661] " pinskia at gcc dot gnu dot org
2005-01-28 17:02 ` [Bug c++/19661] " bangerth at dealii dot org
2005-01-28 18:53 ` [Bug middle-end/19661] " pinskia at gcc dot gnu dot org
2005-01-28 19:11 ` bangerth at dealii dot org
2005-09-24 17:43 ` [Bug tree-optimization/19661] " pinskia at gcc dot gnu dot org
     [not found] <bug-19661-6649@http.gcc.gnu.org/bugzilla/>
2008-02-20 21:53 ` pinskia at gcc dot gnu dot org
     [not found] <bug-19661-4@http.gcc.gnu.org/bugzilla/>
2021-09-24  7:41 ` antoshkka at gmail dot com
2022-11-02 15:47 ` pinskia at gcc dot gnu.org
2022-11-02 15:53 ` redi at gcc dot gnu.org
2022-11-02 17:16 ` redi at gcc dot gnu.org
2024-03-15 22:56 ` pinskia at gcc dot gnu.org
2024-03-15 23:40 ` pinskia at gcc dot gnu.org
2024-03-16  2:17 ` pinskia at gcc dot gnu.org
2024-03-16 22:47 ` i at maskray dot me
2024-04-19  0:39 ` pinskia at gcc dot gnu.org
2024-04-19  0:59 ` pinskia at gcc dot gnu.org
2024-05-07 21:47 ` cvs-commit at gcc dot gnu.org
2024-05-07 21:47 ` pinskia at gcc dot gnu.org

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