comparison gcc/ipa-icf.c @ 131:84e7813d76e9

gcc-8.2
author mir3636
date Thu, 25 Oct 2018 07:37:49 +0900
parents 04ced10e8804
children 1830386684a0
comparison
equal deleted inserted replaced
111:04ced10e8804 131:84e7813d76e9
1 /* Interprocedural Identical Code Folding pass 1 /* Interprocedural Identical Code Folding pass
2 Copyright (C) 2014-2017 Free Software Foundation, Inc. 2 Copyright (C) 2014-2018 Free Software Foundation, Inc.
3 3
4 Contributed by Jan Hubicka <hubicka@ucw.cz> and Martin Liska <mliska@suse.cz> 4 Contributed by Jan Hubicka <hubicka@ucw.cz> and Martin Liska <mliska@suse.cz>
5 5
6 This file is part of GCC. 6 This file is part of GCC.
7 7
81 #include "ipa-utils.h" 81 #include "ipa-utils.h"
82 #include "ipa-icf-gimple.h" 82 #include "ipa-icf-gimple.h"
83 #include "ipa-icf.h" 83 #include "ipa-icf.h"
84 #include "stor-layout.h" 84 #include "stor-layout.h"
85 #include "dbgcnt.h" 85 #include "dbgcnt.h"
86 #include "tree-vector-builder.h"
86 87
87 using namespace ipa_icf_gimple; 88 using namespace ipa_icf_gimple;
88 89
89 namespace ipa_icf { 90 namespace ipa_icf {
90 91
223 void sem_item::set_hash (hashval_t hash) 224 void sem_item::set_hash (hashval_t hash)
224 { 225 {
225 m_hash = hash; 226 m_hash = hash;
226 m_hash_set = true; 227 m_hash_set = true;
227 } 228 }
229
230 hash_map<const_tree, hashval_t> sem_item::m_type_hash_cache;
228 231
229 /* Semantic function constructor that uses STACK as bitmap memory stack. */ 232 /* Semantic function constructor that uses STACK as bitmap memory stack. */
230 233
231 sem_function::sem_function (bitmap_obstack *stack) 234 sem_function::sem_function (bitmap_obstack *stack)
232 : sem_item (FUNC, stack), m_checker (NULL), m_compared_func (NULL) 235 : sem_item (FUNC, stack), m_checker (NULL), m_compared_func (NULL)
300 } 303 }
301 304
302 return m_hash; 305 return m_hash;
303 } 306 }
304 307
305 /* Return ture if A1 and A2 represent equivalent function attribute lists.
306 Based on comp_type_attributes. */
307
308 bool
309 sem_item::compare_attributes (const_tree a1, const_tree a2)
310 {
311 const_tree a;
312 if (a1 == a2)
313 return true;
314 for (a = a1; a != NULL_TREE; a = TREE_CHAIN (a))
315 {
316 const struct attribute_spec *as;
317 const_tree attr;
318
319 as = lookup_attribute_spec (get_attribute_name (a));
320 /* TODO: We can introduce as->affects_decl_identity
321 and as->affects_decl_reference_identity if attribute mismatch
322 gets a common reason to give up on merging. It may not be worth
323 the effort.
324 For example returns_nonnull affects only references, while
325 optimize attribute can be ignored because it is already lowered
326 into flags representation and compared separately. */
327 if (!as)
328 continue;
329
330 attr = lookup_attribute (as->name, CONST_CAST_TREE (a2));
331 if (!attr || !attribute_value_equal (a, attr))
332 break;
333 }
334 if (!a)
335 {
336 for (a = a2; a != NULL_TREE; a = TREE_CHAIN (a))
337 {
338 const struct attribute_spec *as;
339
340 as = lookup_attribute_spec (get_attribute_name (a));
341 if (!as)
342 continue;
343
344 if (!lookup_attribute (as->name, CONST_CAST_TREE (a1)))
345 break;
346 /* We don't need to compare trees again, as we did this
347 already in first loop. */
348 }
349 if (!a)
350 return true;
351 }
352 /* TODO: As in comp_type_attributes we may want to introduce target hook. */
353 return false;
354 }
355
356 /* Compare properties of symbols N1 and N2 that does not affect semantics of 308 /* Compare properties of symbols N1 and N2 that does not affect semantics of
357 symbol itself but affects semantics of its references from USED_BY (which 309 symbol itself but affects semantics of its references from USED_BY (which
358 may be NULL if it is unknown). If comparsion is false, symbols 310 may be NULL if it is unknown). If comparsion is false, symbols
359 can still be merged but any symbols referring them can't. 311 can still be merged but any symbols referring them can't.
360 312
424 /* For functions we compare attributes in equals_wpa, because we do 376 /* For functions we compare attributes in equals_wpa, because we do
425 not know what attributes may cause codegen differences, but for 377 not know what attributes may cause codegen differences, but for
426 variables just compare attributes for references - the codegen 378 variables just compare attributes for references - the codegen
427 for constructors is affected only by those attributes that we lower 379 for constructors is affected only by those attributes that we lower
428 to explicit representation (such as DECL_ALIGN or DECL_SECTION). */ 380 to explicit representation (such as DECL_ALIGN or DECL_SECTION). */
429 if (!compare_attributes (DECL_ATTRIBUTES (n1->decl), 381 if (!attribute_list_equal (DECL_ATTRIBUTES (n1->decl),
430 DECL_ATTRIBUTES (n2->decl))) 382 DECL_ATTRIBUTES (n2->decl)))
431 return return_false_with_msg ("different var decl attributes"); 383 return return_false_with_msg ("different var decl attributes");
432 if (comp_type_attributes (TREE_TYPE (n1->decl), 384 if (comp_type_attributes (TREE_TYPE (n1->decl),
433 TREE_TYPE (n2->decl)) != 1) 385 TREE_TYPE (n2->decl)) != 1)
434 return return_false_with_msg ("different var type attributes"); 386 return return_false_with_msg ("different var type attributes");
435 } 387 }
588 { 540 {
589 if (cnode->thunk.fixed_offset != cnode2->thunk.fixed_offset) 541 if (cnode->thunk.fixed_offset != cnode2->thunk.fixed_offset)
590 return return_false_with_msg ("thunk fixed_offset mismatch"); 542 return return_false_with_msg ("thunk fixed_offset mismatch");
591 if (cnode->thunk.virtual_value != cnode2->thunk.virtual_value) 543 if (cnode->thunk.virtual_value != cnode2->thunk.virtual_value)
592 return return_false_with_msg ("thunk virtual_value mismatch"); 544 return return_false_with_msg ("thunk virtual_value mismatch");
545 if (cnode->thunk.indirect_offset != cnode2->thunk.indirect_offset)
546 return return_false_with_msg ("thunk indirect_offset mismatch");
593 if (cnode->thunk.this_adjusting != cnode2->thunk.this_adjusting) 547 if (cnode->thunk.this_adjusting != cnode2->thunk.this_adjusting)
594 return return_false_with_msg ("thunk this_adjusting mismatch"); 548 return return_false_with_msg ("thunk this_adjusting mismatch");
595 if (cnode->thunk.virtual_offset_p != cnode2->thunk.virtual_offset_p) 549 if (cnode->thunk.virtual_offset_p != cnode2->thunk.virtual_offset_p)
596 return return_false_with_msg ("thunk virtual_offset_p mismatch"); 550 return return_false_with_msg ("thunk virtual_offset_p mismatch");
597 if (cnode->thunk.add_pointer_bounds_args 551 if (cnode->thunk.add_pointer_bounds_args
655 } 609 }
656 610
657 cl_optimization *opt1 = opts_for_fn (decl); 611 cl_optimization *opt1 = opts_for_fn (decl);
658 cl_optimization *opt2 = opts_for_fn (item->decl); 612 cl_optimization *opt2 = opts_for_fn (item->decl);
659 613
660 if (opt1 != opt2 && memcmp (opt1, opt2, sizeof(cl_optimization))) 614 if (opt1 != opt2 && !cl_optimization_option_eq (opt1, opt2))
661 { 615 {
662 if (dump_file && (dump_flags & TDF_DETAILS)) 616 if (dump_file && (dump_flags & TDF_DETAILS))
663 { 617 {
664 fprintf (dump_file, "optimization flags difference"); 618 fprintf (dump_file, "optimization flags difference");
665 cl_optimization_print_diff (dump_file, 2, opt1, opt2); 619 cl_optimization_print_diff (dump_file, 2, opt1, opt2);
709 /* Checking function attributes. 663 /* Checking function attributes.
710 This is quadratic in number of attributes */ 664 This is quadratic in number of attributes */
711 if (comp_type_attributes (TREE_TYPE (decl), 665 if (comp_type_attributes (TREE_TYPE (decl),
712 TREE_TYPE (item->decl)) != 1) 666 TREE_TYPE (item->decl)) != 1)
713 return return_false_with_msg ("different type attributes"); 667 return return_false_with_msg ("different type attributes");
714 if (!compare_attributes (DECL_ATTRIBUTES (decl), 668 if (!attribute_list_equal (DECL_ATTRIBUTES (decl),
715 DECL_ATTRIBUTES (item->decl))) 669 DECL_ATTRIBUTES (item->decl)))
716 return return_false_with_msg ("different decl attributes"); 670 return return_false_with_msg ("different decl attributes");
717 671
718 /* The type of THIS pointer type memory location for 672 /* The type of THIS pointer type memory location for
719 ipa-polymorphic-call-analysis. */ 673 ipa-polymorphic-call-analysis. */
720 if (opt_for_fn (decl, flag_devirtualize) 674 if (opt_for_fn (decl, flag_devirtualize)
1107 { 1061 {
1108 if (dump_file) 1062 if (dump_file)
1109 fprintf (dump_file, 1063 fprintf (dump_file,
1110 "Not unifying; " 1064 "Not unifying; "
1111 "original and alias are in different sections.\n\n"); 1065 "original and alias are in different sections.\n\n");
1066 return false;
1067 }
1068
1069 if (!original->in_same_comdat_group_p (alias)
1070 || original->comdat_local_p ())
1071 {
1072 if (dump_file)
1073 fprintf (dump_file,
1074 "Not unifying; alias nor wrapper cannot be created; "
1075 "across comdat group boundary\n\n");
1076
1112 return false; 1077 return false;
1113 } 1078 }
1114 1079
1115 /* See if original is in a section that can be discarded if the main 1080 /* See if original is in a section that can be discarded if the main
1116 symbol is not used. */ 1081 symbol is not used. */
1185 if (dump_file) 1150 if (dump_file)
1186 fprintf (dump_file, 1151 fprintf (dump_file,
1187 "can not create wrapper of stdarg function.\n"); 1152 "can not create wrapper of stdarg function.\n");
1188 } 1153 }
1189 else if (ipa_fn_summaries 1154 else if (ipa_fn_summaries
1155 && ipa_fn_summaries->get (alias) != NULL
1190 && ipa_fn_summaries->get (alias)->self_size <= 2) 1156 && ipa_fn_summaries->get (alias)->self_size <= 2)
1191 { 1157 {
1192 if (dump_file) 1158 if (dump_file)
1193 fprintf (dump_file, "Wrapper creation is not " 1159 fprintf (dump_file, "Wrapper creation is not "
1194 "profitable (function is too small).\n"); 1160 "profitable (function is too small).\n");
1206 1172
1207 /* We can redirect local calls in the case both alias and orignal 1173 /* We can redirect local calls in the case both alias and orignal
1208 are not interposable. */ 1174 are not interposable. */
1209 redirect_callers 1175 redirect_callers
1210 = alias->get_availability () > AVAIL_INTERPOSABLE 1176 = alias->get_availability () > AVAIL_INTERPOSABLE
1211 && original->get_availability () > AVAIL_INTERPOSABLE 1177 && original->get_availability () > AVAIL_INTERPOSABLE;
1212 && !alias->instrumented_version;
1213 /* TODO: We can redirect, but we need to produce alias of ORIGINAL 1178 /* TODO: We can redirect, but we need to produce alias of ORIGINAL
1214 with proper properties. */ 1179 with proper properties. */
1215 if (!sem_item::compare_referenced_symbol_properties (NULL, original, alias, 1180 if (!sem_item::compare_referenced_symbol_properties (NULL, original, alias,
1216 alias->address_taken)) 1181 alias->address_taken))
1217 redirect_callers = false; 1182 redirect_callers = false;
1566 /* Do not hash size, so complete and incomplete types can match. */ 1531 /* Do not hash size, so complete and incomplete types can match. */
1567 sem_item::add_type (TREE_TYPE (type), hstate); 1532 sem_item::add_type (TREE_TYPE (type), hstate);
1568 } 1533 }
1569 else if (RECORD_OR_UNION_TYPE_P (type)) 1534 else if (RECORD_OR_UNION_TYPE_P (type))
1570 { 1535 {
1571 gcc_checking_assert (COMPLETE_TYPE_P (type)); 1536 /* Incomplete types must be skipped here. */
1572 hashval_t *val = optimizer->m_type_hash_cache.get (type); 1537 if (!COMPLETE_TYPE_P (type))
1538 {
1539 hstate.add_int (RECORD_TYPE);
1540 return;
1541 }
1542
1543 hashval_t *val = m_type_hash_cache.get (type);
1573 1544
1574 if (!val) 1545 if (!val)
1575 { 1546 {
1576 inchash::hash hstate2; 1547 inchash::hash hstate2;
1577 unsigned nf; 1548 unsigned nf;
1578 tree f; 1549 tree f;
1579 hashval_t hash; 1550 hashval_t hash;
1580 1551
1581 hstate2.add_int (RECORD_TYPE); 1552 hstate2.add_int (RECORD_TYPE);
1582 gcc_assert (COMPLETE_TYPE_P (type));
1583
1584 for (f = TYPE_FIELDS (type), nf = 0; f; f = TREE_CHAIN (f)) 1553 for (f = TYPE_FIELDS (type), nf = 0; f; f = TREE_CHAIN (f))
1585 if (TREE_CODE (f) == FIELD_DECL) 1554 if (TREE_CODE (f) == FIELD_DECL)
1586 { 1555 {
1587 add_type (TREE_TYPE (f), hstate2); 1556 add_type (TREE_TYPE (f), hstate2);
1588 nf++; 1557 nf++;
1589 } 1558 }
1590 1559
1591 hstate2.add_int (nf); 1560 hstate2.add_int (nf);
1592 hash = hstate2.end (); 1561 hash = hstate2.end ();
1593 hstate.add_hwi (hash); 1562 hstate.add_hwi (hash);
1594 optimizer->m_type_hash_cache.put (type, hash); 1563 m_type_hash_cache.put (type, hash);
1595 } 1564 }
1596 else 1565 else
1597 hstate.add_hwi (*val); 1566 hstate.add_hwi (*val);
1598 } 1567 }
1599 } 1568 }
1965 if (!func_checker::compatible_types_p (TREE_TYPE (x1), TREE_TYPE (x2))) 1934 if (!func_checker::compatible_types_p (TREE_TYPE (x1), TREE_TYPE (x2)))
1966 return return_false (); 1935 return return_false ();
1967 1936
1968 /* Type of the offset on MEM_REF does not matter. */ 1937 /* Type of the offset on MEM_REF does not matter. */
1969 return return_with_debug (sem_variable::equals (x1, x2) 1938 return return_with_debug (sem_variable::equals (x1, x2)
1970 && wi::to_offset (y1) 1939 && known_eq (wi::to_poly_offset (y1),
1971 == wi::to_offset (y2)); 1940 wi::to_poly_offset (y2)));
1972 } 1941 }
1973 case ADDR_EXPR: 1942 case ADDR_EXPR:
1974 case FDESC_EXPR: 1943 case FDESC_EXPR:
1975 { 1944 {
1976 tree op1 = TREE_OPERAND (t1, 0); 1945 tree op1 = TREE_OPERAND (t1, 0);
2022 return return_false_with_msg ("REAL_CST precision mismatch"); 1991 return return_false_with_msg ("REAL_CST precision mismatch");
2023 return return_with_debug (real_identical (&TREE_REAL_CST (t1), 1992 return return_with_debug (real_identical (&TREE_REAL_CST (t1),
2024 &TREE_REAL_CST (t2))); 1993 &TREE_REAL_CST (t2)));
2025 case VECTOR_CST: 1994 case VECTOR_CST:
2026 { 1995 {
2027 unsigned i; 1996 if (maybe_ne (VECTOR_CST_NELTS (t1), VECTOR_CST_NELTS (t2)))
2028 1997 return return_false_with_msg ("VECTOR_CST nelts mismatch");
2029 if (VECTOR_CST_NELTS (t1) != VECTOR_CST_NELTS (t2)) 1998
2030 return return_false_with_msg ("VECTOR_CST nelts mismatch"); 1999 unsigned int count
2031 2000 = tree_vector_builder::binary_encoded_nelts (t1, t2);
2032 for (i = 0; i < VECTOR_CST_NELTS (t1); ++i) 2001 for (unsigned int i = 0; i < count; ++i)
2033 if (!sem_variable::equals (VECTOR_CST_ELT (t1, i), 2002 if (!sem_variable::equals (VECTOR_CST_ENCODED_ELT (t1, i),
2034 VECTOR_CST_ELT (t2, i))) 2003 VECTOR_CST_ENCODED_ELT (t2, i)))
2035 return 0; 2004 return false;
2036 2005
2037 return 1; 2006 return true;
2038 } 2007 }
2039 case ARRAY_REF: 2008 case ARRAY_REF:
2040 case ARRAY_RANGE_REF: 2009 case ARRAY_RANGE_REF:
2041 { 2010 {
2042 tree x1 = TREE_OPERAND (t1, 0); 2011 tree x1 = TREE_OPERAND (t1, 0);
2119 set_hash (hstate.end ()); 2088 set_hash (hstate.end ());
2120 2089
2121 return m_hash; 2090 return m_hash;
2122 } 2091 }
2123 2092
2124 /* Set all points-to UIDs of aliases pointing to node N as UID. */
2125
2126 static void
2127 set_alias_uids (symtab_node *n, int uid)
2128 {
2129 ipa_ref *ref;
2130 FOR_EACH_ALIAS (n, ref)
2131 {
2132 if (dump_file)
2133 fprintf (dump_file, " Setting points-to UID of [%s] as %d\n",
2134 xstrdup_for_dump (ref->referring->asm_name ()), uid);
2135
2136 SET_DECL_PT_UID (ref->referring->decl, uid);
2137 set_alias_uids (ref->referring, uid);
2138 }
2139 }
2140
2141 /* Merges instance with an ALIAS_ITEM, where alias, thunk or redirection can 2093 /* Merges instance with an ALIAS_ITEM, where alias, thunk or redirection can
2142 be applied. */ 2094 be applied. */
2143 2095
2144 bool 2096 bool
2145 sem_variable::merge (sem_item *alias_item) 2097 sem_variable::merge (sem_item *alias_item)
2262 alias->resolve_alias (original); 2214 alias->resolve_alias (original);
2263 2215
2264 if (dump_file) 2216 if (dump_file)
2265 fprintf (dump_file, "Unified; Variable alias has been created.\n"); 2217 fprintf (dump_file, "Unified; Variable alias has been created.\n");
2266 2218
2267 set_alias_uids (original, DECL_UID (original->decl));
2268 return true; 2219 return true;
2269 } 2220 }
2270 } 2221 }
2271 2222
2272 /* Dump symbol to FILE. */ 2223 /* Dump symbol to FILE. */
2282 2233
2283 unsigned int sem_item_optimizer::class_id = 0; 2234 unsigned int sem_item_optimizer::class_id = 0;
2284 2235
2285 sem_item_optimizer::sem_item_optimizer () 2236 sem_item_optimizer::sem_item_optimizer ()
2286 : worklist (0), m_classes (0), m_classes_count (0), m_cgraph_node_hooks (NULL), 2237 : worklist (0), m_classes (0), m_classes_count (0), m_cgraph_node_hooks (NULL),
2287 m_varpool_node_hooks (NULL) 2238 m_varpool_node_hooks (NULL), m_merged_variables ()
2288 { 2239 {
2289 m_items.create (0); 2240 m_items.create (0);
2290 bitmap_obstack_initialize (&m_bmstack); 2241 bitmap_obstack_initialize (&m_bmstack);
2291 } 2242 }
2292 2243
2307 } 2258 }
2308 2259
2309 m_items.release (); 2260 m_items.release ();
2310 2261
2311 bitmap_obstack_release (&m_bmstack); 2262 bitmap_obstack_release (&m_bmstack);
2263 m_merged_variables.release ();
2312 } 2264 }
2313 2265
2314 /* Write IPA ICF summary for symbols. */ 2266 /* Write IPA ICF summary for symbols. */
2315 2267
2316 void 2268 void
3558 source->dump_to_file (dump_file); 3510 source->dump_to_file (dump_file);
3559 alias->dump_to_file (dump_file); 3511 alias->dump_to_file (dump_file);
3560 } 3512 }
3561 3513
3562 if (dbg_cnt (merged_ipa_icf)) 3514 if (dbg_cnt (merged_ipa_icf))
3563 merged_p |= source->merge (alias); 3515 {
3516 bool merged = source->merge (alias);
3517 merged_p |= merged;
3518
3519 if (merged && alias->type == VAR)
3520 {
3521 symtab_pair p = symtab_pair (source->node, alias->node);
3522 m_merged_variables.safe_push (p);
3523 }
3524 }
3564 } 3525 }
3565 } 3526 }
3566 3527
3528 if (!m_merged_variables.is_empty ())
3529 fixup_points_to_sets ();
3530
3567 return merged_p; 3531 return merged_p;
3532 }
3533
3534 /* Fixup points to set PT. */
3535
3536 void
3537 sem_item_optimizer::fixup_pt_set (struct pt_solution *pt)
3538 {
3539 if (pt->vars == NULL)
3540 return;
3541
3542 unsigned i;
3543 symtab_pair *item;
3544 FOR_EACH_VEC_ELT (m_merged_variables, i, item)
3545 if (bitmap_bit_p (pt->vars, DECL_UID (item->second->decl)))
3546 bitmap_set_bit (pt->vars, DECL_UID (item->first->decl));
3547 }
3548
3549 /* Set all points-to UIDs of aliases pointing to node N as UID. */
3550
3551 static void
3552 set_alias_uids (symtab_node *n, int uid)
3553 {
3554 ipa_ref *ref;
3555 FOR_EACH_ALIAS (n, ref)
3556 {
3557 if (dump_file)
3558 fprintf (dump_file, " Setting points-to UID of [%s] as %d\n",
3559 xstrdup_for_dump (ref->referring->asm_name ()), uid);
3560
3561 SET_DECL_PT_UID (ref->referring->decl, uid);
3562 set_alias_uids (ref->referring, uid);
3563 }
3564 }
3565
3566 /* Fixup points to analysis info. */
3567
3568 void
3569 sem_item_optimizer::fixup_points_to_sets (void)
3570 {
3571 /* TODO: remove in GCC 9 and trigger PTA re-creation after IPA passes. */
3572 cgraph_node *cnode;
3573
3574 FOR_EACH_DEFINED_FUNCTION (cnode)
3575 {
3576 tree name;
3577 unsigned i;
3578 function *fn = DECL_STRUCT_FUNCTION (cnode->decl);
3579 if (!gimple_in_ssa_p (fn))
3580 continue;
3581
3582 FOR_EACH_SSA_NAME (i, name, fn)
3583 if (POINTER_TYPE_P (TREE_TYPE (name))
3584 && SSA_NAME_PTR_INFO (name))
3585 fixup_pt_set (&SSA_NAME_PTR_INFO (name)->pt);
3586 fixup_pt_set (&fn->gimple_df->escaped);
3587
3588 /* The above get's us to 99% I guess, at least catching the
3589 address compares. Below also gets us aliasing correct
3590 but as said we're giving leeway to the situation with
3591 readonly vars anyway, so ... */
3592 basic_block bb;
3593 FOR_EACH_BB_FN (bb, fn)
3594 for (gimple_stmt_iterator gsi = gsi_start_bb (bb); !gsi_end_p (gsi);
3595 gsi_next (&gsi))
3596 {
3597 gcall *call = dyn_cast<gcall *> (gsi_stmt (gsi));
3598 if (call)
3599 {
3600 fixup_pt_set (gimple_call_use_set (call));
3601 fixup_pt_set (gimple_call_clobber_set (call));
3602 }
3603 }
3604 }
3605
3606 unsigned i;
3607 symtab_pair *item;
3608 FOR_EACH_VEC_ELT (m_merged_variables, i, item)
3609 set_alias_uids (item->first, DECL_UID (item->first->decl));
3568 } 3610 }
3569 3611
3570 /* Dump function prints all class members to a FILE with an INDENT. */ 3612 /* Dump function prints all class members to a FILE with an INDENT. */
3571 3613
3572 void 3614 void