1 /* Straight-line strength reduction.
2 Copyright (C) 2012 Free Software Foundation, Inc.
3 Contributed by Bill Schmidt, IBM <wschmidt@linux.ibm.com>
5 This file is part of GCC.
7 GCC is free software; you can redistribute it and/or modify it under
8 the terms of the GNU General Public License as published by the Free
9 Software Foundation; either version 3, or (at your option) any later
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
17 You should have received a copy of the GNU General Public License
18 along with GCC; see the file COPYING3. If not see
19 <http://www.gnu.org/licenses/>. */
21 /* There are many algorithms for performing strength reduction on
22 loops. This is not one of them. IVOPTS handles strength reduction
23 of induction variables just fine. This pass is intended to pick
24 up the crumbs it leaves behind, by considering opportunities for
25 strength reduction along dominator paths.
27 Strength reduction will be implemented in four stages, gradually
28 adding more complex candidates:
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,
35 3) Implicit multiplies in addressing expressions. (pending)
36 4) Explicit multiplies, conditional increments. (pending)
38 It would also be possible to apply strength reduction to divisions
39 and modulos, but such opportunities are relatively uncommon.
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. */
47 #include "coretypes.h"
50 #include "basic-block.h"
51 #include "tree-pass.h"
54 #include "tree-pretty-print.h"
55 #include "gimple-pretty-print.h"
56 #include "tree-flow.h"
58 #include "pointer-set.h"
60 /* Information about a strength reduction candidate. Each statement
61 in the candidate table represents an expression of one of the
62 following forms (the special case of CAND_REF will be described
65 (CAND_MULT) S1: X = (B + i) * S
66 (CAND_ADD) S1: X = B + (i * S)
68 Here X and B are SSA names, i is an integer constant, and S is
69 either an SSA name or a constant. We call B the "base," i the
70 "index", and S the "stride."
72 Any statement S0 that dominates S1 and is of the form:
74 (CAND_MULT) S0: Y = (B + i') * S
75 (CAND_ADD) S0: Y = B + (i' * S)
77 is called a "basis" for S1. In both cases, S1 may be replaced by
79 S1': X = Y + (i - i') * S,
81 where (i - i') * S is folded to the extent possible.
83 All gimple statements are visited in dominator order, and each
84 statement that may contribute to one of the forms of S1 above is
85 given at least one entry in the candidate table. Such statements
86 include addition, pointer addition, subtraction, multiplication,
87 negation, copies, and nontrivial type casts. If a statement may
88 represent more than one expression of the forms of S1 above,
89 multiple "interpretations" are stored in the table and chained
92 * An add of two SSA names may treat either operand as the base.
93 * A multiply of two SSA names, likewise.
94 * A copy or cast may be thought of as either a CAND_MULT with
95 i = 0 and S = 1, or as a CAND_ADD with i = 0 or S = 0.
97 Candidate records are allocated from an obstack. They are addressed
98 both from a hash table keyed on S1, and from a vector of candidate
99 pointers arranged in predominator order.
103 Currently we don't recognize:
108 as a strength reduction opportunity, even though this S1 would
109 also be replaceable by the S1' above. This can be added if it
110 comes up in practice. */
113 /* Index into the candidate vector, offset by 1. VECs are zero-based,
114 while cand_idx's are one-based, with zero indicating null. */
115 typedef unsigned cand_idx
;
117 /* The kind of candidate. */
126 /* The candidate statement S1. */
129 /* The base SSA name B. */
135 /* The index constant i. */
138 /* The type of the candidate. This is normally the type of base_name,
139 but casts may have occurred when combining feeding instructions.
140 A candidate can only be a basis for candidates of the same final type. */
143 /* The kind of candidate (CAND_MULT, etc.). */
146 /* Index of this candidate in the candidate vector. */
149 /* Index of the next candidate record for the same statement.
150 A statement may be useful in more than one way (e.g., due to
151 commutativity). So we can have multiple "interpretations"
153 cand_idx next_interp
;
155 /* Index of the basis statement S0, if any, in the candidate vector. */
158 /* First candidate for which this candidate is a basis, if one exists. */
161 /* Next candidate having the same basis as this one. */
164 /* If this is a conditional candidate, the defining PHI statement
165 for the base SSA name B. For future use; always NULL for now. */
168 /* Savings that can be expected from eliminating dead code if this
169 candidate is replaced. */
173 typedef struct slsr_cand_d slsr_cand
, *slsr_cand_t
;
174 typedef const struct slsr_cand_d
*const_slsr_cand_t
;
176 /* Pointers to candidates are chained together as part of a mapping
177 from SSA names to the candidates that use them as a base name. */
181 /* SSA name that serves as a base name for the chain of candidates. */
184 /* Pointer to a candidate. */
188 struct cand_chain_d
*next
;
192 typedef struct cand_chain_d cand_chain
, *cand_chain_t
;
193 typedef const struct cand_chain_d
*const_cand_chain_t
;
195 /* Candidates are maintained in a vector. If candidate X dominates
196 candidate Y, then X appears before Y in the vector; but the
197 converse does not necessarily hold. */
198 DEF_VEC_P (slsr_cand_t
);
199 DEF_VEC_ALLOC_P (slsr_cand_t
, heap
);
200 static VEC (slsr_cand_t
, heap
) *cand_vec
;
208 /* Pointer map embodying a mapping from statements to candidates. */
209 static struct pointer_map_t
*stmt_cand_map
;
211 /* Obstack for candidates. */
212 static struct obstack cand_obstack
;
214 /* Array mapping from base SSA names to chains of candidates. */
215 static cand_chain_t
*base_cand_map
;
217 /* Obstack for candidate chains. */
218 static struct obstack chain_obstack
;
220 /* Produce a pointer to the IDX'th candidate in the candidate vector. */
223 lookup_cand (cand_idx idx
)
225 return VEC_index (slsr_cand_t
, cand_vec
, idx
- 1);
228 /* Use the base name from candidate C to look for possible candidates
229 that can serve as a basis for C. Each potential basis must also
230 appear in a block that dominates the candidate statement and have
231 the same stride and type. If more than one possible basis exists,
232 the one with highest index in the vector is chosen; this will be
233 the most immediately dominating basis. */
236 find_basis_for_candidate (slsr_cand_t c
)
239 slsr_cand_t basis
= NULL
;
241 gcc_assert (TREE_CODE (c
->base_name
) == SSA_NAME
);
242 chain
= base_cand_map
[SSA_NAME_VERSION (c
->base_name
)];
244 for (; chain
; chain
= chain
->next
)
246 slsr_cand_t one_basis
= chain
->cand
;
248 if (one_basis
->kind
!= c
->kind
249 || !operand_equal_p (one_basis
->stride
, c
->stride
, 0)
250 || !types_compatible_p (one_basis
->cand_type
, c
->cand_type
)
251 || !dominated_by_p (CDI_DOMINATORS
,
252 gimple_bb (c
->cand_stmt
),
253 gimple_bb (one_basis
->cand_stmt
)))
256 if (!basis
|| basis
->cand_num
< one_basis
->cand_num
)
262 c
->sibling
= basis
->dependent
;
263 basis
->dependent
= c
->cand_num
;
264 return basis
->cand_num
;
270 /* Record a mapping from the base name of C to C itself, indicating that
271 C may potentially serve as a basis using that base name. */
274 record_potential_basis (slsr_cand_t c
)
276 cand_chain_t node
, head
;
279 node
= (cand_chain_t
) obstack_alloc (&chain_obstack
, sizeof (cand_chain
));
280 node
->base_name
= c
->base_name
;
283 index
= SSA_NAME_VERSION (c
->base_name
);
284 head
= base_cand_map
[index
];
288 node
->next
= head
->next
;
292 base_cand_map
[index
] = node
;
295 /* Allocate storage for a new candidate and initialize its fields.
296 Attempt to find a basis for the candidate. */
299 alloc_cand_and_find_basis (enum cand_kind kind
, gimple gs
, tree base
,
300 double_int index
, tree stride
, tree ctype
,
303 slsr_cand_t c
= (slsr_cand_t
) obstack_alloc (&cand_obstack
,
309 c
->cand_type
= ctype
;
311 c
->cand_num
= VEC_length (slsr_cand_t
, cand_vec
) + 1;
316 c
->dead_savings
= savings
;
318 VEC_safe_push (slsr_cand_t
, heap
, cand_vec
, c
);
319 c
->basis
= find_basis_for_candidate (c
);
320 record_potential_basis (c
);
325 /* Determine the target cost of statement GS when compiling according
329 stmt_cost (gimple gs
, bool speed
)
331 tree lhs
, rhs1
, rhs2
;
332 enum machine_mode lhs_mode
;
334 gcc_assert (is_gimple_assign (gs
));
335 lhs
= gimple_assign_lhs (gs
);
336 rhs1
= gimple_assign_rhs1 (gs
);
337 lhs_mode
= TYPE_MODE (TREE_TYPE (lhs
));
339 switch (gimple_assign_rhs_code (gs
))
342 rhs2
= gimple_assign_rhs2 (gs
);
344 if (host_integerp (rhs2
, 0))
345 return multiply_by_const_cost (TREE_INT_CST_LOW (rhs2
), lhs_mode
,
348 gcc_assert (TREE_CODE (rhs1
) != INTEGER_CST
);
349 return multiply_regs_cost (TYPE_MODE (TREE_TYPE (lhs
)), speed
);
352 case POINTER_PLUS_EXPR
:
354 rhs2
= gimple_assign_rhs2 (gs
);
356 if (host_integerp (rhs2
, 0))
357 return add_const_cost (TYPE_MODE (TREE_TYPE (rhs1
)), speed
);
359 gcc_assert (TREE_CODE (rhs1
) != INTEGER_CST
);
360 return add_regs_cost (lhs_mode
, speed
);
363 return negate_reg_cost (lhs_mode
, speed
);
366 return extend_or_trunc_reg_cost (TREE_TYPE (lhs
), TREE_TYPE (rhs1
),
369 /* Note that we don't assign costs to copies that in most cases
379 /* Look up the defining statement for BASE_IN and return a pointer
380 to its candidate in the candidate table, if any; otherwise NULL.
381 Only CAND_ADD and CAND_MULT candidates are returned. */
384 base_cand_from_table (tree base_in
)
388 gimple def
= SSA_NAME_DEF_STMT (base_in
);
390 return (slsr_cand_t
) NULL
;
392 result
= (slsr_cand_t
*) pointer_map_contains (stmt_cand_map
, def
);
394 return (slsr_cand_t
) NULL
;
399 /* Add an entry to the statement-to-candidate mapping. */
402 add_cand_for_stmt (gimple gs
, slsr_cand_t c
)
404 void **slot
= pointer_map_insert (stmt_cand_map
, gs
);
409 /* Create a candidate entry for a statement GS, where GS multiplies
410 two SSA names BASE_IN and STRIDE_IN. Propagate any known information
411 about the two SSA names into the new candidate. Return the new
415 create_mul_ssa_cand (gimple gs
, tree base_in
, tree stride_in
, bool speed
)
417 tree base
= NULL_TREE
, stride
= NULL_TREE
, ctype
= NULL_TREE
;
419 unsigned savings
= 0;
421 slsr_cand_t base_cand
= base_cand_from_table (base_in
);
423 /* Look at all interpretations of the base candidate, if necessary,
424 to find information to propagate into this candidate. */
425 while (base_cand
&& !base
)
428 if (base_cand
->kind
== CAND_MULT
429 && operand_equal_p (base_cand
->stride
, integer_one_node
, 0))
435 base
= base_cand
->base_name
;
436 index
= base_cand
->index
;
438 ctype
= base_cand
->cand_type
;
439 if (has_single_use (base_in
))
440 savings
= (base_cand
->dead_savings
441 + stmt_cost (base_cand
->cand_stmt
, speed
));
443 else if (base_cand
->kind
== CAND_ADD
444 && TREE_CODE (base_cand
->stride
) == INTEGER_CST
)
446 /* Y = B + (i' * S), S constant
448 ============================
449 X = B + ((i' * S) * Z) */
450 base
= base_cand
->base_name
;
451 index
= double_int_mul (base_cand
->index
,
452 tree_to_double_int (base_cand
->stride
));
454 ctype
= base_cand
->cand_type
;
455 if (has_single_use (base_in
))
456 savings
= (base_cand
->dead_savings
457 + stmt_cost (base_cand
->cand_stmt
, speed
));
460 if (base_cand
->next_interp
)
461 base_cand
= lookup_cand (base_cand
->next_interp
);
468 /* No interpretations had anything useful to propagate, so
469 produce X = (Y + 0) * Z. */
471 index
= double_int_zero
;
473 ctype
= TREE_TYPE (SSA_NAME_VAR (base_in
));
476 c
= alloc_cand_and_find_basis (CAND_MULT
, gs
, base
, index
, stride
,
481 /* Create a candidate entry for a statement GS, where GS multiplies
482 SSA name BASE_IN by constant STRIDE_IN. Propagate any known
483 information about BASE_IN into the new candidate. Return the new
487 create_mul_imm_cand (gimple gs
, tree base_in
, tree stride_in
, bool speed
)
489 tree base
= NULL_TREE
, stride
= NULL_TREE
, ctype
= NULL_TREE
;
490 double_int index
, temp
;
491 unsigned savings
= 0;
493 slsr_cand_t base_cand
= base_cand_from_table (base_in
);
495 /* Look at all interpretations of the base candidate, if necessary,
496 to find information to propagate into this candidate. */
497 while (base_cand
&& !base
)
499 if (base_cand
->kind
== CAND_MULT
500 && TREE_CODE (base_cand
->stride
) == INTEGER_CST
)
502 /* Y = (B + i') * S, S constant
504 ============================
505 X = (B + i') * (S * c) */
506 base
= base_cand
->base_name
;
507 index
= base_cand
->index
;
508 temp
= double_int_mul (tree_to_double_int (base_cand
->stride
),
509 tree_to_double_int (stride_in
));
510 stride
= double_int_to_tree (TREE_TYPE (stride_in
), temp
);
511 ctype
= base_cand
->cand_type
;
512 if (has_single_use (base_in
))
513 savings
= (base_cand
->dead_savings
514 + stmt_cost (base_cand
->cand_stmt
, speed
));
516 else if (base_cand
->kind
== CAND_ADD
517 && operand_equal_p (base_cand
->stride
, integer_one_node
, 0))
521 ===========================
523 base
= base_cand
->base_name
;
524 index
= base_cand
->index
;
526 ctype
= base_cand
->cand_type
;
527 if (has_single_use (base_in
))
528 savings
= (base_cand
->dead_savings
529 + stmt_cost (base_cand
->cand_stmt
, speed
));
531 else if (base_cand
->kind
== CAND_ADD
532 && double_int_one_p (base_cand
->index
)
533 && TREE_CODE (base_cand
->stride
) == INTEGER_CST
)
535 /* Y = B + (1 * S), S constant
537 ===========================
539 base
= base_cand
->base_name
;
540 index
= tree_to_double_int (base_cand
->stride
);
542 ctype
= base_cand
->cand_type
;
543 if (has_single_use (base_in
))
544 savings
= (base_cand
->dead_savings
545 + stmt_cost (base_cand
->cand_stmt
, speed
));
548 if (base_cand
->next_interp
)
549 base_cand
= lookup_cand (base_cand
->next_interp
);
556 /* No interpretations had anything useful to propagate, so
557 produce X = (Y + 0) * c. */
559 index
= double_int_zero
;
561 ctype
= TREE_TYPE (SSA_NAME_VAR (base_in
));
564 c
= alloc_cand_and_find_basis (CAND_MULT
, gs
, base
, index
, stride
,
569 /* Given GS which is a multiply of scalar integers, make an appropriate
570 entry in the candidate table. If this is a multiply of two SSA names,
571 create two CAND_MULT interpretations and attempt to find a basis for
572 each of them. Otherwise, create a single CAND_MULT and attempt to
576 slsr_process_mul (gimple gs
, tree rhs1
, tree rhs2
, bool speed
)
580 /* If this is a multiply of an SSA name with itself, it is highly
581 unlikely that we will get a strength reduction opportunity, so
582 don't record it as a candidate. This simplifies the logic for
583 finding a basis, so if this is removed that must be considered. */
587 if (TREE_CODE (rhs2
) == SSA_NAME
)
589 /* Record an interpretation of this statement in the candidate table
590 assuming RHS1 is the base name and RHS2 is the stride. */
591 c
= create_mul_ssa_cand (gs
, rhs1
, rhs2
, speed
);
593 /* Add the first interpretation to the statement-candidate mapping. */
594 add_cand_for_stmt (gs
, c
);
596 /* Record another interpretation of this statement assuming RHS1
597 is the stride and RHS2 is the base name. */
598 c2
= create_mul_ssa_cand (gs
, rhs2
, rhs1
, speed
);
599 c
->next_interp
= c2
->cand_num
;
603 /* Record an interpretation for the multiply-immediate. */
604 c
= create_mul_imm_cand (gs
, rhs1
, rhs2
, speed
);
606 /* Add the interpretation to the statement-candidate mapping. */
607 add_cand_for_stmt (gs
, c
);
611 /* Create a candidate entry for a statement GS, where GS adds two
612 SSA names BASE_IN and ADDEND_IN if SUBTRACT_P is false, and
613 subtracts ADDEND_IN from BASE_IN otherwise. Propagate any known
614 information about the two SSA names into the new candidate.
615 Return the new candidate. */
618 create_add_ssa_cand (gimple gs
, tree base_in
, tree addend_in
,
619 bool subtract_p
, bool speed
)
621 tree base
= NULL_TREE
, stride
= NULL_TREE
, ctype
= NULL
;
623 unsigned savings
= 0;
625 slsr_cand_t base_cand
= base_cand_from_table (base_in
);
626 slsr_cand_t addend_cand
= base_cand_from_table (addend_in
);
628 /* The most useful transformation is a multiply-immediate feeding
629 an add or subtract. Look for that first. */
630 while (addend_cand
&& !base
)
632 if (addend_cand
->kind
== CAND_MULT
633 && double_int_zero_p (addend_cand
->index
)
634 && TREE_CODE (addend_cand
->stride
) == INTEGER_CST
)
636 /* Z = (B + 0) * S, S constant
638 ===========================
639 X = Y + ((+/-1 * S) * B) */
641 index
= tree_to_double_int (addend_cand
->stride
);
643 index
= double_int_neg (index
);
644 stride
= addend_cand
->base_name
;
645 ctype
= TREE_TYPE (SSA_NAME_VAR (base_in
));
646 if (has_single_use (addend_in
))
647 savings
= (addend_cand
->dead_savings
648 + stmt_cost (addend_cand
->cand_stmt
, speed
));
651 if (addend_cand
->next_interp
)
652 addend_cand
= lookup_cand (addend_cand
->next_interp
);
657 while (base_cand
&& !base
)
659 if (base_cand
->kind
== CAND_ADD
660 && (double_int_zero_p (base_cand
->index
)
661 || operand_equal_p (base_cand
->stride
,
662 integer_zero_node
, 0)))
664 /* Y = B + (i' * S), i' * S = 0
666 ============================
667 X = B + (+/-1 * Z) */
668 base
= base_cand
->base_name
;
669 index
= subtract_p
? double_int_minus_one
: double_int_one
;
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
));
678 slsr_cand_t subtrahend_cand
= base_cand_from_table (addend_in
);
680 while (subtrahend_cand
&& !base
)
682 if (subtrahend_cand
->kind
== CAND_MULT
683 && double_int_zero_p (subtrahend_cand
->index
)
684 && TREE_CODE (subtrahend_cand
->stride
) == INTEGER_CST
)
686 /* Z = (B + 0) * S, S constant
688 ===========================
689 Value: X = Y + ((-1 * S) * B) */
691 index
= tree_to_double_int (subtrahend_cand
->stride
);
692 index
= double_int_neg (index
);
693 stride
= subtrahend_cand
->base_name
;
694 ctype
= TREE_TYPE (SSA_NAME_VAR (base_in
));
695 if (has_single_use (addend_in
))
696 savings
= (subtrahend_cand
->dead_savings
697 + stmt_cost (subtrahend_cand
->cand_stmt
, speed
));
700 if (subtrahend_cand
->next_interp
)
701 subtrahend_cand
= lookup_cand (subtrahend_cand
->next_interp
);
703 subtrahend_cand
= NULL
;
707 if (base_cand
->next_interp
)
708 base_cand
= lookup_cand (base_cand
->next_interp
);
715 /* No interpretations had anything useful to propagate, so
716 produce X = Y + (1 * Z). */
718 index
= subtract_p
? double_int_minus_one
: double_int_one
;
720 ctype
= TREE_TYPE (SSA_NAME_VAR (base_in
));
723 c
= alloc_cand_and_find_basis (CAND_ADD
, gs
, base
, index
, stride
,
728 /* Create a candidate entry for a statement GS, where GS adds SSA
729 name BASE_IN to constant INDEX_IN. Propagate any known information
730 about BASE_IN into the new candidate. Return the new candidate. */
733 create_add_imm_cand (gimple gs
, tree base_in
, double_int index_in
, bool speed
)
735 enum cand_kind kind
= CAND_ADD
;
736 tree base
= NULL_TREE
, stride
= NULL_TREE
, ctype
= NULL_TREE
;
737 double_int index
, multiple
;
738 unsigned savings
= 0;
740 slsr_cand_t base_cand
= base_cand_from_table (base_in
);
742 while (base_cand
&& !base
)
744 bool unsigned_p
= TYPE_UNSIGNED (TREE_TYPE (base_cand
->stride
));
746 if (TREE_CODE (base_cand
->stride
) == INTEGER_CST
747 && double_int_multiple_of (index_in
,
748 tree_to_double_int (base_cand
->stride
),
752 /* Y = (B + i') * S, S constant, c = kS for some integer k
754 ============================
755 X = (B + (i'+ k)) * S
757 Y = B + (i' * S), S constant, c = kS for some integer k
759 ============================
760 X = (B + (i'+ k)) * S */
761 kind
= base_cand
->kind
;
762 base
= base_cand
->base_name
;
763 index
= double_int_add (base_cand
->index
, multiple
);
764 stride
= base_cand
->stride
;
765 ctype
= base_cand
->cand_type
;
766 if (has_single_use (base_in
))
767 savings
= (base_cand
->dead_savings
768 + stmt_cost (base_cand
->cand_stmt
, speed
));
771 if (base_cand
->next_interp
)
772 base_cand
= lookup_cand (base_cand
->next_interp
);
779 /* No interpretations had anything useful to propagate, so
780 produce X = Y + (c * 1). */
784 stride
= integer_one_node
;
785 ctype
= TREE_TYPE (SSA_NAME_VAR (base_in
));
788 c
= alloc_cand_and_find_basis (kind
, gs
, base
, index
, stride
,
793 /* Given GS which is an add or subtract of scalar integers or pointers,
794 make at least one appropriate entry in the candidate table. */
797 slsr_process_add (gimple gs
, tree rhs1
, tree rhs2
, bool speed
)
799 bool subtract_p
= gimple_assign_rhs_code (gs
) == MINUS_EXPR
;
800 slsr_cand_t c
= NULL
, c2
;
802 if (TREE_CODE (rhs2
) == SSA_NAME
)
804 /* First record an interpretation assuming RHS1 is the base name
805 and RHS2 is the stride. But it doesn't make sense for the
806 stride to be a pointer, so don't record a candidate in that case. */
807 if (!POINTER_TYPE_P (TREE_TYPE (SSA_NAME_VAR (rhs2
))))
809 c
= create_add_ssa_cand (gs
, rhs1
, rhs2
, subtract_p
, speed
);
811 /* Add the first interpretation to the statement-candidate
813 add_cand_for_stmt (gs
, c
);
816 /* If the two RHS operands are identical, or this is a subtract,
818 if (operand_equal_p (rhs1
, rhs2
, 0) || subtract_p
)
821 /* Otherwise, record another interpretation assuming RHS2 is the
822 base name and RHS1 is the stride, again provided that the
823 stride is not a pointer. */
824 if (!POINTER_TYPE_P (TREE_TYPE (SSA_NAME_VAR (rhs1
))))
826 c2
= create_add_ssa_cand (gs
, rhs2
, rhs1
, false, speed
);
828 c
->next_interp
= c2
->cand_num
;
830 add_cand_for_stmt (gs
, c2
);
837 /* Record an interpretation for the add-immediate. */
838 index
= tree_to_double_int (rhs2
);
840 index
= double_int_neg (index
);
842 c
= create_add_imm_cand (gs
, rhs1
, index
, speed
);
844 /* Add the interpretation to the statement-candidate mapping. */
845 add_cand_for_stmt (gs
, c
);
849 /* Given GS which is a negate of a scalar integer, make an appropriate
850 entry in the candidate table. A negate is equivalent to a multiply
854 slsr_process_neg (gimple gs
, tree rhs1
, bool speed
)
856 /* Record a CAND_MULT interpretation for the multiply by -1. */
857 slsr_cand_t c
= create_mul_imm_cand (gs
, rhs1
, integer_minus_one_node
, speed
);
859 /* Add the interpretation to the statement-candidate mapping. */
860 add_cand_for_stmt (gs
, c
);
863 /* Return TRUE if GS is a statement that defines an SSA name from
864 a conversion and is legal for us to combine with an add and multiply
865 in the candidate table. For example, suppose we have:
871 Without the type-cast, we would create a CAND_MULT for D with base B,
872 index i, and stride S. We want to record this candidate only if it
873 is equivalent to apply the type cast following the multiply:
879 We will record the type with the candidate for D. This allows us
880 to use a similar previous candidate as a basis. If we have earlier seen
886 we can replace D with
888 D = D' + (i - i') * S;
890 But if moving the type-cast would change semantics, we mustn't do this.
892 This is legitimate for casts from a non-wrapping integral type to
893 any integral type of the same or larger size. It is not legitimate
894 to convert a wrapping type to a non-wrapping type, or to a wrapping
895 type of a different size. I.e., with a wrapping type, we must
896 assume that the addition B + i could wrap, in which case performing
897 the multiply before or after one of the "illegal" type casts will
898 have different semantics. */
901 legal_cast_p (gimple gs
, tree rhs
)
903 tree lhs
, lhs_type
, rhs_type
;
904 unsigned lhs_size
, rhs_size
;
905 bool lhs_wraps
, rhs_wraps
;
907 if (!is_gimple_assign (gs
)
908 || !CONVERT_EXPR_CODE_P (gimple_assign_rhs_code (gs
)))
911 lhs
= gimple_assign_lhs (gs
);
912 lhs_type
= TREE_TYPE (lhs
);
913 rhs_type
= TREE_TYPE (rhs
);
914 lhs_size
= TYPE_PRECISION (lhs_type
);
915 rhs_size
= TYPE_PRECISION (rhs_type
);
916 lhs_wraps
= TYPE_OVERFLOW_WRAPS (lhs_type
);
917 rhs_wraps
= TYPE_OVERFLOW_WRAPS (rhs_type
);
919 if (lhs_size
< rhs_size
920 || (rhs_wraps
&& !lhs_wraps
)
921 || (rhs_wraps
&& lhs_wraps
&& rhs_size
!= lhs_size
))
927 /* Given GS which is a cast to a scalar integer type, determine whether
928 the cast is legal for strength reduction. If so, make at least one
929 appropriate entry in the candidate table. */
932 slsr_process_cast (gimple gs
, tree rhs1
, bool speed
)
935 slsr_cand_t base_cand
, c
, c2
;
936 unsigned savings
= 0;
938 if (!legal_cast_p (gs
, rhs1
))
941 lhs
= gimple_assign_lhs (gs
);
942 base_cand
= base_cand_from_table (rhs1
);
943 ctype
= TREE_TYPE (lhs
);
949 /* Propagate all data from the base candidate except the type,
950 which comes from the cast, and the base candidate's cast,
951 which is no longer applicable. */
952 if (has_single_use (rhs1
))
953 savings
= (base_cand
->dead_savings
954 + stmt_cost (base_cand
->cand_stmt
, speed
));
956 c
= alloc_cand_and_find_basis (base_cand
->kind
, gs
,
957 base_cand
->base_name
,
958 base_cand
->index
, base_cand
->stride
,
960 if (base_cand
->next_interp
)
961 base_cand
= lookup_cand (base_cand
->next_interp
);
968 /* If nothing is known about the RHS, create fresh CAND_ADD and
969 CAND_MULT interpretations:
974 The first of these is somewhat arbitrary, but the choice of
975 1 for the stride simplifies the logic for propagating casts
977 c
= alloc_cand_and_find_basis (CAND_ADD
, gs
, rhs1
, double_int_zero
,
978 integer_one_node
, ctype
, 0);
979 c2
= alloc_cand_and_find_basis (CAND_MULT
, gs
, rhs1
, double_int_zero
,
980 integer_one_node
, ctype
, 0);
981 c
->next_interp
= c2
->cand_num
;
984 /* Add the first (or only) interpretation to the statement-candidate
986 add_cand_for_stmt (gs
, c
);
989 /* Given GS which is a copy of a scalar integer type, make at least one
990 appropriate entry in the candidate table.
992 This interface is included for completeness, but is unnecessary
993 if this pass immediately follows a pass that performs copy
994 propagation, such as DOM. */
997 slsr_process_copy (gimple gs
, tree rhs1
, bool speed
)
999 slsr_cand_t base_cand
, c
, c2
;
1000 unsigned savings
= 0;
1002 base_cand
= base_cand_from_table (rhs1
);
1008 /* Propagate all data from the base candidate. */
1009 if (has_single_use (rhs1
))
1010 savings
= (base_cand
->dead_savings
1011 + stmt_cost (base_cand
->cand_stmt
, speed
));
1013 c
= alloc_cand_and_find_basis (base_cand
->kind
, gs
,
1014 base_cand
->base_name
,
1015 base_cand
->index
, base_cand
->stride
,
1016 base_cand
->cand_type
, savings
);
1017 if (base_cand
->next_interp
)
1018 base_cand
= lookup_cand (base_cand
->next_interp
);
1025 /* If nothing is known about the RHS, create fresh CAND_ADD and
1026 CAND_MULT interpretations:
1031 The first of these is somewhat arbitrary, but the choice of
1032 1 for the stride simplifies the logic for propagating casts
1034 c
= alloc_cand_and_find_basis (CAND_ADD
, gs
, rhs1
, double_int_zero
,
1035 integer_one_node
, TREE_TYPE (rhs1
), 0);
1036 c2
= alloc_cand_and_find_basis (CAND_MULT
, gs
, rhs1
, double_int_zero
,
1037 integer_one_node
, TREE_TYPE (rhs1
), 0);
1038 c
->next_interp
= c2
->cand_num
;
1041 /* Add the first (or only) interpretation to the statement-candidate
1043 add_cand_for_stmt (gs
, c
);
1046 /* Find strength-reduction candidates in block BB. */
1049 find_candidates_in_block (struct dom_walk_data
*walk_data ATTRIBUTE_UNUSED
,
1052 bool speed
= optimize_bb_for_speed_p (bb
);
1053 gimple_stmt_iterator gsi
;
1055 for (gsi
= gsi_start_bb (bb
); !gsi_end_p (gsi
); gsi_next (&gsi
))
1057 gimple gs
= gsi_stmt (gsi
);
1059 if (is_gimple_assign (gs
)
1060 && SCALAR_INT_MODE_P (TYPE_MODE (TREE_TYPE (gimple_assign_lhs (gs
)))))
1062 tree rhs1
= NULL_TREE
, rhs2
= NULL_TREE
;
1064 switch (gimple_assign_rhs_code (gs
))
1068 rhs1
= gimple_assign_rhs1 (gs
);
1069 rhs2
= gimple_assign_rhs2 (gs
);
1070 /* Should never happen, but currently some buggy situations
1071 in earlier phases put constants in rhs1. */
1072 if (TREE_CODE (rhs1
) != SSA_NAME
)
1076 /* Possible future opportunity: rhs1 of a ptr+ can be
1078 case POINTER_PLUS_EXPR
:
1080 rhs2
= gimple_assign_rhs2 (gs
);
1086 rhs1
= gimple_assign_rhs1 (gs
);
1087 if (TREE_CODE (rhs1
) != SSA_NAME
)
1095 switch (gimple_assign_rhs_code (gs
))
1098 slsr_process_mul (gs
, rhs1
, rhs2
, speed
);
1102 case POINTER_PLUS_EXPR
:
1104 slsr_process_add (gs
, rhs1
, rhs2
, speed
);
1108 slsr_process_neg (gs
, rhs1
, speed
);
1112 slsr_process_cast (gs
, rhs1
, speed
);
1116 slsr_process_copy (gs
, rhs1
, speed
);
1126 /* Dump a candidate for debug. */
1129 dump_candidate (slsr_cand_t c
)
1131 fprintf (dump_file
, "%3d [%d] ", c
->cand_num
,
1132 gimple_bb (c
->cand_stmt
)->index
);
1133 print_gimple_stmt (dump_file
, c
->cand_stmt
, 0, 0);
1137 fputs (" MULT : (", dump_file
);
1138 print_generic_expr (dump_file
, c
->base_name
, 0);
1139 fputs (" + ", dump_file
);
1140 dump_double_int (dump_file
, c
->index
, false);
1141 fputs (") * ", dump_file
);
1142 print_generic_expr (dump_file
, c
->stride
, 0);
1143 fputs (" : ", dump_file
);
1146 fputs (" ADD : ", dump_file
);
1147 print_generic_expr (dump_file
, c
->base_name
, 0);
1148 fputs (" + (", dump_file
);
1149 dump_double_int (dump_file
, c
->index
, false);
1150 fputs (" * ", dump_file
);
1151 print_generic_expr (dump_file
, c
->stride
, 0);
1152 fputs (") : ", dump_file
);
1157 print_generic_expr (dump_file
, c
->cand_type
, 0);
1158 fprintf (dump_file
, "\n basis: %d dependent: %d sibling: %d\n",
1159 c
->basis
, c
->dependent
, c
->sibling
);
1160 fprintf (dump_file
, " next-interp: %d dead-savings: %d\n",
1161 c
->next_interp
, c
->dead_savings
);
1164 fputs (" phi: ", dump_file
);
1165 print_gimple_stmt (dump_file
, c
->def_phi
, 0, 0);
1167 fputs ("\n", dump_file
);
1170 /* Dump the candidate vector for debug. */
1173 dump_cand_vec (void)
1178 fprintf (dump_file
, "\nStrength reduction candidate vector:\n\n");
1180 FOR_EACH_VEC_ELT (slsr_cand_t
, cand_vec
, i
, c
)
1184 /* Dump the candidate chains. */
1187 dump_cand_chains (void)
1191 fprintf (dump_file
, "\nStrength reduction candidate chains:\n\n");
1193 for (i
= 0; i
< num_ssa_names
; i
++)
1195 const_cand_chain_t chain
= base_cand_map
[i
];
1201 print_generic_expr (dump_file
, chain
->base_name
, 0);
1202 fprintf (dump_file
, " -> %d", chain
->cand
->cand_num
);
1204 for (p
= chain
->next
; p
; p
= p
->next
)
1205 fprintf (dump_file
, " -> %d", p
->cand
->cand_num
);
1207 fputs ("\n", dump_file
);
1211 fputs ("\n", dump_file
);
1215 /* Recursive helper for unconditional_cands_with_known_stride_p.
1216 Returns TRUE iff C, its siblings, and its dependents are all
1217 unconditional candidates. */
1220 unconditional_cands (slsr_cand_t c
)
1225 if (c
->sibling
&& !unconditional_cands (lookup_cand (c
->sibling
)))
1228 if (c
->dependent
&& !unconditional_cands (lookup_cand (c
->dependent
)))
1234 /* Determine whether or not the tree of candidates rooted at
1235 ROOT consists entirely of unconditional increments with
1236 an INTEGER_CST stride. */
1239 unconditional_cands_with_known_stride_p (slsr_cand_t root
)
1241 /* The stride is identical for all related candidates, so
1243 if (TREE_CODE (root
->stride
) != INTEGER_CST
)
1246 return unconditional_cands (lookup_cand (root
->dependent
));
1249 /* Calculate the increment required for candidate C relative to
1253 cand_increment (slsr_cand_t c
)
1257 /* If the candidate doesn't have a basis, just return its own
1258 index. This is useful in record_increments to help us find
1259 an existing initializer. */
1263 basis
= lookup_cand (c
->basis
);
1264 gcc_assert (operand_equal_p (c
->base_name
, basis
->base_name
, 0));
1265 return double_int_sub (c
->index
, basis
->index
);
1268 /* Return TRUE iff candidate C has already been replaced under
1269 another interpretation. */
1272 cand_already_replaced (slsr_cand_t c
)
1274 return (gimple_bb (c
->cand_stmt
) == 0);
1277 /* Helper routine for replace_dependents, doing the work for a
1278 single candidate C. */
1281 replace_dependent (slsr_cand_t c
, enum tree_code cand_code
)
1283 double_int stride
= tree_to_double_int (c
->stride
);
1284 double_int bump
= double_int_mul (cand_increment (c
), stride
);
1285 gimple stmt_to_print
= NULL
;
1287 tree basis_name
, incr_type
, bump_tree
;
1288 enum tree_code code
;
1290 /* It is highly unlikely, but possible, that the resulting
1291 bump doesn't fit in a HWI. Abandon the replacement
1292 in this case. Restriction to signed HWI is conservative
1293 for unsigned types but allows for safe negation without
1295 if (!double_int_fits_in_shwi_p (bump
))
1298 basis
= lookup_cand (c
->basis
);
1299 basis_name
= gimple_assign_lhs (basis
->cand_stmt
);
1300 incr_type
= TREE_TYPE (gimple_assign_rhs1 (c
->cand_stmt
));
1303 if (double_int_negative_p (bump
))
1306 bump
= double_int_neg (bump
);
1309 bump_tree
= double_int_to_tree (incr_type
, bump
);
1311 if (dump_file
&& (dump_flags
& TDF_DETAILS
))
1313 fputs ("Replacing: ", dump_file
);
1314 print_gimple_stmt (dump_file
, c
->cand_stmt
, 0, 0);
1317 if (double_int_zero_p (bump
))
1319 tree lhs
= gimple_assign_lhs (c
->cand_stmt
);
1320 gimple copy_stmt
= gimple_build_assign (lhs
, basis_name
);
1321 gimple_stmt_iterator gsi
= gsi_for_stmt (c
->cand_stmt
);
1322 gimple_set_location (copy_stmt
, gimple_location (c
->cand_stmt
));
1323 gsi_replace (&gsi
, copy_stmt
, false);
1324 if (dump_file
&& (dump_flags
& TDF_DETAILS
))
1325 stmt_to_print
= copy_stmt
;
1329 tree rhs1
= gimple_assign_rhs1 (c
->cand_stmt
);
1330 tree rhs2
= gimple_assign_rhs2 (c
->cand_stmt
);
1331 if (cand_code
!= NEGATE_EXPR
1332 && ((operand_equal_p (rhs1
, basis_name
, 0)
1333 && operand_equal_p (rhs2
, bump_tree
, 0))
1334 || (operand_equal_p (rhs1
, bump_tree
, 0)
1335 && operand_equal_p (rhs2
, basis_name
, 0))))
1337 if (dump_file
&& (dump_flags
& TDF_DETAILS
))
1339 fputs ("(duplicate, not actually replacing)", dump_file
);
1340 stmt_to_print
= c
->cand_stmt
;
1345 gimple_stmt_iterator gsi
= gsi_for_stmt (c
->cand_stmt
);
1346 gimple_assign_set_rhs_with_ops (&gsi
, code
, basis_name
, bump_tree
);
1347 update_stmt (gsi_stmt (gsi
));
1348 if (dump_file
&& (dump_flags
& TDF_DETAILS
))
1349 stmt_to_print
= gsi_stmt (gsi
);
1353 if (dump_file
&& (dump_flags
& TDF_DETAILS
))
1355 fputs ("With: ", dump_file
);
1356 print_gimple_stmt (dump_file
, stmt_to_print
, 0, 0);
1357 fputs ("\n", dump_file
);
1361 /* Replace candidate C, each sibling of candidate C, and each
1362 dependent of candidate C with an add or subtract. Note that we
1363 only operate on CAND_MULTs with known strides, so we will never
1364 generate a POINTER_PLUS_EXPR. Each candidate X = (B + i) * S is
1365 replaced by X = Y + ((i - i') * S), as described in the module
1366 commentary. The folded value ((i - i') * S) is referred to here
1370 replace_dependents (slsr_cand_t c
)
1372 enum tree_code cand_code
= gimple_assign_rhs_code (c
->cand_stmt
);
1374 /* It is not useful to replace casts, copies, or adds of an SSA name
1375 and a constant. Also skip candidates that have already been
1376 replaced under another interpretation. */
1377 if (cand_code
!= MODIFY_EXPR
1378 && cand_code
!= NOP_EXPR
1379 && c
->kind
== CAND_MULT
1380 && !cand_already_replaced (c
))
1381 replace_dependent (c
, cand_code
);
1384 replace_dependents (lookup_cand (c
->sibling
));
1387 replace_dependents (lookup_cand (c
->dependent
));
1390 /* Analyze costs of related candidates in the candidate vector,
1391 and make beneficial replacements. */
1394 analyze_candidates_and_replace (void)
1399 /* Each candidate that has a null basis and a non-null
1400 dependent is the root of a tree of related statements.
1401 Analyze each tree to determine a subset of those
1402 statements that can be replaced with maximum benefit. */
1403 FOR_EACH_VEC_ELT (slsr_cand_t
, cand_vec
, i
, c
)
1405 slsr_cand_t first_dep
;
1407 if (c
->basis
!= 0 || c
->dependent
== 0)
1410 if (dump_file
&& (dump_flags
& TDF_DETAILS
))
1411 fprintf (dump_file
, "\nProcessing dependency tree rooted at %d.\n",
1414 first_dep
= lookup_cand (c
->dependent
);
1416 /* If the common stride of all related candidates is a
1417 known constant, and none of these has a phi-dependence,
1418 then all replacements are considered profitable.
1419 Each replaces a multiply by a single add, with the
1420 possibility that a feeding add also goes dead as a
1422 if (unconditional_cands_with_known_stride_p (c
))
1423 replace_dependents (first_dep
);
1425 /* TODO: When the stride is an SSA name, it may still be
1426 profitable to replace some or all of the dependent
1427 candidates, depending on whether the introduced increments
1428 can be reused, or are less expensive to calculate than
1429 the replaced statements. */
1431 /* TODO: Strength-reduce data references with implicit
1432 multiplication in their addressing expressions. */
1434 /* TODO: When conditional increments occur so that a
1435 candidate is dependent upon a phi-basis, the cost of
1436 introducing a temporary must be accounted for. */
1441 execute_strength_reduction (void)
1443 struct dom_walk_data walk_data
;
1445 /* Create the obstack where candidates will reside. */
1446 gcc_obstack_init (&cand_obstack
);
1448 /* Allocate the candidate vector. */
1449 cand_vec
= VEC_alloc (slsr_cand_t
, heap
, 128);
1451 /* Allocate the mapping from statements to candidate indices. */
1452 stmt_cand_map
= pointer_map_create ();
1454 /* Create the obstack where candidate chains will reside. */
1455 gcc_obstack_init (&chain_obstack
);
1457 /* Allocate the mapping from base names to candidate chains. */
1458 base_cand_map
= XNEWVEC (cand_chain_t
, num_ssa_names
);
1459 memset (base_cand_map
, 0, num_ssa_names
* sizeof (cand_chain_t
));
1461 /* Initialize the loop optimizer. We need to detect flow across
1462 back edges, and this gives us dominator information as well. */
1463 loop_optimizer_init (AVOID_CFG_MODIFICATIONS
);
1465 /* Initialize costs tables in IVOPTS. */
1466 initialize_costs ();
1468 /* Set up callbacks for the generic dominator tree walker. */
1469 walk_data
.dom_direction
= CDI_DOMINATORS
;
1470 walk_data
.initialize_block_local_data
= NULL
;
1471 walk_data
.before_dom_children
= find_candidates_in_block
;
1472 walk_data
.after_dom_children
= NULL
;
1473 walk_data
.global_data
= NULL
;
1474 walk_data
.block_local_data_size
= 0;
1475 init_walk_dominator_tree (&walk_data
);
1477 /* Walk the CFG in predominator order looking for strength reduction
1479 walk_dominator_tree (&walk_data
, ENTRY_BLOCK_PTR
);
1481 if (dump_file
&& (dump_flags
& TDF_DETAILS
))
1484 dump_cand_chains ();
1487 /* Analyze costs and make appropriate replacements. */
1488 analyze_candidates_and_replace ();
1490 /* Free resources. */
1491 fini_walk_dominator_tree (&walk_data
);
1492 loop_optimizer_finalize ();
1493 free (base_cand_map
);
1494 obstack_free (&chain_obstack
, NULL
);
1495 pointer_map_destroy (stmt_cand_map
);
1496 VEC_free (slsr_cand_t
, heap
, cand_vec
);
1497 obstack_free (&cand_obstack
, NULL
);
1504 gate_strength_reduction (void)
1506 return optimize
> 0;
1509 struct gimple_opt_pass pass_strength_reduction
=
1514 gate_strength_reduction
, /* gate */
1515 execute_strength_reduction
, /* execute */
1518 0, /* static_pass_number */
1519 TV_GIMPLE_SLSR
, /* tv_id */
1520 PROP_cfg
| PROP_ssa
, /* properties_required */
1521 0, /* properties_provided */
1522 0, /* properties_destroyed */
1523 0, /* todo_flags_start */
1524 TODO_verify_ssa
/* todo_flags_finish */