From mboxrd@z Thu Jan 1 00:00:00 1970 Return-Path: Received: (qmail 6499 invoked by alias); 11 Jul 2019 06:45:36 -0000 Mailing-List: contact gcc-patches-help@gcc.gnu.org; run by ezmlm Precedence: bulk List-Id: List-Archive: List-Post: List-Help: Sender: gcc-patches-owner@gcc.gnu.org Received: (qmail 6407 invoked by uid 89); 11 Jul 2019 06:45:27 -0000 Authentication-Results: sourceware.org; auth=none X-Spam-SWARE-Status: No, score=-17.2 required=5.0 tests=AWL,BAYES_00,GIT_PATCH_0,GIT_PATCH_1,GIT_PATCH_2,GIT_PATCH_3,KAM_SHORT,SPF_PASS autolearn=ham version=3.3.1 spammy= X-HELO: mx1.suse.de Received: from mx2.suse.de (HELO mx1.suse.de) (195.135.220.15) by sourceware.org (qpsmtpd/0.93/v0.84-503-g423c35a) with ESMTP; Thu, 11 Jul 2019 06:45:14 +0000 Received: from relay2.suse.de (unknown [195.135.220.254]) by mx1.suse.de (Postfix) with ESMTP id 9E83FAED6; Thu, 11 Jul 2019 06:45:07 +0000 (UTC) Subject: Re: [PATCH 1/2] Come up with function_decl_type and use it in tree_function_decl. To: Jason Merrill , Marc Glisse Cc: Richard Biener , gcc-patches@gcc.gnu.org, David Malcolm , dominik.infuehr@theobroma-systems.com, Nathan Sidwell References: <8305B5F4-2A96-4698-8C2E-3255658B5C12@theobroma-systems.com> <20171122103742.GN14653@tucnak> <20171129083045.GX2353@tucnak> <1511972121.27881.39.camel@redhat.com> <0dd24714-1f35-6a80-c607-7c8a332e95b9@suse.cz> <9D090495-3C97-4873-B0DF-2610B478F621@gmail.com> <70688da3-caf4-53c1-d0ee-63d16cbaadd9@suse.cz> <12f00f76-31c1-d3ca-a71b-c14b85892ef5@suse.cz> <6b43a610-4a16-cd1a-b7fa-ef2da7a77729@redhat.com> From: =?UTF-8?Q?Martin_Li=c5=a1ka?= Message-ID: <74ce7d0b-2610-8cb6-4c22-60f9ed2bfc23@suse.cz> Date: Thu, 11 Jul 2019 06:48:00 -0000 User-Agent: Mozilla/5.0 (X11; Linux x86_64; rv:60.0) Gecko/20100101 Thunderbird/60.7.2 MIME-Version: 1.0 In-Reply-To: <6b43a610-4a16-cd1a-b7fa-ef2da7a77729@redhat.com> Content-Type: multipart/mixed; boundary="------------A6DBABD32BA411480950BF28" X-IsSubscribed: yes X-SW-Source: 2019-07/txt/msg00844.txt.bz2 This is a multi-part message in MIME format. --------------A6DBABD32BA411480950BF28 Content-Type: text/plain; charset=iso-8859-15; format=flowed Content-Transfer-Encoding: 8bit Content-length: 3481 On 7/9/19 11:00 PM, Jason Merrill wrote: > On 7/9/19 6:17 AM, Marc Glisse wrote: >> On Tue, 9 Jul 2019, Martin Li¨ka wrote: >> >>> On 7/9/19 9:49 AM, Marc Glisse wrote: >>>> On Tue, 9 Jul 2019, Marc Glisse wrote: >>>> >>>>> On Mon, 8 Jul 2019, Martin Li¨ka wrote: >>>>> >>>>>>> The patch apparently has DECL_IS_OPERATOR_DELETE only on the replaceable global deallocation functions, not all delete operators, contrary to DECL_IS_OPERATOR_NEW, so the name is misleading. On the other hand, those seem to be the ones for which the optimization is legal (well, not quite, the rules are in terms of operator new, and I am not sure how well operator delete has to match, but close enough). >>>>>> >>>>>> Are you talking about this location where we set OPERATOR_NEW: >>>>>> https://github.com/gcc-mirror/gcc/blob/master/gcc/cp/decl.c#L13643 >>>>>> ? >>>>>> >>>>>> That's the only place where we set OPERATOR_NEW flag and not OPERATOR_DELETE. >>>>> >>>>> Yes, I think that's the place. >>>>> >>>>> Again, not setting DECL_IS_OPERATOR_DELETE on local operator delete >>>>> seems misleading, but setting it would let us optimize in cases where we >>>>> are not really allowed to. Maybe just rename your macro to >>>>> DECL_IS_GLOBAL_OPERATOR_DELETE? >>>> >>>> Hmm, I replied too fast. >>>> >>>> Global operator delete does not seem like a good terminology, the ones marked in the patch would be the usual (=non-placement) replaceable deallocation functions. >>>> >>>> I cannot find a requirement that operator new and operator delete should match. The rules to omit allocation are stated in terms of which operator new is called, but do not seem to care which operator delete is used. So allocating with the global operator new and deallocating with a class overload of operator delete can be removed, but not the reverse (not sure how they came up with such a rule...). > > Correct.  The standard just says that an implementation is allowed to omit a call to the replaceable ::operator new; it does not place any constraints on that, the conditions for such omission are left up to the implementation. > > If the user's code uses global new and class delete for the same pointer, that would suggest that they're doing something odd, and we might as well leave it alone.  I would expect this to be very rare. > >>>> Which means we would need: >>> >>> Thank you Mark for digging deep in that. >>> >>>> >>>> keep DECL_IS_OPERATOR_NEW for the current uses >>>> >>>> DECL_IS_REPLACEABLE_OPERATOR_NEW (equivalent to DECL_IS_OPERATOR_NEW && DECL_IS_MALLOC? not exactly but close I think) for DCE >>>> >>>> DECL_IS_OPERATOR_DELETE (which also includes some class overloads) for DCE >>> >>> Note that with the current version of the patch we are out of free bits in struct GTY(()) tree_function_decl. >>> Would it be possible to tweak the current patch to cover what you described? >> >> If you approximate DECL_IS_REPLACEABLE_OPERATOR_NEW with DECL_IS_OPERATOR_NEW && DECL_IS_MALLOC, it shouldn't need more bits than the current patch. I think the main difference is if a user adds attribute malloc to his class-specific operator new, where it will enable DCE, but since the attribute is non-standard, we can just document that behavior, it might even be desirable. > > Sure, it seems desirable to me. > > Jason Ok, I hopefully addressed the suggested improvements to the patch. Patch can bootstrap on x86_64-linux-gnu and survives regression tests. Ready to be installed? Thanks, Martin --------------A6DBABD32BA411480950BF28 Content-Type: text/x-patch; name="0001-Extend-DCE-to-remove-unnecessary-new-delete-pairs-PR.patch" Content-Transfer-Encoding: 7bit Content-Disposition: attachment; filename*0="0001-Extend-DCE-to-remove-unnecessary-new-delete-pairs-PR.pa"; filename*1="tch" Content-length: 17119 >From 771d9128144745fe530577912521fc8228ca7424 Mon Sep 17 00:00:00 2001 From: Martin Liska Date: Tue, 2 Jul 2019 09:08:27 +0200 Subject: [PATCH] Extend DCE to remove unnecessary new/delete-pairs (PR c++/23383). gcc/ChangeLog: 2019-07-02 Martin Liska Dominik Infuhr PR c++/23383 * common.opt: Add -fallocation-dce * gimple.c (gimple_call_operator_delete_p): New. * gimple.h (gimple_call_operator_delete_p): Likewise. * tree-core.h (enum function_decl_type): Add OPERATOR_DELETE. * tree-ssa-dce.c (mark_stmt_if_obviously_necessary): Handle DECL_IS_OPERATOR_DELETE_P. (mark_all_reaching_defs_necessary_1): Likewise. (propagate_necessity): Likewise. (eliminate_unnecessary_stmts): Handle gimple_call_operator_delete_p. * tree-streamer-in.c (unpack_ts_function_decl_value_fields): Add packing of OPERATOR_DELETE. * tree-streamer-out.c (pack_ts_function_decl_value_fields): Similarly here. * tree.h (DECL_IS_OPERATOR_DELETE_P): New. (DECL_SET_IS_OPERATOR_DELETE): New. (DECL_IS_REPLACEABLE_OPERATOR_NEW_P): Likewise. gcc/c/ChangeLog: 2019-07-02 Martin Liska Dominik Infuhr PR c++/23383 * c-decl.c (merge_decls): Merge OPERATOR_DELETE flag. gcc/cp/ChangeLog: 2019-07-02 Martin Liska Dominik Infuhr PR c++/23383 * decl.c (cxx_init_decl_processing): Mark delete operators with DECL_SET_IS_OPERATOR_DELETE. gcc/testsuite/ChangeLog: 2019-07-02 Martin Liska PR c++/23383 * g++.dg/cpp1y/new1.C: New test. libstdc++-v3/ChangeLog: 2019-07-02 Martin Liska Dominik Infuhr PR c++/23383 * testsuite/ext/bitmap_allocator/check_delete.cc: Add -fno-allocation-dce. * testsuite/ext/bitmap_allocator/check_new.cc: Likewise. * testsuite/ext/new_allocator/check_delete.cc: Likewise. * testsuite/ext/new_allocator/check_new.cc: Likewise. --- gcc/c/c-decl.c | 2 + gcc/common.opt | 4 ++ gcc/cp/decl.c | 24 ++++--- gcc/gimple.c | 12 ++++ gcc/gimple.h | 1 + gcc/testsuite/g++.dg/cpp1y/new1.C | 65 +++++++++++++++++++ gcc/tree-core.h | 1 + gcc/tree-ssa-dce.c | 34 ++++++++-- gcc/tree-streamer-in.c | 1 + gcc/tree-streamer-out.c | 1 + gcc/tree.h | 11 ++++ .../ext/bitmap_allocator/check_delete.cc | 2 + .../ext/bitmap_allocator/check_new.cc | 2 + .../ext/new_allocator/check_delete.cc | 2 + .../testsuite/ext/new_allocator/check_new.cc | 2 + 15 files changed, 150 insertions(+), 14 deletions(-) create mode 100644 gcc/testsuite/g++.dg/cpp1y/new1.C diff --git a/gcc/c/c-decl.c b/gcc/c/c-decl.c index b1392213fe3..42f7baf06e2 100644 --- a/gcc/c/c-decl.c +++ b/gcc/c/c-decl.c @@ -2641,6 +2641,8 @@ merge_decls (tree newdecl, tree olddecl, tree newtype, tree oldtype) DECL_IS_MALLOC (newdecl) |= DECL_IS_MALLOC (olddecl); if (DECL_IS_OPERATOR_NEW_P (olddecl)) DECL_SET_IS_OPERATOR_NEW (newdecl, true); + if (DECL_IS_OPERATOR_DELETE_P (olddecl)) + DECL_SET_IS_OPERATOR_DELETE (newdecl, true); TREE_READONLY (newdecl) |= TREE_READONLY (olddecl); DECL_PURE_P (newdecl) |= DECL_PURE_P (olddecl); DECL_IS_NOVOPS (newdecl) |= DECL_IS_NOVOPS (olddecl); diff --git a/gcc/common.opt b/gcc/common.opt index b998b25522b..11637c8cab0 100644 --- a/gcc/common.opt +++ b/gcc/common.opt @@ -2211,6 +2211,10 @@ Enum(live_patching_level) String(inline-only-static) Value(LIVE_PATCHING_INLINE_ EnumValue Enum(live_patching_level) String(inline-clone) Value(LIVE_PATCHING_INLINE_CLONE) +fallocation-dce +Common Report Var(flag_allocation_dce) Init(1) Optimization +Tell DCE to remove unused C++ allocations. + 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/decl.c b/gcc/cp/decl.c index 28adb205078..9cafec84c6e 100644 --- a/gcc/cp/decl.c +++ b/gcc/cp/decl.c @@ -4363,8 +4363,10 @@ cxx_init_decl_processing (void) opnew = push_cp_library_fn (VEC_NEW_EXPR, newtype, 0); DECL_IS_MALLOC (opnew) = 1; DECL_SET_IS_OPERATOR_NEW (opnew, true); - push_cp_library_fn (DELETE_EXPR, deltype, ECF_NOTHROW); - push_cp_library_fn (VEC_DELETE_EXPR, deltype, ECF_NOTHROW); + tree opdel = push_cp_library_fn (DELETE_EXPR, deltype, ECF_NOTHROW); + DECL_SET_IS_OPERATOR_DELETE (opdel, true); + opdel = push_cp_library_fn (VEC_DELETE_EXPR, deltype, ECF_NOTHROW); + DECL_SET_IS_OPERATOR_DELETE (opdel, true); if (flag_sized_deallocation) { /* Also push the sized deallocation variants: @@ -4376,8 +4378,10 @@ cxx_init_decl_processing (void) deltype = cp_build_type_attribute_variant (void_ftype_ptr_size, extvisattr); deltype = build_exception_variant (deltype, empty_except_spec); - push_cp_library_fn (DELETE_EXPR, deltype, ECF_NOTHROW); - push_cp_library_fn (VEC_DELETE_EXPR, deltype, ECF_NOTHROW); + opdel = push_cp_library_fn (DELETE_EXPR, deltype, ECF_NOTHROW); + DECL_SET_IS_OPERATOR_DELETE (opdel, true); + opdel = push_cp_library_fn (VEC_DELETE_EXPR, deltype, ECF_NOTHROW); + DECL_SET_IS_OPERATOR_DELETE (opdel, true); } if (aligned_new_threshold) @@ -4405,8 +4409,10 @@ cxx_init_decl_processing (void) align_type_node, NULL_TREE); deltype = cp_build_type_attribute_variant (deltype, extvisattr); deltype = build_exception_variant (deltype, empty_except_spec); - push_cp_library_fn (DELETE_EXPR, deltype, ECF_NOTHROW); - push_cp_library_fn (VEC_DELETE_EXPR, deltype, ECF_NOTHROW); + opdel = push_cp_library_fn (DELETE_EXPR, deltype, ECF_NOTHROW); + DECL_SET_IS_OPERATOR_DELETE (opdel, true); + opdel = push_cp_library_fn (VEC_DELETE_EXPR, deltype, ECF_NOTHROW); + DECL_SET_IS_OPERATOR_DELETE (opdel, true); if (flag_sized_deallocation) { @@ -4416,8 +4422,10 @@ cxx_init_decl_processing (void) NULL_TREE); deltype = cp_build_type_attribute_variant (deltype, extvisattr); deltype = build_exception_variant (deltype, empty_except_spec); - push_cp_library_fn (DELETE_EXPR, deltype, ECF_NOTHROW); - push_cp_library_fn (VEC_DELETE_EXPR, deltype, ECF_NOTHROW); + opdel = push_cp_library_fn (DELETE_EXPR, deltype, ECF_NOTHROW); + DECL_SET_IS_OPERATOR_DELETE (opdel, true); + opdel = push_cp_library_fn (VEC_DELETE_EXPR, deltype, ECF_NOTHROW); + DECL_SET_IS_OPERATOR_DELETE (opdel, true); } } diff --git a/gcc/gimple.c b/gcc/gimple.c index 513bde209e2..a0eac8703bd 100644 --- a/gcc/gimple.c +++ b/gcc/gimple.c @@ -2695,6 +2695,18 @@ gimple_builtin_call_types_compatible_p (const gimple *stmt, tree fndecl) return true; } +/* Return true when STMT is operator delete call. */ + +bool +gimple_call_operator_delete_p (const gcall *stmt) +{ + tree fndecl; + + if ((fndecl = gimple_call_fndecl (stmt)) != NULL_TREE) + return DECL_IS_OPERATOR_DELETE_P (fndecl); + return false; +} + /* Return true when STMT is builtins call. */ bool diff --git a/gcc/gimple.h b/gcc/gimple.h index 47070e7f409..f5872178109 100644 --- a/gcc/gimple.h +++ b/gcc/gimple.h @@ -1549,6 +1549,7 @@ extern alias_set_type gimple_get_alias_set (tree); extern bool gimple_ior_addresses_taken (bitmap, gimple *); extern bool gimple_builtin_call_types_compatible_p (const gimple *, tree); extern combined_fn gimple_call_combined_fn (const gimple *); +extern bool gimple_call_operator_delete_p (const gcall *); extern bool gimple_call_builtin_p (const gimple *); extern bool gimple_call_builtin_p (const gimple *, enum built_in_class); extern bool gimple_call_builtin_p (const gimple *, enum built_in_function); diff --git a/gcc/testsuite/g++.dg/cpp1y/new1.C b/gcc/testsuite/g++.dg/cpp1y/new1.C new file mode 100644 index 00000000000..a95dd4d1ee3 --- /dev/null +++ b/gcc/testsuite/g++.dg/cpp1y/new1.C @@ -0,0 +1,65 @@ +/* { dg-do compile } */ +/* { dg-options "-O2 -fdump-tree-cddce-details" } */ + +#include + +void +new_without_use() { + int *x = new int; +} + +void +new_array_without_use() { + int *x = new int[5]; +} + +void +new_primitive() { + int *x = new int; + delete x; +} + +void +new_array() { + int *x = new int[10]; + delete [] x; +} + +void +new_primitive_store() { + int *x = new int; + *x = 10; + delete x; +} + +void +new_primitive_load() { + int *x = new int; + int tmp = *x; + delete x; +} + +int +new_primitive_load_with_use() { + int *x = new int; + int tmp = *x; + delete x; + return tmp; +} + +void +new_array_store() { + int *x = new int[10]; + x[4] = 10; + delete [] x; +} + +void +new_array_load() { + int *x = new int[10]; + int tmp = x[4]; + delete [] x; +} + +/* { dg-final { scan-tree-dump-times "Deleting : operator delete" 5 "cddce1"} } */ +/* { dg-final { scan-tree-dump-times "Deleting : _\\d+ = operator new" 7 "cddce1"} } */ diff --git a/gcc/tree-core.h b/gcc/tree-core.h index 1b1a50df52a..e22e1c67699 100644 --- a/gcc/tree-core.h +++ b/gcc/tree-core.h @@ -1813,6 +1813,7 @@ enum function_decl_type { NONE, OPERATOR_NEW, + OPERATOR_DELETE, LAMBDA_FUNCTION /* 0 values left */ diff --git a/gcc/tree-ssa-dce.c b/gcc/tree-ssa-dce.c index 6398c1e4457..90b3f4d7c45 100644 --- a/gcc/tree-ssa-dce.c +++ b/gcc/tree-ssa-dce.c @@ -237,6 +237,12 @@ mark_stmt_if_obviously_necessary (gimple *stmt, bool aggressive) default:; } + + if (callee != NULL_TREE + && flag_allocation_dce + && DECL_IS_REPLACEABLE_OPERATOR_NEW_P (callee)) + return; + /* Most, but not all function calls are required. Function calls that produce no result and have no side effects (i.e. const pure functions) are unnecessary. */ @@ -588,6 +594,11 @@ mark_all_reaching_defs_necessary_1 (ao_ref *ref ATTRIBUTE_UNUSED, default:; } + + if (callee != NULL_TREE + && (DECL_IS_REPLACEABLE_OPERATOR_NEW_P (callee) + || DECL_IS_OPERATOR_DELETE_P (callee))) + return false; } if (! gimple_clobber_p (def_stmt)) @@ -774,7 +785,10 @@ propagate_necessity (bool aggressive) /* If this is a call to free which is directly fed by an allocation function do not mark that necessary through processing the argument. */ - if (gimple_call_builtin_p (stmt, BUILT_IN_FREE)) + if (gimple_call_builtin_p (stmt, BUILT_IN_FREE) + || (is_gimple_call (stmt) + && gimple_call_operator_delete_p (as_a (stmt)))) + { tree ptr = gimple_call_arg (stmt, 0); gimple *def_stmt; @@ -784,10 +798,11 @@ propagate_necessity (bool aggressive) if (TREE_CODE (ptr) == SSA_NAME && is_gimple_call (def_stmt = SSA_NAME_DEF_STMT (ptr)) && (def_callee = gimple_call_fndecl (def_stmt)) - && DECL_BUILT_IN_CLASS (def_callee) == BUILT_IN_NORMAL - && (DECL_FUNCTION_CODE (def_callee) == BUILT_IN_ALIGNED_ALLOC - || DECL_FUNCTION_CODE (def_callee) == BUILT_IN_MALLOC - || DECL_FUNCTION_CODE (def_callee) == BUILT_IN_CALLOC)) + && ((DECL_BUILT_IN_CLASS (def_callee) == BUILT_IN_NORMAL + && (DECL_FUNCTION_CODE (def_callee) == BUILT_IN_ALIGNED_ALLOC + || DECL_FUNCTION_CODE (def_callee) == BUILT_IN_MALLOC + || DECL_FUNCTION_CODE (def_callee) == BUILT_IN_CALLOC)) + || DECL_IS_REPLACEABLE_OPERATOR_NEW_P (def_callee))) continue; } @@ -842,6 +857,11 @@ propagate_necessity (bool aggressive) || DECL_FUNCTION_CODE (callee) == BUILT_IN_ASSUME_ALIGNED)) continue; + if (callee != NULL_TREE + && (DECL_IS_REPLACEABLE_OPERATOR_NEW_P (callee) + || DECL_IS_OPERATOR_DELETE_P (callee))) + continue; + /* Calls implicitly load from memory, their arguments in addition may explicitly perform memory loads. */ mark_all_reaching_defs_necessary (stmt); @@ -1262,7 +1282,9 @@ eliminate_unnecessary_stmts (void) defining statement of its argument is not necessary (and thus is getting removed). */ if (gimple_plf (stmt, STMT_NECESSARY) - && gimple_call_builtin_p (stmt, BUILT_IN_FREE)) + && (gimple_call_builtin_p (stmt, BUILT_IN_FREE) + || (is_gimple_call (stmt) + && gimple_call_operator_delete_p (as_a (stmt))))) { tree ptr = gimple_call_arg (stmt, 0); if (TREE_CODE (ptr) == SSA_NAME) diff --git a/gcc/tree-streamer-in.c b/gcc/tree-streamer-in.c index f2880f1021f..7ab72a7e0d7 100644 --- a/gcc/tree-streamer-in.c +++ b/gcc/tree-streamer-in.c @@ -334,6 +334,7 @@ unpack_ts_function_decl_value_fields (struct bitpack_d *bp, tree expr) DECL_IS_RETURNS_TWICE (expr) = (unsigned) bp_unpack_value (bp, 1); DECL_IS_MALLOC (expr) = (unsigned) bp_unpack_value (bp, 1); DECL_SET_IS_OPERATOR_NEW (expr, (unsigned) bp_unpack_value (bp, 1)); + DECL_SET_IS_OPERATOR_DELETE (expr, (unsigned) bp_unpack_value (bp, 1)); DECL_DECLARED_INLINE_P (expr) = (unsigned) bp_unpack_value (bp, 1); DECL_STATIC_CHAIN (expr) = (unsigned) bp_unpack_value (bp, 1); DECL_NO_INLINE_WARNING_P (expr) = (unsigned) bp_unpack_value (bp, 1); diff --git a/gcc/tree-streamer-out.c b/gcc/tree-streamer-out.c index 7e93e6c23bb..dbdc5d5e736 100644 --- a/gcc/tree-streamer-out.c +++ b/gcc/tree-streamer-out.c @@ -296,6 +296,7 @@ pack_ts_function_decl_value_fields (struct bitpack_d *bp, tree expr) bp_pack_value (bp, DECL_IS_RETURNS_TWICE (expr), 1); bp_pack_value (bp, DECL_IS_MALLOC (expr), 1); bp_pack_value (bp, DECL_IS_OPERATOR_NEW_P (expr), 1); + bp_pack_value (bp, DECL_IS_OPERATOR_DELETE_P (expr), 1); bp_pack_value (bp, DECL_DECLARED_INLINE_P (expr), 1); bp_pack_value (bp, DECL_STATIC_CHAIN (expr), 1); bp_pack_value (bp, DECL_NO_INLINE_WARNING_P (expr), 1); diff --git a/gcc/tree.h b/gcc/tree.h index 308836fba73..95cd583f4ae 100644 --- a/gcc/tree.h +++ b/gcc/tree.h @@ -3017,9 +3017,20 @@ set_function_decl_type (tree decl, function_decl_type t, bool set) #define DECL_IS_OPERATOR_NEW_P(NODE) \ (FUNCTION_DECL_CHECK (NODE)->function_decl.decl_type == OPERATOR_NEW) +#define DECL_IS_REPLACEABLE_OPERATOR_NEW_P(NODE) \ + (DECL_IS_OPERATOR_NEW_P (NODE) && DECL_IS_MALLOC (NODE)) + #define DECL_SET_IS_OPERATOR_NEW(NODE, VAL) \ set_function_decl_type (FUNCTION_DECL_CHECK (NODE), OPERATOR_NEW, VAL) +/* Nonzero in a FUNCTION_DECL means this function should be treated as + C++ operator delete. */ +#define DECL_IS_OPERATOR_DELETE_P(NODE) \ + (FUNCTION_DECL_CHECK (NODE)->function_decl.decl_type == OPERATOR_DELETE) + +#define DECL_SET_IS_OPERATOR_DELETE(NODE, VAL) \ + set_function_decl_type (FUNCTION_DECL_CHECK (NODE), OPERATOR_DELETE, VAL) + /* Nonzero in a FUNCTION_DECL means this function may return more than once. */ #define DECL_IS_RETURNS_TWICE(NODE) \ diff --git a/libstdc++-v3/testsuite/ext/bitmap_allocator/check_delete.cc b/libstdc++-v3/testsuite/ext/bitmap_allocator/check_delete.cc index 1b445643599..1ad1f3c242c 100644 --- a/libstdc++-v3/testsuite/ext/bitmap_allocator/check_delete.cc +++ b/libstdc++-v3/testsuite/ext/bitmap_allocator/check_delete.cc @@ -15,6 +15,8 @@ // with this library; see the file COPYING3. If not see // . +// { dg-options "-fno-allocation-dce" } + // 20.4.1.1 allocator members #include diff --git a/libstdc++-v3/testsuite/ext/bitmap_allocator/check_new.cc b/libstdc++-v3/testsuite/ext/bitmap_allocator/check_new.cc index 0c5f9b6da7c..be16952c10d 100644 --- a/libstdc++-v3/testsuite/ext/bitmap_allocator/check_new.cc +++ b/libstdc++-v3/testsuite/ext/bitmap_allocator/check_new.cc @@ -15,6 +15,8 @@ // with this library; see the file COPYING3. If not see // . +// { dg-options "-fno-allocation-dce" } + // 20.4.1.1 allocator members #include diff --git a/libstdc++-v3/testsuite/ext/new_allocator/check_delete.cc b/libstdc++-v3/testsuite/ext/new_allocator/check_delete.cc index 8778bc9ccaa..dccee1d5293 100644 --- a/libstdc++-v3/testsuite/ext/new_allocator/check_delete.cc +++ b/libstdc++-v3/testsuite/ext/new_allocator/check_delete.cc @@ -17,6 +17,8 @@ // with this library; see the file COPYING3. If not see // . +// { dg-options "-fno-allocation-dce" } + // 20.4.1.1 allocator members #include diff --git a/libstdc++-v3/testsuite/ext/new_allocator/check_new.cc b/libstdc++-v3/testsuite/ext/new_allocator/check_new.cc index fd90d284224..a1d164a6d49 100644 --- a/libstdc++-v3/testsuite/ext/new_allocator/check_new.cc +++ b/libstdc++-v3/testsuite/ext/new_allocator/check_new.cc @@ -17,6 +17,8 @@ // with this library; see the file COPYING3. If not see // . +// { dg-options "-fno-allocation-dce" } + // 20.4.1.1 allocator members #include -- 2.22.0 --------------A6DBABD32BA411480950BF28--