From f522930c8fe1554c4af6f4d87b6529be1b716ffc Mon Sep 17 00:00:00 2001 From: Jason Merrill Date: Thu, 12 Feb 2015 15:28:41 -0500 Subject: [PATCH] common.opt (-flifetime-dse): New. gcc/ * common.opt (-flifetime-dse): New. gcc/cp/ * decl.c (begin_destructor_body): Condition clobber on -flifetime-dse. From-SVN: r220657 --- gcc/ChangeLog | 4 ++++ gcc/common.opt | 5 +++++ gcc/cp/ChangeLog | 5 +++++ gcc/cp/decl.c | 22 +++++++++++++--------- gcc/doc/invoke.texi | 10 ++++++++++ gcc/testsuite/g++.dg/opt/flifetime-dse1.C | 23 +++++++++++++++++++++++ 6 files changed, 60 insertions(+), 9 deletions(-) create mode 100644 gcc/testsuite/g++.dg/opt/flifetime-dse1.C diff --git a/gcc/ChangeLog b/gcc/ChangeLog index 60af263eebd..767e8803b9a 100644 --- a/gcc/ChangeLog +++ b/gcc/ChangeLog @@ -1,3 +1,7 @@ +2015-02-12 Jason Merrill + + * common.opt (-flifetime-dse): New. + 2015-02-12 Jakub Jelinek PR sanitizer/65019 diff --git a/gcc/common.opt b/gcc/common.opt index cf4e5035e55..6e65757b1b1 100644 --- a/gcc/common.opt +++ b/gcc/common.opt @@ -1856,6 +1856,11 @@ fregmove Common Ignore Does nothing. Preserved for backward compatibility. +flifetime-dse +Common Report Var(flag_lifetime_dse) Init(1) Optimization +Tell DSE that the storage for a C++ object is dead when the constructor +starts and when the destructor finishes. + flive-range-shrinkage Common Report Var(flag_live_range_shrinkage) Init(0) Optimization Relief of register pressure through live range shrinkage diff --git a/gcc/cp/ChangeLog b/gcc/cp/ChangeLog index e460c55619d..4f7564644e2 100644 --- a/gcc/cp/ChangeLog +++ b/gcc/cp/ChangeLog @@ -1,3 +1,8 @@ +2015-02-12 Jason Merrill + + * decl.c (begin_destructor_body): Condition clobber on + -flifetime-dse. + 2015-02-12 Andrea Azzarone PR c++/64959 diff --git a/gcc/cp/decl.c b/gcc/cp/decl.c index 50b062497fa..810acd56e60 100644 --- a/gcc/cp/decl.c +++ b/gcc/cp/decl.c @@ -13936,15 +13936,19 @@ begin_destructor_body (void) initialize_vtbl_ptrs (current_class_ptr); finish_compound_stmt (compound_stmt); - /* Insert a cleanup to let the back end know that the object is dead - when we exit the destructor, either normally or via exception. */ - tree btype = CLASSTYPE_AS_BASE (current_class_type); - tree clobber = build_constructor (btype, NULL); - TREE_THIS_VOLATILE (clobber) = true; - tree bref = build_nop (build_reference_type (btype), current_class_ptr); - bref = convert_from_reference (bref); - tree exprstmt = build2 (MODIFY_EXPR, btype, bref, clobber); - finish_decl_cleanup (NULL_TREE, exprstmt); + if (flag_lifetime_dse) + { + /* Insert a cleanup to let the back end know that the object is dead + when we exit the destructor, either normally or via exception. */ + tree btype = CLASSTYPE_AS_BASE (current_class_type); + tree clobber = build_constructor (btype, NULL); + TREE_THIS_VOLATILE (clobber) = true; + tree bref = build_nop (build_reference_type (btype), + current_class_ptr); + bref = convert_from_reference (bref); + tree exprstmt = build2 (MODIFY_EXPR, btype, bref, clobber); + finish_decl_cleanup (NULL_TREE, exprstmt); + } /* And insert cleanups for our bases and members so that they will be properly destroyed if we throw. */ diff --git a/gcc/doc/invoke.texi b/gcc/doc/invoke.texi index 8a04790fc1a..5cce4f73634 100644 --- a/gcc/doc/invoke.texi +++ b/gcc/doc/invoke.texi @@ -7888,6 +7888,16 @@ registers after writing to their lower 32-bit half. Enabled for Alpha, AArch64 and x86 at levels @option{-O2}, @option{-O3}, @option{-Os}. +@item -fno-lifetime-dse +@opindex fno-lifetime-dse +In C++ the value of an object is only affected by changes within its +lifetime: when the constructor begins, the object has an indeterminate +value, and any changes during the lifetime of the object are dead when +the object is destroyed. Normally dead store elimination will take +advantage of this; if your code relies on the value of the object +storage persisting beyond the lifetime of the object, you can use this +flag to disable this optimization. + @item -flive-range-shrinkage @opindex flive-range-shrinkage Attempt to decrease register pressure through register live range diff --git a/gcc/testsuite/g++.dg/opt/flifetime-dse1.C b/gcc/testsuite/g++.dg/opt/flifetime-dse1.C new file mode 100644 index 00000000000..733d28a794f --- /dev/null +++ b/gcc/testsuite/g++.dg/opt/flifetime-dse1.C @@ -0,0 +1,23 @@ +// { dg-options "-O3 -fno-lifetime-dse" } +// { dg-do run } + +typedef __SIZE_TYPE__ size_t; +inline void * operator new (size_t, void *p) { return p; } + +struct A +{ + int i; + A() {} + ~A() {} +}; + +int main() +{ + int ar[1]; + + A* ap = new(ar) A; + ap->i = 42; + ap->~A(); + + if (ar[0] != 42) __builtin_abort(); +} -- 2.30.2