2013-10-11 Marc Glisse <marc.glisse@inria.fr>
[official-gcc.git] / gcc / gimple-ssa-strength-reduction.c
bloba558f349c410a7ba86f702dfc3ee9bdff91b0703
1 /* Straight-line strength reduction.
2 Copyright (C) 2012-2013 Free Software Foundation, Inc.
3 Contributed by Bill Schmidt, IBM <wschmidt@linux.ibm.com>
5 This file is part of GCC.
7 GCC is free software; you can redistribute it and/or modify it under
8 the terms of the GNU General Public License as published by the Free
9 Software Foundation; either version 3, or (at your option) any later
10 version.
12 GCC is distributed in the hope that it will be useful, but WITHOUT ANY
13 WARRANTY; without even the implied warranty of MERCHANTABILITY or
14 FITNESS FOR A PARTICULAR PURPOSE. See the GNU General Public License
15 for more details.
17 You should have received a copy of the GNU General Public License
18 along with GCC; see the file COPYING3. If not see
19 <http://www.gnu.org/licenses/>. */
21 /* There are many algorithms for performing strength reduction on
22 loops. This is not one of them. IVOPTS handles strength reduction
23 of induction variables just fine. This pass is intended to pick
24 up the crumbs it leaves behind, by considering opportunities for
25 strength reduction along dominator paths.
27 Strength reduction addresses explicit multiplies, and certain
28 multiplies implicit in addressing expressions. It would also be
29 possible to apply strength reduction to divisions and modulos,
30 but such opportunities are relatively uncommon.
32 Strength reduction is also currently restricted to integer operations.
33 If desired, it could be extended to floating-point operations under
34 control of something like -funsafe-math-optimizations. */
36 #include "config.h"
37 #include "system.h"
38 #include "coretypes.h"
39 #include "tree.h"
40 #include "gimple.h"
41 #include "basic-block.h"
42 #include "tree-pass.h"
43 #include "cfgloop.h"
44 #include "gimple-pretty-print.h"
45 #include "tree-ssa.h"
46 #include "domwalk.h"
47 #include "pointer-set.h"
48 #include "expmed.h"
49 #include "params.h"
50 #include "hash-table.h"
52 /* Information about a strength reduction candidate. Each statement
53 in the candidate table represents an expression of one of the
54 following forms (the special case of CAND_REF will be described
55 later):
57 (CAND_MULT) S1: X = (B + i) * S
58 (CAND_ADD) S1: X = B + (i * S)
60 Here X and B are SSA names, i is an integer constant, and S is
61 either an SSA name or a constant. We call B the "base," i the
62 "index", and S the "stride."
64 Any statement S0 that dominates S1 and is of the form:
66 (CAND_MULT) S0: Y = (B + i') * S
67 (CAND_ADD) S0: Y = B + (i' * S)
69 is called a "basis" for S1. In both cases, S1 may be replaced by
71 S1': X = Y + (i - i') * S,
73 where (i - i') * S is folded to the extent possible.
75 All gimple statements are visited in dominator order, and each
76 statement that may contribute to one of the forms of S1 above is
77 given at least one entry in the candidate table. Such statements
78 include addition, pointer addition, subtraction, multiplication,
79 negation, copies, and nontrivial type casts. If a statement may
80 represent more than one expression of the forms of S1 above,
81 multiple "interpretations" are stored in the table and chained
82 together. Examples:
84 * An add of two SSA names may treat either operand as the base.
85 * A multiply of two SSA names, likewise.
86 * A copy or cast may be thought of as either a CAND_MULT with
87 i = 0 and S = 1, or as a CAND_ADD with i = 0 or S = 0.
89 Candidate records are allocated from an obstack. They are addressed
90 both from a hash table keyed on S1, and from a vector of candidate
91 pointers arranged in predominator order.
93 Opportunity note
94 ----------------
95 Currently we don't recognize:
97 S0: Y = (S * i') - B
98 S1: X = (S * i) - B
100 as a strength reduction opportunity, even though this S1 would
101 also be replaceable by the S1' above. This can be added if it
102 comes up in practice.
104 Strength reduction in addressing
105 --------------------------------
106 There is another kind of candidate known as CAND_REF. A CAND_REF
107 describes a statement containing a memory reference having
108 complex addressing that might benefit from strength reduction.
109 Specifically, we are interested in references for which
110 get_inner_reference returns a base address, offset, and bitpos as
111 follows:
113 base: MEM_REF (T1, C1)
114 offset: MULT_EXPR (PLUS_EXPR (T2, C2), C3)
115 bitpos: C4 * BITS_PER_UNIT
117 Here T1 and T2 are arbitrary trees, and C1, C2, C3, C4 are
118 arbitrary integer constants. Note that C2 may be zero, in which
119 case the offset will be MULT_EXPR (T2, C3).
121 When this pattern is recognized, the original memory reference
122 can be replaced with:
124 MEM_REF (POINTER_PLUS_EXPR (T1, MULT_EXPR (T2, C3)),
125 C1 + (C2 * C3) + C4)
127 which distributes the multiply to allow constant folding. When
128 two or more addressing expressions can be represented by MEM_REFs
129 of this form, differing only in the constants C1, C2, and C4,
130 making this substitution produces more efficient addressing during
131 the RTL phases. When there are not at least two expressions with
132 the same values of T1, T2, and C3, there is nothing to be gained
133 by the replacement.
135 Strength reduction of CAND_REFs uses the same infrastructure as
136 that used by CAND_MULTs and CAND_ADDs. We record T1 in the base (B)
137 field, MULT_EXPR (T2, C3) in the stride (S) field, and
138 C1 + (C2 * C3) + C4 in the index (i) field. A basis for a CAND_REF
139 is thus another CAND_REF with the same B and S values. When at
140 least two CAND_REFs are chained together using the basis relation,
141 each of them is replaced as above, resulting in improved code
142 generation for addressing.
144 Conditional candidates
145 ======================
147 Conditional candidates are best illustrated with an example.
148 Consider the code sequence:
150 (1) x_0 = ...;
151 (2) a_0 = x_0 * 5; MULT (B: x_0; i: 0; S: 5)
152 if (...)
153 (3) x_1 = x_0 + 1; ADD (B: x_0, i: 1; S: 1)
154 (4) x_2 = PHI <x_0, x_1>; PHI (B: x_0, i: 0, S: 1)
155 (5) x_3 = x_2 + 1; ADD (B: x_2, i: 1, S: 1)
156 (6) a_1 = x_3 * 5; MULT (B: x_2, i: 1; S: 5)
158 Here strength reduction is complicated by the uncertain value of x_2.
159 A legitimate transformation is:
161 (1) x_0 = ...;
162 (2) a_0 = x_0 * 5;
163 if (...)
165 (3) [x_1 = x_0 + 1;]
166 (3a) t_1 = a_0 + 5;
168 (4) [x_2 = PHI <x_0, x_1>;]
169 (4a) t_2 = PHI <a_0, t_1>;
170 (5) [x_3 = x_2 + 1;]
171 (6r) a_1 = t_2 + 5;
173 where the bracketed instructions may go dead.
175 To recognize this opportunity, we have to observe that statement (6)
176 has a "hidden basis" (2). The hidden basis is unlike a normal basis
177 in that the statement and the hidden basis have different base SSA
178 names (x_2 and x_0, respectively). The relationship is established
179 when a statement's base name (x_2) is defined by a phi statement (4),
180 each argument of which (x_0, x_1) has an identical "derived base name."
181 If the argument is defined by a candidate (as x_1 is by (3)) that is a
182 CAND_ADD having a stride of 1, the derived base name of the argument is
183 the base name of the candidate (x_0). Otherwise, the argument itself
184 is its derived base name (as is the case with argument x_0).
186 The hidden basis for statement (6) is the nearest dominating candidate
187 whose base name is the derived base name (x_0) of the feeding phi (4),
188 and whose stride is identical to that of the statement. We can then
189 create the new "phi basis" (4a) and feeding adds along incoming arcs (3a),
190 allowing the final replacement of (6) by the strength-reduced (6r).
192 To facilitate this, a new kind of candidate (CAND_PHI) is introduced.
193 A CAND_PHI is not a candidate for replacement, but is maintained in the
194 candidate table to ease discovery of hidden bases. Any phi statement
195 whose arguments share a common derived base name is entered into the
196 table with the derived base name, an (arbitrary) index of zero, and a
197 stride of 1. A statement with a hidden basis can then be detected by
198 simply looking up its feeding phi definition in the candidate table,
199 extracting the derived base name, and searching for a basis in the
200 usual manner after substituting the derived base name.
202 Note that the transformation is only valid when the original phi and
203 the statements that define the phi's arguments are all at the same
204 position in the loop hierarchy. */
207 /* Index into the candidate vector, offset by 1. VECs are zero-based,
208 while cand_idx's are one-based, with zero indicating null. */
209 typedef unsigned cand_idx;
211 /* The kind of candidate. */
212 enum cand_kind
214 CAND_MULT,
215 CAND_ADD,
216 CAND_REF,
217 CAND_PHI
220 struct slsr_cand_d
222 /* The candidate statement S1. */
223 gimple cand_stmt;
225 /* The base expression B: often an SSA name, but not always. */
226 tree base_expr;
228 /* The stride S. */
229 tree stride;
231 /* The index constant i. */
232 double_int index;
234 /* The type of the candidate. This is normally the type of base_expr,
235 but casts may have occurred when combining feeding instructions.
236 A candidate can only be a basis for candidates of the same final type.
237 (For CAND_REFs, this is the type to be used for operand 1 of the
238 replacement MEM_REF.) */
239 tree cand_type;
241 /* The kind of candidate (CAND_MULT, etc.). */
242 enum cand_kind kind;
244 /* Index of this candidate in the candidate vector. */
245 cand_idx cand_num;
247 /* Index of the next candidate record for the same statement.
248 A statement may be useful in more than one way (e.g., due to
249 commutativity). So we can have multiple "interpretations"
250 of a statement. */
251 cand_idx next_interp;
253 /* Index of the basis statement S0, if any, in the candidate vector. */
254 cand_idx basis;
256 /* First candidate for which this candidate is a basis, if one exists. */
257 cand_idx dependent;
259 /* Next candidate having the same basis as this one. */
260 cand_idx sibling;
262 /* If this is a conditional candidate, the CAND_PHI candidate
263 that defines the base SSA name B. */
264 cand_idx def_phi;
266 /* Savings that can be expected from eliminating dead code if this
267 candidate is replaced. */
268 int dead_savings;
271 typedef struct slsr_cand_d slsr_cand, *slsr_cand_t;
272 typedef const struct slsr_cand_d *const_slsr_cand_t;
274 /* Pointers to candidates are chained together as part of a mapping
275 from base expressions to the candidates that use them. */
277 struct cand_chain_d
279 /* Base expression for the chain of candidates: often, but not
280 always, an SSA name. */
281 tree base_expr;
283 /* Pointer to a candidate. */
284 slsr_cand_t cand;
286 /* Chain pointer. */
287 struct cand_chain_d *next;
291 typedef struct cand_chain_d cand_chain, *cand_chain_t;
292 typedef const struct cand_chain_d *const_cand_chain_t;
294 /* Information about a unique "increment" associated with candidates
295 having an SSA name for a stride. An increment is the difference
296 between the index of the candidate and the index of its basis,
297 i.e., (i - i') as discussed in the module commentary.
299 When we are not going to generate address arithmetic we treat
300 increments that differ only in sign as the same, allowing sharing
301 of the cost of initializers. The absolute value of the increment
302 is stored in the incr_info. */
304 struct incr_info_d
306 /* The increment that relates a candidate to its basis. */
307 double_int incr;
309 /* How many times the increment occurs in the candidate tree. */
310 unsigned count;
312 /* Cost of replacing candidates using this increment. Negative and
313 zero costs indicate replacement should be performed. */
314 int cost;
316 /* If this increment is profitable but is not -1, 0, or 1, it requires
317 an initializer T_0 = stride * incr to be found or introduced in the
318 nearest common dominator of all candidates. This field holds T_0
319 for subsequent use. */
320 tree initializer;
322 /* If the initializer was found to already exist, this is the block
323 where it was found. */
324 basic_block init_bb;
327 typedef struct incr_info_d incr_info, *incr_info_t;
329 /* Candidates are maintained in a vector. If candidate X dominates
330 candidate Y, then X appears before Y in the vector; but the
331 converse does not necessarily hold. */
332 static vec<slsr_cand_t> cand_vec;
334 enum cost_consts
336 COST_NEUTRAL = 0,
337 COST_INFINITE = 1000
340 enum stride_status
342 UNKNOWN_STRIDE = 0,
343 KNOWN_STRIDE = 1
346 enum phi_adjust_status
348 NOT_PHI_ADJUST = 0,
349 PHI_ADJUST = 1
352 enum count_phis_status
354 DONT_COUNT_PHIS = 0,
355 COUNT_PHIS = 1
358 /* Pointer map embodying a mapping from statements to candidates. */
359 static struct pointer_map_t *stmt_cand_map;
361 /* Obstack for candidates. */
362 static struct obstack cand_obstack;
364 /* Obstack for candidate chains. */
365 static struct obstack chain_obstack;
367 /* An array INCR_VEC of incr_infos is used during analysis of related
368 candidates having an SSA name for a stride. INCR_VEC_LEN describes
369 its current length. MAX_INCR_VEC_LEN is used to avoid costly
370 pathological cases. */
371 static incr_info_t incr_vec;
372 static unsigned incr_vec_len;
373 const int MAX_INCR_VEC_LEN = 16;
375 /* For a chain of candidates with unknown stride, indicates whether or not
376 we must generate pointer arithmetic when replacing statements. */
377 static bool address_arithmetic_p;
379 /* Forward function declarations. */
380 static slsr_cand_t base_cand_from_table (tree);
381 static tree introduce_cast_before_cand (slsr_cand_t, tree, tree);
382 static bool legal_cast_p_1 (tree, tree);
384 /* Produce a pointer to the IDX'th candidate in the candidate vector. */
386 static slsr_cand_t
387 lookup_cand (cand_idx idx)
389 return cand_vec[idx - 1];
392 /* Helper for hashing a candidate chain header. */
394 struct cand_chain_hasher : typed_noop_remove <cand_chain>
396 typedef cand_chain value_type;
397 typedef cand_chain compare_type;
398 static inline hashval_t hash (const value_type *);
399 static inline bool equal (const value_type *, const compare_type *);
402 inline hashval_t
403 cand_chain_hasher::hash (const value_type *p)
405 tree base_expr = p->base_expr;
406 return iterative_hash_expr (base_expr, 0);
409 inline bool
410 cand_chain_hasher::equal (const value_type *chain1, const compare_type *chain2)
412 return operand_equal_p (chain1->base_expr, chain2->base_expr, 0);
415 /* Hash table embodying a mapping from base exprs to chains of candidates. */
416 static hash_table <cand_chain_hasher> base_cand_map;
418 /* Look in the candidate table for a CAND_PHI that defines BASE and
419 return it if found; otherwise return NULL. */
421 static cand_idx
422 find_phi_def (tree base)
424 slsr_cand_t c;
426 if (TREE_CODE (base) != SSA_NAME)
427 return 0;
429 c = base_cand_from_table (base);
431 if (!c || c->kind != CAND_PHI)
432 return 0;
434 return c->cand_num;
437 /* Helper routine for find_basis_for_candidate. May be called twice:
438 once for the candidate's base expr, and optionally again for the
439 candidate's phi definition. */
441 static slsr_cand_t
442 find_basis_for_base_expr (slsr_cand_t c, tree base_expr)
444 cand_chain mapping_key;
445 cand_chain_t chain;
446 slsr_cand_t basis = NULL;
448 // Limit potential of N^2 behavior for long candidate chains.
449 int iters = 0;
450 int max_iters = PARAM_VALUE (PARAM_MAX_SLSR_CANDIDATE_SCAN);
452 mapping_key.base_expr = base_expr;
453 chain = base_cand_map.find (&mapping_key);
455 for (; chain && iters < max_iters; chain = chain->next, ++iters)
457 slsr_cand_t one_basis = chain->cand;
459 if (one_basis->kind != c->kind
460 || one_basis->cand_stmt == c->cand_stmt
461 || !operand_equal_p (one_basis->stride, c->stride, 0)
462 || !types_compatible_p (one_basis->cand_type, c->cand_type)
463 || !dominated_by_p (CDI_DOMINATORS,
464 gimple_bb (c->cand_stmt),
465 gimple_bb (one_basis->cand_stmt)))
466 continue;
468 if (!basis || basis->cand_num < one_basis->cand_num)
469 basis = one_basis;
472 return basis;
475 /* Use the base expr from candidate C to look for possible candidates
476 that can serve as a basis for C. Each potential basis must also
477 appear in a block that dominates the candidate statement and have
478 the same stride and type. If more than one possible basis exists,
479 the one with highest index in the vector is chosen; this will be
480 the most immediately dominating basis. */
482 static int
483 find_basis_for_candidate (slsr_cand_t c)
485 slsr_cand_t basis = find_basis_for_base_expr (c, c->base_expr);
487 /* If a candidate doesn't have a basis using its base expression,
488 it may have a basis hidden by one or more intervening phis. */
489 if (!basis && c->def_phi)
491 basic_block basis_bb, phi_bb;
492 slsr_cand_t phi_cand = lookup_cand (c->def_phi);
493 basis = find_basis_for_base_expr (c, phi_cand->base_expr);
495 if (basis)
497 /* A hidden basis must dominate the phi-definition of the
498 candidate's base name. */
499 phi_bb = gimple_bb (phi_cand->cand_stmt);
500 basis_bb = gimple_bb (basis->cand_stmt);
502 if (phi_bb == basis_bb
503 || !dominated_by_p (CDI_DOMINATORS, phi_bb, basis_bb))
505 basis = NULL;
506 c->basis = 0;
509 /* If we found a hidden basis, estimate additional dead-code
510 savings if the phi and its feeding statements can be removed. */
511 if (basis && has_single_use (gimple_phi_result (phi_cand->cand_stmt)))
512 c->dead_savings += phi_cand->dead_savings;
516 if (basis)
518 c->sibling = basis->dependent;
519 basis->dependent = c->cand_num;
520 return basis->cand_num;
523 return 0;
526 /* Record a mapping from the base expression of C to C itself, indicating that
527 C may potentially serve as a basis using that base expression. */
529 static void
530 record_potential_basis (slsr_cand_t c)
532 cand_chain_t node;
533 cand_chain **slot;
535 node = (cand_chain_t) obstack_alloc (&chain_obstack, sizeof (cand_chain));
536 node->base_expr = c->base_expr;
537 node->cand = c;
538 node->next = NULL;
539 slot = base_cand_map.find_slot (node, INSERT);
541 if (*slot)
543 cand_chain_t head = (cand_chain_t) (*slot);
544 node->next = head->next;
545 head->next = node;
547 else
548 *slot = node;
551 /* Allocate storage for a new candidate and initialize its fields.
552 Attempt to find a basis for the candidate. */
554 static slsr_cand_t
555 alloc_cand_and_find_basis (enum cand_kind kind, gimple gs, tree base,
556 double_int index, tree stride, tree ctype,
557 unsigned savings)
559 slsr_cand_t c = (slsr_cand_t) obstack_alloc (&cand_obstack,
560 sizeof (slsr_cand));
561 c->cand_stmt = gs;
562 c->base_expr = base;
563 c->stride = stride;
564 c->index = index;
565 c->cand_type = ctype;
566 c->kind = kind;
567 c->cand_num = cand_vec.length () + 1;
568 c->next_interp = 0;
569 c->dependent = 0;
570 c->sibling = 0;
571 c->def_phi = kind == CAND_MULT ? find_phi_def (base) : 0;
572 c->dead_savings = savings;
574 cand_vec.safe_push (c);
576 if (kind == CAND_PHI)
577 c->basis = 0;
578 else
579 c->basis = find_basis_for_candidate (c);
581 record_potential_basis (c);
583 return c;
586 /* Determine the target cost of statement GS when compiling according
587 to SPEED. */
589 static int
590 stmt_cost (gimple gs, bool speed)
592 tree lhs, rhs1, rhs2;
593 enum machine_mode lhs_mode;
595 gcc_assert (is_gimple_assign (gs));
596 lhs = gimple_assign_lhs (gs);
597 rhs1 = gimple_assign_rhs1 (gs);
598 lhs_mode = TYPE_MODE (TREE_TYPE (lhs));
600 switch (gimple_assign_rhs_code (gs))
602 case MULT_EXPR:
603 rhs2 = gimple_assign_rhs2 (gs);
605 if (host_integerp (rhs2, 0))
606 return mult_by_coeff_cost (TREE_INT_CST_LOW (rhs2), lhs_mode, speed);
608 gcc_assert (TREE_CODE (rhs1) != INTEGER_CST);
609 return mul_cost (speed, lhs_mode);
611 case PLUS_EXPR:
612 case POINTER_PLUS_EXPR:
613 case MINUS_EXPR:
614 return add_cost (speed, lhs_mode);
616 case NEGATE_EXPR:
617 return neg_cost (speed, lhs_mode);
619 case NOP_EXPR:
620 return convert_cost (lhs_mode, TYPE_MODE (TREE_TYPE (rhs1)), speed);
622 /* Note that we don't assign costs to copies that in most cases
623 will go away. */
624 default:
628 gcc_unreachable ();
629 return 0;
632 /* Look up the defining statement for BASE_IN and return a pointer
633 to its candidate in the candidate table, if any; otherwise NULL.
634 Only CAND_ADD and CAND_MULT candidates are returned. */
636 static slsr_cand_t
637 base_cand_from_table (tree base_in)
639 slsr_cand_t *result;
641 gimple def = SSA_NAME_DEF_STMT (base_in);
642 if (!def)
643 return (slsr_cand_t) NULL;
645 result = (slsr_cand_t *) pointer_map_contains (stmt_cand_map, def);
647 if (result && (*result)->kind != CAND_REF)
648 return *result;
650 return (slsr_cand_t) NULL;
653 /* Add an entry to the statement-to-candidate mapping. */
655 static void
656 add_cand_for_stmt (gimple gs, slsr_cand_t c)
658 void **slot = pointer_map_insert (stmt_cand_map, gs);
659 gcc_assert (!*slot);
660 *slot = c;
663 /* Given PHI which contains a phi statement, determine whether it
664 satisfies all the requirements of a phi candidate. If so, create
665 a candidate. Note that a CAND_PHI never has a basis itself, but
666 is used to help find a basis for subsequent candidates. */
668 static void
669 slsr_process_phi (gimple phi, bool speed)
671 unsigned i;
672 tree arg0_base = NULL_TREE, base_type;
673 slsr_cand_t c;
674 struct loop *cand_loop = gimple_bb (phi)->loop_father;
675 unsigned savings = 0;
677 /* A CAND_PHI requires each of its arguments to have the same
678 derived base name. (See the module header commentary for a
679 definition of derived base names.) Furthermore, all feeding
680 definitions must be in the same position in the loop hierarchy
681 as PHI. */
683 for (i = 0; i < gimple_phi_num_args (phi); i++)
685 slsr_cand_t arg_cand;
686 tree arg = gimple_phi_arg_def (phi, i);
687 tree derived_base_name = NULL_TREE;
688 gimple arg_stmt = NULL;
689 basic_block arg_bb = NULL;
691 if (TREE_CODE (arg) != SSA_NAME)
692 return;
694 arg_cand = base_cand_from_table (arg);
696 if (arg_cand)
698 while (arg_cand->kind != CAND_ADD && arg_cand->kind != CAND_PHI)
700 if (!arg_cand->next_interp)
701 return;
703 arg_cand = lookup_cand (arg_cand->next_interp);
706 if (!integer_onep (arg_cand->stride))
707 return;
709 derived_base_name = arg_cand->base_expr;
710 arg_stmt = arg_cand->cand_stmt;
711 arg_bb = gimple_bb (arg_stmt);
713 /* Gather potential dead code savings if the phi statement
714 can be removed later on. */
715 if (has_single_use (arg))
717 if (gimple_code (arg_stmt) == GIMPLE_PHI)
718 savings += arg_cand->dead_savings;
719 else
720 savings += stmt_cost (arg_stmt, speed);
723 else
725 derived_base_name = arg;
727 if (SSA_NAME_IS_DEFAULT_DEF (arg))
728 arg_bb = single_succ (ENTRY_BLOCK_PTR);
729 else
730 gimple_bb (SSA_NAME_DEF_STMT (arg));
733 if (!arg_bb || arg_bb->loop_father != cand_loop)
734 return;
736 if (i == 0)
737 arg0_base = derived_base_name;
738 else if (!operand_equal_p (derived_base_name, arg0_base, 0))
739 return;
742 /* Create the candidate. "alloc_cand_and_find_basis" is named
743 misleadingly for this case, as no basis will be sought for a
744 CAND_PHI. */
745 base_type = TREE_TYPE (arg0_base);
747 c = alloc_cand_and_find_basis (CAND_PHI, phi, arg0_base, double_int_zero,
748 integer_one_node, base_type, savings);
750 /* Add the candidate to the statement-candidate mapping. */
751 add_cand_for_stmt (phi, c);
754 /* Given PBASE which is a pointer to tree, look up the defining
755 statement for it and check whether the candidate is in the
756 form of:
758 X = B + (1 * S), S is integer constant
759 X = B + (i * S), S is integer one
761 If so, set PBASE to the candidate's base_expr and return double
762 int (i * S).
763 Otherwise, just return double int zero. */
765 static double_int
766 backtrace_base_for_ref (tree *pbase)
768 tree base_in = *pbase;
769 slsr_cand_t base_cand;
771 STRIP_NOPS (base_in);
773 /* Strip off widening conversion(s) to handle cases where
774 e.g. 'B' is widened from an 'int' in order to calculate
775 a 64-bit address. */
776 if (CONVERT_EXPR_P (base_in)
777 && legal_cast_p_1 (base_in, TREE_OPERAND (base_in, 0)))
778 base_in = get_unwidened (base_in, NULL_TREE);
780 if (TREE_CODE (base_in) != SSA_NAME)
781 return tree_to_double_int (integer_zero_node);
783 base_cand = base_cand_from_table (base_in);
785 while (base_cand && base_cand->kind != CAND_PHI)
787 if (base_cand->kind == CAND_ADD
788 && base_cand->index.is_one ()
789 && TREE_CODE (base_cand->stride) == INTEGER_CST)
791 /* X = B + (1 * S), S is integer constant. */
792 *pbase = base_cand->base_expr;
793 return tree_to_double_int (base_cand->stride);
795 else if (base_cand->kind == CAND_ADD
796 && TREE_CODE (base_cand->stride) == INTEGER_CST
797 && integer_onep (base_cand->stride))
799 /* X = B + (i * S), S is integer one. */
800 *pbase = base_cand->base_expr;
801 return base_cand->index;
804 if (base_cand->next_interp)
805 base_cand = lookup_cand (base_cand->next_interp);
806 else
807 base_cand = NULL;
810 return tree_to_double_int (integer_zero_node);
813 /* Look for the following pattern:
815 *PBASE: MEM_REF (T1, C1)
817 *POFFSET: MULT_EXPR (T2, C3) [C2 is zero]
819 MULT_EXPR (PLUS_EXPR (T2, C2), C3)
821 MULT_EXPR (MINUS_EXPR (T2, -C2), C3)
823 *PINDEX: C4 * BITS_PER_UNIT
825 If not present, leave the input values unchanged and return FALSE.
826 Otherwise, modify the input values as follows and return TRUE:
828 *PBASE: T1
829 *POFFSET: MULT_EXPR (T2, C3)
830 *PINDEX: C1 + (C2 * C3) + C4
832 When T2 is recorded by a CAND_ADD in the form of (T2' + C5), it
833 will be further restructured to:
835 *PBASE: T1
836 *POFFSET: MULT_EXPR (T2', C3)
837 *PINDEX: C1 + (C2 * C3) + C4 + (C5 * C3) */
839 static bool
840 restructure_reference (tree *pbase, tree *poffset, double_int *pindex,
841 tree *ptype)
843 tree base = *pbase, offset = *poffset;
844 double_int index = *pindex;
845 double_int bpu = double_int::from_uhwi (BITS_PER_UNIT);
846 tree mult_op0, mult_op1, t1, t2, type;
847 double_int c1, c2, c3, c4, c5;
849 if (!base
850 || !offset
851 || TREE_CODE (base) != MEM_REF
852 || TREE_CODE (offset) != MULT_EXPR
853 || TREE_CODE (TREE_OPERAND (offset, 1)) != INTEGER_CST
854 || !index.umod (bpu, FLOOR_MOD_EXPR).is_zero ())
855 return false;
857 t1 = TREE_OPERAND (base, 0);
858 c1 = mem_ref_offset (base);
859 type = TREE_TYPE (TREE_OPERAND (base, 1));
861 mult_op0 = TREE_OPERAND (offset, 0);
862 mult_op1 = TREE_OPERAND (offset, 1);
864 c3 = tree_to_double_int (mult_op1);
866 if (TREE_CODE (mult_op0) == PLUS_EXPR)
868 if (TREE_CODE (TREE_OPERAND (mult_op0, 1)) == INTEGER_CST)
870 t2 = TREE_OPERAND (mult_op0, 0);
871 c2 = tree_to_double_int (TREE_OPERAND (mult_op0, 1));
873 else
874 return false;
876 else if (TREE_CODE (mult_op0) == MINUS_EXPR)
878 if (TREE_CODE (TREE_OPERAND (mult_op0, 1)) == INTEGER_CST)
880 t2 = TREE_OPERAND (mult_op0, 0);
881 c2 = -tree_to_double_int (TREE_OPERAND (mult_op0, 1));
883 else
884 return false;
886 else
888 t2 = mult_op0;
889 c2 = double_int_zero;
892 c4 = index.udiv (bpu, FLOOR_DIV_EXPR);
893 c5 = backtrace_base_for_ref (&t2);
895 *pbase = t1;
896 *poffset = fold_build2 (MULT_EXPR, sizetype, fold_convert (sizetype, t2),
897 double_int_to_tree (sizetype, c3));
898 *pindex = c1 + c2 * c3 + c4 + c5 * c3;
899 *ptype = type;
901 return true;
904 /* Given GS which contains a data reference, create a CAND_REF entry in
905 the candidate table and attempt to find a basis. */
907 static void
908 slsr_process_ref (gimple gs)
910 tree ref_expr, base, offset, type;
911 HOST_WIDE_INT bitsize, bitpos;
912 enum machine_mode mode;
913 int unsignedp, volatilep;
914 double_int index;
915 slsr_cand_t c;
917 if (gimple_vdef (gs))
918 ref_expr = gimple_assign_lhs (gs);
919 else
920 ref_expr = gimple_assign_rhs1 (gs);
922 if (!handled_component_p (ref_expr)
923 || TREE_CODE (ref_expr) == BIT_FIELD_REF
924 || (TREE_CODE (ref_expr) == COMPONENT_REF
925 && DECL_BIT_FIELD (TREE_OPERAND (ref_expr, 1))))
926 return;
928 base = get_inner_reference (ref_expr, &bitsize, &bitpos, &offset, &mode,
929 &unsignedp, &volatilep, false);
930 index = double_int::from_uhwi (bitpos);
932 if (!restructure_reference (&base, &offset, &index, &type))
933 return;
935 c = alloc_cand_and_find_basis (CAND_REF, gs, base, index, offset,
936 type, 0);
938 /* Add the candidate to the statement-candidate mapping. */
939 add_cand_for_stmt (gs, c);
942 /* Create a candidate entry for a statement GS, where GS multiplies
943 two SSA names BASE_IN and STRIDE_IN. Propagate any known information
944 about the two SSA names into the new candidate. Return the new
945 candidate. */
947 static slsr_cand_t
948 create_mul_ssa_cand (gimple gs, tree base_in, tree stride_in, bool speed)
950 tree base = NULL_TREE, stride = NULL_TREE, ctype = NULL_TREE;
951 double_int index;
952 unsigned savings = 0;
953 slsr_cand_t c;
954 slsr_cand_t base_cand = base_cand_from_table (base_in);
956 /* Look at all interpretations of the base candidate, if necessary,
957 to find information to propagate into this candidate. */
958 while (base_cand && !base && base_cand->kind != CAND_PHI)
961 if (base_cand->kind == CAND_MULT && integer_onep (base_cand->stride))
963 /* Y = (B + i') * 1
964 X = Y * Z
965 ================
966 X = (B + i') * Z */
967 base = base_cand->base_expr;
968 index = base_cand->index;
969 stride = stride_in;
970 ctype = base_cand->cand_type;
971 if (has_single_use (base_in))
972 savings = (base_cand->dead_savings
973 + stmt_cost (base_cand->cand_stmt, speed));
975 else if (base_cand->kind == CAND_ADD
976 && TREE_CODE (base_cand->stride) == INTEGER_CST)
978 /* Y = B + (i' * S), S constant
979 X = Y * Z
980 ============================
981 X = B + ((i' * S) * Z) */
982 base = base_cand->base_expr;
983 index = base_cand->index * tree_to_double_int (base_cand->stride);
984 stride = stride_in;
985 ctype = base_cand->cand_type;
986 if (has_single_use (base_in))
987 savings = (base_cand->dead_savings
988 + stmt_cost (base_cand->cand_stmt, speed));
991 if (base_cand->next_interp)
992 base_cand = lookup_cand (base_cand->next_interp);
993 else
994 base_cand = NULL;
997 if (!base)
999 /* No interpretations had anything useful to propagate, so
1000 produce X = (Y + 0) * Z. */
1001 base = base_in;
1002 index = double_int_zero;
1003 stride = stride_in;
1004 ctype = TREE_TYPE (base_in);
1007 c = alloc_cand_and_find_basis (CAND_MULT, gs, base, index, stride,
1008 ctype, savings);
1009 return c;
1012 /* Create a candidate entry for a statement GS, where GS multiplies
1013 SSA name BASE_IN by constant STRIDE_IN. Propagate any known
1014 information about BASE_IN into the new candidate. Return the new
1015 candidate. */
1017 static slsr_cand_t
1018 create_mul_imm_cand (gimple gs, tree base_in, tree stride_in, bool speed)
1020 tree base = NULL_TREE, stride = NULL_TREE, ctype = NULL_TREE;
1021 double_int index, temp;
1022 unsigned savings = 0;
1023 slsr_cand_t c;
1024 slsr_cand_t base_cand = base_cand_from_table (base_in);
1026 /* Look at all interpretations of the base candidate, if necessary,
1027 to find information to propagate into this candidate. */
1028 while (base_cand && !base && base_cand->kind != CAND_PHI)
1030 if (base_cand->kind == CAND_MULT
1031 && TREE_CODE (base_cand->stride) == INTEGER_CST)
1033 /* Y = (B + i') * S, S constant
1034 X = Y * c
1035 ============================
1036 X = (B + i') * (S * c) */
1037 base = base_cand->base_expr;
1038 index = base_cand->index;
1039 temp = tree_to_double_int (base_cand->stride)
1040 * tree_to_double_int (stride_in);
1041 stride = double_int_to_tree (TREE_TYPE (stride_in), temp);
1042 ctype = base_cand->cand_type;
1043 if (has_single_use (base_in))
1044 savings = (base_cand->dead_savings
1045 + stmt_cost (base_cand->cand_stmt, speed));
1047 else if (base_cand->kind == CAND_ADD && integer_onep (base_cand->stride))
1049 /* Y = B + (i' * 1)
1050 X = Y * c
1051 ===========================
1052 X = (B + i') * c */
1053 base = base_cand->base_expr;
1054 index = base_cand->index;
1055 stride = stride_in;
1056 ctype = base_cand->cand_type;
1057 if (has_single_use (base_in))
1058 savings = (base_cand->dead_savings
1059 + stmt_cost (base_cand->cand_stmt, speed));
1061 else if (base_cand->kind == CAND_ADD
1062 && base_cand->index.is_one ()
1063 && TREE_CODE (base_cand->stride) == INTEGER_CST)
1065 /* Y = B + (1 * S), S constant
1066 X = Y * c
1067 ===========================
1068 X = (B + S) * c */
1069 base = base_cand->base_expr;
1070 index = tree_to_double_int (base_cand->stride);
1071 stride = stride_in;
1072 ctype = base_cand->cand_type;
1073 if (has_single_use (base_in))
1074 savings = (base_cand->dead_savings
1075 + stmt_cost (base_cand->cand_stmt, speed));
1078 if (base_cand->next_interp)
1079 base_cand = lookup_cand (base_cand->next_interp);
1080 else
1081 base_cand = NULL;
1084 if (!base)
1086 /* No interpretations had anything useful to propagate, so
1087 produce X = (Y + 0) * c. */
1088 base = base_in;
1089 index = double_int_zero;
1090 stride = stride_in;
1091 ctype = TREE_TYPE (base_in);
1094 c = alloc_cand_and_find_basis (CAND_MULT, gs, base, index, stride,
1095 ctype, savings);
1096 return c;
1099 /* Given GS which is a multiply of scalar integers, make an appropriate
1100 entry in the candidate table. If this is a multiply of two SSA names,
1101 create two CAND_MULT interpretations and attempt to find a basis for
1102 each of them. Otherwise, create a single CAND_MULT and attempt to
1103 find a basis. */
1105 static void
1106 slsr_process_mul (gimple gs, tree rhs1, tree rhs2, bool speed)
1108 slsr_cand_t c, c2;
1110 /* If this is a multiply of an SSA name with itself, it is highly
1111 unlikely that we will get a strength reduction opportunity, so
1112 don't record it as a candidate. This simplifies the logic for
1113 finding a basis, so if this is removed that must be considered. */
1114 if (rhs1 == rhs2)
1115 return;
1117 if (TREE_CODE (rhs2) == SSA_NAME)
1119 /* Record an interpretation of this statement in the candidate table
1120 assuming RHS1 is the base expression and RHS2 is the stride. */
1121 c = create_mul_ssa_cand (gs, rhs1, rhs2, speed);
1123 /* Add the first interpretation to the statement-candidate mapping. */
1124 add_cand_for_stmt (gs, c);
1126 /* Record another interpretation of this statement assuming RHS1
1127 is the stride and RHS2 is the base expression. */
1128 c2 = create_mul_ssa_cand (gs, rhs2, rhs1, speed);
1129 c->next_interp = c2->cand_num;
1131 else
1133 /* Record an interpretation for the multiply-immediate. */
1134 c = create_mul_imm_cand (gs, rhs1, rhs2, speed);
1136 /* Add the interpretation to the statement-candidate mapping. */
1137 add_cand_for_stmt (gs, c);
1141 /* Create a candidate entry for a statement GS, where GS adds two
1142 SSA names BASE_IN and ADDEND_IN if SUBTRACT_P is false, and
1143 subtracts ADDEND_IN from BASE_IN otherwise. Propagate any known
1144 information about the two SSA names into the new candidate.
1145 Return the new candidate. */
1147 static slsr_cand_t
1148 create_add_ssa_cand (gimple gs, tree base_in, tree addend_in,
1149 bool subtract_p, bool speed)
1151 tree base = NULL_TREE, stride = NULL_TREE, ctype = NULL;
1152 double_int index;
1153 unsigned savings = 0;
1154 slsr_cand_t c;
1155 slsr_cand_t base_cand = base_cand_from_table (base_in);
1156 slsr_cand_t addend_cand = base_cand_from_table (addend_in);
1158 /* The most useful transformation is a multiply-immediate feeding
1159 an add or subtract. Look for that first. */
1160 while (addend_cand && !base && addend_cand->kind != CAND_PHI)
1162 if (addend_cand->kind == CAND_MULT
1163 && addend_cand->index.is_zero ()
1164 && TREE_CODE (addend_cand->stride) == INTEGER_CST)
1166 /* Z = (B + 0) * S, S constant
1167 X = Y +/- Z
1168 ===========================
1169 X = Y + ((+/-1 * S) * B) */
1170 base = base_in;
1171 index = tree_to_double_int (addend_cand->stride);
1172 if (subtract_p)
1173 index = -index;
1174 stride = addend_cand->base_expr;
1175 ctype = TREE_TYPE (base_in);
1176 if (has_single_use (addend_in))
1177 savings = (addend_cand->dead_savings
1178 + stmt_cost (addend_cand->cand_stmt, speed));
1181 if (addend_cand->next_interp)
1182 addend_cand = lookup_cand (addend_cand->next_interp);
1183 else
1184 addend_cand = NULL;
1187 while (base_cand && !base && base_cand->kind != CAND_PHI)
1189 if (base_cand->kind == CAND_ADD
1190 && (base_cand->index.is_zero ()
1191 || operand_equal_p (base_cand->stride,
1192 integer_zero_node, 0)))
1194 /* Y = B + (i' * S), i' * S = 0
1195 X = Y +/- Z
1196 ============================
1197 X = B + (+/-1 * Z) */
1198 base = base_cand->base_expr;
1199 index = subtract_p ? double_int_minus_one : double_int_one;
1200 stride = addend_in;
1201 ctype = base_cand->cand_type;
1202 if (has_single_use (base_in))
1203 savings = (base_cand->dead_savings
1204 + stmt_cost (base_cand->cand_stmt, speed));
1206 else if (subtract_p)
1208 slsr_cand_t subtrahend_cand = base_cand_from_table (addend_in);
1210 while (subtrahend_cand && !base && subtrahend_cand->kind != CAND_PHI)
1212 if (subtrahend_cand->kind == CAND_MULT
1213 && subtrahend_cand->index.is_zero ()
1214 && TREE_CODE (subtrahend_cand->stride) == INTEGER_CST)
1216 /* Z = (B + 0) * S, S constant
1217 X = Y - Z
1218 ===========================
1219 Value: X = Y + ((-1 * S) * B) */
1220 base = base_in;
1221 index = tree_to_double_int (subtrahend_cand->stride);
1222 index = -index;
1223 stride = subtrahend_cand->base_expr;
1224 ctype = TREE_TYPE (base_in);
1225 if (has_single_use (addend_in))
1226 savings = (subtrahend_cand->dead_savings
1227 + stmt_cost (subtrahend_cand->cand_stmt, speed));
1230 if (subtrahend_cand->next_interp)
1231 subtrahend_cand = lookup_cand (subtrahend_cand->next_interp);
1232 else
1233 subtrahend_cand = NULL;
1237 if (base_cand->next_interp)
1238 base_cand = lookup_cand (base_cand->next_interp);
1239 else
1240 base_cand = NULL;
1243 if (!base)
1245 /* No interpretations had anything useful to propagate, so
1246 produce X = Y + (1 * Z). */
1247 base = base_in;
1248 index = subtract_p ? double_int_minus_one : double_int_one;
1249 stride = addend_in;
1250 ctype = TREE_TYPE (base_in);
1253 c = alloc_cand_and_find_basis (CAND_ADD, gs, base, index, stride,
1254 ctype, savings);
1255 return c;
1258 /* Create a candidate entry for a statement GS, where GS adds SSA
1259 name BASE_IN to constant INDEX_IN. Propagate any known information
1260 about BASE_IN into the new candidate. Return the new candidate. */
1262 static slsr_cand_t
1263 create_add_imm_cand (gimple gs, tree base_in, double_int index_in, bool speed)
1265 enum cand_kind kind = CAND_ADD;
1266 tree base = NULL_TREE, stride = NULL_TREE, ctype = NULL_TREE;
1267 double_int index, multiple;
1268 unsigned savings = 0;
1269 slsr_cand_t c;
1270 slsr_cand_t base_cand = base_cand_from_table (base_in);
1272 while (base_cand && !base && base_cand->kind != CAND_PHI)
1274 bool unsigned_p = TYPE_UNSIGNED (TREE_TYPE (base_cand->stride));
1276 if (TREE_CODE (base_cand->stride) == INTEGER_CST
1277 && index_in.multiple_of (tree_to_double_int (base_cand->stride),
1278 unsigned_p, &multiple))
1280 /* Y = (B + i') * S, S constant, c = kS for some integer k
1281 X = Y + c
1282 ============================
1283 X = (B + (i'+ k)) * S
1285 Y = B + (i' * S), S constant, c = kS for some integer k
1286 X = Y + c
1287 ============================
1288 X = (B + (i'+ k)) * S */
1289 kind = base_cand->kind;
1290 base = base_cand->base_expr;
1291 index = base_cand->index + multiple;
1292 stride = base_cand->stride;
1293 ctype = base_cand->cand_type;
1294 if (has_single_use (base_in))
1295 savings = (base_cand->dead_savings
1296 + stmt_cost (base_cand->cand_stmt, speed));
1299 if (base_cand->next_interp)
1300 base_cand = lookup_cand (base_cand->next_interp);
1301 else
1302 base_cand = NULL;
1305 if (!base)
1307 /* No interpretations had anything useful to propagate, so
1308 produce X = Y + (c * 1). */
1309 kind = CAND_ADD;
1310 base = base_in;
1311 index = index_in;
1312 stride = integer_one_node;
1313 ctype = TREE_TYPE (base_in);
1316 c = alloc_cand_and_find_basis (kind, gs, base, index, stride,
1317 ctype, savings);
1318 return c;
1321 /* Given GS which is an add or subtract of scalar integers or pointers,
1322 make at least one appropriate entry in the candidate table. */
1324 static void
1325 slsr_process_add (gimple gs, tree rhs1, tree rhs2, bool speed)
1327 bool subtract_p = gimple_assign_rhs_code (gs) == MINUS_EXPR;
1328 slsr_cand_t c = NULL, c2;
1330 if (TREE_CODE (rhs2) == SSA_NAME)
1332 /* First record an interpretation assuming RHS1 is the base expression
1333 and RHS2 is the stride. But it doesn't make sense for the
1334 stride to be a pointer, so don't record a candidate in that case. */
1335 if (!POINTER_TYPE_P (TREE_TYPE (rhs2)))
1337 c = create_add_ssa_cand (gs, rhs1, rhs2, subtract_p, speed);
1339 /* Add the first interpretation to the statement-candidate
1340 mapping. */
1341 add_cand_for_stmt (gs, c);
1344 /* If the two RHS operands are identical, or this is a subtract,
1345 we're done. */
1346 if (operand_equal_p (rhs1, rhs2, 0) || subtract_p)
1347 return;
1349 /* Otherwise, record another interpretation assuming RHS2 is the
1350 base expression and RHS1 is the stride, again provided that the
1351 stride is not a pointer. */
1352 if (!POINTER_TYPE_P (TREE_TYPE (rhs1)))
1354 c2 = create_add_ssa_cand (gs, rhs2, rhs1, false, speed);
1355 if (c)
1356 c->next_interp = c2->cand_num;
1357 else
1358 add_cand_for_stmt (gs, c2);
1361 else
1363 double_int index;
1365 /* Record an interpretation for the add-immediate. */
1366 index = tree_to_double_int (rhs2);
1367 if (subtract_p)
1368 index = -index;
1370 c = create_add_imm_cand (gs, rhs1, index, speed);
1372 /* Add the interpretation to the statement-candidate mapping. */
1373 add_cand_for_stmt (gs, c);
1377 /* Given GS which is a negate of a scalar integer, make an appropriate
1378 entry in the candidate table. A negate is equivalent to a multiply
1379 by -1. */
1381 static void
1382 slsr_process_neg (gimple gs, tree rhs1, bool speed)
1384 /* Record a CAND_MULT interpretation for the multiply by -1. */
1385 slsr_cand_t c = create_mul_imm_cand (gs, rhs1, integer_minus_one_node, speed);
1387 /* Add the interpretation to the statement-candidate mapping. */
1388 add_cand_for_stmt (gs, c);
1391 /* Help function for legal_cast_p, operating on two trees. Checks
1392 whether it's allowable to cast from RHS to LHS. See legal_cast_p
1393 for more details. */
1395 static bool
1396 legal_cast_p_1 (tree lhs, tree rhs)
1398 tree lhs_type, rhs_type;
1399 unsigned lhs_size, rhs_size;
1400 bool lhs_wraps, rhs_wraps;
1402 lhs_type = TREE_TYPE (lhs);
1403 rhs_type = TREE_TYPE (rhs);
1404 lhs_size = TYPE_PRECISION (lhs_type);
1405 rhs_size = TYPE_PRECISION (rhs_type);
1406 lhs_wraps = TYPE_OVERFLOW_WRAPS (lhs_type);
1407 rhs_wraps = TYPE_OVERFLOW_WRAPS (rhs_type);
1409 if (lhs_size < rhs_size
1410 || (rhs_wraps && !lhs_wraps)
1411 || (rhs_wraps && lhs_wraps && rhs_size != lhs_size))
1412 return false;
1414 return true;
1417 /* Return TRUE if GS is a statement that defines an SSA name from
1418 a conversion and is legal for us to combine with an add and multiply
1419 in the candidate table. For example, suppose we have:
1421 A = B + i;
1422 C = (type) A;
1423 D = C * S;
1425 Without the type-cast, we would create a CAND_MULT for D with base B,
1426 index i, and stride S. We want to record this candidate only if it
1427 is equivalent to apply the type cast following the multiply:
1429 A = B + i;
1430 E = A * S;
1431 D = (type) E;
1433 We will record the type with the candidate for D. This allows us
1434 to use a similar previous candidate as a basis. If we have earlier seen
1436 A' = B + i';
1437 C' = (type) A';
1438 D' = C' * S;
1440 we can replace D with
1442 D = D' + (i - i') * S;
1444 But if moving the type-cast would change semantics, we mustn't do this.
1446 This is legitimate for casts from a non-wrapping integral type to
1447 any integral type of the same or larger size. It is not legitimate
1448 to convert a wrapping type to a non-wrapping type, or to a wrapping
1449 type of a different size. I.e., with a wrapping type, we must
1450 assume that the addition B + i could wrap, in which case performing
1451 the multiply before or after one of the "illegal" type casts will
1452 have different semantics. */
1454 static bool
1455 legal_cast_p (gimple gs, tree rhs)
1457 if (!is_gimple_assign (gs)
1458 || !CONVERT_EXPR_CODE_P (gimple_assign_rhs_code (gs)))
1459 return false;
1461 return legal_cast_p_1 (gimple_assign_lhs (gs), rhs);
1464 /* Given GS which is a cast to a scalar integer type, determine whether
1465 the cast is legal for strength reduction. If so, make at least one
1466 appropriate entry in the candidate table. */
1468 static void
1469 slsr_process_cast (gimple gs, tree rhs1, bool speed)
1471 tree lhs, ctype;
1472 slsr_cand_t base_cand, c, c2;
1473 unsigned savings = 0;
1475 if (!legal_cast_p (gs, rhs1))
1476 return;
1478 lhs = gimple_assign_lhs (gs);
1479 base_cand = base_cand_from_table (rhs1);
1480 ctype = TREE_TYPE (lhs);
1482 if (base_cand && base_cand->kind != CAND_PHI)
1484 while (base_cand)
1486 /* Propagate all data from the base candidate except the type,
1487 which comes from the cast, and the base candidate's cast,
1488 which is no longer applicable. */
1489 if (has_single_use (rhs1))
1490 savings = (base_cand->dead_savings
1491 + stmt_cost (base_cand->cand_stmt, speed));
1493 c = alloc_cand_and_find_basis (base_cand->kind, gs,
1494 base_cand->base_expr,
1495 base_cand->index, base_cand->stride,
1496 ctype, savings);
1497 if (base_cand->next_interp)
1498 base_cand = lookup_cand (base_cand->next_interp);
1499 else
1500 base_cand = NULL;
1503 else
1505 /* If nothing is known about the RHS, create fresh CAND_ADD and
1506 CAND_MULT interpretations:
1508 X = Y + (0 * 1)
1509 X = (Y + 0) * 1
1511 The first of these is somewhat arbitrary, but the choice of
1512 1 for the stride simplifies the logic for propagating casts
1513 into their uses. */
1514 c = alloc_cand_and_find_basis (CAND_ADD, gs, rhs1, double_int_zero,
1515 integer_one_node, ctype, 0);
1516 c2 = alloc_cand_and_find_basis (CAND_MULT, gs, rhs1, double_int_zero,
1517 integer_one_node, ctype, 0);
1518 c->next_interp = c2->cand_num;
1521 /* Add the first (or only) interpretation to the statement-candidate
1522 mapping. */
1523 add_cand_for_stmt (gs, c);
1526 /* Given GS which is a copy of a scalar integer type, make at least one
1527 appropriate entry in the candidate table.
1529 This interface is included for completeness, but is unnecessary
1530 if this pass immediately follows a pass that performs copy
1531 propagation, such as DOM. */
1533 static void
1534 slsr_process_copy (gimple gs, tree rhs1, bool speed)
1536 slsr_cand_t base_cand, c, c2;
1537 unsigned savings = 0;
1539 base_cand = base_cand_from_table (rhs1);
1541 if (base_cand && base_cand->kind != CAND_PHI)
1543 while (base_cand)
1545 /* Propagate all data from the base candidate. */
1546 if (has_single_use (rhs1))
1547 savings = (base_cand->dead_savings
1548 + stmt_cost (base_cand->cand_stmt, speed));
1550 c = alloc_cand_and_find_basis (base_cand->kind, gs,
1551 base_cand->base_expr,
1552 base_cand->index, base_cand->stride,
1553 base_cand->cand_type, savings);
1554 if (base_cand->next_interp)
1555 base_cand = lookup_cand (base_cand->next_interp);
1556 else
1557 base_cand = NULL;
1560 else
1562 /* If nothing is known about the RHS, create fresh CAND_ADD and
1563 CAND_MULT interpretations:
1565 X = Y + (0 * 1)
1566 X = (Y + 0) * 1
1568 The first of these is somewhat arbitrary, but the choice of
1569 1 for the stride simplifies the logic for propagating casts
1570 into their uses. */
1571 c = alloc_cand_and_find_basis (CAND_ADD, gs, rhs1, double_int_zero,
1572 integer_one_node, TREE_TYPE (rhs1), 0);
1573 c2 = alloc_cand_and_find_basis (CAND_MULT, gs, rhs1, double_int_zero,
1574 integer_one_node, TREE_TYPE (rhs1), 0);
1575 c->next_interp = c2->cand_num;
1578 /* Add the first (or only) interpretation to the statement-candidate
1579 mapping. */
1580 add_cand_for_stmt (gs, c);
1583 class find_candidates_dom_walker : public dom_walker
1585 public:
1586 find_candidates_dom_walker (cdi_direction direction)
1587 : dom_walker (direction) {}
1588 virtual void before_dom_children (basic_block);
1591 /* Find strength-reduction candidates in block BB. */
1593 void
1594 find_candidates_dom_walker::before_dom_children (basic_block bb)
1596 bool speed = optimize_bb_for_speed_p (bb);
1597 gimple_stmt_iterator gsi;
1599 for (gsi = gsi_start_phis (bb); !gsi_end_p (gsi); gsi_next (&gsi))
1600 slsr_process_phi (gsi_stmt (gsi), speed);
1602 for (gsi = gsi_start_bb (bb); !gsi_end_p (gsi); gsi_next (&gsi))
1604 gimple gs = gsi_stmt (gsi);
1606 if (gimple_vuse (gs) && gimple_assign_single_p (gs))
1607 slsr_process_ref (gs);
1609 else if (is_gimple_assign (gs)
1610 && SCALAR_INT_MODE_P
1611 (TYPE_MODE (TREE_TYPE (gimple_assign_lhs (gs)))))
1613 tree rhs1 = NULL_TREE, rhs2 = NULL_TREE;
1615 switch (gimple_assign_rhs_code (gs))
1617 case MULT_EXPR:
1618 case PLUS_EXPR:
1619 rhs1 = gimple_assign_rhs1 (gs);
1620 rhs2 = gimple_assign_rhs2 (gs);
1621 /* Should never happen, but currently some buggy situations
1622 in earlier phases put constants in rhs1. */
1623 if (TREE_CODE (rhs1) != SSA_NAME)
1624 continue;
1625 break;
1627 /* Possible future opportunity: rhs1 of a ptr+ can be
1628 an ADDR_EXPR. */
1629 case POINTER_PLUS_EXPR:
1630 case MINUS_EXPR:
1631 rhs2 = gimple_assign_rhs2 (gs);
1632 /* Fall-through. */
1634 case NOP_EXPR:
1635 case MODIFY_EXPR:
1636 case NEGATE_EXPR:
1637 rhs1 = gimple_assign_rhs1 (gs);
1638 if (TREE_CODE (rhs1) != SSA_NAME)
1639 continue;
1640 break;
1642 default:
1646 switch (gimple_assign_rhs_code (gs))
1648 case MULT_EXPR:
1649 slsr_process_mul (gs, rhs1, rhs2, speed);
1650 break;
1652 case PLUS_EXPR:
1653 case POINTER_PLUS_EXPR:
1654 case MINUS_EXPR:
1655 slsr_process_add (gs, rhs1, rhs2, speed);
1656 break;
1658 case NEGATE_EXPR:
1659 slsr_process_neg (gs, rhs1, speed);
1660 break;
1662 case NOP_EXPR:
1663 slsr_process_cast (gs, rhs1, speed);
1664 break;
1666 case MODIFY_EXPR:
1667 slsr_process_copy (gs, rhs1, speed);
1668 break;
1670 default:
1677 /* Dump a candidate for debug. */
1679 static void
1680 dump_candidate (slsr_cand_t c)
1682 fprintf (dump_file, "%3d [%d] ", c->cand_num,
1683 gimple_bb (c->cand_stmt)->index);
1684 print_gimple_stmt (dump_file, c->cand_stmt, 0, 0);
1685 switch (c->kind)
1687 case CAND_MULT:
1688 fputs (" MULT : (", dump_file);
1689 print_generic_expr (dump_file, c->base_expr, 0);
1690 fputs (" + ", dump_file);
1691 dump_double_int (dump_file, c->index, false);
1692 fputs (") * ", dump_file);
1693 print_generic_expr (dump_file, c->stride, 0);
1694 fputs (" : ", dump_file);
1695 break;
1696 case CAND_ADD:
1697 fputs (" ADD : ", dump_file);
1698 print_generic_expr (dump_file, c->base_expr, 0);
1699 fputs (" + (", dump_file);
1700 dump_double_int (dump_file, c->index, false);
1701 fputs (" * ", dump_file);
1702 print_generic_expr (dump_file, c->stride, 0);
1703 fputs (") : ", dump_file);
1704 break;
1705 case CAND_REF:
1706 fputs (" REF : ", dump_file);
1707 print_generic_expr (dump_file, c->base_expr, 0);
1708 fputs (" + (", dump_file);
1709 print_generic_expr (dump_file, c->stride, 0);
1710 fputs (") + ", dump_file);
1711 dump_double_int (dump_file, c->index, false);
1712 fputs (" : ", dump_file);
1713 break;
1714 case CAND_PHI:
1715 fputs (" PHI : ", dump_file);
1716 print_generic_expr (dump_file, c->base_expr, 0);
1717 fputs (" + (unknown * ", dump_file);
1718 print_generic_expr (dump_file, c->stride, 0);
1719 fputs (") : ", dump_file);
1720 break;
1721 default:
1722 gcc_unreachable ();
1724 print_generic_expr (dump_file, c->cand_type, 0);
1725 fprintf (dump_file, "\n basis: %d dependent: %d sibling: %d\n",
1726 c->basis, c->dependent, c->sibling);
1727 fprintf (dump_file, " next-interp: %d dead-savings: %d\n",
1728 c->next_interp, c->dead_savings);
1729 if (c->def_phi)
1730 fprintf (dump_file, " phi: %d\n", c->def_phi);
1731 fputs ("\n", dump_file);
1734 /* Dump the candidate vector for debug. */
1736 static void
1737 dump_cand_vec (void)
1739 unsigned i;
1740 slsr_cand_t c;
1742 fprintf (dump_file, "\nStrength reduction candidate vector:\n\n");
1744 FOR_EACH_VEC_ELT (cand_vec, i, c)
1745 dump_candidate (c);
1748 /* Callback used to dump the candidate chains hash table. */
1751 ssa_base_cand_dump_callback (cand_chain **slot, void *ignored ATTRIBUTE_UNUSED)
1753 const_cand_chain_t chain = *slot;
1754 cand_chain_t p;
1756 print_generic_expr (dump_file, chain->base_expr, 0);
1757 fprintf (dump_file, " -> %d", chain->cand->cand_num);
1759 for (p = chain->next; p; p = p->next)
1760 fprintf (dump_file, " -> %d", p->cand->cand_num);
1762 fputs ("\n", dump_file);
1763 return 1;
1766 /* Dump the candidate chains. */
1768 static void
1769 dump_cand_chains (void)
1771 fprintf (dump_file, "\nStrength reduction candidate chains:\n\n");
1772 base_cand_map.traverse_noresize <void *, ssa_base_cand_dump_callback> (NULL);
1773 fputs ("\n", dump_file);
1776 /* Dump the increment vector for debug. */
1778 static void
1779 dump_incr_vec (void)
1781 if (dump_file && (dump_flags & TDF_DETAILS))
1783 unsigned i;
1785 fprintf (dump_file, "\nIncrement vector:\n\n");
1787 for (i = 0; i < incr_vec_len; i++)
1789 fprintf (dump_file, "%3d increment: ", i);
1790 dump_double_int (dump_file, incr_vec[i].incr, false);
1791 fprintf (dump_file, "\n count: %d", incr_vec[i].count);
1792 fprintf (dump_file, "\n cost: %d", incr_vec[i].cost);
1793 fputs ("\n initializer: ", dump_file);
1794 print_generic_expr (dump_file, incr_vec[i].initializer, 0);
1795 fputs ("\n\n", dump_file);
1800 /* Replace *EXPR in candidate C with an equivalent strength-reduced
1801 data reference. */
1803 static void
1804 replace_ref (tree *expr, slsr_cand_t c)
1806 tree add_expr, mem_ref, acc_type = TREE_TYPE (*expr);
1807 unsigned HOST_WIDE_INT misalign;
1808 unsigned align;
1810 /* Ensure the memory reference carries the minimum alignment
1811 requirement for the data type. See PR58041. */
1812 get_object_alignment_1 (*expr, &align, &misalign);
1813 if (misalign != 0)
1814 align = (misalign & -misalign);
1815 if (align < TYPE_ALIGN (acc_type))
1816 acc_type = build_aligned_type (acc_type, align);
1818 add_expr = fold_build2 (POINTER_PLUS_EXPR, TREE_TYPE (c->base_expr),
1819 c->base_expr, c->stride);
1820 mem_ref = fold_build2 (MEM_REF, acc_type, add_expr,
1821 double_int_to_tree (c->cand_type, c->index));
1823 /* Gimplify the base addressing expression for the new MEM_REF tree. */
1824 gimple_stmt_iterator gsi = gsi_for_stmt (c->cand_stmt);
1825 TREE_OPERAND (mem_ref, 0)
1826 = force_gimple_operand_gsi (&gsi, TREE_OPERAND (mem_ref, 0),
1827 /*simple_p=*/true, NULL,
1828 /*before=*/true, GSI_SAME_STMT);
1829 copy_ref_info (mem_ref, *expr);
1830 *expr = mem_ref;
1831 update_stmt (c->cand_stmt);
1834 /* Replace CAND_REF candidate C, each sibling of candidate C, and each
1835 dependent of candidate C with an equivalent strength-reduced data
1836 reference. */
1838 static void
1839 replace_refs (slsr_cand_t c)
1841 if (gimple_vdef (c->cand_stmt))
1843 tree *lhs = gimple_assign_lhs_ptr (c->cand_stmt);
1844 replace_ref (lhs, c);
1846 else
1848 tree *rhs = gimple_assign_rhs1_ptr (c->cand_stmt);
1849 replace_ref (rhs, c);
1852 if (c->sibling)
1853 replace_refs (lookup_cand (c->sibling));
1855 if (c->dependent)
1856 replace_refs (lookup_cand (c->dependent));
1859 /* Return TRUE if candidate C is dependent upon a PHI. */
1861 static bool
1862 phi_dependent_cand_p (slsr_cand_t c)
1864 /* A candidate is not necessarily dependent upon a PHI just because
1865 it has a phi definition for its base name. It may have a basis
1866 that relies upon the same phi definition, in which case the PHI
1867 is irrelevant to this candidate. */
1868 return (c->def_phi
1869 && c->basis
1870 && lookup_cand (c->basis)->def_phi != c->def_phi);
1873 /* Calculate the increment required for candidate C relative to
1874 its basis. */
1876 static double_int
1877 cand_increment (slsr_cand_t c)
1879 slsr_cand_t basis;
1881 /* If the candidate doesn't have a basis, just return its own
1882 index. This is useful in record_increments to help us find
1883 an existing initializer. Also, if the candidate's basis is
1884 hidden by a phi, then its own index will be the increment
1885 from the newly introduced phi basis. */
1886 if (!c->basis || phi_dependent_cand_p (c))
1887 return c->index;
1889 basis = lookup_cand (c->basis);
1890 gcc_assert (operand_equal_p (c->base_expr, basis->base_expr, 0));
1891 return c->index - basis->index;
1894 /* Calculate the increment required for candidate C relative to
1895 its basis. If we aren't going to generate pointer arithmetic
1896 for this candidate, return the absolute value of that increment
1897 instead. */
1899 static inline double_int
1900 cand_abs_increment (slsr_cand_t c)
1902 double_int increment = cand_increment (c);
1904 if (!address_arithmetic_p && increment.is_negative ())
1905 increment = -increment;
1907 return increment;
1910 /* Return TRUE iff candidate C has already been replaced under
1911 another interpretation. */
1913 static inline bool
1914 cand_already_replaced (slsr_cand_t c)
1916 return (gimple_bb (c->cand_stmt) == 0);
1919 /* Common logic used by replace_unconditional_candidate and
1920 replace_conditional_candidate. */
1922 static void
1923 replace_mult_candidate (slsr_cand_t c, tree basis_name, double_int bump)
1925 tree target_type = TREE_TYPE (gimple_assign_lhs (c->cand_stmt));
1926 enum tree_code cand_code = gimple_assign_rhs_code (c->cand_stmt);
1928 /* It is highly unlikely, but possible, that the resulting
1929 bump doesn't fit in a HWI. Abandon the replacement
1930 in this case. This does not affect siblings or dependents
1931 of C. Restriction to signed HWI is conservative for unsigned
1932 types but allows for safe negation without twisted logic. */
1933 if (bump.fits_shwi ()
1934 && bump.to_shwi () != HOST_WIDE_INT_MIN
1935 /* It is not useful to replace casts, copies, or adds of
1936 an SSA name and a constant. */
1937 && cand_code != MODIFY_EXPR
1938 && cand_code != NOP_EXPR
1939 && cand_code != PLUS_EXPR
1940 && cand_code != POINTER_PLUS_EXPR
1941 && cand_code != MINUS_EXPR)
1943 enum tree_code code = PLUS_EXPR;
1944 tree bump_tree;
1945 gimple stmt_to_print = NULL;
1947 /* If the basis name and the candidate's LHS have incompatible
1948 types, introduce a cast. */
1949 if (!useless_type_conversion_p (target_type, TREE_TYPE (basis_name)))
1950 basis_name = introduce_cast_before_cand (c, target_type, basis_name);
1951 if (bump.is_negative ())
1953 code = MINUS_EXPR;
1954 bump = -bump;
1957 bump_tree = double_int_to_tree (target_type, bump);
1959 if (dump_file && (dump_flags & TDF_DETAILS))
1961 fputs ("Replacing: ", dump_file);
1962 print_gimple_stmt (dump_file, c->cand_stmt, 0, 0);
1965 if (bump.is_zero ())
1967 tree lhs = gimple_assign_lhs (c->cand_stmt);
1968 gimple copy_stmt = gimple_build_assign (lhs, basis_name);
1969 gimple_stmt_iterator gsi = gsi_for_stmt (c->cand_stmt);
1970 gimple_set_location (copy_stmt, gimple_location (c->cand_stmt));
1971 gsi_replace (&gsi, copy_stmt, false);
1972 c->cand_stmt = copy_stmt;
1973 if (dump_file && (dump_flags & TDF_DETAILS))
1974 stmt_to_print = copy_stmt;
1976 else
1978 tree rhs1, rhs2;
1979 if (cand_code != NEGATE_EXPR) {
1980 rhs1 = gimple_assign_rhs1 (c->cand_stmt);
1981 rhs2 = gimple_assign_rhs2 (c->cand_stmt);
1983 if (cand_code != NEGATE_EXPR
1984 && ((operand_equal_p (rhs1, basis_name, 0)
1985 && operand_equal_p (rhs2, bump_tree, 0))
1986 || (operand_equal_p (rhs1, bump_tree, 0)
1987 && operand_equal_p (rhs2, basis_name, 0))))
1989 if (dump_file && (dump_flags & TDF_DETAILS))
1991 fputs ("(duplicate, not actually replacing)", dump_file);
1992 stmt_to_print = c->cand_stmt;
1995 else
1997 gimple_stmt_iterator gsi = gsi_for_stmt (c->cand_stmt);
1998 gimple_assign_set_rhs_with_ops (&gsi, code,
1999 basis_name, bump_tree);
2000 update_stmt (gsi_stmt (gsi));
2001 c->cand_stmt = gsi_stmt (gsi);
2002 if (dump_file && (dump_flags & TDF_DETAILS))
2003 stmt_to_print = gsi_stmt (gsi);
2007 if (dump_file && (dump_flags & TDF_DETAILS))
2009 fputs ("With: ", dump_file);
2010 print_gimple_stmt (dump_file, stmt_to_print, 0, 0);
2011 fputs ("\n", dump_file);
2016 /* Replace candidate C with an add or subtract. Note that we only
2017 operate on CAND_MULTs with known strides, so we will never generate
2018 a POINTER_PLUS_EXPR. Each candidate X = (B + i) * S is replaced by
2019 X = Y + ((i - i') * S), as described in the module commentary. The
2020 folded value ((i - i') * S) is referred to here as the "bump." */
2022 static void
2023 replace_unconditional_candidate (slsr_cand_t c)
2025 slsr_cand_t basis;
2026 double_int stride, bump;
2028 if (cand_already_replaced (c))
2029 return;
2031 basis = lookup_cand (c->basis);
2032 stride = tree_to_double_int (c->stride);
2033 bump = cand_increment (c) * stride;
2035 replace_mult_candidate (c, gimple_assign_lhs (basis->cand_stmt), bump);
2038 /* Return the index in the increment vector of the given INCREMENT,
2039 or -1 if not found. The latter can occur if more than
2040 MAX_INCR_VEC_LEN increments have been found. */
2042 static inline int
2043 incr_vec_index (double_int increment)
2045 unsigned i;
2047 for (i = 0; i < incr_vec_len && increment != incr_vec[i].incr; i++)
2050 if (i < incr_vec_len)
2051 return i;
2052 else
2053 return -1;
2056 /* Create a new statement along edge E to add BASIS_NAME to the product
2057 of INCREMENT and the stride of candidate C. Create and return a new
2058 SSA name from *VAR to be used as the LHS of the new statement.
2059 KNOWN_STRIDE is true iff C's stride is a constant. */
2061 static tree
2062 create_add_on_incoming_edge (slsr_cand_t c, tree basis_name,
2063 double_int increment, edge e, location_t loc,
2064 bool known_stride)
2066 basic_block insert_bb;
2067 gimple_stmt_iterator gsi;
2068 tree lhs, basis_type;
2069 gimple new_stmt;
2071 /* If the add candidate along this incoming edge has the same
2072 index as C's hidden basis, the hidden basis represents this
2073 edge correctly. */
2074 if (increment.is_zero ())
2075 return basis_name;
2077 basis_type = TREE_TYPE (basis_name);
2078 lhs = make_temp_ssa_name (basis_type, NULL, "slsr");
2080 if (known_stride)
2082 tree bump_tree;
2083 enum tree_code code = PLUS_EXPR;
2084 double_int bump = increment * tree_to_double_int (c->stride);
2085 if (bump.is_negative ())
2087 code = MINUS_EXPR;
2088 bump = -bump;
2091 bump_tree = double_int_to_tree (basis_type, bump);
2092 new_stmt = gimple_build_assign_with_ops (code, lhs, basis_name,
2093 bump_tree);
2095 else
2097 int i;
2098 bool negate_incr = (!address_arithmetic_p && increment.is_negative ());
2099 i = incr_vec_index (negate_incr ? -increment : increment);
2100 gcc_assert (i >= 0);
2102 if (incr_vec[i].initializer)
2104 enum tree_code code = negate_incr ? MINUS_EXPR : PLUS_EXPR;
2105 new_stmt = gimple_build_assign_with_ops (code, lhs, basis_name,
2106 incr_vec[i].initializer);
2108 else if (increment.is_one ())
2109 new_stmt = gimple_build_assign_with_ops (PLUS_EXPR, lhs, basis_name,
2110 c->stride);
2111 else if (increment.is_minus_one ())
2112 new_stmt = gimple_build_assign_with_ops (MINUS_EXPR, lhs, basis_name,
2113 c->stride);
2114 else
2115 gcc_unreachable ();
2118 insert_bb = single_succ_p (e->src) ? e->src : split_edge (e);
2119 gsi = gsi_last_bb (insert_bb);
2121 if (!gsi_end_p (gsi) && is_ctrl_stmt (gsi_stmt (gsi)))
2122 gsi_insert_before (&gsi, new_stmt, GSI_NEW_STMT);
2123 else
2124 gsi_insert_after (&gsi, new_stmt, GSI_NEW_STMT);
2126 gimple_set_location (new_stmt, loc);
2128 if (dump_file && (dump_flags & TDF_DETAILS))
2130 fprintf (dump_file, "Inserting in block %d: ", insert_bb->index);
2131 print_gimple_stmt (dump_file, new_stmt, 0, 0);
2134 return lhs;
2137 /* Given a candidate C with BASIS_NAME being the LHS of C's basis which
2138 is hidden by the phi node FROM_PHI, create a new phi node in the same
2139 block as FROM_PHI. The new phi is suitable for use as a basis by C,
2140 with its phi arguments representing conditional adjustments to the
2141 hidden basis along conditional incoming paths. Those adjustments are
2142 made by creating add statements (and sometimes recursively creating
2143 phis) along those incoming paths. LOC is the location to attach to
2144 the introduced statements. KNOWN_STRIDE is true iff C's stride is a
2145 constant. */
2147 static tree
2148 create_phi_basis (slsr_cand_t c, gimple from_phi, tree basis_name,
2149 location_t loc, bool known_stride)
2151 int i;
2152 tree name, phi_arg;
2153 gimple phi;
2154 vec<tree> phi_args;
2155 slsr_cand_t basis = lookup_cand (c->basis);
2156 int nargs = gimple_phi_num_args (from_phi);
2157 basic_block phi_bb = gimple_bb (from_phi);
2158 slsr_cand_t phi_cand = base_cand_from_table (gimple_phi_result (from_phi));
2159 phi_args.create (nargs);
2161 /* Process each argument of the existing phi that represents
2162 conditionally-executed add candidates. */
2163 for (i = 0; i < nargs; i++)
2165 edge e = (*phi_bb->preds)[i];
2166 tree arg = gimple_phi_arg_def (from_phi, i);
2167 tree feeding_def;
2169 /* If the phi argument is the base name of the CAND_PHI, then
2170 this incoming arc should use the hidden basis. */
2171 if (operand_equal_p (arg, phi_cand->base_expr, 0))
2172 if (basis->index.is_zero ())
2173 feeding_def = gimple_assign_lhs (basis->cand_stmt);
2174 else
2176 double_int incr = -basis->index;
2177 feeding_def = create_add_on_incoming_edge (c, basis_name, incr,
2178 e, loc, known_stride);
2180 else
2182 gimple arg_def = SSA_NAME_DEF_STMT (arg);
2184 /* If there is another phi along this incoming edge, we must
2185 process it in the same fashion to ensure that all basis
2186 adjustments are made along its incoming edges. */
2187 if (gimple_code (arg_def) == GIMPLE_PHI)
2188 feeding_def = create_phi_basis (c, arg_def, basis_name,
2189 loc, known_stride);
2190 else
2192 slsr_cand_t arg_cand = base_cand_from_table (arg);
2193 double_int diff = arg_cand->index - basis->index;
2194 feeding_def = create_add_on_incoming_edge (c, basis_name, diff,
2195 e, loc, known_stride);
2199 /* Because of recursion, we need to save the arguments in a vector
2200 so we can create the PHI statement all at once. Otherwise the
2201 storage for the half-created PHI can be reclaimed. */
2202 phi_args.safe_push (feeding_def);
2205 /* Create the new phi basis. */
2206 name = make_temp_ssa_name (TREE_TYPE (basis_name), NULL, "slsr");
2207 phi = create_phi_node (name, phi_bb);
2208 SSA_NAME_DEF_STMT (name) = phi;
2210 FOR_EACH_VEC_ELT (phi_args, i, phi_arg)
2212 edge e = (*phi_bb->preds)[i];
2213 add_phi_arg (phi, phi_arg, e, loc);
2216 update_stmt (phi);
2218 if (dump_file && (dump_flags & TDF_DETAILS))
2220 fputs ("Introducing new phi basis: ", dump_file);
2221 print_gimple_stmt (dump_file, phi, 0, 0);
2224 return name;
2227 /* Given a candidate C whose basis is hidden by at least one intervening
2228 phi, introduce a matching number of new phis to represent its basis
2229 adjusted by conditional increments along possible incoming paths. Then
2230 replace C as though it were an unconditional candidate, using the new
2231 basis. */
2233 static void
2234 replace_conditional_candidate (slsr_cand_t c)
2236 tree basis_name, name;
2237 slsr_cand_t basis;
2238 location_t loc;
2239 double_int stride, bump;
2241 /* Look up the LHS SSA name from C's basis. This will be the
2242 RHS1 of the adds we will introduce to create new phi arguments. */
2243 basis = lookup_cand (c->basis);
2244 basis_name = gimple_assign_lhs (basis->cand_stmt);
2246 /* Create a new phi statement which will represent C's true basis
2247 after the transformation is complete. */
2248 loc = gimple_location (c->cand_stmt);
2249 name = create_phi_basis (c, lookup_cand (c->def_phi)->cand_stmt,
2250 basis_name, loc, KNOWN_STRIDE);
2251 /* Replace C with an add of the new basis phi and a constant. */
2252 stride = tree_to_double_int (c->stride);
2253 bump = c->index * stride;
2255 replace_mult_candidate (c, name, bump);
2258 /* Compute the expected costs of inserting basis adjustments for
2259 candidate C with phi-definition PHI. The cost of inserting
2260 one adjustment is given by ONE_ADD_COST. If PHI has arguments
2261 which are themselves phi results, recursively calculate costs
2262 for those phis as well. */
2264 static int
2265 phi_add_costs (gimple phi, slsr_cand_t c, int one_add_cost)
2267 unsigned i;
2268 int cost = 0;
2269 slsr_cand_t phi_cand = base_cand_from_table (gimple_phi_result (phi));
2271 /* If we work our way back to a phi that isn't dominated by the hidden
2272 basis, this isn't a candidate for replacement. Indicate this by
2273 returning an unreasonably high cost. It's not easy to detect
2274 these situations when determining the basis, so we defer the
2275 decision until now. */
2276 basic_block phi_bb = gimple_bb (phi);
2277 slsr_cand_t basis = lookup_cand (c->basis);
2278 basic_block basis_bb = gimple_bb (basis->cand_stmt);
2280 if (phi_bb == basis_bb || !dominated_by_p (CDI_DOMINATORS, phi_bb, basis_bb))
2281 return COST_INFINITE;
2283 for (i = 0; i < gimple_phi_num_args (phi); i++)
2285 tree arg = gimple_phi_arg_def (phi, i);
2287 if (arg != phi_cand->base_expr)
2289 gimple arg_def = SSA_NAME_DEF_STMT (arg);
2291 if (gimple_code (arg_def) == GIMPLE_PHI)
2292 cost += phi_add_costs (arg_def, c, one_add_cost);
2293 else
2295 slsr_cand_t arg_cand = base_cand_from_table (arg);
2297 if (arg_cand->index != c->index)
2298 cost += one_add_cost;
2303 return cost;
2306 /* For candidate C, each sibling of candidate C, and each dependent of
2307 candidate C, determine whether the candidate is dependent upon a
2308 phi that hides its basis. If not, replace the candidate unconditionally.
2309 Otherwise, determine whether the cost of introducing compensation code
2310 for the candidate is offset by the gains from strength reduction. If
2311 so, replace the candidate and introduce the compensation code. */
2313 static void
2314 replace_uncond_cands_and_profitable_phis (slsr_cand_t c)
2316 if (phi_dependent_cand_p (c))
2318 if (c->kind == CAND_MULT)
2320 /* A candidate dependent upon a phi will replace a multiply by
2321 a constant with an add, and will insert at most one add for
2322 each phi argument. Add these costs with the potential dead-code
2323 savings to determine profitability. */
2324 bool speed = optimize_bb_for_speed_p (gimple_bb (c->cand_stmt));
2325 int mult_savings = stmt_cost (c->cand_stmt, speed);
2326 gimple phi = lookup_cand (c->def_phi)->cand_stmt;
2327 tree phi_result = gimple_phi_result (phi);
2328 int one_add_cost = add_cost (speed,
2329 TYPE_MODE (TREE_TYPE (phi_result)));
2330 int add_costs = one_add_cost + phi_add_costs (phi, c, one_add_cost);
2331 int cost = add_costs - mult_savings - c->dead_savings;
2333 if (dump_file && (dump_flags & TDF_DETAILS))
2335 fprintf (dump_file, " Conditional candidate %d:\n", c->cand_num);
2336 fprintf (dump_file, " add_costs = %d\n", add_costs);
2337 fprintf (dump_file, " mult_savings = %d\n", mult_savings);
2338 fprintf (dump_file, " dead_savings = %d\n", c->dead_savings);
2339 fprintf (dump_file, " cost = %d\n", cost);
2340 if (cost <= COST_NEUTRAL)
2341 fputs (" Replacing...\n", dump_file);
2342 else
2343 fputs (" Not replaced.\n", dump_file);
2346 if (cost <= COST_NEUTRAL)
2347 replace_conditional_candidate (c);
2350 else
2351 replace_unconditional_candidate (c);
2353 if (c->sibling)
2354 replace_uncond_cands_and_profitable_phis (lookup_cand (c->sibling));
2356 if (c->dependent)
2357 replace_uncond_cands_and_profitable_phis (lookup_cand (c->dependent));
2360 /* Count the number of candidates in the tree rooted at C that have
2361 not already been replaced under other interpretations. */
2363 static int
2364 count_candidates (slsr_cand_t c)
2366 unsigned count = cand_already_replaced (c) ? 0 : 1;
2368 if (c->sibling)
2369 count += count_candidates (lookup_cand (c->sibling));
2371 if (c->dependent)
2372 count += count_candidates (lookup_cand (c->dependent));
2374 return count;
2377 /* Increase the count of INCREMENT by one in the increment vector.
2378 INCREMENT is associated with candidate C. If INCREMENT is to be
2379 conditionally executed as part of a conditional candidate replacement,
2380 IS_PHI_ADJUST is true, otherwise false. If an initializer
2381 T_0 = stride * I is provided by a candidate that dominates all
2382 candidates with the same increment, also record T_0 for subsequent use. */
2384 static void
2385 record_increment (slsr_cand_t c, double_int increment, bool is_phi_adjust)
2387 bool found = false;
2388 unsigned i;
2390 /* Treat increments that differ only in sign as identical so as to
2391 share initializers, unless we are generating pointer arithmetic. */
2392 if (!address_arithmetic_p && increment.is_negative ())
2393 increment = -increment;
2395 for (i = 0; i < incr_vec_len; i++)
2397 if (incr_vec[i].incr == increment)
2399 incr_vec[i].count++;
2400 found = true;
2402 /* If we previously recorded an initializer that doesn't
2403 dominate this candidate, it's not going to be useful to
2404 us after all. */
2405 if (incr_vec[i].initializer
2406 && !dominated_by_p (CDI_DOMINATORS,
2407 gimple_bb (c->cand_stmt),
2408 incr_vec[i].init_bb))
2410 incr_vec[i].initializer = NULL_TREE;
2411 incr_vec[i].init_bb = NULL;
2414 break;
2418 if (!found && incr_vec_len < MAX_INCR_VEC_LEN - 1)
2420 /* The first time we see an increment, create the entry for it.
2421 If this is the root candidate which doesn't have a basis, set
2422 the count to zero. We're only processing it so it can possibly
2423 provide an initializer for other candidates. */
2424 incr_vec[incr_vec_len].incr = increment;
2425 incr_vec[incr_vec_len].count = c->basis || is_phi_adjust ? 1 : 0;
2426 incr_vec[incr_vec_len].cost = COST_INFINITE;
2428 /* Optimistically record the first occurrence of this increment
2429 as providing an initializer (if it does); we will revise this
2430 opinion later if it doesn't dominate all other occurrences.
2431 Exception: increments of -1, 0, 1 never need initializers;
2432 and phi adjustments don't ever provide initializers. */
2433 if (c->kind == CAND_ADD
2434 && !is_phi_adjust
2435 && c->index == increment
2436 && (increment.sgt (double_int_one)
2437 || increment.slt (double_int_minus_one))
2438 && (gimple_assign_rhs_code (c->cand_stmt) == PLUS_EXPR
2439 || gimple_assign_rhs_code (c->cand_stmt) == POINTER_PLUS_EXPR))
2441 tree t0 = NULL_TREE;
2442 tree rhs1 = gimple_assign_rhs1 (c->cand_stmt);
2443 tree rhs2 = gimple_assign_rhs2 (c->cand_stmt);
2444 if (operand_equal_p (rhs1, c->base_expr, 0))
2445 t0 = rhs2;
2446 else if (operand_equal_p (rhs2, c->base_expr, 0))
2447 t0 = rhs1;
2448 if (t0
2449 && SSA_NAME_DEF_STMT (t0)
2450 && gimple_bb (SSA_NAME_DEF_STMT (t0)))
2452 incr_vec[incr_vec_len].initializer = t0;
2453 incr_vec[incr_vec_len++].init_bb
2454 = gimple_bb (SSA_NAME_DEF_STMT (t0));
2456 else
2458 incr_vec[incr_vec_len].initializer = NULL_TREE;
2459 incr_vec[incr_vec_len++].init_bb = NULL;
2462 else
2464 incr_vec[incr_vec_len].initializer = NULL_TREE;
2465 incr_vec[incr_vec_len++].init_bb = NULL;
2470 /* Given phi statement PHI that hides a candidate from its BASIS, find
2471 the increments along each incoming arc (recursively handling additional
2472 phis that may be present) and record them. These increments are the
2473 difference in index between the index-adjusting statements and the
2474 index of the basis. */
2476 static void
2477 record_phi_increments (slsr_cand_t basis, gimple phi)
2479 unsigned i;
2480 slsr_cand_t phi_cand = base_cand_from_table (gimple_phi_result (phi));
2482 for (i = 0; i < gimple_phi_num_args (phi); i++)
2484 tree arg = gimple_phi_arg_def (phi, i);
2486 if (!operand_equal_p (arg, phi_cand->base_expr, 0))
2488 gimple arg_def = SSA_NAME_DEF_STMT (arg);
2490 if (gimple_code (arg_def) == GIMPLE_PHI)
2491 record_phi_increments (basis, arg_def);
2492 else
2494 slsr_cand_t arg_cand = base_cand_from_table (arg);
2495 double_int diff = arg_cand->index - basis->index;
2496 record_increment (arg_cand, diff, PHI_ADJUST);
2502 /* Determine how many times each unique increment occurs in the set
2503 of candidates rooted at C's parent, recording the data in the
2504 increment vector. For each unique increment I, if an initializer
2505 T_0 = stride * I is provided by a candidate that dominates all
2506 candidates with the same increment, also record T_0 for subsequent
2507 use. */
2509 static void
2510 record_increments (slsr_cand_t c)
2512 if (!cand_already_replaced (c))
2514 if (!phi_dependent_cand_p (c))
2515 record_increment (c, cand_increment (c), NOT_PHI_ADJUST);
2516 else
2518 /* A candidate with a basis hidden by a phi will have one
2519 increment for its relationship to the index represented by
2520 the phi, and potentially additional increments along each
2521 incoming edge. For the root of the dependency tree (which
2522 has no basis), process just the initial index in case it has
2523 an initializer that can be used by subsequent candidates. */
2524 record_increment (c, c->index, NOT_PHI_ADJUST);
2526 if (c->basis)
2527 record_phi_increments (lookup_cand (c->basis),
2528 lookup_cand (c->def_phi)->cand_stmt);
2532 if (c->sibling)
2533 record_increments (lookup_cand (c->sibling));
2535 if (c->dependent)
2536 record_increments (lookup_cand (c->dependent));
2539 /* Add up and return the costs of introducing add statements that
2540 require the increment INCR on behalf of candidate C and phi
2541 statement PHI. Accumulate into *SAVINGS the potential savings
2542 from removing existing statements that feed PHI and have no other
2543 uses. */
2545 static int
2546 phi_incr_cost (slsr_cand_t c, double_int incr, gimple phi, int *savings)
2548 unsigned i;
2549 int cost = 0;
2550 slsr_cand_t basis = lookup_cand (c->basis);
2551 slsr_cand_t phi_cand = base_cand_from_table (gimple_phi_result (phi));
2553 for (i = 0; i < gimple_phi_num_args (phi); i++)
2555 tree arg = gimple_phi_arg_def (phi, i);
2557 if (!operand_equal_p (arg, phi_cand->base_expr, 0))
2559 gimple arg_def = SSA_NAME_DEF_STMT (arg);
2561 if (gimple_code (arg_def) == GIMPLE_PHI)
2563 int feeding_savings = 0;
2564 cost += phi_incr_cost (c, incr, arg_def, &feeding_savings);
2565 if (has_single_use (gimple_phi_result (arg_def)))
2566 *savings += feeding_savings;
2568 else
2570 slsr_cand_t arg_cand = base_cand_from_table (arg);
2571 double_int diff = arg_cand->index - basis->index;
2573 if (incr == diff)
2575 tree basis_lhs = gimple_assign_lhs (basis->cand_stmt);
2576 tree lhs = gimple_assign_lhs (arg_cand->cand_stmt);
2577 cost += add_cost (true, TYPE_MODE (TREE_TYPE (basis_lhs)));
2578 if (has_single_use (lhs))
2579 *savings += stmt_cost (arg_cand->cand_stmt, true);
2585 return cost;
2588 /* Return the first candidate in the tree rooted at C that has not
2589 already been replaced, favoring siblings over dependents. */
2591 static slsr_cand_t
2592 unreplaced_cand_in_tree (slsr_cand_t c)
2594 if (!cand_already_replaced (c))
2595 return c;
2597 if (c->sibling)
2599 slsr_cand_t sib = unreplaced_cand_in_tree (lookup_cand (c->sibling));
2600 if (sib)
2601 return sib;
2604 if (c->dependent)
2606 slsr_cand_t dep = unreplaced_cand_in_tree (lookup_cand (c->dependent));
2607 if (dep)
2608 return dep;
2611 return NULL;
2614 /* Return TRUE if the candidates in the tree rooted at C should be
2615 optimized for speed, else FALSE. We estimate this based on the block
2616 containing the most dominant candidate in the tree that has not yet
2617 been replaced. */
2619 static bool
2620 optimize_cands_for_speed_p (slsr_cand_t c)
2622 slsr_cand_t c2 = unreplaced_cand_in_tree (c);
2623 gcc_assert (c2);
2624 return optimize_bb_for_speed_p (gimple_bb (c2->cand_stmt));
2627 /* Add COST_IN to the lowest cost of any dependent path starting at
2628 candidate C or any of its siblings, counting only candidates along
2629 such paths with increment INCR. Assume that replacing a candidate
2630 reduces cost by REPL_SAVINGS. Also account for savings from any
2631 statements that would go dead. If COUNT_PHIS is true, include
2632 costs of introducing feeding statements for conditional candidates. */
2634 static int
2635 lowest_cost_path (int cost_in, int repl_savings, slsr_cand_t c,
2636 double_int incr, bool count_phis)
2638 int local_cost, sib_cost, savings = 0;
2639 double_int cand_incr = cand_abs_increment (c);
2641 if (cand_already_replaced (c))
2642 local_cost = cost_in;
2643 else if (incr == cand_incr)
2644 local_cost = cost_in - repl_savings - c->dead_savings;
2645 else
2646 local_cost = cost_in - c->dead_savings;
2648 if (count_phis
2649 && phi_dependent_cand_p (c)
2650 && !cand_already_replaced (c))
2652 gimple phi = lookup_cand (c->def_phi)->cand_stmt;
2653 local_cost += phi_incr_cost (c, incr, phi, &savings);
2655 if (has_single_use (gimple_phi_result (phi)))
2656 local_cost -= savings;
2659 if (c->dependent)
2660 local_cost = lowest_cost_path (local_cost, repl_savings,
2661 lookup_cand (c->dependent), incr,
2662 count_phis);
2664 if (c->sibling)
2666 sib_cost = lowest_cost_path (cost_in, repl_savings,
2667 lookup_cand (c->sibling), incr,
2668 count_phis);
2669 local_cost = MIN (local_cost, sib_cost);
2672 return local_cost;
2675 /* Compute the total savings that would accrue from all replacements
2676 in the candidate tree rooted at C, counting only candidates with
2677 increment INCR. Assume that replacing a candidate reduces cost
2678 by REPL_SAVINGS. Also account for savings from statements that
2679 would go dead. */
2681 static int
2682 total_savings (int repl_savings, slsr_cand_t c, double_int incr,
2683 bool count_phis)
2685 int savings = 0;
2686 double_int cand_incr = cand_abs_increment (c);
2688 if (incr == cand_incr && !cand_already_replaced (c))
2689 savings += repl_savings + c->dead_savings;
2691 if (count_phis
2692 && phi_dependent_cand_p (c)
2693 && !cand_already_replaced (c))
2695 int phi_savings = 0;
2696 gimple phi = lookup_cand (c->def_phi)->cand_stmt;
2697 savings -= phi_incr_cost (c, incr, phi, &phi_savings);
2699 if (has_single_use (gimple_phi_result (phi)))
2700 savings += phi_savings;
2703 if (c->dependent)
2704 savings += total_savings (repl_savings, lookup_cand (c->dependent), incr,
2705 count_phis);
2707 if (c->sibling)
2708 savings += total_savings (repl_savings, lookup_cand (c->sibling), incr,
2709 count_phis);
2711 return savings;
2714 /* Use target-specific costs to determine and record which increments
2715 in the current candidate tree are profitable to replace, assuming
2716 MODE and SPEED. FIRST_DEP is the first dependent of the root of
2717 the candidate tree.
2719 One slight limitation here is that we don't account for the possible
2720 introduction of casts in some cases. See replace_one_candidate for
2721 the cases where these are introduced. This should probably be cleaned
2722 up sometime. */
2724 static void
2725 analyze_increments (slsr_cand_t first_dep, enum machine_mode mode, bool speed)
2727 unsigned i;
2729 for (i = 0; i < incr_vec_len; i++)
2731 HOST_WIDE_INT incr = incr_vec[i].incr.to_shwi ();
2733 /* If somehow this increment is bigger than a HWI, we won't
2734 be optimizing candidates that use it. And if the increment
2735 has a count of zero, nothing will be done with it. */
2736 if (!incr_vec[i].incr.fits_shwi () || !incr_vec[i].count)
2737 incr_vec[i].cost = COST_INFINITE;
2739 /* Increments of 0, 1, and -1 are always profitable to replace,
2740 because they always replace a multiply or add with an add or
2741 copy, and may cause one or more existing instructions to go
2742 dead. Exception: -1 can't be assumed to be profitable for
2743 pointer addition. */
2744 else if (incr == 0
2745 || incr == 1
2746 || (incr == -1
2747 && (gimple_assign_rhs_code (first_dep->cand_stmt)
2748 != POINTER_PLUS_EXPR)))
2749 incr_vec[i].cost = COST_NEUTRAL;
2751 /* FORNOW: If we need to add an initializer, give up if a cast from
2752 the candidate's type to its stride's type can lose precision.
2753 This could eventually be handled better by expressly retaining the
2754 result of a cast to a wider type in the stride. Example:
2756 short int _1;
2757 _2 = (int) _1;
2758 _3 = _2 * 10;
2759 _4 = x + _3; ADD: x + (10 * _1) : int
2760 _5 = _2 * 15;
2761 _6 = x + _3; ADD: x + (15 * _1) : int
2763 Right now replacing _6 would cause insertion of an initializer
2764 of the form "short int T = _1 * 5;" followed by a cast to
2765 int, which could overflow incorrectly. Had we recorded _2 or
2766 (int)_1 as the stride, this wouldn't happen. However, doing
2767 this breaks other opportunities, so this will require some
2768 care. */
2769 else if (!incr_vec[i].initializer
2770 && TREE_CODE (first_dep->stride) != INTEGER_CST
2771 && !legal_cast_p_1 (first_dep->stride,
2772 gimple_assign_lhs (first_dep->cand_stmt)))
2774 incr_vec[i].cost = COST_INFINITE;
2776 /* If we need to add an initializer, make sure we don't introduce
2777 a multiply by a pointer type, which can happen in certain cast
2778 scenarios. FIXME: When cleaning up these cast issues, we can
2779 afford to introduce the multiply provided we cast out to an
2780 unsigned int of appropriate size. */
2781 else if (!incr_vec[i].initializer
2782 && TREE_CODE (first_dep->stride) != INTEGER_CST
2783 && POINTER_TYPE_P (TREE_TYPE (first_dep->stride)))
2785 incr_vec[i].cost = COST_INFINITE;
2787 /* For any other increment, if this is a multiply candidate, we
2788 must introduce a temporary T and initialize it with
2789 T_0 = stride * increment. When optimizing for speed, walk the
2790 candidate tree to calculate the best cost reduction along any
2791 path; if it offsets the fixed cost of inserting the initializer,
2792 replacing the increment is profitable. When optimizing for
2793 size, instead calculate the total cost reduction from replacing
2794 all candidates with this increment. */
2795 else if (first_dep->kind == CAND_MULT)
2797 int cost = mult_by_coeff_cost (incr, mode, speed);
2798 int repl_savings = mul_cost (speed, mode) - add_cost (speed, mode);
2799 if (speed)
2800 cost = lowest_cost_path (cost, repl_savings, first_dep,
2801 incr_vec[i].incr, COUNT_PHIS);
2802 else
2803 cost -= total_savings (repl_savings, first_dep, incr_vec[i].incr,
2804 COUNT_PHIS);
2806 incr_vec[i].cost = cost;
2809 /* If this is an add candidate, the initializer may already
2810 exist, so only calculate the cost of the initializer if it
2811 doesn't. We are replacing one add with another here, so the
2812 known replacement savings is zero. We will account for removal
2813 of dead instructions in lowest_cost_path or total_savings. */
2814 else
2816 int cost = 0;
2817 if (!incr_vec[i].initializer)
2818 cost = mult_by_coeff_cost (incr, mode, speed);
2820 if (speed)
2821 cost = lowest_cost_path (cost, 0, first_dep, incr_vec[i].incr,
2822 DONT_COUNT_PHIS);
2823 else
2824 cost -= total_savings (0, first_dep, incr_vec[i].incr,
2825 DONT_COUNT_PHIS);
2827 incr_vec[i].cost = cost;
2832 /* Return the nearest common dominator of BB1 and BB2. If the blocks
2833 are identical, return the earlier of C1 and C2 in *WHERE. Otherwise,
2834 if the NCD matches BB1, return C1 in *WHERE; if the NCD matches BB2,
2835 return C2 in *WHERE; and if the NCD matches neither, return NULL in
2836 *WHERE. Note: It is possible for one of C1 and C2 to be NULL. */
2838 static basic_block
2839 ncd_for_two_cands (basic_block bb1, basic_block bb2,
2840 slsr_cand_t c1, slsr_cand_t c2, slsr_cand_t *where)
2842 basic_block ncd;
2844 if (!bb1)
2846 *where = c2;
2847 return bb2;
2850 if (!bb2)
2852 *where = c1;
2853 return bb1;
2856 ncd = nearest_common_dominator (CDI_DOMINATORS, bb1, bb2);
2858 /* If both candidates are in the same block, the earlier
2859 candidate wins. */
2860 if (bb1 == ncd && bb2 == ncd)
2862 if (!c1 || (c2 && c2->cand_num < c1->cand_num))
2863 *where = c2;
2864 else
2865 *where = c1;
2868 /* Otherwise, if one of them produced a candidate in the
2869 dominator, that one wins. */
2870 else if (bb1 == ncd)
2871 *where = c1;
2873 else if (bb2 == ncd)
2874 *where = c2;
2876 /* If neither matches the dominator, neither wins. */
2877 else
2878 *where = NULL;
2880 return ncd;
2883 /* Consider all candidates that feed PHI. Find the nearest common
2884 dominator of those candidates requiring the given increment INCR.
2885 Further find and return the nearest common dominator of this result
2886 with block NCD. If the returned block contains one or more of the
2887 candidates, return the earliest candidate in the block in *WHERE. */
2889 static basic_block
2890 ncd_with_phi (slsr_cand_t c, double_int incr, gimple phi,
2891 basic_block ncd, slsr_cand_t *where)
2893 unsigned i;
2894 slsr_cand_t basis = lookup_cand (c->basis);
2895 slsr_cand_t phi_cand = base_cand_from_table (gimple_phi_result (phi));
2897 for (i = 0; i < gimple_phi_num_args (phi); i++)
2899 tree arg = gimple_phi_arg_def (phi, i);
2901 if (!operand_equal_p (arg, phi_cand->base_expr, 0))
2903 gimple arg_def = SSA_NAME_DEF_STMT (arg);
2905 if (gimple_code (arg_def) == GIMPLE_PHI)
2906 ncd = ncd_with_phi (c, incr, arg_def, ncd, where);
2907 else
2909 slsr_cand_t arg_cand = base_cand_from_table (arg);
2910 double_int diff = arg_cand->index - basis->index;
2912 if ((incr == diff) || (!address_arithmetic_p && incr == -diff))
2913 ncd = ncd_for_two_cands (ncd, gimple_bb (arg_cand->cand_stmt),
2914 *where, arg_cand, where);
2919 return ncd;
2922 /* Consider the candidate C together with any candidates that feed
2923 C's phi dependence (if any). Find and return the nearest common
2924 dominator of those candidates requiring the given increment INCR.
2925 If the returned block contains one or more of the candidates,
2926 return the earliest candidate in the block in *WHERE. */
2928 static basic_block
2929 ncd_of_cand_and_phis (slsr_cand_t c, double_int incr, slsr_cand_t *where)
2931 basic_block ncd = NULL;
2933 if (cand_abs_increment (c) == incr)
2935 ncd = gimple_bb (c->cand_stmt);
2936 *where = c;
2939 if (phi_dependent_cand_p (c))
2940 ncd = ncd_with_phi (c, incr, lookup_cand (c->def_phi)->cand_stmt,
2941 ncd, where);
2943 return ncd;
2946 /* Consider all candidates in the tree rooted at C for which INCR
2947 represents the required increment of C relative to its basis.
2948 Find and return the basic block that most nearly dominates all
2949 such candidates. If the returned block contains one or more of
2950 the candidates, return the earliest candidate in the block in
2951 *WHERE. */
2953 static basic_block
2954 nearest_common_dominator_for_cands (slsr_cand_t c, double_int incr,
2955 slsr_cand_t *where)
2957 basic_block sib_ncd = NULL, dep_ncd = NULL, this_ncd = NULL, ncd;
2958 slsr_cand_t sib_where = NULL, dep_where = NULL, this_where = NULL, new_where;
2960 /* First find the NCD of all siblings and dependents. */
2961 if (c->sibling)
2962 sib_ncd = nearest_common_dominator_for_cands (lookup_cand (c->sibling),
2963 incr, &sib_where);
2964 if (c->dependent)
2965 dep_ncd = nearest_common_dominator_for_cands (lookup_cand (c->dependent),
2966 incr, &dep_where);
2967 if (!sib_ncd && !dep_ncd)
2969 new_where = NULL;
2970 ncd = NULL;
2972 else if (sib_ncd && !dep_ncd)
2974 new_where = sib_where;
2975 ncd = sib_ncd;
2977 else if (dep_ncd && !sib_ncd)
2979 new_where = dep_where;
2980 ncd = dep_ncd;
2982 else
2983 ncd = ncd_for_two_cands (sib_ncd, dep_ncd, sib_where,
2984 dep_where, &new_where);
2986 /* If the candidate's increment doesn't match the one we're interested
2987 in (and nor do any increments for feeding defs of a phi-dependence),
2988 then the result depends only on siblings and dependents. */
2989 this_ncd = ncd_of_cand_and_phis (c, incr, &this_where);
2991 if (!this_ncd || cand_already_replaced (c))
2993 *where = new_where;
2994 return ncd;
2997 /* Otherwise, compare this candidate with the result from all siblings
2998 and dependents. */
2999 ncd = ncd_for_two_cands (ncd, this_ncd, new_where, this_where, where);
3001 return ncd;
3004 /* Return TRUE if the increment indexed by INDEX is profitable to replace. */
3006 static inline bool
3007 profitable_increment_p (unsigned index)
3009 return (incr_vec[index].cost <= COST_NEUTRAL);
3012 /* For each profitable increment in the increment vector not equal to
3013 0 or 1 (or -1, for non-pointer arithmetic), find the nearest common
3014 dominator of all statements in the candidate chain rooted at C
3015 that require that increment, and insert an initializer
3016 T_0 = stride * increment at that location. Record T_0 with the
3017 increment record. */
3019 static void
3020 insert_initializers (slsr_cand_t c)
3022 unsigned i;
3024 for (i = 0; i < incr_vec_len; i++)
3026 basic_block bb;
3027 slsr_cand_t where = NULL;
3028 gimple init_stmt;
3029 tree stride_type, new_name, incr_tree;
3030 double_int incr = incr_vec[i].incr;
3032 if (!profitable_increment_p (i)
3033 || incr.is_one ()
3034 || (incr.is_minus_one ()
3035 && gimple_assign_rhs_code (c->cand_stmt) != POINTER_PLUS_EXPR)
3036 || incr.is_zero ())
3037 continue;
3039 /* We may have already identified an existing initializer that
3040 will suffice. */
3041 if (incr_vec[i].initializer)
3043 if (dump_file && (dump_flags & TDF_DETAILS))
3045 fputs ("Using existing initializer: ", dump_file);
3046 print_gimple_stmt (dump_file,
3047 SSA_NAME_DEF_STMT (incr_vec[i].initializer),
3048 0, 0);
3050 continue;
3053 /* Find the block that most closely dominates all candidates
3054 with this increment. If there is at least one candidate in
3055 that block, the earliest one will be returned in WHERE. */
3056 bb = nearest_common_dominator_for_cands (c, incr, &where);
3058 /* Create a new SSA name to hold the initializer's value. */
3059 stride_type = TREE_TYPE (c->stride);
3060 new_name = make_temp_ssa_name (stride_type, NULL, "slsr");
3061 incr_vec[i].initializer = new_name;
3063 /* Create the initializer and insert it in the latest possible
3064 dominating position. */
3065 incr_tree = double_int_to_tree (stride_type, incr);
3066 init_stmt = gimple_build_assign_with_ops (MULT_EXPR, new_name,
3067 c->stride, incr_tree);
3068 if (where)
3070 gimple_stmt_iterator gsi = gsi_for_stmt (where->cand_stmt);
3071 gsi_insert_before (&gsi, init_stmt, GSI_SAME_STMT);
3072 gimple_set_location (init_stmt, gimple_location (where->cand_stmt));
3074 else
3076 gimple_stmt_iterator gsi = gsi_last_bb (bb);
3077 gimple basis_stmt = lookup_cand (c->basis)->cand_stmt;
3079 if (!gsi_end_p (gsi) && is_ctrl_stmt (gsi_stmt (gsi)))
3080 gsi_insert_before (&gsi, init_stmt, GSI_SAME_STMT);
3081 else
3082 gsi_insert_after (&gsi, init_stmt, GSI_SAME_STMT);
3084 gimple_set_location (init_stmt, gimple_location (basis_stmt));
3087 if (dump_file && (dump_flags & TDF_DETAILS))
3089 fputs ("Inserting initializer: ", dump_file);
3090 print_gimple_stmt (dump_file, init_stmt, 0, 0);
3095 /* Return TRUE iff all required increments for candidates feeding PHI
3096 are profitable to replace on behalf of candidate C. */
3098 static bool
3099 all_phi_incrs_profitable (slsr_cand_t c, gimple phi)
3101 unsigned i;
3102 slsr_cand_t basis = lookup_cand (c->basis);
3103 slsr_cand_t phi_cand = base_cand_from_table (gimple_phi_result (phi));
3105 for (i = 0; i < gimple_phi_num_args (phi); i++)
3107 tree arg = gimple_phi_arg_def (phi, i);
3109 if (!operand_equal_p (arg, phi_cand->base_expr, 0))
3111 gimple arg_def = SSA_NAME_DEF_STMT (arg);
3113 if (gimple_code (arg_def) == GIMPLE_PHI)
3115 if (!all_phi_incrs_profitable (c, arg_def))
3116 return false;
3118 else
3120 int j;
3121 slsr_cand_t arg_cand = base_cand_from_table (arg);
3122 double_int increment = arg_cand->index - basis->index;
3124 if (!address_arithmetic_p && increment.is_negative ())
3125 increment = -increment;
3127 j = incr_vec_index (increment);
3129 if (dump_file && (dump_flags & TDF_DETAILS))
3131 fprintf (dump_file, " Conditional candidate %d, phi: ",
3132 c->cand_num);
3133 print_gimple_stmt (dump_file, phi, 0, 0);
3134 fputs (" increment: ", dump_file);
3135 dump_double_int (dump_file, increment, false);
3136 if (j < 0)
3137 fprintf (dump_file,
3138 "\n Not replaced; incr_vec overflow.\n");
3139 else {
3140 fprintf (dump_file, "\n cost: %d\n", incr_vec[j].cost);
3141 if (profitable_increment_p (j))
3142 fputs (" Replacing...\n", dump_file);
3143 else
3144 fputs (" Not replaced.\n", dump_file);
3148 if (j < 0 || !profitable_increment_p (j))
3149 return false;
3154 return true;
3157 /* Create a NOP_EXPR that copies FROM_EXPR into a new SSA name of
3158 type TO_TYPE, and insert it in front of the statement represented
3159 by candidate C. Use *NEW_VAR to create the new SSA name. Return
3160 the new SSA name. */
3162 static tree
3163 introduce_cast_before_cand (slsr_cand_t c, tree to_type, tree from_expr)
3165 tree cast_lhs;
3166 gimple cast_stmt;
3167 gimple_stmt_iterator gsi = gsi_for_stmt (c->cand_stmt);
3169 cast_lhs = make_temp_ssa_name (to_type, NULL, "slsr");
3170 cast_stmt = gimple_build_assign_with_ops (NOP_EXPR, cast_lhs,
3171 from_expr, NULL_TREE);
3172 gimple_set_location (cast_stmt, gimple_location (c->cand_stmt));
3173 gsi_insert_before (&gsi, cast_stmt, GSI_SAME_STMT);
3175 if (dump_file && (dump_flags & TDF_DETAILS))
3177 fputs (" Inserting: ", dump_file);
3178 print_gimple_stmt (dump_file, cast_stmt, 0, 0);
3181 return cast_lhs;
3184 /* Replace the RHS of the statement represented by candidate C with
3185 NEW_CODE, NEW_RHS1, and NEW_RHS2, provided that to do so doesn't
3186 leave C unchanged or just interchange its operands. The original
3187 operation and operands are in OLD_CODE, OLD_RHS1, and OLD_RHS2.
3188 If the replacement was made and we are doing a details dump,
3189 return the revised statement, else NULL. */
3191 static gimple
3192 replace_rhs_if_not_dup (enum tree_code new_code, tree new_rhs1, tree new_rhs2,
3193 enum tree_code old_code, tree old_rhs1, tree old_rhs2,
3194 slsr_cand_t c)
3196 if (new_code != old_code
3197 || ((!operand_equal_p (new_rhs1, old_rhs1, 0)
3198 || !operand_equal_p (new_rhs2, old_rhs2, 0))
3199 && (!operand_equal_p (new_rhs1, old_rhs2, 0)
3200 || !operand_equal_p (new_rhs2, old_rhs1, 0))))
3202 gimple_stmt_iterator gsi = gsi_for_stmt (c->cand_stmt);
3203 gimple_assign_set_rhs_with_ops (&gsi, new_code, new_rhs1, new_rhs2);
3204 update_stmt (gsi_stmt (gsi));
3205 c->cand_stmt = gsi_stmt (gsi);
3207 if (dump_file && (dump_flags & TDF_DETAILS))
3208 return gsi_stmt (gsi);
3211 else if (dump_file && (dump_flags & TDF_DETAILS))
3212 fputs (" (duplicate, not actually replacing)\n", dump_file);
3214 return NULL;
3217 /* Strength-reduce the statement represented by candidate C by replacing
3218 it with an equivalent addition or subtraction. I is the index into
3219 the increment vector identifying C's increment. NEW_VAR is used to
3220 create a new SSA name if a cast needs to be introduced. BASIS_NAME
3221 is the rhs1 to use in creating the add/subtract. */
3223 static void
3224 replace_one_candidate (slsr_cand_t c, unsigned i, tree basis_name)
3226 gimple stmt_to_print = NULL;
3227 tree orig_rhs1, orig_rhs2;
3228 tree rhs2;
3229 enum tree_code orig_code, repl_code;
3230 double_int cand_incr;
3232 orig_code = gimple_assign_rhs_code (c->cand_stmt);
3233 orig_rhs1 = gimple_assign_rhs1 (c->cand_stmt);
3234 orig_rhs2 = gimple_assign_rhs2 (c->cand_stmt);
3235 cand_incr = cand_increment (c);
3237 if (dump_file && (dump_flags & TDF_DETAILS))
3239 fputs ("Replacing: ", dump_file);
3240 print_gimple_stmt (dump_file, c->cand_stmt, 0, 0);
3241 stmt_to_print = c->cand_stmt;
3244 if (address_arithmetic_p)
3245 repl_code = POINTER_PLUS_EXPR;
3246 else
3247 repl_code = PLUS_EXPR;
3249 /* If the increment has an initializer T_0, replace the candidate
3250 statement with an add of the basis name and the initializer. */
3251 if (incr_vec[i].initializer)
3253 tree init_type = TREE_TYPE (incr_vec[i].initializer);
3254 tree orig_type = TREE_TYPE (orig_rhs2);
3256 if (types_compatible_p (orig_type, init_type))
3257 rhs2 = incr_vec[i].initializer;
3258 else
3259 rhs2 = introduce_cast_before_cand (c, orig_type,
3260 incr_vec[i].initializer);
3262 if (incr_vec[i].incr != cand_incr)
3264 gcc_assert (repl_code == PLUS_EXPR);
3265 repl_code = MINUS_EXPR;
3268 stmt_to_print = replace_rhs_if_not_dup (repl_code, basis_name, rhs2,
3269 orig_code, orig_rhs1, orig_rhs2,
3273 /* Otherwise, the increment is one of -1, 0, and 1. Replace
3274 with a subtract of the stride from the basis name, a copy
3275 from the basis name, or an add of the stride to the basis
3276 name, respectively. It may be necessary to introduce a
3277 cast (or reuse an existing cast). */
3278 else if (cand_incr.is_one ())
3280 tree stride_type = TREE_TYPE (c->stride);
3281 tree orig_type = TREE_TYPE (orig_rhs2);
3283 if (types_compatible_p (orig_type, stride_type))
3284 rhs2 = c->stride;
3285 else
3286 rhs2 = introduce_cast_before_cand (c, orig_type, c->stride);
3288 stmt_to_print = replace_rhs_if_not_dup (repl_code, basis_name, rhs2,
3289 orig_code, orig_rhs1, orig_rhs2,
3293 else if (cand_incr.is_minus_one ())
3295 tree stride_type = TREE_TYPE (c->stride);
3296 tree orig_type = TREE_TYPE (orig_rhs2);
3297 gcc_assert (repl_code != POINTER_PLUS_EXPR);
3299 if (types_compatible_p (orig_type, stride_type))
3300 rhs2 = c->stride;
3301 else
3302 rhs2 = introduce_cast_before_cand (c, orig_type, c->stride);
3304 if (orig_code != MINUS_EXPR
3305 || !operand_equal_p (basis_name, orig_rhs1, 0)
3306 || !operand_equal_p (rhs2, orig_rhs2, 0))
3308 gimple_stmt_iterator gsi = gsi_for_stmt (c->cand_stmt);
3309 gimple_assign_set_rhs_with_ops (&gsi, MINUS_EXPR, basis_name, rhs2);
3310 update_stmt (gsi_stmt (gsi));
3311 c->cand_stmt = gsi_stmt (gsi);
3313 if (dump_file && (dump_flags & TDF_DETAILS))
3314 stmt_to_print = gsi_stmt (gsi);
3316 else if (dump_file && (dump_flags & TDF_DETAILS))
3317 fputs (" (duplicate, not actually replacing)\n", dump_file);
3320 else if (cand_incr.is_zero ())
3322 tree lhs = gimple_assign_lhs (c->cand_stmt);
3323 tree lhs_type = TREE_TYPE (lhs);
3324 tree basis_type = TREE_TYPE (basis_name);
3326 if (types_compatible_p (lhs_type, basis_type))
3328 gimple copy_stmt = gimple_build_assign (lhs, basis_name);
3329 gimple_stmt_iterator gsi = gsi_for_stmt (c->cand_stmt);
3330 gimple_set_location (copy_stmt, gimple_location (c->cand_stmt));
3331 gsi_replace (&gsi, copy_stmt, false);
3332 c->cand_stmt = copy_stmt;
3334 if (dump_file && (dump_flags & TDF_DETAILS))
3335 stmt_to_print = copy_stmt;
3337 else
3339 gimple_stmt_iterator gsi = gsi_for_stmt (c->cand_stmt);
3340 gimple cast_stmt = gimple_build_assign_with_ops (NOP_EXPR, lhs,
3341 basis_name,
3342 NULL_TREE);
3343 gimple_set_location (cast_stmt, gimple_location (c->cand_stmt));
3344 gsi_replace (&gsi, cast_stmt, false);
3345 c->cand_stmt = cast_stmt;
3347 if (dump_file && (dump_flags & TDF_DETAILS))
3348 stmt_to_print = cast_stmt;
3351 else
3352 gcc_unreachable ();
3354 if (dump_file && (dump_flags & TDF_DETAILS) && stmt_to_print)
3356 fputs ("With: ", dump_file);
3357 print_gimple_stmt (dump_file, stmt_to_print, 0, 0);
3358 fputs ("\n", dump_file);
3362 /* For each candidate in the tree rooted at C, replace it with
3363 an increment if such has been shown to be profitable. */
3365 static void
3366 replace_profitable_candidates (slsr_cand_t c)
3368 if (!cand_already_replaced (c))
3370 double_int increment = cand_abs_increment (c);
3371 enum tree_code orig_code = gimple_assign_rhs_code (c->cand_stmt);
3372 int i;
3374 i = incr_vec_index (increment);
3376 /* Only process profitable increments. Nothing useful can be done
3377 to a cast or copy. */
3378 if (i >= 0
3379 && profitable_increment_p (i)
3380 && orig_code != MODIFY_EXPR
3381 && orig_code != NOP_EXPR)
3383 if (phi_dependent_cand_p (c))
3385 gimple phi = lookup_cand (c->def_phi)->cand_stmt;
3387 if (all_phi_incrs_profitable (c, phi))
3389 /* Look up the LHS SSA name from C's basis. This will be
3390 the RHS1 of the adds we will introduce to create new
3391 phi arguments. */
3392 slsr_cand_t basis = lookup_cand (c->basis);
3393 tree basis_name = gimple_assign_lhs (basis->cand_stmt);
3395 /* Create a new phi statement that will represent C's true
3396 basis after the transformation is complete. */
3397 location_t loc = gimple_location (c->cand_stmt);
3398 tree name = create_phi_basis (c, phi, basis_name,
3399 loc, UNKNOWN_STRIDE);
3401 /* Replace C with an add of the new basis phi and the
3402 increment. */
3403 replace_one_candidate (c, i, name);
3406 else
3408 slsr_cand_t basis = lookup_cand (c->basis);
3409 tree basis_name = gimple_assign_lhs (basis->cand_stmt);
3410 replace_one_candidate (c, i, basis_name);
3415 if (c->sibling)
3416 replace_profitable_candidates (lookup_cand (c->sibling));
3418 if (c->dependent)
3419 replace_profitable_candidates (lookup_cand (c->dependent));
3422 /* Analyze costs of related candidates in the candidate vector,
3423 and make beneficial replacements. */
3425 static void
3426 analyze_candidates_and_replace (void)
3428 unsigned i;
3429 slsr_cand_t c;
3431 /* Each candidate that has a null basis and a non-null
3432 dependent is the root of a tree of related statements.
3433 Analyze each tree to determine a subset of those
3434 statements that can be replaced with maximum benefit. */
3435 FOR_EACH_VEC_ELT (cand_vec, i, c)
3437 slsr_cand_t first_dep;
3439 if (c->basis != 0 || c->dependent == 0)
3440 continue;
3442 if (dump_file && (dump_flags & TDF_DETAILS))
3443 fprintf (dump_file, "\nProcessing dependency tree rooted at %d.\n",
3444 c->cand_num);
3446 first_dep = lookup_cand (c->dependent);
3448 /* If this is a chain of CAND_REFs, unconditionally replace
3449 each of them with a strength-reduced data reference. */
3450 if (c->kind == CAND_REF)
3451 replace_refs (c);
3453 /* If the common stride of all related candidates is a known
3454 constant, each candidate without a phi-dependence can be
3455 profitably replaced. Each replaces a multiply by a single
3456 add, with the possibility that a feeding add also goes dead.
3457 A candidate with a phi-dependence is replaced only if the
3458 compensation code it requires is offset by the strength
3459 reduction savings. */
3460 else if (TREE_CODE (c->stride) == INTEGER_CST)
3461 replace_uncond_cands_and_profitable_phis (first_dep);
3463 /* When the stride is an SSA name, it may still be profitable
3464 to replace some or all of the dependent candidates, depending
3465 on whether the introduced increments can be reused, or are
3466 less expensive to calculate than the replaced statements. */
3467 else
3469 enum machine_mode mode;
3470 bool speed;
3472 /* Determine whether we'll be generating pointer arithmetic
3473 when replacing candidates. */
3474 address_arithmetic_p = (c->kind == CAND_ADD
3475 && POINTER_TYPE_P (c->cand_type));
3477 /* If all candidates have already been replaced under other
3478 interpretations, nothing remains to be done. */
3479 if (!count_candidates (c))
3480 continue;
3482 /* Construct an array of increments for this candidate chain. */
3483 incr_vec = XNEWVEC (incr_info, MAX_INCR_VEC_LEN);
3484 incr_vec_len = 0;
3485 record_increments (c);
3487 /* Determine which increments are profitable to replace. */
3488 mode = TYPE_MODE (TREE_TYPE (gimple_assign_lhs (c->cand_stmt)));
3489 speed = optimize_cands_for_speed_p (c);
3490 analyze_increments (first_dep, mode, speed);
3492 /* Insert initializers of the form T_0 = stride * increment
3493 for use in profitable replacements. */
3494 insert_initializers (first_dep);
3495 dump_incr_vec ();
3497 /* Perform the replacements. */
3498 replace_profitable_candidates (first_dep);
3499 free (incr_vec);
3504 static unsigned
3505 execute_strength_reduction (void)
3507 /* Create the obstack where candidates will reside. */
3508 gcc_obstack_init (&cand_obstack);
3510 /* Allocate the candidate vector. */
3511 cand_vec.create (128);
3513 /* Allocate the mapping from statements to candidate indices. */
3514 stmt_cand_map = pointer_map_create ();
3516 /* Create the obstack where candidate chains will reside. */
3517 gcc_obstack_init (&chain_obstack);
3519 /* Allocate the mapping from base expressions to candidate chains. */
3520 base_cand_map.create (500);
3522 /* Initialize the loop optimizer. We need to detect flow across
3523 back edges, and this gives us dominator information as well. */
3524 loop_optimizer_init (AVOID_CFG_MODIFICATIONS);
3526 /* Walk the CFG in predominator order looking for strength reduction
3527 candidates. */
3528 find_candidates_dom_walker (CDI_DOMINATORS)
3529 .walk (cfun->cfg->x_entry_block_ptr);
3531 if (dump_file && (dump_flags & TDF_DETAILS))
3533 dump_cand_vec ();
3534 dump_cand_chains ();
3537 /* Analyze costs and make appropriate replacements. */
3538 analyze_candidates_and_replace ();
3540 loop_optimizer_finalize ();
3541 base_cand_map.dispose ();
3542 obstack_free (&chain_obstack, NULL);
3543 pointer_map_destroy (stmt_cand_map);
3544 cand_vec.release ();
3545 obstack_free (&cand_obstack, NULL);
3547 return 0;
3550 static bool
3551 gate_strength_reduction (void)
3553 return flag_tree_slsr;
3556 namespace {
3558 const pass_data pass_data_strength_reduction =
3560 GIMPLE_PASS, /* type */
3561 "slsr", /* name */
3562 OPTGROUP_NONE, /* optinfo_flags */
3563 true, /* has_gate */
3564 true, /* has_execute */
3565 TV_GIMPLE_SLSR, /* tv_id */
3566 ( PROP_cfg | PROP_ssa ), /* properties_required */
3567 0, /* properties_provided */
3568 0, /* properties_destroyed */
3569 0, /* todo_flags_start */
3570 TODO_verify_ssa, /* todo_flags_finish */
3573 class pass_strength_reduction : public gimple_opt_pass
3575 public:
3576 pass_strength_reduction (gcc::context *ctxt)
3577 : gimple_opt_pass (pass_data_strength_reduction, ctxt)
3580 /* opt_pass methods: */
3581 bool gate () { return gate_strength_reduction (); }
3582 unsigned int execute () { return execute_strength_reduction (); }
3584 }; // class pass_strength_reduction
3586 } // anon namespace
3588 gimple_opt_pass *
3589 make_pass_strength_reduction (gcc::context *ctxt)
3591 return new pass_strength_reduction (ctxt);