From: Jason Merrill Date: Thu, 26 Feb 2015 02:43:52 +0000 (-0500) Subject: common.opt (-flifetime-dse): New. X-Git-Tag: releases/gcc-4.9.3~322 X-Git-Url: http://git.ipfire.org/cgi-bin/gitweb.cgi?a=commitdiff_plain;h=f85347cdaee5fb3ce8b77266e7929e29d60ed5cf;p=thirdparty%2Fgcc.git 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: r220996 --- diff --git a/gcc/ChangeLog b/gcc/ChangeLog index 326a98ddfb44..0d8f66fff7c7 100644 --- a/gcc/ChangeLog +++ b/gcc/ChangeLog @@ -1,3 +1,7 @@ +2015-02-25 Jason Merrill + + * common.opt (-flifetime-dse): New. + 2015-02-25 Kai Tietz PR tree-optimization/61917 diff --git a/gcc/common.opt b/gcc/common.opt index 2259f29d19e4..51ddd77c9a9c 100644 --- a/gcc/common.opt +++ b/gcc/common.opt @@ -1745,6 +1745,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 90f2923f99e1..30b1c3f24fd1 100644 --- a/gcc/cp/ChangeLog +++ b/gcc/cp/ChangeLog @@ -1,3 +1,8 @@ +2015-02-25 Jason Merrill + + * decl.c (begin_destructor_body): Condition clobber on + -flifetime-dse. + 2015-02-13 Jason Merrill PR c++/62017 diff --git a/gcc/cp/decl.c b/gcc/cp/decl.c index 631ce9191325..b0bbf9e4fb25 100644 --- a/gcc/cp/decl.c +++ b/gcc/cp/decl.c @@ -13667,15 +13667,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 870e637f93df..1aea050d0cdd 100644 --- a/gcc/doc/invoke.texi +++ b/gcc/doc/invoke.texi @@ -7401,6 +7401,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 000000000000..733d28a794f4 --- /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(); +}