* [C++ PATCH] Optimize C++ comdat ctors/dtors in classes without virtual bases (PR c++/3187, take 3) @ 2009-11-30 22:38 Jakub Jelinek 2009-12-01 3:53 ` Jason Merrill ` (2 more replies) 0 siblings, 3 replies; 17+ messages in thread From: Jakub Jelinek @ 2009-11-30 22:38 UTC (permalink / raw) To: Jason Merrill; +Cc: gcc-patches Hi! Here is the latest version of the cdtor optimization patch. The comdat group name is *[CD]5* and if the dtor is virtual, deleting dtor is emitted into that comdat group as well. libstdc++ symbol version script has been adjusted, so that it exports exactly what it used to export before this patch. On x86_64-linux this patch saves 21KB of libstdc++.so's .text. Bootstrapped/regtested on x86_64-linux, ok for trunk? 2009-11-30 Jakub Jelinek <jakub@redhat.com> PR c++/3187 * optimize.c (cdtor_comdat_group): New function. (maybe_clone_body): Also optimize DECL_COMDAT base/complete cdtors and in that case put also the deleting dtor in the same comdat group as base and complete dtor if dtor is virtual. * config/abi/pre/gnu.ver: Don't export certain base dtors that weren't previously exported. --- gcc/cp/optimize.c.jj 2009-11-30 15:53:13.000000000 +0100 +++ gcc/cp/optimize.c 2009-11-30 19:18:51.000000000 +0100 @@ -142,6 +142,46 @@ build_delete_destructor_body (tree delet } } +/* Return name of comdat group for complete and base ctor (or dtor) + that have the same body. If dtor is virtual, deleting dtor goes + into this comdat group as well. */ + +static tree +cdtor_comdat_group (tree complete, tree base) +{ + tree complete_name = DECL_COMDAT_GROUP (complete); + tree base_name = DECL_COMDAT_GROUP (base); + char *grp_name; + const char *p, *q; + bool diff_seen = false; + size_t idx; + if (complete_name == NULL) + complete_name = cxx_comdat_group (complete); + if (base_name == NULL) + base_name = cxx_comdat_group (base); + gcc_assert (IDENTIFIER_LENGTH (complete_name) + == IDENTIFIER_LENGTH (base_name)); + grp_name = XALLOCAVEC (char, IDENTIFIER_LENGTH (complete_name) + 1); + p = IDENTIFIER_POINTER (complete_name); + q = IDENTIFIER_POINTER (base_name); + for (idx = 0; idx < IDENTIFIER_LENGTH (complete_name); idx++) + if (p[idx] == q[idx]) + grp_name[idx] = p[idx]; + else + { + gcc_assert (!diff_seen + && idx > 0 + && (p[idx - 1] == 'C' || p[idx - 1] == 'D') + && p[idx] == '1' + && q[idx] == '2'); + grp_name[idx] = '5'; + diff_seen = true; + } + grp_name[idx] = '\0'; + gcc_assert (diff_seen); + return get_identifier (grp_name); +} + /* FN is a function that has a complete body. Clone the body as necessary. Returns nonzero if there's no longer any need to process the main body. */ @@ -149,6 +189,7 @@ build_delete_destructor_body (tree delet bool maybe_clone_body (tree fn) { + tree comdat_group = NULL_TREE; tree clone; tree fns[3]; bool first = true; @@ -248,12 +289,28 @@ maybe_clone_body (tree fn) && idx == 1 && !flag_use_repository && DECL_INTERFACE_KNOWN (fns[0]) - && !DECL_ONE_ONLY (fns[0]) + && (SUPPORTS_ONE_ONLY || !DECL_WEAK (fns[0])) + && (!DECL_ONE_ONLY (fns[0]) + || (HAVE_COMDAT_GROUP && DECL_WEAK (fns[0]))) && cgraph_same_body_alias (clone, fns[0])) { alias = true; + if (DECL_ONE_ONLY (fns[0])) + { + /* For comdat base and complete cdtors put them + into the same, *[CD]5* comdat group instead of + *[CD][12]*. */ + comdat_group = cdtor_comdat_group (fns[1], fns[0]); + DECL_COMDAT_GROUP (fns[0]) = comdat_group; + DECL_COMDAT_GROUP (fns[1]) = comdat_group; + } emit_associated_thunks (clone); } + else if (idx == 2 && comdat_group) + /* If *[CD][12]* dtors go into the *[CD]5* comdat group + and dtor is virtual, it goes into the same comdat group + as well. */ + DECL_COMDAT_GROUP (fns[2]) = comdat_group; /* Build the delete destructor by calling complete destructor and delete function. */ --- libstdc++-v3/config/abi/pre/gnu.ver.jj 2009-11-12 14:14:03.000000000 +0100 +++ libstdc++-v3/config/abi/pre/gnu.ver 2009-11-30 20:47:34.000000000 +0100 @@ -72,13 +72,18 @@ GLIBCXX_3.4 { std::c[v-z]*; # std::[d-g]*; std::d[a-d]*; - std::d[f-z]*; + std::d[f-n]*; + std::domain_error::d*; +# std::domain_error::~d*; + std::d[p-z]*; std::e[a-q]*; std::error[^_]*; std::e[s-z]*; std::gslice*; std::h[^a]*; - std::i[a-n]*; + std::i[a-m]*; + std::invalid_argument::i*; +# std::invalid_argument::~i*; # std::ios_base::[A-Ha-z]*; std::ios_base::[A-Ha-f]*; std::ios_base::goodbit; @@ -94,7 +99,8 @@ GLIBCXX_3.4 { std::istrstream*; std::i[t-z]*; std::[A-Zj-k]*; - std::length_error*; + std::length_error::l*; +# std::length_error::~l*; std::logic_error*; std::locale::[A-Za-e]*; std::locale::facet::[A-Za-z]*; @@ -122,10 +128,14 @@ GLIBCXX_3.4 { std::nu[^m]*; std::num[^e]*; std::ostrstream*; - std::out_of_range*; - std::overflow_error*; + std::out_of_range::o*; +# std::out_of_range::~o*; + std::overflow_error::o*; +# std::overflow_error::~o*; # std::[p-q]*; - std::r[^e]*; + std::r[^ae]*; + std::range_error::r*; +# std::range_error::~r*; std::re[^t]*; # std::rethrow_exception std::set_new_handler*; @@ -143,7 +153,8 @@ GLIBCXX_3.4 { std::tr1::h[^a]*; std::t[s-z]*; # std::[A-Zu-z]*; - std::underflow_error*; + std::underflow_error::u*; +# std::underflow_error::~u*; std::uncaught_exception*; std::unexpected*; std::[A-Zv-z]*; @@ -284,7 +295,8 @@ GLIBCXX_3.4 { _ZNSt15basic_streambufI[cw]St11char_traitsI[cw]EEaSERKS2_; # std::basic_stringbuf - _ZNSt15basic_stringbufI[cw]St11char_traitsI[cw]ESaI[cw]EE[CD]*; + _ZNSt15basic_stringbufI[cw]St11char_traitsI[cw]ESaI[cw]EEC*; + _ZNSt15basic_stringbufI[cw]St11char_traitsI[cw]ESaI[cw]EED[^2]*; _ZNSt15basic_stringbufI[cw]St11char_traitsI[cw]ESaI[cw]EE[0-9][a-r]*; _ZNSt15basic_stringbufI[cw]St11char_traitsI[cw]ESaI[cw]EE[0-9]seek*; _ZNSt15basic_stringbufI[cw]St11char_traitsI[cw]ESaI[cw]EE[0-9]set*; @@ -639,6 +651,16 @@ GLIBCXX_3.4 { _ZGVNSt[^1]*; _ZGVNSt1[^7]*; + # complete and deleting destructors where base destructors should not + # be exported. + _ZNSt11range_errorD[01]Ev; + _ZNSt12domain_errorD[01]Ev; + _ZNSt12length_errorD[01]Ev; + _ZNSt12out_of_rangeD[01]Ev; + _ZNSt14overflow_errorD[01]Ev; + _ZNSt15underflow_errorD[01]Ev; + _ZNSt16invalid_argumentD[01]Ev; + # virtual function thunks _ZThn8_NS*; _ZThn16_NS*; @@ -891,7 +913,8 @@ GLIBCXX_3.4.10 { _ZNSt15basic_streambufI[cw]St11char_traitsI[cw]EE6stosscEv; _ZN9__gnu_cxx18stdio_sync_filebufI[cw]St11char_traitsI[cw]EE4syncEv; - _ZN9__gnu_cxx18stdio_sync_filebufI[cw]St11char_traitsI[cw]EE[5-9CD]*; + _ZN9__gnu_cxx18stdio_sync_filebufI[cw]St11char_traitsI[cw]EE[5-9C]*; + _ZN9__gnu_cxx18stdio_sync_filebufI[cw]St11char_traitsI[cw]EED[^2]*; } GLIBCXX_3.4.9; Jakub ^ permalink raw reply [flat|nested] 17+ messages in thread
* Re: [C++ PATCH] Optimize C++ comdat ctors/dtors in classes without virtual bases (PR c++/3187, take 3) 2009-11-30 22:38 [C++ PATCH] Optimize C++ comdat ctors/dtors in classes without virtual bases (PR c++/3187, take 3) Jakub Jelinek @ 2009-12-01 3:53 ` Jason Merrill 2009-12-01 8:07 ` Jakub Jelinek 2009-12-01 9:52 ` [C++ PATCH] Optimize C++ comdat ctors/dtors in classes without virtual bases (PR c++/3187, take 4) Jakub Jelinek 2009-12-01 21:15 ` [C++ PATCH] Optimize C++ comdat ctors/dtors in classes without virtual bases (PR c++/3187, take 3) Daniel Jacobowitz 2 siblings, 1 reply; 17+ messages in thread From: Jason Merrill @ 2009-12-01 3:53 UTC (permalink / raw) To: Jakub Jelinek; +Cc: gcc-patches On 11/30/2009 05:36 PM, Jakub Jelinek wrote: > * config/abi/pre/gnu.ver: Don't export certain base dtors that > weren't previously exported. Is this necessary? I thought it was OK to add new exported symbols, but you'd know better than I. > + && (SUPPORTS_ONE_ONLY || !DECL_WEAK (fns[0])) This test seems unnecessary; I don't see the problem with using aliases on targets with weak symbols but no one-only support. Jason ^ permalink raw reply [flat|nested] 17+ messages in thread
* Re: [C++ PATCH] Optimize C++ comdat ctors/dtors in classes without virtual bases (PR c++/3187, take 3) 2009-12-01 3:53 ` Jason Merrill @ 2009-12-01 8:07 ` Jakub Jelinek 2009-12-01 15:39 ` Jason Merrill 0 siblings, 1 reply; 17+ messages in thread From: Jakub Jelinek @ 2009-12-01 8:07 UTC (permalink / raw) To: Jason Merrill; +Cc: gcc-patches, libstdc++ On Mon, Nov 30, 2009 at 10:46:31PM -0500, Jason Merrill wrote: > On 11/30/2009 05:36 PM, Jakub Jelinek wrote: > > * config/abi/pre/gnu.ver: Don't export certain base dtors that > > weren't previously exported. > > Is this necessary? I thought it was OK to add new exported symbols, but > you'd know better than I. Yes. We definitely must not export them with the old symbol versions where they have not been exported before (GLIBCXX_3.4 and GLIBCXX_3.4.10). We could export them at @@GLIBCXX_3.4.14 (which would mean the same gnu.ver changes and mentioning the D2 symbols in GLIBCXX_3.4.14 section), but that has a problem that we only emit those D2 symbols when HAVE_COMDAT_GROUP, so in !HAVE_COMDAT_GROUP configurations the exported list would be different. I have no idea how to force generation of those symbols otherwise so that they are exported on all targets. > > >+ && (SUPPORTS_ONE_ONLY || !DECL_WEAK (fns[0])) > > This test seems unnecessary; I don't see the problem with using aliases > on targets with weak symbols but no one-only support. This is to fix AIX (and is actually unrelated to this patch, it can be dealt with separately). In theory it should work well, but David Edelsohn reported that some symbols were missing from libstdc++.so without it. I have no access to AIX and have no idea what AIX linker is doing with the symbols. !SUPPORTS_ONE_ONLY targets don't have DECL_ONE_ONLY, but instead just use DECL_WEAK symbols, so I thought when we don't do this optimization on !HAVE_COMDAT_GROUP SUPPORTS_ONE_ONLY targets for comdat and comdat-like symbols, the world wouldn't end if we didn't support it even on the far rarer !HAVE_COMDAT_GROUP !SUPPORTS_ONE_ONLY targets. Jakub ^ permalink raw reply [flat|nested] 17+ messages in thread
* Re: [C++ PATCH] Optimize C++ comdat ctors/dtors in classes without virtual bases (PR c++/3187, take 3) 2009-12-01 8:07 ` Jakub Jelinek @ 2009-12-01 15:39 ` Jason Merrill 0 siblings, 0 replies; 17+ messages in thread From: Jason Merrill @ 2009-12-01 15:39 UTC (permalink / raw) To: Jakub Jelinek; +Cc: gcc-patches, libstdc++ On 12/01/2009 02:45 AM, Jakub Jelinek wrote: > On Mon, Nov 30, 2009 at 10:46:31PM -0500, Jason Merrill wrote: >> On 11/30/2009 05:36 PM, Jakub Jelinek wrote: >>> * config/abi/pre/gnu.ver: Don't export certain base dtors that >>> weren't previously exported. >> >> Is this necessary? > > Yes. OK. >>> + && (SUPPORTS_ONE_ONLY || !DECL_WEAK (fns[0])) >> >> This test seems unnecessary; I don't see the problem with using aliases >> on targets with weak symbols but no one-only support. > > This is to fix AIX (and is actually unrelated to this patch, it can be dealt > with separately). In theory it should work well, but David Edelsohn > reported that some symbols were missing from libstdc++.so without it. I > have no access to AIX and have no idea what AIX linker is doing with the > symbols. OK. The patch is OK. Jason ^ permalink raw reply [flat|nested] 17+ messages in thread
* [C++ PATCH] Optimize C++ comdat ctors/dtors in classes without virtual bases (PR c++/3187, take 4) 2009-11-30 22:38 [C++ PATCH] Optimize C++ comdat ctors/dtors in classes without virtual bases (PR c++/3187, take 3) Jakub Jelinek 2009-12-01 3:53 ` Jason Merrill @ 2009-12-01 9:52 ` Jakub Jelinek 2009-12-01 15:40 ` Jakub Jelinek 2009-12-01 19:35 ` [C++ PATCH] Optimize C++ comdat ctors/dtors in classes without virtual bases (PR c++/3187, take 5) Jakub Jelinek 2009-12-01 21:15 ` [C++ PATCH] Optimize C++ comdat ctors/dtors in classes without virtual bases (PR c++/3187, take 3) Daniel Jacobowitz 2 siblings, 2 replies; 17+ messages in thread From: Jakub Jelinek @ 2009-12-01 9:52 UTC (permalink / raw) To: Jason Merrill; +Cc: gcc-patches [-- Attachment #1: Type: text/plain, Size: 1458 bytes --] Hi! On Mon, Nov 30, 2009 at 05:36:53PM -0500, Jakub Jelinek wrote: > > Here is the latest version of the cdtor optimization patch. > The comdat group name is *[CD]5* and if the dtor is virtual, deleting dtor > is emitted into that comdat group as well. > libstdc++ symbol version script has been adjusted, so that it exports > exactly what it used to export before this patch. > On x86_64-linux this patch saves 21KB of libstdc++.so's .text. Apparently the previous patch didn't actually put deleting dtors in the D5 comdat group, because expand_or_defer_fn changed again its DECL_COMDAT_GROUP to the D0 one. The first patch fixes that by setting DECL_COMDAT_GROUP of the alias (which doesn't matter much) and of the deleting dtor after that call. Unfortunately, when bootstrapping with extra checking patch (second patch) where I wanted to verify that for classes with comdat virtual dtors we always emit either both D2 (and D1 alias to it) and D0 dtor, or none of them, build in libstdc++ revealed that we emit e.g. in complex_io.cc (reduced testcase attached last, cc1plus -O2 cplx.ii) only the _ZN1DIi1BIiE1CIiEED2Ev (and _ZN1DIi1BIiE1CIiEED1Ev alias) dtor in the _ZN1DIi1BIiE1CIiEED5Ev comdat group, but not _ZN1DIi1BIiE1CIiEED0Ev. The class is extern template class, so either the g++ is buggy and emits something it never should, because the template is extern, or putting the *D0* dtors also in the *D5* comdat group is not a good idea. Jakub [-- Attachment #2: Y477 --] [-- Type: text/plain, Size: 6526 bytes --] 2009-12-01 Jakub Jelinek <jakub@redhat.com> PR c++/3187 * optimize.c (cdtor_comdat_group): New function. (maybe_clone_body): Also optimize DECL_COMDAT base/complete cdtors and in that case put also the deleting dtor in the same comdat group as base and complete dtor if dtor is virtual. * config/abi/pre/gnu.ver: Don't export certain base dtors that weren't previously exported. --- gcc/cp/optimize.c.jj 2009-11-30 15:53:13.000000000 +0100 +++ gcc/cp/optimize.c 2009-11-30 19:18:51.000000000 +0100 @@ -142,6 +142,46 @@ build_delete_destructor_body (tree delet } } +/* Return name of comdat group for complete and base ctor (or dtor) + that have the same body. If dtor is virtual, deleting dtor goes + into this comdat group as well. */ + +static tree +cdtor_comdat_group (tree complete, tree base) +{ + tree complete_name = DECL_COMDAT_GROUP (complete); + tree base_name = DECL_COMDAT_GROUP (base); + char *grp_name; + const char *p, *q; + bool diff_seen = false; + size_t idx; + if (complete_name == NULL) + complete_name = cxx_comdat_group (complete); + if (base_name == NULL) + base_name = cxx_comdat_group (base); + gcc_assert (IDENTIFIER_LENGTH (complete_name) + == IDENTIFIER_LENGTH (base_name)); + grp_name = XALLOCAVEC (char, IDENTIFIER_LENGTH (complete_name) + 1); + p = IDENTIFIER_POINTER (complete_name); + q = IDENTIFIER_POINTER (base_name); + for (idx = 0; idx < IDENTIFIER_LENGTH (complete_name); idx++) + if (p[idx] == q[idx]) + grp_name[idx] = p[idx]; + else + { + gcc_assert (!diff_seen + && idx > 0 + && (p[idx - 1] == 'C' || p[idx - 1] == 'D') + && p[idx] == '1' + && q[idx] == '2'); + grp_name[idx] = '5'; + diff_seen = true; + } + grp_name[idx] = '\0'; + gcc_assert (diff_seen); + return get_identifier (grp_name); +} + /* FN is a function that has a complete body. Clone the body as necessary. Returns nonzero if there's no longer any need to process the main body. */ @@ -149,6 +189,7 @@ build_delete_destructor_body (tree delet bool maybe_clone_body (tree fn) { + tree comdat_group = NULL_TREE; tree clone; tree fns[3]; bool first = true; @@ -248,10 +289,20 @@ maybe_clone_body (tree fn) && idx == 1 && !flag_use_repository && DECL_INTERFACE_KNOWN (fns[0]) - && !DECL_ONE_ONLY (fns[0]) + && (SUPPORTS_ONE_ONLY || !DECL_WEAK (fns[0])) + && (!DECL_ONE_ONLY (fns[0]) + || (HAVE_COMDAT_GROUP && DECL_WEAK (fns[0]))) && cgraph_same_body_alias (clone, fns[0])) { alias = true; + if (DECL_ONE_ONLY (fns[0])) + { + /* For comdat base and complete cdtors put them + into the same, *[CD]5* comdat group instead of + *[CD][12]*. */ + comdat_group = cdtor_comdat_group (fns[1], fns[0]); + DECL_COMDAT_GROUP (fns[0]) = comdat_group; + } emit_associated_thunks (clone); } @@ -333,6 +384,15 @@ maybe_clone_body (tree fn) } pop_from_top_level (); + if (comdat_group) + { + DECL_COMDAT_GROUP (fns[1]) = comdat_group; + if (fns[2]) + /* If *[CD][12]* dtors go into the *[CD]5* comdat group and dtor is + virtual, it goes into the same comdat group as well. */ + DECL_COMDAT_GROUP (fns[2]) = comdat_group; + } + /* We don't need to process the original function any further. */ return 1; } --- libstdc++-v3/config/abi/pre/gnu.ver.jj 2009-11-12 14:14:03.000000000 +0100 +++ libstdc++-v3/config/abi/pre/gnu.ver 2009-11-30 20:47:34.000000000 +0100 @@ -72,13 +72,18 @@ GLIBCXX_3.4 { std::c[v-z]*; # std::[d-g]*; std::d[a-d]*; - std::d[f-z]*; + std::d[f-n]*; + std::domain_error::d*; +# std::domain_error::~d*; + std::d[p-z]*; std::e[a-q]*; std::error[^_]*; std::e[s-z]*; std::gslice*; std::h[^a]*; - std::i[a-n]*; + std::i[a-m]*; + std::invalid_argument::i*; +# std::invalid_argument::~i*; # std::ios_base::[A-Ha-z]*; std::ios_base::[A-Ha-f]*; std::ios_base::goodbit; @@ -94,7 +99,8 @@ GLIBCXX_3.4 { std::istrstream*; std::i[t-z]*; std::[A-Zj-k]*; - std::length_error*; + std::length_error::l*; +# std::length_error::~l*; std::logic_error*; std::locale::[A-Za-e]*; std::locale::facet::[A-Za-z]*; @@ -122,10 +128,14 @@ GLIBCXX_3.4 { std::nu[^m]*; std::num[^e]*; std::ostrstream*; - std::out_of_range*; - std::overflow_error*; + std::out_of_range::o*; +# std::out_of_range::~o*; + std::overflow_error::o*; +# std::overflow_error::~o*; # std::[p-q]*; - std::r[^e]*; + std::r[^ae]*; + std::range_error::r*; +# std::range_error::~r*; std::re[^t]*; # std::rethrow_exception std::set_new_handler*; @@ -143,7 +153,8 @@ GLIBCXX_3.4 { std::tr1::h[^a]*; std::t[s-z]*; # std::[A-Zu-z]*; - std::underflow_error*; + std::underflow_error::u*; +# std::underflow_error::~u*; std::uncaught_exception*; std::unexpected*; std::[A-Zv-z]*; @@ -284,7 +295,8 @@ GLIBCXX_3.4 { _ZNSt15basic_streambufI[cw]St11char_traitsI[cw]EEaSERKS2_; # std::basic_stringbuf - _ZNSt15basic_stringbufI[cw]St11char_traitsI[cw]ESaI[cw]EE[CD]*; + _ZNSt15basic_stringbufI[cw]St11char_traitsI[cw]ESaI[cw]EEC*; + _ZNSt15basic_stringbufI[cw]St11char_traitsI[cw]ESaI[cw]EED[^2]*; _ZNSt15basic_stringbufI[cw]St11char_traitsI[cw]ESaI[cw]EE[0-9][a-r]*; _ZNSt15basic_stringbufI[cw]St11char_traitsI[cw]ESaI[cw]EE[0-9]seek*; _ZNSt15basic_stringbufI[cw]St11char_traitsI[cw]ESaI[cw]EE[0-9]set*; @@ -639,6 +651,16 @@ GLIBCXX_3.4 { _ZGVNSt[^1]*; _ZGVNSt1[^7]*; + # complete and deleting destructors where base destructors should not + # be exported. + _ZNSt11range_errorD[01]Ev; + _ZNSt12domain_errorD[01]Ev; + _ZNSt12length_errorD[01]Ev; + _ZNSt12out_of_rangeD[01]Ev; + _ZNSt14overflow_errorD[01]Ev; + _ZNSt15underflow_errorD[01]Ev; + _ZNSt16invalid_argumentD[01]Ev; + # virtual function thunks _ZThn8_NS*; _ZThn16_NS*; @@ -891,7 +913,8 @@ GLIBCXX_3.4.10 { _ZNSt15basic_streambufI[cw]St11char_traitsI[cw]EE6stosscEv; _ZN9__gnu_cxx18stdio_sync_filebufI[cw]St11char_traitsI[cw]EE4syncEv; - _ZN9__gnu_cxx18stdio_sync_filebufI[cw]St11char_traitsI[cw]EE[5-9CD]*; + _ZN9__gnu_cxx18stdio_sync_filebufI[cw]St11char_traitsI[cw]EE[5-9C]*; + _ZN9__gnu_cxx18stdio_sync_filebufI[cw]St11char_traitsI[cw]EED[^2]*; } GLIBCXX_3.4.9; [-- Attachment #3: Y478 --] [-- Type: text/plain, Size: 1784 bytes --] --- gcc/cp/decl2.c.jj 2009-11-18 15:48:50.000000000 +0100 +++ gcc/cp/decl2.c 2009-12-01 08:33:36.000000000 +0100 @@ -3449,6 +3449,16 @@ no_linkage_error (tree decl) "is used but never defined", decl, t); } +#ifdef ENABLE_CHECKING +static GTY(()) tree vdtor_pairs; +void add_vdtor_pair (tree, tree); +void +add_vdtor_pair (tree base_dtor, tree deleting_dtor) +{ + vdtor_pairs = tree_cons (base_dtor, deleting_dtor, vdtor_pairs); +} +#endif + /* This routine is called at the end of compilation. Its job is to create all the code needed to initialize and destroy the global aggregates. We do the destruction @@ -3823,6 +3833,9 @@ cp_write_global_declarations (void) #ifdef ENABLE_CHECKING validate_conversion_obstack (); + + for (; vdtor_pairs; vdtor_pairs = TREE_CHAIN (vdtor_pairs)) + gcc_assert (!(TREE_ASM_WRITTEN (TREE_VALUE (vdtor_pairs)) ^ TREE_ASM_WRITTEN (TREE_PURPOSE (vdtor_pairs)))); #endif /* ENABLE_CHECKING */ } --- gcc/cp/optimize.c.jj 2009-12-01 10:32:13.000000000 +0100 +++ gcc/cp/optimize.c 2009-12-01 00:02:09.000000000 +0100 @@ -388,9 +388,15 @@ maybe_clone_body (tree fn) { DECL_COMDAT_GROUP (fns[1]) = comdat_group; if (fns[2]) - /* If *[CD][12]* dtors go into the *[CD]5* comdat group and dtor is - virtual, it goes into the same comdat group as well. */ - DECL_COMDAT_GROUP (fns[2]) = comdat_group; + { +#ifdef ENABLE_CHECKING +extern void add_vdtor_pair (tree base_dtor, tree deleting_dtor); +add_vdtor_pair (fns[0], fns[2]); +#endif + /* If *[CD][12]* dtors go into the *[CD]5* comdat group and dtor is + virtual, it goes into the same comdat group as well. */ + DECL_COMDAT_GROUP (fns[2]) = comdat_group; + } } /* We don't need to process the original function any further. */ [-- Attachment #4: cplx.ii --] [-- Type: text/plain, Size: 1163 bytes --] template <typename> class C; template <class> struct B; template <typename A, typename = B <A>, typename = C <A> > class D; template <typename A, typename = B <A>, typename = C <A> > class E; template <typename _Tp> class C { }; template <typename A, typename F, typename G> struct H { struct I { void fn1 (G __a) { fn2 (__a); } void fn2 (G) throw (); }; I *fn3 () {} H (); ~H () { fn3 ()->fn1 (fn4 ()); } G fn4 () {} }; struct J { static int j1; static int j2; }; template <typename A, typename> struct K { virtual ~ K () {} }; template <typename A, typename F> struct L { void fn5 (K <A, F> *); }; template <typename A, typename F, typename G> struct D : public K <A, F> { H <A, F, G> d; D (int = J::j1) : K <A, F> (), d () {} }; template <typename A, typename F, typename G> struct E : public L <A, F> { D <A, F, G> e; E (int = J::j2) : L <A, F> (), e () { fn5 (&e); } }; extern template class D <int>; template <typename> class M; template <typename _Tp, typename A, class F> L <A, F> &operator<<(L <A, F> &, const M <_Tp> &) { E <A, F> e; } template L <int, B <int> > &operator<<(L <int, B <int> >&, const M <long>&); ^ permalink raw reply [flat|nested] 17+ messages in thread
* Re: [C++ PATCH] Optimize C++ comdat ctors/dtors in classes without virtual bases (PR c++/3187, take 4) 2009-12-01 9:52 ` [C++ PATCH] Optimize C++ comdat ctors/dtors in classes without virtual bases (PR c++/3187, take 4) Jakub Jelinek @ 2009-12-01 15:40 ` Jakub Jelinek 2009-12-01 16:38 ` Dave Korn 2009-12-01 19:35 ` [C++ PATCH] Optimize C++ comdat ctors/dtors in classes without virtual bases (PR c++/3187, take 5) Jakub Jelinek 1 sibling, 1 reply; 17+ messages in thread From: Jakub Jelinek @ 2009-12-01 15:40 UTC (permalink / raw) To: Jason Merrill; +Cc: gcc-patches On Tue, Dec 01, 2009 at 04:46:52AM -0500, Jakub Jelinek wrote: > Unfortunately, when bootstrapping with extra checking patch (second patch) > where I wanted to verify that for classes with comdat virtual dtors we > always emit either both D2 (and D1 alias to it) and D0 dtor, or none of > them, build in libstdc++ revealed that we emit e.g. in complex_io.cc > (reduced testcase attached last, cc1plus -O2 cplx.ii) only the > _ZN1DIi1BIiE1CIiEED2Ev (and _ZN1DIi1BIiE1CIiEED1Ev alias) dtor in > the _ZN1DIi1BIiE1CIiEED5Ev comdat group, but not _ZN1DIi1BIiE1CIiEED0Ev. > The class is extern template class, so either the g++ is buggy and emits > something it never should, because the template is extern, or > putting the *D0* dtors also in the *D5* comdat group is not a good idea. Here is the additional patch that allowed the 2 patches to bootstrap. The problem is with implicitly defined methods in extern template class XXX<NNN> instantiations. The synthetized methods don't have DECL_TEMPLATE_INSTANTIATION set, thus don't go through instantiate_class_member and thus are emitted whenever something needs them (and the side with explicit non-extern instantiation doesn't necessarily define all the functions). In this light the patch below is an ABI change (not sure what other compilers do though), as with the patch newly compiled code with extern template class XXX<NNN> would no longer emit routines it needs it, instead rely on the CU with extern template class XXX<NNN>; template class XXX<NNN>; to emit them. But as the code emitted by older G++ doesn't guarantee all the implicitly declared methods are emitted there, mixing new code and old code could result in undefined references. The methods are usually inlined, sure, but e.g. if ipa-inline.c considers them called in cold blocks, it decides not to inline them. --- gcc/cp/pt.c.jj 2009-12-01 12:09:10.000000000 +0100 +++ gcc/cp/pt.c 2009-12-01 13:33:39.000000000 +0100 @@ -16055,6 +16055,31 @@ do_type_instantiation (tree t, tree stor if (TREE_CODE (tmp) == FUNCTION_DECL && DECL_TEMPLATE_INSTANTIATION (tmp)) instantiate_class_member (tmp, extern_p); + else if (TREE_CODE (tmp) == FUNCTION_DECL + && DECL_ARTIFICIAL (tmp) + && (DECL_CONSTRUCTOR_P (tmp) + || DECL_DESTRUCTOR_P (tmp) + || DECL_ASSIGNMENT_OPERATOR_P (tmp))) + { + /* Ensure the implicitly declared ctors/dtors/assignment operators + will be either inlined, or extern calls for extern_p, + or defined in the current TU otherwise. */ + DECL_EXTERNAL (tmp) = 1; + if (extern_p) + DECL_NOT_REALLY_EXTERN (tmp) = 0; + else + { + mark_definable (tmp); + /* Always make artificials weak. */ + if (flag_weak) + comdat_linkage (tmp); + /* For WIN32 we also want to put explicit instantiations in + linkonce sections. */ + else if (TREE_PUBLIC (tmp)) + maybe_make_one_only (tmp); + } + DECL_INTERFACE_KNOWN (tmp) = 1; + } for (tmp = TYPE_FIELDS (t); tmp; tmp = TREE_CHAIN (tmp)) if (TREE_CODE (tmp) == VAR_DECL && DECL_TEMPLATE_INSTANTIATION (tmp)) Jakub ^ permalink raw reply [flat|nested] 17+ messages in thread
* Re: [C++ PATCH] Optimize C++ comdat ctors/dtors in classes without virtual bases (PR c++/3187, take 4) 2009-12-01 15:40 ` Jakub Jelinek @ 2009-12-01 16:38 ` Dave Korn 0 siblings, 0 replies; 17+ messages in thread From: Dave Korn @ 2009-12-01 16:38 UTC (permalink / raw) To: Jakub Jelinek; +Cc: Jason Merrill, gcc-patches Jakub Jelinek wrote: > + mark_definable (tmp); > + /* Always make artificials weak. */ > + if (flag_weak) > + comdat_linkage (tmp); > + /* For WIN32 we also want to put explicit instantiations in > + linkonce sections. */ > + else if (TREE_PUBLIC (tmp)) > + maybe_make_one_only (tmp); > + } > + DECL_INTERFACE_KNOWN (tmp) = 1; > + } Hi Jakub, I'd like to test this on cygwin for you, as I sometimes get a bit nervous about how robust the win32 backend declspec handling code necessarily is w.r.t. changes in the handling of DECL_EXTERNAL et. al. (there was in fact some transient breakage recently that fortunately got fixed on head before I had to track it down). So I have just a couple of questions: - Can you confirm the exact combination of patches I should test? I think it's the Y477 and Y478 patches in the first "take 4" post followed by the patch above from the reply to that post, yes? - Do you happen to know off the top of your head of an area of the g++ or libstdc testsuite that would be worth running first because you would suspect that's where problems might show up? A full run takes over a day (groan, can't parallelise it owing to some kind of tasking/threading bug extant in the cygwin dll at the moment) so it'd be handy if there was a smaller subset worth running as a quick first check. cheers, DaveK ^ permalink raw reply [flat|nested] 17+ messages in thread
* [C++ PATCH] Optimize C++ comdat ctors/dtors in classes without virtual bases (PR c++/3187, take 5) 2009-12-01 9:52 ` [C++ PATCH] Optimize C++ comdat ctors/dtors in classes without virtual bases (PR c++/3187, take 4) Jakub Jelinek 2009-12-01 15:40 ` Jakub Jelinek @ 2009-12-01 19:35 ` Jakub Jelinek 2009-12-01 20:14 ` Jason Merrill ` (2 more replies) 1 sibling, 3 replies; 17+ messages in thread From: Jakub Jelinek @ 2009-12-01 19:35 UTC (permalink / raw) To: Jason Merrill; +Cc: gcc-patches Hi! After discussions on IRC, here is the latest version of the patch. For now the problematic implicitly defined virtual comdat destructors aren't optimized, even when the base and complete dtor have the same body, as the deleting dtor isn't necessarily emitted iff the base/complete dtors are emitted. The nice effect of that patch is that the libstdc++ symbol version script changes aren't needed. Bootstrapped/regtested on x86_64-linux (with the checking patch on top of it), ok for trunk? 2009-12-01 Jakub Jelinek <jakub@redhat.com> PR c++/3187 * optimize.c (cdtor_comdat_group): New function. (maybe_clone_body): Also optimize DECL_COMDAT base/complete cdtors and in that case put also the deleting dtor in the same comdat group as base and complete dtor if dtor is virtual. --- gcc/cp/optimize.c.jj 2009-11-30 15:53:13.000000000 +0100 +++ gcc/cp/optimize.c 2009-11-30 19:18:51.000000000 +0100 @@ -142,6 +142,46 @@ build_delete_destructor_body (tree delet } } +/* Return name of comdat group for complete and base ctor (or dtor) + that have the same body. If dtor is virtual, deleting dtor goes + into this comdat group as well. */ + +static tree +cdtor_comdat_group (tree complete, tree base) +{ + tree complete_name = DECL_COMDAT_GROUP (complete); + tree base_name = DECL_COMDAT_GROUP (base); + char *grp_name; + const char *p, *q; + bool diff_seen = false; + size_t idx; + if (complete_name == NULL) + complete_name = cxx_comdat_group (complete); + if (base_name == NULL) + base_name = cxx_comdat_group (base); + gcc_assert (IDENTIFIER_LENGTH (complete_name) + == IDENTIFIER_LENGTH (base_name)); + grp_name = XALLOCAVEC (char, IDENTIFIER_LENGTH (complete_name) + 1); + p = IDENTIFIER_POINTER (complete_name); + q = IDENTIFIER_POINTER (base_name); + for (idx = 0; idx < IDENTIFIER_LENGTH (complete_name); idx++) + if (p[idx] == q[idx]) + grp_name[idx] = p[idx]; + else + { + gcc_assert (!diff_seen + && idx > 0 + && (p[idx - 1] == 'C' || p[idx - 1] == 'D') + && p[idx] == '1' + && q[idx] == '2'); + grp_name[idx] = '5'; + diff_seen = true; + } + grp_name[idx] = '\0'; + gcc_assert (diff_seen); + return get_identifier (grp_name); +} + /* FN is a function that has a complete body. Clone the body as necessary. Returns nonzero if there's no longer any need to process the main body. */ @@ -149,6 +189,7 @@ build_delete_destructor_body (tree delet bool maybe_clone_body (tree fn) { + tree comdat_group = NULL_TREE; tree clone; tree fns[3]; bool first = true; @@ -248,10 +289,26 @@ maybe_clone_body (tree fn) && idx == 1 && !flag_use_repository && DECL_INTERFACE_KNOWN (fns[0]) - && !DECL_ONE_ONLY (fns[0]) + && (SUPPORTS_ONE_ONLY || !DECL_WEAK (fns[0])) + && (!DECL_ONE_ONLY (fns[0]) + || (HAVE_COMDAT_GROUP + && DECL_WEAK (fns[0]) + /* Don't optimize synthetized virtual dtors, because then + the deleting and other dtors are emitted when needed + and so it is not certain we would emit both + deleting and complete/base dtors in the comdat group. */ + && (fns[2] == NULL || !DECL_ARTIFICIAL (fn)))) && cgraph_same_body_alias (clone, fns[0])) { alias = true; + if (DECL_ONE_ONLY (fns[0])) + { + /* For comdat base and complete cdtors put them + into the same, *[CD]5* comdat group instead of + *[CD][12]*. */ + comdat_group = cdtor_comdat_group (fns[1], fns[0]); + DECL_COMDAT_GROUP (fns[0]) = comdat_group; + } emit_associated_thunks (clone); } @@ -333,6 +390,15 @@ maybe_clone_body (tree fn) } pop_from_top_level (); + if (comdat_group) + { + DECL_COMDAT_GROUP (fns[1]) = comdat_group; + if (fns[2]) + /* If *[CD][12]* dtors go into the *[CD]5* comdat group and dtor is + virtual, it goes into the same comdat group as well. */ + DECL_COMDAT_GROUP (fns[2]) = comdat_group; + } + /* We don't need to process the original function any further. */ return 1; } Jakub ^ permalink raw reply [flat|nested] 17+ messages in thread
* Re: [C++ PATCH] Optimize C++ comdat ctors/dtors in classes without virtual bases (PR c++/3187, take 5) 2009-12-01 19:35 ` [C++ PATCH] Optimize C++ comdat ctors/dtors in classes without virtual bases (PR c++/3187, take 5) Jakub Jelinek @ 2009-12-01 20:14 ` Jason Merrill 2009-12-01 21:03 ` Dave Korn 2009-12-27 13:36 ` H.J. Lu 2 siblings, 0 replies; 17+ messages in thread From: Jason Merrill @ 2009-12-01 20:14 UTC (permalink / raw) To: Jakub Jelinek; +Cc: gcc-patches On 12/01/2009 02:22 PM, Jakub Jelinek wrote: > After discussions on IRC, here is the latest version of the patch. > For now the problematic implicitly defined virtual comdat destructors aren't > optimized, even when the base and complete dtor have the same body, as the > deleting dtor isn't necessarily emitted iff the base/complete dtors are > emitted. OK. Jason ^ permalink raw reply [flat|nested] 17+ messages in thread
* Re: [C++ PATCH] Optimize C++ comdat ctors/dtors in classes without virtual bases (PR c++/3187, take 5) 2009-12-01 19:35 ` [C++ PATCH] Optimize C++ comdat ctors/dtors in classes without virtual bases (PR c++/3187, take 5) Jakub Jelinek 2009-12-01 20:14 ` Jason Merrill @ 2009-12-01 21:03 ` Dave Korn 2009-12-04 18:19 ` Dave Korn 2009-12-27 13:36 ` H.J. Lu 2 siblings, 1 reply; 17+ messages in thread From: Dave Korn @ 2009-12-01 21:03 UTC (permalink / raw) To: Jakub Jelinek; +Cc: Jason Merrill, gcc-patches Jakub Jelinek wrote: > Bootstrapped/regtested on x86_64-linux (with the checking patch on top of > it) Is that the Y478 one? cheers, DaveK ^ permalink raw reply [flat|nested] 17+ messages in thread
* Re: [C++ PATCH] Optimize C++ comdat ctors/dtors in classes without virtual bases (PR c++/3187, take 5) 2009-12-01 21:03 ` Dave Korn @ 2009-12-04 18:19 ` Dave Korn 2009-12-04 18:29 ` Jakub Jelinek 0 siblings, 1 reply; 17+ messages in thread From: Dave Korn @ 2009-12-04 18:19 UTC (permalink / raw) To: Dave Korn; +Cc: Jakub Jelinek, Jason Merrill, gcc-patches Dave Korn wrote: > Jakub Jelinek wrote: > >> Bootstrapped/regtested on x86_64-linux (with the checking patch on top of >> it) > > Is that the Y478 one? I assumed it was, but for reasons stated elsewhere it wasn't practical to run with full checking on so I tested it unchecked; nothing untoward happened. JFTR. cheers, DaveK ^ permalink raw reply [flat|nested] 17+ messages in thread
* Re: [C++ PATCH] Optimize C++ comdat ctors/dtors in classes without virtual bases (PR c++/3187, take 5) 2009-12-04 18:19 ` Dave Korn @ 2009-12-04 18:29 ` Jakub Jelinek 2009-12-04 18:46 ` Dave Korn 0 siblings, 1 reply; 17+ messages in thread From: Jakub Jelinek @ 2009-12-04 18:29 UTC (permalink / raw) To: Dave Korn; +Cc: Jason Merrill, gcc-patches On Fri, Dec 04, 2009 at 06:33:41PM +0000, Dave Korn wrote: > I assumed it was, but for reasons stated elsewhere it wasn't practical to > run with full checking on so I tested it unchecked; nothing untoward happened. I think cygwin doesn't HAVE_COMDAT_GROUP anyway, so it wouldn't make any difference. Jakub ^ permalink raw reply [flat|nested] 17+ messages in thread
* Re: [C++ PATCH] Optimize C++ comdat ctors/dtors in classes without virtual bases (PR c++/3187, take 5) 2009-12-04 18:29 ` Jakub Jelinek @ 2009-12-04 18:46 ` Dave Korn 0 siblings, 0 replies; 17+ messages in thread From: Dave Korn @ 2009-12-04 18:46 UTC (permalink / raw) To: Jakub Jelinek; +Cc: Dave Korn, Jason Merrill, gcc-patches Jakub Jelinek wrote: > On Fri, Dec 04, 2009 at 06:33:41PM +0000, Dave Korn wrote: >> I assumed it was, but for reasons stated elsewhere it wasn't practical to >> run with full checking on so I tested it unchecked; nothing untoward happened. > > I think cygwin doesn't HAVE_COMDAT_GROUP anyway, so it wouldn't make any > difference. Heh, you're right. I was worrying for nothing(*). cheers, DaveK -- (*) - Well, not quite for nothing, I was worrying because /something/ recently caused some kind of breakage in that area somewhere between r.154010 and r.154114, and although it got fixed again within the week I thought I'd do some proactive keeping-an-eye-out-for-problems-before-they-arise. ^ permalink raw reply [flat|nested] 17+ messages in thread
* Re: [C++ PATCH] Optimize C++ comdat ctors/dtors in classes without virtual bases (PR c++/3187, take 5) 2009-12-01 19:35 ` [C++ PATCH] Optimize C++ comdat ctors/dtors in classes without virtual bases (PR c++/3187, take 5) Jakub Jelinek 2009-12-01 20:14 ` Jason Merrill 2009-12-01 21:03 ` Dave Korn @ 2009-12-27 13:36 ` H.J. Lu 2 siblings, 0 replies; 17+ messages in thread From: H.J. Lu @ 2009-12-27 13:36 UTC (permalink / raw) To: Jakub Jelinek; +Cc: Jason Merrill, gcc-patches On Tue, Dec 1, 2009 at 11:22 AM, Jakub Jelinek <jakub@redhat.com> wrote: > Hi! > > After discussions on IRC, here is the latest version of the patch. > For now the problematic implicitly defined virtual comdat destructors aren't > optimized, even when the base and complete dtor have the same body, as the > deleting dtor isn't necessarily emitted iff the base/complete dtors are > emitted. > > The nice effect of that patch is that the libstdc++ symbol version script > changes aren't needed. > > Bootstrapped/regtested on x86_64-linux (with the checking patch on top of > it), ok for trunk? > This caused: http://gcc.gnu.org/bugzilla/show_bug.cgi?id=42508 -- H.J. ^ permalink raw reply [flat|nested] 17+ messages in thread
* Re: [C++ PATCH] Optimize C++ comdat ctors/dtors in classes without virtual bases (PR c++/3187, take 3) 2009-11-30 22:38 [C++ PATCH] Optimize C++ comdat ctors/dtors in classes without virtual bases (PR c++/3187, take 3) Jakub Jelinek 2009-12-01 3:53 ` Jason Merrill 2009-12-01 9:52 ` [C++ PATCH] Optimize C++ comdat ctors/dtors in classes without virtual bases (PR c++/3187, take 4) Jakub Jelinek @ 2009-12-01 21:15 ` Daniel Jacobowitz 2009-12-01 21:20 ` Jakub Jelinek 2 siblings, 1 reply; 17+ messages in thread From: Daniel Jacobowitz @ 2009-12-01 21:15 UTC (permalink / raw) To: Jakub Jelinek; +Cc: Jason Merrill, gcc-patches On Mon, Nov 30, 2009 at 05:36:53PM -0500, Jakub Jelinek wrote: > Hi! > > Here is the latest version of the cdtor optimization patch. > The comdat group name is *[CD]5* and if the dtor is virtual, deleting dtor > is emitted into that comdat group as well. > libstdc++ symbol version script has been adjusted, so that it exports > exactly what it used to export before this patch. > On x86_64-linux this patch saves 21KB of libstdc++.so's .text. Can you explain how this patch is ABI-safe at the object (.o) level? Suppose that some other or older compiler creates a C0 comdat group in first.o. second.o references the C0 symbol. Then suppose that GCC creates a C5 comdat group in third.o, and defines C0 and C1 in that group. A reference to C1 will now pull in the group in third.o and we have two definitions of the global symbol for the C0 constructor. Neither can be discarded at this point. -- Daniel Jacobowitz CodeSourcery ^ permalink raw reply [flat|nested] 17+ messages in thread
* Re: [C++ PATCH] Optimize C++ comdat ctors/dtors in classes without virtual bases (PR c++/3187, take 3) 2009-12-01 21:15 ` [C++ PATCH] Optimize C++ comdat ctors/dtors in classes without virtual bases (PR c++/3187, take 3) Daniel Jacobowitz @ 2009-12-01 21:20 ` Jakub Jelinek 2009-12-01 21:50 ` Daniel Jacobowitz 0 siblings, 1 reply; 17+ messages in thread From: Jakub Jelinek @ 2009-12-01 21:20 UTC (permalink / raw) To: Jason Merrill, gcc-patches On Tue, Dec 01, 2009 at 04:03:25PM -0500, Daniel Jacobowitz wrote: > On Mon, Nov 30, 2009 at 05:36:53PM -0500, Jakub Jelinek wrote: > > Hi! > > > > Here is the latest version of the cdtor optimization patch. > > The comdat group name is *[CD]5* and if the dtor is virtual, deleting dtor > > is emitted into that comdat group as well. > > libstdc++ symbol version script has been adjusted, so that it exports > > exactly what it used to export before this patch. > > On x86_64-linux this patch saves 21KB of libstdc++.so's .text. > > Can you explain how this patch is ABI-safe at the object (.o) level? > > Suppose that some other or older compiler creates a C0 comdat group in > first.o. second.o references the C0 symbol. Then suppose that GCC > creates a C5 comdat group in third.o, and defines C0 and C1 in that > group. A reference to C1 will now pull in the group in third.o and > we have two definitions of the global symbol for the C0 constructor. > Neither can be discarded at this point. That's why this is done only if the symbols are weak. If you mix .o files from different G++ versions (pre-4.5 and 4.5+), then worst case you'll end up with some .text duplication, but as the symbols are weak, the linker will just pick one of the definitions for the symbols. When you don't mix .o files from different G++ versions in one .so or executable, you on the other side gain code size savings. Jakub ^ permalink raw reply [flat|nested] 17+ messages in thread
* Re: [C++ PATCH] Optimize C++ comdat ctors/dtors in classes without virtual bases (PR c++/3187, take 3) 2009-12-01 21:20 ` Jakub Jelinek @ 2009-12-01 21:50 ` Daniel Jacobowitz 0 siblings, 0 replies; 17+ messages in thread From: Daniel Jacobowitz @ 2009-12-01 21:50 UTC (permalink / raw) To: gcc-patches On Tue, Dec 01, 2009 at 04:15:38PM -0500, Jakub Jelinek wrote: > That's why this is done only if the symbols are weak. If you mix .o files > from different G++ versions (pre-4.5 and 4.5+), then worst case you'll > end up with some .text duplication, but as the symbols are weak, the linker > will just pick one of the definitions for the symbols. When you don't mix > .o files from different G++ versions in one .so or executable, you on the > other side gain code size savings. I see. Unless the ABI has something to say on the matter, I would suggest using a GNU-specific string for the COMDAT signature; IMO that's less confusing. As I said on IRC, I tried to test my theories with ARM's compiler. But that compiler already causes GNU ld fits; among other things, it puts both C1 and C2 constructors into the group with a C1 signature. And something involving discarded hidden symbols made my linker fall down, anyway. -- Daniel Jacobowitz CodeSourcery ^ permalink raw reply [flat|nested] 17+ messages in thread
end of thread, other threads:[~2009-12-26 21:06 UTC | newest] Thread overview: 17+ messages (download: mbox.gz / follow: Atom feed) -- links below jump to the message on this page -- 2009-11-30 22:38 [C++ PATCH] Optimize C++ comdat ctors/dtors in classes without virtual bases (PR c++/3187, take 3) Jakub Jelinek 2009-12-01 3:53 ` Jason Merrill 2009-12-01 8:07 ` Jakub Jelinek 2009-12-01 15:39 ` Jason Merrill 2009-12-01 9:52 ` [C++ PATCH] Optimize C++ comdat ctors/dtors in classes without virtual bases (PR c++/3187, take 4) Jakub Jelinek 2009-12-01 15:40 ` Jakub Jelinek 2009-12-01 16:38 ` Dave Korn 2009-12-01 19:35 ` [C++ PATCH] Optimize C++ comdat ctors/dtors in classes without virtual bases (PR c++/3187, take 5) Jakub Jelinek 2009-12-01 20:14 ` Jason Merrill 2009-12-01 21:03 ` Dave Korn 2009-12-04 18:19 ` Dave Korn 2009-12-04 18:29 ` Jakub Jelinek 2009-12-04 18:46 ` Dave Korn 2009-12-27 13:36 ` H.J. Lu 2009-12-01 21:15 ` [C++ PATCH] Optimize C++ comdat ctors/dtors in classes without virtual bases (PR c++/3187, take 3) Daniel Jacobowitz 2009-12-01 21:20 ` Jakub Jelinek 2009-12-01 21:50 ` Daniel Jacobowitz
This is a public inbox, see mirroring instructions for how to clone and mirror all data and code used for this inbox; as well as URLs for read-only IMAP folder(s) and NNTP newsgroup(s).