This patch rewrites the old VEC macro-based interface into a new one based on the...
[gcc.git] / gcc / gimple-ssa-strength-reduction.c
1 /* Straight-line strength reduction.
2 Copyright (C) 2012 Free Software Foundation, Inc.
3 Contributed by Bill Schmidt, IBM <wschmidt@linux.ibm.com>
4
5 This file is part of GCC.
6
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.
11
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.
16
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/>. */
20
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.
26
27 Strength reduction will be implemented in four stages, gradually
28 adding more complex candidates:
29
30 1) Explicit multiplies, known constant multipliers, no
31 conditional increments. (complete)
32 2) Explicit multiplies, unknown constant multipliers,
33 no conditional increments. (complete)
34 3) Implicit multiplies in addressing expressions. (complete)
35 4) Explicit multiplies, conditional increments. (pending)
36
37 It would also be possible to apply strength reduction to divisions
38 and modulos, but such opportunities are relatively uncommon.
39
40 Strength reduction is also currently restricted to integer operations.
41 If desired, it could be extended to floating-point operations under
42 control of something like -funsafe-math-optimizations. */
43
44 #include "config.h"
45 #include "system.h"
46 #include "coretypes.h"
47 #include "tree.h"
48 #include "gimple.h"
49 #include "basic-block.h"
50 #include "tree-pass.h"
51 #include "cfgloop.h"
52 #include "gimple-pretty-print.h"
53 #include "tree-flow.h"
54 #include "domwalk.h"
55 #include "pointer-set.h"
56 #include "expmed.h"
57 #include "params.h"
58 \f
59 /* Information about a strength reduction candidate. Each statement
60 in the candidate table represents an expression of one of the
61 following forms (the special case of CAND_REF will be described
62 later):
63
64 (CAND_MULT) S1: X = (B + i) * S
65 (CAND_ADD) S1: X = B + (i * S)
66
67 Here X and B are SSA names, i is an integer constant, and S is
68 either an SSA name or a constant. We call B the "base," i the
69 "index", and S the "stride."
70
71 Any statement S0 that dominates S1 and is of the form:
72
73 (CAND_MULT) S0: Y = (B + i') * S
74 (CAND_ADD) S0: Y = B + (i' * S)
75
76 is called a "basis" for S1. In both cases, S1 may be replaced by
77
78 S1': X = Y + (i - i') * S,
79
80 where (i - i') * S is folded to the extent possible.
81
82 All gimple statements are visited in dominator order, and each
83 statement that may contribute to one of the forms of S1 above is
84 given at least one entry in the candidate table. Such statements
85 include addition, pointer addition, subtraction, multiplication,
86 negation, copies, and nontrivial type casts. If a statement may
87 represent more than one expression of the forms of S1 above,
88 multiple "interpretations" are stored in the table and chained
89 together. Examples:
90
91 * An add of two SSA names may treat either operand as the base.
92 * A multiply of two SSA names, likewise.
93 * A copy or cast may be thought of as either a CAND_MULT with
94 i = 0 and S = 1, or as a CAND_ADD with i = 0 or S = 0.
95
96 Candidate records are allocated from an obstack. They are addressed
97 both from a hash table keyed on S1, and from a vector of candidate
98 pointers arranged in predominator order.
99
100 Opportunity note
101 ----------------
102 Currently we don't recognize:
103
104 S0: Y = (S * i') - B
105 S1: X = (S * i) - B
106
107 as a strength reduction opportunity, even though this S1 would
108 also be replaceable by the S1' above. This can be added if it
109 comes up in practice.
110
111 Strength reduction in addressing
112 --------------------------------
113 There is another kind of candidate known as CAND_REF. A CAND_REF
114 describes a statement containing a memory reference having
115 complex addressing that might benefit from strength reduction.
116 Specifically, we are interested in references for which
117 get_inner_reference returns a base address, offset, and bitpos as
118 follows:
119
120 base: MEM_REF (T1, C1)
121 offset: MULT_EXPR (PLUS_EXPR (T2, C2), C3)
122 bitpos: C4 * BITS_PER_UNIT
123
124 Here T1 and T2 are arbitrary trees, and C1, C2, C3, C4 are
125 arbitrary integer constants. Note that C2 may be zero, in which
126 case the offset will be MULT_EXPR (T2, C3).
127
128 When this pattern is recognized, the original memory reference
129 can be replaced with:
130
131 MEM_REF (POINTER_PLUS_EXPR (T1, MULT_EXPR (T2, C3)),
132 C1 + (C2 * C3) + C4)
133
134 which distributes the multiply to allow constant folding. When
135 two or more addressing expressions can be represented by MEM_REFs
136 of this form, differing only in the constants C1, C2, and C4,
137 making this substitution produces more efficient addressing during
138 the RTL phases. When there are not at least two expressions with
139 the same values of T1, T2, and C3, there is nothing to be gained
140 by the replacement.
141
142 Strength reduction of CAND_REFs uses the same infrastructure as
143 that used by CAND_MULTs and CAND_ADDs. We record T1 in the base (B)
144 field, MULT_EXPR (T2, C3) in the stride (S) field, and
145 C1 + (C2 * C3) + C4 in the index (i) field. A basis for a CAND_REF
146 is thus another CAND_REF with the same B and S values. When at
147 least two CAND_REFs are chained together using the basis relation,
148 each of them is replaced as above, resulting in improved code
149 generation for addressing. */
150
151
152 /* Index into the candidate vector, offset by 1. VECs are zero-based,
153 while cand_idx's are one-based, with zero indicating null. */
154 typedef unsigned cand_idx;
155
156 /* The kind of candidate. */
157 enum cand_kind
158 {
159 CAND_MULT,
160 CAND_ADD,
161 CAND_REF
162 };
163
164 struct slsr_cand_d
165 {
166 /* The candidate statement S1. */
167 gimple cand_stmt;
168
169 /* The base expression B: often an SSA name, but not always. */
170 tree base_expr;
171
172 /* The stride S. */
173 tree stride;
174
175 /* The index constant i. */
176 double_int index;
177
178 /* The type of the candidate. This is normally the type of base_expr,
179 but casts may have occurred when combining feeding instructions.
180 A candidate can only be a basis for candidates of the same final type.
181 (For CAND_REFs, this is the type to be used for operand 1 of the
182 replacement MEM_REF.) */
183 tree cand_type;
184
185 /* The kind of candidate (CAND_MULT, etc.). */
186 enum cand_kind kind;
187
188 /* Index of this candidate in the candidate vector. */
189 cand_idx cand_num;
190
191 /* Index of the next candidate record for the same statement.
192 A statement may be useful in more than one way (e.g., due to
193 commutativity). So we can have multiple "interpretations"
194 of a statement. */
195 cand_idx next_interp;
196
197 /* Index of the basis statement S0, if any, in the candidate vector. */
198 cand_idx basis;
199
200 /* First candidate for which this candidate is a basis, if one exists. */
201 cand_idx dependent;
202
203 /* Next candidate having the same basis as this one. */
204 cand_idx sibling;
205
206 /* If this is a conditional candidate, the defining PHI statement
207 for the base SSA name B. For future use; always NULL for now. */
208 gimple def_phi;
209
210 /* Savings that can be expected from eliminating dead code if this
211 candidate is replaced. */
212 int dead_savings;
213 };
214
215 typedef struct slsr_cand_d slsr_cand, *slsr_cand_t;
216 typedef const struct slsr_cand_d *const_slsr_cand_t;
217
218 /* Pointers to candidates are chained together as part of a mapping
219 from base expressions to the candidates that use them. */
220
221 struct cand_chain_d
222 {
223 /* Base expression for the chain of candidates: often, but not
224 always, an SSA name. */
225 tree base_expr;
226
227 /* Pointer to a candidate. */
228 slsr_cand_t cand;
229
230 /* Chain pointer. */
231 struct cand_chain_d *next;
232
233 };
234
235 typedef struct cand_chain_d cand_chain, *cand_chain_t;
236 typedef const struct cand_chain_d *const_cand_chain_t;
237
238 /* Information about a unique "increment" associated with candidates
239 having an SSA name for a stride. An increment is the difference
240 between the index of the candidate and the index of its basis,
241 i.e., (i - i') as discussed in the module commentary.
242
243 When we are not going to generate address arithmetic we treat
244 increments that differ only in sign as the same, allowing sharing
245 of the cost of initializers. The absolute value of the increment
246 is stored in the incr_info. */
247
248 struct incr_info_d
249 {
250 /* The increment that relates a candidate to its basis. */
251 double_int incr;
252
253 /* How many times the increment occurs in the candidate tree. */
254 unsigned count;
255
256 /* Cost of replacing candidates using this increment. Negative and
257 zero costs indicate replacement should be performed. */
258 int cost;
259
260 /* If this increment is profitable but is not -1, 0, or 1, it requires
261 an initializer T_0 = stride * incr to be found or introduced in the
262 nearest common dominator of all candidates. This field holds T_0
263 for subsequent use. */
264 tree initializer;
265
266 /* If the initializer was found to already exist, this is the block
267 where it was found. */
268 basic_block init_bb;
269 };
270
271 typedef struct incr_info_d incr_info, *incr_info_t;
272
273 /* Candidates are maintained in a vector. If candidate X dominates
274 candidate Y, then X appears before Y in the vector; but the
275 converse does not necessarily hold. */
276 static vec<slsr_cand_t> cand_vec;
277
278 enum cost_consts
279 {
280 COST_NEUTRAL = 0,
281 COST_INFINITE = 1000
282 };
283
284 /* Pointer map embodying a mapping from statements to candidates. */
285 static struct pointer_map_t *stmt_cand_map;
286
287 /* Obstack for candidates. */
288 static struct obstack cand_obstack;
289
290 /* Hash table embodying a mapping from base exprs to chains of candidates. */
291 static htab_t base_cand_map;
292
293 /* Obstack for candidate chains. */
294 static struct obstack chain_obstack;
295
296 /* An array INCR_VEC of incr_infos is used during analysis of related
297 candidates having an SSA name for a stride. INCR_VEC_LEN describes
298 its current length. */
299 static incr_info_t incr_vec;
300 static unsigned incr_vec_len;
301
302 /* For a chain of candidates with unknown stride, indicates whether or not
303 we must generate pointer arithmetic when replacing statements. */
304 static bool address_arithmetic_p;
305 \f
306 /* Produce a pointer to the IDX'th candidate in the candidate vector. */
307
308 static slsr_cand_t
309 lookup_cand (cand_idx idx)
310 {
311 return cand_vec[idx - 1];
312 }
313
314 /* Callback to produce a hash value for a candidate chain header. */
315
316 static hashval_t
317 base_cand_hash (const void *p)
318 {
319 tree base_expr = ((const_cand_chain_t) p)->base_expr;
320 return iterative_hash_expr (base_expr, 0);
321 }
322
323 /* Callback when an element is removed from the hash table.
324 We never remove entries until the entire table is released. */
325
326 static void
327 base_cand_free (void *p ATTRIBUTE_UNUSED)
328 {
329 }
330
331 /* Callback to return true if two candidate chain headers are equal. */
332
333 static int
334 base_cand_eq (const void *p1, const void *p2)
335 {
336 const_cand_chain_t const chain1 = (const_cand_chain_t) p1;
337 const_cand_chain_t const chain2 = (const_cand_chain_t) p2;
338 return operand_equal_p (chain1->base_expr, chain2->base_expr, 0);
339 }
340 \f
341 /* Use the base expr from candidate C to look for possible candidates
342 that can serve as a basis for C. Each potential basis must also
343 appear in a block that dominates the candidate statement and have
344 the same stride and type. If more than one possible basis exists,
345 the one with highest index in the vector is chosen; this will be
346 the most immediately dominating basis. */
347
348 static int
349 find_basis_for_candidate (slsr_cand_t c)
350 {
351 cand_chain mapping_key;
352 cand_chain_t chain;
353 slsr_cand_t basis = NULL;
354
355 // Limit potential of N^2 behavior for long candidate chains.
356 int iters = 0;
357 int max_iters = PARAM_VALUE (PARAM_MAX_SLSR_CANDIDATE_SCAN);
358
359 mapping_key.base_expr = c->base_expr;
360 chain = (cand_chain_t) htab_find (base_cand_map, &mapping_key);
361
362 for (; chain && iters < max_iters; chain = chain->next, ++iters)
363 {
364 slsr_cand_t one_basis = chain->cand;
365
366 if (one_basis->kind != c->kind
367 || one_basis->cand_stmt == c->cand_stmt
368 || !operand_equal_p (one_basis->stride, c->stride, 0)
369 || !types_compatible_p (one_basis->cand_type, c->cand_type)
370 || !dominated_by_p (CDI_DOMINATORS,
371 gimple_bb (c->cand_stmt),
372 gimple_bb (one_basis->cand_stmt)))
373 continue;
374
375 if (!basis || basis->cand_num < one_basis->cand_num)
376 basis = one_basis;
377 }
378
379 if (basis)
380 {
381 c->sibling = basis->dependent;
382 basis->dependent = c->cand_num;
383 return basis->cand_num;
384 }
385
386 return 0;
387 }
388
389 /* Record a mapping from the base expression of C to C itself, indicating that
390 C may potentially serve as a basis using that base expression. */
391
392 static void
393 record_potential_basis (slsr_cand_t c)
394 {
395 cand_chain_t node;
396 void **slot;
397
398 node = (cand_chain_t) obstack_alloc (&chain_obstack, sizeof (cand_chain));
399 node->base_expr = c->base_expr;
400 node->cand = c;
401 node->next = NULL;
402 slot = htab_find_slot (base_cand_map, node, INSERT);
403
404 if (*slot)
405 {
406 cand_chain_t head = (cand_chain_t) (*slot);
407 node->next = head->next;
408 head->next = node;
409 }
410 else
411 *slot = node;
412 }
413
414 /* Allocate storage for a new candidate and initialize its fields.
415 Attempt to find a basis for the candidate. */
416
417 static slsr_cand_t
418 alloc_cand_and_find_basis (enum cand_kind kind, gimple gs, tree base,
419 double_int index, tree stride, tree ctype,
420 unsigned savings)
421 {
422 slsr_cand_t c = (slsr_cand_t) obstack_alloc (&cand_obstack,
423 sizeof (slsr_cand));
424 c->cand_stmt = gs;
425 c->base_expr = base;
426 c->stride = stride;
427 c->index = index;
428 c->cand_type = ctype;
429 c->kind = kind;
430 c->cand_num = cand_vec.length () + 1;
431 c->next_interp = 0;
432 c->dependent = 0;
433 c->sibling = 0;
434 c->def_phi = NULL;
435 c->dead_savings = savings;
436
437 cand_vec.safe_push (c);
438 c->basis = find_basis_for_candidate (c);
439 record_potential_basis (c);
440
441 return c;
442 }
443
444 /* Determine the target cost of statement GS when compiling according
445 to SPEED. */
446
447 static int
448 stmt_cost (gimple gs, bool speed)
449 {
450 tree lhs, rhs1, rhs2;
451 enum machine_mode lhs_mode;
452
453 gcc_assert (is_gimple_assign (gs));
454 lhs = gimple_assign_lhs (gs);
455 rhs1 = gimple_assign_rhs1 (gs);
456 lhs_mode = TYPE_MODE (TREE_TYPE (lhs));
457
458 switch (gimple_assign_rhs_code (gs))
459 {
460 case MULT_EXPR:
461 rhs2 = gimple_assign_rhs2 (gs);
462
463 if (host_integerp (rhs2, 0))
464 return mult_by_coeff_cost (TREE_INT_CST_LOW (rhs2), lhs_mode, speed);
465
466 gcc_assert (TREE_CODE (rhs1) != INTEGER_CST);
467 return mul_cost (speed, lhs_mode);
468
469 case PLUS_EXPR:
470 case POINTER_PLUS_EXPR:
471 case MINUS_EXPR:
472 return add_cost (speed, lhs_mode);
473
474 case NEGATE_EXPR:
475 return neg_cost (speed, lhs_mode);
476
477 case NOP_EXPR:
478 return convert_cost (lhs_mode, TYPE_MODE (TREE_TYPE (rhs1)), speed);
479
480 /* Note that we don't assign costs to copies that in most cases
481 will go away. */
482 default:
483 ;
484 }
485
486 gcc_unreachable ();
487 return 0;
488 }
489
490 /* Look up the defining statement for BASE_IN and return a pointer
491 to its candidate in the candidate table, if any; otherwise NULL.
492 Only CAND_ADD and CAND_MULT candidates are returned. */
493
494 static slsr_cand_t
495 base_cand_from_table (tree base_in)
496 {
497 slsr_cand_t *result;
498
499 gimple def = SSA_NAME_DEF_STMT (base_in);
500 if (!def)
501 return (slsr_cand_t) NULL;
502
503 result = (slsr_cand_t *) pointer_map_contains (stmt_cand_map, def);
504
505 if (result && (*result)->kind != CAND_REF)
506 return *result;
507
508 return (slsr_cand_t) NULL;
509 }
510
511 /* Add an entry to the statement-to-candidate mapping. */
512
513 static void
514 add_cand_for_stmt (gimple gs, slsr_cand_t c)
515 {
516 void **slot = pointer_map_insert (stmt_cand_map, gs);
517 gcc_assert (!*slot);
518 *slot = c;
519 }
520 \f
521 /* Look for the following pattern:
522
523 *PBASE: MEM_REF (T1, C1)
524
525 *POFFSET: MULT_EXPR (T2, C3) [C2 is zero]
526 or
527 MULT_EXPR (PLUS_EXPR (T2, C2), C3)
528 or
529 MULT_EXPR (MINUS_EXPR (T2, -C2), C3)
530
531 *PINDEX: C4 * BITS_PER_UNIT
532
533 If not present, leave the input values unchanged and return FALSE.
534 Otherwise, modify the input values as follows and return TRUE:
535
536 *PBASE: T1
537 *POFFSET: MULT_EXPR (T2, C3)
538 *PINDEX: C1 + (C2 * C3) + C4 */
539
540 static bool
541 restructure_reference (tree *pbase, tree *poffset, double_int *pindex,
542 tree *ptype)
543 {
544 tree base = *pbase, offset = *poffset;
545 double_int index = *pindex;
546 double_int bpu = double_int::from_uhwi (BITS_PER_UNIT);
547 tree mult_op0, mult_op1, t1, t2, type;
548 double_int c1, c2, c3, c4;
549
550 if (!base
551 || !offset
552 || TREE_CODE (base) != MEM_REF
553 || TREE_CODE (offset) != MULT_EXPR
554 || TREE_CODE (TREE_OPERAND (offset, 1)) != INTEGER_CST
555 || !index.umod (bpu, FLOOR_MOD_EXPR).is_zero ())
556 return false;
557
558 t1 = TREE_OPERAND (base, 0);
559 c1 = mem_ref_offset (base);
560 type = TREE_TYPE (TREE_OPERAND (base, 1));
561
562 mult_op0 = TREE_OPERAND (offset, 0);
563 mult_op1 = TREE_OPERAND (offset, 1);
564
565 c3 = tree_to_double_int (mult_op1);
566
567 if (TREE_CODE (mult_op0) == PLUS_EXPR)
568
569 if (TREE_CODE (TREE_OPERAND (mult_op0, 1)) == INTEGER_CST)
570 {
571 t2 = TREE_OPERAND (mult_op0, 0);
572 c2 = tree_to_double_int (TREE_OPERAND (mult_op0, 1));
573 }
574 else
575 return false;
576
577 else if (TREE_CODE (mult_op0) == MINUS_EXPR)
578
579 if (TREE_CODE (TREE_OPERAND (mult_op0, 1)) == INTEGER_CST)
580 {
581 t2 = TREE_OPERAND (mult_op0, 0);
582 c2 = -tree_to_double_int (TREE_OPERAND (mult_op0, 1));
583 }
584 else
585 return false;
586
587 else
588 {
589 t2 = mult_op0;
590 c2 = double_int_zero;
591 }
592
593 c4 = index.udiv (bpu, FLOOR_DIV_EXPR);
594
595 *pbase = t1;
596 *poffset = fold_build2 (MULT_EXPR, sizetype, t2,
597 double_int_to_tree (sizetype, c3));
598 *pindex = c1 + c2 * c3 + c4;
599 *ptype = type;
600
601 return true;
602 }
603
604 /* Given GS which contains a data reference, create a CAND_REF entry in
605 the candidate table and attempt to find a basis. */
606
607 static void
608 slsr_process_ref (gimple gs)
609 {
610 tree ref_expr, base, offset, type;
611 HOST_WIDE_INT bitsize, bitpos;
612 enum machine_mode mode;
613 int unsignedp, volatilep;
614 double_int index;
615 slsr_cand_t c;
616
617 if (gimple_vdef (gs))
618 ref_expr = gimple_assign_lhs (gs);
619 else
620 ref_expr = gimple_assign_rhs1 (gs);
621
622 if (!handled_component_p (ref_expr)
623 || TREE_CODE (ref_expr) == BIT_FIELD_REF
624 || (TREE_CODE (ref_expr) == COMPONENT_REF
625 && DECL_BIT_FIELD (TREE_OPERAND (ref_expr, 1))))
626 return;
627
628 base = get_inner_reference (ref_expr, &bitsize, &bitpos, &offset, &mode,
629 &unsignedp, &volatilep, false);
630 index = double_int::from_uhwi (bitpos);
631
632 if (!restructure_reference (&base, &offset, &index, &type))
633 return;
634
635 c = alloc_cand_and_find_basis (CAND_REF, gs, base, index, offset,
636 type, 0);
637
638 /* Add the candidate to the statement-candidate mapping. */
639 add_cand_for_stmt (gs, c);
640 }
641
642 /* Create a candidate entry for a statement GS, where GS multiplies
643 two SSA names BASE_IN and STRIDE_IN. Propagate any known information
644 about the two SSA names into the new candidate. Return the new
645 candidate. */
646
647 static slsr_cand_t
648 create_mul_ssa_cand (gimple gs, tree base_in, tree stride_in, bool speed)
649 {
650 tree base = NULL_TREE, stride = NULL_TREE, ctype = NULL_TREE;
651 double_int index;
652 unsigned savings = 0;
653 slsr_cand_t c;
654 slsr_cand_t base_cand = base_cand_from_table (base_in);
655
656 /* Look at all interpretations of the base candidate, if necessary,
657 to find information to propagate into this candidate. */
658 while (base_cand && !base)
659 {
660
661 if (base_cand->kind == CAND_MULT
662 && operand_equal_p (base_cand->stride, integer_one_node, 0))
663 {
664 /* Y = (B + i') * 1
665 X = Y * Z
666 ================
667 X = (B + i') * Z */
668 base = base_cand->base_expr;
669 index = base_cand->index;
670 stride = stride_in;
671 ctype = base_cand->cand_type;
672 if (has_single_use (base_in))
673 savings = (base_cand->dead_savings
674 + stmt_cost (base_cand->cand_stmt, speed));
675 }
676 else if (base_cand->kind == CAND_ADD
677 && TREE_CODE (base_cand->stride) == INTEGER_CST)
678 {
679 /* Y = B + (i' * S), S constant
680 X = Y * Z
681 ============================
682 X = B + ((i' * S) * Z) */
683 base = base_cand->base_expr;
684 index = base_cand->index * tree_to_double_int (base_cand->stride);
685 stride = stride_in;
686 ctype = base_cand->cand_type;
687 if (has_single_use (base_in))
688 savings = (base_cand->dead_savings
689 + stmt_cost (base_cand->cand_stmt, speed));
690 }
691
692 if (base_cand->next_interp)
693 base_cand = lookup_cand (base_cand->next_interp);
694 else
695 base_cand = NULL;
696 }
697
698 if (!base)
699 {
700 /* No interpretations had anything useful to propagate, so
701 produce X = (Y + 0) * Z. */
702 base = base_in;
703 index = double_int_zero;
704 stride = stride_in;
705 ctype = TREE_TYPE (base_in);
706 }
707
708 c = alloc_cand_and_find_basis (CAND_MULT, gs, base, index, stride,
709 ctype, savings);
710 return c;
711 }
712
713 /* Create a candidate entry for a statement GS, where GS multiplies
714 SSA name BASE_IN by constant STRIDE_IN. Propagate any known
715 information about BASE_IN into the new candidate. Return the new
716 candidate. */
717
718 static slsr_cand_t
719 create_mul_imm_cand (gimple gs, tree base_in, tree stride_in, bool speed)
720 {
721 tree base = NULL_TREE, stride = NULL_TREE, ctype = NULL_TREE;
722 double_int index, temp;
723 unsigned savings = 0;
724 slsr_cand_t c;
725 slsr_cand_t base_cand = base_cand_from_table (base_in);
726
727 /* Look at all interpretations of the base candidate, if necessary,
728 to find information to propagate into this candidate. */
729 while (base_cand && !base)
730 {
731 if (base_cand->kind == CAND_MULT
732 && TREE_CODE (base_cand->stride) == INTEGER_CST)
733 {
734 /* Y = (B + i') * S, S constant
735 X = Y * c
736 ============================
737 X = (B + i') * (S * c) */
738 base = base_cand->base_expr;
739 index = base_cand->index;
740 temp = tree_to_double_int (base_cand->stride)
741 * tree_to_double_int (stride_in);
742 stride = double_int_to_tree (TREE_TYPE (stride_in), temp);
743 ctype = base_cand->cand_type;
744 if (has_single_use (base_in))
745 savings = (base_cand->dead_savings
746 + stmt_cost (base_cand->cand_stmt, speed));
747 }
748 else if (base_cand->kind == CAND_ADD
749 && operand_equal_p (base_cand->stride, integer_one_node, 0))
750 {
751 /* Y = B + (i' * 1)
752 X = Y * c
753 ===========================
754 X = (B + i') * c */
755 base = base_cand->base_expr;
756 index = base_cand->index;
757 stride = stride_in;
758 ctype = base_cand->cand_type;
759 if (has_single_use (base_in))
760 savings = (base_cand->dead_savings
761 + stmt_cost (base_cand->cand_stmt, speed));
762 }
763 else if (base_cand->kind == CAND_ADD
764 && base_cand->index.is_one ()
765 && TREE_CODE (base_cand->stride) == INTEGER_CST)
766 {
767 /* Y = B + (1 * S), S constant
768 X = Y * c
769 ===========================
770 X = (B + S) * c */
771 base = base_cand->base_expr;
772 index = tree_to_double_int (base_cand->stride);
773 stride = stride_in;
774 ctype = base_cand->cand_type;
775 if (has_single_use (base_in))
776 savings = (base_cand->dead_savings
777 + stmt_cost (base_cand->cand_stmt, speed));
778 }
779
780 if (base_cand->next_interp)
781 base_cand = lookup_cand (base_cand->next_interp);
782 else
783 base_cand = NULL;
784 }
785
786 if (!base)
787 {
788 /* No interpretations had anything useful to propagate, so
789 produce X = (Y + 0) * c. */
790 base = base_in;
791 index = double_int_zero;
792 stride = stride_in;
793 ctype = TREE_TYPE (base_in);
794 }
795
796 c = alloc_cand_and_find_basis (CAND_MULT, gs, base, index, stride,
797 ctype, savings);
798 return c;
799 }
800
801 /* Given GS which is a multiply of scalar integers, make an appropriate
802 entry in the candidate table. If this is a multiply of two SSA names,
803 create two CAND_MULT interpretations and attempt to find a basis for
804 each of them. Otherwise, create a single CAND_MULT and attempt to
805 find a basis. */
806
807 static void
808 slsr_process_mul (gimple gs, tree rhs1, tree rhs2, bool speed)
809 {
810 slsr_cand_t c, c2;
811
812 /* If this is a multiply of an SSA name with itself, it is highly
813 unlikely that we will get a strength reduction opportunity, so
814 don't record it as a candidate. This simplifies the logic for
815 finding a basis, so if this is removed that must be considered. */
816 if (rhs1 == rhs2)
817 return;
818
819 if (TREE_CODE (rhs2) == SSA_NAME)
820 {
821 /* Record an interpretation of this statement in the candidate table
822 assuming RHS1 is the base expression and RHS2 is the stride. */
823 c = create_mul_ssa_cand (gs, rhs1, rhs2, speed);
824
825 /* Add the first interpretation to the statement-candidate mapping. */
826 add_cand_for_stmt (gs, c);
827
828 /* Record another interpretation of this statement assuming RHS1
829 is the stride and RHS2 is the base expression. */
830 c2 = create_mul_ssa_cand (gs, rhs2, rhs1, speed);
831 c->next_interp = c2->cand_num;
832 }
833 else
834 {
835 /* Record an interpretation for the multiply-immediate. */
836 c = create_mul_imm_cand (gs, rhs1, rhs2, speed);
837
838 /* Add the interpretation to the statement-candidate mapping. */
839 add_cand_for_stmt (gs, c);
840 }
841 }
842
843 /* Create a candidate entry for a statement GS, where GS adds two
844 SSA names BASE_IN and ADDEND_IN if SUBTRACT_P is false, and
845 subtracts ADDEND_IN from BASE_IN otherwise. Propagate any known
846 information about the two SSA names into the new candidate.
847 Return the new candidate. */
848
849 static slsr_cand_t
850 create_add_ssa_cand (gimple gs, tree base_in, tree addend_in,
851 bool subtract_p, bool speed)
852 {
853 tree base = NULL_TREE, stride = NULL_TREE, ctype = NULL;
854 double_int index;
855 unsigned savings = 0;
856 slsr_cand_t c;
857 slsr_cand_t base_cand = base_cand_from_table (base_in);
858 slsr_cand_t addend_cand = base_cand_from_table (addend_in);
859
860 /* The most useful transformation is a multiply-immediate feeding
861 an add or subtract. Look for that first. */
862 while (addend_cand && !base)
863 {
864 if (addend_cand->kind == CAND_MULT
865 && addend_cand->index.is_zero ()
866 && TREE_CODE (addend_cand->stride) == INTEGER_CST)
867 {
868 /* Z = (B + 0) * S, S constant
869 X = Y +/- Z
870 ===========================
871 X = Y + ((+/-1 * S) * B) */
872 base = base_in;
873 index = tree_to_double_int (addend_cand->stride);
874 if (subtract_p)
875 index = -index;
876 stride = addend_cand->base_expr;
877 ctype = TREE_TYPE (base_in);
878 if (has_single_use (addend_in))
879 savings = (addend_cand->dead_savings
880 + stmt_cost (addend_cand->cand_stmt, speed));
881 }
882
883 if (addend_cand->next_interp)
884 addend_cand = lookup_cand (addend_cand->next_interp);
885 else
886 addend_cand = NULL;
887 }
888
889 while (base_cand && !base)
890 {
891 if (base_cand->kind == CAND_ADD
892 && (base_cand->index.is_zero ()
893 || operand_equal_p (base_cand->stride,
894 integer_zero_node, 0)))
895 {
896 /* Y = B + (i' * S), i' * S = 0
897 X = Y +/- Z
898 ============================
899 X = B + (+/-1 * Z) */
900 base = base_cand->base_expr;
901 index = subtract_p ? double_int_minus_one : double_int_one;
902 stride = addend_in;
903 ctype = base_cand->cand_type;
904 if (has_single_use (base_in))
905 savings = (base_cand->dead_savings
906 + stmt_cost (base_cand->cand_stmt, speed));
907 }
908 else if (subtract_p)
909 {
910 slsr_cand_t subtrahend_cand = base_cand_from_table (addend_in);
911
912 while (subtrahend_cand && !base)
913 {
914 if (subtrahend_cand->kind == CAND_MULT
915 && subtrahend_cand->index.is_zero ()
916 && TREE_CODE (subtrahend_cand->stride) == INTEGER_CST)
917 {
918 /* Z = (B + 0) * S, S constant
919 X = Y - Z
920 ===========================
921 Value: X = Y + ((-1 * S) * B) */
922 base = base_in;
923 index = tree_to_double_int (subtrahend_cand->stride);
924 index = -index;
925 stride = subtrahend_cand->base_expr;
926 ctype = TREE_TYPE (base_in);
927 if (has_single_use (addend_in))
928 savings = (subtrahend_cand->dead_savings
929 + stmt_cost (subtrahend_cand->cand_stmt, speed));
930 }
931
932 if (subtrahend_cand->next_interp)
933 subtrahend_cand = lookup_cand (subtrahend_cand->next_interp);
934 else
935 subtrahend_cand = NULL;
936 }
937 }
938
939 if (base_cand->next_interp)
940 base_cand = lookup_cand (base_cand->next_interp);
941 else
942 base_cand = NULL;
943 }
944
945 if (!base)
946 {
947 /* No interpretations had anything useful to propagate, so
948 produce X = Y + (1 * Z). */
949 base = base_in;
950 index = subtract_p ? double_int_minus_one : double_int_one;
951 stride = addend_in;
952 ctype = TREE_TYPE (base_in);
953 }
954
955 c = alloc_cand_and_find_basis (CAND_ADD, gs, base, index, stride,
956 ctype, savings);
957 return c;
958 }
959
960 /* Create a candidate entry for a statement GS, where GS adds SSA
961 name BASE_IN to constant INDEX_IN. Propagate any known information
962 about BASE_IN into the new candidate. Return the new candidate. */
963
964 static slsr_cand_t
965 create_add_imm_cand (gimple gs, tree base_in, double_int index_in, bool speed)
966 {
967 enum cand_kind kind = CAND_ADD;
968 tree base = NULL_TREE, stride = NULL_TREE, ctype = NULL_TREE;
969 double_int index, multiple;
970 unsigned savings = 0;
971 slsr_cand_t c;
972 slsr_cand_t base_cand = base_cand_from_table (base_in);
973
974 while (base_cand && !base)
975 {
976 bool unsigned_p = TYPE_UNSIGNED (TREE_TYPE (base_cand->stride));
977
978 if (TREE_CODE (base_cand->stride) == INTEGER_CST
979 && index_in.multiple_of (tree_to_double_int (base_cand->stride),
980 unsigned_p, &multiple))
981 {
982 /* Y = (B + i') * S, S constant, c = kS for some integer k
983 X = Y + c
984 ============================
985 X = (B + (i'+ k)) * S
986 OR
987 Y = B + (i' * S), S constant, c = kS for some integer k
988 X = Y + c
989 ============================
990 X = (B + (i'+ k)) * S */
991 kind = base_cand->kind;
992 base = base_cand->base_expr;
993 index = base_cand->index + multiple;
994 stride = base_cand->stride;
995 ctype = base_cand->cand_type;
996 if (has_single_use (base_in))
997 savings = (base_cand->dead_savings
998 + stmt_cost (base_cand->cand_stmt, speed));
999 }
1000
1001 if (base_cand->next_interp)
1002 base_cand = lookup_cand (base_cand->next_interp);
1003 else
1004 base_cand = NULL;
1005 }
1006
1007 if (!base)
1008 {
1009 /* No interpretations had anything useful to propagate, so
1010 produce X = Y + (c * 1). */
1011 kind = CAND_ADD;
1012 base = base_in;
1013 index = index_in;
1014 stride = integer_one_node;
1015 ctype = TREE_TYPE (base_in);
1016 }
1017
1018 c = alloc_cand_and_find_basis (kind, gs, base, index, stride,
1019 ctype, savings);
1020 return c;
1021 }
1022
1023 /* Given GS which is an add or subtract of scalar integers or pointers,
1024 make at least one appropriate entry in the candidate table. */
1025
1026 static void
1027 slsr_process_add (gimple gs, tree rhs1, tree rhs2, bool speed)
1028 {
1029 bool subtract_p = gimple_assign_rhs_code (gs) == MINUS_EXPR;
1030 slsr_cand_t c = NULL, c2;
1031
1032 if (TREE_CODE (rhs2) == SSA_NAME)
1033 {
1034 /* First record an interpretation assuming RHS1 is the base expression
1035 and RHS2 is the stride. But it doesn't make sense for the
1036 stride to be a pointer, so don't record a candidate in that case. */
1037 if (!POINTER_TYPE_P (TREE_TYPE (rhs2)))
1038 {
1039 c = create_add_ssa_cand (gs, rhs1, rhs2, subtract_p, speed);
1040
1041 /* Add the first interpretation to the statement-candidate
1042 mapping. */
1043 add_cand_for_stmt (gs, c);
1044 }
1045
1046 /* If the two RHS operands are identical, or this is a subtract,
1047 we're done. */
1048 if (operand_equal_p (rhs1, rhs2, 0) || subtract_p)
1049 return;
1050
1051 /* Otherwise, record another interpretation assuming RHS2 is the
1052 base expression and RHS1 is the stride, again provided that the
1053 stride is not a pointer. */
1054 if (!POINTER_TYPE_P (TREE_TYPE (rhs1)))
1055 {
1056 c2 = create_add_ssa_cand (gs, rhs2, rhs1, false, speed);
1057 if (c)
1058 c->next_interp = c2->cand_num;
1059 else
1060 add_cand_for_stmt (gs, c2);
1061 }
1062 }
1063 else
1064 {
1065 double_int index;
1066
1067 /* Record an interpretation for the add-immediate. */
1068 index = tree_to_double_int (rhs2);
1069 if (subtract_p)
1070 index = -index;
1071
1072 c = create_add_imm_cand (gs, rhs1, index, speed);
1073
1074 /* Add the interpretation to the statement-candidate mapping. */
1075 add_cand_for_stmt (gs, c);
1076 }
1077 }
1078
1079 /* Given GS which is a negate of a scalar integer, make an appropriate
1080 entry in the candidate table. A negate is equivalent to a multiply
1081 by -1. */
1082
1083 static void
1084 slsr_process_neg (gimple gs, tree rhs1, bool speed)
1085 {
1086 /* Record a CAND_MULT interpretation for the multiply by -1. */
1087 slsr_cand_t c = create_mul_imm_cand (gs, rhs1, integer_minus_one_node, speed);
1088
1089 /* Add the interpretation to the statement-candidate mapping. */
1090 add_cand_for_stmt (gs, c);
1091 }
1092
1093 /* Help function for legal_cast_p, operating on two trees. Checks
1094 whether it's allowable to cast from RHS to LHS. See legal_cast_p
1095 for more details. */
1096
1097 static bool
1098 legal_cast_p_1 (tree lhs, tree rhs)
1099 {
1100 tree lhs_type, rhs_type;
1101 unsigned lhs_size, rhs_size;
1102 bool lhs_wraps, rhs_wraps;
1103
1104 lhs_type = TREE_TYPE (lhs);
1105 rhs_type = TREE_TYPE (rhs);
1106 lhs_size = TYPE_PRECISION (lhs_type);
1107 rhs_size = TYPE_PRECISION (rhs_type);
1108 lhs_wraps = TYPE_OVERFLOW_WRAPS (lhs_type);
1109 rhs_wraps = TYPE_OVERFLOW_WRAPS (rhs_type);
1110
1111 if (lhs_size < rhs_size
1112 || (rhs_wraps && !lhs_wraps)
1113 || (rhs_wraps && lhs_wraps && rhs_size != lhs_size))
1114 return false;
1115
1116 return true;
1117 }
1118
1119 /* Return TRUE if GS is a statement that defines an SSA name from
1120 a conversion and is legal for us to combine with an add and multiply
1121 in the candidate table. For example, suppose we have:
1122
1123 A = B + i;
1124 C = (type) A;
1125 D = C * S;
1126
1127 Without the type-cast, we would create a CAND_MULT for D with base B,
1128 index i, and stride S. We want to record this candidate only if it
1129 is equivalent to apply the type cast following the multiply:
1130
1131 A = B + i;
1132 E = A * S;
1133 D = (type) E;
1134
1135 We will record the type with the candidate for D. This allows us
1136 to use a similar previous candidate as a basis. If we have earlier seen
1137
1138 A' = B + i';
1139 C' = (type) A';
1140 D' = C' * S;
1141
1142 we can replace D with
1143
1144 D = D' + (i - i') * S;
1145
1146 But if moving the type-cast would change semantics, we mustn't do this.
1147
1148 This is legitimate for casts from a non-wrapping integral type to
1149 any integral type of the same or larger size. It is not legitimate
1150 to convert a wrapping type to a non-wrapping type, or to a wrapping
1151 type of a different size. I.e., with a wrapping type, we must
1152 assume that the addition B + i could wrap, in which case performing
1153 the multiply before or after one of the "illegal" type casts will
1154 have different semantics. */
1155
1156 static bool
1157 legal_cast_p (gimple gs, tree rhs)
1158 {
1159 if (!is_gimple_assign (gs)
1160 || !CONVERT_EXPR_CODE_P (gimple_assign_rhs_code (gs)))
1161 return false;
1162
1163 return legal_cast_p_1 (gimple_assign_lhs (gs), rhs);
1164 }
1165
1166 /* Given GS which is a cast to a scalar integer type, determine whether
1167 the cast is legal for strength reduction. If so, make at least one
1168 appropriate entry in the candidate table. */
1169
1170 static void
1171 slsr_process_cast (gimple gs, tree rhs1, bool speed)
1172 {
1173 tree lhs, ctype;
1174 slsr_cand_t base_cand, c, c2;
1175 unsigned savings = 0;
1176
1177 if (!legal_cast_p (gs, rhs1))
1178 return;
1179
1180 lhs = gimple_assign_lhs (gs);
1181 base_cand = base_cand_from_table (rhs1);
1182 ctype = TREE_TYPE (lhs);
1183
1184 if (base_cand)
1185 {
1186 while (base_cand)
1187 {
1188 /* Propagate all data from the base candidate except the type,
1189 which comes from the cast, and the base candidate's cast,
1190 which is no longer applicable. */
1191 if (has_single_use (rhs1))
1192 savings = (base_cand->dead_savings
1193 + stmt_cost (base_cand->cand_stmt, speed));
1194
1195 c = alloc_cand_and_find_basis (base_cand->kind, gs,
1196 base_cand->base_expr,
1197 base_cand->index, base_cand->stride,
1198 ctype, savings);
1199 if (base_cand->next_interp)
1200 base_cand = lookup_cand (base_cand->next_interp);
1201 else
1202 base_cand = NULL;
1203 }
1204 }
1205 else
1206 {
1207 /* If nothing is known about the RHS, create fresh CAND_ADD and
1208 CAND_MULT interpretations:
1209
1210 X = Y + (0 * 1)
1211 X = (Y + 0) * 1
1212
1213 The first of these is somewhat arbitrary, but the choice of
1214 1 for the stride simplifies the logic for propagating casts
1215 into their uses. */
1216 c = alloc_cand_and_find_basis (CAND_ADD, gs, rhs1, double_int_zero,
1217 integer_one_node, ctype, 0);
1218 c2 = alloc_cand_and_find_basis (CAND_MULT, gs, rhs1, double_int_zero,
1219 integer_one_node, ctype, 0);
1220 c->next_interp = c2->cand_num;
1221 }
1222
1223 /* Add the first (or only) interpretation to the statement-candidate
1224 mapping. */
1225 add_cand_for_stmt (gs, c);
1226 }
1227
1228 /* Given GS which is a copy of a scalar integer type, make at least one
1229 appropriate entry in the candidate table.
1230
1231 This interface is included for completeness, but is unnecessary
1232 if this pass immediately follows a pass that performs copy
1233 propagation, such as DOM. */
1234
1235 static void
1236 slsr_process_copy (gimple gs, tree rhs1, bool speed)
1237 {
1238 slsr_cand_t base_cand, c, c2;
1239 unsigned savings = 0;
1240
1241 base_cand = base_cand_from_table (rhs1);
1242
1243 if (base_cand)
1244 {
1245 while (base_cand)
1246 {
1247 /* Propagate all data from the base candidate. */
1248 if (has_single_use (rhs1))
1249 savings = (base_cand->dead_savings
1250 + stmt_cost (base_cand->cand_stmt, speed));
1251
1252 c = alloc_cand_and_find_basis (base_cand->kind, gs,
1253 base_cand->base_expr,
1254 base_cand->index, base_cand->stride,
1255 base_cand->cand_type, savings);
1256 if (base_cand->next_interp)
1257 base_cand = lookup_cand (base_cand->next_interp);
1258 else
1259 base_cand = NULL;
1260 }
1261 }
1262 else
1263 {
1264 /* If nothing is known about the RHS, create fresh CAND_ADD and
1265 CAND_MULT interpretations:
1266
1267 X = Y + (0 * 1)
1268 X = (Y + 0) * 1
1269
1270 The first of these is somewhat arbitrary, but the choice of
1271 1 for the stride simplifies the logic for propagating casts
1272 into their uses. */
1273 c = alloc_cand_and_find_basis (CAND_ADD, gs, rhs1, double_int_zero,
1274 integer_one_node, TREE_TYPE (rhs1), 0);
1275 c2 = alloc_cand_and_find_basis (CAND_MULT, gs, rhs1, double_int_zero,
1276 integer_one_node, TREE_TYPE (rhs1), 0);
1277 c->next_interp = c2->cand_num;
1278 }
1279
1280 /* Add the first (or only) interpretation to the statement-candidate
1281 mapping. */
1282 add_cand_for_stmt (gs, c);
1283 }
1284 \f
1285 /* Find strength-reduction candidates in block BB. */
1286
1287 static void
1288 find_candidates_in_block (struct dom_walk_data *walk_data ATTRIBUTE_UNUSED,
1289 basic_block bb)
1290 {
1291 bool speed = optimize_bb_for_speed_p (bb);
1292 gimple_stmt_iterator gsi;
1293
1294 for (gsi = gsi_start_bb (bb); !gsi_end_p (gsi); gsi_next (&gsi))
1295 {
1296 gimple gs = gsi_stmt (gsi);
1297
1298 if (gimple_vuse (gs) && gimple_assign_single_p (gs))
1299 slsr_process_ref (gs);
1300
1301 else if (is_gimple_assign (gs)
1302 && SCALAR_INT_MODE_P
1303 (TYPE_MODE (TREE_TYPE (gimple_assign_lhs (gs)))))
1304 {
1305 tree rhs1 = NULL_TREE, rhs2 = NULL_TREE;
1306
1307 switch (gimple_assign_rhs_code (gs))
1308 {
1309 case MULT_EXPR:
1310 case PLUS_EXPR:
1311 rhs1 = gimple_assign_rhs1 (gs);
1312 rhs2 = gimple_assign_rhs2 (gs);
1313 /* Should never happen, but currently some buggy situations
1314 in earlier phases put constants in rhs1. */
1315 if (TREE_CODE (rhs1) != SSA_NAME)
1316 continue;
1317 break;
1318
1319 /* Possible future opportunity: rhs1 of a ptr+ can be
1320 an ADDR_EXPR. */
1321 case POINTER_PLUS_EXPR:
1322 case MINUS_EXPR:
1323 rhs2 = gimple_assign_rhs2 (gs);
1324 /* Fall-through. */
1325
1326 case NOP_EXPR:
1327 case MODIFY_EXPR:
1328 case NEGATE_EXPR:
1329 rhs1 = gimple_assign_rhs1 (gs);
1330 if (TREE_CODE (rhs1) != SSA_NAME)
1331 continue;
1332 break;
1333
1334 default:
1335 ;
1336 }
1337
1338 switch (gimple_assign_rhs_code (gs))
1339 {
1340 case MULT_EXPR:
1341 slsr_process_mul (gs, rhs1, rhs2, speed);
1342 break;
1343
1344 case PLUS_EXPR:
1345 case POINTER_PLUS_EXPR:
1346 case MINUS_EXPR:
1347 slsr_process_add (gs, rhs1, rhs2, speed);
1348 break;
1349
1350 case NEGATE_EXPR:
1351 slsr_process_neg (gs, rhs1, speed);
1352 break;
1353
1354 case NOP_EXPR:
1355 slsr_process_cast (gs, rhs1, speed);
1356 break;
1357
1358 case MODIFY_EXPR:
1359 slsr_process_copy (gs, rhs1, speed);
1360 break;
1361
1362 default:
1363 ;
1364 }
1365 }
1366 }
1367 }
1368 \f
1369 /* Dump a candidate for debug. */
1370
1371 static void
1372 dump_candidate (slsr_cand_t c)
1373 {
1374 fprintf (dump_file, "%3d [%d] ", c->cand_num,
1375 gimple_bb (c->cand_stmt)->index);
1376 print_gimple_stmt (dump_file, c->cand_stmt, 0, 0);
1377 switch (c->kind)
1378 {
1379 case CAND_MULT:
1380 fputs (" MULT : (", dump_file);
1381 print_generic_expr (dump_file, c->base_expr, 0);
1382 fputs (" + ", dump_file);
1383 dump_double_int (dump_file, c->index, false);
1384 fputs (") * ", dump_file);
1385 print_generic_expr (dump_file, c->stride, 0);
1386 fputs (" : ", dump_file);
1387 break;
1388 case CAND_ADD:
1389 fputs (" ADD : ", dump_file);
1390 print_generic_expr (dump_file, c->base_expr, 0);
1391 fputs (" + (", dump_file);
1392 dump_double_int (dump_file, c->index, false);
1393 fputs (" * ", dump_file);
1394 print_generic_expr (dump_file, c->stride, 0);
1395 fputs (") : ", dump_file);
1396 break;
1397 case CAND_REF:
1398 fputs (" REF : ", dump_file);
1399 print_generic_expr (dump_file, c->base_expr, 0);
1400 fputs (" + (", dump_file);
1401 print_generic_expr (dump_file, c->stride, 0);
1402 fputs (") + ", dump_file);
1403 dump_double_int (dump_file, c->index, false);
1404 fputs (" : ", dump_file);
1405 break;
1406 default:
1407 gcc_unreachable ();
1408 }
1409 print_generic_expr (dump_file, c->cand_type, 0);
1410 fprintf (dump_file, "\n basis: %d dependent: %d sibling: %d\n",
1411 c->basis, c->dependent, c->sibling);
1412 fprintf (dump_file, " next-interp: %d dead-savings: %d\n",
1413 c->next_interp, c->dead_savings);
1414 if (c->def_phi)
1415 {
1416 fputs (" phi: ", dump_file);
1417 print_gimple_stmt (dump_file, c->def_phi, 0, 0);
1418 }
1419 fputs ("\n", dump_file);
1420 }
1421
1422 /* Dump the candidate vector for debug. */
1423
1424 static void
1425 dump_cand_vec (void)
1426 {
1427 unsigned i;
1428 slsr_cand_t c;
1429
1430 fprintf (dump_file, "\nStrength reduction candidate vector:\n\n");
1431
1432 FOR_EACH_VEC_ELT (cand_vec, i, c)
1433 dump_candidate (c);
1434 }
1435
1436 /* Callback used to dump the candidate chains hash table. */
1437
1438 static int
1439 base_cand_dump_callback (void **slot, void *ignored ATTRIBUTE_UNUSED)
1440 {
1441 const_cand_chain_t chain = *((const_cand_chain_t *) slot);
1442 cand_chain_t p;
1443
1444 print_generic_expr (dump_file, chain->base_expr, 0);
1445 fprintf (dump_file, " -> %d", chain->cand->cand_num);
1446
1447 for (p = chain->next; p; p = p->next)
1448 fprintf (dump_file, " -> %d", p->cand->cand_num);
1449
1450 fputs ("\n", dump_file);
1451 return 1;
1452 }
1453
1454 /* Dump the candidate chains. */
1455
1456 static void
1457 dump_cand_chains (void)
1458 {
1459 fprintf (dump_file, "\nStrength reduction candidate chains:\n\n");
1460 htab_traverse_noresize (base_cand_map, base_cand_dump_callback, NULL);
1461 fputs ("\n", dump_file);
1462 }
1463
1464 /* Dump the increment vector for debug. */
1465
1466 static void
1467 dump_incr_vec (void)
1468 {
1469 if (dump_file && (dump_flags & TDF_DETAILS))
1470 {
1471 unsigned i;
1472
1473 fprintf (dump_file, "\nIncrement vector:\n\n");
1474
1475 for (i = 0; i < incr_vec_len; i++)
1476 {
1477 fprintf (dump_file, "%3d increment: ", i);
1478 dump_double_int (dump_file, incr_vec[i].incr, false);
1479 fprintf (dump_file, "\n count: %d", incr_vec[i].count);
1480 fprintf (dump_file, "\n cost: %d", incr_vec[i].cost);
1481 fputs ("\n initializer: ", dump_file);
1482 print_generic_expr (dump_file, incr_vec[i].initializer, 0);
1483 fputs ("\n\n", dump_file);
1484 }
1485 }
1486 }
1487 \f
1488 /* Recursive helper for unconditional_cands_with_known_stride_p.
1489 Returns TRUE iff C, its siblings, and its dependents are all
1490 unconditional candidates. */
1491
1492 static bool
1493 unconditional_cands (slsr_cand_t c)
1494 {
1495 if (c->def_phi)
1496 return false;
1497
1498 if (c->sibling && !unconditional_cands (lookup_cand (c->sibling)))
1499 return false;
1500
1501 if (c->dependent && !unconditional_cands (lookup_cand (c->dependent)))
1502 return false;
1503
1504 return true;
1505 }
1506
1507 /* Determine whether or not the tree of candidates rooted at
1508 ROOT consists entirely of unconditional increments with
1509 an INTEGER_CST stride. */
1510
1511 static bool
1512 unconditional_cands_with_known_stride_p (slsr_cand_t root)
1513 {
1514 /* The stride is identical for all related candidates, so
1515 check it once. */
1516 if (TREE_CODE (root->stride) != INTEGER_CST)
1517 return false;
1518
1519 return unconditional_cands (lookup_cand (root->dependent));
1520 }
1521
1522 /* Replace *EXPR in candidate C with an equivalent strength-reduced
1523 data reference. */
1524
1525 static void
1526 replace_ref (tree *expr, slsr_cand_t c)
1527 {
1528 tree add_expr = fold_build2 (POINTER_PLUS_EXPR, TREE_TYPE (c->base_expr),
1529 c->base_expr, c->stride);
1530 tree mem_ref = fold_build2 (MEM_REF, TREE_TYPE (*expr), add_expr,
1531 double_int_to_tree (c->cand_type, c->index));
1532
1533 /* Gimplify the base addressing expression for the new MEM_REF tree. */
1534 gimple_stmt_iterator gsi = gsi_for_stmt (c->cand_stmt);
1535 TREE_OPERAND (mem_ref, 0)
1536 = force_gimple_operand_gsi (&gsi, TREE_OPERAND (mem_ref, 0),
1537 /*simple_p=*/true, NULL,
1538 /*before=*/true, GSI_SAME_STMT);
1539 copy_ref_info (mem_ref, *expr);
1540 *expr = mem_ref;
1541 update_stmt (c->cand_stmt);
1542 }
1543
1544 /* Replace CAND_REF candidate C, each sibling of candidate C, and each
1545 dependent of candidate C with an equivalent strength-reduced data
1546 reference. */
1547
1548 static void
1549 replace_refs (slsr_cand_t c)
1550 {
1551 if (gimple_vdef (c->cand_stmt))
1552 {
1553 tree *lhs = gimple_assign_lhs_ptr (c->cand_stmt);
1554 replace_ref (lhs, c);
1555 }
1556 else
1557 {
1558 tree *rhs = gimple_assign_rhs1_ptr (c->cand_stmt);
1559 replace_ref (rhs, c);
1560 }
1561
1562 if (c->sibling)
1563 replace_refs (lookup_cand (c->sibling));
1564
1565 if (c->dependent)
1566 replace_refs (lookup_cand (c->dependent));
1567 }
1568
1569 /* Calculate the increment required for candidate C relative to
1570 its basis. */
1571
1572 static double_int
1573 cand_increment (slsr_cand_t c)
1574 {
1575 slsr_cand_t basis;
1576
1577 /* If the candidate doesn't have a basis, just return its own
1578 index. This is useful in record_increments to help us find
1579 an existing initializer. */
1580 if (!c->basis)
1581 return c->index;
1582
1583 basis = lookup_cand (c->basis);
1584 gcc_assert (operand_equal_p (c->base_expr, basis->base_expr, 0));
1585 return c->index - basis->index;
1586 }
1587
1588 /* Calculate the increment required for candidate C relative to
1589 its basis. If we aren't going to generate pointer arithmetic
1590 for this candidate, return the absolute value of that increment
1591 instead. */
1592
1593 static inline double_int
1594 cand_abs_increment (slsr_cand_t c)
1595 {
1596 double_int increment = cand_increment (c);
1597
1598 if (!address_arithmetic_p && increment.is_negative ())
1599 increment = -increment;
1600
1601 return increment;
1602 }
1603
1604 /* If *VAR is NULL or is not of a compatible type with TYPE, create a
1605 new temporary reg of type TYPE and store it in *VAR. */
1606
1607 static inline void
1608 lazy_create_slsr_reg (tree *var, tree type)
1609 {
1610 if (!*var || !types_compatible_p (TREE_TYPE (*var), type))
1611 *var = create_tmp_reg (type, "slsr");
1612 }
1613
1614 /* Return TRUE iff candidate C has already been replaced under
1615 another interpretation. */
1616
1617 static inline bool
1618 cand_already_replaced (slsr_cand_t c)
1619 {
1620 return (gimple_bb (c->cand_stmt) == 0);
1621 }
1622
1623 /* Helper routine for replace_dependents, doing the work for a
1624 single candidate C. */
1625
1626 static void
1627 replace_dependent (slsr_cand_t c, enum tree_code cand_code)
1628 {
1629 double_int stride = tree_to_double_int (c->stride);
1630 double_int bump = cand_increment (c) * stride;
1631 gimple stmt_to_print = NULL;
1632 slsr_cand_t basis;
1633 tree basis_name, incr_type, bump_tree;
1634 enum tree_code code;
1635
1636 /* It is highly unlikely, but possible, that the resulting
1637 bump doesn't fit in a HWI. Abandon the replacement
1638 in this case. Restriction to signed HWI is conservative
1639 for unsigned types but allows for safe negation without
1640 twisted logic. */
1641 if (!bump.fits_shwi ())
1642 return;
1643
1644 basis = lookup_cand (c->basis);
1645 basis_name = gimple_assign_lhs (basis->cand_stmt);
1646 incr_type = TREE_TYPE (gimple_assign_rhs1 (c->cand_stmt));
1647 code = PLUS_EXPR;
1648
1649 if (bump.is_negative ())
1650 {
1651 code = MINUS_EXPR;
1652 bump = -bump;
1653 }
1654
1655 bump_tree = double_int_to_tree (incr_type, bump);
1656
1657 if (dump_file && (dump_flags & TDF_DETAILS))
1658 {
1659 fputs ("Replacing: ", dump_file);
1660 print_gimple_stmt (dump_file, c->cand_stmt, 0, 0);
1661 }
1662
1663 if (bump.is_zero ())
1664 {
1665 tree lhs = gimple_assign_lhs (c->cand_stmt);
1666 gimple copy_stmt = gimple_build_assign (lhs, basis_name);
1667 gimple_stmt_iterator gsi = gsi_for_stmt (c->cand_stmt);
1668 gimple_set_location (copy_stmt, gimple_location (c->cand_stmt));
1669 gsi_replace (&gsi, copy_stmt, false);
1670 if (dump_file && (dump_flags & TDF_DETAILS))
1671 stmt_to_print = copy_stmt;
1672 }
1673 else
1674 {
1675 tree rhs1 = gimple_assign_rhs1 (c->cand_stmt);
1676 tree rhs2 = gimple_assign_rhs2 (c->cand_stmt);
1677 if (cand_code != NEGATE_EXPR
1678 && ((operand_equal_p (rhs1, basis_name, 0)
1679 && operand_equal_p (rhs2, bump_tree, 0))
1680 || (operand_equal_p (rhs1, bump_tree, 0)
1681 && operand_equal_p (rhs2, basis_name, 0))))
1682 {
1683 if (dump_file && (dump_flags & TDF_DETAILS))
1684 {
1685 fputs ("(duplicate, not actually replacing)", dump_file);
1686 stmt_to_print = c->cand_stmt;
1687 }
1688 }
1689 else
1690 {
1691 gimple_stmt_iterator gsi = gsi_for_stmt (c->cand_stmt);
1692 gimple_assign_set_rhs_with_ops (&gsi, code, basis_name, bump_tree);
1693 update_stmt (gsi_stmt (gsi));
1694 if (dump_file && (dump_flags & TDF_DETAILS))
1695 stmt_to_print = gsi_stmt (gsi);
1696 }
1697 }
1698
1699 if (dump_file && (dump_flags & TDF_DETAILS))
1700 {
1701 fputs ("With: ", dump_file);
1702 print_gimple_stmt (dump_file, stmt_to_print, 0, 0);
1703 fputs ("\n", dump_file);
1704 }
1705 }
1706
1707 /* Replace candidate C, each sibling of candidate C, and each
1708 dependent of candidate C with an add or subtract. Note that we
1709 only operate on CAND_MULTs with known strides, so we will never
1710 generate a POINTER_PLUS_EXPR. Each candidate X = (B + i) * S is
1711 replaced by X = Y + ((i - i') * S), as described in the module
1712 commentary. The folded value ((i - i') * S) is referred to here
1713 as the "bump." */
1714
1715 static void
1716 replace_dependents (slsr_cand_t c)
1717 {
1718 enum tree_code cand_code = gimple_assign_rhs_code (c->cand_stmt);
1719
1720 /* It is not useful to replace casts, copies, or adds of an SSA name
1721 and a constant. Also skip candidates that have already been
1722 replaced under another interpretation. */
1723 if (cand_code != MODIFY_EXPR
1724 && cand_code != NOP_EXPR
1725 && c->kind == CAND_MULT
1726 && !cand_already_replaced (c))
1727 replace_dependent (c, cand_code);
1728
1729 if (c->sibling)
1730 replace_dependents (lookup_cand (c->sibling));
1731
1732 if (c->dependent)
1733 replace_dependents (lookup_cand (c->dependent));
1734 }
1735 \f
1736 /* Return the index in the increment vector of the given INCREMENT. */
1737
1738 static inline unsigned
1739 incr_vec_index (double_int increment)
1740 {
1741 unsigned i;
1742
1743 for (i = 0; i < incr_vec_len && increment != incr_vec[i].incr; i++)
1744 ;
1745
1746 gcc_assert (i < incr_vec_len);
1747 return i;
1748 }
1749
1750 /* Count the number of candidates in the tree rooted at C that have
1751 not already been replaced under other interpretations. */
1752
1753 static unsigned
1754 count_candidates (slsr_cand_t c)
1755 {
1756 unsigned count = cand_already_replaced (c) ? 0 : 1;
1757
1758 if (c->sibling)
1759 count += count_candidates (lookup_cand (c->sibling));
1760
1761 if (c->dependent)
1762 count += count_candidates (lookup_cand (c->dependent));
1763
1764 return count;
1765 }
1766
1767 /* Increase the count of INCREMENT by one in the increment vector.
1768 INCREMENT is associated with candidate C. If an initializer
1769 T_0 = stride * I is provided by a candidate that dominates all
1770 candidates with the same increment, also record T_0 for subsequent use. */
1771
1772 static void
1773 record_increment (slsr_cand_t c, double_int increment)
1774 {
1775 bool found = false;
1776 unsigned i;
1777
1778 /* Treat increments that differ only in sign as identical so as to
1779 share initializers, unless we are generating pointer arithmetic. */
1780 if (!address_arithmetic_p && increment.is_negative ())
1781 increment = -increment;
1782
1783 for (i = 0; i < incr_vec_len; i++)
1784 {
1785 if (incr_vec[i].incr == increment)
1786 {
1787 incr_vec[i].count++;
1788 found = true;
1789
1790 /* If we previously recorded an initializer that doesn't
1791 dominate this candidate, it's not going to be useful to
1792 us after all. */
1793 if (incr_vec[i].initializer
1794 && !dominated_by_p (CDI_DOMINATORS,
1795 gimple_bb (c->cand_stmt),
1796 incr_vec[i].init_bb))
1797 {
1798 incr_vec[i].initializer = NULL_TREE;
1799 incr_vec[i].init_bb = NULL;
1800 }
1801
1802 break;
1803 }
1804 }
1805
1806 if (!found)
1807 {
1808 /* The first time we see an increment, create the entry for it.
1809 If this is the root candidate which doesn't have a basis, set
1810 the count to zero. We're only processing it so it can possibly
1811 provide an initializer for other candidates. */
1812 incr_vec[incr_vec_len].incr = increment;
1813 incr_vec[incr_vec_len].count = c->basis ? 1 : 0;
1814 incr_vec[incr_vec_len].cost = COST_INFINITE;
1815
1816 /* Optimistically record the first occurrence of this increment
1817 as providing an initializer (if it does); we will revise this
1818 opinion later if it doesn't dominate all other occurrences.
1819 Exception: increments of -1, 0, 1 never need initializers. */
1820 if (c->kind == CAND_ADD
1821 && c->index == increment
1822 && (increment.sgt (double_int_one)
1823 || increment.slt (double_int_minus_one)))
1824 {
1825 tree t0;
1826 tree rhs1 = gimple_assign_rhs1 (c->cand_stmt);
1827 tree rhs2 = gimple_assign_rhs2 (c->cand_stmt);
1828 if (operand_equal_p (rhs1, c->base_expr, 0))
1829 t0 = rhs2;
1830 else
1831 t0 = rhs1;
1832 if (SSA_NAME_DEF_STMT (t0) && gimple_bb (SSA_NAME_DEF_STMT (t0)))
1833 {
1834 incr_vec[incr_vec_len].initializer = t0;
1835 incr_vec[incr_vec_len++].init_bb
1836 = gimple_bb (SSA_NAME_DEF_STMT (t0));
1837 }
1838 else
1839 {
1840 incr_vec[incr_vec_len].initializer = NULL_TREE;
1841 incr_vec[incr_vec_len++].init_bb = NULL;
1842 }
1843 }
1844 else
1845 {
1846 incr_vec[incr_vec_len].initializer = NULL_TREE;
1847 incr_vec[incr_vec_len++].init_bb = NULL;
1848 }
1849 }
1850 }
1851
1852 /* Determine how many times each unique increment occurs in the set
1853 of candidates rooted at C's parent, recording the data in the
1854 increment vector. For each unique increment I, if an initializer
1855 T_0 = stride * I is provided by a candidate that dominates all
1856 candidates with the same increment, also record T_0 for subsequent
1857 use. */
1858
1859 static void
1860 record_increments (slsr_cand_t c)
1861 {
1862 if (!cand_already_replaced (c))
1863 record_increment (c, cand_increment (c));
1864
1865 if (c->sibling)
1866 record_increments (lookup_cand (c->sibling));
1867
1868 if (c->dependent)
1869 record_increments (lookup_cand (c->dependent));
1870 }
1871
1872 /* Return the first candidate in the tree rooted at C that has not
1873 already been replaced, favoring siblings over dependents. */
1874
1875 static slsr_cand_t
1876 unreplaced_cand_in_tree (slsr_cand_t c)
1877 {
1878 if (!cand_already_replaced (c))
1879 return c;
1880
1881 if (c->sibling)
1882 {
1883 slsr_cand_t sib = unreplaced_cand_in_tree (lookup_cand (c->sibling));
1884 if (sib)
1885 return sib;
1886 }
1887
1888 if (c->dependent)
1889 {
1890 slsr_cand_t dep = unreplaced_cand_in_tree (lookup_cand (c->dependent));
1891 if (dep)
1892 return dep;
1893 }
1894
1895 return NULL;
1896 }
1897
1898 /* Return TRUE if the candidates in the tree rooted at C should be
1899 optimized for speed, else FALSE. We estimate this based on the block
1900 containing the most dominant candidate in the tree that has not yet
1901 been replaced. */
1902
1903 static bool
1904 optimize_cands_for_speed_p (slsr_cand_t c)
1905 {
1906 slsr_cand_t c2 = unreplaced_cand_in_tree (c);
1907 gcc_assert (c2);
1908 return optimize_bb_for_speed_p (gimple_bb (c2->cand_stmt));
1909 }
1910
1911 /* Add COST_IN to the lowest cost of any dependent path starting at
1912 candidate C or any of its siblings, counting only candidates along
1913 such paths with increment INCR. Assume that replacing a candidate
1914 reduces cost by REPL_SAVINGS. Also account for savings from any
1915 statements that would go dead. */
1916
1917 static int
1918 lowest_cost_path (int cost_in, int repl_savings, slsr_cand_t c, double_int incr)
1919 {
1920 int local_cost, sib_cost;
1921 double_int cand_incr = cand_abs_increment (c);
1922
1923 if (cand_already_replaced (c))
1924 local_cost = cost_in;
1925 else if (incr == cand_incr)
1926 local_cost = cost_in - repl_savings - c->dead_savings;
1927 else
1928 local_cost = cost_in - c->dead_savings;
1929
1930 if (c->dependent)
1931 local_cost = lowest_cost_path (local_cost, repl_savings,
1932 lookup_cand (c->dependent), incr);
1933
1934 if (c->sibling)
1935 {
1936 sib_cost = lowest_cost_path (cost_in, repl_savings,
1937 lookup_cand (c->sibling), incr);
1938 local_cost = MIN (local_cost, sib_cost);
1939 }
1940
1941 return local_cost;
1942 }
1943
1944 /* Compute the total savings that would accrue from all replacements
1945 in the candidate tree rooted at C, counting only candidates with
1946 increment INCR. Assume that replacing a candidate reduces cost
1947 by REPL_SAVINGS. Also account for savings from statements that
1948 would go dead. */
1949
1950 static int
1951 total_savings (int repl_savings, slsr_cand_t c, double_int incr)
1952 {
1953 int savings = 0;
1954 double_int cand_incr = cand_abs_increment (c);
1955
1956 if (incr == cand_incr && !cand_already_replaced (c))
1957 savings += repl_savings + c->dead_savings;
1958
1959 if (c->dependent)
1960 savings += total_savings (repl_savings, lookup_cand (c->dependent), incr);
1961
1962 if (c->sibling)
1963 savings += total_savings (repl_savings, lookup_cand (c->sibling), incr);
1964
1965 return savings;
1966 }
1967
1968 /* Use target-specific costs to determine and record which increments
1969 in the current candidate tree are profitable to replace, assuming
1970 MODE and SPEED. FIRST_DEP is the first dependent of the root of
1971 the candidate tree.
1972
1973 One slight limitation here is that we don't account for the possible
1974 introduction of casts in some cases. See replace_one_candidate for
1975 the cases where these are introduced. This should probably be cleaned
1976 up sometime. */
1977
1978 static void
1979 analyze_increments (slsr_cand_t first_dep, enum machine_mode mode, bool speed)
1980 {
1981 unsigned i;
1982
1983 for (i = 0; i < incr_vec_len; i++)
1984 {
1985 HOST_WIDE_INT incr = incr_vec[i].incr.to_shwi ();
1986
1987 /* If somehow this increment is bigger than a HWI, we won't
1988 be optimizing candidates that use it. And if the increment
1989 has a count of zero, nothing will be done with it. */
1990 if (!incr_vec[i].incr.fits_shwi () || !incr_vec[i].count)
1991 incr_vec[i].cost = COST_INFINITE;
1992
1993 /* Increments of 0, 1, and -1 are always profitable to replace,
1994 because they always replace a multiply or add with an add or
1995 copy, and may cause one or more existing instructions to go
1996 dead. Exception: -1 can't be assumed to be profitable for
1997 pointer addition. */
1998 else if (incr == 0
1999 || incr == 1
2000 || (incr == -1
2001 && (gimple_assign_rhs_code (first_dep->cand_stmt)
2002 != POINTER_PLUS_EXPR)))
2003 incr_vec[i].cost = COST_NEUTRAL;
2004
2005 /* FORNOW: If we need to add an initializer, give up if a cast from
2006 the candidate's type to its stride's type can lose precision.
2007 This could eventually be handled better by expressly retaining the
2008 result of a cast to a wider type in the stride. Example:
2009
2010 short int _1;
2011 _2 = (int) _1;
2012 _3 = _2 * 10;
2013 _4 = x + _3; ADD: x + (10 * _1) : int
2014 _5 = _2 * 15;
2015 _6 = x + _3; ADD: x + (15 * _1) : int
2016
2017 Right now replacing _6 would cause insertion of an initializer
2018 of the form "short int T = _1 * 5;" followed by a cast to
2019 int, which could overflow incorrectly. Had we recorded _2 or
2020 (int)_1 as the stride, this wouldn't happen. However, doing
2021 this breaks other opportunities, so this will require some
2022 care. */
2023 else if (!incr_vec[i].initializer
2024 && TREE_CODE (first_dep->stride) != INTEGER_CST
2025 && !legal_cast_p_1 (first_dep->stride,
2026 gimple_assign_lhs (first_dep->cand_stmt)))
2027
2028 incr_vec[i].cost = COST_INFINITE;
2029
2030 /* If we need to add an initializer, make sure we don't introduce
2031 a multiply by a pointer type, which can happen in certain cast
2032 scenarios. FIXME: When cleaning up these cast issues, we can
2033 afford to introduce the multiply provided we cast out to an
2034 unsigned int of appropriate size. */
2035 else if (!incr_vec[i].initializer
2036 && TREE_CODE (first_dep->stride) != INTEGER_CST
2037 && POINTER_TYPE_P (TREE_TYPE (first_dep->stride)))
2038
2039 incr_vec[i].cost = COST_INFINITE;
2040
2041 /* For any other increment, if this is a multiply candidate, we
2042 must introduce a temporary T and initialize it with
2043 T_0 = stride * increment. When optimizing for speed, walk the
2044 candidate tree to calculate the best cost reduction along any
2045 path; if it offsets the fixed cost of inserting the initializer,
2046 replacing the increment is profitable. When optimizing for
2047 size, instead calculate the total cost reduction from replacing
2048 all candidates with this increment. */
2049 else if (first_dep->kind == CAND_MULT)
2050 {
2051 int cost = mult_by_coeff_cost (incr, mode, speed);
2052 int repl_savings = mul_cost (speed, mode) - add_cost (speed, mode);
2053 if (speed)
2054 cost = lowest_cost_path (cost, repl_savings, first_dep,
2055 incr_vec[i].incr);
2056 else
2057 cost -= total_savings (repl_savings, first_dep, incr_vec[i].incr);
2058
2059 incr_vec[i].cost = cost;
2060 }
2061
2062 /* If this is an add candidate, the initializer may already
2063 exist, so only calculate the cost of the initializer if it
2064 doesn't. We are replacing one add with another here, so the
2065 known replacement savings is zero. We will account for removal
2066 of dead instructions in lowest_cost_path or total_savings. */
2067 else
2068 {
2069 int cost = 0;
2070 if (!incr_vec[i].initializer)
2071 cost = mult_by_coeff_cost (incr, mode, speed);
2072
2073 if (speed)
2074 cost = lowest_cost_path (cost, 0, first_dep, incr_vec[i].incr);
2075 else
2076 cost -= total_savings (0, first_dep, incr_vec[i].incr);
2077
2078 incr_vec[i].cost = cost;
2079 }
2080 }
2081 }
2082
2083 /* Return the nearest common dominator of BB1 and BB2. If the blocks
2084 are identical, return the earlier of C1 and C2 in *WHERE. Otherwise,
2085 if the NCD matches BB1, return C1 in *WHERE; if the NCD matches BB2,
2086 return C2 in *WHERE; and if the NCD matches neither, return NULL in
2087 *WHERE. Note: It is possible for one of C1 and C2 to be NULL. */
2088
2089 static basic_block
2090 ncd_for_two_cands (basic_block bb1, basic_block bb2,
2091 slsr_cand_t c1, slsr_cand_t c2, slsr_cand_t *where)
2092 {
2093 basic_block ncd;
2094
2095 if (!bb1)
2096 {
2097 *where = c2;
2098 return bb2;
2099 }
2100
2101 if (!bb2)
2102 {
2103 *where = c1;
2104 return bb1;
2105 }
2106
2107 ncd = nearest_common_dominator (CDI_DOMINATORS, bb1, bb2);
2108
2109 /* If both candidates are in the same block, the earlier
2110 candidate wins. */
2111 if (bb1 == ncd && bb2 == ncd)
2112 {
2113 if (!c1 || (c2 && c2->cand_num < c1->cand_num))
2114 *where = c2;
2115 else
2116 *where = c1;
2117 }
2118
2119 /* Otherwise, if one of them produced a candidate in the
2120 dominator, that one wins. */
2121 else if (bb1 == ncd)
2122 *where = c1;
2123
2124 else if (bb2 == ncd)
2125 *where = c2;
2126
2127 /* If neither matches the dominator, neither wins. */
2128 else
2129 *where = NULL;
2130
2131 return ncd;
2132 }
2133
2134 /* Consider all candidates in the tree rooted at C for which INCR
2135 represents the required increment of C relative to its basis.
2136 Find and return the basic block that most nearly dominates all
2137 such candidates. If the returned block contains one or more of
2138 the candidates, return the earliest candidate in the block in
2139 *WHERE. */
2140
2141 static basic_block
2142 nearest_common_dominator_for_cands (slsr_cand_t c, double_int incr,
2143 slsr_cand_t *where)
2144 {
2145 basic_block sib_ncd = NULL, dep_ncd = NULL, this_ncd = NULL, ncd;
2146 slsr_cand_t sib_where = NULL, dep_where = NULL, this_where = NULL, new_where;
2147 double_int cand_incr;
2148
2149 /* First find the NCD of all siblings and dependents. */
2150 if (c->sibling)
2151 sib_ncd = nearest_common_dominator_for_cands (lookup_cand (c->sibling),
2152 incr, &sib_where);
2153 if (c->dependent)
2154 dep_ncd = nearest_common_dominator_for_cands (lookup_cand (c->dependent),
2155 incr, &dep_where);
2156 if (!sib_ncd && !dep_ncd)
2157 {
2158 new_where = NULL;
2159 ncd = NULL;
2160 }
2161 else if (sib_ncd && !dep_ncd)
2162 {
2163 new_where = sib_where;
2164 ncd = sib_ncd;
2165 }
2166 else if (dep_ncd && !sib_ncd)
2167 {
2168 new_where = dep_where;
2169 ncd = dep_ncd;
2170 }
2171 else
2172 ncd = ncd_for_two_cands (sib_ncd, dep_ncd, sib_where,
2173 dep_where, &new_where);
2174
2175 /* If the candidate's increment doesn't match the one we're interested
2176 in, then the result depends only on siblings and dependents. */
2177 cand_incr = cand_abs_increment (c);
2178
2179 if (cand_incr != incr || cand_already_replaced (c))
2180 {
2181 *where = new_where;
2182 return ncd;
2183 }
2184
2185 /* Otherwise, compare this candidate with the result from all siblings
2186 and dependents. */
2187 this_where = c;
2188 this_ncd = gimple_bb (c->cand_stmt);
2189 ncd = ncd_for_two_cands (ncd, this_ncd, new_where, this_where, where);
2190
2191 return ncd;
2192 }
2193
2194 /* Return TRUE if the increment indexed by INDEX is profitable to replace. */
2195
2196 static inline bool
2197 profitable_increment_p (unsigned index)
2198 {
2199 return (incr_vec[index].cost <= COST_NEUTRAL);
2200 }
2201
2202 /* For each profitable increment in the increment vector not equal to
2203 0 or 1 (or -1, for non-pointer arithmetic), find the nearest common
2204 dominator of all statements in the candidate chain rooted at C
2205 that require that increment, and insert an initializer
2206 T_0 = stride * increment at that location. Record T_0 with the
2207 increment record. */
2208
2209 static void
2210 insert_initializers (slsr_cand_t c)
2211 {
2212 unsigned i;
2213 tree new_var = NULL_TREE;
2214
2215 for (i = 0; i < incr_vec_len; i++)
2216 {
2217 basic_block bb;
2218 slsr_cand_t where = NULL;
2219 gimple init_stmt;
2220 tree stride_type, new_name, incr_tree;
2221 double_int incr = incr_vec[i].incr;
2222
2223 if (!profitable_increment_p (i)
2224 || incr.is_one ()
2225 || (incr.is_minus_one ()
2226 && gimple_assign_rhs_code (c->cand_stmt) != POINTER_PLUS_EXPR)
2227 || incr.is_zero ())
2228 continue;
2229
2230 /* We may have already identified an existing initializer that
2231 will suffice. */
2232 if (incr_vec[i].initializer)
2233 {
2234 if (dump_file && (dump_flags & TDF_DETAILS))
2235 {
2236 fputs ("Using existing initializer: ", dump_file);
2237 print_gimple_stmt (dump_file,
2238 SSA_NAME_DEF_STMT (incr_vec[i].initializer),
2239 0, 0);
2240 }
2241 continue;
2242 }
2243
2244 /* Find the block that most closely dominates all candidates
2245 with this increment. If there is at least one candidate in
2246 that block, the earliest one will be returned in WHERE. */
2247 bb = nearest_common_dominator_for_cands (c, incr, &where);
2248
2249 /* Create a new SSA name to hold the initializer's value. */
2250 stride_type = TREE_TYPE (c->stride);
2251 lazy_create_slsr_reg (&new_var, stride_type);
2252 new_name = make_ssa_name (new_var, NULL);
2253 incr_vec[i].initializer = new_name;
2254
2255 /* Create the initializer and insert it in the latest possible
2256 dominating position. */
2257 incr_tree = double_int_to_tree (stride_type, incr);
2258 init_stmt = gimple_build_assign_with_ops (MULT_EXPR, new_name,
2259 c->stride, incr_tree);
2260 if (where)
2261 {
2262 gimple_stmt_iterator gsi = gsi_for_stmt (where->cand_stmt);
2263 gsi_insert_before (&gsi, init_stmt, GSI_SAME_STMT);
2264 gimple_set_location (init_stmt, gimple_location (where->cand_stmt));
2265 }
2266 else
2267 {
2268 gimple_stmt_iterator gsi = gsi_last_bb (bb);
2269 gimple basis_stmt = lookup_cand (c->basis)->cand_stmt;
2270
2271 if (!gsi_end_p (gsi) && is_ctrl_stmt (gsi_stmt (gsi)))
2272 gsi_insert_before (&gsi, init_stmt, GSI_SAME_STMT);
2273 else
2274 gsi_insert_after (&gsi, init_stmt, GSI_SAME_STMT);
2275
2276 gimple_set_location (init_stmt, gimple_location (basis_stmt));
2277 }
2278
2279 if (dump_file && (dump_flags & TDF_DETAILS))
2280 {
2281 fputs ("Inserting initializer: ", dump_file);
2282 print_gimple_stmt (dump_file, init_stmt, 0, 0);
2283 }
2284 }
2285 }
2286
2287 /* Create a NOP_EXPR that copies FROM_EXPR into a new SSA name of
2288 type TO_TYPE, and insert it in front of the statement represented
2289 by candidate C. Use *NEW_VAR to create the new SSA name. Return
2290 the new SSA name. */
2291
2292 static tree
2293 introduce_cast_before_cand (slsr_cand_t c, tree to_type,
2294 tree from_expr, tree *new_var)
2295 {
2296 tree cast_lhs;
2297 gimple cast_stmt;
2298 gimple_stmt_iterator gsi = gsi_for_stmt (c->cand_stmt);
2299
2300 lazy_create_slsr_reg (new_var, to_type);
2301 cast_lhs = make_ssa_name (*new_var, NULL);
2302 cast_stmt = gimple_build_assign_with_ops (NOP_EXPR, cast_lhs,
2303 from_expr, NULL_TREE);
2304 gimple_set_location (cast_stmt, gimple_location (c->cand_stmt));
2305 gsi_insert_before (&gsi, cast_stmt, GSI_SAME_STMT);
2306
2307 if (dump_file && (dump_flags & TDF_DETAILS))
2308 {
2309 fputs (" Inserting: ", dump_file);
2310 print_gimple_stmt (dump_file, cast_stmt, 0, 0);
2311 }
2312
2313 return cast_lhs;
2314 }
2315
2316 /* Replace the RHS of the statement represented by candidate C with
2317 NEW_CODE, NEW_RHS1, and NEW_RHS2, provided that to do so doesn't
2318 leave C unchanged or just interchange its operands. The original
2319 operation and operands are in OLD_CODE, OLD_RHS1, and OLD_RHS2.
2320 If the replacement was made and we are doing a details dump,
2321 return the revised statement, else NULL. */
2322
2323 static gimple
2324 replace_rhs_if_not_dup (enum tree_code new_code, tree new_rhs1, tree new_rhs2,
2325 enum tree_code old_code, tree old_rhs1, tree old_rhs2,
2326 slsr_cand_t c)
2327 {
2328 if (new_code != old_code
2329 || ((!operand_equal_p (new_rhs1, old_rhs1, 0)
2330 || !operand_equal_p (new_rhs2, old_rhs2, 0))
2331 && (!operand_equal_p (new_rhs1, old_rhs2, 0)
2332 || !operand_equal_p (new_rhs2, old_rhs1, 0))))
2333 {
2334 gimple_stmt_iterator gsi = gsi_for_stmt (c->cand_stmt);
2335 gimple_assign_set_rhs_with_ops (&gsi, new_code, new_rhs1, new_rhs2);
2336 update_stmt (gsi_stmt (gsi));
2337
2338 if (dump_file && (dump_flags & TDF_DETAILS))
2339 return gsi_stmt (gsi);
2340 }
2341
2342 else if (dump_file && (dump_flags & TDF_DETAILS))
2343 fputs (" (duplicate, not actually replacing)\n", dump_file);
2344
2345 return NULL;
2346 }
2347
2348 /* Strength-reduce the statement represented by candidate C by replacing
2349 it with an equivalent addition or subtraction. I is the index into
2350 the increment vector identifying C's increment. NEW_VAR is used to
2351 create a new SSA name if a cast needs to be introduced. BASIS_NAME
2352 is the rhs1 to use in creating the add/subtract. */
2353
2354 static void
2355 replace_one_candidate (slsr_cand_t c, unsigned i, tree *new_var,
2356 tree basis_name)
2357 {
2358 gimple stmt_to_print = NULL;
2359 tree orig_rhs1, orig_rhs2;
2360 tree rhs2;
2361 enum tree_code orig_code, repl_code;
2362 double_int cand_incr;
2363
2364 orig_code = gimple_assign_rhs_code (c->cand_stmt);
2365 orig_rhs1 = gimple_assign_rhs1 (c->cand_stmt);
2366 orig_rhs2 = gimple_assign_rhs2 (c->cand_stmt);
2367 cand_incr = cand_increment (c);
2368
2369 if (dump_file && (dump_flags & TDF_DETAILS))
2370 {
2371 fputs ("Replacing: ", dump_file);
2372 print_gimple_stmt (dump_file, c->cand_stmt, 0, 0);
2373 stmt_to_print = c->cand_stmt;
2374 }
2375
2376 if (address_arithmetic_p)
2377 repl_code = POINTER_PLUS_EXPR;
2378 else
2379 repl_code = PLUS_EXPR;
2380
2381 /* If the increment has an initializer T_0, replace the candidate
2382 statement with an add of the basis name and the initializer. */
2383 if (incr_vec[i].initializer)
2384 {
2385 tree init_type = TREE_TYPE (incr_vec[i].initializer);
2386 tree orig_type = TREE_TYPE (orig_rhs2);
2387
2388 if (types_compatible_p (orig_type, init_type))
2389 rhs2 = incr_vec[i].initializer;
2390 else
2391 rhs2 = introduce_cast_before_cand (c, orig_type,
2392 incr_vec[i].initializer,
2393 new_var);
2394
2395 if (incr_vec[i].incr != cand_incr)
2396 {
2397 gcc_assert (repl_code == PLUS_EXPR);
2398 repl_code = MINUS_EXPR;
2399 }
2400
2401 stmt_to_print = replace_rhs_if_not_dup (repl_code, basis_name, rhs2,
2402 orig_code, orig_rhs1, orig_rhs2,
2403 c);
2404 }
2405
2406 /* Otherwise, the increment is one of -1, 0, and 1. Replace
2407 with a subtract of the stride from the basis name, a copy
2408 from the basis name, or an add of the stride to the basis
2409 name, respectively. It may be necessary to introduce a
2410 cast (or reuse an existing cast). */
2411 else if (cand_incr.is_one ())
2412 {
2413 tree stride_type = TREE_TYPE (c->stride);
2414 tree orig_type = TREE_TYPE (orig_rhs2);
2415
2416 if (types_compatible_p (orig_type, stride_type))
2417 rhs2 = c->stride;
2418 else
2419 rhs2 = introduce_cast_before_cand (c, orig_type, c->stride, new_var);
2420
2421 stmt_to_print = replace_rhs_if_not_dup (repl_code, basis_name, rhs2,
2422 orig_code, orig_rhs1, orig_rhs2,
2423 c);
2424 }
2425
2426 else if (cand_incr.is_minus_one ())
2427 {
2428 tree stride_type = TREE_TYPE (c->stride);
2429 tree orig_type = TREE_TYPE (orig_rhs2);
2430 gcc_assert (repl_code != POINTER_PLUS_EXPR);
2431
2432 if (types_compatible_p (orig_type, stride_type))
2433 rhs2 = c->stride;
2434 else
2435 rhs2 = introduce_cast_before_cand (c, orig_type, c->stride, new_var);
2436
2437 if (orig_code != MINUS_EXPR
2438 || !operand_equal_p (basis_name, orig_rhs1, 0)
2439 || !operand_equal_p (rhs2, orig_rhs2, 0))
2440 {
2441 gimple_stmt_iterator gsi = gsi_for_stmt (c->cand_stmt);
2442 gimple_assign_set_rhs_with_ops (&gsi, MINUS_EXPR, basis_name, rhs2);
2443 update_stmt (gsi_stmt (gsi));
2444
2445 if (dump_file && (dump_flags & TDF_DETAILS))
2446 stmt_to_print = gsi_stmt (gsi);
2447 }
2448 else if (dump_file && (dump_flags & TDF_DETAILS))
2449 fputs (" (duplicate, not actually replacing)\n", dump_file);
2450 }
2451
2452 else if (cand_incr.is_zero ())
2453 {
2454 tree lhs = gimple_assign_lhs (c->cand_stmt);
2455 tree lhs_type = TREE_TYPE (lhs);
2456 tree basis_type = TREE_TYPE (basis_name);
2457
2458 if (types_compatible_p (lhs_type, basis_type))
2459 {
2460 gimple copy_stmt = gimple_build_assign (lhs, basis_name);
2461 gimple_stmt_iterator gsi = gsi_for_stmt (c->cand_stmt);
2462 gimple_set_location (copy_stmt, gimple_location (c->cand_stmt));
2463 gsi_replace (&gsi, copy_stmt, false);
2464
2465 if (dump_file && (dump_flags & TDF_DETAILS))
2466 stmt_to_print = copy_stmt;
2467 }
2468 else
2469 {
2470 gimple_stmt_iterator gsi = gsi_for_stmt (c->cand_stmt);
2471 gimple cast_stmt = gimple_build_assign_with_ops (NOP_EXPR, lhs,
2472 basis_name,
2473 NULL_TREE);
2474 gimple_set_location (cast_stmt, gimple_location (c->cand_stmt));
2475 gsi_replace (&gsi, cast_stmt, false);
2476
2477 if (dump_file && (dump_flags & TDF_DETAILS))
2478 stmt_to_print = cast_stmt;
2479 }
2480 }
2481 else
2482 gcc_unreachable ();
2483
2484 if (dump_file && (dump_flags & TDF_DETAILS) && stmt_to_print)
2485 {
2486 fputs ("With: ", dump_file);
2487 print_gimple_stmt (dump_file, stmt_to_print, 0, 0);
2488 fputs ("\n", dump_file);
2489 }
2490 }
2491
2492 /* For each candidate in the tree rooted at C, replace it with
2493 an increment if such has been shown to be profitable. */
2494
2495 static void
2496 replace_profitable_candidates (slsr_cand_t c)
2497 {
2498 if (!cand_already_replaced (c))
2499 {
2500 double_int increment = cand_abs_increment (c);
2501 tree new_var = NULL;
2502 enum tree_code orig_code = gimple_assign_rhs_code (c->cand_stmt);
2503 unsigned i;
2504
2505 i = incr_vec_index (increment);
2506
2507 /* Only process profitable increments. Nothing useful can be done
2508 to a cast or copy. */
2509 if (profitable_increment_p (i)
2510 && orig_code != MODIFY_EXPR
2511 && orig_code != NOP_EXPR)
2512 {
2513 slsr_cand_t basis = lookup_cand (c->basis);
2514 tree basis_name = gimple_assign_lhs (basis->cand_stmt);
2515 replace_one_candidate (c, i, &new_var, basis_name);
2516 }
2517 }
2518
2519 if (c->sibling)
2520 replace_profitable_candidates (lookup_cand (c->sibling));
2521
2522 if (c->dependent)
2523 replace_profitable_candidates (lookup_cand (c->dependent));
2524 }
2525 \f
2526 /* Analyze costs of related candidates in the candidate vector,
2527 and make beneficial replacements. */
2528
2529 static void
2530 analyze_candidates_and_replace (void)
2531 {
2532 unsigned i;
2533 slsr_cand_t c;
2534
2535 /* Each candidate that has a null basis and a non-null
2536 dependent is the root of a tree of related statements.
2537 Analyze each tree to determine a subset of those
2538 statements that can be replaced with maximum benefit. */
2539 FOR_EACH_VEC_ELT (cand_vec, i, c)
2540 {
2541 slsr_cand_t first_dep;
2542
2543 if (c->basis != 0 || c->dependent == 0)
2544 continue;
2545
2546 if (dump_file && (dump_flags & TDF_DETAILS))
2547 fprintf (dump_file, "\nProcessing dependency tree rooted at %d.\n",
2548 c->cand_num);
2549
2550 first_dep = lookup_cand (c->dependent);
2551
2552 /* If this is a chain of CAND_REFs, unconditionally replace
2553 each of them with a strength-reduced data reference. */
2554 if (c->kind == CAND_REF)
2555 replace_refs (c);
2556
2557 /* If the common stride of all related candidates is a
2558 known constant, and none of these has a phi-dependence,
2559 then all replacements are considered profitable.
2560 Each replaces a multiply by a single add, with the
2561 possibility that a feeding add also goes dead as a
2562 result. */
2563 else if (unconditional_cands_with_known_stride_p (c))
2564 replace_dependents (first_dep);
2565
2566 /* When the stride is an SSA name, it may still be profitable
2567 to replace some or all of the dependent candidates, depending
2568 on whether the introduced increments can be reused, or are
2569 less expensive to calculate than the replaced statements. */
2570 else
2571 {
2572 unsigned length;
2573 enum machine_mode mode;
2574 bool speed;
2575
2576 /* Determine whether we'll be generating pointer arithmetic
2577 when replacing candidates. */
2578 address_arithmetic_p = (c->kind == CAND_ADD
2579 && POINTER_TYPE_P (c->cand_type));
2580
2581 /* If all candidates have already been replaced under other
2582 interpretations, nothing remains to be done. */
2583 length = count_candidates (c);
2584 if (!length)
2585 continue;
2586
2587 /* Construct an array of increments for this candidate chain. */
2588 incr_vec = XNEWVEC (incr_info, length);
2589 incr_vec_len = 0;
2590 record_increments (c);
2591
2592 /* Determine which increments are profitable to replace. */
2593 mode = TYPE_MODE (TREE_TYPE (gimple_assign_lhs (c->cand_stmt)));
2594 speed = optimize_cands_for_speed_p (c);
2595 analyze_increments (first_dep, mode, speed);
2596
2597 /* Insert initializers of the form T_0 = stride * increment
2598 for use in profitable replacements. */
2599 insert_initializers (first_dep);
2600 dump_incr_vec ();
2601
2602 /* Perform the replacements. */
2603 replace_profitable_candidates (first_dep);
2604 free (incr_vec);
2605 }
2606
2607 /* TODO: When conditional increments occur so that a
2608 candidate is dependent upon a phi-basis, the cost of
2609 introducing a temporary must be accounted for. */
2610 }
2611 }
2612
2613 static unsigned
2614 execute_strength_reduction (void)
2615 {
2616 struct dom_walk_data walk_data;
2617
2618 /* Create the obstack where candidates will reside. */
2619 gcc_obstack_init (&cand_obstack);
2620
2621 /* Allocate the candidate vector. */
2622 cand_vec.create (128);
2623
2624 /* Allocate the mapping from statements to candidate indices. */
2625 stmt_cand_map = pointer_map_create ();
2626
2627 /* Create the obstack where candidate chains will reside. */
2628 gcc_obstack_init (&chain_obstack);
2629
2630 /* Allocate the mapping from base expressions to candidate chains. */
2631 base_cand_map = htab_create (500, base_cand_hash,
2632 base_cand_eq, base_cand_free);
2633
2634 /* Initialize the loop optimizer. We need to detect flow across
2635 back edges, and this gives us dominator information as well. */
2636 loop_optimizer_init (AVOID_CFG_MODIFICATIONS);
2637
2638 /* Set up callbacks for the generic dominator tree walker. */
2639 walk_data.dom_direction = CDI_DOMINATORS;
2640 walk_data.initialize_block_local_data = NULL;
2641 walk_data.before_dom_children = find_candidates_in_block;
2642 walk_data.after_dom_children = NULL;
2643 walk_data.global_data = NULL;
2644 walk_data.block_local_data_size = 0;
2645 init_walk_dominator_tree (&walk_data);
2646
2647 /* Walk the CFG in predominator order looking for strength reduction
2648 candidates. */
2649 walk_dominator_tree (&walk_data, ENTRY_BLOCK_PTR);
2650
2651 if (dump_file && (dump_flags & TDF_DETAILS))
2652 {
2653 dump_cand_vec ();
2654 dump_cand_chains ();
2655 }
2656
2657 /* Analyze costs and make appropriate replacements. */
2658 analyze_candidates_and_replace ();
2659
2660 /* Free resources. */
2661 fini_walk_dominator_tree (&walk_data);
2662 loop_optimizer_finalize ();
2663 htab_delete (base_cand_map);
2664 obstack_free (&chain_obstack, NULL);
2665 pointer_map_destroy (stmt_cand_map);
2666 cand_vec.release ();
2667 obstack_free (&cand_obstack, NULL);
2668
2669 return 0;
2670 }
2671
2672 static bool
2673 gate_strength_reduction (void)
2674 {
2675 return flag_tree_slsr;
2676 }
2677
2678 struct gimple_opt_pass pass_strength_reduction =
2679 {
2680 {
2681 GIMPLE_PASS,
2682 "slsr", /* name */
2683 OPTGROUP_NONE, /* optinfo_flags */
2684 gate_strength_reduction, /* gate */
2685 execute_strength_reduction, /* execute */
2686 NULL, /* sub */
2687 NULL, /* next */
2688 0, /* static_pass_number */
2689 TV_GIMPLE_SLSR, /* tv_id */
2690 PROP_cfg | PROP_ssa, /* properties_required */
2691 0, /* properties_provided */
2692 0, /* properties_destroyed */
2693 0, /* todo_flags_start */
2694 TODO_verify_ssa /* todo_flags_finish */
2695 }
2696 };