Mercurial > hg > CbC > CbC_gcc
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 |