* [PATCH] IPA ICF: make hash values finer
@ 2015-03-24 14:29 Martin Liška
2015-03-24 17:32 ` Jan Hubicka
0 siblings, 1 reply; 2+ messages in thread
From: Martin Liška @ 2015-03-24 14:29 UTC (permalink / raw)
To: GCC Patches; +Cc: Jan Hubicka
[-- Attachment #1: Type: text/plain, Size: 606 bytes --]
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
[-- Attachment #2: chrome-icf-hash-before.txt --]
[-- Type: text/plain, Size: 7106 bytes --]
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
[-- Attachment #3: chrome-icf-hash-enhancement.txt --]
[-- Type: text/plain, Size: 6954 bytes --]
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
[-- Attachment #4: 0001-IPA-ICF-enhance-hash-value-calculated-in-TU.patch --]
[-- Type: text/x-patch, Size: 11290 bytes --]
From 1943aa293c1ff7622cf9090a834d7bd9dfaaf086 Mon Sep 17 00:00:00 2001
From: mliska <mliska@suse.cz>
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 <hubicka@ucw.cz>
Martin Liska <mliska@suse.cz>
* 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 <gswitch *> (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 <cgraph_node *>(m_items[i]->node)), 0))
+ && static_cast<sem_function *> (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<const_tree, hashval_t> m_type_hash_cache;
private:
/* For each semantic item, append hash values of references. */
--
2.1.4
^ permalink raw reply [flat|nested] 2+ messages in thread
* Re: [PATCH] IPA ICF: make hash values finer
2015-03-24 14:29 [PATCH] IPA ICF: make hash values finer Martin Liška
@ 2015-03-24 17:32 ` Jan Hubicka
0 siblings, 0 replies; 2+ messages in thread
From: Jan Hubicka @ 2015-03-24 17:32 UTC (permalink / raw)
To: Martin Liška; +Cc: GCC Patches, Jan Hubicka
> >From 1943aa293c1ff7622cf9090a834d7bd9dfaaf086 Mon Sep 17 00:00:00 2001
> From: mliska <mliska@suse.cz>
> 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 <hubicka@ucw.cz>
> Martin Liska <mliska@suse.cz>
>
> * 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.
OK,
thanks!
Honza
^ permalink raw reply [flat|nested] 2+ messages in thread
end of thread, other threads:[~2015-03-24 17:32 UTC | newest]
Thread overview: 2+ messages (download: mbox.gz / follow: Atom feed)
-- links below jump to the message on this page --
2015-03-24 14:29 [PATCH] IPA ICF: make hash values finer Martin Liška
2015-03-24 17:32 ` Jan Hubicka
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).