1 1.1 mrg /* Straight-line strength reduction. 2 1.1 mrg Copyright (C) 2012-2022 Free Software Foundation, Inc. 3 1.1 mrg Contributed by Bill Schmidt, IBM <wschmidt (at) linux.ibm.com> 4 1.1 mrg 5 1.1 mrg This file is part of GCC. 6 1.1 mrg 7 1.1 mrg GCC is free software; you can redistribute it and/or modify it under 8 1.1 mrg the terms of the GNU General Public License as published by the Free 9 1.1 mrg Software Foundation; either version 3, or (at your option) any later 10 1.1 mrg version. 11 1.1 mrg 12 1.1 mrg GCC is distributed in the hope that it will be useful, but WITHOUT ANY 13 1.1 mrg WARRANTY; without even the implied warranty of MERCHANTABILITY or 14 1.1 mrg FITNESS FOR A PARTICULAR PURPOSE. See the GNU General Public License 15 1.1 mrg for more details. 16 1.1 mrg 17 1.1 mrg You should have received a copy of the GNU General Public License 18 1.1 mrg along with GCC; see the file COPYING3. If not see 19 1.1 mrg <http://www.gnu.org/licenses/>. */ 20 1.1 mrg 21 1.1 mrg /* There are many algorithms for performing strength reduction on 22 1.1 mrg loops. This is not one of them. IVOPTS handles strength reduction 23 1.1 mrg of induction variables just fine. This pass is intended to pick 24 1.1 mrg up the crumbs it leaves behind, by considering opportunities for 25 1.1 mrg strength reduction along dominator paths. 26 1.1 mrg 27 1.1 mrg Strength reduction addresses explicit multiplies, and certain 28 1.1 mrg multiplies implicit in addressing expressions. It would also be 29 1.1 mrg possible to apply strength reduction to divisions and modulos, 30 1.1 mrg but such opportunities are relatively uncommon. 31 1.1 mrg 32 1.1 mrg Strength reduction is also currently restricted to integer operations. 33 1.1 mrg If desired, it could be extended to floating-point operations under 34 1.1 mrg control of something like -funsafe-math-optimizations. */ 35 1.1 mrg 36 1.1 mrg #include "config.h" 37 1.1 mrg #include "system.h" 38 1.1 mrg #include "coretypes.h" 39 1.1 mrg #include "backend.h" 40 1.1 mrg #include "rtl.h" 41 1.1 mrg #include "tree.h" 42 1.1 mrg #include "gimple.h" 43 1.1 mrg #include "cfghooks.h" 44 1.1 mrg #include "tree-pass.h" 45 1.1 mrg #include "ssa.h" 46 1.1 mrg #include "expmed.h" 47 1.1 mrg #include "gimple-pretty-print.h" 48 1.1 mrg #include "fold-const.h" 49 1.1 mrg #include "gimple-iterator.h" 50 1.1 mrg #include "gimplify-me.h" 51 1.1 mrg #include "stor-layout.h" 52 1.1 mrg #include "cfgloop.h" 53 1.1 mrg #include "tree-cfg.h" 54 1.1 mrg #include "domwalk.h" 55 1.1 mrg #include "tree-ssa-address.h" 56 1.1 mrg #include "tree-affine.h" 57 1.1 mrg #include "tree-eh.h" 58 1.1 mrg #include "builtins.h" 59 1.1 mrg 60 1.1 mrg /* Information about a strength reduction candidate. Each statement 62 1.1 mrg in the candidate table represents an expression of one of the 63 1.1 mrg following forms (the special case of CAND_REF will be described 64 1.1 mrg later): 65 1.1 mrg 66 1.1 mrg (CAND_MULT) S1: X = (B + i) * S 67 1.1 mrg (CAND_ADD) S1: X = B + (i * S) 68 1.1 mrg 69 1.1 mrg Here X and B are SSA names, i is an integer constant, and S is 70 1.1 mrg either an SSA name or a constant. We call B the "base," i the 71 1.1 mrg "index", and S the "stride." 72 1.1 mrg 73 1.1 mrg Any statement S0 that dominates S1 and is of the form: 74 1.1 mrg 75 1.1 mrg (CAND_MULT) S0: Y = (B + i') * S 76 1.1 mrg (CAND_ADD) S0: Y = B + (i' * S) 77 1.1 mrg 78 1.1 mrg is called a "basis" for S1. In both cases, S1 may be replaced by 79 1.1 mrg 80 1.1 mrg S1': X = Y + (i - i') * S, 81 1.1 mrg 82 1.1 mrg where (i - i') * S is folded to the extent possible. 83 1.1 mrg 84 1.1 mrg All gimple statements are visited in dominator order, and each 85 1.1 mrg statement that may contribute to one of the forms of S1 above is 86 1.1 mrg given at least one entry in the candidate table. Such statements 87 1.1 mrg include addition, pointer addition, subtraction, multiplication, 88 1.1 mrg negation, copies, and nontrivial type casts. If a statement may 89 1.1 mrg represent more than one expression of the forms of S1 above, 90 1.1 mrg multiple "interpretations" are stored in the table and chained 91 1.1 mrg together. Examples: 92 1.1 mrg 93 1.1 mrg * An add of two SSA names may treat either operand as the base. 94 1.1 mrg * A multiply of two SSA names, likewise. 95 1.1 mrg * A copy or cast may be thought of as either a CAND_MULT with 96 1.1 mrg i = 0 and S = 1, or as a CAND_ADD with i = 0 or S = 0. 97 1.1 mrg 98 1.1 mrg Candidate records are allocated from an obstack. They are addressed 99 1.1 mrg both from a hash table keyed on S1, and from a vector of candidate 100 1.1 mrg pointers arranged in predominator order. 101 1.1 mrg 102 1.1 mrg Opportunity note 103 1.1 mrg ---------------- 104 1.1 mrg Currently we don't recognize: 105 1.1 mrg 106 1.1 mrg S0: Y = (S * i') - B 107 1.1 mrg S1: X = (S * i) - B 108 1.1 mrg 109 1.1 mrg as a strength reduction opportunity, even though this S1 would 110 1.1 mrg also be replaceable by the S1' above. This can be added if it 111 1.1 mrg comes up in practice. 112 1.1 mrg 113 1.1 mrg Strength reduction in addressing 114 1.1 mrg -------------------------------- 115 1.1 mrg There is another kind of candidate known as CAND_REF. A CAND_REF 116 1.1 mrg describes a statement containing a memory reference having 117 1.1 mrg complex addressing that might benefit from strength reduction. 118 1.1 mrg Specifically, we are interested in references for which 119 1.1 mrg get_inner_reference returns a base address, offset, and bitpos as 120 1.1 mrg follows: 121 1.1 mrg 122 1.1 mrg base: MEM_REF (T1, C1) 123 1.1 mrg offset: MULT_EXPR (PLUS_EXPR (T2, C2), C3) 124 1.1 mrg bitpos: C4 * BITS_PER_UNIT 125 1.1 mrg 126 1.1 mrg Here T1 and T2 are arbitrary trees, and C1, C2, C3, C4 are 127 1.1 mrg arbitrary integer constants. Note that C2 may be zero, in which 128 1.1 mrg case the offset will be MULT_EXPR (T2, C3). 129 1.1 mrg 130 1.1 mrg When this pattern is recognized, the original memory reference 131 1.1 mrg can be replaced with: 132 1.1 mrg 133 1.1 mrg MEM_REF (POINTER_PLUS_EXPR (T1, MULT_EXPR (T2, C3)), 134 1.1 mrg C1 + (C2 * C3) + C4) 135 1.1 mrg 136 1.1 mrg which distributes the multiply to allow constant folding. When 137 1.1 mrg two or more addressing expressions can be represented by MEM_REFs 138 1.1 mrg of this form, differing only in the constants C1, C2, and C4, 139 1.1 mrg making this substitution produces more efficient addressing during 140 1.1 mrg the RTL phases. When there are not at least two expressions with 141 1.1 mrg the same values of T1, T2, and C3, there is nothing to be gained 142 1.1 mrg by the replacement. 143 1.1 mrg 144 1.1 mrg Strength reduction of CAND_REFs uses the same infrastructure as 145 1.1 mrg that used by CAND_MULTs and CAND_ADDs. We record T1 in the base (B) 146 1.1 mrg field, MULT_EXPR (T2, C3) in the stride (S) field, and 147 1.1 mrg C1 + (C2 * C3) + C4 in the index (i) field. A basis for a CAND_REF 148 1.1 mrg is thus another CAND_REF with the same B and S values. When at 149 1.1 mrg least two CAND_REFs are chained together using the basis relation, 150 1.1 mrg each of them is replaced as above, resulting in improved code 151 1.1 mrg generation for addressing. 152 1.1 mrg 153 1.1 mrg Conditional candidates 154 1.1 mrg ====================== 155 1.1 mrg 156 1.1 mrg Conditional candidates are best illustrated with an example. 157 1.1 mrg Consider the code sequence: 158 1.1 mrg 159 1.1 mrg (1) x_0 = ...; 160 1.1 mrg (2) a_0 = x_0 * 5; MULT (B: x_0; i: 0; S: 5) 161 1.1 mrg if (...) 162 1.1 mrg (3) x_1 = x_0 + 1; ADD (B: x_0, i: 1; S: 1) 163 1.1 mrg (4) x_2 = PHI <x_0, x_1>; PHI (B: x_0, i: 0, S: 1) 164 1.1 mrg (5) x_3 = x_2 + 1; ADD (B: x_2, i: 1, S: 1) 165 1.1 mrg (6) a_1 = x_3 * 5; MULT (B: x_2, i: 1; S: 5) 166 1.1 mrg 167 1.1 mrg Here strength reduction is complicated by the uncertain value of x_2. 168 1.1 mrg A legitimate transformation is: 169 1.1 mrg 170 1.1 mrg (1) x_0 = ...; 171 1.1 mrg (2) a_0 = x_0 * 5; 172 1.1 mrg if (...) 173 1.1 mrg { 174 1.1 mrg (3) [x_1 = x_0 + 1;] 175 1.1 mrg (3a) t_1 = a_0 + 5; 176 1.1 mrg } 177 1.1 mrg (4) [x_2 = PHI <x_0, x_1>;] 178 1.1 mrg (4a) t_2 = PHI <a_0, t_1>; 179 1.1 mrg (5) [x_3 = x_2 + 1;] 180 1.1 mrg (6r) a_1 = t_2 + 5; 181 1.1 mrg 182 1.1 mrg where the bracketed instructions may go dead. 183 1.1 mrg 184 1.1 mrg To recognize this opportunity, we have to observe that statement (6) 185 1.1 mrg has a "hidden basis" (2). The hidden basis is unlike a normal basis 186 1.1 mrg in that the statement and the hidden basis have different base SSA 187 1.1 mrg names (x_2 and x_0, respectively). The relationship is established 188 1.1 mrg when a statement's base name (x_2) is defined by a phi statement (4), 189 1.1 mrg each argument of which (x_0, x_1) has an identical "derived base name." 190 1.1 mrg If the argument is defined by a candidate (as x_1 is by (3)) that is a 191 1.1 mrg CAND_ADD having a stride of 1, the derived base name of the argument is 192 1.1 mrg the base name of the candidate (x_0). Otherwise, the argument itself 193 1.1 mrg is its derived base name (as is the case with argument x_0). 194 1.1 mrg 195 1.1 mrg The hidden basis for statement (6) is the nearest dominating candidate 196 1.1 mrg whose base name is the derived base name (x_0) of the feeding phi (4), 197 1.1 mrg and whose stride is identical to that of the statement. We can then 198 1.1 mrg create the new "phi basis" (4a) and feeding adds along incoming arcs (3a), 199 1.1 mrg allowing the final replacement of (6) by the strength-reduced (6r). 200 1.1 mrg 201 1.1 mrg To facilitate this, a new kind of candidate (CAND_PHI) is introduced. 202 1.1 mrg A CAND_PHI is not a candidate for replacement, but is maintained in the 203 1.1 mrg candidate table to ease discovery of hidden bases. Any phi statement 204 1.1 mrg whose arguments share a common derived base name is entered into the 205 1.1 mrg table with the derived base name, an (arbitrary) index of zero, and a 206 1.1 mrg stride of 1. A statement with a hidden basis can then be detected by 207 1.1 mrg simply looking up its feeding phi definition in the candidate table, 208 1.1 mrg extracting the derived base name, and searching for a basis in the 209 1.1 mrg usual manner after substituting the derived base name. 210 1.1 mrg 211 1.1 mrg Note that the transformation is only valid when the original phi and 212 1.1 mrg the statements that define the phi's arguments are all at the same 213 1.1 mrg position in the loop hierarchy. */ 214 1.1 mrg 215 1.1 mrg 216 1.1 mrg /* Index into the candidate vector, offset by 1. VECs are zero-based, 217 1.1 mrg while cand_idx's are one-based, with zero indicating null. */ 218 1.1 mrg typedef unsigned cand_idx; 219 1.1 mrg 220 1.1 mrg /* The kind of candidate. */ 221 1.1 mrg enum cand_kind 222 1.1 mrg { 223 1.1 mrg CAND_MULT, 224 1.1 mrg CAND_ADD, 225 1.1 mrg CAND_REF, 226 1.1 mrg CAND_PHI 227 1.1 mrg }; 228 1.1 mrg 229 1.1 mrg class slsr_cand_d 230 1.1 mrg { 231 1.1 mrg public: 232 1.1 mrg /* The candidate statement S1. */ 233 1.1 mrg gimple *cand_stmt; 234 1.1 mrg 235 1.1 mrg /* The base expression B: often an SSA name, but not always. */ 236 1.1 mrg tree base_expr; 237 1.1 mrg 238 1.1 mrg /* The stride S. */ 239 1.1 mrg tree stride; 240 1.1 mrg 241 1.1 mrg /* The index constant i. */ 242 1.1 mrg widest_int index; 243 1.1 mrg 244 1.1 mrg /* The type of the candidate. This is normally the type of base_expr, 245 1.1 mrg but casts may have occurred when combining feeding instructions. 246 1.1 mrg A candidate can only be a basis for candidates of the same final type. 247 1.1 mrg (For CAND_REFs, this is the type to be used for operand 1 of the 248 1.1 mrg replacement MEM_REF.) */ 249 1.1 mrg tree cand_type; 250 1.1 mrg 251 1.1 mrg /* The type to be used to interpret the stride field when the stride 252 1.1 mrg is not a constant. Normally the same as the type of the recorded 253 1.1 mrg stride, but when the stride has been cast we need to maintain that 254 1.1 mrg knowledge in order to make legal substitutions without losing 255 1.1 mrg precision. When the stride is a constant, this will be sizetype. */ 256 1.1 mrg tree stride_type; 257 1.1 mrg 258 1.1 mrg /* The kind of candidate (CAND_MULT, etc.). */ 259 1.1 mrg enum cand_kind kind; 260 1.1 mrg 261 1.1 mrg /* Index of this candidate in the candidate vector. */ 262 1.1 mrg cand_idx cand_num; 263 1.1 mrg 264 1.1 mrg /* Index of the next candidate record for the same statement. 265 1.1 mrg A statement may be useful in more than one way (e.g., due to 266 1.1 mrg commutativity). So we can have multiple "interpretations" 267 1.1 mrg of a statement. */ 268 1.1 mrg cand_idx next_interp; 269 1.1 mrg 270 1.1 mrg /* Index of the first candidate record in a chain for the same 271 1.1 mrg statement. */ 272 1.1 mrg cand_idx first_interp; 273 1.1 mrg 274 1.1 mrg /* Index of the basis statement S0, if any, in the candidate vector. */ 275 1.1 mrg cand_idx basis; 276 1.1 mrg 277 1.1 mrg /* First candidate for which this candidate is a basis, if one exists. */ 278 1.1 mrg cand_idx dependent; 279 1.1 mrg 280 1.1 mrg /* Next candidate having the same basis as this one. */ 281 1.1 mrg cand_idx sibling; 282 1.1 mrg 283 1.1 mrg /* If this is a conditional candidate, the CAND_PHI candidate 284 1.1 mrg that defines the base SSA name B. */ 285 1.1 mrg cand_idx def_phi; 286 1.1 mrg 287 1.1 mrg /* Savings that can be expected from eliminating dead code if this 288 1.1 mrg candidate is replaced. */ 289 1.1 mrg int dead_savings; 290 1.1 mrg 291 1.1 mrg /* For PHI candidates, use a visited flag to keep from processing the 292 1.1 mrg same PHI twice from multiple paths. */ 293 1.1 mrg int visited; 294 1.1 mrg 295 1.1 mrg /* We sometimes have to cache a phi basis with a phi candidate to 296 1.1 mrg avoid processing it twice. Valid only if visited==1. */ 297 1.1 mrg tree cached_basis; 298 1.1 mrg }; 299 1.1 mrg 300 1.1 mrg typedef class slsr_cand_d slsr_cand, *slsr_cand_t; 301 1.1 mrg typedef const class slsr_cand_d *const_slsr_cand_t; 302 1.1 mrg 303 1.1 mrg /* Pointers to candidates are chained together as part of a mapping 304 1.1 mrg from base expressions to the candidates that use them. */ 305 1.1 mrg 306 1.1 mrg struct cand_chain_d 307 1.1 mrg { 308 1.1 mrg /* Base expression for the chain of candidates: often, but not 309 1.1 mrg always, an SSA name. */ 310 1.1 mrg tree base_expr; 311 1.1 mrg 312 1.1 mrg /* Pointer to a candidate. */ 313 1.1 mrg slsr_cand_t cand; 314 1.1 mrg 315 1.1 mrg /* Chain pointer. */ 316 1.1 mrg struct cand_chain_d *next; 317 1.1 mrg 318 1.1 mrg }; 319 1.1 mrg 320 1.1 mrg typedef struct cand_chain_d cand_chain, *cand_chain_t; 321 1.1 mrg typedef const struct cand_chain_d *const_cand_chain_t; 322 1.1 mrg 323 1.1 mrg /* Information about a unique "increment" associated with candidates 324 1.1 mrg having an SSA name for a stride. An increment is the difference 325 1.1 mrg between the index of the candidate and the index of its basis, 326 1.1 mrg i.e., (i - i') as discussed in the module commentary. 327 1.1 mrg 328 1.1 mrg When we are not going to generate address arithmetic we treat 329 1.1 mrg increments that differ only in sign as the same, allowing sharing 330 1.1 mrg of the cost of initializers. The absolute value of the increment 331 1.1 mrg is stored in the incr_info. */ 332 1.1 mrg 333 1.1 mrg class incr_info_d 334 1.1 mrg { 335 1.1 mrg public: 336 1.1 mrg /* The increment that relates a candidate to its basis. */ 337 1.1 mrg widest_int incr; 338 1.1 mrg 339 1.1 mrg /* How many times the increment occurs in the candidate tree. */ 340 1.1 mrg unsigned count; 341 1.1 mrg 342 1.1 mrg /* Cost of replacing candidates using this increment. Negative and 343 1.1 mrg zero costs indicate replacement should be performed. */ 344 1.1 mrg int cost; 345 1.1 mrg 346 1.1 mrg /* If this increment is profitable but is not -1, 0, or 1, it requires 347 1.1 mrg an initializer T_0 = stride * incr to be found or introduced in the 348 1.1 mrg nearest common dominator of all candidates. This field holds T_0 349 1.1 mrg for subsequent use. */ 350 1.1 mrg tree initializer; 351 1.1 mrg 352 1.1 mrg /* If the initializer was found to already exist, this is the block 353 1.1 mrg where it was found. */ 354 1.1 mrg basic_block init_bb; 355 1.1 mrg }; 356 1.1 mrg 357 1.1 mrg typedef class incr_info_d incr_info, *incr_info_t; 358 1.1 mrg 359 1.1 mrg /* Candidates are maintained in a vector. If candidate X dominates 360 1.1 mrg candidate Y, then X appears before Y in the vector; but the 361 1.1 mrg converse does not necessarily hold. */ 362 1.1 mrg static vec<slsr_cand_t> cand_vec; 363 1.1 mrg 364 1.1 mrg enum cost_consts 365 1.1 mrg { 366 1.1 mrg COST_NEUTRAL = 0, 367 1.1 mrg COST_INFINITE = 1000 368 1.1 mrg }; 369 1.1 mrg 370 1.1 mrg enum stride_status 371 1.1 mrg { 372 1.1 mrg UNKNOWN_STRIDE = 0, 373 1.1 mrg KNOWN_STRIDE = 1 374 1.1 mrg }; 375 1.1 mrg 376 1.1 mrg enum phi_adjust_status 377 1.1 mrg { 378 1.1 mrg NOT_PHI_ADJUST = 0, 379 1.1 mrg PHI_ADJUST = 1 380 1.1 mrg }; 381 1.1 mrg 382 1.1 mrg enum count_phis_status 383 1.1 mrg { 384 1.1 mrg DONT_COUNT_PHIS = 0, 385 1.1 mrg COUNT_PHIS = 1 386 1.1 mrg }; 387 1.1 mrg 388 1.1 mrg /* Constrain how many PHI nodes we will visit for a conditional 389 1.1 mrg candidate (depth and breadth). */ 390 1.1 mrg const int MAX_SPREAD = 16; 391 1.1 mrg 392 1.1 mrg /* Pointer map embodying a mapping from statements to candidates. */ 393 1.1 mrg static hash_map<gimple *, slsr_cand_t> *stmt_cand_map; 394 1.1 mrg 395 1.1 mrg /* Obstack for candidates. */ 396 1.1 mrg static struct obstack cand_obstack; 397 1.1 mrg 398 1.1 mrg /* Obstack for candidate chains. */ 399 1.1 mrg static struct obstack chain_obstack; 400 1.1 mrg 401 1.1 mrg /* An array INCR_VEC of incr_infos is used during analysis of related 402 1.1 mrg candidates having an SSA name for a stride. INCR_VEC_LEN describes 403 1.1 mrg its current length. MAX_INCR_VEC_LEN is used to avoid costly 404 1.1 mrg pathological cases. */ 405 1.1 mrg static incr_info_t incr_vec; 406 1.1 mrg static unsigned incr_vec_len; 407 1.1 mrg const int MAX_INCR_VEC_LEN = 16; 408 1.1 mrg 409 1.1 mrg /* For a chain of candidates with unknown stride, indicates whether or not 410 1.1 mrg we must generate pointer arithmetic when replacing statements. */ 411 1.1 mrg static bool address_arithmetic_p; 412 1.1 mrg 413 1.1 mrg /* Forward function declarations. */ 414 1.1 mrg static slsr_cand_t base_cand_from_table (tree); 415 1.1 mrg static tree introduce_cast_before_cand (slsr_cand_t, tree, tree); 416 1.1 mrg static bool legal_cast_p_1 (tree, tree); 417 1.1 mrg 418 1.1 mrg /* Produce a pointer to the IDX'th candidate in the candidate vector. */ 420 1.1 mrg 421 1.1 mrg static slsr_cand_t 422 1.1 mrg lookup_cand (cand_idx idx) 423 1.1 mrg { 424 1.1 mrg return cand_vec[idx]; 425 1.1 mrg } 426 1.1 mrg 427 1.1 mrg /* Helper for hashing a candidate chain header. */ 428 1.1 mrg 429 1.1 mrg struct cand_chain_hasher : nofree_ptr_hash <cand_chain> 430 1.1 mrg { 431 1.1 mrg static inline hashval_t hash (const cand_chain *); 432 1.1 mrg static inline bool equal (const cand_chain *, const cand_chain *); 433 1.1 mrg }; 434 1.1 mrg 435 1.1 mrg inline hashval_t 436 1.1 mrg cand_chain_hasher::hash (const cand_chain *p) 437 1.1 mrg { 438 1.1 mrg tree base_expr = p->base_expr; 439 1.1 mrg return iterative_hash_expr (base_expr, 0); 440 1.1 mrg } 441 1.1 mrg 442 1.1 mrg inline bool 443 1.1 mrg cand_chain_hasher::equal (const cand_chain *chain1, const cand_chain *chain2) 444 1.1 mrg { 445 1.1 mrg return operand_equal_p (chain1->base_expr, chain2->base_expr, 0); 446 1.1 mrg } 447 1.1 mrg 448 1.1 mrg /* Hash table embodying a mapping from base exprs to chains of candidates. */ 449 1.1 mrg static hash_table<cand_chain_hasher> *base_cand_map; 450 1.1 mrg 451 1.1 mrg /* Pointer map used by tree_to_aff_combination_expand. */ 453 1.1 mrg static hash_map<tree, name_expansion *> *name_expansions; 454 1.1 mrg /* Pointer map embodying a mapping from bases to alternative bases. */ 455 1.1 mrg static hash_map<tree, tree> *alt_base_map; 456 1.1 mrg 457 1.1 mrg /* Given BASE, use the tree affine combiniation facilities to 458 1.1 mrg find the underlying tree expression for BASE, with any 459 1.1 mrg immediate offset excluded. 460 1.1 mrg 461 1.1 mrg N.B. we should eliminate this backtracking with better forward 462 1.1 mrg analysis in a future release. */ 463 1.1 mrg 464 1.1 mrg static tree 465 1.1 mrg get_alternative_base (tree base) 466 1.1 mrg { 467 1.1 mrg tree *result = alt_base_map->get (base); 468 1.1 mrg 469 1.1 mrg if (result == NULL) 470 1.1 mrg { 471 1.1 mrg tree expr; 472 1.1 mrg aff_tree aff; 473 1.1 mrg 474 1.1 mrg tree_to_aff_combination_expand (base, TREE_TYPE (base), 475 1.1 mrg &aff, &name_expansions); 476 1.1 mrg aff.offset = 0; 477 1.1 mrg expr = aff_combination_to_tree (&aff); 478 1.1 mrg 479 1.1 mrg bool existed = alt_base_map->put (base, base == expr ? NULL : expr); 480 1.1 mrg gcc_assert (!existed); 481 1.1 mrg 482 1.1 mrg return expr == base ? NULL : expr; 483 1.1 mrg } 484 1.1 mrg 485 1.1 mrg return *result; 486 1.1 mrg } 487 1.1 mrg 488 1.1 mrg /* Look in the candidate table for a CAND_PHI that defines BASE and 489 1.1 mrg return it if found; otherwise return NULL. */ 490 1.1 mrg 491 1.1 mrg static cand_idx 492 1.1 mrg find_phi_def (tree base) 493 1.1 mrg { 494 1.1 mrg slsr_cand_t c; 495 1.1 mrg 496 1.1 mrg if (TREE_CODE (base) != SSA_NAME) 497 1.1 mrg return 0; 498 1.1 mrg 499 1.1 mrg c = base_cand_from_table (base); 500 1.1 mrg 501 1.1 mrg if (!c || c->kind != CAND_PHI 502 1.1 mrg || SSA_NAME_OCCURS_IN_ABNORMAL_PHI (gimple_phi_result (c->cand_stmt))) 503 1.1 mrg return 0; 504 1.1 mrg 505 1.1 mrg return c->cand_num; 506 1.1 mrg } 507 1.1 mrg 508 1.1 mrg /* Determine whether all uses of NAME are directly or indirectly 509 1.1 mrg used by STMT. That is, we want to know whether if STMT goes 510 1.1 mrg dead, the definition of NAME also goes dead. */ 511 1.1 mrg static bool 512 1.1 mrg uses_consumed_by_stmt (tree name, gimple *stmt, unsigned recurse = 0) 513 1.1 mrg { 514 1.1 mrg gimple *use_stmt; 515 1.1 mrg imm_use_iterator iter; 516 1.1 mrg bool retval = true; 517 1.1 mrg 518 1.1 mrg FOR_EACH_IMM_USE_STMT (use_stmt, iter, name) 519 1.1 mrg { 520 1.1 mrg if (use_stmt == stmt || is_gimple_debug (use_stmt)) 521 1.1 mrg continue; 522 1.1 mrg 523 1.1 mrg if (!is_gimple_assign (use_stmt) 524 1.1 mrg || !gimple_get_lhs (use_stmt) 525 1.1 mrg || !is_gimple_reg (gimple_get_lhs (use_stmt)) 526 1.1 mrg || recurse >= 10 527 1.1 mrg || !uses_consumed_by_stmt (gimple_get_lhs (use_stmt), stmt, 528 1.1 mrg recurse + 1)) 529 1.1 mrg { 530 1.1 mrg retval = false; 531 1.1 mrg break; 532 1.1 mrg } 533 1.1 mrg } 534 1.1 mrg 535 1.1 mrg return retval; 536 1.1 mrg } 537 1.1 mrg 538 1.1 mrg /* Helper routine for find_basis_for_candidate. May be called twice: 539 1.1 mrg once for the candidate's base expr, and optionally again either for 540 1.1 mrg the candidate's phi definition or for a CAND_REF's alternative base 541 1.1 mrg expression. */ 542 1.1 mrg 543 1.1 mrg static slsr_cand_t 544 1.1 mrg find_basis_for_base_expr (slsr_cand_t c, tree base_expr) 545 1.1 mrg { 546 1.1 mrg cand_chain mapping_key; 547 1.1 mrg cand_chain_t chain; 548 1.1 mrg slsr_cand_t basis = NULL; 549 1.1 mrg 550 1.1 mrg // Limit potential of N^2 behavior for long candidate chains. 551 1.1 mrg int iters = 0; 552 1.1 mrg int max_iters = param_max_slsr_candidate_scan; 553 1.1 mrg 554 1.1 mrg mapping_key.base_expr = base_expr; 555 1.1 mrg chain = base_cand_map->find (&mapping_key); 556 1.1 mrg 557 1.1 mrg for (; chain && iters < max_iters; chain = chain->next, ++iters) 558 1.1 mrg { 559 1.1 mrg slsr_cand_t one_basis = chain->cand; 560 1.1 mrg 561 1.1 mrg if (one_basis->kind != c->kind 562 1.1 mrg || one_basis->cand_stmt == c->cand_stmt 563 1.1 mrg || !operand_equal_p (one_basis->stride, c->stride, 0) 564 1.1 mrg || !types_compatible_p (one_basis->cand_type, c->cand_type) 565 1.1 mrg || !types_compatible_p (one_basis->stride_type, c->stride_type) 566 1.1 mrg || !dominated_by_p (CDI_DOMINATORS, 567 1.1 mrg gimple_bb (c->cand_stmt), 568 1.1 mrg gimple_bb (one_basis->cand_stmt))) 569 1.1 mrg continue; 570 1.1 mrg 571 1.1 mrg tree lhs = gimple_assign_lhs (one_basis->cand_stmt); 572 1.1 mrg if (lhs && TREE_CODE (lhs) == SSA_NAME 573 1.1 mrg && SSA_NAME_OCCURS_IN_ABNORMAL_PHI (lhs)) 574 1.1 mrg continue; 575 1.1 mrg 576 1.1 mrg if (!basis || basis->cand_num < one_basis->cand_num) 577 1.1 mrg basis = one_basis; 578 1.1 mrg } 579 1.1 mrg 580 1.1 mrg return basis; 581 1.1 mrg } 582 1.1 mrg 583 1.1 mrg /* Use the base expr from candidate C to look for possible candidates 584 1.1 mrg that can serve as a basis for C. Each potential basis must also 585 1.1 mrg appear in a block that dominates the candidate statement and have 586 1.1 mrg the same stride and type. If more than one possible basis exists, 587 1.1 mrg the one with highest index in the vector is chosen; this will be 588 1.1 mrg the most immediately dominating basis. */ 589 1.1 mrg 590 1.1 mrg static int 591 1.1 mrg find_basis_for_candidate (slsr_cand_t c) 592 1.1 mrg { 593 1.1 mrg slsr_cand_t basis = find_basis_for_base_expr (c, c->base_expr); 594 1.1 mrg 595 1.1 mrg /* If a candidate doesn't have a basis using its base expression, 596 1.1 mrg it may have a basis hidden by one or more intervening phis. */ 597 1.1 mrg if (!basis && c->def_phi) 598 1.1 mrg { 599 1.1 mrg basic_block basis_bb, phi_bb; 600 1.1 mrg slsr_cand_t phi_cand = lookup_cand (c->def_phi); 601 1.1 mrg basis = find_basis_for_base_expr (c, phi_cand->base_expr); 602 1.1 mrg 603 1.1 mrg if (basis) 604 1.1 mrg { 605 1.1 mrg /* A hidden basis must dominate the phi-definition of the 606 1.1 mrg candidate's base name. */ 607 1.1 mrg phi_bb = gimple_bb (phi_cand->cand_stmt); 608 1.1 mrg basis_bb = gimple_bb (basis->cand_stmt); 609 1.1 mrg 610 1.1 mrg if (phi_bb == basis_bb 611 1.1 mrg || !dominated_by_p (CDI_DOMINATORS, phi_bb, basis_bb)) 612 1.1 mrg { 613 1.1 mrg basis = NULL; 614 1.1 mrg c->basis = 0; 615 1.1 mrg } 616 1.1 mrg 617 1.1 mrg /* If we found a hidden basis, estimate additional dead-code 618 1.1 mrg savings if the phi and its feeding statements can be removed. */ 619 1.1 mrg tree feeding_var = gimple_phi_result (phi_cand->cand_stmt); 620 1.1 mrg if (basis && uses_consumed_by_stmt (feeding_var, c->cand_stmt)) 621 1.1 mrg c->dead_savings += phi_cand->dead_savings; 622 1.1 mrg } 623 1.1 mrg } 624 1.1 mrg 625 1.1 mrg if (flag_expensive_optimizations && !basis && c->kind == CAND_REF) 626 1.1 mrg { 627 1.1 mrg tree alt_base_expr = get_alternative_base (c->base_expr); 628 1.1 mrg if (alt_base_expr) 629 1.1 mrg basis = find_basis_for_base_expr (c, alt_base_expr); 630 1.1 mrg } 631 1.1 mrg 632 1.1 mrg if (basis) 633 1.1 mrg { 634 1.1 mrg c->sibling = basis->dependent; 635 1.1 mrg basis->dependent = c->cand_num; 636 1.1 mrg return basis->cand_num; 637 1.1 mrg } 638 1.1 mrg 639 1.1 mrg return 0; 640 1.1 mrg } 641 1.1 mrg 642 1.1 mrg /* Record a mapping from BASE to C, indicating that C may potentially serve 643 1.1 mrg as a basis using that base expression. BASE may be the same as 644 1.1 mrg C->BASE_EXPR; alternatively BASE can be a different tree that share the 645 1.1 mrg underlining expression of C->BASE_EXPR. */ 646 1.1 mrg 647 1.1 mrg static void 648 1.1 mrg record_potential_basis (slsr_cand_t c, tree base) 649 1.1 mrg { 650 1.1 mrg cand_chain_t node; 651 1.1 mrg cand_chain **slot; 652 1.1 mrg 653 1.1 mrg gcc_assert (base); 654 1.1 mrg 655 1.1 mrg node = (cand_chain_t) obstack_alloc (&chain_obstack, sizeof (cand_chain)); 656 1.1 mrg node->base_expr = base; 657 1.1 mrg node->cand = c; 658 1.1 mrg node->next = NULL; 659 1.1 mrg slot = base_cand_map->find_slot (node, INSERT); 660 1.1 mrg 661 1.1 mrg if (*slot) 662 1.1 mrg { 663 1.1 mrg cand_chain_t head = (cand_chain_t) (*slot); 664 1.1 mrg node->next = head->next; 665 1.1 mrg head->next = node; 666 1.1 mrg } 667 1.1 mrg else 668 1.1 mrg *slot = node; 669 1.1 mrg } 670 1.1 mrg 671 1.1 mrg /* Allocate storage for a new candidate and initialize its fields. 672 1.1 mrg Attempt to find a basis for the candidate. 673 1.1 mrg 674 1.1 mrg For CAND_REF, an alternative base may also be recorded and used 675 1.1 mrg to find a basis. This helps cases where the expression hidden 676 1.1 mrg behind BASE (which is usually an SSA_NAME) has immediate offset, 677 1.1 mrg e.g. 678 1.1 mrg 679 1.1 mrg a2[i][j] = 1; 680 1.1 mrg a2[i + 20][j] = 2; */ 681 1.1 mrg 682 1.1 mrg static slsr_cand_t 683 1.1 mrg alloc_cand_and_find_basis (enum cand_kind kind, gimple *gs, tree base, 684 1.1 mrg const widest_int &index, tree stride, tree ctype, 685 1.1 mrg tree stype, unsigned savings) 686 1.1 mrg { 687 1.1 mrg slsr_cand_t c = (slsr_cand_t) obstack_alloc (&cand_obstack, 688 1.1 mrg sizeof (slsr_cand)); 689 1.1 mrg c->cand_stmt = gs; 690 1.1 mrg c->base_expr = base; 691 1.1 mrg c->stride = stride; 692 1.1 mrg c->index = index; 693 1.1 mrg c->cand_type = ctype; 694 1.1 mrg c->stride_type = stype; 695 1.1 mrg c->kind = kind; 696 1.1 mrg c->cand_num = cand_vec.length (); 697 1.1 mrg c->next_interp = 0; 698 1.1 mrg c->first_interp = c->cand_num; 699 1.1 mrg c->dependent = 0; 700 1.1 mrg c->sibling = 0; 701 1.1 mrg c->def_phi = kind == CAND_MULT ? find_phi_def (base) : 0; 702 1.1 mrg c->dead_savings = savings; 703 1.1 mrg c->visited = 0; 704 1.1 mrg c->cached_basis = NULL_TREE; 705 1.1 mrg 706 1.1 mrg cand_vec.safe_push (c); 707 1.1 mrg 708 1.1 mrg if (kind == CAND_PHI) 709 1.1 mrg c->basis = 0; 710 1.1 mrg else 711 1.1 mrg c->basis = find_basis_for_candidate (c); 712 1.1 mrg 713 1.1 mrg record_potential_basis (c, base); 714 1.1 mrg if (flag_expensive_optimizations && kind == CAND_REF) 715 1.1 mrg { 716 1.1 mrg tree alt_base = get_alternative_base (base); 717 1.1 mrg if (alt_base) 718 1.1 mrg record_potential_basis (c, alt_base); 719 1.1 mrg } 720 1.1 mrg 721 1.1 mrg return c; 722 1.1 mrg } 723 1.1 mrg 724 1.1 mrg /* Determine the target cost of statement GS when compiling according 725 1.1 mrg to SPEED. */ 726 1.1 mrg 727 1.1 mrg static int 728 1.1 mrg stmt_cost (gimple *gs, bool speed) 729 1.1 mrg { 730 1.1 mrg tree lhs, rhs1, rhs2; 731 1.1 mrg machine_mode lhs_mode; 732 1.1 mrg 733 1.1 mrg gcc_assert (is_gimple_assign (gs)); 734 1.1 mrg lhs = gimple_assign_lhs (gs); 735 1.1 mrg rhs1 = gimple_assign_rhs1 (gs); 736 1.1 mrg lhs_mode = TYPE_MODE (TREE_TYPE (lhs)); 737 1.1 mrg 738 1.1 mrg switch (gimple_assign_rhs_code (gs)) 739 1.1 mrg { 740 1.1 mrg case MULT_EXPR: 741 1.1 mrg rhs2 = gimple_assign_rhs2 (gs); 742 1.1 mrg 743 1.1 mrg if (tree_fits_shwi_p (rhs2)) 744 1.1 mrg return mult_by_coeff_cost (tree_to_shwi (rhs2), lhs_mode, speed); 745 1.1 mrg 746 1.1 mrg gcc_assert (TREE_CODE (rhs1) != INTEGER_CST); 747 1.1 mrg return mul_cost (speed, lhs_mode); 748 1.1 mrg 749 1.1 mrg case PLUS_EXPR: 750 1.1 mrg case POINTER_PLUS_EXPR: 751 1.1 mrg case MINUS_EXPR: 752 1.1 mrg return add_cost (speed, lhs_mode); 753 1.1 mrg 754 1.1 mrg case NEGATE_EXPR: 755 1.1 mrg return neg_cost (speed, lhs_mode); 756 1.1 mrg 757 1.1 mrg CASE_CONVERT: 758 1.1 mrg return convert_cost (lhs_mode, TYPE_MODE (TREE_TYPE (rhs1)), speed); 759 1.1 mrg 760 1.1 mrg /* Note that we don't assign costs to copies that in most cases 761 1.1 mrg will go away. */ 762 1.1 mrg case SSA_NAME: 763 1.1 mrg return 0; 764 1.1 mrg 765 1.1 mrg default: 766 1.1 mrg ; 767 1.1 mrg } 768 1.1 mrg 769 1.1 mrg gcc_unreachable (); 770 1.1 mrg } 771 1.1 mrg 772 1.1 mrg /* Look up the defining statement for BASE_IN and return a pointer 773 1.1 mrg to its candidate in the candidate table, if any; otherwise NULL. 774 1.1 mrg Only CAND_ADD and CAND_MULT candidates are returned. */ 775 1.1 mrg 776 1.1 mrg static slsr_cand_t 777 1.1 mrg base_cand_from_table (tree base_in) 778 1.1 mrg { 779 1.1 mrg slsr_cand_t *result; 780 1.1 mrg 781 1.1 mrg gimple *def = SSA_NAME_DEF_STMT (base_in); 782 1.1 mrg if (!def) 783 1.1 mrg return (slsr_cand_t) NULL; 784 1.1 mrg 785 1.1 mrg result = stmt_cand_map->get (def); 786 1.1 mrg 787 1.1 mrg if (result && (*result)->kind != CAND_REF) 788 1.1 mrg return *result; 789 1.1 mrg 790 1.1 mrg return (slsr_cand_t) NULL; 791 1.1 mrg } 792 1.1 mrg 793 1.1 mrg /* Add an entry to the statement-to-candidate mapping. */ 794 1.1 mrg 795 1.1 mrg static void 796 1.1 mrg add_cand_for_stmt (gimple *gs, slsr_cand_t c) 797 1.1 mrg { 798 1.1 mrg bool existed = stmt_cand_map->put (gs, c); 799 1.1 mrg gcc_assert (!existed); 800 1.1 mrg } 801 1.1 mrg 802 1.1 mrg /* Given PHI which contains a phi statement, determine whether it 804 1.1 mrg satisfies all the requirements of a phi candidate. If so, create 805 1.1 mrg a candidate. Note that a CAND_PHI never has a basis itself, but 806 1.1 mrg is used to help find a basis for subsequent candidates. */ 807 1.1 mrg 808 1.1 mrg static void 809 1.1 mrg slsr_process_phi (gphi *phi, bool speed) 810 1.1 mrg { 811 1.1 mrg unsigned i; 812 1.1 mrg tree arg0_base = NULL_TREE, base_type; 813 1.1 mrg slsr_cand_t c; 814 1.1 mrg class loop *cand_loop = gimple_bb (phi)->loop_father; 815 1.1 mrg unsigned savings = 0; 816 1.1 mrg 817 1.1 mrg /* A CAND_PHI requires each of its arguments to have the same 818 1.1 mrg derived base name. (See the module header commentary for a 819 1.1 mrg definition of derived base names.) Furthermore, all feeding 820 1.1 mrg definitions must be in the same position in the loop hierarchy 821 1.1 mrg as PHI. */ 822 1.1 mrg 823 1.1 mrg for (i = 0; i < gimple_phi_num_args (phi); i++) 824 1.1 mrg { 825 1.1 mrg slsr_cand_t arg_cand; 826 1.1 mrg tree arg = gimple_phi_arg_def (phi, i); 827 1.1 mrg tree derived_base_name = NULL_TREE; 828 1.1 mrg gimple *arg_stmt = NULL; 829 1.1 mrg basic_block arg_bb = NULL; 830 1.1 mrg 831 1.1 mrg if (TREE_CODE (arg) != SSA_NAME) 832 1.1 mrg return; 833 1.1 mrg 834 1.1 mrg arg_cand = base_cand_from_table (arg); 835 1.1 mrg 836 1.1 mrg if (arg_cand) 837 1.1 mrg { 838 1.1 mrg while (arg_cand->kind != CAND_ADD && arg_cand->kind != CAND_PHI) 839 1.1 mrg { 840 1.1 mrg if (!arg_cand->next_interp) 841 1.1 mrg return; 842 1.1 mrg 843 1.1 mrg arg_cand = lookup_cand (arg_cand->next_interp); 844 1.1 mrg } 845 1.1 mrg 846 1.1 mrg if (!integer_onep (arg_cand->stride)) 847 1.1 mrg return; 848 1.1 mrg 849 1.1 mrg derived_base_name = arg_cand->base_expr; 850 1.1 mrg arg_stmt = arg_cand->cand_stmt; 851 1.1 mrg arg_bb = gimple_bb (arg_stmt); 852 1.1 mrg 853 1.1 mrg /* Gather potential dead code savings if the phi statement 854 1.1 mrg can be removed later on. */ 855 1.1 mrg if (uses_consumed_by_stmt (arg, phi)) 856 1.1 mrg { 857 1.1 mrg if (gimple_code (arg_stmt) == GIMPLE_PHI) 858 1.1 mrg savings += arg_cand->dead_savings; 859 1.1 mrg else 860 1.1 mrg savings += stmt_cost (arg_stmt, speed); 861 1.1 mrg } 862 1.1 mrg } 863 1.1 mrg else if (SSA_NAME_IS_DEFAULT_DEF (arg)) 864 1.1 mrg { 865 1.1 mrg derived_base_name = arg; 866 1.1 mrg arg_bb = single_succ (ENTRY_BLOCK_PTR_FOR_FN (cfun)); 867 1.1 mrg } 868 1.1 mrg 869 1.1 mrg if (!arg_bb || arg_bb->loop_father != cand_loop) 870 1.1 mrg return; 871 1.1 mrg 872 1.1 mrg if (i == 0) 873 1.1 mrg arg0_base = derived_base_name; 874 1.1 mrg else if (!operand_equal_p (derived_base_name, arg0_base, 0)) 875 1.1 mrg return; 876 1.1 mrg } 877 1.1 mrg 878 1.1 mrg /* Create the candidate. "alloc_cand_and_find_basis" is named 879 1.1 mrg misleadingly for this case, as no basis will be sought for a 880 1.1 mrg CAND_PHI. */ 881 1.1 mrg base_type = TREE_TYPE (arg0_base); 882 1.1 mrg 883 1.1 mrg c = alloc_cand_and_find_basis (CAND_PHI, phi, arg0_base, 884 1.1 mrg 0, integer_one_node, base_type, 885 1.1 mrg sizetype, savings); 886 1.1 mrg 887 1.1 mrg /* Add the candidate to the statement-candidate mapping. */ 888 1.1 mrg add_cand_for_stmt (phi, c); 889 1.1 mrg } 890 1.1 mrg 891 1.1 mrg /* Given PBASE which is a pointer to tree, look up the defining 892 1.1 mrg statement for it and check whether the candidate is in the 893 1.1 mrg form of: 894 1.1 mrg 895 1.1 mrg X = B + (1 * S), S is integer constant 896 1.1 mrg X = B + (i * S), S is integer one 897 1.1 mrg 898 1.1 mrg If so, set PBASE to the candidate's base_expr and return double 899 1.1 mrg int (i * S). 900 1.1 mrg Otherwise, just return double int zero. */ 901 1.1 mrg 902 1.1 mrg static widest_int 903 1.1 mrg backtrace_base_for_ref (tree *pbase) 904 1.1 mrg { 905 1.1 mrg tree base_in = *pbase; 906 1.1 mrg slsr_cand_t base_cand; 907 1.1 mrg 908 1.1 mrg STRIP_NOPS (base_in); 909 1.1 mrg 910 1.1 mrg /* Strip off widening conversion(s) to handle cases where 911 1.1 mrg e.g. 'B' is widened from an 'int' in order to calculate 912 1.1 mrg a 64-bit address. */ 913 1.1 mrg if (CONVERT_EXPR_P (base_in) 914 1.1 mrg && legal_cast_p_1 (TREE_TYPE (base_in), 915 1.1 mrg TREE_TYPE (TREE_OPERAND (base_in, 0)))) 916 1.1 mrg base_in = get_unwidened (base_in, NULL_TREE); 917 1.1 mrg 918 1.1 mrg if (TREE_CODE (base_in) != SSA_NAME) 919 1.1 mrg return 0; 920 1.1 mrg 921 1.1 mrg base_cand = base_cand_from_table (base_in); 922 1.1 mrg 923 1.1 mrg while (base_cand && base_cand->kind != CAND_PHI) 924 1.1 mrg { 925 1.1 mrg if (base_cand->kind == CAND_ADD 926 1.1 mrg && base_cand->index == 1 927 1.1 mrg && TREE_CODE (base_cand->stride) == INTEGER_CST) 928 1.1 mrg { 929 1.1 mrg /* X = B + (1 * S), S is integer constant. */ 930 1.1 mrg *pbase = base_cand->base_expr; 931 1.1 mrg return wi::to_widest (base_cand->stride); 932 1.1 mrg } 933 1.1 mrg else if (base_cand->kind == CAND_ADD 934 1.1 mrg && TREE_CODE (base_cand->stride) == INTEGER_CST 935 1.1 mrg && integer_onep (base_cand->stride)) 936 1.1 mrg { 937 1.1 mrg /* X = B + (i * S), S is integer one. */ 938 1.1 mrg *pbase = base_cand->base_expr; 939 1.1 mrg return base_cand->index; 940 1.1 mrg } 941 1.1 mrg 942 1.1 mrg base_cand = lookup_cand (base_cand->next_interp); 943 1.1 mrg } 944 1.1 mrg 945 1.1 mrg return 0; 946 1.1 mrg } 947 1.1 mrg 948 1.1 mrg /* Look for the following pattern: 949 1.1 mrg 950 1.1 mrg *PBASE: MEM_REF (T1, C1) 951 1.1 mrg 952 1.1 mrg *POFFSET: MULT_EXPR (T2, C3) [C2 is zero] 953 1.1 mrg or 954 1.1 mrg MULT_EXPR (PLUS_EXPR (T2, C2), C3) 955 1.1 mrg or 956 1.1 mrg MULT_EXPR (MINUS_EXPR (T2, -C2), C3) 957 1.1 mrg 958 1.1 mrg *PINDEX: C4 * BITS_PER_UNIT 959 1.1 mrg 960 1.1 mrg If not present, leave the input values unchanged and return FALSE. 961 1.1 mrg Otherwise, modify the input values as follows and return TRUE: 962 1.1 mrg 963 1.1 mrg *PBASE: T1 964 1.1 mrg *POFFSET: MULT_EXPR (T2, C3) 965 1.1 mrg *PINDEX: C1 + (C2 * C3) + C4 966 1.1 mrg 967 1.1 mrg When T2 is recorded by a CAND_ADD in the form of (T2' + C5), it 968 1.1 mrg will be further restructured to: 969 1.1 mrg 970 1.1 mrg *PBASE: T1 971 1.1 mrg *POFFSET: MULT_EXPR (T2', C3) 972 1.1 mrg *PINDEX: C1 + (C2 * C3) + C4 + (C5 * C3) */ 973 1.1 mrg 974 1.1 mrg static bool 975 1.1 mrg restructure_reference (tree *pbase, tree *poffset, widest_int *pindex, 976 1.1 mrg tree *ptype) 977 1.1 mrg { 978 1.1 mrg tree base = *pbase, offset = *poffset; 979 1.1 mrg widest_int index = *pindex; 980 1.1 mrg tree mult_op0, t1, t2, type; 981 1.1 mrg widest_int c1, c2, c3, c4, c5; 982 1.1 mrg offset_int mem_offset; 983 1.1 mrg 984 1.1 mrg if (!base 985 1.1 mrg || !offset 986 1.1 mrg || TREE_CODE (base) != MEM_REF 987 1.1 mrg || !mem_ref_offset (base).is_constant (&mem_offset) 988 1.1 mrg || TREE_CODE (offset) != MULT_EXPR 989 1.1 mrg || TREE_CODE (TREE_OPERAND (offset, 1)) != INTEGER_CST 990 1.1 mrg || wi::umod_floor (index, BITS_PER_UNIT) != 0) 991 1.1 mrg return false; 992 1.1 mrg 993 1.1 mrg t1 = TREE_OPERAND (base, 0); 994 1.1 mrg c1 = widest_int::from (mem_offset, SIGNED); 995 1.1 mrg type = TREE_TYPE (TREE_OPERAND (base, 1)); 996 1.1 mrg 997 1.1 mrg mult_op0 = TREE_OPERAND (offset, 0); 998 1.1 mrg c3 = wi::to_widest (TREE_OPERAND (offset, 1)); 999 1.1 mrg 1000 1.1 mrg if (TREE_CODE (mult_op0) == PLUS_EXPR) 1001 1.1 mrg 1002 1.1 mrg if (TREE_CODE (TREE_OPERAND (mult_op0, 1)) == INTEGER_CST) 1003 1.1 mrg { 1004 1.1 mrg t2 = TREE_OPERAND (mult_op0, 0); 1005 1.1 mrg c2 = wi::to_widest (TREE_OPERAND (mult_op0, 1)); 1006 1.1 mrg } 1007 1.1 mrg else 1008 1.1 mrg return false; 1009 1.1 mrg 1010 1.1 mrg else if (TREE_CODE (mult_op0) == MINUS_EXPR) 1011 1.1 mrg 1012 1.1 mrg if (TREE_CODE (TREE_OPERAND (mult_op0, 1)) == INTEGER_CST) 1013 1.1 mrg { 1014 1.1 mrg t2 = TREE_OPERAND (mult_op0, 0); 1015 1.1 mrg c2 = -wi::to_widest (TREE_OPERAND (mult_op0, 1)); 1016 1.1 mrg } 1017 1.1 mrg else 1018 1.1 mrg return false; 1019 1.1 mrg 1020 1.1 mrg else 1021 1.1 mrg { 1022 1.1 mrg t2 = mult_op0; 1023 1.1 mrg c2 = 0; 1024 1.1 mrg } 1025 1.1 mrg 1026 1.1 mrg c4 = index >> LOG2_BITS_PER_UNIT; 1027 1.1 mrg c5 = backtrace_base_for_ref (&t2); 1028 1.1 mrg 1029 1.1 mrg *pbase = t1; 1030 1.1 mrg *poffset = fold_build2 (MULT_EXPR, sizetype, fold_convert (sizetype, t2), 1031 1.1 mrg wide_int_to_tree (sizetype, c3)); 1032 1.1 mrg *pindex = c1 + c2 * c3 + c4 + c5 * c3; 1033 1.1 mrg *ptype = type; 1034 1.1 mrg 1035 1.1 mrg return true; 1036 1.1 mrg } 1037 1.1 mrg 1038 1.1 mrg /* Given GS which contains a data reference, create a CAND_REF entry in 1039 1.1 mrg the candidate table and attempt to find a basis. */ 1040 1.1 mrg 1041 1.1 mrg static void 1042 1.1 mrg slsr_process_ref (gimple *gs) 1043 1.1 mrg { 1044 1.1 mrg tree ref_expr, base, offset, type; 1045 1.1 mrg poly_int64 bitsize, bitpos; 1046 1.1 mrg machine_mode mode; 1047 1.1 mrg int unsignedp, reversep, volatilep; 1048 1.1 mrg slsr_cand_t c; 1049 1.1 mrg 1050 1.1 mrg if (gimple_vdef (gs)) 1051 1.1 mrg ref_expr = gimple_assign_lhs (gs); 1052 1.1 mrg else 1053 1.1 mrg ref_expr = gimple_assign_rhs1 (gs); 1054 1.1 mrg 1055 1.1 mrg if (!handled_component_p (ref_expr) 1056 1.1 mrg || TREE_CODE (ref_expr) == BIT_FIELD_REF 1057 1.1 mrg || (TREE_CODE (ref_expr) == COMPONENT_REF 1058 1.1 mrg && DECL_BIT_FIELD (TREE_OPERAND (ref_expr, 1)))) 1059 1.1 mrg return; 1060 1.1 mrg 1061 1.1 mrg base = get_inner_reference (ref_expr, &bitsize, &bitpos, &offset, &mode, 1062 1.1 mrg &unsignedp, &reversep, &volatilep); 1063 1.1 mrg HOST_WIDE_INT cbitpos; 1064 1.1 mrg if (reversep || !bitpos.is_constant (&cbitpos)) 1065 1.1 mrg return; 1066 1.1 mrg widest_int index = cbitpos; 1067 1.1 mrg 1068 1.1 mrg if (!restructure_reference (&base, &offset, &index, &type)) 1069 1.1 mrg return; 1070 1.1 mrg 1071 1.1 mrg c = alloc_cand_and_find_basis (CAND_REF, gs, base, index, offset, 1072 1.1 mrg type, sizetype, 0); 1073 1.1 mrg 1074 1.1 mrg /* Add the candidate to the statement-candidate mapping. */ 1075 1.1 mrg add_cand_for_stmt (gs, c); 1076 1.1 mrg } 1077 1.1 mrg 1078 1.1 mrg /* Create a candidate entry for a statement GS, where GS multiplies 1079 1.1 mrg two SSA names BASE_IN and STRIDE_IN. Propagate any known information 1080 1.1 mrg about the two SSA names into the new candidate. Return the new 1081 1.1 mrg candidate. */ 1082 1.1 mrg 1083 1.1 mrg static slsr_cand_t 1084 1.1 mrg create_mul_ssa_cand (gimple *gs, tree base_in, tree stride_in, bool speed) 1085 1.1 mrg { 1086 1.1 mrg tree base = NULL_TREE, stride = NULL_TREE, ctype = NULL_TREE; 1087 1.1 mrg tree stype = NULL_TREE; 1088 1.1 mrg widest_int index; 1089 1.1 mrg unsigned savings = 0; 1090 1.1 mrg slsr_cand_t c; 1091 1.1 mrg slsr_cand_t base_cand = base_cand_from_table (base_in); 1092 1.1 mrg 1093 1.1 mrg /* Look at all interpretations of the base candidate, if necessary, 1094 1.1 mrg to find information to propagate into this candidate. */ 1095 1.1 mrg while (base_cand && !base && base_cand->kind != CAND_PHI) 1096 1.1 mrg { 1097 1.1 mrg 1098 1.1 mrg if (base_cand->kind == CAND_MULT && integer_onep (base_cand->stride)) 1099 1.1 mrg { 1100 1.1 mrg /* Y = (B + i') * 1 1101 1.1 mrg X = Y * Z 1102 1.1 mrg ================ 1103 1.1 mrg X = (B + i') * Z */ 1104 1.1 mrg base = base_cand->base_expr; 1105 1.1 mrg index = base_cand->index; 1106 1.1 mrg stride = stride_in; 1107 1.1 mrg ctype = base_cand->cand_type; 1108 1.1 mrg stype = TREE_TYPE (stride_in); 1109 1.1 mrg if (has_single_use (base_in)) 1110 1.1 mrg savings = (base_cand->dead_savings 1111 1.1 mrg + stmt_cost (base_cand->cand_stmt, speed)); 1112 1.1 mrg } 1113 1.1 mrg else if (base_cand->kind == CAND_ADD 1114 1.1 mrg && TREE_CODE (base_cand->stride) == INTEGER_CST) 1115 1.1 mrg { 1116 1.1 mrg /* Y = B + (i' * S), S constant 1117 1.1 mrg X = Y * Z 1118 1.1 mrg ============================ 1119 1.1 mrg X = B + ((i' * S) * Z) */ 1120 1.1 mrg base = base_cand->base_expr; 1121 1.1 mrg index = base_cand->index * wi::to_widest (base_cand->stride); 1122 1.1 mrg stride = stride_in; 1123 1.1 mrg ctype = base_cand->cand_type; 1124 1.1 mrg stype = TREE_TYPE (stride_in); 1125 1.1 mrg if (has_single_use (base_in)) 1126 1.1 mrg savings = (base_cand->dead_savings 1127 1.1 mrg + stmt_cost (base_cand->cand_stmt, speed)); 1128 1.1 mrg } 1129 1.1 mrg 1130 1.1 mrg base_cand = lookup_cand (base_cand->next_interp); 1131 1.1 mrg } 1132 1.1 mrg 1133 1.1 mrg if (!base) 1134 1.1 mrg { 1135 1.1 mrg /* No interpretations had anything useful to propagate, so 1136 1.1 mrg produce X = (Y + 0) * Z. */ 1137 1.1 mrg base = base_in; 1138 1.1 mrg index = 0; 1139 1.1 mrg stride = stride_in; 1140 1.1 mrg ctype = TREE_TYPE (base_in); 1141 1.1 mrg stype = TREE_TYPE (stride_in); 1142 1.1 mrg } 1143 1.1 mrg 1144 1.1 mrg c = alloc_cand_and_find_basis (CAND_MULT, gs, base, index, stride, 1145 1.1 mrg ctype, stype, savings); 1146 1.1 mrg return c; 1147 1.1 mrg } 1148 1.1 mrg 1149 1.1 mrg /* Create a candidate entry for a statement GS, where GS multiplies 1150 1.1 mrg SSA name BASE_IN by constant STRIDE_IN. Propagate any known 1151 1.1 mrg information about BASE_IN into the new candidate. Return the new 1152 1.1 mrg candidate. */ 1153 1.1 mrg 1154 1.1 mrg static slsr_cand_t 1155 1.1 mrg create_mul_imm_cand (gimple *gs, tree base_in, tree stride_in, bool speed) 1156 1.1 mrg { 1157 1.1 mrg tree base = NULL_TREE, stride = NULL_TREE, ctype = NULL_TREE; 1158 1.1 mrg widest_int index, temp; 1159 1.1 mrg unsigned savings = 0; 1160 1.1 mrg slsr_cand_t c; 1161 1.1 mrg slsr_cand_t base_cand = base_cand_from_table (base_in); 1162 1.1 mrg 1163 1.1 mrg /* Look at all interpretations of the base candidate, if necessary, 1164 1.1 mrg to find information to propagate into this candidate. */ 1165 1.1 mrg while (base_cand && !base && base_cand->kind != CAND_PHI) 1166 1.1 mrg { 1167 1.1 mrg if (base_cand->kind == CAND_MULT 1168 1.1 mrg && TREE_CODE (base_cand->stride) == INTEGER_CST) 1169 1.1 mrg { 1170 1.1 mrg /* Y = (B + i') * S, S constant 1171 1.1 mrg X = Y * c 1172 1.1 mrg ============================ 1173 1.1 mrg X = (B + i') * (S * c) */ 1174 1.1 mrg temp = wi::to_widest (base_cand->stride) * wi::to_widest (stride_in); 1175 1.1 mrg if (wi::fits_to_tree_p (temp, TREE_TYPE (stride_in))) 1176 1.1 mrg { 1177 1.1 mrg base = base_cand->base_expr; 1178 1.1 mrg index = base_cand->index; 1179 1.1 mrg stride = wide_int_to_tree (TREE_TYPE (stride_in), temp); 1180 1.1 mrg ctype = base_cand->cand_type; 1181 1.1 mrg if (has_single_use (base_in)) 1182 1.1 mrg savings = (base_cand->dead_savings 1183 1.1 mrg + stmt_cost (base_cand->cand_stmt, speed)); 1184 1.1 mrg } 1185 1.1 mrg } 1186 1.1 mrg else if (base_cand->kind == CAND_ADD && integer_onep (base_cand->stride)) 1187 1.1 mrg { 1188 1.1 mrg /* Y = B + (i' * 1) 1189 1.1 mrg X = Y * c 1190 1.1 mrg =========================== 1191 1.1 mrg X = (B + i') * c */ 1192 1.1 mrg base = base_cand->base_expr; 1193 1.1 mrg index = base_cand->index; 1194 1.1 mrg stride = stride_in; 1195 1.1 mrg ctype = base_cand->cand_type; 1196 1.1 mrg if (has_single_use (base_in)) 1197 1.1 mrg savings = (base_cand->dead_savings 1198 1.1 mrg + stmt_cost (base_cand->cand_stmt, speed)); 1199 1.1 mrg } 1200 1.1 mrg else if (base_cand->kind == CAND_ADD 1201 1.1 mrg && base_cand->index == 1 1202 1.1 mrg && TREE_CODE (base_cand->stride) == INTEGER_CST) 1203 1.1 mrg { 1204 1.1 mrg /* Y = B + (1 * S), S constant 1205 1.1 mrg X = Y * c 1206 1.1 mrg =========================== 1207 1.1 mrg X = (B + S) * c */ 1208 1.1 mrg base = base_cand->base_expr; 1209 1.1 mrg index = wi::to_widest (base_cand->stride); 1210 1.1 mrg stride = stride_in; 1211 1.1 mrg ctype = base_cand->cand_type; 1212 1.1 mrg if (has_single_use (base_in)) 1213 1.1 mrg savings = (base_cand->dead_savings 1214 1.1 mrg + stmt_cost (base_cand->cand_stmt, speed)); 1215 1.1 mrg } 1216 1.1 mrg 1217 1.1 mrg base_cand = lookup_cand (base_cand->next_interp); 1218 1.1 mrg } 1219 1.1 mrg 1220 1.1 mrg if (!base) 1221 1.1 mrg { 1222 1.1 mrg /* No interpretations had anything useful to propagate, so 1223 1.1 mrg produce X = (Y + 0) * c. */ 1224 1.1 mrg base = base_in; 1225 1.1 mrg index = 0; 1226 1.1 mrg stride = stride_in; 1227 1.1 mrg ctype = TREE_TYPE (base_in); 1228 1.1 mrg } 1229 1.1 mrg 1230 1.1 mrg c = alloc_cand_and_find_basis (CAND_MULT, gs, base, index, stride, 1231 1.1 mrg ctype, sizetype, savings); 1232 1.1 mrg return c; 1233 1.1 mrg } 1234 1.1 mrg 1235 1.1 mrg /* Given GS which is a multiply of scalar integers, make an appropriate 1236 1.1 mrg entry in the candidate table. If this is a multiply of two SSA names, 1237 1.1 mrg create two CAND_MULT interpretations and attempt to find a basis for 1238 1.1 mrg each of them. Otherwise, create a single CAND_MULT and attempt to 1239 1.1 mrg find a basis. */ 1240 1.1 mrg 1241 1.1 mrg static void 1242 1.1 mrg slsr_process_mul (gimple *gs, tree rhs1, tree rhs2, bool speed) 1243 1.1 mrg { 1244 1.1 mrg slsr_cand_t c, c2; 1245 1.1 mrg 1246 1.1 mrg /* If this is a multiply of an SSA name with itself, it is highly 1247 1.1 mrg unlikely that we will get a strength reduction opportunity, so 1248 1.1 mrg don't record it as a candidate. This simplifies the logic for 1249 1.1 mrg finding a basis, so if this is removed that must be considered. */ 1250 1.1 mrg if (rhs1 == rhs2) 1251 1.1 mrg return; 1252 1.1 mrg 1253 1.1 mrg if (TREE_CODE (rhs2) == SSA_NAME) 1254 1.1 mrg { 1255 1.1 mrg /* Record an interpretation of this statement in the candidate table 1256 1.1 mrg assuming RHS1 is the base expression and RHS2 is the stride. */ 1257 1.1 mrg c = create_mul_ssa_cand (gs, rhs1, rhs2, speed); 1258 1.1 mrg 1259 1.1 mrg /* Add the first interpretation to the statement-candidate mapping. */ 1260 1.1 mrg add_cand_for_stmt (gs, c); 1261 1.1 mrg 1262 1.1 mrg /* Record another interpretation of this statement assuming RHS1 1263 1.1 mrg is the stride and RHS2 is the base expression. */ 1264 1.1 mrg c2 = create_mul_ssa_cand (gs, rhs2, rhs1, speed); 1265 1.1 mrg c->next_interp = c2->cand_num; 1266 1.1 mrg c2->first_interp = c->cand_num; 1267 1.1 mrg } 1268 1.1 mrg else if (TREE_CODE (rhs2) == INTEGER_CST && !integer_zerop (rhs2)) 1269 1.1 mrg { 1270 1.1 mrg /* Record an interpretation for the multiply-immediate. */ 1271 1.1 mrg c = create_mul_imm_cand (gs, rhs1, rhs2, speed); 1272 1.1 mrg 1273 1.1 mrg /* Add the interpretation to the statement-candidate mapping. */ 1274 1.1 mrg add_cand_for_stmt (gs, c); 1275 1.1 mrg } 1276 1.1 mrg } 1277 1.1 mrg 1278 1.1 mrg /* Create a candidate entry for a statement GS, where GS adds two 1279 1.1 mrg SSA names BASE_IN and ADDEND_IN if SUBTRACT_P is false, and 1280 1.1 mrg subtracts ADDEND_IN from BASE_IN otherwise. Propagate any known 1281 1.1 mrg information about the two SSA names into the new candidate. 1282 1.1 mrg Return the new candidate. */ 1283 1.1 mrg 1284 1.1 mrg static slsr_cand_t 1285 1.1 mrg create_add_ssa_cand (gimple *gs, tree base_in, tree addend_in, 1286 1.1 mrg bool subtract_p, bool speed) 1287 1.1 mrg { 1288 1.1 mrg tree base = NULL_TREE, stride = NULL_TREE, ctype = NULL_TREE; 1289 1.1 mrg tree stype = NULL_TREE; 1290 1.1 mrg widest_int index; 1291 1.1 mrg unsigned savings = 0; 1292 1.1 mrg slsr_cand_t c; 1293 1.1 mrg slsr_cand_t base_cand = base_cand_from_table (base_in); 1294 1.1 mrg slsr_cand_t addend_cand = base_cand_from_table (addend_in); 1295 1.1 mrg 1296 1.1 mrg /* The most useful transformation is a multiply-immediate feeding 1297 1.1 mrg an add or subtract. Look for that first. */ 1298 1.1 mrg while (addend_cand && !base && addend_cand->kind != CAND_PHI) 1299 1.1 mrg { 1300 1.1 mrg if (addend_cand->kind == CAND_MULT 1301 1.1 mrg && addend_cand->index == 0 1302 1.1 mrg && TREE_CODE (addend_cand->stride) == INTEGER_CST) 1303 1.1 mrg { 1304 1.1 mrg /* Z = (B + 0) * S, S constant 1305 1.1 mrg X = Y +/- Z 1306 1.1 mrg =========================== 1307 1.1 mrg X = Y + ((+/-1 * S) * B) */ 1308 1.1 mrg base = base_in; 1309 1.1 mrg index = wi::to_widest (addend_cand->stride); 1310 1.1 mrg if (subtract_p) 1311 1.1 mrg index = -index; 1312 1.1 mrg stride = addend_cand->base_expr; 1313 1.1 mrg ctype = TREE_TYPE (base_in); 1314 1.1 mrg stype = addend_cand->cand_type; 1315 1.1 mrg if (has_single_use (addend_in)) 1316 1.1 mrg savings = (addend_cand->dead_savings 1317 1.1 mrg + stmt_cost (addend_cand->cand_stmt, speed)); 1318 1.1 mrg } 1319 1.1 mrg 1320 1.1 mrg addend_cand = lookup_cand (addend_cand->next_interp); 1321 1.1 mrg } 1322 1.1 mrg 1323 1.1 mrg while (base_cand && !base && base_cand->kind != CAND_PHI) 1324 1.1 mrg { 1325 1.1 mrg if (base_cand->kind == CAND_ADD 1326 1.1 mrg && (base_cand->index == 0 1327 1.1 mrg || operand_equal_p (base_cand->stride, 1328 1.1 mrg integer_zero_node, 0))) 1329 1.1 mrg { 1330 1.1 mrg /* Y = B + (i' * S), i' * S = 0 1331 1.1 mrg X = Y +/- Z 1332 1.1 mrg ============================ 1333 1.1 mrg X = B + (+/-1 * Z) */ 1334 1.1 mrg base = base_cand->base_expr; 1335 1.1 mrg index = subtract_p ? -1 : 1; 1336 1.1 mrg stride = addend_in; 1337 1.1 mrg ctype = base_cand->cand_type; 1338 1.1 mrg stype = (TREE_CODE (addend_in) == INTEGER_CST ? sizetype 1339 1.1 mrg : TREE_TYPE (addend_in)); 1340 1.1 mrg if (has_single_use (base_in)) 1341 1.1 mrg savings = (base_cand->dead_savings 1342 1.1 mrg + stmt_cost (base_cand->cand_stmt, speed)); 1343 1.1 mrg } 1344 1.1 mrg else if (subtract_p) 1345 1.1 mrg { 1346 1.1 mrg slsr_cand_t subtrahend_cand = base_cand_from_table (addend_in); 1347 1.1 mrg 1348 1.1 mrg while (subtrahend_cand && !base && subtrahend_cand->kind != CAND_PHI) 1349 1.1 mrg { 1350 1.1 mrg if (subtrahend_cand->kind == CAND_MULT 1351 1.1 mrg && subtrahend_cand->index == 0 1352 1.1 mrg && TREE_CODE (subtrahend_cand->stride) == INTEGER_CST) 1353 1.1 mrg { 1354 1.1 mrg /* Z = (B + 0) * S, S constant 1355 1.1 mrg X = Y - Z 1356 1.1 mrg =========================== 1357 1.1 mrg Value: X = Y + ((-1 * S) * B) */ 1358 1.1 mrg base = base_in; 1359 1.1 mrg index = wi::to_widest (subtrahend_cand->stride); 1360 1.1 mrg index = -index; 1361 1.1 mrg stride = subtrahend_cand->base_expr; 1362 1.1 mrg ctype = TREE_TYPE (base_in); 1363 1.1 mrg stype = subtrahend_cand->cand_type; 1364 1.1 mrg if (has_single_use (addend_in)) 1365 1.1 mrg savings = (subtrahend_cand->dead_savings 1366 1.1 mrg + stmt_cost (subtrahend_cand->cand_stmt, speed)); 1367 1.1 mrg } 1368 1.1 mrg 1369 1.1 mrg subtrahend_cand = lookup_cand (subtrahend_cand->next_interp); 1370 1.1 mrg } 1371 1.1 mrg } 1372 1.1 mrg 1373 1.1 mrg base_cand = lookup_cand (base_cand->next_interp); 1374 1.1 mrg } 1375 1.1 mrg 1376 1.1 mrg if (!base) 1377 1.1 mrg { 1378 1.1 mrg /* No interpretations had anything useful to propagate, so 1379 1.1 mrg produce X = Y + (1 * Z). */ 1380 1.1 mrg base = base_in; 1381 1.1 mrg index = subtract_p ? -1 : 1; 1382 1.1 mrg stride = addend_in; 1383 1.1 mrg ctype = TREE_TYPE (base_in); 1384 1.1 mrg stype = (TREE_CODE (addend_in) == INTEGER_CST ? sizetype 1385 1.1 mrg : TREE_TYPE (addend_in)); 1386 1.1 mrg } 1387 1.1 mrg 1388 1.1 mrg c = alloc_cand_and_find_basis (CAND_ADD, gs, base, index, stride, 1389 1.1 mrg ctype, stype, savings); 1390 1.1 mrg return c; 1391 1.1 mrg } 1392 1.1 mrg 1393 1.1 mrg /* Create a candidate entry for a statement GS, where GS adds SSA 1394 1.1 mrg name BASE_IN to constant INDEX_IN. Propagate any known information 1395 1.1 mrg about BASE_IN into the new candidate. Return the new candidate. */ 1396 1.1 mrg 1397 1.1 mrg static slsr_cand_t 1398 1.1 mrg create_add_imm_cand (gimple *gs, tree base_in, const widest_int &index_in, 1399 1.1 mrg bool speed) 1400 1.1 mrg { 1401 1.1 mrg enum cand_kind kind = CAND_ADD; 1402 1.1 mrg tree base = NULL_TREE, stride = NULL_TREE, ctype = NULL_TREE; 1403 1.1 mrg tree stype = NULL_TREE; 1404 1.1 mrg widest_int index, multiple; 1405 1.1 mrg unsigned savings = 0; 1406 1.1 mrg slsr_cand_t c; 1407 1.1 mrg slsr_cand_t base_cand = base_cand_from_table (base_in); 1408 1.1 mrg 1409 1.1 mrg while (base_cand && !base && base_cand->kind != CAND_PHI) 1410 1.1 mrg { 1411 1.1 mrg signop sign = TYPE_SIGN (TREE_TYPE (base_cand->stride)); 1412 1.1 mrg 1413 1.1 mrg if (TREE_CODE (base_cand->stride) == INTEGER_CST 1414 1.1 mrg && wi::multiple_of_p (index_in, wi::to_widest (base_cand->stride), 1415 1.1 mrg sign, &multiple)) 1416 1.1 mrg { 1417 1.1 mrg /* Y = (B + i') * S, S constant, c = kS for some integer k 1418 1.1 mrg X = Y + c 1419 1.1 mrg ============================ 1420 1.1 mrg X = (B + (i'+ k)) * S 1421 1.1 mrg OR 1422 1.1 mrg Y = B + (i' * S), S constant, c = kS for some integer k 1423 1.1 mrg X = Y + c 1424 1.1 mrg ============================ 1425 1.1 mrg X = (B + (i'+ k)) * S */ 1426 1.1 mrg kind = base_cand->kind; 1427 1.1 mrg base = base_cand->base_expr; 1428 1.1 mrg index = base_cand->index + multiple; 1429 1.1 mrg stride = base_cand->stride; 1430 1.1 mrg ctype = base_cand->cand_type; 1431 1.1 mrg stype = base_cand->stride_type; 1432 1.1 mrg if (has_single_use (base_in)) 1433 1.1 mrg savings = (base_cand->dead_savings 1434 1.1 mrg + stmt_cost (base_cand->cand_stmt, speed)); 1435 1.1 mrg } 1436 1.1 mrg 1437 1.1 mrg base_cand = lookup_cand (base_cand->next_interp); 1438 1.1 mrg } 1439 1.1 mrg 1440 1.1 mrg if (!base) 1441 1.1 mrg { 1442 1.1 mrg /* No interpretations had anything useful to propagate, so 1443 1.1 mrg produce X = Y + (c * 1). */ 1444 1.1 mrg kind = CAND_ADD; 1445 1.1 mrg base = base_in; 1446 1.1 mrg index = index_in; 1447 1.1 mrg stride = integer_one_node; 1448 1.1 mrg ctype = TREE_TYPE (base_in); 1449 1.1 mrg stype = sizetype; 1450 1.1 mrg } 1451 1.1 mrg 1452 1.1 mrg c = alloc_cand_and_find_basis (kind, gs, base, index, stride, 1453 1.1 mrg ctype, stype, savings); 1454 1.1 mrg return c; 1455 1.1 mrg } 1456 1.1 mrg 1457 1.1 mrg /* Given GS which is an add or subtract of scalar integers or pointers, 1458 1.1 mrg make at least one appropriate entry in the candidate table. */ 1459 1.1 mrg 1460 1.1 mrg static void 1461 1.1 mrg slsr_process_add (gimple *gs, tree rhs1, tree rhs2, bool speed) 1462 1.1 mrg { 1463 1.1 mrg bool subtract_p = gimple_assign_rhs_code (gs) == MINUS_EXPR; 1464 1.1 mrg slsr_cand_t c = NULL, c2; 1465 1.1 mrg 1466 1.1 mrg if (TREE_CODE (rhs2) == SSA_NAME) 1467 1.1 mrg { 1468 1.1 mrg /* First record an interpretation assuming RHS1 is the base expression 1469 1.1 mrg and RHS2 is the stride. But it doesn't make sense for the 1470 1.1 mrg stride to be a pointer, so don't record a candidate in that case. */ 1471 1.1 mrg if (!POINTER_TYPE_P (TREE_TYPE (rhs2))) 1472 1.1 mrg { 1473 1.1 mrg c = create_add_ssa_cand (gs, rhs1, rhs2, subtract_p, speed); 1474 1.1 mrg 1475 1.1 mrg /* Add the first interpretation to the statement-candidate 1476 1.1 mrg mapping. */ 1477 1.1 mrg add_cand_for_stmt (gs, c); 1478 1.1 mrg } 1479 1.1 mrg 1480 1.1 mrg /* If the two RHS operands are identical, or this is a subtract, 1481 1.1 mrg we're done. */ 1482 1.1 mrg if (operand_equal_p (rhs1, rhs2, 0) || subtract_p) 1483 1.1 mrg return; 1484 1.1 mrg 1485 1.1 mrg /* Otherwise, record another interpretation assuming RHS2 is the 1486 1.1 mrg base expression and RHS1 is the stride, again provided that the 1487 1.1 mrg stride is not a pointer. */ 1488 1.1 mrg if (!POINTER_TYPE_P (TREE_TYPE (rhs1))) 1489 1.1 mrg { 1490 1.1 mrg c2 = create_add_ssa_cand (gs, rhs2, rhs1, false, speed); 1491 1.1 mrg if (c) 1492 1.1 mrg { 1493 1.1 mrg c->next_interp = c2->cand_num; 1494 1.1 mrg c2->first_interp = c->cand_num; 1495 1.1 mrg } 1496 1.1 mrg else 1497 1.1 mrg add_cand_for_stmt (gs, c2); 1498 1.1 mrg } 1499 1.1 mrg } 1500 1.1 mrg else if (TREE_CODE (rhs2) == INTEGER_CST) 1501 1.1 mrg { 1502 1.1 mrg /* Record an interpretation for the add-immediate. */ 1503 1.1 mrg widest_int index = wi::to_widest (rhs2); 1504 1.1 mrg if (subtract_p) 1505 1.1 mrg index = -index; 1506 1.1 mrg 1507 1.1 mrg c = create_add_imm_cand (gs, rhs1, index, speed); 1508 1.1 mrg 1509 1.1 mrg /* Add the interpretation to the statement-candidate mapping. */ 1510 1.1 mrg add_cand_for_stmt (gs, c); 1511 1.1 mrg } 1512 1.1 mrg } 1513 1.1 mrg 1514 1.1 mrg /* Given GS which is a negate of a scalar integer, make an appropriate 1515 1.1 mrg entry in the candidate table. A negate is equivalent to a multiply 1516 1.1 mrg by -1. */ 1517 1.1 mrg 1518 1.1 mrg static void 1519 1.1 mrg slsr_process_neg (gimple *gs, tree rhs1, bool speed) 1520 1.1 mrg { 1521 1.1 mrg /* Record a CAND_MULT interpretation for the multiply by -1. */ 1522 1.1 mrg slsr_cand_t c = create_mul_imm_cand (gs, rhs1, integer_minus_one_node, speed); 1523 1.1 mrg 1524 1.1 mrg /* Add the interpretation to the statement-candidate mapping. */ 1525 1.1 mrg add_cand_for_stmt (gs, c); 1526 1.1 mrg } 1527 1.1 mrg 1528 1.1 mrg /* Help function for legal_cast_p, operating on two trees. Checks 1529 1.1 mrg whether it's allowable to cast from RHS to LHS. See legal_cast_p 1530 1.1 mrg for more details. */ 1531 1.1 mrg 1532 1.1 mrg static bool 1533 1.1 mrg legal_cast_p_1 (tree lhs_type, tree rhs_type) 1534 1.1 mrg { 1535 1.1 mrg unsigned lhs_size, rhs_size; 1536 1.1 mrg bool lhs_wraps, rhs_wraps; 1537 1.1 mrg 1538 1.1 mrg lhs_size = TYPE_PRECISION (lhs_type); 1539 1.1 mrg rhs_size = TYPE_PRECISION (rhs_type); 1540 1.1 mrg lhs_wraps = ANY_INTEGRAL_TYPE_P (lhs_type) && TYPE_OVERFLOW_WRAPS (lhs_type); 1541 1.1 mrg rhs_wraps = ANY_INTEGRAL_TYPE_P (rhs_type) && TYPE_OVERFLOW_WRAPS (rhs_type); 1542 1.1 mrg 1543 1.1 mrg if (lhs_size < rhs_size 1544 1.1 mrg || (rhs_wraps && !lhs_wraps) 1545 1.1 mrg || (rhs_wraps && lhs_wraps && rhs_size != lhs_size)) 1546 1.1 mrg return false; 1547 1.1 mrg 1548 1.1 mrg return true; 1549 1.1 mrg } 1550 1.1 mrg 1551 1.1 mrg /* Return TRUE if GS is a statement that defines an SSA name from 1552 1.1 mrg a conversion and is legal for us to combine with an add and multiply 1553 1.1 mrg in the candidate table. For example, suppose we have: 1554 1.1 mrg 1555 1.1 mrg A = B + i; 1556 1.1 mrg C = (type) A; 1557 1.1 mrg D = C * S; 1558 1.1 mrg 1559 1.1 mrg Without the type-cast, we would create a CAND_MULT for D with base B, 1560 1.1 mrg index i, and stride S. We want to record this candidate only if it 1561 1.1 mrg is equivalent to apply the type cast following the multiply: 1562 1.1 mrg 1563 1.1 mrg A = B + i; 1564 1.1 mrg E = A * S; 1565 1.1 mrg D = (type) E; 1566 1.1 mrg 1567 1.1 mrg We will record the type with the candidate for D. This allows us 1568 1.1 mrg to use a similar previous candidate as a basis. If we have earlier seen 1569 1.1 mrg 1570 1.1 mrg A' = B + i'; 1571 1.1 mrg C' = (type) A'; 1572 1.1 mrg D' = C' * S; 1573 1.1 mrg 1574 1.1 mrg we can replace D with 1575 1.1 mrg 1576 1.1 mrg D = D' + (i - i') * S; 1577 1.1 mrg 1578 1.1 mrg But if moving the type-cast would change semantics, we mustn't do this. 1579 1.1 mrg 1580 1.1 mrg This is legitimate for casts from a non-wrapping integral type to 1581 1.1 mrg any integral type of the same or larger size. It is not legitimate 1582 1.1 mrg to convert a wrapping type to a non-wrapping type, or to a wrapping 1583 1.1 mrg type of a different size. I.e., with a wrapping type, we must 1584 1.1 mrg assume that the addition B + i could wrap, in which case performing 1585 1.1 mrg the multiply before or after one of the "illegal" type casts will 1586 1.1 mrg have different semantics. */ 1587 1.1 mrg 1588 1.1 mrg static bool 1589 1.1 mrg legal_cast_p (gimple *gs, tree rhs) 1590 1.1 mrg { 1591 1.1 mrg if (!is_gimple_assign (gs) 1592 1.1 mrg || !CONVERT_EXPR_CODE_P (gimple_assign_rhs_code (gs))) 1593 1.1 mrg return false; 1594 1.1 mrg 1595 1.1 mrg return legal_cast_p_1 (TREE_TYPE (gimple_assign_lhs (gs)), TREE_TYPE (rhs)); 1596 1.1 mrg } 1597 1.1 mrg 1598 1.1 mrg /* Given GS which is a cast to a scalar integer type, determine whether 1599 1.1 mrg the cast is legal for strength reduction. If so, make at least one 1600 1.1 mrg appropriate entry in the candidate table. */ 1601 1.1 mrg 1602 1.1 mrg static void 1603 1.1 mrg slsr_process_cast (gimple *gs, tree rhs1, bool speed) 1604 1.1 mrg { 1605 1.1 mrg tree lhs, ctype; 1606 1.1 mrg slsr_cand_t base_cand, c = NULL, c2; 1607 1.1 mrg unsigned savings = 0; 1608 1.1 mrg 1609 1.1 mrg if (!legal_cast_p (gs, rhs1)) 1610 1.1 mrg return; 1611 1.1 mrg 1612 1.1 mrg lhs = gimple_assign_lhs (gs); 1613 1.1 mrg base_cand = base_cand_from_table (rhs1); 1614 1.1 mrg ctype = TREE_TYPE (lhs); 1615 1.1 mrg 1616 1.1 mrg if (base_cand && base_cand->kind != CAND_PHI) 1617 1.1 mrg { 1618 1.1 mrg slsr_cand_t first_cand = NULL; 1619 1.1 mrg 1620 1.1 mrg while (base_cand) 1621 1.1 mrg { 1622 1.1 mrg /* Propagate all data from the base candidate except the type, 1623 1.1 mrg which comes from the cast, and the base candidate's cast, 1624 1.1 mrg which is no longer applicable. */ 1625 1.1 mrg if (has_single_use (rhs1)) 1626 1.1 mrg savings = (base_cand->dead_savings 1627 1.1 mrg + stmt_cost (base_cand->cand_stmt, speed)); 1628 1.1 mrg 1629 1.1 mrg c = alloc_cand_and_find_basis (base_cand->kind, gs, 1630 1.1 mrg base_cand->base_expr, 1631 1.1 mrg base_cand->index, base_cand->stride, 1632 1.1 mrg ctype, base_cand->stride_type, 1633 1.1 mrg savings); 1634 1.1 mrg if (!first_cand) 1635 1.1 mrg first_cand = c; 1636 1.1 mrg 1637 1.1 mrg if (first_cand != c) 1638 1.1 mrg c->first_interp = first_cand->cand_num; 1639 1.1 mrg 1640 1.1 mrg base_cand = lookup_cand (base_cand->next_interp); 1641 1.1 mrg } 1642 1.1 mrg } 1643 1.1 mrg else 1644 1.1 mrg { 1645 1.1 mrg /* If nothing is known about the RHS, create fresh CAND_ADD and 1646 1.1 mrg CAND_MULT interpretations: 1647 1.1 mrg 1648 1.1 mrg X = Y + (0 * 1) 1649 1.1 mrg X = (Y + 0) * 1 1650 1.1 mrg 1651 1.1 mrg The first of these is somewhat arbitrary, but the choice of 1652 1.1 mrg 1 for the stride simplifies the logic for propagating casts 1653 1.1 mrg into their uses. */ 1654 1.1 mrg c = alloc_cand_and_find_basis (CAND_ADD, gs, rhs1, 0, 1655 1.1 mrg integer_one_node, ctype, sizetype, 0); 1656 1.1 mrg c2 = alloc_cand_and_find_basis (CAND_MULT, gs, rhs1, 0, 1657 1.1 mrg integer_one_node, ctype, sizetype, 0); 1658 1.1 mrg c->next_interp = c2->cand_num; 1659 1.1 mrg c2->first_interp = c->cand_num; 1660 1.1 mrg } 1661 1.1 mrg 1662 1.1 mrg /* Add the first (or only) interpretation to the statement-candidate 1663 1.1 mrg mapping. */ 1664 1.1 mrg add_cand_for_stmt (gs, c); 1665 1.1 mrg } 1666 1.1 mrg 1667 1.1 mrg /* Given GS which is a copy of a scalar integer type, make at least one 1668 1.1 mrg appropriate entry in the candidate table. 1669 1.1 mrg 1670 1.1 mrg This interface is included for completeness, but is unnecessary 1671 1.1 mrg if this pass immediately follows a pass that performs copy 1672 1.1 mrg propagation, such as DOM. */ 1673 1.1 mrg 1674 1.1 mrg static void 1675 1.1 mrg slsr_process_copy (gimple *gs, tree rhs1, bool speed) 1676 1.1 mrg { 1677 1.1 mrg slsr_cand_t base_cand, c = NULL, c2; 1678 1.1 mrg unsigned savings = 0; 1679 1.1 mrg 1680 1.1 mrg base_cand = base_cand_from_table (rhs1); 1681 1.1 mrg 1682 1.1 mrg if (base_cand && base_cand->kind != CAND_PHI) 1683 1.1 mrg { 1684 1.1 mrg slsr_cand_t first_cand = NULL; 1685 1.1 mrg 1686 1.1 mrg while (base_cand) 1687 1.1 mrg { 1688 1.1 mrg /* Propagate all data from the base candidate. */ 1689 1.1 mrg if (has_single_use (rhs1)) 1690 1.1 mrg savings = (base_cand->dead_savings 1691 1.1 mrg + stmt_cost (base_cand->cand_stmt, speed)); 1692 1.1 mrg 1693 1.1 mrg c = alloc_cand_and_find_basis (base_cand->kind, gs, 1694 1.1 mrg base_cand->base_expr, 1695 1.1 mrg base_cand->index, base_cand->stride, 1696 1.1 mrg base_cand->cand_type, 1697 1.1 mrg base_cand->stride_type, savings); 1698 1.1 mrg if (!first_cand) 1699 1.1 mrg first_cand = c; 1700 1.1 mrg 1701 1.1 mrg if (first_cand != c) 1702 1.1 mrg c->first_interp = first_cand->cand_num; 1703 1.1 mrg 1704 1.1 mrg base_cand = lookup_cand (base_cand->next_interp); 1705 1.1 mrg } 1706 1.1 mrg } 1707 1.1 mrg else 1708 1.1 mrg { 1709 1.1 mrg /* If nothing is known about the RHS, create fresh CAND_ADD and 1710 1.1 mrg CAND_MULT interpretations: 1711 1.1 mrg 1712 1.1 mrg X = Y + (0 * 1) 1713 1.1 mrg X = (Y + 0) * 1 1714 1.1 mrg 1715 1.1 mrg The first of these is somewhat arbitrary, but the choice of 1716 1.1 mrg 1 for the stride simplifies the logic for propagating casts 1717 1.1 mrg into their uses. */ 1718 1.1 mrg c = alloc_cand_and_find_basis (CAND_ADD, gs, rhs1, 0, 1719 1.1 mrg integer_one_node, TREE_TYPE (rhs1), 1720 1.1 mrg sizetype, 0); 1721 1.1 mrg c2 = alloc_cand_and_find_basis (CAND_MULT, gs, rhs1, 0, 1722 1.1 mrg integer_one_node, TREE_TYPE (rhs1), 1723 1.1 mrg sizetype, 0); 1724 1.1 mrg c->next_interp = c2->cand_num; 1725 1.1 mrg c2->first_interp = c->cand_num; 1726 1.1 mrg } 1727 1.1 mrg 1728 1.1 mrg /* Add the first (or only) interpretation to the statement-candidate 1729 1.1 mrg mapping. */ 1730 1.1 mrg add_cand_for_stmt (gs, c); 1731 1.1 mrg } 1732 1.1 mrg 1733 1.1 mrg class find_candidates_dom_walker : public dom_walker 1735 1.1 mrg { 1736 1.1 mrg public: 1737 1.1 mrg find_candidates_dom_walker (cdi_direction direction) 1738 1.1 mrg : dom_walker (direction) {} 1739 1.1 mrg virtual edge before_dom_children (basic_block); 1740 1.1 mrg }; 1741 1.1 mrg 1742 1.1 mrg /* Find strength-reduction candidates in block BB. */ 1743 1.1 mrg 1744 1.1 mrg edge 1745 1.1 mrg find_candidates_dom_walker::before_dom_children (basic_block bb) 1746 1.1 mrg { 1747 1.1 mrg bool speed = optimize_bb_for_speed_p (bb); 1748 1.1 mrg 1749 1.1 mrg for (gphi_iterator gsi = gsi_start_phis (bb); !gsi_end_p (gsi); 1750 1.1 mrg gsi_next (&gsi)) 1751 1.1 mrg slsr_process_phi (gsi.phi (), speed); 1752 1.1 mrg 1753 1.1 mrg for (gimple_stmt_iterator gsi = gsi_start_bb (bb); !gsi_end_p (gsi); 1754 1.1 mrg gsi_next (&gsi)) 1755 1.1 mrg { 1756 1.1 mrg gimple *gs = gsi_stmt (gsi); 1757 1.1 mrg 1758 1.1 mrg if (stmt_could_throw_p (cfun, gs)) 1759 1.1 mrg continue; 1760 1.1 mrg 1761 1.1 mrg if (gimple_vuse (gs) && gimple_assign_single_p (gs)) 1762 1.1 mrg slsr_process_ref (gs); 1763 1.1 mrg 1764 1.1 mrg else if (is_gimple_assign (gs) 1765 1.1 mrg && (INTEGRAL_TYPE_P (TREE_TYPE (gimple_assign_lhs (gs))) 1766 1.1 mrg || POINTER_TYPE_P (TREE_TYPE (gimple_assign_lhs (gs))))) 1767 1.1 mrg { 1768 1.1 mrg tree rhs1 = NULL_TREE, rhs2 = NULL_TREE; 1769 1.1 mrg 1770 1.1 mrg switch (gimple_assign_rhs_code (gs)) 1771 1.1 mrg { 1772 1.1 mrg case MULT_EXPR: 1773 1.1 mrg case PLUS_EXPR: 1774 1.1 mrg rhs1 = gimple_assign_rhs1 (gs); 1775 1.1 mrg rhs2 = gimple_assign_rhs2 (gs); 1776 1.1 mrg /* Should never happen, but currently some buggy situations 1777 1.1 mrg in earlier phases put constants in rhs1. */ 1778 1.1 mrg if (TREE_CODE (rhs1) != SSA_NAME) 1779 1.1 mrg continue; 1780 1.1 mrg break; 1781 1.1 mrg 1782 1.1 mrg /* Possible future opportunity: rhs1 of a ptr+ can be 1783 1.1 mrg an ADDR_EXPR. */ 1784 1.1 mrg case POINTER_PLUS_EXPR: 1785 1.1 mrg case MINUS_EXPR: 1786 1.1 mrg rhs2 = gimple_assign_rhs2 (gs); 1787 1.1 mrg gcc_fallthrough (); 1788 1.1 mrg 1789 1.1 mrg CASE_CONVERT: 1790 1.1 mrg case SSA_NAME: 1791 1.1 mrg case NEGATE_EXPR: 1792 1.1 mrg rhs1 = gimple_assign_rhs1 (gs); 1793 1.1 mrg if (TREE_CODE (rhs1) != SSA_NAME) 1794 1.1 mrg continue; 1795 1.1 mrg break; 1796 1.1 mrg 1797 1.1 mrg default: 1798 1.1 mrg ; 1799 1.1 mrg } 1800 1.1 mrg 1801 1.1 mrg switch (gimple_assign_rhs_code (gs)) 1802 1.1 mrg { 1803 1.1 mrg case MULT_EXPR: 1804 1.1 mrg slsr_process_mul (gs, rhs1, rhs2, speed); 1805 1.1 mrg break; 1806 1.1 mrg 1807 1.1 mrg case PLUS_EXPR: 1808 1.1 mrg case POINTER_PLUS_EXPR: 1809 1.1 mrg case MINUS_EXPR: 1810 1.1 mrg slsr_process_add (gs, rhs1, rhs2, speed); 1811 1.1 mrg break; 1812 1.1 mrg 1813 1.1 mrg case NEGATE_EXPR: 1814 1.1 mrg slsr_process_neg (gs, rhs1, speed); 1815 1.1 mrg break; 1816 1.1 mrg 1817 1.1 mrg CASE_CONVERT: 1818 1.1 mrg slsr_process_cast (gs, rhs1, speed); 1819 1.1 mrg break; 1820 1.1 mrg 1821 1.1 mrg case SSA_NAME: 1822 1.1 mrg slsr_process_copy (gs, rhs1, speed); 1823 1.1 mrg break; 1824 1.1 mrg 1825 1.1 mrg default: 1826 1.1 mrg ; 1827 1.1 mrg } 1828 1.1 mrg } 1829 1.1 mrg } 1830 1.1 mrg return NULL; 1831 1.1 mrg } 1832 1.1 mrg 1833 1.1 mrg /* Dump a candidate for debug. */ 1835 1.1 mrg 1836 1.1 mrg static void 1837 1.1 mrg dump_candidate (slsr_cand_t c) 1838 1.1 mrg { 1839 1.1 mrg fprintf (dump_file, "%3d [%d] ", c->cand_num, 1840 1.1 mrg gimple_bb (c->cand_stmt)->index); 1841 1.1 mrg print_gimple_stmt (dump_file, c->cand_stmt, 0); 1842 1.1 mrg switch (c->kind) 1843 1.1 mrg { 1844 1.1 mrg case CAND_MULT: 1845 1.1 mrg fputs (" MULT : (", dump_file); 1846 1.1 mrg print_generic_expr (dump_file, c->base_expr); 1847 1.1 mrg fputs (" + ", dump_file); 1848 1.1 mrg print_decs (c->index, dump_file); 1849 1.1 mrg fputs (") * ", dump_file); 1850 1.1 mrg if (TREE_CODE (c->stride) != INTEGER_CST 1851 1.1 mrg && c->stride_type != TREE_TYPE (c->stride)) 1852 1.1 mrg { 1853 1.1 mrg fputs ("(", dump_file); 1854 1.1 mrg print_generic_expr (dump_file, c->stride_type); 1855 1.1 mrg fputs (")", dump_file); 1856 1.1 mrg } 1857 1.1 mrg print_generic_expr (dump_file, c->stride); 1858 1.1 mrg fputs (" : ", dump_file); 1859 1.1 mrg break; 1860 1.1 mrg case CAND_ADD: 1861 1.1 mrg fputs (" ADD : ", dump_file); 1862 1.1 mrg print_generic_expr (dump_file, c->base_expr); 1863 1.1 mrg fputs (" + (", dump_file); 1864 1.1 mrg print_decs (c->index, dump_file); 1865 1.1 mrg fputs (" * ", dump_file); 1866 1.1 mrg if (TREE_CODE (c->stride) != INTEGER_CST 1867 1.1 mrg && c->stride_type != TREE_TYPE (c->stride)) 1868 1.1 mrg { 1869 1.1 mrg fputs ("(", dump_file); 1870 1.1 mrg print_generic_expr (dump_file, c->stride_type); 1871 1.1 mrg fputs (")", dump_file); 1872 1.1 mrg } 1873 1.1 mrg print_generic_expr (dump_file, c->stride); 1874 1.1 mrg fputs (") : ", dump_file); 1875 1.1 mrg break; 1876 1.1 mrg case CAND_REF: 1877 1.1 mrg fputs (" REF : ", dump_file); 1878 1.1 mrg print_generic_expr (dump_file, c->base_expr); 1879 1.1 mrg fputs (" + (", dump_file); 1880 1.1 mrg print_generic_expr (dump_file, c->stride); 1881 1.1 mrg fputs (") + ", dump_file); 1882 1.1 mrg print_decs (c->index, dump_file); 1883 1.1 mrg fputs (" : ", dump_file); 1884 1.1 mrg break; 1885 1.1 mrg case CAND_PHI: 1886 1.1 mrg fputs (" PHI : ", dump_file); 1887 1.1 mrg print_generic_expr (dump_file, c->base_expr); 1888 1.1 mrg fputs (" + (unknown * ", dump_file); 1889 1.1 mrg print_generic_expr (dump_file, c->stride); 1890 1.1 mrg fputs (") : ", dump_file); 1891 1.1 mrg break; 1892 1.1 mrg default: 1893 1.1 mrg gcc_unreachable (); 1894 1.1 mrg } 1895 1.1 mrg print_generic_expr (dump_file, c->cand_type); 1896 1.1 mrg fprintf (dump_file, "\n basis: %d dependent: %d sibling: %d\n", 1897 1.1 mrg c->basis, c->dependent, c->sibling); 1898 1.1 mrg fprintf (dump_file, 1899 1.1 mrg " next-interp: %d first-interp: %d dead-savings: %d\n", 1900 1.1 mrg c->next_interp, c->first_interp, c->dead_savings); 1901 1.1 mrg if (c->def_phi) 1902 1.1 mrg fprintf (dump_file, " phi: %d\n", c->def_phi); 1903 1.1 mrg fputs ("\n", dump_file); 1904 1.1 mrg } 1905 1.1 mrg 1906 1.1 mrg /* Dump the candidate vector for debug. */ 1907 1.1 mrg 1908 1.1 mrg static void 1909 1.1 mrg dump_cand_vec (void) 1910 1.1 mrg { 1911 1.1 mrg unsigned i; 1912 1.1 mrg slsr_cand_t c; 1913 1.1 mrg 1914 1.1 mrg fprintf (dump_file, "\nStrength reduction candidate vector:\n\n"); 1915 1.1 mrg 1916 1.1 mrg FOR_EACH_VEC_ELT (cand_vec, i, c) 1917 1.1 mrg if (c != NULL) 1918 1.1 mrg dump_candidate (c); 1919 1.1 mrg } 1920 1.1 mrg 1921 1.1 mrg /* Callback used to dump the candidate chains hash table. */ 1922 1.1 mrg 1923 1.1 mrg int 1924 1.1 mrg ssa_base_cand_dump_callback (cand_chain **slot, void *ignored ATTRIBUTE_UNUSED) 1925 1.1 mrg { 1926 1.1 mrg const_cand_chain_t chain = *slot; 1927 1.1 mrg cand_chain_t p; 1928 1.1 mrg 1929 1.1 mrg print_generic_expr (dump_file, chain->base_expr); 1930 1.1 mrg fprintf (dump_file, " -> %d", chain->cand->cand_num); 1931 1.1 mrg 1932 1.1 mrg for (p = chain->next; p; p = p->next) 1933 1.1 mrg fprintf (dump_file, " -> %d", p->cand->cand_num); 1934 1.1 mrg 1935 1.1 mrg fputs ("\n", dump_file); 1936 1.1 mrg return 1; 1937 1.1 mrg } 1938 1.1 mrg 1939 1.1 mrg /* Dump the candidate chains. */ 1940 1.1 mrg 1941 1.1 mrg static void 1942 1.1 mrg dump_cand_chains (void) 1943 1.1 mrg { 1944 1.1 mrg fprintf (dump_file, "\nStrength reduction candidate chains:\n\n"); 1945 1.1 mrg base_cand_map->traverse_noresize <void *, ssa_base_cand_dump_callback> 1946 1.1 mrg (NULL); 1947 1.1 mrg fputs ("\n", dump_file); 1948 1.1 mrg } 1949 1.1 mrg 1950 1.1 mrg /* Dump the increment vector for debug. */ 1951 1.1 mrg 1952 1.1 mrg static void 1953 1.1 mrg dump_incr_vec (void) 1954 1.1 mrg { 1955 1.1 mrg if (dump_file && (dump_flags & TDF_DETAILS)) 1956 1.1 mrg { 1957 1.1 mrg unsigned i; 1958 1.1 mrg 1959 1.1 mrg fprintf (dump_file, "\nIncrement vector:\n\n"); 1960 1.1 mrg 1961 1.1 mrg for (i = 0; i < incr_vec_len; i++) 1962 1.1 mrg { 1963 1.1 mrg fprintf (dump_file, "%3d increment: ", i); 1964 1.1 mrg print_decs (incr_vec[i].incr, dump_file); 1965 1.1 mrg fprintf (dump_file, "\n count: %d", incr_vec[i].count); 1966 1.1 mrg fprintf (dump_file, "\n cost: %d", incr_vec[i].cost); 1967 1.1 mrg fputs ("\n initializer: ", dump_file); 1968 1.1 mrg print_generic_expr (dump_file, incr_vec[i].initializer); 1969 1.1 mrg fputs ("\n\n", dump_file); 1970 1.1 mrg } 1971 1.1 mrg } 1972 1.1 mrg } 1973 1.1 mrg 1974 1.1 mrg /* Replace *EXPR in candidate C with an equivalent strength-reduced 1976 1.1 mrg data reference. */ 1977 1.1 mrg 1978 1.1 mrg static void 1979 1.1 mrg replace_ref (tree *expr, slsr_cand_t c) 1980 1.1 mrg { 1981 1.1 mrg tree add_expr, mem_ref, acc_type = TREE_TYPE (*expr); 1982 1.1 mrg unsigned HOST_WIDE_INT misalign; 1983 1.1 mrg unsigned align; 1984 1.1 mrg 1985 1.1 mrg /* Ensure the memory reference carries the minimum alignment 1986 1.1 mrg requirement for the data type. See PR58041. */ 1987 1.1 mrg get_object_alignment_1 (*expr, &align, &misalign); 1988 1.1 mrg if (misalign != 0) 1989 1.1 mrg align = least_bit_hwi (misalign); 1990 1.1 mrg if (align < TYPE_ALIGN (acc_type)) 1991 1.1 mrg acc_type = build_aligned_type (acc_type, align); 1992 1.1 mrg 1993 1.1 mrg add_expr = fold_build2 (POINTER_PLUS_EXPR, c->cand_type, 1994 1.1 mrg c->base_expr, c->stride); 1995 1.1 mrg mem_ref = fold_build2 (MEM_REF, acc_type, add_expr, 1996 1.1 mrg wide_int_to_tree (c->cand_type, c->index)); 1997 1.1 mrg 1998 1.1 mrg /* Gimplify the base addressing expression for the new MEM_REF tree. */ 1999 1.1 mrg gimple_stmt_iterator gsi = gsi_for_stmt (c->cand_stmt); 2000 1.1 mrg TREE_OPERAND (mem_ref, 0) 2001 1.1 mrg = force_gimple_operand_gsi (&gsi, TREE_OPERAND (mem_ref, 0), 2002 1.1 mrg /*simple_p=*/true, NULL, 2003 1.1 mrg /*before=*/true, GSI_SAME_STMT); 2004 1.1 mrg copy_ref_info (mem_ref, *expr); 2005 1.1 mrg *expr = mem_ref; 2006 1.1 mrg update_stmt (c->cand_stmt); 2007 1.1 mrg } 2008 1.1 mrg 2009 1.1 mrg /* Return true if CAND_REF candidate C is a valid memory reference. */ 2010 1.1 mrg 2011 1.1 mrg static bool 2012 1.1 mrg valid_mem_ref_cand_p (slsr_cand_t c) 2013 1.1 mrg { 2014 1.1 mrg if (TREE_CODE (TREE_OPERAND (c->stride, 1)) != INTEGER_CST) 2015 1.1 mrg return false; 2016 1.1 mrg 2017 1.1 mrg struct mem_address addr 2018 1.1 mrg = { NULL_TREE, c->base_expr, TREE_OPERAND (c->stride, 0), 2019 1.1 mrg TREE_OPERAND (c->stride, 1), wide_int_to_tree (sizetype, c->index) }; 2020 1.1 mrg 2021 1.1 mrg return 2022 1.1 mrg valid_mem_ref_p (TYPE_MODE (c->cand_type), TYPE_ADDR_SPACE (c->cand_type), 2023 1.1 mrg &addr); 2024 1.1 mrg } 2025 1.1 mrg 2026 1.1 mrg /* Replace CAND_REF candidate C, each sibling of candidate C, and each 2027 1.1 mrg dependent of candidate C with an equivalent strength-reduced data 2028 1.1 mrg reference. */ 2029 1.1 mrg 2030 1.1 mrg static void 2031 1.1 mrg replace_refs (slsr_cand_t c) 2032 1.1 mrg { 2033 1.1 mrg /* Replacing a chain of only 2 candidates which are valid memory references 2034 1.1 mrg is generally counter-productive because you cannot recoup the additional 2035 1.1 mrg calculation added in front of them. */ 2036 1.1 mrg if (c->basis == 0 2037 1.1 mrg && c->dependent 2038 1.1 mrg && !lookup_cand (c->dependent)->dependent 2039 1.1 mrg && valid_mem_ref_cand_p (c) 2040 1.1 mrg && valid_mem_ref_cand_p (lookup_cand (c->dependent))) 2041 1.1 mrg return; 2042 1.1 mrg 2043 1.1 mrg if (dump_file && (dump_flags & TDF_DETAILS)) 2044 1.1 mrg { 2045 1.1 mrg fputs ("Replacing reference: ", dump_file); 2046 1.1 mrg print_gimple_stmt (dump_file, c->cand_stmt, 0); 2047 1.1 mrg } 2048 1.1 mrg 2049 1.1 mrg if (gimple_vdef (c->cand_stmt)) 2050 1.1 mrg { 2051 1.1 mrg tree *lhs = gimple_assign_lhs_ptr (c->cand_stmt); 2052 1.1 mrg replace_ref (lhs, c); 2053 1.1 mrg } 2054 1.1 mrg else 2055 1.1 mrg { 2056 1.1 mrg tree *rhs = gimple_assign_rhs1_ptr (c->cand_stmt); 2057 1.1 mrg replace_ref (rhs, c); 2058 1.1 mrg } 2059 1.1 mrg 2060 1.1 mrg if (dump_file && (dump_flags & TDF_DETAILS)) 2061 1.1 mrg { 2062 1.1 mrg fputs ("With: ", dump_file); 2063 1.1 mrg print_gimple_stmt (dump_file, c->cand_stmt, 0); 2064 1.1 mrg fputs ("\n", dump_file); 2065 1.1 mrg } 2066 1.1 mrg 2067 1.1 mrg if (c->sibling) 2068 1.1 mrg replace_refs (lookup_cand (c->sibling)); 2069 1.1 mrg 2070 1.1 mrg if (c->dependent) 2071 1.1 mrg replace_refs (lookup_cand (c->dependent)); 2072 1.1 mrg } 2073 1.1 mrg 2074 1.1 mrg /* Return TRUE if candidate C is dependent upon a PHI. */ 2075 1.1 mrg 2076 1.1 mrg static bool 2077 1.1 mrg phi_dependent_cand_p (slsr_cand_t c) 2078 1.1 mrg { 2079 1.1 mrg /* A candidate is not necessarily dependent upon a PHI just because 2080 1.1 mrg it has a phi definition for its base name. It may have a basis 2081 1.1 mrg that relies upon the same phi definition, in which case the PHI 2082 1.1 mrg is irrelevant to this candidate. */ 2083 1.1 mrg return (c->def_phi 2084 1.1 mrg && c->basis 2085 1.1 mrg && lookup_cand (c->basis)->def_phi != c->def_phi); 2086 1.1 mrg } 2087 1.1 mrg 2088 1.1 mrg /* Calculate the increment required for candidate C relative to 2089 1.1 mrg its basis. */ 2090 1.1 mrg 2091 1.1 mrg static widest_int 2092 1.1 mrg cand_increment (slsr_cand_t c) 2093 1.1 mrg { 2094 1.1 mrg slsr_cand_t basis; 2095 1.1 mrg 2096 1.1 mrg /* If the candidate doesn't have a basis, just return its own 2097 1.1 mrg index. This is useful in record_increments to help us find 2098 1.1 mrg an existing initializer. Also, if the candidate's basis is 2099 1.1 mrg hidden by a phi, then its own index will be the increment 2100 1.1 mrg from the newly introduced phi basis. */ 2101 1.1 mrg if (!c->basis || phi_dependent_cand_p (c)) 2102 1.1 mrg return c->index; 2103 1.1 mrg 2104 1.1 mrg basis = lookup_cand (c->basis); 2105 1.1 mrg gcc_assert (operand_equal_p (c->base_expr, basis->base_expr, 0)); 2106 1.1 mrg return c->index - basis->index; 2107 1.1 mrg } 2108 1.1 mrg 2109 1.1 mrg /* Calculate the increment required for candidate C relative to 2110 1.1 mrg its basis. If we aren't going to generate pointer arithmetic 2111 1.1 mrg for this candidate, return the absolute value of that increment 2112 1.1 mrg instead. */ 2113 1.1 mrg 2114 1.1 mrg static inline widest_int 2115 1.1 mrg cand_abs_increment (slsr_cand_t c) 2116 1.1 mrg { 2117 1.1 mrg widest_int increment = cand_increment (c); 2118 1.1 mrg 2119 1.1 mrg if (!address_arithmetic_p && wi::neg_p (increment)) 2120 1.1 mrg increment = -increment; 2121 1.1 mrg 2122 1.1 mrg return increment; 2123 1.1 mrg } 2124 1.1 mrg 2125 1.1 mrg /* Return TRUE iff candidate C has already been replaced under 2126 1.1 mrg another interpretation. */ 2127 1.1 mrg 2128 1.1 mrg static inline bool 2129 1.1 mrg cand_already_replaced (slsr_cand_t c) 2130 1.1 mrg { 2131 1.1 mrg return (gimple_bb (c->cand_stmt) == 0); 2132 1.1 mrg } 2133 1.1 mrg 2134 1.1 mrg /* Common logic used by replace_unconditional_candidate and 2135 1.1 mrg replace_conditional_candidate. */ 2136 1.1 mrg 2137 1.1 mrg static void 2138 1.1 mrg replace_mult_candidate (slsr_cand_t c, tree basis_name, widest_int bump) 2139 1.1 mrg { 2140 1.1 mrg tree target_type = TREE_TYPE (gimple_assign_lhs (c->cand_stmt)); 2141 1.1 mrg enum tree_code cand_code = gimple_assign_rhs_code (c->cand_stmt); 2142 1.1 mrg 2143 1.1 mrg /* It is not useful to replace casts, copies, negates, or adds of 2144 1.1 mrg an SSA name and a constant. */ 2145 1.1 mrg if (cand_code == SSA_NAME 2146 1.1 mrg || CONVERT_EXPR_CODE_P (cand_code) 2147 1.1 mrg || cand_code == PLUS_EXPR 2148 1.1 mrg || cand_code == POINTER_PLUS_EXPR 2149 1.1 mrg || cand_code == MINUS_EXPR 2150 1.1 mrg || cand_code == NEGATE_EXPR) 2151 1.1 mrg return; 2152 1.1 mrg 2153 1.1 mrg enum tree_code code = PLUS_EXPR; 2154 1.1 mrg tree bump_tree; 2155 1.1 mrg gimple *stmt_to_print = NULL; 2156 1.1 mrg 2157 1.1 mrg if (wi::neg_p (bump)) 2158 1.1 mrg { 2159 1.1 mrg code = MINUS_EXPR; 2160 1.1 mrg bump = -bump; 2161 1.1 mrg } 2162 1.1 mrg 2163 1.1 mrg /* It is possible that the resulting bump doesn't fit in target_type. 2164 1.1 mrg Abandon the replacement in this case. This does not affect 2165 1.1 mrg siblings or dependents of C. */ 2166 1.1 mrg if (bump != wi::ext (bump, TYPE_PRECISION (target_type), 2167 1.1 mrg TYPE_SIGN (target_type))) 2168 1.1 mrg return; 2169 1.1 mrg 2170 1.1 mrg bump_tree = wide_int_to_tree (target_type, bump); 2171 1.1 mrg 2172 1.1 mrg /* If the basis name and the candidate's LHS have incompatible types, 2173 1.1 mrg introduce a cast. */ 2174 1.1 mrg if (!useless_type_conversion_p (target_type, TREE_TYPE (basis_name))) 2175 1.1 mrg basis_name = introduce_cast_before_cand (c, target_type, basis_name); 2176 1.1 mrg 2177 1.1 mrg if (dump_file && (dump_flags & TDF_DETAILS)) 2178 1.1 mrg { 2179 1.1 mrg fputs ("Replacing: ", dump_file); 2180 1.1 mrg print_gimple_stmt (dump_file, c->cand_stmt, 0); 2181 1.1 mrg } 2182 1.1 mrg 2183 1.1 mrg if (bump == 0) 2184 1.1 mrg { 2185 1.1 mrg tree lhs = gimple_assign_lhs (c->cand_stmt); 2186 1.1 mrg gassign *copy_stmt = gimple_build_assign (lhs, basis_name); 2187 1.1 mrg gimple_stmt_iterator gsi = gsi_for_stmt (c->cand_stmt); 2188 1.1 mrg slsr_cand_t cc = lookup_cand (c->first_interp); 2189 1.1 mrg gimple_set_location (copy_stmt, gimple_location (c->cand_stmt)); 2190 1.1 mrg gsi_replace (&gsi, copy_stmt, false); 2191 1.1 mrg while (cc) 2192 1.1 mrg { 2193 1.1 mrg cc->cand_stmt = copy_stmt; 2194 1.1 mrg cc = lookup_cand (cc->next_interp); 2195 1.1 mrg } 2196 1.1 mrg if (dump_file && (dump_flags & TDF_DETAILS)) 2197 1.1 mrg stmt_to_print = copy_stmt; 2198 1.1 mrg } 2199 1.1 mrg else 2200 1.1 mrg { 2201 1.1 mrg tree rhs1, rhs2; 2202 1.1 mrg if (cand_code != NEGATE_EXPR) { 2203 1.1 mrg rhs1 = gimple_assign_rhs1 (c->cand_stmt); 2204 1.1 mrg rhs2 = gimple_assign_rhs2 (c->cand_stmt); 2205 1.1 mrg } 2206 1.1 mrg if (cand_code != NEGATE_EXPR 2207 1.1 mrg && ((operand_equal_p (rhs1, basis_name, 0) 2208 1.1 mrg && operand_equal_p (rhs2, bump_tree, 0)) 2209 1.1 mrg || (operand_equal_p (rhs1, bump_tree, 0) 2210 1.1 mrg && operand_equal_p (rhs2, basis_name, 0)))) 2211 1.1 mrg { 2212 1.1 mrg if (dump_file && (dump_flags & TDF_DETAILS)) 2213 1.1 mrg { 2214 1.1 mrg fputs ("(duplicate, not actually replacing)", dump_file); 2215 1.1 mrg stmt_to_print = c->cand_stmt; 2216 1.1 mrg } 2217 1.1 mrg } 2218 1.1 mrg else 2219 1.1 mrg { 2220 1.1 mrg gimple_stmt_iterator gsi = gsi_for_stmt (c->cand_stmt); 2221 1.1 mrg slsr_cand_t cc = lookup_cand (c->first_interp); 2222 1.1 mrg gimple_assign_set_rhs_with_ops (&gsi, code, basis_name, bump_tree); 2223 1.1 mrg update_stmt (gsi_stmt (gsi)); 2224 1.1 mrg while (cc) 2225 1.1 mrg { 2226 1.1 mrg cc->cand_stmt = gsi_stmt (gsi); 2227 1.1 mrg cc = lookup_cand (cc->next_interp); 2228 1.1 mrg } 2229 1.1 mrg if (dump_file && (dump_flags & TDF_DETAILS)) 2230 1.1 mrg stmt_to_print = gsi_stmt (gsi); 2231 1.1 mrg } 2232 1.1 mrg } 2233 1.1 mrg 2234 1.1 mrg if (dump_file && (dump_flags & TDF_DETAILS)) 2235 1.1 mrg { 2236 1.1 mrg fputs ("With: ", dump_file); 2237 1.1 mrg print_gimple_stmt (dump_file, stmt_to_print, 0); 2238 1.1 mrg fputs ("\n", dump_file); 2239 1.1 mrg } 2240 1.1 mrg } 2241 1.1 mrg 2242 1.1 mrg /* Replace candidate C with an add or subtract. Note that we only 2243 1.1 mrg operate on CAND_MULTs with known strides, so we will never generate 2244 1.1 mrg a POINTER_PLUS_EXPR. Each candidate X = (B + i) * S is replaced by 2245 1.1 mrg X = Y + ((i - i') * S), as described in the module commentary. The 2246 1.1 mrg folded value ((i - i') * S) is referred to here as the "bump." */ 2247 1.1 mrg 2248 1.1 mrg static void 2249 1.1 mrg replace_unconditional_candidate (slsr_cand_t c) 2250 1.1 mrg { 2251 1.1 mrg slsr_cand_t basis; 2252 1.1 mrg 2253 1.1 mrg if (cand_already_replaced (c)) 2254 1.1 mrg return; 2255 1.1 mrg 2256 1.1 mrg basis = lookup_cand (c->basis); 2257 1.1 mrg widest_int bump = cand_increment (c) * wi::to_widest (c->stride); 2258 1.1 mrg 2259 1.1 mrg replace_mult_candidate (c, gimple_assign_lhs (basis->cand_stmt), bump); 2260 1.1 mrg } 2261 1.1 mrg 2262 1.1 mrg /* Return the index in the increment vector of the given INCREMENT, 2264 1.1 mrg or -1 if not found. The latter can occur if more than 2265 1.1 mrg MAX_INCR_VEC_LEN increments have been found. */ 2266 1.1 mrg 2267 1.1 mrg static inline int 2268 1.1 mrg incr_vec_index (const widest_int &increment) 2269 1.1 mrg { 2270 1.1 mrg unsigned i; 2271 1.1 mrg 2272 1.1 mrg for (i = 0; i < incr_vec_len && increment != incr_vec[i].incr; i++) 2273 1.1 mrg ; 2274 1.1 mrg 2275 1.1 mrg if (i < incr_vec_len) 2276 1.1 mrg return i; 2277 1.1 mrg else 2278 1.1 mrg return -1; 2279 1.1 mrg } 2280 1.1 mrg 2281 1.1 mrg /* Create a new statement along edge E to add BASIS_NAME to the product 2282 1.1 mrg of INCREMENT and the stride of candidate C. Create and return a new 2283 1.1 mrg SSA name from *VAR to be used as the LHS of the new statement. 2284 1.1 mrg KNOWN_STRIDE is true iff C's stride is a constant. */ 2285 1.1 mrg 2286 1.1 mrg static tree 2287 1.1 mrg create_add_on_incoming_edge (slsr_cand_t c, tree basis_name, 2288 1.1 mrg widest_int increment, edge e, location_t loc, 2289 1.1 mrg bool known_stride) 2290 1.1 mrg { 2291 1.1 mrg tree lhs, basis_type; 2292 1.1 mrg gassign *new_stmt, *cast_stmt = NULL; 2293 1.1 mrg 2294 1.1 mrg /* If the add candidate along this incoming edge has the same 2295 1.1 mrg index as C's hidden basis, the hidden basis represents this 2296 1.1 mrg edge correctly. */ 2297 1.1 mrg if (increment == 0) 2298 1.1 mrg return basis_name; 2299 1.1 mrg 2300 1.1 mrg basis_type = TREE_TYPE (basis_name); 2301 1.1 mrg lhs = make_temp_ssa_name (basis_type, NULL, "slsr"); 2302 1.1 mrg 2303 1.1 mrg /* Occasionally people convert integers to pointers without a 2304 1.1 mrg cast, leading us into trouble if we aren't careful. */ 2305 1.1 mrg enum tree_code plus_code 2306 1.1 mrg = POINTER_TYPE_P (basis_type) ? POINTER_PLUS_EXPR : PLUS_EXPR; 2307 1.1 mrg 2308 1.1 mrg if (known_stride) 2309 1.1 mrg { 2310 1.1 mrg tree bump_tree; 2311 1.1 mrg enum tree_code code = plus_code; 2312 1.1 mrg widest_int bump = increment * wi::to_widest (c->stride); 2313 1.1 mrg if (wi::neg_p (bump) && !POINTER_TYPE_P (basis_type)) 2314 1.1 mrg { 2315 1.1 mrg code = MINUS_EXPR; 2316 1.1 mrg bump = -bump; 2317 1.1 mrg } 2318 1.1 mrg 2319 1.1 mrg tree stride_type = POINTER_TYPE_P (basis_type) ? sizetype : basis_type; 2320 1.1 mrg bump_tree = wide_int_to_tree (stride_type, bump); 2321 1.1 mrg new_stmt = gimple_build_assign (lhs, code, basis_name, bump_tree); 2322 1.1 mrg } 2323 1.1 mrg else 2324 1.1 mrg { 2325 1.1 mrg int i; 2326 1.1 mrg bool negate_incr = !POINTER_TYPE_P (basis_type) && wi::neg_p (increment); 2327 1.1 mrg i = incr_vec_index (negate_incr ? -increment : increment); 2328 1.1 mrg gcc_assert (i >= 0); 2329 1.1 mrg 2330 1.1 mrg if (incr_vec[i].initializer) 2331 1.1 mrg { 2332 1.1 mrg enum tree_code code = negate_incr ? MINUS_EXPR : plus_code; 2333 1.1 mrg new_stmt = gimple_build_assign (lhs, code, basis_name, 2334 1.1 mrg incr_vec[i].initializer); 2335 1.1 mrg } 2336 1.1 mrg else { 2337 1.1 mrg tree stride; 2338 1.1 mrg 2339 1.1 mrg if (!types_compatible_p (TREE_TYPE (c->stride), c->stride_type)) 2340 1.1 mrg { 2341 1.1 mrg tree cast_stride = make_temp_ssa_name (c->stride_type, NULL, 2342 1.1 mrg "slsr"); 2343 1.1 mrg cast_stmt = gimple_build_assign (cast_stride, NOP_EXPR, 2344 1.1 mrg c->stride); 2345 1.1 mrg stride = cast_stride; 2346 1.1 mrg } 2347 1.1 mrg else 2348 1.1 mrg stride = c->stride; 2349 1.1 mrg 2350 1.1 mrg if (increment == 1) 2351 1.1 mrg new_stmt = gimple_build_assign (lhs, plus_code, basis_name, stride); 2352 1.1 mrg else if (increment == -1) 2353 1.1 mrg new_stmt = gimple_build_assign (lhs, MINUS_EXPR, basis_name, stride); 2354 1.1 mrg else 2355 1.1 mrg gcc_unreachable (); 2356 1.1 mrg } 2357 1.1 mrg } 2358 1.1 mrg 2359 1.1 mrg if (cast_stmt) 2360 1.1 mrg { 2361 1.1 mrg gimple_set_location (cast_stmt, loc); 2362 1.1 mrg gsi_insert_on_edge (e, cast_stmt); 2363 1.1 mrg } 2364 1.1 mrg 2365 1.1 mrg gimple_set_location (new_stmt, loc); 2366 1.1 mrg gsi_insert_on_edge (e, new_stmt); 2367 1.1 mrg 2368 1.1 mrg if (dump_file && (dump_flags & TDF_DETAILS)) 2369 1.1 mrg { 2370 1.1 mrg if (cast_stmt) 2371 1.1 mrg { 2372 1.1 mrg fprintf (dump_file, "Inserting cast on edge %d->%d: ", 2373 1.1 mrg e->src->index, e->dest->index); 2374 1.1 mrg print_gimple_stmt (dump_file, cast_stmt, 0); 2375 1.1 mrg } 2376 1.1 mrg fprintf (dump_file, "Inserting on edge %d->%d: ", e->src->index, 2377 1.1 mrg e->dest->index); 2378 1.1 mrg print_gimple_stmt (dump_file, new_stmt, 0); 2379 1.1 mrg } 2380 1.1 mrg 2381 1.1 mrg return lhs; 2382 1.1 mrg } 2383 1.1 mrg 2384 1.1 mrg /* Clear the visited field for a tree of PHI candidates. */ 2385 1.1 mrg 2386 1.1 mrg static void 2387 1.1 mrg clear_visited (gphi *phi) 2388 1.1 mrg { 2389 1.1 mrg unsigned i; 2390 1.1 mrg slsr_cand_t phi_cand = *stmt_cand_map->get (phi); 2391 1.1 mrg 2392 1.1 mrg if (phi_cand->visited) 2393 1.1 mrg { 2394 1.1 mrg phi_cand->visited = 0; 2395 1.1 mrg 2396 1.1 mrg for (i = 0; i < gimple_phi_num_args (phi); i++) 2397 1.1 mrg { 2398 1.1 mrg tree arg = gimple_phi_arg_def (phi, i); 2399 1.1 mrg gimple *arg_def = SSA_NAME_DEF_STMT (arg); 2400 1.1 mrg if (gimple_code (arg_def) == GIMPLE_PHI) 2401 1.1 mrg clear_visited (as_a <gphi *> (arg_def)); 2402 1.1 mrg } 2403 1.1 mrg } 2404 1.1 mrg } 2405 1.1 mrg 2406 1.1 mrg /* Recursive helper function for create_phi_basis. */ 2407 1.1 mrg 2408 1.1 mrg static tree 2409 1.1 mrg create_phi_basis_1 (slsr_cand_t c, gimple *from_phi, tree basis_name, 2410 1.1 mrg location_t loc, bool known_stride) 2411 1.1 mrg { 2412 1.1 mrg int i; 2413 1.1 mrg tree name, phi_arg; 2414 1.1 mrg gphi *phi; 2415 1.1 mrg slsr_cand_t basis = lookup_cand (c->basis); 2416 1.1 mrg int nargs = gimple_phi_num_args (from_phi); 2417 1.1 mrg basic_block phi_bb = gimple_bb (from_phi); 2418 1.1 mrg slsr_cand_t phi_cand = *stmt_cand_map->get (from_phi); 2419 1.1 mrg auto_vec<tree> phi_args (nargs); 2420 1.1 mrg 2421 1.1 mrg if (phi_cand->visited) 2422 1.1 mrg return phi_cand->cached_basis; 2423 1.1 mrg phi_cand->visited = 1; 2424 1.1 mrg 2425 1.1 mrg /* Process each argument of the existing phi that represents 2426 1.1 mrg conditionally-executed add candidates. */ 2427 1.1 mrg for (i = 0; i < nargs; i++) 2428 1.1 mrg { 2429 1.1 mrg edge e = (*phi_bb->preds)[i]; 2430 1.1 mrg tree arg = gimple_phi_arg_def (from_phi, i); 2431 1.1 mrg tree feeding_def; 2432 1.1 mrg 2433 1.1 mrg /* If the phi argument is the base name of the CAND_PHI, then 2434 1.1 mrg this incoming arc should use the hidden basis. */ 2435 1.1 mrg if (operand_equal_p (arg, phi_cand->base_expr, 0)) 2436 1.1 mrg if (basis->index == 0) 2437 1.1 mrg feeding_def = gimple_assign_lhs (basis->cand_stmt); 2438 1.1 mrg else 2439 1.1 mrg { 2440 1.1 mrg widest_int incr = -basis->index; 2441 1.1 mrg feeding_def = create_add_on_incoming_edge (c, basis_name, incr, 2442 1.1 mrg e, loc, known_stride); 2443 1.1 mrg } 2444 1.1 mrg else 2445 1.1 mrg { 2446 1.1 mrg gimple *arg_def = SSA_NAME_DEF_STMT (arg); 2447 1.1 mrg 2448 1.1 mrg /* If there is another phi along this incoming edge, we must 2449 1.1 mrg process it in the same fashion to ensure that all basis 2450 1.1 mrg adjustments are made along its incoming edges. */ 2451 1.1 mrg if (gimple_code (arg_def) == GIMPLE_PHI) 2452 1.1 mrg feeding_def = create_phi_basis_1 (c, arg_def, basis_name, 2453 1.1 mrg loc, known_stride); 2454 1.1 mrg else 2455 1.1 mrg { 2456 1.1 mrg slsr_cand_t arg_cand = base_cand_from_table (arg); 2457 1.1 mrg widest_int diff = arg_cand->index - basis->index; 2458 1.1 mrg feeding_def = create_add_on_incoming_edge (c, basis_name, diff, 2459 1.1 mrg e, loc, known_stride); 2460 1.1 mrg } 2461 1.1 mrg } 2462 1.1 mrg 2463 1.1 mrg /* Because of recursion, we need to save the arguments in a vector 2464 1.1 mrg so we can create the PHI statement all at once. Otherwise the 2465 1.1 mrg storage for the half-created PHI can be reclaimed. */ 2466 1.1 mrg phi_args.safe_push (feeding_def); 2467 1.1 mrg } 2468 1.1 mrg 2469 1.1 mrg /* Create the new phi basis. */ 2470 1.1 mrg name = make_temp_ssa_name (TREE_TYPE (basis_name), NULL, "slsr"); 2471 1.1 mrg phi = create_phi_node (name, phi_bb); 2472 1.1 mrg SSA_NAME_DEF_STMT (name) = phi; 2473 1.1 mrg 2474 1.1 mrg FOR_EACH_VEC_ELT (phi_args, i, phi_arg) 2475 1.1 mrg { 2476 1.1 mrg edge e = (*phi_bb->preds)[i]; 2477 1.1 mrg add_phi_arg (phi, phi_arg, e, loc); 2478 1.1 mrg } 2479 1.1 mrg 2480 1.1 mrg update_stmt (phi); 2481 1.1 mrg 2482 1.1 mrg if (dump_file && (dump_flags & TDF_DETAILS)) 2483 1.1 mrg { 2484 1.1 mrg fputs ("Introducing new phi basis: ", dump_file); 2485 1.1 mrg print_gimple_stmt (dump_file, phi, 0); 2486 1.1 mrg } 2487 1.1 mrg 2488 1.1 mrg phi_cand->cached_basis = name; 2489 1.1 mrg return name; 2490 1.1 mrg } 2491 1.1 mrg 2492 1.1 mrg /* Given a candidate C with BASIS_NAME being the LHS of C's basis which 2493 1.1 mrg is hidden by the phi node FROM_PHI, create a new phi node in the same 2494 1.1 mrg block as FROM_PHI. The new phi is suitable for use as a basis by C, 2495 1.1 mrg with its phi arguments representing conditional adjustments to the 2496 1.1 mrg hidden basis along conditional incoming paths. Those adjustments are 2497 1.1 mrg made by creating add statements (and sometimes recursively creating 2498 1.1 mrg phis) along those incoming paths. LOC is the location to attach to 2499 1.1 mrg the introduced statements. KNOWN_STRIDE is true iff C's stride is a 2500 1.1 mrg constant. */ 2501 1.1 mrg 2502 1.1 mrg static tree 2503 1.1 mrg create_phi_basis (slsr_cand_t c, gimple *from_phi, tree basis_name, 2504 1.1 mrg location_t loc, bool known_stride) 2505 1.1 mrg { 2506 1.1 mrg tree retval = create_phi_basis_1 (c, from_phi, basis_name, loc, 2507 1.1 mrg known_stride); 2508 1.1 mrg gcc_assert (retval); 2509 1.1 mrg clear_visited (as_a <gphi *> (from_phi)); 2510 1.1 mrg return retval; 2511 1.1 mrg } 2512 1.1 mrg 2513 1.1 mrg /* Given a candidate C whose basis is hidden by at least one intervening 2514 1.1 mrg phi, introduce a matching number of new phis to represent its basis 2515 1.1 mrg adjusted by conditional increments along possible incoming paths. Then 2516 1.1 mrg replace C as though it were an unconditional candidate, using the new 2517 1.1 mrg basis. */ 2518 1.1 mrg 2519 1.1 mrg static void 2520 1.1 mrg replace_conditional_candidate (slsr_cand_t c) 2521 1.1 mrg { 2522 1.1 mrg tree basis_name, name; 2523 1.1 mrg slsr_cand_t basis; 2524 1.1 mrg location_t loc; 2525 1.1 mrg 2526 1.1 mrg /* Look up the LHS SSA name from C's basis. This will be the 2527 1.1 mrg RHS1 of the adds we will introduce to create new phi arguments. */ 2528 1.1 mrg basis = lookup_cand (c->basis); 2529 1.1 mrg basis_name = gimple_assign_lhs (basis->cand_stmt); 2530 1.1 mrg 2531 1.1 mrg /* Create a new phi statement which will represent C's true basis 2532 1.1 mrg after the transformation is complete. */ 2533 1.1 mrg loc = gimple_location (c->cand_stmt); 2534 1.1 mrg name = create_phi_basis (c, lookup_cand (c->def_phi)->cand_stmt, 2535 1.1 mrg basis_name, loc, KNOWN_STRIDE); 2536 1.1 mrg 2537 1.1 mrg /* Replace C with an add of the new basis phi and a constant. */ 2538 1.1 mrg widest_int bump = c->index * wi::to_widest (c->stride); 2539 1.1 mrg 2540 1.1 mrg replace_mult_candidate (c, name, bump); 2541 1.1 mrg } 2542 1.1 mrg 2543 1.1 mrg /* Recursive helper function for phi_add_costs. SPREAD is a measure of 2544 1.1 mrg how many PHI nodes we have visited at this point in the tree walk. */ 2545 1.1 mrg 2546 1.1 mrg static int 2547 1.1 mrg phi_add_costs_1 (gimple *phi, slsr_cand_t c, int one_add_cost, int *spread) 2548 1.1 mrg { 2549 1.1 mrg unsigned i; 2550 1.1 mrg int cost = 0; 2551 1.1 mrg slsr_cand_t phi_cand = *stmt_cand_map->get (phi); 2552 1.1 mrg 2553 1.1 mrg if (phi_cand->visited) 2554 1.1 mrg return 0; 2555 1.1 mrg 2556 1.1 mrg phi_cand->visited = 1; 2557 1.1 mrg (*spread)++; 2558 1.1 mrg 2559 1.1 mrg /* If we work our way back to a phi that isn't dominated by the hidden 2560 1.1 mrg basis, this isn't a candidate for replacement. Indicate this by 2561 1.1 mrg returning an unreasonably high cost. It's not easy to detect 2562 1.1 mrg these situations when determining the basis, so we defer the 2563 1.1 mrg decision until now. */ 2564 1.1 mrg basic_block phi_bb = gimple_bb (phi); 2565 1.1 mrg slsr_cand_t basis = lookup_cand (c->basis); 2566 1.1 mrg basic_block basis_bb = gimple_bb (basis->cand_stmt); 2567 1.1 mrg 2568 1.1 mrg if (phi_bb == basis_bb || !dominated_by_p (CDI_DOMINATORS, phi_bb, basis_bb)) 2569 1.1 mrg return COST_INFINITE; 2570 1.1 mrg 2571 1.1 mrg for (i = 0; i < gimple_phi_num_args (phi); i++) 2572 1.1 mrg { 2573 1.1 mrg tree arg = gimple_phi_arg_def (phi, i); 2574 1.1 mrg 2575 1.1 mrg if (arg != phi_cand->base_expr) 2576 1.1 mrg { 2577 1.1 mrg gimple *arg_def = SSA_NAME_DEF_STMT (arg); 2578 1.1 mrg 2579 1.1 mrg if (gimple_code (arg_def) == GIMPLE_PHI) 2580 1.1 mrg { 2581 1.1 mrg cost += phi_add_costs_1 (arg_def, c, one_add_cost, spread); 2582 1.1 mrg 2583 1.1 mrg if (cost >= COST_INFINITE || *spread > MAX_SPREAD) 2584 1.1 mrg return COST_INFINITE; 2585 1.1 mrg } 2586 1.1 mrg else 2587 1.1 mrg { 2588 1.1 mrg slsr_cand_t arg_cand = base_cand_from_table (arg); 2589 1.1 mrg 2590 1.1 mrg if (arg_cand->index != c->index) 2591 1.1 mrg cost += one_add_cost; 2592 1.1 mrg } 2593 1.1 mrg } 2594 1.1 mrg } 2595 1.1 mrg 2596 1.1 mrg return cost; 2597 1.1 mrg } 2598 1.1 mrg 2599 1.1 mrg /* Compute the expected costs of inserting basis adjustments for 2600 1.1 mrg candidate C with phi-definition PHI. The cost of inserting 2601 1.1 mrg one adjustment is given by ONE_ADD_COST. If PHI has arguments 2602 1.1 mrg which are themselves phi results, recursively calculate costs 2603 1.1 mrg for those phis as well. */ 2604 1.1 mrg 2605 1.1 mrg static int 2606 1.1 mrg phi_add_costs (gimple *phi, slsr_cand_t c, int one_add_cost) 2607 1.1 mrg { 2608 1.1 mrg int spread = 0; 2609 1.1 mrg int retval = phi_add_costs_1 (phi, c, one_add_cost, &spread); 2610 1.1 mrg clear_visited (as_a <gphi *> (phi)); 2611 1.1 mrg return retval; 2612 1.1 mrg } 2613 1.1 mrg /* For candidate C, each sibling of candidate C, and each dependent of 2614 1.1 mrg candidate C, determine whether the candidate is dependent upon a 2615 1.1 mrg phi that hides its basis. If not, replace the candidate unconditionally. 2616 1.1 mrg Otherwise, determine whether the cost of introducing compensation code 2617 1.1 mrg for the candidate is offset by the gains from strength reduction. If 2618 1.1 mrg so, replace the candidate and introduce the compensation code. */ 2619 1.1 mrg 2620 1.1 mrg static void 2621 1.1 mrg replace_uncond_cands_and_profitable_phis (slsr_cand_t c) 2622 1.1 mrg { 2623 1.1 mrg if (phi_dependent_cand_p (c)) 2624 1.1 mrg { 2625 1.1 mrg /* A multiply candidate with a stride of 1 is just an artifice 2626 1.1 mrg of a copy or cast; there is no value in replacing it. */ 2627 1.1 mrg if (c->kind == CAND_MULT && wi::to_widest (c->stride) != 1) 2628 1.1 mrg { 2629 1.1 mrg /* A candidate dependent upon a phi will replace a multiply by 2630 1.1 mrg a constant with an add, and will insert at most one add for 2631 1.1 mrg each phi argument. Add these costs with the potential dead-code 2632 1.1 mrg savings to determine profitability. */ 2633 1.1 mrg bool speed = optimize_bb_for_speed_p (gimple_bb (c->cand_stmt)); 2634 1.1 mrg int mult_savings = stmt_cost (c->cand_stmt, speed); 2635 1.1 mrg gimple *phi = lookup_cand (c->def_phi)->cand_stmt; 2636 1.1 mrg tree phi_result = gimple_phi_result (phi); 2637 1.1 mrg int one_add_cost = add_cost (speed, 2638 1.1 mrg TYPE_MODE (TREE_TYPE (phi_result))); 2639 1.1 mrg int add_costs = one_add_cost + phi_add_costs (phi, c, one_add_cost); 2640 1.1 mrg int cost = add_costs - mult_savings - c->dead_savings; 2641 1.1 mrg 2642 1.1 mrg if (dump_file && (dump_flags & TDF_DETAILS)) 2643 1.1 mrg { 2644 1.1 mrg fprintf (dump_file, " Conditional candidate %d:\n", c->cand_num); 2645 1.1 mrg fprintf (dump_file, " add_costs = %d\n", add_costs); 2646 1.1 mrg fprintf (dump_file, " mult_savings = %d\n", mult_savings); 2647 1.1 mrg fprintf (dump_file, " dead_savings = %d\n", c->dead_savings); 2648 1.1 mrg fprintf (dump_file, " cost = %d\n", cost); 2649 1.1 mrg if (cost <= COST_NEUTRAL) 2650 1.1 mrg fputs (" Replacing...\n", dump_file); 2651 1.1 mrg else 2652 1.1 mrg fputs (" Not replaced.\n", dump_file); 2653 1.1 mrg } 2654 1.1 mrg 2655 1.1 mrg if (cost <= COST_NEUTRAL) 2656 1.1 mrg replace_conditional_candidate (c); 2657 1.1 mrg } 2658 1.1 mrg } 2659 1.1 mrg else 2660 1.1 mrg replace_unconditional_candidate (c); 2661 1.1 mrg 2662 1.1 mrg if (c->sibling) 2663 1.1 mrg replace_uncond_cands_and_profitable_phis (lookup_cand (c->sibling)); 2664 1.1 mrg 2665 1.1 mrg if (c->dependent) 2666 1.1 mrg replace_uncond_cands_and_profitable_phis (lookup_cand (c->dependent)); 2667 1.1 mrg } 2668 1.1 mrg 2669 1.1 mrg /* Count the number of candidates in the tree rooted at C that have 2671 1.1 mrg not already been replaced under other interpretations. */ 2672 1.1 mrg 2673 1.1 mrg static int 2674 1.1 mrg count_candidates (slsr_cand_t c) 2675 1.1 mrg { 2676 1.1 mrg unsigned count = cand_already_replaced (c) ? 0 : 1; 2677 1.1 mrg 2678 1.1 mrg if (c->sibling) 2679 1.1 mrg count += count_candidates (lookup_cand (c->sibling)); 2680 1.1 mrg 2681 1.1 mrg if (c->dependent) 2682 1.1 mrg count += count_candidates (lookup_cand (c->dependent)); 2683 1.1 mrg 2684 1.1 mrg return count; 2685 1.1 mrg } 2686 1.1 mrg 2687 1.1 mrg /* Increase the count of INCREMENT by one in the increment vector. 2688 1.1 mrg INCREMENT is associated with candidate C. If INCREMENT is to be 2689 1.1 mrg conditionally executed as part of a conditional candidate replacement, 2690 1.1 mrg IS_PHI_ADJUST is true, otherwise false. If an initializer 2691 1.1 mrg T_0 = stride * I is provided by a candidate that dominates all 2692 1.1 mrg candidates with the same increment, also record T_0 for subsequent use. */ 2693 1.1 mrg 2694 1.1 mrg static void 2695 1.1 mrg record_increment (slsr_cand_t c, widest_int increment, bool is_phi_adjust) 2696 1.1 mrg { 2697 1.1 mrg bool found = false; 2698 1.1 mrg unsigned i; 2699 1.1 mrg 2700 1.1 mrg /* Treat increments that differ only in sign as identical so as to 2701 1.1 mrg share initializers, unless we are generating pointer arithmetic. */ 2702 1.1 mrg if (!address_arithmetic_p && wi::neg_p (increment)) 2703 1.1 mrg increment = -increment; 2704 1.1 mrg 2705 1.1 mrg for (i = 0; i < incr_vec_len; i++) 2706 1.1 mrg { 2707 1.1 mrg if (incr_vec[i].incr == increment) 2708 1.1 mrg { 2709 1.1 mrg incr_vec[i].count++; 2710 1.1 mrg found = true; 2711 1.1 mrg 2712 1.1 mrg /* If we previously recorded an initializer that doesn't 2713 1.1 mrg dominate this candidate, it's not going to be useful to 2714 1.1 mrg us after all. */ 2715 1.1 mrg if (incr_vec[i].initializer 2716 1.1 mrg && !dominated_by_p (CDI_DOMINATORS, 2717 1.1 mrg gimple_bb (c->cand_stmt), 2718 1.1 mrg incr_vec[i].init_bb)) 2719 1.1 mrg { 2720 1.1 mrg incr_vec[i].initializer = NULL_TREE; 2721 1.1 mrg incr_vec[i].init_bb = NULL; 2722 1.1 mrg } 2723 1.1 mrg 2724 1.1 mrg break; 2725 1.1 mrg } 2726 1.1 mrg } 2727 1.1 mrg 2728 1.1 mrg if (!found && incr_vec_len < MAX_INCR_VEC_LEN - 1) 2729 1.1 mrg { 2730 1.1 mrg /* The first time we see an increment, create the entry for it. 2731 1.1 mrg If this is the root candidate which doesn't have a basis, set 2732 1.1 mrg the count to zero. We're only processing it so it can possibly 2733 1.1 mrg provide an initializer for other candidates. */ 2734 1.1 mrg incr_vec[incr_vec_len].incr = increment; 2735 1.1 mrg incr_vec[incr_vec_len].count = c->basis || is_phi_adjust ? 1 : 0; 2736 1.1 mrg incr_vec[incr_vec_len].cost = COST_INFINITE; 2737 1.1 mrg 2738 1.1 mrg /* Optimistically record the first occurrence of this increment 2739 1.1 mrg as providing an initializer (if it does); we will revise this 2740 1.1 mrg opinion later if it doesn't dominate all other occurrences. 2741 1.1 mrg Exception: increments of 0, 1 never need initializers; 2742 1.1 mrg and phi adjustments don't ever provide initializers. */ 2743 1.1 mrg if (c->kind == CAND_ADD 2744 1.1 mrg && !is_phi_adjust 2745 1.1 mrg && c->index == increment 2746 1.1 mrg && (increment > 1 || increment < 0) 2747 1.1 mrg && (gimple_assign_rhs_code (c->cand_stmt) == PLUS_EXPR 2748 1.1 mrg || gimple_assign_rhs_code (c->cand_stmt) == POINTER_PLUS_EXPR)) 2749 1.1 mrg { 2750 1.1 mrg tree t0 = NULL_TREE; 2751 1.1 mrg tree rhs1 = gimple_assign_rhs1 (c->cand_stmt); 2752 1.1 mrg tree rhs2 = gimple_assign_rhs2 (c->cand_stmt); 2753 1.1 mrg if (operand_equal_p (rhs1, c->base_expr, 0)) 2754 1.1 mrg t0 = rhs2; 2755 1.1 mrg else if (operand_equal_p (rhs2, c->base_expr, 0)) 2756 1.1 mrg t0 = rhs1; 2757 1.1 mrg if (t0 2758 1.1 mrg && SSA_NAME_DEF_STMT (t0) 2759 1.1 mrg && gimple_bb (SSA_NAME_DEF_STMT (t0))) 2760 1.1 mrg { 2761 1.1 mrg incr_vec[incr_vec_len].initializer = t0; 2762 1.1 mrg incr_vec[incr_vec_len++].init_bb 2763 1.1 mrg = gimple_bb (SSA_NAME_DEF_STMT (t0)); 2764 1.1 mrg } 2765 1.1 mrg else 2766 1.1 mrg { 2767 1.1 mrg incr_vec[incr_vec_len].initializer = NULL_TREE; 2768 1.1 mrg incr_vec[incr_vec_len++].init_bb = NULL; 2769 1.1 mrg } 2770 1.1 mrg } 2771 1.1 mrg else 2772 1.1 mrg { 2773 1.1 mrg incr_vec[incr_vec_len].initializer = NULL_TREE; 2774 1.1 mrg incr_vec[incr_vec_len++].init_bb = NULL; 2775 1.1 mrg } 2776 1.1 mrg } 2777 1.1 mrg } 2778 1.1 mrg 2779 1.1 mrg /* Recursive helper function for record_phi_increments. */ 2780 1.1 mrg 2781 1.1 mrg static void 2782 1.1 mrg record_phi_increments_1 (slsr_cand_t basis, gimple *phi) 2783 1.1 mrg { 2784 1.1 mrg unsigned i; 2785 1.1 mrg slsr_cand_t phi_cand = *stmt_cand_map->get (phi); 2786 1.1 mrg 2787 1.1 mrg if (phi_cand->visited) 2788 1.1 mrg return; 2789 1.1 mrg phi_cand->visited = 1; 2790 1.1 mrg 2791 1.1 mrg for (i = 0; i < gimple_phi_num_args (phi); i++) 2792 1.1 mrg { 2793 1.1 mrg tree arg = gimple_phi_arg_def (phi, i); 2794 1.1 mrg gimple *arg_def = SSA_NAME_DEF_STMT (arg); 2795 1.1 mrg 2796 1.1 mrg if (gimple_code (arg_def) == GIMPLE_PHI) 2797 1.1 mrg record_phi_increments_1 (basis, arg_def); 2798 1.1 mrg else 2799 1.1 mrg { 2800 1.1 mrg widest_int diff; 2801 1.1 mrg 2802 1.1 mrg if (operand_equal_p (arg, phi_cand->base_expr, 0)) 2803 1.1 mrg { 2804 1.1 mrg diff = -basis->index; 2805 1.1 mrg record_increment (phi_cand, diff, PHI_ADJUST); 2806 1.1 mrg } 2807 1.1 mrg else 2808 1.1 mrg { 2809 1.1 mrg slsr_cand_t arg_cand = base_cand_from_table (arg); 2810 1.1 mrg diff = arg_cand->index - basis->index; 2811 1.1 mrg record_increment (arg_cand, diff, PHI_ADJUST); 2812 1.1 mrg } 2813 1.1 mrg } 2814 1.1 mrg } 2815 1.1 mrg } 2816 1.1 mrg 2817 1.1 mrg /* Given phi statement PHI that hides a candidate from its BASIS, find 2818 1.1 mrg the increments along each incoming arc (recursively handling additional 2819 1.1 mrg phis that may be present) and record them. These increments are the 2820 1.1 mrg difference in index between the index-adjusting statements and the 2821 1.1 mrg index of the basis. */ 2822 1.1 mrg 2823 1.1 mrg static void 2824 1.1 mrg record_phi_increments (slsr_cand_t basis, gimple *phi) 2825 1.1 mrg { 2826 1.1 mrg record_phi_increments_1 (basis, phi); 2827 1.1 mrg clear_visited (as_a <gphi *> (phi)); 2828 1.1 mrg } 2829 1.1 mrg 2830 1.1 mrg /* Determine how many times each unique increment occurs in the set 2831 1.1 mrg of candidates rooted at C's parent, recording the data in the 2832 1.1 mrg increment vector. For each unique increment I, if an initializer 2833 1.1 mrg T_0 = stride * I is provided by a candidate that dominates all 2834 1.1 mrg candidates with the same increment, also record T_0 for subsequent 2835 1.1 mrg use. */ 2836 1.1 mrg 2837 1.1 mrg static void 2838 1.1 mrg record_increments (slsr_cand_t c) 2839 1.1 mrg { 2840 1.1 mrg if (!cand_already_replaced (c)) 2841 1.1 mrg { 2842 1.1 mrg if (!phi_dependent_cand_p (c)) 2843 1.1 mrg record_increment (c, cand_increment (c), NOT_PHI_ADJUST); 2844 1.1 mrg else 2845 1.1 mrg { 2846 1.1 mrg /* A candidate with a basis hidden by a phi will have one 2847 1.1 mrg increment for its relationship to the index represented by 2848 1.1 mrg the phi, and potentially additional increments along each 2849 1.1 mrg incoming edge. For the root of the dependency tree (which 2850 1.1 mrg has no basis), process just the initial index in case it has 2851 1.1 mrg an initializer that can be used by subsequent candidates. */ 2852 1.1 mrg record_increment (c, c->index, NOT_PHI_ADJUST); 2853 1.1 mrg 2854 1.1 mrg if (c->basis) 2855 1.1 mrg record_phi_increments (lookup_cand (c->basis), 2856 1.1 mrg lookup_cand (c->def_phi)->cand_stmt); 2857 1.1 mrg } 2858 1.1 mrg } 2859 1.1 mrg 2860 1.1 mrg if (c->sibling) 2861 1.1 mrg record_increments (lookup_cand (c->sibling)); 2862 1.1 mrg 2863 1.1 mrg if (c->dependent) 2864 1.1 mrg record_increments (lookup_cand (c->dependent)); 2865 1.1 mrg } 2866 1.1 mrg 2867 1.1 mrg /* Recursive helper function for phi_incr_cost. */ 2868 1.1 mrg 2869 1.1 mrg static int 2870 1.1 mrg phi_incr_cost_1 (slsr_cand_t c, const widest_int &incr, gimple *phi, 2871 1.1 mrg int *savings) 2872 1.1 mrg { 2873 1.1 mrg unsigned i; 2874 1.1 mrg int cost = 0; 2875 1.1 mrg slsr_cand_t basis = lookup_cand (c->basis); 2876 1.1 mrg slsr_cand_t phi_cand = *stmt_cand_map->get (phi); 2877 1.1 mrg 2878 1.1 mrg if (phi_cand->visited) 2879 1.1 mrg return 0; 2880 1.1 mrg phi_cand->visited = 1; 2881 1.1 mrg 2882 1.1 mrg for (i = 0; i < gimple_phi_num_args (phi); i++) 2883 1.1 mrg { 2884 1.1 mrg tree arg = gimple_phi_arg_def (phi, i); 2885 1.1 mrg gimple *arg_def = SSA_NAME_DEF_STMT (arg); 2886 1.1 mrg 2887 1.1 mrg if (gimple_code (arg_def) == GIMPLE_PHI) 2888 1.1 mrg { 2889 1.1 mrg int feeding_savings = 0; 2890 1.1 mrg tree feeding_var = gimple_phi_result (arg_def); 2891 1.1 mrg cost += phi_incr_cost_1 (c, incr, arg_def, &feeding_savings); 2892 1.1 mrg if (uses_consumed_by_stmt (feeding_var, phi)) 2893 1.1 mrg *savings += feeding_savings; 2894 1.1 mrg } 2895 1.1 mrg else 2896 1.1 mrg { 2897 1.1 mrg widest_int diff; 2898 1.1 mrg slsr_cand_t arg_cand; 2899 1.1 mrg 2900 1.1 mrg /* When the PHI argument is just a pass-through to the base 2901 1.1 mrg expression of the hidden basis, the difference is zero minus 2902 1.1 mrg the index of the basis. There is no potential savings by 2903 1.1 mrg eliminating a statement in this case. */ 2904 1.1 mrg if (operand_equal_p (arg, phi_cand->base_expr, 0)) 2905 1.1 mrg { 2906 1.1 mrg arg_cand = (slsr_cand_t)NULL; 2907 1.1 mrg diff = -basis->index; 2908 1.1 mrg } 2909 1.1 mrg else 2910 1.1 mrg { 2911 1.1 mrg arg_cand = base_cand_from_table (arg); 2912 1.1 mrg diff = arg_cand->index - basis->index; 2913 1.1 mrg } 2914 1.1 mrg 2915 1.1 mrg if (incr == diff) 2916 1.1 mrg { 2917 1.1 mrg tree basis_lhs = gimple_assign_lhs (basis->cand_stmt); 2918 1.1 mrg cost += add_cost (true, TYPE_MODE (TREE_TYPE (basis_lhs))); 2919 1.1 mrg if (arg_cand) 2920 1.1 mrg { 2921 1.1 mrg tree lhs = gimple_assign_lhs (arg_cand->cand_stmt); 2922 1.1 mrg if (uses_consumed_by_stmt (lhs, phi)) 2923 1.1 mrg *savings += stmt_cost (arg_cand->cand_stmt, true); 2924 1.1 mrg } 2925 1.1 mrg } 2926 1.1 mrg } 2927 1.1 mrg } 2928 1.1 mrg 2929 1.1 mrg return cost; 2930 1.1 mrg } 2931 1.1 mrg 2932 1.1 mrg /* Add up and return the costs of introducing add statements that 2933 1.1 mrg require the increment INCR on behalf of candidate C and phi 2934 1.1 mrg statement PHI. Accumulate into *SAVINGS the potential savings 2935 1.1 mrg from removing existing statements that feed PHI and have no other 2936 1.1 mrg uses. */ 2937 1.1 mrg 2938 1.1 mrg static int 2939 1.1 mrg phi_incr_cost (slsr_cand_t c, const widest_int &incr, gimple *phi, 2940 1.1 mrg int *savings) 2941 1.1 mrg { 2942 1.1 mrg int retval = phi_incr_cost_1 (c, incr, phi, savings); 2943 1.1 mrg clear_visited (as_a <gphi *> (phi)); 2944 1.1 mrg return retval; 2945 1.1 mrg } 2946 1.1 mrg 2947 1.1 mrg /* Return the first candidate in the tree rooted at C that has not 2948 1.1 mrg already been replaced, favoring siblings over dependents. */ 2949 1.1 mrg 2950 1.1 mrg static slsr_cand_t 2951 1.1 mrg unreplaced_cand_in_tree (slsr_cand_t c) 2952 1.1 mrg { 2953 1.1 mrg if (!cand_already_replaced (c)) 2954 1.1 mrg return c; 2955 1.1 mrg 2956 1.1 mrg if (c->sibling) 2957 1.1 mrg { 2958 1.1 mrg slsr_cand_t sib = unreplaced_cand_in_tree (lookup_cand (c->sibling)); 2959 1.1 mrg if (sib) 2960 1.1 mrg return sib; 2961 1.1 mrg } 2962 1.1 mrg 2963 1.1 mrg if (c->dependent) 2964 1.1 mrg { 2965 1.1 mrg slsr_cand_t dep = unreplaced_cand_in_tree (lookup_cand (c->dependent)); 2966 1.1 mrg if (dep) 2967 1.1 mrg return dep; 2968 1.1 mrg } 2969 1.1 mrg 2970 1.1 mrg return NULL; 2971 1.1 mrg } 2972 1.1 mrg 2973 1.1 mrg /* Return TRUE if the candidates in the tree rooted at C should be 2974 1.1 mrg optimized for speed, else FALSE. We estimate this based on the block 2975 1.1 mrg containing the most dominant candidate in the tree that has not yet 2976 1.1 mrg been replaced. */ 2977 1.1 mrg 2978 1.1 mrg static bool 2979 1.1 mrg optimize_cands_for_speed_p (slsr_cand_t c) 2980 1.1 mrg { 2981 1.1 mrg slsr_cand_t c2 = unreplaced_cand_in_tree (c); 2982 1.1 mrg gcc_assert (c2); 2983 1.1 mrg return optimize_bb_for_speed_p (gimple_bb (c2->cand_stmt)); 2984 1.1 mrg } 2985 1.1 mrg 2986 1.1 mrg /* Add COST_IN to the lowest cost of any dependent path starting at 2987 1.1 mrg candidate C or any of its siblings, counting only candidates along 2988 1.1 mrg such paths with increment INCR. Assume that replacing a candidate 2989 1.1 mrg reduces cost by REPL_SAVINGS. Also account for savings from any 2990 1.1 mrg statements that would go dead. If COUNT_PHIS is true, include 2991 1.1 mrg costs of introducing feeding statements for conditional candidates. */ 2992 1.1 mrg 2993 1.1 mrg static int 2994 1.1 mrg lowest_cost_path (int cost_in, int repl_savings, slsr_cand_t c, 2995 1.1 mrg const widest_int &incr, bool count_phis) 2996 1.1 mrg { 2997 1.1 mrg int local_cost, sib_cost, savings = 0; 2998 1.1 mrg widest_int cand_incr = cand_abs_increment (c); 2999 1.1 mrg 3000 1.1 mrg if (cand_already_replaced (c)) 3001 1.1 mrg local_cost = cost_in; 3002 1.1 mrg else if (incr == cand_incr) 3003 1.1 mrg local_cost = cost_in - repl_savings - c->dead_savings; 3004 1.1 mrg else 3005 1.1 mrg local_cost = cost_in - c->dead_savings; 3006 1.1 mrg 3007 1.1 mrg if (count_phis 3008 1.1 mrg && phi_dependent_cand_p (c) 3009 1.1 mrg && !cand_already_replaced (c)) 3010 1.1 mrg { 3011 1.1 mrg gimple *phi = lookup_cand (c->def_phi)->cand_stmt; 3012 1.1 mrg local_cost += phi_incr_cost (c, incr, phi, &savings); 3013 1.1 mrg 3014 1.1 mrg if (uses_consumed_by_stmt (gimple_phi_result (phi), c->cand_stmt)) 3015 1.1 mrg local_cost -= savings; 3016 1.1 mrg } 3017 1.1 mrg 3018 1.1 mrg if (c->dependent) 3019 1.1 mrg local_cost = lowest_cost_path (local_cost, repl_savings, 3020 1.1 mrg lookup_cand (c->dependent), incr, 3021 1.1 mrg count_phis); 3022 1.1 mrg 3023 1.1 mrg if (c->sibling) 3024 1.1 mrg { 3025 1.1 mrg sib_cost = lowest_cost_path (cost_in, repl_savings, 3026 1.1 mrg lookup_cand (c->sibling), incr, 3027 1.1 mrg count_phis); 3028 1.1 mrg local_cost = MIN (local_cost, sib_cost); 3029 1.1 mrg } 3030 1.1 mrg 3031 1.1 mrg return local_cost; 3032 1.1 mrg } 3033 1.1 mrg 3034 1.1 mrg /* Compute the total savings that would accrue from all replacements 3035 1.1 mrg in the candidate tree rooted at C, counting only candidates with 3036 1.1 mrg increment INCR. Assume that replacing a candidate reduces cost 3037 1.1 mrg by REPL_SAVINGS. Also account for savings from statements that 3038 1.1 mrg would go dead. */ 3039 1.1 mrg 3040 1.1 mrg static int 3041 1.1 mrg total_savings (int repl_savings, slsr_cand_t c, const widest_int &incr, 3042 1.1 mrg bool count_phis) 3043 1.1 mrg { 3044 1.1 mrg int savings = 0; 3045 1.1 mrg widest_int cand_incr = cand_abs_increment (c); 3046 1.1 mrg 3047 1.1 mrg if (incr == cand_incr && !cand_already_replaced (c)) 3048 1.1 mrg savings += repl_savings + c->dead_savings; 3049 1.1 mrg 3050 1.1 mrg if (count_phis 3051 1.1 mrg && phi_dependent_cand_p (c) 3052 1.1 mrg && !cand_already_replaced (c)) 3053 1.1 mrg { 3054 1.1 mrg int phi_savings = 0; 3055 1.1 mrg gimple *phi = lookup_cand (c->def_phi)->cand_stmt; 3056 1.1 mrg savings -= phi_incr_cost (c, incr, phi, &phi_savings); 3057 1.1 mrg 3058 1.1 mrg if (uses_consumed_by_stmt (gimple_phi_result (phi), c->cand_stmt)) 3059 1.1 mrg savings += phi_savings; 3060 1.1 mrg } 3061 1.1 mrg 3062 1.1 mrg if (c->dependent) 3063 1.1 mrg savings += total_savings (repl_savings, lookup_cand (c->dependent), incr, 3064 1.1 mrg count_phis); 3065 1.1 mrg 3066 1.1 mrg if (c->sibling) 3067 1.1 mrg savings += total_savings (repl_savings, lookup_cand (c->sibling), incr, 3068 1.1 mrg count_phis); 3069 1.1 mrg 3070 1.1 mrg return savings; 3071 1.1 mrg } 3072 1.1 mrg 3073 1.1 mrg /* Use target-specific costs to determine and record which increments 3074 1.1 mrg in the current candidate tree are profitable to replace, assuming 3075 1.1 mrg MODE and SPEED. FIRST_DEP is the first dependent of the root of 3076 1.1 mrg the candidate tree. 3077 1.1 mrg 3078 1.1 mrg One slight limitation here is that we don't account for the possible 3079 1.1 mrg introduction of casts in some cases. See replace_one_candidate for 3080 1.1 mrg the cases where these are introduced. This should probably be cleaned 3081 1.1 mrg up sometime. */ 3082 1.1 mrg 3083 1.1 mrg static void 3084 1.1 mrg analyze_increments (slsr_cand_t first_dep, machine_mode mode, bool speed) 3085 1.1 mrg { 3086 1.1 mrg unsigned i; 3087 1.1 mrg 3088 1.1 mrg for (i = 0; i < incr_vec_len; i++) 3089 1.1 mrg { 3090 1.1 mrg HOST_WIDE_INT incr = incr_vec[i].incr.to_shwi (); 3091 1.1 mrg 3092 1.1 mrg /* If somehow this increment is bigger than a HWI, we won't 3093 1.1 mrg be optimizing candidates that use it. And if the increment 3094 1.1 mrg has a count of zero, nothing will be done with it. */ 3095 1.1 mrg if (!wi::fits_shwi_p (incr_vec[i].incr) || !incr_vec[i].count) 3096 1.1 mrg incr_vec[i].cost = COST_INFINITE; 3097 1.1 mrg 3098 1.1 mrg /* Increments of 0, 1, and -1 are always profitable to replace, 3099 1.1 mrg because they always replace a multiply or add with an add or 3100 1.1 mrg copy, and may cause one or more existing instructions to go 3101 1.1 mrg dead. Exception: -1 can't be assumed to be profitable for 3102 1.1 mrg pointer addition. */ 3103 1.1 mrg else if (incr == 0 3104 1.1 mrg || incr == 1 3105 1.1 mrg || (incr == -1 3106 1.1 mrg && !POINTER_TYPE_P (first_dep->cand_type))) 3107 1.1 mrg incr_vec[i].cost = COST_NEUTRAL; 3108 1.1 mrg 3109 1.1 mrg /* If we need to add an initializer, give up if a cast from the 3110 1.1 mrg candidate's type to its stride's type can lose precision. 3111 1.1 mrg Note that this already takes into account that the stride may 3112 1.1 mrg have been cast to a wider type, in which case this test won't 3113 1.1 mrg fire. Example: 3114 1.1 mrg 3115 1.1 mrg short int _1; 3116 1.1 mrg _2 = (int) _1; 3117 1.1 mrg _3 = _2 * 10; 3118 1.1 mrg _4 = x + _3; ADD: x + (10 * (int)_1) : int 3119 1.1 mrg _5 = _2 * 15; 3120 1.1 mrg _6 = x + _5; ADD: x + (15 * (int)_1) : int 3121 1.1 mrg 3122 1.1 mrg Although the stride was a short int initially, the stride 3123 1.1 mrg used in the analysis has been widened to an int, and such 3124 1.1 mrg widening will be done in the initializer as well. */ 3125 1.1 mrg else if (!incr_vec[i].initializer 3126 1.1 mrg && TREE_CODE (first_dep->stride) != INTEGER_CST 3127 1.1 mrg && !legal_cast_p_1 (first_dep->stride_type, 3128 1.1 mrg TREE_TYPE (gimple_assign_lhs 3129 1.1 mrg (first_dep->cand_stmt)))) 3130 1.1 mrg incr_vec[i].cost = COST_INFINITE; 3131 1.1 mrg 3132 1.1 mrg /* If we need to add an initializer, make sure we don't introduce 3133 1.1 mrg a multiply by a pointer type, which can happen in certain cast 3134 1.1 mrg scenarios. */ 3135 1.1 mrg else if (!incr_vec[i].initializer 3136 1.1 mrg && TREE_CODE (first_dep->stride) != INTEGER_CST 3137 1.1 mrg && POINTER_TYPE_P (first_dep->stride_type)) 3138 1.1 mrg incr_vec[i].cost = COST_INFINITE; 3139 1.1 mrg 3140 1.1 mrg /* For any other increment, if this is a multiply candidate, we 3141 1.1 mrg must introduce a temporary T and initialize it with 3142 1.1 mrg T_0 = stride * increment. When optimizing for speed, walk the 3143 1.1 mrg candidate tree to calculate the best cost reduction along any 3144 1.1 mrg path; if it offsets the fixed cost of inserting the initializer, 3145 1.1 mrg replacing the increment is profitable. When optimizing for 3146 1.1 mrg size, instead calculate the total cost reduction from replacing 3147 1.1 mrg all candidates with this increment. */ 3148 1.1 mrg else if (first_dep->kind == CAND_MULT) 3149 1.1 mrg { 3150 1.1 mrg int cost = mult_by_coeff_cost (incr, mode, speed); 3151 1.1 mrg int repl_savings; 3152 1.1 mrg 3153 1.1 mrg if (tree_fits_shwi_p (first_dep->stride)) 3154 1.1 mrg { 3155 1.1 mrg HOST_WIDE_INT hwi_stride = tree_to_shwi (first_dep->stride); 3156 1.1 mrg repl_savings = mult_by_coeff_cost (hwi_stride, mode, speed); 3157 1.1 mrg } 3158 1.1 mrg else 3159 1.1 mrg repl_savings = mul_cost (speed, mode); 3160 1.1 mrg repl_savings -= add_cost (speed, mode); 3161 1.1 mrg 3162 1.1 mrg if (speed) 3163 1.1 mrg cost = lowest_cost_path (cost, repl_savings, first_dep, 3164 1.1 mrg incr_vec[i].incr, COUNT_PHIS); 3165 1.1 mrg else 3166 1.1 mrg cost -= total_savings (repl_savings, first_dep, incr_vec[i].incr, 3167 1.1 mrg COUNT_PHIS); 3168 1.1 mrg 3169 1.1 mrg incr_vec[i].cost = cost; 3170 1.1 mrg } 3171 1.1 mrg 3172 1.1 mrg /* If this is an add candidate, the initializer may already 3173 1.1 mrg exist, so only calculate the cost of the initializer if it 3174 1.1 mrg doesn't. We are replacing one add with another here, so the 3175 1.1 mrg known replacement savings is zero. We will account for removal 3176 1.1 mrg of dead instructions in lowest_cost_path or total_savings. */ 3177 1.1 mrg else 3178 1.1 mrg { 3179 1.1 mrg int cost = 0; 3180 1.1 mrg if (!incr_vec[i].initializer) 3181 1.1 mrg cost = mult_by_coeff_cost (incr, mode, speed); 3182 1.1 mrg 3183 1.1 mrg if (speed) 3184 1.1 mrg cost = lowest_cost_path (cost, 0, first_dep, incr_vec[i].incr, 3185 1.1 mrg DONT_COUNT_PHIS); 3186 1.1 mrg else 3187 1.1 mrg cost -= total_savings (0, first_dep, incr_vec[i].incr, 3188 1.1 mrg DONT_COUNT_PHIS); 3189 1.1 mrg 3190 1.1 mrg incr_vec[i].cost = cost; 3191 1.1 mrg } 3192 1.1 mrg } 3193 1.1 mrg } 3194 1.1 mrg 3195 1.1 mrg /* Return the nearest common dominator of BB1 and BB2. If the blocks 3196 1.1 mrg are identical, return the earlier of C1 and C2 in *WHERE. Otherwise, 3197 1.1 mrg if the NCD matches BB1, return C1 in *WHERE; if the NCD matches BB2, 3198 1.1 mrg return C2 in *WHERE; and if the NCD matches neither, return NULL in 3199 1.1 mrg *WHERE. Note: It is possible for one of C1 and C2 to be NULL. */ 3200 1.1 mrg 3201 1.1 mrg static basic_block 3202 1.1 mrg ncd_for_two_cands (basic_block bb1, basic_block bb2, 3203 1.1 mrg slsr_cand_t c1, slsr_cand_t c2, slsr_cand_t *where) 3204 1.1 mrg { 3205 1.1 mrg basic_block ncd; 3206 1.1 mrg 3207 1.1 mrg if (!bb1) 3208 1.1 mrg { 3209 1.1 mrg *where = c2; 3210 1.1 mrg return bb2; 3211 1.1 mrg } 3212 1.1 mrg 3213 1.1 mrg if (!bb2) 3214 1.1 mrg { 3215 1.1 mrg *where = c1; 3216 1.1 mrg return bb1; 3217 1.1 mrg } 3218 1.1 mrg 3219 1.1 mrg ncd = nearest_common_dominator (CDI_DOMINATORS, bb1, bb2); 3220 1.1 mrg 3221 1.1 mrg /* If both candidates are in the same block, the earlier 3222 1.1 mrg candidate wins. */ 3223 1.1 mrg if (bb1 == ncd && bb2 == ncd) 3224 1.1 mrg { 3225 1.1 mrg if (!c1 || (c2 && c2->cand_num < c1->cand_num)) 3226 1.1 mrg *where = c2; 3227 1.1 mrg else 3228 1.1 mrg *where = c1; 3229 1.1 mrg } 3230 1.1 mrg 3231 1.1 mrg /* Otherwise, if one of them produced a candidate in the 3232 1.1 mrg dominator, that one wins. */ 3233 1.1 mrg else if (bb1 == ncd) 3234 1.1 mrg *where = c1; 3235 1.1 mrg 3236 1.1 mrg else if (bb2 == ncd) 3237 1.1 mrg *where = c2; 3238 1.1 mrg 3239 1.1 mrg /* If neither matches the dominator, neither wins. */ 3240 1.1 mrg else 3241 1.1 mrg *where = NULL; 3242 1.1 mrg 3243 1.1 mrg return ncd; 3244 1.1 mrg } 3245 1.1 mrg 3246 1.1 mrg /* Consider all candidates that feed PHI. Find the nearest common 3247 1.1 mrg dominator of those candidates requiring the given increment INCR. 3248 1.1 mrg Further find and return the nearest common dominator of this result 3249 1.1 mrg with block NCD. If the returned block contains one or more of the 3250 1.1 mrg candidates, return the earliest candidate in the block in *WHERE. */ 3251 1.1 mrg 3252 1.1 mrg static basic_block 3253 1.1 mrg ncd_with_phi (slsr_cand_t c, const widest_int &incr, gphi *phi, 3254 1.1 mrg basic_block ncd, slsr_cand_t *where) 3255 1.1 mrg { 3256 1.1 mrg unsigned i; 3257 1.1 mrg slsr_cand_t basis = lookup_cand (c->basis); 3258 1.1 mrg slsr_cand_t phi_cand = *stmt_cand_map->get (phi); 3259 1.1 mrg 3260 1.1 mrg for (i = 0; i < gimple_phi_num_args (phi); i++) 3261 1.1 mrg { 3262 1.1 mrg tree arg = gimple_phi_arg_def (phi, i); 3263 1.1 mrg gimple *arg_def = SSA_NAME_DEF_STMT (arg); 3264 1.1 mrg 3265 1.1 mrg if (gimple_code (arg_def) == GIMPLE_PHI) 3266 1.1 mrg ncd = ncd_with_phi (c, incr, as_a <gphi *> (arg_def), ncd, where); 3267 1.1 mrg else 3268 1.1 mrg { 3269 1.1 mrg widest_int diff; 3270 1.1 mrg 3271 1.1 mrg if (operand_equal_p (arg, phi_cand->base_expr, 0)) 3272 1.1 mrg diff = -basis->index; 3273 1.1 mrg else 3274 1.1 mrg { 3275 1.1 mrg slsr_cand_t arg_cand = base_cand_from_table (arg); 3276 1.1 mrg diff = arg_cand->index - basis->index; 3277 1.1 mrg } 3278 1.1 mrg 3279 1.1 mrg basic_block pred = gimple_phi_arg_edge (phi, i)->src; 3280 1.1 mrg 3281 1.1 mrg if ((incr == diff) || (!address_arithmetic_p && incr == -diff)) 3282 1.1 mrg ncd = ncd_for_two_cands (ncd, pred, *where, NULL, where); 3283 1.1 mrg } 3284 1.1 mrg } 3285 1.1 mrg 3286 1.1 mrg return ncd; 3287 1.1 mrg } 3288 1.1 mrg 3289 1.1 mrg /* Consider the candidate C together with any candidates that feed 3290 1.1 mrg C's phi dependence (if any). Find and return the nearest common 3291 1.1 mrg dominator of those candidates requiring the given increment INCR. 3292 1.1 mrg If the returned block contains one or more of the candidates, 3293 1.1 mrg return the earliest candidate in the block in *WHERE. */ 3294 1.1 mrg 3295 1.1 mrg static basic_block 3296 1.1 mrg ncd_of_cand_and_phis (slsr_cand_t c, const widest_int &incr, slsr_cand_t *where) 3297 1.1 mrg { 3298 1.1 mrg basic_block ncd = NULL; 3299 1.1 mrg 3300 1.1 mrg if (cand_abs_increment (c) == incr) 3301 1.1 mrg { 3302 1.1 mrg ncd = gimple_bb (c->cand_stmt); 3303 1.1 mrg *where = c; 3304 1.1 mrg } 3305 1.1 mrg 3306 1.1 mrg if (phi_dependent_cand_p (c)) 3307 1.1 mrg ncd = ncd_with_phi (c, incr, 3308 1.1 mrg as_a <gphi *> (lookup_cand (c->def_phi)->cand_stmt), 3309 1.1 mrg ncd, where); 3310 1.1 mrg 3311 1.1 mrg return ncd; 3312 1.1 mrg } 3313 1.1 mrg 3314 1.1 mrg /* Consider all candidates in the tree rooted at C for which INCR 3315 1.1 mrg represents the required increment of C relative to its basis. 3316 1.1 mrg Find and return the basic block that most nearly dominates all 3317 1.1 mrg such candidates. If the returned block contains one or more of 3318 1.1 mrg the candidates, return the earliest candidate in the block in 3319 1.1 mrg *WHERE. */ 3320 1.1 mrg 3321 1.1 mrg static basic_block 3322 1.1 mrg nearest_common_dominator_for_cands (slsr_cand_t c, const widest_int &incr, 3323 1.1 mrg slsr_cand_t *where) 3324 1.1 mrg { 3325 1.1 mrg basic_block sib_ncd = NULL, dep_ncd = NULL, this_ncd = NULL, ncd; 3326 1.1 mrg slsr_cand_t sib_where = NULL, dep_where = NULL, this_where = NULL, new_where; 3327 1.1 mrg 3328 1.1 mrg /* First find the NCD of all siblings and dependents. */ 3329 1.1 mrg if (c->sibling) 3330 1.1 mrg sib_ncd = nearest_common_dominator_for_cands (lookup_cand (c->sibling), 3331 1.1 mrg incr, &sib_where); 3332 1.1 mrg if (c->dependent) 3333 1.1 mrg dep_ncd = nearest_common_dominator_for_cands (lookup_cand (c->dependent), 3334 1.1 mrg incr, &dep_where); 3335 1.1 mrg if (!sib_ncd && !dep_ncd) 3336 1.1 mrg { 3337 1.1 mrg new_where = NULL; 3338 1.1 mrg ncd = NULL; 3339 1.1 mrg } 3340 1.1 mrg else if (sib_ncd && !dep_ncd) 3341 1.1 mrg { 3342 1.1 mrg new_where = sib_where; 3343 1.1 mrg ncd = sib_ncd; 3344 1.1 mrg } 3345 1.1 mrg else if (dep_ncd && !sib_ncd) 3346 1.1 mrg { 3347 1.1 mrg new_where = dep_where; 3348 1.1 mrg ncd = dep_ncd; 3349 1.1 mrg } 3350 1.1 mrg else 3351 1.1 mrg ncd = ncd_for_two_cands (sib_ncd, dep_ncd, sib_where, 3352 1.1 mrg dep_where, &new_where); 3353 1.1 mrg 3354 1.1 mrg /* If the candidate's increment doesn't match the one we're interested 3355 1.1 mrg in (and nor do any increments for feeding defs of a phi-dependence), 3356 1.1 mrg then the result depends only on siblings and dependents. */ 3357 1.1 mrg this_ncd = ncd_of_cand_and_phis (c, incr, &this_where); 3358 1.1 mrg 3359 1.1 mrg if (!this_ncd || cand_already_replaced (c)) 3360 1.1 mrg { 3361 1.1 mrg *where = new_where; 3362 1.1 mrg return ncd; 3363 1.1 mrg } 3364 1.1 mrg 3365 1.1 mrg /* Otherwise, compare this candidate with the result from all siblings 3366 1.1 mrg and dependents. */ 3367 1.1 mrg ncd = ncd_for_two_cands (ncd, this_ncd, new_where, this_where, where); 3368 1.1 mrg 3369 1.1 mrg return ncd; 3370 1.1 mrg } 3371 1.1 mrg 3372 1.1 mrg /* Return TRUE if the increment indexed by INDEX is profitable to replace. */ 3373 1.1 mrg 3374 1.1 mrg static inline bool 3375 1.1 mrg profitable_increment_p (unsigned index) 3376 1.1 mrg { 3377 1.1 mrg return (incr_vec[index].cost <= COST_NEUTRAL); 3378 1.1 mrg } 3379 1.1 mrg 3380 1.1 mrg /* For each profitable increment in the increment vector not equal to 3381 1.1 mrg 0 or 1 (or -1, for non-pointer arithmetic), find the nearest common 3382 1.1 mrg dominator of all statements in the candidate chain rooted at C 3383 1.1 mrg that require that increment, and insert an initializer 3384 1.1 mrg T_0 = stride * increment at that location. Record T_0 with the 3385 1.1 mrg increment record. */ 3386 1.1 mrg 3387 1.1 mrg static void 3388 1.1 mrg insert_initializers (slsr_cand_t c) 3389 1.1 mrg { 3390 1.1 mrg unsigned i; 3391 1.1 mrg 3392 1.1 mrg for (i = 0; i < incr_vec_len; i++) 3393 1.1 mrg { 3394 1.1 mrg basic_block bb; 3395 1.1 mrg slsr_cand_t where = NULL; 3396 1.1 mrg gassign *init_stmt; 3397 1.1 mrg gassign *cast_stmt = NULL; 3398 1.1 mrg tree new_name, incr_tree, init_stride; 3399 1.1 mrg widest_int incr = incr_vec[i].incr; 3400 1.1 mrg 3401 1.1 mrg if (!profitable_increment_p (i) 3402 1.1 mrg || incr == 1 3403 1.1 mrg || (incr == -1 3404 1.1 mrg && (!POINTER_TYPE_P (lookup_cand (c->basis)->cand_type))) 3405 1.1 mrg || incr == 0) 3406 1.1 mrg continue; 3407 1.1 mrg 3408 1.1 mrg /* We may have already identified an existing initializer that 3409 1.1 mrg will suffice. */ 3410 1.1 mrg if (incr_vec[i].initializer) 3411 1.1 mrg { 3412 1.1 mrg if (dump_file && (dump_flags & TDF_DETAILS)) 3413 1.1 mrg { 3414 1.1 mrg fputs ("Using existing initializer: ", dump_file); 3415 1.1 mrg print_gimple_stmt (dump_file, 3416 1.1 mrg SSA_NAME_DEF_STMT (incr_vec[i].initializer), 3417 1.1 mrg 0, TDF_NONE); 3418 1.1 mrg } 3419 1.1 mrg continue; 3420 1.1 mrg } 3421 1.1 mrg 3422 1.1 mrg /* Find the block that most closely dominates all candidates 3423 1.1 mrg with this increment. If there is at least one candidate in 3424 1.1 mrg that block, the earliest one will be returned in WHERE. */ 3425 1.1 mrg bb = nearest_common_dominator_for_cands (c, incr, &where); 3426 1.1 mrg 3427 1.1 mrg /* If the NCD is not dominated by the block containing the 3428 1.1 mrg definition of the stride, we can't legally insert a 3429 1.1 mrg single initializer. Mark the increment as unprofitable 3430 1.1 mrg so we don't make any replacements. FIXME: Multiple 3431 1.1 mrg initializers could be placed with more analysis. */ 3432 1.1 mrg gimple *stride_def = SSA_NAME_DEF_STMT (c->stride); 3433 1.1 mrg basic_block stride_bb = gimple_bb (stride_def); 3434 1.1 mrg 3435 1.1 mrg if (stride_bb && !dominated_by_p (CDI_DOMINATORS, bb, stride_bb)) 3436 1.1 mrg { 3437 1.1 mrg if (dump_file && (dump_flags & TDF_DETAILS)) 3438 1.1 mrg fprintf (dump_file, 3439 1.1 mrg "Initializer #%d cannot be legally placed\n", i); 3440 1.1 mrg incr_vec[i].cost = COST_INFINITE; 3441 1.1 mrg continue; 3442 1.1 mrg } 3443 1.1 mrg 3444 1.1 mrg /* If the nominal stride has a different type than the recorded 3445 1.1 mrg stride type, build a cast from the nominal stride to that type. */ 3446 1.1 mrg if (!types_compatible_p (TREE_TYPE (c->stride), c->stride_type)) 3447 1.1 mrg { 3448 1.1 mrg init_stride = make_temp_ssa_name (c->stride_type, NULL, "slsr"); 3449 1.1 mrg cast_stmt = gimple_build_assign (init_stride, NOP_EXPR, c->stride); 3450 1.1 mrg } 3451 1.1 mrg else 3452 1.1 mrg init_stride = c->stride; 3453 1.1 mrg 3454 1.1 mrg /* Create a new SSA name to hold the initializer's value. */ 3455 1.1 mrg new_name = make_temp_ssa_name (c->stride_type, NULL, "slsr"); 3456 1.1 mrg incr_vec[i].initializer = new_name; 3457 1.1 mrg 3458 1.1 mrg /* Create the initializer and insert it in the latest possible 3459 1.1 mrg dominating position. */ 3460 1.1 mrg incr_tree = wide_int_to_tree (c->stride_type, incr); 3461 1.1 mrg init_stmt = gimple_build_assign (new_name, MULT_EXPR, 3462 1.1 mrg init_stride, incr_tree); 3463 1.1 mrg if (where) 3464 1.1 mrg { 3465 1.1 mrg gimple_stmt_iterator gsi = gsi_for_stmt (where->cand_stmt); 3466 1.1 mrg location_t loc = gimple_location (where->cand_stmt); 3467 1.1 mrg 3468 1.1 mrg if (cast_stmt) 3469 1.1 mrg { 3470 1.1 mrg gsi_insert_before (&gsi, cast_stmt, GSI_SAME_STMT); 3471 1.1 mrg gimple_set_location (cast_stmt, loc); 3472 1.1 mrg } 3473 1.1 mrg 3474 1.1 mrg gsi_insert_before (&gsi, init_stmt, GSI_SAME_STMT); 3475 1.1 mrg gimple_set_location (init_stmt, loc); 3476 1.1 mrg } 3477 1.1 mrg else 3478 1.1 mrg { 3479 1.1 mrg gimple_stmt_iterator gsi = gsi_last_bb (bb); 3480 1.1 mrg gimple *basis_stmt = lookup_cand (c->basis)->cand_stmt; 3481 1.1 mrg location_t loc = gimple_location (basis_stmt); 3482 1.1 mrg 3483 1.1 mrg if (!gsi_end_p (gsi) && stmt_ends_bb_p (gsi_stmt (gsi))) 3484 1.1 mrg { 3485 1.1 mrg if (cast_stmt) 3486 1.1 mrg { 3487 1.1 mrg gsi_insert_before (&gsi, cast_stmt, GSI_SAME_STMT); 3488 1.1 mrg gimple_set_location (cast_stmt, loc); 3489 1.1 mrg } 3490 1.1 mrg gsi_insert_before (&gsi, init_stmt, GSI_SAME_STMT); 3491 1.1 mrg } 3492 1.1 mrg else 3493 1.1 mrg { 3494 1.1 mrg if (cast_stmt) 3495 1.1 mrg { 3496 1.1 mrg gsi_insert_after (&gsi, cast_stmt, GSI_NEW_STMT); 3497 1.1 mrg gimple_set_location (cast_stmt, loc); 3498 1.1 mrg } 3499 1.1 mrg gsi_insert_after (&gsi, init_stmt, GSI_NEW_STMT); 3500 1.1 mrg } 3501 1.1 mrg 3502 1.1 mrg gimple_set_location (init_stmt, gimple_location (basis_stmt)); 3503 1.1 mrg } 3504 1.1 mrg 3505 1.1 mrg if (dump_file && (dump_flags & TDF_DETAILS)) 3506 1.1 mrg { 3507 1.1 mrg if (cast_stmt) 3508 1.1 mrg { 3509 1.1 mrg fputs ("Inserting stride cast: ", dump_file); 3510 1.1 mrg print_gimple_stmt (dump_file, cast_stmt, 0); 3511 1.1 mrg } 3512 1.1 mrg fputs ("Inserting initializer: ", dump_file); 3513 1.1 mrg print_gimple_stmt (dump_file, init_stmt, 0); 3514 1.1 mrg } 3515 1.1 mrg } 3516 1.1 mrg } 3517 1.1 mrg 3518 1.1 mrg /* Recursive helper function for all_phi_incrs_profitable. */ 3519 1.1 mrg 3520 1.1 mrg static bool 3521 1.1 mrg all_phi_incrs_profitable_1 (slsr_cand_t c, gphi *phi, int *spread) 3522 1.1 mrg { 3523 1.1 mrg unsigned i; 3524 1.1 mrg slsr_cand_t basis = lookup_cand (c->basis); 3525 1.1 mrg slsr_cand_t phi_cand = *stmt_cand_map->get (phi); 3526 1.1 mrg 3527 1.1 mrg if (phi_cand->visited) 3528 1.1 mrg return true; 3529 1.1 mrg 3530 1.1 mrg phi_cand->visited = 1; 3531 1.1 mrg (*spread)++; 3532 1.1 mrg 3533 1.1 mrg /* If the basis doesn't dominate the PHI (including when the PHI is 3534 1.1 mrg in the same block as the basis), we won't be able to create a PHI 3535 1.1 mrg using the basis here. */ 3536 1.1 mrg basic_block basis_bb = gimple_bb (basis->cand_stmt); 3537 1.1 mrg basic_block phi_bb = gimple_bb (phi); 3538 1.1 mrg 3539 1.1 mrg if (phi_bb == basis_bb 3540 1.1 mrg || !dominated_by_p (CDI_DOMINATORS, phi_bb, basis_bb)) 3541 1.1 mrg return false; 3542 1.1 mrg 3543 1.1 mrg for (i = 0; i < gimple_phi_num_args (phi); i++) 3544 1.1 mrg { 3545 1.1 mrg /* If the PHI arg resides in a block not dominated by the basis, 3546 1.1 mrg we won't be able to create a PHI using the basis here. */ 3547 1.1 mrg basic_block pred_bb = gimple_phi_arg_edge (phi, i)->src; 3548 1.1 mrg 3549 1.1 mrg if (!dominated_by_p (CDI_DOMINATORS, pred_bb, basis_bb)) 3550 1.1 mrg return false; 3551 1.1 mrg 3552 1.1 mrg tree arg = gimple_phi_arg_def (phi, i); 3553 1.1 mrg gimple *arg_def = SSA_NAME_DEF_STMT (arg); 3554 1.1 mrg 3555 1.1 mrg if (gimple_code (arg_def) == GIMPLE_PHI) 3556 1.1 mrg { 3557 1.1 mrg if (!all_phi_incrs_profitable_1 (c, as_a <gphi *> (arg_def), spread) 3558 1.1 mrg || *spread > MAX_SPREAD) 3559 1.1 mrg return false; 3560 1.1 mrg } 3561 1.1 mrg else 3562 1.1 mrg { 3563 1.1 mrg int j; 3564 1.1 mrg widest_int increment; 3565 1.1 mrg 3566 1.1 mrg if (operand_equal_p (arg, phi_cand->base_expr, 0)) 3567 1.1 mrg increment = -basis->index; 3568 1.1 mrg else 3569 1.1 mrg { 3570 1.1 mrg slsr_cand_t arg_cand = base_cand_from_table (arg); 3571 1.1 mrg increment = arg_cand->index - basis->index; 3572 1.1 mrg } 3573 1.1 mrg 3574 1.1 mrg if (!address_arithmetic_p && wi::neg_p (increment)) 3575 1.1 mrg increment = -increment; 3576 1.1 mrg 3577 1.1 mrg j = incr_vec_index (increment); 3578 1.1 mrg 3579 1.1 mrg if (dump_file && (dump_flags & TDF_DETAILS)) 3580 1.1 mrg { 3581 1.1 mrg fprintf (dump_file, " Conditional candidate %d, phi: ", 3582 1.1 mrg c->cand_num); 3583 1.1 mrg print_gimple_stmt (dump_file, phi, 0); 3584 1.1 mrg fputs (" increment: ", dump_file); 3585 1.1 mrg print_decs (increment, dump_file); 3586 1.1 mrg if (j < 0) 3587 1.1 mrg fprintf (dump_file, 3588 1.1 mrg "\n Not replaced; incr_vec overflow.\n"); 3589 1.1 mrg else { 3590 1.1 mrg fprintf (dump_file, "\n cost: %d\n", incr_vec[j].cost); 3591 1.1 mrg if (profitable_increment_p (j)) 3592 1.1 mrg fputs (" Replacing...\n", dump_file); 3593 1.1 mrg else 3594 1.1 mrg fputs (" Not replaced.\n", dump_file); 3595 1.1 mrg } 3596 1.1 mrg } 3597 1.1 mrg 3598 1.1 mrg if (j < 0 || !profitable_increment_p (j)) 3599 1.1 mrg return false; 3600 1.1 mrg } 3601 1.1 mrg } 3602 1.1 mrg 3603 1.1 mrg return true; 3604 1.1 mrg } 3605 1.1 mrg 3606 1.1 mrg /* Return TRUE iff all required increments for candidates feeding PHI 3607 1.1 mrg are profitable (and legal!) to replace on behalf of candidate C. */ 3608 1.1 mrg 3609 1.1 mrg static bool 3610 1.1 mrg all_phi_incrs_profitable (slsr_cand_t c, gphi *phi) 3611 1.1 mrg { 3612 1.1 mrg int spread = 0; 3613 1.1 mrg bool retval = all_phi_incrs_profitable_1 (c, phi, &spread); 3614 1.1 mrg clear_visited (phi); 3615 1.1 mrg return retval; 3616 1.1 mrg } 3617 1.1 mrg 3618 1.1 mrg /* Create a NOP_EXPR that copies FROM_EXPR into a new SSA name of 3619 1.1 mrg type TO_TYPE, and insert it in front of the statement represented 3620 1.1 mrg by candidate C. Use *NEW_VAR to create the new SSA name. Return 3621 1.1 mrg the new SSA name. */ 3622 1.1 mrg 3623 1.1 mrg static tree 3624 1.1 mrg introduce_cast_before_cand (slsr_cand_t c, tree to_type, tree from_expr) 3625 1.1 mrg { 3626 1.1 mrg tree cast_lhs; 3627 1.1 mrg gassign *cast_stmt; 3628 1.1 mrg gimple_stmt_iterator gsi = gsi_for_stmt (c->cand_stmt); 3629 1.1 mrg 3630 1.1 mrg cast_lhs = make_temp_ssa_name (to_type, NULL, "slsr"); 3631 1.1 mrg cast_stmt = gimple_build_assign (cast_lhs, NOP_EXPR, from_expr); 3632 1.1 mrg gimple_set_location (cast_stmt, gimple_location (c->cand_stmt)); 3633 1.1 mrg gsi_insert_before (&gsi, cast_stmt, GSI_SAME_STMT); 3634 1.1 mrg 3635 1.1 mrg if (dump_file && (dump_flags & TDF_DETAILS)) 3636 1.1 mrg { 3637 1.1 mrg fputs (" Inserting: ", dump_file); 3638 1.1 mrg print_gimple_stmt (dump_file, cast_stmt, 0); 3639 1.1 mrg } 3640 1.1 mrg 3641 1.1 mrg return cast_lhs; 3642 1.1 mrg } 3643 1.1 mrg 3644 1.1 mrg /* Replace the RHS of the statement represented by candidate C with 3645 1.1 mrg NEW_CODE, NEW_RHS1, and NEW_RHS2, provided that to do so doesn't 3646 1.1 mrg leave C unchanged or just interchange its operands. The original 3647 1.1 mrg operation and operands are in OLD_CODE, OLD_RHS1, and OLD_RHS2. 3648 1.1 mrg If the replacement was made and we are doing a details dump, 3649 1.1 mrg return the revised statement, else NULL. */ 3650 1.1 mrg 3651 1.1 mrg static gimple * 3652 1.1 mrg replace_rhs_if_not_dup (enum tree_code new_code, tree new_rhs1, tree new_rhs2, 3653 1.1 mrg enum tree_code old_code, tree old_rhs1, tree old_rhs2, 3654 1.1 mrg slsr_cand_t c) 3655 1.1 mrg { 3656 1.1 mrg if (new_code != old_code 3657 1.1 mrg || ((!operand_equal_p (new_rhs1, old_rhs1, 0) 3658 1.1 mrg || !operand_equal_p (new_rhs2, old_rhs2, 0)) 3659 1.1 mrg && (!operand_equal_p (new_rhs1, old_rhs2, 0) 3660 1.1 mrg || !operand_equal_p (new_rhs2, old_rhs1, 0)))) 3661 1.1 mrg { 3662 1.1 mrg gimple_stmt_iterator gsi = gsi_for_stmt (c->cand_stmt); 3663 1.1 mrg slsr_cand_t cc = lookup_cand (c->first_interp); 3664 1.1 mrg gimple_assign_set_rhs_with_ops (&gsi, new_code, new_rhs1, new_rhs2); 3665 1.1 mrg update_stmt (gsi_stmt (gsi)); 3666 1.1 mrg while (cc) 3667 1.1 mrg { 3668 1.1 mrg cc->cand_stmt = gsi_stmt (gsi); 3669 1.1 mrg cc = lookup_cand (cc->next_interp); 3670 1.1 mrg } 3671 1.1 mrg 3672 1.1 mrg if (dump_file && (dump_flags & TDF_DETAILS)) 3673 1.1 mrg return gsi_stmt (gsi); 3674 1.1 mrg } 3675 1.1 mrg 3676 1.1 mrg else if (dump_file && (dump_flags & TDF_DETAILS)) 3677 1.1 mrg fputs (" (duplicate, not actually replacing)\n", dump_file); 3678 1.1 mrg 3679 1.1 mrg return NULL; 3680 1.1 mrg } 3681 1.1 mrg 3682 1.1 mrg /* Strength-reduce the statement represented by candidate C by replacing 3683 1.1 mrg it with an equivalent addition or subtraction. I is the index into 3684 1.1 mrg the increment vector identifying C's increment. NEW_VAR is used to 3685 1.1 mrg create a new SSA name if a cast needs to be introduced. BASIS_NAME 3686 1.1 mrg is the rhs1 to use in creating the add/subtract. */ 3687 1.1 mrg 3688 1.1 mrg static void 3689 1.1 mrg replace_one_candidate (slsr_cand_t c, unsigned i, tree basis_name) 3690 1.1 mrg { 3691 1.1 mrg gimple *stmt_to_print = NULL; 3692 1.1 mrg tree orig_rhs1, orig_rhs2; 3693 1.1 mrg tree rhs2; 3694 1.1 mrg enum tree_code orig_code, repl_code; 3695 1.1 mrg widest_int cand_incr; 3696 1.1 mrg 3697 1.1 mrg orig_code = gimple_assign_rhs_code (c->cand_stmt); 3698 1.1 mrg orig_rhs1 = gimple_assign_rhs1 (c->cand_stmt); 3699 1.1 mrg orig_rhs2 = gimple_assign_rhs2 (c->cand_stmt); 3700 1.1 mrg cand_incr = cand_increment (c); 3701 1.1 mrg 3702 1.1 mrg /* If orig_rhs2 is NULL, we have already replaced this in situ with 3703 1.1 mrg a copy statement under another interpretation. */ 3704 1.1 mrg if (!orig_rhs2) 3705 1.1 mrg return; 3706 1.1 mrg 3707 1.1 mrg if (dump_file && (dump_flags & TDF_DETAILS)) 3708 1.1 mrg { 3709 1.1 mrg fputs ("Replacing: ", dump_file); 3710 1.1 mrg print_gimple_stmt (dump_file, c->cand_stmt, 0); 3711 1.1 mrg stmt_to_print = c->cand_stmt; 3712 1.1 mrg } 3713 1.1 mrg 3714 1.1 mrg if (address_arithmetic_p) 3715 1.1 mrg repl_code = POINTER_PLUS_EXPR; 3716 1.1 mrg else 3717 1.1 mrg repl_code = PLUS_EXPR; 3718 1.1 mrg 3719 1.1 mrg /* If the increment has an initializer T_0, replace the candidate 3720 1.1 mrg statement with an add of the basis name and the initializer. */ 3721 1.1 mrg if (incr_vec[i].initializer) 3722 1.1 mrg { 3723 1.1 mrg tree init_type = TREE_TYPE (incr_vec[i].initializer); 3724 1.1 mrg tree orig_type = TREE_TYPE (orig_rhs2); 3725 1.1 mrg 3726 1.1 mrg if (types_compatible_p (orig_type, init_type)) 3727 1.1 mrg rhs2 = incr_vec[i].initializer; 3728 1.1 mrg else 3729 1.1 mrg rhs2 = introduce_cast_before_cand (c, orig_type, 3730 1.1 mrg incr_vec[i].initializer); 3731 1.1 mrg 3732 1.1 mrg if (incr_vec[i].incr != cand_incr) 3733 1.1 mrg { 3734 1.1 mrg gcc_assert (repl_code == PLUS_EXPR); 3735 1.1 mrg repl_code = MINUS_EXPR; 3736 1.1 mrg } 3737 1.1 mrg 3738 1.1 mrg stmt_to_print = replace_rhs_if_not_dup (repl_code, basis_name, rhs2, 3739 1.1 mrg orig_code, orig_rhs1, orig_rhs2, 3740 1.1 mrg c); 3741 1.1 mrg } 3742 1.1 mrg 3743 1.1 mrg /* Otherwise, the increment is one of -1, 0, and 1. Replace 3744 1.1 mrg with a subtract of the stride from the basis name, a copy 3745 1.1 mrg from the basis name, or an add of the stride to the basis 3746 1.1 mrg name, respectively. It may be necessary to introduce a 3747 1.1 mrg cast (or reuse an existing cast). */ 3748 1.1 mrg else if (cand_incr == 1) 3749 1.1 mrg { 3750 1.1 mrg tree stride_type = TREE_TYPE (c->stride); 3751 1.1 mrg tree orig_type = TREE_TYPE (orig_rhs2); 3752 1.1 mrg 3753 1.1 mrg if (types_compatible_p (orig_type, stride_type)) 3754 1.1 mrg rhs2 = c->stride; 3755 1.1 mrg else 3756 1.1 mrg rhs2 = introduce_cast_before_cand (c, orig_type, c->stride); 3757 1.1 mrg 3758 1.1 mrg stmt_to_print = replace_rhs_if_not_dup (repl_code, basis_name, rhs2, 3759 1.1 mrg orig_code, orig_rhs1, orig_rhs2, 3760 1.1 mrg c); 3761 1.1 mrg } 3762 1.1 mrg 3763 1.1 mrg else if (cand_incr == -1) 3764 1.1 mrg { 3765 1.1 mrg tree stride_type = TREE_TYPE (c->stride); 3766 1.1 mrg tree orig_type = TREE_TYPE (orig_rhs2); 3767 1.1 mrg gcc_assert (repl_code != POINTER_PLUS_EXPR); 3768 1.1 mrg 3769 1.1 mrg if (types_compatible_p (orig_type, stride_type)) 3770 1.1 mrg rhs2 = c->stride; 3771 1.1 mrg else 3772 1.1 mrg rhs2 = introduce_cast_before_cand (c, orig_type, c->stride); 3773 1.1 mrg 3774 1.1 mrg if (orig_code != MINUS_EXPR 3775 1.1 mrg || !operand_equal_p (basis_name, orig_rhs1, 0) 3776 1.1 mrg || !operand_equal_p (rhs2, orig_rhs2, 0)) 3777 1.1 mrg { 3778 1.1 mrg gimple_stmt_iterator gsi = gsi_for_stmt (c->cand_stmt); 3779 1.1 mrg slsr_cand_t cc = lookup_cand (c->first_interp); 3780 1.1 mrg gimple_assign_set_rhs_with_ops (&gsi, MINUS_EXPR, basis_name, rhs2); 3781 1.1 mrg update_stmt (gsi_stmt (gsi)); 3782 1.1 mrg while (cc) 3783 1.1 mrg { 3784 1.1 mrg cc->cand_stmt = gsi_stmt (gsi); 3785 1.1 mrg cc = lookup_cand (cc->next_interp); 3786 1.1 mrg } 3787 1.1 mrg 3788 1.1 mrg if (dump_file && (dump_flags & TDF_DETAILS)) 3789 1.1 mrg stmt_to_print = gsi_stmt (gsi); 3790 1.1 mrg } 3791 1.1 mrg else if (dump_file && (dump_flags & TDF_DETAILS)) 3792 1.1 mrg fputs (" (duplicate, not actually replacing)\n", dump_file); 3793 1.1 mrg } 3794 1.1 mrg 3795 1.1 mrg else if (cand_incr == 0) 3796 1.1 mrg { 3797 1.1 mrg tree lhs = gimple_assign_lhs (c->cand_stmt); 3798 1.1 mrg tree lhs_type = TREE_TYPE (lhs); 3799 1.1 mrg tree basis_type = TREE_TYPE (basis_name); 3800 1.1 mrg 3801 1.1 mrg if (types_compatible_p (lhs_type, basis_type)) 3802 1.1 mrg { 3803 1.1 mrg gassign *copy_stmt = gimple_build_assign (lhs, basis_name); 3804 1.1 mrg gimple_stmt_iterator gsi = gsi_for_stmt (c->cand_stmt); 3805 1.1 mrg slsr_cand_t cc = lookup_cand (c->first_interp); 3806 1.1 mrg gimple_set_location (copy_stmt, gimple_location (c->cand_stmt)); 3807 1.1 mrg gsi_replace (&gsi, copy_stmt, false); 3808 1.1 mrg while (cc) 3809 1.1 mrg { 3810 1.1 mrg cc->cand_stmt = copy_stmt; 3811 1.1 mrg cc = lookup_cand (cc->next_interp); 3812 1.1 mrg } 3813 1.1 mrg 3814 1.1 mrg if (dump_file && (dump_flags & TDF_DETAILS)) 3815 1.1 mrg stmt_to_print = copy_stmt; 3816 1.1 mrg } 3817 1.1 mrg else 3818 1.1 mrg { 3819 1.1 mrg gimple_stmt_iterator gsi = gsi_for_stmt (c->cand_stmt); 3820 1.1 mrg gassign *cast_stmt = gimple_build_assign (lhs, NOP_EXPR, basis_name); 3821 1.1 mrg slsr_cand_t cc = lookup_cand (c->first_interp); 3822 1.1 mrg gimple_set_location (cast_stmt, gimple_location (c->cand_stmt)); 3823 1.1 mrg gsi_replace (&gsi, cast_stmt, false); 3824 1.1 mrg while (cc) 3825 1.1 mrg { 3826 1.1 mrg cc->cand_stmt = cast_stmt; 3827 1.1 mrg cc = lookup_cand (cc->next_interp); 3828 1.1 mrg } 3829 1.1 mrg 3830 1.1 mrg if (dump_file && (dump_flags & TDF_DETAILS)) 3831 1.1 mrg stmt_to_print = cast_stmt; 3832 1.1 mrg } 3833 1.1 mrg } 3834 1.1 mrg else 3835 1.1 mrg gcc_unreachable (); 3836 1.1 mrg 3837 1.1 mrg if (dump_file && (dump_flags & TDF_DETAILS) && stmt_to_print) 3838 1.1 mrg { 3839 1.1 mrg fputs ("With: ", dump_file); 3840 1.1 mrg print_gimple_stmt (dump_file, stmt_to_print, 0); 3841 1.1 mrg fputs ("\n", dump_file); 3842 1.1 mrg } 3843 1.1 mrg } 3844 1.1 mrg 3845 1.1 mrg /* For each candidate in the tree rooted at C, replace it with 3846 1.1 mrg an increment if such has been shown to be profitable. */ 3847 1.1 mrg 3848 1.1 mrg static void 3849 1.1 mrg replace_profitable_candidates (slsr_cand_t c) 3850 1.1 mrg { 3851 1.1 mrg if (!cand_already_replaced (c)) 3852 1.1 mrg { 3853 1.1 mrg widest_int increment = cand_abs_increment (c); 3854 1.1 mrg enum tree_code orig_code = gimple_assign_rhs_code (c->cand_stmt); 3855 1.1 mrg int i; 3856 1.1 mrg 3857 1.1 mrg i = incr_vec_index (increment); 3858 1.1 mrg 3859 1.1 mrg /* Only process profitable increments. Nothing useful can be done 3860 1.1 mrg to a cast or copy. */ 3861 1.1 mrg if (i >= 0 3862 1.1 mrg && profitable_increment_p (i) 3863 1.1 mrg && orig_code != SSA_NAME 3864 1.1 mrg && !CONVERT_EXPR_CODE_P (orig_code)) 3865 1.1 mrg { 3866 1.1 mrg if (phi_dependent_cand_p (c)) 3867 1.1 mrg { 3868 1.1 mrg gphi *phi = as_a <gphi *> (lookup_cand (c->def_phi)->cand_stmt); 3869 1.1 mrg 3870 1.1 mrg if (all_phi_incrs_profitable (c, phi)) 3871 1.1 mrg { 3872 1.1 mrg /* Look up the LHS SSA name from C's basis. This will be 3873 1.1 mrg the RHS1 of the adds we will introduce to create new 3874 1.1 mrg phi arguments. */ 3875 1.1 mrg slsr_cand_t basis = lookup_cand (c->basis); 3876 1.1 mrg tree basis_name = gimple_assign_lhs (basis->cand_stmt); 3877 1.1 mrg 3878 1.1 mrg /* Create a new phi statement that will represent C's true 3879 1.1 mrg basis after the transformation is complete. */ 3880 1.1 mrg location_t loc = gimple_location (c->cand_stmt); 3881 1.1 mrg tree name = create_phi_basis (c, phi, basis_name, 3882 1.1 mrg loc, UNKNOWN_STRIDE); 3883 1.1 mrg 3884 1.1 mrg /* Replace C with an add of the new basis phi and the 3885 1.1 mrg increment. */ 3886 1.1 mrg replace_one_candidate (c, i, name); 3887 1.1 mrg } 3888 1.1 mrg } 3889 1.1 mrg else 3890 1.1 mrg { 3891 1.1 mrg slsr_cand_t basis = lookup_cand (c->basis); 3892 1.1 mrg tree basis_name = gimple_assign_lhs (basis->cand_stmt); 3893 1.1 mrg replace_one_candidate (c, i, basis_name); 3894 1.1 mrg } 3895 1.1 mrg } 3896 1.1 mrg } 3897 1.1 mrg 3898 1.1 mrg if (c->sibling) 3899 1.1 mrg replace_profitable_candidates (lookup_cand (c->sibling)); 3900 1.1 mrg 3901 1.1 mrg if (c->dependent) 3902 1.1 mrg replace_profitable_candidates (lookup_cand (c->dependent)); 3903 1.1 mrg } 3904 1.1 mrg 3905 1.1 mrg /* Analyze costs of related candidates in the candidate vector, 3907 1.1 mrg and make beneficial replacements. */ 3908 1.1 mrg 3909 1.1 mrg static void 3910 1.1 mrg analyze_candidates_and_replace (void) 3911 1.1 mrg { 3912 1.1 mrg unsigned i; 3913 1.1 mrg slsr_cand_t c; 3914 1.1 mrg 3915 1.1 mrg /* Each candidate that has a null basis and a non-null 3916 1.1 mrg dependent is the root of a tree of related statements. 3917 1.1 mrg Analyze each tree to determine a subset of those 3918 1.1 mrg statements that can be replaced with maximum benefit. 3919 1.1 mrg 3920 1.1 mrg Note the first NULL element is skipped. */ 3921 1.1 mrg FOR_EACH_VEC_ELT_FROM (cand_vec, i, c, 1) 3922 1.1 mrg { 3923 1.1 mrg slsr_cand_t first_dep; 3924 1.1 mrg 3925 1.1 mrg if (c->basis != 0 || c->dependent == 0) 3926 1.1 mrg continue; 3927 1.1 mrg 3928 1.1 mrg if (dump_file && (dump_flags & TDF_DETAILS)) 3929 1.1 mrg fprintf (dump_file, "\nProcessing dependency tree rooted at %d.\n", 3930 1.1 mrg c->cand_num); 3931 1.1 mrg 3932 1.1 mrg first_dep = lookup_cand (c->dependent); 3933 1.1 mrg 3934 1.1 mrg /* If this is a chain of CAND_REFs, unconditionally replace 3935 1.1 mrg each of them with a strength-reduced data reference. */ 3936 1.1 mrg if (c->kind == CAND_REF) 3937 1.1 mrg replace_refs (c); 3938 1.1 mrg 3939 1.1 mrg /* If the common stride of all related candidates is a known 3940 1.1 mrg constant, each candidate without a phi-dependence can be 3941 1.1 mrg profitably replaced. Each replaces a multiply by a single 3942 1.1 mrg add, with the possibility that a feeding add also goes dead. 3943 1.1 mrg A candidate with a phi-dependence is replaced only if the 3944 1.1 mrg compensation code it requires is offset by the strength 3945 1.1 mrg reduction savings. */ 3946 1.1 mrg else if (TREE_CODE (c->stride) == INTEGER_CST) 3947 1.1 mrg replace_uncond_cands_and_profitable_phis (first_dep); 3948 1.1 mrg 3949 1.1 mrg /* When the stride is an SSA name, it may still be profitable 3950 1.1 mrg to replace some or all of the dependent candidates, depending 3951 1.1 mrg on whether the introduced increments can be reused, or are 3952 1.1 mrg less expensive to calculate than the replaced statements. */ 3953 1.1 mrg else 3954 1.1 mrg { 3955 1.1 mrg machine_mode mode; 3956 1.1 mrg bool speed; 3957 1.1 mrg 3958 1.1 mrg /* Determine whether we'll be generating pointer arithmetic 3959 1.1 mrg when replacing candidates. */ 3960 1.1 mrg address_arithmetic_p = (c->kind == CAND_ADD 3961 1.1 mrg && POINTER_TYPE_P (c->cand_type)); 3962 1.1 mrg 3963 1.1 mrg /* If all candidates have already been replaced under other 3964 1.1 mrg interpretations, nothing remains to be done. */ 3965 1.1 mrg if (!count_candidates (c)) 3966 1.1 mrg continue; 3967 1.1 mrg 3968 1.1 mrg /* Construct an array of increments for this candidate chain. */ 3969 1.1 mrg incr_vec = XNEWVEC (incr_info, MAX_INCR_VEC_LEN); 3970 1.1 mrg incr_vec_len = 0; 3971 1.1 mrg record_increments (c); 3972 1.1 mrg 3973 1.1 mrg /* Determine which increments are profitable to replace. */ 3974 1.1 mrg mode = TYPE_MODE (TREE_TYPE (gimple_assign_lhs (c->cand_stmt))); 3975 1.1 mrg speed = optimize_cands_for_speed_p (c); 3976 1.1 mrg analyze_increments (first_dep, mode, speed); 3977 1.1 mrg 3978 1.1 mrg /* Insert initializers of the form T_0 = stride * increment 3979 1.1 mrg for use in profitable replacements. */ 3980 1.1 mrg insert_initializers (first_dep); 3981 1.1 mrg dump_incr_vec (); 3982 1.1 mrg 3983 1.1 mrg /* Perform the replacements. */ 3984 1.1 mrg replace_profitable_candidates (first_dep); 3985 1.1 mrg free (incr_vec); 3986 1.1 mrg } 3987 1.1 mrg } 3988 1.1 mrg 3989 1.1 mrg /* For conditional candidates, we may have uncommitted insertions 3990 1.1 mrg on edges to clean up. */ 3991 1.1 mrg gsi_commit_edge_inserts (); 3992 1.1 mrg } 3993 1.1 mrg 3994 1.1 mrg namespace { 3995 1.1 mrg 3996 1.1 mrg const pass_data pass_data_strength_reduction = 3997 1.1 mrg { 3998 1.1 mrg GIMPLE_PASS, /* type */ 3999 1.1 mrg "slsr", /* name */ 4000 1.1 mrg OPTGROUP_NONE, /* optinfo_flags */ 4001 1.1 mrg TV_GIMPLE_SLSR, /* tv_id */ 4002 1.1 mrg ( PROP_cfg | PROP_ssa ), /* properties_required */ 4003 1.1 mrg 0, /* properties_provided */ 4004 1.1 mrg 0, /* properties_destroyed */ 4005 1.1 mrg 0, /* todo_flags_start */ 4006 1.1 mrg 0, /* todo_flags_finish */ 4007 1.1 mrg }; 4008 1.1 mrg 4009 1.1 mrg class pass_strength_reduction : public gimple_opt_pass 4010 1.1 mrg { 4011 1.1 mrg public: 4012 1.1 mrg pass_strength_reduction (gcc::context *ctxt) 4013 1.1 mrg : gimple_opt_pass (pass_data_strength_reduction, ctxt) 4014 1.1 mrg {} 4015 1.1 mrg 4016 1.1 mrg /* opt_pass methods: */ 4017 1.1 mrg virtual bool gate (function *) { return flag_tree_slsr; } 4018 1.1 mrg virtual unsigned int execute (function *); 4019 1.1 mrg 4020 1.1 mrg }; // class pass_strength_reduction 4021 1.1 mrg 4022 1.1 mrg unsigned 4023 1.1 mrg pass_strength_reduction::execute (function *fun) 4024 1.1 mrg { 4025 1.1 mrg /* Create the obstack where candidates will reside. */ 4026 1.1 mrg gcc_obstack_init (&cand_obstack); 4027 1.1 mrg 4028 1.1 mrg /* Allocate the candidate vector and initialize the first NULL element. */ 4029 1.1 mrg cand_vec.create (128); 4030 1.1 mrg cand_vec.safe_push (NULL); 4031 1.1 mrg 4032 1.1 mrg /* Allocate the mapping from statements to candidate indices. */ 4033 1.1 mrg stmt_cand_map = new hash_map<gimple *, slsr_cand_t>; 4034 1.1 mrg 4035 1.1 mrg /* Create the obstack where candidate chains will reside. */ 4036 1.1 mrg gcc_obstack_init (&chain_obstack); 4037 1.1 mrg 4038 1.1 mrg /* Allocate the mapping from base expressions to candidate chains. */ 4039 1.1 mrg base_cand_map = new hash_table<cand_chain_hasher> (500); 4040 1.1 mrg 4041 1.1 mrg /* Allocate the mapping from bases to alternative bases. */ 4042 1.1 mrg alt_base_map = new hash_map<tree, tree>; 4043 1.1 mrg 4044 1.1 mrg /* Initialize the loop optimizer. We need to detect flow across 4045 1.1 mrg back edges, and this gives us dominator information as well. */ 4046 1.1 mrg loop_optimizer_init (AVOID_CFG_MODIFICATIONS); 4047 1.1 mrg 4048 1.1 mrg /* Walk the CFG in predominator order looking for strength reduction 4049 1.1 mrg candidates. */ 4050 1.1 mrg find_candidates_dom_walker (CDI_DOMINATORS) 4051 1.1 mrg .walk (fun->cfg->x_entry_block_ptr); 4052 1.1 mrg 4053 1.1 mrg if (dump_file && (dump_flags & TDF_DETAILS)) 4054 1.1 mrg { 4055 1.1 mrg dump_cand_vec (); 4056 1.1 mrg dump_cand_chains (); 4057 1.1 mrg } 4058 1.1 mrg 4059 1.1 mrg delete alt_base_map; 4060 1.1 mrg free_affine_expand_cache (&name_expansions); 4061 1.1 mrg 4062 1.1 mrg /* Analyze costs and make appropriate replacements. */ 4063 1.1 mrg analyze_candidates_and_replace (); 4064 1.1 mrg 4065 1.1 mrg loop_optimizer_finalize (); 4066 1.1 mrg delete base_cand_map; 4067 1.1 mrg base_cand_map = NULL; 4068 1.1 mrg obstack_free (&chain_obstack, NULL); 4069 1.1 mrg delete stmt_cand_map; 4070 1.1 mrg cand_vec.release (); 4071 1.1 mrg obstack_free (&cand_obstack, NULL); 4072 1.1 mrg 4073 return 0; 4074 } 4075 4076 } // anon namespace 4077 4078 gimple_opt_pass * 4079 make_pass_strength_reduction (gcc::context *ctxt) 4080 { 4081 return new pass_strength_reduction (ctxt); 4082 } 4083