1 1.1 mrg /* Interprocedural constant propagation 2 1.1 mrg Copyright (C) 2005-2022 Free Software Foundation, Inc. 3 1.1 mrg 4 1.1 mrg Contributed by Razya Ladelsky <RAZYA (at) il.ibm.com> and Martin Jambor 5 1.1 mrg <mjambor (at) suse.cz> 6 1.1 mrg 7 1.1 mrg This file is part of GCC. 8 1.1 mrg 9 1.1 mrg GCC is free software; you can redistribute it and/or modify it under 10 1.1 mrg the terms of the GNU General Public License as published by the Free 11 1.1 mrg Software Foundation; either version 3, or (at your option) any later 12 1.1 mrg version. 13 1.1 mrg 14 1.1 mrg GCC is distributed in the hope that it will be useful, but WITHOUT ANY 15 1.1 mrg WARRANTY; without even the implied warranty of MERCHANTABILITY or 16 1.1 mrg FITNESS FOR A PARTICULAR PURPOSE. See the GNU General Public License 17 1.1 mrg for more details. 18 1.1 mrg 19 1.1 mrg You should have received a copy of the GNU General Public License 20 1.1 mrg along with GCC; see the file COPYING3. If not see 21 1.1 mrg <http://www.gnu.org/licenses/>. */ 22 1.1 mrg 23 1.1 mrg /* Interprocedural constant propagation (IPA-CP). 24 1.1 mrg 25 1.1 mrg The goal of this transformation is to 26 1.1 mrg 27 1.1 mrg 1) discover functions which are always invoked with some arguments with the 28 1.1 mrg same known constant values and modify the functions so that the 29 1.1 mrg subsequent optimizations can take advantage of the knowledge, and 30 1.1 mrg 31 1.1 mrg 2) partial specialization - create specialized versions of functions 32 1.1 mrg transformed in this way if some parameters are known constants only in 33 1.1 mrg certain contexts but the estimated tradeoff between speedup and cost size 34 1.1 mrg is deemed good. 35 1.1 mrg 36 1.1 mrg The algorithm also propagates types and attempts to perform type based 37 1.1 mrg devirtualization. Types are propagated much like constants. 38 1.1 mrg 39 1.1 mrg The algorithm basically consists of three stages. In the first, functions 40 1.1 mrg are analyzed one at a time and jump functions are constructed for all known 41 1.1 mrg call-sites. In the second phase, the pass propagates information from the 42 1.1 mrg jump functions across the call to reveal what values are available at what 43 1.1 mrg call sites, performs estimations of effects of known values on functions and 44 1.1 mrg their callees, and finally decides what specialized extra versions should be 45 1.1 mrg created. In the third, the special versions materialize and appropriate 46 1.1 mrg calls are redirected. 47 1.1 mrg 48 1.1 mrg The algorithm used is to a certain extent based on "Interprocedural Constant 49 1.1 mrg Propagation", by David Callahan, Keith D Cooper, Ken Kennedy, Linda Torczon, 50 1.1 mrg Comp86, pg 152-161 and "A Methodology for Procedure Cloning" by Keith D 51 1.1 mrg Cooper, Mary W. Hall, and Ken Kennedy. 52 1.1 mrg 53 1.1 mrg 54 1.1 mrg First stage - intraprocedural analysis 55 1.1 mrg ======================================= 56 1.1 mrg 57 1.1 mrg This phase computes jump_function and modification flags. 58 1.1 mrg 59 1.1 mrg A jump function for a call-site represents the values passed as an actual 60 1.1 mrg arguments of a given call-site. In principle, there are three types of 61 1.1 mrg values: 62 1.1 mrg 63 1.1 mrg Pass through - the caller's formal parameter is passed as an actual 64 1.1 mrg argument, plus an operation on it can be performed. 65 1.1 mrg Constant - a constant is passed as an actual argument. 66 1.1 mrg Unknown - neither of the above. 67 1.1 mrg 68 1.1 mrg All jump function types are described in detail in ipa-prop.h, together with 69 1.1 mrg the data structures that represent them and methods of accessing them. 70 1.1 mrg 71 1.1 mrg ipcp_generate_summary() is the main function of the first stage. 72 1.1 mrg 73 1.1 mrg Second stage - interprocedural analysis 74 1.1 mrg ======================================== 75 1.1 mrg 76 1.1 mrg This stage is itself divided into two phases. In the first, we propagate 77 1.1 mrg known values over the call graph, in the second, we make cloning decisions. 78 1.1 mrg It uses a different algorithm than the original Callahan's paper. 79 1.1 mrg 80 1.1 mrg First, we traverse the functions topologically from callers to callees and, 81 1.1 mrg for each strongly connected component (SCC), we propagate constants 82 1.1 mrg according to previously computed jump functions. We also record what known 83 1.1 mrg values depend on other known values and estimate local effects. Finally, we 84 1.1 mrg propagate cumulative information about these effects from dependent values 85 1.1 mrg to those on which they depend. 86 1.1 mrg 87 1.1 mrg Second, we again traverse the call graph in the same topological order and 88 1.1 mrg make clones for functions which we know are called with the same values in 89 1.1 mrg all contexts and decide about extra specialized clones of functions just for 90 1.1 mrg some contexts - these decisions are based on both local estimates and 91 1.1 mrg cumulative estimates propagated from callees. 92 1.1 mrg 93 1.1 mrg ipcp_propagate_stage() and ipcp_decision_stage() together constitute the 94 1.1 mrg third stage. 95 1.1 mrg 96 1.1 mrg Third phase - materialization of clones, call statement updates. 97 1.1 mrg ============================================ 98 1.1 mrg 99 1.1 mrg This stage is currently performed by call graph code (mainly in cgraphunit.cc 100 1.1 mrg and tree-inline.cc) according to instructions inserted to the call graph by 101 1.1 mrg the second stage. */ 102 1.1 mrg 103 1.1 mrg #include "config.h" 104 1.1 mrg #include "system.h" 105 1.1 mrg #include "coretypes.h" 106 1.1 mrg #include "backend.h" 107 1.1 mrg #include "tree.h" 108 1.1 mrg #include "gimple-expr.h" 109 1.1 mrg #include "gimple.h" 110 1.1 mrg #include "predict.h" 111 1.1 mrg #include "alloc-pool.h" 112 1.1 mrg #include "tree-pass.h" 113 1.1 mrg #include "cgraph.h" 114 1.1 mrg #include "diagnostic.h" 115 1.1 mrg #include "fold-const.h" 116 1.1 mrg #include "gimple-fold.h" 117 1.1 mrg #include "symbol-summary.h" 118 1.1 mrg #include "tree-vrp.h" 119 1.1 mrg #include "ipa-prop.h" 120 1.1 mrg #include "tree-pretty-print.h" 121 1.1 mrg #include "tree-inline.h" 122 1.1 mrg #include "ipa-fnsummary.h" 123 1.1 mrg #include "ipa-utils.h" 124 1.1 mrg #include "tree-ssa-ccp.h" 125 1.1 mrg #include "stringpool.h" 126 1.1 mrg #include "attribs.h" 127 1.1 mrg #include "dbgcnt.h" 128 1.1 mrg #include "symtab-clones.h" 129 1.1 mrg 130 1.1 mrg template <typename valtype> class ipcp_value; 131 1.1 mrg 132 1.1 mrg /* Describes a particular source for an IPA-CP value. */ 133 1.1 mrg 134 1.1 mrg template <typename valtype> 135 1.1 mrg struct ipcp_value_source 136 1.1 mrg { 137 1.1 mrg public: 138 1.1 mrg /* Aggregate offset of the source, negative if the source is scalar value of 139 1.1 mrg the argument itself. */ 140 1.1 mrg HOST_WIDE_INT offset; 141 1.1 mrg /* The incoming edge that brought the value. */ 142 1.1 mrg cgraph_edge *cs; 143 1.1 mrg /* If the jump function that resulted into his value was a pass-through or an 144 1.1 mrg ancestor, this is the ipcp_value of the caller from which the described 145 1.1 mrg value has been derived. Otherwise it is NULL. */ 146 1.1 mrg ipcp_value<valtype> *val; 147 1.1 mrg /* Next pointer in a linked list of sources of a value. */ 148 1.1 mrg ipcp_value_source *next; 149 1.1 mrg /* If the jump function that resulted into his value was a pass-through or an 150 1.1 mrg ancestor, this is the index of the parameter of the caller the jump 151 1.1 mrg function references. */ 152 1.1 mrg int index; 153 1.1 mrg }; 154 1.1 mrg 155 1.1 mrg /* Common ancestor for all ipcp_value instantiations. */ 156 1.1 mrg 157 1.1 mrg class ipcp_value_base 158 1.1 mrg { 159 1.1 mrg public: 160 1.1 mrg /* Time benefit and that specializing the function for this value would bring 161 1.1 mrg about in this function alone. */ 162 1.1 mrg sreal local_time_benefit; 163 1.1 mrg /* Time benefit that specializing the function for this value can bring about 164 1.1 mrg in it's callees. */ 165 1.1 mrg sreal prop_time_benefit; 166 1.1 mrg /* Size cost that specializing the function for this value would bring about 167 1.1 mrg in this function alone. */ 168 1.1 mrg int local_size_cost; 169 1.1 mrg /* Size cost that specializing the function for this value can bring about in 170 1.1 mrg it's callees. */ 171 1.1 mrg int prop_size_cost; 172 1.1 mrg 173 1.1 mrg ipcp_value_base () 174 1.1 mrg : local_time_benefit (0), prop_time_benefit (0), 175 1.1 mrg local_size_cost (0), prop_size_cost (0) {} 176 1.1 mrg }; 177 1.1 mrg 178 1.1 mrg /* Describes one particular value stored in struct ipcp_lattice. */ 179 1.1 mrg 180 1.1 mrg template <typename valtype> 181 1.1 mrg class ipcp_value : public ipcp_value_base 182 1.1 mrg { 183 1.1 mrg public: 184 1.1 mrg /* The actual value for the given parameter. */ 185 1.1 mrg valtype value; 186 1.1 mrg /* The list of sources from which this value originates. */ 187 1.1 mrg ipcp_value_source <valtype> *sources = nullptr; 188 1.1 mrg /* Next pointers in a linked list of all values in a lattice. */ 189 1.1 mrg ipcp_value *next = nullptr; 190 1.1 mrg /* Next pointers in a linked list of values in a strongly connected component 191 1.1 mrg of values. */ 192 1.1 mrg ipcp_value *scc_next = nullptr; 193 1.1 mrg /* Next pointers in a linked list of SCCs of values sorted topologically 194 1.1 mrg according their sources. */ 195 1.1 mrg ipcp_value *topo_next = nullptr; 196 1.1 mrg /* A specialized node created for this value, NULL if none has been (so far) 197 1.1 mrg created. */ 198 1.1 mrg cgraph_node *spec_node = nullptr; 199 1.1 mrg /* Depth first search number and low link for topological sorting of 200 1.1 mrg values. */ 201 1.1 mrg int dfs = 0; 202 1.1 mrg int low_link = 0; 203 1.1 mrg /* SCC number to identify values which recursively feed into each other. 204 1.1 mrg Values in the same SCC have the same SCC number. */ 205 1.1 mrg int scc_no = 0; 206 1.1 mrg /* Non zero if the value is generated from another value in the same lattice 207 1.1 mrg for a self-recursive call, the actual number is how many times the 208 1.1 mrg operation has been performed. In the unlikely event of the value being 209 1.1 mrg present in two chains fo self-recursive value generation chains, it is the 210 1.1 mrg maximum. */ 211 1.1 mrg unsigned self_recursion_generated_level = 0; 212 1.1 mrg /* True if this value is currently on the topo-sort stack. */ 213 1.1 mrg bool on_stack = false; 214 1.1 mrg 215 1.1 mrg void add_source (cgraph_edge *cs, ipcp_value *src_val, int src_idx, 216 1.1 mrg HOST_WIDE_INT offset); 217 1.1 mrg 218 1.1 mrg /* Return true if both THIS value and O feed into each other. */ 219 1.1 mrg 220 1.1 mrg bool same_scc (const ipcp_value<valtype> *o) 221 1.1 mrg { 222 1.1 mrg return o->scc_no == scc_no; 223 1.1 mrg } 224 1.1 mrg 225 1.1 mrg /* Return true, if a this value has been generated for a self-recursive call as 226 1.1 mrg a result of an arithmetic pass-through jump-function acting on a value in 227 1.1 mrg the same lattice function. */ 228 1.1 mrg 229 1.1 mrg bool self_recursion_generated_p () 230 1.1 mrg { 231 1.1 mrg return self_recursion_generated_level > 0; 232 1.1 mrg } 233 1.1 mrg }; 234 1.1 mrg 235 1.1 mrg /* Lattice describing potential values of a formal parameter of a function, or 236 1.1 mrg a part of an aggregate. TOP is represented by a lattice with zero values 237 1.1 mrg and with contains_variable and bottom flags cleared. BOTTOM is represented 238 1.1 mrg by a lattice with the bottom flag set. In that case, values and 239 1.1 mrg contains_variable flag should be disregarded. */ 240 1.1 mrg 241 1.1 mrg template <typename valtype> 242 1.1 mrg struct ipcp_lattice 243 1.1 mrg { 244 1.1 mrg public: 245 1.1 mrg /* The list of known values and types in this lattice. Note that values are 246 1.1 mrg not deallocated if a lattice is set to bottom because there may be value 247 1.1 mrg sources referencing them. */ 248 1.1 mrg ipcp_value<valtype> *values; 249 1.1 mrg /* Number of known values and types in this lattice. */ 250 1.1 mrg int values_count; 251 1.1 mrg /* The lattice contains a variable component (in addition to values). */ 252 1.1 mrg bool contains_variable; 253 1.1 mrg /* The value of the lattice is bottom (i.e. variable and unusable for any 254 1.1 mrg propagation). */ 255 1.1 mrg bool bottom; 256 1.1 mrg 257 1.1 mrg inline bool is_single_const (); 258 1.1 mrg inline bool set_to_bottom (); 259 1.1 mrg inline bool set_contains_variable (); 260 1.1 mrg bool add_value (valtype newval, cgraph_edge *cs, 261 1.1 mrg ipcp_value<valtype> *src_val = NULL, 262 1.1 mrg int src_idx = 0, HOST_WIDE_INT offset = -1, 263 1.1 mrg ipcp_value<valtype> **val_p = NULL, 264 1.1 mrg unsigned same_lat_gen_level = 0); 265 1.1 mrg void print (FILE * f, bool dump_sources, bool dump_benefits); 266 1.1 mrg }; 267 1.1 mrg 268 1.1 mrg /* Lattice of tree values with an offset to describe a part of an 269 1.1 mrg aggregate. */ 270 1.1 mrg 271 1.1 mrg struct ipcp_agg_lattice : public ipcp_lattice<tree> 272 1.1 mrg { 273 1.1 mrg public: 274 1.1 mrg /* Offset that is being described by this lattice. */ 275 1.1 mrg HOST_WIDE_INT offset; 276 1.1 mrg /* Size so that we don't have to re-compute it every time we traverse the 277 1.1 mrg list. Must correspond to TYPE_SIZE of all lat values. */ 278 1.1 mrg HOST_WIDE_INT size; 279 1.1 mrg /* Next element of the linked list. */ 280 1.1 mrg struct ipcp_agg_lattice *next; 281 1.1 mrg }; 282 1.1 mrg 283 1.1 mrg /* Lattice of known bits, only capable of holding one value. 284 1.1 mrg Bitwise constant propagation propagates which bits of a 285 1.1 mrg value are constant. 286 1.1 mrg For eg: 287 1.1 mrg int f(int x) 288 1.1 mrg { 289 1.1 mrg return some_op (x); 290 1.1 mrg } 291 1.1 mrg 292 1.1 mrg int f1(int y) 293 1.1 mrg { 294 1.1 mrg if (cond) 295 1.1 mrg return f (y & 0xff); 296 1.1 mrg else 297 1.1 mrg return f (y & 0xf); 298 1.1 mrg } 299 1.1 mrg 300 1.1 mrg In the above case, the param 'x' will always have all 301 1.1 mrg the bits (except the bits in lsb) set to 0. 302 1.1 mrg Hence the mask of 'x' would be 0xff. The mask 303 1.1 mrg reflects that the bits in lsb are unknown. 304 1.1 mrg The actual propagated value is given by m_value & ~m_mask. */ 305 1.1 mrg 306 1.1 mrg class ipcp_bits_lattice 307 1.1 mrg { 308 1.1 mrg public: 309 1.1 mrg bool bottom_p () const { return m_lattice_val == IPA_BITS_VARYING; } 310 1.1 mrg bool top_p () const { return m_lattice_val == IPA_BITS_UNDEFINED; } 311 1.1 mrg bool constant_p () const { return m_lattice_val == IPA_BITS_CONSTANT; } 312 1.1 mrg bool set_to_bottom (); 313 1.1 mrg bool set_to_constant (widest_int, widest_int); 314 1.1 mrg bool known_nonzero_p () const; 315 1.1 mrg 316 1.1 mrg widest_int get_value () const { return m_value; } 317 1.1 mrg widest_int get_mask () const { return m_mask; } 318 1.1 mrg 319 1.1 mrg bool meet_with (ipcp_bits_lattice& other, unsigned, signop, 320 1.1 mrg enum tree_code, tree, bool); 321 1.1 mrg 322 1.1 mrg bool meet_with (widest_int, widest_int, unsigned); 323 1.1 mrg 324 1.1 mrg void print (FILE *); 325 1.1 mrg 326 1.1 mrg private: 327 1.1 mrg enum { IPA_BITS_UNDEFINED, IPA_BITS_CONSTANT, IPA_BITS_VARYING } m_lattice_val; 328 1.1 mrg 329 1.1 mrg /* Similar to ccp_lattice_t, mask represents which bits of value are constant. 330 1.1 mrg If a bit in mask is set to 0, then the corresponding bit in 331 1.1 mrg value is known to be constant. */ 332 1.1 mrg widest_int m_value, m_mask; 333 1.1 mrg 334 1.1 mrg bool meet_with_1 (widest_int, widest_int, unsigned, bool); 335 1.1 mrg void get_value_and_mask (tree, widest_int *, widest_int *); 336 1.1 mrg }; 337 1.1 mrg 338 1.1 mrg /* Lattice of value ranges. */ 339 1.1 mrg 340 1.1 mrg class ipcp_vr_lattice 341 1.1 mrg { 342 1.1 mrg public: 343 1.1 mrg value_range m_vr; 344 1.1 mrg 345 1.1 mrg inline bool bottom_p () const; 346 1.1 mrg inline bool top_p () const; 347 1.1 mrg inline bool set_to_bottom (); 348 1.1 mrg bool meet_with (const value_range *p_vr); 349 1.1 mrg bool meet_with (const ipcp_vr_lattice &other); 350 1.1 mrg void init () { gcc_assert (m_vr.undefined_p ()); } 351 1.1 mrg void print (FILE * f); 352 1.1 mrg 353 1.1 mrg private: 354 1.1 mrg bool meet_with_1 (const value_range *other_vr); 355 1.1 mrg }; 356 1.1 mrg 357 1.1 mrg /* Structure containing lattices for a parameter itself and for pieces of 358 1.1 mrg aggregates that are passed in the parameter or by a reference in a parameter 359 1.1 mrg plus some other useful flags. */ 360 1.1 mrg 361 1.1 mrg class ipcp_param_lattices 362 1.1 mrg { 363 1.1 mrg public: 364 1.1 mrg /* Lattice describing the value of the parameter itself. */ 365 1.1 mrg ipcp_lattice<tree> itself; 366 1.1 mrg /* Lattice describing the polymorphic contexts of a parameter. */ 367 1.1 mrg ipcp_lattice<ipa_polymorphic_call_context> ctxlat; 368 1.1 mrg /* Lattices describing aggregate parts. */ 369 1.1 mrg ipcp_agg_lattice *aggs; 370 1.1 mrg /* Lattice describing known bits. */ 371 1.1 mrg ipcp_bits_lattice bits_lattice; 372 1.1 mrg /* Lattice describing value range. */ 373 1.1 mrg ipcp_vr_lattice m_value_range; 374 1.1 mrg /* Number of aggregate lattices */ 375 1.1 mrg int aggs_count; 376 1.1 mrg /* True if aggregate data were passed by reference (as opposed to by 377 1.1 mrg value). */ 378 1.1 mrg bool aggs_by_ref; 379 1.1 mrg /* All aggregate lattices contain a variable component (in addition to 380 1.1 mrg values). */ 381 1.1 mrg bool aggs_contain_variable; 382 1.1 mrg /* The value of all aggregate lattices is bottom (i.e. variable and unusable 383 1.1 mrg for any propagation). */ 384 1.1 mrg bool aggs_bottom; 385 1.1 mrg 386 1.1 mrg /* There is a virtual call based on this parameter. */ 387 1.1 mrg bool virt_call; 388 1.1 mrg }; 389 1.1 mrg 390 1.1 mrg /* Allocation pools for values and their sources in ipa-cp. */ 391 1.1 mrg 392 1.1 mrg object_allocator<ipcp_value<tree> > ipcp_cst_values_pool 393 1.1 mrg ("IPA-CP constant values"); 394 1.1 mrg 395 1.1 mrg object_allocator<ipcp_value<ipa_polymorphic_call_context> > 396 1.1 mrg ipcp_poly_ctx_values_pool ("IPA-CP polymorphic contexts"); 397 1.1 mrg 398 1.1 mrg object_allocator<ipcp_value_source<tree> > ipcp_sources_pool 399 1.1 mrg ("IPA-CP value sources"); 400 1.1 mrg 401 1.1 mrg object_allocator<ipcp_agg_lattice> ipcp_agg_lattice_pool 402 1.1 mrg ("IPA_CP aggregate lattices"); 403 1.1 mrg 404 1.1 mrg /* Base count to use in heuristics when using profile feedback. */ 405 1.1 mrg 406 1.1 mrg static profile_count base_count; 407 1.1 mrg 408 1.1 mrg /* Original overall size of the program. */ 409 1.1 mrg 410 1.1 mrg static long overall_size, orig_overall_size; 411 1.1 mrg 412 1.1 mrg /* Node name to unique clone suffix number map. */ 413 1.1 mrg static hash_map<const char *, unsigned> *clone_num_suffixes; 414 1.1 mrg 415 1.1 mrg /* Return the param lattices structure corresponding to the Ith formal 416 1.1 mrg parameter of the function described by INFO. */ 417 1.1 mrg static inline class ipcp_param_lattices * 418 1.1 mrg ipa_get_parm_lattices (class ipa_node_params *info, int i) 419 1.1 mrg { 420 1.1 mrg gcc_assert (i >= 0 && i < ipa_get_param_count (info)); 421 1.1 mrg gcc_checking_assert (!info->ipcp_orig_node); 422 1.1 mrg gcc_checking_assert (info->lattices); 423 1.1 mrg return &(info->lattices[i]); 424 1.1 mrg } 425 1.1 mrg 426 1.1 mrg /* Return the lattice corresponding to the scalar value of the Ith formal 427 1.1 mrg parameter of the function described by INFO. */ 428 1.1 mrg static inline ipcp_lattice<tree> * 429 1.1 mrg ipa_get_scalar_lat (class ipa_node_params *info, int i) 430 1.1 mrg { 431 1.1 mrg class ipcp_param_lattices *plats = ipa_get_parm_lattices (info, i); 432 1.1 mrg return &plats->itself; 433 1.1 mrg } 434 1.1 mrg 435 1.1 mrg /* Return the lattice corresponding to the scalar value of the Ith formal 436 1.1 mrg parameter of the function described by INFO. */ 437 1.1 mrg static inline ipcp_lattice<ipa_polymorphic_call_context> * 438 1.1 mrg ipa_get_poly_ctx_lat (class ipa_node_params *info, int i) 439 1.1 mrg { 440 1.1 mrg class ipcp_param_lattices *plats = ipa_get_parm_lattices (info, i); 441 1.1 mrg return &plats->ctxlat; 442 1.1 mrg } 443 1.1 mrg 444 1.1 mrg /* Return whether LAT is a lattice with a single constant and without an 445 1.1 mrg undefined value. */ 446 1.1 mrg 447 1.1 mrg template <typename valtype> 448 1.1 mrg inline bool 449 1.1 mrg ipcp_lattice<valtype>::is_single_const () 450 1.1 mrg { 451 1.1 mrg if (bottom || contains_variable || values_count != 1) 452 1.1 mrg return false; 453 1.1 mrg else 454 1.1 mrg return true; 455 1.1 mrg } 456 1.1 mrg 457 1.1 mrg /* Print V which is extracted from a value in a lattice to F. */ 458 1.1 mrg 459 1.1 mrg static void 460 1.1 mrg print_ipcp_constant_value (FILE * f, tree v) 461 1.1 mrg { 462 1.1 mrg if (TREE_CODE (v) == ADDR_EXPR 463 1.1 mrg && TREE_CODE (TREE_OPERAND (v, 0)) == CONST_DECL) 464 1.1 mrg { 465 1.1 mrg fprintf (f, "& "); 466 1.1 mrg print_generic_expr (f, DECL_INITIAL (TREE_OPERAND (v, 0))); 467 1.1 mrg } 468 1.1 mrg else 469 1.1 mrg print_generic_expr (f, v); 470 1.1 mrg } 471 1.1 mrg 472 1.1 mrg /* Print V which is extracted from a value in a lattice to F. */ 473 1.1 mrg 474 1.1 mrg static void 475 1.1 mrg print_ipcp_constant_value (FILE * f, ipa_polymorphic_call_context v) 476 1.1 mrg { 477 1.1 mrg v.dump(f, false); 478 1.1 mrg } 479 1.1 mrg 480 1.1 mrg /* Print a lattice LAT to F. */ 481 1.1 mrg 482 1.1 mrg template <typename valtype> 483 1.1 mrg void 484 1.1 mrg ipcp_lattice<valtype>::print (FILE * f, bool dump_sources, bool dump_benefits) 485 1.1 mrg { 486 1.1 mrg ipcp_value<valtype> *val; 487 1.1 mrg bool prev = false; 488 1.1 mrg 489 1.1 mrg if (bottom) 490 1.1 mrg { 491 1.1 mrg fprintf (f, "BOTTOM\n"); 492 1.1 mrg return; 493 1.1 mrg } 494 1.1 mrg 495 1.1 mrg if (!values_count && !contains_variable) 496 1.1 mrg { 497 1.1 mrg fprintf (f, "TOP\n"); 498 1.1 mrg return; 499 1.1 mrg } 500 1.1 mrg 501 1.1 mrg if (contains_variable) 502 1.1 mrg { 503 1.1 mrg fprintf (f, "VARIABLE"); 504 1.1 mrg prev = true; 505 1.1 mrg if (dump_benefits) 506 1.1 mrg fprintf (f, "\n"); 507 1.1 mrg } 508 1.1 mrg 509 1.1 mrg for (val = values; val; val = val->next) 510 1.1 mrg { 511 1.1 mrg if (dump_benefits && prev) 512 1.1 mrg fprintf (f, " "); 513 1.1 mrg else if (!dump_benefits && prev) 514 1.1 mrg fprintf (f, ", "); 515 1.1 mrg else 516 1.1 mrg prev = true; 517 1.1 mrg 518 1.1 mrg print_ipcp_constant_value (f, val->value); 519 1.1 mrg 520 1.1 mrg if (dump_sources) 521 1.1 mrg { 522 1.1 mrg ipcp_value_source<valtype> *s; 523 1.1 mrg 524 1.1 mrg if (val->self_recursion_generated_p ()) 525 1.1 mrg fprintf (f, " [self_gen(%i), from:", 526 1.1 mrg val->self_recursion_generated_level); 527 1.1 mrg else 528 1.1 mrg fprintf (f, " [scc: %i, from:", val->scc_no); 529 1.1 mrg for (s = val->sources; s; s = s->next) 530 1.1 mrg fprintf (f, " %i(%f)", s->cs->caller->order, 531 1.1 mrg s->cs->sreal_frequency ().to_double ()); 532 1.1 mrg fprintf (f, "]"); 533 1.1 mrg } 534 1.1 mrg 535 1.1 mrg if (dump_benefits) 536 1.1 mrg fprintf (f, " [loc_time: %g, loc_size: %i, " 537 1.1 mrg "prop_time: %g, prop_size: %i]\n", 538 1.1 mrg val->local_time_benefit.to_double (), val->local_size_cost, 539 1.1 mrg val->prop_time_benefit.to_double (), val->prop_size_cost); 540 1.1 mrg } 541 1.1 mrg if (!dump_benefits) 542 1.1 mrg fprintf (f, "\n"); 543 1.1 mrg } 544 1.1 mrg 545 1.1 mrg void 546 1.1 mrg ipcp_bits_lattice::print (FILE *f) 547 1.1 mrg { 548 1.1 mrg if (top_p ()) 549 1.1 mrg fprintf (f, " Bits unknown (TOP)\n"); 550 1.1 mrg else if (bottom_p ()) 551 1.1 mrg fprintf (f, " Bits unusable (BOTTOM)\n"); 552 1.1 mrg else 553 1.1 mrg { 554 1.1 mrg fprintf (f, " Bits: value = "); print_hex (get_value (), f); 555 1.1 mrg fprintf (f, ", mask = "); print_hex (get_mask (), f); 556 1.1 mrg fprintf (f, "\n"); 557 1.1 mrg } 558 1.1 mrg } 559 1.1 mrg 560 1.1 mrg /* Print value range lattice to F. */ 561 1.1 mrg 562 1.1 mrg void 563 1.1 mrg ipcp_vr_lattice::print (FILE * f) 564 1.1 mrg { 565 1.1 mrg dump_value_range (f, &m_vr); 566 1.1 mrg } 567 1.1 mrg 568 1.1 mrg /* Print all ipcp_lattices of all functions to F. */ 569 1.1 mrg 570 1.1 mrg static void 571 1.1 mrg print_all_lattices (FILE * f, bool dump_sources, bool dump_benefits) 572 1.1 mrg { 573 1.1 mrg struct cgraph_node *node; 574 1.1 mrg int i, count; 575 1.1 mrg 576 1.1 mrg fprintf (f, "\nLattices:\n"); 577 1.1 mrg FOR_EACH_FUNCTION_WITH_GIMPLE_BODY (node) 578 1.1 mrg { 579 1.1 mrg class ipa_node_params *info; 580 1.1 mrg 581 1.1 mrg info = ipa_node_params_sum->get (node); 582 1.1 mrg /* Skip unoptimized functions and constprop clones since we don't make 583 1.1 mrg lattices for them. */ 584 1.1 mrg if (!info || info->ipcp_orig_node) 585 1.1 mrg continue; 586 1.1 mrg fprintf (f, " Node: %s:\n", node->dump_name ()); 587 1.1 mrg count = ipa_get_param_count (info); 588 1.1 mrg for (i = 0; i < count; i++) 589 1.1 mrg { 590 1.1 mrg struct ipcp_agg_lattice *aglat; 591 1.1 mrg class ipcp_param_lattices *plats = ipa_get_parm_lattices (info, i); 592 1.1 mrg fprintf (f, " param [%d]: ", i); 593 1.1 mrg plats->itself.print (f, dump_sources, dump_benefits); 594 1.1 mrg fprintf (f, " ctxs: "); 595 1.1 mrg plats->ctxlat.print (f, dump_sources, dump_benefits); 596 1.1 mrg plats->bits_lattice.print (f); 597 1.1 mrg fprintf (f, " "); 598 1.1 mrg plats->m_value_range.print (f); 599 1.1 mrg fprintf (f, "\n"); 600 1.1 mrg if (plats->virt_call) 601 1.1 mrg fprintf (f, " virt_call flag set\n"); 602 1.1 mrg 603 1.1 mrg if (plats->aggs_bottom) 604 1.1 mrg { 605 1.1 mrg fprintf (f, " AGGS BOTTOM\n"); 606 1.1 mrg continue; 607 1.1 mrg } 608 1.1 mrg if (plats->aggs_contain_variable) 609 1.1 mrg fprintf (f, " AGGS VARIABLE\n"); 610 1.1 mrg for (aglat = plats->aggs; aglat; aglat = aglat->next) 611 1.1 mrg { 612 1.1 mrg fprintf (f, " %soffset " HOST_WIDE_INT_PRINT_DEC ": ", 613 1.1 mrg plats->aggs_by_ref ? "ref " : "", aglat->offset); 614 1.1 mrg aglat->print (f, dump_sources, dump_benefits); 615 1.1 mrg } 616 1.1 mrg } 617 1.1 mrg } 618 1.1 mrg } 619 1.1 mrg 620 1.1 mrg /* Determine whether it is at all technically possible to create clones of NODE 621 1.1 mrg and store this information in the ipa_node_params structure associated 622 1.1 mrg with NODE. */ 623 1.1 mrg 624 1.1 mrg static void 625 1.1 mrg determine_versionability (struct cgraph_node *node, 626 1.1 mrg class ipa_node_params *info) 627 1.1 mrg { 628 1.1 mrg const char *reason = NULL; 629 1.1 mrg 630 1.1 mrg /* There are a number of generic reasons functions cannot be versioned. We 631 1.1 mrg also cannot remove parameters if there are type attributes such as fnspec 632 1.1 mrg present. */ 633 1.1 mrg if (node->alias || node->thunk) 634 1.1 mrg reason = "alias or thunk"; 635 1.1 mrg else if (!node->versionable) 636 1.1 mrg reason = "not a tree_versionable_function"; 637 1.1 mrg else if (node->get_availability () <= AVAIL_INTERPOSABLE) 638 1.1 mrg reason = "insufficient body availability"; 639 1.1 mrg else if (!opt_for_fn (node->decl, optimize) 640 1.1 mrg || !opt_for_fn (node->decl, flag_ipa_cp)) 641 1.1 mrg reason = "non-optimized function"; 642 1.1 mrg else if (lookup_attribute ("omp declare simd", DECL_ATTRIBUTES (node->decl))) 643 1.1 mrg { 644 1.1 mrg /* Ideally we should clone the SIMD clones themselves and create 645 1.1 mrg vector copies of them, so IPA-cp and SIMD clones can happily 646 1.1 mrg coexist, but that may not be worth the effort. */ 647 1.1 mrg reason = "function has SIMD clones"; 648 1.1 mrg } 649 1.1 mrg else if (lookup_attribute ("target_clones", DECL_ATTRIBUTES (node->decl))) 650 1.1 mrg { 651 1.1 mrg /* Ideally we should clone the target clones themselves and create 652 1.1 mrg copies of them, so IPA-cp and target clones can happily 653 1.1 mrg coexist, but that may not be worth the effort. */ 654 1.1 mrg reason = "function target_clones attribute"; 655 1.1 mrg } 656 1.1 mrg /* Don't clone decls local to a comdat group; it breaks and for C++ 657 1.1 mrg decloned constructors, inlining is always better anyway. */ 658 1.1 mrg else if (node->comdat_local_p ()) 659 1.1 mrg reason = "comdat-local function"; 660 1.1 mrg else if (node->calls_comdat_local) 661 1.1 mrg { 662 1.1 mrg /* TODO: call is versionable if we make sure that all 663 1.1 mrg callers are inside of a comdat group. */ 664 1.1 mrg reason = "calls comdat-local function"; 665 1.1 mrg } 666 1.1 mrg 667 1.1 mrg /* Functions calling BUILT_IN_VA_ARG_PACK and BUILT_IN_VA_ARG_PACK_LEN 668 1.1 mrg work only when inlined. Cloning them may still lead to better code 669 1.1 mrg because ipa-cp will not give up on cloning further. If the function is 670 1.1 mrg external this however leads to wrong code because we may end up producing 671 1.1 mrg offline copy of the function. */ 672 1.1 mrg if (DECL_EXTERNAL (node->decl)) 673 1.1 mrg for (cgraph_edge *edge = node->callees; !reason && edge; 674 1.1 mrg edge = edge->next_callee) 675 1.1 mrg if (fndecl_built_in_p (edge->callee->decl, BUILT_IN_NORMAL)) 676 1.1 mrg { 677 1.1 mrg if (DECL_FUNCTION_CODE (edge->callee->decl) == BUILT_IN_VA_ARG_PACK) 678 1.1 mrg reason = "external function which calls va_arg_pack"; 679 1.1 mrg if (DECL_FUNCTION_CODE (edge->callee->decl) 680 1.1 mrg == BUILT_IN_VA_ARG_PACK_LEN) 681 1.1 mrg reason = "external function which calls va_arg_pack_len"; 682 1.1 mrg } 683 1.1 mrg 684 1.1 mrg if (reason && dump_file && !node->alias && !node->thunk) 685 1.1 mrg fprintf (dump_file, "Function %s is not versionable, reason: %s.\n", 686 1.1 mrg node->dump_name (), reason); 687 1.1 mrg 688 1.1 mrg info->versionable = (reason == NULL); 689 1.1 mrg } 690 1.1 mrg 691 1.1 mrg /* Return true if it is at all technically possible to create clones of a 692 1.1 mrg NODE. */ 693 1.1 mrg 694 1.1 mrg static bool 695 1.1 mrg ipcp_versionable_function_p (struct cgraph_node *node) 696 1.1 mrg { 697 1.1 mrg ipa_node_params *info = ipa_node_params_sum->get (node); 698 1.1 mrg return info && info->versionable; 699 1.1 mrg } 700 1.1 mrg 701 1.1 mrg /* Structure holding accumulated information about callers of a node. */ 702 1.1 mrg 703 1.1 mrg struct caller_statistics 704 1.1 mrg { 705 1.1 mrg /* If requested (see below), self-recursive call counts are summed into this 706 1.1 mrg field. */ 707 1.1 mrg profile_count rec_count_sum; 708 1.1 mrg /* The sum of all ipa counts of all the other (non-recursive) calls. */ 709 1.1 mrg profile_count count_sum; 710 1.1 mrg /* Sum of all frequencies for all calls. */ 711 1.1 mrg sreal freq_sum; 712 1.1 mrg /* Number of calls and hot calls respectively. */ 713 1.1 mrg int n_calls, n_hot_calls; 714 1.1 mrg /* If itself is set up, also count the number of non-self-recursive 715 1.1 mrg calls. */ 716 1.1 mrg int n_nonrec_calls; 717 1.1 mrg /* If non-NULL, this is the node itself and calls from it should have their 718 1.1 mrg counts included in rec_count_sum and not count_sum. */ 719 1.1 mrg cgraph_node *itself; 720 1.1 mrg }; 721 1.1 mrg 722 1.1 mrg /* Initialize fields of STAT to zeroes and optionally set it up so that edges 723 1.1 mrg from IGNORED_CALLER are not counted. */ 724 1.1 mrg 725 1.1 mrg static inline void 726 1.1 mrg init_caller_stats (caller_statistics *stats, cgraph_node *itself = NULL) 727 1.1 mrg { 728 1.1 mrg stats->rec_count_sum = profile_count::zero (); 729 1.1 mrg stats->count_sum = profile_count::zero (); 730 1.1 mrg stats->n_calls = 0; 731 1.1 mrg stats->n_hot_calls = 0; 732 1.1 mrg stats->n_nonrec_calls = 0; 733 1.1 mrg stats->freq_sum = 0; 734 1.1 mrg stats->itself = itself; 735 1.1 mrg } 736 1.1 mrg 737 1.1 mrg /* Worker callback of cgraph_for_node_and_aliases accumulating statistics of 738 1.1 mrg non-thunk incoming edges to NODE. */ 739 1.1 mrg 740 1.1 mrg static bool 741 1.1 mrg gather_caller_stats (struct cgraph_node *node, void *data) 742 1.1 mrg { 743 1.1 mrg struct caller_statistics *stats = (struct caller_statistics *) data; 744 1.1 mrg struct cgraph_edge *cs; 745 1.1 mrg 746 1.1 mrg for (cs = node->callers; cs; cs = cs->next_caller) 747 1.1 mrg if (!cs->caller->thunk) 748 1.1 mrg { 749 1.1 mrg ipa_node_params *info = ipa_node_params_sum->get (cs->caller); 750 1.1 mrg if (info && info->node_dead) 751 1.1 mrg continue; 752 1.1 mrg 753 1.1 mrg if (cs->count.ipa ().initialized_p ()) 754 1.1 mrg { 755 1.1 mrg if (stats->itself && stats->itself == cs->caller) 756 1.1 mrg stats->rec_count_sum += cs->count.ipa (); 757 1.1 mrg else 758 1.1 mrg stats->count_sum += cs->count.ipa (); 759 1.1 mrg } 760 1.1 mrg stats->freq_sum += cs->sreal_frequency (); 761 1.1 mrg stats->n_calls++; 762 1.1 mrg if (stats->itself && stats->itself != cs->caller) 763 1.1 mrg stats->n_nonrec_calls++; 764 1.1 mrg 765 1.1 mrg if (cs->maybe_hot_p ()) 766 1.1 mrg stats->n_hot_calls ++; 767 1.1 mrg } 768 1.1 mrg return false; 769 1.1 mrg 770 1.1 mrg } 771 1.1 mrg 772 1.1 mrg /* Return true if this NODE is viable candidate for cloning. */ 773 1.1 mrg 774 1.1 mrg static bool 775 1.1 mrg ipcp_cloning_candidate_p (struct cgraph_node *node) 776 1.1 mrg { 777 1.1 mrg struct caller_statistics stats; 778 1.1 mrg 779 1.1 mrg gcc_checking_assert (node->has_gimple_body_p ()); 780 1.1 mrg 781 1.1 mrg if (!opt_for_fn (node->decl, flag_ipa_cp_clone)) 782 1.1 mrg { 783 1.1 mrg if (dump_file) 784 1.1 mrg fprintf (dump_file, "Not considering %s for cloning; " 785 1.1 mrg "-fipa-cp-clone disabled.\n", 786 1.1 mrg node->dump_name ()); 787 1.1 mrg return false; 788 1.1 mrg } 789 1.1 mrg 790 1.1 mrg if (node->optimize_for_size_p ()) 791 1.1 mrg { 792 1.1 mrg if (dump_file) 793 1.1 mrg fprintf (dump_file, "Not considering %s for cloning; " 794 1.1 mrg "optimizing it for size.\n", 795 1.1 mrg node->dump_name ()); 796 1.1 mrg return false; 797 1.1 mrg } 798 1.1 mrg 799 1.1 mrg init_caller_stats (&stats); 800 1.1 mrg node->call_for_symbol_thunks_and_aliases (gather_caller_stats, &stats, false); 801 1.1 mrg 802 1.1 mrg if (ipa_size_summaries->get (node)->self_size < stats.n_calls) 803 1.1 mrg { 804 1.1 mrg if (dump_file) 805 1.1 mrg fprintf (dump_file, "Considering %s for cloning; code might shrink.\n", 806 1.1 mrg node->dump_name ()); 807 1.1 mrg return true; 808 1.1 mrg } 809 1.1 mrg 810 1.1 mrg /* When profile is available and function is hot, propagate into it even if 811 1.1 mrg calls seems cold; constant propagation can improve function's speed 812 1.1 mrg significantly. */ 813 1.1 mrg if (stats.count_sum > profile_count::zero () 814 1.1 mrg && node->count.ipa ().initialized_p ()) 815 1.1 mrg { 816 1.1 mrg if (stats.count_sum > node->count.ipa ().apply_scale (90, 100)) 817 1.1 mrg { 818 1.1 mrg if (dump_file) 819 1.1 mrg fprintf (dump_file, "Considering %s for cloning; " 820 1.1 mrg "usually called directly.\n", 821 1.1 mrg node->dump_name ()); 822 1.1 mrg return true; 823 1.1 mrg } 824 1.1 mrg } 825 1.1 mrg if (!stats.n_hot_calls) 826 1.1 mrg { 827 1.1 mrg if (dump_file) 828 1.1 mrg fprintf (dump_file, "Not considering %s for cloning; no hot calls.\n", 829 1.1 mrg node->dump_name ()); 830 1.1 mrg return false; 831 1.1 mrg } 832 1.1 mrg if (dump_file) 833 1.1 mrg fprintf (dump_file, "Considering %s for cloning.\n", 834 1.1 mrg node->dump_name ()); 835 1.1 mrg return true; 836 1.1 mrg } 837 1.1 mrg 838 1.1 mrg template <typename valtype> 839 1.1 mrg class value_topo_info 840 1.1 mrg { 841 1.1 mrg public: 842 1.1 mrg /* Head of the linked list of topologically sorted values. */ 843 1.1 mrg ipcp_value<valtype> *values_topo; 844 1.1 mrg /* Stack for creating SCCs, represented by a linked list too. */ 845 1.1 mrg ipcp_value<valtype> *stack; 846 1.1 mrg /* Counter driving the algorithm in add_val_to_toposort. */ 847 1.1 mrg int dfs_counter; 848 1.1 mrg 849 1.1 mrg value_topo_info () : values_topo (NULL), stack (NULL), dfs_counter (0) 850 1.1 mrg {} 851 1.1 mrg void add_val (ipcp_value<valtype> *cur_val); 852 1.1 mrg void propagate_effects (); 853 1.1 mrg }; 854 1.1 mrg 855 1.1 mrg /* Arrays representing a topological ordering of call graph nodes and a stack 856 1.1 mrg of nodes used during constant propagation and also data required to perform 857 1.1 mrg topological sort of values and propagation of benefits in the determined 858 1.1 mrg order. */ 859 1.1 mrg 860 1.1 mrg class ipa_topo_info 861 1.1 mrg { 862 1.1 mrg public: 863 1.1 mrg /* Array with obtained topological order of cgraph nodes. */ 864 1.1 mrg struct cgraph_node **order; 865 1.1 mrg /* Stack of cgraph nodes used during propagation within SCC until all values 866 1.1 mrg in the SCC stabilize. */ 867 1.1 mrg struct cgraph_node **stack; 868 1.1 mrg int nnodes, stack_top; 869 1.1 mrg 870 1.1 mrg value_topo_info<tree> constants; 871 1.1 mrg value_topo_info<ipa_polymorphic_call_context> contexts; 872 1.1 mrg 873 1.1 mrg ipa_topo_info () : order(NULL), stack(NULL), nnodes(0), stack_top(0), 874 1.1 mrg constants () 875 1.1 mrg {} 876 1.1 mrg }; 877 1.1 mrg 878 1.1 mrg /* Skip edges from and to nodes without ipa_cp enabled. 879 1.1 mrg Ignore not available symbols. */ 880 1.1 mrg 881 1.1 mrg static bool 882 1.1 mrg ignore_edge_p (cgraph_edge *e) 883 1.1 mrg { 884 1.1 mrg enum availability avail; 885 1.1 mrg cgraph_node *ultimate_target 886 1.1 mrg = e->callee->function_or_virtual_thunk_symbol (&avail, e->caller); 887 1.1 mrg 888 1.1 mrg return (avail <= AVAIL_INTERPOSABLE 889 1.1 mrg || !opt_for_fn (ultimate_target->decl, optimize) 890 1.1 mrg || !opt_for_fn (ultimate_target->decl, flag_ipa_cp)); 891 1.1 mrg } 892 1.1 mrg 893 1.1 mrg /* Allocate the arrays in TOPO and topologically sort the nodes into order. */ 894 1.1 mrg 895 1.1 mrg static void 896 1.1 mrg build_toporder_info (class ipa_topo_info *topo) 897 1.1 mrg { 898 1.1 mrg topo->order = XCNEWVEC (struct cgraph_node *, symtab->cgraph_count); 899 1.1 mrg topo->stack = XCNEWVEC (struct cgraph_node *, symtab->cgraph_count); 900 1.1 mrg 901 1.1 mrg gcc_checking_assert (topo->stack_top == 0); 902 1.1 mrg topo->nnodes = ipa_reduced_postorder (topo->order, true, 903 1.1 mrg ignore_edge_p); 904 1.1 mrg } 905 1.1 mrg 906 1.1 mrg /* Free information about strongly connected components and the arrays in 907 1.1 mrg TOPO. */ 908 1.1 mrg 909 1.1 mrg static void 910 1.1 mrg free_toporder_info (class ipa_topo_info *topo) 911 1.1 mrg { 912 1.1 mrg ipa_free_postorder_info (); 913 1.1 mrg free (topo->order); 914 1.1 mrg free (topo->stack); 915 1.1 mrg } 916 1.1 mrg 917 1.1 mrg /* Add NODE to the stack in TOPO, unless it is already there. */ 918 1.1 mrg 919 1.1 mrg static inline void 920 1.1 mrg push_node_to_stack (class ipa_topo_info *topo, struct cgraph_node *node) 921 1.1 mrg { 922 1.1 mrg ipa_node_params *info = ipa_node_params_sum->get (node); 923 1.1 mrg if (info->node_enqueued) 924 1.1 mrg return; 925 1.1 mrg info->node_enqueued = 1; 926 1.1 mrg topo->stack[topo->stack_top++] = node; 927 1.1 mrg } 928 1.1 mrg 929 1.1 mrg /* Pop a node from the stack in TOPO and return it or return NULL if the stack 930 1.1 mrg is empty. */ 931 1.1 mrg 932 1.1 mrg static struct cgraph_node * 933 1.1 mrg pop_node_from_stack (class ipa_topo_info *topo) 934 1.1 mrg { 935 1.1 mrg if (topo->stack_top) 936 1.1 mrg { 937 1.1 mrg struct cgraph_node *node; 938 1.1 mrg topo->stack_top--; 939 1.1 mrg node = topo->stack[topo->stack_top]; 940 1.1 mrg ipa_node_params_sum->get (node)->node_enqueued = 0; 941 1.1 mrg return node; 942 1.1 mrg } 943 1.1 mrg else 944 1.1 mrg return NULL; 945 1.1 mrg } 946 1.1 mrg 947 1.1 mrg /* Set lattice LAT to bottom and return true if it previously was not set as 948 1.1 mrg such. */ 949 1.1 mrg 950 1.1 mrg template <typename valtype> 951 1.1 mrg inline bool 952 1.1 mrg ipcp_lattice<valtype>::set_to_bottom () 953 1.1 mrg { 954 1.1 mrg bool ret = !bottom; 955 1.1 mrg bottom = true; 956 1.1 mrg return ret; 957 1.1 mrg } 958 1.1 mrg 959 1.1 mrg /* Mark lattice as containing an unknown value and return true if it previously 960 1.1 mrg was not marked as such. */ 961 1.1 mrg 962 1.1 mrg template <typename valtype> 963 1.1 mrg inline bool 964 1.1 mrg ipcp_lattice<valtype>::set_contains_variable () 965 1.1 mrg { 966 1.1 mrg bool ret = !contains_variable; 967 1.1 mrg contains_variable = true; 968 1.1 mrg return ret; 969 1.1 mrg } 970 1.1 mrg 971 1.1 mrg /* Set all aggregate lattices in PLATS to bottom and return true if they were 972 1.1 mrg not previously set as such. */ 973 1.1 mrg 974 1.1 mrg static inline bool 975 1.1 mrg set_agg_lats_to_bottom (class ipcp_param_lattices *plats) 976 1.1 mrg { 977 1.1 mrg bool ret = !plats->aggs_bottom; 978 1.1 mrg plats->aggs_bottom = true; 979 1.1 mrg return ret; 980 1.1 mrg } 981 1.1 mrg 982 1.1 mrg /* Mark all aggregate lattices in PLATS as containing an unknown value and 983 1.1 mrg return true if they were not previously marked as such. */ 984 1.1 mrg 985 1.1 mrg static inline bool 986 1.1 mrg set_agg_lats_contain_variable (class ipcp_param_lattices *plats) 987 1.1 mrg { 988 1.1 mrg bool ret = !plats->aggs_contain_variable; 989 1.1 mrg plats->aggs_contain_variable = true; 990 1.1 mrg return ret; 991 1.1 mrg } 992 1.1 mrg 993 1.1 mrg bool 994 1.1 mrg ipcp_vr_lattice::meet_with (const ipcp_vr_lattice &other) 995 1.1 mrg { 996 1.1 mrg return meet_with_1 (&other.m_vr); 997 1.1 mrg } 998 1.1 mrg 999 1.1 mrg /* Meet the current value of the lattice with value range described by VR 1000 1.1 mrg lattice. */ 1001 1.1 mrg 1002 1.1 mrg bool 1003 1.1 mrg ipcp_vr_lattice::meet_with (const value_range *p_vr) 1004 1.1 mrg { 1005 1.1 mrg return meet_with_1 (p_vr); 1006 1.1 mrg } 1007 1.1 mrg 1008 1.1 mrg /* Meet the current value of the lattice with value range described by 1009 1.1 mrg OTHER_VR lattice. Return TRUE if anything changed. */ 1010 1.1 mrg 1011 1.1 mrg bool 1012 1.1 mrg ipcp_vr_lattice::meet_with_1 (const value_range *other_vr) 1013 1.1 mrg { 1014 1.1 mrg if (bottom_p ()) 1015 1.1 mrg return false; 1016 1.1 mrg 1017 1.1 mrg if (other_vr->varying_p ()) 1018 1.1 mrg return set_to_bottom (); 1019 1.1 mrg 1020 1.1 mrg value_range save (m_vr); 1021 1.1 mrg m_vr.union_ (other_vr); 1022 1.1 mrg return !m_vr.equal_p (save); 1023 1.1 mrg } 1024 1.1 mrg 1025 1.1 mrg /* Return true if value range information in the lattice is yet unknown. */ 1026 1.1 mrg 1027 1.1 mrg bool 1028 1.1 mrg ipcp_vr_lattice::top_p () const 1029 1.1 mrg { 1030 1.1 mrg return m_vr.undefined_p (); 1031 1.1 mrg } 1032 1.1 mrg 1033 1.1 mrg /* Return true if value range information in the lattice is known to be 1034 1.1 mrg unusable. */ 1035 1.1 mrg 1036 1.1 mrg bool 1037 1.1 mrg ipcp_vr_lattice::bottom_p () const 1038 1.1 mrg { 1039 1.1 mrg return m_vr.varying_p (); 1040 1.1 mrg } 1041 1.1 mrg 1042 1.1 mrg /* Set value range information in the lattice to bottom. Return true if it 1043 1.1 mrg previously was in a different state. */ 1044 1.1 mrg 1045 1.1 mrg bool 1046 1.1 mrg ipcp_vr_lattice::set_to_bottom () 1047 1.1 mrg { 1048 1.1 mrg if (m_vr.varying_p ()) 1049 1.1 mrg return false; 1050 1.1 mrg /* ?? We create all sorts of VARYING ranges for floats, structures, 1051 1.1 mrg and other types which we cannot handle as ranges. We should 1052 1.1 mrg probably avoid handling them throughout the pass, but it's easier 1053 1.1 mrg to create a sensible VARYING here and let the lattice 1054 1.1 mrg propagate. */ 1055 1.1 mrg m_vr.set_varying (integer_type_node); 1056 1.1 mrg return true; 1057 1.1 mrg } 1058 1.1 mrg 1059 1.1 mrg /* Set lattice value to bottom, if it already isn't the case. */ 1060 1.1 mrg 1061 1.1 mrg bool 1062 1.1 mrg ipcp_bits_lattice::set_to_bottom () 1063 1.1 mrg { 1064 1.1 mrg if (bottom_p ()) 1065 1.1 mrg return false; 1066 1.1 mrg m_lattice_val = IPA_BITS_VARYING; 1067 1.1 mrg m_value = 0; 1068 1.1 mrg m_mask = -1; 1069 1.1 mrg return true; 1070 1.1 mrg } 1071 1.1 mrg 1072 1.1 mrg /* Set to constant if it isn't already. Only meant to be called 1073 1.1 mrg when switching state from TOP. */ 1074 1.1 mrg 1075 1.1 mrg bool 1076 1.1 mrg ipcp_bits_lattice::set_to_constant (widest_int value, widest_int mask) 1077 1.1 mrg { 1078 1.1 mrg gcc_assert (top_p ()); 1079 1.1 mrg m_lattice_val = IPA_BITS_CONSTANT; 1080 1.1 mrg m_value = wi::bit_and (wi::bit_not (mask), value); 1081 1.1 mrg m_mask = mask; 1082 1.1 mrg return true; 1083 1.1 mrg } 1084 1.1 mrg 1085 1.1 mrg /* Return true if any of the known bits are non-zero. */ 1086 1.1 mrg 1087 1.1 mrg bool 1088 1.1 mrg ipcp_bits_lattice::known_nonzero_p () const 1089 1.1 mrg { 1090 1.1 mrg if (!constant_p ()) 1091 1.1 mrg return false; 1092 1.1 mrg return wi::ne_p (wi::bit_and (wi::bit_not (m_mask), m_value), 0); 1093 1.1 mrg } 1094 1.1 mrg 1095 1.1 mrg /* Convert operand to value, mask form. */ 1096 1.1 mrg 1097 1.1 mrg void 1098 1.1 mrg ipcp_bits_lattice::get_value_and_mask (tree operand, widest_int *valuep, widest_int *maskp) 1099 1.1 mrg { 1100 1.1 mrg wide_int get_nonzero_bits (const_tree); 1101 1.1 mrg 1102 1.1 mrg if (TREE_CODE (operand) == INTEGER_CST) 1103 1.1 mrg { 1104 1.1 mrg *valuep = wi::to_widest (operand); 1105 1.1 mrg *maskp = 0; 1106 1.1 mrg } 1107 1.1 mrg else 1108 1.1 mrg { 1109 1.1 mrg *valuep = 0; 1110 1.1 mrg *maskp = -1; 1111 1.1 mrg } 1112 1.1 mrg } 1113 1.1 mrg 1114 1.1 mrg /* Meet operation, similar to ccp_lattice_meet, we xor values 1115 1.1 mrg if this->value, value have different values at same bit positions, we want 1116 1.1 mrg to drop that bit to varying. Return true if mask is changed. 1117 1.1 mrg This function assumes that the lattice value is in CONSTANT state. If 1118 1.1 mrg DROP_ALL_ONES, mask out any known bits with value one afterwards. */ 1119 1.1 mrg 1120 1.1 mrg bool 1121 1.1 mrg ipcp_bits_lattice::meet_with_1 (widest_int value, widest_int mask, 1122 1.1 mrg unsigned precision, bool drop_all_ones) 1123 1.1 mrg { 1124 1.1 mrg gcc_assert (constant_p ()); 1125 1.1 mrg 1126 1.1 mrg widest_int old_mask = m_mask; 1127 1.1 mrg m_mask = (m_mask | mask) | (m_value ^ value); 1128 1.1 mrg if (drop_all_ones) 1129 1.1 mrg m_mask |= m_value; 1130 1.1 mrg m_value &= ~m_mask; 1131 1.1 mrg 1132 1.1 mrg if (wi::sext (m_mask, precision) == -1) 1133 1.1 mrg return set_to_bottom (); 1134 1.1 mrg 1135 1.1 mrg return m_mask != old_mask; 1136 1.1 mrg } 1137 1.1 mrg 1138 1.1 mrg /* Meet the bits lattice with operand 1139 1.1 mrg described by <value, mask, sgn, precision. */ 1140 1.1 mrg 1141 1.1 mrg bool 1142 1.1 mrg ipcp_bits_lattice::meet_with (widest_int value, widest_int mask, 1143 1.1 mrg unsigned precision) 1144 1.1 mrg { 1145 1.1 mrg if (bottom_p ()) 1146 1.1 mrg return false; 1147 1.1 mrg 1148 1.1 mrg if (top_p ()) 1149 1.1 mrg { 1150 1.1 mrg if (wi::sext (mask, precision) == -1) 1151 1.1 mrg return set_to_bottom (); 1152 1.1 mrg return set_to_constant (value, mask); 1153 1.1 mrg } 1154 1.1 mrg 1155 1.1 mrg return meet_with_1 (value, mask, precision, false); 1156 1.1 mrg } 1157 1.1 mrg 1158 1.1 mrg /* Meet bits lattice with the result of bit_value_binop (other, operand) 1159 1.1 mrg if code is binary operation or bit_value_unop (other) if code is unary op. 1160 1.1 mrg In the case when code is nop_expr, no adjustment is required. If 1161 1.1 mrg DROP_ALL_ONES, mask out any known bits with value one afterwards. */ 1162 1.1 mrg 1163 1.1 mrg bool 1164 1.1 mrg ipcp_bits_lattice::meet_with (ipcp_bits_lattice& other, unsigned precision, 1165 1.1 mrg signop sgn, enum tree_code code, tree operand, 1166 1.1 mrg bool drop_all_ones) 1167 1.1 mrg { 1168 1.1 mrg if (other.bottom_p ()) 1169 1.1 mrg return set_to_bottom (); 1170 1.1 mrg 1171 1.1 mrg if (bottom_p () || other.top_p ()) 1172 1.1 mrg return false; 1173 1.1 mrg 1174 1.1 mrg widest_int adjusted_value, adjusted_mask; 1175 1.1 mrg 1176 1.1 mrg if (TREE_CODE_CLASS (code) == tcc_binary) 1177 1.1 mrg { 1178 1.1 mrg tree type = TREE_TYPE (operand); 1179 1.1 mrg widest_int o_value, o_mask; 1180 1.1 mrg get_value_and_mask (operand, &o_value, &o_mask); 1181 1.1 mrg 1182 1.1 mrg bit_value_binop (code, sgn, precision, &adjusted_value, &adjusted_mask, 1183 1.1 mrg sgn, precision, other.get_value (), other.get_mask (), 1184 1.1 mrg TYPE_SIGN (type), TYPE_PRECISION (type), o_value, o_mask); 1185 1.1 mrg 1186 1.1 mrg if (wi::sext (adjusted_mask, precision) == -1) 1187 1.1 mrg return set_to_bottom (); 1188 1.1 mrg } 1189 1.1 mrg 1190 1.1 mrg else if (TREE_CODE_CLASS (code) == tcc_unary) 1191 1.1 mrg { 1192 1.1 mrg bit_value_unop (code, sgn, precision, &adjusted_value, 1193 1.1 mrg &adjusted_mask, sgn, precision, other.get_value (), 1194 1.1 mrg other.get_mask ()); 1195 1.1 mrg 1196 1.1 mrg if (wi::sext (adjusted_mask, precision) == -1) 1197 1.1 mrg return set_to_bottom (); 1198 1.1 mrg } 1199 1.1 mrg 1200 1.1 mrg else 1201 1.1 mrg return set_to_bottom (); 1202 1.1 mrg 1203 1.1 mrg if (top_p ()) 1204 1.1 mrg { 1205 1.1 mrg if (drop_all_ones) 1206 1.1 mrg { 1207 1.1 mrg adjusted_mask |= adjusted_value; 1208 1.1 mrg adjusted_value &= ~adjusted_mask; 1209 1.1 mrg } 1210 1.1 mrg if (wi::sext (adjusted_mask, precision) == -1) 1211 1.1 mrg return set_to_bottom (); 1212 1.1 mrg return set_to_constant (adjusted_value, adjusted_mask); 1213 1.1 mrg } 1214 1.1 mrg else 1215 1.1 mrg return meet_with_1 (adjusted_value, adjusted_mask, precision, 1216 1.1 mrg drop_all_ones); 1217 1.1 mrg } 1218 1.1 mrg 1219 1.1 mrg /* Mark bot aggregate and scalar lattices as containing an unknown variable, 1220 1.1 mrg return true is any of them has not been marked as such so far. */ 1221 1.1 mrg 1222 1.1 mrg static inline bool 1223 1.1 mrg set_all_contains_variable (class ipcp_param_lattices *plats) 1224 1.1 mrg { 1225 1.1 mrg bool ret; 1226 1.1 mrg ret = plats->itself.set_contains_variable (); 1227 1.1 mrg ret |= plats->ctxlat.set_contains_variable (); 1228 1.1 mrg ret |= set_agg_lats_contain_variable (plats); 1229 1.1 mrg ret |= plats->bits_lattice.set_to_bottom (); 1230 1.1 mrg ret |= plats->m_value_range.set_to_bottom (); 1231 1.1 mrg return ret; 1232 1.1 mrg } 1233 1.1 mrg 1234 1.1 mrg /* Worker of call_for_symbol_thunks_and_aliases, increment the integer DATA 1235 1.1 mrg points to by the number of callers to NODE. */ 1236 1.1 mrg 1237 1.1 mrg static bool 1238 1.1 mrg count_callers (cgraph_node *node, void *data) 1239 1.1 mrg { 1240 1.1 mrg int *caller_count = (int *) data; 1241 1.1 mrg 1242 1.1 mrg for (cgraph_edge *cs = node->callers; cs; cs = cs->next_caller) 1243 1.1 mrg /* Local thunks can be handled transparently, but if the thunk cannot 1244 1.1 mrg be optimized out, count it as a real use. */ 1245 1.1 mrg if (!cs->caller->thunk || !cs->caller->local) 1246 1.1 mrg ++*caller_count; 1247 1.1 mrg return false; 1248 1.1 mrg } 1249 1.1 mrg 1250 1.1 mrg /* Worker of call_for_symbol_thunks_and_aliases, it is supposed to be called on 1251 1.1 mrg the one caller of some other node. Set the caller's corresponding flag. */ 1252 1.1 mrg 1253 1.1 mrg static bool 1254 1.1 mrg set_single_call_flag (cgraph_node *node, void *) 1255 1.1 mrg { 1256 1.1 mrg cgraph_edge *cs = node->callers; 1257 1.1 mrg /* Local thunks can be handled transparently, skip them. */ 1258 1.1 mrg while (cs && cs->caller->thunk && cs->caller->local) 1259 1.1 mrg cs = cs->next_caller; 1260 1.1 mrg if (cs) 1261 1.1 mrg if (ipa_node_params* info = ipa_node_params_sum->get (cs->caller)) 1262 1.1 mrg { 1263 1.1 mrg info->node_calling_single_call = true; 1264 1.1 mrg return true; 1265 1.1 mrg } 1266 1.1 mrg return false; 1267 1.1 mrg } 1268 1.1 mrg 1269 1.1 mrg /* Initialize ipcp_lattices. */ 1270 1.1 mrg 1271 1.1 mrg static void 1272 1.1 mrg initialize_node_lattices (struct cgraph_node *node) 1273 1.1 mrg { 1274 1.1 mrg ipa_node_params *info = ipa_node_params_sum->get (node); 1275 1.1 mrg struct cgraph_edge *ie; 1276 1.1 mrg bool disable = false, variable = false; 1277 1.1 mrg int i; 1278 1.1 mrg 1279 1.1 mrg gcc_checking_assert (node->has_gimple_body_p ()); 1280 1.1 mrg 1281 1.1 mrg if (!ipa_get_param_count (info)) 1282 1.1 mrg disable = true; 1283 1.1 mrg else if (node->local) 1284 1.1 mrg { 1285 1.1 mrg int caller_count = 0; 1286 1.1 mrg node->call_for_symbol_thunks_and_aliases (count_callers, &caller_count, 1287 1.1 mrg true); 1288 1.1 mrg gcc_checking_assert (caller_count > 0); 1289 1.1 mrg if (caller_count == 1) 1290 1.1 mrg node->call_for_symbol_thunks_and_aliases (set_single_call_flag, 1291 1.1 mrg NULL, true); 1292 1.1 mrg } 1293 1.1 mrg else 1294 1.1 mrg { 1295 1.1 mrg /* When cloning is allowed, we can assume that externally visible 1296 1.1 mrg functions are not called. We will compensate this by cloning 1297 1.1 mrg later. */ 1298 1.1 mrg if (ipcp_versionable_function_p (node) 1299 1.1 mrg && ipcp_cloning_candidate_p (node)) 1300 1.1 mrg variable = true; 1301 1.1 mrg else 1302 1.1 mrg disable = true; 1303 1.1 mrg } 1304 1.1 mrg 1305 1.1 mrg if (dump_file && (dump_flags & TDF_DETAILS) 1306 1.1 mrg && !node->alias && !node->thunk) 1307 1.1 mrg { 1308 1.1 mrg fprintf (dump_file, "Initializing lattices of %s\n", 1309 1.1 mrg node->dump_name ()); 1310 1.1 mrg if (disable || variable) 1311 1.1 mrg fprintf (dump_file, " Marking all lattices as %s\n", 1312 1.1 mrg disable ? "BOTTOM" : "VARIABLE"); 1313 1.1 mrg } 1314 1.1 mrg 1315 1.1 mrg auto_vec<bool, 16> surviving_params; 1316 1.1 mrg bool pre_modified = false; 1317 1.1 mrg 1318 1.1 mrg clone_info *cinfo = clone_info::get (node); 1319 1.1 mrg 1320 1.1 mrg if (!disable && cinfo && cinfo->param_adjustments) 1321 1.1 mrg { 1322 1.1 mrg /* At the moment all IPA optimizations should use the number of 1323 1.1 mrg parameters of the prevailing decl as the m_always_copy_start. 1324 1.1 mrg Handling any other value would complicate the code below, so for the 1325 1.1 mrg time bing let's only assert it is so. */ 1326 1.1 mrg gcc_assert ((cinfo->param_adjustments->m_always_copy_start 1327 1.1 mrg == ipa_get_param_count (info)) 1328 1.1 mrg || cinfo->param_adjustments->m_always_copy_start < 0); 1329 1.1 mrg 1330 1.1 mrg pre_modified = true; 1331 1.1 mrg cinfo->param_adjustments->get_surviving_params (&surviving_params); 1332 1.1 mrg 1333 1.1 mrg if (dump_file && (dump_flags & TDF_DETAILS) 1334 1.1 mrg && !node->alias && !node->thunk) 1335 1.1 mrg { 1336 1.1 mrg bool first = true; 1337 1.1 mrg for (int j = 0; j < ipa_get_param_count (info); j++) 1338 1.1 mrg { 1339 1.1 mrg if (j < (int) surviving_params.length () 1340 1.1 mrg && surviving_params[j]) 1341 1.1 mrg continue; 1342 1.1 mrg if (first) 1343 1.1 mrg { 1344 1.1 mrg fprintf (dump_file, 1345 1.1 mrg " The following parameters are dead on arrival:"); 1346 1.1 mrg first = false; 1347 1.1 mrg } 1348 1.1 mrg fprintf (dump_file, " %u", j); 1349 1.1 mrg } 1350 1.1 mrg if (!first) 1351 1.1 mrg fprintf (dump_file, "\n"); 1352 1.1 mrg } 1353 1.1 mrg } 1354 1.1 mrg 1355 1.1 mrg for (i = 0; i < ipa_get_param_count (info); i++) 1356 1.1 mrg { 1357 1.1 mrg ipcp_param_lattices *plats = ipa_get_parm_lattices (info, i); 1358 1.1 mrg if (disable 1359 1.1 mrg || !ipa_get_type (info, i) 1360 1.1 mrg || (pre_modified && (surviving_params.length () <= (unsigned) i 1361 1.1 mrg || !surviving_params[i]))) 1362 1.1 mrg { 1363 1.1 mrg plats->itself.set_to_bottom (); 1364 1.1 mrg plats->ctxlat.set_to_bottom (); 1365 1.1 mrg set_agg_lats_to_bottom (plats); 1366 1.1 mrg plats->bits_lattice.set_to_bottom (); 1367 1.1 mrg plats->m_value_range.m_vr = value_range (); 1368 1.1 mrg plats->m_value_range.set_to_bottom (); 1369 1.1 mrg } 1370 1.1 mrg else 1371 1.1 mrg { 1372 1.1 mrg plats->m_value_range.init (); 1373 1.1 mrg if (variable) 1374 1.1 mrg set_all_contains_variable (plats); 1375 1.1 mrg } 1376 1.1 mrg } 1377 1.1 mrg 1378 1.1 mrg for (ie = node->indirect_calls; ie; ie = ie->next_callee) 1379 1.1 mrg if (ie->indirect_info->polymorphic 1380 1.1 mrg && ie->indirect_info->param_index >= 0) 1381 1.1 mrg { 1382 1.1 mrg gcc_checking_assert (ie->indirect_info->param_index >= 0); 1383 1.1 mrg ipa_get_parm_lattices (info, 1384 1.1 mrg ie->indirect_info->param_index)->virt_call = 1; 1385 1.1 mrg } 1386 1.1 mrg } 1387 1.1 mrg 1388 1.1 mrg /* Return true if VALUE can be safely IPA-CP propagated to a parameter of type 1389 1.1 mrg PARAM_TYPE. */ 1390 1.1 mrg 1391 1.1 mrg static bool 1392 1.1 mrg ipacp_value_safe_for_type (tree param_type, tree value) 1393 1.1 mrg { 1394 1.1 mrg tree val_type = TREE_TYPE (value); 1395 1.1 mrg if (param_type == val_type 1396 1.1 mrg || useless_type_conversion_p (param_type, val_type) 1397 1.1 mrg || fold_convertible_p (param_type, value)) 1398 1.1 mrg return true; 1399 1.1 mrg else 1400 1.1 mrg return false; 1401 1.1 mrg } 1402 1.1 mrg 1403 1.1 mrg /* Return true iff X and Y should be considered equal values by IPA-CP. */ 1404 1.1 mrg 1405 1.1 mrg bool 1406 1.1 mrg values_equal_for_ipcp_p (tree x, tree y) 1407 1.1 mrg { 1408 1.1 mrg gcc_checking_assert (x != NULL_TREE && y != NULL_TREE); 1409 1.1 mrg 1410 1.1 mrg if (x == y) 1411 1.1 mrg return true; 1412 1.1 mrg 1413 1.1 mrg if (TREE_CODE (x) == ADDR_EXPR 1414 1.1 mrg && TREE_CODE (y) == ADDR_EXPR 1415 1.1 mrg && TREE_CODE (TREE_OPERAND (x, 0)) == CONST_DECL 1416 1.1 mrg && TREE_CODE (TREE_OPERAND (y, 0)) == CONST_DECL) 1417 1.1 mrg return operand_equal_p (DECL_INITIAL (TREE_OPERAND (x, 0)), 1418 1.1 mrg DECL_INITIAL (TREE_OPERAND (y, 0)), 0); 1419 1.1 mrg else 1420 1.1 mrg return operand_equal_p (x, y, 0); 1421 1.1 mrg } 1422 1.1 mrg 1423 1.1 mrg /* Return the result of a (possibly arithmetic) operation on the constant 1424 1.1 mrg value INPUT. OPERAND is 2nd operand for binary operation. RES_TYPE is 1425 1.1 mrg the type of the parameter to which the result is passed. Return 1426 1.1 mrg NULL_TREE if that cannot be determined or be considered an 1427 1.1 mrg interprocedural invariant. */ 1428 1.1 mrg 1429 1.1 mrg static tree 1430 1.1 mrg ipa_get_jf_arith_result (enum tree_code opcode, tree input, tree operand, 1431 1.1 mrg tree res_type) 1432 1.1 mrg { 1433 1.1 mrg tree res; 1434 1.1 mrg 1435 1.1 mrg if (opcode == NOP_EXPR) 1436 1.1 mrg return input; 1437 1.1 mrg if (!is_gimple_ip_invariant (input)) 1438 1.1 mrg return NULL_TREE; 1439 1.1 mrg 1440 1.1 mrg if (opcode == ASSERT_EXPR) 1441 1.1 mrg { 1442 1.1 mrg if (values_equal_for_ipcp_p (input, operand)) 1443 1.1 mrg return input; 1444 1.1 mrg else 1445 1.1 mrg return NULL_TREE; 1446 1.1 mrg } 1447 1.1 mrg 1448 1.1 mrg if (!res_type) 1449 1.1 mrg { 1450 1.1 mrg if (TREE_CODE_CLASS (opcode) == tcc_comparison) 1451 1.1 mrg res_type = boolean_type_node; 1452 1.1 mrg else if (expr_type_first_operand_type_p (opcode)) 1453 1.1 mrg res_type = TREE_TYPE (input); 1454 1.1 mrg else 1455 1.1 mrg return NULL_TREE; 1456 1.1 mrg } 1457 1.1 mrg 1458 1.1 mrg if (TREE_CODE_CLASS (opcode) == tcc_unary) 1459 1.1 mrg res = fold_unary (opcode, res_type, input); 1460 1.1 mrg else 1461 1.1 mrg res = fold_binary (opcode, res_type, input, operand); 1462 1.1 mrg 1463 1.1 mrg if (res && !is_gimple_ip_invariant (res)) 1464 1.1 mrg return NULL_TREE; 1465 1.1 mrg 1466 1.1 mrg return res; 1467 1.1 mrg } 1468 1.1 mrg 1469 1.1 mrg /* Return the result of a (possibly arithmetic) pass through jump function 1470 1.1 mrg JFUNC on the constant value INPUT. RES_TYPE is the type of the parameter 1471 1.1 mrg to which the result is passed. Return NULL_TREE if that cannot be 1472 1.1 mrg determined or be considered an interprocedural invariant. */ 1473 1.1 mrg 1474 1.1 mrg static tree 1475 1.1 mrg ipa_get_jf_pass_through_result (struct ipa_jump_func *jfunc, tree input, 1476 1.1 mrg tree res_type) 1477 1.1 mrg { 1478 1.1 mrg return ipa_get_jf_arith_result (ipa_get_jf_pass_through_operation (jfunc), 1479 1.1 mrg input, 1480 1.1 mrg ipa_get_jf_pass_through_operand (jfunc), 1481 1.1 mrg res_type); 1482 1.1 mrg } 1483 1.1 mrg 1484 1.1 mrg /* Return the result of an ancestor jump function JFUNC on the constant value 1485 1.1 mrg INPUT. Return NULL_TREE if that cannot be determined. */ 1486 1.1 mrg 1487 1.1 mrg static tree 1488 1.1 mrg ipa_get_jf_ancestor_result (struct ipa_jump_func *jfunc, tree input) 1489 1.1 mrg { 1490 1.1 mrg gcc_checking_assert (TREE_CODE (input) != TREE_BINFO); 1491 1.1 mrg if (TREE_CODE (input) == ADDR_EXPR) 1492 1.1 mrg { 1493 1.1 mrg gcc_checking_assert (is_gimple_ip_invariant_address (input)); 1494 1.1 mrg poly_int64 off = ipa_get_jf_ancestor_offset (jfunc); 1495 1.1 mrg if (known_eq (off, 0)) 1496 1.1 mrg return input; 1497 1.1 mrg poly_int64 byte_offset = exact_div (off, BITS_PER_UNIT); 1498 1.1 mrg return build1 (ADDR_EXPR, TREE_TYPE (input), 1499 1.1 mrg fold_build2 (MEM_REF, TREE_TYPE (TREE_TYPE (input)), input, 1500 1.1 mrg build_int_cst (ptr_type_node, byte_offset))); 1501 1.1 mrg } 1502 1.1 mrg else if (ipa_get_jf_ancestor_keep_null (jfunc) 1503 1.1 mrg && zerop (input)) 1504 1.1 mrg return input; 1505 1.1 mrg else 1506 1.1 mrg return NULL_TREE; 1507 1.1 mrg } 1508 1.1 mrg 1509 1.1 mrg /* Determine whether JFUNC evaluates to a single known constant value and if 1510 1.1 mrg so, return it. Otherwise return NULL. INFO describes the caller node or 1511 1.1 mrg the one it is inlined to, so that pass-through jump functions can be 1512 1.1 mrg evaluated. PARM_TYPE is the type of the parameter to which the result is 1513 1.1 mrg passed. */ 1514 1.1 mrg 1515 1.1 mrg tree 1516 1.1 mrg ipa_value_from_jfunc (class ipa_node_params *info, struct ipa_jump_func *jfunc, 1517 1.1 mrg tree parm_type) 1518 1.1 mrg { 1519 1.1 mrg if (jfunc->type == IPA_JF_CONST) 1520 1.1 mrg return ipa_get_jf_constant (jfunc); 1521 1.1 mrg else if (jfunc->type == IPA_JF_PASS_THROUGH 1522 1.1 mrg || jfunc->type == IPA_JF_ANCESTOR) 1523 1.1 mrg { 1524 1.1 mrg tree input; 1525 1.1 mrg int idx; 1526 1.1 mrg 1527 1.1 mrg if (jfunc->type == IPA_JF_PASS_THROUGH) 1528 1.1 mrg idx = ipa_get_jf_pass_through_formal_id (jfunc); 1529 1.1 mrg else 1530 1.1 mrg idx = ipa_get_jf_ancestor_formal_id (jfunc); 1531 1.1 mrg 1532 1.1 mrg if (info->ipcp_orig_node) 1533 1.1 mrg input = info->known_csts[idx]; 1534 1.1 mrg else 1535 1.1 mrg { 1536 1.1 mrg ipcp_lattice<tree> *lat; 1537 1.1 mrg 1538 1.1 mrg if (!info->lattices 1539 1.1 mrg || idx >= ipa_get_param_count (info)) 1540 1.1 mrg return NULL_TREE; 1541 1.1 mrg lat = ipa_get_scalar_lat (info, idx); 1542 1.1 mrg if (!lat->is_single_const ()) 1543 1.1 mrg return NULL_TREE; 1544 1.1 mrg input = lat->values->value; 1545 1.1 mrg } 1546 1.1 mrg 1547 1.1 mrg if (!input) 1548 1.1 mrg return NULL_TREE; 1549 1.1 mrg 1550 1.1 mrg if (jfunc->type == IPA_JF_PASS_THROUGH) 1551 1.1 mrg return ipa_get_jf_pass_through_result (jfunc, input, parm_type); 1552 1.1 mrg else 1553 1.1 mrg return ipa_get_jf_ancestor_result (jfunc, input); 1554 1.1 mrg } 1555 1.1 mrg else 1556 1.1 mrg return NULL_TREE; 1557 1.1 mrg } 1558 1.1 mrg 1559 1.1 mrg /* Determine whether JFUNC evaluates to single known polymorphic context, given 1560 1.1 mrg that INFO describes the caller node or the one it is inlined to, CS is the 1561 1.1 mrg call graph edge corresponding to JFUNC and CSIDX index of the described 1562 1.1 mrg parameter. */ 1563 1.1 mrg 1564 1.1 mrg ipa_polymorphic_call_context 1565 1.1 mrg ipa_context_from_jfunc (ipa_node_params *info, cgraph_edge *cs, int csidx, 1566 1.1 mrg ipa_jump_func *jfunc) 1567 1.1 mrg { 1568 1.1 mrg ipa_edge_args *args = ipa_edge_args_sum->get (cs); 1569 1.1 mrg ipa_polymorphic_call_context ctx; 1570 1.1 mrg ipa_polymorphic_call_context *edge_ctx 1571 1.1 mrg = cs ? ipa_get_ith_polymorhic_call_context (args, csidx) : NULL; 1572 1.1 mrg 1573 1.1 mrg if (edge_ctx && !edge_ctx->useless_p ()) 1574 1.1 mrg ctx = *edge_ctx; 1575 1.1 mrg 1576 1.1 mrg if (jfunc->type == IPA_JF_PASS_THROUGH 1577 1.1 mrg || jfunc->type == IPA_JF_ANCESTOR) 1578 1.1 mrg { 1579 1.1 mrg ipa_polymorphic_call_context srcctx; 1580 1.1 mrg int srcidx; 1581 1.1 mrg bool type_preserved = true; 1582 1.1 mrg if (jfunc->type == IPA_JF_PASS_THROUGH) 1583 1.1 mrg { 1584 1.1 mrg if (ipa_get_jf_pass_through_operation (jfunc) != NOP_EXPR) 1585 1.1 mrg return ctx; 1586 1.1 mrg type_preserved = ipa_get_jf_pass_through_type_preserved (jfunc); 1587 1.1 mrg srcidx = ipa_get_jf_pass_through_formal_id (jfunc); 1588 1.1 mrg } 1589 1.1 mrg else 1590 1.1 mrg { 1591 1.1 mrg type_preserved = ipa_get_jf_ancestor_type_preserved (jfunc); 1592 1.1 mrg srcidx = ipa_get_jf_ancestor_formal_id (jfunc); 1593 1.1 mrg } 1594 1.1 mrg if (info->ipcp_orig_node) 1595 1.1 mrg { 1596 1.1 mrg if (info->known_contexts.exists ()) 1597 1.1 mrg srcctx = info->known_contexts[srcidx]; 1598 1.1 mrg } 1599 1.1 mrg else 1600 1.1 mrg { 1601 1.1 mrg if (!info->lattices 1602 1.1 mrg || srcidx >= ipa_get_param_count (info)) 1603 1.1 mrg return ctx; 1604 1.1 mrg ipcp_lattice<ipa_polymorphic_call_context> *lat; 1605 1.1 mrg lat = ipa_get_poly_ctx_lat (info, srcidx); 1606 1.1 mrg if (!lat->is_single_const ()) 1607 1.1 mrg return ctx; 1608 1.1 mrg srcctx = lat->values->value; 1609 1.1 mrg } 1610 1.1 mrg if (srcctx.useless_p ()) 1611 1.1 mrg return ctx; 1612 1.1 mrg if (jfunc->type == IPA_JF_ANCESTOR) 1613 1.1 mrg srcctx.offset_by (ipa_get_jf_ancestor_offset (jfunc)); 1614 1.1 mrg if (!type_preserved) 1615 1.1 mrg srcctx.possible_dynamic_type_change (cs->in_polymorphic_cdtor); 1616 1.1 mrg srcctx.combine_with (ctx); 1617 1.1 mrg return srcctx; 1618 1.1 mrg } 1619 1.1 mrg 1620 1.1 mrg return ctx; 1621 1.1 mrg } 1622 1.1 mrg 1623 1.1 mrg /* Emulate effects of unary OPERATION and/or conversion from SRC_TYPE to 1624 1.1 mrg DST_TYPE on value range in SRC_VR and store it to DST_VR. Return true if 1625 1.1 mrg the result is a range or an anti-range. */ 1626 1.1 mrg 1627 1.1 mrg static bool 1628 1.1 mrg ipa_vr_operation_and_type_effects (value_range *dst_vr, 1629 1.1 mrg value_range *src_vr, 1630 1.1 mrg enum tree_code operation, 1631 1.1 mrg tree dst_type, tree src_type) 1632 1.1 mrg { 1633 1.1 mrg range_fold_unary_expr (dst_vr, operation, dst_type, src_vr, src_type); 1634 1.1 mrg if (dst_vr->varying_p () || dst_vr->undefined_p ()) 1635 1.1 mrg return false; 1636 1.1 mrg return true; 1637 1.1 mrg } 1638 1.1 mrg 1639 1.1 mrg /* Determine value_range of JFUNC given that INFO describes the caller node or 1640 1.1 mrg the one it is inlined to, CS is the call graph edge corresponding to JFUNC 1641 1.1 mrg and PARM_TYPE of the parameter. */ 1642 1.1 mrg 1643 1.1 mrg value_range 1644 1.1 mrg ipa_value_range_from_jfunc (ipa_node_params *info, cgraph_edge *cs, 1645 1.1 mrg ipa_jump_func *jfunc, tree parm_type) 1646 1.1 mrg { 1647 1.1 mrg value_range vr; 1648 1.1 mrg if (jfunc->m_vr) 1649 1.1 mrg ipa_vr_operation_and_type_effects (&vr, 1650 1.1 mrg jfunc->m_vr, 1651 1.1 mrg NOP_EXPR, parm_type, 1652 1.1 mrg jfunc->m_vr->type ()); 1653 1.1 mrg if (vr.singleton_p ()) 1654 1.1 mrg return vr; 1655 1.1 mrg if (jfunc->type == IPA_JF_PASS_THROUGH) 1656 1.1 mrg { 1657 1.1 mrg int idx; 1658 1.1 mrg ipcp_transformation *sum 1659 1.1 mrg = ipcp_get_transformation_summary (cs->caller->inlined_to 1660 1.1 mrg ? cs->caller->inlined_to 1661 1.1 mrg : cs->caller); 1662 1.1 mrg if (!sum || !sum->m_vr) 1663 1.1 mrg return vr; 1664 1.1 mrg 1665 1.1 mrg idx = ipa_get_jf_pass_through_formal_id (jfunc); 1666 1.1 mrg 1667 1.1 mrg if (!(*sum->m_vr)[idx].known) 1668 1.1 mrg return vr; 1669 1.1 mrg tree vr_type = ipa_get_type (info, idx); 1670 1.1 mrg value_range srcvr (wide_int_to_tree (vr_type, (*sum->m_vr)[idx].min), 1671 1.1 mrg wide_int_to_tree (vr_type, (*sum->m_vr)[idx].max), 1672 1.1 mrg (*sum->m_vr)[idx].type); 1673 1.1 mrg 1674 1.1 mrg enum tree_code operation = ipa_get_jf_pass_through_operation (jfunc); 1675 1.1 mrg 1676 1.1 mrg if (TREE_CODE_CLASS (operation) == tcc_unary) 1677 1.1 mrg { 1678 1.1 mrg value_range res; 1679 1.1 mrg 1680 1.1 mrg if (ipa_vr_operation_and_type_effects (&res, 1681 1.1 mrg &srcvr, 1682 1.1 mrg operation, parm_type, 1683 1.1 mrg vr_type)) 1684 1.1 mrg vr.intersect (res); 1685 1.1 mrg } 1686 1.1 mrg else 1687 1.1 mrg { 1688 1.1 mrg value_range op_res, res; 1689 1.1 mrg tree op = ipa_get_jf_pass_through_operand (jfunc); 1690 1.1 mrg value_range op_vr (op, op); 1691 1.1 mrg 1692 1.1 mrg range_fold_binary_expr (&op_res, operation, vr_type, &srcvr, &op_vr); 1693 1.1 mrg if (ipa_vr_operation_and_type_effects (&res, 1694 1.1 mrg &op_res, 1695 1.1 mrg NOP_EXPR, parm_type, 1696 1.1 mrg vr_type)) 1697 1.1 mrg vr.intersect (res); 1698 1.1 mrg } 1699 1.1 mrg } 1700 1.1 mrg return vr; 1701 1.1 mrg } 1702 1.1 mrg 1703 1.1 mrg /* See if NODE is a clone with a known aggregate value at a given OFFSET of a 1704 1.1 mrg parameter with the given INDEX. */ 1705 1.1 mrg 1706 1.1 mrg static tree 1707 1.1 mrg get_clone_agg_value (struct cgraph_node *node, HOST_WIDE_INT offset, 1708 1.1 mrg int index) 1709 1.1 mrg { 1710 1.1 mrg struct ipa_agg_replacement_value *aggval; 1711 1.1 mrg 1712 1.1 mrg aggval = ipa_get_agg_replacements_for_node (node); 1713 1.1 mrg while (aggval) 1714 1.1 mrg { 1715 1.1 mrg if (aggval->offset == offset 1716 1.1 mrg && aggval->index == index) 1717 1.1 mrg return aggval->value; 1718 1.1 mrg aggval = aggval->next; 1719 1.1 mrg } 1720 1.1 mrg return NULL_TREE; 1721 1.1 mrg } 1722 1.1 mrg 1723 1.1 mrg /* Determine whether ITEM, jump function for an aggregate part, evaluates to a 1724 1.1 mrg single known constant value and if so, return it. Otherwise return NULL. 1725 1.1 mrg NODE and INFO describes the caller node or the one it is inlined to, and 1726 1.1 mrg its related info. */ 1727 1.1 mrg 1728 1.1 mrg static tree 1729 1.1 mrg ipa_agg_value_from_node (class ipa_node_params *info, 1730 1.1 mrg struct cgraph_node *node, 1731 1.1 mrg struct ipa_agg_jf_item *item) 1732 1.1 mrg { 1733 1.1 mrg tree value = NULL_TREE; 1734 1.1 mrg int src_idx; 1735 1.1 mrg 1736 1.1 mrg if (item->offset < 0 || item->jftype == IPA_JF_UNKNOWN) 1737 1.1 mrg return NULL_TREE; 1738 1.1 mrg 1739 1.1 mrg if (item->jftype == IPA_JF_CONST) 1740 1.1 mrg return item->value.constant; 1741 1.1 mrg 1742 1.1 mrg gcc_checking_assert (item->jftype == IPA_JF_PASS_THROUGH 1743 1.1 mrg || item->jftype == IPA_JF_LOAD_AGG); 1744 1.1 mrg 1745 1.1 mrg src_idx = item->value.pass_through.formal_id; 1746 1.1 mrg 1747 1.1 mrg if (info->ipcp_orig_node) 1748 1.1 mrg { 1749 1.1 mrg if (item->jftype == IPA_JF_PASS_THROUGH) 1750 1.1 mrg value = info->known_csts[src_idx]; 1751 1.1 mrg else 1752 1.1 mrg value = get_clone_agg_value (node, item->value.load_agg.offset, 1753 1.1 mrg src_idx); 1754 1.1 mrg } 1755 1.1 mrg else if (info->lattices) 1756 1.1 mrg { 1757 1.1 mrg class ipcp_param_lattices *src_plats 1758 1.1 mrg = ipa_get_parm_lattices (info, src_idx); 1759 1.1 mrg 1760 1.1 mrg if (item->jftype == IPA_JF_PASS_THROUGH) 1761 1.1 mrg { 1762 1.1 mrg struct ipcp_lattice<tree> *lat = &src_plats->itself; 1763 1.1 mrg 1764 1.1 mrg if (!lat->is_single_const ()) 1765 1.1 mrg return NULL_TREE; 1766 1.1 mrg 1767 1.1 mrg value = lat->values->value; 1768 1.1 mrg } 1769 1.1 mrg else if (src_plats->aggs 1770 1.1 mrg && !src_plats->aggs_bottom 1771 1.1 mrg && !src_plats->aggs_contain_variable 1772 1.1 mrg && src_plats->aggs_by_ref == item->value.load_agg.by_ref) 1773 1.1 mrg { 1774 1.1 mrg struct ipcp_agg_lattice *aglat; 1775 1.1 mrg 1776 1.1 mrg for (aglat = src_plats->aggs; aglat; aglat = aglat->next) 1777 1.1 mrg { 1778 1.1 mrg if (aglat->offset > item->value.load_agg.offset) 1779 1.1 mrg break; 1780 1.1 mrg 1781 1.1 mrg if (aglat->offset == item->value.load_agg.offset) 1782 1.1 mrg { 1783 1.1 mrg if (aglat->is_single_const ()) 1784 1.1 mrg value = aglat->values->value; 1785 1.1 mrg break; 1786 1.1 mrg } 1787 1.1 mrg } 1788 1.1 mrg } 1789 1.1 mrg } 1790 1.1 mrg 1791 1.1 mrg if (!value) 1792 1.1 mrg return NULL_TREE; 1793 1.1 mrg 1794 1.1 mrg if (item->jftype == IPA_JF_LOAD_AGG) 1795 1.1 mrg { 1796 1.1 mrg tree load_type = item->value.load_agg.type; 1797 1.1 mrg tree value_type = TREE_TYPE (value); 1798 1.1 mrg 1799 1.1 mrg /* Ensure value type is compatible with load type. */ 1800 1.1 mrg if (!useless_type_conversion_p (load_type, value_type)) 1801 1.1 mrg return NULL_TREE; 1802 1.1 mrg } 1803 1.1 mrg 1804 1.1 mrg return ipa_get_jf_arith_result (item->value.pass_through.operation, 1805 1.1 mrg value, 1806 1.1 mrg item->value.pass_through.operand, 1807 1.1 mrg item->type); 1808 1.1 mrg } 1809 1.1 mrg 1810 1.1 mrg /* Determine whether AGG_JFUNC evaluates to a set of known constant value for 1811 1.1 mrg an aggregate and if so, return it. Otherwise return an empty set. NODE 1812 1.1 mrg and INFO describes the caller node or the one it is inlined to, and its 1813 1.1 mrg related info. */ 1814 1.1 mrg 1815 1.1 mrg struct ipa_agg_value_set 1816 1.1 mrg ipa_agg_value_set_from_jfunc (class ipa_node_params *info, cgraph_node *node, 1817 1.1 mrg struct ipa_agg_jump_function *agg_jfunc) 1818 1.1 mrg { 1819 1.1 mrg struct ipa_agg_value_set agg; 1820 1.1 mrg struct ipa_agg_jf_item *item; 1821 1.1 mrg int i; 1822 1.1 mrg 1823 1.1 mrg agg.items = vNULL; 1824 1.1 mrg agg.by_ref = agg_jfunc->by_ref; 1825 1.1 mrg 1826 1.1 mrg FOR_EACH_VEC_SAFE_ELT (agg_jfunc->items, i, item) 1827 1.1 mrg { 1828 1.1 mrg tree value = ipa_agg_value_from_node (info, node, item); 1829 1.1 mrg 1830 1.1 mrg if (value) 1831 1.1 mrg { 1832 1.1 mrg struct ipa_agg_value value_item; 1833 1.1 mrg 1834 1.1 mrg value_item.offset = item->offset; 1835 1.1 mrg value_item.value = value; 1836 1.1 mrg 1837 1.1 mrg agg.items.safe_push (value_item); 1838 1.1 mrg } 1839 1.1 mrg } 1840 1.1 mrg return agg; 1841 1.1 mrg } 1842 1.1 mrg 1843 1.1 mrg /* If checking is enabled, verify that no lattice is in the TOP state, i.e. not 1844 1.1 mrg bottom, not containing a variable component and without any known value at 1845 1.1 mrg the same time. */ 1846 1.1 mrg 1847 1.1 mrg DEBUG_FUNCTION void 1848 1.1 mrg ipcp_verify_propagated_values (void) 1849 1.1 mrg { 1850 1.1 mrg struct cgraph_node *node; 1851 1.1 mrg 1852 1.1 mrg FOR_EACH_FUNCTION_WITH_GIMPLE_BODY (node) 1853 1.1 mrg { 1854 1.1 mrg ipa_node_params *info = ipa_node_params_sum->get (node); 1855 1.1 mrg if (!opt_for_fn (node->decl, flag_ipa_cp) 1856 1.1 mrg || !opt_for_fn (node->decl, optimize)) 1857 1.1 mrg continue; 1858 1.1 mrg int i, count = ipa_get_param_count (info); 1859 1.1 mrg 1860 1.1 mrg for (i = 0; i < count; i++) 1861 1.1 mrg { 1862 1.1 mrg ipcp_lattice<tree> *lat = ipa_get_scalar_lat (info, i); 1863 1.1 mrg 1864 1.1 mrg if (!lat->bottom 1865 1.1 mrg && !lat->contains_variable 1866 1.1 mrg && lat->values_count == 0) 1867 1.1 mrg { 1868 1.1 mrg if (dump_file) 1869 1.1 mrg { 1870 1.1 mrg symtab->dump (dump_file); 1871 1.1 mrg fprintf (dump_file, "\nIPA lattices after constant " 1872 1.1 mrg "propagation, before gcc_unreachable:\n"); 1873 1.1 mrg print_all_lattices (dump_file, true, false); 1874 1.1 mrg } 1875 1.1 mrg 1876 1.1 mrg gcc_unreachable (); 1877 1.1 mrg } 1878 1.1 mrg } 1879 1.1 mrg } 1880 1.1 mrg } 1881 1.1 mrg 1882 1.1 mrg /* Return true iff X and Y should be considered equal contexts by IPA-CP. */ 1883 1.1 mrg 1884 1.1 mrg static bool 1885 1.1 mrg values_equal_for_ipcp_p (ipa_polymorphic_call_context x, 1886 1.1 mrg ipa_polymorphic_call_context y) 1887 1.1 mrg { 1888 1.1 mrg return x.equal_to (y); 1889 1.1 mrg } 1890 1.1 mrg 1891 1.1 mrg 1892 1.1 mrg /* Add a new value source to the value represented by THIS, marking that a 1893 1.1 mrg value comes from edge CS and (if the underlying jump function is a 1894 1.1 mrg pass-through or an ancestor one) from a caller value SRC_VAL of a caller 1895 1.1 mrg parameter described by SRC_INDEX. OFFSET is negative if the source was the 1896 1.1 mrg scalar value of the parameter itself or the offset within an aggregate. */ 1897 1.1 mrg 1898 1.1 mrg template <typename valtype> 1899 1.1 mrg void 1900 1.1 mrg ipcp_value<valtype>::add_source (cgraph_edge *cs, ipcp_value *src_val, 1901 1.1 mrg int src_idx, HOST_WIDE_INT offset) 1902 1.1 mrg { 1903 1.1 mrg ipcp_value_source<valtype> *src; 1904 1.1 mrg 1905 1.1 mrg src = new (ipcp_sources_pool.allocate ()) ipcp_value_source<valtype>; 1906 1.1 mrg src->offset = offset; 1907 1.1 mrg src->cs = cs; 1908 1.1 mrg src->val = src_val; 1909 1.1 mrg src->index = src_idx; 1910 1.1 mrg 1911 1.1 mrg src->next = sources; 1912 1.1 mrg sources = src; 1913 1.1 mrg } 1914 1.1 mrg 1915 1.1 mrg /* Allocate a new ipcp_value holding a tree constant, initialize its value to 1916 1.1 mrg SOURCE and clear all other fields. */ 1917 1.1 mrg 1918 1.1 mrg static ipcp_value<tree> * 1919 1.1 mrg allocate_and_init_ipcp_value (tree cst, unsigned same_lat_gen_level) 1920 1.1 mrg { 1921 1.1 mrg ipcp_value<tree> *val; 1922 1.1 mrg 1923 1.1 mrg val = new (ipcp_cst_values_pool.allocate ()) ipcp_value<tree>(); 1924 1.1 mrg val->value = cst; 1925 1.1 mrg val->self_recursion_generated_level = same_lat_gen_level; 1926 1.1 mrg return val; 1927 1.1 mrg } 1928 1.1 mrg 1929 1.1 mrg /* Allocate a new ipcp_value holding a polymorphic context, initialize its 1930 1.1 mrg value to SOURCE and clear all other fields. */ 1931 1.1 mrg 1932 1.1 mrg static ipcp_value<ipa_polymorphic_call_context> * 1933 1.1 mrg allocate_and_init_ipcp_value (ipa_polymorphic_call_context ctx, 1934 1.1 mrg unsigned same_lat_gen_level) 1935 1.1 mrg { 1936 1.1 mrg ipcp_value<ipa_polymorphic_call_context> *val; 1937 1.1 mrg 1938 1.1 mrg val = new (ipcp_poly_ctx_values_pool.allocate ()) 1939 1.1 mrg ipcp_value<ipa_polymorphic_call_context>(); 1940 1.1 mrg val->value = ctx; 1941 1.1 mrg val->self_recursion_generated_level = same_lat_gen_level; 1942 1.1 mrg return val; 1943 1.1 mrg } 1944 1.1 mrg 1945 1.1 mrg /* Try to add NEWVAL to LAT, potentially creating a new ipcp_value for it. CS, 1946 1.1 mrg SRC_VAL SRC_INDEX and OFFSET are meant for add_source and have the same 1947 1.1 mrg meaning. OFFSET -1 means the source is scalar and not a part of an 1948 1.1 mrg aggregate. If non-NULL, VAL_P records address of existing or newly added 1949 1.1 mrg ipcp_value. 1950 1.1 mrg 1951 1.1 mrg If the value is generated for a self-recursive call as a result of an 1952 1.1 mrg arithmetic pass-through jump-function acting on a value in the same lattice, 1953 1.1 mrg SAME_LAT_GEN_LEVEL must be the length of such chain, otherwise it must be 1954 1.1 mrg zero. If it is non-zero, PARAM_IPA_CP_VALUE_LIST_SIZE limit is ignored. */ 1955 1.1 mrg 1956 1.1 mrg template <typename valtype> 1957 1.1 mrg bool 1958 1.1 mrg ipcp_lattice<valtype>::add_value (valtype newval, cgraph_edge *cs, 1959 1.1 mrg ipcp_value<valtype> *src_val, 1960 1.1 mrg int src_idx, HOST_WIDE_INT offset, 1961 1.1 mrg ipcp_value<valtype> **val_p, 1962 1.1 mrg unsigned same_lat_gen_level) 1963 1.1 mrg { 1964 1.1 mrg ipcp_value<valtype> *val, *last_val = NULL; 1965 1.1 mrg 1966 1.1 mrg if (val_p) 1967 1.1 mrg *val_p = NULL; 1968 1.1 mrg 1969 1.1 mrg if (bottom) 1970 1.1 mrg return false; 1971 1.1 mrg 1972 1.1 mrg for (val = values; val; last_val = val, val = val->next) 1973 1.1 mrg if (values_equal_for_ipcp_p (val->value, newval)) 1974 1.1 mrg { 1975 1.1 mrg if (val_p) 1976 1.1 mrg *val_p = val; 1977 1.1 mrg 1978 1.1 mrg if (val->self_recursion_generated_level < same_lat_gen_level) 1979 1.1 mrg val->self_recursion_generated_level = same_lat_gen_level; 1980 1.1 mrg 1981 1.1 mrg if (ipa_edge_within_scc (cs)) 1982 1.1 mrg { 1983 1.1 mrg ipcp_value_source<valtype> *s; 1984 1.1 mrg for (s = val->sources; s; s = s->next) 1985 1.1 mrg if (s->cs == cs && s->val == src_val) 1986 1.1 mrg break; 1987 1.1 mrg if (s) 1988 1.1 mrg return false; 1989 1.1 mrg } 1990 1.1 mrg 1991 1.1 mrg val->add_source (cs, src_val, src_idx, offset); 1992 1.1 mrg return false; 1993 1.1 mrg } 1994 1.1 mrg 1995 1.1 mrg if (!same_lat_gen_level && values_count == opt_for_fn (cs->caller->decl, 1996 1.1 mrg param_ipa_cp_value_list_size)) 1997 1.1 mrg { 1998 1.1 mrg /* We can only free sources, not the values themselves, because sources 1999 1.1 mrg of other values in this SCC might point to them. */ 2000 1.1 mrg for (val = values; val; val = val->next) 2001 1.1 mrg { 2002 1.1 mrg while (val->sources) 2003 1.1 mrg { 2004 1.1 mrg ipcp_value_source<valtype> *src = val->sources; 2005 1.1 mrg val->sources = src->next; 2006 1.1 mrg ipcp_sources_pool.remove ((ipcp_value_source<tree>*)src); 2007 1.1 mrg } 2008 1.1 mrg } 2009 1.1 mrg values = NULL; 2010 1.1 mrg return set_to_bottom (); 2011 1.1 mrg } 2012 1.1 mrg 2013 1.1 mrg values_count++; 2014 1.1 mrg val = allocate_and_init_ipcp_value (newval, same_lat_gen_level); 2015 1.1 mrg val->add_source (cs, src_val, src_idx, offset); 2016 1.1 mrg val->next = NULL; 2017 1.1 mrg 2018 1.1 mrg /* Add the new value to end of value list, which can reduce iterations 2019 1.1 mrg of propagation stage for recursive function. */ 2020 1.1 mrg if (last_val) 2021 1.1 mrg last_val->next = val; 2022 1.1 mrg else 2023 1.1 mrg values = val; 2024 1.1 mrg 2025 1.1 mrg if (val_p) 2026 1.1 mrg *val_p = val; 2027 1.1 mrg 2028 1.1 mrg return true; 2029 1.1 mrg } 2030 1.1 mrg 2031 1.1 mrg /* A helper function that returns result of operation specified by OPCODE on 2032 1.1 mrg the value of SRC_VAL. If non-NULL, OPND1_TYPE is expected type for the 2033 1.1 mrg value of SRC_VAL. If the operation is binary, OPND2 is a constant value 2034 1.1 mrg acting as its second operand. If non-NULL, RES_TYPE is expected type of 2035 1.1 mrg the result. */ 2036 1.1 mrg 2037 1.1 mrg static tree 2038 1.1 mrg get_val_across_arith_op (enum tree_code opcode, 2039 1.1 mrg tree opnd1_type, 2040 1.1 mrg tree opnd2, 2041 1.1 mrg ipcp_value<tree> *src_val, 2042 1.1 mrg tree res_type) 2043 1.1 mrg { 2044 1.1 mrg tree opnd1 = src_val->value; 2045 1.1 mrg 2046 1.1 mrg /* Skip source values that is incompatible with specified type. */ 2047 1.1 mrg if (opnd1_type 2048 1.1 mrg && !useless_type_conversion_p (opnd1_type, TREE_TYPE (opnd1))) 2049 1.1 mrg return NULL_TREE; 2050 1.1 mrg 2051 1.1 mrg return ipa_get_jf_arith_result (opcode, opnd1, opnd2, res_type); 2052 1.1 mrg } 2053 1.1 mrg 2054 1.1 mrg /* Propagate values through an arithmetic transformation described by a jump 2055 1.1 mrg function associated with edge CS, taking values from SRC_LAT and putting 2056 1.1 mrg them into DEST_LAT. OPND1_TYPE is expected type for the values in SRC_LAT. 2057 1.1 mrg OPND2 is a constant value if transformation is a binary operation. 2058 1.1 mrg SRC_OFFSET specifies offset in an aggregate if SRC_LAT describes lattice of 2059 1.1 mrg a part of the aggregate. SRC_IDX is the index of the source parameter. 2060 1.1 mrg RES_TYPE is the value type of result being propagated into. Return true if 2061 1.1 mrg DEST_LAT changed. */ 2062 1.1 mrg 2063 1.1 mrg static bool 2064 1.1 mrg propagate_vals_across_arith_jfunc (cgraph_edge *cs, 2065 1.1 mrg enum tree_code opcode, 2066 1.1 mrg tree opnd1_type, 2067 1.1 mrg tree opnd2, 2068 1.1 mrg ipcp_lattice<tree> *src_lat, 2069 1.1 mrg ipcp_lattice<tree> *dest_lat, 2070 1.1 mrg HOST_WIDE_INT src_offset, 2071 1.1 mrg int src_idx, 2072 1.1 mrg tree res_type) 2073 1.1 mrg { 2074 1.1 mrg ipcp_value<tree> *src_val; 2075 1.1 mrg bool ret = false; 2076 1.1 mrg 2077 1.1 mrg /* Due to circular dependencies, propagating within an SCC through arithmetic 2078 1.1 mrg transformation would create infinite number of values. But for 2079 1.1 mrg self-feeding recursive function, we could allow propagation in a limited 2080 1.1 mrg count, and this can enable a simple kind of recursive function versioning. 2081 1.1 mrg For other scenario, we would just make lattices bottom. */ 2082 1.1 mrg if (opcode != NOP_EXPR && ipa_edge_within_scc (cs)) 2083 1.1 mrg { 2084 1.1 mrg int i; 2085 1.1 mrg 2086 1.1 mrg int max_recursive_depth = opt_for_fn(cs->caller->decl, 2087 1.1 mrg param_ipa_cp_max_recursive_depth); 2088 1.1 mrg if (src_lat != dest_lat || max_recursive_depth < 1) 2089 1.1 mrg return dest_lat->set_contains_variable (); 2090 1.1 mrg 2091 1.1 mrg /* No benefit if recursive execution is in low probability. */ 2092 1.1 mrg if (cs->sreal_frequency () * 100 2093 1.1 mrg <= ((sreal) 1) * opt_for_fn (cs->caller->decl, 2094 1.1 mrg param_ipa_cp_min_recursive_probability)) 2095 1.1 mrg return dest_lat->set_contains_variable (); 2096 1.1 mrg 2097 1.1 mrg auto_vec<ipcp_value<tree> *, 8> val_seeds; 2098 1.1 mrg 2099 1.1 mrg for (src_val = src_lat->values; src_val; src_val = src_val->next) 2100 1.1 mrg { 2101 1.1 mrg /* Now we do not use self-recursively generated value as propagation 2102 1.1 mrg source, this is absolutely conservative, but could avoid explosion 2103 1.1 mrg of lattice's value space, especially when one recursive function 2104 1.1 mrg calls another recursive. */ 2105 1.1 mrg if (src_val->self_recursion_generated_p ()) 2106 1.1 mrg { 2107 1.1 mrg ipcp_value_source<tree> *s; 2108 1.1 mrg 2109 1.1 mrg /* If the lattice has already been propagated for the call site, 2110 1.1 mrg no need to do that again. */ 2111 1.1 mrg for (s = src_val->sources; s; s = s->next) 2112 1.1 mrg if (s->cs == cs) 2113 1.1 mrg return dest_lat->set_contains_variable (); 2114 1.1 mrg } 2115 1.1 mrg else 2116 1.1 mrg val_seeds.safe_push (src_val); 2117 1.1 mrg } 2118 1.1 mrg 2119 1.1 mrg gcc_assert ((int) val_seeds.length () <= param_ipa_cp_value_list_size); 2120 1.1 mrg 2121 1.1 mrg /* Recursively generate lattice values with a limited count. */ 2122 1.1 mrg FOR_EACH_VEC_ELT (val_seeds, i, src_val) 2123 1.1 mrg { 2124 1.1 mrg for (int j = 1; j < max_recursive_depth; j++) 2125 1.1 mrg { 2126 1.1 mrg tree cstval = get_val_across_arith_op (opcode, opnd1_type, opnd2, 2127 1.1 mrg src_val, res_type); 2128 1.1 mrg if (!cstval 2129 1.1 mrg || !ipacp_value_safe_for_type (res_type, cstval)) 2130 1.1 mrg break; 2131 1.1 mrg 2132 1.1 mrg ret |= dest_lat->add_value (cstval, cs, src_val, src_idx, 2133 1.1 mrg src_offset, &src_val, j); 2134 1.1 mrg gcc_checking_assert (src_val); 2135 1.1 mrg } 2136 1.1 mrg } 2137 1.1 mrg ret |= dest_lat->set_contains_variable (); 2138 1.1 mrg } 2139 1.1 mrg else 2140 1.1 mrg for (src_val = src_lat->values; src_val; src_val = src_val->next) 2141 1.1 mrg { 2142 1.1 mrg /* Now we do not use self-recursively generated value as propagation 2143 1.1 mrg source, otherwise it is easy to make value space of normal lattice 2144 1.1 mrg overflow. */ 2145 1.1 mrg if (src_val->self_recursion_generated_p ()) 2146 1.1 mrg { 2147 1.1 mrg ret |= dest_lat->set_contains_variable (); 2148 1.1 mrg continue; 2149 1.1 mrg } 2150 1.1 mrg 2151 1.1 mrg tree cstval = get_val_across_arith_op (opcode, opnd1_type, opnd2, 2152 1.1 mrg src_val, res_type); 2153 1.1 mrg if (cstval 2154 1.1 mrg && ipacp_value_safe_for_type (res_type, cstval)) 2155 1.1 mrg ret |= dest_lat->add_value (cstval, cs, src_val, src_idx, 2156 1.1 mrg src_offset); 2157 1.1 mrg else 2158 1.1 mrg ret |= dest_lat->set_contains_variable (); 2159 1.1 mrg } 2160 1.1 mrg 2161 1.1 mrg return ret; 2162 1.1 mrg } 2163 1.1 mrg 2164 1.1 mrg /* Propagate values through a pass-through jump function JFUNC associated with 2165 1.1 mrg edge CS, taking values from SRC_LAT and putting them into DEST_LAT. SRC_IDX 2166 1.1 mrg is the index of the source parameter. PARM_TYPE is the type of the 2167 1.1 mrg parameter to which the result is passed. */ 2168 1.1 mrg 2169 1.1 mrg static bool 2170 1.1 mrg propagate_vals_across_pass_through (cgraph_edge *cs, ipa_jump_func *jfunc, 2171 1.1 mrg ipcp_lattice<tree> *src_lat, 2172 1.1 mrg ipcp_lattice<tree> *dest_lat, int src_idx, 2173 1.1 mrg tree parm_type) 2174 1.1 mrg { 2175 1.1 mrg return propagate_vals_across_arith_jfunc (cs, 2176 1.1 mrg ipa_get_jf_pass_through_operation (jfunc), 2177 1.1 mrg NULL_TREE, 2178 1.1 mrg ipa_get_jf_pass_through_operand (jfunc), 2179 1.1 mrg src_lat, dest_lat, -1, src_idx, parm_type); 2180 1.1 mrg } 2181 1.1 mrg 2182 1.1 mrg /* Propagate values through an ancestor jump function JFUNC associated with 2183 1.1 mrg edge CS, taking values from SRC_LAT and putting them into DEST_LAT. SRC_IDX 2184 1.1 mrg is the index of the source parameter. */ 2185 1.1 mrg 2186 1.1 mrg static bool 2187 1.1 mrg propagate_vals_across_ancestor (struct cgraph_edge *cs, 2188 1.1 mrg struct ipa_jump_func *jfunc, 2189 1.1 mrg ipcp_lattice<tree> *src_lat, 2190 1.1 mrg ipcp_lattice<tree> *dest_lat, int src_idx, 2191 1.1 mrg tree param_type) 2192 1.1 mrg { 2193 1.1 mrg ipcp_value<tree> *src_val; 2194 1.1 mrg bool ret = false; 2195 1.1 mrg 2196 1.1 mrg if (ipa_edge_within_scc (cs)) 2197 1.1 mrg return dest_lat->set_contains_variable (); 2198 1.1 mrg 2199 1.1 mrg for (src_val = src_lat->values; src_val; src_val = src_val->next) 2200 1.1 mrg { 2201 1.1 mrg tree t = ipa_get_jf_ancestor_result (jfunc, src_val->value); 2202 1.1 mrg 2203 1.1 mrg if (t && ipacp_value_safe_for_type (param_type, t)) 2204 1.1 mrg ret |= dest_lat->add_value (t, cs, src_val, src_idx); 2205 1.1 mrg else 2206 1.1 mrg ret |= dest_lat->set_contains_variable (); 2207 1.1 mrg } 2208 1.1 mrg 2209 1.1 mrg return ret; 2210 1.1 mrg } 2211 1.1 mrg 2212 1.1 mrg /* Propagate scalar values across jump function JFUNC that is associated with 2213 1.1 mrg edge CS and put the values into DEST_LAT. PARM_TYPE is the type of the 2214 1.1 mrg parameter to which the result is passed. */ 2215 1.1 mrg 2216 1.1 mrg static bool 2217 1.1 mrg propagate_scalar_across_jump_function (struct cgraph_edge *cs, 2218 1.1 mrg struct ipa_jump_func *jfunc, 2219 1.1 mrg ipcp_lattice<tree> *dest_lat, 2220 1.1 mrg tree param_type) 2221 1.1 mrg { 2222 1.1 mrg if (dest_lat->bottom) 2223 1.1 mrg return false; 2224 1.1 mrg 2225 1.1 mrg if (jfunc->type == IPA_JF_CONST) 2226 1.1 mrg { 2227 1.1 mrg tree val = ipa_get_jf_constant (jfunc); 2228 1.1 mrg if (ipacp_value_safe_for_type (param_type, val)) 2229 1.1 mrg return dest_lat->add_value (val, cs, NULL, 0); 2230 1.1 mrg else 2231 1.1 mrg return dest_lat->set_contains_variable (); 2232 1.1 mrg } 2233 1.1 mrg else if (jfunc->type == IPA_JF_PASS_THROUGH 2234 1.1 mrg || jfunc->type == IPA_JF_ANCESTOR) 2235 1.1 mrg { 2236 1.1 mrg ipa_node_params *caller_info = ipa_node_params_sum->get (cs->caller); 2237 1.1 mrg ipcp_lattice<tree> *src_lat; 2238 1.1 mrg int src_idx; 2239 1.1 mrg bool ret; 2240 1.1 mrg 2241 1.1 mrg if (jfunc->type == IPA_JF_PASS_THROUGH) 2242 1.1 mrg src_idx = ipa_get_jf_pass_through_formal_id (jfunc); 2243 1.1 mrg else 2244 1.1 mrg src_idx = ipa_get_jf_ancestor_formal_id (jfunc); 2245 1.1 mrg 2246 1.1 mrg src_lat = ipa_get_scalar_lat (caller_info, src_idx); 2247 1.1 mrg if (src_lat->bottom) 2248 1.1 mrg return dest_lat->set_contains_variable (); 2249 1.1 mrg 2250 1.1 mrg /* If we would need to clone the caller and cannot, do not propagate. */ 2251 1.1 mrg if (!ipcp_versionable_function_p (cs->caller) 2252 1.1 mrg && (src_lat->contains_variable 2253 1.1 mrg || (src_lat->values_count > 1))) 2254 1.1 mrg return dest_lat->set_contains_variable (); 2255 1.1 mrg 2256 1.1 mrg if (jfunc->type == IPA_JF_PASS_THROUGH) 2257 1.1 mrg ret = propagate_vals_across_pass_through (cs, jfunc, src_lat, 2258 1.1 mrg dest_lat, src_idx, 2259 1.1 mrg param_type); 2260 1.1 mrg else 2261 1.1 mrg ret = propagate_vals_across_ancestor (cs, jfunc, src_lat, dest_lat, 2262 1.1 mrg src_idx, param_type); 2263 1.1 mrg 2264 1.1 mrg if (src_lat->contains_variable) 2265 1.1 mrg ret |= dest_lat->set_contains_variable (); 2266 1.1 mrg 2267 1.1 mrg return ret; 2268 1.1 mrg } 2269 1.1 mrg 2270 1.1 mrg /* TODO: We currently do not handle member method pointers in IPA-CP (we only 2271 1.1 mrg use it for indirect inlining), we should propagate them too. */ 2272 1.1 mrg return dest_lat->set_contains_variable (); 2273 1.1 mrg } 2274 1.1 mrg 2275 1.1 mrg /* Propagate scalar values across jump function JFUNC that is associated with 2276 1.1 mrg edge CS and describes argument IDX and put the values into DEST_LAT. */ 2277 1.1 mrg 2278 1.1 mrg static bool 2279 1.1 mrg propagate_context_across_jump_function (cgraph_edge *cs, 2280 1.1 mrg ipa_jump_func *jfunc, int idx, 2281 1.1 mrg ipcp_lattice<ipa_polymorphic_call_context> *dest_lat) 2282 1.1 mrg { 2283 1.1 mrg if (dest_lat->bottom) 2284 1.1 mrg return false; 2285 1.1 mrg ipa_edge_args *args = ipa_edge_args_sum->get (cs); 2286 1.1 mrg bool ret = false; 2287 1.1 mrg bool added_sth = false; 2288 1.1 mrg bool type_preserved = true; 2289 1.1 mrg 2290 1.1 mrg ipa_polymorphic_call_context edge_ctx, *edge_ctx_ptr 2291 1.1 mrg = ipa_get_ith_polymorhic_call_context (args, idx); 2292 1.1 mrg 2293 1.1 mrg if (edge_ctx_ptr) 2294 1.1 mrg edge_ctx = *edge_ctx_ptr; 2295 1.1 mrg 2296 1.1 mrg if (jfunc->type == IPA_JF_PASS_THROUGH 2297 1.1 mrg || jfunc->type == IPA_JF_ANCESTOR) 2298 1.1 mrg { 2299 1.1 mrg ipa_node_params *caller_info = ipa_node_params_sum->get (cs->caller); 2300 1.1 mrg int src_idx; 2301 1.1 mrg ipcp_lattice<ipa_polymorphic_call_context> *src_lat; 2302 1.1 mrg 2303 1.1 mrg /* TODO: Once we figure out how to propagate speculations, it will 2304 1.1 mrg probably be a good idea to switch to speculation if type_preserved is 2305 1.1 mrg not set instead of punting. */ 2306 1.1 mrg if (jfunc->type == IPA_JF_PASS_THROUGH) 2307 1.1 mrg { 2308 1.1 mrg if (ipa_get_jf_pass_through_operation (jfunc) != NOP_EXPR) 2309 1.1 mrg goto prop_fail; 2310 1.1 mrg type_preserved = ipa_get_jf_pass_through_type_preserved (jfunc); 2311 1.1 mrg src_idx = ipa_get_jf_pass_through_formal_id (jfunc); 2312 1.1 mrg } 2313 1.1 mrg else 2314 1.1 mrg { 2315 1.1 mrg type_preserved = ipa_get_jf_ancestor_type_preserved (jfunc); 2316 1.1 mrg src_idx = ipa_get_jf_ancestor_formal_id (jfunc); 2317 1.1 mrg } 2318 1.1 mrg 2319 1.1 mrg src_lat = ipa_get_poly_ctx_lat (caller_info, src_idx); 2320 1.1 mrg /* If we would need to clone the caller and cannot, do not propagate. */ 2321 1.1 mrg if (!ipcp_versionable_function_p (cs->caller) 2322 1.1 mrg && (src_lat->contains_variable 2323 1.1 mrg || (src_lat->values_count > 1))) 2324 1.1 mrg goto prop_fail; 2325 1.1 mrg 2326 1.1 mrg ipcp_value<ipa_polymorphic_call_context> *src_val; 2327 1.1 mrg for (src_val = src_lat->values; src_val; src_val = src_val->next) 2328 1.1 mrg { 2329 1.1 mrg ipa_polymorphic_call_context cur = src_val->value; 2330 1.1 mrg 2331 1.1 mrg if (!type_preserved) 2332 1.1 mrg cur.possible_dynamic_type_change (cs->in_polymorphic_cdtor); 2333 1.1 mrg if (jfunc->type == IPA_JF_ANCESTOR) 2334 1.1 mrg cur.offset_by (ipa_get_jf_ancestor_offset (jfunc)); 2335 1.1 mrg /* TODO: In cases we know how the context is going to be used, 2336 1.1 mrg we can improve the result by passing proper OTR_TYPE. */ 2337 1.1 mrg cur.combine_with (edge_ctx); 2338 1.1 mrg if (!cur.useless_p ()) 2339 1.1 mrg { 2340 1.1 mrg if (src_lat->contains_variable 2341 1.1 mrg && !edge_ctx.equal_to (cur)) 2342 1.1 mrg ret |= dest_lat->set_contains_variable (); 2343 1.1 mrg ret |= dest_lat->add_value (cur, cs, src_val, src_idx); 2344 1.1 mrg added_sth = true; 2345 1.1 mrg } 2346 1.1 mrg } 2347 1.1 mrg } 2348 1.1 mrg 2349 1.1 mrg prop_fail: 2350 1.1 mrg if (!added_sth) 2351 1.1 mrg { 2352 1.1 mrg if (!edge_ctx.useless_p ()) 2353 1.1 mrg ret |= dest_lat->add_value (edge_ctx, cs); 2354 1.1 mrg else 2355 1.1 mrg ret |= dest_lat->set_contains_variable (); 2356 1.1 mrg } 2357 1.1 mrg 2358 1.1 mrg return ret; 2359 1.1 mrg } 2360 1.1 mrg 2361 1.1 mrg /* Propagate bits across jfunc that is associated with 2362 1.1 mrg edge cs and update dest_lattice accordingly. */ 2363 1.1 mrg 2364 1.1 mrg bool 2365 1.1 mrg propagate_bits_across_jump_function (cgraph_edge *cs, int idx, 2366 1.1 mrg ipa_jump_func *jfunc, 2367 1.1 mrg ipcp_bits_lattice *dest_lattice) 2368 1.1 mrg { 2369 1.1 mrg if (dest_lattice->bottom_p ()) 2370 1.1 mrg return false; 2371 1.1 mrg 2372 1.1 mrg enum availability availability; 2373 1.1 mrg cgraph_node *callee = cs->callee->function_symbol (&availability); 2374 1.1 mrg ipa_node_params *callee_info = ipa_node_params_sum->get (callee); 2375 1.1 mrg tree parm_type = ipa_get_type (callee_info, idx); 2376 1.1 mrg 2377 1.1 mrg /* For K&R C programs, ipa_get_type() could return NULL_TREE. Avoid the 2378 1.1 mrg transform for these cases. Similarly, we can have bad type mismatches 2379 1.1 mrg with LTO, avoid doing anything with those too. */ 2380 1.1 mrg if (!parm_type 2381 1.1 mrg || (!INTEGRAL_TYPE_P (parm_type) && !POINTER_TYPE_P (parm_type))) 2382 1.1 mrg { 2383 1.1 mrg if (dump_file && (dump_flags & TDF_DETAILS)) 2384 1.1 mrg fprintf (dump_file, "Setting dest_lattice to bottom, because type of " 2385 1.1 mrg "param %i of %s is NULL or unsuitable for bits propagation\n", 2386 1.1 mrg idx, cs->callee->dump_name ()); 2387 1.1 mrg 2388 1.1 mrg return dest_lattice->set_to_bottom (); 2389 1.1 mrg } 2390 1.1 mrg 2391 1.1 mrg unsigned precision = TYPE_PRECISION (parm_type); 2392 1.1 mrg signop sgn = TYPE_SIGN (parm_type); 2393 1.1 mrg 2394 1.1 mrg if (jfunc->type == IPA_JF_PASS_THROUGH 2395 1.1 mrg || jfunc->type == IPA_JF_ANCESTOR) 2396 1.1 mrg { 2397 1.1 mrg ipa_node_params *caller_info = ipa_node_params_sum->get (cs->caller); 2398 1.1 mrg tree operand = NULL_TREE; 2399 1.1 mrg enum tree_code code; 2400 1.1 mrg unsigned src_idx; 2401 1.1 mrg bool keep_null = false; 2402 1.1 mrg 2403 1.1 mrg if (jfunc->type == IPA_JF_PASS_THROUGH) 2404 1.1 mrg { 2405 1.1 mrg code = ipa_get_jf_pass_through_operation (jfunc); 2406 1.1 mrg src_idx = ipa_get_jf_pass_through_formal_id (jfunc); 2407 1.1 mrg if (code != NOP_EXPR) 2408 1.1 mrg operand = ipa_get_jf_pass_through_operand (jfunc); 2409 1.1 mrg } 2410 1.1 mrg else 2411 1.1 mrg { 2412 1.1 mrg code = POINTER_PLUS_EXPR; 2413 1.1 mrg src_idx = ipa_get_jf_ancestor_formal_id (jfunc); 2414 1.1 mrg unsigned HOST_WIDE_INT offset 2415 1.1 mrg = ipa_get_jf_ancestor_offset (jfunc) / BITS_PER_UNIT; 2416 1.1 mrg keep_null = (ipa_get_jf_ancestor_keep_null (jfunc) || !offset); 2417 1.1 mrg operand = build_int_cstu (size_type_node, offset); 2418 1.1 mrg } 2419 1.1 mrg 2420 1.1 mrg class ipcp_param_lattices *src_lats 2421 1.1 mrg = ipa_get_parm_lattices (caller_info, src_idx); 2422 1.1 mrg 2423 1.1 mrg /* Try to propagate bits if src_lattice is bottom, but jfunc is known. 2424 1.1 mrg for eg consider: 2425 1.1 mrg int f(int x) 2426 1.1 mrg { 2427 1.1 mrg g (x & 0xff); 2428 1.1 mrg } 2429 1.1 mrg Assume lattice for x is bottom, however we can still propagate 2430 1.1 mrg result of x & 0xff == 0xff, which gets computed during ccp1 pass 2431 1.1 mrg and we store it in jump function during analysis stage. */ 2432 1.1 mrg 2433 1.1 mrg if (!src_lats->bits_lattice.bottom_p ()) 2434 1.1 mrg { 2435 1.1 mrg bool drop_all_ones 2436 1.1 mrg = keep_null && !src_lats->bits_lattice.known_nonzero_p (); 2437 1.1 mrg 2438 1.1 mrg return dest_lattice->meet_with (src_lats->bits_lattice, precision, 2439 1.1 mrg sgn, code, operand, drop_all_ones); 2440 1.1 mrg } 2441 1.1 mrg } 2442 1.1 mrg 2443 1.1 mrg if (jfunc->bits) 2444 1.1 mrg return dest_lattice->meet_with (jfunc->bits->value, jfunc->bits->mask, 2445 1.1 mrg precision); 2446 1.1 mrg else 2447 1.1 mrg return dest_lattice->set_to_bottom (); 2448 1.1 mrg } 2449 1.1 mrg 2450 1.1 mrg /* Propagate value range across jump function JFUNC that is associated with 2451 1.1 mrg edge CS with param of callee of PARAM_TYPE and update DEST_PLATS 2452 1.1 mrg accordingly. */ 2453 1.1 mrg 2454 1.1 mrg static bool 2455 1.1 mrg propagate_vr_across_jump_function (cgraph_edge *cs, ipa_jump_func *jfunc, 2456 1.1 mrg class ipcp_param_lattices *dest_plats, 2457 1.1 mrg tree param_type) 2458 1.1 mrg { 2459 1.1 mrg ipcp_vr_lattice *dest_lat = &dest_plats->m_value_range; 2460 1.1 mrg 2461 1.1 mrg if (dest_lat->bottom_p ()) 2462 1.1 mrg return false; 2463 1.1 mrg 2464 1.1 mrg if (!param_type 2465 1.1 mrg || (!INTEGRAL_TYPE_P (param_type) 2466 1.1 mrg && !POINTER_TYPE_P (param_type))) 2467 1.1 mrg return dest_lat->set_to_bottom (); 2468 1.1 mrg 2469 1.1 mrg if (jfunc->type == IPA_JF_PASS_THROUGH) 2470 1.1 mrg { 2471 1.1 mrg enum tree_code operation = ipa_get_jf_pass_through_operation (jfunc); 2472 1.1 mrg ipa_node_params *caller_info = ipa_node_params_sum->get (cs->caller); 2473 1.1 mrg int src_idx = ipa_get_jf_pass_through_formal_id (jfunc); 2474 1.1 mrg class ipcp_param_lattices *src_lats 2475 1.1 mrg = ipa_get_parm_lattices (caller_info, src_idx); 2476 1.1 mrg tree operand_type = ipa_get_type (caller_info, src_idx); 2477 1.1 mrg 2478 1.1 mrg if (src_lats->m_value_range.bottom_p ()) 2479 1.1 mrg return dest_lat->set_to_bottom (); 2480 1.1 mrg 2481 1.1 mrg value_range vr; 2482 1.1 mrg if (TREE_CODE_CLASS (operation) == tcc_unary) 2483 1.1 mrg ipa_vr_operation_and_type_effects (&vr, 2484 1.1 mrg &src_lats->m_value_range.m_vr, 2485 1.1 mrg operation, param_type, 2486 1.1 mrg operand_type); 2487 1.1 mrg /* A crude way to prevent unbounded number of value range updates 2488 1.1 mrg in SCC components. We should allow limited number of updates within 2489 1.1 mrg SCC, too. */ 2490 1.1 mrg else if (!ipa_edge_within_scc (cs)) 2491 1.1 mrg { 2492 1.1 mrg tree op = ipa_get_jf_pass_through_operand (jfunc); 2493 1.1 mrg value_range op_vr (op, op); 2494 1.1 mrg value_range op_res,res; 2495 1.1 mrg 2496 1.1 mrg range_fold_binary_expr (&op_res, operation, operand_type, 2497 1.1 mrg &src_lats->m_value_range.m_vr, &op_vr); 2498 1.1 mrg ipa_vr_operation_and_type_effects (&vr, 2499 1.1 mrg &op_res, 2500 1.1 mrg NOP_EXPR, param_type, 2501 1.1 mrg operand_type); 2502 1.1 mrg } 2503 1.1 mrg if (!vr.undefined_p () && !vr.varying_p ()) 2504 1.1 mrg { 2505 1.1 mrg if (jfunc->m_vr) 2506 1.1 mrg { 2507 1.1 mrg value_range jvr; 2508 1.1 mrg if (ipa_vr_operation_and_type_effects (&jvr, jfunc->m_vr, 2509 1.1 mrg NOP_EXPR, 2510 1.1 mrg param_type, 2511 1.1 mrg jfunc->m_vr->type ())) 2512 1.1 mrg vr.intersect (jvr); 2513 1.1 mrg } 2514 1.1 mrg return dest_lat->meet_with (&vr); 2515 1.1 mrg } 2516 1.1 mrg } 2517 1.1 mrg else if (jfunc->type == IPA_JF_CONST) 2518 1.1 mrg { 2519 1.1 mrg tree val = ipa_get_jf_constant (jfunc); 2520 1.1 mrg if (TREE_CODE (val) == INTEGER_CST) 2521 1.1 mrg { 2522 1.1 mrg val = fold_convert (param_type, val); 2523 1.1 mrg if (TREE_OVERFLOW_P (val)) 2524 1.1 mrg val = drop_tree_overflow (val); 2525 1.1 mrg 2526 1.1 mrg value_range tmpvr (val, val); 2527 1.1 mrg return dest_lat->meet_with (&tmpvr); 2528 1.1 mrg } 2529 1.1 mrg } 2530 1.1 mrg 2531 1.1 mrg value_range vr; 2532 1.1 mrg if (jfunc->m_vr 2533 1.1 mrg && ipa_vr_operation_and_type_effects (&vr, jfunc->m_vr, NOP_EXPR, 2534 1.1 mrg param_type, 2535 1.1 mrg jfunc->m_vr->type ())) 2536 1.1 mrg return dest_lat->meet_with (&vr); 2537 1.1 mrg else 2538 1.1 mrg return dest_lat->set_to_bottom (); 2539 1.1 mrg } 2540 1.1 mrg 2541 1.1 mrg /* If DEST_PLATS already has aggregate items, check that aggs_by_ref matches 2542 1.1 mrg NEW_AGGS_BY_REF and if not, mark all aggs as bottoms and return true (in all 2543 1.1 mrg other cases, return false). If there are no aggregate items, set 2544 1.1 mrg aggs_by_ref to NEW_AGGS_BY_REF. */ 2545 1.1 mrg 2546 1.1 mrg static bool 2547 1.1 mrg set_check_aggs_by_ref (class ipcp_param_lattices *dest_plats, 2548 1.1 mrg bool new_aggs_by_ref) 2549 1.1 mrg { 2550 1.1 mrg if (dest_plats->aggs) 2551 1.1 mrg { 2552 1.1 mrg if (dest_plats->aggs_by_ref != new_aggs_by_ref) 2553 1.1 mrg { 2554 1.1 mrg set_agg_lats_to_bottom (dest_plats); 2555 1.1 mrg return true; 2556 1.1 mrg } 2557 1.1 mrg } 2558 1.1 mrg else 2559 1.1 mrg dest_plats->aggs_by_ref = new_aggs_by_ref; 2560 1.1 mrg return false; 2561 1.1 mrg } 2562 1.1 mrg 2563 1.1 mrg /* Walk aggregate lattices in DEST_PLATS from ***AGLAT on, until ***aglat is an 2564 1.1 mrg already existing lattice for the given OFFSET and SIZE, marking all skipped 2565 1.1 mrg lattices as containing variable and checking for overlaps. If there is no 2566 1.1 mrg already existing lattice for the OFFSET and VAL_SIZE, create one, initialize 2567 1.1 mrg it with offset, size and contains_variable to PRE_EXISTING, and return true, 2568 1.1 mrg unless there are too many already. If there are two many, return false. If 2569 1.1 mrg there are overlaps turn whole DEST_PLATS to bottom and return false. If any 2570 1.1 mrg skipped lattices were newly marked as containing variable, set *CHANGE to 2571 1.1 mrg true. MAX_AGG_ITEMS is the maximum number of lattices. */ 2572 1.1 mrg 2573 1.1 mrg static bool 2574 1.1 mrg merge_agg_lats_step (class ipcp_param_lattices *dest_plats, 2575 1.1 mrg HOST_WIDE_INT offset, HOST_WIDE_INT val_size, 2576 1.1 mrg struct ipcp_agg_lattice ***aglat, 2577 1.1 mrg bool pre_existing, bool *change, int max_agg_items) 2578 1.1 mrg { 2579 1.1 mrg gcc_checking_assert (offset >= 0); 2580 1.1 mrg 2581 1.1 mrg while (**aglat && (**aglat)->offset < offset) 2582 1.1 mrg { 2583 1.1 mrg if ((**aglat)->offset + (**aglat)->size > offset) 2584 1.1 mrg { 2585 1.1 mrg set_agg_lats_to_bottom (dest_plats); 2586 1.1 mrg return false; 2587 1.1 mrg } 2588 1.1 mrg *change |= (**aglat)->set_contains_variable (); 2589 1.1 mrg *aglat = &(**aglat)->next; 2590 1.1 mrg } 2591 1.1 mrg 2592 1.1 mrg if (**aglat && (**aglat)->offset == offset) 2593 1.1 mrg { 2594 1.1 mrg if ((**aglat)->size != val_size) 2595 1.1 mrg { 2596 1.1 mrg set_agg_lats_to_bottom (dest_plats); 2597 1.1 mrg return false; 2598 1.1 mrg } 2599 1.1 mrg gcc_assert (!(**aglat)->next 2600 1.1 mrg || (**aglat)->next->offset >= offset + val_size); 2601 1.1 mrg return true; 2602 1.1 mrg } 2603 1.1 mrg else 2604 1.1 mrg { 2605 1.1 mrg struct ipcp_agg_lattice *new_al; 2606 1.1 mrg 2607 1.1 mrg if (**aglat && (**aglat)->offset < offset + val_size) 2608 1.1 mrg { 2609 1.1 mrg set_agg_lats_to_bottom (dest_plats); 2610 1.1 mrg return false; 2611 1.1 mrg } 2612 1.1 mrg if (dest_plats->aggs_count == max_agg_items) 2613 1.1 mrg return false; 2614 1.1 mrg dest_plats->aggs_count++; 2615 1.1 mrg new_al = ipcp_agg_lattice_pool.allocate (); 2616 1.1 mrg memset (new_al, 0, sizeof (*new_al)); 2617 1.1 mrg 2618 1.1 mrg new_al->offset = offset; 2619 1.1 mrg new_al->size = val_size; 2620 1.1 mrg new_al->contains_variable = pre_existing; 2621 1.1 mrg 2622 1.1 mrg new_al->next = **aglat; 2623 1.1 mrg **aglat = new_al; 2624 1.1 mrg return true; 2625 1.1 mrg } 2626 1.1 mrg } 2627 1.1 mrg 2628 1.1 mrg /* Set all AGLAT and all other aggregate lattices reachable by next pointers as 2629 1.1 mrg containing an unknown value. */ 2630 1.1 mrg 2631 1.1 mrg static bool 2632 1.1 mrg set_chain_of_aglats_contains_variable (struct ipcp_agg_lattice *aglat) 2633 1.1 mrg { 2634 1.1 mrg bool ret = false; 2635 1.1 mrg while (aglat) 2636 1.1 mrg { 2637 1.1 mrg ret |= aglat->set_contains_variable (); 2638 1.1 mrg aglat = aglat->next; 2639 1.1 mrg } 2640 1.1 mrg return ret; 2641 1.1 mrg } 2642 1.1 mrg 2643 1.1 mrg /* Merge existing aggregate lattices in SRC_PLATS to DEST_PLATS, subtracting 2644 1.1 mrg DELTA_OFFSET. CS is the call graph edge and SRC_IDX the index of the source 2645 1.1 mrg parameter used for lattice value sources. Return true if DEST_PLATS changed 2646 1.1 mrg in any way. */ 2647 1.1 mrg 2648 1.1 mrg static bool 2649 1.1 mrg merge_aggregate_lattices (struct cgraph_edge *cs, 2650 1.1 mrg class ipcp_param_lattices *dest_plats, 2651 1.1 mrg class ipcp_param_lattices *src_plats, 2652 1.1 mrg int src_idx, HOST_WIDE_INT offset_delta) 2653 1.1 mrg { 2654 1.1 mrg bool pre_existing = dest_plats->aggs != NULL; 2655 1.1 mrg struct ipcp_agg_lattice **dst_aglat; 2656 1.1 mrg bool ret = false; 2657 1.1 mrg 2658 1.1 mrg if (set_check_aggs_by_ref (dest_plats, src_plats->aggs_by_ref)) 2659 1.1 mrg return true; 2660 1.1 mrg if (src_plats->aggs_bottom) 2661 1.1 mrg return set_agg_lats_contain_variable (dest_plats); 2662 1.1 mrg if (src_plats->aggs_contain_variable) 2663 1.1 mrg ret |= set_agg_lats_contain_variable (dest_plats); 2664 1.1 mrg dst_aglat = &dest_plats->aggs; 2665 1.1 mrg 2666 1.1 mrg int max_agg_items = opt_for_fn (cs->callee->function_symbol ()->decl, 2667 1.1 mrg param_ipa_max_agg_items); 2668 1.1 mrg for (struct ipcp_agg_lattice *src_aglat = src_plats->aggs; 2669 1.1 mrg src_aglat; 2670 1.1 mrg src_aglat = src_aglat->next) 2671 1.1 mrg { 2672 1.1 mrg HOST_WIDE_INT new_offset = src_aglat->offset - offset_delta; 2673 1.1 mrg 2674 1.1 mrg if (new_offset < 0) 2675 1.1 mrg continue; 2676 1.1 mrg if (merge_agg_lats_step (dest_plats, new_offset, src_aglat->size, 2677 1.1 mrg &dst_aglat, pre_existing, &ret, max_agg_items)) 2678 1.1 mrg { 2679 1.1 mrg struct ipcp_agg_lattice *new_al = *dst_aglat; 2680 1.1 mrg 2681 1.1 mrg dst_aglat = &(*dst_aglat)->next; 2682 1.1 mrg if (src_aglat->bottom) 2683 1.1 mrg { 2684 1.1 mrg ret |= new_al->set_contains_variable (); 2685 1.1 mrg continue; 2686 1.1 mrg } 2687 1.1 mrg if (src_aglat->contains_variable) 2688 1.1 mrg ret |= new_al->set_contains_variable (); 2689 1.1 mrg for (ipcp_value<tree> *val = src_aglat->values; 2690 1.1 mrg val; 2691 1.1 mrg val = val->next) 2692 1.1 mrg ret |= new_al->add_value (val->value, cs, val, src_idx, 2693 1.1 mrg src_aglat->offset); 2694 1.1 mrg } 2695 1.1 mrg else if (dest_plats->aggs_bottom) 2696 1.1 mrg return true; 2697 1.1 mrg } 2698 1.1 mrg ret |= set_chain_of_aglats_contains_variable (*dst_aglat); 2699 1.1 mrg return ret; 2700 1.1 mrg } 2701 1.1 mrg 2702 1.1 mrg /* Determine whether there is anything to propagate FROM SRC_PLATS through a 2703 1.1 mrg pass-through JFUNC and if so, whether it has conform and conforms to the 2704 1.1 mrg rules about propagating values passed by reference. */ 2705 1.1 mrg 2706 1.1 mrg static bool 2707 1.1 mrg agg_pass_through_permissible_p (class ipcp_param_lattices *src_plats, 2708 1.1 mrg struct ipa_jump_func *jfunc) 2709 1.1 mrg { 2710 1.1 mrg return src_plats->aggs 2711 1.1 mrg && (!src_plats->aggs_by_ref 2712 1.1 mrg || ipa_get_jf_pass_through_agg_preserved (jfunc)); 2713 1.1 mrg } 2714 1.1 mrg 2715 1.1 mrg /* Propagate values through ITEM, jump function for a part of an aggregate, 2716 1.1 mrg into corresponding aggregate lattice AGLAT. CS is the call graph edge 2717 1.1 mrg associated with the jump function. Return true if AGLAT changed in any 2718 1.1 mrg way. */ 2719 1.1 mrg 2720 1.1 mrg static bool 2721 1.1 mrg propagate_aggregate_lattice (struct cgraph_edge *cs, 2722 1.1 mrg struct ipa_agg_jf_item *item, 2723 1.1 mrg struct ipcp_agg_lattice *aglat) 2724 1.1 mrg { 2725 1.1 mrg class ipa_node_params *caller_info; 2726 1.1 mrg class ipcp_param_lattices *src_plats; 2727 1.1 mrg struct ipcp_lattice<tree> *src_lat; 2728 1.1 mrg HOST_WIDE_INT src_offset; 2729 1.1 mrg int src_idx; 2730 1.1 mrg tree load_type; 2731 1.1 mrg bool ret; 2732 1.1 mrg 2733 1.1 mrg if (item->jftype == IPA_JF_CONST) 2734 1.1 mrg { 2735 1.1 mrg tree value = item->value.constant; 2736 1.1 mrg 2737 1.1 mrg gcc_checking_assert (is_gimple_ip_invariant (value)); 2738 1.1 mrg return aglat->add_value (value, cs, NULL, 0); 2739 1.1 mrg } 2740 1.1 mrg 2741 1.1 mrg gcc_checking_assert (item->jftype == IPA_JF_PASS_THROUGH 2742 1.1 mrg || item->jftype == IPA_JF_LOAD_AGG); 2743 1.1 mrg 2744 1.1 mrg caller_info = ipa_node_params_sum->get (cs->caller); 2745 1.1 mrg src_idx = item->value.pass_through.formal_id; 2746 1.1 mrg src_plats = ipa_get_parm_lattices (caller_info, src_idx); 2747 1.1 mrg 2748 1.1 mrg if (item->jftype == IPA_JF_PASS_THROUGH) 2749 1.1 mrg { 2750 1.1 mrg load_type = NULL_TREE; 2751 1.1 mrg src_lat = &src_plats->itself; 2752 1.1 mrg src_offset = -1; 2753 1.1 mrg } 2754 1.1 mrg else 2755 1.1 mrg { 2756 1.1 mrg HOST_WIDE_INT load_offset = item->value.load_agg.offset; 2757 1.1 mrg struct ipcp_agg_lattice *src_aglat; 2758 1.1 mrg 2759 1.1 mrg for (src_aglat = src_plats->aggs; src_aglat; src_aglat = src_aglat->next) 2760 1.1 mrg if (src_aglat->offset >= load_offset) 2761 1.1 mrg break; 2762 1.1 mrg 2763 1.1 mrg load_type = item->value.load_agg.type; 2764 1.1 mrg if (!src_aglat 2765 1.1 mrg || src_aglat->offset > load_offset 2766 1.1 mrg || src_aglat->size != tree_to_shwi (TYPE_SIZE (load_type)) 2767 1.1 mrg || src_plats->aggs_by_ref != item->value.load_agg.by_ref) 2768 1.1 mrg return aglat->set_contains_variable (); 2769 1.1 mrg 2770 1.1 mrg src_lat = src_aglat; 2771 1.1 mrg src_offset = load_offset; 2772 1.1 mrg } 2773 1.1 mrg 2774 1.1 mrg if (src_lat->bottom 2775 1.1 mrg || (!ipcp_versionable_function_p (cs->caller) 2776 1.1 mrg && !src_lat->is_single_const ())) 2777 1.1 mrg return aglat->set_contains_variable (); 2778 1.1 mrg 2779 1.1 mrg ret = propagate_vals_across_arith_jfunc (cs, 2780 1.1 mrg item->value.pass_through.operation, 2781 1.1 mrg load_type, 2782 1.1 mrg item->value.pass_through.operand, 2783 1.1 mrg src_lat, aglat, 2784 1.1 mrg src_offset, 2785 1.1 mrg src_idx, 2786 1.1 mrg item->type); 2787 1.1 mrg 2788 1.1 mrg if (src_lat->contains_variable) 2789 1.1 mrg ret |= aglat->set_contains_variable (); 2790 1.1 mrg 2791 1.1 mrg return ret; 2792 1.1 mrg } 2793 1.1 mrg 2794 1.1 mrg /* Propagate scalar values across jump function JFUNC that is associated with 2795 1.1 mrg edge CS and put the values into DEST_LAT. */ 2796 1.1 mrg 2797 1.1 mrg static bool 2798 1.1 mrg propagate_aggs_across_jump_function (struct cgraph_edge *cs, 2799 1.1 mrg struct ipa_jump_func *jfunc, 2800 1.1 mrg class ipcp_param_lattices *dest_plats) 2801 1.1 mrg { 2802 1.1 mrg bool ret = false; 2803 1.1 mrg 2804 1.1 mrg if (dest_plats->aggs_bottom) 2805 1.1 mrg return false; 2806 1.1 mrg 2807 1.1 mrg if (jfunc->type == IPA_JF_PASS_THROUGH 2808 1.1 mrg && ipa_get_jf_pass_through_operation (jfunc) == NOP_EXPR) 2809 1.1 mrg { 2810 1.1 mrg ipa_node_params *caller_info = ipa_node_params_sum->get (cs->caller); 2811 1.1 mrg int src_idx = ipa_get_jf_pass_through_formal_id (jfunc); 2812 1.1 mrg class ipcp_param_lattices *src_plats; 2813 1.1 mrg 2814 1.1 mrg src_plats = ipa_get_parm_lattices (caller_info, src_idx); 2815 1.1 mrg if (agg_pass_through_permissible_p (src_plats, jfunc)) 2816 1.1 mrg { 2817 1.1 mrg /* Currently we do not produce clobber aggregate jump 2818 1.1 mrg functions, replace with merging when we do. */ 2819 1.1 mrg gcc_assert (!jfunc->agg.items); 2820 1.1 mrg ret |= merge_aggregate_lattices (cs, dest_plats, src_plats, 2821 1.1 mrg src_idx, 0); 2822 1.1 mrg return ret; 2823 1.1 mrg } 2824 1.1 mrg } 2825 1.1 mrg else if (jfunc->type == IPA_JF_ANCESTOR 2826 1.1 mrg && ipa_get_jf_ancestor_agg_preserved (jfunc)) 2827 1.1 mrg { 2828 1.1 mrg ipa_node_params *caller_info = ipa_node_params_sum->get (cs->caller); 2829 1.1 mrg int src_idx = ipa_get_jf_ancestor_formal_id (jfunc); 2830 1.1 mrg class ipcp_param_lattices *src_plats; 2831 1.1 mrg 2832 1.1 mrg src_plats = ipa_get_parm_lattices (caller_info, src_idx); 2833 1.1 mrg if (src_plats->aggs && src_plats->aggs_by_ref) 2834 1.1 mrg { 2835 1.1 mrg /* Currently we do not produce clobber aggregate jump 2836 1.1 mrg functions, replace with merging when we do. */ 2837 1.1 mrg gcc_assert (!jfunc->agg.items); 2838 1.1 mrg ret |= merge_aggregate_lattices (cs, dest_plats, src_plats, src_idx, 2839 1.1 mrg ipa_get_jf_ancestor_offset (jfunc)); 2840 1.1 mrg } 2841 1.1 mrg else if (!src_plats->aggs_by_ref) 2842 1.1 mrg ret |= set_agg_lats_to_bottom (dest_plats); 2843 1.1 mrg else 2844 1.1 mrg ret |= set_agg_lats_contain_variable (dest_plats); 2845 1.1 mrg return ret; 2846 1.1 mrg } 2847 1.1 mrg 2848 1.1 mrg if (jfunc->agg.items) 2849 1.1 mrg { 2850 1.1 mrg bool pre_existing = dest_plats->aggs != NULL; 2851 1.1 mrg struct ipcp_agg_lattice **aglat = &dest_plats->aggs; 2852 1.1 mrg struct ipa_agg_jf_item *item; 2853 1.1 mrg int i; 2854 1.1 mrg 2855 1.1 mrg if (set_check_aggs_by_ref (dest_plats, jfunc->agg.by_ref)) 2856 1.1 mrg return true; 2857 1.1 mrg 2858 1.1 mrg int max_agg_items = opt_for_fn (cs->callee->function_symbol ()->decl, 2859 1.1 mrg param_ipa_max_agg_items); 2860 1.1 mrg FOR_EACH_VEC_ELT (*jfunc->agg.items, i, item) 2861 1.1 mrg { 2862 1.1 mrg HOST_WIDE_INT val_size; 2863 1.1 mrg 2864 1.1 mrg if (item->offset < 0 || item->jftype == IPA_JF_UNKNOWN) 2865 1.1 mrg continue; 2866 1.1 mrg val_size = tree_to_shwi (TYPE_SIZE (item->type)); 2867 1.1 mrg 2868 1.1 mrg if (merge_agg_lats_step (dest_plats, item->offset, val_size, 2869 1.1 mrg &aglat, pre_existing, &ret, max_agg_items)) 2870 1.1 mrg { 2871 1.1 mrg ret |= propagate_aggregate_lattice (cs, item, *aglat); 2872 1.1 mrg aglat = &(*aglat)->next; 2873 1.1 mrg } 2874 1.1 mrg else if (dest_plats->aggs_bottom) 2875 1.1 mrg return true; 2876 1.1 mrg } 2877 1.1 mrg 2878 1.1 mrg ret |= set_chain_of_aglats_contains_variable (*aglat); 2879 1.1 mrg } 2880 1.1 mrg else 2881 1.1 mrg ret |= set_agg_lats_contain_variable (dest_plats); 2882 1.1 mrg 2883 1.1 mrg return ret; 2884 1.1 mrg } 2885 1.1 mrg 2886 1.1 mrg /* Return true if on the way cfrom CS->caller to the final (non-alias and 2887 1.1 mrg non-thunk) destination, the call passes through a thunk. */ 2888 1.1 mrg 2889 1.1 mrg static bool 2890 1.1 mrg call_passes_through_thunk (cgraph_edge *cs) 2891 1.1 mrg { 2892 1.1 mrg cgraph_node *alias_or_thunk = cs->callee; 2893 1.1 mrg while (alias_or_thunk->alias) 2894 1.1 mrg alias_or_thunk = alias_or_thunk->get_alias_target (); 2895 1.1 mrg return alias_or_thunk->thunk; 2896 1.1 mrg } 2897 1.1 mrg 2898 1.1 mrg /* Propagate constants from the caller to the callee of CS. INFO describes the 2899 1.1 mrg caller. */ 2900 1.1 mrg 2901 1.1 mrg static bool 2902 1.1 mrg propagate_constants_across_call (struct cgraph_edge *cs) 2903 1.1 mrg { 2904 1.1 mrg class ipa_node_params *callee_info; 2905 1.1 mrg enum availability availability; 2906 1.1 mrg cgraph_node *callee; 2907 1.1 mrg class ipa_edge_args *args; 2908 1.1 mrg bool ret = false; 2909 1.1 mrg int i, args_count, parms_count; 2910 1.1 mrg 2911 1.1 mrg callee = cs->callee->function_symbol (&availability); 2912 1.1 mrg if (!callee->definition) 2913 1.1 mrg return false; 2914 1.1 mrg gcc_checking_assert (callee->has_gimple_body_p ()); 2915 1.1 mrg callee_info = ipa_node_params_sum->get (callee); 2916 1.1 mrg if (!callee_info) 2917 1.1 mrg return false; 2918 1.1 mrg 2919 1.1 mrg args = ipa_edge_args_sum->get (cs); 2920 1.1 mrg parms_count = ipa_get_param_count (callee_info); 2921 1.1 mrg if (parms_count == 0) 2922 1.1 mrg return false; 2923 1.1 mrg if (!args 2924 1.1 mrg || !opt_for_fn (cs->caller->decl, flag_ipa_cp) 2925 1.1 mrg || !opt_for_fn (cs->caller->decl, optimize)) 2926 1.1 mrg { 2927 1.1 mrg for (i = 0; i < parms_count; i++) 2928 1.1 mrg ret |= set_all_contains_variable (ipa_get_parm_lattices (callee_info, 2929 1.1 mrg i)); 2930 1.1 mrg return ret; 2931 1.1 mrg } 2932 1.1 mrg args_count = ipa_get_cs_argument_count (args); 2933 1.1 mrg 2934 1.1 mrg /* If this call goes through a thunk we must not propagate to the first (0th) 2935 1.1 mrg parameter. However, we might need to uncover a thunk from below a series 2936 1.1 mrg of aliases first. */ 2937 1.1 mrg if (call_passes_through_thunk (cs)) 2938 1.1 mrg { 2939 1.1 mrg ret |= set_all_contains_variable (ipa_get_parm_lattices (callee_info, 2940 1.1 mrg 0)); 2941 1.1 mrg i = 1; 2942 1.1 mrg } 2943 1.1 mrg else 2944 1.1 mrg i = 0; 2945 1.1 mrg 2946 1.1 mrg for (; (i < args_count) && (i < parms_count); i++) 2947 1.1 mrg { 2948 1.1 mrg struct ipa_jump_func *jump_func = ipa_get_ith_jump_func (args, i); 2949 1.1 mrg class ipcp_param_lattices *dest_plats; 2950 1.1 mrg tree param_type = ipa_get_type (callee_info, i); 2951 1.1 mrg 2952 1.1 mrg dest_plats = ipa_get_parm_lattices (callee_info, i); 2953 1.1 mrg if (availability == AVAIL_INTERPOSABLE) 2954 1.1 mrg ret |= set_all_contains_variable (dest_plats); 2955 1.1 mrg else 2956 1.1 mrg { 2957 1.1 mrg ret |= propagate_scalar_across_jump_function (cs, jump_func, 2958 1.1 mrg &dest_plats->itself, 2959 1.1 mrg param_type); 2960 1.1 mrg ret |= propagate_context_across_jump_function (cs, jump_func, i, 2961 1.1 mrg &dest_plats->ctxlat); 2962 1.1 mrg ret 2963 1.1 mrg |= propagate_bits_across_jump_function (cs, i, jump_func, 2964 1.1 mrg &dest_plats->bits_lattice); 2965 1.1 mrg ret |= propagate_aggs_across_jump_function (cs, jump_func, 2966 1.1 mrg dest_plats); 2967 1.1 mrg if (opt_for_fn (callee->decl, flag_ipa_vrp)) 2968 1.1 mrg ret |= propagate_vr_across_jump_function (cs, jump_func, 2969 1.1 mrg dest_plats, param_type); 2970 1.1 mrg else 2971 1.1 mrg ret |= dest_plats->m_value_range.set_to_bottom (); 2972 1.1 mrg } 2973 1.1 mrg } 2974 1.1 mrg for (; i < parms_count; i++) 2975 1.1 mrg ret |= set_all_contains_variable (ipa_get_parm_lattices (callee_info, i)); 2976 1.1 mrg 2977 1.1 mrg return ret; 2978 1.1 mrg } 2979 1.1 mrg 2980 1.1 mrg /* If an indirect edge IE can be turned into a direct one based on KNOWN_VALS 2981 1.1 mrg KNOWN_CONTEXTS, KNOWN_AGGS or AGG_REPS return the destination. The latter 2982 1.1 mrg three can be NULL. If AGG_REPS is not NULL, KNOWN_AGGS is ignored. */ 2983 1.1 mrg 2984 1.1 mrg static tree 2985 1.1 mrg ipa_get_indirect_edge_target_1 (struct cgraph_edge *ie, 2986 1.1 mrg const vec<tree> &known_csts, 2987 1.1 mrg const vec<ipa_polymorphic_call_context> &known_contexts, 2988 1.1 mrg const vec<ipa_agg_value_set> &known_aggs, 2989 1.1 mrg struct ipa_agg_replacement_value *agg_reps, 2990 1.1 mrg bool *speculative) 2991 1.1 mrg { 2992 1.1 mrg int param_index = ie->indirect_info->param_index; 2993 1.1 mrg HOST_WIDE_INT anc_offset; 2994 1.1 mrg tree t = NULL; 2995 1.1 mrg tree target = NULL; 2996 1.1 mrg 2997 1.1 mrg *speculative = false; 2998 1.1 mrg 2999 1.1 mrg if (param_index == -1) 3000 1.1 mrg return NULL_TREE; 3001 1.1 mrg 3002 1.1 mrg if (!ie->indirect_info->polymorphic) 3003 1.1 mrg { 3004 1.1 mrg tree t = NULL; 3005 1.1 mrg 3006 1.1 mrg if (ie->indirect_info->agg_contents) 3007 1.1 mrg { 3008 1.1 mrg t = NULL; 3009 1.1 mrg if (agg_reps && ie->indirect_info->guaranteed_unmodified) 3010 1.1 mrg { 3011 1.1 mrg while (agg_reps) 3012 1.1 mrg { 3013 1.1 mrg if (agg_reps->index == param_index 3014 1.1 mrg && agg_reps->offset == ie->indirect_info->offset 3015 1.1 mrg && agg_reps->by_ref == ie->indirect_info->by_ref) 3016 1.1 mrg { 3017 1.1 mrg t = agg_reps->value; 3018 1.1 mrg break; 3019 1.1 mrg } 3020 1.1 mrg agg_reps = agg_reps->next; 3021 1.1 mrg } 3022 1.1 mrg } 3023 1.1 mrg if (!t) 3024 1.1 mrg { 3025 1.1 mrg const ipa_agg_value_set *agg; 3026 1.1 mrg if (known_aggs.length () > (unsigned int) param_index) 3027 1.1 mrg agg = &known_aggs[param_index]; 3028 1.1 mrg else 3029 1.1 mrg agg = NULL; 3030 1.1 mrg bool from_global_constant; 3031 1.1 mrg t = ipa_find_agg_cst_for_param (agg, 3032 1.1 mrg (unsigned) param_index 3033 1.1 mrg < known_csts.length () 3034 1.1 mrg ? known_csts[param_index] 3035 1.1 mrg : NULL, 3036 1.1 mrg ie->indirect_info->offset, 3037 1.1 mrg ie->indirect_info->by_ref, 3038 1.1 mrg &from_global_constant); 3039 1.1 mrg if (t 3040 1.1 mrg && !from_global_constant 3041 1.1 mrg && !ie->indirect_info->guaranteed_unmodified) 3042 1.1 mrg t = NULL_TREE; 3043 1.1 mrg } 3044 1.1 mrg } 3045 1.1 mrg else if ((unsigned) param_index < known_csts.length ()) 3046 1.1 mrg t = known_csts[param_index]; 3047 1.1 mrg 3048 1.1 mrg if (t 3049 1.1 mrg && TREE_CODE (t) == ADDR_EXPR 3050 1.1 mrg && TREE_CODE (TREE_OPERAND (t, 0)) == FUNCTION_DECL) 3051 1.1 mrg return TREE_OPERAND (t, 0); 3052 1.1 mrg else 3053 1.1 mrg return NULL_TREE; 3054 1.1 mrg } 3055 1.1 mrg 3056 1.1 mrg if (!opt_for_fn (ie->caller->decl, flag_devirtualize)) 3057 1.1 mrg return NULL_TREE; 3058 1.1 mrg 3059 1.1 mrg gcc_assert (!ie->indirect_info->agg_contents); 3060 1.1 mrg anc_offset = ie->indirect_info->offset; 3061 1.1 mrg 3062 1.1 mrg t = NULL; 3063 1.1 mrg 3064 1.1 mrg /* Try to work out value of virtual table pointer value in replacements. */ 3065 1.1 mrg if (!t && agg_reps && !ie->indirect_info->by_ref) 3066 1.1 mrg { 3067 1.1 mrg while (agg_reps) 3068 1.1 mrg { 3069 1.1 mrg if (agg_reps->index == param_index 3070 1.1 mrg && agg_reps->offset == ie->indirect_info->offset 3071 1.1 mrg && agg_reps->by_ref) 3072 1.1 mrg { 3073 1.1 mrg t = agg_reps->value; 3074 1.1 mrg break; 3075 1.1 mrg } 3076 1.1 mrg agg_reps = agg_reps->next; 3077 1.1 mrg } 3078 1.1 mrg } 3079 1.1 mrg 3080 1.1 mrg /* Try to work out value of virtual table pointer value in known 3081 1.1 mrg aggregate values. */ 3082 1.1 mrg if (!t && known_aggs.length () > (unsigned int) param_index 3083 1.1 mrg && !ie->indirect_info->by_ref) 3084 1.1 mrg { 3085 1.1 mrg const ipa_agg_value_set *agg = &known_aggs[param_index]; 3086 1.1 mrg t = ipa_find_agg_cst_for_param (agg, 3087 1.1 mrg (unsigned) param_index 3088 1.1 mrg < known_csts.length () 3089 1.1 mrg ? known_csts[param_index] : NULL, 3090 1.1 mrg ie->indirect_info->offset, true); 3091 1.1 mrg } 3092 1.1 mrg 3093 1.1 mrg /* If we found the virtual table pointer, lookup the target. */ 3094 1.1 mrg if (t) 3095 1.1 mrg { 3096 1.1 mrg tree vtable; 3097 1.1 mrg unsigned HOST_WIDE_INT offset; 3098 1.1 mrg if (vtable_pointer_value_to_vtable (t, &vtable, &offset)) 3099 1.1 mrg { 3100 1.1 mrg bool can_refer; 3101 1.1 mrg target = gimple_get_virt_method_for_vtable (ie->indirect_info->otr_token, 3102 1.1 mrg vtable, offset, &can_refer); 3103 1.1 mrg if (can_refer) 3104 1.1 mrg { 3105 1.1 mrg if (!target 3106 1.1 mrg || fndecl_built_in_p (target, BUILT_IN_UNREACHABLE) 3107 1.1 mrg || !possible_polymorphic_call_target_p 3108 1.1 mrg (ie, cgraph_node::get (target))) 3109 1.1 mrg { 3110 1.1 mrg /* Do not speculate builtin_unreachable, it is stupid! */ 3111 1.1 mrg if (ie->indirect_info->vptr_changed) 3112 1.1 mrg return NULL; 3113 1.1 mrg target = ipa_impossible_devirt_target (ie, target); 3114 1.1 mrg } 3115 1.1 mrg *speculative = ie->indirect_info->vptr_changed; 3116 1.1 mrg if (!*speculative) 3117 1.1 mrg return target; 3118 1.1 mrg } 3119 1.1 mrg } 3120 1.1 mrg } 3121 1.1 mrg 3122 1.1 mrg /* Do we know the constant value of pointer? */ 3123 1.1 mrg if (!t && (unsigned) param_index < known_csts.length ()) 3124 1.1 mrg t = known_csts[param_index]; 3125 1.1 mrg 3126 1.1 mrg gcc_checking_assert (!t || TREE_CODE (t) != TREE_BINFO); 3127 1.1 mrg 3128 1.1 mrg ipa_polymorphic_call_context context; 3129 1.1 mrg if (known_contexts.length () > (unsigned int) param_index) 3130 1.1 mrg { 3131 1.1 mrg context = known_contexts[param_index]; 3132 1.1 mrg context.offset_by (anc_offset); 3133 1.1 mrg if (ie->indirect_info->vptr_changed) 3134 1.1 mrg context.possible_dynamic_type_change (ie->in_polymorphic_cdtor, 3135 1.1 mrg ie->indirect_info->otr_type); 3136 1.1 mrg if (t) 3137 1.1 mrg { 3138 1.1 mrg ipa_polymorphic_call_context ctx2 = ipa_polymorphic_call_context 3139 1.1 mrg (t, ie->indirect_info->otr_type, anc_offset); 3140 1.1 mrg if (!ctx2.useless_p ()) 3141 1.1 mrg context.combine_with (ctx2, ie->indirect_info->otr_type); 3142 1.1 mrg } 3143 1.1 mrg } 3144 1.1 mrg else if (t) 3145 1.1 mrg { 3146 1.1 mrg context = ipa_polymorphic_call_context (t, ie->indirect_info->otr_type, 3147 1.1 mrg anc_offset); 3148 1.1 mrg if (ie->indirect_info->vptr_changed) 3149 1.1 mrg context.possible_dynamic_type_change (ie->in_polymorphic_cdtor, 3150 1.1 mrg ie->indirect_info->otr_type); 3151 1.1 mrg } 3152 1.1 mrg else 3153 1.1 mrg return NULL_TREE; 3154 1.1 mrg 3155 1.1 mrg vec <cgraph_node *>targets; 3156 1.1 mrg bool final; 3157 1.1 mrg 3158 1.1 mrg targets = possible_polymorphic_call_targets 3159 1.1 mrg (ie->indirect_info->otr_type, 3160 1.1 mrg ie->indirect_info->otr_token, 3161 1.1 mrg context, &final); 3162 1.1 mrg if (!final || targets.length () > 1) 3163 1.1 mrg { 3164 1.1 mrg struct cgraph_node *node; 3165 1.1 mrg if (*speculative) 3166 1.1 mrg return target; 3167 1.1 mrg if (!opt_for_fn (ie->caller->decl, flag_devirtualize_speculatively) 3168 1.1 mrg || ie->speculative || !ie->maybe_hot_p ()) 3169 1.1 mrg return NULL; 3170 1.1 mrg node = try_speculative_devirtualization (ie->indirect_info->otr_type, 3171 1.1 mrg ie->indirect_info->otr_token, 3172 1.1 mrg context); 3173 1.1 mrg if (node) 3174 1.1 mrg { 3175 1.1 mrg *speculative = true; 3176 1.1 mrg target = node->decl; 3177 1.1 mrg } 3178 1.1 mrg else 3179 1.1 mrg return NULL; 3180 1.1 mrg } 3181 1.1 mrg else 3182 1.1 mrg { 3183 1.1 mrg *speculative = false; 3184 1.1 mrg if (targets.length () == 1) 3185 1.1 mrg target = targets[0]->decl; 3186 1.1 mrg else 3187 1.1 mrg target = ipa_impossible_devirt_target (ie, NULL_TREE); 3188 1.1 mrg } 3189 1.1 mrg 3190 1.1 mrg if (target && !possible_polymorphic_call_target_p (ie, 3191 1.1 mrg cgraph_node::get (target))) 3192 1.1 mrg { 3193 1.1 mrg if (*speculative) 3194 1.1 mrg return NULL; 3195 1.1 mrg target = ipa_impossible_devirt_target (ie, target); 3196 1.1 mrg } 3197 1.1 mrg 3198 1.1 mrg return target; 3199 1.1 mrg } 3200 1.1 mrg 3201 1.1 mrg /* If an indirect edge IE can be turned into a direct one based on data in 3202 1.1 mrg AVALS, return the destination. Store into *SPECULATIVE a boolean determinig 3203 1.1 mrg whether the discovered target is only speculative guess. */ 3204 1.1 mrg 3205 1.1 mrg tree 3206 1.1 mrg ipa_get_indirect_edge_target (struct cgraph_edge *ie, 3207 1.1 mrg ipa_call_arg_values *avals, 3208 1.1 mrg bool *speculative) 3209 1.1 mrg { 3210 1.1 mrg return ipa_get_indirect_edge_target_1 (ie, avals->m_known_vals, 3211 1.1 mrg avals->m_known_contexts, 3212 1.1 mrg avals->m_known_aggs, 3213 1.1 mrg NULL, speculative); 3214 1.1 mrg } 3215 1.1 mrg 3216 1.1 mrg /* The same functionality as above overloaded for ipa_auto_call_arg_values. */ 3217 1.1 mrg 3218 1.1 mrg tree 3219 1.1 mrg ipa_get_indirect_edge_target (struct cgraph_edge *ie, 3220 1.1 mrg ipa_auto_call_arg_values *avals, 3221 1.1 mrg bool *speculative) 3222 1.1 mrg { 3223 1.1 mrg return ipa_get_indirect_edge_target_1 (ie, avals->m_known_vals, 3224 1.1 mrg avals->m_known_contexts, 3225 1.1 mrg avals->m_known_aggs, 3226 1.1 mrg NULL, speculative); 3227 1.1 mrg } 3228 1.1 mrg 3229 1.1 mrg /* Calculate devirtualization time bonus for NODE, assuming we know information 3230 1.1 mrg about arguments stored in AVALS. */ 3231 1.1 mrg 3232 1.1 mrg static int 3233 1.1 mrg devirtualization_time_bonus (struct cgraph_node *node, 3234 1.1 mrg ipa_auto_call_arg_values *avals) 3235 1.1 mrg { 3236 1.1 mrg struct cgraph_edge *ie; 3237 1.1 mrg int res = 0; 3238 1.1 mrg 3239 1.1 mrg for (ie = node->indirect_calls; ie; ie = ie->next_callee) 3240 1.1 mrg { 3241 1.1 mrg struct cgraph_node *callee; 3242 1.1 mrg class ipa_fn_summary *isummary; 3243 1.1 mrg enum availability avail; 3244 1.1 mrg tree target; 3245 1.1 mrg bool speculative; 3246 1.1 mrg 3247 1.1 mrg target = ipa_get_indirect_edge_target (ie, avals, &speculative); 3248 1.1 mrg if (!target) 3249 1.1 mrg continue; 3250 1.1 mrg 3251 1.1 mrg /* Only bare minimum benefit for clearly un-inlineable targets. */ 3252 1.1 mrg res += 1; 3253 1.1 mrg callee = cgraph_node::get (target); 3254 1.1 mrg if (!callee || !callee->definition) 3255 1.1 mrg continue; 3256 1.1 mrg callee = callee->function_symbol (&avail); 3257 1.1 mrg if (avail < AVAIL_AVAILABLE) 3258 1.1 mrg continue; 3259 1.1 mrg isummary = ipa_fn_summaries->get (callee); 3260 1.1 mrg if (!isummary || !isummary->inlinable) 3261 1.1 mrg continue; 3262 1.1 mrg 3263 1.1 mrg int size = ipa_size_summaries->get (callee)->size; 3264 1.1 mrg /* FIXME: The values below need re-considering and perhaps also 3265 1.1 mrg integrating into the cost metrics, at lest in some very basic way. */ 3266 1.1 mrg int max_inline_insns_auto 3267 1.1 mrg = opt_for_fn (callee->decl, param_max_inline_insns_auto); 3268 1.1 mrg if (size <= max_inline_insns_auto / 4) 3269 1.1 mrg res += 31 / ((int)speculative + 1); 3270 1.1 mrg else if (size <= max_inline_insns_auto / 2) 3271 1.1 mrg res += 15 / ((int)speculative + 1); 3272 1.1 mrg else if (size <= max_inline_insns_auto 3273 1.1 mrg || DECL_DECLARED_INLINE_P (callee->decl)) 3274 1.1 mrg res += 7 / ((int)speculative + 1); 3275 1.1 mrg } 3276 1.1 mrg 3277 1.1 mrg return res; 3278 1.1 mrg } 3279 1.1 mrg 3280 1.1 mrg /* Return time bonus incurred because of hints stored in ESTIMATES. */ 3281 1.1 mrg 3282 1.1 mrg static int 3283 1.1 mrg hint_time_bonus (cgraph_node *node, const ipa_call_estimates &estimates) 3284 1.1 mrg { 3285 1.1 mrg int result = 0; 3286 1.1 mrg ipa_hints hints = estimates.hints; 3287 1.1 mrg if (hints & (INLINE_HINT_loop_iterations | INLINE_HINT_loop_stride)) 3288 1.1 mrg result += opt_for_fn (node->decl, param_ipa_cp_loop_hint_bonus); 3289 1.1 mrg 3290 1.1 mrg sreal bonus_for_one = opt_for_fn (node->decl, param_ipa_cp_loop_hint_bonus); 3291 1.1 mrg 3292 1.1 mrg if (hints & INLINE_HINT_loop_iterations) 3293 1.1 mrg result += (estimates.loops_with_known_iterations * bonus_for_one).to_int (); 3294 1.1 mrg 3295 1.1 mrg if (hints & INLINE_HINT_loop_stride) 3296 1.1 mrg result += (estimates.loops_with_known_strides * bonus_for_one).to_int (); 3297 1.1 mrg 3298 1.1 mrg return result; 3299 1.1 mrg } 3300 1.1 mrg 3301 1.1 mrg /* If there is a reason to penalize the function described by INFO in the 3302 1.1 mrg cloning goodness evaluation, do so. */ 3303 1.1 mrg 3304 1.1 mrg static inline sreal 3305 1.1 mrg incorporate_penalties (cgraph_node *node, ipa_node_params *info, 3306 1.1 mrg sreal evaluation) 3307 1.1 mrg { 3308 1.1 mrg if (info->node_within_scc && !info->node_is_self_scc) 3309 1.1 mrg evaluation = (evaluation 3310 1.1 mrg * (100 - opt_for_fn (node->decl, 3311 1.1 mrg param_ipa_cp_recursion_penalty))) / 100; 3312 1.1 mrg 3313 1.1 mrg if (info->node_calling_single_call) 3314 1.1 mrg evaluation = (evaluation 3315 1.1 mrg * (100 - opt_for_fn (node->decl, 3316 1.1 mrg param_ipa_cp_single_call_penalty))) 3317 1.1 mrg / 100; 3318 1.1 mrg 3319 1.1 mrg return evaluation; 3320 1.1 mrg } 3321 1.1 mrg 3322 1.1 mrg /* Return true if cloning NODE is a good idea, given the estimated TIME_BENEFIT 3323 1.1 mrg and SIZE_COST and with the sum of frequencies of incoming edges to the 3324 1.1 mrg potential new clone in FREQUENCIES. */ 3325 1.1 mrg 3326 1.1 mrg static bool 3327 1.1 mrg good_cloning_opportunity_p (struct cgraph_node *node, sreal time_benefit, 3328 1.1 mrg sreal freq_sum, profile_count count_sum, 3329 1.1 mrg int size_cost) 3330 1.1 mrg { 3331 1.1 mrg if (time_benefit == 0 3332 1.1 mrg || !opt_for_fn (node->decl, flag_ipa_cp_clone) 3333 1.1 mrg || node->optimize_for_size_p ()) 3334 1.1 mrg return false; 3335 1.1 mrg 3336 1.1 mrg gcc_assert (size_cost > 0); 3337 1.1 mrg 3338 1.1 mrg ipa_node_params *info = ipa_node_params_sum->get (node); 3339 1.1 mrg int eval_threshold = opt_for_fn (node->decl, param_ipa_cp_eval_threshold); 3340 1.1 mrg if (count_sum > profile_count::zero ()) 3341 1.1 mrg { 3342 1.1 mrg gcc_assert (base_count > profile_count::zero ()); 3343 1.1 mrg sreal factor = count_sum.probability_in (base_count).to_sreal (); 3344 1.1 mrg sreal evaluation = (time_benefit * factor) / size_cost; 3345 1.1 mrg evaluation = incorporate_penalties (node, info, evaluation); 3346 1.1 mrg evaluation *= 1000; 3347 1.1 mrg 3348 1.1 mrg if (dump_file && (dump_flags & TDF_DETAILS)) 3349 1.1 mrg { 3350 1.1 mrg fprintf (dump_file, " good_cloning_opportunity_p (time: %g, " 3351 1.1 mrg "size: %i, count_sum: ", time_benefit.to_double (), 3352 1.1 mrg size_cost); 3353 1.1 mrg count_sum.dump (dump_file); 3354 1.1 mrg fprintf (dump_file, "%s%s) -> evaluation: %.2f, threshold: %i\n", 3355 1.1 mrg info->node_within_scc 3356 1.1 mrg ? (info->node_is_self_scc ? ", self_scc" : ", scc") : "", 3357 1.1 mrg info->node_calling_single_call ? ", single_call" : "", 3358 1.1 mrg evaluation.to_double (), eval_threshold); 3359 1.1 mrg } 3360 1.1 mrg 3361 1.1 mrg return evaluation.to_int () >= eval_threshold; 3362 1.1 mrg } 3363 1.1 mrg else 3364 1.1 mrg { 3365 1.1 mrg sreal evaluation = (time_benefit * freq_sum) / size_cost; 3366 1.1 mrg evaluation = incorporate_penalties (node, info, evaluation); 3367 1.1 mrg evaluation *= 1000; 3368 1.1 mrg 3369 1.1 mrg if (dump_file && (dump_flags & TDF_DETAILS)) 3370 1.1 mrg fprintf (dump_file, " good_cloning_opportunity_p (time: %g, " 3371 1.1 mrg "size: %i, freq_sum: %g%s%s) -> evaluation: %.2f, " 3372 1.1 mrg "threshold: %i\n", 3373 1.1 mrg time_benefit.to_double (), size_cost, freq_sum.to_double (), 3374 1.1 mrg info->node_within_scc 3375 1.1 mrg ? (info->node_is_self_scc ? ", self_scc" : ", scc") : "", 3376 1.1 mrg info->node_calling_single_call ? ", single_call" : "", 3377 1.1 mrg evaluation.to_double (), eval_threshold); 3378 1.1 mrg 3379 1.1 mrg return evaluation.to_int () >= eval_threshold; 3380 1.1 mrg } 3381 1.1 mrg } 3382 1.1 mrg 3383 1.1 mrg /* Return all context independent values from aggregate lattices in PLATS in a 3384 1.1 mrg vector. Return NULL if there are none. */ 3385 1.1 mrg 3386 1.1 mrg static vec<ipa_agg_value> 3387 1.1 mrg context_independent_aggregate_values (class ipcp_param_lattices *plats) 3388 1.1 mrg { 3389 1.1 mrg vec<ipa_agg_value> res = vNULL; 3390 1.1 mrg 3391 1.1 mrg if (plats->aggs_bottom 3392 1.1 mrg || plats->aggs_contain_variable 3393 1.1 mrg || plats->aggs_count == 0) 3394 1.1 mrg return vNULL; 3395 1.1 mrg 3396 1.1 mrg for (struct ipcp_agg_lattice *aglat = plats->aggs; 3397 1.1 mrg aglat; 3398 1.1 mrg aglat = aglat->next) 3399 1.1 mrg if (aglat->is_single_const ()) 3400 1.1 mrg { 3401 1.1 mrg struct ipa_agg_value item; 3402 1.1 mrg item.offset = aglat->offset; 3403 1.1 mrg item.value = aglat->values->value; 3404 1.1 mrg res.safe_push (item); 3405 1.1 mrg } 3406 1.1 mrg return res; 3407 1.1 mrg } 3408 1.1 mrg 3409 1.1 mrg /* Grow vectors in AVALS and fill them with information about values of 3410 1.1 mrg parameters that are known to be independent of the context. Only calculate 3411 1.1 mrg m_known_aggs if CALCULATE_AGGS is true. INFO describes the function. If 3412 1.1 mrg REMOVABLE_PARAMS_COST is non-NULL, the movement cost of all removable 3413 1.1 mrg parameters will be stored in it. 3414 1.1 mrg 3415 1.1 mrg TODO: Also grow context independent value range vectors. */ 3416 1.1 mrg 3417 1.1 mrg static bool 3418 1.1 mrg gather_context_independent_values (class ipa_node_params *info, 3419 1.1 mrg ipa_auto_call_arg_values *avals, 3420 1.1 mrg bool calculate_aggs, 3421 1.1 mrg int *removable_params_cost) 3422 1.1 mrg { 3423 1.1 mrg int i, count = ipa_get_param_count (info); 3424 1.1 mrg bool ret = false; 3425 1.1 mrg 3426 1.1 mrg avals->m_known_vals.safe_grow_cleared (count, true); 3427 1.1 mrg avals->m_known_contexts.safe_grow_cleared (count, true); 3428 1.1 mrg if (calculate_aggs) 3429 1.1 mrg avals->m_known_aggs.safe_grow_cleared (count, true); 3430 1.1 mrg 3431 1.1 mrg if (removable_params_cost) 3432 1.1 mrg *removable_params_cost = 0; 3433 1.1 mrg 3434 1.1 mrg for (i = 0; i < count; i++) 3435 1.1 mrg { 3436 1.1 mrg class ipcp_param_lattices *plats = ipa_get_parm_lattices (info, i); 3437 1.1 mrg ipcp_lattice<tree> *lat = &plats->itself; 3438 1.1 mrg 3439 1.1 mrg if (lat->is_single_const ()) 3440 1.1 mrg { 3441 1.1 mrg ipcp_value<tree> *val = lat->values; 3442 1.1 mrg gcc_checking_assert (TREE_CODE (val->value) != TREE_BINFO); 3443 1.1 mrg avals->m_known_vals[i] = val->value; 3444 1.1 mrg if (removable_params_cost) 3445 1.1 mrg *removable_params_cost 3446 1.1 mrg += estimate_move_cost (TREE_TYPE (val->value), false); 3447 1.1 mrg ret = true; 3448 1.1 mrg } 3449 1.1 mrg else if (removable_params_cost 3450 1.1 mrg && !ipa_is_param_used (info, i)) 3451 1.1 mrg *removable_params_cost 3452 1.1 mrg += ipa_get_param_move_cost (info, i); 3453 1.1 mrg 3454 1.1 mrg if (!ipa_is_param_used (info, i)) 3455 1.1 mrg continue; 3456 1.1 mrg 3457 1.1 mrg ipcp_lattice<ipa_polymorphic_call_context> *ctxlat = &plats->ctxlat; 3458 1.1 mrg /* Do not account known context as reason for cloning. We can see 3459 1.1 mrg if it permits devirtualization. */ 3460 1.1 mrg if (ctxlat->is_single_const ()) 3461 1.1 mrg avals->m_known_contexts[i] = ctxlat->values->value; 3462 1.1 mrg 3463 1.1 mrg if (calculate_aggs) 3464 1.1 mrg { 3465 1.1 mrg vec<ipa_agg_value> agg_items; 3466 1.1 mrg struct ipa_agg_value_set *agg; 3467 1.1 mrg 3468 1.1 mrg agg_items = context_independent_aggregate_values (plats); 3469 1.1 mrg agg = &avals->m_known_aggs[i]; 3470 1.1 mrg agg->items = agg_items; 3471 1.1 mrg agg->by_ref = plats->aggs_by_ref; 3472 1.1 mrg ret |= !agg_items.is_empty (); 3473 1.1 mrg } 3474 1.1 mrg } 3475 1.1 mrg 3476 1.1 mrg return ret; 3477 1.1 mrg } 3478 1.1 mrg 3479 1.1 mrg /* Perform time and size measurement of NODE with the context given in AVALS, 3480 1.1 mrg calculate the benefit compared to the node without specialization and store 3481 1.1 mrg it into VAL. Take into account REMOVABLE_PARAMS_COST of all 3482 1.1 mrg context-independent or unused removable parameters and EST_MOVE_COST, the 3483 1.1 mrg estimated movement of the considered parameter. */ 3484 1.1 mrg 3485 1.1 mrg static void 3486 1.1 mrg perform_estimation_of_a_value (cgraph_node *node, 3487 1.1 mrg ipa_auto_call_arg_values *avals, 3488 1.1 mrg int removable_params_cost, int est_move_cost, 3489 1.1 mrg ipcp_value_base *val) 3490 1.1 mrg { 3491 1.1 mrg sreal time_benefit; 3492 1.1 mrg ipa_call_estimates estimates; 3493 1.1 mrg 3494 1.1 mrg estimate_ipcp_clone_size_and_time (node, avals, &estimates); 3495 1.1 mrg 3496 1.1 mrg /* Extern inline functions have no cloning local time benefits because they 3497 1.1 mrg will be inlined anyway. The only reason to clone them is if it enables 3498 1.1 mrg optimization in any of the functions they call. */ 3499 1.1 mrg if (DECL_EXTERNAL (node->decl) && DECL_DECLARED_INLINE_P (node->decl)) 3500 1.1 mrg time_benefit = 0; 3501 1.1 mrg else 3502 1.1 mrg time_benefit = (estimates.nonspecialized_time - estimates.time) 3503 1.1 mrg + (devirtualization_time_bonus (node, avals) 3504 1.1 mrg + hint_time_bonus (node, estimates) 3505 1.1 mrg + removable_params_cost + est_move_cost); 3506 1.1 mrg 3507 1.1 mrg int size = estimates.size; 3508 1.1 mrg gcc_checking_assert (size >=0); 3509 1.1 mrg /* The inliner-heuristics based estimates may think that in certain 3510 1.1 mrg contexts some functions do not have any size at all but we want 3511 1.1 mrg all specializations to have at least a tiny cost, not least not to 3512 1.1 mrg divide by zero. */ 3513 1.1 mrg if (size == 0) 3514 1.1 mrg size = 1; 3515 1.1 mrg 3516 1.1 mrg val->local_time_benefit = time_benefit; 3517 1.1 mrg val->local_size_cost = size; 3518 1.1 mrg } 3519 1.1 mrg 3520 1.1 mrg /* Get the overall limit oof growth based on parameters extracted from growth. 3521 1.1 mrg it does not really make sense to mix functions with different overall growth 3522 1.1 mrg limits but it is possible and if it happens, we do not want to select one 3523 1.1 mrg limit at random. */ 3524 1.1 mrg 3525 1.1 mrg static long 3526 1.1 mrg get_max_overall_size (cgraph_node *node) 3527 1.1 mrg { 3528 1.1 mrg long max_new_size = orig_overall_size; 3529 1.1 mrg long large_unit = opt_for_fn (node->decl, param_ipa_cp_large_unit_insns); 3530 1.1 mrg if (max_new_size < large_unit) 3531 1.1 mrg max_new_size = large_unit; 3532 1.1 mrg int unit_growth = opt_for_fn (node->decl, param_ipa_cp_unit_growth); 3533 1.1 mrg max_new_size += max_new_size * unit_growth / 100 + 1; 3534 1.1 mrg return max_new_size; 3535 1.1 mrg } 3536 1.1 mrg 3537 1.1 mrg /* Iterate over known values of parameters of NODE and estimate the local 3538 1.1 mrg effects in terms of time and size they have. */ 3539 1.1 mrg 3540 1.1 mrg static void 3541 1.1 mrg estimate_local_effects (struct cgraph_node *node) 3542 1.1 mrg { 3543 1.1 mrg ipa_node_params *info = ipa_node_params_sum->get (node); 3544 1.1 mrg int i, count = ipa_get_param_count (info); 3545 1.1 mrg bool always_const; 3546 1.1 mrg int removable_params_cost; 3547 1.1 mrg 3548 1.1 mrg if (!count || !ipcp_versionable_function_p (node)) 3549 1.1 mrg return; 3550 1.1 mrg 3551 1.1 mrg if (dump_file && (dump_flags & TDF_DETAILS)) 3552 1.1 mrg fprintf (dump_file, "\nEstimating effects for %s.\n", node->dump_name ()); 3553 1.1 mrg 3554 1.1 mrg ipa_auto_call_arg_values avals; 3555 1.1 mrg always_const = gather_context_independent_values (info, &avals, true, 3556 1.1 mrg &removable_params_cost); 3557 1.1 mrg int devirt_bonus = devirtualization_time_bonus (node, &avals); 3558 1.1 mrg if (always_const || devirt_bonus 3559 1.1 mrg || (removable_params_cost && node->can_change_signature)) 3560 1.1 mrg { 3561 1.1 mrg struct caller_statistics stats; 3562 1.1 mrg ipa_call_estimates estimates; 3563 1.1 mrg 3564 1.1 mrg init_caller_stats (&stats); 3565 1.1 mrg node->call_for_symbol_thunks_and_aliases (gather_caller_stats, &stats, 3566 1.1 mrg false); 3567 1.1 mrg estimate_ipcp_clone_size_and_time (node, &avals, &estimates); 3568 1.1 mrg sreal time = estimates.nonspecialized_time - estimates.time; 3569 1.1 mrg time += devirt_bonus; 3570 1.1 mrg time += hint_time_bonus (node, estimates); 3571 1.1 mrg time += removable_params_cost; 3572 1.1 mrg int size = estimates.size - stats.n_calls * removable_params_cost; 3573 1.1 mrg 3574 1.1 mrg if (dump_file) 3575 1.1 mrg fprintf (dump_file, " - context independent values, size: %i, " 3576 1.1 mrg "time_benefit: %f\n", size, (time).to_double ()); 3577 1.1 mrg 3578 1.1 mrg if (size <= 0 || node->local) 3579 1.1 mrg { 3580 1.1 mrg info->do_clone_for_all_contexts = true; 3581 1.1 mrg 3582 1.1 mrg if (dump_file) 3583 1.1 mrg fprintf (dump_file, " Decided to specialize for all " 3584 1.1 mrg "known contexts, code not going to grow.\n"); 3585 1.1 mrg } 3586 1.1 mrg else if (good_cloning_opportunity_p (node, time, stats.freq_sum, 3587 1.1 mrg stats.count_sum, size)) 3588 1.1 mrg { 3589 1.1 mrg if (size + overall_size <= get_max_overall_size (node)) 3590 1.1 mrg { 3591 1.1 mrg info->do_clone_for_all_contexts = true; 3592 1.1 mrg overall_size += size; 3593 1.1 mrg 3594 1.1 mrg if (dump_file) 3595 1.1 mrg fprintf (dump_file, " Decided to specialize for all " 3596 1.1 mrg "known contexts, growth (to %li) deemed " 3597 1.1 mrg "beneficial.\n", overall_size); 3598 1.1 mrg } 3599 1.1 mrg else if (dump_file && (dump_flags & TDF_DETAILS)) 3600 1.1 mrg fprintf (dump_file, " Not cloning for all contexts because " 3601 1.1 mrg "maximum unit size would be reached with %li.\n", 3602 1.1 mrg size + overall_size); 3603 1.1 mrg } 3604 1.1 mrg else if (dump_file && (dump_flags & TDF_DETAILS)) 3605 1.1 mrg fprintf (dump_file, " Not cloning for all contexts because " 3606 1.1 mrg "!good_cloning_opportunity_p.\n"); 3607 1.1 mrg 3608 1.1 mrg } 3609 1.1 mrg 3610 1.1 mrg for (i = 0; i < count; i++) 3611 1.1 mrg { 3612 1.1 mrg class ipcp_param_lattices *plats = ipa_get_parm_lattices (info, i); 3613 1.1 mrg ipcp_lattice<tree> *lat = &plats->itself; 3614 1.1 mrg ipcp_value<tree> *val; 3615 1.1 mrg 3616 1.1 mrg if (lat->bottom 3617 1.1 mrg || !lat->values 3618 1.1 mrg || avals.m_known_vals[i]) 3619 1.1 mrg continue; 3620 1.1 mrg 3621 1.1 mrg for (val = lat->values; val; val = val->next) 3622 1.1 mrg { 3623 1.1 mrg gcc_checking_assert (TREE_CODE (val->value) != TREE_BINFO); 3624 1.1 mrg avals.m_known_vals[i] = val->value; 3625 1.1 mrg 3626 1.1 mrg int emc = estimate_move_cost (TREE_TYPE (val->value), true); 3627 1.1 mrg perform_estimation_of_a_value (node, &avals, removable_params_cost, 3628 1.1 mrg emc, val); 3629 1.1 mrg 3630 1.1 mrg if (dump_file && (dump_flags & TDF_DETAILS)) 3631 1.1 mrg { 3632 1.1 mrg fprintf (dump_file, " - estimates for value "); 3633 1.1 mrg print_ipcp_constant_value (dump_file, val->value); 3634 1.1 mrg fprintf (dump_file, " for "); 3635 1.1 mrg ipa_dump_param (dump_file, info, i); 3636 1.1 mrg fprintf (dump_file, ": time_benefit: %g, size: %i\n", 3637 1.1 mrg val->local_time_benefit.to_double (), 3638 1.1 mrg val->local_size_cost); 3639 1.1 mrg } 3640 1.1 mrg } 3641 1.1 mrg avals.m_known_vals[i] = NULL_TREE; 3642 1.1 mrg } 3643 1.1 mrg 3644 1.1 mrg for (i = 0; i < count; i++) 3645 1.1 mrg { 3646 1.1 mrg class ipcp_param_lattices *plats = ipa_get_parm_lattices (info, i); 3647 1.1 mrg 3648 1.1 mrg if (!plats->virt_call) 3649 1.1 mrg continue; 3650 1.1 mrg 3651 1.1 mrg ipcp_lattice<ipa_polymorphic_call_context> *ctxlat = &plats->ctxlat; 3652 1.1 mrg ipcp_value<ipa_polymorphic_call_context> *val; 3653 1.1 mrg 3654 1.1 mrg if (ctxlat->bottom 3655 1.1 mrg || !ctxlat->values 3656 1.1 mrg || !avals.m_known_contexts[i].useless_p ()) 3657 1.1 mrg continue; 3658 1.1 mrg 3659 1.1 mrg for (val = ctxlat->values; val; val = val->next) 3660 1.1 mrg { 3661 1.1 mrg avals.m_known_contexts[i] = val->value; 3662 1.1 mrg perform_estimation_of_a_value (node, &avals, removable_params_cost, 3663 1.1 mrg 0, val); 3664 1.1 mrg 3665 1.1 mrg if (dump_file && (dump_flags & TDF_DETAILS)) 3666 1.1 mrg { 3667 1.1 mrg fprintf (dump_file, " - estimates for polymorphic context "); 3668 1.1 mrg print_ipcp_constant_value (dump_file, val->value); 3669 1.1 mrg fprintf (dump_file, " for "); 3670 1.1 mrg ipa_dump_param (dump_file, info, i); 3671 1.1 mrg fprintf (dump_file, ": time_benefit: %g, size: %i\n", 3672 1.1 mrg val->local_time_benefit.to_double (), 3673 1.1 mrg val->local_size_cost); 3674 1.1 mrg } 3675 1.1 mrg } 3676 1.1 mrg avals.m_known_contexts[i] = ipa_polymorphic_call_context (); 3677 1.1 mrg } 3678 1.1 mrg 3679 1.1 mrg for (i = 0; i < count; i++) 3680 1.1 mrg { 3681 1.1 mrg class ipcp_param_lattices *plats = ipa_get_parm_lattices (info, i); 3682 1.1 mrg 3683 1.1 mrg if (plats->aggs_bottom || !plats->aggs) 3684 1.1 mrg continue; 3685 1.1 mrg 3686 1.1 mrg ipa_agg_value_set *agg = &avals.m_known_aggs[i]; 3687 1.1 mrg for (ipcp_agg_lattice *aglat = plats->aggs; aglat; aglat = aglat->next) 3688 1.1 mrg { 3689 1.1 mrg ipcp_value<tree> *val; 3690 1.1 mrg if (aglat->bottom || !aglat->values 3691 1.1 mrg /* If the following is true, the one value is in known_aggs. */ 3692 1.1 mrg || (!plats->aggs_contain_variable 3693 1.1 mrg && aglat->is_single_const ())) 3694 1.1 mrg continue; 3695 1.1 mrg 3696 1.1 mrg for (val = aglat->values; val; val = val->next) 3697 1.1 mrg { 3698 1.1 mrg struct ipa_agg_value item; 3699 1.1 mrg 3700 1.1 mrg item.offset = aglat->offset; 3701 1.1 mrg item.value = val->value; 3702 1.1 mrg agg->items.safe_push (item); 3703 1.1 mrg 3704 1.1 mrg perform_estimation_of_a_value (node, &avals, 3705 1.1 mrg removable_params_cost, 0, val); 3706 1.1 mrg 3707 1.1 mrg if (dump_file && (dump_flags & TDF_DETAILS)) 3708 1.1 mrg { 3709 1.1 mrg fprintf (dump_file, " - estimates for value "); 3710 1.1 mrg print_ipcp_constant_value (dump_file, val->value); 3711 1.1 mrg fprintf (dump_file, " for "); 3712 1.1 mrg ipa_dump_param (dump_file, info, i); 3713 1.1 mrg fprintf (dump_file, "[%soffset: " HOST_WIDE_INT_PRINT_DEC 3714 1.1 mrg "]: time_benefit: %g, size: %i\n", 3715 1.1 mrg plats->aggs_by_ref ? "ref " : "", 3716 1.1 mrg aglat->offset, 3717 1.1 mrg val->local_time_benefit.to_double (), 3718 1.1 mrg val->local_size_cost); 3719 1.1 mrg } 3720 1.1 mrg 3721 1.1 mrg agg->items.pop (); 3722 1.1 mrg } 3723 1.1 mrg } 3724 1.1 mrg } 3725 1.1 mrg } 3726 1.1 mrg 3727 1.1 mrg 3728 1.1 mrg /* Add value CUR_VAL and all yet-unsorted values it is dependent on to the 3729 1.1 mrg topological sort of values. */ 3730 1.1 mrg 3731 1.1 mrg template <typename valtype> 3732 1.1 mrg void 3733 1.1 mrg value_topo_info<valtype>::add_val (ipcp_value<valtype> *cur_val) 3734 1.1 mrg { 3735 1.1 mrg ipcp_value_source<valtype> *src; 3736 1.1 mrg 3737 1.1 mrg if (cur_val->dfs) 3738 1.1 mrg return; 3739 1.1 mrg 3740 1.1 mrg dfs_counter++; 3741 1.1 mrg cur_val->dfs = dfs_counter; 3742 1.1 mrg cur_val->low_link = dfs_counter; 3743 1.1 mrg 3744 1.1 mrg cur_val->topo_next = stack; 3745 1.1 mrg stack = cur_val; 3746 1.1 mrg cur_val->on_stack = true; 3747 1.1 mrg 3748 1.1 mrg for (src = cur_val->sources; src; src = src->next) 3749 1.1 mrg if (src->val) 3750 1.1 mrg { 3751 1.1 mrg if (src->val->dfs == 0) 3752 1.1 mrg { 3753 1.1 mrg add_val (src->val); 3754 1.1 mrg if (src->val->low_link < cur_val->low_link) 3755 1.1 mrg cur_val->low_link = src->val->low_link; 3756 1.1 mrg } 3757 1.1 mrg else if (src->val->on_stack 3758 1.1 mrg && src->val->dfs < cur_val->low_link) 3759 1.1 mrg cur_val->low_link = src->val->dfs; 3760 1.1 mrg } 3761 1.1 mrg 3762 1.1 mrg if (cur_val->dfs == cur_val->low_link) 3763 1.1 mrg { 3764 1.1 mrg ipcp_value<valtype> *v, *scc_list = NULL; 3765 1.1 mrg 3766 1.1 mrg do 3767 1.1 mrg { 3768 1.1 mrg v = stack; 3769 1.1 mrg stack = v->topo_next; 3770 1.1 mrg v->on_stack = false; 3771 1.1 mrg v->scc_no = cur_val->dfs; 3772 1.1 mrg 3773 1.1 mrg v->scc_next = scc_list; 3774 1.1 mrg scc_list = v; 3775 1.1 mrg } 3776 1.1 mrg while (v != cur_val); 3777 1.1 mrg 3778 1.1 mrg cur_val->topo_next = values_topo; 3779 1.1 mrg values_topo = cur_val; 3780 1.1 mrg } 3781 1.1 mrg } 3782 1.1 mrg 3783 1.1 mrg /* Add all values in lattices associated with NODE to the topological sort if 3784 1.1 mrg they are not there yet. */ 3785 1.1 mrg 3786 1.1 mrg static void 3787 1.1 mrg add_all_node_vals_to_toposort (cgraph_node *node, ipa_topo_info *topo) 3788 1.1 mrg { 3789 1.1 mrg ipa_node_params *info = ipa_node_params_sum->get (node); 3790 1.1 mrg int i, count = ipa_get_param_count (info); 3791 1.1 mrg 3792 1.1 mrg for (i = 0; i < count; i++) 3793 1.1 mrg { 3794 1.1 mrg class ipcp_param_lattices *plats = ipa_get_parm_lattices (info, i); 3795 1.1 mrg ipcp_lattice<tree> *lat = &plats->itself; 3796 1.1 mrg struct ipcp_agg_lattice *aglat; 3797 1.1 mrg 3798 1.1 mrg if (!lat->bottom) 3799 1.1 mrg { 3800 1.1 mrg ipcp_value<tree> *val; 3801 1.1 mrg for (val = lat->values; val; val = val->next) 3802 1.1 mrg topo->constants.add_val (val); 3803 1.1 mrg } 3804 1.1 mrg 3805 1.1 mrg if (!plats->aggs_bottom) 3806 1.1 mrg for (aglat = plats->aggs; aglat; aglat = aglat->next) 3807 1.1 mrg if (!aglat->bottom) 3808 1.1 mrg { 3809 1.1 mrg ipcp_value<tree> *val; 3810 1.1 mrg for (val = aglat->values; val; val = val->next) 3811 1.1 mrg topo->constants.add_val (val); 3812 1.1 mrg } 3813 1.1 mrg 3814 1.1 mrg ipcp_lattice<ipa_polymorphic_call_context> *ctxlat = &plats->ctxlat; 3815 1.1 mrg if (!ctxlat->bottom) 3816 1.1 mrg { 3817 1.1 mrg ipcp_value<ipa_polymorphic_call_context> *ctxval; 3818 1.1 mrg for (ctxval = ctxlat->values; ctxval; ctxval = ctxval->next) 3819 1.1 mrg topo->contexts.add_val (ctxval); 3820 1.1 mrg } 3821 1.1 mrg } 3822 1.1 mrg } 3823 1.1 mrg 3824 1.1 mrg /* One pass of constants propagation along the call graph edges, from callers 3825 1.1 mrg to callees (requires topological ordering in TOPO), iterate over strongly 3826 1.1 mrg connected components. */ 3827 1.1 mrg 3828 1.1 mrg static void 3829 1.1 mrg propagate_constants_topo (class ipa_topo_info *topo) 3830 1.1 mrg { 3831 1.1 mrg int i; 3832 1.1 mrg 3833 1.1 mrg for (i = topo->nnodes - 1; i >= 0; i--) 3834 1.1 mrg { 3835 1.1 mrg unsigned j; 3836 1.1 mrg struct cgraph_node *v, *node = topo->order[i]; 3837 1.1 mrg vec<cgraph_node *> cycle_nodes = ipa_get_nodes_in_cycle (node); 3838 1.1 mrg 3839 1.1 mrg /* First, iteratively propagate within the strongly connected component 3840 1.1 mrg until all lattices stabilize. */ 3841 1.1 mrg FOR_EACH_VEC_ELT (cycle_nodes, j, v) 3842 1.1 mrg if (v->has_gimple_body_p ()) 3843 1.1 mrg { 3844 1.1 mrg if (opt_for_fn (v->decl, flag_ipa_cp) 3845 1.1 mrg && opt_for_fn (v->decl, optimize)) 3846 1.1 mrg push_node_to_stack (topo, v); 3847 1.1 mrg /* When V is not optimized, we can not push it to stack, but 3848 1.1 mrg still we need to set all its callees lattices to bottom. */ 3849 1.1 mrg else 3850 1.1 mrg { 3851 1.1 mrg for (cgraph_edge *cs = v->callees; cs; cs = cs->next_callee) 3852 1.1 mrg propagate_constants_across_call (cs); 3853 1.1 mrg } 3854 1.1 mrg } 3855 1.1 mrg 3856 1.1 mrg v = pop_node_from_stack (topo); 3857 1.1 mrg while (v) 3858 1.1 mrg { 3859 1.1 mrg struct cgraph_edge *cs; 3860 1.1 mrg class ipa_node_params *info = NULL; 3861 1.1 mrg bool self_scc = true; 3862 1.1 mrg 3863 1.1 mrg for (cs = v->callees; cs; cs = cs->next_callee) 3864 1.1 mrg if (ipa_edge_within_scc (cs)) 3865 1.1 mrg { 3866 1.1 mrg cgraph_node *callee = cs->callee->function_symbol (); 3867 1.1 mrg 3868 1.1 mrg if (v != callee) 3869 1.1 mrg self_scc = false; 3870 1.1 mrg 3871 1.1 mrg if (!info) 3872 1.1 mrg { 3873 1.1 mrg info = ipa_node_params_sum->get (v); 3874 1.1 mrg info->node_within_scc = true; 3875 1.1 mrg } 3876 1.1 mrg 3877 1.1 mrg if (propagate_constants_across_call (cs)) 3878 1.1 mrg push_node_to_stack (topo, callee); 3879 1.1 mrg } 3880 1.1 mrg 3881 1.1 mrg if (info) 3882 1.1 mrg info->node_is_self_scc = self_scc; 3883 1.1 mrg 3884 1.1 mrg v = pop_node_from_stack (topo); 3885 1.1 mrg } 3886 1.1 mrg 3887 1.1 mrg /* Afterwards, propagate along edges leading out of the SCC, calculates 3888 1.1 mrg the local effects of the discovered constants and all valid values to 3889 1.1 mrg their topological sort. */ 3890 1.1 mrg FOR_EACH_VEC_ELT (cycle_nodes, j, v) 3891 1.1 mrg if (v->has_gimple_body_p () 3892 1.1 mrg && opt_for_fn (v->decl, flag_ipa_cp) 3893 1.1 mrg && opt_for_fn (v->decl, optimize)) 3894 1.1 mrg { 3895 1.1 mrg struct cgraph_edge *cs; 3896 1.1 mrg 3897 1.1 mrg estimate_local_effects (v); 3898 1.1 mrg add_all_node_vals_to_toposort (v, topo); 3899 1.1 mrg for (cs = v->callees; cs; cs = cs->next_callee) 3900 1.1 mrg if (!ipa_edge_within_scc (cs)) 3901 1.1 mrg propagate_constants_across_call (cs); 3902 1.1 mrg } 3903 1.1 mrg cycle_nodes.release (); 3904 1.1 mrg } 3905 1.1 mrg } 3906 1.1 mrg 3907 1.1 mrg /* Propagate the estimated effects of individual values along the topological 3908 1.1 mrg from the dependent values to those they depend on. */ 3909 1.1 mrg 3910 1.1 mrg template <typename valtype> 3911 1.1 mrg void 3912 1.1 mrg value_topo_info<valtype>::propagate_effects () 3913 1.1 mrg { 3914 1.1 mrg ipcp_value<valtype> *base; 3915 1.1 mrg hash_set<ipcp_value<valtype> *> processed_srcvals; 3916 1.1 mrg 3917 1.1 mrg for (base = values_topo; base; base = base->topo_next) 3918 1.1 mrg { 3919 1.1 mrg ipcp_value_source<valtype> *src; 3920 1.1 mrg ipcp_value<valtype> *val; 3921 1.1 mrg sreal time = 0; 3922 1.1 mrg HOST_WIDE_INT size = 0; 3923 1.1 mrg 3924 1.1 mrg for (val = base; val; val = val->scc_next) 3925 1.1 mrg { 3926 1.1 mrg time = time + val->local_time_benefit + val->prop_time_benefit; 3927 1.1 mrg size = size + val->local_size_cost + val->prop_size_cost; 3928 1.1 mrg } 3929 1.1 mrg 3930 1.1 mrg for (val = base; val; val = val->scc_next) 3931 1.1 mrg { 3932 1.1 mrg processed_srcvals.empty (); 3933 1.1 mrg for (src = val->sources; src; src = src->next) 3934 1.1 mrg if (src->val 3935 1.1 mrg && src->cs->maybe_hot_p ()) 3936 1.1 mrg { 3937 1.1 mrg if (!processed_srcvals.add (src->val)) 3938 1.1 mrg { 3939 1.1 mrg HOST_WIDE_INT prop_size = size + src->val->prop_size_cost; 3940 1.1 mrg if (prop_size < INT_MAX) 3941 1.1 mrg src->val->prop_size_cost = prop_size; 3942 1.1 mrg else 3943 1.1 mrg continue; 3944 1.1 mrg } 3945 1.1 mrg 3946 1.1 mrg int special_factor = 1; 3947 1.1 mrg if (val->same_scc (src->val)) 3948 1.1 mrg special_factor 3949 1.1 mrg = opt_for_fn(src->cs->caller->decl, 3950 1.1 mrg param_ipa_cp_recursive_freq_factor); 3951 1.1 mrg else if (val->self_recursion_generated_p () 3952 1.1 mrg && (src->cs->callee->function_symbol () 3953 1.1 mrg == src->cs->caller)) 3954 1.1 mrg { 3955 1.1 mrg int max_recur_gen_depth 3956 1.1 mrg = opt_for_fn(src->cs->caller->decl, 3957 1.1 mrg param_ipa_cp_max_recursive_depth); 3958 1.1 mrg special_factor = max_recur_gen_depth 3959 1.1 mrg - val->self_recursion_generated_level + 1; 3960 1.1 mrg } 3961 1.1 mrg 3962 1.1 mrg src->val->prop_time_benefit 3963 1.1 mrg += time * special_factor * src->cs->sreal_frequency (); 3964 1.1 mrg } 3965 1.1 mrg 3966 1.1 mrg if (size < INT_MAX) 3967 1.1 mrg { 3968 1.1 mrg val->prop_time_benefit = time; 3969 1.1 mrg val->prop_size_cost = size; 3970 1.1 mrg } 3971 1.1 mrg else 3972 1.1 mrg { 3973 1.1 mrg val->prop_time_benefit = 0; 3974 1.1 mrg val->prop_size_cost = 0; 3975 1.1 mrg } 3976 1.1 mrg } 3977 1.1 mrg } 3978 1.1 mrg } 3979 1.1 mrg 3980 1.1 mrg /* Callback for qsort to sort counts of all edges. */ 3981 1.1 mrg 3982 1.1 mrg static int 3983 1.1 mrg compare_edge_profile_counts (const void *a, const void *b) 3984 1.1 mrg { 3985 1.1 mrg const profile_count *cnt1 = (const profile_count *) a; 3986 1.1 mrg const profile_count *cnt2 = (const profile_count *) b; 3987 1.1 mrg 3988 1.1 mrg if (*cnt1 < *cnt2) 3989 1.1 mrg return 1; 3990 1.1 mrg if (*cnt1 > *cnt2) 3991 1.1 mrg return -1; 3992 1.1 mrg return 0; 3993 1.1 mrg } 3994 1.1 mrg 3995 1.1 mrg 3996 1.1 mrg /* Propagate constants, polymorphic contexts and their effects from the 3997 1.1 mrg summaries interprocedurally. */ 3998 1.1 mrg 3999 1.1 mrg static void 4000 1.1 mrg ipcp_propagate_stage (class ipa_topo_info *topo) 4001 1.1 mrg { 4002 1.1 mrg struct cgraph_node *node; 4003 1.1 mrg 4004 1.1 mrg if (dump_file) 4005 1.1 mrg fprintf (dump_file, "\n Propagating constants:\n\n"); 4006 1.1 mrg 4007 1.1 mrg base_count = profile_count::uninitialized (); 4008 1.1 mrg 4009 1.1 mrg bool compute_count_base = false; 4010 1.1 mrg unsigned base_count_pos_percent = 0; 4011 1.1 mrg FOR_EACH_DEFINED_FUNCTION (node) 4012 1.1 mrg { 4013 1.1 mrg if (node->has_gimple_body_p () 4014 1.1 mrg && opt_for_fn (node->decl, flag_ipa_cp) 4015 1.1 mrg && opt_for_fn (node->decl, optimize)) 4016 1.1 mrg { 4017 1.1 mrg ipa_node_params *info = ipa_node_params_sum->get (node); 4018 1.1 mrg determine_versionability (node, info); 4019 1.1 mrg 4020 1.1 mrg unsigned nlattices = ipa_get_param_count (info); 4021 1.1 mrg void *chunk = XCNEWVEC (class ipcp_param_lattices, nlattices); 4022 1.1 mrg info->lattices = new (chunk) ipcp_param_lattices[nlattices]; 4023 1.1 mrg initialize_node_lattices (node); 4024 1.1 mrg } 4025 1.1 mrg ipa_size_summary *s = ipa_size_summaries->get (node); 4026 1.1 mrg if (node->definition && !node->alias && s != NULL) 4027 1.1 mrg overall_size += s->self_size; 4028 1.1 mrg if (node->count.ipa ().initialized_p ()) 4029 1.1 mrg { 4030 1.1 mrg compute_count_base = true; 4031 1.1 mrg unsigned pos_percent = opt_for_fn (node->decl, 4032 1.1 mrg param_ipa_cp_profile_count_base); 4033 1.1 mrg base_count_pos_percent = MAX (base_count_pos_percent, pos_percent); 4034 1.1 mrg } 4035 1.1 mrg } 4036 1.1 mrg 4037 1.1 mrg if (compute_count_base) 4038 1.1 mrg { 4039 1.1 mrg auto_vec<profile_count> all_edge_counts; 4040 1.1 mrg all_edge_counts.reserve_exact (symtab->edges_count); 4041 1.1 mrg FOR_EACH_DEFINED_FUNCTION (node) 4042 1.1 mrg for (cgraph_edge *cs = node->callees; cs; cs = cs->next_callee) 4043 1.1 mrg { 4044 1.1 mrg profile_count count = cs->count.ipa (); 4045 1.1 mrg if (!(count > profile_count::zero ())) 4046 1.1 mrg continue; 4047 1.1 mrg 4048 1.1 mrg enum availability avail; 4049 1.1 mrg cgraph_node *tgt 4050 1.1 mrg = cs->callee->function_or_virtual_thunk_symbol (&avail); 4051 1.1 mrg ipa_node_params *info = ipa_node_params_sum->get (tgt); 4052 1.1 mrg if (info && info->versionable) 4053 1.1 mrg all_edge_counts.quick_push (count); 4054 1.1 mrg } 4055 1.1 mrg 4056 1.1 mrg if (!all_edge_counts.is_empty ()) 4057 1.1 mrg { 4058 1.1 mrg gcc_assert (base_count_pos_percent <= 100); 4059 1.1 mrg all_edge_counts.qsort (compare_edge_profile_counts); 4060 1.1 mrg 4061 1.1 mrg unsigned base_count_pos 4062 1.1 mrg = ((all_edge_counts.length () * (base_count_pos_percent)) / 100); 4063 1.1 mrg base_count = all_edge_counts[base_count_pos]; 4064 1.1 mrg 4065 1.1 mrg if (dump_file) 4066 1.1 mrg { 4067 1.1 mrg fprintf (dump_file, "\nSelected base_count from %u edges at " 4068 1.1 mrg "position %u, arriving at: ", all_edge_counts.length (), 4069 1.1 mrg base_count_pos); 4070 1.1 mrg base_count.dump (dump_file); 4071 1.1 mrg fprintf (dump_file, "\n"); 4072 1.1 mrg } 4073 1.1 mrg } 4074 1.1 mrg else if (dump_file) 4075 1.1 mrg fprintf (dump_file, "\nNo candidates with non-zero call count found, " 4076 1.1 mrg "continuing as if without profile feedback.\n"); 4077 1.1 mrg } 4078 1.1 mrg 4079 1.1 mrg orig_overall_size = overall_size; 4080 1.1 mrg 4081 1.1 mrg if (dump_file) 4082 1.1 mrg fprintf (dump_file, "\noverall_size: %li\n", overall_size); 4083 1.1 mrg 4084 1.1 mrg propagate_constants_topo (topo); 4085 1.1 mrg if (flag_checking) 4086 1.1 mrg ipcp_verify_propagated_values (); 4087 1.1 mrg topo->constants.propagate_effects (); 4088 1.1 mrg topo->contexts.propagate_effects (); 4089 1.1 mrg 4090 1.1 mrg if (dump_file) 4091 1.1 mrg { 4092 1.1 mrg fprintf (dump_file, "\nIPA lattices after all propagation:\n"); 4093 1.1 mrg print_all_lattices (dump_file, (dump_flags & TDF_DETAILS), true); 4094 1.1 mrg } 4095 1.1 mrg } 4096 1.1 mrg 4097 1.1 mrg /* Discover newly direct outgoing edges from NODE which is a new clone with 4098 1.1 mrg known KNOWN_CSTS and make them direct. */ 4099 1.1 mrg 4100 1.1 mrg static void 4101 1.1 mrg ipcp_discover_new_direct_edges (struct cgraph_node *node, 4102 1.1 mrg vec<tree> known_csts, 4103 1.1 mrg vec<ipa_polymorphic_call_context> 4104 1.1 mrg known_contexts, 4105 1.1 mrg struct ipa_agg_replacement_value *aggvals) 4106 1.1 mrg { 4107 1.1 mrg struct cgraph_edge *ie, *next_ie; 4108 1.1 mrg bool found = false; 4109 1.1 mrg 4110 1.1 mrg for (ie = node->indirect_calls; ie; ie = next_ie) 4111 1.1 mrg { 4112 1.1 mrg tree target; 4113 1.1 mrg bool speculative; 4114 1.1 mrg 4115 1.1 mrg next_ie = ie->next_callee; 4116 1.1 mrg target = ipa_get_indirect_edge_target_1 (ie, known_csts, known_contexts, 4117 1.1 mrg vNULL, aggvals, &speculative); 4118 1.1 mrg if (target) 4119 1.1 mrg { 4120 1.1 mrg bool agg_contents = ie->indirect_info->agg_contents; 4121 1.1 mrg bool polymorphic = ie->indirect_info->polymorphic; 4122 1.1 mrg int param_index = ie->indirect_info->param_index; 4123 1.1 mrg struct cgraph_edge *cs = ipa_make_edge_direct_to_target (ie, target, 4124 1.1 mrg speculative); 4125 1.1 mrg found = true; 4126 1.1 mrg 4127 1.1 mrg if (cs && !agg_contents && !polymorphic) 4128 1.1 mrg { 4129 1.1 mrg ipa_node_params *info = ipa_node_params_sum->get (node); 4130 1.1 mrg int c = ipa_get_controlled_uses (info, param_index); 4131 1.1 mrg if (c != IPA_UNDESCRIBED_USE 4132 1.1 mrg && !ipa_get_param_load_dereferenced (info, param_index)) 4133 1.1 mrg { 4134 1.1 mrg struct ipa_ref *to_del; 4135 1.1 mrg 4136 1.1 mrg c--; 4137 1.1 mrg ipa_set_controlled_uses (info, param_index, c); 4138 1.1 mrg if (dump_file && (dump_flags & TDF_DETAILS)) 4139 1.1 mrg fprintf (dump_file, " controlled uses count of param " 4140 1.1 mrg "%i bumped down to %i\n", param_index, c); 4141 1.1 mrg if (c == 0 4142 1.1 mrg && (to_del = node->find_reference (cs->callee, NULL, 0, 4143 1.1 mrg IPA_REF_ADDR))) 4144 1.1 mrg { 4145 1.1 mrg if (dump_file && (dump_flags & TDF_DETAILS)) 4146 1.1 mrg fprintf (dump_file, " and even removing its " 4147 1.1 mrg "cloning-created reference\n"); 4148 1.1 mrg to_del->remove_reference (); 4149 1.1 mrg } 4150 1.1 mrg } 4151 1.1 mrg } 4152 1.1 mrg } 4153 1.1 mrg } 4154 1.1 mrg /* Turning calls to direct calls will improve overall summary. */ 4155 1.1 mrg if (found) 4156 1.1 mrg ipa_update_overall_fn_summary (node); 4157 1.1 mrg } 4158 1.1 mrg 4159 1.1 mrg class edge_clone_summary; 4160 1.1 mrg static call_summary <edge_clone_summary *> *edge_clone_summaries = NULL; 4161 1.1 mrg 4162 1.1 mrg /* Edge clone summary. */ 4163 1.1 mrg 4164 1.1 mrg class edge_clone_summary 4165 1.1 mrg { 4166 1.1 mrg public: 4167 1.1 mrg /* Default constructor. */ 4168 1.1 mrg edge_clone_summary (): prev_clone (NULL), next_clone (NULL) {} 4169 1.1 mrg 4170 1.1 mrg /* Default destructor. */ 4171 1.1 mrg ~edge_clone_summary () 4172 1.1 mrg { 4173 1.1 mrg if (prev_clone) 4174 1.1 mrg edge_clone_summaries->get (prev_clone)->next_clone = next_clone; 4175 1.1 mrg if (next_clone) 4176 1.1 mrg edge_clone_summaries->get (next_clone)->prev_clone = prev_clone; 4177 1.1 mrg } 4178 1.1 mrg 4179 1.1 mrg cgraph_edge *prev_clone; 4180 1.1 mrg cgraph_edge *next_clone; 4181 1.1 mrg }; 4182 1.1 mrg 4183 1.1 mrg class edge_clone_summary_t: 4184 1.1 mrg public call_summary <edge_clone_summary *> 4185 1.1 mrg { 4186 1.1 mrg public: 4187 1.1 mrg edge_clone_summary_t (symbol_table *symtab): 4188 1.1 mrg call_summary <edge_clone_summary *> (symtab) 4189 1.1 mrg { 4190 1.1 mrg m_initialize_when_cloning = true; 4191 1.1 mrg } 4192 1.1 mrg 4193 1.1 mrg virtual void duplicate (cgraph_edge *src_edge, cgraph_edge *dst_edge, 4194 1.1 mrg edge_clone_summary *src_data, 4195 1.1 mrg edge_clone_summary *dst_data); 4196 1.1 mrg }; 4197 1.1 mrg 4198 1.1 mrg /* Edge duplication hook. */ 4199 1.1 mrg 4200 1.1 mrg void 4201 1.1 mrg edge_clone_summary_t::duplicate (cgraph_edge *src_edge, cgraph_edge *dst_edge, 4202 1.1 mrg edge_clone_summary *src_data, 4203 1.1 mrg edge_clone_summary *dst_data) 4204 1.1 mrg { 4205 1.1 mrg if (src_data->next_clone) 4206 1.1 mrg edge_clone_summaries->get (src_data->next_clone)->prev_clone = dst_edge; 4207 1.1 mrg dst_data->prev_clone = src_edge; 4208 1.1 mrg dst_data->next_clone = src_data->next_clone; 4209 1.1 mrg src_data->next_clone = dst_edge; 4210 1.1 mrg } 4211 1.1 mrg 4212 1.1 mrg /* Return true is CS calls DEST or its clone for all contexts. When 4213 1.1 mrg ALLOW_RECURSION_TO_CLONE is false, also return false for self-recursive 4214 1.1 mrg edges from/to an all-context clone. */ 4215 1.1 mrg 4216 1.1 mrg static bool 4217 1.1 mrg calls_same_node_or_its_all_contexts_clone_p (cgraph_edge *cs, cgraph_node *dest, 4218 1.1 mrg bool allow_recursion_to_clone) 4219 1.1 mrg { 4220 1.1 mrg enum availability availability; 4221 1.1 mrg cgraph_node *callee = cs->callee->function_symbol (&availability); 4222 1.1 mrg 4223 1.1 mrg if (availability <= AVAIL_INTERPOSABLE) 4224 1.1 mrg return false; 4225 1.1 mrg if (callee == dest) 4226 1.1 mrg return true; 4227 1.1 mrg if (!allow_recursion_to_clone && cs->caller == callee) 4228 1.1 mrg return false; 4229 1.1 mrg 4230 1.1 mrg ipa_node_params *info = ipa_node_params_sum->get (callee); 4231 1.1 mrg return info->is_all_contexts_clone && info->ipcp_orig_node == dest; 4232 1.1 mrg } 4233 1.1 mrg 4234 1.1 mrg /* Return true if edge CS does bring about the value described by SRC to 4235 1.1 mrg DEST_VAL of node DEST or its clone for all contexts. */ 4236 1.1 mrg 4237 1.1 mrg static bool 4238 1.1 mrg cgraph_edge_brings_value_p (cgraph_edge *cs, ipcp_value_source<tree> *src, 4239 1.1 mrg cgraph_node *dest, ipcp_value<tree> *dest_val) 4240 1.1 mrg { 4241 1.1 mrg ipa_node_params *caller_info = ipa_node_params_sum->get (cs->caller); 4242 1.1 mrg 4243 1.1 mrg if (!calls_same_node_or_its_all_contexts_clone_p (cs, dest, !src->val) 4244 1.1 mrg || caller_info->node_dead) 4245 1.1 mrg return false; 4246 1.1 mrg 4247 1.1 mrg if (!src->val) 4248 1.1 mrg return true; 4249 1.1 mrg 4250 1.1 mrg if (caller_info->ipcp_orig_node) 4251 1.1 mrg { 4252 1.1 mrg tree t; 4253 1.1 mrg if (src->offset == -1) 4254 1.1 mrg t = caller_info->known_csts[src->index]; 4255 1.1 mrg else 4256 1.1 mrg t = get_clone_agg_value (cs->caller, src->offset, src->index); 4257 1.1 mrg return (t != NULL_TREE 4258 1.1 mrg && values_equal_for_ipcp_p (src->val->value, t)); 4259 1.1 mrg } 4260 1.1 mrg else 4261 1.1 mrg { 4262 1.1 mrg if (src->val == dest_val) 4263 1.1 mrg return true; 4264 1.1 mrg 4265 1.1 mrg struct ipcp_agg_lattice *aglat; 4266 1.1 mrg class ipcp_param_lattices *plats = ipa_get_parm_lattices (caller_info, 4267 1.1 mrg src->index); 4268 1.1 mrg if (src->offset == -1) 4269 1.1 mrg return (plats->itself.is_single_const () 4270 1.1 mrg && values_equal_for_ipcp_p (src->val->value, 4271 1.1 mrg plats->itself.values->value)); 4272 1.1 mrg else 4273 1.1 mrg { 4274 1.1 mrg if (plats->aggs_bottom || plats->aggs_contain_variable) 4275 1.1 mrg return false; 4276 1.1 mrg for (aglat = plats->aggs; aglat; aglat = aglat->next) 4277 1.1 mrg if (aglat->offset == src->offset) 4278 1.1 mrg return (aglat->is_single_const () 4279 1.1 mrg && values_equal_for_ipcp_p (src->val->value, 4280 1.1 mrg aglat->values->value)); 4281 1.1 mrg } 4282 1.1 mrg return false; 4283 1.1 mrg } 4284 1.1 mrg } 4285 1.1 mrg 4286 1.1 mrg /* Return true if edge CS does bring about the value described by SRC to 4287 1.1 mrg DST_VAL of node DEST or its clone for all contexts. */ 4288 1.1 mrg 4289 1.1 mrg static bool 4290 1.1 mrg cgraph_edge_brings_value_p (cgraph_edge *cs, 4291 1.1 mrg ipcp_value_source<ipa_polymorphic_call_context> *src, 4292 1.1 mrg cgraph_node *dest, 4293 1.1 mrg ipcp_value<ipa_polymorphic_call_context> *) 4294 1.1 mrg { 4295 1.1 mrg ipa_node_params *caller_info = ipa_node_params_sum->get (cs->caller); 4296 1.1 mrg 4297 1.1 mrg if (!calls_same_node_or_its_all_contexts_clone_p (cs, dest, true) 4298 1.1 mrg || caller_info->node_dead) 4299 1.1 mrg return false; 4300 1.1 mrg if (!src->val) 4301 1.1 mrg return true; 4302 1.1 mrg 4303 1.1 mrg if (caller_info->ipcp_orig_node) 4304 1.1 mrg return (caller_info->known_contexts.length () > (unsigned) src->index) 4305 1.1 mrg && values_equal_for_ipcp_p (src->val->value, 4306 1.1 mrg caller_info->known_contexts[src->index]); 4307 1.1 mrg 4308 1.1 mrg class ipcp_param_lattices *plats = ipa_get_parm_lattices (caller_info, 4309 1.1 mrg src->index); 4310 1.1 mrg return plats->ctxlat.is_single_const () 4311 1.1 mrg && values_equal_for_ipcp_p (src->val->value, 4312 1.1 mrg plats->ctxlat.values->value); 4313 1.1 mrg } 4314 1.1 mrg 4315 1.1 mrg /* Get the next clone in the linked list of clones of an edge. */ 4316 1.1 mrg 4317 1.1 mrg static inline struct cgraph_edge * 4318 1.1 mrg get_next_cgraph_edge_clone (struct cgraph_edge *cs) 4319 1.1 mrg { 4320 1.1 mrg edge_clone_summary *s = edge_clone_summaries->get (cs); 4321 1.1 mrg return s != NULL ? s->next_clone : NULL; 4322 1.1 mrg } 4323 1.1 mrg 4324 1.1 mrg /* Given VAL that is intended for DEST, iterate over all its sources and if any 4325 1.1 mrg of them is viable and hot, return true. In that case, for those that still 4326 1.1 mrg hold, add their edge frequency and their number and cumulative profile 4327 1.1 mrg counts of self-ecursive and other edges into *FREQUENCY, *CALLER_COUNT, 4328 1.1 mrg REC_COUNT_SUM and NONREC_COUNT_SUM respectively. */ 4329 1.1 mrg 4330 1.1 mrg template <typename valtype> 4331 1.1 mrg static bool 4332 1.1 mrg get_info_about_necessary_edges (ipcp_value<valtype> *val, cgraph_node *dest, 4333 1.1 mrg sreal *freq_sum, int *caller_count, 4334 1.1 mrg profile_count *rec_count_sum, 4335 1.1 mrg profile_count *nonrec_count_sum) 4336 1.1 mrg { 4337 1.1 mrg ipcp_value_source<valtype> *src; 4338 1.1 mrg sreal freq = 0; 4339 1.1 mrg int count = 0; 4340 1.1 mrg profile_count rec_cnt = profile_count::zero (); 4341 1.1 mrg profile_count nonrec_cnt = profile_count::zero (); 4342 1.1 mrg bool hot = false; 4343 1.1 mrg bool non_self_recursive = false; 4344 1.1 mrg 4345 1.1 mrg for (src = val->sources; src; src = src->next) 4346 1.1 mrg { 4347 1.1 mrg struct cgraph_edge *cs = src->cs; 4348 1.1 mrg while (cs) 4349 1.1 mrg { 4350 1.1 mrg if (cgraph_edge_brings_value_p (cs, src, dest, val)) 4351 1.1 mrg { 4352 1.1 mrg count++; 4353 1.1 mrg freq += cs->sreal_frequency (); 4354 1.1 mrg hot |= cs->maybe_hot_p (); 4355 1.1 mrg if (cs->caller != dest) 4356 1.1 mrg { 4357 1.1 mrg non_self_recursive = true; 4358 1.1 mrg if (cs->count.ipa ().initialized_p ()) 4359 1.1 mrg rec_cnt += cs->count.ipa (); 4360 1.1 mrg } 4361 1.1 mrg else if (cs->count.ipa ().initialized_p ()) 4362 1.1 mrg nonrec_cnt += cs->count.ipa (); 4363 1.1 mrg } 4364 1.1 mrg cs = get_next_cgraph_edge_clone (cs); 4365 1.1 mrg } 4366 1.1 mrg } 4367 1.1 mrg 4368 1.1 mrg /* If the only edges bringing a value are self-recursive ones, do not bother 4369 1.1 mrg evaluating it. */ 4370 1.1 mrg if (!non_self_recursive) 4371 1.1 mrg return false; 4372 1.1 mrg 4373 1.1 mrg *freq_sum = freq; 4374 1.1 mrg *caller_count = count; 4375 1.1 mrg *rec_count_sum = rec_cnt; 4376 1.1 mrg *nonrec_count_sum = nonrec_cnt; 4377 1.1 mrg 4378 1.1 mrg if (!hot && ipa_node_params_sum->get (dest)->node_within_scc) 4379 1.1 mrg { 4380 1.1 mrg struct cgraph_edge *cs; 4381 1.1 mrg 4382 1.1 mrg /* Cold non-SCC source edge could trigger hot recursive execution of 4383 1.1 mrg function. Consider the case as hot and rely on following cost model 4384 1.1 mrg computation to further select right one. */ 4385 1.1 mrg for (cs = dest->callers; cs; cs = cs->next_caller) 4386 1.1 mrg if (cs->caller == dest && cs->maybe_hot_p ()) 4387 1.1 mrg return true; 4388 1.1 mrg } 4389 1.1 mrg 4390 1.1 mrg return hot; 4391 1.1 mrg } 4392 1.1 mrg 4393 1.1 mrg /* Given a NODE, and a set of its CALLERS, try to adjust order of the callers 4394 1.1 mrg to let a non-self-recursive caller be the first element. Thus, we can 4395 1.1 mrg simplify intersecting operations on values that arrive from all of these 4396 1.1 mrg callers, especially when there exists self-recursive call. Return true if 4397 1.1 mrg this kind of adjustment is possible. */ 4398 1.1 mrg 4399 1.1 mrg static bool 4400 1.1 mrg adjust_callers_for_value_intersection (vec<cgraph_edge *> &callers, 4401 1.1 mrg cgraph_node *node) 4402 1.1 mrg { 4403 1.1 mrg for (unsigned i = 0; i < callers.length (); i++) 4404 1.1 mrg { 4405 1.1 mrg cgraph_edge *cs = callers[i]; 4406 1.1 mrg 4407 1.1 mrg if (cs->caller != node) 4408 1.1 mrg { 4409 1.1 mrg if (i > 0) 4410 1.1 mrg { 4411 1.1 mrg callers[i] = callers[0]; 4412 1.1 mrg callers[0] = cs; 4413 1.1 mrg } 4414 1.1 mrg return true; 4415 1.1 mrg } 4416 1.1 mrg } 4417 1.1 mrg return false; 4418 1.1 mrg } 4419 1.1 mrg 4420 1.1 mrg /* Return a vector of incoming edges that do bring value VAL to node DEST. It 4421 1.1 mrg is assumed their number is known and equal to CALLER_COUNT. */ 4422 1.1 mrg 4423 1.1 mrg template <typename valtype> 4424 1.1 mrg static vec<cgraph_edge *> 4425 1.1 mrg gather_edges_for_value (ipcp_value<valtype> *val, cgraph_node *dest, 4426 1.1 mrg int caller_count) 4427 1.1 mrg { 4428 1.1 mrg ipcp_value_source<valtype> *src; 4429 1.1 mrg vec<cgraph_edge *> ret; 4430 1.1 mrg 4431 1.1 mrg ret.create (caller_count); 4432 1.1 mrg for (src = val->sources; src; src = src->next) 4433 1.1 mrg { 4434 1.1 mrg struct cgraph_edge *cs = src->cs; 4435 1.1 mrg while (cs) 4436 1.1 mrg { 4437 1.1 mrg if (cgraph_edge_brings_value_p (cs, src, dest, val)) 4438 1.1 mrg ret.quick_push (cs); 4439 1.1 mrg cs = get_next_cgraph_edge_clone (cs); 4440 1.1 mrg } 4441 1.1 mrg } 4442 1.1 mrg 4443 1.1 mrg if (caller_count > 1) 4444 1.1 mrg adjust_callers_for_value_intersection (ret, dest); 4445 1.1 mrg 4446 1.1 mrg return ret; 4447 1.1 mrg } 4448 1.1 mrg 4449 1.1 mrg /* Construct a replacement map for a know VALUE for a formal parameter PARAM. 4450 1.1 mrg Return it or NULL if for some reason it cannot be created. FORCE_LOAD_REF 4451 1.1 mrg should be set to true when the reference created for the constant should be 4452 1.1 mrg a load one and not an address one because the corresponding parameter p is 4453 1.1 mrg only used as *p. */ 4454 1.1 mrg 4455 1.1 mrg static struct ipa_replace_map * 4456 1.1 mrg get_replacement_map (class ipa_node_params *info, tree value, int parm_num, 4457 1.1 mrg bool force_load_ref) 4458 1.1 mrg { 4459 1.1 mrg struct ipa_replace_map *replace_map; 4460 1.1 mrg 4461 1.1 mrg replace_map = ggc_alloc<ipa_replace_map> (); 4462 1.1 mrg if (dump_file) 4463 1.1 mrg { 4464 1.1 mrg fprintf (dump_file, " replacing "); 4465 1.1 mrg ipa_dump_param (dump_file, info, parm_num); 4466 1.1 mrg 4467 1.1 mrg fprintf (dump_file, " with const "); 4468 1.1 mrg print_generic_expr (dump_file, value); 4469 1.1 mrg 4470 1.1 mrg if (force_load_ref) 4471 1.1 mrg fprintf (dump_file, " - forcing load reference\n"); 4472 1.1 mrg else 4473 1.1 mrg fprintf (dump_file, "\n"); 4474 1.1 mrg } 4475 1.1 mrg replace_map->parm_num = parm_num; 4476 1.1 mrg replace_map->new_tree = value; 4477 1.1 mrg replace_map->force_load_ref = force_load_ref; 4478 1.1 mrg return replace_map; 4479 1.1 mrg } 4480 1.1 mrg 4481 1.1 mrg /* Dump new profiling counts of NODE. SPEC is true when NODE is a specialzied 4482 1.1 mrg one, otherwise it will be referred to as the original node. */ 4483 1.1 mrg 4484 1.1 mrg static void 4485 1.1 mrg dump_profile_updates (cgraph_node *node, bool spec) 4486 1.1 mrg { 4487 1.1 mrg if (spec) 4488 1.1 mrg fprintf (dump_file, " setting count of the specialized node %s to ", 4489 1.1 mrg node->dump_name ()); 4490 1.1 mrg else 4491 1.1 mrg fprintf (dump_file, " setting count of the original node %s to ", 4492 1.1 mrg node->dump_name ()); 4493 1.1 mrg 4494 1.1 mrg node->count.dump (dump_file); 4495 1.1 mrg fprintf (dump_file, "\n"); 4496 1.1 mrg for (cgraph_edge *cs = node->callees; cs; cs = cs->next_callee) 4497 1.1 mrg { 4498 1.1 mrg fprintf (dump_file, " edge to %s has count ", 4499 1.1 mrg cs->callee->dump_name ()); 4500 1.1 mrg cs->count.dump (dump_file); 4501 1.1 mrg fprintf (dump_file, "\n"); 4502 1.1 mrg } 4503 1.1 mrg } 4504 1.1 mrg 4505 1.1 mrg /* With partial train run we do not want to assume that original's count is 4506 1.1 mrg zero whenever we redurect all executed edges to clone. Simply drop profile 4507 1.1 mrg to local one in this case. In eany case, return the new value. ORIG_NODE 4508 1.1 mrg is the original node and its count has not been updaed yet. */ 4509 1.1 mrg 4510 1.1 mrg profile_count 4511 1.1 mrg lenient_count_portion_handling (profile_count remainder, cgraph_node *orig_node) 4512 1.1 mrg { 4513 1.1 mrg if (remainder.ipa_p () && !remainder.ipa ().nonzero_p () 4514 1.1 mrg && orig_node->count.ipa_p () && orig_node->count.ipa ().nonzero_p () 4515 1.1 mrg && opt_for_fn (orig_node->decl, flag_profile_partial_training)) 4516 1.1 mrg remainder = remainder.guessed_local (); 4517 1.1 mrg 4518 1.1 mrg return remainder; 4519 1.1 mrg } 4520 1.1 mrg 4521 1.1 mrg /* Structure to sum counts coming from nodes other than the original node and 4522 1.1 mrg its clones. */ 4523 1.1 mrg 4524 1.1 mrg struct gather_other_count_struct 4525 1.1 mrg { 4526 1.1 mrg cgraph_node *orig; 4527 1.1 mrg profile_count other_count; 4528 1.1 mrg }; 4529 1.1 mrg 4530 1.1 mrg /* Worker callback of call_for_symbol_thunks_and_aliases summing the number of 4531 1.1 mrg counts that come from non-self-recursive calls.. */ 4532 1.1 mrg 4533 1.1 mrg static bool 4534 1.1 mrg gather_count_of_non_rec_edges (cgraph_node *node, void *data) 4535 1.1 mrg { 4536 1.1 mrg gather_other_count_struct *desc = (gather_other_count_struct *) data; 4537 1.1 mrg for (cgraph_edge *cs = node->callers; cs; cs = cs->next_caller) 4538 1.1 mrg if (cs->caller != desc->orig && cs->caller->clone_of != desc->orig) 4539 1.1 mrg desc->other_count += cs->count.ipa (); 4540 1.1 mrg return false; 4541 1.1 mrg } 4542 1.1 mrg 4543 1.1 mrg /* Structure to help analyze if we need to boost counts of some clones of some 4544 1.1 mrg non-recursive edges to match the new callee count. */ 4545 1.1 mrg 4546 1.1 mrg struct desc_incoming_count_struct 4547 1.1 mrg { 4548 1.1 mrg cgraph_node *orig; 4549 1.1 mrg hash_set <cgraph_edge *> *processed_edges; 4550 1.1 mrg profile_count count; 4551 1.1 mrg unsigned unproc_orig_rec_edges; 4552 1.1 mrg }; 4553 1.1 mrg 4554 1.1 mrg /* Go over edges calling NODE and its thunks and gather information about 4555 1.1 mrg incoming counts so that we know if we need to make any adjustments. */ 4556 1.1 mrg 4557 1.1 mrg static void 4558 1.1 mrg analyze_clone_icoming_counts (cgraph_node *node, 4559 1.1 mrg desc_incoming_count_struct *desc) 4560 1.1 mrg { 4561 1.1 mrg for (cgraph_edge *cs = node->callers; cs; cs = cs->next_caller) 4562 1.1 mrg if (cs->caller->thunk) 4563 1.1 mrg { 4564 1.1 mrg analyze_clone_icoming_counts (cs->caller, desc); 4565 1.1 mrg continue; 4566 1.1 mrg } 4567 1.1 mrg else 4568 1.1 mrg { 4569 1.1 mrg if (cs->count.initialized_p ()) 4570 1.1 mrg desc->count += cs->count.ipa (); 4571 1.1 mrg if (!desc->processed_edges->contains (cs) 4572 1.1 mrg && cs->caller->clone_of == desc->orig) 4573 1.1 mrg desc->unproc_orig_rec_edges++; 4574 1.1 mrg } 4575 1.1 mrg } 4576 1.1 mrg 4577 1.1 mrg /* If caller edge counts of a clone created for a self-recursive arithmetic 4578 1.1 mrg jump function must be adjusted because it is coming from a the "seed" clone 4579 1.1 mrg for the first value and so has been excessively scaled back as if it was not 4580 1.1 mrg a recursive call, adjust it so that the incoming counts of NODE match its 4581 1.1 mrg count. NODE is the node or its thunk. */ 4582 1.1 mrg 4583 1.1 mrg static void 4584 1.1 mrg adjust_clone_incoming_counts (cgraph_node *node, 4585 1.1 mrg desc_incoming_count_struct *desc) 4586 1.1 mrg { 4587 1.1 mrg for (cgraph_edge *cs = node->callers; cs; cs = cs->next_caller) 4588 1.1 mrg if (cs->caller->thunk) 4589 1.1 mrg { 4590 1.1 mrg adjust_clone_incoming_counts (cs->caller, desc); 4591 1.1 mrg profile_count sum = profile_count::zero (); 4592 1.1 mrg for (cgraph_edge *e = cs->caller->callers; e; e = e->next_caller) 4593 1.1 mrg if (e->count.initialized_p ()) 4594 1.1 mrg sum += e->count.ipa (); 4595 1.1 mrg cs->count = cs->count.combine_with_ipa_count (sum); 4596 1.1 mrg } 4597 1.1 mrg else if (!desc->processed_edges->contains (cs) 4598 1.1 mrg && cs->caller->clone_of == desc->orig) 4599 1.1 mrg { 4600 1.1 mrg cs->count += desc->count; 4601 1.1 mrg if (dump_file) 4602 1.1 mrg { 4603 1.1 mrg fprintf (dump_file, " Adjusted count of an incoming edge of " 4604 1.1 mrg "a clone %s -> %s to ", cs->caller->dump_name (), 4605 1.1 mrg cs->callee->dump_name ()); 4606 1.1 mrg cs->count.dump (dump_file); 4607 1.1 mrg fprintf (dump_file, "\n"); 4608 1.1 mrg } 4609 1.1 mrg } 4610 1.1 mrg } 4611 1.1 mrg 4612 1.1 mrg /* When ORIG_NODE has been cloned for values which have been generated fora 4613 1.1 mrg self-recursive call as a result of an arithmetic pass-through 4614 1.1 mrg jump-functions, adjust its count together with counts of all such clones in 4615 1.1 mrg SELF_GEN_CLONES which also at this point contains ORIG_NODE itself. 4616 1.1 mrg 4617 1.1 mrg The function sums the counts of the original node and all its clones that 4618 1.1 mrg cannot be attributed to a specific clone because it comes from a 4619 1.1 mrg non-recursive edge. This sum is then evenly divided between the clones and 4620 1.1 mrg on top of that each one gets all the counts which can be attributed directly 4621 1.1 mrg to it. */ 4622 1.1 mrg 4623 1.1 mrg static void 4624 1.1 mrg update_counts_for_self_gen_clones (cgraph_node *orig_node, 4625 1.1 mrg const vec<cgraph_node *> &self_gen_clones) 4626 1.1 mrg { 4627 1.1 mrg profile_count redist_sum = orig_node->count.ipa (); 4628 1.1 mrg if (!(redist_sum > profile_count::zero ())) 4629 1.1 mrg return; 4630 1.1 mrg 4631 1.1 mrg if (dump_file) 4632 1.1 mrg fprintf (dump_file, " Updating profile of self recursive clone " 4633 1.1 mrg "series\n"); 4634 1.1 mrg 4635 1.1 mrg gather_other_count_struct gocs; 4636 1.1 mrg gocs.orig = orig_node; 4637 1.1 mrg gocs.other_count = profile_count::zero (); 4638 1.1 mrg 4639 1.1 mrg auto_vec <profile_count, 8> other_edges_count; 4640 1.1 mrg for (cgraph_node *n : self_gen_clones) 4641 1.1 mrg { 4642 1.1 mrg gocs.other_count = profile_count::zero (); 4643 1.1 mrg n->call_for_symbol_thunks_and_aliases (gather_count_of_non_rec_edges, 4644 1.1 mrg &gocs, false); 4645 1.1 mrg other_edges_count.safe_push (gocs.other_count); 4646 1.1 mrg redist_sum -= gocs.other_count; 4647 1.1 mrg } 4648 1.1 mrg 4649 1.1 mrg hash_set<cgraph_edge *> processed_edges; 4650 1.1 mrg unsigned i = 0; 4651 1.1 mrg for (cgraph_node *n : self_gen_clones) 4652 1.1 mrg { 4653 1.1 mrg profile_count orig_count = n->count; 4654 1.1 mrg profile_count new_count 4655 1.1 mrg = (redist_sum.apply_scale (1, self_gen_clones.length ()) 4656 1.1 mrg + other_edges_count[i]); 4657 1.1 mrg new_count = lenient_count_portion_handling (new_count, orig_node); 4658 1.1 mrg n->count = new_count; 4659 1.1 mrg profile_count::adjust_for_ipa_scaling (&new_count, &orig_count); 4660 1.1 mrg for (cgraph_edge *cs = n->callees; cs; cs = cs->next_callee) 4661 1.1 mrg { 4662 1.1 mrg cs->count = cs->count.apply_scale (new_count, orig_count); 4663 1.1 mrg processed_edges.add (cs); 4664 1.1 mrg } 4665 1.1 mrg for (cgraph_edge *cs = n->indirect_calls; cs; cs = cs->next_callee) 4666 1.1 mrg cs->count = cs->count.apply_scale (new_count, orig_count); 4667 1.1 mrg 4668 1.1 mrg i++; 4669 1.1 mrg } 4670 1.1 mrg 4671 1.1 mrg /* There are still going to be edges to ORIG_NODE that have one or more 4672 1.1 mrg clones coming from another node clone in SELF_GEN_CLONES and which we 4673 1.1 mrg scaled by the same amount, which means that the total incoming sum of 4674 1.1 mrg counts to ORIG_NODE will be too high, scale such edges back. */ 4675 1.1 mrg for (cgraph_edge *cs = orig_node->callees; cs; cs = cs->next_callee) 4676 1.1 mrg { 4677 1.1 mrg if (cs->callee->ultimate_alias_target () == orig_node) 4678 1.1 mrg { 4679 1.1 mrg unsigned den = 0; 4680 1.1 mrg for (cgraph_edge *e = cs; e; e = get_next_cgraph_edge_clone (e)) 4681 1.1 mrg if (e->callee->ultimate_alias_target () == orig_node 4682 1.1 mrg && processed_edges.contains (e)) 4683 1.1 mrg den++; 4684 1.1 mrg if (den > 0) 4685 1.1 mrg for (cgraph_edge *e = cs; e; e = get_next_cgraph_edge_clone (e)) 4686 1.1 mrg if (e->callee->ultimate_alias_target () == orig_node 4687 1.1 mrg && processed_edges.contains (e)) 4688 1.1 mrg e->count = e->count.apply_scale (1, den); 4689 1.1 mrg } 4690 1.1 mrg } 4691 1.1 mrg 4692 1.1 mrg /* Edges from the seeds of the valus generated for arithmetic jump-functions 4693 1.1 mrg along self-recursive edges are likely to have fairly low count and so 4694 1.1 mrg edges from them to nodes in the self_gen_clones do not correspond to the 4695 1.1 mrg artificially distributed count of the nodes, the total sum of incoming 4696 1.1 mrg edges to some clones might be too low. Detect this situation and correct 4697 1.1 mrg it. */ 4698 1.1 mrg for (cgraph_node *n : self_gen_clones) 4699 1.1 mrg { 4700 1.1 mrg if (!(n->count.ipa () > profile_count::zero ())) 4701 1.1 mrg continue; 4702 1.1 mrg 4703 1.1 mrg desc_incoming_count_struct desc; 4704 1.1 mrg desc.orig = orig_node; 4705 1.1 mrg desc.processed_edges = &processed_edges; 4706 1.1 mrg desc.count = profile_count::zero (); 4707 1.1 mrg desc.unproc_orig_rec_edges = 0; 4708 1.1 mrg analyze_clone_icoming_counts (n, &desc); 4709 1.1 mrg 4710 1.1 mrg if (n->count.differs_from_p (desc.count)) 4711 1.1 mrg { 4712 1.1 mrg if (n->count > desc.count 4713 1.1 mrg && desc.unproc_orig_rec_edges > 0) 4714 1.1 mrg { 4715 1.1 mrg desc.count = n->count - desc.count; 4716 1.1 mrg desc.count 4717 1.1 mrg = desc.count.apply_scale (1, desc.unproc_orig_rec_edges); 4718 1.1 mrg adjust_clone_incoming_counts (n, &desc); 4719 1.1 mrg } 4720 1.1 mrg else if (dump_file) 4721 1.1 mrg fprintf (dump_file, 4722 1.1 mrg " Unable to fix up incoming counts for %s.\n", 4723 1.1 mrg n->dump_name ()); 4724 1.1 mrg } 4725 1.1 mrg } 4726 1.1 mrg 4727 1.1 mrg if (dump_file) 4728 1.1 mrg for (cgraph_node *n : self_gen_clones) 4729 1.1 mrg dump_profile_updates (n, n != orig_node); 4730 1.1 mrg return; 4731 1.1 mrg } 4732 1.1 mrg 4733 1.1 mrg /* After a specialized NEW_NODE version of ORIG_NODE has been created, update 4734 1.1 mrg their profile information to reflect this. This function should not be used 4735 1.1 mrg for clones generated for arithmetic pass-through jump functions on a 4736 1.1 mrg self-recursive call graph edge, that situation is handled by 4737 1.1 mrg update_counts_for_self_gen_clones. */ 4738 1.1 mrg 4739 1.1 mrg static void 4740 1.1 mrg update_profiling_info (struct cgraph_node *orig_node, 4741 1.1 mrg struct cgraph_node *new_node) 4742 1.1 mrg { 4743 1.1 mrg struct caller_statistics stats; 4744 1.1 mrg profile_count new_sum; 4745 1.1 mrg profile_count remainder, orig_node_count = orig_node->count.ipa (); 4746 1.1 mrg 4747 1.1 mrg if (!(orig_node_count > profile_count::zero ())) 4748 1.1 mrg return; 4749 1.1 mrg 4750 1.1 mrg if (dump_file) 4751 1.1 mrg { 4752 1.1 mrg fprintf (dump_file, " Updating profile from original count: "); 4753 1.1 mrg orig_node_count.dump (dump_file); 4754 1.1 mrg fprintf (dump_file, "\n"); 4755 1.1 mrg } 4756 1.1 mrg 4757 1.1 mrg init_caller_stats (&stats, new_node); 4758 1.1 mrg new_node->call_for_symbol_thunks_and_aliases (gather_caller_stats, &stats, 4759 1.1 mrg false); 4760 1.1 mrg new_sum = stats.count_sum; 4761 1.1 mrg 4762 1.1 mrg if (new_sum > orig_node_count) 4763 1.1 mrg { 4764 1.1 mrg /* TODO: Perhaps this should be gcc_unreachable ()? */ 4765 1.1 mrg remainder = profile_count::zero ().guessed_local (); 4766 1.1 mrg } 4767 1.1 mrg else if (stats.rec_count_sum.nonzero_p ()) 4768 1.1 mrg { 4769 1.1 mrg int new_nonrec_calls = stats.n_nonrec_calls; 4770 1.1 mrg /* There are self-recursive edges which are likely to bring in the 4771 1.1 mrg majority of calls but which we must divide in between the original and 4772 1.1 mrg new node. */ 4773 1.1 mrg init_caller_stats (&stats, orig_node); 4774 1.1 mrg orig_node->call_for_symbol_thunks_and_aliases (gather_caller_stats, 4775 1.1 mrg &stats, false); 4776 1.1 mrg int orig_nonrec_calls = stats.n_nonrec_calls; 4777 1.1 mrg profile_count orig_nonrec_call_count = stats.count_sum; 4778 1.1 mrg 4779 1.1 mrg if (orig_node->local) 4780 1.1 mrg { 4781 1.1 mrg if (!orig_nonrec_call_count.nonzero_p ()) 4782 1.1 mrg { 4783 1.1 mrg if (dump_file) 4784 1.1 mrg fprintf (dump_file, " The original is local and the only " 4785 1.1 mrg "incoming edges from non-dead callers with nonzero " 4786 1.1 mrg "counts are self-recursive, assuming it is cold.\n"); 4787 1.1 mrg /* The NEW_NODE count and counts of all its outgoing edges 4788 1.1 mrg are still unmodified copies of ORIG_NODE's. Just clear 4789 1.1 mrg the latter and bail out. */ 4790 1.1 mrg profile_count zero; 4791 1.1 mrg if (opt_for_fn (orig_node->decl, flag_profile_partial_training)) 4792 1.1 mrg zero = profile_count::zero ().guessed_local (); 4793 1.1 mrg else 4794 1.1 mrg zero = profile_count::adjusted_zero (); 4795 1.1 mrg orig_node->count = zero; 4796 1.1 mrg for (cgraph_edge *cs = orig_node->callees; 4797 1.1 mrg cs; 4798 1.1 mrg cs = cs->next_callee) 4799 1.1 mrg cs->count = zero; 4800 1.1 mrg for (cgraph_edge *cs = orig_node->indirect_calls; 4801 1.1 mrg cs; 4802 1.1 mrg cs = cs->next_callee) 4803 1.1 mrg cs->count = zero; 4804 1.1 mrg return; 4805 1.1 mrg } 4806 1.1 mrg } 4807 1.1 mrg else 4808 1.1 mrg { 4809 1.1 mrg /* Let's behave as if there was another caller that accounts for all 4810 1.1 mrg the calls that were either indirect or from other compilation 4811 1.1 mrg units. */ 4812 1.1 mrg orig_nonrec_calls++; 4813 1.1 mrg profile_count pretend_caller_count 4814 1.1 mrg = (orig_node_count - new_sum - orig_nonrec_call_count 4815 1.1 mrg - stats.rec_count_sum); 4816 1.1 mrg orig_nonrec_call_count += pretend_caller_count; 4817 1.1 mrg } 4818 1.1 mrg 4819 1.1 mrg /* Divide all "unexplained" counts roughly proportionally to sums of 4820 1.1 mrg counts of non-recursive calls. 4821 1.1 mrg 4822 1.1 mrg We put rather arbitrary limits on how many counts we claim because the 4823 1.1 mrg number of non-self-recursive incoming count is only a rough guideline 4824 1.1 mrg and there are cases (such as mcf) where using it blindly just takes 4825 1.1 mrg too many. And if lattices are considered in the opposite order we 4826 1.1 mrg could also take too few. */ 4827 1.1 mrg profile_count unexp = orig_node_count - new_sum - orig_nonrec_call_count; 4828 1.1 mrg 4829 1.1 mrg int limit_den = 2 * (orig_nonrec_calls + new_nonrec_calls); 4830 1.1 mrg profile_count new_part 4831 1.1 mrg = MAX(MIN (unexp.apply_scale (new_sum, 4832 1.1 mrg new_sum + orig_nonrec_call_count), 4833 1.1 mrg unexp.apply_scale (limit_den - 1, limit_den)), 4834 1.1 mrg unexp.apply_scale (new_nonrec_calls, limit_den)); 4835 1.1 mrg if (dump_file) 4836 1.1 mrg { 4837 1.1 mrg fprintf (dump_file, " Claiming "); 4838 1.1 mrg new_part.dump (dump_file); 4839 1.1 mrg fprintf (dump_file, " of unexplained "); 4840 1.1 mrg unexp.dump (dump_file); 4841 1.1 mrg fprintf (dump_file, " counts because of self-recursive " 4842 1.1 mrg "calls\n"); 4843 1.1 mrg } 4844 1.1 mrg new_sum += new_part; 4845 1.1 mrg remainder = lenient_count_portion_handling (orig_node_count - new_sum, 4846 1.1 mrg orig_node); 4847 1.1 mrg } 4848 1.1 mrg else 4849 1.1 mrg remainder = lenient_count_portion_handling (orig_node_count - new_sum, 4850 1.1 mrg orig_node); 4851 1.1 mrg 4852 1.1 mrg new_sum = orig_node_count.combine_with_ipa_count (new_sum); 4853 1.1 mrg new_node->count = new_sum; 4854 1.1 mrg orig_node->count = remainder; 4855 1.1 mrg 4856 1.1 mrg profile_count orig_new_node_count = orig_node_count; 4857 1.1 mrg profile_count::adjust_for_ipa_scaling (&new_sum, &orig_new_node_count); 4858 1.1 mrg for (cgraph_edge *cs = new_node->callees; cs; cs = cs->next_callee) 4859 1.1 mrg cs->count = cs->count.apply_scale (new_sum, orig_new_node_count); 4860 1.1 mrg for (cgraph_edge *cs = new_node->indirect_calls; cs; cs = cs->next_callee) 4861 1.1 mrg cs->count = cs->count.apply_scale (new_sum, orig_new_node_count); 4862 1.1 mrg 4863 1.1 mrg profile_count::adjust_for_ipa_scaling (&remainder, &orig_node_count); 4864 1.1 mrg for (cgraph_edge *cs = orig_node->callees; cs; cs = cs->next_callee) 4865 1.1 mrg cs->count = cs->count.apply_scale (remainder, orig_node_count); 4866 1.1 mrg for (cgraph_edge *cs = orig_node->indirect_calls; cs; cs = cs->next_callee) 4867 1.1 mrg cs->count = cs->count.apply_scale (remainder, orig_node_count); 4868 1.1 mrg 4869 1.1 mrg if (dump_file) 4870 1.1 mrg { 4871 1.1 mrg dump_profile_updates (new_node, true); 4872 1.1 mrg dump_profile_updates (orig_node, false); 4873 1.1 mrg } 4874 1.1 mrg } 4875 1.1 mrg 4876 1.1 mrg /* Update the respective profile of specialized NEW_NODE and the original 4877 1.1 mrg ORIG_NODE after additional edges with cumulative count sum REDIRECTED_SUM 4878 1.1 mrg have been redirected to the specialized version. */ 4879 1.1 mrg 4880 1.1 mrg static void 4881 1.1 mrg update_specialized_profile (struct cgraph_node *new_node, 4882 1.1 mrg struct cgraph_node *orig_node, 4883 1.1 mrg profile_count redirected_sum) 4884 1.1 mrg { 4885 1.1 mrg struct cgraph_edge *cs; 4886 1.1 mrg profile_count new_node_count, orig_node_count = orig_node->count.ipa (); 4887 1.1 mrg 4888 1.1 mrg if (dump_file) 4889 1.1 mrg { 4890 1.1 mrg fprintf (dump_file, " the sum of counts of redirected edges is "); 4891 1.1 mrg redirected_sum.dump (dump_file); 4892 1.1 mrg fprintf (dump_file, "\n old ipa count of the original node is "); 4893 1.1 mrg orig_node_count.dump (dump_file); 4894 1.1 mrg fprintf (dump_file, "\n"); 4895 1.1 mrg } 4896 1.1 mrg if (!(orig_node_count > profile_count::zero ())) 4897 1.1 mrg return; 4898 1.1 mrg 4899 1.1 mrg new_node_count = new_node->count; 4900 1.1 mrg new_node->count += redirected_sum; 4901 1.1 mrg orig_node->count 4902 1.1 mrg = lenient_count_portion_handling (orig_node->count - redirected_sum, 4903 1.1 mrg orig_node); 4904 1.1 mrg 4905 1.1 mrg for (cs = new_node->callees; cs; cs = cs->next_callee) 4906 1.1 mrg cs->count += cs->count.apply_scale (redirected_sum, new_node_count); 4907 1.1 mrg 4908 1.1 mrg for (cs = orig_node->callees; cs; cs = cs->next_callee) 4909 1.1 mrg { 4910 1.1 mrg profile_count dec = cs->count.apply_scale (redirected_sum, 4911 1.1 mrg orig_node_count); 4912 1.1 mrg cs->count -= dec; 4913 1.1 mrg } 4914 1.1 mrg 4915 1.1 mrg if (dump_file) 4916 1.1 mrg { 4917 1.1 mrg dump_profile_updates (new_node, true); 4918 1.1 mrg dump_profile_updates (orig_node, false); 4919 1.1 mrg } 4920 1.1 mrg } 4921 1.1 mrg 4922 1.1 mrg static void adjust_references_in_caller (cgraph_edge *cs, 4923 1.1 mrg symtab_node *symbol, int index); 4924 1.1 mrg 4925 1.1 mrg /* Simple structure to pass a symbol and index (with same meaning as parameters 4926 1.1 mrg of adjust_references_in_caller) through a void* parameter of a 4927 1.1 mrg call_for_symbol_thunks_and_aliases callback. */ 4928 1.1 mrg struct symbol_and_index_together 4929 1.1 mrg { 4930 1.1 mrg symtab_node *symbol; 4931 1.1 mrg int index; 4932 1.1 mrg }; 4933 1.1 mrg 4934 1.1 mrg /* Worker callback of call_for_symbol_thunks_and_aliases to recursively call 4935 1.1 mrg adjust_references_in_caller on edges up in the call-graph, if necessary. */ 4936 1.1 mrg static bool 4937 1.1 mrg adjust_refs_in_act_callers (struct cgraph_node *node, void *data) 4938 1.1 mrg { 4939 1.1 mrg symbol_and_index_together *pack = (symbol_and_index_together *) data; 4940 1.1 mrg for (cgraph_edge *cs = node->callers; cs; cs = cs->next_caller) 4941 1.1 mrg if (!cs->caller->thunk) 4942 1.1 mrg adjust_references_in_caller (cs, pack->symbol, pack->index); 4943 1.1 mrg return false; 4944 1.1 mrg } 4945 1.1 mrg 4946 1.1 mrg /* At INDEX of a function being called by CS there is an ADDR_EXPR of a 4947 1.1 mrg variable which is only dereferenced and which is represented by SYMBOL. See 4948 1.1 mrg if we can remove ADDR reference in callers assosiated witht the call. */ 4949 1.1 mrg 4950 1.1 mrg static void 4951 1.1 mrg adjust_references_in_caller (cgraph_edge *cs, symtab_node *symbol, int index) 4952 1.1 mrg { 4953 1.1 mrg ipa_edge_args *args = ipa_edge_args_sum->get (cs); 4954 1.1 mrg ipa_jump_func *jfunc = ipa_get_ith_jump_func (args, index); 4955 1.1 mrg if (jfunc->type == IPA_JF_CONST) 4956 1.1 mrg { 4957 1.1 mrg ipa_ref *to_del = cs->caller->find_reference (symbol, cs->call_stmt, 4958 1.1 mrg cs->lto_stmt_uid, 4959 1.1 mrg IPA_REF_ADDR); 4960 1.1 mrg if (!to_del) 4961 1.1 mrg return; 4962 1.1 mrg to_del->remove_reference (); 4963 1.1 mrg ipa_zap_jf_refdesc (jfunc); 4964 1.1 mrg if (dump_file) 4965 1.1 mrg fprintf (dump_file, " Removed a reference from %s to %s.\n", 4966 1.1 mrg cs->caller->dump_name (), symbol->dump_name ()); 4967 1.1 mrg return; 4968 1.1 mrg } 4969 1.1 mrg 4970 1.1 mrg if (jfunc->type != IPA_JF_PASS_THROUGH 4971 1.1 mrg || ipa_get_jf_pass_through_operation (jfunc) != NOP_EXPR 4972 1.1 mrg || ipa_get_jf_pass_through_refdesc_decremented (jfunc)) 4973 1.1 mrg return; 4974 1.1 mrg 4975 1.1 mrg int fidx = ipa_get_jf_pass_through_formal_id (jfunc); 4976 1.1 mrg cgraph_node *caller = cs->caller; 4977 1.1 mrg ipa_node_params *caller_info = ipa_node_params_sum->get (caller); 4978 1.1 mrg /* TODO: This consistency check may be too big and not really 4979 1.1 mrg that useful. Consider removing it. */ 4980 1.1 mrg tree cst; 4981 1.1 mrg if (caller_info->ipcp_orig_node) 4982 1.1 mrg cst = caller_info->known_csts[fidx]; 4983 1.1 mrg else 4984 1.1 mrg { 4985 1.1 mrg ipcp_lattice<tree> *lat = ipa_get_scalar_lat (caller_info, fidx); 4986 1.1 mrg gcc_assert (lat->is_single_const ()); 4987 1.1 mrg cst = lat->values->value; 4988 1.1 mrg } 4989 1.1 mrg gcc_assert (TREE_CODE (cst) == ADDR_EXPR 4990 1.1 mrg && (symtab_node::get (get_base_address (TREE_OPERAND (cst, 0))) 4991 1.1 mrg == symbol)); 4992 1.1 mrg 4993 1.1 mrg int cuses = ipa_get_controlled_uses (caller_info, fidx); 4994 1.1 mrg if (cuses == IPA_UNDESCRIBED_USE) 4995 1.1 mrg return; 4996 1.1 mrg gcc_assert (cuses > 0); 4997 1.1 mrg cuses--; 4998 1.1 mrg ipa_set_controlled_uses (caller_info, fidx, cuses); 4999 1.1 mrg ipa_set_jf_pass_through_refdesc_decremented (jfunc, true); 5000 1.1 mrg if (dump_file && (dump_flags & TDF_DETAILS)) 5001 1.1 mrg fprintf (dump_file, " Controlled uses of parameter %i of %s dropped " 5002 1.1 mrg "to %i.\n", fidx, caller->dump_name (), cuses); 5003 1.1 mrg if (cuses) 5004 1.1 mrg return; 5005 1.1 mrg 5006 1.1 mrg if (caller_info->ipcp_orig_node) 5007 1.1 mrg { 5008 1.1 mrg /* Cloning machinery has created a reference here, we need to either 5009 1.1 mrg remove it or change it to a read one. */ 5010 1.1 mrg ipa_ref *to_del = caller->find_reference (symbol, NULL, 0, IPA_REF_ADDR); 5011 1.1 mrg if (to_del) 5012 1.1 mrg { 5013 1.1 mrg to_del->remove_reference (); 5014 1.1 mrg if (dump_file) 5015 1.1 mrg fprintf (dump_file, " Removed a reference from %s to %s.\n", 5016 1.1 mrg cs->caller->dump_name (), symbol->dump_name ()); 5017 1.1 mrg if (ipa_get_param_load_dereferenced (caller_info, fidx)) 5018 1.1 mrg { 5019 1.1 mrg caller->create_reference (symbol, IPA_REF_LOAD, NULL); 5020 1.1 mrg if (dump_file) 5021 1.1 mrg fprintf (dump_file, 5022 1.1 mrg " ...and replaced it with LOAD one.\n"); 5023 1.1 mrg } 5024 1.1 mrg } 5025 1.1 mrg } 5026 1.1 mrg 5027 1.1 mrg symbol_and_index_together pack; 5028 1.1 mrg pack.symbol = symbol; 5029 1.1 mrg pack.index = fidx; 5030 1.1 mrg if (caller->can_change_signature) 5031 1.1 mrg caller->call_for_symbol_thunks_and_aliases (adjust_refs_in_act_callers, 5032 1.1 mrg &pack, true); 5033 1.1 mrg } 5034 1.1 mrg 5035 1.1 mrg 5036 1.1 mrg /* Return true if we would like to remove a parameter from NODE when cloning it 5037 1.1 mrg with KNOWN_CSTS scalar constants. */ 5038 1.1 mrg 5039 1.1 mrg static bool 5040 1.1 mrg want_remove_some_param_p (cgraph_node *node, vec<tree> known_csts) 5041 1.1 mrg { 5042 1.1 mrg auto_vec<bool, 16> surviving; 5043 1.1 mrg bool filled_vec = false; 5044 1.1 mrg ipa_node_params *info = ipa_node_params_sum->get (node); 5045 1.1 mrg int i, count = ipa_get_param_count (info); 5046 1.1 mrg 5047 1.1 mrg for (i = 0; i < count; i++) 5048 1.1 mrg { 5049 1.1 mrg if (!known_csts[i] && ipa_is_param_used (info, i)) 5050 1.1 mrg continue; 5051 1.1 mrg 5052 1.1 mrg if (!filled_vec) 5053 1.1 mrg { 5054 1.1 mrg clone_info *info = clone_info::get (node); 5055 1.1 mrg if (!info || !info->param_adjustments) 5056 1.1 mrg return true; 5057 1.1 mrg info->param_adjustments->get_surviving_params (&surviving); 5058 1.1 mrg filled_vec = true; 5059 1.1 mrg } 5060 1.1 mrg if (surviving.length() < (unsigned) i && surviving[i]) 5061 1.1 mrg return true; 5062 1.1 mrg } 5063 1.1 mrg return false; 5064 1.1 mrg } 5065 1.1 mrg 5066 1.1 mrg /* Create a specialized version of NODE with known constants in KNOWN_CSTS, 5067 1.1 mrg known contexts in KNOWN_CONTEXTS and known aggregate values in AGGVALS and 5068 1.1 mrg redirect all edges in CALLERS to it. */ 5069 1.1 mrg 5070 1.1 mrg static struct cgraph_node * 5071 1.1 mrg create_specialized_node (struct cgraph_node *node, 5072 1.1 mrg vec<tree> known_csts, 5073 1.1 mrg vec<ipa_polymorphic_call_context> known_contexts, 5074 1.1 mrg struct ipa_agg_replacement_value *aggvals, 5075 1.1 mrg vec<cgraph_edge *> &callers) 5076 1.1 mrg { 5077 1.1 mrg ipa_node_params *new_info, *info = ipa_node_params_sum->get (node); 5078 1.1 mrg vec<ipa_replace_map *, va_gc> *replace_trees = NULL; 5079 1.1 mrg vec<ipa_adjusted_param, va_gc> *new_params = NULL; 5080 1.1 mrg struct ipa_agg_replacement_value *av; 5081 1.1 mrg struct cgraph_node *new_node; 5082 1.1 mrg int i, count = ipa_get_param_count (info); 5083 1.1 mrg clone_info *cinfo = clone_info::get (node); 5084 1.1 mrg ipa_param_adjustments *old_adjustments = cinfo 5085 1.1 mrg ? cinfo->param_adjustments : NULL; 5086 1.1 mrg ipa_param_adjustments *new_adjustments; 5087 1.1 mrg gcc_assert (!info->ipcp_orig_node); 5088 1.1 mrg gcc_assert (node->can_change_signature 5089 1.1 mrg || !old_adjustments); 5090 1.1 mrg 5091 1.1 mrg if (old_adjustments) 5092 1.1 mrg { 5093 1.1 mrg /* At the moment all IPA optimizations should use the number of 5094 1.1 mrg parameters of the prevailing decl as the m_always_copy_start. 5095 1.1 mrg Handling any other value would complicate the code below, so for the 5096 1.1 mrg time bing let's only assert it is so. */ 5097 1.1 mrg gcc_assert (old_adjustments->m_always_copy_start == count 5098 1.1 mrg || old_adjustments->m_always_copy_start < 0); 5099 1.1 mrg int old_adj_count = vec_safe_length (old_adjustments->m_adj_params); 5100 1.1 mrg for (i = 0; i < old_adj_count; i++) 5101 1.1 mrg { 5102 1.1 mrg ipa_adjusted_param *old_adj = &(*old_adjustments->m_adj_params)[i]; 5103 1.1 mrg if (!node->can_change_signature 5104 1.1 mrg || old_adj->op != IPA_PARAM_OP_COPY 5105 1.1 mrg || (!known_csts[old_adj->base_index] 5106 1.1 mrg && ipa_is_param_used (info, old_adj->base_index))) 5107 1.1 mrg { 5108 1.1 mrg ipa_adjusted_param new_adj = *old_adj; 5109 1.1 mrg 5110 1.1 mrg new_adj.prev_clone_adjustment = true; 5111 1.1 mrg new_adj.prev_clone_index = i; 5112 1.1 mrg vec_safe_push (new_params, new_adj); 5113 1.1 mrg } 5114 1.1 mrg } 5115 1.1 mrg bool skip_return = old_adjustments->m_skip_return; 5116 1.1 mrg new_adjustments = (new (ggc_alloc <ipa_param_adjustments> ()) 5117 1.1 mrg ipa_param_adjustments (new_params, count, 5118 1.1 mrg skip_return)); 5119 1.1 mrg } 5120 1.1 mrg else if (node->can_change_signature 5121 1.1 mrg && want_remove_some_param_p (node, known_csts)) 5122 1.1 mrg { 5123 1.1 mrg ipa_adjusted_param adj; 5124 1.1 mrg memset (&adj, 0, sizeof (adj)); 5125 1.1 mrg adj.op = IPA_PARAM_OP_COPY; 5126 1.1 mrg for (i = 0; i < count; i++) 5127 1.1 mrg if (!known_csts[i] && ipa_is_param_used (info, i)) 5128 1.1 mrg { 5129 1.1 mrg adj.base_index = i; 5130 1.1 mrg adj.prev_clone_index = i; 5131 1.1 mrg vec_safe_push (new_params, adj); 5132 1.1 mrg } 5133 1.1 mrg new_adjustments = (new (ggc_alloc <ipa_param_adjustments> ()) 5134 1.1 mrg ipa_param_adjustments (new_params, count, false)); 5135 1.1 mrg } 5136 1.1 mrg else 5137 1.1 mrg new_adjustments = NULL; 5138 1.1 mrg 5139 1.1 mrg auto_vec<cgraph_edge *, 2> self_recursive_calls; 5140 1.1 mrg for (i = callers.length () - 1; i >= 0; i--) 5141 1.1 mrg { 5142 1.1 mrg cgraph_edge *cs = callers[i]; 5143 1.1 mrg if (cs->caller == node) 5144 1.1 mrg { 5145 1.1 mrg self_recursive_calls.safe_push (cs); 5146 1.1 mrg callers.unordered_remove (i); 5147 1.1 mrg } 5148 1.1 mrg } 5149 1.1 mrg replace_trees = cinfo ? vec_safe_copy (cinfo->tree_map) : NULL; 5150 1.1 mrg for (i = 0; i < count; i++) 5151 1.1 mrg { 5152 1.1 mrg tree t = known_csts[i]; 5153 1.1 mrg if (!t) 5154 1.1 mrg continue; 5155 1.1 mrg 5156 1.1 mrg gcc_checking_assert (TREE_CODE (t) != TREE_BINFO); 5157 1.1 mrg 5158 1.1 mrg bool load_ref = false; 5159 1.1 mrg symtab_node *ref_symbol; 5160 1.1 mrg if (TREE_CODE (t) == ADDR_EXPR) 5161 1.1 mrg { 5162 1.1 mrg tree base = get_base_address (TREE_OPERAND (t, 0)); 5163 1.1 mrg if (TREE_CODE (base) == VAR_DECL 5164 1.1 mrg && ipa_get_controlled_uses (info, i) == 0 5165 1.1 mrg && ipa_get_param_load_dereferenced (info, i) 5166 1.1 mrg && (ref_symbol = symtab_node::get (base))) 5167 1.1 mrg { 5168 1.1 mrg load_ref = true; 5169 1.1 mrg if (node->can_change_signature) 5170 1.1 mrg for (cgraph_edge *caller : callers) 5171 1.1 mrg adjust_references_in_caller (caller, ref_symbol, i); 5172 1.1 mrg } 5173 1.1 mrg } 5174 1.1 mrg 5175 1.1 mrg ipa_replace_map *replace_map = get_replacement_map (info, t, i, load_ref); 5176 1.1 mrg if (replace_map) 5177 1.1 mrg vec_safe_push (replace_trees, replace_map); 5178 1.1 mrg } 5179 1.1 mrg 5180 1.1 mrg unsigned &suffix_counter = clone_num_suffixes->get_or_insert ( 5181 1.1 mrg IDENTIFIER_POINTER (DECL_ASSEMBLER_NAME ( 5182 1.1 mrg node->decl))); 5183 1.1 mrg new_node = node->create_virtual_clone (callers, replace_trees, 5184 1.1 mrg new_adjustments, "constprop", 5185 1.1 mrg suffix_counter); 5186 1.1 mrg suffix_counter++; 5187 1.1 mrg 5188 1.1 mrg bool have_self_recursive_calls = !self_recursive_calls.is_empty (); 5189 1.1 mrg for (unsigned j = 0; j < self_recursive_calls.length (); j++) 5190 1.1 mrg { 5191 1.1 mrg cgraph_edge *cs = get_next_cgraph_edge_clone (self_recursive_calls[j]); 5192 1.1 mrg /* Cloned edges can disappear during cloning as speculation can be 5193 1.1 mrg resolved, check that we have one and that it comes from the last 5194 1.1 mrg cloning. */ 5195 1.1 mrg if (cs && cs->caller == new_node) 5196 1.1 mrg cs->redirect_callee_duplicating_thunks (new_node); 5197 1.1 mrg /* Any future code that would make more than one clone of an outgoing 5198 1.1 mrg edge would confuse this mechanism, so let's check that does not 5199 1.1 mrg happen. */ 5200 1.1 mrg gcc_checking_assert (!cs 5201 1.1 mrg || !get_next_cgraph_edge_clone (cs) 5202 1.1 mrg || get_next_cgraph_edge_clone (cs)->caller != new_node); 5203 1.1 mrg } 5204 1.1 mrg if (have_self_recursive_calls) 5205 1.1 mrg new_node->expand_all_artificial_thunks (); 5206 1.1 mrg 5207 1.1 mrg ipa_set_node_agg_value_chain (new_node, aggvals); 5208 1.1 mrg for (av = aggvals; av; av = av->next) 5209 1.1 mrg new_node->maybe_create_reference (av->value, NULL); 5210 1.1 mrg 5211 1.1 mrg if (dump_file && (dump_flags & TDF_DETAILS)) 5212 1.1 mrg { 5213 1.1 mrg fprintf (dump_file, " the new node is %s.\n", new_node->dump_name ()); 5214 1.1 mrg if (known_contexts.exists ()) 5215 1.1 mrg { 5216 1.1 mrg for (i = 0; i < count; i++) 5217 1.1 mrg if (!known_contexts[i].useless_p ()) 5218 1.1 mrg { 5219 1.1 mrg fprintf (dump_file, " known ctx %i is ", i); 5220 1.1 mrg known_contexts[i].dump (dump_file); 5221 1.1 mrg } 5222 1.1 mrg } 5223 1.1 mrg if (aggvals) 5224 1.1 mrg ipa_dump_agg_replacement_values (dump_file, aggvals); 5225 1.1 mrg } 5226 1.1 mrg 5227 1.1 mrg new_info = ipa_node_params_sum->get (new_node); 5228 1.1 mrg new_info->ipcp_orig_node = node; 5229 1.1 mrg new_node->ipcp_clone = true; 5230 1.1 mrg new_info->known_csts = known_csts; 5231 1.1 mrg new_info->known_contexts = known_contexts; 5232 1.1 mrg 5233 1.1 mrg ipcp_discover_new_direct_edges (new_node, known_csts, known_contexts, aggvals); 5234 1.1 mrg 5235 1.1 mrg return new_node; 5236 1.1 mrg } 5237 1.1 mrg 5238 1.1 mrg /* Return true if JFUNC, which describes a i-th parameter of call CS, is a 5239 1.1 mrg pass-through function to itself when the cgraph_node involved is not an 5240 1.1 mrg IPA-CP clone. When SIMPLE is true, further check if JFUNC is a simple 5241 1.1 mrg no-operation pass-through. */ 5242 1.1 mrg 5243 1.1 mrg static bool 5244 1.1 mrg self_recursive_pass_through_p (cgraph_edge *cs, ipa_jump_func *jfunc, int i, 5245 1.1 mrg bool simple = true) 5246 1.1 mrg { 5247 1.1 mrg enum availability availability; 5248 1.1 mrg if (cs->caller == cs->callee->function_symbol (&availability) 5249 1.1 mrg && availability > AVAIL_INTERPOSABLE 5250 1.1 mrg && jfunc->type == IPA_JF_PASS_THROUGH 5251 1.1 mrg && (!simple || ipa_get_jf_pass_through_operation (jfunc) == NOP_EXPR) 5252 1.1 mrg && ipa_get_jf_pass_through_formal_id (jfunc) == i 5253 1.1 mrg && ipa_node_params_sum->get (cs->caller) 5254 1.1 mrg && !ipa_node_params_sum->get (cs->caller)->ipcp_orig_node) 5255 1.1 mrg return true; 5256 1.1 mrg return false; 5257 1.1 mrg } 5258 1.1 mrg 5259 1.1 mrg /* Return true if JFUNC, which describes a part of an aggregate represented or 5260 1.1 mrg pointed to by the i-th parameter of call CS, is a pass-through function to 5261 1.1 mrg itself when the cgraph_node involved is not an IPA-CP clone.. When 5262 1.1 mrg SIMPLE is true, further check if JFUNC is a simple no-operation 5263 1.1 mrg pass-through. */ 5264 1.1 mrg 5265 1.1 mrg static bool 5266 1.1 mrg self_recursive_agg_pass_through_p (cgraph_edge *cs, ipa_agg_jf_item *jfunc, 5267 1.1 mrg int i, bool simple = true) 5268 1.1 mrg { 5269 1.1 mrg enum availability availability; 5270 1.1 mrg if (cs->caller == cs->callee->function_symbol (&availability) 5271 1.1 mrg && availability > AVAIL_INTERPOSABLE 5272 1.1 mrg && jfunc->jftype == IPA_JF_LOAD_AGG 5273 1.1 mrg && jfunc->offset == jfunc->value.load_agg.offset 5274 1.1 mrg && (!simple || jfunc->value.pass_through.operation == NOP_EXPR) 5275 1.1 mrg && jfunc->value.pass_through.formal_id == i 5276 1.1 mrg && useless_type_conversion_p (jfunc->value.load_agg.type, jfunc->type) 5277 1.1 mrg && ipa_node_params_sum->get (cs->caller) 5278 1.1 mrg && !ipa_node_params_sum->get (cs->caller)->ipcp_orig_node) 5279 1.1 mrg return true; 5280 1.1 mrg return false; 5281 1.1 mrg } 5282 1.1 mrg 5283 1.1 mrg /* Given a NODE, and a subset of its CALLERS, try to populate blanks slots in 5284 1.1 mrg KNOWN_CSTS with constants that are also known for all of the CALLERS. */ 5285 1.1 mrg 5286 1.1 mrg static void 5287 1.1 mrg find_more_scalar_values_for_callers_subset (struct cgraph_node *node, 5288 1.1 mrg vec<tree> &known_csts, 5289 1.1 mrg const vec<cgraph_edge *> &callers) 5290 1.1 mrg { 5291 1.1 mrg ipa_node_params *info = ipa_node_params_sum->get (node); 5292 1.1 mrg int i, count = ipa_get_param_count (info); 5293 1.1 mrg 5294 1.1 mrg for (i = 0; i < count; i++) 5295 1.1 mrg { 5296 1.1 mrg struct cgraph_edge *cs; 5297 1.1 mrg tree newval = NULL_TREE; 5298 1.1 mrg int j; 5299 1.1 mrg bool first = true; 5300 1.1 mrg tree type = ipa_get_type (info, i); 5301 1.1 mrg 5302 1.1 mrg if (ipa_get_scalar_lat (info, i)->bottom || known_csts[i]) 5303 1.1 mrg continue; 5304 1.1 mrg 5305 1.1 mrg FOR_EACH_VEC_ELT (callers, j, cs) 5306 1.1 mrg { 5307 1.1 mrg struct ipa_jump_func *jump_func; 5308 1.1 mrg tree t; 5309 1.1 mrg 5310 1.1 mrg ipa_edge_args *args = ipa_edge_args_sum->get (cs); 5311 1.1 mrg if (!args 5312 1.1 mrg || i >= ipa_get_cs_argument_count (args) 5313 1.1 mrg || (i == 0 5314 1.1 mrg && call_passes_through_thunk (cs))) 5315 1.1 mrg { 5316 1.1 mrg newval = NULL_TREE; 5317 1.1 mrg break; 5318 1.1 mrg } 5319 1.1 mrg jump_func = ipa_get_ith_jump_func (args, i); 5320 1.1 mrg 5321 1.1 mrg /* Besides simple pass-through jump function, arithmetic jump 5322 1.1 mrg function could also introduce argument-direct-pass-through for 5323 1.1 mrg self-feeding recursive call. For example, 5324 1.1 mrg 5325 1.1 mrg fn (int i) 5326 1.1 mrg { 5327 1.1 mrg fn (i & 1); 5328 1.1 mrg } 5329 1.1 mrg 5330 1.1 mrg Given that i is 0, recursive propagation via (i & 1) also gets 5331 1.1 mrg 0. */ 5332 1.1 mrg if (self_recursive_pass_through_p (cs, jump_func, i, false)) 5333 1.1 mrg { 5334 1.1 mrg gcc_assert (newval); 5335 1.1 mrg t = ipa_get_jf_arith_result ( 5336 1.1 mrg ipa_get_jf_pass_through_operation (jump_func), 5337 1.1 mrg newval, 5338 1.1 mrg ipa_get_jf_pass_through_operand (jump_func), 5339 1.1 mrg type); 5340 1.1 mrg } 5341 1.1 mrg else 5342 1.1 mrg t = ipa_value_from_jfunc (ipa_node_params_sum->get (cs->caller), 5343 1.1 mrg jump_func, type); 5344 1.1 mrg if (!t 5345 1.1 mrg || (newval 5346 1.1 mrg && !values_equal_for_ipcp_p (t, newval)) 5347 1.1 mrg || (!first && !newval)) 5348 1.1 mrg { 5349 1.1 mrg newval = NULL_TREE; 5350 1.1 mrg break; 5351 1.1 mrg } 5352 1.1 mrg else 5353 1.1 mrg newval = t; 5354 1.1 mrg first = false; 5355 1.1 mrg } 5356 1.1 mrg 5357 1.1 mrg if (newval) 5358 1.1 mrg { 5359 1.1 mrg if (dump_file && (dump_flags & TDF_DETAILS)) 5360 1.1 mrg { 5361 1.1 mrg fprintf (dump_file, " adding an extra known scalar value "); 5362 1.1 mrg print_ipcp_constant_value (dump_file, newval); 5363 1.1 mrg fprintf (dump_file, " for "); 5364 1.1 mrg ipa_dump_param (dump_file, info, i); 5365 1.1 mrg fprintf (dump_file, "\n"); 5366 1.1 mrg } 5367 1.1 mrg 5368 1.1 mrg known_csts[i] = newval; 5369 1.1 mrg } 5370 1.1 mrg } 5371 1.1 mrg } 5372 1.1 mrg 5373 1.1 mrg /* Given a NODE and a subset of its CALLERS, try to populate plank slots in 5374 1.1 mrg KNOWN_CONTEXTS with polymorphic contexts that are also known for all of the 5375 1.1 mrg CALLERS. */ 5376 1.1 mrg 5377 1.1 mrg static void 5378 1.1 mrg find_more_contexts_for_caller_subset (cgraph_node *node, 5379 1.1 mrg vec<ipa_polymorphic_call_context> 5380 1.1 mrg *known_contexts, 5381 1.1 mrg const vec<cgraph_edge *> &callers) 5382 1.1 mrg { 5383 1.1 mrg ipa_node_params *info = ipa_node_params_sum->get (node); 5384 1.1 mrg int i, count = ipa_get_param_count (info); 5385 1.1 mrg 5386 1.1 mrg for (i = 0; i < count; i++) 5387 1.1 mrg { 5388 1.1 mrg cgraph_edge *cs; 5389 1.1 mrg 5390 1.1 mrg if (ipa_get_poly_ctx_lat (info, i)->bottom 5391 1.1 mrg || (known_contexts->exists () 5392 1.1 mrg && !(*known_contexts)[i].useless_p ())) 5393 1.1 mrg continue; 5394 1.1 mrg 5395 1.1 mrg ipa_polymorphic_call_context newval; 5396 1.1 mrg bool first = true; 5397 1.1 mrg int j; 5398 1.1 mrg 5399 1.1 mrg FOR_EACH_VEC_ELT (callers, j, cs) 5400 1.1 mrg { 5401 1.1 mrg ipa_edge_args *args = ipa_edge_args_sum->get (cs); 5402 1.1 mrg if (!args 5403 1.1 mrg || i >= ipa_get_cs_argument_count (args)) 5404 1.1 mrg return; 5405 1.1 mrg ipa_jump_func *jfunc = ipa_get_ith_jump_func (args, i); 5406 1.1 mrg ipa_polymorphic_call_context ctx; 5407 1.1 mrg ctx = ipa_context_from_jfunc (ipa_node_params_sum->get (cs->caller), 5408 1.1 mrg cs, i, jfunc); 5409 1.1 mrg if (first) 5410 1.1 mrg { 5411 1.1 mrg newval = ctx; 5412 1.1 mrg first = false; 5413 1.1 mrg } 5414 1.1 mrg else 5415 1.1 mrg newval.meet_with (ctx); 5416 1.1 mrg if (newval.useless_p ()) 5417 1.1 mrg break; 5418 1.1 mrg } 5419 1.1 mrg 5420 1.1 mrg if (!newval.useless_p ()) 5421 1.1 mrg { 5422 1.1 mrg if (dump_file && (dump_flags & TDF_DETAILS)) 5423 1.1 mrg { 5424 1.1 mrg fprintf (dump_file, " adding an extra known polymorphic " 5425 1.1 mrg "context "); 5426 1.1 mrg print_ipcp_constant_value (dump_file, newval); 5427 1.1 mrg fprintf (dump_file, " for "); 5428 1.1 mrg ipa_dump_param (dump_file, info, i); 5429 1.1 mrg fprintf (dump_file, "\n"); 5430 1.1 mrg } 5431 1.1 mrg 5432 1.1 mrg if (!known_contexts->exists ()) 5433 1.1 mrg known_contexts->safe_grow_cleared (ipa_get_param_count (info), 5434 1.1 mrg true); 5435 1.1 mrg (*known_contexts)[i] = newval; 5436 1.1 mrg } 5437 1.1 mrg 5438 1.1 mrg } 5439 1.1 mrg } 5440 1.1 mrg 5441 1.1 mrg /* Go through PLATS and create a vector of values consisting of values and 5442 1.1 mrg offsets (minus OFFSET) of lattices that contain only a single value. */ 5443 1.1 mrg 5444 1.1 mrg static vec<ipa_agg_value> 5445 1.1 mrg copy_plats_to_inter (class ipcp_param_lattices *plats, HOST_WIDE_INT offset) 5446 1.1 mrg { 5447 1.1 mrg vec<ipa_agg_value> res = vNULL; 5448 1.1 mrg 5449 1.1 mrg if (!plats->aggs || plats->aggs_contain_variable || plats->aggs_bottom) 5450 1.1 mrg return vNULL; 5451 1.1 mrg 5452 1.1 mrg for (struct ipcp_agg_lattice *aglat = plats->aggs; aglat; aglat = aglat->next) 5453 1.1 mrg if (aglat->is_single_const ()) 5454 1.1 mrg { 5455 1.1 mrg struct ipa_agg_value ti; 5456 1.1 mrg ti.offset = aglat->offset - offset; 5457 1.1 mrg ti.value = aglat->values->value; 5458 1.1 mrg res.safe_push (ti); 5459 1.1 mrg } 5460 1.1 mrg return res; 5461 1.1 mrg } 5462 1.1 mrg 5463 1.1 mrg /* Intersect all values in INTER with single value lattices in PLATS (while 5464 1.1 mrg subtracting OFFSET). */ 5465 1.1 mrg 5466 1.1 mrg static void 5467 1.1 mrg intersect_with_plats (class ipcp_param_lattices *plats, 5468 1.1 mrg vec<ipa_agg_value> *inter, 5469 1.1 mrg HOST_WIDE_INT offset) 5470 1.1 mrg { 5471 1.1 mrg struct ipcp_agg_lattice *aglat; 5472 1.1 mrg struct ipa_agg_value *item; 5473 1.1 mrg int k; 5474 1.1 mrg 5475 1.1 mrg if (!plats->aggs || plats->aggs_contain_variable || plats->aggs_bottom) 5476 1.1 mrg { 5477 1.1 mrg inter->release (); 5478 1.1 mrg return; 5479 1.1 mrg } 5480 1.1 mrg 5481 1.1 mrg aglat = plats->aggs; 5482 1.1 mrg FOR_EACH_VEC_ELT (*inter, k, item) 5483 1.1 mrg { 5484 1.1 mrg bool found = false; 5485 1.1 mrg if (!item->value) 5486 1.1 mrg continue; 5487 1.1 mrg while (aglat) 5488 1.1 mrg { 5489 1.1 mrg if (aglat->offset - offset > item->offset) 5490 1.1 mrg break; 5491 1.1 mrg if (aglat->offset - offset == item->offset) 5492 1.1 mrg { 5493 1.1 mrg if (aglat->is_single_const ()) 5494 1.1 mrg { 5495 1.1 mrg tree value = aglat->values->value; 5496 1.1 mrg 5497 1.1 mrg if (values_equal_for_ipcp_p (item->value, value)) 5498 1.1 mrg found = true; 5499 1.1 mrg } 5500 1.1 mrg break; 5501 1.1 mrg } 5502 1.1 mrg aglat = aglat->next; 5503 1.1 mrg } 5504 1.1 mrg if (!found) 5505 1.1 mrg item->value = NULL_TREE; 5506 1.1 mrg } 5507 1.1 mrg } 5508 1.1 mrg 5509 1.1 mrg /* Copy aggregate replacement values of NODE (which is an IPA-CP clone) to the 5510 1.1 mrg vector result while subtracting OFFSET from the individual value offsets. */ 5511 1.1 mrg 5512 1.1 mrg static vec<ipa_agg_value> 5513 1.1 mrg agg_replacements_to_vector (struct cgraph_node *node, int index, 5514 1.1 mrg HOST_WIDE_INT offset) 5515 1.1 mrg { 5516 1.1 mrg struct ipa_agg_replacement_value *av; 5517 1.1 mrg vec<ipa_agg_value> res = vNULL; 5518 1.1 mrg 5519 1.1 mrg for (av = ipa_get_agg_replacements_for_node (node); av; av = av->next) 5520 1.1 mrg if (av->index == index 5521 1.1 mrg && (av->offset - offset) >= 0) 5522 1.1 mrg { 5523 1.1 mrg struct ipa_agg_value item; 5524 1.1 mrg gcc_checking_assert (av->value); 5525 1.1 mrg item.offset = av->offset - offset; 5526 1.1 mrg item.value = av->value; 5527 1.1 mrg res.safe_push (item); 5528 1.1 mrg } 5529 1.1 mrg 5530 1.1 mrg return res; 5531 1.1 mrg } 5532 1.1 mrg 5533 1.1 mrg /* Intersect all values in INTER with those that we have already scheduled to 5534 1.1 mrg be replaced in parameter number INDEX of NODE, which is an IPA-CP clone 5535 1.1 mrg (while subtracting OFFSET). */ 5536 1.1 mrg 5537 1.1 mrg static void 5538 1.1 mrg intersect_with_agg_replacements (struct cgraph_node *node, int index, 5539 1.1 mrg vec<ipa_agg_value> *inter, 5540 1.1 mrg HOST_WIDE_INT offset) 5541 1.1 mrg { 5542 1.1 mrg struct ipa_agg_replacement_value *srcvals; 5543 1.1 mrg struct ipa_agg_value *item; 5544 1.1 mrg int i; 5545 1.1 mrg 5546 1.1 mrg srcvals = ipa_get_agg_replacements_for_node (node); 5547 1.1 mrg if (!srcvals) 5548 1.1 mrg { 5549 1.1 mrg inter->release (); 5550 1.1 mrg return; 5551 1.1 mrg } 5552 1.1 mrg 5553 1.1 mrg FOR_EACH_VEC_ELT (*inter, i, item) 5554 1.1 mrg { 5555 1.1 mrg struct ipa_agg_replacement_value *av; 5556 1.1 mrg bool found = false; 5557 1.1 mrg if (!item->value) 5558 1.1 mrg continue; 5559 1.1 mrg for (av = srcvals; av; av = av->next) 5560 1.1 mrg { 5561 1.1 mrg gcc_checking_assert (av->value); 5562 1.1 mrg if (av->index == index 5563 1.1 mrg && av->offset - offset == item->offset) 5564 1.1 mrg { 5565 1.1 mrg if (values_equal_for_ipcp_p (item->value, av->value)) 5566 1.1 mrg found = true; 5567 1.1 mrg break; 5568 1.1 mrg } 5569 1.1 mrg } 5570 1.1 mrg if (!found) 5571 1.1 mrg item->value = NULL_TREE; 5572 1.1 mrg } 5573 1.1 mrg } 5574 1.1 mrg 5575 1.1 mrg /* Intersect values in INTER with aggregate values that come along edge CS to 5576 1.1 mrg parameter number INDEX and return it. If INTER does not actually exist yet, 5577 1.1 mrg copy all incoming values to it. If we determine we ended up with no values 5578 1.1 mrg whatsoever, return a released vector. */ 5579 1.1 mrg 5580 1.1 mrg static vec<ipa_agg_value> 5581 1.1 mrg intersect_aggregates_with_edge (struct cgraph_edge *cs, int index, 5582 1.1 mrg vec<ipa_agg_value> inter) 5583 1.1 mrg { 5584 1.1 mrg struct ipa_jump_func *jfunc; 5585 1.1 mrg jfunc = ipa_get_ith_jump_func (ipa_edge_args_sum->get (cs), index); 5586 1.1 mrg if (jfunc->type == IPA_JF_PASS_THROUGH 5587 1.1 mrg && ipa_get_jf_pass_through_operation (jfunc) == NOP_EXPR) 5588 1.1 mrg { 5589 1.1 mrg ipa_node_params *caller_info = ipa_node_params_sum->get (cs->caller); 5590 1.1 mrg int src_idx = ipa_get_jf_pass_through_formal_id (jfunc); 5591 1.1 mrg 5592 1.1 mrg if (caller_info->ipcp_orig_node) 5593 1.1 mrg { 5594 1.1 mrg struct cgraph_node *orig_node = caller_info->ipcp_orig_node; 5595 1.1 mrg class ipcp_param_lattices *orig_plats; 5596 1.1 mrg ipa_node_params *orig_info = ipa_node_params_sum->get (orig_node); 5597 1.1 mrg orig_plats = ipa_get_parm_lattices (orig_info, src_idx); 5598 1.1 mrg if (agg_pass_through_permissible_p (orig_plats, jfunc)) 5599 1.1 mrg { 5600 1.1 mrg if (!inter.exists ()) 5601 1.1 mrg inter = agg_replacements_to_vector (cs->caller, src_idx, 0); 5602 1.1 mrg else 5603 1.1 mrg intersect_with_agg_replacements (cs->caller, src_idx, 5604 1.1 mrg &inter, 0); 5605 1.1 mrg return inter; 5606 1.1 mrg } 5607 1.1 mrg } 5608 1.1 mrg else 5609 1.1 mrg { 5610 1.1 mrg class ipcp_param_lattices *src_plats; 5611 1.1 mrg src_plats = ipa_get_parm_lattices (caller_info, src_idx); 5612 1.1 mrg if (agg_pass_through_permissible_p (src_plats, jfunc)) 5613 1.1 mrg { 5614 1.1 mrg /* Currently we do not produce clobber aggregate jump 5615 1.1 mrg functions, adjust when we do. */ 5616 1.1 mrg gcc_checking_assert (!jfunc->agg.items); 5617 1.1 mrg if (!inter.exists ()) 5618 1.1 mrg inter = copy_plats_to_inter (src_plats, 0); 5619 1.1 mrg else 5620 1.1 mrg intersect_with_plats (src_plats, &inter, 0); 5621 1.1 mrg return inter; 5622 1.1 mrg } 5623 1.1 mrg } 5624 1.1 mrg } 5625 1.1 mrg else if (jfunc->type == IPA_JF_ANCESTOR 5626 1.1 mrg && ipa_get_jf_ancestor_agg_preserved (jfunc)) 5627 1.1 mrg { 5628 1.1 mrg ipa_node_params *caller_info = ipa_node_params_sum->get (cs->caller); 5629 1.1 mrg int src_idx = ipa_get_jf_ancestor_formal_id (jfunc); 5630 1.1 mrg class ipcp_param_lattices *src_plats; 5631 1.1 mrg HOST_WIDE_INT delta = ipa_get_jf_ancestor_offset (jfunc); 5632 1.1 mrg 5633 1.1 mrg if (caller_info->ipcp_orig_node) 5634 1.1 mrg { 5635 1.1 mrg if (!inter.exists ()) 5636 1.1 mrg inter = agg_replacements_to_vector (cs->caller, src_idx, delta); 5637 1.1 mrg else 5638 1.1 mrg intersect_with_agg_replacements (cs->caller, src_idx, &inter, 5639 1.1 mrg delta); 5640 1.1 mrg } 5641 1.1 mrg else 5642 1.1 mrg { 5643 1.1 mrg src_plats = ipa_get_parm_lattices (caller_info, src_idx); 5644 1.1 mrg /* Currently we do not produce clobber aggregate jump 5645 1.1 mrg functions, adjust when we do. */ 5646 1.1 mrg gcc_checking_assert (!src_plats->aggs || !jfunc->agg.items); 5647 1.1 mrg if (!inter.exists ()) 5648 1.1 mrg inter = copy_plats_to_inter (src_plats, delta); 5649 1.1 mrg else 5650 1.1 mrg intersect_with_plats (src_plats, &inter, delta); 5651 1.1 mrg } 5652 1.1 mrg return inter; 5653 1.1 mrg } 5654 1.1 mrg 5655 1.1 mrg if (jfunc->agg.items) 5656 1.1 mrg { 5657 1.1 mrg ipa_node_params *caller_info = ipa_node_params_sum->get (cs->caller); 5658 1.1 mrg struct ipa_agg_value *item; 5659 1.1 mrg int k; 5660 1.1 mrg 5661 1.1 mrg if (!inter.exists ()) 5662 1.1 mrg for (unsigned i = 0; i < jfunc->agg.items->length (); i++) 5663 1.1 mrg { 5664 1.1 mrg struct ipa_agg_jf_item *agg_item = &(*jfunc->agg.items)[i]; 5665 1.1 mrg tree value = ipa_agg_value_from_node (caller_info, cs->caller, 5666 1.1 mrg agg_item); 5667 1.1 mrg if (value) 5668 1.1 mrg { 5669 1.1 mrg struct ipa_agg_value agg_value; 5670 1.1 mrg 5671 1.1 mrg agg_value.value = value; 5672 1.1 mrg agg_value.offset = agg_item->offset; 5673 1.1 mrg inter.safe_push (agg_value); 5674 1.1 mrg } 5675 1.1 mrg } 5676 1.1 mrg else 5677 1.1 mrg FOR_EACH_VEC_ELT (inter, k, item) 5678 1.1 mrg { 5679 1.1 mrg int l = 0; 5680 1.1 mrg bool found = false; 5681 1.1 mrg 5682 1.1 mrg if (!item->value) 5683 1.1 mrg continue; 5684 1.1 mrg 5685 1.1 mrg while ((unsigned) l < jfunc->agg.items->length ()) 5686 1.1 mrg { 5687 1.1 mrg struct ipa_agg_jf_item *ti; 5688 1.1 mrg ti = &(*jfunc->agg.items)[l]; 5689 1.1 mrg if (ti->offset > item->offset) 5690 1.1 mrg break; 5691 1.1 mrg if (ti->offset == item->offset) 5692 1.1 mrg { 5693 1.1 mrg tree value; 5694 1.1 mrg 5695 1.1 mrg /* Besides simple pass-through aggregate jump function, 5696 1.1 mrg arithmetic aggregate jump function could also bring 5697 1.1 mrg same aggregate value as parameter passed-in for 5698 1.1 mrg self-feeding recursive call. For example, 5699 1.1 mrg 5700 1.1 mrg fn (int *i) 5701 1.1 mrg { 5702 1.1 mrg int j = *i & 1; 5703 1.1 mrg fn (&j); 5704 1.1 mrg } 5705 1.1 mrg 5706 1.1 mrg Given that *i is 0, recursive propagation via (*i & 1) 5707 1.1 mrg also gets 0. */ 5708 1.1 mrg if (self_recursive_agg_pass_through_p (cs, ti, index, 5709 1.1 mrg false)) 5710 1.1 mrg value = ipa_get_jf_arith_result ( 5711 1.1 mrg ti->value.pass_through.operation, 5712 1.1 mrg item->value, 5713 1.1 mrg ti->value.pass_through.operand, 5714 1.1 mrg ti->type); 5715 1.1 mrg else 5716 1.1 mrg value = ipa_agg_value_from_node (caller_info, 5717 1.1 mrg cs->caller, ti); 5718 1.1 mrg 5719 1.1 mrg if (value && values_equal_for_ipcp_p (item->value, value)) 5720 1.1 mrg found = true; 5721 1.1 mrg break; 5722 1.1 mrg } 5723 1.1 mrg l++; 5724 1.1 mrg } 5725 1.1 mrg if (!found) 5726 1.1 mrg item->value = NULL; 5727 1.1 mrg } 5728 1.1 mrg } 5729 1.1 mrg else 5730 1.1 mrg { 5731 1.1 mrg inter.release (); 5732 1.1 mrg return vNULL; 5733 1.1 mrg } 5734 1.1 mrg return inter; 5735 1.1 mrg } 5736 1.1 mrg 5737 1.1 mrg /* Look at edges in CALLERS and collect all known aggregate values that arrive 5738 1.1 mrg from all of them. */ 5739 1.1 mrg 5740 1.1 mrg static struct ipa_agg_replacement_value * 5741 1.1 mrg find_aggregate_values_for_callers_subset (struct cgraph_node *node, 5742 1.1 mrg const vec<cgraph_edge *> &callers) 5743 1.1 mrg { 5744 1.1 mrg ipa_node_params *dest_info = ipa_node_params_sum->get (node); 5745 1.1 mrg struct ipa_agg_replacement_value *res; 5746 1.1 mrg struct ipa_agg_replacement_value **tail = &res; 5747 1.1 mrg struct cgraph_edge *cs; 5748 1.1 mrg int i, j, count = ipa_get_param_count (dest_info); 5749 1.1 mrg 5750 1.1 mrg FOR_EACH_VEC_ELT (callers, j, cs) 5751 1.1 mrg { 5752 1.1 mrg ipa_edge_args *args = ipa_edge_args_sum->get (cs); 5753 1.1 mrg if (!args) 5754 1.1 mrg { 5755 1.1 mrg count = 0; 5756 1.1 mrg break; 5757 1.1 mrg } 5758 1.1 mrg int c = ipa_get_cs_argument_count (args); 5759 1.1 mrg if (c < count) 5760 1.1 mrg count = c; 5761 1.1 mrg } 5762 1.1 mrg 5763 1.1 mrg for (i = 0; i < count; i++) 5764 1.1 mrg { 5765 1.1 mrg struct cgraph_edge *cs; 5766 1.1 mrg vec<ipa_agg_value> inter = vNULL; 5767 1.1 mrg struct ipa_agg_value *item; 5768 1.1 mrg class ipcp_param_lattices *plats = ipa_get_parm_lattices (dest_info, i); 5769 1.1 mrg int j; 5770 1.1 mrg 5771 1.1 mrg /* Among other things, the following check should deal with all by_ref 5772 1.1 mrg mismatches. */ 5773 1.1 mrg if (plats->aggs_bottom) 5774 1.1 mrg continue; 5775 1.1 mrg 5776 1.1 mrg FOR_EACH_VEC_ELT (callers, j, cs) 5777 1.1 mrg { 5778 1.1 mrg struct ipa_jump_func *jfunc 5779 1.1 mrg = ipa_get_ith_jump_func (ipa_edge_args_sum->get (cs), i); 5780 1.1 mrg if (self_recursive_pass_through_p (cs, jfunc, i) 5781 1.1 mrg && (!plats->aggs_by_ref 5782 1.1 mrg || ipa_get_jf_pass_through_agg_preserved (jfunc))) 5783 1.1 mrg continue; 5784 1.1 mrg inter = intersect_aggregates_with_edge (cs, i, inter); 5785 1.1 mrg 5786 1.1 mrg if (!inter.exists ()) 5787 1.1 mrg goto next_param; 5788 1.1 mrg } 5789 1.1 mrg 5790 1.1 mrg FOR_EACH_VEC_ELT (inter, j, item) 5791 1.1 mrg { 5792 1.1 mrg struct ipa_agg_replacement_value *v; 5793 1.1 mrg 5794 1.1 mrg if (!item->value) 5795 1.1 mrg continue; 5796 1.1 mrg 5797 1.1 mrg v = ggc_alloc<ipa_agg_replacement_value> (); 5798 1.1 mrg v->index = i; 5799 1.1 mrg v->offset = item->offset; 5800 1.1 mrg v->value = item->value; 5801 1.1 mrg v->by_ref = plats->aggs_by_ref; 5802 1.1 mrg *tail = v; 5803 1.1 mrg tail = &v->next; 5804 1.1 mrg } 5805 1.1 mrg 5806 1.1 mrg next_param: 5807 1.1 mrg if (inter.exists ()) 5808 1.1 mrg inter.release (); 5809 1.1 mrg } 5810 1.1 mrg *tail = NULL; 5811 1.1 mrg return res; 5812 1.1 mrg } 5813 1.1 mrg 5814 1.1 mrg /* Determine whether CS also brings all scalar values that the NODE is 5815 1.1 mrg specialized for. */ 5816 1.1 mrg 5817 1.1 mrg static bool 5818 1.1 mrg cgraph_edge_brings_all_scalars_for_node (struct cgraph_edge *cs, 5819 1.1 mrg struct cgraph_node *node) 5820 1.1 mrg { 5821 1.1 mrg ipa_node_params *dest_info = ipa_node_params_sum->get (node); 5822 1.1 mrg int count = ipa_get_param_count (dest_info); 5823 1.1 mrg class ipa_node_params *caller_info; 5824 1.1 mrg class ipa_edge_args *args; 5825 1.1 mrg int i; 5826 1.1 mrg 5827 1.1 mrg caller_info = ipa_node_params_sum->get (cs->caller); 5828 1.1 mrg args = ipa_edge_args_sum->get (cs); 5829 1.1 mrg for (i = 0; i < count; i++) 5830 1.1 mrg { 5831 1.1 mrg struct ipa_jump_func *jump_func; 5832 1.1 mrg tree val, t; 5833 1.1 mrg 5834 1.1 mrg val = dest_info->known_csts[i]; 5835 1.1 mrg if (!val) 5836 1.1 mrg continue; 5837 1.1 mrg 5838 1.1 mrg if (i >= ipa_get_cs_argument_count (args)) 5839 1.1 mrg return false; 5840 1.1 mrg jump_func = ipa_get_ith_jump_func (args, i); 5841 1.1 mrg t = ipa_value_from_jfunc (caller_info, jump_func, 5842 1.1 mrg ipa_get_type (dest_info, i)); 5843 1.1 mrg if (!t || !values_equal_for_ipcp_p (val, t)) 5844 1.1 mrg return false; 5845 1.1 mrg } 5846 1.1 mrg return true; 5847 1.1 mrg } 5848 1.1 mrg 5849 1.1 mrg /* Determine whether CS also brings all aggregate values that NODE is 5850 1.1 mrg specialized for. */ 5851 1.1 mrg static bool 5852 1.1 mrg cgraph_edge_brings_all_agg_vals_for_node (struct cgraph_edge *cs, 5853 1.1 mrg struct cgraph_node *node) 5854 1.1 mrg { 5855 1.1 mrg struct ipa_agg_replacement_value *aggval; 5856 1.1 mrg int i, ec, count; 5857 1.1 mrg 5858 1.1 mrg aggval = ipa_get_agg_replacements_for_node (node); 5859 1.1 mrg if (!aggval) 5860 1.1 mrg return true; 5861 1.1 mrg 5862 1.1 mrg ipa_node_params *clone_node_info = ipa_node_params_sum->get (node); 5863 1.1 mrg count = ipa_get_param_count (clone_node_info); 5864 1.1 mrg ec = ipa_get_cs_argument_count (ipa_edge_args_sum->get (cs)); 5865 1.1 mrg if (ec < count) 5866 1.1 mrg for (struct ipa_agg_replacement_value *av = aggval; av; av = av->next) 5867 1.1 mrg if (aggval->index >= ec) 5868 1.1 mrg return false; 5869 1.1 mrg 5870 1.1 mrg ipa_node_params *orig_node_info 5871 1.1 mrg = ipa_node_params_sum->get (clone_node_info->ipcp_orig_node); 5872 1.1 mrg 5873 1.1 mrg for (i = 0; i < count; i++) 5874 1.1 mrg { 5875 1.1 mrg class ipcp_param_lattices *plats; 5876 1.1 mrg bool interesting = false; 5877 1.1 mrg for (struct ipa_agg_replacement_value *av = aggval; av; av = av->next) 5878 1.1 mrg if (aggval->index == i) 5879 1.1 mrg { 5880 1.1 mrg interesting = true; 5881 1.1 mrg break; 5882 1.1 mrg } 5883 1.1 mrg if (!interesting) 5884 1.1 mrg continue; 5885 1.1 mrg 5886 1.1 mrg plats = ipa_get_parm_lattices (orig_node_info, aggval->index); 5887 1.1 mrg if (plats->aggs_bottom) 5888 1.1 mrg return false; 5889 1.1 mrg 5890 1.1 mrg vec<ipa_agg_value> values = intersect_aggregates_with_edge (cs, i, vNULL); 5891 1.1 mrg if (!values.exists ()) 5892 1.1 mrg return false; 5893 1.1 mrg 5894 1.1 mrg for (struct ipa_agg_replacement_value *av = aggval; av; av = av->next) 5895 1.1 mrg if (aggval->index == i) 5896 1.1 mrg { 5897 1.1 mrg struct ipa_agg_value *item; 5898 1.1 mrg int j; 5899 1.1 mrg bool found = false; 5900 1.1 mrg FOR_EACH_VEC_ELT (values, j, item) 5901 1.1 mrg if (item->value 5902 1.1 mrg && item->offset == av->offset 5903 1.1 mrg && values_equal_for_ipcp_p (item->value, av->value)) 5904 1.1 mrg { 5905 1.1 mrg found = true; 5906 1.1 mrg break; 5907 1.1 mrg } 5908 1.1 mrg if (!found) 5909 1.1 mrg { 5910 1.1 mrg values.release (); 5911 1.1 mrg return false; 5912 1.1 mrg } 5913 1.1 mrg } 5914 1.1 mrg values.release (); 5915 1.1 mrg } 5916 1.1 mrg return true; 5917 1.1 mrg } 5918 1.1 mrg 5919 1.1 mrg /* Given an original NODE and a VAL for which we have already created a 5920 1.1 mrg specialized clone, look whether there are incoming edges that still lead 5921 1.1 mrg into the old node but now also bring the requested value and also conform to 5922 1.1 mrg all other criteria such that they can be redirected the special node. 5923 1.1 mrg This function can therefore redirect the final edge in a SCC. */ 5924 1.1 mrg 5925 1.1 mrg template <typename valtype> 5926 1.1 mrg static void 5927 1.1 mrg perhaps_add_new_callers (cgraph_node *node, ipcp_value<valtype> *val) 5928 1.1 mrg { 5929 1.1 mrg ipcp_value_source<valtype> *src; 5930 1.1 mrg profile_count redirected_sum = profile_count::zero (); 5931 1.1 mrg 5932 1.1 mrg for (src = val->sources; src; src = src->next) 5933 1.1 mrg { 5934 1.1 mrg struct cgraph_edge *cs = src->cs; 5935 1.1 mrg while (cs) 5936 1.1 mrg { 5937 1.1 mrg if (cgraph_edge_brings_value_p (cs, src, node, val) 5938 1.1 mrg && cgraph_edge_brings_all_scalars_for_node (cs, val->spec_node) 5939 1.1 mrg && cgraph_edge_brings_all_agg_vals_for_node (cs, val->spec_node)) 5940 1.1 mrg { 5941 1.1 mrg if (dump_file) 5942 1.1 mrg fprintf (dump_file, " - adding an extra caller %s of %s\n", 5943 1.1 mrg cs->caller->dump_name (), 5944 1.1 mrg val->spec_node->dump_name ()); 5945 1.1 mrg 5946 1.1 mrg cs->redirect_callee_duplicating_thunks (val->spec_node); 5947 1.1 mrg val->spec_node->expand_all_artificial_thunks (); 5948 1.1 mrg if (cs->count.ipa ().initialized_p ()) 5949 1.1 mrg redirected_sum = redirected_sum + cs->count.ipa (); 5950 1.1 mrg } 5951 1.1 mrg cs = get_next_cgraph_edge_clone (cs); 5952 1.1 mrg } 5953 1.1 mrg } 5954 1.1 mrg 5955 1.1 mrg if (redirected_sum.nonzero_p ()) 5956 1.1 mrg update_specialized_profile (val->spec_node, node, redirected_sum); 5957 1.1 mrg } 5958 1.1 mrg 5959 1.1 mrg /* Return true if KNOWN_CONTEXTS contain at least one useful context. */ 5960 1.1 mrg 5961 1.1 mrg static bool 5962 1.1 mrg known_contexts_useful_p (vec<ipa_polymorphic_call_context> known_contexts) 5963 1.1 mrg { 5964 1.1 mrg ipa_polymorphic_call_context *ctx; 5965 1.1 mrg int i; 5966 1.1 mrg 5967 1.1 mrg FOR_EACH_VEC_ELT (known_contexts, i, ctx) 5968 1.1 mrg if (!ctx->useless_p ()) 5969 1.1 mrg return true; 5970 1.1 mrg return false; 5971 1.1 mrg } 5972 1.1 mrg 5973 1.1 mrg /* Return a copy of KNOWN_CSTS if it is not empty, otherwise return vNULL. */ 5974 1.1 mrg 5975 1.1 mrg static vec<ipa_polymorphic_call_context> 5976 1.1 mrg copy_useful_known_contexts (const vec<ipa_polymorphic_call_context> &known_contexts) 5977 1.1 mrg { 5978 1.1 mrg if (known_contexts_useful_p (known_contexts)) 5979 1.1 mrg return known_contexts.copy (); 5980 1.1 mrg else 5981 1.1 mrg return vNULL; 5982 1.1 mrg } 5983 1.1 mrg 5984 1.1 mrg /* Copy known scalar values from AVALS into KNOWN_CSTS and modify the copy 5985 1.1 mrg according to VAL and INDEX. If non-empty, replace KNOWN_CONTEXTS with its 5986 1.1 mrg copy too. */ 5987 1.1 mrg 5988 1.1 mrg static void 5989 1.1 mrg copy_known_vectors_add_val (ipa_auto_call_arg_values *avals, 5990 1.1 mrg vec<tree> *known_csts, 5991 1.1 mrg vec<ipa_polymorphic_call_context> *known_contexts, 5992 1.1 mrg ipcp_value<tree> *val, int index) 5993 1.1 mrg { 5994 1.1 mrg *known_csts = avals->m_known_vals.copy (); 5995 1.1 mrg *known_contexts = copy_useful_known_contexts (avals->m_known_contexts); 5996 1.1 mrg (*known_csts)[index] = val->value; 5997 1.1 mrg } 5998 1.1 mrg 5999 1.1 mrg /* Copy known scalar values from AVALS into KNOWN_CSTS. Similarly, copy 6000 1.1 mrg contexts to KNOWN_CONTEXTS and modify the copy according to VAL and 6001 1.1 mrg INDEX. */ 6002 1.1 mrg 6003 1.1 mrg static void 6004 1.1 mrg copy_known_vectors_add_val (ipa_auto_call_arg_values *avals, 6005 1.1 mrg vec<tree> *known_csts, 6006 1.1 mrg vec<ipa_polymorphic_call_context> *known_contexts, 6007 1.1 mrg ipcp_value<ipa_polymorphic_call_context> *val, 6008 1.1 mrg int index) 6009 1.1 mrg { 6010 1.1 mrg *known_csts = avals->m_known_vals.copy (); 6011 1.1 mrg *known_contexts = avals->m_known_contexts.copy (); 6012 1.1 mrg (*known_contexts)[index] = val->value; 6013 1.1 mrg } 6014 1.1 mrg 6015 1.1 mrg /* Return true if OFFSET indicates this was not an aggregate value or there is 6016 1.1 mrg a replacement equivalent to VALUE, INDEX and OFFSET among those in the 6017 1.1 mrg AGGVALS list. */ 6018 1.1 mrg 6019 1.1 mrg DEBUG_FUNCTION bool 6020 1.1 mrg ipcp_val_agg_replacement_ok_p (ipa_agg_replacement_value *aggvals, 6021 1.1 mrg int index, HOST_WIDE_INT offset, tree value) 6022 1.1 mrg { 6023 1.1 mrg if (offset == -1) 6024 1.1 mrg return true; 6025 1.1 mrg 6026 1.1 mrg while (aggvals) 6027 1.1 mrg { 6028 1.1 mrg if (aggvals->index == index 6029 1.1 mrg && aggvals->offset == offset 6030 1.1 mrg && values_equal_for_ipcp_p (aggvals->value, value)) 6031 1.1 mrg return true; 6032 1.1 mrg aggvals = aggvals->next; 6033 1.1 mrg } 6034 1.1 mrg return false; 6035 1.1 mrg } 6036 1.1 mrg 6037 1.1 mrg /* Return true if offset is minus one because source of a polymorphic context 6038 1.1 mrg cannot be an aggregate value. */ 6039 1.1 mrg 6040 1.1 mrg DEBUG_FUNCTION bool 6041 1.1 mrg ipcp_val_agg_replacement_ok_p (ipa_agg_replacement_value *, 6042 1.1 mrg int , HOST_WIDE_INT offset, 6043 1.1 mrg ipa_polymorphic_call_context) 6044 1.1 mrg { 6045 1.1 mrg return offset == -1; 6046 1.1 mrg } 6047 1.1 mrg 6048 1.1 mrg /* Decide whether to create a special version of NODE for value VAL of 6049 1.1 mrg parameter at the given INDEX. If OFFSET is -1, the value is for the 6050 1.1 mrg parameter itself, otherwise it is stored at the given OFFSET of the 6051 1.1 mrg parameter. AVALS describes the other already known values. SELF_GEN_CLONES 6052 1.1 mrg is a vector which contains clones created for self-recursive calls with an 6053 1.1 mrg arithmetic pass-through jump function. */ 6054 1.1 mrg 6055 1.1 mrg template <typename valtype> 6056 1.1 mrg static bool 6057 1.1 mrg decide_about_value (struct cgraph_node *node, int index, HOST_WIDE_INT offset, 6058 1.1 mrg ipcp_value<valtype> *val, ipa_auto_call_arg_values *avals, 6059 1.1 mrg vec<cgraph_node *> *self_gen_clones) 6060 1.1 mrg { 6061 1.1 mrg struct ipa_agg_replacement_value *aggvals; 6062 1.1 mrg int caller_count; 6063 1.1 mrg sreal freq_sum; 6064 1.1 mrg profile_count count_sum, rec_count_sum; 6065 1.1 mrg vec<cgraph_edge *> callers; 6066 1.1 mrg 6067 1.1 mrg if (val->spec_node) 6068 1.1 mrg { 6069 1.1 mrg perhaps_add_new_callers (node, val); 6070 1.1 mrg return false; 6071 1.1 mrg } 6072 1.1 mrg else if (val->local_size_cost + overall_size > get_max_overall_size (node)) 6073 1.1 mrg { 6074 1.1 mrg if (dump_file && (dump_flags & TDF_DETAILS)) 6075 1.1 mrg fprintf (dump_file, " Ignoring candidate value because " 6076 1.1 mrg "maximum unit size would be reached with %li.\n", 6077 1.1 mrg val->local_size_cost + overall_size); 6078 1.1 mrg return false; 6079 1.1 mrg } 6080 1.1 mrg else if (!get_info_about_necessary_edges (val, node, &freq_sum, &caller_count, 6081 1.1 mrg &rec_count_sum, &count_sum)) 6082 1.1 mrg return false; 6083 1.1 mrg 6084 1.1 mrg if (!dbg_cnt (ipa_cp_values)) 6085 1.1 mrg return false; 6086 1.1 mrg 6087 1.1 mrg if (val->self_recursion_generated_p ()) 6088 1.1 mrg { 6089 1.1 mrg /* The edge counts in this case might not have been adjusted yet. 6090 1.1 mrg Nevertleless, even if they were it would be only a guesswork which we 6091 1.1 mrg can do now. The recursive part of the counts can be derived from the 6092 1.1 mrg count of the original node anyway. */ 6093 1.1 mrg if (node->count.ipa ().nonzero_p ()) 6094 1.1 mrg { 6095 1.1 mrg unsigned dem = self_gen_clones->length () + 1; 6096 1.1 mrg rec_count_sum = node->count.ipa ().apply_scale (1, dem); 6097 1.1 mrg } 6098 1.1 mrg else 6099 1.1 mrg rec_count_sum = profile_count::zero (); 6100 1.1 mrg } 6101 1.1 mrg 6102 1.1 mrg /* get_info_about_necessary_edges only sums up ipa counts. */ 6103 1.1 mrg count_sum += rec_count_sum; 6104 1.1 mrg 6105 1.1 mrg if (dump_file && (dump_flags & TDF_DETAILS)) 6106 1.1 mrg { 6107 1.1 mrg fprintf (dump_file, " - considering value "); 6108 1.1 mrg print_ipcp_constant_value (dump_file, val->value); 6109 1.1 mrg fprintf (dump_file, " for "); 6110 1.1 mrg ipa_dump_param (dump_file, ipa_node_params_sum->get (node), index); 6111 1.1 mrg if (offset != -1) 6112 1.1 mrg fprintf (dump_file, ", offset: " HOST_WIDE_INT_PRINT_DEC, offset); 6113 1.1 mrg fprintf (dump_file, " (caller_count: %i)\n", caller_count); 6114 1.1 mrg } 6115 1.1 mrg 6116 1.1 mrg if (!good_cloning_opportunity_p (node, val->local_time_benefit, 6117 1.1 mrg freq_sum, count_sum, 6118 1.1 mrg val->local_size_cost) 6119 1.1 mrg && !good_cloning_opportunity_p (node, val->prop_time_benefit, 6120 1.1 mrg freq_sum, count_sum, val->prop_size_cost)) 6121 1.1 mrg return false; 6122 1.1 mrg 6123 1.1 mrg if (dump_file) 6124 1.1 mrg fprintf (dump_file, " Creating a specialized node of %s.\n", 6125 1.1 mrg node->dump_name ()); 6126 1.1 mrg 6127 1.1 mrg vec<tree> known_csts; 6128 1.1 mrg vec<ipa_polymorphic_call_context> known_contexts; 6129 1.1 mrg 6130 1.1 mrg callers = gather_edges_for_value (val, node, caller_count); 6131 1.1 mrg if (offset == -1) 6132 1.1 mrg copy_known_vectors_add_val (avals, &known_csts, &known_contexts, val, index); 6133 1.1 mrg else 6134 1.1 mrg { 6135 1.1 mrg known_csts = avals->m_known_vals.copy (); 6136 1.1 mrg known_contexts = copy_useful_known_contexts (avals->m_known_contexts); 6137 1.1 mrg } 6138 1.1 mrg find_more_scalar_values_for_callers_subset (node, known_csts, callers); 6139 1.1 mrg find_more_contexts_for_caller_subset (node, &known_contexts, callers); 6140 1.1 mrg aggvals = find_aggregate_values_for_callers_subset (node, callers); 6141 1.1 mrg gcc_checking_assert (ipcp_val_agg_replacement_ok_p (aggvals, index, 6142 1.1 mrg offset, val->value)); 6143 1.1 mrg val->spec_node = create_specialized_node (node, known_csts, known_contexts, 6144 1.1 mrg aggvals, callers); 6145 1.1 mrg 6146 1.1 mrg if (val->self_recursion_generated_p ()) 6147 1.1 mrg self_gen_clones->safe_push (val->spec_node); 6148 1.1 mrg else 6149 1.1 mrg update_profiling_info (node, val->spec_node); 6150 1.1 mrg 6151 1.1 mrg callers.release (); 6152 1.1 mrg overall_size += val->local_size_cost; 6153 1.1 mrg if (dump_file && (dump_flags & TDF_DETAILS)) 6154 1.1 mrg fprintf (dump_file, " overall size reached %li\n", 6155 1.1 mrg overall_size); 6156 1.1 mrg 6157 1.1 mrg /* TODO: If for some lattice there is only one other known value 6158 1.1 mrg left, make a special node for it too. */ 6159 1.1 mrg 6160 1.1 mrg return true; 6161 1.1 mrg } 6162 1.1 mrg 6163 1.1 mrg /* Decide whether and what specialized clones of NODE should be created. */ 6164 1.1 mrg 6165 1.1 mrg static bool 6166 1.1 mrg decide_whether_version_node (struct cgraph_node *node) 6167 1.1 mrg { 6168 1.1 mrg ipa_node_params *info = ipa_node_params_sum->get (node); 6169 1.1 mrg int i, count = ipa_get_param_count (info); 6170 1.1 mrg bool ret = false; 6171 1.1 mrg 6172 1.1 mrg if (count == 0) 6173 1.1 mrg return false; 6174 1.1 mrg 6175 1.1 mrg if (dump_file && (dump_flags & TDF_DETAILS)) 6176 1.1 mrg fprintf (dump_file, "\nEvaluating opportunities for %s.\n", 6177 1.1 mrg node->dump_name ()); 6178 1.1 mrg 6179 1.1 mrg auto_vec <cgraph_node *, 9> self_gen_clones; 6180 1.1 mrg ipa_auto_call_arg_values avals; 6181 1.1 mrg gather_context_independent_values (info, &avals, false, NULL); 6182 1.1 mrg 6183 1.1 mrg for (i = 0; i < count;i++) 6184 1.1 mrg { 6185 1.1 mrg class ipcp_param_lattices *plats = ipa_get_parm_lattices (info, i); 6186 1.1 mrg ipcp_lattice<tree> *lat = &plats->itself; 6187 1.1 mrg ipcp_lattice<ipa_polymorphic_call_context> *ctxlat = &plats->ctxlat; 6188 1.1 mrg 6189 1.1 mrg if (!lat->bottom 6190 1.1 mrg && !avals.m_known_vals[i]) 6191 1.1 mrg { 6192 1.1 mrg ipcp_value<tree> *val; 6193 1.1 mrg for (val = lat->values; val; val = val->next) 6194 1.1 mrg { 6195 1.1 mrg /* If some values generated for self-recursive calls with 6196 1.1 mrg arithmetic jump functions fall outside of the known 6197 1.1 mrg value_range for the parameter, we can skip them. VR interface 6198 1.1 mrg supports this only for integers now. */ 6199 1.1 mrg if (TREE_CODE (val->value) == INTEGER_CST 6200 1.1 mrg && !plats->m_value_range.bottom_p () 6201 1.1 mrg && !plats->m_value_range.m_vr.contains_p (val->value)) 6202 1.1 mrg { 6203 1.1 mrg /* This can happen also if a constant present in the source 6204 1.1 mrg code falls outside of the range of parameter's type, so we 6205 1.1 mrg cannot assert. */ 6206 1.1 mrg if (dump_file && (dump_flags & TDF_DETAILS)) 6207 1.1 mrg { 6208 1.1 mrg fprintf (dump_file, " - skipping%s value ", 6209 1.1 mrg val->self_recursion_generated_p () 6210 1.1 mrg ? " self_recursion_generated" : ""); 6211 1.1 mrg print_ipcp_constant_value (dump_file, val->value); 6212 1.1 mrg fprintf (dump_file, " because it is outside known " 6213 1.1 mrg "value range.\n"); 6214 1.1 mrg } 6215 1.1 mrg continue; 6216 1.1 mrg } 6217 1.1 mrg ret |= decide_about_value (node, i, -1, val, &avals, 6218 1.1 mrg &self_gen_clones); 6219 1.1 mrg } 6220 1.1 mrg } 6221 1.1 mrg 6222 1.1 mrg if (!plats->aggs_bottom) 6223 1.1 mrg { 6224 1.1 mrg struct ipcp_agg_lattice *aglat; 6225 1.1 mrg ipcp_value<tree> *val; 6226 1.1 mrg for (aglat = plats->aggs; aglat; aglat = aglat->next) 6227 1.1 mrg if (!aglat->bottom && aglat->values 6228 1.1 mrg /* If the following is false, the one value has been considered 6229 1.1 mrg for cloning for all contexts. */ 6230 1.1 mrg && (plats->aggs_contain_variable 6231 1.1 mrg || !aglat->is_single_const ())) 6232 1.1 mrg for (val = aglat->values; val; val = val->next) 6233 1.1 mrg ret |= decide_about_value (node, i, aglat->offset, val, &avals, 6234 1.1 mrg &self_gen_clones); 6235 1.1 mrg } 6236 1.1 mrg 6237 1.1 mrg if (!ctxlat->bottom 6238 1.1 mrg && avals.m_known_contexts[i].useless_p ()) 6239 1.1 mrg { 6240 1.1 mrg ipcp_value<ipa_polymorphic_call_context> *val; 6241 1.1 mrg for (val = ctxlat->values; val; val = val->next) 6242 1.1 mrg ret |= decide_about_value (node, i, -1, val, &avals, 6243 1.1 mrg &self_gen_clones); 6244 1.1 mrg } 6245 1.1 mrg } 6246 1.1 mrg 6247 1.1 mrg if (!self_gen_clones.is_empty ()) 6248 1.1 mrg { 6249 1.1 mrg self_gen_clones.safe_push (node); 6250 1.1 mrg update_counts_for_self_gen_clones (node, self_gen_clones); 6251 1.1 mrg } 6252 1.1 mrg 6253 1.1 mrg if (info->do_clone_for_all_contexts) 6254 1.1 mrg { 6255 1.1 mrg if (!dbg_cnt (ipa_cp_values)) 6256 1.1 mrg { 6257 1.1 mrg info->do_clone_for_all_contexts = false; 6258 1.1 mrg return ret; 6259 1.1 mrg } 6260 1.1 mrg 6261 1.1 mrg struct cgraph_node *clone; 6262 1.1 mrg auto_vec<cgraph_edge *> callers = node->collect_callers (); 6263 1.1 mrg 6264 1.1 mrg for (int i = callers.length () - 1; i >= 0; i--) 6265 1.1 mrg { 6266 1.1 mrg cgraph_edge *cs = callers[i]; 6267 1.1 mrg ipa_node_params *caller_info = ipa_node_params_sum->get (cs->caller); 6268 1.1 mrg 6269 1.1 mrg if (caller_info && caller_info->node_dead) 6270 1.1 mrg callers.unordered_remove (i); 6271 1.1 mrg } 6272 1.1 mrg 6273 1.1 mrg if (!adjust_callers_for_value_intersection (callers, node)) 6274 1.1 mrg { 6275 1.1 mrg /* If node is not called by anyone, or all its caller edges are 6276 1.1 mrg self-recursive, the node is not really in use, no need to do 6277 1.1 mrg cloning. */ 6278 1.1 mrg info->do_clone_for_all_contexts = false; 6279 1.1 mrg return ret; 6280 1.1 mrg } 6281 1.1 mrg 6282 1.1 mrg if (dump_file) 6283 1.1 mrg fprintf (dump_file, " - Creating a specialized node of %s " 6284 1.1 mrg "for all known contexts.\n", node->dump_name ()); 6285 1.1 mrg 6286 1.1 mrg vec<tree> known_csts = avals.m_known_vals.copy (); 6287 1.1 mrg vec<ipa_polymorphic_call_context> known_contexts 6288 1.1 mrg = copy_useful_known_contexts (avals.m_known_contexts); 6289 1.1 mrg find_more_scalar_values_for_callers_subset (node, known_csts, callers); 6290 1.1 mrg find_more_contexts_for_caller_subset (node, &known_contexts, callers); 6291 1.1 mrg ipa_agg_replacement_value *aggvals 6292 1.1 mrg = find_aggregate_values_for_callers_subset (node, callers); 6293 1.1 mrg 6294 1.1 mrg if (!known_contexts_useful_p (known_contexts)) 6295 1.1 mrg { 6296 1.1 mrg known_contexts.release (); 6297 1.1 mrg known_contexts = vNULL; 6298 1.1 mrg } 6299 1.1 mrg clone = create_specialized_node (node, known_csts, known_contexts, 6300 1.1 mrg aggvals, callers); 6301 1.1 mrg info->do_clone_for_all_contexts = false; 6302 1.1 mrg ipa_node_params_sum->get (clone)->is_all_contexts_clone = true; 6303 1.1 mrg ret = true; 6304 1.1 mrg } 6305 1.1 mrg 6306 1.1 mrg return ret; 6307 1.1 mrg } 6308 1.1 mrg 6309 1.1 mrg /* Transitively mark all callees of NODE within the same SCC as not dead. */ 6310 1.1 mrg 6311 1.1 mrg static void 6312 1.1 mrg spread_undeadness (struct cgraph_node *node) 6313 1.1 mrg { 6314 1.1 mrg struct cgraph_edge *cs; 6315 1.1 mrg 6316 1.1 mrg for (cs = node->callees; cs; cs = cs->next_callee) 6317 1.1 mrg if (ipa_edge_within_scc (cs)) 6318 1.1 mrg { 6319 1.1 mrg struct cgraph_node *callee; 6320 1.1 mrg class ipa_node_params *info; 6321 1.1 mrg 6322 1.1 mrg callee = cs->callee->function_symbol (NULL); 6323 1.1 mrg info = ipa_node_params_sum->get (callee); 6324 1.1 mrg 6325 1.1 mrg if (info && info->node_dead) 6326 1.1 mrg { 6327 1.1 mrg info->node_dead = 0; 6328 1.1 mrg spread_undeadness (callee); 6329 1.1 mrg } 6330 1.1 mrg } 6331 1.1 mrg } 6332 1.1 mrg 6333 1.1 mrg /* Return true if NODE has a caller from outside of its SCC that is not 6334 1.1 mrg dead. Worker callback for cgraph_for_node_and_aliases. */ 6335 1.1 mrg 6336 1.1 mrg static bool 6337 1.1 mrg has_undead_caller_from_outside_scc_p (struct cgraph_node *node, 6338 1.1 mrg void *data ATTRIBUTE_UNUSED) 6339 1.1 mrg { 6340 1.1 mrg struct cgraph_edge *cs; 6341 1.1 mrg 6342 1.1 mrg for (cs = node->callers; cs; cs = cs->next_caller) 6343 1.1 mrg if (cs->caller->thunk 6344 1.1 mrg && cs->caller->call_for_symbol_thunks_and_aliases 6345 1.1 mrg (has_undead_caller_from_outside_scc_p, NULL, true)) 6346 1.1 mrg return true; 6347 1.1 mrg else if (!ipa_edge_within_scc (cs)) 6348 1.1 mrg { 6349 1.1 mrg ipa_node_params *caller_info = ipa_node_params_sum->get (cs->caller); 6350 1.1 mrg if (!caller_info /* Unoptimized caller are like dead ones. */ 6351 1.1 mrg || !caller_info->node_dead) 6352 1.1 mrg return true; 6353 1.1 mrg } 6354 1.1 mrg return false; 6355 1.1 mrg } 6356 1.1 mrg 6357 1.1 mrg 6358 1.1 mrg /* Identify nodes within the same SCC as NODE which are no longer needed 6359 1.1 mrg because of new clones and will be removed as unreachable. */ 6360 1.1 mrg 6361 1.1 mrg static void 6362 1.1 mrg identify_dead_nodes (struct cgraph_node *node) 6363 1.1 mrg { 6364 1.1 mrg struct cgraph_node *v; 6365 1.1 mrg for (v = node; v; v = ((struct ipa_dfs_info *) v->aux)->next_cycle) 6366 1.1 mrg if (v->local) 6367 1.1 mrg { 6368 1.1 mrg ipa_node_params *info = ipa_node_params_sum->get (v); 6369 1.1 mrg if (info 6370 1.1 mrg && !v->call_for_symbol_thunks_and_aliases 6371 1.1 mrg (has_undead_caller_from_outside_scc_p, NULL, true)) 6372 1.1 mrg info->node_dead = 1; 6373 1.1 mrg } 6374 1.1 mrg 6375 1.1 mrg for (v = node; v; v = ((struct ipa_dfs_info *) v->aux)->next_cycle) 6376 1.1 mrg { 6377 1.1 mrg ipa_node_params *info = ipa_node_params_sum->get (v); 6378 1.1 mrg if (info && !info->node_dead) 6379 1.1 mrg spread_undeadness (v); 6380 1.1 mrg } 6381 1.1 mrg 6382 1.1 mrg if (dump_file && (dump_flags & TDF_DETAILS)) 6383 1.1 mrg { 6384 1.1 mrg for (v = node; v; v = ((struct ipa_dfs_info *) v->aux)->next_cycle) 6385 1.1 mrg if (ipa_node_params_sum->get (v) 6386 1.1 mrg && ipa_node_params_sum->get (v)->node_dead) 6387 1.1 mrg fprintf (dump_file, " Marking node as dead: %s.\n", 6388 1.1 mrg v->dump_name ()); 6389 1.1 mrg } 6390 1.1 mrg } 6391 1.1 mrg 6392 1.1 mrg /* The decision stage. Iterate over the topological order of call graph nodes 6393 1.1 mrg TOPO and make specialized clones if deemed beneficial. */ 6394 1.1 mrg 6395 1.1 mrg static void 6396 1.1 mrg ipcp_decision_stage (class ipa_topo_info *topo) 6397 1.1 mrg { 6398 1.1 mrg int i; 6399 1.1 mrg 6400 1.1 mrg if (dump_file) 6401 1.1 mrg fprintf (dump_file, "\nIPA decision stage:\n\n"); 6402 1.1 mrg 6403 1.1 mrg for (i = topo->nnodes - 1; i >= 0; i--) 6404 1.1 mrg { 6405 1.1 mrg struct cgraph_node *node = topo->order[i]; 6406 1.1 mrg bool change = false, iterate = true; 6407 1.1 mrg 6408 1.1 mrg while (iterate) 6409 1.1 mrg { 6410 1.1 mrg struct cgraph_node *v; 6411 1.1 mrg iterate = false; 6412 1.1 mrg for (v = node; v; v = ((struct ipa_dfs_info *) v->aux)->next_cycle) 6413 1.1 mrg if (v->has_gimple_body_p () 6414 1.1 mrg && ipcp_versionable_function_p (v)) 6415 1.1 mrg iterate |= decide_whether_version_node (v); 6416 1.1 mrg 6417 1.1 mrg change |= iterate; 6418 1.1 mrg } 6419 1.1 mrg if (change) 6420 1.1 mrg identify_dead_nodes (node); 6421 1.1 mrg } 6422 1.1 mrg } 6423 1.1 mrg 6424 1.1 mrg /* Look up all the bits information that we have discovered and copy it over 6425 1.1 mrg to the transformation summary. */ 6426 1.1 mrg 6427 1.1 mrg static void 6428 1.1 mrg ipcp_store_bits_results (void) 6429 1.1 mrg { 6430 1.1 mrg cgraph_node *node; 6431 1.1 mrg 6432 1.1 mrg FOR_EACH_FUNCTION_WITH_GIMPLE_BODY (node) 6433 1.1 mrg { 6434 1.1 mrg ipa_node_params *info = ipa_node_params_sum->get (node); 6435 1.1 mrg bool dumped_sth = false; 6436 1.1 mrg bool found_useful_result = false; 6437 1.1 mrg 6438 1.1 mrg if (!opt_for_fn (node->decl, flag_ipa_bit_cp) || !info) 6439 1.1 mrg { 6440 1.1 mrg if (dump_file) 6441 1.1 mrg fprintf (dump_file, "Not considering %s for ipa bitwise propagation " 6442 1.1 mrg "; -fipa-bit-cp: disabled.\n", 6443 1.1 mrg node->dump_name ()); 6444 1.1 mrg continue; 6445 1.1 mrg } 6446 1.1 mrg 6447 1.1 mrg if (info->ipcp_orig_node) 6448 1.1 mrg info = ipa_node_params_sum->get (info->ipcp_orig_node); 6449 1.1 mrg if (!info->lattices) 6450 1.1 mrg /* Newly expanded artificial thunks do not have lattices. */ 6451 1.1 mrg continue; 6452 1.1 mrg 6453 1.1 mrg unsigned count = ipa_get_param_count (info); 6454 1.1 mrg for (unsigned i = 0; i < count; i++) 6455 1.1 mrg { 6456 1.1 mrg ipcp_param_lattices *plats = ipa_get_parm_lattices (info, i); 6457 1.1 mrg if (plats->bits_lattice.constant_p ()) 6458 1.1 mrg { 6459 1.1 mrg found_useful_result = true; 6460 1.1 mrg break; 6461 1.1 mrg } 6462 1.1 mrg } 6463 1.1 mrg 6464 1.1 mrg if (!found_useful_result) 6465 1.1 mrg continue; 6466 1.1 mrg 6467 1.1 mrg ipcp_transformation_initialize (); 6468 1.1 mrg ipcp_transformation *ts = ipcp_transformation_sum->get_create (node); 6469 1.1 mrg vec_safe_reserve_exact (ts->bits, count); 6470 1.1 mrg 6471 1.1 mrg for (unsigned i = 0; i < count; i++) 6472 1.1 mrg { 6473 1.1 mrg ipcp_param_lattices *plats = ipa_get_parm_lattices (info, i); 6474 1.1 mrg ipa_bits *jfbits; 6475 1.1 mrg 6476 1.1 mrg if (plats->bits_lattice.constant_p ()) 6477 1.1 mrg { 6478 1.1 mrg jfbits 6479 1.1 mrg = ipa_get_ipa_bits_for_value (plats->bits_lattice.get_value (), 6480 1.1 mrg plats->bits_lattice.get_mask ()); 6481 1.1 mrg if (!dbg_cnt (ipa_cp_bits)) 6482 1.1 mrg jfbits = NULL; 6483 1.1 mrg } 6484 1.1 mrg else 6485 1.1 mrg jfbits = NULL; 6486 1.1 mrg 6487 1.1 mrg ts->bits->quick_push (jfbits); 6488 1.1 mrg if (!dump_file || !jfbits) 6489 1.1 mrg continue; 6490 1.1 mrg if (!dumped_sth) 6491 1.1 mrg { 6492 1.1 mrg fprintf (dump_file, "Propagated bits info for function %s:\n", 6493 1.1 mrg node->dump_name ()); 6494 1.1 mrg dumped_sth = true; 6495 1.1 mrg } 6496 1.1 mrg fprintf (dump_file, " param %i: value = ", i); 6497 1.1 mrg print_hex (jfbits->value, dump_file); 6498 1.1 mrg fprintf (dump_file, ", mask = "); 6499 1.1 mrg print_hex (jfbits->mask, dump_file); 6500 1.1 mrg fprintf (dump_file, "\n"); 6501 1.1 mrg } 6502 1.1 mrg } 6503 1.1 mrg } 6504 1.1 mrg 6505 1.1 mrg /* Look up all VR information that we have discovered and copy it over 6506 1.1 mrg to the transformation summary. */ 6507 1.1 mrg 6508 1.1 mrg static void 6509 1.1 mrg ipcp_store_vr_results (void) 6510 1.1 mrg { 6511 1.1 mrg cgraph_node *node; 6512 1.1 mrg 6513 1.1 mrg FOR_EACH_FUNCTION_WITH_GIMPLE_BODY (node) 6514 1.1 mrg { 6515 1.1 mrg ipa_node_params *info = ipa_node_params_sum->get (node); 6516 1.1 mrg bool found_useful_result = false; 6517 1.1 mrg 6518 1.1 mrg if (!info || !opt_for_fn (node->decl, flag_ipa_vrp)) 6519 1.1 mrg { 6520 1.1 mrg if (dump_file) 6521 1.1 mrg fprintf (dump_file, "Not considering %s for VR discovery " 6522 1.1 mrg "and propagate; -fipa-ipa-vrp: disabled.\n", 6523 1.1 mrg node->dump_name ()); 6524 1.1 mrg continue; 6525 1.1 mrg } 6526 1.1 mrg 6527 1.1 mrg if (info->ipcp_orig_node) 6528 1.1 mrg info = ipa_node_params_sum->get (info->ipcp_orig_node); 6529 1.1 mrg if (!info->lattices) 6530 1.1 mrg /* Newly expanded artificial thunks do not have lattices. */ 6531 1.1 mrg continue; 6532 1.1 mrg 6533 1.1 mrg unsigned count = ipa_get_param_count (info); 6534 1.1 mrg for (unsigned i = 0; i < count; i++) 6535 1.1 mrg { 6536 1.1 mrg ipcp_param_lattices *plats = ipa_get_parm_lattices (info, i); 6537 1.1 mrg if (!plats->m_value_range.bottom_p () 6538 1.1 mrg && !plats->m_value_range.top_p ()) 6539 1.1 mrg { 6540 1.1 mrg found_useful_result = true; 6541 1.1 mrg break; 6542 1.1 mrg } 6543 1.1 mrg } 6544 1.1 mrg if (!found_useful_result) 6545 1.1 mrg continue; 6546 1.1 mrg 6547 1.1 mrg ipcp_transformation_initialize (); 6548 1.1 mrg ipcp_transformation *ts = ipcp_transformation_sum->get_create (node); 6549 1.1 mrg vec_safe_reserve_exact (ts->m_vr, count); 6550 1.1 mrg 6551 1.1 mrg for (unsigned i = 0; i < count; i++) 6552 1.1 mrg { 6553 1.1 mrg ipcp_param_lattices *plats = ipa_get_parm_lattices (info, i); 6554 1.1 mrg ipa_vr vr; 6555 1.1 mrg 6556 1.1 mrg if (!plats->m_value_range.bottom_p () 6557 1.1 mrg && !plats->m_value_range.top_p () 6558 1.1 mrg && dbg_cnt (ipa_cp_vr)) 6559 1.1 mrg { 6560 1.1 mrg vr.known = true; 6561 1.1 mrg vr.type = plats->m_value_range.m_vr.kind (); 6562 1.1 mrg vr.min = wi::to_wide (plats->m_value_range.m_vr.min ()); 6563 1.1 mrg vr.max = wi::to_wide (plats->m_value_range.m_vr.max ()); 6564 1.1 mrg } 6565 1.1 mrg else 6566 1.1 mrg { 6567 1.1 mrg vr.known = false; 6568 1.1 mrg vr.type = VR_VARYING; 6569 1.1 mrg vr.min = vr.max = wi::zero (INT_TYPE_SIZE); 6570 1.1 mrg } 6571 1.1 mrg ts->m_vr->quick_push (vr); 6572 1.1 mrg } 6573 1.1 mrg } 6574 1.1 mrg } 6575 1.1 mrg 6576 1.1 mrg /* The IPCP driver. */ 6577 1.1 mrg 6578 1.1 mrg static unsigned int 6579 1.1 mrg ipcp_driver (void) 6580 1.1 mrg { 6581 1.1 mrg class ipa_topo_info topo; 6582 1.1 mrg 6583 1.1 mrg if (edge_clone_summaries == NULL) 6584 1.1 mrg edge_clone_summaries = new edge_clone_summary_t (symtab); 6585 1.1 mrg 6586 1.1 mrg ipa_check_create_node_params (); 6587 1.1 mrg ipa_check_create_edge_args (); 6588 1.1 mrg clone_num_suffixes = new hash_map<const char *, unsigned>; 6589 1.1 mrg 6590 1.1 mrg if (dump_file) 6591 1.1 mrg { 6592 1.1 mrg fprintf (dump_file, "\nIPA structures before propagation:\n"); 6593 1.1 mrg if (dump_flags & TDF_DETAILS) 6594 1.1 mrg ipa_print_all_params (dump_file); 6595 1.1 mrg ipa_print_all_jump_functions (dump_file); 6596 1.1 mrg } 6597 1.1 mrg 6598 1.1 mrg /* Topological sort. */ 6599 1.1 mrg build_toporder_info (&topo); 6600 1.1 mrg /* Do the interprocedural propagation. */ 6601 1.1 mrg ipcp_propagate_stage (&topo); 6602 1.1 mrg /* Decide what constant propagation and cloning should be performed. */ 6603 1.1 mrg ipcp_decision_stage (&topo); 6604 1.1 mrg /* Store results of bits propagation. */ 6605 1.1 mrg ipcp_store_bits_results (); 6606 1.1 mrg /* Store results of value range propagation. */ 6607 1.1 mrg ipcp_store_vr_results (); 6608 1.1 mrg 6609 1.1 mrg /* Free all IPCP structures. */ 6610 1.1 mrg delete clone_num_suffixes; 6611 1.1 mrg free_toporder_info (&topo); 6612 1.1 mrg delete edge_clone_summaries; 6613 1.1 mrg edge_clone_summaries = NULL; 6614 1.1 mrg ipa_free_all_structures_after_ipa_cp (); 6615 1.1 mrg if (dump_file) 6616 1.1 mrg fprintf (dump_file, "\nIPA constant propagation end\n"); 6617 1.1 mrg return 0; 6618 1.1 mrg } 6619 1.1 mrg 6620 1.1 mrg /* Initialization and computation of IPCP data structures. This is the initial 6621 1.1 mrg intraprocedural analysis of functions, which gathers information to be 6622 1.1 mrg propagated later on. */ 6623 1.1 mrg 6624 1.1 mrg static void 6625 1.1 mrg ipcp_generate_summary (void) 6626 1.1 mrg { 6627 1.1 mrg struct cgraph_node *node; 6628 1.1 mrg 6629 1.1 mrg if (dump_file) 6630 1.1 mrg fprintf (dump_file, "\nIPA constant propagation start:\n"); 6631 1.1 mrg ipa_register_cgraph_hooks (); 6632 1.1 mrg 6633 1.1 mrg FOR_EACH_FUNCTION_WITH_GIMPLE_BODY (node) 6634 1.1 mrg ipa_analyze_node (node); 6635 1.1 mrg } 6636 1.1 mrg 6637 1.1 mrg namespace { 6638 1.1 mrg 6639 1.1 mrg const pass_data pass_data_ipa_cp = 6640 1.1 mrg { 6641 1.1 mrg IPA_PASS, /* type */ 6642 1.1 mrg "cp", /* name */ 6643 1.1 mrg OPTGROUP_NONE, /* optinfo_flags */ 6644 1.1 mrg TV_IPA_CONSTANT_PROP, /* tv_id */ 6645 1.1 mrg 0, /* properties_required */ 6646 1.1 mrg 0, /* properties_provided */ 6647 1.1 mrg 0, /* properties_destroyed */ 6648 1.1 mrg 0, /* todo_flags_start */ 6649 1.1 mrg ( TODO_dump_symtab | TODO_remove_functions ), /* todo_flags_finish */ 6650 1.1 mrg }; 6651 1.1 mrg 6652 1.1 mrg class pass_ipa_cp : public ipa_opt_pass_d 6653 1.1 mrg { 6654 1.1 mrg public: 6655 1.1 mrg pass_ipa_cp (gcc::context *ctxt) 6656 1.1 mrg : ipa_opt_pass_d (pass_data_ipa_cp, ctxt, 6657 1.1 mrg ipcp_generate_summary, /* generate_summary */ 6658 1.1 mrg NULL, /* write_summary */ 6659 1.1 mrg NULL, /* read_summary */ 6660 1.1 mrg ipcp_write_transformation_summaries, /* 6661 1.1 mrg write_optimization_summary */ 6662 1.1 mrg ipcp_read_transformation_summaries, /* 6663 1.1 mrg read_optimization_summary */ 6664 1.1 mrg NULL, /* stmt_fixup */ 6665 1.1 mrg 0, /* function_transform_todo_flags_start */ 6666 1.1 mrg ipcp_transform_function, /* function_transform */ 6667 1.1 mrg NULL) /* variable_transform */ 6668 1.1 mrg {} 6669 1.1 mrg 6670 1.1 mrg /* opt_pass methods: */ 6671 1.1 mrg virtual bool gate (function *) 6672 1.1 mrg { 6673 1.1 mrg /* FIXME: We should remove the optimize check after we ensure we never run 6674 1.1 mrg IPA passes when not optimizing. */ 6675 1.1 mrg return (flag_ipa_cp && optimize) || in_lto_p; 6676 1.1 mrg } 6677 1.1 mrg 6678 1.1 mrg virtual unsigned int execute (function *) { return ipcp_driver (); } 6679 1.1 mrg 6680 1.1 mrg }; // class pass_ipa_cp 6681 1.1 mrg 6682 1.1 mrg } // anon namespace 6683 1.1 mrg 6684 1.1 mrg ipa_opt_pass_d * 6685 1.1 mrg make_pass_ipa_cp (gcc::context *ctxt) 6686 1.1 mrg { 6687 1.1 mrg return new pass_ipa_cp (ctxt); 6688 1.1 mrg } 6689 1.1 mrg 6690 1.1 mrg /* Reset all state within ipa-cp.cc so that we can rerun the compiler 6691 1.1 mrg within the same process. For use by toplev::finalize. */ 6692 1.1 mrg 6693 1.1 mrg void 6694 1.1 mrg ipa_cp_cc_finalize (void) 6695 1.1 mrg { 6696 1.1 mrg base_count = profile_count::uninitialized (); 6697 1.1 mrg overall_size = 0; 6698 1.1 mrg orig_overall_size = 0; 6699 1.1 mrg ipcp_free_transformation_sum (); 6700 1.1 mrg } 6701