comparison gcc/ipa-cp.c @ 145:1830386684a0

gcc-9.2.0
author anatofuz
date Thu, 13 Feb 2020 11:34:05 +0900
parents 84e7813d76e9
children
comparison
equal deleted inserted replaced
131:84e7813d76e9 145:1830386684a0
1 /* Interprocedural constant propagation 1 /* Interprocedural constant propagation
2 Copyright (C) 2005-2018 Free Software Foundation, Inc. 2 Copyright (C) 2005-2020 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.
116 #include "symbol-summary.h" 116 #include "symbol-summary.h"
117 #include "tree-vrp.h" 117 #include "tree-vrp.h"
118 #include "ipa-prop.h" 118 #include "ipa-prop.h"
119 #include "tree-pretty-print.h" 119 #include "tree-pretty-print.h"
120 #include "tree-inline.h" 120 #include "tree-inline.h"
121 #include "params.h"
122 #include "ipa-fnsummary.h" 121 #include "ipa-fnsummary.h"
123 #include "ipa-utils.h" 122 #include "ipa-utils.h"
124 #include "tree-ssa-ccp.h" 123 #include "tree-ssa-ccp.h"
125 #include "stringpool.h" 124 #include "stringpool.h"
126 #include "attribs.h" 125 #include "attribs.h"
128 template <typename valtype> class ipcp_value; 127 template <typename valtype> class ipcp_value;
129 128
130 /* Describes a particular source for an IPA-CP value. */ 129 /* Describes a particular source for an IPA-CP value. */
131 130
132 template <typename valtype> 131 template <typename valtype>
133 class ipcp_value_source 132 struct ipcp_value_source
134 { 133 {
135 public: 134 public:
136 /* Aggregate offset of the source, negative if the source is scalar value of 135 /* Aggregate offset of the source, negative if the source is scalar value of
137 the argument itself. */ 136 the argument itself. */
138 HOST_WIDE_INT offset; 137 HOST_WIDE_INT offset;
189 created. */ 188 created. */
190 cgraph_node *spec_node; 189 cgraph_node *spec_node;
191 /* Depth first search number and low link for topological sorting of 190 /* Depth first search number and low link for topological sorting of
192 values. */ 191 values. */
193 int dfs, low_link; 192 int dfs, low_link;
194 /* True if this valye is currently on the topo-sort stack. */ 193 /* True if this value is currently on the topo-sort stack. */
195 bool on_stack; 194 bool on_stack;
196 195
197 ipcp_value() 196 ipcp_value()
198 : sources (0), next (0), scc_next (0), topo_next (0), 197 : sources (0), next (0), scc_next (0), topo_next (0),
199 spec_node (0), dfs (0), low_link (0), on_stack (false) {} 198 spec_node (0), dfs (0), low_link (0), on_stack (false) {}
207 and with contains_variable and bottom flags cleared. BOTTOM is represented 206 and with contains_variable and bottom flags cleared. BOTTOM is represented
208 by a lattice with the bottom flag set. In that case, values and 207 by a lattice with the bottom flag set. In that case, values and
209 contains_variable flag should be disregarded. */ 208 contains_variable flag should be disregarded. */
210 209
211 template <typename valtype> 210 template <typename valtype>
212 class ipcp_lattice 211 struct ipcp_lattice
213 { 212 {
214 public: 213 public:
215 /* The list of known values and types in this lattice. Note that values are 214 /* The list of known values and types in this lattice. Note that values are
216 not deallocated if a lattice is set to bottom because there may be value 215 not deallocated if a lattice is set to bottom because there may be value
217 sources referencing them. */ 216 sources referencing them. */
227 inline bool is_single_const (); 226 inline bool is_single_const ();
228 inline bool set_to_bottom (); 227 inline bool set_to_bottom ();
229 inline bool set_contains_variable (); 228 inline bool set_contains_variable ();
230 bool add_value (valtype newval, cgraph_edge *cs, 229 bool add_value (valtype newval, cgraph_edge *cs,
231 ipcp_value<valtype> *src_val = NULL, 230 ipcp_value<valtype> *src_val = NULL,
232 int src_idx = 0, HOST_WIDE_INT offset = -1); 231 int src_idx = 0, HOST_WIDE_INT offset = -1,
232 ipcp_value<valtype> **val_p = NULL,
233 bool unlimited = false);
233 void print (FILE * f, bool dump_sources, bool dump_benefits); 234 void print (FILE * f, bool dump_sources, bool dump_benefits);
234 }; 235 };
235 236
236 /* Lattice of tree values with an offset to describe a part of an 237 /* Lattice of tree values with an offset to describe a part of an
237 aggregate. */ 238 aggregate. */
238 239
239 class ipcp_agg_lattice : public ipcp_lattice<tree> 240 struct ipcp_agg_lattice : public ipcp_lattice<tree>
240 { 241 {
241 public: 242 public:
242 /* Offset that is being described by this lattice. */ 243 /* Offset that is being described by this lattice. */
243 HOST_WIDE_INT offset; 244 HOST_WIDE_INT offset;
244 /* Size so that we don't have to re-compute it every time we traverse the 245 /* Size so that we don't have to re-compute it every time we traverse the
372 373
373 static profile_count max_count; 374 static profile_count max_count;
374 375
375 /* Original overall size of the program. */ 376 /* Original overall size of the program. */
376 377
377 static long overall_size, max_new_size; 378 static long overall_size, orig_overall_size;
379
380 /* Node name to unique clone suffix number map. */
381 static hash_map<const char *, unsigned> *clone_num_suffixes;
378 382
379 /* Return the param lattices structure corresponding to the Ith formal 383 /* Return the param lattices structure corresponding to the Ith formal
380 parameter of the function described by INFO. */ 384 parameter of the function described by INFO. */
381 static inline struct ipcp_param_lattices * 385 static inline class ipcp_param_lattices *
382 ipa_get_parm_lattices (struct ipa_node_params *info, int i) 386 ipa_get_parm_lattices (class ipa_node_params *info, int i)
383 { 387 {
384 gcc_assert (i >= 0 && i < ipa_get_param_count (info)); 388 gcc_assert (i >= 0 && i < ipa_get_param_count (info));
385 gcc_checking_assert (!info->ipcp_orig_node); 389 gcc_checking_assert (!info->ipcp_orig_node);
386 gcc_checking_assert (info->lattices); 390 gcc_checking_assert (info->lattices);
387 return &(info->lattices[i]); 391 return &(info->lattices[i]);
388 } 392 }
389 393
390 /* Return the lattice corresponding to the scalar value of the Ith formal 394 /* Return the lattice corresponding to the scalar value of the Ith formal
391 parameter of the function described by INFO. */ 395 parameter of the function described by INFO. */
392 static inline ipcp_lattice<tree> * 396 static inline ipcp_lattice<tree> *
393 ipa_get_scalar_lat (struct ipa_node_params *info, int i) 397 ipa_get_scalar_lat (class ipa_node_params *info, int i)
394 { 398 {
395 struct ipcp_param_lattices *plats = ipa_get_parm_lattices (info, i); 399 class ipcp_param_lattices *plats = ipa_get_parm_lattices (info, i);
396 return &plats->itself; 400 return &plats->itself;
397 } 401 }
398 402
399 /* Return the lattice corresponding to the scalar value of the Ith formal 403 /* Return the lattice corresponding to the scalar value of the Ith formal
400 parameter of the function described by INFO. */ 404 parameter of the function described by INFO. */
401 static inline ipcp_lattice<ipa_polymorphic_call_context> * 405 static inline ipcp_lattice<ipa_polymorphic_call_context> *
402 ipa_get_poly_ctx_lat (struct ipa_node_params *info, int i) 406 ipa_get_poly_ctx_lat (class ipa_node_params *info, int i)
403 { 407 {
404 struct ipcp_param_lattices *plats = ipa_get_parm_lattices (info, i); 408 class ipcp_param_lattices *plats = ipa_get_parm_lattices (info, i);
405 return &plats->ctxlat; 409 return &plats->ctxlat;
406 } 410 }
407 411
408 /* Return whether LAT is a lattice with a single constant and without an 412 /* Return whether LAT is a lattice with a single constant and without an
409 undefined value. */ 413 undefined value. */
534 int i, count; 538 int i, count;
535 539
536 fprintf (f, "\nLattices:\n"); 540 fprintf (f, "\nLattices:\n");
537 FOR_EACH_FUNCTION_WITH_GIMPLE_BODY (node) 541 FOR_EACH_FUNCTION_WITH_GIMPLE_BODY (node)
538 { 542 {
539 struct ipa_node_params *info; 543 class ipa_node_params *info;
540 544
541 info = IPA_NODE_REF (node); 545 info = IPA_NODE_REF (node);
546 /* Skip unoptimized functions and constprop clones since we don't make
547 lattices for them. */
548 if (!info || info->ipcp_orig_node)
549 continue;
542 fprintf (f, " Node: %s:\n", node->dump_name ()); 550 fprintf (f, " Node: %s:\n", node->dump_name ());
543 count = ipa_get_param_count (info); 551 count = ipa_get_param_count (info);
544 for (i = 0; i < count; i++) 552 for (i = 0; i < count; i++)
545 { 553 {
546 struct ipcp_agg_lattice *aglat; 554 struct ipcp_agg_lattice *aglat;
547 struct ipcp_param_lattices *plats = ipa_get_parm_lattices (info, i); 555 class ipcp_param_lattices *plats = ipa_get_parm_lattices (info, i);
548 fprintf (f, " param [%d]: ", i); 556 fprintf (f, " param [%d]: ", i);
549 plats->itself.print (f, dump_sources, dump_benefits); 557 plats->itself.print (f, dump_sources, dump_benefits);
550 fprintf (f, " ctxs: "); 558 fprintf (f, " ctxs: ");
551 plats->ctxlat.print (f, dump_sources, dump_benefits); 559 plats->ctxlat.print (f, dump_sources, dump_benefits);
552 plats->bits_lattice.print (f); 560 plats->bits_lattice.print (f);
577 and store this information in the ipa_node_params structure associated 585 and store this information in the ipa_node_params structure associated
578 with NODE. */ 586 with NODE. */
579 587
580 static void 588 static void
581 determine_versionability (struct cgraph_node *node, 589 determine_versionability (struct cgraph_node *node,
582 struct ipa_node_params *info) 590 class ipa_node_params *info)
583 { 591 {
584 const char *reason = NULL; 592 const char *reason = NULL;
585 593
586 /* There are a number of generic reasons functions cannot be versioned. We 594 /* There are a number of generic reasons functions cannot be versioned. We
587 also cannot remove parameters if there are type attributes such as fnspec 595 also cannot remove parameters if there are type attributes such as fnspec
588 present. */ 596 present. */
589 if (node->alias || node->thunk.thunk_p) 597 if (node->alias || node->thunk.thunk_p)
590 reason = "alias or thunk"; 598 reason = "alias or thunk";
591 else if (!node->local.versionable) 599 else if (!node->versionable)
592 reason = "not a tree_versionable_function"; 600 reason = "not a tree_versionable_function";
593 else if (node->get_availability () <= AVAIL_INTERPOSABLE) 601 else if (node->get_availability () <= AVAIL_INTERPOSABLE)
594 reason = "insufficient body availability"; 602 reason = "insufficient body availability";
595 else if (!opt_for_fn (node->decl, optimize) 603 else if (!opt_for_fn (node->decl, optimize)
596 || !opt_for_fn (node->decl, flag_ipa_cp)) 604 || !opt_for_fn (node->decl, flag_ipa_cp))
648 NODE. */ 656 NODE. */
649 657
650 static bool 658 static bool
651 ipcp_versionable_function_p (struct cgraph_node *node) 659 ipcp_versionable_function_p (struct cgraph_node *node)
652 { 660 {
653 return IPA_NODE_REF (node)->versionable; 661 return IPA_NODE_REF (node) && IPA_NODE_REF (node)->versionable;
654 } 662 }
655 663
656 /* Structure holding accumulated information about callers of a node. */ 664 /* Structure holding accumulated information about callers of a node. */
657 665
658 struct caller_statistics 666 struct caller_statistics
707 if (!opt_for_fn (node->decl, flag_ipa_cp_clone)) 715 if (!opt_for_fn (node->decl, flag_ipa_cp_clone))
708 { 716 {
709 if (dump_file) 717 if (dump_file)
710 fprintf (dump_file, "Not considering %s for cloning; " 718 fprintf (dump_file, "Not considering %s for cloning; "
711 "-fipa-cp-clone disabled.\n", 719 "-fipa-cp-clone disabled.\n",
712 node->name ()); 720 node->dump_name ());
713 return false; 721 return false;
714 } 722 }
715 723
716 if (node->optimize_for_size_p ()) 724 if (node->optimize_for_size_p ())
717 { 725 {
718 if (dump_file) 726 if (dump_file)
719 fprintf (dump_file, "Not considering %s for cloning; " 727 fprintf (dump_file, "Not considering %s for cloning; "
720 "optimizing it for size.\n", 728 "optimizing it for size.\n",
721 node->name ()); 729 node->dump_name ());
722 return false; 730 return false;
723 } 731 }
724 732
725 init_caller_stats (&stats); 733 init_caller_stats (&stats);
726 node->call_for_symbol_thunks_and_aliases (gather_caller_stats, &stats, false); 734 node->call_for_symbol_thunks_and_aliases (gather_caller_stats, &stats, false);
727 735
728 if (ipa_fn_summaries->get (node)->self_size < stats.n_calls) 736 if (ipa_size_summaries->get (node)->self_size < stats.n_calls)
729 { 737 {
730 if (dump_file) 738 if (dump_file)
731 fprintf (dump_file, "Considering %s for cloning; code might shrink.\n", 739 fprintf (dump_file, "Considering %s for cloning; code might shrink.\n",
732 node->name ()); 740 node->dump_name ());
733 return true; 741 return true;
734 } 742 }
735 743
736 /* When profile is available and function is hot, propagate into it even if 744 /* When profile is available and function is hot, propagate into it even if
737 calls seems cold; constant propagation can improve function's speed 745 calls seems cold; constant propagation can improve function's speed
741 if (stats.count_sum > node->count.ipa ().apply_scale (90, 100)) 749 if (stats.count_sum > node->count.ipa ().apply_scale (90, 100))
742 { 750 {
743 if (dump_file) 751 if (dump_file)
744 fprintf (dump_file, "Considering %s for cloning; " 752 fprintf (dump_file, "Considering %s for cloning; "
745 "usually called directly.\n", 753 "usually called directly.\n",
746 node->name ()); 754 node->dump_name ());
747 return true; 755 return true;
748 } 756 }
749 } 757 }
750 if (!stats.n_hot_calls) 758 if (!stats.n_hot_calls)
751 { 759 {
752 if (dump_file) 760 if (dump_file)
753 fprintf (dump_file, "Not considering %s for cloning; no hot calls.\n", 761 fprintf (dump_file, "Not considering %s for cloning; no hot calls.\n",
754 node->name ()); 762 node->dump_name ());
755 return false; 763 return false;
756 } 764 }
757 if (dump_file) 765 if (dump_file)
758 fprintf (dump_file, "Considering %s for cloning.\n", 766 fprintf (dump_file, "Considering %s for cloning.\n",
759 node->name ()); 767 node->dump_name ());
760 return true; 768 return true;
761 } 769 }
762 770
763 template <typename valtype> 771 template <typename valtype>
764 class value_topo_info 772 class value_topo_info
798 ipa_topo_info () : order(NULL), stack(NULL), nnodes(0), stack_top(0), 806 ipa_topo_info () : order(NULL), stack(NULL), nnodes(0), stack_top(0),
799 constants () 807 constants ()
800 {} 808 {}
801 }; 809 };
802 810
811 /* Skip edges from and to nodes without ipa_cp enabled.
812 Ignore not available symbols. */
813
814 static bool
815 ignore_edge_p (cgraph_edge *e)
816 {
817 enum availability avail;
818 cgraph_node *ultimate_target
819 = e->callee->function_or_virtual_thunk_symbol (&avail, e->caller);
820
821 return (avail <= AVAIL_INTERPOSABLE
822 || !opt_for_fn (ultimate_target->decl, optimize)
823 || !opt_for_fn (ultimate_target->decl, flag_ipa_cp));
824 }
825
803 /* Allocate the arrays in TOPO and topologically sort the nodes into order. */ 826 /* Allocate the arrays in TOPO and topologically sort the nodes into order. */
804 827
805 static void 828 static void
806 build_toporder_info (struct ipa_topo_info *topo) 829 build_toporder_info (class ipa_topo_info *topo)
807 { 830 {
808 topo->order = XCNEWVEC (struct cgraph_node *, symtab->cgraph_count); 831 topo->order = XCNEWVEC (struct cgraph_node *, symtab->cgraph_count);
809 topo->stack = XCNEWVEC (struct cgraph_node *, symtab->cgraph_count); 832 topo->stack = XCNEWVEC (struct cgraph_node *, symtab->cgraph_count);
810 833
811 gcc_checking_assert (topo->stack_top == 0); 834 gcc_checking_assert (topo->stack_top == 0);
812 topo->nnodes = ipa_reduced_postorder (topo->order, true, true, NULL); 835 topo->nnodes = ipa_reduced_postorder (topo->order, true,
836 ignore_edge_p);
813 } 837 }
814 838
815 /* Free information about strongly connected components and the arrays in 839 /* Free information about strongly connected components and the arrays in
816 TOPO. */ 840 TOPO. */
817 841
818 static void 842 static void
819 free_toporder_info (struct ipa_topo_info *topo) 843 free_toporder_info (class ipa_topo_info *topo)
820 { 844 {
821 ipa_free_postorder_info (); 845 ipa_free_postorder_info ();
822 free (topo->order); 846 free (topo->order);
823 free (topo->stack); 847 free (topo->stack);
824 } 848 }
825 849
826 /* Add NODE to the stack in TOPO, unless it is already there. */ 850 /* Add NODE to the stack in TOPO, unless it is already there. */
827 851
828 static inline void 852 static inline void
829 push_node_to_stack (struct ipa_topo_info *topo, struct cgraph_node *node) 853 push_node_to_stack (class ipa_topo_info *topo, struct cgraph_node *node)
830 { 854 {
831 struct ipa_node_params *info = IPA_NODE_REF (node); 855 class ipa_node_params *info = IPA_NODE_REF (node);
832 if (info->node_enqueued) 856 if (info->node_enqueued)
833 return; 857 return;
834 info->node_enqueued = 1; 858 info->node_enqueued = 1;
835 topo->stack[topo->stack_top++] = node; 859 topo->stack[topo->stack_top++] = node;
836 } 860 }
837 861
838 /* Pop a node from the stack in TOPO and return it or return NULL if the stack 862 /* Pop a node from the stack in TOPO and return it or return NULL if the stack
839 is empty. */ 863 is empty. */
840 864
841 static struct cgraph_node * 865 static struct cgraph_node *
842 pop_node_from_stack (struct ipa_topo_info *topo) 866 pop_node_from_stack (class ipa_topo_info *topo)
843 { 867 {
844 if (topo->stack_top) 868 if (topo->stack_top)
845 { 869 {
846 struct cgraph_node *node; 870 struct cgraph_node *node;
847 topo->stack_top--; 871 topo->stack_top--;
875 bool ret = !contains_variable; 899 bool ret = !contains_variable;
876 contains_variable = true; 900 contains_variable = true;
877 return ret; 901 return ret;
878 } 902 }
879 903
880 /* Set all aggegate lattices in PLATS to bottom and return true if they were 904 /* Set all aggregate lattices in PLATS to bottom and return true if they were
881 not previously set as such. */ 905 not previously set as such. */
882 906
883 static inline bool 907 static inline bool
884 set_agg_lats_to_bottom (struct ipcp_param_lattices *plats) 908 set_agg_lats_to_bottom (class ipcp_param_lattices *plats)
885 { 909 {
886 bool ret = !plats->aggs_bottom; 910 bool ret = !plats->aggs_bottom;
887 plats->aggs_bottom = true; 911 plats->aggs_bottom = true;
888 return ret; 912 return ret;
889 } 913 }
890 914
891 /* Mark all aggegate lattices in PLATS as containing an unknown value and 915 /* Mark all aggregate lattices in PLATS as containing an unknown value and
892 return true if they were not previously marked as such. */ 916 return true if they were not previously marked as such. */
893 917
894 static inline bool 918 static inline bool
895 set_agg_lats_contain_variable (struct ipcp_param_lattices *plats) 919 set_agg_lats_contain_variable (class ipcp_param_lattices *plats)
896 { 920 {
897 bool ret = !plats->aggs_contain_variable; 921 bool ret = !plats->aggs_contain_variable;
898 plats->aggs_contain_variable = true; 922 plats->aggs_contain_variable = true;
899 return ret; 923 return ret;
900 } 924 }
903 ipcp_vr_lattice::meet_with (const ipcp_vr_lattice &other) 927 ipcp_vr_lattice::meet_with (const ipcp_vr_lattice &other)
904 { 928 {
905 return meet_with_1 (&other.m_vr); 929 return meet_with_1 (&other.m_vr);
906 } 930 }
907 931
908 /* Meet the current value of the lattice with value ranfge described by VR 932 /* Meet the current value of the lattice with value range described by VR
909 lattice. */ 933 lattice. */
910 934
911 bool 935 bool
912 ipcp_vr_lattice::meet_with (const value_range *p_vr) 936 ipcp_vr_lattice::meet_with (const value_range *p_vr)
913 { 937 {
926 if (other_vr->varying_p ()) 950 if (other_vr->varying_p ())
927 return set_to_bottom (); 951 return set_to_bottom ();
928 952
929 value_range save (m_vr); 953 value_range save (m_vr);
930 m_vr.union_ (other_vr); 954 m_vr.union_ (other_vr);
931 return !m_vr.ignore_equivs_equal_p (save); 955 return !m_vr.equal_p (save);
932 } 956 }
933 957
934 /* Return true if value range information in the lattice is yet unknown. */ 958 /* Return true if value range information in the lattice is yet unknown. */
935 959
936 bool 960 bool
954 bool 978 bool
955 ipcp_vr_lattice::set_to_bottom () 979 ipcp_vr_lattice::set_to_bottom ()
956 { 980 {
957 if (m_vr.varying_p ()) 981 if (m_vr.varying_p ())
958 return false; 982 return false;
959 m_vr.set_varying (); 983 /* ?? We create all sorts of VARYING ranges for floats, structures,
984 and other types which we cannot handle as ranges. We should
985 probably avoid handling them throughout the pass, but it's easier
986 to create a sensible VARYING here and let the lattice
987 propagate. */
988 m_vr.set_varying (integer_type_node);
960 return true; 989 return true;
961 } 990 }
962 991
963 /* Set lattice value to bottom, if it already isn't the case. */ 992 /* Set lattice value to bottom, if it already isn't the case. */
964 993
1062 widest_int adjusted_value, adjusted_mask; 1091 widest_int adjusted_value, adjusted_mask;
1063 1092
1064 if (TREE_CODE_CLASS (code) == tcc_binary) 1093 if (TREE_CODE_CLASS (code) == tcc_binary)
1065 { 1094 {
1066 tree type = TREE_TYPE (operand); 1095 tree type = TREE_TYPE (operand);
1067 gcc_assert (INTEGRAL_TYPE_P (type));
1068 widest_int o_value, o_mask; 1096 widest_int o_value, o_mask;
1069 get_value_and_mask (operand, &o_value, &o_mask); 1097 get_value_and_mask (operand, &o_value, &o_mask);
1070 1098
1071 bit_value_binop (code, sgn, precision, &adjusted_value, &adjusted_mask, 1099 bit_value_binop (code, sgn, precision, &adjusted_value, &adjusted_mask,
1072 sgn, precision, other.get_value (), other.get_mask (), 1100 sgn, precision, other.get_value (), other.get_mask (),
1101 1129
1102 /* Mark bot aggregate and scalar lattices as containing an unknown variable, 1130 /* Mark bot aggregate and scalar lattices as containing an unknown variable,
1103 return true is any of them has not been marked as such so far. */ 1131 return true is any of them has not been marked as such so far. */
1104 1132
1105 static inline bool 1133 static inline bool
1106 set_all_contains_variable (struct ipcp_param_lattices *plats) 1134 set_all_contains_variable (class ipcp_param_lattices *plats)
1107 { 1135 {
1108 bool ret; 1136 bool ret;
1109 ret = plats->itself.set_contains_variable (); 1137 ret = plats->itself.set_contains_variable ();
1110 ret |= plats->ctxlat.set_contains_variable (); 1138 ret |= plats->ctxlat.set_contains_variable ();
1111 ret |= set_agg_lats_contain_variable (plats); 1139 ret |= set_agg_lats_contain_variable (plats);
1121 count_callers (cgraph_node *node, void *data) 1149 count_callers (cgraph_node *node, void *data)
1122 { 1150 {
1123 int *caller_count = (int *) data; 1151 int *caller_count = (int *) data;
1124 1152
1125 for (cgraph_edge *cs = node->callers; cs; cs = cs->next_caller) 1153 for (cgraph_edge *cs = node->callers; cs; cs = cs->next_caller)
1126 /* Local thunks can be handled transparently, but if the thunk can not 1154 /* Local thunks can be handled transparently, but if the thunk cannot
1127 be optimized out, count it as a real use. */ 1155 be optimized out, count it as a real use. */
1128 if (!cs->caller->thunk.thunk_p || !cs->caller->local.local) 1156 if (!cs->caller->thunk.thunk_p || !cs->caller->local)
1129 ++*caller_count; 1157 ++*caller_count;
1130 return false; 1158 return false;
1131 } 1159 }
1132 1160
1133 /* Worker of call_for_symbol_thunks_and_aliases, it is supposed to be called on 1161 /* Worker of call_for_symbol_thunks_and_aliases, it is supposed to be called on
1136 static bool 1164 static bool
1137 set_single_call_flag (cgraph_node *node, void *) 1165 set_single_call_flag (cgraph_node *node, void *)
1138 { 1166 {
1139 cgraph_edge *cs = node->callers; 1167 cgraph_edge *cs = node->callers;
1140 /* Local thunks can be handled transparently, skip them. */ 1168 /* Local thunks can be handled transparently, skip them. */
1141 while (cs && cs->caller->thunk.thunk_p && cs->caller->local.local) 1169 while (cs && cs->caller->thunk.thunk_p && cs->caller->local)
1142 cs = cs->next_caller; 1170 cs = cs->next_caller;
1143 if (cs) 1171 if (cs && IPA_NODE_REF (cs->caller))
1144 { 1172 {
1145 IPA_NODE_REF (cs->caller)->node_calling_single_call = true; 1173 IPA_NODE_REF (cs->caller)->node_calling_single_call = true;
1146 return true; 1174 return true;
1147 } 1175 }
1148 return false; 1176 return false;
1151 /* Initialize ipcp_lattices. */ 1179 /* Initialize ipcp_lattices. */
1152 1180
1153 static void 1181 static void
1154 initialize_node_lattices (struct cgraph_node *node) 1182 initialize_node_lattices (struct cgraph_node *node)
1155 { 1183 {
1156 struct ipa_node_params *info = IPA_NODE_REF (node); 1184 class ipa_node_params *info = IPA_NODE_REF (node);
1157 struct cgraph_edge *ie; 1185 struct cgraph_edge *ie;
1158 bool disable = false, variable = false; 1186 bool disable = false, variable = false;
1159 int i; 1187 int i;
1160 1188
1161 gcc_checking_assert (node->has_gimple_body_p ()); 1189 gcc_checking_assert (node->has_gimple_body_p ());
1162 if (node->local.local) 1190
1191 if (!ipa_get_param_count (info))
1192 disable = true;
1193 else if (node->local)
1163 { 1194 {
1164 int caller_count = 0; 1195 int caller_count = 0;
1165 node->call_for_symbol_thunks_and_aliases (count_callers, &caller_count, 1196 node->call_for_symbol_thunks_and_aliases (count_callers, &caller_count,
1166 true); 1197 true);
1167 gcc_checking_assert (caller_count > 0); 1198 gcc_checking_assert (caller_count > 0);
1179 variable = true; 1210 variable = true;
1180 else 1211 else
1181 disable = true; 1212 disable = true;
1182 } 1213 }
1183 1214
1184 for (i = 0; i < ipa_get_param_count (info); i++) 1215 if (dump_file && (dump_flags & TDF_DETAILS)
1185 { 1216 && !node->alias && !node->thunk.thunk_p)
1186 struct ipcp_param_lattices *plats = ipa_get_parm_lattices (info, i); 1217 {
1187 plats->m_value_range.init (); 1218 fprintf (dump_file, "Initializing lattices of %s\n",
1188 } 1219 node->dump_name ());
1189 1220 if (disable || variable)
1190 if (disable || variable) 1221 fprintf (dump_file, " Marking all lattices as %s\n",
1191 { 1222 disable ? "BOTTOM" : "VARIABLE");
1192 for (i = 0; i < ipa_get_param_count (info); i++) 1223 }
1193 { 1224
1194 struct ipcp_param_lattices *plats = ipa_get_parm_lattices (info, i); 1225 auto_vec<bool, 16> surviving_params;
1195 if (disable) 1226 bool pre_modified = false;
1196 { 1227 if (!disable && node->clone.param_adjustments)
1197 plats->itself.set_to_bottom (); 1228 {
1198 plats->ctxlat.set_to_bottom (); 1229 /* At the moment all IPA optimizations should use the number of
1199 set_agg_lats_to_bottom (plats); 1230 parameters of the prevailing decl as the m_always_copy_start.
1200 plats->bits_lattice.set_to_bottom (); 1231 Handling any other value would complicate the code below, so for the
1201 plats->m_value_range.set_to_bottom (); 1232 time bing let's only assert it is so. */
1202 } 1233 gcc_assert ((node->clone.param_adjustments->m_always_copy_start
1203 else 1234 == ipa_get_param_count (info))
1204 set_all_contains_variable (plats); 1235 || node->clone.param_adjustments->m_always_copy_start < 0);
1205 } 1236
1237 pre_modified = true;
1238 node->clone.param_adjustments->get_surviving_params (&surviving_params);
1239
1206 if (dump_file && (dump_flags & TDF_DETAILS) 1240 if (dump_file && (dump_flags & TDF_DETAILS)
1207 && !node->alias && !node->thunk.thunk_p) 1241 && !node->alias && !node->thunk.thunk_p)
1208 fprintf (dump_file, "Marking all lattices of %s as %s\n", 1242 {
1209 node->dump_name (), disable ? "BOTTOM" : "VARIABLE"); 1243 bool first = true;
1244 for (int j = 0; j < ipa_get_param_count (info); j++)
1245 {
1246 if (j < (int) surviving_params.length ()
1247 && surviving_params[j])
1248 continue;
1249 if (first)
1250 {
1251 fprintf (dump_file,
1252 " The following parameters are dead on arrival:");
1253 first = false;
1254 }
1255 fprintf (dump_file, " %u", j);
1256 }
1257 if (!first)
1258 fprintf (dump_file, "\n");
1259 }
1260 }
1261
1262 for (i = 0; i < ipa_get_param_count (info); i++)
1263 {
1264 ipcp_param_lattices *plats = ipa_get_parm_lattices (info, i);
1265 if (disable
1266 || (pre_modified && (surviving_params.length () <= (unsigned) i
1267 || !surviving_params[i])))
1268 {
1269 plats->itself.set_to_bottom ();
1270 plats->ctxlat.set_to_bottom ();
1271 set_agg_lats_to_bottom (plats);
1272 plats->bits_lattice.set_to_bottom ();
1273 plats->m_value_range.set_to_bottom ();
1274 }
1275 else
1276 {
1277 plats->m_value_range.init ();
1278 if (variable)
1279 set_all_contains_variable (plats);
1280 }
1210 } 1281 }
1211 1282
1212 for (ie = node->indirect_calls; ie; ie = ie->next_callee) 1283 for (ie = node->indirect_calls; ie; ie = ie->next_callee)
1213 if (ie->indirect_info->polymorphic 1284 if (ie->indirect_info->polymorphic
1214 && ie->indirect_info->param_index >= 0) 1285 && ie->indirect_info->param_index >= 0)
1217 ipa_get_parm_lattices (info, 1288 ipa_get_parm_lattices (info,
1218 ie->indirect_info->param_index)->virt_call = 1; 1289 ie->indirect_info->param_index)->virt_call = 1;
1219 } 1290 }
1220 } 1291 }
1221 1292
1222 /* Return the result of a (possibly arithmetic) pass through jump function 1293 /* Return the result of a (possibly arithmetic) operation on the constant
1223 JFUNC on the constant value INPUT. RES_TYPE is the type of the parameter 1294 value INPUT. OPERAND is 2nd operand for binary operation. RES_TYPE is
1224 to which the result is passed. Return NULL_TREE if that cannot be 1295 the type of the parameter to which the result is passed. Return
1225 determined or be considered an interprocedural invariant. */ 1296 NULL_TREE if that cannot be determined or be considered an
1297 interprocedural invariant. */
1226 1298
1227 static tree 1299 static tree
1228 ipa_get_jf_pass_through_result (struct ipa_jump_func *jfunc, tree input, 1300 ipa_get_jf_arith_result (enum tree_code opcode, tree input, tree operand,
1229 tree res_type) 1301 tree res_type)
1230 { 1302 {
1231 tree res; 1303 tree res;
1232 1304
1233 if (ipa_get_jf_pass_through_operation (jfunc) == NOP_EXPR) 1305 if (opcode == NOP_EXPR)
1234 return input; 1306 return input;
1235 if (!is_gimple_ip_invariant (input)) 1307 if (!is_gimple_ip_invariant (input))
1236 return NULL_TREE; 1308 return NULL_TREE;
1237 1309
1238 tree_code opcode = ipa_get_jf_pass_through_operation (jfunc);
1239 if (!res_type) 1310 if (!res_type)
1240 { 1311 {
1241 if (TREE_CODE_CLASS (opcode) == tcc_comparison) 1312 if (TREE_CODE_CLASS (opcode) == tcc_comparison)
1242 res_type = boolean_type_node; 1313 res_type = boolean_type_node;
1243 else if (expr_type_first_operand_type_p (opcode)) 1314 else if (expr_type_first_operand_type_p (opcode))
1247 } 1318 }
1248 1319
1249 if (TREE_CODE_CLASS (opcode) == tcc_unary) 1320 if (TREE_CODE_CLASS (opcode) == tcc_unary)
1250 res = fold_unary (opcode, res_type, input); 1321 res = fold_unary (opcode, res_type, input);
1251 else 1322 else
1252 res = fold_binary (opcode, res_type, input, 1323 res = fold_binary (opcode, res_type, input, operand);
1253 ipa_get_jf_pass_through_operand (jfunc));
1254 1324
1255 if (res && !is_gimple_ip_invariant (res)) 1325 if (res && !is_gimple_ip_invariant (res))
1256 return NULL_TREE; 1326 return NULL_TREE;
1257 1327
1258 return res; 1328 return res;
1329 }
1330
1331 /* Return the result of a (possibly arithmetic) pass through jump function
1332 JFUNC on the constant value INPUT. RES_TYPE is the type of the parameter
1333 to which the result is passed. Return NULL_TREE if that cannot be
1334 determined or be considered an interprocedural invariant. */
1335
1336 static tree
1337 ipa_get_jf_pass_through_result (struct ipa_jump_func *jfunc, tree input,
1338 tree res_type)
1339 {
1340 return ipa_get_jf_arith_result (ipa_get_jf_pass_through_operation (jfunc),
1341 input,
1342 ipa_get_jf_pass_through_operand (jfunc),
1343 res_type);
1259 } 1344 }
1260 1345
1261 /* Return the result of an ancestor jump function JFUNC on the constant value 1346 /* Return the result of an ancestor jump function JFUNC on the constant value
1262 INPUT. Return NULL_TREE if that cannot be determined. */ 1347 INPUT. Return NULL_TREE if that cannot be determined. */
1263 1348
1282 the one it is inlined to, so that pass-through jump functions can be 1367 the one it is inlined to, so that pass-through jump functions can be
1283 evaluated. PARM_TYPE is the type of the parameter to which the result is 1368 evaluated. PARM_TYPE is the type of the parameter to which the result is
1284 passed. */ 1369 passed. */
1285 1370
1286 tree 1371 tree
1287 ipa_value_from_jfunc (struct ipa_node_params *info, struct ipa_jump_func *jfunc, 1372 ipa_value_from_jfunc (class ipa_node_params *info, struct ipa_jump_func *jfunc,
1288 tree parm_type) 1373 tree parm_type)
1289 { 1374 {
1290 if (jfunc->type == IPA_JF_CONST) 1375 if (jfunc->type == IPA_JF_CONST)
1291 return ipa_get_jf_constant (jfunc); 1376 return ipa_get_jf_constant (jfunc);
1292 else if (jfunc->type == IPA_JF_PASS_THROUGH 1377 else if (jfunc->type == IPA_JF_PASS_THROUGH
1325 } 1410 }
1326 else 1411 else
1327 return NULL_TREE; 1412 return NULL_TREE;
1328 } 1413 }
1329 1414
1330 /* Determie whether JFUNC evaluates to single known polymorphic context, given 1415 /* Determine whether JFUNC evaluates to single known polymorphic context, given
1331 that INFO describes the caller node or the one it is inlined to, CS is the 1416 that INFO describes the caller node or the one it is inlined to, CS is the
1332 call graph edge corresponding to JFUNC and CSIDX index of the described 1417 call graph edge corresponding to JFUNC and CSIDX index of the described
1333 parameter. */ 1418 parameter. */
1334 1419
1335 ipa_polymorphic_call_context 1420 ipa_polymorphic_call_context
1389 } 1474 }
1390 1475
1391 return ctx; 1476 return ctx;
1392 } 1477 }
1393 1478
1479 /* Emulate effects of unary OPERATION and/or conversion from SRC_TYPE to
1480 DST_TYPE on value range in SRC_VR and store it to DST_VR. Return true if
1481 the result is a range or an anti-range. */
1482
1483 static bool
1484 ipa_vr_operation_and_type_effects (value_range *dst_vr,
1485 value_range *src_vr,
1486 enum tree_code operation,
1487 tree dst_type, tree src_type)
1488 {
1489 range_fold_unary_expr (dst_vr, operation, dst_type, src_vr, src_type);
1490 if (dst_vr->varying_p () || dst_vr->undefined_p ())
1491 return false;
1492 return true;
1493 }
1494
1495 /* Determine value_range of JFUNC given that INFO describes the caller node or
1496 the one it is inlined to, CS is the call graph edge corresponding to JFUNC
1497 and PARM_TYPE of the parameter. */
1498
1499 value_range
1500 ipa_value_range_from_jfunc (ipa_node_params *info, cgraph_edge *cs,
1501 ipa_jump_func *jfunc, tree parm_type)
1502 {
1503 value_range vr;
1504 return vr;
1505 if (jfunc->m_vr)
1506 ipa_vr_operation_and_type_effects (&vr,
1507 jfunc->m_vr,
1508 NOP_EXPR, parm_type,
1509 jfunc->m_vr->type ());
1510 if (vr.singleton_p ())
1511 return vr;
1512 if (jfunc->type == IPA_JF_PASS_THROUGH)
1513 {
1514 int idx;
1515 ipcp_transformation *sum
1516 = ipcp_get_transformation_summary (cs->caller->inlined_to
1517 ? cs->caller->inlined_to
1518 : cs->caller);
1519 if (!sum || !sum->m_vr)
1520 return vr;
1521
1522 idx = ipa_get_jf_pass_through_formal_id (jfunc);
1523
1524 if (!(*sum->m_vr)[idx].known)
1525 return vr;
1526 tree vr_type = ipa_get_type (info, idx);
1527 value_range srcvr (wide_int_to_tree (vr_type, (*sum->m_vr)[idx].min),
1528 wide_int_to_tree (vr_type, (*sum->m_vr)[idx].max),
1529 (*sum->m_vr)[idx].type);
1530
1531 enum tree_code operation = ipa_get_jf_pass_through_operation (jfunc);
1532
1533 if (TREE_CODE_CLASS (operation) == tcc_unary)
1534 {
1535 value_range res;
1536
1537 if (ipa_vr_operation_and_type_effects (&res,
1538 &srcvr,
1539 operation, parm_type,
1540 vr_type))
1541 vr.intersect (res);
1542 }
1543 else
1544 {
1545 value_range op_res, res;
1546 tree op = ipa_get_jf_pass_through_operand (jfunc);
1547 value_range op_vr (op, op);
1548
1549 range_fold_binary_expr (&op_res, operation, vr_type, &srcvr, &op_vr);
1550 if (ipa_vr_operation_and_type_effects (&res,
1551 &op_res,
1552 NOP_EXPR, parm_type,
1553 vr_type))
1554 vr.intersect (res);
1555 }
1556 }
1557 return vr;
1558 }
1559
1560 /* See if NODE is a clone with a known aggregate value at a given OFFSET of a
1561 parameter with the given INDEX. */
1562
1563 static tree
1564 get_clone_agg_value (struct cgraph_node *node, HOST_WIDE_INT offset,
1565 int index)
1566 {
1567 struct ipa_agg_replacement_value *aggval;
1568
1569 aggval = ipa_get_agg_replacements_for_node (node);
1570 while (aggval)
1571 {
1572 if (aggval->offset == offset
1573 && aggval->index == index)
1574 return aggval->value;
1575 aggval = aggval->next;
1576 }
1577 return NULL_TREE;
1578 }
1579
1580 /* Determine whether ITEM, jump function for an aggregate part, evaluates to a
1581 single known constant value and if so, return it. Otherwise return NULL.
1582 NODE and INFO describes the caller node or the one it is inlined to, and
1583 its related info. */
1584
1585 static tree
1586 ipa_agg_value_from_node (class ipa_node_params *info,
1587 struct cgraph_node *node,
1588 struct ipa_agg_jf_item *item)
1589 {
1590 tree value = NULL_TREE;
1591 int src_idx;
1592
1593 if (item->offset < 0 || item->jftype == IPA_JF_UNKNOWN)
1594 return NULL_TREE;
1595
1596 if (item->jftype == IPA_JF_CONST)
1597 return item->value.constant;
1598
1599 gcc_checking_assert (item->jftype == IPA_JF_PASS_THROUGH
1600 || item->jftype == IPA_JF_LOAD_AGG);
1601
1602 src_idx = item->value.pass_through.formal_id;
1603
1604 if (info->ipcp_orig_node)
1605 {
1606 if (item->jftype == IPA_JF_PASS_THROUGH)
1607 value = info->known_csts[src_idx];
1608 else
1609 value = get_clone_agg_value (node, item->value.load_agg.offset,
1610 src_idx);
1611 }
1612 else if (info->lattices)
1613 {
1614 class ipcp_param_lattices *src_plats
1615 = ipa_get_parm_lattices (info, src_idx);
1616
1617 if (item->jftype == IPA_JF_PASS_THROUGH)
1618 {
1619 struct ipcp_lattice<tree> *lat = &src_plats->itself;
1620
1621 if (!lat->is_single_const ())
1622 return NULL_TREE;
1623
1624 value = lat->values->value;
1625 }
1626 else if (src_plats->aggs
1627 && !src_plats->aggs_bottom
1628 && !src_plats->aggs_contain_variable
1629 && src_plats->aggs_by_ref == item->value.load_agg.by_ref)
1630 {
1631 struct ipcp_agg_lattice *aglat;
1632
1633 for (aglat = src_plats->aggs; aglat; aglat = aglat->next)
1634 {
1635 if (aglat->offset > item->value.load_agg.offset)
1636 break;
1637
1638 if (aglat->offset == item->value.load_agg.offset)
1639 {
1640 if (aglat->is_single_const ())
1641 value = aglat->values->value;
1642 break;
1643 }
1644 }
1645 }
1646 }
1647
1648 if (!value)
1649 return NULL_TREE;
1650
1651 if (item->jftype == IPA_JF_LOAD_AGG)
1652 {
1653 tree load_type = item->value.load_agg.type;
1654 tree value_type = TREE_TYPE (value);
1655
1656 /* Ensure value type is compatible with load type. */
1657 if (!useless_type_conversion_p (load_type, value_type))
1658 return NULL_TREE;
1659 }
1660
1661 return ipa_get_jf_arith_result (item->value.pass_through.operation,
1662 value,
1663 item->value.pass_through.operand,
1664 item->type);
1665 }
1666
1667 /* Determine whether AGG_JFUNC evaluates to a set of known constant value for
1668 an aggregate and if so, return it. Otherwise return an empty set. NODE
1669 and INFO describes the caller node or the one it is inlined to, and its
1670 related info. */
1671
1672 struct ipa_agg_value_set
1673 ipa_agg_value_set_from_jfunc (class ipa_node_params *info, cgraph_node *node,
1674 struct ipa_agg_jump_function *agg_jfunc)
1675 {
1676 struct ipa_agg_value_set agg;
1677 struct ipa_agg_jf_item *item;
1678 int i;
1679
1680 agg.items = vNULL;
1681 agg.by_ref = agg_jfunc->by_ref;
1682
1683 FOR_EACH_VEC_SAFE_ELT (agg_jfunc->items, i, item)
1684 {
1685 tree value = ipa_agg_value_from_node (info, node, item);
1686
1687 if (value)
1688 {
1689 struct ipa_agg_value value_item;
1690
1691 value_item.offset = item->offset;
1692 value_item.value = value;
1693
1694 agg.items.safe_push (value_item);
1695 }
1696 }
1697 return agg;
1698 }
1699
1394 /* If checking is enabled, verify that no lattice is in the TOP state, i.e. not 1700 /* If checking is enabled, verify that no lattice is in the TOP state, i.e. not
1395 bottom, not containing a variable component and without any known value at 1701 bottom, not containing a variable component and without any known value at
1396 the same time. */ 1702 the same time. */
1397 1703
1398 DEBUG_FUNCTION void 1704 DEBUG_FUNCTION void
1400 { 1706 {
1401 struct cgraph_node *node; 1707 struct cgraph_node *node;
1402 1708
1403 FOR_EACH_FUNCTION_WITH_GIMPLE_BODY (node) 1709 FOR_EACH_FUNCTION_WITH_GIMPLE_BODY (node)
1404 { 1710 {
1405 struct ipa_node_params *info = IPA_NODE_REF (node); 1711 class ipa_node_params *info = IPA_NODE_REF (node);
1712 if (!opt_for_fn (node->decl, flag_ipa_cp)
1713 || !opt_for_fn (node->decl, optimize))
1714 continue;
1406 int i, count = ipa_get_param_count (info); 1715 int i, count = ipa_get_param_count (info);
1407 1716
1408 for (i = 0; i < count; i++) 1717 for (i = 0; i < count; i++)
1409 { 1718 {
1410 ipcp_lattice<tree> *lat = ipa_get_scalar_lat (info, i); 1719 ipcp_lattice<tree> *lat = ipa_get_scalar_lat (info, i);
1509 } 1818 }
1510 1819
1511 /* Try to add NEWVAL to LAT, potentially creating a new ipcp_value for it. CS, 1820 /* Try to add NEWVAL to LAT, potentially creating a new ipcp_value for it. CS,
1512 SRC_VAL SRC_INDEX and OFFSET are meant for add_source and have the same 1821 SRC_VAL SRC_INDEX and OFFSET are meant for add_source and have the same
1513 meaning. OFFSET -1 means the source is scalar and not a part of an 1822 meaning. OFFSET -1 means the source is scalar and not a part of an
1514 aggregate. */ 1823 aggregate. If non-NULL, VAL_P records address of existing or newly added
1824 ipcp_value. UNLIMITED means whether value count should not exceed the limit
1825 given by PARAM_IPA_CP_VALUE_LIST_SIZE. */
1515 1826
1516 template <typename valtype> 1827 template <typename valtype>
1517 bool 1828 bool
1518 ipcp_lattice<valtype>::add_value (valtype newval, cgraph_edge *cs, 1829 ipcp_lattice<valtype>::add_value (valtype newval, cgraph_edge *cs,
1519 ipcp_value<valtype> *src_val, 1830 ipcp_value<valtype> *src_val,
1520 int src_idx, HOST_WIDE_INT offset) 1831 int src_idx, HOST_WIDE_INT offset,
1521 { 1832 ipcp_value<valtype> **val_p,
1522 ipcp_value<valtype> *val; 1833 bool unlimited)
1834 {
1835 ipcp_value<valtype> *val, *last_val = NULL;
1836
1837 if (val_p)
1838 *val_p = NULL;
1523 1839
1524 if (bottom) 1840 if (bottom)
1525 return false; 1841 return false;
1526 1842
1527 for (val = values; val; val = val->next) 1843 for (val = values; val; last_val = val, val = val->next)
1528 if (values_equal_for_ipcp_p (val->value, newval)) 1844 if (values_equal_for_ipcp_p (val->value, newval))
1529 { 1845 {
1846 if (val_p)
1847 *val_p = val;
1848
1530 if (ipa_edge_within_scc (cs)) 1849 if (ipa_edge_within_scc (cs))
1531 { 1850 {
1532 ipcp_value_source<valtype> *s; 1851 ipcp_value_source<valtype> *s;
1533 for (s = val->sources; s; s = s->next) 1852 for (s = val->sources; s; s = s->next)
1534 if (s->cs == cs) 1853 if (s->cs == cs && s->val == src_val)
1535 break; 1854 break;
1536 if (s) 1855 if (s)
1537 return false; 1856 return false;
1538 } 1857 }
1539 1858
1540 val->add_source (cs, src_val, src_idx, offset); 1859 val->add_source (cs, src_val, src_idx, offset);
1541 return false; 1860 return false;
1542 } 1861 }
1543 1862
1544 if (values_count == PARAM_VALUE (PARAM_IPA_CP_VALUE_LIST_SIZE)) 1863 if (!unlimited && values_count == opt_for_fn (cs->caller->decl,
1864 param_ipa_cp_value_list_size))
1545 { 1865 {
1546 /* We can only free sources, not the values themselves, because sources 1866 /* We can only free sources, not the values themselves, because sources
1547 of other values in this SCC might point to them. */ 1867 of other values in this SCC might point to them. */
1548 for (val = values; val; val = val->next) 1868 for (val = values; val; val = val->next)
1549 { 1869 {
1552 ipcp_value_source<valtype> *src = val->sources; 1872 ipcp_value_source<valtype> *src = val->sources;
1553 val->sources = src->next; 1873 val->sources = src->next;
1554 ipcp_sources_pool.remove ((ipcp_value_source<tree>*)src); 1874 ipcp_sources_pool.remove ((ipcp_value_source<tree>*)src);
1555 } 1875 }
1556 } 1876 }
1557
1558 values = NULL; 1877 values = NULL;
1559 return set_to_bottom (); 1878 return set_to_bottom ();
1560 } 1879 }
1561 1880
1562 values_count++; 1881 values_count++;
1563 val = allocate_and_init_ipcp_value (newval); 1882 val = allocate_and_init_ipcp_value (newval);
1564 val->add_source (cs, src_val, src_idx, offset); 1883 val->add_source (cs, src_val, src_idx, offset);
1565 val->next = values; 1884 val->next = NULL;
1566 values = val; 1885
1886 /* Add the new value to end of value list, which can reduce iterations
1887 of propagation stage for recursive function. */
1888 if (last_val)
1889 last_val->next = val;
1890 else
1891 values = val;
1892
1893 if (val_p)
1894 *val_p = val;
1895
1567 return true; 1896 return true;
1897 }
1898
1899 /* Return true, if a ipcp_value VAL is orginated from parameter value of
1900 self-feeding recursive function by applying non-passthrough arithmetic
1901 transformation. */
1902
1903 static bool
1904 self_recursively_generated_p (ipcp_value<tree> *val)
1905 {
1906 class ipa_node_params *info = NULL;
1907
1908 for (ipcp_value_source<tree> *src = val->sources; src; src = src->next)
1909 {
1910 cgraph_edge *cs = src->cs;
1911
1912 if (!src->val || cs->caller != cs->callee->function_symbol ()
1913 || src->val == val)
1914 return false;
1915
1916 if (!info)
1917 info = IPA_NODE_REF (cs->caller);
1918
1919 class ipcp_param_lattices *plats = ipa_get_parm_lattices (info,
1920 src->index);
1921 ipcp_lattice<tree> *src_lat;
1922 ipcp_value<tree> *src_val;
1923
1924 if (src->offset == -1)
1925 src_lat = &plats->itself;
1926 else
1927 {
1928 struct ipcp_agg_lattice *src_aglat;
1929
1930 for (src_aglat = plats->aggs; src_aglat; src_aglat = src_aglat->next)
1931 if (src_aglat->offset == src->offset)
1932 break;
1933
1934 if (!src_aglat)
1935 return false;
1936
1937 src_lat = src_aglat;
1938 }
1939
1940 for (src_val = src_lat->values; src_val; src_val = src_val->next)
1941 if (src_val == val)
1942 break;
1943
1944 if (!src_val)
1945 return false;
1946 }
1947
1948 return true;
1949 }
1950
1951 /* A helper function that returns result of operation specified by OPCODE on
1952 the value of SRC_VAL. If non-NULL, OPND1_TYPE is expected type for the
1953 value of SRC_VAL. If the operation is binary, OPND2 is a constant value
1954 acting as its second operand. If non-NULL, RES_TYPE is expected type of
1955 the result. */
1956
1957 static tree
1958 get_val_across_arith_op (enum tree_code opcode,
1959 tree opnd1_type,
1960 tree opnd2,
1961 ipcp_value<tree> *src_val,
1962 tree res_type)
1963 {
1964 tree opnd1 = src_val->value;
1965
1966 /* Skip source values that is incompatible with specified type. */
1967 if (opnd1_type
1968 && !useless_type_conversion_p (opnd1_type, TREE_TYPE (opnd1)))
1969 return NULL_TREE;
1970
1971 return ipa_get_jf_arith_result (opcode, opnd1, opnd2, res_type);
1972 }
1973
1974 /* Propagate values through an arithmetic transformation described by a jump
1975 function associated with edge CS, taking values from SRC_LAT and putting
1976 them into DEST_LAT. OPND1_TYPE is expected type for the values in SRC_LAT.
1977 OPND2 is a constant value if transformation is a binary operation.
1978 SRC_OFFSET specifies offset in an aggregate if SRC_LAT describes lattice of
1979 a part of the aggregate. SRC_IDX is the index of the source parameter.
1980 RES_TYPE is the value type of result being propagated into. Return true if
1981 DEST_LAT changed. */
1982
1983 static bool
1984 propagate_vals_across_arith_jfunc (cgraph_edge *cs,
1985 enum tree_code opcode,
1986 tree opnd1_type,
1987 tree opnd2,
1988 ipcp_lattice<tree> *src_lat,
1989 ipcp_lattice<tree> *dest_lat,
1990 HOST_WIDE_INT src_offset,
1991 int src_idx,
1992 tree res_type)
1993 {
1994 ipcp_value<tree> *src_val;
1995 bool ret = false;
1996
1997 /* Due to circular dependencies, propagating within an SCC through arithmetic
1998 transformation would create infinite number of values. But for
1999 self-feeding recursive function, we could allow propagation in a limited
2000 count, and this can enable a simple kind of recursive function versioning.
2001 For other scenario, we would just make lattices bottom. */
2002 if (opcode != NOP_EXPR && ipa_edge_within_scc (cs))
2003 {
2004 int i;
2005
2006 int max_recursive_depth = opt_for_fn(cs->caller->decl,
2007 param_ipa_cp_max_recursive_depth);
2008 if (src_lat != dest_lat || max_recursive_depth < 1)
2009 return dest_lat->set_contains_variable ();
2010
2011 /* No benefit if recursive execution is in low probability. */
2012 if (cs->sreal_frequency () * 100
2013 <= ((sreal) 1) * opt_for_fn (cs->caller->decl,
2014 param_ipa_cp_min_recursive_probability))
2015 return dest_lat->set_contains_variable ();
2016
2017 auto_vec<ipcp_value<tree> *, 8> val_seeds;
2018
2019 for (src_val = src_lat->values; src_val; src_val = src_val->next)
2020 {
2021 /* Now we do not use self-recursively generated value as propagation
2022 source, this is absolutely conservative, but could avoid explosion
2023 of lattice's value space, especially when one recursive function
2024 calls another recursive. */
2025 if (self_recursively_generated_p (src_val))
2026 {
2027 ipcp_value_source<tree> *s;
2028
2029 /* If the lattice has already been propagated for the call site,
2030 no need to do that again. */
2031 for (s = src_val->sources; s; s = s->next)
2032 if (s->cs == cs)
2033 return dest_lat->set_contains_variable ();
2034 }
2035 else
2036 val_seeds.safe_push (src_val);
2037 }
2038
2039 gcc_assert ((int) val_seeds.length () <= param_ipa_cp_value_list_size);
2040
2041 /* Recursively generate lattice values with a limited count. */
2042 FOR_EACH_VEC_ELT (val_seeds, i, src_val)
2043 {
2044 for (int j = 1; j < max_recursive_depth; j++)
2045 {
2046 tree cstval = get_val_across_arith_op (opcode, opnd1_type, opnd2,
2047 src_val, res_type);
2048 if (!cstval)
2049 break;
2050
2051 ret |= dest_lat->add_value (cstval, cs, src_val, src_idx,
2052 src_offset, &src_val, true);
2053 gcc_checking_assert (src_val);
2054 }
2055 }
2056 ret |= dest_lat->set_contains_variable ();
2057 }
2058 else
2059 for (src_val = src_lat->values; src_val; src_val = src_val->next)
2060 {
2061 /* Now we do not use self-recursively generated value as propagation
2062 source, otherwise it is easy to make value space of normal lattice
2063 overflow. */
2064 if (self_recursively_generated_p (src_val))
2065 {
2066 ret |= dest_lat->set_contains_variable ();
2067 continue;
2068 }
2069
2070 tree cstval = get_val_across_arith_op (opcode, opnd1_type, opnd2,
2071 src_val, res_type);
2072 if (cstval)
2073 ret |= dest_lat->add_value (cstval, cs, src_val, src_idx,
2074 src_offset);
2075 else
2076 ret |= dest_lat->set_contains_variable ();
2077 }
2078
2079 return ret;
1568 } 2080 }
1569 2081
1570 /* Propagate values through a pass-through jump function JFUNC associated with 2082 /* Propagate values through a pass-through jump function JFUNC associated with
1571 edge CS, taking values from SRC_LAT and putting them into DEST_LAT. SRC_IDX 2083 edge CS, taking values from SRC_LAT and putting them into DEST_LAT. SRC_IDX
1572 is the index of the source parameter. PARM_TYPE is the type of the 2084 is the index of the source parameter. PARM_TYPE is the type of the
1576 propagate_vals_across_pass_through (cgraph_edge *cs, ipa_jump_func *jfunc, 2088 propagate_vals_across_pass_through (cgraph_edge *cs, ipa_jump_func *jfunc,
1577 ipcp_lattice<tree> *src_lat, 2089 ipcp_lattice<tree> *src_lat,
1578 ipcp_lattice<tree> *dest_lat, int src_idx, 2090 ipcp_lattice<tree> *dest_lat, int src_idx,
1579 tree parm_type) 2091 tree parm_type)
1580 { 2092 {
1581 ipcp_value<tree> *src_val; 2093 return propagate_vals_across_arith_jfunc (cs,
1582 bool ret = false; 2094 ipa_get_jf_pass_through_operation (jfunc),
1583 2095 NULL_TREE,
1584 /* Do not create new values when propagating within an SCC because if there 2096 ipa_get_jf_pass_through_operand (jfunc),
1585 are arithmetic functions with circular dependencies, there is infinite 2097 src_lat, dest_lat, -1, src_idx, parm_type);
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. */
1589 if ((ipa_get_jf_pass_through_operation (jfunc) != NOP_EXPR)
1590 && ipa_edge_within_scc (cs))
1591 ret = dest_lat->set_contains_variable ();
1592 else
1593 for (src_val = src_lat->values; src_val; src_val = src_val->next)
1594 {
1595 tree cstval = ipa_get_jf_pass_through_result (jfunc, src_val->value,
1596 parm_type);
1597
1598 if (cstval)
1599 ret |= dest_lat->add_value (cstval, cs, src_val, src_idx);
1600 else
1601 ret |= dest_lat->set_contains_variable ();
1602 }
1603
1604 return ret;
1605 } 2098 }
1606 2099
1607 /* Propagate values through an ancestor jump function JFUNC associated with 2100 /* Propagate values through an ancestor jump function JFUNC associated with
1608 edge CS, taking values from SRC_LAT and putting them into DEST_LAT. SRC_IDX 2101 edge CS, taking values from SRC_LAT and putting them into DEST_LAT. SRC_IDX
1609 is the index of the source parameter. */ 2102 is the index of the source parameter. */
1652 return dest_lat->add_value (val, cs, NULL, 0); 2145 return dest_lat->add_value (val, cs, NULL, 0);
1653 } 2146 }
1654 else if (jfunc->type == IPA_JF_PASS_THROUGH 2147 else if (jfunc->type == IPA_JF_PASS_THROUGH
1655 || jfunc->type == IPA_JF_ANCESTOR) 2148 || jfunc->type == IPA_JF_ANCESTOR)
1656 { 2149 {
1657 struct ipa_node_params *caller_info = IPA_NODE_REF (cs->caller); 2150 class ipa_node_params *caller_info = IPA_NODE_REF (cs->caller);
1658 ipcp_lattice<tree> *src_lat; 2151 ipcp_lattice<tree> *src_lat;
1659 int src_idx; 2152 int src_idx;
1660 bool ret; 2153 bool ret;
1661 2154
1662 if (jfunc->type == IPA_JF_PASS_THROUGH) 2155 if (jfunc->type == IPA_JF_PASS_THROUGH)
1714 edge_ctx = *edge_ctx_ptr; 2207 edge_ctx = *edge_ctx_ptr;
1715 2208
1716 if (jfunc->type == IPA_JF_PASS_THROUGH 2209 if (jfunc->type == IPA_JF_PASS_THROUGH
1717 || jfunc->type == IPA_JF_ANCESTOR) 2210 || jfunc->type == IPA_JF_ANCESTOR)
1718 { 2211 {
1719 struct ipa_node_params *caller_info = IPA_NODE_REF (cs->caller); 2212 class ipa_node_params *caller_info = IPA_NODE_REF (cs->caller);
1720 int src_idx; 2213 int src_idx;
1721 ipcp_lattice<ipa_polymorphic_call_context> *src_lat; 2214 ipcp_lattice<ipa_polymorphic_call_context> *src_lat;
1722 2215
1723 /* TODO: Once we figure out how to propagate speculations, it will 2216 /* TODO: Once we figure out how to propagate speculations, it will
1724 probably be a good idea to switch to speculation if type_preserved is 2217 probably be a good idea to switch to speculation if type_preserved is
1762 ret |= dest_lat->set_contains_variable (); 2255 ret |= dest_lat->set_contains_variable ();
1763 ret |= dest_lat->add_value (cur, cs, src_val, src_idx); 2256 ret |= dest_lat->add_value (cur, cs, src_val, src_idx);
1764 added_sth = true; 2257 added_sth = true;
1765 } 2258 }
1766 } 2259 }
1767
1768 } 2260 }
1769 2261
1770 prop_fail: 2262 prop_fail:
1771 if (!added_sth) 2263 if (!added_sth)
1772 { 2264 {
1790 if (dest_lattice->bottom_p ()) 2282 if (dest_lattice->bottom_p ())
1791 return false; 2283 return false;
1792 2284
1793 enum availability availability; 2285 enum availability availability;
1794 cgraph_node *callee = cs->callee->function_symbol (&availability); 2286 cgraph_node *callee = cs->callee->function_symbol (&availability);
1795 struct ipa_node_params *callee_info = IPA_NODE_REF (callee); 2287 class ipa_node_params *callee_info = IPA_NODE_REF (callee);
1796 tree parm_type = ipa_get_type (callee_info, idx); 2288 tree parm_type = ipa_get_type (callee_info, idx);
1797 2289
1798 /* For K&R C programs, ipa_get_type() could return NULL_TREE. Avoid the 2290 /* For K&R C programs, ipa_get_type() could return NULL_TREE. Avoid the
1799 transform for these cases. Similarly, we can have bad type mismatches 2291 transform for these cases. Similarly, we can have bad type mismatches
1800 with LTO, avoid doing anything with those too. */ 2292 with LTO, avoid doing anything with those too. */
1802 || (!INTEGRAL_TYPE_P (parm_type) && !POINTER_TYPE_P (parm_type))) 2294 || (!INTEGRAL_TYPE_P (parm_type) && !POINTER_TYPE_P (parm_type)))
1803 { 2295 {
1804 if (dump_file && (dump_flags & TDF_DETAILS)) 2296 if (dump_file && (dump_flags & TDF_DETAILS))
1805 fprintf (dump_file, "Setting dest_lattice to bottom, because type of " 2297 fprintf (dump_file, "Setting dest_lattice to bottom, because type of "
1806 "param %i of %s is NULL or unsuitable for bits propagation\n", 2298 "param %i of %s is NULL or unsuitable for bits propagation\n",
1807 idx, cs->callee->name ()); 2299 idx, cs->callee->dump_name ());
1808 2300
1809 return dest_lattice->set_to_bottom (); 2301 return dest_lattice->set_to_bottom ();
1810 } 2302 }
1811 2303
1812 unsigned precision = TYPE_PRECISION (parm_type); 2304 unsigned precision = TYPE_PRECISION (parm_type);
1813 signop sgn = TYPE_SIGN (parm_type); 2305 signop sgn = TYPE_SIGN (parm_type);
1814 2306
1815 if (jfunc->type == IPA_JF_PASS_THROUGH 2307 if (jfunc->type == IPA_JF_PASS_THROUGH
1816 || jfunc->type == IPA_JF_ANCESTOR) 2308 || jfunc->type == IPA_JF_ANCESTOR)
1817 { 2309 {
1818 struct ipa_node_params *caller_info = IPA_NODE_REF (cs->caller); 2310 class ipa_node_params *caller_info = IPA_NODE_REF (cs->caller);
1819 tree operand = NULL_TREE; 2311 tree operand = NULL_TREE;
1820 enum tree_code code; 2312 enum tree_code code;
1821 unsigned src_idx; 2313 unsigned src_idx;
1822 2314
1823 if (jfunc->type == IPA_JF_PASS_THROUGH) 2315 if (jfunc->type == IPA_JF_PASS_THROUGH)
1833 src_idx = ipa_get_jf_ancestor_formal_id (jfunc); 2325 src_idx = ipa_get_jf_ancestor_formal_id (jfunc);
1834 unsigned HOST_WIDE_INT offset = ipa_get_jf_ancestor_offset (jfunc) / BITS_PER_UNIT; 2326 unsigned HOST_WIDE_INT offset = ipa_get_jf_ancestor_offset (jfunc) / BITS_PER_UNIT;
1835 operand = build_int_cstu (size_type_node, offset); 2327 operand = build_int_cstu (size_type_node, offset);
1836 } 2328 }
1837 2329
1838 struct ipcp_param_lattices *src_lats 2330 class ipcp_param_lattices *src_lats
1839 = ipa_get_parm_lattices (caller_info, src_idx); 2331 = ipa_get_parm_lattices (caller_info, src_idx);
1840 2332
1841 /* Try to propagate bits if src_lattice is bottom, but jfunc is known. 2333 /* Try to propagate bits if src_lattice is bottom, but jfunc is known.
1842 for eg consider: 2334 for eg consider:
1843 int f(int x) 2335 int f(int x)
1864 precision); 2356 precision);
1865 else 2357 else
1866 return dest_lattice->set_to_bottom (); 2358 return dest_lattice->set_to_bottom ();
1867 } 2359 }
1868 2360
1869 /* Emulate effects of unary OPERATION and/or conversion from SRC_TYPE to
1870 DST_TYPE on value range in SRC_VR and store it to DST_VR. Return true if
1871 the result is a range or an anti-range. */
1872
1873 static bool
1874 ipa_vr_operation_and_type_effects (value_range *dst_vr, value_range *src_vr,
1875 enum tree_code operation,
1876 tree dst_type, tree src_type)
1877 {
1878 *dst_vr = value_range ();
1879 extract_range_from_unary_expr (dst_vr, operation, dst_type, src_vr, src_type);
1880 if (dst_vr->varying_p () || dst_vr->undefined_p ())
1881 return false;
1882 return true;
1883 }
1884
1885 /* Propagate value range across jump function JFUNC that is associated with 2361 /* Propagate value range across jump function JFUNC that is associated with
1886 edge CS with param of callee of PARAM_TYPE and update DEST_PLATS 2362 edge CS with param of callee of PARAM_TYPE and update DEST_PLATS
1887 accordingly. */ 2363 accordingly. */
1888 2364
1889 static bool 2365 static bool
1890 propagate_vr_across_jump_function (cgraph_edge *cs, ipa_jump_func *jfunc, 2366 propagate_vr_across_jump_function (cgraph_edge *cs, ipa_jump_func *jfunc,
1891 struct ipcp_param_lattices *dest_plats, 2367 class ipcp_param_lattices *dest_plats,
1892 tree param_type) 2368 tree param_type)
1893 { 2369 {
1894 ipcp_vr_lattice *dest_lat = &dest_plats->m_value_range; 2370 ipcp_vr_lattice *dest_lat = &dest_plats->m_value_range;
1895 2371
1896 if (dest_lat->bottom_p ()) 2372 if (dest_lat->bottom_p ())
1902 return dest_lat->set_to_bottom (); 2378 return dest_lat->set_to_bottom ();
1903 2379
1904 if (jfunc->type == IPA_JF_PASS_THROUGH) 2380 if (jfunc->type == IPA_JF_PASS_THROUGH)
1905 { 2381 {
1906 enum tree_code operation = ipa_get_jf_pass_through_operation (jfunc); 2382 enum tree_code operation = ipa_get_jf_pass_through_operation (jfunc);
1907 2383 class ipa_node_params *caller_info = IPA_NODE_REF (cs->caller);
2384 int src_idx = ipa_get_jf_pass_through_formal_id (jfunc);
2385 class ipcp_param_lattices *src_lats
2386 = ipa_get_parm_lattices (caller_info, src_idx);
2387 tree operand_type = ipa_get_type (caller_info, src_idx);
2388
2389 if (src_lats->m_value_range.bottom_p ())
2390 return dest_lat->set_to_bottom ();
2391
2392 value_range vr;
1908 if (TREE_CODE_CLASS (operation) == tcc_unary) 2393 if (TREE_CODE_CLASS (operation) == tcc_unary)
1909 { 2394 ipa_vr_operation_and_type_effects (&vr,
1910 struct ipa_node_params *caller_info = IPA_NODE_REF (cs->caller); 2395 &src_lats->m_value_range.m_vr,
1911 int src_idx = ipa_get_jf_pass_through_formal_id (jfunc); 2396 operation, param_type,
1912 tree operand_type = ipa_get_type (caller_info, src_idx); 2397 operand_type);
1913 struct ipcp_param_lattices *src_lats 2398 /* A crude way to prevent unbounded number of value range updates
1914 = ipa_get_parm_lattices (caller_info, src_idx); 2399 in SCC components. We should allow limited number of updates within
1915 2400 SCC, too. */
1916 if (src_lats->m_value_range.bottom_p ()) 2401 else if (!ipa_edge_within_scc (cs))
1917 return dest_lat->set_to_bottom (); 2402 {
1918 value_range vr; 2403 tree op = ipa_get_jf_pass_through_operand (jfunc);
1919 if (ipa_vr_operation_and_type_effects (&vr, 2404 value_range op_vr (op, op);
1920 &src_lats->m_value_range.m_vr, 2405 value_range op_res,res;
1921 operation, param_type, 2406
1922 operand_type)) 2407 range_fold_binary_expr (&op_res, operation, operand_type,
1923 return dest_lat->meet_with (&vr); 2408 &src_lats->m_value_range.m_vr, &op_vr);
2409 ipa_vr_operation_and_type_effects (&vr,
2410 &op_res,
2411 NOP_EXPR, param_type,
2412 operand_type);
2413 }
2414 if (!vr.undefined_p () && !vr.varying_p ())
2415 {
2416 if (jfunc->m_vr)
2417 {
2418 value_range jvr;
2419 if (ipa_vr_operation_and_type_effects (&jvr, jfunc->m_vr,
2420 NOP_EXPR,
2421 param_type,
2422 jfunc->m_vr->type ()))
2423 vr.intersect (jvr);
2424 }
2425 return dest_lat->meet_with (&vr);
1924 } 2426 }
1925 } 2427 }
1926 else if (jfunc->type == IPA_JF_CONST) 2428 else if (jfunc->type == IPA_JF_CONST)
1927 { 2429 {
1928 tree val = ipa_get_jf_constant (jfunc); 2430 tree val = ipa_get_jf_constant (jfunc);
1930 { 2432 {
1931 val = fold_convert (param_type, val); 2433 val = fold_convert (param_type, val);
1932 if (TREE_OVERFLOW_P (val)) 2434 if (TREE_OVERFLOW_P (val))
1933 val = drop_tree_overflow (val); 2435 val = drop_tree_overflow (val);
1934 2436
1935 value_range tmpvr (VR_RANGE, val, val); 2437 value_range tmpvr (val, val);
1936 return dest_lat->meet_with (&tmpvr); 2438 return dest_lat->meet_with (&tmpvr);
1937 } 2439 }
1938 } 2440 }
1939 2441
1940 value_range vr; 2442 value_range vr;
1951 NEW_AGGS_BY_REF and if not, mark all aggs as bottoms and return true (in all 2453 NEW_AGGS_BY_REF and if not, mark all aggs as bottoms and return true (in all
1952 other cases, return false). If there are no aggregate items, set 2454 other cases, return false). If there are no aggregate items, set
1953 aggs_by_ref to NEW_AGGS_BY_REF. */ 2455 aggs_by_ref to NEW_AGGS_BY_REF. */
1954 2456
1955 static bool 2457 static bool
1956 set_check_aggs_by_ref (struct ipcp_param_lattices *dest_plats, 2458 set_check_aggs_by_ref (class ipcp_param_lattices *dest_plats,
1957 bool new_aggs_by_ref) 2459 bool new_aggs_by_ref)
1958 { 2460 {
1959 if (dest_plats->aggs) 2461 if (dest_plats->aggs)
1960 { 2462 {
1961 if (dest_plats->aggs_by_ref != new_aggs_by_ref) 2463 if (dest_plats->aggs_by_ref != new_aggs_by_ref)
1975 already existing lattice for the OFFSET and VAL_SIZE, create one, initialize 2477 already existing lattice for the OFFSET and VAL_SIZE, create one, initialize
1976 it with offset, size and contains_variable to PRE_EXISTING, and return true, 2478 it with offset, size and contains_variable to PRE_EXISTING, and return true,
1977 unless there are too many already. If there are two many, return false. If 2479 unless there are too many already. If there are two many, return false. If
1978 there are overlaps turn whole DEST_PLATS to bottom and return false. If any 2480 there are overlaps turn whole DEST_PLATS to bottom and return false. If any
1979 skipped lattices were newly marked as containing variable, set *CHANGE to 2481 skipped lattices were newly marked as containing variable, set *CHANGE to
1980 true. */ 2482 true. MAX_AGG_ITEMS is the maximum number of lattices. */
1981 2483
1982 static bool 2484 static bool
1983 merge_agg_lats_step (struct ipcp_param_lattices *dest_plats, 2485 merge_agg_lats_step (class ipcp_param_lattices *dest_plats,
1984 HOST_WIDE_INT offset, HOST_WIDE_INT val_size, 2486 HOST_WIDE_INT offset, HOST_WIDE_INT val_size,
1985 struct ipcp_agg_lattice ***aglat, 2487 struct ipcp_agg_lattice ***aglat,
1986 bool pre_existing, bool *change) 2488 bool pre_existing, bool *change, int max_agg_items)
1987 { 2489 {
1988 gcc_checking_assert (offset >= 0); 2490 gcc_checking_assert (offset >= 0);
1989 2491
1990 while (**aglat && (**aglat)->offset < offset) 2492 while (**aglat && (**aglat)->offset < offset)
1991 { 2493 {
1998 *aglat = &(**aglat)->next; 2500 *aglat = &(**aglat)->next;
1999 } 2501 }
2000 2502
2001 if (**aglat && (**aglat)->offset == offset) 2503 if (**aglat && (**aglat)->offset == offset)
2002 { 2504 {
2003 if ((**aglat)->size != val_size 2505 if ((**aglat)->size != val_size)
2004 || ((**aglat)->next
2005 && (**aglat)->next->offset < offset + val_size))
2006 { 2506 {
2007 set_agg_lats_to_bottom (dest_plats); 2507 set_agg_lats_to_bottom (dest_plats);
2008 return false; 2508 return false;
2009 } 2509 }
2010 gcc_checking_assert (!(**aglat)->next 2510 gcc_assert (!(**aglat)->next
2011 || (**aglat)->next->offset >= offset + val_size); 2511 || (**aglat)->next->offset >= offset + val_size);
2012 return true; 2512 return true;
2013 } 2513 }
2014 else 2514 else
2015 { 2515 {
2016 struct ipcp_agg_lattice *new_al; 2516 struct ipcp_agg_lattice *new_al;
2018 if (**aglat && (**aglat)->offset < offset + val_size) 2518 if (**aglat && (**aglat)->offset < offset + val_size)
2019 { 2519 {
2020 set_agg_lats_to_bottom (dest_plats); 2520 set_agg_lats_to_bottom (dest_plats);
2021 return false; 2521 return false;
2022 } 2522 }
2023 if (dest_plats->aggs_count == PARAM_VALUE (PARAM_IPA_MAX_AGG_ITEMS)) 2523 if (dest_plats->aggs_count == max_agg_items)
2024 return false; 2524 return false;
2025 dest_plats->aggs_count++; 2525 dest_plats->aggs_count++;
2026 new_al = ipcp_agg_lattice_pool.allocate (); 2526 new_al = ipcp_agg_lattice_pool.allocate ();
2027 memset (new_al, 0, sizeof (*new_al)); 2527 memset (new_al, 0, sizeof (*new_al));
2028 2528
2056 parameter used for lattice value sources. Return true if DEST_PLATS changed 2556 parameter used for lattice value sources. Return true if DEST_PLATS changed
2057 in any way. */ 2557 in any way. */
2058 2558
2059 static bool 2559 static bool
2060 merge_aggregate_lattices (struct cgraph_edge *cs, 2560 merge_aggregate_lattices (struct cgraph_edge *cs,
2061 struct ipcp_param_lattices *dest_plats, 2561 class ipcp_param_lattices *dest_plats,
2062 struct ipcp_param_lattices *src_plats, 2562 class ipcp_param_lattices *src_plats,
2063 int src_idx, HOST_WIDE_INT offset_delta) 2563 int src_idx, HOST_WIDE_INT offset_delta)
2064 { 2564 {
2065 bool pre_existing = dest_plats->aggs != NULL; 2565 bool pre_existing = dest_plats->aggs != NULL;
2066 struct ipcp_agg_lattice **dst_aglat; 2566 struct ipcp_agg_lattice **dst_aglat;
2067 bool ret = false; 2567 bool ret = false;
2072 return set_agg_lats_contain_variable (dest_plats); 2572 return set_agg_lats_contain_variable (dest_plats);
2073 if (src_plats->aggs_contain_variable) 2573 if (src_plats->aggs_contain_variable)
2074 ret |= set_agg_lats_contain_variable (dest_plats); 2574 ret |= set_agg_lats_contain_variable (dest_plats);
2075 dst_aglat = &dest_plats->aggs; 2575 dst_aglat = &dest_plats->aggs;
2076 2576
2577 int max_agg_items = opt_for_fn (cs->callee->function_symbol ()->decl,
2578 param_ipa_max_agg_items);
2077 for (struct ipcp_agg_lattice *src_aglat = src_plats->aggs; 2579 for (struct ipcp_agg_lattice *src_aglat = src_plats->aggs;
2078 src_aglat; 2580 src_aglat;
2079 src_aglat = src_aglat->next) 2581 src_aglat = src_aglat->next)
2080 { 2582 {
2081 HOST_WIDE_INT new_offset = src_aglat->offset - offset_delta; 2583 HOST_WIDE_INT new_offset = src_aglat->offset - offset_delta;
2082 2584
2083 if (new_offset < 0) 2585 if (new_offset < 0)
2084 continue; 2586 continue;
2085 if (merge_agg_lats_step (dest_plats, new_offset, src_aglat->size, 2587 if (merge_agg_lats_step (dest_plats, new_offset, src_aglat->size,
2086 &dst_aglat, pre_existing, &ret)) 2588 &dst_aglat, pre_existing, &ret, max_agg_items))
2087 { 2589 {
2088 struct ipcp_agg_lattice *new_al = *dst_aglat; 2590 struct ipcp_agg_lattice *new_al = *dst_aglat;
2089 2591
2090 dst_aglat = &(*dst_aglat)->next; 2592 dst_aglat = &(*dst_aglat)->next;
2091 if (src_aglat->bottom) 2593 if (src_aglat->bottom)
2111 /* Determine whether there is anything to propagate FROM SRC_PLATS through a 2613 /* Determine whether there is anything to propagate FROM SRC_PLATS through a
2112 pass-through JFUNC and if so, whether it has conform and conforms to the 2614 pass-through JFUNC and if so, whether it has conform and conforms to the
2113 rules about propagating values passed by reference. */ 2615 rules about propagating values passed by reference. */
2114 2616
2115 static bool 2617 static bool
2116 agg_pass_through_permissible_p (struct ipcp_param_lattices *src_plats, 2618 agg_pass_through_permissible_p (class ipcp_param_lattices *src_plats,
2117 struct ipa_jump_func *jfunc) 2619 struct ipa_jump_func *jfunc)
2118 { 2620 {
2119 return src_plats->aggs 2621 return src_plats->aggs
2120 && (!src_plats->aggs_by_ref 2622 && (!src_plats->aggs_by_ref
2121 || ipa_get_jf_pass_through_agg_preserved (jfunc)); 2623 || ipa_get_jf_pass_through_agg_preserved (jfunc));
2122 } 2624 }
2123 2625
2626 /* Propagate values through ITEM, jump function for a part of an aggregate,
2627 into corresponding aggregate lattice AGLAT. CS is the call graph edge
2628 associated with the jump function. Return true if AGLAT changed in any
2629 way. */
2630
2631 static bool
2632 propagate_aggregate_lattice (struct cgraph_edge *cs,
2633 struct ipa_agg_jf_item *item,
2634 struct ipcp_agg_lattice *aglat)
2635 {
2636 class ipa_node_params *caller_info;
2637 class ipcp_param_lattices *src_plats;
2638 struct ipcp_lattice<tree> *src_lat;
2639 HOST_WIDE_INT src_offset;
2640 int src_idx;
2641 tree load_type;
2642 bool ret;
2643
2644 if (item->jftype == IPA_JF_CONST)
2645 {
2646 tree value = item->value.constant;
2647
2648 gcc_checking_assert (is_gimple_ip_invariant (value));
2649 return aglat->add_value (value, cs, NULL, 0);
2650 }
2651
2652 gcc_checking_assert (item->jftype == IPA_JF_PASS_THROUGH
2653 || item->jftype == IPA_JF_LOAD_AGG);
2654
2655 caller_info = IPA_NODE_REF (cs->caller);
2656 src_idx = item->value.pass_through.formal_id;
2657 src_plats = ipa_get_parm_lattices (caller_info, src_idx);
2658
2659 if (item->jftype == IPA_JF_PASS_THROUGH)
2660 {
2661 load_type = NULL_TREE;
2662 src_lat = &src_plats->itself;
2663 src_offset = -1;
2664 }
2665 else
2666 {
2667 HOST_WIDE_INT load_offset = item->value.load_agg.offset;
2668 struct ipcp_agg_lattice *src_aglat;
2669
2670 for (src_aglat = src_plats->aggs; src_aglat; src_aglat = src_aglat->next)
2671 if (src_aglat->offset >= load_offset)
2672 break;
2673
2674 load_type = item->value.load_agg.type;
2675 if (!src_aglat
2676 || src_aglat->offset > load_offset
2677 || src_aglat->size != tree_to_shwi (TYPE_SIZE (load_type))
2678 || src_plats->aggs_by_ref != item->value.load_agg.by_ref)
2679 return aglat->set_contains_variable ();
2680
2681 src_lat = src_aglat;
2682 src_offset = load_offset;
2683 }
2684
2685 if (src_lat->bottom
2686 || (!ipcp_versionable_function_p (cs->caller)
2687 && !src_lat->is_single_const ()))
2688 return aglat->set_contains_variable ();
2689
2690 ret = propagate_vals_across_arith_jfunc (cs,
2691 item->value.pass_through.operation,
2692 load_type,
2693 item->value.pass_through.operand,
2694 src_lat, aglat,
2695 src_offset,
2696 src_idx,
2697 item->type);
2698
2699 if (src_lat->contains_variable)
2700 ret |= aglat->set_contains_variable ();
2701
2702 return ret;
2703 }
2704
2124 /* Propagate scalar values across jump function JFUNC that is associated with 2705 /* Propagate scalar values across jump function JFUNC that is associated with
2125 edge CS and put the values into DEST_LAT. */ 2706 edge CS and put the values into DEST_LAT. */
2126 2707
2127 static bool 2708 static bool
2128 propagate_aggs_across_jump_function (struct cgraph_edge *cs, 2709 propagate_aggs_across_jump_function (struct cgraph_edge *cs,
2129 struct ipa_jump_func *jfunc, 2710 struct ipa_jump_func *jfunc,
2130 struct ipcp_param_lattices *dest_plats) 2711 class ipcp_param_lattices *dest_plats)
2131 { 2712 {
2132 bool ret = false; 2713 bool ret = false;
2133 2714
2134 if (dest_plats->aggs_bottom) 2715 if (dest_plats->aggs_bottom)
2135 return false; 2716 return false;
2136 2717
2137 if (jfunc->type == IPA_JF_PASS_THROUGH 2718 if (jfunc->type == IPA_JF_PASS_THROUGH
2138 && ipa_get_jf_pass_through_operation (jfunc) == NOP_EXPR) 2719 && ipa_get_jf_pass_through_operation (jfunc) == NOP_EXPR)
2139 { 2720 {
2140 struct ipa_node_params *caller_info = IPA_NODE_REF (cs->caller); 2721 class ipa_node_params *caller_info = IPA_NODE_REF (cs->caller);
2141 int src_idx = ipa_get_jf_pass_through_formal_id (jfunc); 2722 int src_idx = ipa_get_jf_pass_through_formal_id (jfunc);
2142 struct ipcp_param_lattices *src_plats; 2723 class ipcp_param_lattices *src_plats;
2143 2724
2144 src_plats = ipa_get_parm_lattices (caller_info, src_idx); 2725 src_plats = ipa_get_parm_lattices (caller_info, src_idx);
2145 if (agg_pass_through_permissible_p (src_plats, jfunc)) 2726 if (agg_pass_through_permissible_p (src_plats, jfunc))
2146 { 2727 {
2147 /* Currently we do not produce clobber aggregate jump 2728 /* Currently we do not produce clobber aggregate jump
2154 ret |= set_agg_lats_contain_variable (dest_plats); 2735 ret |= set_agg_lats_contain_variable (dest_plats);
2155 } 2736 }
2156 else if (jfunc->type == IPA_JF_ANCESTOR 2737 else if (jfunc->type == IPA_JF_ANCESTOR
2157 && ipa_get_jf_ancestor_agg_preserved (jfunc)) 2738 && ipa_get_jf_ancestor_agg_preserved (jfunc))
2158 { 2739 {
2159 struct ipa_node_params *caller_info = IPA_NODE_REF (cs->caller); 2740 class ipa_node_params *caller_info = IPA_NODE_REF (cs->caller);
2160 int src_idx = ipa_get_jf_ancestor_formal_id (jfunc); 2741 int src_idx = ipa_get_jf_ancestor_formal_id (jfunc);
2161 struct ipcp_param_lattices *src_plats; 2742 class ipcp_param_lattices *src_plats;
2162 2743
2163 src_plats = ipa_get_parm_lattices (caller_info, src_idx); 2744 src_plats = ipa_get_parm_lattices (caller_info, src_idx);
2164 if (src_plats->aggs && src_plats->aggs_by_ref) 2745 if (src_plats->aggs && src_plats->aggs_by_ref)
2165 { 2746 {
2166 /* Currently we do not produce clobber aggregate jump 2747 /* Currently we do not produce clobber aggregate jump
2182 int i; 2763 int i;
2183 2764
2184 if (set_check_aggs_by_ref (dest_plats, jfunc->agg.by_ref)) 2765 if (set_check_aggs_by_ref (dest_plats, jfunc->agg.by_ref))
2185 return true; 2766 return true;
2186 2767
2768 int max_agg_items = opt_for_fn (cs->callee->function_symbol ()->decl,
2769 param_ipa_max_agg_items);
2187 FOR_EACH_VEC_ELT (*jfunc->agg.items, i, item) 2770 FOR_EACH_VEC_ELT (*jfunc->agg.items, i, item)
2188 { 2771 {
2189 HOST_WIDE_INT val_size; 2772 HOST_WIDE_INT val_size;
2190 2773
2191 if (item->offset < 0) 2774 if (item->offset < 0 || item->jftype == IPA_JF_UNKNOWN)
2192 continue; 2775 continue;
2193 gcc_checking_assert (is_gimple_ip_invariant (item->value)); 2776 val_size = tree_to_shwi (TYPE_SIZE (item->type));
2194 val_size = tree_to_uhwi (TYPE_SIZE (TREE_TYPE (item->value)));
2195 2777
2196 if (merge_agg_lats_step (dest_plats, item->offset, val_size, 2778 if (merge_agg_lats_step (dest_plats, item->offset, val_size,
2197 &aglat, pre_existing, &ret)) 2779 &aglat, pre_existing, &ret, max_agg_items))
2198 { 2780 {
2199 ret |= (*aglat)->add_value (item->value, cs, NULL, 0, 0); 2781 ret |= propagate_aggregate_lattice (cs, item, *aglat);
2200 aglat = &(*aglat)->next; 2782 aglat = &(*aglat)->next;
2201 } 2783 }
2202 else if (dest_plats->aggs_bottom) 2784 else if (dest_plats->aggs_bottom)
2203 return true; 2785 return true;
2204 } 2786 }
2227 caller. */ 2809 caller. */
2228 2810
2229 static bool 2811 static bool
2230 propagate_constants_across_call (struct cgraph_edge *cs) 2812 propagate_constants_across_call (struct cgraph_edge *cs)
2231 { 2813 {
2232 struct ipa_node_params *callee_info; 2814 class ipa_node_params *callee_info;
2233 enum availability availability; 2815 enum availability availability;
2234 cgraph_node *callee; 2816 cgraph_node *callee;
2235 struct ipa_edge_args *args; 2817 class ipa_edge_args *args;
2236 bool ret = false; 2818 bool ret = false;
2237 int i, args_count, parms_count; 2819 int i, args_count, parms_count;
2238 2820
2239 callee = cs->callee->function_symbol (&availability); 2821 callee = cs->callee->function_symbol (&availability);
2240 if (!callee->definition) 2822 if (!callee->definition)
2241 return false; 2823 return false;
2242 gcc_checking_assert (callee->has_gimple_body_p ()); 2824 gcc_checking_assert (callee->has_gimple_body_p ());
2243 callee_info = IPA_NODE_REF (callee); 2825 callee_info = IPA_NODE_REF (callee);
2826 if (!callee_info)
2827 return false;
2244 2828
2245 args = IPA_EDGE_REF (cs); 2829 args = IPA_EDGE_REF (cs);
2246 args_count = ipa_get_cs_argument_count (args);
2247 parms_count = ipa_get_param_count (callee_info); 2830 parms_count = ipa_get_param_count (callee_info);
2248 if (parms_count == 0) 2831 if (parms_count == 0)
2249 return false; 2832 return false;
2833 if (!args
2834 || !opt_for_fn (cs->caller->decl, flag_ipa_cp)
2835 || !opt_for_fn (cs->caller->decl, optimize))
2836 {
2837 for (i = 0; i < parms_count; i++)
2838 ret |= set_all_contains_variable (ipa_get_parm_lattices (callee_info,
2839 i));
2840 return ret;
2841 }
2842 args_count = ipa_get_cs_argument_count (args);
2250 2843
2251 /* If this call goes through a thunk we must not propagate to the first (0th) 2844 /* If this call goes through a thunk we must not propagate to the first (0th)
2252 parameter. However, we might need to uncover a thunk from below a series 2845 parameter. However, we might need to uncover a thunk from below a series
2253 of aliases first. */ 2846 of aliases first. */
2254 if (call_passes_through_thunk_p (cs)) 2847 if (call_passes_through_thunk_p (cs))
2261 i = 0; 2854 i = 0;
2262 2855
2263 for (; (i < args_count) && (i < parms_count); i++) 2856 for (; (i < args_count) && (i < parms_count); i++)
2264 { 2857 {
2265 struct ipa_jump_func *jump_func = ipa_get_ith_jump_func (args, i); 2858 struct ipa_jump_func *jump_func = ipa_get_ith_jump_func (args, i);
2266 struct ipcp_param_lattices *dest_plats; 2859 class ipcp_param_lattices *dest_plats;
2267 tree param_type = ipa_get_type (callee_info, i); 2860 tree param_type = ipa_get_type (callee_info, i);
2268 2861
2269 dest_plats = ipa_get_parm_lattices (callee_info, i); 2862 dest_plats = ipa_get_parm_lattices (callee_info, i);
2270 if (availability == AVAIL_INTERPOSABLE) 2863 if (availability == AVAIL_INTERPOSABLE)
2271 ret |= set_all_contains_variable (dest_plats); 2864 ret |= set_all_contains_variable (dest_plats);
2300 2893
2301 static tree 2894 static tree
2302 ipa_get_indirect_edge_target_1 (struct cgraph_edge *ie, 2895 ipa_get_indirect_edge_target_1 (struct cgraph_edge *ie,
2303 vec<tree> known_csts, 2896 vec<tree> known_csts,
2304 vec<ipa_polymorphic_call_context> known_contexts, 2897 vec<ipa_polymorphic_call_context> known_contexts,
2305 vec<ipa_agg_jump_function_p> known_aggs, 2898 vec<ipa_agg_value_set> known_aggs,
2306 struct ipa_agg_replacement_value *agg_reps, 2899 struct ipa_agg_replacement_value *agg_reps,
2307 bool *speculative) 2900 bool *speculative)
2308 { 2901 {
2309 int param_index = ie->indirect_info->param_index; 2902 int param_index = ie->indirect_info->param_index;
2310 HOST_WIDE_INT anc_offset; 2903 HOST_WIDE_INT anc_offset;
2311 tree t; 2904 tree t = NULL;
2312 tree target = NULL; 2905 tree target = NULL;
2313 2906
2314 *speculative = false; 2907 *speculative = false;
2315 2908
2316 if (param_index == -1 2909 if (param_index == -1)
2317 || known_csts.length () <= (unsigned int) param_index)
2318 return NULL_TREE; 2910 return NULL_TREE;
2319 2911
2320 if (!ie->indirect_info->polymorphic) 2912 if (!ie->indirect_info->polymorphic)
2321 { 2913 {
2322 tree t; 2914 tree t = NULL;
2323 2915
2324 if (ie->indirect_info->agg_contents) 2916 if (ie->indirect_info->agg_contents)
2325 { 2917 {
2326 t = NULL; 2918 t = NULL;
2327 if (agg_reps && ie->indirect_info->guaranteed_unmodified) 2919 if (agg_reps && ie->indirect_info->guaranteed_unmodified)
2338 agg_reps = agg_reps->next; 2930 agg_reps = agg_reps->next;
2339 } 2931 }
2340 } 2932 }
2341 if (!t) 2933 if (!t)
2342 { 2934 {
2343 struct ipa_agg_jump_function *agg; 2935 struct ipa_agg_value_set *agg;
2344 if (known_aggs.length () > (unsigned int) param_index) 2936 if (known_aggs.length () > (unsigned int) param_index)
2345 agg = known_aggs[param_index]; 2937 agg = &known_aggs[param_index];
2346 else 2938 else
2347 agg = NULL; 2939 agg = NULL;
2348 bool from_global_constant; 2940 bool from_global_constant;
2349 t = ipa_find_agg_cst_for_param (agg, known_csts[param_index], 2941 t = ipa_find_agg_cst_for_param (agg,
2942 (unsigned) param_index
2943 < known_csts.length ()
2944 ? known_csts[param_index]
2945 : NULL,
2350 ie->indirect_info->offset, 2946 ie->indirect_info->offset,
2351 ie->indirect_info->by_ref, 2947 ie->indirect_info->by_ref,
2352 &from_global_constant); 2948 &from_global_constant);
2353 if (t 2949 if (t
2354 && !from_global_constant 2950 && !from_global_constant
2355 && !ie->indirect_info->guaranteed_unmodified) 2951 && !ie->indirect_info->guaranteed_unmodified)
2356 t = NULL_TREE; 2952 t = NULL_TREE;
2357 } 2953 }
2358 } 2954 }
2359 else 2955 else if ((unsigned) param_index < known_csts.length ())
2360 t = known_csts[param_index]; 2956 t = known_csts[param_index];
2361 2957
2362 if (t 2958 if (t
2363 && TREE_CODE (t) == ADDR_EXPR 2959 && TREE_CODE (t) == ADDR_EXPR
2364 && TREE_CODE (TREE_OPERAND (t, 0)) == FUNCTION_DECL) 2960 && TREE_CODE (TREE_OPERAND (t, 0)) == FUNCTION_DECL)
2373 gcc_assert (!ie->indirect_info->agg_contents); 2969 gcc_assert (!ie->indirect_info->agg_contents);
2374 anc_offset = ie->indirect_info->offset; 2970 anc_offset = ie->indirect_info->offset;
2375 2971
2376 t = NULL; 2972 t = NULL;
2377 2973
2378 /* Try to work out value of virtual table pointer value in replacemnets. */ 2974 /* Try to work out value of virtual table pointer value in replacements. */
2379 if (!t && agg_reps && !ie->indirect_info->by_ref) 2975 if (!t && agg_reps && !ie->indirect_info->by_ref)
2380 { 2976 {
2381 while (agg_reps) 2977 while (agg_reps)
2382 { 2978 {
2383 if (agg_reps->index == param_index 2979 if (agg_reps->index == param_index
2394 /* Try to work out value of virtual table pointer value in known 2990 /* Try to work out value of virtual table pointer value in known
2395 aggregate values. */ 2991 aggregate values. */
2396 if (!t && known_aggs.length () > (unsigned int) param_index 2992 if (!t && known_aggs.length () > (unsigned int) param_index
2397 && !ie->indirect_info->by_ref) 2993 && !ie->indirect_info->by_ref)
2398 { 2994 {
2399 struct ipa_agg_jump_function *agg; 2995 struct ipa_agg_value_set *agg = &known_aggs[param_index];
2400 agg = known_aggs[param_index]; 2996 t = ipa_find_agg_cst_for_param (agg,
2401 t = ipa_find_agg_cst_for_param (agg, known_csts[param_index], 2997 (unsigned) param_index
2998 < known_csts.length ()
2999 ? known_csts[param_index] : NULL,
2402 ie->indirect_info->offset, true); 3000 ie->indirect_info->offset, true);
2403 } 3001 }
2404 3002
2405 /* If we found the virtual table pointer, lookup the target. */ 3003 /* If we found the virtual table pointer, lookup the target. */
2406 if (t) 3004 if (t)
2413 target = gimple_get_virt_method_for_vtable (ie->indirect_info->otr_token, 3011 target = gimple_get_virt_method_for_vtable (ie->indirect_info->otr_token,
2414 vtable, offset, &can_refer); 3012 vtable, offset, &can_refer);
2415 if (can_refer) 3013 if (can_refer)
2416 { 3014 {
2417 if (!target 3015 if (!target
2418 || (TREE_CODE (TREE_TYPE (target)) == FUNCTION_TYPE 3016 || fndecl_built_in_p (target, BUILT_IN_UNREACHABLE)
2419 && DECL_FUNCTION_CODE (target) == BUILT_IN_UNREACHABLE)
2420 || !possible_polymorphic_call_target_p 3017 || !possible_polymorphic_call_target_p
2421 (ie, cgraph_node::get (target))) 3018 (ie, cgraph_node::get (target)))
2422 { 3019 {
2423 /* Do not speculate builtin_unreachable, it is stupid! */ 3020 /* Do not speculate builtin_unreachable, it is stupid! */
2424 if (ie->indirect_info->vptr_changed) 3021 if (ie->indirect_info->vptr_changed)
2431 } 3028 }
2432 } 3029 }
2433 } 3030 }
2434 3031
2435 /* Do we know the constant value of pointer? */ 3032 /* Do we know the constant value of pointer? */
2436 if (!t) 3033 if (!t && (unsigned) param_index < known_csts.length ())
2437 t = known_csts[param_index]; 3034 t = known_csts[param_index];
2438 3035
2439 gcc_checking_assert (!t || TREE_CODE (t) != TREE_BINFO); 3036 gcc_checking_assert (!t || TREE_CODE (t) != TREE_BINFO);
2440 3037
2441 ipa_polymorphic_call_context context; 3038 ipa_polymorphic_call_context context;
2518 3115
2519 tree 3116 tree
2520 ipa_get_indirect_edge_target (struct cgraph_edge *ie, 3117 ipa_get_indirect_edge_target (struct cgraph_edge *ie,
2521 vec<tree> known_csts, 3118 vec<tree> known_csts,
2522 vec<ipa_polymorphic_call_context> known_contexts, 3119 vec<ipa_polymorphic_call_context> known_contexts,
2523 vec<ipa_agg_jump_function_p> known_aggs, 3120 vec<ipa_agg_value_set> known_aggs,
2524 bool *speculative) 3121 bool *speculative)
2525 { 3122 {
2526 return ipa_get_indirect_edge_target_1 (ie, known_csts, known_contexts, 3123 return ipa_get_indirect_edge_target_1 (ie, known_csts, known_contexts,
2527 known_aggs, NULL, speculative); 3124 known_aggs, NULL, speculative);
2528 } 3125 }
2532 3129
2533 static int 3130 static int
2534 devirtualization_time_bonus (struct cgraph_node *node, 3131 devirtualization_time_bonus (struct cgraph_node *node,
2535 vec<tree> known_csts, 3132 vec<tree> known_csts,
2536 vec<ipa_polymorphic_call_context> known_contexts, 3133 vec<ipa_polymorphic_call_context> known_contexts,
2537 vec<ipa_agg_jump_function_p> known_aggs) 3134 vec<ipa_agg_value_set> known_aggs)
2538 { 3135 {
2539 struct cgraph_edge *ie; 3136 struct cgraph_edge *ie;
2540 int res = 0; 3137 int res = 0;
2541 3138
2542 for (ie = node->indirect_calls; ie; ie = ie->next_callee) 3139 for (ie = node->indirect_calls; ie; ie = ie->next_callee)
2543 { 3140 {
2544 struct cgraph_node *callee; 3141 struct cgraph_node *callee;
2545 struct ipa_fn_summary *isummary; 3142 class ipa_fn_summary *isummary;
2546 enum availability avail; 3143 enum availability avail;
2547 tree target; 3144 tree target;
2548 bool speculative; 3145 bool speculative;
2549 3146
2550 target = ipa_get_indirect_edge_target (ie, known_csts, known_contexts, 3147 target = ipa_get_indirect_edge_target (ie, known_csts, known_contexts,
2559 continue; 3156 continue;
2560 callee = callee->function_symbol (&avail); 3157 callee = callee->function_symbol (&avail);
2561 if (avail < AVAIL_AVAILABLE) 3158 if (avail < AVAIL_AVAILABLE)
2562 continue; 3159 continue;
2563 isummary = ipa_fn_summaries->get (callee); 3160 isummary = ipa_fn_summaries->get (callee);
2564 if (!isummary->inlinable) 3161 if (!isummary || !isummary->inlinable)
2565 continue; 3162 continue;
2566 3163
3164 int size = ipa_size_summaries->get (callee)->size;
2567 /* FIXME: The values below need re-considering and perhaps also 3165 /* FIXME: The values below need re-considering and perhaps also
2568 integrating into the cost metrics, at lest in some very basic way. */ 3166 integrating into the cost metrics, at lest in some very basic way. */
2569 if (isummary->size <= MAX_INLINE_INSNS_AUTO / 4) 3167 int max_inline_insns_auto
3168 = opt_for_fn (callee->decl, param_max_inline_insns_auto);
3169 if (size <= max_inline_insns_auto / 4)
2570 res += 31 / ((int)speculative + 1); 3170 res += 31 / ((int)speculative + 1);
2571 else if (isummary->size <= MAX_INLINE_INSNS_AUTO / 2) 3171 else if (size <= max_inline_insns_auto / 2)
2572 res += 15 / ((int)speculative + 1); 3172 res += 15 / ((int)speculative + 1);
2573 else if (isummary->size <= MAX_INLINE_INSNS_AUTO 3173 else if (size <= max_inline_insns_auto
2574 || DECL_DECLARED_INLINE_P (callee->decl)) 3174 || DECL_DECLARED_INLINE_P (callee->decl))
2575 res += 7 / ((int)speculative + 1); 3175 res += 7 / ((int)speculative + 1);
2576 } 3176 }
2577 3177
2578 return res; 3178 return res;
2579 } 3179 }
2580 3180
2581 /* Return time bonus incurred because of HINTS. */ 3181 /* Return time bonus incurred because of HINTS. */
2582 3182
2583 static int 3183 static int
2584 hint_time_bonus (ipa_hints hints) 3184 hint_time_bonus (cgraph_node *node, ipa_hints hints)
2585 { 3185 {
2586 int result = 0; 3186 int result = 0;
2587 if (hints & (INLINE_HINT_loop_iterations | INLINE_HINT_loop_stride)) 3187 if (hints & (INLINE_HINT_loop_iterations | INLINE_HINT_loop_stride))
2588 result += PARAM_VALUE (PARAM_IPA_CP_LOOP_HINT_BONUS); 3188 result += opt_for_fn (node->decl, param_ipa_cp_loop_hint_bonus);
2589 if (hints & INLINE_HINT_array_index)
2590 result += PARAM_VALUE (PARAM_IPA_CP_ARRAY_INDEX_HINT_BONUS);
2591 return result; 3189 return result;
2592 } 3190 }
2593 3191
2594 /* If there is a reason to penalize the function described by INFO in the 3192 /* If there is a reason to penalize the function described by INFO in the
2595 cloning goodness evaluation, do so. */ 3193 cloning goodness evaluation, do so. */
2596 3194
2597 static inline int64_t 3195 static inline int64_t
2598 incorporate_penalties (ipa_node_params *info, int64_t evaluation) 3196 incorporate_penalties (cgraph_node *node, ipa_node_params *info,
2599 { 3197 int64_t evaluation)
2600 if (info->node_within_scc) 3198 {
3199 if (info->node_within_scc && !info->node_is_self_scc)
2601 evaluation = (evaluation 3200 evaluation = (evaluation
2602 * (100 - PARAM_VALUE (PARAM_IPA_CP_RECURSION_PENALTY))) / 100; 3201 * (100 - opt_for_fn (node->decl,
3202 param_ipa_cp_recursion_penalty))) / 100;
2603 3203
2604 if (info->node_calling_single_call) 3204 if (info->node_calling_single_call)
2605 evaluation = (evaluation 3205 evaluation = (evaluation
2606 * (100 - PARAM_VALUE (PARAM_IPA_CP_SINGLE_CALL_PENALTY))) 3206 * (100 - opt_for_fn (node->decl,
3207 param_ipa_cp_single_call_penalty)))
2607 / 100; 3208 / 100;
2608 3209
2609 return evaluation; 3210 return evaluation;
2610 } 3211 }
2611 3212
2622 || node->optimize_for_size_p ()) 3223 || node->optimize_for_size_p ())
2623 return false; 3224 return false;
2624 3225
2625 gcc_assert (size_cost > 0); 3226 gcc_assert (size_cost > 0);
2626 3227
2627 struct ipa_node_params *info = IPA_NODE_REF (node); 3228 class ipa_node_params *info = IPA_NODE_REF (node);
3229 int eval_threshold = opt_for_fn (node->decl, param_ipa_cp_eval_threshold);
2628 if (max_count > profile_count::zero ()) 3230 if (max_count > profile_count::zero ())
2629 { 3231 {
2630 int factor = RDIV (count_sum.probability_in 3232 int factor = RDIV (count_sum.probability_in
2631 (max_count).to_reg_br_prob_base () 3233 (max_count).to_reg_br_prob_base ()
2632 * 1000, REG_BR_PROB_BASE); 3234 * 1000, REG_BR_PROB_BASE);
2633 int64_t evaluation = (((int64_t) time_benefit * factor) 3235 int64_t evaluation = (((int64_t) time_benefit * factor)
2634 / size_cost); 3236 / size_cost);
2635 evaluation = incorporate_penalties (info, evaluation); 3237 evaluation = incorporate_penalties (node, info, evaluation);
2636 3238
2637 if (dump_file && (dump_flags & TDF_DETAILS)) 3239 if (dump_file && (dump_flags & TDF_DETAILS))
2638 { 3240 {
2639 fprintf (dump_file, " good_cloning_opportunity_p (time: %i, " 3241 fprintf (dump_file, " good_cloning_opportunity_p (time: %i, "
2640 "size: %i, count_sum: ", time_benefit, size_cost); 3242 "size: %i, count_sum: ", time_benefit, size_cost);
2641 count_sum.dump (dump_file); 3243 count_sum.dump (dump_file);
2642 fprintf (dump_file, "%s%s) -> evaluation: " "%" PRId64 3244 fprintf (dump_file, "%s%s) -> evaluation: " "%" PRId64
2643 ", threshold: %i\n", 3245 ", threshold: %i\n",
2644 info->node_within_scc ? ", scc" : "", 3246 info->node_within_scc
3247 ? (info->node_is_self_scc ? ", self_scc" : ", scc") : "",
2645 info->node_calling_single_call ? ", single_call" : "", 3248 info->node_calling_single_call ? ", single_call" : "",
2646 evaluation, PARAM_VALUE (PARAM_IPA_CP_EVAL_THRESHOLD)); 3249 evaluation, eval_threshold);
2647 } 3250 }
2648 3251
2649 return evaluation >= PARAM_VALUE (PARAM_IPA_CP_EVAL_THRESHOLD); 3252 return evaluation >= eval_threshold;
2650 } 3253 }
2651 else 3254 else
2652 { 3255 {
2653 int64_t evaluation = (((int64_t) time_benefit * freq_sum) 3256 int64_t evaluation = (((int64_t) time_benefit * freq_sum)
2654 / size_cost); 3257 / size_cost);
2655 evaluation = incorporate_penalties (info, evaluation); 3258 evaluation = incorporate_penalties (node, info, evaluation);
2656 3259
2657 if (dump_file && (dump_flags & TDF_DETAILS)) 3260 if (dump_file && (dump_flags & TDF_DETAILS))
2658 fprintf (dump_file, " good_cloning_opportunity_p (time: %i, " 3261 fprintf (dump_file, " good_cloning_opportunity_p (time: %i, "
2659 "size: %i, freq_sum: %i%s%s) -> evaluation: " 3262 "size: %i, freq_sum: %i%s%s) -> evaluation: "
2660 "%" PRId64 ", threshold: %i\n", 3263 "%" PRId64 ", threshold: %i\n",
2661 time_benefit, size_cost, freq_sum, 3264 time_benefit, size_cost, freq_sum,
2662 info->node_within_scc ? ", scc" : "", 3265 info->node_within_scc
3266 ? (info->node_is_self_scc ? ", self_scc" : ", scc") : "",
2663 info->node_calling_single_call ? ", single_call" : "", 3267 info->node_calling_single_call ? ", single_call" : "",
2664 evaluation, PARAM_VALUE (PARAM_IPA_CP_EVAL_THRESHOLD)); 3268 evaluation, eval_threshold);
2665 3269
2666 return evaluation >= PARAM_VALUE (PARAM_IPA_CP_EVAL_THRESHOLD); 3270 return evaluation >= eval_threshold;
2667 } 3271 }
2668 } 3272 }
2669 3273
2670 /* Return all context independent values from aggregate lattices in PLATS in a 3274 /* Return all context independent values from aggregate lattices in PLATS in a
2671 vector. Return NULL if there are none. */ 3275 vector. Return NULL if there are none. */
2672 3276
2673 static vec<ipa_agg_jf_item, va_gc> * 3277 static vec<ipa_agg_value>
2674 context_independent_aggregate_values (struct ipcp_param_lattices *plats) 3278 context_independent_aggregate_values (class ipcp_param_lattices *plats)
2675 { 3279 {
2676 vec<ipa_agg_jf_item, va_gc> *res = NULL; 3280 vec<ipa_agg_value> res = vNULL;
2677 3281
2678 if (plats->aggs_bottom 3282 if (plats->aggs_bottom
2679 || plats->aggs_contain_variable 3283 || plats->aggs_contain_variable
2680 || plats->aggs_count == 0) 3284 || plats->aggs_count == 0)
2681 return NULL; 3285 return vNULL;
2682 3286
2683 for (struct ipcp_agg_lattice *aglat = plats->aggs; 3287 for (struct ipcp_agg_lattice *aglat = plats->aggs;
2684 aglat; 3288 aglat;
2685 aglat = aglat->next) 3289 aglat = aglat->next)
2686 if (aglat->is_single_const ()) 3290 if (aglat->is_single_const ())
2687 { 3291 {
2688 struct ipa_agg_jf_item item; 3292 struct ipa_agg_value item;
2689 item.offset = aglat->offset; 3293 item.offset = aglat->offset;
2690 item.value = aglat->values->value; 3294 item.value = aglat->values->value;
2691 vec_safe_push (res, item); 3295 res.safe_push (item);
2692 } 3296 }
2693 return res; 3297 return res;
2694 } 3298 }
2695 3299
2696 /* Allocate KNOWN_CSTS, KNOWN_CONTEXTS and, if non-NULL, KNOWN_AGGS and 3300 /* Allocate KNOWN_CSTS, KNOWN_CONTEXTS and, if non-NULL, KNOWN_AGGS and
2698 context. INFO describes the function. If REMOVABLE_PARAMS_COST is 3302 context. INFO describes the function. If REMOVABLE_PARAMS_COST is
2699 non-NULL, the movement cost of all removable parameters will be stored in 3303 non-NULL, the movement cost of all removable parameters will be stored in
2700 it. */ 3304 it. */
2701 3305
2702 static bool 3306 static bool
2703 gather_context_independent_values (struct ipa_node_params *info, 3307 gather_context_independent_values (class ipa_node_params *info,
2704 vec<tree> *known_csts, 3308 vec<tree> *known_csts,
2705 vec<ipa_polymorphic_call_context> 3309 vec<ipa_polymorphic_call_context>
2706 *known_contexts, 3310 *known_contexts,
2707 vec<ipa_agg_jump_function> *known_aggs, 3311 vec<ipa_agg_value_set> *known_aggs,
2708 int *removable_params_cost) 3312 int *removable_params_cost)
2709 { 3313 {
2710 int i, count = ipa_get_param_count (info); 3314 int i, count = ipa_get_param_count (info);
2711 bool ret = false; 3315 bool ret = false;
2712 3316
2723 if (removable_params_cost) 3327 if (removable_params_cost)
2724 *removable_params_cost = 0; 3328 *removable_params_cost = 0;
2725 3329
2726 for (i = 0; i < count; i++) 3330 for (i = 0; i < count; i++)
2727 { 3331 {
2728 struct ipcp_param_lattices *plats = ipa_get_parm_lattices (info, i); 3332 class ipcp_param_lattices *plats = ipa_get_parm_lattices (info, i);
2729 ipcp_lattice<tree> *lat = &plats->itself; 3333 ipcp_lattice<tree> *lat = &plats->itself;
2730 3334
2731 if (lat->is_single_const ()) 3335 if (lat->is_single_const ())
2732 { 3336 {
2733 ipcp_value<tree> *val = lat->values; 3337 ipcp_value<tree> *val = lat->values;
2752 if (ctxlat->is_single_const ()) 3356 if (ctxlat->is_single_const ())
2753 (*known_contexts)[i] = ctxlat->values->value; 3357 (*known_contexts)[i] = ctxlat->values->value;
2754 3358
2755 if (known_aggs) 3359 if (known_aggs)
2756 { 3360 {
2757 vec<ipa_agg_jf_item, va_gc> *agg_items; 3361 vec<ipa_agg_value> agg_items;
2758 struct ipa_agg_jump_function *ajf; 3362 struct ipa_agg_value_set *agg;
2759 3363
2760 agg_items = context_independent_aggregate_values (plats); 3364 agg_items = context_independent_aggregate_values (plats);
2761 ajf = &(*known_aggs)[i]; 3365 agg = &(*known_aggs)[i];
2762 ajf->items = agg_items; 3366 agg->items = agg_items;
2763 ajf->by_ref = plats->aggs_by_ref; 3367 agg->by_ref = plats->aggs_by_ref;
2764 ret |= agg_items != NULL; 3368 ret |= !agg_items.is_empty ();
2765 } 3369 }
2766 } 3370 }
2767 3371
2768 return ret;
2769 }
2770
2771 /* The current interface in ipa-inline-analysis requires a pointer vector.
2772 Create it.
2773
2774 FIXME: That interface should be re-worked, this is slightly silly. Still,
2775 I'd like to discuss how to change it first and this demonstrates the
2776 issue. */
2777
2778 static vec<ipa_agg_jump_function_p>
2779 agg_jmp_p_vec_for_t_vec (vec<ipa_agg_jump_function> known_aggs)
2780 {
2781 vec<ipa_agg_jump_function_p> ret;
2782 struct ipa_agg_jump_function *ajf;
2783 int i;
2784
2785 ret.create (known_aggs.length ());
2786 FOR_EACH_VEC_ELT (known_aggs, i, ajf)
2787 ret.quick_push (ajf);
2788 return ret; 3372 return ret;
2789 } 3373 }
2790 3374
2791 /* Perform time and size measurement of NODE with the context given in 3375 /* Perform time and size measurement of NODE with the context given in
2792 KNOWN_CSTS, KNOWN_CONTEXTS and KNOWN_AGGS, calculate the benefit and cost 3376 KNOWN_CSTS, KNOWN_CONTEXTS and KNOWN_AGGS, calculate the benefit and cost
2795 movement of the considered parameter and store it into VAL. */ 3379 movement of the considered parameter and store it into VAL. */
2796 3380
2797 static void 3381 static void
2798 perform_estimation_of_a_value (cgraph_node *node, vec<tree> known_csts, 3382 perform_estimation_of_a_value (cgraph_node *node, vec<tree> known_csts,
2799 vec<ipa_polymorphic_call_context> known_contexts, 3383 vec<ipa_polymorphic_call_context> known_contexts,
2800 vec<ipa_agg_jump_function_p> known_aggs_ptrs, 3384 vec<ipa_agg_value_set> known_aggs,
2801 int removable_params_cost, 3385 int removable_params_cost,
2802 int est_move_cost, ipcp_value_base *val) 3386 int est_move_cost, ipcp_value_base *val)
2803 { 3387 {
2804 int size, time_benefit; 3388 int size, time_benefit;
2805 sreal time, base_time; 3389 sreal time, base_time;
2806 ipa_hints hints; 3390 ipa_hints hints;
2807 3391
2808 estimate_ipcp_clone_size_and_time (node, known_csts, known_contexts, 3392 estimate_ipcp_clone_size_and_time (node, known_csts, known_contexts,
2809 known_aggs_ptrs, &size, &time, 3393 known_aggs, &size, &time,
2810 &base_time, &hints); 3394 &base_time, &hints);
2811 base_time -= time; 3395 base_time -= time;
2812 if (base_time > 65535) 3396 if (base_time > 65535)
2813 base_time = 65535; 3397 base_time = 65535;
2814 time_benefit = base_time.to_int () 3398
2815 + devirtualization_time_bonus (node, known_csts, known_contexts, 3399 /* Extern inline functions have no cloning local time benefits because they
2816 known_aggs_ptrs) 3400 will be inlined anyway. The only reason to clone them is if it enables
2817 + hint_time_bonus (hints) 3401 optimization in any of the functions they call. */
2818 + removable_params_cost + est_move_cost; 3402 if (DECL_EXTERNAL (node->decl) && DECL_DECLARED_INLINE_P (node->decl))
3403 time_benefit = 0;
3404 else
3405 time_benefit = base_time.to_int ()
3406 + devirtualization_time_bonus (node, known_csts, known_contexts,
3407 known_aggs)
3408 + hint_time_bonus (node, hints)
3409 + removable_params_cost + est_move_cost;
2819 3410
2820 gcc_checking_assert (size >=0); 3411 gcc_checking_assert (size >=0);
2821 /* The inliner-heuristics based estimates may think that in certain 3412 /* The inliner-heuristics based estimates may think that in certain
2822 contexts some functions do not have any size at all but we want 3413 contexts some functions do not have any size at all but we want
2823 all specializations to have at least a tiny cost, not least not to 3414 all specializations to have at least a tiny cost, not least not to
2827 3418
2828 val->local_time_benefit = time_benefit; 3419 val->local_time_benefit = time_benefit;
2829 val->local_size_cost = size; 3420 val->local_size_cost = size;
2830 } 3421 }
2831 3422
3423 /* Get the overall limit oof growth based on parameters extracted from growth.
3424 it does not really make sense to mix functions with different overall growth
3425 limits but it is possible and if it happens, we do not want to select one
3426 limit at random. */
3427
3428 static long
3429 get_max_overall_size (cgraph_node *node)
3430 {
3431 long max_new_size = orig_overall_size;
3432 long large_unit = opt_for_fn (node->decl, param_large_unit_insns);
3433 if (max_new_size < large_unit)
3434 max_new_size = large_unit;
3435 int unit_growth = opt_for_fn (node->decl, param_ipa_cp_unit_growth);
3436 max_new_size += max_new_size * unit_growth / 100 + 1;
3437 return max_new_size;
3438 }
3439
2832 /* Iterate over known values of parameters of NODE and estimate the local 3440 /* Iterate over known values of parameters of NODE and estimate the local
2833 effects in terms of time and size they have. */ 3441 effects in terms of time and size they have. */
2834 3442
2835 static void 3443 static void
2836 estimate_local_effects (struct cgraph_node *node) 3444 estimate_local_effects (struct cgraph_node *node)
2837 { 3445 {
2838 struct ipa_node_params *info = IPA_NODE_REF (node); 3446 class ipa_node_params *info = IPA_NODE_REF (node);
2839 int i, count = ipa_get_param_count (info); 3447 int i, count = ipa_get_param_count (info);
2840 vec<tree> known_csts; 3448 vec<tree> known_csts;
2841 vec<ipa_polymorphic_call_context> known_contexts; 3449 vec<ipa_polymorphic_call_context> known_contexts;
2842 vec<ipa_agg_jump_function> known_aggs; 3450 vec<ipa_agg_value_set> known_aggs;
2843 vec<ipa_agg_jump_function_p> known_aggs_ptrs;
2844 bool always_const; 3451 bool always_const;
2845 int removable_params_cost; 3452 int removable_params_cost;
2846 3453
2847 if (!count || !ipcp_versionable_function_p (node)) 3454 if (!count || !ipcp_versionable_function_p (node))
2848 return; 3455 return;
2851 fprintf (dump_file, "\nEstimating effects for %s.\n", node->dump_name ()); 3458 fprintf (dump_file, "\nEstimating effects for %s.\n", node->dump_name ());
2852 3459
2853 always_const = gather_context_independent_values (info, &known_csts, 3460 always_const = gather_context_independent_values (info, &known_csts,
2854 &known_contexts, &known_aggs, 3461 &known_contexts, &known_aggs,
2855 &removable_params_cost); 3462 &removable_params_cost);
2856 known_aggs_ptrs = agg_jmp_p_vec_for_t_vec (known_aggs);
2857 int devirt_bonus = devirtualization_time_bonus (node, known_csts, 3463 int devirt_bonus = devirtualization_time_bonus (node, known_csts,
2858 known_contexts, known_aggs_ptrs); 3464 known_contexts, known_aggs);
2859 if (always_const || devirt_bonus 3465 if (always_const || devirt_bonus
2860 || (removable_params_cost && node->local.can_change_signature)) 3466 || (removable_params_cost && node->can_change_signature))
2861 { 3467 {
2862 struct caller_statistics stats; 3468 struct caller_statistics stats;
2863 ipa_hints hints; 3469 ipa_hints hints;
2864 sreal time, base_time; 3470 sreal time, base_time;
2865 int size; 3471 int size;
2866 3472
2867 init_caller_stats (&stats); 3473 init_caller_stats (&stats);
2868 node->call_for_symbol_thunks_and_aliases (gather_caller_stats, &stats, 3474 node->call_for_symbol_thunks_and_aliases (gather_caller_stats, &stats,
2869 false); 3475 false);
2870 estimate_ipcp_clone_size_and_time (node, known_csts, known_contexts, 3476 estimate_ipcp_clone_size_and_time (node, known_csts, known_contexts,
2871 known_aggs_ptrs, &size, &time, 3477 known_aggs, &size, &time,
2872 &base_time, &hints); 3478 &base_time, &hints);
2873 time -= devirt_bonus; 3479 time -= devirt_bonus;
2874 time -= hint_time_bonus (hints); 3480 time -= hint_time_bonus (node, hints);
2875 time -= removable_params_cost; 3481 time -= removable_params_cost;
2876 size -= stats.n_calls * removable_params_cost; 3482 size -= stats.n_calls * removable_params_cost;
2877 3483
2878 if (dump_file) 3484 if (dump_file)
2879 fprintf (dump_file, " - context independent values, size: %i, " 3485 fprintf (dump_file, " - context independent values, size: %i, "
2880 "time_benefit: %f\n", size, (base_time - time).to_double ()); 3486 "time_benefit: %f\n", size, (base_time - time).to_double ());
2881 3487
2882 if (size <= 0 || node->local.local) 3488 if (size <= 0 || node->local)
2883 { 3489 {
2884 info->do_clone_for_all_contexts = true; 3490 info->do_clone_for_all_contexts = true;
2885 3491
2886 if (dump_file) 3492 if (dump_file)
2887 fprintf (dump_file, " Decided to specialize for all " 3493 fprintf (dump_file, " Decided to specialize for all "
2891 MIN ((base_time - time).to_int (), 3497 MIN ((base_time - time).to_int (),
2892 65536), 3498 65536),
2893 stats.freq_sum, stats.count_sum, 3499 stats.freq_sum, stats.count_sum,
2894 size)) 3500 size))
2895 { 3501 {
2896 if (size + overall_size <= max_new_size) 3502 if (size + overall_size <= get_max_overall_size (node))
2897 { 3503 {
2898 info->do_clone_for_all_contexts = true; 3504 info->do_clone_for_all_contexts = true;
2899 overall_size += size; 3505 overall_size += size;
2900 3506
2901 if (dump_file) 3507 if (dump_file)
2902 fprintf (dump_file, " Decided to specialize for all " 3508 fprintf (dump_file, " Decided to specialize for all "
2903 "known contexts, growth deemed beneficial.\n"); 3509 "known contexts, growth deemed beneficial.\n");
2904 } 3510 }
2905 else if (dump_file && (dump_flags & TDF_DETAILS)) 3511 else if (dump_file && (dump_flags & TDF_DETAILS))
2906 fprintf (dump_file, " Not cloning for all contexts because " 3512 fprintf (dump_file, " Not cloning for all contexts because "
2907 "max_new_size would be reached with %li.\n", 3513 "maximum unit size would be reached with %li.\n",
2908 size + overall_size); 3514 size + overall_size);
2909 } 3515 }
2910 else if (dump_file && (dump_flags & TDF_DETAILS)) 3516 else if (dump_file && (dump_flags & TDF_DETAILS))
2911 fprintf (dump_file, " Not cloning for all contexts because " 3517 fprintf (dump_file, " Not cloning for all contexts because "
2912 "!good_cloning_opportunity_p.\n"); 3518 "!good_cloning_opportunity_p.\n");
2913 3519
2914 } 3520 }
2915 3521
2916 for (i = 0; i < count; i++) 3522 for (i = 0; i < count; i++)
2917 { 3523 {
2918 struct ipcp_param_lattices *plats = ipa_get_parm_lattices (info, i); 3524 class ipcp_param_lattices *plats = ipa_get_parm_lattices (info, i);
2919 ipcp_lattice<tree> *lat = &plats->itself; 3525 ipcp_lattice<tree> *lat = &plats->itself;
2920 ipcp_value<tree> *val; 3526 ipcp_value<tree> *val;
2921 3527
2922 if (lat->bottom 3528 if (lat->bottom
2923 || !lat->values 3529 || !lat->values
2929 gcc_checking_assert (TREE_CODE (val->value) != TREE_BINFO); 3535 gcc_checking_assert (TREE_CODE (val->value) != TREE_BINFO);
2930 known_csts[i] = val->value; 3536 known_csts[i] = val->value;
2931 3537
2932 int emc = estimate_move_cost (TREE_TYPE (val->value), true); 3538 int emc = estimate_move_cost (TREE_TYPE (val->value), true);
2933 perform_estimation_of_a_value (node, known_csts, known_contexts, 3539 perform_estimation_of_a_value (node, known_csts, known_contexts,
2934 known_aggs_ptrs, 3540 known_aggs,
2935 removable_params_cost, emc, val); 3541 removable_params_cost, emc, val);
2936 3542
2937 if (dump_file && (dump_flags & TDF_DETAILS)) 3543 if (dump_file && (dump_flags & TDF_DETAILS))
2938 { 3544 {
2939 fprintf (dump_file, " - estimates for value "); 3545 fprintf (dump_file, " - estimates for value ");
2947 known_csts[i] = NULL_TREE; 3553 known_csts[i] = NULL_TREE;
2948 } 3554 }
2949 3555
2950 for (i = 0; i < count; i++) 3556 for (i = 0; i < count; i++)
2951 { 3557 {
2952 struct ipcp_param_lattices *plats = ipa_get_parm_lattices (info, i); 3558 class ipcp_param_lattices *plats = ipa_get_parm_lattices (info, i);
2953 3559
2954 if (!plats->virt_call) 3560 if (!plats->virt_call)
2955 continue; 3561 continue;
2956 3562
2957 ipcp_lattice<ipa_polymorphic_call_context> *ctxlat = &plats->ctxlat; 3563 ipcp_lattice<ipa_polymorphic_call_context> *ctxlat = &plats->ctxlat;
2964 3570
2965 for (val = ctxlat->values; val; val = val->next) 3571 for (val = ctxlat->values; val; val = val->next)
2966 { 3572 {
2967 known_contexts[i] = val->value; 3573 known_contexts[i] = val->value;
2968 perform_estimation_of_a_value (node, known_csts, known_contexts, 3574 perform_estimation_of_a_value (node, known_csts, known_contexts,
2969 known_aggs_ptrs, 3575 known_aggs,
2970 removable_params_cost, 0, val); 3576 removable_params_cost, 0, val);
2971 3577
2972 if (dump_file && (dump_flags & TDF_DETAILS)) 3578 if (dump_file && (dump_flags & TDF_DETAILS))
2973 { 3579 {
2974 fprintf (dump_file, " - estimates for polymorphic context "); 3580 fprintf (dump_file, " - estimates for polymorphic context ");
2982 known_contexts[i] = ipa_polymorphic_call_context (); 3588 known_contexts[i] = ipa_polymorphic_call_context ();
2983 } 3589 }
2984 3590
2985 for (i = 0; i < count; i++) 3591 for (i = 0; i < count; i++)
2986 { 3592 {
2987 struct ipcp_param_lattices *plats = ipa_get_parm_lattices (info, i); 3593 class ipcp_param_lattices *plats = ipa_get_parm_lattices (info, i);
2988 struct ipa_agg_jump_function *ajf; 3594 struct ipa_agg_value_set *agg;
2989 struct ipcp_agg_lattice *aglat; 3595 struct ipcp_agg_lattice *aglat;
2990 3596
2991 if (plats->aggs_bottom || !plats->aggs) 3597 if (plats->aggs_bottom || !plats->aggs)
2992 continue; 3598 continue;
2993 3599
2994 ajf = &known_aggs[i]; 3600 agg = &known_aggs[i];
2995 for (aglat = plats->aggs; aglat; aglat = aglat->next) 3601 for (aglat = plats->aggs; aglat; aglat = aglat->next)
2996 { 3602 {
2997 ipcp_value<tree> *val; 3603 ipcp_value<tree> *val;
2998 if (aglat->bottom || !aglat->values 3604 if (aglat->bottom || !aglat->values
2999 /* If the following is true, the one value is in known_aggs. */ 3605 /* If the following is true, the one value is in known_aggs. */
3001 && aglat->is_single_const ())) 3607 && aglat->is_single_const ()))
3002 continue; 3608 continue;
3003 3609
3004 for (val = aglat->values; val; val = val->next) 3610 for (val = aglat->values; val; val = val->next)
3005 { 3611 {
3006 struct ipa_agg_jf_item item; 3612 struct ipa_agg_value item;
3007 3613
3008 item.offset = aglat->offset; 3614 item.offset = aglat->offset;
3009 item.value = val->value; 3615 item.value = val->value;
3010 vec_safe_push (ajf->items, item); 3616 agg->items.safe_push (item);
3011 3617
3012 perform_estimation_of_a_value (node, known_csts, known_contexts, 3618 perform_estimation_of_a_value (node, known_csts, known_contexts,
3013 known_aggs_ptrs, 3619 known_aggs,
3014 removable_params_cost, 0, val); 3620 removable_params_cost, 0, val);
3015 3621
3016 if (dump_file && (dump_flags & TDF_DETAILS)) 3622 if (dump_file && (dump_flags & TDF_DETAILS))
3017 { 3623 {
3018 fprintf (dump_file, " - estimates for value "); 3624 fprintf (dump_file, " - estimates for value ");
3024 plats->aggs_by_ref ? "ref " : "", 3630 plats->aggs_by_ref ? "ref " : "",
3025 aglat->offset, 3631 aglat->offset,
3026 val->local_time_benefit, val->local_size_cost); 3632 val->local_time_benefit, val->local_size_cost);
3027 } 3633 }
3028 3634
3029 ajf->items->pop (); 3635 agg->items.pop ();
3030 } 3636 }
3031 } 3637 }
3032 } 3638 }
3033
3034 for (i = 0; i < count; i++)
3035 vec_free (known_aggs[i].items);
3036 3639
3037 known_csts.release (); 3640 known_csts.release ();
3038 known_contexts.release (); 3641 known_contexts.release ();
3039 known_aggs.release (); 3642 ipa_release_agg_values (known_aggs);
3040 known_aggs_ptrs.release ();
3041 } 3643 }
3042 3644
3043 3645
3044 /* Add value CUR_VAL and all yet-unsorted values it is dependent on to the 3646 /* Add value CUR_VAL and all yet-unsorted values it is dependent on to the
3045 topological sort of values. */ 3647 topological sort of values. */
3099 they are not there yet. */ 3701 they are not there yet. */
3100 3702
3101 static void 3703 static void
3102 add_all_node_vals_to_toposort (cgraph_node *node, ipa_topo_info *topo) 3704 add_all_node_vals_to_toposort (cgraph_node *node, ipa_topo_info *topo)
3103 { 3705 {
3104 struct ipa_node_params *info = IPA_NODE_REF (node); 3706 class ipa_node_params *info = IPA_NODE_REF (node);
3105 int i, count = ipa_get_param_count (info); 3707 int i, count = ipa_get_param_count (info);
3106 3708
3107 for (i = 0; i < count; i++) 3709 for (i = 0; i < count; i++)
3108 { 3710 {
3109 struct ipcp_param_lattices *plats = ipa_get_parm_lattices (info, i); 3711 class ipcp_param_lattices *plats = ipa_get_parm_lattices (info, i);
3110 ipcp_lattice<tree> *lat = &plats->itself; 3712 ipcp_lattice<tree> *lat = &plats->itself;
3111 struct ipcp_agg_lattice *aglat; 3713 struct ipcp_agg_lattice *aglat;
3112 3714
3113 if (!lat->bottom) 3715 if (!lat->bottom)
3114 { 3716 {
3139 /* One pass of constants propagation along the call graph edges, from callers 3741 /* One pass of constants propagation along the call graph edges, from callers
3140 to callees (requires topological ordering in TOPO), iterate over strongly 3742 to callees (requires topological ordering in TOPO), iterate over strongly
3141 connected components. */ 3743 connected components. */
3142 3744
3143 static void 3745 static void
3144 propagate_constants_topo (struct ipa_topo_info *topo) 3746 propagate_constants_topo (class ipa_topo_info *topo)
3145 { 3747 {
3146 int i; 3748 int i;
3147 3749
3148 for (i = topo->nnodes - 1; i >= 0; i--) 3750 for (i = topo->nnodes - 1; i >= 0; i--)
3149 { 3751 {
3153 3755
3154 /* First, iteratively propagate within the strongly connected component 3756 /* First, iteratively propagate within the strongly connected component
3155 until all lattices stabilize. */ 3757 until all lattices stabilize. */
3156 FOR_EACH_VEC_ELT (cycle_nodes, j, v) 3758 FOR_EACH_VEC_ELT (cycle_nodes, j, v)
3157 if (v->has_gimple_body_p ()) 3759 if (v->has_gimple_body_p ())
3158 push_node_to_stack (topo, v); 3760 {
3761 if (opt_for_fn (v->decl, flag_ipa_cp)
3762 && opt_for_fn (v->decl, optimize))
3763 push_node_to_stack (topo, v);
3764 /* When V is not optimized, we can not push it to stack, but
3765 still we need to set all its callees lattices to bottom. */
3766 else
3767 {
3768 for (cgraph_edge *cs = v->callees; cs; cs = cs->next_callee)
3769 propagate_constants_across_call (cs);
3770 }
3771 }
3159 3772
3160 v = pop_node_from_stack (topo); 3773 v = pop_node_from_stack (topo);
3161 while (v) 3774 while (v)
3162 { 3775 {
3163 struct cgraph_edge *cs; 3776 struct cgraph_edge *cs;
3777 class ipa_node_params *info = NULL;
3778 bool self_scc = true;
3164 3779
3165 for (cs = v->callees; cs; cs = cs->next_callee) 3780 for (cs = v->callees; cs; cs = cs->next_callee)
3166 if (ipa_edge_within_scc (cs)) 3781 if (ipa_edge_within_scc (cs))
3167 { 3782 {
3168 IPA_NODE_REF (v)->node_within_scc = true; 3783 cgraph_node *callee = cs->callee->function_symbol ();
3784
3785 if (v != callee)
3786 self_scc = false;
3787
3788 if (!info)
3789 {
3790 info = IPA_NODE_REF (v);
3791 info->node_within_scc = true;
3792 }
3793
3169 if (propagate_constants_across_call (cs)) 3794 if (propagate_constants_across_call (cs))
3170 push_node_to_stack (topo, cs->callee->function_symbol ()); 3795 push_node_to_stack (topo, callee);
3171 } 3796 }
3797
3798 if (info)
3799 info->node_is_self_scc = self_scc;
3800
3172 v = pop_node_from_stack (topo); 3801 v = pop_node_from_stack (topo);
3173 } 3802 }
3174 3803
3175 /* Afterwards, propagate along edges leading out of the SCC, calculates 3804 /* Afterwards, propagate along edges leading out of the SCC, calculates
3176 the local effects of the discovered constants and all valid values to 3805 the local effects of the discovered constants and all valid values to
3177 their topological sort. */ 3806 their topological sort. */
3178 FOR_EACH_VEC_ELT (cycle_nodes, j, v) 3807 FOR_EACH_VEC_ELT (cycle_nodes, j, v)
3179 if (v->has_gimple_body_p ()) 3808 if (v->has_gimple_body_p ()
3809 && opt_for_fn (v->decl, flag_ipa_cp)
3810 && opt_for_fn (v->decl, optimize))
3180 { 3811 {
3181 struct cgraph_edge *cs; 3812 struct cgraph_edge *cs;
3182 3813
3183 estimate_local_effects (v); 3814 estimate_local_effects (v);
3184 add_all_node_vals_to_toposort (v, topo); 3815 add_all_node_vals_to_toposort (v, topo);
3242 3873
3243 /* Propagate constants, polymorphic contexts and their effects from the 3874 /* Propagate constants, polymorphic contexts and their effects from the
3244 summaries interprocedurally. */ 3875 summaries interprocedurally. */
3245 3876
3246 static void 3877 static void
3247 ipcp_propagate_stage (struct ipa_topo_info *topo) 3878 ipcp_propagate_stage (class ipa_topo_info *topo)
3248 { 3879 {
3249 struct cgraph_node *node; 3880 struct cgraph_node *node;
3250 3881
3251 if (dump_file) 3882 if (dump_file)
3252 fprintf (dump_file, "\n Propagating constants:\n\n"); 3883 fprintf (dump_file, "\n Propagating constants:\n\n");
3253 3884
3254 max_count = profile_count::uninitialized (); 3885 max_count = profile_count::uninitialized ();
3255 3886
3256 FOR_EACH_DEFINED_FUNCTION (node) 3887 FOR_EACH_DEFINED_FUNCTION (node)
3257 { 3888 {
3258 struct ipa_node_params *info = IPA_NODE_REF (node); 3889 if (node->has_gimple_body_p ()
3259 3890 && opt_for_fn (node->decl, flag_ipa_cp)
3260 determine_versionability (node, info); 3891 && opt_for_fn (node->decl, optimize))
3261 if (node->has_gimple_body_p ())
3262 { 3892 {
3263 info->lattices = XCNEWVEC (struct ipcp_param_lattices, 3893 class ipa_node_params *info = IPA_NODE_REF (node);
3894 determine_versionability (node, info);
3895 info->lattices = XCNEWVEC (class ipcp_param_lattices,
3264 ipa_get_param_count (info)); 3896 ipa_get_param_count (info));
3265 initialize_node_lattices (node); 3897 initialize_node_lattices (node);
3266 } 3898 }
3267 ipa_fn_summary *s = ipa_fn_summaries->get (node); 3899 ipa_size_summary *s = ipa_size_summaries->get (node);
3268 if (node->definition && !node->alias && s != NULL) 3900 if (node->definition && !node->alias && s != NULL)
3269 overall_size += s->self_size; 3901 overall_size += s->self_size;
3270 max_count = max_count.max (node->count.ipa ()); 3902 max_count = max_count.max (node->count.ipa ());
3271 } 3903 }
3272 3904
3273 max_new_size = overall_size; 3905 orig_overall_size = overall_size;
3274 if (max_new_size < PARAM_VALUE (PARAM_LARGE_UNIT_INSNS))
3275 max_new_size = PARAM_VALUE (PARAM_LARGE_UNIT_INSNS);
3276 max_new_size += max_new_size * PARAM_VALUE (PARAM_IPCP_UNIT_GROWTH) / 100 + 1;
3277 3906
3278 if (dump_file) 3907 if (dump_file)
3279 fprintf (dump_file, "\noverall_size: %li, max_new_size: %li\n", 3908 fprintf (dump_file, "\noverall_size: %li\n", overall_size);
3280 overall_size, max_new_size);
3281 3909
3282 propagate_constants_topo (topo); 3910 propagate_constants_topo (topo);
3283 if (flag_checking) 3911 if (flag_checking)
3284 ipcp_verify_propagated_values (); 3912 ipcp_verify_propagated_values ();
3285 topo->constants.propagate_effects (); 3913 topo->constants.propagate_effects ();
3322 speculative); 3950 speculative);
3323 found = true; 3951 found = true;
3324 3952
3325 if (cs && !agg_contents && !polymorphic) 3953 if (cs && !agg_contents && !polymorphic)
3326 { 3954 {
3327 struct ipa_node_params *info = IPA_NODE_REF (node); 3955 class ipa_node_params *info = IPA_NODE_REF (node);
3328 int c = ipa_get_controlled_uses (info, param_index); 3956 int c = ipa_get_controlled_uses (info, param_index);
3329 if (c != IPA_UNDESCRIBED_USE) 3957 if (c != IPA_UNDESCRIBED_USE)
3330 { 3958 {
3331 struct ipa_ref *to_del; 3959 struct ipa_ref *to_del;
3332 3960
3355 class edge_clone_summary; 3983 class edge_clone_summary;
3356 static call_summary <edge_clone_summary *> *edge_clone_summaries = NULL; 3984 static call_summary <edge_clone_summary *> *edge_clone_summaries = NULL;
3357 3985
3358 /* Edge clone summary. */ 3986 /* Edge clone summary. */
3359 3987
3360 struct edge_clone_summary 3988 class edge_clone_summary
3361 { 3989 {
3990 public:
3362 /* Default constructor. */ 3991 /* Default constructor. */
3363 edge_clone_summary (): prev_clone (NULL), next_clone (NULL) {} 3992 edge_clone_summary (): prev_clone (NULL), next_clone (NULL) {}
3364 3993
3365 /* Default destructor. */ 3994 /* Default destructor. */
3366 ~edge_clone_summary () 3995 ~edge_clone_summary ()
3402 dst_data->prev_clone = src_edge; 4031 dst_data->prev_clone = src_edge;
3403 dst_data->next_clone = src_data->next_clone; 4032 dst_data->next_clone = src_data->next_clone;
3404 src_data->next_clone = dst_edge; 4033 src_data->next_clone = dst_edge;
3405 } 4034 }
3406 4035
3407 /* See if NODE is a clone with a known aggregate value at a given OFFSET of a
3408 parameter with the given INDEX. */
3409
3410 static tree
3411 get_clone_agg_value (struct cgraph_node *node, HOST_WIDE_INT offset,
3412 int index)
3413 {
3414 struct ipa_agg_replacement_value *aggval;
3415
3416 aggval = ipa_get_agg_replacements_for_node (node);
3417 while (aggval)
3418 {
3419 if (aggval->offset == offset
3420 && aggval->index == index)
3421 return aggval->value;
3422 aggval = aggval->next;
3423 }
3424 return NULL_TREE;
3425 }
3426
3427 /* Return true is NODE is DEST or its clone for all contexts. */ 4036 /* Return true is NODE is DEST or its clone for all contexts. */
3428 4037
3429 static bool 4038 static bool
3430 same_node_or_its_all_contexts_clone_p (cgraph_node *node, cgraph_node *dest) 4039 same_node_or_its_all_contexts_clone_p (cgraph_node *node, cgraph_node *dest)
3431 { 4040 {
3432 if (node == dest) 4041 if (node == dest)
3433 return true; 4042 return true;
3434 4043
3435 struct ipa_node_params *info = IPA_NODE_REF (node); 4044 class ipa_node_params *info = IPA_NODE_REF (node);
3436 return info->is_all_contexts_clone && info->ipcp_orig_node == dest; 4045 return info->is_all_contexts_clone && info->ipcp_orig_node == dest;
3437 } 4046 }
3438 4047
3439 /* Return true if edge CS does bring about the value described by SRC to 4048 /* Return true if edge CS does bring about the value described by SRC to
3440 DEST_VAL of node DEST or its clone for all contexts. */ 4049 DEST_VAL of node DEST or its clone for all contexts. */
3441 4050
3442 static bool 4051 static bool
3443 cgraph_edge_brings_value_p (cgraph_edge *cs, ipcp_value_source<tree> *src, 4052 cgraph_edge_brings_value_p (cgraph_edge *cs, ipcp_value_source<tree> *src,
3444 cgraph_node *dest, ipcp_value<tree> *dest_val) 4053 cgraph_node *dest, ipcp_value<tree> *dest_val)
3445 { 4054 {
3446 struct ipa_node_params *caller_info = IPA_NODE_REF (cs->caller); 4055 class ipa_node_params *caller_info = IPA_NODE_REF (cs->caller);
3447 enum availability availability; 4056 enum availability availability;
3448 cgraph_node *real_dest = cs->callee->function_symbol (&availability); 4057 cgraph_node *real_dest = cs->callee->function_symbol (&availability);
3449 4058
3450 if (!same_node_or_its_all_contexts_clone_p (real_dest, dest) 4059 if (availability <= AVAIL_INTERPOSABLE
3451 || availability <= AVAIL_INTERPOSABLE 4060 || !same_node_or_its_all_contexts_clone_p (real_dest, dest)
3452 || caller_info->node_dead) 4061 || caller_info->node_dead)
3453 return false; 4062 return false;
3454 4063
3455 if (!src->val) 4064 if (!src->val)
3456 return true; 4065 return true;
3472 way. */ 4081 way. */
3473 if (src->val == dest_val) 4082 if (src->val == dest_val)
3474 return true; 4083 return true;
3475 4084
3476 struct ipcp_agg_lattice *aglat; 4085 struct ipcp_agg_lattice *aglat;
3477 struct ipcp_param_lattices *plats = ipa_get_parm_lattices (caller_info, 4086 class ipcp_param_lattices *plats = ipa_get_parm_lattices (caller_info,
3478 src->index); 4087 src->index);
3479 if (src->offset == -1) 4088 if (src->offset == -1)
3480 return (plats->itself.is_single_const () 4089 return (plats->itself.is_single_const ()
3481 && values_equal_for_ipcp_p (src->val->value, 4090 && values_equal_for_ipcp_p (src->val->value,
3482 plats->itself.values->value)); 4091 plats->itself.values->value));
3501 cgraph_edge_brings_value_p (cgraph_edge *cs, 4110 cgraph_edge_brings_value_p (cgraph_edge *cs,
3502 ipcp_value_source<ipa_polymorphic_call_context> *src, 4111 ipcp_value_source<ipa_polymorphic_call_context> *src,
3503 cgraph_node *dest, 4112 cgraph_node *dest,
3504 ipcp_value<ipa_polymorphic_call_context> *) 4113 ipcp_value<ipa_polymorphic_call_context> *)
3505 { 4114 {
3506 struct ipa_node_params *caller_info = IPA_NODE_REF (cs->caller); 4115 class ipa_node_params *caller_info = IPA_NODE_REF (cs->caller);
3507 cgraph_node *real_dest = cs->callee->function_symbol (); 4116 enum availability avail;
3508 4117 cgraph_node *real_dest = cs->callee->function_symbol (&avail);
3509 if (!same_node_or_its_all_contexts_clone_p (real_dest, dest) 4118
4119 if (avail <= AVAIL_INTERPOSABLE
4120 || !same_node_or_its_all_contexts_clone_p (real_dest, dest)
3510 || caller_info->node_dead) 4121 || caller_info->node_dead)
3511 return false; 4122 return false;
3512 if (!src->val) 4123 if (!src->val)
3513 return true; 4124 return true;
3514 4125
3515 if (caller_info->ipcp_orig_node) 4126 if (caller_info->ipcp_orig_node)
3516 return (caller_info->known_contexts.length () > (unsigned) src->index) 4127 return (caller_info->known_contexts.length () > (unsigned) src->index)
3517 && values_equal_for_ipcp_p (src->val->value, 4128 && values_equal_for_ipcp_p (src->val->value,
3518 caller_info->known_contexts[src->index]); 4129 caller_info->known_contexts[src->index]);
3519 4130
3520 struct ipcp_param_lattices *plats = ipa_get_parm_lattices (caller_info, 4131 class ipcp_param_lattices *plats = ipa_get_parm_lattices (caller_info,
3521 src->index); 4132 src->index);
3522 return plats->ctxlat.is_single_const () 4133 return plats->ctxlat.is_single_const ()
3523 && values_equal_for_ipcp_p (src->val->value, 4134 && values_equal_for_ipcp_p (src->val->value,
3524 plats->ctxlat.values->value); 4135 plats->ctxlat.values->value);
3525 } 4136 }
3575 return false; 4186 return false;
3576 4187
3577 *freq_sum = freq; 4188 *freq_sum = freq;
3578 *count_sum = cnt; 4189 *count_sum = cnt;
3579 *caller_count = count; 4190 *caller_count = count;
4191
4192 if (!hot && IPA_NODE_REF (dest)->node_within_scc)
4193 {
4194 struct cgraph_edge *cs;
4195
4196 /* Cold non-SCC source edge could trigger hot recursive execution of
4197 function. Consider the case as hot and rely on following cost model
4198 computation to further select right one. */
4199 for (cs = dest->callers; cs; cs = cs->next_caller)
4200 if (cs->caller == dest && cs->maybe_hot_p ())
4201 return true;
4202 }
4203
3580 return hot; 4204 return hot;
4205 }
4206
4207 /* Given a NODE, and a set of its CALLERS, try to adjust order of the callers
4208 to let a non-self-recursive caller be the first element. Thus, we can
4209 simplify intersecting operations on values that arrive from all of these
4210 callers, especially when there exists self-recursive call. Return true if
4211 this kind of adjustment is possible. */
4212
4213 static bool
4214 adjust_callers_for_value_intersection (vec<cgraph_edge *> callers,
4215 cgraph_node *node)
4216 {
4217 for (unsigned i = 0; i < callers.length (); i++)
4218 {
4219 cgraph_edge *cs = callers[i];
4220
4221 if (cs->caller != node)
4222 {
4223 if (i > 0)
4224 {
4225 callers[i] = callers[0];
4226 callers[0] = cs;
4227 }
4228 return true;
4229 }
4230 }
4231 return false;
3581 } 4232 }
3582 4233
3583 /* Return a vector of incoming edges that do bring value VAL to node DEST. It 4234 /* Return a vector of incoming edges that do bring value VAL to node DEST. It
3584 is assumed their number is known and equal to CALLER_COUNT. */ 4235 is assumed their number is known and equal to CALLER_COUNT. */
3585 4236
3601 ret.quick_push (cs); 4252 ret.quick_push (cs);
3602 cs = get_next_cgraph_edge_clone (cs); 4253 cs = get_next_cgraph_edge_clone (cs);
3603 } 4254 }
3604 } 4255 }
3605 4256
4257 if (caller_count > 1)
4258 adjust_callers_for_value_intersection (ret, dest);
4259
3606 return ret; 4260 return ret;
3607 } 4261 }
3608 4262
3609 /* Construct a replacement map for a know VALUE for a formal parameter PARAM. 4263 /* Construct a replacement map for a know VALUE for a formal parameter PARAM.
3610 Return it or NULL if for some reason it cannot be created. */ 4264 Return it or NULL if for some reason it cannot be created. */
3611 4265
3612 static struct ipa_replace_map * 4266 static struct ipa_replace_map *
3613 get_replacement_map (struct ipa_node_params *info, tree value, int parm_num) 4267 get_replacement_map (class ipa_node_params *info, tree value, int parm_num)
3614 { 4268 {
3615 struct ipa_replace_map *replace_map; 4269 struct ipa_replace_map *replace_map;
3616
3617 4270
3618 replace_map = ggc_alloc<ipa_replace_map> (); 4271 replace_map = ggc_alloc<ipa_replace_map> ();
3619 if (dump_file) 4272 if (dump_file)
3620 { 4273 {
3621 fprintf (dump_file, " replacing "); 4274 fprintf (dump_file, " replacing ");
3623 4276
3624 fprintf (dump_file, " with const "); 4277 fprintf (dump_file, " with const ");
3625 print_generic_expr (dump_file, value); 4278 print_generic_expr (dump_file, value);
3626 fprintf (dump_file, "\n"); 4279 fprintf (dump_file, "\n");
3627 } 4280 }
3628 replace_map->old_tree = NULL;
3629 replace_map->parm_num = parm_num; 4281 replace_map->parm_num = parm_num;
3630 replace_map->new_tree = value; 4282 replace_map->new_tree = value;
3631 replace_map->replace_p = true;
3632 replace_map->ref_p = false;
3633
3634 return replace_map; 4283 return replace_map;
3635 } 4284 }
3636 4285
3637 /* Dump new profiling counts */ 4286 /* Dump new profiling counts */
3638 4287
3646 new_node->count.dump (dump_file); 4295 new_node->count.dump (dump_file);
3647 fprintf (dump_file, "\n"); 4296 fprintf (dump_file, "\n");
3648 for (cs = new_node->callees; cs; cs = cs->next_callee) 4297 for (cs = new_node->callees; cs; cs = cs->next_callee)
3649 { 4298 {
3650 fprintf (dump_file, " edge to %s has count ", 4299 fprintf (dump_file, " edge to %s has count ",
3651 cs->callee->name ()); 4300 cs->callee->dump_name ());
3652 cs->count.dump (dump_file); 4301 cs->count.dump (dump_file);
3653 fprintf (dump_file, "\n"); 4302 fprintf (dump_file, "\n");
3654 } 4303 }
3655 4304
3656 fprintf (dump_file, " setting count of the original node to "); 4305 fprintf (dump_file, " setting count of the original node to ");
3657 orig_node->count.dump (dump_file); 4306 orig_node->count.dump (dump_file);
3658 fprintf (dump_file, "\n"); 4307 fprintf (dump_file, "\n");
3659 for (cs = orig_node->callees; cs; cs = cs->next_callee) 4308 for (cs = orig_node->callees; cs; cs = cs->next_callee)
3660 { 4309 {
3661 fprintf (dump_file, " edge to %s is left with ", 4310 fprintf (dump_file, " edge to %s is left with ",
3662 cs->callee->name ()); 4311 cs->callee->dump_name ());
3663 cs->count.dump (dump_file); 4312 cs->count.dump (dump_file);
3664 fprintf (dump_file, "\n"); 4313 fprintf (dump_file, "\n");
3665 } 4314 }
3666 } 4315 }
3667 4316
3674 { 4323 {
3675 struct cgraph_edge *cs; 4324 struct cgraph_edge *cs;
3676 struct caller_statistics stats; 4325 struct caller_statistics stats;
3677 profile_count new_sum, orig_sum; 4326 profile_count new_sum, orig_sum;
3678 profile_count remainder, orig_node_count = orig_node->count; 4327 profile_count remainder, orig_node_count = orig_node->count;
4328 profile_count orig_new_node_count = new_node->count;
3679 4329
3680 if (!(orig_node_count.ipa () > profile_count::zero ())) 4330 if (!(orig_node_count.ipa () > profile_count::zero ()))
3681 return; 4331 return;
3682 4332
3683 init_caller_stats (&stats); 4333 init_caller_stats (&stats);
3710 } 4360 }
3711 } 4361 }
3712 4362
3713 remainder = orig_node_count.combine_with_ipa_count (orig_node_count.ipa () 4363 remainder = orig_node_count.combine_with_ipa_count (orig_node_count.ipa ()
3714 - new_sum.ipa ()); 4364 - new_sum.ipa ());
4365
4366 /* With partial train run we do not want to assume that original's
4367 count is zero whenever we redurect all executed edges to clone.
4368 Simply drop profile to local one in this case. */
4369 if (remainder.ipa_p () && !remainder.ipa ().nonzero_p ()
4370 && orig_node->count.ipa_p () && orig_node->count.ipa ().nonzero_p ()
4371 && flag_profile_partial_training)
4372 remainder = remainder.guessed_local ();
4373
3715 new_sum = orig_node_count.combine_with_ipa_count (new_sum); 4374 new_sum = orig_node_count.combine_with_ipa_count (new_sum);
4375 new_node->count = new_sum;
3716 orig_node->count = remainder; 4376 orig_node->count = remainder;
3717 4377
4378 profile_count::adjust_for_ipa_scaling (&new_sum, &orig_new_node_count);
3718 for (cs = new_node->callees; cs; cs = cs->next_callee) 4379 for (cs = new_node->callees; cs; cs = cs->next_callee)
3719 cs->count = cs->count.apply_scale (new_sum, orig_node_count); 4380 cs->count = cs->count.apply_scale (new_sum, orig_new_node_count);
3720 4381 for (cs = new_node->indirect_calls; cs; cs = cs->next_callee)
4382 cs->count = cs->count.apply_scale (new_sum, orig_new_node_count);
4383
4384 profile_count::adjust_for_ipa_scaling (&remainder, &orig_node_count);
3721 for (cs = orig_node->callees; cs; cs = cs->next_callee) 4385 for (cs = orig_node->callees; cs; cs = cs->next_callee)
4386 cs->count = cs->count.apply_scale (remainder, orig_node_count);
4387 for (cs = orig_node->indirect_calls; cs; cs = cs->next_callee)
3722 cs->count = cs->count.apply_scale (remainder, orig_node_count); 4388 cs->count = cs->count.apply_scale (remainder, orig_node_count);
3723 4389
3724 if (dump_file) 4390 if (dump_file)
3725 dump_profile_updates (orig_node, new_node); 4391 dump_profile_updates (orig_node, new_node);
3726 } 4392 }
3762 cs->count -= dec; 4428 cs->count -= dec;
3763 } 4429 }
3764 4430
3765 if (dump_file) 4431 if (dump_file)
3766 dump_profile_updates (orig_node, new_node); 4432 dump_profile_updates (orig_node, new_node);
4433 }
4434
4435 /* Return true if we would like to remove a parameter from NODE when cloning it
4436 with KNOWN_CSTS scalar constants. */
4437
4438 static bool
4439 want_remove_some_param_p (cgraph_node *node, vec<tree> known_csts)
4440 {
4441 auto_vec<bool, 16> surviving;
4442 bool filled_vec = false;
4443 ipa_node_params *info = IPA_NODE_REF (node);
4444 int i, count = ipa_get_param_count (info);
4445
4446 for (i = 0; i < count; i++)
4447 {
4448 if (!known_csts[i] && ipa_is_param_used (info, i))
4449 continue;
4450
4451 if (!filled_vec)
4452 {
4453 if (!node->clone.param_adjustments)
4454 return true;
4455 node->clone.param_adjustments->get_surviving_params (&surviving);
4456 filled_vec = true;
4457 }
4458 if (surviving.length() < (unsigned) i && surviving[i])
4459 return true;
4460 }
4461 return false;
3767 } 4462 }
3768 4463
3769 /* Create a specialized version of NODE with known constants in KNOWN_CSTS, 4464 /* Create a specialized version of NODE with known constants in KNOWN_CSTS,
3770 known contexts in KNOWN_CONTEXTS and known aggregate values in AGGVALS and 4465 known contexts in KNOWN_CONTEXTS and known aggregate values in AGGVALS and
3771 redirect all edges in CALLERS to it. */ 4466 redirect all edges in CALLERS to it. */
3775 vec<tree> known_csts, 4470 vec<tree> known_csts,
3776 vec<ipa_polymorphic_call_context> known_contexts, 4471 vec<ipa_polymorphic_call_context> known_contexts,
3777 struct ipa_agg_replacement_value *aggvals, 4472 struct ipa_agg_replacement_value *aggvals,
3778 vec<cgraph_edge *> callers) 4473 vec<cgraph_edge *> callers)
3779 { 4474 {
3780 struct ipa_node_params *new_info, *info = IPA_NODE_REF (node); 4475 class ipa_node_params *new_info, *info = IPA_NODE_REF (node);
3781 vec<ipa_replace_map *, va_gc> *replace_trees = NULL; 4476 vec<ipa_replace_map *, va_gc> *replace_trees = NULL;
4477 vec<ipa_adjusted_param, va_gc> *new_params = NULL;
3782 struct ipa_agg_replacement_value *av; 4478 struct ipa_agg_replacement_value *av;
3783 struct cgraph_node *new_node; 4479 struct cgraph_node *new_node;
3784 int i, count = ipa_get_param_count (info); 4480 int i, count = ipa_get_param_count (info);
3785 bitmap args_to_skip; 4481 ipa_param_adjustments *old_adjustments = node->clone.param_adjustments;
3786 4482 ipa_param_adjustments *new_adjustments;
3787 gcc_assert (!info->ipcp_orig_node); 4483 gcc_assert (!info->ipcp_orig_node);
3788 4484 gcc_assert (node->can_change_signature
3789 if (node->local.can_change_signature) 4485 || !old_adjustments);
3790 { 4486
3791 args_to_skip = BITMAP_GGC_ALLOC (); 4487 if (old_adjustments)
4488 {
4489 /* At the moment all IPA optimizations should use the number of
4490 parameters of the prevailing decl as the m_always_copy_start.
4491 Handling any other value would complicate the code below, so for the
4492 time bing let's only assert it is so. */
4493 gcc_assert (old_adjustments->m_always_copy_start == count
4494 || old_adjustments->m_always_copy_start < 0);
4495 int old_adj_count = vec_safe_length (old_adjustments->m_adj_params);
4496 for (i = 0; i < old_adj_count; i++)
4497 {
4498 ipa_adjusted_param *old_adj = &(*old_adjustments->m_adj_params)[i];
4499 if (!node->can_change_signature
4500 || old_adj->op != IPA_PARAM_OP_COPY
4501 || (!known_csts[old_adj->base_index]
4502 && ipa_is_param_used (info, old_adj->base_index)))
4503 {
4504 ipa_adjusted_param new_adj = *old_adj;
4505
4506 new_adj.prev_clone_adjustment = true;
4507 new_adj.prev_clone_index = i;
4508 vec_safe_push (new_params, new_adj);
4509 }
4510 }
4511 bool skip_return = old_adjustments->m_skip_return;
4512 new_adjustments = (new (ggc_alloc <ipa_param_adjustments> ())
4513 ipa_param_adjustments (new_params, count,
4514 skip_return));
4515 }
4516 else if (node->can_change_signature
4517 && want_remove_some_param_p (node, known_csts))
4518 {
4519 ipa_adjusted_param adj;
4520 memset (&adj, 0, sizeof (adj));
4521 adj.op = IPA_PARAM_OP_COPY;
3792 for (i = 0; i < count; i++) 4522 for (i = 0; i < count; i++)
3793 { 4523 if (!known_csts[i] && ipa_is_param_used (info, i))
3794 tree t = known_csts[i]; 4524 {
3795 4525 adj.base_index = i;
3796 if (t || !ipa_is_param_used (info, i)) 4526 adj.prev_clone_index = i;
3797 bitmap_set_bit (args_to_skip, i); 4527 vec_safe_push (new_params, adj);
3798 } 4528 }
4529 new_adjustments = (new (ggc_alloc <ipa_param_adjustments> ())
4530 ipa_param_adjustments (new_params, count, false));
3799 } 4531 }
3800 else 4532 else
3801 { 4533 new_adjustments = NULL;
3802 args_to_skip = NULL; 4534
3803 if (dump_file && (dump_flags & TDF_DETAILS)) 4535 replace_trees = vec_safe_copy (node->clone.tree_map);
3804 fprintf (dump_file, " cannot change function signature\n");
3805 }
3806
3807 for (i = 0; i < count; i++) 4536 for (i = 0; i < count; i++)
3808 { 4537 {
3809 tree t = known_csts[i]; 4538 tree t = known_csts[i];
3810 if (t) 4539 if (t)
3811 { 4540 {
3826 self_recursive_calls.safe_push (cs); 4555 self_recursive_calls.safe_push (cs);
3827 callers.unordered_remove (i); 4556 callers.unordered_remove (i);
3828 } 4557 }
3829 } 4558 }
3830 4559
4560 unsigned &suffix_counter = clone_num_suffixes->get_or_insert (
4561 IDENTIFIER_POINTER (DECL_ASSEMBLER_NAME (
4562 node->decl)));
3831 new_node = node->create_virtual_clone (callers, replace_trees, 4563 new_node = node->create_virtual_clone (callers, replace_trees,
3832 args_to_skip, "constprop"); 4564 new_adjustments, "constprop",
4565 suffix_counter);
4566 suffix_counter++;
3833 4567
3834 bool have_self_recursive_calls = !self_recursive_calls.is_empty (); 4568 bool have_self_recursive_calls = !self_recursive_calls.is_empty ();
3835 for (unsigned j = 0; j < self_recursive_calls.length (); j++) 4569 for (unsigned j = 0; j < self_recursive_calls.length (); j++)
3836 { 4570 {
3837 cgraph_edge *cs = get_next_cgraph_edge_clone (self_recursive_calls[j]); 4571 cgraph_edge *cs = get_next_cgraph_edge_clone (self_recursive_calls[j]);
3871 } 4605 }
3872 ipa_check_create_node_params (); 4606 ipa_check_create_node_params ();
3873 update_profiling_info (node, new_node); 4607 update_profiling_info (node, new_node);
3874 new_info = IPA_NODE_REF (new_node); 4608 new_info = IPA_NODE_REF (new_node);
3875 new_info->ipcp_orig_node = node; 4609 new_info->ipcp_orig_node = node;
4610 new_node->ipcp_clone = true;
3876 new_info->known_csts = known_csts; 4611 new_info->known_csts = known_csts;
3877 new_info->known_contexts = known_contexts; 4612 new_info->known_contexts = known_contexts;
3878 4613
3879 ipcp_discover_new_direct_edges (new_node, known_csts, known_contexts, aggvals); 4614 ipcp_discover_new_direct_edges (new_node, known_csts, known_contexts, aggvals);
3880 4615
3881 callers.release (); 4616 callers.release ();
3882 return new_node; 4617 return new_node;
3883 } 4618 }
3884 4619
3885 /* Return true, if JFUNC, which describes a i-th parameter of call CS, is a 4620 /* Return true, if JFUNC, which describes a i-th parameter of call CS, is a
3886 simple no-operation pass-through function to itself. */ 4621 pass-through function to itself. When SIMPLE is true, further check if
4622 JFUNC is a simple no-operation pass-through. */
3887 4623
3888 static bool 4624 static bool
3889 self_recursive_pass_through_p (cgraph_edge *cs, ipa_jump_func *jfunc, int i) 4625 self_recursive_pass_through_p (cgraph_edge *cs, ipa_jump_func *jfunc, int i,
4626 bool simple = true)
3890 { 4627 {
3891 enum availability availability; 4628 enum availability availability;
3892 if (cs->caller == cs->callee->function_symbol (&availability) 4629 if (cs->caller == cs->callee->function_symbol (&availability)
3893 && availability > AVAIL_INTERPOSABLE 4630 && availability > AVAIL_INTERPOSABLE
3894 && jfunc->type == IPA_JF_PASS_THROUGH 4631 && jfunc->type == IPA_JF_PASS_THROUGH
3895 && ipa_get_jf_pass_through_operation (jfunc) == NOP_EXPR 4632 && (!simple || ipa_get_jf_pass_through_operation (jfunc) == NOP_EXPR)
3896 && ipa_get_jf_pass_through_formal_id (jfunc) == i) 4633 && ipa_get_jf_pass_through_formal_id (jfunc) == i)
4634 return true;
4635 return false;
4636 }
4637
4638 /* Return true, if JFUNC, which describes a part of an aggregate represented
4639 or pointed to by the i-th parameter of call CS, is a pass-through function
4640 to itself. When SIMPLE is true, further check if JFUNC is a simple
4641 no-operation pass-through. */
4642
4643 static bool
4644 self_recursive_agg_pass_through_p (cgraph_edge *cs, ipa_agg_jf_item *jfunc,
4645 int i, bool simple = true)
4646 {
4647 enum availability availability;
4648 if (cs->caller == cs->callee->function_symbol (&availability)
4649 && availability > AVAIL_INTERPOSABLE
4650 && jfunc->jftype == IPA_JF_LOAD_AGG
4651 && jfunc->offset == jfunc->value.load_agg.offset
4652 && (!simple || jfunc->value.pass_through.operation == NOP_EXPR)
4653 && jfunc->value.pass_through.formal_id == i
4654 && useless_type_conversion_p (jfunc->value.load_agg.type, jfunc->type))
3897 return true; 4655 return true;
3898 return false; 4656 return false;
3899 } 4657 }
3900 4658
3901 /* Given a NODE, and a subset of its CALLERS, try to populate blanks slots in 4659 /* Given a NODE, and a subset of its CALLERS, try to populate blanks slots in
3904 static void 4662 static void
3905 find_more_scalar_values_for_callers_subset (struct cgraph_node *node, 4663 find_more_scalar_values_for_callers_subset (struct cgraph_node *node,
3906 vec<tree> known_csts, 4664 vec<tree> known_csts,
3907 vec<cgraph_edge *> callers) 4665 vec<cgraph_edge *> callers)
3908 { 4666 {
3909 struct ipa_node_params *info = IPA_NODE_REF (node); 4667 class ipa_node_params *info = IPA_NODE_REF (node);
3910 int i, count = ipa_get_param_count (info); 4668 int i, count = ipa_get_param_count (info);
3911 4669
3912 for (i = 0; i < count; i++) 4670 for (i = 0; i < count; i++)
3913 { 4671 {
3914 struct cgraph_edge *cs; 4672 struct cgraph_edge *cs;
3923 FOR_EACH_VEC_ELT (callers, j, cs) 4681 FOR_EACH_VEC_ELT (callers, j, cs)
3924 { 4682 {
3925 struct ipa_jump_func *jump_func; 4683 struct ipa_jump_func *jump_func;
3926 tree t; 4684 tree t;
3927 4685
3928 if (IPA_NODE_REF (cs->caller)->node_dead) 4686 if (!IPA_EDGE_REF (cs)
3929 continue; 4687 || i >= ipa_get_cs_argument_count (IPA_EDGE_REF (cs))
3930
3931 if (i >= ipa_get_cs_argument_count (IPA_EDGE_REF (cs))
3932 || (i == 0 4688 || (i == 0
3933 && call_passes_through_thunk_p (cs))) 4689 && call_passes_through_thunk_p (cs)))
3934 { 4690 {
3935 newval = NULL_TREE; 4691 newval = NULL_TREE;
3936 break; 4692 break;
3937 } 4693 }
3938 jump_func = ipa_get_ith_jump_func (IPA_EDGE_REF (cs), i); 4694 jump_func = ipa_get_ith_jump_func (IPA_EDGE_REF (cs), i);
3939 if (self_recursive_pass_through_p (cs, jump_func, i)) 4695
3940 continue; 4696 /* Besides simple pass-through jump function, arithmetic jump
3941 4697 function could also introduce argument-direct-pass-through for
3942 t = ipa_value_from_jfunc (IPA_NODE_REF (cs->caller), jump_func, type); 4698 self-feeding recursive call. For example,
4699
4700 fn (int i)
4701 {
4702 fn (i & 1);
4703 }
4704
4705 Given that i is 0, recursive propagation via (i & 1) also gets
4706 0. */
4707 if (self_recursive_pass_through_p (cs, jump_func, i, false))
4708 {
4709 gcc_assert (newval);
4710 t = ipa_get_jf_arith_result (
4711 ipa_get_jf_pass_through_operation (jump_func),
4712 newval,
4713 ipa_get_jf_pass_through_operand (jump_func),
4714 type);
4715 }
4716 else
4717 t = ipa_value_from_jfunc (IPA_NODE_REF (cs->caller), jump_func,
4718 type);
3943 if (!t 4719 if (!t
3944 || (newval 4720 || (newval
3945 && !values_equal_for_ipcp_p (t, newval)) 4721 && !values_equal_for_ipcp_p (t, newval))
3946 || (!first && !newval)) 4722 || (!first && !newval))
3947 { 4723 {
3995 bool first = true; 4771 bool first = true;
3996 int j; 4772 int j;
3997 4773
3998 FOR_EACH_VEC_ELT (callers, j, cs) 4774 FOR_EACH_VEC_ELT (callers, j, cs)
3999 { 4775 {
4000 if (i >= ipa_get_cs_argument_count (IPA_EDGE_REF (cs))) 4776 if (!IPA_EDGE_REF (cs)
4777 || i >= ipa_get_cs_argument_count (IPA_EDGE_REF (cs)))
4001 return; 4778 return;
4002 ipa_jump_func *jfunc = ipa_get_ith_jump_func (IPA_EDGE_REF (cs), 4779 ipa_jump_func *jfunc = ipa_get_ith_jump_func (IPA_EDGE_REF (cs),
4003 i); 4780 i);
4004 ipa_polymorphic_call_context ctx; 4781 ipa_polymorphic_call_context ctx;
4005 ctx = ipa_context_from_jfunc (IPA_NODE_REF (cs->caller), cs, i, 4782 ctx = ipa_context_from_jfunc (IPA_NODE_REF (cs->caller), cs, i,
4036 } 4813 }
4037 4814
4038 /* Go through PLATS and create a vector of values consisting of values and 4815 /* Go through PLATS and create a vector of values consisting of values and
4039 offsets (minus OFFSET) of lattices that contain only a single value. */ 4816 offsets (minus OFFSET) of lattices that contain only a single value. */
4040 4817
4041 static vec<ipa_agg_jf_item> 4818 static vec<ipa_agg_value>
4042 copy_plats_to_inter (struct ipcp_param_lattices *plats, HOST_WIDE_INT offset) 4819 copy_plats_to_inter (class ipcp_param_lattices *plats, HOST_WIDE_INT offset)
4043 { 4820 {
4044 vec<ipa_agg_jf_item> res = vNULL; 4821 vec<ipa_agg_value> res = vNULL;
4045 4822
4046 if (!plats->aggs || plats->aggs_contain_variable || plats->aggs_bottom) 4823 if (!plats->aggs || plats->aggs_contain_variable || plats->aggs_bottom)
4047 return vNULL; 4824 return vNULL;
4048 4825
4049 for (struct ipcp_agg_lattice *aglat = plats->aggs; aglat; aglat = aglat->next) 4826 for (struct ipcp_agg_lattice *aglat = plats->aggs; aglat; aglat = aglat->next)
4050 if (aglat->is_single_const ()) 4827 if (aglat->is_single_const ())
4051 { 4828 {
4052 struct ipa_agg_jf_item ti; 4829 struct ipa_agg_value ti;
4053 ti.offset = aglat->offset - offset; 4830 ti.offset = aglat->offset - offset;
4054 ti.value = aglat->values->value; 4831 ti.value = aglat->values->value;
4055 res.safe_push (ti); 4832 res.safe_push (ti);
4056 } 4833 }
4057 return res; 4834 return res;
4059 4836
4060 /* Intersect all values in INTER with single value lattices in PLATS (while 4837 /* Intersect all values in INTER with single value lattices in PLATS (while
4061 subtracting OFFSET). */ 4838 subtracting OFFSET). */
4062 4839
4063 static void 4840 static void
4064 intersect_with_plats (struct ipcp_param_lattices *plats, 4841 intersect_with_plats (class ipcp_param_lattices *plats,
4065 vec<ipa_agg_jf_item> *inter, 4842 vec<ipa_agg_value> *inter,
4066 HOST_WIDE_INT offset) 4843 HOST_WIDE_INT offset)
4067 { 4844 {
4068 struct ipcp_agg_lattice *aglat; 4845 struct ipcp_agg_lattice *aglat;
4069 struct ipa_agg_jf_item *item; 4846 struct ipa_agg_value *item;
4070 int k; 4847 int k;
4071 4848
4072 if (!plats->aggs || plats->aggs_contain_variable || plats->aggs_bottom) 4849 if (!plats->aggs || plats->aggs_contain_variable || plats->aggs_bottom)
4073 { 4850 {
4074 inter->release (); 4851 inter->release ();
4085 { 4862 {
4086 if (aglat->offset - offset > item->offset) 4863 if (aglat->offset - offset > item->offset)
4087 break; 4864 break;
4088 if (aglat->offset - offset == item->offset) 4865 if (aglat->offset - offset == item->offset)
4089 { 4866 {
4090 gcc_checking_assert (item->value); 4867 if (aglat->is_single_const ())
4091 if (aglat->is_single_const () 4868 {
4092 && values_equal_for_ipcp_p (item->value, 4869 tree value = aglat->values->value;
4093 aglat->values->value)) 4870
4094 found = true; 4871 if (values_equal_for_ipcp_p (item->value, value))
4872 found = true;
4873 }
4095 break; 4874 break;
4096 } 4875 }
4097 aglat = aglat->next; 4876 aglat = aglat->next;
4098 } 4877 }
4099 if (!found) 4878 if (!found)
4102 } 4881 }
4103 4882
4104 /* Copy aggregate replacement values of NODE (which is an IPA-CP clone) to the 4883 /* Copy aggregate replacement values of NODE (which is an IPA-CP clone) to the
4105 vector result while subtracting OFFSET from the individual value offsets. */ 4884 vector result while subtracting OFFSET from the individual value offsets. */
4106 4885
4107 static vec<ipa_agg_jf_item> 4886 static vec<ipa_agg_value>
4108 agg_replacements_to_vector (struct cgraph_node *node, int index, 4887 agg_replacements_to_vector (struct cgraph_node *node, int index,
4109 HOST_WIDE_INT offset) 4888 HOST_WIDE_INT offset)
4110 { 4889 {
4111 struct ipa_agg_replacement_value *av; 4890 struct ipa_agg_replacement_value *av;
4112 vec<ipa_agg_jf_item> res = vNULL; 4891 vec<ipa_agg_value> res = vNULL;
4113 4892
4114 for (av = ipa_get_agg_replacements_for_node (node); av; av = av->next) 4893 for (av = ipa_get_agg_replacements_for_node (node); av; av = av->next)
4115 if (av->index == index 4894 if (av->index == index
4116 && (av->offset - offset) >= 0) 4895 && (av->offset - offset) >= 0)
4117 { 4896 {
4118 struct ipa_agg_jf_item item; 4897 struct ipa_agg_value item;
4119 gcc_checking_assert (av->value); 4898 gcc_checking_assert (av->value);
4120 item.offset = av->offset - offset; 4899 item.offset = av->offset - offset;
4121 item.value = av->value; 4900 item.value = av->value;
4122 res.safe_push (item); 4901 res.safe_push (item);
4123 } 4902 }
4129 be replaced in parameter number INDEX of NODE, which is an IPA-CP clone 4908 be replaced in parameter number INDEX of NODE, which is an IPA-CP clone
4130 (while subtracting OFFSET). */ 4909 (while subtracting OFFSET). */
4131 4910
4132 static void 4911 static void
4133 intersect_with_agg_replacements (struct cgraph_node *node, int index, 4912 intersect_with_agg_replacements (struct cgraph_node *node, int index,
4134 vec<ipa_agg_jf_item> *inter, 4913 vec<ipa_agg_value> *inter,
4135 HOST_WIDE_INT offset) 4914 HOST_WIDE_INT offset)
4136 { 4915 {
4137 struct ipa_agg_replacement_value *srcvals; 4916 struct ipa_agg_replacement_value *srcvals;
4138 struct ipa_agg_jf_item *item; 4917 struct ipa_agg_value *item;
4139 int i; 4918 int i;
4140 4919
4141 srcvals = ipa_get_agg_replacements_for_node (node); 4920 srcvals = ipa_get_agg_replacements_for_node (node);
4142 if (!srcvals) 4921 if (!srcvals)
4143 { 4922 {
4170 /* Intersect values in INTER with aggregate values that come along edge CS to 4949 /* Intersect values in INTER with aggregate values that come along edge CS to
4171 parameter number INDEX and return it. If INTER does not actually exist yet, 4950 parameter number INDEX and return it. If INTER does not actually exist yet,
4172 copy all incoming values to it. If we determine we ended up with no values 4951 copy all incoming values to it. If we determine we ended up with no values
4173 whatsoever, return a released vector. */ 4952 whatsoever, return a released vector. */
4174 4953
4175 static vec<ipa_agg_jf_item> 4954 static vec<ipa_agg_value>
4176 intersect_aggregates_with_edge (struct cgraph_edge *cs, int index, 4955 intersect_aggregates_with_edge (struct cgraph_edge *cs, int index,
4177 vec<ipa_agg_jf_item> inter) 4956 vec<ipa_agg_value> inter)
4178 { 4957 {
4179 struct ipa_jump_func *jfunc; 4958 struct ipa_jump_func *jfunc;
4180 jfunc = ipa_get_ith_jump_func (IPA_EDGE_REF (cs), index); 4959 jfunc = ipa_get_ith_jump_func (IPA_EDGE_REF (cs), index);
4181 if (jfunc->type == IPA_JF_PASS_THROUGH 4960 if (jfunc->type == IPA_JF_PASS_THROUGH
4182 && ipa_get_jf_pass_through_operation (jfunc) == NOP_EXPR) 4961 && ipa_get_jf_pass_through_operation (jfunc) == NOP_EXPR)
4183 { 4962 {
4184 struct ipa_node_params *caller_info = IPA_NODE_REF (cs->caller); 4963 class ipa_node_params *caller_info = IPA_NODE_REF (cs->caller);
4185 int src_idx = ipa_get_jf_pass_through_formal_id (jfunc); 4964 int src_idx = ipa_get_jf_pass_through_formal_id (jfunc);
4186 4965
4187 if (caller_info->ipcp_orig_node) 4966 if (caller_info->ipcp_orig_node)
4188 { 4967 {
4189 struct cgraph_node *orig_node = caller_info->ipcp_orig_node; 4968 struct cgraph_node *orig_node = caller_info->ipcp_orig_node;
4190 struct ipcp_param_lattices *orig_plats; 4969 class ipcp_param_lattices *orig_plats;
4191 orig_plats = ipa_get_parm_lattices (IPA_NODE_REF (orig_node), 4970 orig_plats = ipa_get_parm_lattices (IPA_NODE_REF (orig_node),
4192 src_idx); 4971 src_idx);
4193 if (agg_pass_through_permissible_p (orig_plats, jfunc)) 4972 if (agg_pass_through_permissible_p (orig_plats, jfunc))
4194 { 4973 {
4195 if (!inter.exists ()) 4974 if (!inter.exists ())
4204 return vNULL; 4983 return vNULL;
4205 } 4984 }
4206 } 4985 }
4207 else 4986 else
4208 { 4987 {
4209 struct ipcp_param_lattices *src_plats; 4988 class ipcp_param_lattices *src_plats;
4210 src_plats = ipa_get_parm_lattices (caller_info, src_idx); 4989 src_plats = ipa_get_parm_lattices (caller_info, src_idx);
4211 if (agg_pass_through_permissible_p (src_plats, jfunc)) 4990 if (agg_pass_through_permissible_p (src_plats, jfunc))
4212 { 4991 {
4213 /* Currently we do not produce clobber aggregate jump 4992 /* Currently we do not produce clobber aggregate jump
4214 functions, adjust when we do. */ 4993 functions, adjust when we do. */
4226 } 5005 }
4227 } 5006 }
4228 else if (jfunc->type == IPA_JF_ANCESTOR 5007 else if (jfunc->type == IPA_JF_ANCESTOR
4229 && ipa_get_jf_ancestor_agg_preserved (jfunc)) 5008 && ipa_get_jf_ancestor_agg_preserved (jfunc))
4230 { 5009 {
4231 struct ipa_node_params *caller_info = IPA_NODE_REF (cs->caller); 5010 class ipa_node_params *caller_info = IPA_NODE_REF (cs->caller);
4232 int src_idx = ipa_get_jf_ancestor_formal_id (jfunc); 5011 int src_idx = ipa_get_jf_ancestor_formal_id (jfunc);
4233 struct ipcp_param_lattices *src_plats; 5012 class ipcp_param_lattices *src_plats;
4234 HOST_WIDE_INT delta = ipa_get_jf_ancestor_offset (jfunc); 5013 HOST_WIDE_INT delta = ipa_get_jf_ancestor_offset (jfunc);
4235 5014
4236 if (caller_info->ipcp_orig_node) 5015 if (caller_info->ipcp_orig_node)
4237 { 5016 {
4238 if (!inter.exists ()) 5017 if (!inter.exists ())
4253 intersect_with_plats (src_plats, &inter, delta); 5032 intersect_with_plats (src_plats, &inter, delta);
4254 } 5033 }
4255 } 5034 }
4256 else if (jfunc->agg.items) 5035 else if (jfunc->agg.items)
4257 { 5036 {
4258 struct ipa_agg_jf_item *item; 5037 class ipa_node_params *caller_info = IPA_NODE_REF (cs->caller);
5038 struct ipa_agg_value *item;
4259 int k; 5039 int k;
4260 5040
4261 if (!inter.exists ()) 5041 if (!inter.exists ())
4262 for (unsigned i = 0; i < jfunc->agg.items->length (); i++) 5042 for (unsigned i = 0; i < jfunc->agg.items->length (); i++)
4263 inter.safe_push ((*jfunc->agg.items)[i]); 5043 {
5044 struct ipa_agg_jf_item *agg_item = &(*jfunc->agg.items)[i];
5045 tree value = ipa_agg_value_from_node (caller_info, cs->caller,
5046 agg_item);
5047 if (value)
5048 {
5049 struct ipa_agg_value agg_value;
5050
5051 agg_value.value = value;
5052 agg_value.offset = agg_item->offset;
5053 inter.safe_push (agg_value);
5054 }
5055 }
4264 else 5056 else
4265 FOR_EACH_VEC_ELT (inter, k, item) 5057 FOR_EACH_VEC_ELT (inter, k, item)
4266 { 5058 {
4267 int l = 0; 5059 int l = 0;
4268 bool found = false; 5060 bool found = false;
4276 ti = &(*jfunc->agg.items)[l]; 5068 ti = &(*jfunc->agg.items)[l];
4277 if (ti->offset > item->offset) 5069 if (ti->offset > item->offset)
4278 break; 5070 break;
4279 if (ti->offset == item->offset) 5071 if (ti->offset == item->offset)
4280 { 5072 {
4281 gcc_checking_assert (ti->value); 5073 tree value;
4282 if (values_equal_for_ipcp_p (item->value, 5074
4283 ti->value)) 5075 /* Besides simple pass-through aggregate jump function,
5076 arithmetic aggregate jump function could also bring
5077 same aggregate value as parameter passed-in for
5078 self-feeding recursive call. For example,
5079
5080 fn (int *i)
5081 {
5082 int j = *i & 1;
5083 fn (&j);
5084 }
5085
5086 Given that *i is 0, recursive propagation via (*i & 1)
5087 also gets 0. */
5088 if (self_recursive_agg_pass_through_p (cs, ti, index,
5089 false))
5090 value = ipa_get_jf_arith_result (
5091 ti->value.pass_through.operation,
5092 item->value,
5093 ti->value.pass_through.operand,
5094 ti->type);
5095 else
5096 value = ipa_agg_value_from_node (caller_info,
5097 cs->caller, ti);
5098
5099 if (value && values_equal_for_ipcp_p (item->value, value))
4284 found = true; 5100 found = true;
4285 break; 5101 break;
4286 } 5102 }
4287 l++; 5103 l++;
4288 } 5104 }
4291 } 5107 }
4292 } 5108 }
4293 else 5109 else
4294 { 5110 {
4295 inter.release (); 5111 inter.release ();
4296 return vec<ipa_agg_jf_item>(); 5112 return vNULL;
4297 } 5113 }
4298 return inter; 5114 return inter;
4299 } 5115 }
4300 5116
4301 /* Look at edges in CALLERS and collect all known aggregate values that arrive 5117 /* Look at edges in CALLERS and collect all known aggregate values that arrive
4303 5119
4304 static struct ipa_agg_replacement_value * 5120 static struct ipa_agg_replacement_value *
4305 find_aggregate_values_for_callers_subset (struct cgraph_node *node, 5121 find_aggregate_values_for_callers_subset (struct cgraph_node *node,
4306 vec<cgraph_edge *> callers) 5122 vec<cgraph_edge *> callers)
4307 { 5123 {
4308 struct ipa_node_params *dest_info = IPA_NODE_REF (node); 5124 class ipa_node_params *dest_info = IPA_NODE_REF (node);
4309 struct ipa_agg_replacement_value *res; 5125 struct ipa_agg_replacement_value *res;
4310 struct ipa_agg_replacement_value **tail = &res; 5126 struct ipa_agg_replacement_value **tail = &res;
4311 struct cgraph_edge *cs; 5127 struct cgraph_edge *cs;
4312 int i, j, count = ipa_get_param_count (dest_info); 5128 int i, j, count = ipa_get_param_count (dest_info);
4313 5129
4314 FOR_EACH_VEC_ELT (callers, j, cs) 5130 FOR_EACH_VEC_ELT (callers, j, cs)
4315 { 5131 {
5132 if (!IPA_EDGE_REF (cs))
5133 {
5134 count = 0;
5135 break;
5136 }
4316 int c = ipa_get_cs_argument_count (IPA_EDGE_REF (cs)); 5137 int c = ipa_get_cs_argument_count (IPA_EDGE_REF (cs));
4317 if (c < count) 5138 if (c < count)
4318 count = c; 5139 count = c;
4319 } 5140 }
4320 5141
4321 for (i = 0; i < count; i++) 5142 for (i = 0; i < count; i++)
4322 { 5143 {
4323 struct cgraph_edge *cs; 5144 struct cgraph_edge *cs;
4324 vec<ipa_agg_jf_item> inter = vNULL; 5145 vec<ipa_agg_value> inter = vNULL;
4325 struct ipa_agg_jf_item *item; 5146 struct ipa_agg_value *item;
4326 struct ipcp_param_lattices *plats = ipa_get_parm_lattices (dest_info, i); 5147 class ipcp_param_lattices *plats = ipa_get_parm_lattices (dest_info, i);
4327 int j; 5148 int j;
4328 5149
4329 /* Among other things, the following check should deal with all by_ref 5150 /* Among other things, the following check should deal with all by_ref
4330 mismatches. */ 5151 mismatches. */
4331 if (plats->aggs_bottom) 5152 if (plats->aggs_bottom)
4374 5195
4375 static bool 5196 static bool
4376 cgraph_edge_brings_all_scalars_for_node (struct cgraph_edge *cs, 5197 cgraph_edge_brings_all_scalars_for_node (struct cgraph_edge *cs,
4377 struct cgraph_node *node) 5198 struct cgraph_node *node)
4378 { 5199 {
4379 struct ipa_node_params *dest_info = IPA_NODE_REF (node); 5200 class ipa_node_params *dest_info = IPA_NODE_REF (node);
4380 int count = ipa_get_param_count (dest_info); 5201 int count = ipa_get_param_count (dest_info);
4381 struct ipa_node_params *caller_info; 5202 class ipa_node_params *caller_info;
4382 struct ipa_edge_args *args; 5203 class ipa_edge_args *args;
4383 int i; 5204 int i;
4384 5205
4385 caller_info = IPA_NODE_REF (cs->caller); 5206 caller_info = IPA_NODE_REF (cs->caller);
4386 args = IPA_EDGE_REF (cs); 5207 args = IPA_EDGE_REF (cs);
4387 for (i = 0; i < count; i++) 5208 for (i = 0; i < count; i++)
4408 specialized for. */ 5229 specialized for. */
4409 static bool 5230 static bool
4410 cgraph_edge_brings_all_agg_vals_for_node (struct cgraph_edge *cs, 5231 cgraph_edge_brings_all_agg_vals_for_node (struct cgraph_edge *cs,
4411 struct cgraph_node *node) 5232 struct cgraph_node *node)
4412 { 5233 {
4413 struct ipa_node_params *orig_caller_info = IPA_NODE_REF (cs->caller); 5234 class ipa_node_params *orig_node_info;
4414 struct ipa_node_params *orig_node_info;
4415 struct ipa_agg_replacement_value *aggval; 5235 struct ipa_agg_replacement_value *aggval;
4416 int i, ec, count; 5236 int i, ec, count;
4417 5237
4418 aggval = ipa_get_agg_replacements_for_node (node); 5238 aggval = ipa_get_agg_replacements_for_node (node);
4419 if (!aggval) 5239 if (!aggval)
4425 for (struct ipa_agg_replacement_value *av = aggval; av; av = av->next) 5245 for (struct ipa_agg_replacement_value *av = aggval; av; av = av->next)
4426 if (aggval->index >= ec) 5246 if (aggval->index >= ec)
4427 return false; 5247 return false;
4428 5248
4429 orig_node_info = IPA_NODE_REF (IPA_NODE_REF (node)->ipcp_orig_node); 5249 orig_node_info = IPA_NODE_REF (IPA_NODE_REF (node)->ipcp_orig_node);
4430 if (orig_caller_info->ipcp_orig_node)
4431 orig_caller_info = IPA_NODE_REF (orig_caller_info->ipcp_orig_node);
4432 5250
4433 for (i = 0; i < count; i++) 5251 for (i = 0; i < count; i++)
4434 { 5252 {
4435 static vec<ipa_agg_jf_item> values = vec<ipa_agg_jf_item>(); 5253 class ipcp_param_lattices *plats;
4436 struct ipcp_param_lattices *plats;
4437 bool interesting = false; 5254 bool interesting = false;
4438 for (struct ipa_agg_replacement_value *av = aggval; av; av = av->next) 5255 for (struct ipa_agg_replacement_value *av = aggval; av; av = av->next)
4439 if (aggval->index == i) 5256 if (aggval->index == i)
4440 { 5257 {
4441 interesting = true; 5258 interesting = true;
4446 5263
4447 plats = ipa_get_parm_lattices (orig_node_info, aggval->index); 5264 plats = ipa_get_parm_lattices (orig_node_info, aggval->index);
4448 if (plats->aggs_bottom) 5265 if (plats->aggs_bottom)
4449 return false; 5266 return false;
4450 5267
4451 values = intersect_aggregates_with_edge (cs, i, values); 5268 vec<ipa_agg_value> values = intersect_aggregates_with_edge (cs, i, vNULL);
4452 if (!values.exists ()) 5269 if (!values.exists ())
4453 return false; 5270 return false;
4454 5271
4455 for (struct ipa_agg_replacement_value *av = aggval; av; av = av->next) 5272 for (struct ipa_agg_replacement_value *av = aggval; av; av = av->next)
4456 if (aggval->index == i) 5273 if (aggval->index == i)
4457 { 5274 {
4458 struct ipa_agg_jf_item *item; 5275 struct ipa_agg_value *item;
4459 int j; 5276 int j;
4460 bool found = false; 5277 bool found = false;
4461 FOR_EACH_VEC_ELT (values, j, item) 5278 FOR_EACH_VEC_ELT (values, j, item)
4462 if (item->value 5279 if (item->value
4463 && item->offset == av->offset 5280 && item->offset == av->offset
4470 { 5287 {
4471 values.release (); 5288 values.release ();
4472 return false; 5289 return false;
4473 } 5290 }
4474 } 5291 }
5292 values.release ();
4475 } 5293 }
4476 return true; 5294 return true;
4477 } 5295 }
4478 5296
4479 /* Given an original NODE and a VAL for which we have already created a 5297 /* Given an original NODE and a VAL for which we have already created a
4589 aggvals = aggvals->next; 5407 aggvals = aggvals->next;
4590 } 5408 }
4591 return false; 5409 return false;
4592 } 5410 }
4593 5411
4594 /* Return true if offset is minus one because source of a polymorphic contect 5412 /* Return true if offset is minus one because source of a polymorphic context
4595 cannot be an aggregate value. */ 5413 cannot be an aggregate value. */
4596 5414
4597 DEBUG_FUNCTION bool 5415 DEBUG_FUNCTION bool
4598 ipcp_val_agg_replacement_ok_p (ipa_agg_replacement_value *, 5416 ipcp_val_agg_replacement_ok_p (ipa_agg_replacement_value *,
4599 int , HOST_WIDE_INT offset, 5417 int , HOST_WIDE_INT offset,
4600 ipa_polymorphic_call_context) 5418 ipa_polymorphic_call_context)
4601 { 5419 {
4602 return offset == -1; 5420 return offset == -1;
4603 } 5421 }
4604 5422
4605 /* Decide wheter to create a special version of NODE for value VAL of parameter 5423 /* Decide whether to create a special version of NODE for value VAL of parameter
4606 at the given INDEX. If OFFSET is -1, the value is for the parameter itself, 5424 at the given INDEX. If OFFSET is -1, the value is for the parameter itself,
4607 otherwise it is stored at the given OFFSET of the parameter. KNOWN_CSTS, 5425 otherwise it is stored at the given OFFSET of the parameter. KNOWN_CSTS,
4608 KNOWN_CONTEXTS and KNOWN_AGGS describe the other already known values. */ 5426 KNOWN_CONTEXTS and KNOWN_AGGS describe the other already known values. */
4609 5427
4610 template <typename valtype> 5428 template <typename valtype>
4621 if (val->spec_node) 5439 if (val->spec_node)
4622 { 5440 {
4623 perhaps_add_new_callers (node, val); 5441 perhaps_add_new_callers (node, val);
4624 return false; 5442 return false;
4625 } 5443 }
4626 else if (val->local_size_cost + overall_size > max_new_size) 5444 else if (val->local_size_cost + overall_size > get_max_overall_size (node))
4627 { 5445 {
4628 if (dump_file && (dump_flags & TDF_DETAILS)) 5446 if (dump_file && (dump_flags & TDF_DETAILS))
4629 fprintf (dump_file, " Ignoring candidate value because " 5447 fprintf (dump_file, " Ignoring candidate value because "
4630 "max_new_size would be reached with %li.\n", 5448 "maximum unit size would be reached with %li.\n",
4631 val->local_size_cost + overall_size); 5449 val->local_size_cost + overall_size);
4632 return false; 5450 return false;
4633 } 5451 }
4634 else if (!get_info_about_necessary_edges (val, node, &freq_sum, &count_sum, 5452 else if (!get_info_about_necessary_edges (val, node, &freq_sum, &count_sum,
4635 &caller_count)) 5453 &caller_count))
4687 /* Decide whether and what specialized clones of NODE should be created. */ 5505 /* Decide whether and what specialized clones of NODE should be created. */
4688 5506
4689 static bool 5507 static bool
4690 decide_whether_version_node (struct cgraph_node *node) 5508 decide_whether_version_node (struct cgraph_node *node)
4691 { 5509 {
4692 struct ipa_node_params *info = IPA_NODE_REF (node); 5510 class ipa_node_params *info = IPA_NODE_REF (node);
4693 int i, count = ipa_get_param_count (info); 5511 int i, count = ipa_get_param_count (info);
4694 vec<tree> known_csts; 5512 vec<tree> known_csts;
4695 vec<ipa_polymorphic_call_context> known_contexts; 5513 vec<ipa_polymorphic_call_context> known_contexts;
4696 vec<ipa_agg_jump_function> known_aggs = vNULL;
4697 bool ret = false; 5514 bool ret = false;
4698 5515
4699 if (count == 0) 5516 if (count == 0)
4700 return false; 5517 return false;
4701 5518
4702 if (dump_file && (dump_flags & TDF_DETAILS)) 5519 if (dump_file && (dump_flags & TDF_DETAILS))
4703 fprintf (dump_file, "\nEvaluating opportunities for %s.\n", 5520 fprintf (dump_file, "\nEvaluating opportunities for %s.\n",
4704 node->dump_name ()); 5521 node->dump_name ());
4705 5522
4706 gather_context_independent_values (info, &known_csts, &known_contexts, 5523 gather_context_independent_values (info, &known_csts, &known_contexts,
4707 info->do_clone_for_all_contexts ? &known_aggs 5524 NULL, NULL);
4708 : NULL, NULL);
4709 5525
4710 for (i = 0; i < count;i++) 5526 for (i = 0; i < count;i++)
4711 { 5527 {
4712 struct ipcp_param_lattices *plats = ipa_get_parm_lattices (info, i); 5528 class ipcp_param_lattices *plats = ipa_get_parm_lattices (info, i);
4713 ipcp_lattice<tree> *lat = &plats->itself; 5529 ipcp_lattice<tree> *lat = &plats->itself;
4714 ipcp_lattice<ipa_polymorphic_call_context> *ctxlat = &plats->ctxlat; 5530 ipcp_lattice<ipa_polymorphic_call_context> *ctxlat = &plats->ctxlat;
4715 5531
4716 if (!lat->bottom 5532 if (!lat->bottom
4717 && !known_csts[i]) 5533 && !known_csts[i])
4750 } 5566 }
4751 5567
4752 if (info->do_clone_for_all_contexts) 5568 if (info->do_clone_for_all_contexts)
4753 { 5569 {
4754 struct cgraph_node *clone; 5570 struct cgraph_node *clone;
4755 vec<cgraph_edge *> callers; 5571 vec<cgraph_edge *> callers = node->collect_callers ();
5572
5573 for (int i = callers.length () - 1; i >= 0; i--)
5574 {
5575 cgraph_edge *cs = callers[i];
5576 class ipa_node_params *caller_info = IPA_NODE_REF (cs->caller);
5577
5578 if (caller_info && caller_info->node_dead)
5579 callers.unordered_remove (i);
5580 }
5581
5582 if (!adjust_callers_for_value_intersection (callers, node))
5583 {
5584 /* If node is not called by anyone, or all its caller edges are
5585 self-recursive, the node is not really be in use, no need to
5586 do cloning. */
5587 callers.release ();
5588 known_csts.release ();
5589 known_contexts.release ();
5590 info->do_clone_for_all_contexts = false;
5591 return ret;
5592 }
4756 5593
4757 if (dump_file) 5594 if (dump_file)
4758 fprintf (dump_file, " - Creating a specialized node of %s " 5595 fprintf (dump_file, " - Creating a specialized node of %s "
4759 "for all known contexts.\n", node->dump_name ()); 5596 "for all known contexts.\n", node->dump_name ());
4760 5597
4761 callers = node->collect_callers ();
4762 find_more_scalar_values_for_callers_subset (node, known_csts, callers); 5598 find_more_scalar_values_for_callers_subset (node, known_csts, callers);
4763 find_more_contexts_for_caller_subset (node, &known_contexts, callers); 5599 find_more_contexts_for_caller_subset (node, &known_contexts, callers);
4764 ipa_agg_replacement_value *aggvals 5600 ipa_agg_replacement_value *aggvals
4765 = find_aggregate_values_for_callers_subset (node, callers); 5601 = find_aggregate_values_for_callers_subset (node, callers);
4766 5602
4772 clone = create_specialized_node (node, known_csts, known_contexts, 5608 clone = create_specialized_node (node, known_csts, known_contexts,
4773 aggvals, callers); 5609 aggvals, callers);
4774 info = IPA_NODE_REF (node); 5610 info = IPA_NODE_REF (node);
4775 info->do_clone_for_all_contexts = false; 5611 info->do_clone_for_all_contexts = false;
4776 IPA_NODE_REF (clone)->is_all_contexts_clone = true; 5612 IPA_NODE_REF (clone)->is_all_contexts_clone = true;
4777 for (i = 0; i < count; i++)
4778 vec_free (known_aggs[i].items);
4779 known_aggs.release ();
4780 ret = true; 5613 ret = true;
4781 } 5614 }
4782 else 5615 else
4783 { 5616 {
4784 known_csts.release (); 5617 known_csts.release ();
4797 5630
4798 for (cs = node->callees; cs; cs = cs->next_callee) 5631 for (cs = node->callees; cs; cs = cs->next_callee)
4799 if (ipa_edge_within_scc (cs)) 5632 if (ipa_edge_within_scc (cs))
4800 { 5633 {
4801 struct cgraph_node *callee; 5634 struct cgraph_node *callee;
4802 struct ipa_node_params *info; 5635 class ipa_node_params *info;
4803 5636
4804 callee = cs->callee->function_symbol (NULL); 5637 callee = cs->callee->function_symbol (NULL);
4805 info = IPA_NODE_REF (callee); 5638 info = IPA_NODE_REF (callee);
4806 5639
4807 if (info->node_dead) 5640 if (info && info->node_dead)
4808 { 5641 {
4809 info->node_dead = 0; 5642 info->node_dead = 0;
4810 spread_undeadness (callee); 5643 spread_undeadness (callee);
4811 } 5644 }
4812 } 5645 }
4839 static void 5672 static void
4840 identify_dead_nodes (struct cgraph_node *node) 5673 identify_dead_nodes (struct cgraph_node *node)
4841 { 5674 {
4842 struct cgraph_node *v; 5675 struct cgraph_node *v;
4843 for (v = node; v; v = ((struct ipa_dfs_info *) v->aux)->next_cycle) 5676 for (v = node; v; v = ((struct ipa_dfs_info *) v->aux)->next_cycle)
4844 if (v->local.local 5677 if (v->local
5678 && IPA_NODE_REF (v)
4845 && !v->call_for_symbol_thunks_and_aliases 5679 && !v->call_for_symbol_thunks_and_aliases
4846 (has_undead_caller_from_outside_scc_p, NULL, true)) 5680 (has_undead_caller_from_outside_scc_p, NULL, true))
4847 IPA_NODE_REF (v)->node_dead = 1; 5681 IPA_NODE_REF (v)->node_dead = 1;
4848 5682
4849 for (v = node; v; v = ((struct ipa_dfs_info *) v->aux)->next_cycle) 5683 for (v = node; v; v = ((struct ipa_dfs_info *) v->aux)->next_cycle)
4850 if (!IPA_NODE_REF (v)->node_dead) 5684 if (IPA_NODE_REF (v) && !IPA_NODE_REF (v)->node_dead)
4851 spread_undeadness (v); 5685 spread_undeadness (v);
4852 5686
4853 if (dump_file && (dump_flags & TDF_DETAILS)) 5687 if (dump_file && (dump_flags & TDF_DETAILS))
4854 { 5688 {
4855 for (v = node; v; v = ((struct ipa_dfs_info *) v->aux)->next_cycle) 5689 for (v = node; v; v = ((struct ipa_dfs_info *) v->aux)->next_cycle)
4856 if (IPA_NODE_REF (v)->node_dead) 5690 if (IPA_NODE_REF (v) && IPA_NODE_REF (v)->node_dead)
4857 fprintf (dump_file, " Marking node as dead: %s.\n", v->dump_name ()); 5691 fprintf (dump_file, " Marking node as dead: %s.\n", v->dump_name ());
4858 } 5692 }
4859 } 5693 }
4860 5694
4861 /* The decision stage. Iterate over the topological order of call graph nodes 5695 /* The decision stage. Iterate over the topological order of call graph nodes
4862 TOPO and make specialized clones if deemed beneficial. */ 5696 TOPO and make specialized clones if deemed beneficial. */
4863 5697
4864 static void 5698 static void
4865 ipcp_decision_stage (struct ipa_topo_info *topo) 5699 ipcp_decision_stage (class ipa_topo_info *topo)
4866 { 5700 {
4867 int i; 5701 int i;
4868 5702
4869 if (dump_file) 5703 if (dump_file)
4870 fprintf (dump_file, "\nIPA decision stage:\n\n"); 5704 fprintf (dump_file, "\nIPA decision stage:\n\n");
4902 { 5736 {
4903 ipa_node_params *info = IPA_NODE_REF (node); 5737 ipa_node_params *info = IPA_NODE_REF (node);
4904 bool dumped_sth = false; 5738 bool dumped_sth = false;
4905 bool found_useful_result = false; 5739 bool found_useful_result = false;
4906 5740
4907 if (!opt_for_fn (node->decl, flag_ipa_bit_cp)) 5741 if (!opt_for_fn (node->decl, flag_ipa_bit_cp) || !info)
4908 { 5742 {
4909 if (dump_file) 5743 if (dump_file)
4910 fprintf (dump_file, "Not considering %s for ipa bitwise propagation " 5744 fprintf (dump_file, "Not considering %s for ipa bitwise propagation "
4911 "; -fipa-bit-cp: disabled.\n", 5745 "; -fipa-bit-cp: disabled.\n",
4912 node->name ()); 5746 node->dump_name ());
4913 continue; 5747 continue;
4914 } 5748 }
4915 5749
4916 if (info->ipcp_orig_node) 5750 if (info->ipcp_orig_node)
4917 info = IPA_NODE_REF (info->ipcp_orig_node); 5751 info = IPA_NODE_REF (info->ipcp_orig_node);
5752 if (!info->lattices)
5753 /* Newly expanded artificial thunks do not have lattices. */
5754 continue;
4918 5755
4919 unsigned count = ipa_get_param_count (info); 5756 unsigned count = ipa_get_param_count (info);
4920 for (unsigned i = 0; i < count; i++) 5757 for (unsigned i = 0; i < count; i++)
4921 { 5758 {
4922 ipcp_param_lattices *plats = ipa_get_parm_lattices (info, i); 5759 ipcp_param_lattices *plats = ipa_get_parm_lattices (info, i);
4975 FOR_EACH_FUNCTION_WITH_GIMPLE_BODY (node) 5812 FOR_EACH_FUNCTION_WITH_GIMPLE_BODY (node)
4976 { 5813 {
4977 ipa_node_params *info = IPA_NODE_REF (node); 5814 ipa_node_params *info = IPA_NODE_REF (node);
4978 bool found_useful_result = false; 5815 bool found_useful_result = false;
4979 5816
4980 if (!opt_for_fn (node->decl, flag_ipa_vrp)) 5817 if (!info || !opt_for_fn (node->decl, flag_ipa_vrp))
4981 { 5818 {
4982 if (dump_file) 5819 if (dump_file)
4983 fprintf (dump_file, "Not considering %s for VR discovery " 5820 fprintf (dump_file, "Not considering %s for VR discovery "
4984 "and propagate; -fipa-ipa-vrp: disabled.\n", 5821 "and propagate; -fipa-ipa-vrp: disabled.\n",
4985 node->name ()); 5822 node->dump_name ());
4986 continue; 5823 continue;
4987 } 5824 }
4988 5825
4989 if (info->ipcp_orig_node) 5826 if (info->ipcp_orig_node)
4990 info = IPA_NODE_REF (info->ipcp_orig_node); 5827 info = IPA_NODE_REF (info->ipcp_orig_node);
5828 if (!info->lattices)
5829 /* Newly expanded artificial thunks do not have lattices. */
5830 continue;
4991 5831
4992 unsigned count = ipa_get_param_count (info); 5832 unsigned count = ipa_get_param_count (info);
4993 for (unsigned i = 0; i < count; i++) 5833 for (unsigned i = 0; i < count; i++)
4994 { 5834 {
4995 ipcp_param_lattices *plats = ipa_get_parm_lattices (info, i); 5835 ipcp_param_lattices *plats = ipa_get_parm_lattices (info, i);
5034 /* The IPCP driver. */ 5874 /* The IPCP driver. */
5035 5875
5036 static unsigned int 5876 static unsigned int
5037 ipcp_driver (void) 5877 ipcp_driver (void)
5038 { 5878 {
5039 struct ipa_topo_info topo; 5879 class ipa_topo_info topo;
5040 5880
5041 if (edge_clone_summaries == NULL) 5881 if (edge_clone_summaries == NULL)
5042 edge_clone_summaries = new edge_clone_summary_t (symtab); 5882 edge_clone_summaries = new edge_clone_summary_t (symtab);
5043 5883
5044 ipa_check_create_node_params (); 5884 ipa_check_create_node_params ();
5045 ipa_check_create_edge_args (); 5885 ipa_check_create_edge_args ();
5886 clone_num_suffixes = new hash_map<const char *, unsigned>;
5046 5887
5047 if (dump_file) 5888 if (dump_file)
5048 { 5889 {
5049 fprintf (dump_file, "\nIPA structures before propagation:\n"); 5890 fprintf (dump_file, "\nIPA structures before propagation:\n");
5050 if (dump_flags & TDF_DETAILS) 5891 if (dump_flags & TDF_DETAILS)
5062 ipcp_store_bits_results (); 5903 ipcp_store_bits_results ();
5063 /* Store results of value range propagation. */ 5904 /* Store results of value range propagation. */
5064 ipcp_store_vr_results (); 5905 ipcp_store_vr_results ();
5065 5906
5066 /* Free all IPCP structures. */ 5907 /* Free all IPCP structures. */
5908 delete clone_num_suffixes;
5067 free_toporder_info (&topo); 5909 free_toporder_info (&topo);
5068 delete edge_clone_summaries; 5910 delete edge_clone_summaries;
5069 edge_clone_summaries = NULL; 5911 edge_clone_summaries = NULL;
5070 ipa_free_all_structures_after_ipa_cp (); 5912 ipa_free_all_structures_after_ipa_cp ();
5071 if (dump_file) 5913 if (dump_file)
5165 void 6007 void
5166 ipa_cp_c_finalize (void) 6008 ipa_cp_c_finalize (void)
5167 { 6009 {
5168 max_count = profile_count::uninitialized (); 6010 max_count = profile_count::uninitialized ();
5169 overall_size = 0; 6011 overall_size = 0;
5170 max_new_size = 0; 6012 orig_overall_size = 0;
5171 } 6013 ipcp_free_transformation_sum ();
6014 }