From patchwork Thu Jun 6 21:13:04 2019 Content-Type: text/plain; charset="utf-8" MIME-Version: 1.0 Content-Transfer-Encoding: 7bit X-Patchwork-Submitter: Jan Hubicka X-Patchwork-Id: 1111450 Return-Path: X-Original-To: incoming@patchwork.ozlabs.org Delivered-To: patchwork-incoming@bilbo.ozlabs.org Authentication-Results: ozlabs.org; spf=pass (mailfrom) smtp.mailfrom=gcc.gnu.org (client-ip=209.132.180.131; helo=sourceware.org; envelope-from=gcc-patches-return-502518-incoming=patchwork.ozlabs.org@gcc.gnu.org; receiver=) Authentication-Results: ozlabs.org; dmarc=none (p=none dis=none) header.from=ucw.cz Authentication-Results: ozlabs.org; dkim=pass (1024-bit key; unprotected) header.d=gcc.gnu.org header.i=@gcc.gnu.org header.b="ZRolw2fe"; dkim-atps=neutral Received: from sourceware.org (server1.sourceware.org [209.132.180.131]) (using TLSv1.2 with cipher ECDHE-RSA-AES256-GCM-SHA384 (256/256 bits)) (No client certificate requested) by ozlabs.org (Postfix) with ESMTPS id 45KdgF1fJKz9s9y for ; Fri, 7 Jun 2019 07:13:22 +1000 (AEST) DomainKey-Signature: a=rsa-sha1; c=nofws; d=gcc.gnu.org; h=list-id :list-unsubscribe:list-archive:list-post:list-help:sender:date :from:to:subject:message-id:mime-version:content-type; q=dns; s= default; b=PuXaGMeY2g3kqYZ/Hc3Pvr2ll36H+KzUqYYxvTr8kV6Cict83tsnf aq69dtQcC82UgUUHXFWY++OU5dnMNDcdiT/sM/DH/4NEMn2oJymZA2ww2fg/rNXX fVZPmUswFuuqvYLuh7K9S8TH8o8xCiYzq1wtAu/3zJdQt4WdaPbPLA= DKIM-Signature: v=1; a=rsa-sha1; c=relaxed; d=gcc.gnu.org; h=list-id :list-unsubscribe:list-archive:list-post:list-help:sender:date :from:to:subject:message-id:mime-version:content-type; s= default; bh=U3t9qiOm1rijc6jCNSFM2MbhBYQ=; b=ZRolw2feLDT5RrWsL7FI luNlQs2bkmcP2az0nv8HdtHvihluFGR917FXG9zuoDomOyWzavfVghG0mfA/icX8 duTOx15OjqtzNMayTSaskeo9tbGM/3GmftVv1FTYWQzbBC6wPd/tAC1lo/TPSrrB vbWqiECa9yI27gVuzG3TEmg= Received: (qmail 6716 invoked by alias); 6 Jun 2019 21:13:14 -0000 Mailing-List: contact gcc-patches-help@gcc.gnu.org; run by ezmlm Precedence: bulk List-Id: List-Unsubscribe: List-Archive: List-Post: List-Help: Sender: gcc-patches-owner@gcc.gnu.org Delivered-To: mailing list gcc-patches@gcc.gnu.org Received: (qmail 6706 invoked by uid 89); 6 Jun 2019 21:13:14 -0000 Authentication-Results: sourceware.org; auth=none X-Spam-SWARE-Status: No, score=-12.4 required=5.0 tests=AWL, BAYES_00, GIT_PATCH_1, GIT_PATCH_2, GIT_PATCH_3, KAM_ASCII_DIVIDERS autolearn=ham version=3.3.1 spammy=sub-types, Ignore, wpa, WPA X-HELO: nikam.ms.mff.cuni.cz Received: from nikam.ms.mff.cuni.cz (HELO nikam.ms.mff.cuni.cz) (195.113.20.16) by sourceware.org (qpsmtpd/0.93/v0.84-503-g423c35a) with ESMTP; Thu, 06 Jun 2019 21:13:10 +0000 Received: by nikam.ms.mff.cuni.cz (Postfix, from userid 16202) id BC54A2823A7; Thu, 6 Jun 2019 23:13:04 +0200 (CEST) Date: Thu, 6 Jun 2019 23:13:04 +0200 From: Jan Hubicka To: gcc-patches@gcc.gnu.org Subject: Remove -fodr-type-merging Message-ID: <20190606211304.vxwnqlw7w6p5pj5d@kam.mff.cuni.cz> MIME-Version: 1.0 Content-Disposition: inline User-Agent: NeoMutt/20170113 (1.7.2) Hi, at the type introducing ODR type merging via mangled type names I was concerned about streaming overhead of this infrastructure and implemented flag to disable it. Maintaining this flag is harder over a time since we really want to establing ODR based type euivalences and also the type streaming is now relatively cheap after the type simplification and merging improvemets. This patch thus drops the flag. I plan to commit it tomorrow if there are no complains. Honza * common.opt (flto-odr-type-merging): Ignore. * invoke.texi (-flto-odr-type-merging): Remove. * ipa-devirt.c (odr_vtable_hasher:odr_name_hasher): Remove. (can_be_vtable_hashed_p): Remove. (hash_odr_vtable): Remove. (odr_vtable_hasher::hash): Remove. (types_same_for_odr): Remove. (types_odr_comparable): Remove. (odr_vtable_hasher::equal): Remove. (odr_vtable_hash_type, odr_vtable_hash): Remove. (add_type_duplicate): Do not synchronize vtable and name hashtables. (get_odr_type): Do not use vtable hash. (dump_odr_type): Remove commented out code. (build_type_inheritance_graph): Do not allocate vtable hash. (rebuild_type_inheritance_graph): Do not delete vtable hash. * ipa-utils.h (type_with_linkage_p): Drop vtable hash path. (odr_type_p): Likewise. * tree.c (need_assembler_name_p): Remove flag_lto_odr_type_mering test. Index: common.opt =================================================================== --- common.opt (revision 272018) +++ common.opt (working copy) @@ -1888,8 +1888,8 @@ Common Joined RejectNegative UInteger Va -flto-compression-level= Use zlib compression level for IL. flto-odr-type-merging -Common Report Var(flag_lto_odr_type_mering) Init(1) -Merge C++ types using One Definition Rule. +Common Ignore +Does nothing. Preserved for backward compatibility. flto-report Common Report Var(flag_lto_report) Init(0) Index: doc/invoke.texi =================================================================== --- doc/invoke.texi (revision 272018) +++ doc/invoke.texi (working copy) @@ -7357,7 +7357,7 @@ Do not warn about compile-time overflow @opindex Wno-odr @opindex Wodr Warn about One Definition Rule violations during link-time optimization. -Requires @option{-flto-odr-type-merging} to be enabled. Enabled by default. +Enabled by default. @item -Wopenmp-simd @opindex Wopenmp-simd @@ -10353,12 +10353,6 @@ The value @samp{one} specifies that exac used while the value @samp{none} bypasses partitioning and executes the link-time optimization step directly from the WPA phase. -@item -flto-odr-type-merging -@opindex flto-odr-type-merging -Enable streaming of mangled types names of C++ types and their unification -at link time. This increases size of LTO object files, but enables -diagnostics about One Definition Rule violations. - @item -flto-compression-level=@var{n} @opindex flto-compression-level This option specifies the level of compression used for intermediate Index: ipa-devirt.c =================================================================== --- ipa-devirt.c (revision 272018) +++ ipa-devirt.c (working copy) @@ -284,16 +284,6 @@ struct odr_name_hasher : pointer_hash type); } -static bool -can_be_vtable_hashed_p (tree t) -{ - /* vtable hashing can distinguish only main variants. */ - if (TYPE_MAIN_VARIANT (t) != t) - return false; - /* Anonymous namespace types are always handled by name hash. */ - if (type_with_linkage_p (t) && type_in_anonymous_namespace_p (t)) - return false; - return (TREE_CODE (t) == RECORD_TYPE - && TYPE_BINFO (t) && BINFO_VTABLE (TYPE_BINFO (t))); -} - -/* Hash type by assembler name of its vtable. */ - -static hashval_t -hash_odr_vtable (const_tree t) -{ - tree v = BINFO_VTABLE (TYPE_BINFO (TYPE_MAIN_VARIANT (t))); - inchash::hash hstate; - - gcc_checking_assert (in_lto_p); - gcc_checking_assert (!type_in_anonymous_namespace_p (t)); - gcc_checking_assert (TREE_CODE (t) == RECORD_TYPE - && TYPE_BINFO (t) && BINFO_VTABLE (TYPE_BINFO (t))); - gcc_checking_assert (TYPE_MAIN_VARIANT (t) == t); - - if (TREE_CODE (v) == POINTER_PLUS_EXPR) - { - add_expr (TREE_OPERAND (v, 1), hstate); - v = TREE_OPERAND (TREE_OPERAND (v, 0), 0); - } - - hstate.add_hwi (IDENTIFIER_HASH_VALUE (DECL_ASSEMBLER_NAME (v))); - return hstate.end (); -} - -/* Return the computed hashcode for ODR_TYPE. */ - -inline hashval_t -odr_vtable_hasher::hash (const odr_type_d *odr_type) -{ - return hash_odr_vtable (odr_type->type); -} - /* For languages with One Definition Rule, work out if types are the same based on their name. @@ -404,60 +349,6 @@ types_same_for_odr (const_tree type1, co || (type_with_linkage_p (type2) && type_in_anonymous_namespace_p (type2))) return false; - - /* ODR name of the type is set in DECL_ASSEMBLER_NAME of its TYPE_NAME. - - Ideally we should never need types without ODR names here. It can however - happen in two cases: - - 1) for builtin types that are not streamed but rebuilt in lto/lto-lang.c - Here testing for equivalence is safe, since their MAIN_VARIANTs are - unique. - 2) for units streamed with -fno-lto-odr-type-merging. Here we can't - establish precise ODR equivalency, but for correctness we care only - about equivalency on complete polymorphic types. For these we can - compare assembler names of their virtual tables. */ - if ((!TYPE_NAME (type1) || !DECL_ASSEMBLER_NAME_SET_P (TYPE_NAME (type1))) - || (!TYPE_NAME (type2) || !DECL_ASSEMBLER_NAME_SET_P (TYPE_NAME (type2)))) - { - /* See if types are obviously different (i.e. different codes - or polymorphic wrt non-polymorphic). This is not strictly correct - for ODR violating programs, but we can't do better without streaming - ODR names. */ - if (TREE_CODE (type1) != TREE_CODE (type2)) - return false; - if (TREE_CODE (type1) == RECORD_TYPE - && (TYPE_BINFO (type1) == NULL_TREE) - != (TYPE_BINFO (type2) == NULL_TREE)) - return false; - if (TREE_CODE (type1) == RECORD_TYPE && TYPE_BINFO (type1) - && (BINFO_VTABLE (TYPE_BINFO (type1)) == NULL_TREE) - != (BINFO_VTABLE (TYPE_BINFO (type2)) == NULL_TREE)) - return false; - - /* At the moment we have no way to establish ODR equivalence at LTO - other than comparing virtual table pointers of polymorphic types. - Eventually we should start saving mangled names in TYPE_NAME. - Then this condition will become non-trivial. */ - - if (TREE_CODE (type1) == RECORD_TYPE - && TYPE_BINFO (type1) && TYPE_BINFO (type2) - && BINFO_VTABLE (TYPE_BINFO (type1)) - && BINFO_VTABLE (TYPE_BINFO (type2))) - { - tree v1 = BINFO_VTABLE (TYPE_BINFO (type1)); - tree v2 = BINFO_VTABLE (TYPE_BINFO (type2)); - gcc_assert (TREE_CODE (v1) == POINTER_PLUS_EXPR - && TREE_CODE (v2) == POINTER_PLUS_EXPR); - return (operand_equal_p (TREE_OPERAND (v1, 1), - TREE_OPERAND (v2, 1), 0) - && DECL_ASSEMBLER_NAME - (TREE_OPERAND (TREE_OPERAND (v1, 0), 0)) - == DECL_ASSEMBLER_NAME - (TREE_OPERAND (TREE_OPERAND (v2, 0), 0))); - } - gcc_unreachable (); - } return (DECL_ASSEMBLER_NAME (TYPE_NAME (type1)) == DECL_ASSEMBLER_NAME (TYPE_NAME (type2))); } @@ -473,11 +364,7 @@ types_odr_comparable (tree t1, tree t2) return (!in_lto_p || TYPE_MAIN_VARIANT (t1) == TYPE_MAIN_VARIANT (t2) || (odr_type_p (TYPE_MAIN_VARIANT (t1)) - && odr_type_p (TYPE_MAIN_VARIANT (t2))) - || (TREE_CODE (t1) == RECORD_TYPE && TREE_CODE (t2) == RECORD_TYPE - && TYPE_BINFO (t1) && TYPE_BINFO (t2) - && polymorphic_type_binfo_p (TYPE_BINFO (t1)) - && polymorphic_type_binfo_p (TYPE_BINFO (t2)))); + && odr_type_p (TYPE_MAIN_VARIANT (t2)))); } /* Return true if T1 and T2 are ODR equivalent. If ODR equivalency is not @@ -569,31 +456,6 @@ odr_name_hasher::equal (const odr_type_d == DECL_ASSEMBLER_NAME (TYPE_NAME (t2))); } -/* Compare types T1 and T2 and return true if they are - equivalent. */ - -inline bool -odr_vtable_hasher::equal (const odr_type_d *o1, const tree_node *t2) -{ - tree t1 = o1->type; - - gcc_checking_assert (TYPE_MAIN_VARIANT (t2) == t2); - gcc_checking_assert (TYPE_MAIN_VARIANT (t1) == t1); - gcc_checking_assert (in_lto_p); - t1 = TYPE_MAIN_VARIANT (t1); - t2 = TYPE_MAIN_VARIANT (t2); - if (t1 == t2) - return true; - tree v1 = BINFO_VTABLE (TYPE_BINFO (t1)); - tree v2 = BINFO_VTABLE (TYPE_BINFO (t2)); - return (operand_equal_p (TREE_OPERAND (v1, 1), - TREE_OPERAND (v2, 1), 0) - && DECL_ASSEMBLER_NAME - (TREE_OPERAND (TREE_OPERAND (v1, 0), 0)) - == DECL_ASSEMBLER_NAME - (TREE_OPERAND (TREE_OPERAND (v2, 0), 0))); -} - /* Free ODR type V. */ inline void @@ -610,8 +472,6 @@ odr_name_hasher::remove (odr_type_d *v) typedef hash_table odr_hash_type; static odr_hash_type *odr_hash; -typedef hash_table odr_vtable_hash_type; -static odr_vtable_hash_type *odr_vtable_hash; /* ODR types are also stored into ODR_TYPE vector to allow consistent walking. Bases appear before derived types. Vector is garbage collected @@ -1750,12 +1610,8 @@ add_type_duplicate (odr_type val, tree t val->types_set->add (type); - /* If we now have a mangled name, be sure to record it to val->type - so ODR hash can work. */ - - if (can_be_name_hashed_p (type) && !can_be_name_hashed_p (val->type)) - SET_DECL_ASSEMBLER_NAME (TYPE_NAME (val->type), - DECL_ASSEMBLER_NAME (TYPE_NAME (type))); + gcc_checking_assert (can_be_name_hashed_p (type) + && can_be_name_hashed_p (val->type)); bool merge = true; bool base_mismatch = false; @@ -2034,7 +1890,6 @@ odr_type get_odr_type (tree type, bool insert) { odr_type_d **slot = NULL; - odr_type_d **vtable_slot = NULL; odr_type val = NULL; hashval_t hash; bool build_bases = false; @@ -2045,68 +1900,23 @@ get_odr_type (tree type, bool insert) if (!in_lto_p && !TYPE_STRUCTURAL_EQUALITY_P (type)) type = TYPE_CANONICAL (type); - gcc_checking_assert (can_be_name_hashed_p (type) - || can_be_vtable_hashed_p (type)); + gcc_checking_assert (can_be_name_hashed_p (type)); - /* Lookup entry, first try name hash, fallback to vtable hash. */ - if (can_be_name_hashed_p (type)) - { - hash = hash_odr_name (type); - slot = odr_hash->find_slot_with_hash (type, hash, - insert ? INSERT : NO_INSERT); - } - if ((!slot || !*slot) && in_lto_p && can_be_vtable_hashed_p (type)) - { - hash = hash_odr_vtable (type); - if (!odr_vtable_hash) - odr_vtable_hash = new odr_vtable_hash_type (23); - vtable_slot = odr_vtable_hash->find_slot_with_hash (type, hash, - insert ? INSERT : NO_INSERT); - } + hash = hash_odr_name (type); + slot = odr_hash->find_slot_with_hash (type, hash, + insert ? INSERT : NO_INSERT); - if (!slot && !vtable_slot) + if (!slot) return NULL; /* See if we already have entry for type. */ - if ((slot && *slot) || (vtable_slot && *vtable_slot)) + if (*slot) { - if (slot && *slot) - { - val = *slot; - if (flag_checking - && in_lto_p && can_be_vtable_hashed_p (type)) - { - hash = hash_odr_vtable (type); - vtable_slot = odr_vtable_hash->find_slot_with_hash (type, hash, - NO_INSERT); - gcc_assert (!vtable_slot || *vtable_slot == *slot); - vtable_slot = NULL; - } - } - else if (*vtable_slot) - val = *vtable_slot; + val = *slot; if (val->type != type && insert && (!val->types_set || !val->types_set->add (type))) - { - /* We have type duplicate, but it may introduce vtable name or - mangled name; be sure to keep hashes in sync. */ - if (in_lto_p && can_be_vtable_hashed_p (type) - && (!vtable_slot || !*vtable_slot)) - { - if (!vtable_slot) - { - hash = hash_odr_vtable (type); - vtable_slot = odr_vtable_hash->find_slot_with_hash - (type, hash, INSERT); - gcc_checking_assert (!*vtable_slot || *vtable_slot == val); - } - *vtable_slot = val; - } - if (slot && !*slot) - *slot = val; - build_bases = add_type_duplicate (val, type); - } + build_bases = add_type_duplicate (val, type); } else { @@ -2120,10 +1930,7 @@ get_odr_type (tree type, bool insert) val->anonymous_namespace = 0; build_bases = COMPLETE_TYPE_P (val->type); insert_to_odr_array = true; - if (slot) - *slot = val; - if (vtable_slot) - *vtable_slot = val; + *slot = val; } if (build_bases && TREE_CODE (type) == RECORD_TYPE && TYPE_BINFO (type) @@ -2196,11 +2003,7 @@ void register_odr_type (tree type) { if (!odr_hash) - { - odr_hash = new odr_hash_type (23); - if (in_lto_p) - odr_vtable_hash = new odr_vtable_hash_type (23); - } + odr_hash = new odr_hash_type (23); if (type == TYPE_MAIN_VARIANT (type)) { /* To get ODR warings right, first register all sub-types. */ @@ -2258,9 +2061,6 @@ dump_odr_type (FILE *f, odr_type t, int fprintf (f, "%s\n", t->all_derivations_known ? " (derivations known)":""); if (TYPE_NAME (t->type)) { - /*fprintf (f, "%*s defined at: %s:%i\n", indent * 2, "", - DECL_SOURCE_FILE (TYPE_NAME (t->type)), - DECL_SOURCE_LINE (TYPE_NAME (t->type)));*/ if (DECL_ASSEMBLER_NAME_SET_P (TYPE_NAME (t->type))) fprintf (f, "%*s mangled name: %s\n", indent * 2, "", IDENTIFIER_POINTER @@ -2400,8 +2200,6 @@ build_type_inheritance_graph (void) timevar_push (TV_IPA_INHERITANCE); inheritance_dump_file = dump_begin (TDI_inheritance, &flags); odr_hash = new odr_hash_type (23); - if (in_lto_p) - odr_vtable_hash = new odr_vtable_hash_type (23); /* We reconstruct the graph starting of types of all methods seen in the unit. */ @@ -2892,10 +2690,7 @@ rebuild_type_inheritance_graph () if (!odr_hash) return; delete odr_hash; - if (in_lto_p) - delete odr_vtable_hash; odr_hash = NULL; - odr_vtable_hash = NULL; odr_types_ptr = NULL; free_polymorphic_call_targets_hash (); } Index: ipa-utils.h =================================================================== --- ipa-utils.h (revision 272018) +++ ipa-utils.h (working copy) @@ -187,19 +187,14 @@ type_with_linkage_p (const_tree t) if (!TYPE_NAME (t) || TREE_CODE (TYPE_NAME (t)) != TYPE_DECL) return false; - /* To support -fno-lto-odr-type-merigng recognize types with vtables - to have linkage. */ - if (RECORD_OR_UNION_TYPE_P (t) - && TYPE_BINFO (t) && BINFO_VTABLE (TYPE_BINFO (t))) - return true; - - /* After free_lang_data was run and -flto-odr-type-merging we can recongize + /* After free_lang_data was run we can recongize types with linkage by presence of mangled name. */ if (DECL_ASSEMBLER_NAME_SET_P (TYPE_NAME (t))) return true; if (in_lto_p) return false; + /* We used to check for TYPE_STUB_DECL but that is set to NULL for forward declarations. */ @@ -243,23 +238,8 @@ odr_type_p (const_tree t) /* We do not have this information when not in LTO, but we do not need to care, since it is used only for type merging. */ gcc_checking_assert (in_lto_p || flag_lto); - - if (!type_with_linkage_p (t)) - return false; - - /* To support -fno-lto-odr-type-merging consider types with vtables ODR. */ - if (type_in_anonymous_namespace_p (t)) - return true; - - if (TYPE_NAME (t) && DECL_ASSEMBLER_NAME_SET_P (TYPE_NAME (t))) - { - /* C++ FE uses magic as assembler names of anonymous types. - verify that this match with type_in_anonymous_namespace_p. */ - gcc_checking_assert (strcmp ("", - IDENTIFIER_POINTER - (DECL_ASSEMBLER_NAME (TYPE_NAME (t))))); - return true; - } + return TYPE_NAME (t) && TREE_CODE (TYPE_NAME (t)) == TYPE_DECL + && DECL_ASSEMBLER_NAME_SET_P (TYPE_NAME (t)); return false; } Index: tree.c =================================================================== --- tree.c (revision 272018) +++ tree.c (working copy) @@ -5590,8 +5590,7 @@ need_assembler_name_p (tree decl) if (TREE_CODE (decl) == TYPE_DECL) { - if (flag_lto_odr_type_mering - && DECL_NAME (decl) + if (DECL_NAME (decl) && decl == TYPE_NAME (TREE_TYPE (decl)) && TYPE_MAIN_VARIANT (TREE_TYPE (decl)) == TREE_TYPE (decl) && !TYPE_ARTIFICIAL (TREE_TYPE (decl))