diff options
author | Jason Merrill <jason@redhat.com> | 2015-02-12 15:28:41 -0500 |
---|---|---|
committer | Jason Merrill <jason@gcc.gnu.org> | 2015-02-12 15:28:41 -0500 |
commit | f522930c8fe1554c4af6f4d87b6529be1b716ffc (patch) | |
tree | 2d3f895a3da2356f70340af326c8229b80d19433 /gcc | |
parent | bc81eb3f77b27d46e25c218cfd9f32c89cc36b3c (diff) | |
download | gcc-f522930c8fe1554c4af6f4d87b6529be1b716ffc.zip gcc-f522930c8fe1554c4af6f4d87b6529be1b716ffc.tar.gz gcc-f522930c8fe1554c4af6f4d87b6529be1b716ffc.tar.bz2 |
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
Diffstat (limited to 'gcc')
-rw-r--r-- | gcc/ChangeLog | 4 | ||||
-rw-r--r-- | gcc/common.opt | 5 | ||||
-rw-r--r-- | gcc/cp/ChangeLog | 5 | ||||
-rw-r--r-- | gcc/cp/decl.c | 22 | ||||
-rw-r--r-- | gcc/doc/invoke.texi | 10 | ||||
-rw-r--r-- | gcc/testsuite/g++.dg/opt/flifetime-dse1.C | 23 |
6 files changed, 60 insertions, 9 deletions
diff --git a/gcc/ChangeLog b/gcc/ChangeLog index 60af263..767e880 100644 --- a/gcc/ChangeLog +++ b/gcc/ChangeLog @@ -1,3 +1,7 @@ +2015-02-12 Jason Merrill <jason@redhat.com> + + * common.opt (-flifetime-dse): New. + 2015-02-12 Jakub Jelinek <jakub@redhat.com> PR sanitizer/65019 diff --git a/gcc/common.opt b/gcc/common.opt index cf4e503..6e65757 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 e460c55..4f75646 100644 --- a/gcc/cp/ChangeLog +++ b/gcc/cp/ChangeLog @@ -1,3 +1,8 @@ +2015-02-12 Jason Merrill <jason@redhat.com> + + * decl.c (begin_destructor_body): Condition clobber on + -flifetime-dse. + 2015-02-12 Andrea Azzarone <azzaronea@gmail.com> PR c++/64959 diff --git a/gcc/cp/decl.c b/gcc/cp/decl.c index 50b0624..810acd5 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 8a04790..5cce4f7 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 0000000..733d28a --- /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(); +} |