comparison gcc/ipa-cp.c @ 132:d34655255c78

update gcc-8.2
author mir3636
date Thu, 25 Oct 2018 10:21:07 +0900
parents 84e7813d76e9
children 1830386684a0
comparison
equal deleted inserted replaced
130:e108057fa461 132:d34655255c78
1 /* Interprocedural constant propagation 1 /* Interprocedural constant propagation
2 Copyright (C) 2005-2017 Free Software Foundation, Inc. 2 Copyright (C) 2005-2018 Free Software Foundation, Inc.
3 3
4 Contributed by Razya Ladelsky <RAZYA@il.ibm.com> and Martin Jambor 4 Contributed by Razya Ladelsky <RAZYA@il.ibm.com> and Martin Jambor
5 <mjambor@suse.cz> 5 <mjambor@suse.cz>
6 6
7 This file is part of GCC. 7 This file is part of GCC.
312 inline bool bottom_p () const; 312 inline bool bottom_p () const;
313 inline bool top_p () const; 313 inline bool top_p () const;
314 inline bool set_to_bottom (); 314 inline bool set_to_bottom ();
315 bool meet_with (const value_range *p_vr); 315 bool meet_with (const value_range *p_vr);
316 bool meet_with (const ipcp_vr_lattice &other); 316 bool meet_with (const ipcp_vr_lattice &other);
317 void init () { m_vr.type = VR_UNDEFINED; } 317 void init () { gcc_assert (m_vr.undefined_p ()); }
318 void print (FILE * f); 318 void print (FILE * f);
319 319
320 private: 320 private:
321 bool meet_with_1 (const value_range *other_vr); 321 bool meet_with_1 (const value_range *other_vr);
322 }; 322 };
403 { 403 {
404 struct ipcp_param_lattices *plats = ipa_get_parm_lattices (info, i); 404 struct ipcp_param_lattices *plats = ipa_get_parm_lattices (info, i);
405 return &plats->ctxlat; 405 return &plats->ctxlat;
406 } 406 }
407 407
408 /* Return the lattice corresponding to the value range of the Ith formal
409 parameter of the function described by INFO. */
410
411 static inline ipcp_vr_lattice *
412 ipa_get_vr_lat (struct ipa_node_params *info, int i)
413 {
414 struct ipcp_param_lattices *plats = ipa_get_parm_lattices (info, i);
415 return &plats->m_value_range;
416 }
417
418 /* Return whether LAT is a lattice with a single constant and without an 408 /* Return whether LAT is a lattice with a single constant and without an
419 undefined value. */ 409 undefined value. */
420 410
421 template <typename valtype> 411 template <typename valtype>
422 inline bool 412 inline bool
495 { 485 {
496 ipcp_value_source<valtype> *s; 486 ipcp_value_source<valtype> *s;
497 487
498 fprintf (f, " [from:"); 488 fprintf (f, " [from:");
499 for (s = val->sources; s; s = s->next) 489 for (s = val->sources; s; s = s->next)
500 fprintf (f, " %i(%i)", s->cs->caller->order, 490 fprintf (f, " %i(%f)", s->cs->caller->order,
501 s->cs->frequency); 491 s->cs->sreal_frequency ().to_double ());
502 fprintf (f, "]"); 492 fprintf (f, "]");
503 } 493 }
504 494
505 if (dump_benefits) 495 if (dump_benefits)
506 fprintf (f, " [loc_time: %i, loc_size: %i, " 496 fprintf (f, " [loc_time: %i, loc_size: %i, "
628 /* TODO: call is versionable if we make sure that all 618 /* TODO: call is versionable if we make sure that all
629 callers are inside of a comdat group. */ 619 callers are inside of a comdat group. */
630 reason = "calls comdat-local function"; 620 reason = "calls comdat-local function";
631 } 621 }
632 622
623 /* Functions calling BUILT_IN_VA_ARG_PACK and BUILT_IN_VA_ARG_PACK_LEN
624 work only when inlined. Cloning them may still lead to better code
625 because ipa-cp will not give up on cloning further. If the function is
626 external this however leads to wrong code because we may end up producing
627 offline copy of the function. */
628 if (DECL_EXTERNAL (node->decl))
629 for (cgraph_edge *edge = node->callees; !reason && edge;
630 edge = edge->next_callee)
631 if (fndecl_built_in_p (edge->callee->decl, BUILT_IN_NORMAL))
632 {
633 if (DECL_FUNCTION_CODE (edge->callee->decl) == BUILT_IN_VA_ARG_PACK)
634 reason = "external function which calls va_arg_pack";
635 if (DECL_FUNCTION_CODE (edge->callee->decl)
636 == BUILT_IN_VA_ARG_PACK_LEN)
637 reason = "external function which calls va_arg_pack_len";
638 }
639
633 if (reason && dump_file && !node->alias && !node->thunk.thunk_p) 640 if (reason && dump_file && !node->alias && !node->thunk.thunk_p)
634 fprintf (dump_file, "Function %s is not versionable, reason: %s.\n", 641 fprintf (dump_file, "Function %s is not versionable, reason: %s.\n",
635 node->dump_name (), reason); 642 node->dump_name (), reason);
636 643
637 info->versionable = (reason == NULL); 644 info->versionable = (reason == NULL);
675 struct cgraph_edge *cs; 682 struct cgraph_edge *cs;
676 683
677 for (cs = node->callers; cs; cs = cs->next_caller) 684 for (cs = node->callers; cs; cs = cs->next_caller)
678 if (!cs->caller->thunk.thunk_p) 685 if (!cs->caller->thunk.thunk_p)
679 { 686 {
680 if (cs->count.initialized_p ()) 687 if (cs->count.ipa ().initialized_p ())
681 stats->count_sum += cs->count; 688 stats->count_sum += cs->count.ipa ();
682 stats->freq_sum += cs->frequency; 689 stats->freq_sum += cs->frequency ();
683 stats->n_calls++; 690 stats->n_calls++;
684 if (cs->maybe_hot_p ()) 691 if (cs->maybe_hot_p ())
685 stats->n_hot_calls ++; 692 stats->n_hot_calls ++;
686 } 693 }
687 return false; 694 return false;
729 /* When profile is available and function is hot, propagate into it even if 736 /* When profile is available and function is hot, propagate into it even if
730 calls seems cold; constant propagation can improve function's speed 737 calls seems cold; constant propagation can improve function's speed
731 significantly. */ 738 significantly. */
732 if (max_count > profile_count::zero ()) 739 if (max_count > profile_count::zero ())
733 { 740 {
734 if (stats.count_sum > node->count.apply_scale (90, 100)) 741 if (stats.count_sum > node->count.ipa ().apply_scale (90, 100))
735 { 742 {
736 if (dump_file) 743 if (dump_file)
737 fprintf (dump_file, "Considering %s for cloning; " 744 fprintf (dump_file, "Considering %s for cloning; "
738 "usually called directly.\n", 745 "usually called directly.\n",
739 node->name ()); 746 node->name ());
905 ipcp_vr_lattice::meet_with (const value_range *p_vr) 912 ipcp_vr_lattice::meet_with (const value_range *p_vr)
906 { 913 {
907 return meet_with_1 (p_vr); 914 return meet_with_1 (p_vr);
908 } 915 }
909 916
910 /* Meet the current value of the lattice with value ranfge described by 917 /* Meet the current value of the lattice with value range described by
911 OTHER_VR lattice. */ 918 OTHER_VR lattice. Return TRUE if anything changed. */
912 919
913 bool 920 bool
914 ipcp_vr_lattice::meet_with_1 (const value_range *other_vr) 921 ipcp_vr_lattice::meet_with_1 (const value_range *other_vr)
915 { 922 {
916 tree min = m_vr.min, max = m_vr.max;
917 value_range_type type = m_vr.type;
918
919 if (bottom_p ()) 923 if (bottom_p ())
920 return false; 924 return false;
921 925
922 if (other_vr->type == VR_VARYING) 926 if (other_vr->varying_p ())
923 return set_to_bottom (); 927 return set_to_bottom ();
924 928
925 vrp_meet (&m_vr, other_vr); 929 value_range save (m_vr);
926 if (type != m_vr.type 930 m_vr.union_ (other_vr);
927 || min != m_vr.min 931 return !m_vr.ignore_equivs_equal_p (save);
928 || max != m_vr.max)
929 return true;
930 else
931 return false;
932 } 932 }
933 933
934 /* Return true if value range information in the lattice is yet unknown. */ 934 /* Return true if value range information in the lattice is yet unknown. */
935 935
936 bool 936 bool
937 ipcp_vr_lattice::top_p () const 937 ipcp_vr_lattice::top_p () const
938 { 938 {
939 return m_vr.type == VR_UNDEFINED; 939 return m_vr.undefined_p ();
940 } 940 }
941 941
942 /* Return true if value range information in the lattice is known to be 942 /* Return true if value range information in the lattice is known to be
943 unusable. */ 943 unusable. */
944 944
945 bool 945 bool
946 ipcp_vr_lattice::bottom_p () const 946 ipcp_vr_lattice::bottom_p () const
947 { 947 {
948 return m_vr.type == VR_VARYING; 948 return m_vr.varying_p ();
949 } 949 }
950 950
951 /* Set value range information in the lattice to bottom. Return true if it 951 /* Set value range information in the lattice to bottom. Return true if it
952 previously was in a different state. */ 952 previously was in a different state. */
953 953
954 bool 954 bool
955 ipcp_vr_lattice::set_to_bottom () 955 ipcp_vr_lattice::set_to_bottom ()
956 { 956 {
957 if (m_vr.type == VR_VARYING) 957 if (m_vr.varying_p ())
958 return false; 958 return false;
959 m_vr.type = VR_VARYING; 959 m_vr.set_varying ();
960 return true; 960 return true;
961 } 961 }
962 962
963 /* Set lattice value to bottom, if it already isn't the case. */ 963 /* Set lattice value to bottom, if it already isn't the case. */
964 964
1157 struct cgraph_edge *ie; 1157 struct cgraph_edge *ie;
1158 bool disable = false, variable = false; 1158 bool disable = false, variable = false;
1159 int i; 1159 int i;
1160 1160
1161 gcc_checking_assert (node->has_gimple_body_p ()); 1161 gcc_checking_assert (node->has_gimple_body_p ());
1162 if (cgraph_local_p (node)) 1162 if (node->local.local)
1163 { 1163 {
1164 int caller_count = 0; 1164 int caller_count = 0;
1165 node->call_for_symbol_thunks_and_aliases (count_callers, &caller_count, 1165 node->call_for_symbol_thunks_and_aliases (count_callers, &caller_count,
1166 true); 1166 true);
1167 gcc_checking_assert (caller_count > 0); 1167 gcc_checking_assert (caller_count > 0);
1218 ie->indirect_info->param_index)->virt_call = 1; 1218 ie->indirect_info->param_index)->virt_call = 1;
1219 } 1219 }
1220 } 1220 }
1221 1221
1222 /* Return the result of a (possibly arithmetic) pass through jump function 1222 /* Return the result of a (possibly arithmetic) pass through jump function
1223 JFUNC on the constant value INPUT. Return NULL_TREE if that cannot be 1223 JFUNC on the constant value INPUT. RES_TYPE is the type of the parameter
1224 to which the result is passed. Return NULL_TREE if that cannot be
1224 determined or be considered an interprocedural invariant. */ 1225 determined or be considered an interprocedural invariant. */
1225 1226
1226 static tree 1227 static tree
1227 ipa_get_jf_pass_through_result (struct ipa_jump_func *jfunc, tree input) 1228 ipa_get_jf_pass_through_result (struct ipa_jump_func *jfunc, tree input,
1228 { 1229 tree res_type)
1229 tree restype, res; 1230 {
1231 tree res;
1230 1232
1231 if (ipa_get_jf_pass_through_operation (jfunc) == NOP_EXPR) 1233 if (ipa_get_jf_pass_through_operation (jfunc) == NOP_EXPR)
1232 return input; 1234 return input;
1233 if (!is_gimple_ip_invariant (input)) 1235 if (!is_gimple_ip_invariant (input))
1234 return NULL_TREE; 1236 return NULL_TREE;
1235 1237
1236 if (TREE_CODE_CLASS (ipa_get_jf_pass_through_operation (jfunc)) 1238 tree_code opcode = ipa_get_jf_pass_through_operation (jfunc);
1237 == tcc_unary) 1239 if (!res_type)
1238 res = fold_unary (ipa_get_jf_pass_through_operation (jfunc), 1240 {
1239 TREE_TYPE (input), input); 1241 if (TREE_CODE_CLASS (opcode) == tcc_comparison)
1242 res_type = boolean_type_node;
1243 else if (expr_type_first_operand_type_p (opcode))
1244 res_type = TREE_TYPE (input);
1245 else
1246 return NULL_TREE;
1247 }
1248
1249 if (TREE_CODE_CLASS (opcode) == tcc_unary)
1250 res = fold_unary (opcode, res_type, input);
1240 else 1251 else
1241 { 1252 res = fold_binary (opcode, res_type, input,
1242 if (TREE_CODE_CLASS (ipa_get_jf_pass_through_operation (jfunc)) 1253 ipa_get_jf_pass_through_operand (jfunc));
1243 == tcc_comparison) 1254
1244 restype = boolean_type_node;
1245 else
1246 restype = TREE_TYPE (input);
1247 res = fold_binary (ipa_get_jf_pass_through_operation (jfunc), restype,
1248 input, ipa_get_jf_pass_through_operand (jfunc));
1249 }
1250 if (res && !is_gimple_ip_invariant (res)) 1255 if (res && !is_gimple_ip_invariant (res))
1251 return NULL_TREE; 1256 return NULL_TREE;
1252 1257
1253 return res; 1258 return res;
1254 } 1259 }
1273 } 1278 }
1274 1279
1275 /* Determine whether JFUNC evaluates to a single known constant value and if 1280 /* Determine whether JFUNC evaluates to a single known constant value and if
1276 so, return it. Otherwise return NULL. INFO describes the caller node or 1281 so, return it. Otherwise return NULL. INFO describes the caller node or
1277 the one it is inlined to, so that pass-through jump functions can be 1282 the one it is inlined to, so that pass-through jump functions can be
1278 evaluated. */ 1283 evaluated. PARM_TYPE is the type of the parameter to which the result is
1284 passed. */
1279 1285
1280 tree 1286 tree
1281 ipa_value_from_jfunc (struct ipa_node_params *info, struct ipa_jump_func *jfunc) 1287 ipa_value_from_jfunc (struct ipa_node_params *info, struct ipa_jump_func *jfunc,
1288 tree parm_type)
1282 { 1289 {
1283 if (jfunc->type == IPA_JF_CONST) 1290 if (jfunc->type == IPA_JF_CONST)
1284 return ipa_get_jf_constant (jfunc); 1291 return ipa_get_jf_constant (jfunc);
1285 else if (jfunc->type == IPA_JF_PASS_THROUGH 1292 else if (jfunc->type == IPA_JF_PASS_THROUGH
1286 || jfunc->type == IPA_JF_ANCESTOR) 1293 || jfunc->type == IPA_JF_ANCESTOR)
1310 1317
1311 if (!input) 1318 if (!input)
1312 return NULL_TREE; 1319 return NULL_TREE;
1313 1320
1314 if (jfunc->type == IPA_JF_PASS_THROUGH) 1321 if (jfunc->type == IPA_JF_PASS_THROUGH)
1315 return ipa_get_jf_pass_through_result (jfunc, input); 1322 return ipa_get_jf_pass_through_result (jfunc, input, parm_type);
1316 else 1323 else
1317 return ipa_get_jf_ancestor_result (jfunc, input); 1324 return ipa_get_jf_ancestor_result (jfunc, input);
1318 } 1325 }
1319 else 1326 else
1320 return NULL_TREE; 1327 return NULL_TREE;
1560 return true; 1567 return true;
1561 } 1568 }
1562 1569
1563 /* Propagate values through a pass-through jump function JFUNC associated with 1570 /* Propagate values through a pass-through jump function JFUNC associated with
1564 edge CS, taking values from SRC_LAT and putting them into DEST_LAT. SRC_IDX 1571 edge CS, taking values from SRC_LAT and putting them into DEST_LAT. SRC_IDX
1565 is the index of the source parameter. */ 1572 is the index of the source parameter. PARM_TYPE is the type of the
1573 parameter to which the result is passed. */
1566 1574
1567 static bool 1575 static bool
1568 propagate_vals_across_pass_through (cgraph_edge *cs, ipa_jump_func *jfunc, 1576 propagate_vals_across_pass_through (cgraph_edge *cs, ipa_jump_func *jfunc,
1569 ipcp_lattice<tree> *src_lat, 1577 ipcp_lattice<tree> *src_lat,
1570 ipcp_lattice<tree> *dest_lat, int src_idx) 1578 ipcp_lattice<tree> *dest_lat, int src_idx,
1579 tree parm_type)
1571 { 1580 {
1572 ipcp_value<tree> *src_val; 1581 ipcp_value<tree> *src_val;
1573 bool ret = false; 1582 bool ret = false;
1574 1583
1575 /* Do not create new values when propagating within an SCC because if there 1584 /* Do not create new values when propagating within an SCC because if there
1576 are arithmetic functions with circular dependencies, there is infinite 1585 are arithmetic functions with circular dependencies, there is infinite
1577 number of them and we would just make lattices bottom. */ 1586 number of them and we would just make lattices bottom. If this condition
1587 is ever relaxed we have to detect self-feeding recursive calls in
1588 cgraph_edge_brings_value_p in a smarter way. */
1578 if ((ipa_get_jf_pass_through_operation (jfunc) != NOP_EXPR) 1589 if ((ipa_get_jf_pass_through_operation (jfunc) != NOP_EXPR)
1579 && ipa_edge_within_scc (cs)) 1590 && ipa_edge_within_scc (cs))
1580 ret = dest_lat->set_contains_variable (); 1591 ret = dest_lat->set_contains_variable ();
1581 else 1592 else
1582 for (src_val = src_lat->values; src_val; src_val = src_val->next) 1593 for (src_val = src_lat->values; src_val; src_val = src_val->next)
1583 { 1594 {
1584 tree cstval = ipa_get_jf_pass_through_result (jfunc, src_val->value); 1595 tree cstval = ipa_get_jf_pass_through_result (jfunc, src_val->value,
1596 parm_type);
1585 1597
1586 if (cstval) 1598 if (cstval)
1587 ret |= dest_lat->add_value (cstval, cs, src_val, src_idx); 1599 ret |= dest_lat->add_value (cstval, cs, src_val, src_idx);
1588 else 1600 else
1589 ret |= dest_lat->set_contains_variable (); 1601 ret |= dest_lat->set_contains_variable ();
1620 1632
1621 return ret; 1633 return ret;
1622 } 1634 }
1623 1635
1624 /* Propagate scalar values across jump function JFUNC that is associated with 1636 /* Propagate scalar values across jump function JFUNC that is associated with
1625 edge CS and put the values into DEST_LAT. */ 1637 edge CS and put the values into DEST_LAT. PARM_TYPE is the type of the
1638 parameter to which the result is passed. */
1626 1639
1627 static bool 1640 static bool
1628 propagate_scalar_across_jump_function (struct cgraph_edge *cs, 1641 propagate_scalar_across_jump_function (struct cgraph_edge *cs,
1629 struct ipa_jump_func *jfunc, 1642 struct ipa_jump_func *jfunc,
1630 ipcp_lattice<tree> *dest_lat) 1643 ipcp_lattice<tree> *dest_lat,
1644 tree param_type)
1631 { 1645 {
1632 if (dest_lat->bottom) 1646 if (dest_lat->bottom)
1633 return false; 1647 return false;
1634 1648
1635 if (jfunc->type == IPA_JF_CONST) 1649 if (jfunc->type == IPA_JF_CONST)
1660 || (src_lat->values_count > 1))) 1674 || (src_lat->values_count > 1)))
1661 return dest_lat->set_contains_variable (); 1675 return dest_lat->set_contains_variable ();
1662 1676
1663 if (jfunc->type == IPA_JF_PASS_THROUGH) 1677 if (jfunc->type == IPA_JF_PASS_THROUGH)
1664 ret = propagate_vals_across_pass_through (cs, jfunc, src_lat, 1678 ret = propagate_vals_across_pass_through (cs, jfunc, src_lat,
1665 dest_lat, src_idx); 1679 dest_lat, src_idx, param_type);
1666 else 1680 else
1667 ret = propagate_vals_across_ancestor (cs, jfunc, src_lat, dest_lat, 1681 ret = propagate_vals_across_ancestor (cs, jfunc, src_lat, dest_lat,
1668 src_idx); 1682 src_idx);
1669 1683
1670 if (src_lat->contains_variable) 1684 if (src_lat->contains_variable)
1779 enum availability availability; 1793 enum availability availability;
1780 cgraph_node *callee = cs->callee->function_symbol (&availability); 1794 cgraph_node *callee = cs->callee->function_symbol (&availability);
1781 struct ipa_node_params *callee_info = IPA_NODE_REF (callee); 1795 struct ipa_node_params *callee_info = IPA_NODE_REF (callee);
1782 tree parm_type = ipa_get_type (callee_info, idx); 1796 tree parm_type = ipa_get_type (callee_info, idx);
1783 1797
1784 /* For K&R C programs, ipa_get_type() could return NULL_TREE. 1798 /* For K&R C programs, ipa_get_type() could return NULL_TREE. Avoid the
1785 Avoid the transform for these cases. */ 1799 transform for these cases. Similarly, we can have bad type mismatches
1786 if (!parm_type) 1800 with LTO, avoid doing anything with those too. */
1801 if (!parm_type
1802 || (!INTEGRAL_TYPE_P (parm_type) && !POINTER_TYPE_P (parm_type)))
1787 { 1803 {
1788 if (dump_file && (dump_flags & TDF_DETAILS)) 1804 if (dump_file && (dump_flags & TDF_DETAILS))
1789 fprintf (dump_file, "Setting dest_lattice to bottom, because" 1805 fprintf (dump_file, "Setting dest_lattice to bottom, because type of "
1790 " param %i type is NULL for %s\n", idx, 1806 "param %i of %s is NULL or unsuitable for bits propagation\n",
1791 cs->callee->name ()); 1807 idx, cs->callee->name ());
1792 1808
1793 return dest_lattice->set_to_bottom (); 1809 return dest_lattice->set_to_bottom ();
1794 } 1810 }
1795 1811
1796 unsigned precision = TYPE_PRECISION (parm_type); 1812 unsigned precision = TYPE_PRECISION (parm_type);
1857 static bool 1873 static bool
1858 ipa_vr_operation_and_type_effects (value_range *dst_vr, value_range *src_vr, 1874 ipa_vr_operation_and_type_effects (value_range *dst_vr, value_range *src_vr,
1859 enum tree_code operation, 1875 enum tree_code operation,
1860 tree dst_type, tree src_type) 1876 tree dst_type, tree src_type)
1861 { 1877 {
1862 memset (dst_vr, 0, sizeof (*dst_vr)); 1878 *dst_vr = value_range ();
1863 extract_range_from_unary_expr (dst_vr, operation, dst_type, src_vr, src_type); 1879 extract_range_from_unary_expr (dst_vr, operation, dst_type, src_vr, src_type);
1864 if (dst_vr->type == VR_RANGE || dst_vr->type == VR_ANTI_RANGE) 1880 if (dst_vr->varying_p () || dst_vr->undefined_p ())
1865 return true;
1866 else
1867 return false; 1881 return false;
1882 return true;
1868 } 1883 }
1869 1884
1870 /* Propagate value range across jump function JFUNC that is associated with 1885 /* Propagate value range across jump function JFUNC that is associated with
1871 edge CS with param of callee of PARAM_TYPE and update DEST_PLATS 1886 edge CS with param of callee of PARAM_TYPE and update DEST_PLATS
1872 accordingly. */ 1887 accordingly. */
1915 { 1930 {
1916 val = fold_convert (param_type, val); 1931 val = fold_convert (param_type, val);
1917 if (TREE_OVERFLOW_P (val)) 1932 if (TREE_OVERFLOW_P (val))
1918 val = drop_tree_overflow (val); 1933 val = drop_tree_overflow (val);
1919 1934
1920 value_range tmpvr; 1935 value_range tmpvr (VR_RANGE, val, val);
1921 memset (&tmpvr, 0, sizeof (tmpvr));
1922 tmpvr.type = VR_RANGE;
1923 tmpvr.min = val;
1924 tmpvr.max = val;
1925 return dest_lat->meet_with (&tmpvr); 1936 return dest_lat->meet_with (&tmpvr);
1926 } 1937 }
1927 } 1938 }
1928 1939
1929 value_range vr; 1940 value_range vr;
1930 if (jfunc->m_vr 1941 if (jfunc->m_vr
1931 && ipa_vr_operation_and_type_effects (&vr, jfunc->m_vr, NOP_EXPR, 1942 && ipa_vr_operation_and_type_effects (&vr, jfunc->m_vr, NOP_EXPR,
1932 param_type, 1943 param_type,
1933 TREE_TYPE (jfunc->m_vr->min))) 1944 jfunc->m_vr->type ()))
1934 return dest_lat->meet_with (&vr); 1945 return dest_lat->meet_with (&vr);
1935 else 1946 else
1936 return dest_lat->set_to_bottom (); 1947 return dest_lat->set_to_bottom ();
1937 } 1948 }
1938 1949
2235 args_count = ipa_get_cs_argument_count (args); 2246 args_count = ipa_get_cs_argument_count (args);
2236 parms_count = ipa_get_param_count (callee_info); 2247 parms_count = ipa_get_param_count (callee_info);
2237 if (parms_count == 0) 2248 if (parms_count == 0)
2238 return false; 2249 return false;
2239 2250
2240 /* No propagation through instrumentation thunks is available yet.
2241 It should be possible with proper mapping of call args and
2242 instrumented callee params in the propagation loop below. But
2243 this case mostly occurs when legacy code calls instrumented code
2244 and it is not a primary target for optimizations.
2245 We detect instrumentation thunks in aliases and thunks chain by
2246 checking instrumentation_clone flag for chain source and target.
2247 Going through instrumentation thunks we always have it changed
2248 from 0 to 1 and all other nodes do not change it. */
2249 if (!cs->callee->instrumentation_clone
2250 && callee->instrumentation_clone)
2251 {
2252 for (i = 0; i < parms_count; i++)
2253 ret |= set_all_contains_variable (ipa_get_parm_lattices (callee_info,
2254 i));
2255 return ret;
2256 }
2257
2258 /* If this call goes through a thunk we must not propagate to the first (0th) 2251 /* If this call goes through a thunk we must not propagate to the first (0th)
2259 parameter. However, we might need to uncover a thunk from below a series 2252 parameter. However, we might need to uncover a thunk from below a series
2260 of aliases first. */ 2253 of aliases first. */
2261 if (call_passes_through_thunk_p (cs)) 2254 if (call_passes_through_thunk_p (cs))
2262 { 2255 {
2277 if (availability == AVAIL_INTERPOSABLE) 2270 if (availability == AVAIL_INTERPOSABLE)
2278 ret |= set_all_contains_variable (dest_plats); 2271 ret |= set_all_contains_variable (dest_plats);
2279 else 2272 else
2280 { 2273 {
2281 ret |= propagate_scalar_across_jump_function (cs, jump_func, 2274 ret |= propagate_scalar_across_jump_function (cs, jump_func,
2282 &dest_plats->itself); 2275 &dest_plats->itself,
2276 param_type);
2283 ret |= propagate_context_across_jump_function (cs, jump_func, i, 2277 ret |= propagate_context_across_jump_function (cs, jump_func, i,
2284 &dest_plats->ctxlat); 2278 &dest_plats->ctxlat);
2285 ret 2279 ret
2286 |= propagate_bits_across_jump_function (cs, i, jump_func, 2280 |= propagate_bits_across_jump_function (cs, i, jump_func,
2287 &dest_plats->bits_lattice); 2281 &dest_plats->bits_lattice);
2892 if (dump_file) 2886 if (dump_file)
2893 fprintf (dump_file, " Decided to specialize for all " 2887 fprintf (dump_file, " Decided to specialize for all "
2894 "known contexts, code not going to grow.\n"); 2888 "known contexts, code not going to grow.\n");
2895 } 2889 }
2896 else if (good_cloning_opportunity_p (node, 2890 else if (good_cloning_opportunity_p (node,
2897 MAX ((base_time - time).to_int (), 2891 MIN ((base_time - time).to_int (),
2898 65536), 2892 65536),
2899 stats.freq_sum, stats.count_sum, 2893 stats.freq_sum, stats.count_sum,
2900 size)) 2894 size))
2901 { 2895 {
2902 if (size + overall_size <= max_new_size) 2896 if (size + overall_size <= max_new_size)
3255 struct cgraph_node *node; 3249 struct cgraph_node *node;
3256 3250
3257 if (dump_file) 3251 if (dump_file)
3258 fprintf (dump_file, "\n Propagating constants:\n\n"); 3252 fprintf (dump_file, "\n Propagating constants:\n\n");
3259 3253
3254 max_count = profile_count::uninitialized ();
3255
3260 FOR_EACH_DEFINED_FUNCTION (node) 3256 FOR_EACH_DEFINED_FUNCTION (node)
3261 { 3257 {
3262 struct ipa_node_params *info = IPA_NODE_REF (node); 3258 struct ipa_node_params *info = IPA_NODE_REF (node);
3263 3259
3264 determine_versionability (node, info); 3260 determine_versionability (node, info);
3266 { 3262 {
3267 info->lattices = XCNEWVEC (struct ipcp_param_lattices, 3263 info->lattices = XCNEWVEC (struct ipcp_param_lattices,
3268 ipa_get_param_count (info)); 3264 ipa_get_param_count (info));
3269 initialize_node_lattices (node); 3265 initialize_node_lattices (node);
3270 } 3266 }
3271 if (node->definition && !node->alias) 3267 ipa_fn_summary *s = ipa_fn_summaries->get (node);
3272 overall_size += ipa_fn_summaries->get (node)->self_size; 3268 if (node->definition && !node->alias && s != NULL)
3273 if (node->count > max_count) 3269 overall_size += s->self_size;
3274 max_count = node->count; 3270 max_count = max_count.max (node->count.ipa ());
3275 } 3271 }
3276 3272
3277 max_new_size = overall_size; 3273 max_new_size = overall_size;
3278 if (max_new_size < PARAM_VALUE (PARAM_LARGE_UNIT_INSNS)) 3274 if (max_new_size < PARAM_VALUE (PARAM_LARGE_UNIT_INSNS))
3279 max_new_size = PARAM_VALUE (PARAM_LARGE_UNIT_INSNS); 3275 max_new_size = PARAM_VALUE (PARAM_LARGE_UNIT_INSNS);
3354 /* Turning calls to direct calls will improve overall summary. */ 3350 /* Turning calls to direct calls will improve overall summary. */
3355 if (found) 3351 if (found)
3356 ipa_update_overall_fn_summary (node); 3352 ipa_update_overall_fn_summary (node);
3357 } 3353 }
3358 3354
3359 /* Vector of pointers which for linked lists of clones of an original crgaph 3355 class edge_clone_summary;
3360 edge. */ 3356 static call_summary <edge_clone_summary *> *edge_clone_summaries = NULL;
3361 3357
3362 static vec<cgraph_edge *> next_edge_clone; 3358 /* Edge clone summary. */
3363 static vec<cgraph_edge *> prev_edge_clone; 3359
3364 3360 struct edge_clone_summary
3365 static inline void 3361 {
3366 grow_edge_clone_vectors (void) 3362 /* Default constructor. */
3367 { 3363 edge_clone_summary (): prev_clone (NULL), next_clone (NULL) {}
3368 if (next_edge_clone.length () 3364
3369 <= (unsigned) symtab->edges_max_uid) 3365 /* Default destructor. */
3370 next_edge_clone.safe_grow_cleared (symtab->edges_max_uid + 1); 3366 ~edge_clone_summary ()
3371 if (prev_edge_clone.length () 3367 {
3372 <= (unsigned) symtab->edges_max_uid) 3368 if (prev_clone)
3373 prev_edge_clone.safe_grow_cleared (symtab->edges_max_uid + 1); 3369 edge_clone_summaries->get (prev_clone)->next_clone = next_clone;
3374 } 3370 if (next_clone)
3375 3371 edge_clone_summaries->get (next_clone)->prev_clone = prev_clone;
3376 /* Edge duplication hook to grow the appropriate linked list in 3372 }
3377 next_edge_clone. */ 3373
3378 3374 cgraph_edge *prev_clone;
3379 static void 3375 cgraph_edge *next_clone;
3380 ipcp_edge_duplication_hook (struct cgraph_edge *src, struct cgraph_edge *dst, 3376 };
3381 void *) 3377
3382 { 3378 class edge_clone_summary_t:
3383 grow_edge_clone_vectors (); 3379 public call_summary <edge_clone_summary *>
3384 3380 {
3385 struct cgraph_edge *old_next = next_edge_clone[src->uid]; 3381 public:
3386 if (old_next) 3382 edge_clone_summary_t (symbol_table *symtab):
3387 prev_edge_clone[old_next->uid] = dst; 3383 call_summary <edge_clone_summary *> (symtab)
3388 prev_edge_clone[dst->uid] = src; 3384 {
3389 3385 m_initialize_when_cloning = true;
3390 next_edge_clone[dst->uid] = old_next; 3386 }
3391 next_edge_clone[src->uid] = dst; 3387
3392 } 3388 virtual void duplicate (cgraph_edge *src_edge, cgraph_edge *dst_edge,
3393 3389 edge_clone_summary *src_data,
3394 /* Hook that is called by cgraph.c when an edge is removed. */ 3390 edge_clone_summary *dst_data);
3395 3391 };
3396 static void 3392
3397 ipcp_edge_removal_hook (struct cgraph_edge *cs, void *) 3393 /* Edge duplication hook. */
3398 { 3394
3399 grow_edge_clone_vectors (); 3395 void
3400 3396 edge_clone_summary_t::duplicate (cgraph_edge *src_edge, cgraph_edge *dst_edge,
3401 struct cgraph_edge *prev = prev_edge_clone[cs->uid]; 3397 edge_clone_summary *src_data,
3402 struct cgraph_edge *next = next_edge_clone[cs->uid]; 3398 edge_clone_summary *dst_data)
3403 if (prev) 3399 {
3404 next_edge_clone[prev->uid] = next; 3400 if (src_data->next_clone)
3405 if (next) 3401 edge_clone_summaries->get (src_data->next_clone)->prev_clone = dst_edge;
3406 prev_edge_clone[next->uid] = prev; 3402 dst_data->prev_clone = src_edge;
3403 dst_data->next_clone = src_data->next_clone;
3404 src_data->next_clone = dst_edge;
3407 } 3405 }
3408 3406
3409 /* See if NODE is a clone with a known aggregate value at a given OFFSET of a 3407 /* See if NODE is a clone with a known aggregate value at a given OFFSET of a
3410 parameter with the given INDEX. */ 3408 parameter with the given INDEX. */
3411 3409
3436 3434
3437 struct ipa_node_params *info = IPA_NODE_REF (node); 3435 struct ipa_node_params *info = IPA_NODE_REF (node);
3438 return info->is_all_contexts_clone && info->ipcp_orig_node == dest; 3436 return info->is_all_contexts_clone && info->ipcp_orig_node == dest;
3439 } 3437 }
3440 3438
3441 /* Return true if edge CS does bring about the value described by SRC to node 3439 /* Return true if edge CS does bring about the value described by SRC to
3442 DEST or its clone for all contexts. */ 3440 DEST_VAL of node DEST or its clone for all contexts. */
3443 3441
3444 static bool 3442 static bool
3445 cgraph_edge_brings_value_p (cgraph_edge *cs, ipcp_value_source<tree> *src, 3443 cgraph_edge_brings_value_p (cgraph_edge *cs, ipcp_value_source<tree> *src,
3446 cgraph_node *dest) 3444 cgraph_node *dest, ipcp_value<tree> *dest_val)
3447 { 3445 {
3448 struct ipa_node_params *caller_info = IPA_NODE_REF (cs->caller); 3446 struct ipa_node_params *caller_info = IPA_NODE_REF (cs->caller);
3449 enum availability availability; 3447 enum availability availability;
3450 cgraph_node *real_dest = cs->callee->function_symbol (&availability); 3448 cgraph_node *real_dest = cs->callee->function_symbol (&availability);
3451 3449
3452 if (!same_node_or_its_all_contexts_clone_p (real_dest, dest) 3450 if (!same_node_or_its_all_contexts_clone_p (real_dest, dest)
3453 || availability <= AVAIL_INTERPOSABLE 3451 || availability <= AVAIL_INTERPOSABLE
3454 || caller_info->node_dead) 3452 || caller_info->node_dead)
3455 return false; 3453 return false;
3454
3456 if (!src->val) 3455 if (!src->val)
3457 return true; 3456 return true;
3458 3457
3459 if (caller_info->ipcp_orig_node) 3458 if (caller_info->ipcp_orig_node)
3460 { 3459 {
3466 return (t != NULL_TREE 3465 return (t != NULL_TREE
3467 && values_equal_for_ipcp_p (src->val->value, t)); 3466 && values_equal_for_ipcp_p (src->val->value, t));
3468 } 3467 }
3469 else 3468 else
3470 { 3469 {
3470 /* At the moment we do not propagate over arithmetic jump functions in
3471 SCCs, so it is safe to detect self-feeding recursive calls in this
3472 way. */
3473 if (src->val == dest_val)
3474 return true;
3475
3471 struct ipcp_agg_lattice *aglat; 3476 struct ipcp_agg_lattice *aglat;
3472 struct ipcp_param_lattices *plats = ipa_get_parm_lattices (caller_info, 3477 struct ipcp_param_lattices *plats = ipa_get_parm_lattices (caller_info,
3473 src->index); 3478 src->index);
3474 if (src->offset == -1) 3479 if (src->offset == -1)
3475 return (plats->itself.is_single_const () 3480 return (plats->itself.is_single_const ()
3487 } 3492 }
3488 return false; 3493 return false;
3489 } 3494 }
3490 } 3495 }
3491 3496
3492 /* Return true if edge CS does bring about the value described by SRC to node 3497 /* Return true if edge CS does bring about the value described by SRC to
3493 DEST or its clone for all contexts. */ 3498 DST_VAL of node DEST or its clone for all contexts. */
3494 3499
3495 static bool 3500 static bool
3496 cgraph_edge_brings_value_p (cgraph_edge *cs, 3501 cgraph_edge_brings_value_p (cgraph_edge *cs,
3497 ipcp_value_source<ipa_polymorphic_call_context> *src, 3502 ipcp_value_source<ipa_polymorphic_call_context> *src,
3498 cgraph_node *dest) 3503 cgraph_node *dest,
3504 ipcp_value<ipa_polymorphic_call_context> *)
3499 { 3505 {
3500 struct ipa_node_params *caller_info = IPA_NODE_REF (cs->caller); 3506 struct ipa_node_params *caller_info = IPA_NODE_REF (cs->caller);
3501 cgraph_node *real_dest = cs->callee->function_symbol (); 3507 cgraph_node *real_dest = cs->callee->function_symbol ();
3502 3508
3503 if (!same_node_or_its_all_contexts_clone_p (real_dest, dest) 3509 if (!same_node_or_its_all_contexts_clone_p (real_dest, dest)
3521 /* Get the next clone in the linked list of clones of an edge. */ 3527 /* Get the next clone in the linked list of clones of an edge. */
3522 3528
3523 static inline struct cgraph_edge * 3529 static inline struct cgraph_edge *
3524 get_next_cgraph_edge_clone (struct cgraph_edge *cs) 3530 get_next_cgraph_edge_clone (struct cgraph_edge *cs)
3525 { 3531 {
3526 return next_edge_clone[cs->uid]; 3532 edge_clone_summary *s = edge_clone_summaries->get (cs);
3527 } 3533 return s != NULL ? s->next_clone : NULL;
3528 3534 }
3529 /* Given VAL that is intended for DEST, iterate over all its sources and if 3535
3530 they still hold, add their edge frequency and their number into *FREQUENCY 3536 /* Given VAL that is intended for DEST, iterate over all its sources and if any
3531 and *CALLER_COUNT respectively. */ 3537 of them is viable and hot, return true. In that case, for those that still
3538 hold, add their edge frequency and their number into *FREQUENCY and
3539 *CALLER_COUNT respectively. */
3532 3540
3533 template <typename valtype> 3541 template <typename valtype>
3534 static bool 3542 static bool
3535 get_info_about_necessary_edges (ipcp_value<valtype> *val, cgraph_node *dest, 3543 get_info_about_necessary_edges (ipcp_value<valtype> *val, cgraph_node *dest,
3536 int *freq_sum, 3544 int *freq_sum,
3538 { 3546 {
3539 ipcp_value_source<valtype> *src; 3547 ipcp_value_source<valtype> *src;
3540 int freq = 0, count = 0; 3548 int freq = 0, count = 0;
3541 profile_count cnt = profile_count::zero (); 3549 profile_count cnt = profile_count::zero ();
3542 bool hot = false; 3550 bool hot = false;
3551 bool non_self_recursive = false;
3543 3552
3544 for (src = val->sources; src; src = src->next) 3553 for (src = val->sources; src; src = src->next)
3545 { 3554 {
3546 struct cgraph_edge *cs = src->cs; 3555 struct cgraph_edge *cs = src->cs;
3547 while (cs) 3556 while (cs)
3548 { 3557 {
3549 if (cgraph_edge_brings_value_p (cs, src, dest)) 3558 if (cgraph_edge_brings_value_p (cs, src, dest, val))
3550 { 3559 {
3551 count++; 3560 count++;
3552 freq += cs->frequency; 3561 freq += cs->frequency ();
3553 if (cs->count.initialized_p ()) 3562 if (cs->count.ipa ().initialized_p ())
3554 cnt += cs->count; 3563 cnt += cs->count.ipa ();
3555 hot |= cs->maybe_hot_p (); 3564 hot |= cs->maybe_hot_p ();
3565 if (cs->caller != dest)
3566 non_self_recursive = true;
3556 } 3567 }
3557 cs = get_next_cgraph_edge_clone (cs); 3568 cs = get_next_cgraph_edge_clone (cs);
3558 } 3569 }
3559 } 3570 }
3571
3572 /* If the only edges bringing a value are self-recursive ones, do not bother
3573 evaluating it. */
3574 if (!non_self_recursive)
3575 return false;
3560 3576
3561 *freq_sum = freq; 3577 *freq_sum = freq;
3562 *count_sum = cnt; 3578 *count_sum = cnt;
3563 *caller_count = count; 3579 *caller_count = count;
3564 return hot; 3580 return hot;
3579 for (src = val->sources; src; src = src->next) 3595 for (src = val->sources; src; src = src->next)
3580 { 3596 {
3581 struct cgraph_edge *cs = src->cs; 3597 struct cgraph_edge *cs = src->cs;
3582 while (cs) 3598 while (cs)
3583 { 3599 {
3584 if (cgraph_edge_brings_value_p (cs, src, dest)) 3600 if (cgraph_edge_brings_value_p (cs, src, dest, val))
3585 ret.quick_push (cs); 3601 ret.quick_push (cs);
3586 cs = get_next_cgraph_edge_clone (cs); 3602 cs = get_next_cgraph_edge_clone (cs);
3587 } 3603 }
3588 } 3604 }
3589 3605
3659 struct cgraph_edge *cs; 3675 struct cgraph_edge *cs;
3660 struct caller_statistics stats; 3676 struct caller_statistics stats;
3661 profile_count new_sum, orig_sum; 3677 profile_count new_sum, orig_sum;
3662 profile_count remainder, orig_node_count = orig_node->count; 3678 profile_count remainder, orig_node_count = orig_node->count;
3663 3679
3664 if (!(orig_node_count > profile_count::zero ())) 3680 if (!(orig_node_count.ipa () > profile_count::zero ()))
3665 return; 3681 return;
3666 3682
3667 init_caller_stats (&stats); 3683 init_caller_stats (&stats);
3668 orig_node->call_for_symbol_thunks_and_aliases (gather_caller_stats, &stats, 3684 orig_node->call_for_symbol_thunks_and_aliases (gather_caller_stats, &stats,
3669 false); 3685 false);
3692 orig_node_count.dump (dump_file); 3708 orig_node_count.dump (dump_file);
3693 fprintf (dump_file, "\n"); 3709 fprintf (dump_file, "\n");
3694 } 3710 }
3695 } 3711 }
3696 3712
3697 new_node->count = new_sum; 3713 remainder = orig_node_count.combine_with_ipa_count (orig_node_count.ipa ()
3698 remainder = orig_node_count - new_sum; 3714 - new_sum.ipa ());
3715 new_sum = orig_node_count.combine_with_ipa_count (new_sum);
3699 orig_node->count = remainder; 3716 orig_node->count = remainder;
3700 3717
3701 for (cs = new_node->callees; cs; cs = cs->next_callee) 3718 for (cs = new_node->callees; cs; cs = cs->next_callee)
3702 /* FIXME: why we care about non-zero frequency here? */ 3719 cs->count = cs->count.apply_scale (new_sum, orig_node_count);
3703 if (cs->frequency)
3704 cs->count = cs->count.apply_scale (new_sum, orig_node_count);
3705 else
3706 cs->count = profile_count::zero ();
3707 3720
3708 for (cs = orig_node->callees; cs; cs = cs->next_callee) 3721 for (cs = orig_node->callees; cs; cs = cs->next_callee)
3709 cs->count = cs->count.apply_scale (remainder, orig_node_count); 3722 cs->count = cs->count.apply_scale (remainder, orig_node_count);
3710 3723
3711 if (dump_file) 3724 if (dump_file)
3738 new_node_count = new_node->count; 3751 new_node_count = new_node->count;
3739 new_node->count += redirected_sum; 3752 new_node->count += redirected_sum;
3740 orig_node->count -= redirected_sum; 3753 orig_node->count -= redirected_sum;
3741 3754
3742 for (cs = new_node->callees; cs; cs = cs->next_callee) 3755 for (cs = new_node->callees; cs; cs = cs->next_callee)
3743 if (cs->frequency) 3756 cs->count += cs->count.apply_scale (redirected_sum, new_node_count);
3744 cs->count += cs->count.apply_scale (redirected_sum, new_node_count);
3745 else
3746 cs->count = profile_count::zero ();
3747 3757
3748 for (cs = orig_node->callees; cs; cs = cs->next_callee) 3758 for (cs = orig_node->callees; cs; cs = cs->next_callee)
3749 { 3759 {
3750 profile_count dec = cs->count.apply_scale (redirected_sum, 3760 profile_count dec = cs->count.apply_scale (redirected_sum,
3751 orig_node_count); 3761 orig_node_count);
3805 replace_map = get_replacement_map (info, t, i); 3815 replace_map = get_replacement_map (info, t, i);
3806 if (replace_map) 3816 if (replace_map)
3807 vec_safe_push (replace_trees, replace_map); 3817 vec_safe_push (replace_trees, replace_map);
3808 } 3818 }
3809 } 3819 }
3820 auto_vec<cgraph_edge *, 2> self_recursive_calls;
3821 for (i = callers.length () - 1; i >= 0; i--)
3822 {
3823 cgraph_edge *cs = callers[i];
3824 if (cs->caller == node)
3825 {
3826 self_recursive_calls.safe_push (cs);
3827 callers.unordered_remove (i);
3828 }
3829 }
3810 3830
3811 new_node = node->create_virtual_clone (callers, replace_trees, 3831 new_node = node->create_virtual_clone (callers, replace_trees,
3812 args_to_skip, "constprop"); 3832 args_to_skip, "constprop");
3833
3834 bool have_self_recursive_calls = !self_recursive_calls.is_empty ();
3835 for (unsigned j = 0; j < self_recursive_calls.length (); j++)
3836 {
3837 cgraph_edge *cs = get_next_cgraph_edge_clone (self_recursive_calls[j]);
3838 /* Cloned edges can disappear during cloning as speculation can be
3839 resolved, check that we have one and that it comes from the last
3840 cloning. */
3841 if (cs && cs->caller == new_node)
3842 cs->redirect_callee_duplicating_thunks (new_node);
3843 /* Any future code that would make more than one clone of an outgoing
3844 edge would confuse this mechanism, so let's check that does not
3845 happen. */
3846 gcc_checking_assert (!cs
3847 || !get_next_cgraph_edge_clone (cs)
3848 || get_next_cgraph_edge_clone (cs)->caller != new_node);
3849 }
3850 if (have_self_recursive_calls)
3851 new_node->expand_all_artificial_thunks ();
3852
3813 ipa_set_node_agg_value_chain (new_node, aggvals); 3853 ipa_set_node_agg_value_chain (new_node, aggvals);
3814 for (av = aggvals; av; av = av->next) 3854 for (av = aggvals; av; av = av->next)
3815 new_node->maybe_create_reference (av->value, NULL); 3855 new_node->maybe_create_reference (av->value, NULL);
3816 3856
3817 if (dump_file && (dump_flags & TDF_DETAILS)) 3857 if (dump_file && (dump_flags & TDF_DETAILS))
3840 3880
3841 callers.release (); 3881 callers.release ();
3842 return new_node; 3882 return new_node;
3843 } 3883 }
3844 3884
3885 /* Return true, if JFUNC, which describes a i-th parameter of call CS, is a
3886 simple no-operation pass-through function to itself. */
3887
3888 static bool
3889 self_recursive_pass_through_p (cgraph_edge *cs, ipa_jump_func *jfunc, int i)
3890 {
3891 enum availability availability;
3892 if (cs->caller == cs->callee->function_symbol (&availability)
3893 && availability > AVAIL_INTERPOSABLE
3894 && jfunc->type == IPA_JF_PASS_THROUGH
3895 && ipa_get_jf_pass_through_operation (jfunc) == NOP_EXPR
3896 && ipa_get_jf_pass_through_formal_id (jfunc) == i)
3897 return true;
3898 return false;
3899 }
3900
3845 /* Given a NODE, and a subset of its CALLERS, try to populate blanks slots in 3901 /* Given a NODE, and a subset of its CALLERS, try to populate blanks slots in
3846 KNOWN_CSTS with constants that are also known for all of the CALLERS. */ 3902 KNOWN_CSTS with constants that are also known for all of the CALLERS. */
3847 3903
3848 static void 3904 static void
3849 find_more_scalar_values_for_callers_subset (struct cgraph_node *node, 3905 find_more_scalar_values_for_callers_subset (struct cgraph_node *node,
3857 { 3913 {
3858 struct cgraph_edge *cs; 3914 struct cgraph_edge *cs;
3859 tree newval = NULL_TREE; 3915 tree newval = NULL_TREE;
3860 int j; 3916 int j;
3861 bool first = true; 3917 bool first = true;
3918 tree type = ipa_get_type (info, i);
3862 3919
3863 if (ipa_get_scalar_lat (info, i)->bottom || known_csts[i]) 3920 if (ipa_get_scalar_lat (info, i)->bottom || known_csts[i])
3864 continue; 3921 continue;
3865 3922
3866 FOR_EACH_VEC_ELT (callers, j, cs) 3923 FOR_EACH_VEC_ELT (callers, j, cs)
3867 { 3924 {
3868 struct ipa_jump_func *jump_func; 3925 struct ipa_jump_func *jump_func;
3869 tree t; 3926 tree t;
3870 3927
3928 if (IPA_NODE_REF (cs->caller)->node_dead)
3929 continue;
3930
3871 if (i >= ipa_get_cs_argument_count (IPA_EDGE_REF (cs)) 3931 if (i >= ipa_get_cs_argument_count (IPA_EDGE_REF (cs))
3872 || (i == 0 3932 || (i == 0
3873 && call_passes_through_thunk_p (cs)) 3933 && call_passes_through_thunk_p (cs)))
3874 || (!cs->callee->instrumentation_clone
3875 && cs->callee->function_symbol ()->instrumentation_clone))
3876 { 3934 {
3877 newval = NULL_TREE; 3935 newval = NULL_TREE;
3878 break; 3936 break;
3879 } 3937 }
3880 jump_func = ipa_get_ith_jump_func (IPA_EDGE_REF (cs), i); 3938 jump_func = ipa_get_ith_jump_func (IPA_EDGE_REF (cs), i);
3881 t = ipa_value_from_jfunc (IPA_NODE_REF (cs->caller), jump_func); 3939 if (self_recursive_pass_through_p (cs, jump_func, i))
3940 continue;
3941
3942 t = ipa_value_from_jfunc (IPA_NODE_REF (cs->caller), jump_func, type);
3882 if (!t 3943 if (!t
3883 || (newval 3944 || (newval
3884 && !values_equal_for_ipcp_p (t, newval)) 3945 && !values_equal_for_ipcp_p (t, newval))
3885 || (!first && !newval)) 3946 || (!first && !newval))
3886 { 3947 {
4025 if (aglat->offset - offset > item->offset) 4086 if (aglat->offset - offset > item->offset)
4026 break; 4087 break;
4027 if (aglat->offset - offset == item->offset) 4088 if (aglat->offset - offset == item->offset)
4028 { 4089 {
4029 gcc_checking_assert (item->value); 4090 gcc_checking_assert (item->value);
4030 if (values_equal_for_ipcp_p (item->value, aglat->values->value)) 4091 if (aglat->is_single_const ()
4092 && values_equal_for_ipcp_p (item->value,
4093 aglat->values->value))
4031 found = true; 4094 found = true;
4032 break; 4095 break;
4033 } 4096 }
4034 aglat = aglat->next; 4097 aglat = aglat->next;
4035 } 4098 }
4178 intersect_with_agg_replacements (cs->caller, src_idx, &inter, 4241 intersect_with_agg_replacements (cs->caller, src_idx, &inter,
4179 delta); 4242 delta);
4180 } 4243 }
4181 else 4244 else
4182 { 4245 {
4183 src_plats = ipa_get_parm_lattices (caller_info, src_idx);; 4246 src_plats = ipa_get_parm_lattices (caller_info, src_idx);
4184 /* Currently we do not produce clobber aggregate jump 4247 /* Currently we do not produce clobber aggregate jump
4185 functions, adjust when we do. */ 4248 functions, adjust when we do. */
4186 gcc_checking_assert (!src_plats->aggs || !jfunc->agg.items); 4249 gcc_checking_assert (!src_plats->aggs || !jfunc->agg.items);
4187 if (!inter.exists ()) 4250 if (!inter.exists ())
4188 inter = copy_plats_to_inter (src_plats, delta); 4251 inter = copy_plats_to_inter (src_plats, delta);
4200 inter.safe_push ((*jfunc->agg.items)[i]); 4263 inter.safe_push ((*jfunc->agg.items)[i]);
4201 else 4264 else
4202 FOR_EACH_VEC_ELT (inter, k, item) 4265 FOR_EACH_VEC_ELT (inter, k, item)
4203 { 4266 {
4204 int l = 0; 4267 int l = 0;
4205 bool found = false;; 4268 bool found = false;
4206 4269
4207 if (!item->value) 4270 if (!item->value)
4208 continue; 4271 continue;
4209 4272
4210 while ((unsigned) l < jfunc->agg.items->length ()) 4273 while ((unsigned) l < jfunc->agg.items->length ())
4268 if (plats->aggs_bottom) 4331 if (plats->aggs_bottom)
4269 continue; 4332 continue;
4270 4333
4271 FOR_EACH_VEC_ELT (callers, j, cs) 4334 FOR_EACH_VEC_ELT (callers, j, cs)
4272 { 4335 {
4336 struct ipa_jump_func *jfunc
4337 = ipa_get_ith_jump_func (IPA_EDGE_REF (cs), i);
4338 if (self_recursive_pass_through_p (cs, jfunc, i)
4339 && (!plats->aggs_by_ref
4340 || ipa_get_jf_pass_through_agg_preserved (jfunc)))
4341 continue;
4273 inter = intersect_aggregates_with_edge (cs, i, inter); 4342 inter = intersect_aggregates_with_edge (cs, i, inter);
4274 4343
4275 if (!inter.exists ()) 4344 if (!inter.exists ())
4276 goto next_param; 4345 goto next_param;
4277 } 4346 }
4298 } 4367 }
4299 *tail = NULL; 4368 *tail = NULL;
4300 return res; 4369 return res;
4301 } 4370 }
4302 4371
4303 /* Turn KNOWN_AGGS into a list of aggregate replacement values. */
4304
4305 static struct ipa_agg_replacement_value *
4306 known_aggs_to_agg_replacement_list (vec<ipa_agg_jump_function> known_aggs)
4307 {
4308 struct ipa_agg_replacement_value *res;
4309 struct ipa_agg_replacement_value **tail = &res;
4310 struct ipa_agg_jump_function *aggjf;
4311 struct ipa_agg_jf_item *item;
4312 int i, j;
4313
4314 FOR_EACH_VEC_ELT (known_aggs, i, aggjf)
4315 FOR_EACH_VEC_SAFE_ELT (aggjf->items, j, item)
4316 {
4317 struct ipa_agg_replacement_value *v;
4318 v = ggc_alloc<ipa_agg_replacement_value> ();
4319 v->index = i;
4320 v->offset = item->offset;
4321 v->value = item->value;
4322 v->by_ref = aggjf->by_ref;
4323 *tail = v;
4324 tail = &v->next;
4325 }
4326 *tail = NULL;
4327 return res;
4328 }
4329
4330 /* Determine whether CS also brings all scalar values that the NODE is 4372 /* Determine whether CS also brings all scalar values that the NODE is
4331 specialized for. */ 4373 specialized for. */
4332 4374
4333 static bool 4375 static bool
4334 cgraph_edge_brings_all_scalars_for_node (struct cgraph_edge *cs, 4376 cgraph_edge_brings_all_scalars_for_node (struct cgraph_edge *cs,
4352 continue; 4394 continue;
4353 4395
4354 if (i >= ipa_get_cs_argument_count (args)) 4396 if (i >= ipa_get_cs_argument_count (args))
4355 return false; 4397 return false;
4356 jump_func = ipa_get_ith_jump_func (args, i); 4398 jump_func = ipa_get_ith_jump_func (args, i);
4357 t = ipa_value_from_jfunc (caller_info, jump_func); 4399 t = ipa_value_from_jfunc (caller_info, jump_func,
4400 ipa_get_type (dest_info, i));
4358 if (!t || !values_equal_for_ipcp_p (val, t)) 4401 if (!t || !values_equal_for_ipcp_p (val, t))
4359 return false; 4402 return false;
4360 } 4403 }
4361 return true; 4404 return true;
4362 } 4405 }
4449 for (src = val->sources; src; src = src->next) 4492 for (src = val->sources; src; src = src->next)
4450 { 4493 {
4451 struct cgraph_edge *cs = src->cs; 4494 struct cgraph_edge *cs = src->cs;
4452 while (cs) 4495 while (cs)
4453 { 4496 {
4454 if (cgraph_edge_brings_value_p (cs, src, node) 4497 if (cgraph_edge_brings_value_p (cs, src, node, val)
4455 && cgraph_edge_brings_all_scalars_for_node (cs, val->spec_node) 4498 && cgraph_edge_brings_all_scalars_for_node (cs, val->spec_node)
4456 && cgraph_edge_brings_all_agg_vals_for_node (cs, val->spec_node)) 4499 && cgraph_edge_brings_all_agg_vals_for_node (cs, val->spec_node))
4457 { 4500 {
4458 if (dump_file) 4501 if (dump_file)
4459 fprintf (dump_file, " - adding an extra caller %s of %s\n", 4502 fprintf (dump_file, " - adding an extra caller %s of %s\n",
4460 cs->caller->dump_name (), 4503 cs->caller->dump_name (),
4461 val->spec_node->dump_name ()); 4504 val->spec_node->dump_name ());
4462 4505
4463 cs->redirect_callee_duplicating_thunks (val->spec_node); 4506 cs->redirect_callee_duplicating_thunks (val->spec_node);
4464 val->spec_node->expand_all_artificial_thunks (); 4507 val->spec_node->expand_all_artificial_thunks ();
4465 if (cs->count.initialized_p ()) 4508 if (cs->count.ipa ().initialized_p ())
4466 redirected_sum = redirected_sum + cs->count; 4509 redirected_sum = redirected_sum + cs->count.ipa ();
4467 } 4510 }
4468 cs = get_next_cgraph_edge_clone (cs); 4511 cs = get_next_cgraph_edge_clone (cs);
4469 } 4512 }
4470 } 4513 }
4471 4514
4472 if (redirected_sum > profile_count::zero ()) 4515 if (redirected_sum.nonzero_p ())
4473 update_specialized_profile (val->spec_node, node, redirected_sum); 4516 update_specialized_profile (val->spec_node, node, redirected_sum);
4474 } 4517 }
4475 4518
4476 /* Return true if KNOWN_CONTEXTS contain at least one useful context. */ 4519 /* Return true if KNOWN_CONTEXTS contain at least one useful context. */
4477 4520
4714 if (dump_file) 4757 if (dump_file)
4715 fprintf (dump_file, " - Creating a specialized node of %s " 4758 fprintf (dump_file, " - Creating a specialized node of %s "
4716 "for all known contexts.\n", node->dump_name ()); 4759 "for all known contexts.\n", node->dump_name ());
4717 4760
4718 callers = node->collect_callers (); 4761 callers = node->collect_callers ();
4762 find_more_scalar_values_for_callers_subset (node, known_csts, callers);
4763 find_more_contexts_for_caller_subset (node, &known_contexts, callers);
4764 ipa_agg_replacement_value *aggvals
4765 = find_aggregate_values_for_callers_subset (node, callers);
4719 4766
4720 if (!known_contexts_useful_p (known_contexts)) 4767 if (!known_contexts_useful_p (known_contexts))
4721 { 4768 {
4722 known_contexts.release (); 4769 known_contexts.release ();
4723 known_contexts = vNULL; 4770 known_contexts = vNULL;
4724 } 4771 }
4725 clone = create_specialized_node (node, known_csts, known_contexts, 4772 clone = create_specialized_node (node, known_csts, known_contexts,
4726 known_aggs_to_agg_replacement_list (known_aggs), 4773 aggvals, callers);
4727 callers);
4728 info = IPA_NODE_REF (node); 4774 info = IPA_NODE_REF (node);
4729 info->do_clone_for_all_contexts = false; 4775 info->do_clone_for_all_contexts = false;
4730 IPA_NODE_REF (clone)->is_all_contexts_clone = true; 4776 IPA_NODE_REF (clone)->is_all_contexts_clone = true;
4731 for (i = 0; i < count; i++) 4777 for (i = 0; i < count; i++)
4732 vec_free (known_aggs[i].items); 4778 vec_free (known_aggs[i].items);
4882 } 4928 }
4883 4929
4884 if (!found_useful_result) 4930 if (!found_useful_result)
4885 continue; 4931 continue;
4886 4932
4887 ipcp_grow_transformations_if_necessary (); 4933 ipcp_transformation_initialize ();
4888 ipcp_transformation_summary *ts = ipcp_get_transformation_summary (node); 4934 ipcp_transformation *ts = ipcp_transformation_sum->get_create (node);
4889 vec_safe_reserve_exact (ts->bits, count); 4935 vec_safe_reserve_exact (ts->bits, count);
4890 4936
4891 for (unsigned i = 0; i < count; i++) 4937 for (unsigned i = 0; i < count; i++)
4892 { 4938 {
4893 ipcp_param_lattices *plats = ipa_get_parm_lattices (info, i); 4939 ipcp_param_lattices *plats = ipa_get_parm_lattices (info, i);
4955 } 5001 }
4956 } 5002 }
4957 if (!found_useful_result) 5003 if (!found_useful_result)
4958 continue; 5004 continue;
4959 5005
4960 ipcp_grow_transformations_if_necessary (); 5006 ipcp_transformation_initialize ();
4961 ipcp_transformation_summary *ts = ipcp_get_transformation_summary (node); 5007 ipcp_transformation *ts = ipcp_transformation_sum->get_create (node);
4962 vec_safe_reserve_exact (ts->m_vr, count); 5008 vec_safe_reserve_exact (ts->m_vr, count);
4963 5009
4964 for (unsigned i = 0; i < count; i++) 5010 for (unsigned i = 0; i < count; i++)
4965 { 5011 {
4966 ipcp_param_lattices *plats = ipa_get_parm_lattices (info, i); 5012 ipcp_param_lattices *plats = ipa_get_parm_lattices (info, i);
4968 5014
4969 if (!plats->m_value_range.bottom_p () 5015 if (!plats->m_value_range.bottom_p ()
4970 && !plats->m_value_range.top_p ()) 5016 && !plats->m_value_range.top_p ())
4971 { 5017 {
4972 vr.known = true; 5018 vr.known = true;
4973 vr.type = plats->m_value_range.m_vr.type; 5019 vr.type = plats->m_value_range.m_vr.kind ();
4974 vr.min = wi::to_wide (plats->m_value_range.m_vr.min); 5020 vr.min = wi::to_wide (plats->m_value_range.m_vr.min ());
4975 vr.max = wi::to_wide (plats->m_value_range.m_vr.max); 5021 vr.max = wi::to_wide (plats->m_value_range.m_vr.max ());
4976 } 5022 }
4977 else 5023 else
4978 { 5024 {
4979 vr.known = false; 5025 vr.known = false;
4980 vr.type = VR_VARYING; 5026 vr.type = VR_VARYING;
4988 /* The IPCP driver. */ 5034 /* The IPCP driver. */
4989 5035
4990 static unsigned int 5036 static unsigned int
4991 ipcp_driver (void) 5037 ipcp_driver (void)
4992 { 5038 {
4993 struct cgraph_2edge_hook_list *edge_duplication_hook_holder;
4994 struct cgraph_edge_hook_list *edge_removal_hook_holder;
4995 struct ipa_topo_info topo; 5039 struct ipa_topo_info topo;
5040
5041 if (edge_clone_summaries == NULL)
5042 edge_clone_summaries = new edge_clone_summary_t (symtab);
4996 5043
4997 ipa_check_create_node_params (); 5044 ipa_check_create_node_params ();
4998 ipa_check_create_edge_args (); 5045 ipa_check_create_edge_args ();
4999 grow_edge_clone_vectors ();
5000 edge_duplication_hook_holder
5001 = symtab->add_edge_duplication_hook (&ipcp_edge_duplication_hook, NULL);
5002 edge_removal_hook_holder
5003 = symtab->add_edge_removal_hook (&ipcp_edge_removal_hook, NULL);
5004 5046
5005 if (dump_file) 5047 if (dump_file)
5006 { 5048 {
5007 fprintf (dump_file, "\nIPA structures before propagation:\n"); 5049 fprintf (dump_file, "\nIPA structures before propagation:\n");
5008 if (dump_flags & TDF_DETAILS) 5050 if (dump_flags & TDF_DETAILS)
5021 /* Store results of value range propagation. */ 5063 /* Store results of value range propagation. */
5022 ipcp_store_vr_results (); 5064 ipcp_store_vr_results ();
5023 5065
5024 /* Free all IPCP structures. */ 5066 /* Free all IPCP structures. */
5025 free_toporder_info (&topo); 5067 free_toporder_info (&topo);
5026 next_edge_clone.release (); 5068 delete edge_clone_summaries;
5027 prev_edge_clone.release (); 5069 edge_clone_summaries = NULL;
5028 symtab->remove_edge_removal_hook (edge_removal_hook_holder);
5029 symtab->remove_edge_duplication_hook (edge_duplication_hook_holder);
5030 ipa_free_all_structures_after_ipa_cp (); 5070 ipa_free_all_structures_after_ipa_cp ();
5031 if (dump_file) 5071 if (dump_file)
5032 fprintf (dump_file, "\nIPA constant propagation end\n"); 5072 fprintf (dump_file, "\nIPA constant propagation end\n");
5033 return 0; 5073 return 0;
5034 } 5074 }
5123 within the same process. For use by toplev::finalize. */ 5163 within the same process. For use by toplev::finalize. */
5124 5164
5125 void 5165 void
5126 ipa_cp_c_finalize (void) 5166 ipa_cp_c_finalize (void)
5127 { 5167 {
5128 max_count = profile_count::zero (); 5168 max_count = profile_count::uninitialized ();
5129 overall_size = 0; 5169 overall_size = 0;
5130 max_new_size = 0; 5170 max_new_size = 0;
5131 } 5171 }