OSDN Git Service

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