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.
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.
Signed-off-by: Andrew Pinski
---
gcc/testsuite/g++.dg/tree-ssa/cxa_atexit-1.C | 20 +
gcc/testsuite/g++.dg/tree-ssa/cxa_atexit-2.C | 21 ++
gcc/testsuite/g++.dg/tree-ssa/cxa_atexit-3.C | 19 +
gcc/testsuite/g++.dg/tree-ssa/cxa_atexit-4.C | 20 +
gcc/testsuite/g++.dg/tree-ssa/cxa_atexit-5.C | 39 +
gcc/tree-ssa-dce.cc | 44
6 files changed, 163 insertions(+)
create mode 100644 gcc/testsuite/g++.dg/tree-ssa/cxa_atexit-1.C
create mode 100644 gcc/testsuite/g++.dg/tree-ssa/cxa_atexit-2.C
create mode 100644 gcc/testsuite/g++.dg/tree-ssa/cxa_atexit-3.C
create mode 100644 gcc/testsuite/g++.dg/tree-ssa/cxa_atexit-4.C
create mode 100644 gcc/testsuite/g++.dg/tree-ssa/cxa_atexit-5.C
diff --git a/gcc/testsuite/g++.dg/tree-ssa/cxa_atexit-1.C
b/gcc/testsuite/g++.dg/tree-ssa/cxa_atexit-1.C
new file mode 100644
index 000..1f5f431c7e4
--- /dev/null
+++ b/gcc/testsuite/g++.dg/tree-ssa/cxa_atexit-1.C
@@ -0,0 +1,20 @@
+/* { dg-do compile } */
+/* { dg-options "-O2 -fdump-tree-cddce1-details -fdump-tree-optimized" } */
+// { dg-require-effective-target cxa_atexit }
+/* PR tree-optimization/19661 */
+
+/* The call to axexit should be removed as A::~A() is a pure/const function
call
+ and there is no visible effect if A::~A() call does not happen. */
+
+struct A {
+A();
+~A() {}
+};
+
+void foo () {
+ static A a;
+}
+
+/* { dg-final { scan-tree-dump-times "Deleting : __cxxabiv1::__cxa_atexit" 1
"cddce1" } } */
+/* { dg-final { scan-tree-dump-not "__cxa_atexit" "optimized" } } */
+
diff --git a/gcc/testsuite/g++.dg/tree-ssa/cxa_atexit-2.C
b/gcc/testsuite/g++.dg/tree-ssa/cxa_atexit-2.C
new file mode 100644
index 000..4d0656b455c
--- /dev/null
+++ b/gcc/testsuite/g++.dg/tree-ssa/cxa_atexit-2.C
@@ -0,0 +1,21 @@
+/* { dg-do compile { target c++11 } } */
+/* { dg-options "-O2 -fdump-tree-cddce1-details -fdump-tree-optimized" } */
+// { dg-require-effective-target cxa_atexit }
+/* PR tree-optimization/19661 */
+
+/* The call to axexit should be not removed as A::~A() as it marked with
noipa. */
+
+struct A {
+A();
+~A();
+};
+
+[[gnu::noipa]] A::~A() {}
+
+void foo () {
+ static A a;
+}
+
+/* { dg-final { scan-tree-dump-not "Deleting : __cxxabiv1::__cxa_atexit"
"cddce1" } } */
+/* { dg-final { scan-tree-dump-times "__cxa_atexit" 1 "optimized" } } */
+
diff --git a/gcc/testsuite/g++.dg/tree-ssa/cxa_atexit-3.C
b/gcc/testsuite/g++.dg/tree-ssa/cxa_atexit-3.C
new file mode 100644
index 000..03a19209661
--- /dev/null
+++ b/gcc/testsuite/g++.dg/tree-ssa/cxa_atexit-3.C
@@ -0,0 +1,19 @@
+/* { dg-do compile } */
+/* { dg-options "-O2 -fdump-tree-cddce1-details -fdump-tree-optimized" } */
+// { dg-require-effective-target cxa_atexit }
+/* PR tree-optimization/19661 */
+
+/* We should not remove the call to atexit as A::~A is unknown. */
+
+struct A {
+A();
+~A();
+};
+
+void foo () {
+ static A a;
+}
+
+/* { dg-final { scan-tree-dump-not "Deleting : __cxxabiv1::__cxa_atexit"
"cddce1" } } */
+/* { dg-final { scan-tree-dump-times "__cxa_atexit" 1 "optimized" } } */
+
diff --git a/gcc/testsuite/g++.dg/tree-ssa/cxa_atexit-4.C
b/gcc/testsuite/g++.dg/tree-ssa/cxa_atexit-4.C
new file mode 100644
index 000..b85a7efd16b
--- /dev/null
+++ b/gcc/testsuite/g++.dg/tree-ssa/cxa_atexit-4.C
@@ -0,0 +1,20 @@
+/* { dg-do compile { target c++11 } } */
+/* { dg-options "-O2 -fdump-tree-cddce1-details -fdump-tree-optimized -w" } */
+// { dg-require-effective-target cxa_atexit }
+/* PR tree-optimization/19661 */
+
+/* The call to axexit should be removed as A::~A() is a pure/const function
call
+ and there is no visible effect if A::~A() call does not happen. */
+
+struct A {
+A();
+[[gnu::pure]] ~A();
+};
+
+void foo () {
+ static A a;
+}
+
+/* { dg-final { scan-tree-dump-times "Deleting : __cxxabiv1::__cxa_atexit" 1
"cddce1" } } */
+/* { dg-final {