From patchwork Tue Mar 24 14:28:51 2015 Content-Type: text/plain; charset="utf-8" MIME-Version: 1.0 Content-Transfer-Encoding: 7bit X-Patchwork-Submitter: =?utf-8?q?Martin_Li=C5=A1ka?= X-Patchwork-Id: 453855 Return-Path: X-Original-To: incoming@patchwork.ozlabs.org Delivered-To: patchwork-incoming@bilbo.ozlabs.org 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 01F7E1400D5 for ; Wed, 25 Mar 2015 01:29:09 +1100 (AEDT) Authentication-Results: ozlabs.org; dkim=pass reason="1024-bit key; unprotected key" header.d=gcc.gnu.org header.i=@gcc.gnu.org header.b=BOkeNQlk; dkim-adsp=none (unprotected policy); dkim-atps=neutral DomainKey-Signature: a=rsa-sha1; c=nofws; d=gcc.gnu.org; h=list-id :list-unsubscribe:list-archive:list-post:list-help:sender :message-id:date:from:mime-version:to:cc:subject:content-type; q=dns; s=default; b=Uf6iwgJDnVAU2mAlpus59pAgcE7GyloFL53REUnbzrf O9c8xjF12rufCrWexTPkbrlpBEvr5MNRppdDg+rzPKVqUVNk3xnCknwVKg0ZaE2s Hq8sj4WQchQGMzJCmV6fT3rReW7VL0npl/54sjRMrS0jsWhBT6IIkW8cXnilb9f0 = 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 :message-id:date:from:mime-version:to:cc:subject:content-type; s=default; bh=NI9AGQNfEU2E5b+mdZriaNLGTxM=; b=BOkeNQlkFsish9ilp WDvidb78oRwmQnWF+jhVqqGUqB+F5chhA/KVOCX7LiDqWwU1nGKHgCcEbNkwE8kP mgy3BVfQPAB3b24yuLP9MgMLDZj6Ie8Nd25hYTF7IdndYRXhuqteEPy9HIUKqYMt xf+tdHVVGZPdYzl16BK202fk4U= Received: (qmail 55169 invoked by alias); 24 Mar 2015 14:29:01 -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 55152 invoked by uid 89); 24 Mar 2015 14:28:59 -0000 Authentication-Results: sourceware.org; auth=none X-Virus-Found: No X-Spam-SWARE-Status: No, score=0.0 required=5.0 tests=AWL, BAYES_50 autolearn=ham version=3.3.2 X-HELO: mx2.suse.de Received: from cantor2.suse.de (HELO mx2.suse.de) (195.135.220.15) by sourceware.org (qpsmtpd/0.93/v0.84-503-g423c35a) with (CAMELLIA256-SHA encrypted) ESMTPS; Tue, 24 Mar 2015 14:28:56 +0000 Received: from relay1.suse.de (charybdis-ext.suse.de [195.135.220.254]) by mx2.suse.de (Postfix) with ESMTP id 391FEABB1; Tue, 24 Mar 2015 14:28:53 +0000 (UTC) Message-ID: <551174A3.2070400@suse.cz> Date: Tue, 24 Mar 2015 15:28:51 +0100 From: =?UTF-8?B?TWFydGluIExpxaFrYQ==?= User-Agent: Mozilla/5.0 (X11; Linux x86_64; rv:31.0) Gecko/20100101 Thunderbird/31.4.0 MIME-Version: 1.0 To: GCC Patches CC: Jan Hubicka Subject: [PATCH] IPA ICF: make hash values finer X-IsSubscribed: yes Hello. Following patch should be final speed-up patch for IPA ICF. It just basically enhances hash values of a symbol, computed in a TU. Having finer hash values, we do not spend so much time in WPA phase. It shows, we can reduce utilization from 14% -> 9% (_w/o_ WPA streaming out). Time report and ICF dump are added as attachment. Second, very small, part of the patch replaces add_ptr with add_int (for ultimate_alias_target). Can boostrap on ppc64le-linux-pc and no regression seen on x86_64-linux-pc. I've been running LTO builds for chrome, firefox and inkscape. Ready for trunk? Thanks, Martin 1 false returned: '' (compare_phi_node:1426) 4 false returned: '' (compare_operand:490) 4 false returned: 'different dependence info' (compare_memory_operand:351) 5 false returned: 'alignment mismatch' (equals_wpa:1530) 11 false returned: 'TREE_CODE mismatch' (equals:1625) 19 false returned: 'switch label_exprs are different' (compare_gimple_switch:950) 42 false returned: 'INTEGER_CST precision mismatch' (equals:1708) 49 false returned: 'ASM strings are different' (compare_gimple_asm:1027) 57 false returned: 'case high values are different' (compare_gimple_switch:941) 57 false returned: 'operator new flags are different' (equals_wpa:422) 163 false returned: '' (compare_operand:493) 195 false returned: '' (compare_phi_node:1449) 196 false returned: 'PHI node comparison returns false' (equals_private:774) 282 false returned: 'different operand volatility' (compare_memory_operand:312) 283 false returned: 'ao alias sets are different' (compare_memory_operand:316) 399 false returned: 'variables types are different' (equals:1596) 448 false returned: 'Unknown TREE code reached' (compare_operand:572) 477 false returned: 'Declaration mismatch' (equals:1704) 478 false returned: 'case low values are different' (compare_gimple_switch:935) 624 false returned: '' (compare_operand:472) 689 false returned: 'different number of arguments' (equals_wpa:407) 915 false returned: 'memory operands are different' (compare_gimple_call:805) 1469 false returned: 'DECL_DISREGARD_INLINE_LIMITS are different' (equals_wpa:416) 3298 false returned: '' (compare_operand:437) 4918 false returned: 'Target flags are different' (equals_wpa:467) 6036 false returned: 'different access alignment' (compare_memory_operand:334) 7209 false returned: 'one type is not polymorphic' (compatible_polymorphic_types_p:258) 10177 false returned: '' (equals_private:719) 10979 false returned: 'OBJ_TYPE_REF OTR type mismatch' (compare_operand:523) 11271 false returned: '' (equals_private:694) 11282 false returned: 'DELC_CXX_CONSTRUCTOR mismatch' (equals_wpa:433) 11624 false returned: 'alias sets are different' (compatible_types_p:278) 11662 false returned: '' (compare_gimple_call:767) 16327 false returned: 'virtual or final flag mismatch' (equals_wpa:1571) 21104 false returned: 'METHOD_TYPE and FUNCTION_TYPE mismatch' (equals_wpa:523) 26301 false returned: 'result types are different' (equals_wpa:487) 32513 false returned: 'different references' (compare_cgraph_references:374) 60327 false returned: 'DELC_CXX_DESTRUCTOR mismatch' (equals_wpa:436) 73746 false returned: 'decl_or_type flags are different' (equals_wpa:439) 91856 false returned: 'references to virtual tables can not be merged' (compare_cgraph_references:360) 195276 false returned: 'argument type is different' (equals_wpa:498) 209619 false returned: 'call function types are not compatible' (compare_gimple_call:789) 223350 false returned: 'different tree types' (compatible_types_p:269) 427168 false returned: 'ctor polymorphic type mismatch' (equals_wpa:452) 507495 false returned: 'types are not compatible' (compatible_types_p:275) 567596 false returned: 'memory operands are different' (compare_gimple_assign:844) 628846 false returned: 'optimization flags are different' (equals_wpa:481) 815465 false returned: '' (equals_private:737) 15707328 false returned: 'inline attributes are different' (equals_wpa:419) 18891178 false returned: 'THIS pointer ODR type mismatch' (equals_wpa:527) 19311137 false returned: 'types are not same for ODR' (compatible_polymorphic_types_p:260) Execution times (seconds) phase setup : 0.00 ( 0%) usr 0.00 ( 0%) sys 0.00 ( 0%) wall 1978 kB ( 0%) ggc phase opt and generate : 96.43 (45%) usr 2.13 (46%) sys 98.52 (45%) wall 2497753 kB (12%) ggc phase stream in : 120.12 (55%) usr 2.54 (54%) sys 122.61 (55%) wall18700766 kB (88%) ggc callgraph optimization : 0.81 ( 0%) usr 0.00 ( 0%) sys 0.82 ( 0%) wall 14 kB ( 0%) ggc ipa dead code removal : 6.85 ( 3%) usr 0.04 ( 1%) sys 6.76 ( 3%) wall 0 kB ( 0%) ggc ipa virtual call target : 4.04 ( 2%) usr 0.07 ( 1%) sys 4.08 ( 2%) wall 0 kB ( 0%) ggc ipa devirtualization : 0.30 ( 0%) usr 0.00 ( 0%) sys 0.33 ( 0%) wall 34666 kB ( 0%) ggc ipa cp : 5.70 ( 3%) usr 0.38 ( 8%) sys 6.08 ( 3%) wall 919225 kB ( 4%) ggc ipa inlining heuristics : 27.05 (12%) usr 0.40 ( 9%) sys 27.61 (12%) wall 811784 kB ( 4%) ggc ipa comdats : 0.62 ( 0%) usr 0.00 ( 0%) sys 0.62 ( 0%) wall 0 kB ( 0%) ggc ipa lto gimple in : 5.74 ( 3%) usr 0.95 (20%) sys 6.67 ( 3%) wall 1161422 kB ( 5%) ggc ipa lto decl in : 103.66 (48%) usr 1.63 (35%) sys 105.25 (48%) wall16830013 kB (79%) ggc ipa lto constructors in : 0.49 ( 0%) usr 0.05 ( 1%) sys 0.52 ( 0%) wall 27315 kB ( 0%) ggc ipa lto cgraph I/O : 2.20 ( 1%) usr 0.29 ( 6%) sys 2.48 ( 1%) wall 954517 kB ( 5%) ggc ipa lto decl merge : 4.13 ( 2%) usr 0.00 ( 0%) sys 4.13 ( 2%) wall 16383 kB ( 0%) ggc ipa lto cgraph merge : 5.65 ( 3%) usr 0.01 ( 0%) sys 5.63 ( 3%) wall 21738 kB ( 0%) ggc whopr wpa : 1.99 ( 1%) usr 0.00 ( 0%) sys 2.01 ( 1%) wall 2 kB ( 0%) ggc whopr partitioning : 5.23 ( 2%) usr 0.01 ( 0%) sys 5.22 ( 2%) wall 8936 kB ( 0%) ggc ipa reference : 3.57 ( 2%) usr 0.01 ( 0%) sys 3.57 ( 2%) wall 0 kB ( 0%) ggc ipa profile : 0.50 ( 0%) usr 0.03 ( 1%) sys 0.53 ( 0%) wall 0 kB ( 0%) ggc ipa pure const : 4.43 ( 2%) usr 0.07 ( 1%) sys 4.49 ( 2%) wall 0 kB ( 0%) ggc ipa icf : 30.49 (14%) usr 0.27 ( 6%) sys 30.82 (14%) wall 31893 kB ( 0%) ggc tree SSA rewrite : 0.24 ( 0%) usr 0.08 ( 2%) sys 0.38 ( 0%) wall 47000 kB ( 0%) ggc tree SSA other : 0.00 ( 0%) usr 0.00 ( 0%) sys 0.01 ( 0%) wall 0 kB ( 0%) ggc tree SSA incremental : 0.58 ( 0%) usr 0.11 ( 2%) sys 0.52 ( 0%) wall 30453 kB ( 0%) ggc tree operand scan : 0.46 ( 0%) usr 0.09 ( 2%) sys 0.57 ( 0%) wall 302599 kB ( 1%) ggc dominance frontiers : 0.01 ( 0%) usr 0.00 ( 0%) sys 0.03 ( 0%) wall 0 kB ( 0%) ggc dominance computation : 0.34 ( 0%) usr 0.06 ( 1%) sys 0.35 ( 0%) wall 0 kB ( 0%) ggc varconst : 0.03 ( 0%) usr 0.04 ( 1%) sys 0.09 ( 0%) wall 0 kB ( 0%) ggc loop init : 0.02 ( 0%) usr 0.00 ( 0%) sys 0.02 ( 0%) wall 546 kB ( 0%) ggc loop fini : 0.12 ( 0%) usr 0.00 ( 0%) sys 0.15 ( 0%) wall 0 kB ( 0%) ggc unaccounted todo : 1.23 ( 1%) usr 0.00 ( 0%) sys 1.23 ( 1%) wall 0 kB ( 0%) ggc TOTAL : 216.55 4.67 221.13 21200498 kB 1 false returned: '' (compare_phi_node:1534) 2 false returned: 'operator new flags are different' (equals_wpa:442) 4 false returned: '' (compare_operand:490) 4 false returned: 'different dependence info' (compare_memory_operand:351) 5 false returned: 'alignment mismatch' (equals_wpa:1638) 11 false returned: 'TREE_CODE mismatch' (equals:1733) 18 false returned: 'switch label_exprs are different' (compare_gimple_switch:950) 42 false returned: 'INTEGER_CST precision mismatch' (equals:1816) 49 false returned: 'ASM strings are different' (compare_gimple_asm:1027) 57 false returned: 'case high values are different' (compare_gimple_switch:941) 76 false returned: 'one type is not polymorphic' (compatible_polymorphic_types_p:258) 124 false returned: '' (compare_operand:493) 145 false returned: 'ao alias sets are different' (compare_memory_operand:316) 179 false returned: 'different operand volatility' (compare_memory_operand:312) 195 false returned: '' (compare_phi_node:1557) 196 false returned: 'PHI node comparison returns false' (equals_private:794) 382 false returned: 'DECL_CXX_DESTRUCTOR mismatch' (equals_wpa:456) 399 false returned: 'variables types are different' (equals:1704) 447 false returned: 'Unknown TREE code reached' (compare_operand:572) 477 false returned: 'Declaration mismatch' (equals:1812) 478 false returned: 'case low values are different' (compare_gimple_switch:935) 558 false returned: '' (compare_operand:472) 694 false returned: 'different number of arguments' (equals_wpa:427) 836 false returned: 'ctor polymorphic type mismatch' (equals_wpa:472) 915 false returned: 'memory operands are different' (compare_gimple_call:805) 1462 false returned: 'DECL_DISREGARD_INLINE_LIMITS are different' (equals_wpa:436) 2012 false returned: 'METHOD_TYPE and FUNCTION_TYPE mismatch' (equals_wpa:543) 2132 false returned: 'DECL_CXX_CONSTRUCTOR mismatch' (equals_wpa:453) 2937 false returned: 'different access alignment' (compare_memory_operand:334) 3291 false returned: '' (compare_operand:437) 4446 false returned: 'decl_or_type flags are different' (equals_wpa:459) 4498 false returned: 'result types are different' (equals_wpa:507) 6176 false returned: 'alias sets are different' (compatible_types_p:278) 10175 false returned: '' (equals_private:739) 10975 false returned: 'OBJ_TYPE_REF OTR type mismatch' (compare_operand:523) 11271 false returned: '' (equals_private:714) 11472 false returned: '' (compare_gimple_call:767) 16327 false returned: 'virtual or final flag mismatch' (equals_wpa:1679) 30871 false returned: 'optimization flags are different' (equals_wpa:501) 32210 false returned: 'different references' (compare_cgraph_references:394) 61843 false returned: 'THIS pointer ODR type mismatch' (equals_wpa:547) 62603 false returned: 'types are not same for ODR' (compatible_polymorphic_types_p:260) 65471 false returned: 'argument type is different' (equals_wpa:518) 72113 false returned: 'different tree types' (compatible_types_p:269) 82299 false returned: 'references to virtual tables can not be merged' (compare_cgraph_references:380) 149847 false returned: 'inline attributes are different' (equals_wpa:439) 209606 false returned: 'call function types are not compatible' (compare_gimple_call:789) 489018 false returned: 'types are not compatible' (compatible_types_p:275) 540847 false returned: 'memory operands are different' (compare_gimple_assign:844) 765620 false returned: '' (equals_private:757) Equal symbols: 84571 Execution times (seconds) phase setup : 0.00 ( 0%) usr 0.00 ( 0%) sys 0.00 ( 0%) wall 1978 kB ( 0%) ggc phase opt and generate : 70.09 (43%) usr 1.54 (41%) sys 71.60 (43%) wall 2463719 kB (12%) ggc phase stream in : 94.04 (57%) usr 2.26 (59%) sys 96.53 (57%) wall18700766 kB (88%) ggc callgraph optimization : 0.73 ( 0%) usr 0.00 ( 0%) sys 0.73 ( 0%) wall 14 kB ( 0%) ggc ipa dead code removal : 6.07 ( 4%) usr 0.02 ( 1%) sys 5.85 ( 3%) wall 0 kB ( 0%) ggc ipa virtual call target : 3.05 ( 2%) usr 0.05 ( 1%) sys 3.44 ( 2%) wall 0 kB ( 0%) ggc ipa devirtualization : 0.25 ( 0%) usr 0.00 ( 0%) sys 0.24 ( 0%) wall 34666 kB ( 0%) ggc ipa cp : 4.86 ( 3%) usr 0.25 ( 7%) sys 5.08 ( 3%) wall 919225 kB ( 4%) ggc ipa inlining heuristics : 22.24 (14%) usr 0.25 ( 7%) sys 22.44 (13%) wall 811770 kB ( 4%) ggc ipa comdats : 0.55 ( 0%) usr 0.00 ( 0%) sys 0.56 ( 0%) wall 0 kB ( 0%) ggc ipa lto gimple in : 4.27 ( 3%) usr 0.70 (18%) sys 5.01 ( 3%) wall 1136096 kB ( 5%) ggc ipa lto decl in : 80.30 (49%) usr 1.44 (38%) sys 81.97 (49%) wall16830013 kB (80%) ggc ipa lto constructors in : 0.35 ( 0%) usr 0.06 ( 2%) sys 0.38 ( 0%) wall 27315 kB ( 0%) ggc ipa lto cgraph I/O : 1.51 ( 1%) usr 0.27 ( 7%) sys 1.78 ( 1%) wall 954517 kB ( 5%) ggc ipa lto decl merge : 3.56 ( 2%) usr 0.00 ( 0%) sys 3.56 ( 2%) wall 16383 kB ( 0%) ggc ipa lto cgraph merge : 4.89 ( 3%) usr 0.00 ( 0%) sys 4.89 ( 3%) wall 21738 kB ( 0%) ggc whopr wpa : 1.83 ( 1%) usr 0.00 ( 0%) sys 1.87 ( 1%) wall 2 kB ( 0%) ggc whopr partitioning : 4.87 ( 3%) usr 0.01 ( 0%) sys 4.87 ( 3%) wall 8936 kB ( 0%) ggc ipa reference : 2.77 ( 2%) usr 0.01 ( 0%) sys 2.78 ( 2%) wall 0 kB ( 0%) ggc ipa profile : 0.49 ( 0%) usr 0.03 ( 1%) sys 0.54 ( 0%) wall 0 kB ( 0%) ggc ipa pure const : 3.23 ( 2%) usr 0.05 ( 1%) sys 3.28 ( 2%) wall 0 kB ( 0%) ggc ipa icf : 15.59 ( 9%) usr 0.29 ( 8%) sys 15.71 ( 9%) wall 31897 kB ( 0%) ggc tree SSA rewrite : 0.30 ( 0%) usr 0.06 ( 2%) sys 0.26 ( 0%) wall 45801 kB ( 0%) ggc tree SSA incremental : 0.37 ( 0%) usr 0.07 ( 2%) sys 0.54 ( 0%) wall 29452 kB ( 0%) ggc tree operand scan : 0.31 ( 0%) usr 0.09 ( 2%) sys 0.51 ( 0%) wall 296103 kB ( 1%) ggc dominance frontiers : 0.01 ( 0%) usr 0.00 ( 0%) sys 0.02 ( 0%) wall 0 kB ( 0%) ggc dominance computation : 0.30 ( 0%) usr 0.04 ( 1%) sys 0.31 ( 0%) wall 0 kB ( 0%) ggc varconst : 0.04 ( 0%) usr 0.01 ( 0%) sys 0.07 ( 0%) wall 0 kB ( 0%) ggc loop init : 0.01 ( 0%) usr 0.00 ( 0%) sys 0.00 ( 0%) wall 546 kB ( 0%) ggc loop fini : 0.12 ( 0%) usr 0.00 ( 0%) sys 0.14 ( 0%) wall 0 kB ( 0%) ggc unaccounted todo : 1.20 ( 1%) usr 0.00 ( 0%) sys 1.15 ( 1%) wall 0 kB ( 0%) ggc TOTAL : 164.13 3.80 168.13 21166465 kB From 1943aa293c1ff7622cf9090a834d7bd9dfaaf086 Mon Sep 17 00:00:00 2001 From: mliska Date: Mon, 23 Mar 2015 15:36:11 +0100 Subject: [PATCH] IPA ICF: enhance hash value calculated in TU gcc/ChangeLog: 2015-03-23 Jan Hubicka Martin Liska * ipa-icf-gimple.h (return_with_result): Add missing colon to dump. * ipa-icf.c (sem_function::get_hash): Hash new declaration properties. (sem_item::add_type): New function. (sem_function::hash_stmt): Add TREE_TYPE of gimple_op. (sem_function::compare_polymorphic_p): Do not consider indirect calls. (sem_item_optimizer::update_hash_by_addr_refs): Add ODR type to hash. (sem_function::equals_wpa): Fix typo. * ipa-icf.h (sem_item::add_type): New function. (symbol_compare_hashmap_traits): Replace hashing of pointer with symbol order. --- gcc/ipa-icf-gimple.h | 2 +- gcc/ipa-icf.c | 160 ++++++++++++++++++++++++++++++++++++++++++++++----- gcc/ipa-icf.h | 10 +++- 3 files changed, 154 insertions(+), 18 deletions(-) diff --git a/gcc/ipa-icf-gimple.h b/gcc/ipa-icf-gimple.h index 53a1bfe..6a9cbed 100644 --- a/gcc/ipa-icf-gimple.h +++ b/gcc/ipa-icf-gimple.h @@ -75,7 +75,7 @@ static inline bool return_with_result (bool result, const char *func, unsigned int line) { if (!result && dump_file && (dump_flags & TDF_DETAILS)) - fprintf (dump_file, " false returned (%s:%u)\n", func, line); + fprintf (dump_file, " false returned: (%s:%u)\n", func, line); return result; } diff --git a/gcc/ipa-icf.c b/gcc/ipa-icf.c index 48a7d3d..ad868e1 100644 --- a/gcc/ipa-icf.c +++ b/gcc/ipa-icf.c @@ -128,6 +128,11 @@ using namespace ipa_icf_gimple; namespace ipa_icf { +/* Initialization and computation of symtab node hash, there data + are propagated later on. */ + +static sem_item_optimizer *optimizer = NULL; + /* Constructor. */ symbol_compare_collection::symbol_compare_collection (symtab_node *node) @@ -328,6 +333,21 @@ sem_function::get_hash (void) for (unsigned i = 0; i < bb_sizes.length (); i++) hstate.add_int (bb_sizes[i]); + + /* Add common features of declaration itself. */ + if (DECL_FUNCTION_SPECIFIC_TARGET (decl)) + hstate.add_wide_int + (cl_target_option_hash + (TREE_TARGET_OPTION (DECL_FUNCTION_SPECIFIC_TARGET (decl)))); + if (DECL_FUNCTION_SPECIFIC_OPTIMIZATION (decl)) + (cl_optimization_hash + (TREE_OPTIMIZATION (DECL_FUNCTION_SPECIFIC_OPTIMIZATION (decl)))); + hstate.add_flag (DECL_DISREGARD_INLINE_LIMITS (decl)); + hstate.add_flag (DECL_DECLARED_INLINE_P (decl)); + hstate.add_flag (DECL_IS_OPERATOR_NEW (decl)); + hstate.add_flag (DECL_CXX_CONSTRUCTOR_P (decl)); + hstate.add_flag (DECL_CXX_DESTRUCTOR_P (decl)); + hash = hstate.end (); } @@ -430,10 +450,10 @@ sem_function::equals_wpa (sem_item *item, return return_false_with_msg ("no stack limit attributes are different"); if (DECL_CXX_CONSTRUCTOR_P (decl) != DECL_CXX_CONSTRUCTOR_P (item->decl)) - return return_false_with_msg ("DELC_CXX_CONSTRUCTOR mismatch"); + return return_false_with_msg ("DECL_CXX_CONSTRUCTOR mismatch"); if (DECL_CXX_DESTRUCTOR_P (decl) != DECL_CXX_DESTRUCTOR_P (item->decl)) - return return_false_with_msg ("DELC_CXX_DESTRUCTOR mismatch"); + return return_false_with_msg ("DECL_CXX_DESTRUCTOR mismatch"); if (flags_from_decl_or_type (decl) != flags_from_decl_or_type (item->decl)) return return_false_with_msg ("decl_or_type flags are different"); @@ -1283,6 +1303,80 @@ sem_item::add_expr (const_tree exp, inchash::hash &hstate) } } +/* Accumulate to HSTATE a hash of type t. + TYpes that may end up being compatible after LTO type merging needs to have + the same hash. */ + +void +sem_item::add_type (const_tree type, inchash::hash &hstate) +{ + if (type == NULL_TREE) + { + hstate.merge_hash (0); + return; + } + + type = TYPE_MAIN_VARIANT (type); + if (TYPE_CANONICAL (type)) + type = TYPE_CANONICAL (type); + + if (!AGGREGATE_TYPE_P (type)) + hstate.add_int (TYPE_MODE (type)); + + if (TREE_CODE (type) == COMPLEX_TYPE) + { + hstate.add_int (COMPLEX_TYPE); + sem_item::add_type (TREE_TYPE (type), hstate); + } + else if (INTEGRAL_TYPE_P (type)) + { + hstate.add_int (INTEGER_TYPE); + hstate.add_flag (TYPE_UNSIGNED (type)); + hstate.add_int (TYPE_PRECISION (type)); + } + else if (VECTOR_TYPE_P (type)) + { + hstate.add_int (VECTOR_TYPE); + hstate.add_int (TYPE_PRECISION (type)); + sem_item::add_type (TREE_TYPE (type), hstate); + } + else if (TREE_CODE (type) == ARRAY_TYPE) + { + hstate.add_int (ARRAY_TYPE); + /* Do not hash size, so complete and incomplete types can match. */ + sem_item::add_type (TREE_TYPE (type), hstate); + } + else if (RECORD_OR_UNION_TYPE_P (type)) + { + hashval_t *val = optimizer->m_type_hash_cache.get (type); + + if (!val) + { + inchash::hash hstate2; + unsigned nf; + tree f; + hashval_t hash; + + hstate2.add_int (RECORD_TYPE); + gcc_assert (COMPLETE_TYPE_P (type)); + + for (f = TYPE_FIELDS (type), nf = 0; f; f = TREE_CHAIN (f)) + if (TREE_CODE (f) == FIELD_DECL) + { + add_type (TREE_TYPE (f), hstate2); + nf++; + } + + hstate2.add_int (nf); + hash = hstate2.end (); + hstate.add_wide_int (hash); + optimizer->m_type_hash_cache.put (type, hash); + } + else + hstate.add_wide_int (*val); + } +} + /* Improve accumulated hash for HSTATE based on a gimple statement STMT. */ void @@ -1294,16 +1388,27 @@ sem_function::hash_stmt (gimple stmt, inchash::hash &hstate) switch (code) { + case GIMPLE_SWITCH: + add_expr (gimple_switch_index (as_a (stmt)), hstate); + break; case GIMPLE_ASSIGN: + hstate.add_int (gimple_assign_rhs_code (stmt)); if (commutative_tree_code (gimple_assign_rhs_code (stmt)) || commutative_ternary_tree_code (gimple_assign_rhs_code (stmt))) { inchash::hash one, two; add_expr (gimple_assign_rhs1 (stmt), one); + add_type (TREE_TYPE (gimple_assign_rhs1 (stmt)), one); add_expr (gimple_assign_rhs2 (stmt), two); hstate.add_commutative (one, two); + if (commutative_ternary_tree_code (gimple_assign_rhs_code (stmt))) + { + add_expr (gimple_assign_rhs3 (stmt), hstate); + add_type (TREE_TYPE (gimple_assign_rhs3 (stmt)), hstate); + } add_expr (gimple_assign_lhs (stmt), hstate); + add_type (TREE_TYPE (gimple_assign_lhs (stmt)), two); break; } /* ... fall through ... */ @@ -1314,7 +1419,11 @@ sem_function::hash_stmt (gimple stmt, inchash::hash &hstate) case GIMPLE_RETURN: /* All these statements are equivalent if their operands are. */ for (unsigned i = 0; i < gimple_num_ops (stmt); ++i) - add_expr (gimple_op (stmt, i), hstate); + { + add_expr (gimple_op (stmt, i), hstate); + if (gimple_op (stmt, i)) + add_type (TREE_TYPE (gimple_op (stmt, i)), hstate); + } default: break; } @@ -1328,14 +1437,13 @@ sem_function::compare_polymorphic_p (void) { struct cgraph_edge *e; - if (!opt_for_fn (decl, flag_devirtualize)) + if (!opt_for_fn (get_node ()->decl, flag_devirtualize)) return false; - if (get_node ()->indirect_calls != NULL - || m_compared_func->get_node ()->indirect_calls != NULL) + if (get_node ()->indirect_calls != NULL) return true; /* TODO: We can do simple propagation determining what calls may lead to a polymorphic call. */ - for (e = m_compared_func->get_node ()->callees; e; e = e->next_callee) + for (e = get_node ()->callees; e; e = e->next_callee) if (e->callee->definition && opt_for_fn (e->callee->decl, flag_devirtualize)) return true; @@ -2386,9 +2494,38 @@ sem_item_optimizer::add_item_to_class (congruence_class *cls, sem_item *item) void sem_item_optimizer::update_hash_by_addr_refs () { - /* First, append to hash sensitive references. */ + /* First, append to hash sensitive references and class type if it need to + be matched for ODR. */ for (unsigned i = 0; i < m_items.length (); i++) - m_items[i]->update_hash_by_addr_refs (m_symtab_node_map); + { + m_items[i]->update_hash_by_addr_refs (m_symtab_node_map); + if (m_items[i]->type == FUNC) + { + if (TREE_CODE (TREE_TYPE (m_items[i]->decl)) == METHOD_TYPE + && contains_polymorphic_type_p + (method_class_type (TREE_TYPE (m_items[i]->decl))) + && (DECL_CXX_CONSTRUCTOR_P (m_items[i]->decl) + || ((!flag_ipa_cp + || ipa_is_param_used ( + IPA_NODE_REF + (dyn_cast (m_items[i]->node)), 0)) + && static_cast (m_items[i]) + ->compare_polymorphic_p ()))) + { + tree class_type + = method_class_type (TREE_TYPE (m_items[i]->decl)); + inchash::hash hstate (m_items[i]->hash); + + if (TYPE_NAME (class_type) + && DECL_ASSEMBLER_NAME_SET_P (TYPE_NAME (class_type))) + hstate.add_wide_int + (IDENTIFIER_HASH_VALUE + (DECL_ASSEMBLER_NAME (TYPE_NAME (class_type)))); + + m_items[i]->hash = hstate.end (); + } + } + } /* Once all symbols have enhanced hash value, we can append hash values of symbols that are seen by IPA ICF and are @@ -3123,11 +3260,6 @@ congruence_class::is_class_used (void) return false; } -/* Initialization and computation of symtab node hash, there data - are propagated later on. */ - -static sem_item_optimizer *optimizer = NULL; - /* Generate pass summary for IPA ICF pass. */ static void diff --git a/gcc/ipa-icf.h b/gcc/ipa-icf.h index cd21cac..7eb9f27 100644 --- a/gcc/ipa-icf.h +++ b/gcc/ipa-icf.h @@ -96,12 +96,12 @@ struct symbol_compare_hashmap_traits: default_hashmap_traits hstate.add_int (v->m_references.length ()); for (unsigned i = 0; i < v->m_references.length (); i++) - hstate.add_ptr (v->m_references[i]->ultimate_alias_target ()); + hstate.add_int (v->m_references[i]->ultimate_alias_target ()->order); hstate.add_int (v->m_interposables.length ()); for (unsigned i = 0; i < v->m_interposables.length (); i++) - hstate.add_ptr (v->m_interposables[i]->ultimate_alias_target ()); + hstate.add_int (v->m_interposables[i]->ultimate_alias_target ()->order); return hstate.end (); } @@ -243,8 +243,10 @@ public: protected: /* Cached, once calculated hash for the item. */ - /* Accumulate to HSTATE a hash of constructor expression EXP. */ + /* Accumulate to HSTATE a hash of expression EXP. */ static void add_expr (const_tree exp, inchash::hash &hstate); + /* Accumulate to HSTATE a hash of type T. */ + static void add_type (const_tree t, inchash::hash &hstate); /* For a given symbol table nodes N1 and N2, we check that FUNCTION_DECLs point to a same function. Comparison can be skipped if IGNORED_NODES @@ -505,6 +507,8 @@ public: congruence_class_group *get_group_by_hash (hashval_t hash, sem_item_type type); + /* Because types can be arbitrarily large, avoid quadratic bottleneck. */ + hash_map m_type_hash_cache; private: /* For each semantic item, append hash values of references. */ -- 2.1.4