]> git.ipfire.org Git - thirdparty/gcc.git/blob - gcc/gimple-ssa-strength-reduction.c
* expmed.h (alg_hash, alg_hash_used_p, sdiv_pow2_cheap,
[thirdparty/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. (data gathering complete,
34 replacements pending)
35 3) Implicit multiplies in addressing expressions. (pending)
36 4) Explicit multiplies, conditional increments. (pending)
37
38 It would also be possible to apply strength reduction to divisions
39 and modulos, but such opportunities are relatively uncommon.
40
41 Strength reduction is also currently restricted to integer operations.
42 If desired, it could be extended to floating-point operations under
43 control of something like -funsafe-math-optimizations. */
44
45 #include "config.h"
46 #include "system.h"
47 #include "coretypes.h"
48 #include "tree.h"
49 #include "gimple.h"
50 #include "basic-block.h"
51 #include "tree-pass.h"
52 #include "cfgloop.h"
53 #include "gimple-pretty-print.h"
54 #include "tree-flow.h"
55 #include "domwalk.h"
56 #include "pointer-set.h"
57 #include "expmed.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
112 /* Index into the candidate vector, offset by 1. VECs are zero-based,
113 while cand_idx's are one-based, with zero indicating null. */
114 typedef unsigned cand_idx;
115
116 /* The kind of candidate. */
117 enum cand_kind
118 {
119 CAND_MULT,
120 CAND_ADD
121 };
122
123 struct slsr_cand_d
124 {
125 /* The candidate statement S1. */
126 gimple cand_stmt;
127
128 /* The base SSA name B. */
129 tree base_name;
130
131 /* The stride S. */
132 tree stride;
133
134 /* The index constant i. */
135 double_int index;
136
137 /* The type of the candidate. This is normally the type of base_name,
138 but casts may have occurred when combining feeding instructions.
139 A candidate can only be a basis for candidates of the same final type. */
140 tree cand_type;
141
142 /* The kind of candidate (CAND_MULT, etc.). */
143 enum cand_kind kind;
144
145 /* Index of this candidate in the candidate vector. */
146 cand_idx cand_num;
147
148 /* Index of the next candidate record for the same statement.
149 A statement may be useful in more than one way (e.g., due to
150 commutativity). So we can have multiple "interpretations"
151 of a statement. */
152 cand_idx next_interp;
153
154 /* Index of the basis statement S0, if any, in the candidate vector. */
155 cand_idx basis;
156
157 /* First candidate for which this candidate is a basis, if one exists. */
158 cand_idx dependent;
159
160 /* Next candidate having the same basis as this one. */
161 cand_idx sibling;
162
163 /* If this is a conditional candidate, the defining PHI statement
164 for the base SSA name B. For future use; always NULL for now. */
165 gimple def_phi;
166
167 /* Savings that can be expected from eliminating dead code if this
168 candidate is replaced. */
169 int dead_savings;
170 };
171
172 typedef struct slsr_cand_d slsr_cand, *slsr_cand_t;
173 typedef const struct slsr_cand_d *const_slsr_cand_t;
174
175 /* Pointers to candidates are chained together as part of a mapping
176 from SSA names to the candidates that use them as a base name. */
177
178 struct cand_chain_d
179 {
180 /* SSA name that serves as a base name for the chain of candidates. */
181 tree base_name;
182
183 /* Pointer to a candidate. */
184 slsr_cand_t cand;
185
186 /* Chain pointer. */
187 struct cand_chain_d *next;
188
189 };
190
191 typedef struct cand_chain_d cand_chain, *cand_chain_t;
192 typedef const struct cand_chain_d *const_cand_chain_t;
193
194 /* Candidates are maintained in a vector. If candidate X dominates
195 candidate Y, then X appears before Y in the vector; but the
196 converse does not necessarily hold. */
197 DEF_VEC_P (slsr_cand_t);
198 DEF_VEC_ALLOC_P (slsr_cand_t, heap);
199 static VEC (slsr_cand_t, heap) *cand_vec;
200
201 enum cost_consts
202 {
203 COST_NEUTRAL = 0,
204 COST_INFINITE = 1000
205 };
206
207 /* Pointer map embodying a mapping from statements to candidates. */
208 static struct pointer_map_t *stmt_cand_map;
209
210 /* Obstack for candidates. */
211 static struct obstack cand_obstack;
212
213 /* Array mapping from base SSA names to chains of candidates. */
214 static cand_chain_t *base_cand_map;
215
216 /* Obstack for candidate chains. */
217 static struct obstack chain_obstack;
218 \f
219 /* Produce a pointer to the IDX'th candidate in the candidate vector. */
220
221 static slsr_cand_t
222 lookup_cand (cand_idx idx)
223 {
224 return VEC_index (slsr_cand_t, cand_vec, idx - 1);
225 }
226
227 /* Use the base name from candidate C to look for possible candidates
228 that can serve as a basis for C. Each potential basis must also
229 appear in a block that dominates the candidate statement and have
230 the same stride and type. If more than one possible basis exists,
231 the one with highest index in the vector is chosen; this will be
232 the most immediately dominating basis. */
233
234 static int
235 find_basis_for_candidate (slsr_cand_t c)
236 {
237 cand_chain_t chain;
238 slsr_cand_t basis = NULL;
239
240 gcc_assert (TREE_CODE (c->base_name) == SSA_NAME);
241 chain = base_cand_map[SSA_NAME_VERSION (c->base_name)];
242
243 for (; chain; chain = chain->next)
244 {
245 slsr_cand_t one_basis = chain->cand;
246
247 if (one_basis->kind != c->kind
248 || !operand_equal_p (one_basis->stride, c->stride, 0)
249 || !types_compatible_p (one_basis->cand_type, c->cand_type)
250 || !dominated_by_p (CDI_DOMINATORS,
251 gimple_bb (c->cand_stmt),
252 gimple_bb (one_basis->cand_stmt)))
253 continue;
254
255 if (!basis || basis->cand_num < one_basis->cand_num)
256 basis = one_basis;
257 }
258
259 if (basis)
260 {
261 c->sibling = basis->dependent;
262 basis->dependent = c->cand_num;
263 return basis->cand_num;
264 }
265
266 return 0;
267 }
268
269 /* Record a mapping from the base name of C to C itself, indicating that
270 C may potentially serve as a basis using that base name. */
271
272 static void
273 record_potential_basis (slsr_cand_t c)
274 {
275 cand_chain_t node, head;
276 int index;
277
278 node = (cand_chain_t) obstack_alloc (&chain_obstack, sizeof (cand_chain));
279 node->base_name = c->base_name;
280 node->cand = c;
281 node->next = NULL;
282 index = SSA_NAME_VERSION (c->base_name);
283 head = base_cand_map[index];
284
285 if (head)
286 {
287 node->next = head->next;
288 head->next = node;
289 }
290 else
291 base_cand_map[index] = node;
292 }
293
294 /* Allocate storage for a new candidate and initialize its fields.
295 Attempt to find a basis for the candidate. */
296
297 static slsr_cand_t
298 alloc_cand_and_find_basis (enum cand_kind kind, gimple gs, tree base,
299 double_int index, tree stride, tree ctype,
300 unsigned savings)
301 {
302 slsr_cand_t c = (slsr_cand_t) obstack_alloc (&cand_obstack,
303 sizeof (slsr_cand));
304 c->cand_stmt = gs;
305 c->base_name = base;
306 c->stride = stride;
307 c->index = index;
308 c->cand_type = ctype;
309 c->kind = kind;
310 c->cand_num = VEC_length (slsr_cand_t, cand_vec) + 1;
311 c->next_interp = 0;
312 c->dependent = 0;
313 c->sibling = 0;
314 c->def_phi = NULL;
315 c->dead_savings = savings;
316
317 VEC_safe_push (slsr_cand_t, heap, cand_vec, c);
318 c->basis = find_basis_for_candidate (c);
319 record_potential_basis (c);
320
321 return c;
322 }
323
324 /* Determine the target cost of statement GS when compiling according
325 to SPEED. */
326
327 static int
328 stmt_cost (gimple gs, bool speed)
329 {
330 tree lhs, rhs1, rhs2;
331 enum machine_mode lhs_mode;
332
333 gcc_assert (is_gimple_assign (gs));
334 lhs = gimple_assign_lhs (gs);
335 rhs1 = gimple_assign_rhs1 (gs);
336 lhs_mode = TYPE_MODE (TREE_TYPE (lhs));
337
338 switch (gimple_assign_rhs_code (gs))
339 {
340 case MULT_EXPR:
341 rhs2 = gimple_assign_rhs2 (gs);
342
343 if (host_integerp (rhs2, 0))
344 return mult_by_coeff_cost (TREE_INT_CST_LOW (rhs2), lhs_mode, speed);
345
346 gcc_assert (TREE_CODE (rhs1) != INTEGER_CST);
347 return mul_cost (speed, lhs_mode);
348
349 case PLUS_EXPR:
350 case POINTER_PLUS_EXPR:
351 case MINUS_EXPR:
352 rhs2 = gimple_assign_rhs2 (gs);
353 return add_cost (speed, lhs_mode);
354
355 case NEGATE_EXPR:
356 return neg_cost (speed, lhs_mode);
357
358 case NOP_EXPR:
359 return convert_cost (lhs_mode, TYPE_MODE (TREE_TYPE (rhs1)), speed);
360
361 /* Note that we don't assign costs to copies that in most cases
362 will go away. */
363 default:
364 ;
365 }
366
367 gcc_unreachable ();
368 return 0;
369 }
370
371 /* Look up the defining statement for BASE_IN and return a pointer
372 to its candidate in the candidate table, if any; otherwise NULL.
373 Only CAND_ADD and CAND_MULT candidates are returned. */
374
375 static slsr_cand_t
376 base_cand_from_table (tree base_in)
377 {
378 slsr_cand_t *result;
379
380 gimple def = SSA_NAME_DEF_STMT (base_in);
381 if (!def)
382 return (slsr_cand_t) NULL;
383
384 result = (slsr_cand_t *) pointer_map_contains (stmt_cand_map, def);
385 if (!result)
386 return (slsr_cand_t) NULL;
387
388 return *result;
389 }
390
391 /* Add an entry to the statement-to-candidate mapping. */
392
393 static void
394 add_cand_for_stmt (gimple gs, slsr_cand_t c)
395 {
396 void **slot = pointer_map_insert (stmt_cand_map, gs);
397 gcc_assert (!*slot);
398 *slot = c;
399 }
400 \f
401 /* Create a candidate entry for a statement GS, where GS multiplies
402 two SSA names BASE_IN and STRIDE_IN. Propagate any known information
403 about the two SSA names into the new candidate. Return the new
404 candidate. */
405
406 static slsr_cand_t
407 create_mul_ssa_cand (gimple gs, tree base_in, tree stride_in, bool speed)
408 {
409 tree base = NULL_TREE, stride = NULL_TREE, ctype = NULL_TREE;
410 double_int index;
411 unsigned savings = 0;
412 slsr_cand_t c;
413 slsr_cand_t base_cand = base_cand_from_table (base_in);
414
415 /* Look at all interpretations of the base candidate, if necessary,
416 to find information to propagate into this candidate. */
417 while (base_cand && !base)
418 {
419
420 if (base_cand->kind == CAND_MULT
421 && operand_equal_p (base_cand->stride, integer_one_node, 0))
422 {
423 /* Y = (B + i') * 1
424 X = Y * Z
425 ================
426 X = (B + i') * Z */
427 base = base_cand->base_name;
428 index = base_cand->index;
429 stride = stride_in;
430 ctype = base_cand->cand_type;
431 if (has_single_use (base_in))
432 savings = (base_cand->dead_savings
433 + stmt_cost (base_cand->cand_stmt, speed));
434 }
435 else if (base_cand->kind == CAND_ADD
436 && TREE_CODE (base_cand->stride) == INTEGER_CST)
437 {
438 /* Y = B + (i' * S), S constant
439 X = Y * Z
440 ============================
441 X = B + ((i' * S) * Z) */
442 base = base_cand->base_name;
443 index = double_int_mul (base_cand->index,
444 tree_to_double_int (base_cand->stride));
445 stride = stride_in;
446 ctype = base_cand->cand_type;
447 if (has_single_use (base_in))
448 savings = (base_cand->dead_savings
449 + stmt_cost (base_cand->cand_stmt, speed));
450 }
451
452 if (base_cand->next_interp)
453 base_cand = lookup_cand (base_cand->next_interp);
454 else
455 base_cand = NULL;
456 }
457
458 if (!base)
459 {
460 /* No interpretations had anything useful to propagate, so
461 produce X = (Y + 0) * Z. */
462 base = base_in;
463 index = double_int_zero;
464 stride = stride_in;
465 ctype = TREE_TYPE (SSA_NAME_VAR (base_in));
466 }
467
468 c = alloc_cand_and_find_basis (CAND_MULT, gs, base, index, stride,
469 ctype, savings);
470 return c;
471 }
472
473 /* Create a candidate entry for a statement GS, where GS multiplies
474 SSA name BASE_IN by constant STRIDE_IN. Propagate any known
475 information about BASE_IN into the new candidate. Return the new
476 candidate. */
477
478 static slsr_cand_t
479 create_mul_imm_cand (gimple gs, tree base_in, tree stride_in, bool speed)
480 {
481 tree base = NULL_TREE, stride = NULL_TREE, ctype = NULL_TREE;
482 double_int index, temp;
483 unsigned savings = 0;
484 slsr_cand_t c;
485 slsr_cand_t base_cand = base_cand_from_table (base_in);
486
487 /* Look at all interpretations of the base candidate, if necessary,
488 to find information to propagate into this candidate. */
489 while (base_cand && !base)
490 {
491 if (base_cand->kind == CAND_MULT
492 && TREE_CODE (base_cand->stride) == INTEGER_CST)
493 {
494 /* Y = (B + i') * S, S constant
495 X = Y * c
496 ============================
497 X = (B + i') * (S * c) */
498 base = base_cand->base_name;
499 index = base_cand->index;
500 temp = double_int_mul (tree_to_double_int (base_cand->stride),
501 tree_to_double_int (stride_in));
502 stride = double_int_to_tree (TREE_TYPE (stride_in), temp);
503 ctype = base_cand->cand_type;
504 if (has_single_use (base_in))
505 savings = (base_cand->dead_savings
506 + stmt_cost (base_cand->cand_stmt, speed));
507 }
508 else if (base_cand->kind == CAND_ADD
509 && operand_equal_p (base_cand->stride, integer_one_node, 0))
510 {
511 /* Y = B + (i' * 1)
512 X = Y * c
513 ===========================
514 X = (B + i') * c */
515 base = base_cand->base_name;
516 index = base_cand->index;
517 stride = stride_in;
518 ctype = base_cand->cand_type;
519 if (has_single_use (base_in))
520 savings = (base_cand->dead_savings
521 + stmt_cost (base_cand->cand_stmt, speed));
522 }
523 else if (base_cand->kind == CAND_ADD
524 && double_int_one_p (base_cand->index)
525 && TREE_CODE (base_cand->stride) == INTEGER_CST)
526 {
527 /* Y = B + (1 * S), S constant
528 X = Y * c
529 ===========================
530 X = (B + S) * c */
531 base = base_cand->base_name;
532 index = tree_to_double_int (base_cand->stride);
533 stride = stride_in;
534 ctype = base_cand->cand_type;
535 if (has_single_use (base_in))
536 savings = (base_cand->dead_savings
537 + stmt_cost (base_cand->cand_stmt, speed));
538 }
539
540 if (base_cand->next_interp)
541 base_cand = lookup_cand (base_cand->next_interp);
542 else
543 base_cand = NULL;
544 }
545
546 if (!base)
547 {
548 /* No interpretations had anything useful to propagate, so
549 produce X = (Y + 0) * c. */
550 base = base_in;
551 index = double_int_zero;
552 stride = stride_in;
553 ctype = TREE_TYPE (SSA_NAME_VAR (base_in));
554 }
555
556 c = alloc_cand_and_find_basis (CAND_MULT, gs, base, index, stride,
557 ctype, savings);
558 return c;
559 }
560
561 /* Given GS which is a multiply of scalar integers, make an appropriate
562 entry in the candidate table. If this is a multiply of two SSA names,
563 create two CAND_MULT interpretations and attempt to find a basis for
564 each of them. Otherwise, create a single CAND_MULT and attempt to
565 find a basis. */
566
567 static void
568 slsr_process_mul (gimple gs, tree rhs1, tree rhs2, bool speed)
569 {
570 slsr_cand_t c, c2;
571
572 /* If this is a multiply of an SSA name with itself, it is highly
573 unlikely that we will get a strength reduction opportunity, so
574 don't record it as a candidate. This simplifies the logic for
575 finding a basis, so if this is removed that must be considered. */
576 if (rhs1 == rhs2)
577 return;
578
579 if (TREE_CODE (rhs2) == SSA_NAME)
580 {
581 /* Record an interpretation of this statement in the candidate table
582 assuming RHS1 is the base name and RHS2 is the stride. */
583 c = create_mul_ssa_cand (gs, rhs1, rhs2, speed);
584
585 /* Add the first interpretation to the statement-candidate mapping. */
586 add_cand_for_stmt (gs, c);
587
588 /* Record another interpretation of this statement assuming RHS1
589 is the stride and RHS2 is the base name. */
590 c2 = create_mul_ssa_cand (gs, rhs2, rhs1, speed);
591 c->next_interp = c2->cand_num;
592 }
593 else
594 {
595 /* Record an interpretation for the multiply-immediate. */
596 c = create_mul_imm_cand (gs, rhs1, rhs2, speed);
597
598 /* Add the interpretation to the statement-candidate mapping. */
599 add_cand_for_stmt (gs, c);
600 }
601 }
602
603 /* Create a candidate entry for a statement GS, where GS adds two
604 SSA names BASE_IN and ADDEND_IN if SUBTRACT_P is false, and
605 subtracts ADDEND_IN from BASE_IN otherwise. Propagate any known
606 information about the two SSA names into the new candidate.
607 Return the new candidate. */
608
609 static slsr_cand_t
610 create_add_ssa_cand (gimple gs, tree base_in, tree addend_in,
611 bool subtract_p, bool speed)
612 {
613 tree base = NULL_TREE, stride = NULL_TREE, ctype = NULL;
614 double_int index;
615 unsigned savings = 0;
616 slsr_cand_t c;
617 slsr_cand_t base_cand = base_cand_from_table (base_in);
618 slsr_cand_t addend_cand = base_cand_from_table (addend_in);
619
620 /* The most useful transformation is a multiply-immediate feeding
621 an add or subtract. Look for that first. */
622 while (addend_cand && !base)
623 {
624 if (addend_cand->kind == CAND_MULT
625 && double_int_zero_p (addend_cand->index)
626 && TREE_CODE (addend_cand->stride) == INTEGER_CST)
627 {
628 /* Z = (B + 0) * S, S constant
629 X = Y +/- Z
630 ===========================
631 X = Y + ((+/-1 * S) * B) */
632 base = base_in;
633 index = tree_to_double_int (addend_cand->stride);
634 if (subtract_p)
635 index = double_int_neg (index);
636 stride = addend_cand->base_name;
637 ctype = TREE_TYPE (SSA_NAME_VAR (base_in));
638 if (has_single_use (addend_in))
639 savings = (addend_cand->dead_savings
640 + stmt_cost (addend_cand->cand_stmt, speed));
641 }
642
643 if (addend_cand->next_interp)
644 addend_cand = lookup_cand (addend_cand->next_interp);
645 else
646 addend_cand = NULL;
647 }
648
649 while (base_cand && !base)
650 {
651 if (base_cand->kind == CAND_ADD
652 && (double_int_zero_p (base_cand->index)
653 || operand_equal_p (base_cand->stride,
654 integer_zero_node, 0)))
655 {
656 /* Y = B + (i' * S), i' * S = 0
657 X = Y +/- Z
658 ============================
659 X = B + (+/-1 * Z) */
660 base = base_cand->base_name;
661 index = subtract_p ? double_int_minus_one : double_int_one;
662 stride = addend_in;
663 ctype = base_cand->cand_type;
664 if (has_single_use (base_in))
665 savings = (base_cand->dead_savings
666 + stmt_cost (base_cand->cand_stmt, speed));
667 }
668 else if (subtract_p)
669 {
670 slsr_cand_t subtrahend_cand = base_cand_from_table (addend_in);
671
672 while (subtrahend_cand && !base)
673 {
674 if (subtrahend_cand->kind == CAND_MULT
675 && double_int_zero_p (subtrahend_cand->index)
676 && TREE_CODE (subtrahend_cand->stride) == INTEGER_CST)
677 {
678 /* Z = (B + 0) * S, S constant
679 X = Y - Z
680 ===========================
681 Value: X = Y + ((-1 * S) * B) */
682 base = base_in;
683 index = tree_to_double_int (subtrahend_cand->stride);
684 index = double_int_neg (index);
685 stride = subtrahend_cand->base_name;
686 ctype = TREE_TYPE (SSA_NAME_VAR (base_in));
687 if (has_single_use (addend_in))
688 savings = (subtrahend_cand->dead_savings
689 + stmt_cost (subtrahend_cand->cand_stmt, speed));
690 }
691
692 if (subtrahend_cand->next_interp)
693 subtrahend_cand = lookup_cand (subtrahend_cand->next_interp);
694 else
695 subtrahend_cand = NULL;
696 }
697 }
698
699 if (base_cand->next_interp)
700 base_cand = lookup_cand (base_cand->next_interp);
701 else
702 base_cand = NULL;
703 }
704
705 if (!base)
706 {
707 /* No interpretations had anything useful to propagate, so
708 produce X = Y + (1 * Z). */
709 base = base_in;
710 index = subtract_p ? double_int_minus_one : double_int_one;
711 stride = addend_in;
712 ctype = TREE_TYPE (SSA_NAME_VAR (base_in));
713 }
714
715 c = alloc_cand_and_find_basis (CAND_ADD, gs, base, index, stride,
716 ctype, savings);
717 return c;
718 }
719
720 /* Create a candidate entry for a statement GS, where GS adds SSA
721 name BASE_IN to constant INDEX_IN. Propagate any known information
722 about BASE_IN into the new candidate. Return the new candidate. */
723
724 static slsr_cand_t
725 create_add_imm_cand (gimple gs, tree base_in, double_int index_in, bool speed)
726 {
727 enum cand_kind kind = CAND_ADD;
728 tree base = NULL_TREE, stride = NULL_TREE, ctype = NULL_TREE;
729 double_int index, multiple;
730 unsigned savings = 0;
731 slsr_cand_t c;
732 slsr_cand_t base_cand = base_cand_from_table (base_in);
733
734 while (base_cand && !base)
735 {
736 bool unsigned_p = TYPE_UNSIGNED (TREE_TYPE (base_cand->stride));
737
738 if (TREE_CODE (base_cand->stride) == INTEGER_CST
739 && double_int_multiple_of (index_in,
740 tree_to_double_int (base_cand->stride),
741 unsigned_p,
742 &multiple))
743 {
744 /* Y = (B + i') * S, S constant, c = kS for some integer k
745 X = Y + c
746 ============================
747 X = (B + (i'+ k)) * S
748 OR
749 Y = B + (i' * S), S constant, c = kS for some integer k
750 X = Y + c
751 ============================
752 X = (B + (i'+ k)) * S */
753 kind = base_cand->kind;
754 base = base_cand->base_name;
755 index = double_int_add (base_cand->index, multiple);
756 stride = base_cand->stride;
757 ctype = base_cand->cand_type;
758 if (has_single_use (base_in))
759 savings = (base_cand->dead_savings
760 + stmt_cost (base_cand->cand_stmt, speed));
761 }
762
763 if (base_cand->next_interp)
764 base_cand = lookup_cand (base_cand->next_interp);
765 else
766 base_cand = NULL;
767 }
768
769 if (!base)
770 {
771 /* No interpretations had anything useful to propagate, so
772 produce X = Y + (c * 1). */
773 kind = CAND_ADD;
774 base = base_in;
775 index = index_in;
776 stride = integer_one_node;
777 ctype = TREE_TYPE (SSA_NAME_VAR (base_in));
778 }
779
780 c = alloc_cand_and_find_basis (kind, gs, base, index, stride,
781 ctype, savings);
782 return c;
783 }
784
785 /* Given GS which is an add or subtract of scalar integers or pointers,
786 make at least one appropriate entry in the candidate table. */
787
788 static void
789 slsr_process_add (gimple gs, tree rhs1, tree rhs2, bool speed)
790 {
791 bool subtract_p = gimple_assign_rhs_code (gs) == MINUS_EXPR;
792 slsr_cand_t c = NULL, c2;
793
794 if (TREE_CODE (rhs2) == SSA_NAME)
795 {
796 /* First record an interpretation assuming RHS1 is the base name
797 and RHS2 is the stride. But it doesn't make sense for the
798 stride to be a pointer, so don't record a candidate in that case. */
799 if (!POINTER_TYPE_P (TREE_TYPE (SSA_NAME_VAR (rhs2))))
800 {
801 c = create_add_ssa_cand (gs, rhs1, rhs2, subtract_p, speed);
802
803 /* Add the first interpretation to the statement-candidate
804 mapping. */
805 add_cand_for_stmt (gs, c);
806 }
807
808 /* If the two RHS operands are identical, or this is a subtract,
809 we're done. */
810 if (operand_equal_p (rhs1, rhs2, 0) || subtract_p)
811 return;
812
813 /* Otherwise, record another interpretation assuming RHS2 is the
814 base name and RHS1 is the stride, again provided that the
815 stride is not a pointer. */
816 if (!POINTER_TYPE_P (TREE_TYPE (SSA_NAME_VAR (rhs1))))
817 {
818 c2 = create_add_ssa_cand (gs, rhs2, rhs1, false, speed);
819 if (c)
820 c->next_interp = c2->cand_num;
821 else
822 add_cand_for_stmt (gs, c2);
823 }
824 }
825 else
826 {
827 double_int index;
828
829 /* Record an interpretation for the add-immediate. */
830 index = tree_to_double_int (rhs2);
831 if (subtract_p)
832 index = double_int_neg (index);
833
834 c = create_add_imm_cand (gs, rhs1, index, speed);
835
836 /* Add the interpretation to the statement-candidate mapping. */
837 add_cand_for_stmt (gs, c);
838 }
839 }
840
841 /* Given GS which is a negate of a scalar integer, make an appropriate
842 entry in the candidate table. A negate is equivalent to a multiply
843 by -1. */
844
845 static void
846 slsr_process_neg (gimple gs, tree rhs1, bool speed)
847 {
848 /* Record a CAND_MULT interpretation for the multiply by -1. */
849 slsr_cand_t c = create_mul_imm_cand (gs, rhs1, integer_minus_one_node, speed);
850
851 /* Add the interpretation to the statement-candidate mapping. */
852 add_cand_for_stmt (gs, c);
853 }
854
855 /* Return TRUE if GS is a statement that defines an SSA name from
856 a conversion and is legal for us to combine with an add and multiply
857 in the candidate table. For example, suppose we have:
858
859 A = B + i;
860 C = (type) A;
861 D = C * S;
862
863 Without the type-cast, we would create a CAND_MULT for D with base B,
864 index i, and stride S. We want to record this candidate only if it
865 is equivalent to apply the type cast following the multiply:
866
867 A = B + i;
868 E = A * S;
869 D = (type) E;
870
871 We will record the type with the candidate for D. This allows us
872 to use a similar previous candidate as a basis. If we have earlier seen
873
874 A' = B + i';
875 C' = (type) A';
876 D' = C' * S;
877
878 we can replace D with
879
880 D = D' + (i - i') * S;
881
882 But if moving the type-cast would change semantics, we mustn't do this.
883
884 This is legitimate for casts from a non-wrapping integral type to
885 any integral type of the same or larger size. It is not legitimate
886 to convert a wrapping type to a non-wrapping type, or to a wrapping
887 type of a different size. I.e., with a wrapping type, we must
888 assume that the addition B + i could wrap, in which case performing
889 the multiply before or after one of the "illegal" type casts will
890 have different semantics. */
891
892 static bool
893 legal_cast_p (gimple gs, tree rhs)
894 {
895 tree lhs, lhs_type, rhs_type;
896 unsigned lhs_size, rhs_size;
897 bool lhs_wraps, rhs_wraps;
898
899 if (!is_gimple_assign (gs)
900 || !CONVERT_EXPR_CODE_P (gimple_assign_rhs_code (gs)))
901 return false;
902
903 lhs = gimple_assign_lhs (gs);
904 lhs_type = TREE_TYPE (lhs);
905 rhs_type = TREE_TYPE (rhs);
906 lhs_size = TYPE_PRECISION (lhs_type);
907 rhs_size = TYPE_PRECISION (rhs_type);
908 lhs_wraps = TYPE_OVERFLOW_WRAPS (lhs_type);
909 rhs_wraps = TYPE_OVERFLOW_WRAPS (rhs_type);
910
911 if (lhs_size < rhs_size
912 || (rhs_wraps && !lhs_wraps)
913 || (rhs_wraps && lhs_wraps && rhs_size != lhs_size))
914 return false;
915
916 return true;
917 }
918
919 /* Given GS which is a cast to a scalar integer type, determine whether
920 the cast is legal for strength reduction. If so, make at least one
921 appropriate entry in the candidate table. */
922
923 static void
924 slsr_process_cast (gimple gs, tree rhs1, bool speed)
925 {
926 tree lhs, ctype;
927 slsr_cand_t base_cand, c, c2;
928 unsigned savings = 0;
929
930 if (!legal_cast_p (gs, rhs1))
931 return;
932
933 lhs = gimple_assign_lhs (gs);
934 base_cand = base_cand_from_table (rhs1);
935 ctype = TREE_TYPE (lhs);
936
937 if (base_cand)
938 {
939 while (base_cand)
940 {
941 /* Propagate all data from the base candidate except the type,
942 which comes from the cast, and the base candidate's cast,
943 which is no longer applicable. */
944 if (has_single_use (rhs1))
945 savings = (base_cand->dead_savings
946 + stmt_cost (base_cand->cand_stmt, speed));
947
948 c = alloc_cand_and_find_basis (base_cand->kind, gs,
949 base_cand->base_name,
950 base_cand->index, base_cand->stride,
951 ctype, savings);
952 if (base_cand->next_interp)
953 base_cand = lookup_cand (base_cand->next_interp);
954 else
955 base_cand = NULL;
956 }
957 }
958 else
959 {
960 /* If nothing is known about the RHS, create fresh CAND_ADD and
961 CAND_MULT interpretations:
962
963 X = Y + (0 * 1)
964 X = (Y + 0) * 1
965
966 The first of these is somewhat arbitrary, but the choice of
967 1 for the stride simplifies the logic for propagating casts
968 into their uses. */
969 c = alloc_cand_and_find_basis (CAND_ADD, gs, rhs1, double_int_zero,
970 integer_one_node, ctype, 0);
971 c2 = alloc_cand_and_find_basis (CAND_MULT, gs, rhs1, double_int_zero,
972 integer_one_node, ctype, 0);
973 c->next_interp = c2->cand_num;
974 }
975
976 /* Add the first (or only) interpretation to the statement-candidate
977 mapping. */
978 add_cand_for_stmt (gs, c);
979 }
980
981 /* Given GS which is a copy of a scalar integer type, make at least one
982 appropriate entry in the candidate table.
983
984 This interface is included for completeness, but is unnecessary
985 if this pass immediately follows a pass that performs copy
986 propagation, such as DOM. */
987
988 static void
989 slsr_process_copy (gimple gs, tree rhs1, bool speed)
990 {
991 slsr_cand_t base_cand, c, c2;
992 unsigned savings = 0;
993
994 base_cand = base_cand_from_table (rhs1);
995
996 if (base_cand)
997 {
998 while (base_cand)
999 {
1000 /* Propagate all data from the base candidate. */
1001 if (has_single_use (rhs1))
1002 savings = (base_cand->dead_savings
1003 + stmt_cost (base_cand->cand_stmt, speed));
1004
1005 c = alloc_cand_and_find_basis (base_cand->kind, gs,
1006 base_cand->base_name,
1007 base_cand->index, base_cand->stride,
1008 base_cand->cand_type, savings);
1009 if (base_cand->next_interp)
1010 base_cand = lookup_cand (base_cand->next_interp);
1011 else
1012 base_cand = NULL;
1013 }
1014 }
1015 else
1016 {
1017 /* If nothing is known about the RHS, create fresh CAND_ADD and
1018 CAND_MULT interpretations:
1019
1020 X = Y + (0 * 1)
1021 X = (Y + 0) * 1
1022
1023 The first of these is somewhat arbitrary, but the choice of
1024 1 for the stride simplifies the logic for propagating casts
1025 into their uses. */
1026 c = alloc_cand_and_find_basis (CAND_ADD, gs, rhs1, double_int_zero,
1027 integer_one_node, TREE_TYPE (rhs1), 0);
1028 c2 = alloc_cand_and_find_basis (CAND_MULT, gs, rhs1, double_int_zero,
1029 integer_one_node, TREE_TYPE (rhs1), 0);
1030 c->next_interp = c2->cand_num;
1031 }
1032
1033 /* Add the first (or only) interpretation to the statement-candidate
1034 mapping. */
1035 add_cand_for_stmt (gs, c);
1036 }
1037 \f
1038 /* Find strength-reduction candidates in block BB. */
1039
1040 static void
1041 find_candidates_in_block (struct dom_walk_data *walk_data ATTRIBUTE_UNUSED,
1042 basic_block bb)
1043 {
1044 bool speed = optimize_bb_for_speed_p (bb);
1045 gimple_stmt_iterator gsi;
1046
1047 for (gsi = gsi_start_bb (bb); !gsi_end_p (gsi); gsi_next (&gsi))
1048 {
1049 gimple gs = gsi_stmt (gsi);
1050
1051 if (is_gimple_assign (gs)
1052 && SCALAR_INT_MODE_P (TYPE_MODE (TREE_TYPE (gimple_assign_lhs (gs)))))
1053 {
1054 tree rhs1 = NULL_TREE, rhs2 = NULL_TREE;
1055
1056 switch (gimple_assign_rhs_code (gs))
1057 {
1058 case MULT_EXPR:
1059 case PLUS_EXPR:
1060 rhs1 = gimple_assign_rhs1 (gs);
1061 rhs2 = gimple_assign_rhs2 (gs);
1062 /* Should never happen, but currently some buggy situations
1063 in earlier phases put constants in rhs1. */
1064 if (TREE_CODE (rhs1) != SSA_NAME)
1065 continue;
1066 break;
1067
1068 /* Possible future opportunity: rhs1 of a ptr+ can be
1069 an ADDR_EXPR. */
1070 case POINTER_PLUS_EXPR:
1071 case MINUS_EXPR:
1072 rhs2 = gimple_assign_rhs2 (gs);
1073 /* Fall-through. */
1074
1075 case NOP_EXPR:
1076 case MODIFY_EXPR:
1077 case NEGATE_EXPR:
1078 rhs1 = gimple_assign_rhs1 (gs);
1079 if (TREE_CODE (rhs1) != SSA_NAME)
1080 continue;
1081 break;
1082
1083 default:
1084 ;
1085 }
1086
1087 switch (gimple_assign_rhs_code (gs))
1088 {
1089 case MULT_EXPR:
1090 slsr_process_mul (gs, rhs1, rhs2, speed);
1091 break;
1092
1093 case PLUS_EXPR:
1094 case POINTER_PLUS_EXPR:
1095 case MINUS_EXPR:
1096 slsr_process_add (gs, rhs1, rhs2, speed);
1097 break;
1098
1099 case NEGATE_EXPR:
1100 slsr_process_neg (gs, rhs1, speed);
1101 break;
1102
1103 case NOP_EXPR:
1104 slsr_process_cast (gs, rhs1, speed);
1105 break;
1106
1107 case MODIFY_EXPR:
1108 slsr_process_copy (gs, rhs1, speed);
1109 break;
1110
1111 default:
1112 ;
1113 }
1114 }
1115 }
1116 }
1117 \f
1118 /* Dump a candidate for debug. */
1119
1120 static void
1121 dump_candidate (slsr_cand_t c)
1122 {
1123 fprintf (dump_file, "%3d [%d] ", c->cand_num,
1124 gimple_bb (c->cand_stmt)->index);
1125 print_gimple_stmt (dump_file, c->cand_stmt, 0, 0);
1126 switch (c->kind)
1127 {
1128 case CAND_MULT:
1129 fputs (" MULT : (", dump_file);
1130 print_generic_expr (dump_file, c->base_name, 0);
1131 fputs (" + ", dump_file);
1132 dump_double_int (dump_file, c->index, false);
1133 fputs (") * ", dump_file);
1134 print_generic_expr (dump_file, c->stride, 0);
1135 fputs (" : ", dump_file);
1136 break;
1137 case CAND_ADD:
1138 fputs (" ADD : ", dump_file);
1139 print_generic_expr (dump_file, c->base_name, 0);
1140 fputs (" + (", dump_file);
1141 dump_double_int (dump_file, c->index, false);
1142 fputs (" * ", dump_file);
1143 print_generic_expr (dump_file, c->stride, 0);
1144 fputs (") : ", dump_file);
1145 break;
1146 default:
1147 gcc_unreachable ();
1148 }
1149 print_generic_expr (dump_file, c->cand_type, 0);
1150 fprintf (dump_file, "\n basis: %d dependent: %d sibling: %d\n",
1151 c->basis, c->dependent, c->sibling);
1152 fprintf (dump_file, " next-interp: %d dead-savings: %d\n",
1153 c->next_interp, c->dead_savings);
1154 if (c->def_phi)
1155 {
1156 fputs (" phi: ", dump_file);
1157 print_gimple_stmt (dump_file, c->def_phi, 0, 0);
1158 }
1159 fputs ("\n", dump_file);
1160 }
1161
1162 /* Dump the candidate vector for debug. */
1163
1164 static void
1165 dump_cand_vec (void)
1166 {
1167 unsigned i;
1168 slsr_cand_t c;
1169
1170 fprintf (dump_file, "\nStrength reduction candidate vector:\n\n");
1171
1172 FOR_EACH_VEC_ELT (slsr_cand_t, cand_vec, i, c)
1173 dump_candidate (c);
1174 }
1175
1176 /* Dump the candidate chains. */
1177
1178 static void
1179 dump_cand_chains (void)
1180 {
1181 unsigned i;
1182
1183 fprintf (dump_file, "\nStrength reduction candidate chains:\n\n");
1184
1185 for (i = 0; i < num_ssa_names; i++)
1186 {
1187 const_cand_chain_t chain = base_cand_map[i];
1188
1189 if (chain)
1190 {
1191 cand_chain_t p;
1192
1193 print_generic_expr (dump_file, chain->base_name, 0);
1194 fprintf (dump_file, " -> %d", chain->cand->cand_num);
1195
1196 for (p = chain->next; p; p = p->next)
1197 fprintf (dump_file, " -> %d", p->cand->cand_num);
1198
1199 fputs ("\n", dump_file);
1200 }
1201 }
1202
1203 fputs ("\n", dump_file);
1204 }
1205
1206 \f
1207 /* Recursive helper for unconditional_cands_with_known_stride_p.
1208 Returns TRUE iff C, its siblings, and its dependents are all
1209 unconditional candidates. */
1210
1211 static bool
1212 unconditional_cands (slsr_cand_t c)
1213 {
1214 if (c->def_phi)
1215 return false;
1216
1217 if (c->sibling && !unconditional_cands (lookup_cand (c->sibling)))
1218 return false;
1219
1220 if (c->dependent && !unconditional_cands (lookup_cand (c->dependent)))
1221 return false;
1222
1223 return true;
1224 }
1225
1226 /* Determine whether or not the tree of candidates rooted at
1227 ROOT consists entirely of unconditional increments with
1228 an INTEGER_CST stride. */
1229
1230 static bool
1231 unconditional_cands_with_known_stride_p (slsr_cand_t root)
1232 {
1233 /* The stride is identical for all related candidates, so
1234 check it once. */
1235 if (TREE_CODE (root->stride) != INTEGER_CST)
1236 return false;
1237
1238 return unconditional_cands (lookup_cand (root->dependent));
1239 }
1240
1241 /* Calculate the increment required for candidate C relative to
1242 its basis. */
1243
1244 static double_int
1245 cand_increment (slsr_cand_t c)
1246 {
1247 slsr_cand_t basis;
1248
1249 /* If the candidate doesn't have a basis, just return its own
1250 index. This is useful in record_increments to help us find
1251 an existing initializer. */
1252 if (!c->basis)
1253 return c->index;
1254
1255 basis = lookup_cand (c->basis);
1256 gcc_assert (operand_equal_p (c->base_name, basis->base_name, 0));
1257 return double_int_sub (c->index, basis->index);
1258 }
1259
1260 /* Return TRUE iff candidate C has already been replaced under
1261 another interpretation. */
1262
1263 static inline bool
1264 cand_already_replaced (slsr_cand_t c)
1265 {
1266 return (gimple_bb (c->cand_stmt) == 0);
1267 }
1268
1269 /* Helper routine for replace_dependents, doing the work for a
1270 single candidate C. */
1271
1272 static void
1273 replace_dependent (slsr_cand_t c, enum tree_code cand_code)
1274 {
1275 double_int stride = tree_to_double_int (c->stride);
1276 double_int bump = double_int_mul (cand_increment (c), stride);
1277 gimple stmt_to_print = NULL;
1278 slsr_cand_t basis;
1279 tree basis_name, incr_type, bump_tree;
1280 enum tree_code code;
1281
1282 /* It is highly unlikely, but possible, that the resulting
1283 bump doesn't fit in a HWI. Abandon the replacement
1284 in this case. Restriction to signed HWI is conservative
1285 for unsigned types but allows for safe negation without
1286 twisted logic. */
1287 if (!double_int_fits_in_shwi_p (bump))
1288 return;
1289
1290 basis = lookup_cand (c->basis);
1291 basis_name = gimple_assign_lhs (basis->cand_stmt);
1292 incr_type = TREE_TYPE (gimple_assign_rhs1 (c->cand_stmt));
1293 code = PLUS_EXPR;
1294
1295 if (double_int_negative_p (bump))
1296 {
1297 code = MINUS_EXPR;
1298 bump = double_int_neg (bump);
1299 }
1300
1301 bump_tree = double_int_to_tree (incr_type, bump);
1302
1303 if (dump_file && (dump_flags & TDF_DETAILS))
1304 {
1305 fputs ("Replacing: ", dump_file);
1306 print_gimple_stmt (dump_file, c->cand_stmt, 0, 0);
1307 }
1308
1309 if (double_int_zero_p (bump))
1310 {
1311 tree lhs = gimple_assign_lhs (c->cand_stmt);
1312 gimple copy_stmt = gimple_build_assign (lhs, basis_name);
1313 gimple_stmt_iterator gsi = gsi_for_stmt (c->cand_stmt);
1314 gimple_set_location (copy_stmt, gimple_location (c->cand_stmt));
1315 gsi_replace (&gsi, copy_stmt, false);
1316 if (dump_file && (dump_flags & TDF_DETAILS))
1317 stmt_to_print = copy_stmt;
1318 }
1319 else
1320 {
1321 tree rhs1 = gimple_assign_rhs1 (c->cand_stmt);
1322 tree rhs2 = gimple_assign_rhs2 (c->cand_stmt);
1323 if (cand_code != NEGATE_EXPR
1324 && ((operand_equal_p (rhs1, basis_name, 0)
1325 && operand_equal_p (rhs2, bump_tree, 0))
1326 || (operand_equal_p (rhs1, bump_tree, 0)
1327 && operand_equal_p (rhs2, basis_name, 0))))
1328 {
1329 if (dump_file && (dump_flags & TDF_DETAILS))
1330 {
1331 fputs ("(duplicate, not actually replacing)", dump_file);
1332 stmt_to_print = c->cand_stmt;
1333 }
1334 }
1335 else
1336 {
1337 gimple_stmt_iterator gsi = gsi_for_stmt (c->cand_stmt);
1338 gimple_assign_set_rhs_with_ops (&gsi, code, basis_name, bump_tree);
1339 update_stmt (gsi_stmt (gsi));
1340 if (dump_file && (dump_flags & TDF_DETAILS))
1341 stmt_to_print = gsi_stmt (gsi);
1342 }
1343 }
1344
1345 if (dump_file && (dump_flags & TDF_DETAILS))
1346 {
1347 fputs ("With: ", dump_file);
1348 print_gimple_stmt (dump_file, stmt_to_print, 0, 0);
1349 fputs ("\n", dump_file);
1350 }
1351 }
1352
1353 /* Replace candidate C, each sibling of candidate C, and each
1354 dependent of candidate C with an add or subtract. Note that we
1355 only operate on CAND_MULTs with known strides, so we will never
1356 generate a POINTER_PLUS_EXPR. Each candidate X = (B + i) * S is
1357 replaced by X = Y + ((i - i') * S), as described in the module
1358 commentary. The folded value ((i - i') * S) is referred to here
1359 as the "bump." */
1360
1361 static void
1362 replace_dependents (slsr_cand_t c)
1363 {
1364 enum tree_code cand_code = gimple_assign_rhs_code (c->cand_stmt);
1365
1366 /* It is not useful to replace casts, copies, or adds of an SSA name
1367 and a constant. Also skip candidates that have already been
1368 replaced under another interpretation. */
1369 if (cand_code != MODIFY_EXPR
1370 && cand_code != NOP_EXPR
1371 && c->kind == CAND_MULT
1372 && !cand_already_replaced (c))
1373 replace_dependent (c, cand_code);
1374
1375 if (c->sibling)
1376 replace_dependents (lookup_cand (c->sibling));
1377
1378 if (c->dependent)
1379 replace_dependents (lookup_cand (c->dependent));
1380 }
1381 \f
1382 /* Analyze costs of related candidates in the candidate vector,
1383 and make beneficial replacements. */
1384
1385 static void
1386 analyze_candidates_and_replace (void)
1387 {
1388 unsigned i;
1389 slsr_cand_t c;
1390
1391 /* Each candidate that has a null basis and a non-null
1392 dependent is the root of a tree of related statements.
1393 Analyze each tree to determine a subset of those
1394 statements that can be replaced with maximum benefit. */
1395 FOR_EACH_VEC_ELT (slsr_cand_t, cand_vec, i, c)
1396 {
1397 slsr_cand_t first_dep;
1398
1399 if (c->basis != 0 || c->dependent == 0)
1400 continue;
1401
1402 if (dump_file && (dump_flags & TDF_DETAILS))
1403 fprintf (dump_file, "\nProcessing dependency tree rooted at %d.\n",
1404 c->cand_num);
1405
1406 first_dep = lookup_cand (c->dependent);
1407
1408 /* If the common stride of all related candidates is a
1409 known constant, and none of these has a phi-dependence,
1410 then all replacements are considered profitable.
1411 Each replaces a multiply by a single add, with the
1412 possibility that a feeding add also goes dead as a
1413 result. */
1414 if (unconditional_cands_with_known_stride_p (c))
1415 replace_dependents (first_dep);
1416
1417 /* TODO: When the stride is an SSA name, it may still be
1418 profitable to replace some or all of the dependent
1419 candidates, depending on whether the introduced increments
1420 can be reused, or are less expensive to calculate than
1421 the replaced statements. */
1422
1423 /* TODO: Strength-reduce data references with implicit
1424 multiplication in their addressing expressions. */
1425
1426 /* TODO: When conditional increments occur so that a
1427 candidate is dependent upon a phi-basis, the cost of
1428 introducing a temporary must be accounted for. */
1429 }
1430 }
1431
1432 static unsigned
1433 execute_strength_reduction (void)
1434 {
1435 struct dom_walk_data walk_data;
1436
1437 /* Create the obstack where candidates will reside. */
1438 gcc_obstack_init (&cand_obstack);
1439
1440 /* Allocate the candidate vector. */
1441 cand_vec = VEC_alloc (slsr_cand_t, heap, 128);
1442
1443 /* Allocate the mapping from statements to candidate indices. */
1444 stmt_cand_map = pointer_map_create ();
1445
1446 /* Create the obstack where candidate chains will reside. */
1447 gcc_obstack_init (&chain_obstack);
1448
1449 /* Allocate the mapping from base names to candidate chains. */
1450 base_cand_map = XNEWVEC (cand_chain_t, num_ssa_names);
1451 memset (base_cand_map, 0, num_ssa_names * sizeof (cand_chain_t));
1452
1453 /* Initialize the loop optimizer. We need to detect flow across
1454 back edges, and this gives us dominator information as well. */
1455 loop_optimizer_init (AVOID_CFG_MODIFICATIONS);
1456
1457 /* Set up callbacks for the generic dominator tree walker. */
1458 walk_data.dom_direction = CDI_DOMINATORS;
1459 walk_data.initialize_block_local_data = NULL;
1460 walk_data.before_dom_children = find_candidates_in_block;
1461 walk_data.after_dom_children = NULL;
1462 walk_data.global_data = NULL;
1463 walk_data.block_local_data_size = 0;
1464 init_walk_dominator_tree (&walk_data);
1465
1466 /* Walk the CFG in predominator order looking for strength reduction
1467 candidates. */
1468 walk_dominator_tree (&walk_data, ENTRY_BLOCK_PTR);
1469
1470 if (dump_file && (dump_flags & TDF_DETAILS))
1471 {
1472 dump_cand_vec ();
1473 dump_cand_chains ();
1474 }
1475
1476 /* Analyze costs and make appropriate replacements. */
1477 analyze_candidates_and_replace ();
1478
1479 /* Free resources. */
1480 fini_walk_dominator_tree (&walk_data);
1481 loop_optimizer_finalize ();
1482 free (base_cand_map);
1483 obstack_free (&chain_obstack, NULL);
1484 pointer_map_destroy (stmt_cand_map);
1485 VEC_free (slsr_cand_t, heap, cand_vec);
1486 obstack_free (&cand_obstack, NULL);
1487
1488 return 0;
1489 }
1490
1491 static bool
1492 gate_strength_reduction (void)
1493 {
1494 return flag_tree_slsr;
1495 }
1496
1497 struct gimple_opt_pass pass_strength_reduction =
1498 {
1499 {
1500 GIMPLE_PASS,
1501 "slsr", /* name */
1502 gate_strength_reduction, /* gate */
1503 execute_strength_reduction, /* execute */
1504 NULL, /* sub */
1505 NULL, /* next */
1506 0, /* static_pass_number */
1507 TV_GIMPLE_SLSR, /* tv_id */
1508 PROP_cfg | PROP_ssa, /* properties_required */
1509 0, /* properties_provided */
1510 0, /* properties_destroyed */
1511 0, /* todo_flags_start */
1512 TODO_verify_ssa /* todo_flags_finish */
1513 }
1514 };