OSDN Git Service

Daily bump.
[pf3gnuchains/gcc-fork.git] / gcc / tree-ssa-reassoc.c
1 /* Reassociation for trees.
2    Copyright (C) 2005, 2007, 2008, 2009, 2010 Free Software Foundation, Inc.
3    Contributed by Daniel Berlin <dan@dberlin.org>
4
5 This file is part of GCC.
6
7 GCC is free software; you can redistribute it and/or modify
8 it under the terms of the GNU General Public License as published by
9 the Free Software Foundation; either version 3, or (at your option)
10 any later version.
11
12 GCC is distributed in the hope that it will be useful,
13 but WITHOUT ANY WARRANTY; without even the implied warranty of
14 MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE.  See the
15 GNU General Public License 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 #include "config.h"
22 #include "system.h"
23 #include "coretypes.h"
24 #include "tm.h"
25 #include "ggc.h"
26 #include "tree.h"
27 #include "basic-block.h"
28 #include "diagnostic.h"
29 #include "tree-inline.h"
30 #include "tree-flow.h"
31 #include "gimple.h"
32 #include "tree-dump.h"
33 #include "timevar.h"
34 #include "tree-iterator.h"
35 #include "real.h"
36 #include "tree-pass.h"
37 #include "alloc-pool.h"
38 #include "vec.h"
39 #include "langhooks.h"
40 #include "pointer-set.h"
41 #include "cfgloop.h"
42 #include "flags.h"
43
44 /*  This is a simple global reassociation pass.  It is, in part, based
45     on the LLVM pass of the same name (They do some things more/less
46     than we do, in different orders, etc).
47
48     It consists of five steps:
49
50     1. Breaking up subtract operations into addition + negate, where
51     it would promote the reassociation of adds.
52
53     2. Left linearization of the expression trees, so that (A+B)+(C+D)
54     becomes (((A+B)+C)+D), which is easier for us to rewrite later.
55     During linearization, we place the operands of the binary
56     expressions into a vector of operand_entry_t
57
58     3. Optimization of the operand lists, eliminating things like a +
59     -a, a & a, etc.
60
61     4. Rewrite the expression trees we linearized and optimized so
62     they are in proper rank order.
63
64     5. Repropagate negates, as nothing else will clean it up ATM.
65
66     A bit of theory on #4, since nobody seems to write anything down
67     about why it makes sense to do it the way they do it:
68
69     We could do this much nicer theoretically, but don't (for reasons
70     explained after how to do it theoretically nice :P).
71
72     In order to promote the most redundancy elimination, you want
73     binary expressions whose operands are the same rank (or
74     preferably, the same value) exposed to the redundancy eliminator,
75     for possible elimination.
76
77     So the way to do this if we really cared, is to build the new op
78     tree from the leaves to the roots, merging as you go, and putting the
79     new op on the end of the worklist, until you are left with one
80     thing on the worklist.
81
82     IE if you have to rewrite the following set of operands (listed with
83     rank in parentheses), with opcode PLUS_EXPR:
84
85     a (1),  b (1),  c (1),  d (2), e (2)
86
87
88     We start with our merge worklist empty, and the ops list with all of
89     those on it.
90
91     You want to first merge all leaves of the same rank, as much as
92     possible.
93
94     So first build a binary op of
95
96     mergetmp = a + b, and put "mergetmp" on the merge worklist.
97
98     Because there is no three operand form of PLUS_EXPR, c is not going to
99     be exposed to redundancy elimination as a rank 1 operand.
100
101     So you might as well throw it on the merge worklist (you could also
102     consider it to now be a rank two operand, and merge it with d and e,
103     but in this case, you then have evicted e from a binary op. So at
104     least in this situation, you can't win.)
105
106     Then build a binary op of d + e
107     mergetmp2 = d + e
108
109     and put mergetmp2 on the merge worklist.
110
111     so merge worklist = {mergetmp, c, mergetmp2}
112
113     Continue building binary ops of these operations until you have only
114     one operation left on the worklist.
115
116     So we have
117
118     build binary op
119     mergetmp3 = mergetmp + c
120
121     worklist = {mergetmp2, mergetmp3}
122
123     mergetmp4 = mergetmp2 + mergetmp3
124
125     worklist = {mergetmp4}
126
127     because we have one operation left, we can now just set the original
128     statement equal to the result of that operation.
129
130     This will at least expose a + b  and d + e to redundancy elimination
131     as binary operations.
132
133     For extra points, you can reuse the old statements to build the
134     mergetmps, since you shouldn't run out.
135
136     So why don't we do this?
137
138     Because it's expensive, and rarely will help.  Most trees we are
139     reassociating have 3 or less ops.  If they have 2 ops, they already
140     will be written into a nice single binary op.  If you have 3 ops, a
141     single simple check suffices to tell you whether the first two are of the
142     same rank.  If so, you know to order it
143
144     mergetmp = op1 + op2
145     newstmt = mergetmp + op3
146
147     instead of
148     mergetmp = op2 + op3
149     newstmt = mergetmp + op1
150
151     If all three are of the same rank, you can't expose them all in a
152     single binary operator anyway, so the above is *still* the best you
153     can do.
154
155     Thus, this is what we do.  When we have three ops left, we check to see
156     what order to put them in, and call it a day.  As a nod to vector sum
157     reduction, we check if any of the ops are really a phi node that is a
158     destructive update for the associating op, and keep the destructive
159     update together for vector sum reduction recognition.  */
160
161
162 /* Statistics */
163 static struct
164 {
165   int linearized;
166   int constants_eliminated;
167   int ops_eliminated;
168   int rewritten;
169 } reassociate_stats;
170
171 /* Operator, rank pair.  */
172 typedef struct operand_entry
173 {
174   unsigned int rank;
175   int id;
176   tree op;
177 } *operand_entry_t;
178
179 static alloc_pool operand_entry_pool;
180
181 /* This is used to assign a unique ID to each struct operand_entry
182    so that qsort results are identical on different hosts.  */
183 static int next_operand_entry_id;
184
185 /* Starting rank number for a given basic block, so that we can rank
186    operations using unmovable instructions in that BB based on the bb
187    depth.  */
188 static long *bb_rank;
189
190 /* Operand->rank hashtable.  */
191 static struct pointer_map_t *operand_rank;
192
193
194 /* Look up the operand rank structure for expression E.  */
195
196 static inline long
197 find_operand_rank (tree e)
198 {
199   void **slot = pointer_map_contains (operand_rank, e);
200   return slot ? (long) (intptr_t) *slot : -1;
201 }
202
203 /* Insert {E,RANK} into the operand rank hashtable.  */
204
205 static inline void
206 insert_operand_rank (tree e, long rank)
207 {
208   void **slot;
209   gcc_assert (rank > 0);
210   slot = pointer_map_insert (operand_rank, e);
211   gcc_assert (!*slot);
212   *slot = (void *) (intptr_t) rank;
213 }
214
215 /* Given an expression E, return the rank of the expression.  */
216
217 static long
218 get_rank (tree e)
219 {
220   /* Constants have rank 0.  */
221   if (is_gimple_min_invariant (e))
222     return 0;
223
224   /* SSA_NAME's have the rank of the expression they are the result
225      of.
226      For globals and uninitialized values, the rank is 0.
227      For function arguments, use the pre-setup rank.
228      For PHI nodes, stores, asm statements, etc, we use the rank of
229      the BB.
230      For simple operations, the rank is the maximum rank of any of
231      its operands, or the bb_rank, whichever is less.
232      I make no claims that this is optimal, however, it gives good
233      results.  */
234
235   if (TREE_CODE (e) == SSA_NAME)
236     {
237       gimple stmt;
238       long rank, maxrank;
239       int i, n;
240
241       if (TREE_CODE (SSA_NAME_VAR (e)) == PARM_DECL
242           && SSA_NAME_IS_DEFAULT_DEF (e))
243         return find_operand_rank (e);
244
245       stmt = SSA_NAME_DEF_STMT (e);
246       if (gimple_bb (stmt) == NULL)
247         return 0;
248
249       if (!is_gimple_assign (stmt)
250           || gimple_vdef (stmt))
251         return bb_rank[gimple_bb (stmt)->index];
252
253       /* If we already have a rank for this expression, use that.  */
254       rank = find_operand_rank (e);
255       if (rank != -1)
256         return rank;
257
258       /* Otherwise, find the maximum rank for the operands, or the bb
259          rank, whichever is less.   */
260       rank = 0;
261       maxrank = bb_rank[gimple_bb(stmt)->index];
262       if (gimple_assign_single_p (stmt))
263         {
264           tree rhs = gimple_assign_rhs1 (stmt);
265           n = TREE_OPERAND_LENGTH (rhs);
266           if (n == 0)
267             rank = MAX (rank, get_rank (rhs));
268           else
269             {
270               for (i = 0;
271                    i < n && TREE_OPERAND (rhs, i) && rank != maxrank; i++)
272                 rank = MAX(rank, get_rank (TREE_OPERAND (rhs, i)));
273             }
274         }
275       else
276         {
277           n = gimple_num_ops (stmt);
278           for (i = 1; i < n && rank != maxrank; i++)
279             {
280               gcc_assert (gimple_op (stmt, i));
281               rank = MAX(rank, get_rank (gimple_op (stmt, i)));
282             }
283         }
284
285       if (dump_file && (dump_flags & TDF_DETAILS))
286         {
287           fprintf (dump_file, "Rank for ");
288           print_generic_expr (dump_file, e, 0);
289           fprintf (dump_file, " is %ld\n", (rank + 1));
290         }
291
292       /* Note the rank in the hashtable so we don't recompute it.  */
293       insert_operand_rank (e, (rank + 1));
294       return (rank + 1);
295     }
296
297   /* Globals, etc,  are rank 0 */
298   return 0;
299 }
300
301 DEF_VEC_P(operand_entry_t);
302 DEF_VEC_ALLOC_P(operand_entry_t, heap);
303
304 /* We want integer ones to end up last no matter what, since they are
305    the ones we can do the most with.  */
306 #define INTEGER_CONST_TYPE 1 << 3
307 #define FLOAT_CONST_TYPE 1 << 2
308 #define OTHER_CONST_TYPE 1 << 1
309
310 /* Classify an invariant tree into integer, float, or other, so that
311    we can sort them to be near other constants of the same type.  */
312 static inline int
313 constant_type (tree t)
314 {
315   if (INTEGRAL_TYPE_P (TREE_TYPE (t)))
316     return INTEGER_CONST_TYPE;
317   else if (SCALAR_FLOAT_TYPE_P (TREE_TYPE (t)))
318     return FLOAT_CONST_TYPE;
319   else
320     return OTHER_CONST_TYPE;
321 }
322
323 /* qsort comparison function to sort operand entries PA and PB by rank
324    so that the sorted array is ordered by rank in decreasing order.  */
325 static int
326 sort_by_operand_rank (const void *pa, const void *pb)
327 {
328   const operand_entry_t oea = *(const operand_entry_t *)pa;
329   const operand_entry_t oeb = *(const operand_entry_t *)pb;
330
331   /* It's nicer for optimize_expression if constants that are likely
332      to fold when added/multiplied//whatever are put next to each
333      other.  Since all constants have rank 0, order them by type.  */
334   if (oeb->rank == 0 &&  oea->rank == 0)
335     {
336       if (constant_type (oeb->op) != constant_type (oea->op))
337         return constant_type (oeb->op) - constant_type (oea->op);
338       else
339         /* To make sorting result stable, we use unique IDs to determine
340            order.  */
341         return oeb->id - oea->id;
342     }
343
344   /* Lastly, make sure the versions that are the same go next to each
345      other.  We use SSA_NAME_VERSION because it's stable.  */
346   if ((oeb->rank - oea->rank == 0)
347       && TREE_CODE (oea->op) == SSA_NAME
348       && TREE_CODE (oeb->op) == SSA_NAME)
349     {
350       if (SSA_NAME_VERSION (oeb->op) != SSA_NAME_VERSION (oea->op))
351         return SSA_NAME_VERSION (oeb->op) - SSA_NAME_VERSION (oea->op);
352       else
353         return oeb->id - oea->id;
354     }
355
356   if (oeb->rank != oea->rank)
357     return oeb->rank - oea->rank;
358   else
359     return oeb->id - oea->id;
360 }
361
362 /* Add an operand entry to *OPS for the tree operand OP.  */
363
364 static void
365 add_to_ops_vec (VEC(operand_entry_t, heap) **ops, tree op)
366 {
367   operand_entry_t oe = (operand_entry_t) pool_alloc (operand_entry_pool);
368
369   oe->op = op;
370   oe->rank = get_rank (op);
371   oe->id = next_operand_entry_id++;
372   VEC_safe_push (operand_entry_t, heap, *ops, oe);
373 }
374
375 /* Return true if STMT is reassociable operation containing a binary
376    operation with tree code CODE, and is inside LOOP.  */
377
378 static bool
379 is_reassociable_op (gimple stmt, enum tree_code code, struct loop *loop)
380 {
381   basic_block bb = gimple_bb (stmt);
382
383   if (gimple_bb (stmt) == NULL)
384     return false;
385
386   if (!flow_bb_inside_loop_p (loop, bb))
387     return false;
388
389   if (is_gimple_assign (stmt)
390       && gimple_assign_rhs_code (stmt) == code
391       && has_single_use (gimple_assign_lhs (stmt)))
392     return true;
393
394   return false;
395 }
396
397
398 /* Given NAME, if NAME is defined by a unary operation OPCODE, return the
399    operand of the negate operation.  Otherwise, return NULL.  */
400
401 static tree
402 get_unary_op (tree name, enum tree_code opcode)
403 {
404   gimple stmt = SSA_NAME_DEF_STMT (name);
405
406   if (!is_gimple_assign (stmt))
407     return NULL_TREE;
408
409   if (gimple_assign_rhs_code (stmt) == opcode)
410     return gimple_assign_rhs1 (stmt);
411   return NULL_TREE;
412 }
413
414 /* If CURR and LAST are a pair of ops that OPCODE allows us to
415    eliminate through equivalences, do so, remove them from OPS, and
416    return true.  Otherwise, return false.  */
417
418 static bool
419 eliminate_duplicate_pair (enum tree_code opcode,
420                           VEC (operand_entry_t, heap) **ops,
421                           bool *all_done,
422                           unsigned int i,
423                           operand_entry_t curr,
424                           operand_entry_t last)
425 {
426
427   /* If we have two of the same op, and the opcode is & |, min, or max,
428      we can eliminate one of them.
429      If we have two of the same op, and the opcode is ^, we can
430      eliminate both of them.  */
431
432   if (last && last->op == curr->op)
433     {
434       switch (opcode)
435         {
436         case MAX_EXPR:
437         case MIN_EXPR:
438         case BIT_IOR_EXPR:
439         case BIT_AND_EXPR:
440           if (dump_file && (dump_flags & TDF_DETAILS))
441             {
442               fprintf (dump_file, "Equivalence: ");
443               print_generic_expr (dump_file, curr->op, 0);
444               fprintf (dump_file, " [&|minmax] ");
445               print_generic_expr (dump_file, last->op, 0);
446               fprintf (dump_file, " -> ");
447               print_generic_stmt (dump_file, last->op, 0);
448             }
449
450           VEC_ordered_remove (operand_entry_t, *ops, i);
451           reassociate_stats.ops_eliminated ++;
452
453           return true;
454
455         case BIT_XOR_EXPR:
456           if (dump_file && (dump_flags & TDF_DETAILS))
457             {
458               fprintf (dump_file, "Equivalence: ");
459               print_generic_expr (dump_file, curr->op, 0);
460               fprintf (dump_file, " ^ ");
461               print_generic_expr (dump_file, last->op, 0);
462               fprintf (dump_file, " -> nothing\n");
463             }
464
465           reassociate_stats.ops_eliminated += 2;
466
467           if (VEC_length (operand_entry_t, *ops) == 2)
468             {
469               VEC_free (operand_entry_t, heap, *ops);
470               *ops = NULL;
471               add_to_ops_vec (ops, fold_convert (TREE_TYPE (last->op),
472                                                  integer_zero_node));
473               *all_done = true;
474             }
475           else
476             {
477               VEC_ordered_remove (operand_entry_t, *ops, i-1);
478               VEC_ordered_remove (operand_entry_t, *ops, i-1);
479             }
480
481           return true;
482
483         default:
484           break;
485         }
486     }
487   return false;
488 }
489
490 static VEC(tree, heap) *plus_negates;
491
492 /* If OPCODE is PLUS_EXPR, CURR->OP is a negate expression or a bitwise not
493    expression, look in OPS for a corresponding positive operation to cancel
494    it out.  If we find one, remove the other from OPS, replace
495    OPS[CURRINDEX] with 0 or -1, respectively, and return true.  Otherwise,
496    return false. */
497
498 static bool
499 eliminate_plus_minus_pair (enum tree_code opcode,
500                            VEC (operand_entry_t, heap) **ops,
501                            unsigned int currindex,
502                            operand_entry_t curr)
503 {
504   tree negateop;
505   tree notop;
506   unsigned int i;
507   operand_entry_t oe;
508
509   if (opcode != PLUS_EXPR || TREE_CODE (curr->op) != SSA_NAME)
510     return false;
511
512   negateop = get_unary_op (curr->op, NEGATE_EXPR);
513   notop = get_unary_op (curr->op, BIT_NOT_EXPR);
514   if (negateop == NULL_TREE && notop == NULL_TREE)
515     return false;
516
517   /* Any non-negated version will have a rank that is one less than
518      the current rank.  So once we hit those ranks, if we don't find
519      one, we can stop.  */
520
521   for (i = currindex + 1;
522        VEC_iterate (operand_entry_t, *ops, i, oe)
523        && oe->rank >= curr->rank - 1 ;
524        i++)
525     {
526       if (oe->op == negateop)
527         {
528
529           if (dump_file && (dump_flags & TDF_DETAILS))
530             {
531               fprintf (dump_file, "Equivalence: ");
532               print_generic_expr (dump_file, negateop, 0);
533               fprintf (dump_file, " + -");
534               print_generic_expr (dump_file, oe->op, 0);
535               fprintf (dump_file, " -> 0\n");
536             }
537
538           VEC_ordered_remove (operand_entry_t, *ops, i);
539           add_to_ops_vec (ops, fold_convert(TREE_TYPE (oe->op),
540                                             integer_zero_node));
541           VEC_ordered_remove (operand_entry_t, *ops, currindex);
542           reassociate_stats.ops_eliminated ++;
543
544           return true;
545         }
546       else if (oe->op == notop)
547         {
548           tree op_type = TREE_TYPE (oe->op);
549
550           if (dump_file && (dump_flags & TDF_DETAILS))
551             {
552               fprintf (dump_file, "Equivalence: ");
553               print_generic_expr (dump_file, notop, 0);
554               fprintf (dump_file, " + ~");
555               print_generic_expr (dump_file, oe->op, 0);
556               fprintf (dump_file, " -> -1\n");
557             }
558
559           VEC_ordered_remove (operand_entry_t, *ops, i);
560           add_to_ops_vec (ops, build_int_cst_type (op_type, -1));
561           VEC_ordered_remove (operand_entry_t, *ops, currindex);
562           reassociate_stats.ops_eliminated ++;
563
564           return true;
565         }
566     }
567
568   /* CURR->OP is a negate expr in a plus expr: save it for later
569      inspection in repropagate_negates().  */
570   if (negateop != NULL_TREE)
571     VEC_safe_push (tree, heap, plus_negates, curr->op);
572
573   return false;
574 }
575
576 /* If OPCODE is BIT_IOR_EXPR, BIT_AND_EXPR, and, CURR->OP is really a
577    bitwise not expression, look in OPS for a corresponding operand to
578    cancel it out.  If we find one, remove the other from OPS, replace
579    OPS[CURRINDEX] with 0, and return true.  Otherwise, return
580    false. */
581
582 static bool
583 eliminate_not_pairs (enum tree_code opcode,
584                      VEC (operand_entry_t, heap) **ops,
585                      unsigned int currindex,
586                      operand_entry_t curr)
587 {
588   tree notop;
589   unsigned int i;
590   operand_entry_t oe;
591
592   if ((opcode != BIT_IOR_EXPR && opcode != BIT_AND_EXPR)
593       || TREE_CODE (curr->op) != SSA_NAME)
594     return false;
595
596   notop = get_unary_op (curr->op, BIT_NOT_EXPR);
597   if (notop == NULL_TREE)
598     return false;
599
600   /* Any non-not version will have a rank that is one less than
601      the current rank.  So once we hit those ranks, if we don't find
602      one, we can stop.  */
603
604   for (i = currindex + 1;
605        VEC_iterate (operand_entry_t, *ops, i, oe)
606        && oe->rank >= curr->rank - 1;
607        i++)
608     {
609       if (oe->op == notop)
610         {
611           if (dump_file && (dump_flags & TDF_DETAILS))
612             {
613               fprintf (dump_file, "Equivalence: ");
614               print_generic_expr (dump_file, notop, 0);
615               if (opcode == BIT_AND_EXPR)
616                 fprintf (dump_file, " & ~");
617               else if (opcode == BIT_IOR_EXPR)
618                 fprintf (dump_file, " | ~");
619               print_generic_expr (dump_file, oe->op, 0);
620               if (opcode == BIT_AND_EXPR)
621                 fprintf (dump_file, " -> 0\n");
622               else if (opcode == BIT_IOR_EXPR)
623                 fprintf (dump_file, " -> -1\n");
624             }
625
626           if (opcode == BIT_AND_EXPR)
627             oe->op = fold_convert (TREE_TYPE (oe->op), integer_zero_node);
628           else if (opcode == BIT_IOR_EXPR)
629             oe->op = build_low_bits_mask (TREE_TYPE (oe->op),
630                                           TYPE_PRECISION (TREE_TYPE (oe->op)));
631
632           reassociate_stats.ops_eliminated
633             += VEC_length (operand_entry_t, *ops) - 1;
634           VEC_free (operand_entry_t, heap, *ops);
635           *ops = NULL;
636           VEC_safe_push (operand_entry_t, heap, *ops, oe);
637           return true;
638         }
639     }
640
641   return false;
642 }
643
644 /* Use constant value that may be present in OPS to try to eliminate
645    operands.  Note that this function is only really used when we've
646    eliminated ops for other reasons, or merged constants.  Across
647    single statements, fold already does all of this, plus more.  There
648    is little point in duplicating logic, so I've only included the
649    identities that I could ever construct testcases to trigger.  */
650
651 static void
652 eliminate_using_constants (enum tree_code opcode,
653                            VEC(operand_entry_t, heap) **ops)
654 {
655   operand_entry_t oelast = VEC_last (operand_entry_t, *ops);
656   tree type = TREE_TYPE (oelast->op);
657
658   if (oelast->rank == 0
659       && (INTEGRAL_TYPE_P (type) || FLOAT_TYPE_P (type)))
660     {
661       switch (opcode)
662         {
663         case BIT_AND_EXPR:
664           if (integer_zerop (oelast->op))
665             {
666               if (VEC_length (operand_entry_t, *ops) != 1)
667                 {
668                   if (dump_file && (dump_flags & TDF_DETAILS))
669                     fprintf (dump_file, "Found & 0, removing all other ops\n");
670
671                   reassociate_stats.ops_eliminated
672                     += VEC_length (operand_entry_t, *ops) - 1;
673
674                   VEC_free (operand_entry_t, heap, *ops);
675                   *ops = NULL;
676                   VEC_safe_push (operand_entry_t, heap, *ops, oelast);
677                   return;
678                 }
679             }
680           else if (integer_all_onesp (oelast->op))
681             {
682               if (VEC_length (operand_entry_t, *ops) != 1)
683                 {
684                   if (dump_file && (dump_flags & TDF_DETAILS))
685                     fprintf (dump_file, "Found & -1, removing\n");
686                   VEC_pop (operand_entry_t, *ops);
687                   reassociate_stats.ops_eliminated++;
688                 }
689             }
690           break;
691         case BIT_IOR_EXPR:
692           if (integer_all_onesp (oelast->op))
693             {
694               if (VEC_length (operand_entry_t, *ops) != 1)
695                 {
696                   if (dump_file && (dump_flags & TDF_DETAILS))
697                     fprintf (dump_file, "Found | -1, removing all other ops\n");
698
699                   reassociate_stats.ops_eliminated
700                     += VEC_length (operand_entry_t, *ops) - 1;
701
702                   VEC_free (operand_entry_t, heap, *ops);
703                   *ops = NULL;
704                   VEC_safe_push (operand_entry_t, heap, *ops, oelast);
705                   return;
706                 }
707             }
708           else if (integer_zerop (oelast->op))
709             {
710               if (VEC_length (operand_entry_t, *ops) != 1)
711                 {
712                   if (dump_file && (dump_flags & TDF_DETAILS))
713                     fprintf (dump_file, "Found | 0, removing\n");
714                   VEC_pop (operand_entry_t, *ops);
715                   reassociate_stats.ops_eliminated++;
716                 }
717             }
718           break;
719         case MULT_EXPR:
720           if (integer_zerop (oelast->op)
721               || (FLOAT_TYPE_P (type)
722                   && !HONOR_NANS (TYPE_MODE (type))
723                   && !HONOR_SIGNED_ZEROS (TYPE_MODE (type))
724                   && real_zerop (oelast->op)))
725             {
726               if (VEC_length (operand_entry_t, *ops) != 1)
727                 {
728                   if (dump_file && (dump_flags & TDF_DETAILS))
729                     fprintf (dump_file, "Found * 0, removing all other ops\n");
730
731                   reassociate_stats.ops_eliminated
732                     += VEC_length (operand_entry_t, *ops) - 1;
733                   VEC_free (operand_entry_t, heap, *ops);
734                   *ops = NULL;
735                   VEC_safe_push (operand_entry_t, heap, *ops, oelast);
736                   return;
737                 }
738             }
739           else if (integer_onep (oelast->op)
740                    || (FLOAT_TYPE_P (type)
741                        && !HONOR_SNANS (TYPE_MODE (type))
742                        && real_onep (oelast->op)))
743             {
744               if (VEC_length (operand_entry_t, *ops) != 1)
745                 {
746                   if (dump_file && (dump_flags & TDF_DETAILS))
747                     fprintf (dump_file, "Found * 1, removing\n");
748                   VEC_pop (operand_entry_t, *ops);
749                   reassociate_stats.ops_eliminated++;
750                   return;
751                 }
752             }
753           break;
754         case BIT_XOR_EXPR:
755         case PLUS_EXPR:
756         case MINUS_EXPR:
757           if (integer_zerop (oelast->op)
758               || (FLOAT_TYPE_P (type)
759                   && (opcode == PLUS_EXPR || opcode == MINUS_EXPR)
760                   && fold_real_zero_addition_p (type, oelast->op,
761                                                 opcode == MINUS_EXPR)))
762             {
763               if (VEC_length (operand_entry_t, *ops) != 1)
764                 {
765                   if (dump_file && (dump_flags & TDF_DETAILS))
766                     fprintf (dump_file, "Found [|^+] 0, removing\n");
767                   VEC_pop (operand_entry_t, *ops);
768                   reassociate_stats.ops_eliminated++;
769                   return;
770                 }
771             }
772           break;
773         default:
774           break;
775         }
776     }
777 }
778
779
780 static void linearize_expr_tree (VEC(operand_entry_t, heap) **, gimple,
781                                  bool, bool);
782
783 /* Structure for tracking and counting operands.  */
784 typedef struct oecount_s {
785   int cnt;
786   int id;
787   enum tree_code oecode;
788   tree op;
789 } oecount;
790
791 DEF_VEC_O(oecount);
792 DEF_VEC_ALLOC_O(oecount,heap);
793
794 /* The heap for the oecount hashtable and the sorted list of operands.  */
795 static VEC (oecount, heap) *cvec;
796
797 /* Hash function for oecount.  */
798
799 static hashval_t
800 oecount_hash (const void *p)
801 {
802   const oecount *c = VEC_index (oecount, cvec, (size_t)p - 42);
803   return htab_hash_pointer (c->op) ^ (hashval_t)c->oecode;
804 }
805
806 /* Comparison function for oecount.  */
807
808 static int
809 oecount_eq (const void *p1, const void *p2)
810 {
811   const oecount *c1 = VEC_index (oecount, cvec, (size_t)p1 - 42);
812   const oecount *c2 = VEC_index (oecount, cvec, (size_t)p2 - 42);
813   return (c1->oecode == c2->oecode
814           && c1->op == c2->op);
815 }
816
817 /* Comparison function for qsort sorting oecount elements by count.  */
818
819 static int
820 oecount_cmp (const void *p1, const void *p2)
821 {
822   const oecount *c1 = (const oecount *)p1;
823   const oecount *c2 = (const oecount *)p2;
824   if (c1->cnt != c2->cnt)
825     return c1->cnt - c2->cnt;
826   else
827     /* If counts are identical, use unique IDs to stabilize qsort.  */
828     return c1->id - c2->id;
829 }
830
831 /* Walks the linear chain with result *DEF searching for an operation
832    with operand OP and code OPCODE removing that from the chain.  *DEF
833    is updated if there is only one operand but no operation left.  */
834
835 static void
836 zero_one_operation (tree *def, enum tree_code opcode, tree op)
837 {
838   gimple stmt = SSA_NAME_DEF_STMT (*def);
839
840   do
841     {
842       tree name = gimple_assign_rhs1 (stmt);
843
844       /* If this is the operation we look for and one of the operands
845          is ours simply propagate the other operand into the stmts
846          single use.  */
847       if (gimple_assign_rhs_code (stmt) == opcode
848           && (name == op
849               || gimple_assign_rhs2 (stmt) == op))
850         {
851           gimple use_stmt;
852           use_operand_p use;
853           gimple_stmt_iterator gsi;
854           if (name == op)
855             name = gimple_assign_rhs2 (stmt);
856           gcc_assert (has_single_use (gimple_assign_lhs (stmt)));
857           single_imm_use (gimple_assign_lhs (stmt), &use, &use_stmt);
858           if (gimple_assign_lhs (stmt) == *def)
859             *def = name;
860           SET_USE (use, name);
861           if (TREE_CODE (name) != SSA_NAME)
862             update_stmt (use_stmt);
863           gsi = gsi_for_stmt (stmt);
864           gsi_remove (&gsi, true);
865           release_defs (stmt);
866           return;
867         }
868
869       /* Continue walking the chain.  */
870       gcc_assert (name != op
871                   && TREE_CODE (name) == SSA_NAME);
872       stmt = SSA_NAME_DEF_STMT (name);
873     }
874   while (1);
875 }
876
877 /* Builds one statement performing OP1 OPCODE OP2 using TMPVAR for
878    the result.  Places the statement after the definition of either
879    OP1 or OP2.  Returns the new statement.  */
880
881 static gimple
882 build_and_add_sum (tree tmpvar, tree op1, tree op2, enum tree_code opcode)
883 {
884   gimple op1def = NULL, op2def = NULL;
885   gimple_stmt_iterator gsi;
886   tree op;
887   gimple sum;
888
889   /* Create the addition statement.  */
890   sum = gimple_build_assign_with_ops (opcode, tmpvar, op1, op2);
891   op = make_ssa_name (tmpvar, sum);
892   gimple_assign_set_lhs (sum, op);
893
894   /* Find an insertion place and insert.  */
895   if (TREE_CODE (op1) == SSA_NAME)
896     op1def = SSA_NAME_DEF_STMT (op1);
897   if (TREE_CODE (op2) == SSA_NAME)
898     op2def = SSA_NAME_DEF_STMT (op2);
899   if ((!op1def || gimple_nop_p (op1def))
900       && (!op2def || gimple_nop_p (op2def)))
901     {
902       gsi = gsi_after_labels (single_succ (ENTRY_BLOCK_PTR));
903       gsi_insert_before (&gsi, sum, GSI_NEW_STMT);
904     }
905   else if ((!op1def || gimple_nop_p (op1def))
906            || (op2def && !gimple_nop_p (op2def)
907                && stmt_dominates_stmt_p (op1def, op2def)))
908     {
909       if (gimple_code (op2def) == GIMPLE_PHI)
910         {
911           gsi = gsi_after_labels (gimple_bb (op2def));
912           gsi_insert_before (&gsi, sum, GSI_NEW_STMT);
913         }
914       else
915         {
916           if (!stmt_ends_bb_p (op2def))
917             {
918               gsi = gsi_for_stmt (op2def);
919               gsi_insert_after (&gsi, sum, GSI_NEW_STMT);
920             }
921           else
922             {
923               edge e;
924               edge_iterator ei;
925
926               FOR_EACH_EDGE (e, ei, gimple_bb (op2def)->succs)
927                 if (e->flags & EDGE_FALLTHRU)
928                   gsi_insert_on_edge_immediate (e, sum);
929             }
930         }
931     }
932   else
933     {
934       if (gimple_code (op1def) == GIMPLE_PHI)
935         {
936           gsi = gsi_after_labels (gimple_bb (op1def));
937           gsi_insert_before (&gsi, sum, GSI_NEW_STMT);
938         }
939       else
940         {
941           if (!stmt_ends_bb_p (op1def))
942             {
943               gsi = gsi_for_stmt (op1def);
944               gsi_insert_after (&gsi, sum, GSI_NEW_STMT);
945             }
946           else
947             {
948               edge e;
949               edge_iterator ei;
950
951               FOR_EACH_EDGE (e, ei, gimple_bb (op1def)->succs)
952                 if (e->flags & EDGE_FALLTHRU)
953                   gsi_insert_on_edge_immediate (e, sum);
954             }
955         }
956     }
957   update_stmt (sum);
958
959   return sum;
960 }
961
962 /* Perform un-distribution of divisions and multiplications.
963    A * X + B * X is transformed into (A + B) * X and A / X + B / X
964    to (A + B) / X for real X.
965
966    The algorithm is organized as follows.
967
968     - First we walk the addition chain *OPS looking for summands that
969       are defined by a multiplication or a real division.  This results
970       in the candidates bitmap with relevant indices into *OPS.
971
972     - Second we build the chains of multiplications or divisions for
973       these candidates, counting the number of occurences of (operand, code)
974       pairs in all of the candidates chains.
975
976     - Third we sort the (operand, code) pairs by number of occurence and
977       process them starting with the pair with the most uses.
978
979       * For each such pair we walk the candidates again to build a
980         second candidate bitmap noting all multiplication/division chains
981         that have at least one occurence of (operand, code).
982
983       * We build an alternate addition chain only covering these
984         candidates with one (operand, code) operation removed from their
985         multiplication/division chain.
986
987       * The first candidate gets replaced by the alternate addition chain
988         multiplied/divided by the operand.
989
990       * All candidate chains get disabled for further processing and
991         processing of (operand, code) pairs continues.
992
993   The alternate addition chains built are re-processed by the main
994   reassociation algorithm which allows optimizing a * x * y + b * y * x
995   to (a + b ) * x * y in one invocation of the reassociation pass.  */
996
997 static bool
998 undistribute_ops_list (enum tree_code opcode,
999                        VEC (operand_entry_t, heap) **ops, struct loop *loop)
1000 {
1001   unsigned int length = VEC_length (operand_entry_t, *ops);
1002   operand_entry_t oe1;
1003   unsigned i, j;
1004   sbitmap candidates, candidates2;
1005   unsigned nr_candidates, nr_candidates2;
1006   sbitmap_iterator sbi0;
1007   VEC (operand_entry_t, heap) **subops;
1008   htab_t ctable;
1009   bool changed = false;
1010   int next_oecount_id = 0;
1011
1012   if (length <= 1
1013       || opcode != PLUS_EXPR)
1014     return false;
1015
1016   /* Build a list of candidates to process.  */
1017   candidates = sbitmap_alloc (length);
1018   sbitmap_zero (candidates);
1019   nr_candidates = 0;
1020   for (i = 0; VEC_iterate (operand_entry_t, *ops, i, oe1); ++i)
1021     {
1022       enum tree_code dcode;
1023       gimple oe1def;
1024
1025       if (TREE_CODE (oe1->op) != SSA_NAME)
1026         continue;
1027       oe1def = SSA_NAME_DEF_STMT (oe1->op);
1028       if (!is_gimple_assign (oe1def))
1029         continue;
1030       dcode = gimple_assign_rhs_code (oe1def);
1031       if ((dcode != MULT_EXPR
1032            && dcode != RDIV_EXPR)
1033           || !is_reassociable_op (oe1def, dcode, loop))
1034         continue;
1035
1036       SET_BIT (candidates, i);
1037       nr_candidates++;
1038     }
1039
1040   if (nr_candidates < 2)
1041     {
1042       sbitmap_free (candidates);
1043       return false;
1044     }
1045
1046   if (dump_file && (dump_flags & TDF_DETAILS))
1047     {
1048       fprintf (dump_file, "searching for un-distribute opportunities ");
1049       print_generic_expr (dump_file,
1050         VEC_index (operand_entry_t, *ops,
1051                    sbitmap_first_set_bit (candidates))->op, 0);
1052       fprintf (dump_file, " %d\n", nr_candidates);
1053     }
1054
1055   /* Build linearized sub-operand lists and the counting table.  */
1056   cvec = NULL;
1057   ctable = htab_create (15, oecount_hash, oecount_eq, NULL);
1058   subops = XCNEWVEC (VEC (operand_entry_t, heap) *,
1059                      VEC_length (operand_entry_t, *ops));
1060   EXECUTE_IF_SET_IN_SBITMAP (candidates, 0, i, sbi0)
1061     {
1062       gimple oedef;
1063       enum tree_code oecode;
1064       unsigned j;
1065
1066       oedef = SSA_NAME_DEF_STMT (VEC_index (operand_entry_t, *ops, i)->op);
1067       oecode = gimple_assign_rhs_code (oedef);
1068       linearize_expr_tree (&subops[i], oedef,
1069                            associative_tree_code (oecode), false);
1070
1071       for (j = 0; VEC_iterate (operand_entry_t, subops[i], j, oe1); ++j)
1072         {
1073           oecount c;
1074           void **slot;
1075           size_t idx;
1076           c.oecode = oecode;
1077           c.cnt = 1;
1078           c.id = next_oecount_id++;
1079           c.op = oe1->op;
1080           VEC_safe_push (oecount, heap, cvec, &c);
1081           idx = VEC_length (oecount, cvec) + 41;
1082           slot = htab_find_slot (ctable, (void *)idx, INSERT);
1083           if (!*slot)
1084             {
1085               *slot = (void *)idx;
1086             }
1087           else
1088             {
1089               VEC_pop (oecount, cvec);
1090               VEC_index (oecount, cvec, (size_t)*slot - 42)->cnt++;
1091             }
1092         }
1093     }
1094   htab_delete (ctable);
1095
1096   /* Sort the counting table.  */
1097   qsort (VEC_address (oecount, cvec), VEC_length (oecount, cvec),
1098          sizeof (oecount), oecount_cmp);
1099
1100   if (dump_file && (dump_flags & TDF_DETAILS))
1101     {
1102       oecount *c;
1103       fprintf (dump_file, "Candidates:\n");
1104       for (j = 0; VEC_iterate (oecount, cvec, j, c); ++j)
1105         {
1106           fprintf (dump_file, "  %u %s: ", c->cnt,
1107                    c->oecode == MULT_EXPR
1108                    ? "*" : c->oecode == RDIV_EXPR ? "/" : "?");
1109           print_generic_expr (dump_file, c->op, 0);
1110           fprintf (dump_file, "\n");
1111         }
1112     }
1113
1114   /* Process the (operand, code) pairs in order of most occurence.  */
1115   candidates2 = sbitmap_alloc (length);
1116   while (!VEC_empty (oecount, cvec))
1117     {
1118       oecount *c = VEC_last (oecount, cvec);
1119       if (c->cnt < 2)
1120         break;
1121
1122       /* Now collect the operands in the outer chain that contain
1123          the common operand in their inner chain.  */
1124       sbitmap_zero (candidates2);
1125       nr_candidates2 = 0;
1126       EXECUTE_IF_SET_IN_SBITMAP (candidates, 0, i, sbi0)
1127         {
1128           gimple oedef;
1129           enum tree_code oecode;
1130           unsigned j;
1131           tree op = VEC_index (operand_entry_t, *ops, i)->op;
1132
1133           /* If we undistributed in this chain already this may be
1134              a constant.  */
1135           if (TREE_CODE (op) != SSA_NAME)
1136             continue;
1137
1138           oedef = SSA_NAME_DEF_STMT (op);
1139           oecode = gimple_assign_rhs_code (oedef);
1140           if (oecode != c->oecode)
1141             continue;
1142
1143           for (j = 0; VEC_iterate (operand_entry_t, subops[i], j, oe1); ++j)
1144             {
1145               if (oe1->op == c->op)
1146                 {
1147                   SET_BIT (candidates2, i);
1148                   ++nr_candidates2;
1149                   break;
1150                 }
1151             }
1152         }
1153
1154       if (nr_candidates2 >= 2)
1155         {
1156           operand_entry_t oe1, oe2;
1157           tree tmpvar;
1158           gimple prod;
1159           int first = sbitmap_first_set_bit (candidates2);
1160
1161           /* Build the new addition chain.  */
1162           oe1 = VEC_index (operand_entry_t, *ops, first);
1163           if (dump_file && (dump_flags & TDF_DETAILS))
1164             {
1165               fprintf (dump_file, "Building (");
1166               print_generic_expr (dump_file, oe1->op, 0);
1167             }
1168           tmpvar = create_tmp_var (TREE_TYPE (oe1->op), NULL);
1169           add_referenced_var (tmpvar);
1170           zero_one_operation (&oe1->op, c->oecode, c->op);
1171           EXECUTE_IF_SET_IN_SBITMAP (candidates2, first+1, i, sbi0)
1172             {
1173               gimple sum;
1174               oe2 = VEC_index (operand_entry_t, *ops, i);
1175               if (dump_file && (dump_flags & TDF_DETAILS))
1176                 {
1177                   fprintf (dump_file, " + ");
1178                   print_generic_expr (dump_file, oe2->op, 0);
1179                 }
1180               zero_one_operation (&oe2->op, c->oecode, c->op);
1181               sum = build_and_add_sum (tmpvar, oe1->op, oe2->op, opcode);
1182               oe2->op = fold_convert (TREE_TYPE (oe2->op), integer_zero_node);
1183               oe2->rank = 0;
1184               oe1->op = gimple_get_lhs (sum);
1185             }
1186
1187           /* Apply the multiplication/division.  */
1188           prod = build_and_add_sum (tmpvar, oe1->op, c->op, c->oecode);
1189           if (dump_file && (dump_flags & TDF_DETAILS))
1190             {
1191               fprintf (dump_file, ") %s ", c->oecode == MULT_EXPR ? "*" : "/");
1192               print_generic_expr (dump_file, c->op, 0);
1193               fprintf (dump_file, "\n");
1194             }
1195
1196           /* Record it in the addition chain and disable further
1197              undistribution with this op.  */
1198           oe1->op = gimple_assign_lhs (prod);
1199           oe1->rank = get_rank (oe1->op);
1200           VEC_free (operand_entry_t, heap, subops[first]);
1201
1202           changed = true;
1203         }
1204
1205       VEC_pop (oecount, cvec);
1206     }
1207
1208   for (i = 0; i < VEC_length (operand_entry_t, *ops); ++i)
1209     VEC_free (operand_entry_t, heap, subops[i]);
1210   free (subops);
1211   VEC_free (oecount, heap, cvec);
1212   sbitmap_free (candidates);
1213   sbitmap_free (candidates2);
1214
1215   return changed;
1216 }
1217
1218
1219 /* Perform various identities and other optimizations on the list of
1220    operand entries, stored in OPS.  The tree code for the binary
1221    operation between all the operands is OPCODE.  */
1222
1223 static void
1224 optimize_ops_list (enum tree_code opcode,
1225                    VEC (operand_entry_t, heap) **ops)
1226 {
1227   unsigned int length = VEC_length (operand_entry_t, *ops);
1228   unsigned int i;
1229   operand_entry_t oe;
1230   operand_entry_t oelast = NULL;
1231   bool iterate = false;
1232
1233   if (length == 1)
1234     return;
1235
1236   oelast = VEC_last (operand_entry_t, *ops);
1237
1238   /* If the last two are constants, pop the constants off, merge them
1239      and try the next two.  */
1240   if (oelast->rank == 0 && is_gimple_min_invariant (oelast->op))
1241     {
1242       operand_entry_t oelm1 = VEC_index (operand_entry_t, *ops, length - 2);
1243
1244       if (oelm1->rank == 0
1245           && is_gimple_min_invariant (oelm1->op)
1246           && useless_type_conversion_p (TREE_TYPE (oelm1->op),
1247                                        TREE_TYPE (oelast->op)))
1248         {
1249           tree folded = fold_binary (opcode, TREE_TYPE (oelm1->op),
1250                                      oelm1->op, oelast->op);
1251
1252           if (folded && is_gimple_min_invariant (folded))
1253             {
1254               if (dump_file && (dump_flags & TDF_DETAILS))
1255                 fprintf (dump_file, "Merging constants\n");
1256
1257               VEC_pop (operand_entry_t, *ops);
1258               VEC_pop (operand_entry_t, *ops);
1259
1260               add_to_ops_vec (ops, folded);
1261               reassociate_stats.constants_eliminated++;
1262
1263               optimize_ops_list (opcode, ops);
1264               return;
1265             }
1266         }
1267     }
1268
1269   eliminate_using_constants (opcode, ops);
1270   oelast = NULL;
1271
1272   for (i = 0; VEC_iterate (operand_entry_t, *ops, i, oe);)
1273     {
1274       bool done = false;
1275
1276       if (eliminate_not_pairs (opcode, ops, i, oe))
1277         return;
1278       if (eliminate_duplicate_pair (opcode, ops, &done, i, oe, oelast)
1279           || (!done && eliminate_plus_minus_pair (opcode, ops, i, oe)))
1280         {
1281           if (done)
1282             return;
1283           iterate = true;
1284           oelast = NULL;
1285           continue;
1286         }
1287       oelast = oe;
1288       i++;
1289     }
1290
1291   length  = VEC_length (operand_entry_t, *ops);
1292   oelast = VEC_last (operand_entry_t, *ops);
1293
1294   if (iterate)
1295     optimize_ops_list (opcode, ops);
1296 }
1297
1298 /* Return true if OPERAND is defined by a PHI node which uses the LHS
1299    of STMT in it's operands.  This is also known as a "destructive
1300    update" operation.  */
1301
1302 static bool
1303 is_phi_for_stmt (gimple stmt, tree operand)
1304 {
1305   gimple def_stmt;
1306   tree lhs;
1307   use_operand_p arg_p;
1308   ssa_op_iter i;
1309
1310   if (TREE_CODE (operand) != SSA_NAME)
1311     return false;
1312
1313   lhs = gimple_assign_lhs (stmt);
1314
1315   def_stmt = SSA_NAME_DEF_STMT (operand);
1316   if (gimple_code (def_stmt) != GIMPLE_PHI)
1317     return false;
1318
1319   FOR_EACH_PHI_ARG (arg_p, def_stmt, i, SSA_OP_USE)
1320     if (lhs == USE_FROM_PTR (arg_p))
1321       return true;
1322   return false;
1323 }
1324
1325 /* Remove def stmt of VAR if VAR has zero uses and recurse
1326    on rhs1 operand if so.  */
1327
1328 static void
1329 remove_visited_stmt_chain (tree var)
1330 {
1331   gimple stmt;
1332   gimple_stmt_iterator gsi;
1333
1334   while (1)
1335     {
1336       if (TREE_CODE (var) != SSA_NAME || !has_zero_uses (var))
1337         return;
1338       stmt = SSA_NAME_DEF_STMT (var);
1339       if (!is_gimple_assign (stmt)
1340           || !gimple_visited_p (stmt))
1341         return;
1342       var = gimple_assign_rhs1 (stmt);
1343       gsi = gsi_for_stmt (stmt);
1344       gsi_remove (&gsi, true);
1345       release_defs (stmt);
1346     }
1347 }
1348
1349 /* Recursively rewrite our linearized statements so that the operators
1350    match those in OPS[OPINDEX], putting the computation in rank
1351    order.  */
1352
1353 static void
1354 rewrite_expr_tree (gimple stmt, unsigned int opindex,
1355                    VEC(operand_entry_t, heap) * ops, bool moved)
1356 {
1357   tree rhs1 = gimple_assign_rhs1 (stmt);
1358   tree rhs2 = gimple_assign_rhs2 (stmt);
1359   operand_entry_t oe;
1360
1361   /* If we have three operands left, then we want to make sure the one
1362      that gets the double binary op are the ones with the same rank.
1363
1364      The alternative we try is to see if this is a destructive
1365      update style statement, which is like:
1366      b = phi (a, ...)
1367      a = c + b;
1368      In that case, we want to use the destructive update form to
1369      expose the possible vectorizer sum reduction opportunity.
1370      In that case, the third operand will be the phi node.
1371
1372      We could, of course, try to be better as noted above, and do a
1373      lot of work to try to find these opportunities in >3 operand
1374      cases, but it is unlikely to be worth it.  */
1375   if (opindex + 3 == VEC_length (operand_entry_t, ops))
1376     {
1377       operand_entry_t oe1, oe2, oe3;
1378
1379       oe1 = VEC_index (operand_entry_t, ops, opindex);
1380       oe2 = VEC_index (operand_entry_t, ops, opindex + 1);
1381       oe3 = VEC_index (operand_entry_t, ops, opindex + 2);
1382
1383       if ((oe1->rank == oe2->rank
1384            && oe2->rank != oe3->rank)
1385           || (is_phi_for_stmt (stmt, oe3->op)
1386               && !is_phi_for_stmt (stmt, oe1->op)
1387               && !is_phi_for_stmt (stmt, oe2->op)))
1388         {
1389           struct operand_entry temp = *oe3;
1390           oe3->op = oe1->op;
1391           oe3->rank = oe1->rank;
1392           oe1->op = temp.op;
1393           oe1->rank= temp.rank;
1394         }
1395       else if ((oe1->rank == oe3->rank
1396                 && oe2->rank != oe3->rank)
1397                || (is_phi_for_stmt (stmt, oe2->op)
1398                    && !is_phi_for_stmt (stmt, oe1->op)
1399                    && !is_phi_for_stmt (stmt, oe3->op)))
1400         {
1401           struct operand_entry temp = *oe2;
1402           oe2->op = oe1->op;
1403           oe2->rank = oe1->rank;
1404           oe1->op = temp.op;
1405           oe1->rank= temp.rank;
1406         }
1407     }
1408
1409   /* The final recursion case for this function is that you have
1410      exactly two operations left.
1411      If we had one exactly one op in the entire list to start with, we
1412      would have never called this function, and the tail recursion
1413      rewrites them one at a time.  */
1414   if (opindex + 2 == VEC_length (operand_entry_t, ops))
1415     {
1416       operand_entry_t oe1, oe2;
1417
1418       oe1 = VEC_index (operand_entry_t, ops, opindex);
1419       oe2 = VEC_index (operand_entry_t, ops, opindex + 1);
1420
1421       if (rhs1 != oe1->op || rhs2 != oe2->op)
1422         {
1423           if (dump_file && (dump_flags & TDF_DETAILS))
1424             {
1425               fprintf (dump_file, "Transforming ");
1426               print_gimple_stmt (dump_file, stmt, 0, 0);
1427             }
1428
1429           gimple_assign_set_rhs1 (stmt, oe1->op);
1430           gimple_assign_set_rhs2 (stmt, oe2->op);
1431           update_stmt (stmt);
1432           if (rhs1 != oe1->op && rhs1 != oe2->op)
1433             remove_visited_stmt_chain (rhs1);
1434
1435           if (dump_file && (dump_flags & TDF_DETAILS))
1436             {
1437               fprintf (dump_file, " into ");
1438               print_gimple_stmt (dump_file, stmt, 0, 0);
1439             }
1440
1441         }
1442       return;
1443     }
1444
1445   /* If we hit here, we should have 3 or more ops left.  */
1446   gcc_assert (opindex + 2 < VEC_length (operand_entry_t, ops));
1447
1448   /* Rewrite the next operator.  */
1449   oe = VEC_index (operand_entry_t, ops, opindex);
1450
1451   if (oe->op != rhs2)
1452     {
1453       if (!moved)
1454         {
1455           gimple_stmt_iterator gsinow, gsirhs1;
1456           gimple stmt1 = stmt, stmt2;
1457           unsigned int count;
1458
1459           gsinow = gsi_for_stmt (stmt);
1460           count = VEC_length (operand_entry_t, ops) - opindex - 2;
1461           while (count-- != 0)
1462             {
1463               stmt2 = SSA_NAME_DEF_STMT (gimple_assign_rhs1 (stmt1));
1464               gsirhs1 = gsi_for_stmt (stmt2);
1465               gsi_move_before (&gsirhs1, &gsinow);
1466               gsi_prev (&gsinow);
1467               stmt1 = stmt2;
1468             }
1469           moved = true;
1470         }
1471
1472       if (dump_file && (dump_flags & TDF_DETAILS))
1473         {
1474           fprintf (dump_file, "Transforming ");
1475           print_gimple_stmt (dump_file, stmt, 0, 0);
1476         }
1477
1478       gimple_assign_set_rhs2 (stmt, oe->op);
1479       update_stmt (stmt);
1480
1481       if (dump_file && (dump_flags & TDF_DETAILS))
1482         {
1483           fprintf (dump_file, " into ");
1484           print_gimple_stmt (dump_file, stmt, 0, 0);
1485         }
1486     }
1487   /* Recurse on the LHS of the binary operator, which is guaranteed to
1488      be the non-leaf side.  */
1489   rewrite_expr_tree (SSA_NAME_DEF_STMT (rhs1), opindex + 1, ops, moved);
1490 }
1491
1492 /* Transform STMT, which is really (A +B) + (C + D) into the left
1493    linear form, ((A+B)+C)+D.
1494    Recurse on D if necessary.  */
1495
1496 static void
1497 linearize_expr (gimple stmt)
1498 {
1499   gimple_stmt_iterator gsinow, gsirhs;
1500   gimple binlhs = SSA_NAME_DEF_STMT (gimple_assign_rhs1 (stmt));
1501   gimple binrhs = SSA_NAME_DEF_STMT (gimple_assign_rhs2 (stmt));
1502   enum tree_code rhscode = gimple_assign_rhs_code (stmt);
1503   gimple newbinrhs = NULL;
1504   struct loop *loop = loop_containing_stmt (stmt);
1505
1506   gcc_assert (is_reassociable_op (binlhs, rhscode, loop)
1507               && is_reassociable_op (binrhs, rhscode, loop));
1508
1509   gsinow = gsi_for_stmt (stmt);
1510   gsirhs = gsi_for_stmt (binrhs);
1511   gsi_move_before (&gsirhs, &gsinow);
1512
1513   gimple_assign_set_rhs2 (stmt, gimple_assign_rhs1 (binrhs));
1514   gimple_assign_set_rhs1 (binrhs, gimple_assign_lhs (binlhs));
1515   gimple_assign_set_rhs1 (stmt, gimple_assign_lhs (binrhs));
1516
1517   if (TREE_CODE (gimple_assign_rhs2 (stmt)) == SSA_NAME)
1518     newbinrhs = SSA_NAME_DEF_STMT (gimple_assign_rhs2 (stmt));
1519
1520   if (dump_file && (dump_flags & TDF_DETAILS))
1521     {
1522       fprintf (dump_file, "Linearized: ");
1523       print_gimple_stmt (dump_file, stmt, 0, 0);
1524     }
1525
1526   reassociate_stats.linearized++;
1527   update_stmt (binrhs);
1528   update_stmt (binlhs);
1529   update_stmt (stmt);
1530
1531   gimple_set_visited (stmt, true);
1532   gimple_set_visited (binlhs, true);
1533   gimple_set_visited (binrhs, true);
1534
1535   /* Tail recurse on the new rhs if it still needs reassociation.  */
1536   if (newbinrhs && is_reassociable_op (newbinrhs, rhscode, loop))
1537     /* ??? This should probably be linearize_expr (newbinrhs) but I don't
1538            want to change the algorithm while converting to tuples.  */
1539     linearize_expr (stmt);
1540 }
1541
1542 /* If LHS has a single immediate use that is a GIMPLE_ASSIGN statement, return
1543    it.  Otherwise, return NULL.  */
1544
1545 static gimple
1546 get_single_immediate_use (tree lhs)
1547 {
1548   use_operand_p immuse;
1549   gimple immusestmt;
1550
1551   if (TREE_CODE (lhs) == SSA_NAME
1552       && single_imm_use (lhs, &immuse, &immusestmt)
1553       && is_gimple_assign (immusestmt))
1554     return immusestmt;
1555
1556   return NULL;
1557 }
1558
1559 /* Recursively negate the value of TONEGATE, and return the SSA_NAME
1560    representing the negated value.  Insertions of any necessary
1561    instructions go before GSI.
1562    This function is recursive in that, if you hand it "a_5" as the
1563    value to negate, and a_5 is defined by "a_5 = b_3 + b_4", it will
1564    transform b_3 + b_4 into a_5 = -b_3 + -b_4.  */
1565
1566 static tree
1567 negate_value (tree tonegate, gimple_stmt_iterator *gsi)
1568 {
1569   gimple negatedefstmt= NULL;
1570   tree resultofnegate;
1571
1572   /* If we are trying to negate a name, defined by an add, negate the
1573      add operands instead.  */
1574   if (TREE_CODE (tonegate) == SSA_NAME)
1575     negatedefstmt = SSA_NAME_DEF_STMT (tonegate);
1576   if (TREE_CODE (tonegate) == SSA_NAME
1577       && is_gimple_assign (negatedefstmt)
1578       && TREE_CODE (gimple_assign_lhs (negatedefstmt)) == SSA_NAME
1579       && has_single_use (gimple_assign_lhs (negatedefstmt))
1580       && gimple_assign_rhs_code (negatedefstmt) == PLUS_EXPR)
1581     {
1582       gimple_stmt_iterator gsi;
1583       tree rhs1 = gimple_assign_rhs1 (negatedefstmt);
1584       tree rhs2 = gimple_assign_rhs2 (negatedefstmt);
1585
1586       gsi = gsi_for_stmt (negatedefstmt);
1587       rhs1 = negate_value (rhs1, &gsi);
1588       gimple_assign_set_rhs1 (negatedefstmt, rhs1);
1589
1590       gsi = gsi_for_stmt (negatedefstmt);
1591       rhs2 = negate_value (rhs2, &gsi);
1592       gimple_assign_set_rhs2 (negatedefstmt, rhs2);
1593
1594       update_stmt (negatedefstmt);
1595       return gimple_assign_lhs (negatedefstmt);
1596     }
1597
1598   tonegate = fold_build1 (NEGATE_EXPR, TREE_TYPE (tonegate), tonegate);
1599   resultofnegate = force_gimple_operand_gsi (gsi, tonegate, true,
1600                                              NULL_TREE, true, GSI_SAME_STMT);
1601   return resultofnegate;
1602 }
1603
1604 /* Return true if we should break up the subtract in STMT into an add
1605    with negate.  This is true when we the subtract operands are really
1606    adds, or the subtract itself is used in an add expression.  In
1607    either case, breaking up the subtract into an add with negate
1608    exposes the adds to reassociation.  */
1609
1610 static bool
1611 should_break_up_subtract (gimple stmt)
1612 {
1613   tree lhs = gimple_assign_lhs (stmt);
1614   tree binlhs = gimple_assign_rhs1 (stmt);
1615   tree binrhs = gimple_assign_rhs2 (stmt);
1616   gimple immusestmt;
1617   struct loop *loop = loop_containing_stmt (stmt);
1618
1619   if (TREE_CODE (binlhs) == SSA_NAME
1620       && is_reassociable_op (SSA_NAME_DEF_STMT (binlhs), PLUS_EXPR, loop))
1621     return true;
1622
1623   if (TREE_CODE (binrhs) == SSA_NAME
1624       && is_reassociable_op (SSA_NAME_DEF_STMT (binrhs), PLUS_EXPR, loop))
1625     return true;
1626
1627   if (TREE_CODE (lhs) == SSA_NAME
1628       && (immusestmt = get_single_immediate_use (lhs))
1629       && is_gimple_assign (immusestmt)
1630       && (gimple_assign_rhs_code (immusestmt) == PLUS_EXPR
1631           ||  gimple_assign_rhs_code (immusestmt) == MULT_EXPR))
1632     return true;
1633   return false;
1634 }
1635
1636 /* Transform STMT from A - B into A + -B.  */
1637
1638 static void
1639 break_up_subtract (gimple stmt, gimple_stmt_iterator *gsip)
1640 {
1641   tree rhs1 = gimple_assign_rhs1 (stmt);
1642   tree rhs2 = gimple_assign_rhs2 (stmt);
1643
1644   if (dump_file && (dump_flags & TDF_DETAILS))
1645     {
1646       fprintf (dump_file, "Breaking up subtract ");
1647       print_gimple_stmt (dump_file, stmt, 0, 0);
1648     }
1649
1650   rhs2 = negate_value (rhs2, gsip);
1651   gimple_assign_set_rhs_with_ops (gsip, PLUS_EXPR, rhs1, rhs2);
1652   update_stmt (stmt);
1653 }
1654
1655 /* Recursively linearize a binary expression that is the RHS of STMT.
1656    Place the operands of the expression tree in the vector named OPS.  */
1657
1658 static void
1659 linearize_expr_tree (VEC(operand_entry_t, heap) **ops, gimple stmt,
1660                      bool is_associative, bool set_visited)
1661 {
1662   tree binlhs = gimple_assign_rhs1 (stmt);
1663   tree binrhs = gimple_assign_rhs2 (stmt);
1664   gimple binlhsdef, binrhsdef;
1665   bool binlhsisreassoc = false;
1666   bool binrhsisreassoc = false;
1667   enum tree_code rhscode = gimple_assign_rhs_code (stmt);
1668   struct loop *loop = loop_containing_stmt (stmt);
1669
1670   if (set_visited)
1671     gimple_set_visited (stmt, true);
1672
1673   if (TREE_CODE (binlhs) == SSA_NAME)
1674     {
1675       binlhsdef = SSA_NAME_DEF_STMT (binlhs);
1676       binlhsisreassoc = is_reassociable_op (binlhsdef, rhscode, loop);
1677     }
1678
1679   if (TREE_CODE (binrhs) == SSA_NAME)
1680     {
1681       binrhsdef = SSA_NAME_DEF_STMT (binrhs);
1682       binrhsisreassoc = is_reassociable_op (binrhsdef, rhscode, loop);
1683     }
1684
1685   /* If the LHS is not reassociable, but the RHS is, we need to swap
1686      them.  If neither is reassociable, there is nothing we can do, so
1687      just put them in the ops vector.  If the LHS is reassociable,
1688      linearize it.  If both are reassociable, then linearize the RHS
1689      and the LHS.  */
1690
1691   if (!binlhsisreassoc)
1692     {
1693       tree temp;
1694
1695       /* If this is not a associative operation like division, give up.  */
1696       if (!is_associative)
1697         {
1698           add_to_ops_vec (ops, binrhs);
1699           return;
1700         }
1701
1702       if (!binrhsisreassoc)
1703         {
1704           add_to_ops_vec (ops, binrhs);
1705           add_to_ops_vec (ops, binlhs);
1706           return;
1707         }
1708
1709       if (dump_file && (dump_flags & TDF_DETAILS))
1710         {
1711           fprintf (dump_file, "swapping operands of ");
1712           print_gimple_stmt (dump_file, stmt, 0, 0);
1713         }
1714
1715       swap_tree_operands (stmt,
1716                           gimple_assign_rhs1_ptr (stmt),
1717                           gimple_assign_rhs2_ptr (stmt));
1718       update_stmt (stmt);
1719
1720       if (dump_file && (dump_flags & TDF_DETAILS))
1721         {
1722           fprintf (dump_file, " is now ");
1723           print_gimple_stmt (dump_file, stmt, 0, 0);
1724         }
1725
1726       /* We want to make it so the lhs is always the reassociative op,
1727          so swap.  */
1728       temp = binlhs;
1729       binlhs = binrhs;
1730       binrhs = temp;
1731     }
1732   else if (binrhsisreassoc)
1733     {
1734       linearize_expr (stmt);
1735       binlhs = gimple_assign_rhs1 (stmt);
1736       binrhs = gimple_assign_rhs2 (stmt);
1737     }
1738
1739   gcc_assert (TREE_CODE (binrhs) != SSA_NAME
1740               || !is_reassociable_op (SSA_NAME_DEF_STMT (binrhs),
1741                                       rhscode, loop));
1742   linearize_expr_tree (ops, SSA_NAME_DEF_STMT (binlhs),
1743                        is_associative, set_visited);
1744   add_to_ops_vec (ops, binrhs);
1745 }
1746
1747 /* Repropagate the negates back into subtracts, since no other pass
1748    currently does it.  */
1749
1750 static void
1751 repropagate_negates (void)
1752 {
1753   unsigned int i = 0;
1754   tree negate;
1755
1756   for (i = 0; VEC_iterate (tree, plus_negates, i, negate); i++)
1757     {
1758       gimple user = get_single_immediate_use (negate);
1759
1760       if (!user || !is_gimple_assign (user))
1761         continue;
1762
1763       /* The negate operand can be either operand of a PLUS_EXPR
1764          (it can be the LHS if the RHS is a constant for example).
1765
1766          Force the negate operand to the RHS of the PLUS_EXPR, then
1767          transform the PLUS_EXPR into a MINUS_EXPR.  */
1768       if (gimple_assign_rhs_code (user) == PLUS_EXPR)
1769         {
1770           /* If the negated operand appears on the LHS of the
1771              PLUS_EXPR, exchange the operands of the PLUS_EXPR
1772              to force the negated operand to the RHS of the PLUS_EXPR.  */
1773           if (gimple_assign_rhs1 (user) == negate)
1774             {
1775               swap_tree_operands (user,
1776                                   gimple_assign_rhs1_ptr (user),
1777                                   gimple_assign_rhs2_ptr (user));
1778             }
1779
1780           /* Now transform the PLUS_EXPR into a MINUS_EXPR and replace
1781              the RHS of the PLUS_EXPR with the operand of the NEGATE_EXPR.  */
1782           if (gimple_assign_rhs2 (user) == negate)
1783             {
1784               tree rhs1 = gimple_assign_rhs1 (user);
1785               tree rhs2 = get_unary_op (negate, NEGATE_EXPR);
1786               gimple_stmt_iterator gsi = gsi_for_stmt (user);
1787               gimple_assign_set_rhs_with_ops (&gsi, MINUS_EXPR, rhs1, rhs2);
1788               update_stmt (user);
1789             }
1790         }
1791       else if (gimple_assign_rhs_code (user) == MINUS_EXPR)
1792         {
1793           if (gimple_assign_rhs1 (user) == negate)
1794             {
1795               /* We have
1796                    x = -a
1797                    y = x - b
1798                  which we transform into
1799                    x = a + b
1800                    y = -x .
1801                  This pushes down the negate which we possibly can merge
1802                  into some other operation, hence insert it into the
1803                  plus_negates vector.  */
1804               gimple feed = SSA_NAME_DEF_STMT (negate);
1805               tree a = gimple_assign_rhs1 (feed);
1806               tree rhs2 = gimple_assign_rhs2 (user);
1807               gimple_stmt_iterator gsi = gsi_for_stmt (feed), gsi2;
1808               gimple_replace_lhs (feed, negate);
1809               gimple_assign_set_rhs_with_ops (&gsi, PLUS_EXPR, a, rhs2);
1810               update_stmt (gsi_stmt (gsi));
1811               gsi2 = gsi_for_stmt (user);
1812               gimple_assign_set_rhs_with_ops (&gsi2, NEGATE_EXPR, negate, NULL);
1813               update_stmt (gsi_stmt (gsi2));
1814               gsi_move_before (&gsi, &gsi2);
1815               VEC_safe_push (tree, heap, plus_negates,
1816                              gimple_assign_lhs (gsi_stmt (gsi2)));
1817             }
1818           else
1819             {
1820               /* Transform "x = -a; y = b - x" into "y = b + a", getting
1821                  rid of one operation.  */
1822               gimple feed = SSA_NAME_DEF_STMT (negate);
1823               tree a = gimple_assign_rhs1 (feed);
1824               tree rhs1 = gimple_assign_rhs1 (user);
1825               gimple_stmt_iterator gsi = gsi_for_stmt (user);
1826               gimple_assign_set_rhs_with_ops (&gsi, PLUS_EXPR, rhs1, a);
1827               update_stmt (gsi_stmt (gsi));
1828             }
1829         }
1830     }
1831 }
1832
1833 /* Returns true if OP is of a type for which we can do reassociation.
1834    That is for integral or non-saturating fixed-point types, and for
1835    floating point type when associative-math is enabled.  */
1836
1837 static bool
1838 can_reassociate_p (tree op)
1839 {
1840   tree type = TREE_TYPE (op);
1841   if (INTEGRAL_TYPE_P (type)
1842       || NON_SAT_FIXED_POINT_TYPE_P (type)
1843       || (flag_associative_math && SCALAR_FLOAT_TYPE_P (type)))
1844     return true;
1845   return false;
1846 }
1847
1848 /* Break up subtract operations in block BB.
1849
1850    We do this top down because we don't know whether the subtract is
1851    part of a possible chain of reassociation except at the top.
1852
1853    IE given
1854    d = f + g
1855    c = a + e
1856    b = c - d
1857    q = b - r
1858    k = t - q
1859
1860    we want to break up k = t - q, but we won't until we've transformed q
1861    = b - r, which won't be broken up until we transform b = c - d.
1862
1863    En passant, clear the GIMPLE visited flag on every statement.  */
1864
1865 static void
1866 break_up_subtract_bb (basic_block bb)
1867 {
1868   gimple_stmt_iterator gsi;
1869   basic_block son;
1870
1871   for (gsi = gsi_start_bb (bb); !gsi_end_p (gsi); gsi_next (&gsi))
1872     {
1873       gimple stmt = gsi_stmt (gsi);
1874       gimple_set_visited (stmt, false);
1875
1876       if (!is_gimple_assign (stmt)
1877           || !can_reassociate_p (gimple_assign_lhs (stmt)))
1878         continue;
1879
1880       /* Look for simple gimple subtract operations.  */
1881       if (gimple_assign_rhs_code (stmt) == MINUS_EXPR)
1882         {
1883           if (!can_reassociate_p (gimple_assign_rhs1 (stmt))
1884               || !can_reassociate_p (gimple_assign_rhs2 (stmt)))
1885             continue;
1886
1887           /* Check for a subtract used only in an addition.  If this
1888              is the case, transform it into add of a negate for better
1889              reassociation.  IE transform C = A-B into C = A + -B if C
1890              is only used in an addition.  */
1891           if (should_break_up_subtract (stmt))
1892             break_up_subtract (stmt, &gsi);
1893         }
1894       else if (gimple_assign_rhs_code (stmt) == NEGATE_EXPR
1895                && can_reassociate_p (gimple_assign_rhs1 (stmt)))
1896         VEC_safe_push (tree, heap, plus_negates, gimple_assign_lhs (stmt));
1897     }
1898   for (son = first_dom_son (CDI_DOMINATORS, bb);
1899        son;
1900        son = next_dom_son (CDI_DOMINATORS, son))
1901     break_up_subtract_bb (son);
1902 }
1903
1904 /* Reassociate expressions in basic block BB and its post-dominator as
1905    children.  */
1906
1907 static void
1908 reassociate_bb (basic_block bb)
1909 {
1910   gimple_stmt_iterator gsi;
1911   basic_block son;
1912
1913   for (gsi = gsi_last_bb (bb); !gsi_end_p (gsi); gsi_prev (&gsi))
1914     {
1915       gimple stmt = gsi_stmt (gsi);
1916
1917       if (is_gimple_assign (stmt))
1918         {
1919           tree lhs, rhs1, rhs2;
1920           enum tree_code rhs_code = gimple_assign_rhs_code (stmt);
1921
1922           /* If this is not a gimple binary expression, there is
1923              nothing for us to do with it.  */
1924           if (get_gimple_rhs_class (rhs_code) != GIMPLE_BINARY_RHS)
1925             continue;
1926
1927           /* If this was part of an already processed statement,
1928              we don't need to touch it again. */
1929           if (gimple_visited_p (stmt))
1930             {
1931               /* This statement might have become dead because of previous
1932                  reassociations.  */
1933               if (has_zero_uses (gimple_get_lhs (stmt)))
1934                 {
1935                   gsi_remove (&gsi, true);
1936                   release_defs (stmt);
1937                   /* We might end up removing the last stmt above which
1938                      places the iterator to the end of the sequence.
1939                      Reset it to the last stmt in this case which might
1940                      be the end of the sequence as well if we removed
1941                      the last statement of the sequence.  In which case
1942                      we need to bail out.  */
1943                   if (gsi_end_p (gsi))
1944                     {
1945                       gsi = gsi_last_bb (bb);
1946                       if (gsi_end_p (gsi))
1947                         break;
1948                     }
1949                 }
1950               continue;
1951             }
1952
1953           lhs = gimple_assign_lhs (stmt);
1954           rhs1 = gimple_assign_rhs1 (stmt);
1955           rhs2 = gimple_assign_rhs2 (stmt);
1956
1957           if (!can_reassociate_p (lhs)
1958               || !can_reassociate_p (rhs1)
1959               || !can_reassociate_p (rhs2))
1960             continue;
1961
1962           if (associative_tree_code (rhs_code))
1963             {
1964               VEC(operand_entry_t, heap) *ops = NULL;
1965
1966               /* There may be no immediate uses left by the time we
1967                  get here because we may have eliminated them all.  */
1968               if (TREE_CODE (lhs) == SSA_NAME && has_zero_uses (lhs))
1969                 continue;
1970
1971               gimple_set_visited (stmt, true);
1972               linearize_expr_tree (&ops, stmt, true, true);
1973               qsort (VEC_address (operand_entry_t, ops),
1974                      VEC_length (operand_entry_t, ops),
1975                      sizeof (operand_entry_t),
1976                      sort_by_operand_rank);
1977               optimize_ops_list (rhs_code, &ops);
1978               if (undistribute_ops_list (rhs_code, &ops,
1979                                          loop_containing_stmt (stmt)))
1980                 {
1981                   qsort (VEC_address (operand_entry_t, ops),
1982                          VEC_length (operand_entry_t, ops),
1983                          sizeof (operand_entry_t),
1984                          sort_by_operand_rank);
1985                   optimize_ops_list (rhs_code, &ops);
1986                 }
1987
1988               if (VEC_length (operand_entry_t, ops) == 1)
1989                 {
1990                   if (dump_file && (dump_flags & TDF_DETAILS))
1991                     {
1992                       fprintf (dump_file, "Transforming ");
1993                       print_gimple_stmt (dump_file, stmt, 0, 0);
1994                     }
1995
1996                   rhs1 = gimple_assign_rhs1 (stmt);
1997                   gimple_assign_set_rhs_from_tree (&gsi,
1998                                                    VEC_last (operand_entry_t,
1999                                                              ops)->op);
2000                   update_stmt (stmt);
2001                   remove_visited_stmt_chain (rhs1);
2002
2003                   if (dump_file && (dump_flags & TDF_DETAILS))
2004                     {
2005                       fprintf (dump_file, " into ");
2006                       print_gimple_stmt (dump_file, stmt, 0, 0);
2007                     }
2008                 }
2009               else
2010                 rewrite_expr_tree (stmt, 0, ops, false);
2011
2012               VEC_free (operand_entry_t, heap, ops);
2013             }
2014         }
2015     }
2016   for (son = first_dom_son (CDI_POST_DOMINATORS, bb);
2017        son;
2018        son = next_dom_son (CDI_POST_DOMINATORS, son))
2019     reassociate_bb (son);
2020 }
2021
2022 void dump_ops_vector (FILE *file, VEC (operand_entry_t, heap) *ops);
2023 void debug_ops_vector (VEC (operand_entry_t, heap) *ops);
2024
2025 /* Dump the operand entry vector OPS to FILE.  */
2026
2027 void
2028 dump_ops_vector (FILE *file, VEC (operand_entry_t, heap) *ops)
2029 {
2030   operand_entry_t oe;
2031   unsigned int i;
2032
2033   for (i = 0; VEC_iterate (operand_entry_t, ops, i, oe); i++)
2034     {
2035       fprintf (file, "Op %d -> rank: %d, tree: ", i, oe->rank);
2036       print_generic_expr (file, oe->op, 0);
2037     }
2038 }
2039
2040 /* Dump the operand entry vector OPS to STDERR.  */
2041
2042 void
2043 debug_ops_vector (VEC (operand_entry_t, heap) *ops)
2044 {
2045   dump_ops_vector (stderr, ops);
2046 }
2047
2048 static void
2049 do_reassoc (void)
2050 {
2051   break_up_subtract_bb (ENTRY_BLOCK_PTR);
2052   reassociate_bb (EXIT_BLOCK_PTR);
2053 }
2054
2055 /* Initialize the reassociation pass.  */
2056
2057 static void
2058 init_reassoc (void)
2059 {
2060   int i;
2061   long rank = 2;
2062   tree param;
2063   int *bbs = XNEWVEC (int, last_basic_block + 1);
2064
2065   /* Find the loops, so that we can prevent moving calculations in
2066      them.  */
2067   loop_optimizer_init (AVOID_CFG_MODIFICATIONS);
2068
2069   memset (&reassociate_stats, 0, sizeof (reassociate_stats));
2070
2071   operand_entry_pool = create_alloc_pool ("operand entry pool",
2072                                           sizeof (struct operand_entry), 30);
2073   next_operand_entry_id = 0;
2074
2075   /* Reverse RPO (Reverse Post Order) will give us something where
2076      deeper loops come later.  */
2077   pre_and_rev_post_order_compute (NULL, bbs, false);
2078   bb_rank = XCNEWVEC (long, last_basic_block + 1);
2079   operand_rank = pointer_map_create ();
2080
2081   /* Give each argument a distinct rank.   */
2082   for (param = DECL_ARGUMENTS (current_function_decl);
2083        param;
2084        param = TREE_CHAIN (param))
2085     {
2086       if (gimple_default_def (cfun, param) != NULL)
2087         {
2088           tree def = gimple_default_def (cfun, param);
2089           insert_operand_rank (def, ++rank);
2090         }
2091     }
2092
2093   /* Give the chain decl a distinct rank. */
2094   if (cfun->static_chain_decl != NULL)
2095     {
2096       tree def = gimple_default_def (cfun, cfun->static_chain_decl);
2097       if (def != NULL)
2098         insert_operand_rank (def, ++rank);
2099     }
2100
2101   /* Set up rank for each BB  */
2102   for (i = 0; i < n_basic_blocks - NUM_FIXED_BLOCKS; i++)
2103     bb_rank[bbs[i]] = ++rank  << 16;
2104
2105   free (bbs);
2106   calculate_dominance_info (CDI_POST_DOMINATORS);
2107   plus_negates = NULL;
2108 }
2109
2110 /* Cleanup after the reassociation pass, and print stats if
2111    requested.  */
2112
2113 static void
2114 fini_reassoc (void)
2115 {
2116   statistics_counter_event (cfun, "Linearized",
2117                             reassociate_stats.linearized);
2118   statistics_counter_event (cfun, "Constants eliminated",
2119                             reassociate_stats.constants_eliminated);
2120   statistics_counter_event (cfun, "Ops eliminated",
2121                             reassociate_stats.ops_eliminated);
2122   statistics_counter_event (cfun, "Statements rewritten",
2123                             reassociate_stats.rewritten);
2124
2125   pointer_map_destroy (operand_rank);
2126   free_alloc_pool (operand_entry_pool);
2127   free (bb_rank);
2128   VEC_free (tree, heap, plus_negates);
2129   free_dominance_info (CDI_POST_DOMINATORS);
2130   loop_optimizer_finalize ();
2131 }
2132
2133 /* Gate and execute functions for Reassociation.  */
2134
2135 static unsigned int
2136 execute_reassoc (void)
2137 {
2138   init_reassoc ();
2139
2140   do_reassoc ();
2141   repropagate_negates ();
2142
2143   fini_reassoc ();
2144   return 0;
2145 }
2146
2147 static bool
2148 gate_tree_ssa_reassoc (void)
2149 {
2150   return flag_tree_reassoc != 0;
2151 }
2152
2153 struct gimple_opt_pass pass_reassoc =
2154 {
2155  {
2156   GIMPLE_PASS,
2157   "reassoc",                            /* name */
2158   gate_tree_ssa_reassoc,                /* gate */
2159   execute_reassoc,                      /* execute */
2160   NULL,                                 /* sub */
2161   NULL,                                 /* next */
2162   0,                                    /* static_pass_number */
2163   TV_TREE_REASSOC,                      /* tv_id */
2164   PROP_cfg | PROP_ssa,                  /* properties_required */
2165   0,                                    /* properties_provided */
2166   0,                                    /* properties_destroyed */
2167   0,                                    /* todo_flags_start */
2168   TODO_dump_func | TODO_ggc_collect | TODO_verify_ssa /* todo_flags_finish */
2169  }
2170 };
2171