OSDN Git Service

/cp
[pf3gnuchains/gcc-fork.git] / gcc / tree-ssa-reassoc.c
1 /* Reassociation for trees.
2    Copyright (C) 2005, 2007, 2008, 2009, 2010, 2011
3    Free Software Foundation, Inc.
4    Contributed by Daniel Berlin <dan@dberlin.org>
5
6 This file is part of GCC.
7
8 GCC is free software; you can redistribute it and/or modify
9 it under the terms of the GNU General Public License as published by
10 the Free Software Foundation; either version 3, or (at your option)
11 any later version.
12
13 GCC is distributed in the hope that it will be useful,
14 but WITHOUT ANY WARRANTY; without even the implied warranty of
15 MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE.  See the
16 GNU General Public License for more details.
17
18 You should have received a copy of the GNU General Public License
19 along with GCC; see the file COPYING3.  If not see
20 <http://www.gnu.org/licenses/>.  */
21
22 #include "config.h"
23 #include "system.h"
24 #include "coretypes.h"
25 #include "tm.h"
26 #include "tree.h"
27 #include "basic-block.h"
28 #include "tree-pretty-print.h"
29 #include "gimple-pretty-print.h"
30 #include "tree-inline.h"
31 #include "tree-flow.h"
32 #include "gimple.h"
33 #include "tree-dump.h"
34 #include "timevar.h"
35 #include "tree-iterator.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, build_zero_cst (TREE_TYPE (last->op)));
472               *all_done = true;
473             }
474           else
475             {
476               VEC_ordered_remove (operand_entry_t, *ops, i-1);
477               VEC_ordered_remove (operand_entry_t, *ops, i-1);
478             }
479
480           return true;
481
482         default:
483           break;
484         }
485     }
486   return false;
487 }
488
489 static VEC(tree, heap) *plus_negates;
490
491 /* If OPCODE is PLUS_EXPR, CURR->OP is a negate expression or a bitwise not
492    expression, look in OPS for a corresponding positive operation to cancel
493    it out.  If we find one, remove the other from OPS, replace
494    OPS[CURRINDEX] with 0 or -1, respectively, and return true.  Otherwise,
495    return false. */
496
497 static bool
498 eliminate_plus_minus_pair (enum tree_code opcode,
499                            VEC (operand_entry_t, heap) **ops,
500                            unsigned int currindex,
501                            operand_entry_t curr)
502 {
503   tree negateop;
504   tree notop;
505   unsigned int i;
506   operand_entry_t oe;
507
508   if (opcode != PLUS_EXPR || TREE_CODE (curr->op) != SSA_NAME)
509     return false;
510
511   negateop = get_unary_op (curr->op, NEGATE_EXPR);
512   notop = get_unary_op (curr->op, BIT_NOT_EXPR);
513   if (negateop == NULL_TREE && notop == NULL_TREE)
514     return false;
515
516   /* Any non-negated version will have a rank that is one less than
517      the current rank.  So once we hit those ranks, if we don't find
518      one, we can stop.  */
519
520   for (i = currindex + 1;
521        VEC_iterate (operand_entry_t, *ops, i, oe)
522        && oe->rank >= curr->rank - 1 ;
523        i++)
524     {
525       if (oe->op == negateop)
526         {
527
528           if (dump_file && (dump_flags & TDF_DETAILS))
529             {
530               fprintf (dump_file, "Equivalence: ");
531               print_generic_expr (dump_file, negateop, 0);
532               fprintf (dump_file, " + -");
533               print_generic_expr (dump_file, oe->op, 0);
534               fprintf (dump_file, " -> 0\n");
535             }
536
537           VEC_ordered_remove (operand_entry_t, *ops, i);
538           add_to_ops_vec (ops, build_zero_cst (TREE_TYPE (oe->op)));
539           VEC_ordered_remove (operand_entry_t, *ops, currindex);
540           reassociate_stats.ops_eliminated ++;
541
542           return true;
543         }
544       else if (oe->op == notop)
545         {
546           tree op_type = TREE_TYPE (oe->op);
547
548           if (dump_file && (dump_flags & TDF_DETAILS))
549             {
550               fprintf (dump_file, "Equivalence: ");
551               print_generic_expr (dump_file, notop, 0);
552               fprintf (dump_file, " + ~");
553               print_generic_expr (dump_file, oe->op, 0);
554               fprintf (dump_file, " -> -1\n");
555             }
556
557           VEC_ordered_remove (operand_entry_t, *ops, i);
558           add_to_ops_vec (ops, build_int_cst_type (op_type, -1));
559           VEC_ordered_remove (operand_entry_t, *ops, currindex);
560           reassociate_stats.ops_eliminated ++;
561
562           return true;
563         }
564     }
565
566   /* CURR->OP is a negate expr in a plus expr: save it for later
567      inspection in repropagate_negates().  */
568   if (negateop != NULL_TREE)
569     VEC_safe_push (tree, heap, plus_negates, curr->op);
570
571   return false;
572 }
573
574 /* If OPCODE is BIT_IOR_EXPR, BIT_AND_EXPR, and, CURR->OP is really a
575    bitwise not expression, look in OPS for a corresponding operand to
576    cancel it out.  If we find one, remove the other from OPS, replace
577    OPS[CURRINDEX] with 0, and return true.  Otherwise, return
578    false. */
579
580 static bool
581 eliminate_not_pairs (enum tree_code opcode,
582                      VEC (operand_entry_t, heap) **ops,
583                      unsigned int currindex,
584                      operand_entry_t curr)
585 {
586   tree notop;
587   unsigned int i;
588   operand_entry_t oe;
589
590   if ((opcode != BIT_IOR_EXPR && opcode != BIT_AND_EXPR)
591       || TREE_CODE (curr->op) != SSA_NAME)
592     return false;
593
594   notop = get_unary_op (curr->op, BIT_NOT_EXPR);
595   if (notop == NULL_TREE)
596     return false;
597
598   /* Any non-not version will have a rank that is one less than
599      the current rank.  So once we hit those ranks, if we don't find
600      one, we can stop.  */
601
602   for (i = currindex + 1;
603        VEC_iterate (operand_entry_t, *ops, i, oe)
604        && oe->rank >= curr->rank - 1;
605        i++)
606     {
607       if (oe->op == notop)
608         {
609           if (dump_file && (dump_flags & TDF_DETAILS))
610             {
611               fprintf (dump_file, "Equivalence: ");
612               print_generic_expr (dump_file, notop, 0);
613               if (opcode == BIT_AND_EXPR)
614                 fprintf (dump_file, " & ~");
615               else if (opcode == BIT_IOR_EXPR)
616                 fprintf (dump_file, " | ~");
617               print_generic_expr (dump_file, oe->op, 0);
618               if (opcode == BIT_AND_EXPR)
619                 fprintf (dump_file, " -> 0\n");
620               else if (opcode == BIT_IOR_EXPR)
621                 fprintf (dump_file, " -> -1\n");
622             }
623
624           if (opcode == BIT_AND_EXPR)
625             oe->op = build_zero_cst (TREE_TYPE (oe->op));
626           else if (opcode == BIT_IOR_EXPR)
627             oe->op = build_low_bits_mask (TREE_TYPE (oe->op),
628                                           TYPE_PRECISION (TREE_TYPE (oe->op)));
629
630           reassociate_stats.ops_eliminated
631             += VEC_length (operand_entry_t, *ops) - 1;
632           VEC_free (operand_entry_t, heap, *ops);
633           *ops = NULL;
634           VEC_safe_push (operand_entry_t, heap, *ops, oe);
635           return true;
636         }
637     }
638
639   return false;
640 }
641
642 /* Use constant value that may be present in OPS to try to eliminate
643    operands.  Note that this function is only really used when we've
644    eliminated ops for other reasons, or merged constants.  Across
645    single statements, fold already does all of this, plus more.  There
646    is little point in duplicating logic, so I've only included the
647    identities that I could ever construct testcases to trigger.  */
648
649 static void
650 eliminate_using_constants (enum tree_code opcode,
651                            VEC(operand_entry_t, heap) **ops)
652 {
653   operand_entry_t oelast = VEC_last (operand_entry_t, *ops);
654   tree type = TREE_TYPE (oelast->op);
655
656   if (oelast->rank == 0
657       && (INTEGRAL_TYPE_P (type) || FLOAT_TYPE_P (type)))
658     {
659       switch (opcode)
660         {
661         case BIT_AND_EXPR:
662           if (integer_zerop (oelast->op))
663             {
664               if (VEC_length (operand_entry_t, *ops) != 1)
665                 {
666                   if (dump_file && (dump_flags & TDF_DETAILS))
667                     fprintf (dump_file, "Found & 0, removing all other ops\n");
668
669                   reassociate_stats.ops_eliminated
670                     += VEC_length (operand_entry_t, *ops) - 1;
671
672                   VEC_free (operand_entry_t, heap, *ops);
673                   *ops = NULL;
674                   VEC_safe_push (operand_entry_t, heap, *ops, oelast);
675                   return;
676                 }
677             }
678           else if (integer_all_onesp (oelast->op))
679             {
680               if (VEC_length (operand_entry_t, *ops) != 1)
681                 {
682                   if (dump_file && (dump_flags & TDF_DETAILS))
683                     fprintf (dump_file, "Found & -1, removing\n");
684                   VEC_pop (operand_entry_t, *ops);
685                   reassociate_stats.ops_eliminated++;
686                 }
687             }
688           break;
689         case BIT_IOR_EXPR:
690           if (integer_all_onesp (oelast->op))
691             {
692               if (VEC_length (operand_entry_t, *ops) != 1)
693                 {
694                   if (dump_file && (dump_flags & TDF_DETAILS))
695                     fprintf (dump_file, "Found | -1, removing all other ops\n");
696
697                   reassociate_stats.ops_eliminated
698                     += VEC_length (operand_entry_t, *ops) - 1;
699
700                   VEC_free (operand_entry_t, heap, *ops);
701                   *ops = NULL;
702                   VEC_safe_push (operand_entry_t, heap, *ops, oelast);
703                   return;
704                 }
705             }
706           else if (integer_zerop (oelast->op))
707             {
708               if (VEC_length (operand_entry_t, *ops) != 1)
709                 {
710                   if (dump_file && (dump_flags & TDF_DETAILS))
711                     fprintf (dump_file, "Found | 0, removing\n");
712                   VEC_pop (operand_entry_t, *ops);
713                   reassociate_stats.ops_eliminated++;
714                 }
715             }
716           break;
717         case MULT_EXPR:
718           if (integer_zerop (oelast->op)
719               || (FLOAT_TYPE_P (type)
720                   && !HONOR_NANS (TYPE_MODE (type))
721                   && !HONOR_SIGNED_ZEROS (TYPE_MODE (type))
722                   && real_zerop (oelast->op)))
723             {
724               if (VEC_length (operand_entry_t, *ops) != 1)
725                 {
726                   if (dump_file && (dump_flags & TDF_DETAILS))
727                     fprintf (dump_file, "Found * 0, removing all other ops\n");
728
729                   reassociate_stats.ops_eliminated
730                     += VEC_length (operand_entry_t, *ops) - 1;
731                   VEC_free (operand_entry_t, heap, *ops);
732                   *ops = NULL;
733                   VEC_safe_push (operand_entry_t, heap, *ops, oelast);
734                   return;
735                 }
736             }
737           else if (integer_onep (oelast->op)
738                    || (FLOAT_TYPE_P (type)
739                        && !HONOR_SNANS (TYPE_MODE (type))
740                        && real_onep (oelast->op)))
741             {
742               if (VEC_length (operand_entry_t, *ops) != 1)
743                 {
744                   if (dump_file && (dump_flags & TDF_DETAILS))
745                     fprintf (dump_file, "Found * 1, removing\n");
746                   VEC_pop (operand_entry_t, *ops);
747                   reassociate_stats.ops_eliminated++;
748                   return;
749                 }
750             }
751           break;
752         case BIT_XOR_EXPR:
753         case PLUS_EXPR:
754         case MINUS_EXPR:
755           if (integer_zerop (oelast->op)
756               || (FLOAT_TYPE_P (type)
757                   && (opcode == PLUS_EXPR || opcode == MINUS_EXPR)
758                   && fold_real_zero_addition_p (type, oelast->op,
759                                                 opcode == MINUS_EXPR)))
760             {
761               if (VEC_length (operand_entry_t, *ops) != 1)
762                 {
763                   if (dump_file && (dump_flags & TDF_DETAILS))
764                     fprintf (dump_file, "Found [|^+] 0, removing\n");
765                   VEC_pop (operand_entry_t, *ops);
766                   reassociate_stats.ops_eliminated++;
767                   return;
768                 }
769             }
770           break;
771         default:
772           break;
773         }
774     }
775 }
776
777
778 static void linearize_expr_tree (VEC(operand_entry_t, heap) **, gimple,
779                                  bool, bool);
780
781 /* Structure for tracking and counting operands.  */
782 typedef struct oecount_s {
783   int cnt;
784   int id;
785   enum tree_code oecode;
786   tree op;
787 } oecount;
788
789 DEF_VEC_O(oecount);
790 DEF_VEC_ALLOC_O(oecount,heap);
791
792 /* The heap for the oecount hashtable and the sorted list of operands.  */
793 static VEC (oecount, heap) *cvec;
794
795 /* Hash function for oecount.  */
796
797 static hashval_t
798 oecount_hash (const void *p)
799 {
800   const oecount *c = VEC_index (oecount, cvec, (size_t)p - 42);
801   return htab_hash_pointer (c->op) ^ (hashval_t)c->oecode;
802 }
803
804 /* Comparison function for oecount.  */
805
806 static int
807 oecount_eq (const void *p1, const void *p2)
808 {
809   const oecount *c1 = VEC_index (oecount, cvec, (size_t)p1 - 42);
810   const oecount *c2 = VEC_index (oecount, cvec, (size_t)p2 - 42);
811   return (c1->oecode == c2->oecode
812           && c1->op == c2->op);
813 }
814
815 /* Comparison function for qsort sorting oecount elements by count.  */
816
817 static int
818 oecount_cmp (const void *p1, const void *p2)
819 {
820   const oecount *c1 = (const oecount *)p1;
821   const oecount *c2 = (const oecount *)p2;
822   if (c1->cnt != c2->cnt)
823     return c1->cnt - c2->cnt;
824   else
825     /* If counts are identical, use unique IDs to stabilize qsort.  */
826     return c1->id - c2->id;
827 }
828
829 /* Walks the linear chain with result *DEF searching for an operation
830    with operand OP and code OPCODE removing that from the chain.  *DEF
831    is updated if there is only one operand but no operation left.  */
832
833 static void
834 zero_one_operation (tree *def, enum tree_code opcode, tree op)
835 {
836   gimple stmt = SSA_NAME_DEF_STMT (*def);
837
838   do
839     {
840       tree name = gimple_assign_rhs1 (stmt);
841
842       /* If this is the operation we look for and one of the operands
843          is ours simply propagate the other operand into the stmts
844          single use.  */
845       if (gimple_assign_rhs_code (stmt) == opcode
846           && (name == op
847               || gimple_assign_rhs2 (stmt) == op))
848         {
849           gimple use_stmt;
850           use_operand_p use;
851           gimple_stmt_iterator gsi;
852           if (name == op)
853             name = gimple_assign_rhs2 (stmt);
854           gcc_assert (has_single_use (gimple_assign_lhs (stmt)));
855           single_imm_use (gimple_assign_lhs (stmt), &use, &use_stmt);
856           if (gimple_assign_lhs (stmt) == *def)
857             *def = name;
858           SET_USE (use, name);
859           if (TREE_CODE (name) != SSA_NAME)
860             update_stmt (use_stmt);
861           gsi = gsi_for_stmt (stmt);
862           gsi_remove (&gsi, true);
863           release_defs (stmt);
864           return;
865         }
866
867       /* Continue walking the chain.  */
868       gcc_assert (name != op
869                   && TREE_CODE (name) == SSA_NAME);
870       stmt = SSA_NAME_DEF_STMT (name);
871     }
872   while (1);
873 }
874
875 /* Builds one statement performing OP1 OPCODE OP2 using TMPVAR for
876    the result.  Places the statement after the definition of either
877    OP1 or OP2.  Returns the new statement.  */
878
879 static gimple
880 build_and_add_sum (tree tmpvar, tree op1, tree op2, enum tree_code opcode)
881 {
882   gimple op1def = NULL, op2def = NULL;
883   gimple_stmt_iterator gsi;
884   tree op;
885   gimple sum;
886
887   /* Create the addition statement.  */
888   sum = gimple_build_assign_with_ops (opcode, tmpvar, op1, op2);
889   op = make_ssa_name (tmpvar, sum);
890   gimple_assign_set_lhs (sum, op);
891
892   /* Find an insertion place and insert.  */
893   if (TREE_CODE (op1) == SSA_NAME)
894     op1def = SSA_NAME_DEF_STMT (op1);
895   if (TREE_CODE (op2) == SSA_NAME)
896     op2def = SSA_NAME_DEF_STMT (op2);
897   if ((!op1def || gimple_nop_p (op1def))
898       && (!op2def || gimple_nop_p (op2def)))
899     {
900       gsi = gsi_after_labels (single_succ (ENTRY_BLOCK_PTR));
901       gsi_insert_before (&gsi, sum, GSI_NEW_STMT);
902     }
903   else if ((!op1def || gimple_nop_p (op1def))
904            || (op2def && !gimple_nop_p (op2def)
905                && stmt_dominates_stmt_p (op1def, op2def)))
906     {
907       if (gimple_code (op2def) == GIMPLE_PHI)
908         {
909           gsi = gsi_after_labels (gimple_bb (op2def));
910           gsi_insert_before (&gsi, sum, GSI_NEW_STMT);
911         }
912       else
913         {
914           if (!stmt_ends_bb_p (op2def))
915             {
916               gsi = gsi_for_stmt (op2def);
917               gsi_insert_after (&gsi, sum, GSI_NEW_STMT);
918             }
919           else
920             {
921               edge e;
922               edge_iterator ei;
923
924               FOR_EACH_EDGE (e, ei, gimple_bb (op2def)->succs)
925                 if (e->flags & EDGE_FALLTHRU)
926                   gsi_insert_on_edge_immediate (e, sum);
927             }
928         }
929     }
930   else
931     {
932       if (gimple_code (op1def) == GIMPLE_PHI)
933         {
934           gsi = gsi_after_labels (gimple_bb (op1def));
935           gsi_insert_before (&gsi, sum, GSI_NEW_STMT);
936         }
937       else
938         {
939           if (!stmt_ends_bb_p (op1def))
940             {
941               gsi = gsi_for_stmt (op1def);
942               gsi_insert_after (&gsi, sum, GSI_NEW_STMT);
943             }
944           else
945             {
946               edge e;
947               edge_iterator ei;
948
949               FOR_EACH_EDGE (e, ei, gimple_bb (op1def)->succs)
950                 if (e->flags & EDGE_FALLTHRU)
951                   gsi_insert_on_edge_immediate (e, sum);
952             }
953         }
954     }
955   update_stmt (sum);
956
957   return sum;
958 }
959
960 /* Perform un-distribution of divisions and multiplications.
961    A * X + B * X is transformed into (A + B) * X and A / X + B / X
962    to (A + B) / X for real X.
963
964    The algorithm is organized as follows.
965
966     - First we walk the addition chain *OPS looking for summands that
967       are defined by a multiplication or a real division.  This results
968       in the candidates bitmap with relevant indices into *OPS.
969
970     - Second we build the chains of multiplications or divisions for
971       these candidates, counting the number of occurences of (operand, code)
972       pairs in all of the candidates chains.
973
974     - Third we sort the (operand, code) pairs by number of occurence and
975       process them starting with the pair with the most uses.
976
977       * For each such pair we walk the candidates again to build a
978         second candidate bitmap noting all multiplication/division chains
979         that have at least one occurence of (operand, code).
980
981       * We build an alternate addition chain only covering these
982         candidates with one (operand, code) operation removed from their
983         multiplication/division chain.
984
985       * The first candidate gets replaced by the alternate addition chain
986         multiplied/divided by the operand.
987
988       * All candidate chains get disabled for further processing and
989         processing of (operand, code) pairs continues.
990
991   The alternate addition chains built are re-processed by the main
992   reassociation algorithm which allows optimizing a * x * y + b * y * x
993   to (a + b ) * x * y in one invocation of the reassociation pass.  */
994
995 static bool
996 undistribute_ops_list (enum tree_code opcode,
997                        VEC (operand_entry_t, heap) **ops, struct loop *loop)
998 {
999   unsigned int length = VEC_length (operand_entry_t, *ops);
1000   operand_entry_t oe1;
1001   unsigned i, j;
1002   sbitmap candidates, candidates2;
1003   unsigned nr_candidates, nr_candidates2;
1004   sbitmap_iterator sbi0;
1005   VEC (operand_entry_t, heap) **subops;
1006   htab_t ctable;
1007   bool changed = false;
1008   int next_oecount_id = 0;
1009
1010   if (length <= 1
1011       || opcode != PLUS_EXPR)
1012     return false;
1013
1014   /* Build a list of candidates to process.  */
1015   candidates = sbitmap_alloc (length);
1016   sbitmap_zero (candidates);
1017   nr_candidates = 0;
1018   FOR_EACH_VEC_ELT (operand_entry_t, *ops, i, oe1)
1019     {
1020       enum tree_code dcode;
1021       gimple oe1def;
1022
1023       if (TREE_CODE (oe1->op) != SSA_NAME)
1024         continue;
1025       oe1def = SSA_NAME_DEF_STMT (oe1->op);
1026       if (!is_gimple_assign (oe1def))
1027         continue;
1028       dcode = gimple_assign_rhs_code (oe1def);
1029       if ((dcode != MULT_EXPR
1030            && dcode != RDIV_EXPR)
1031           || !is_reassociable_op (oe1def, dcode, loop))
1032         continue;
1033
1034       SET_BIT (candidates, i);
1035       nr_candidates++;
1036     }
1037
1038   if (nr_candidates < 2)
1039     {
1040       sbitmap_free (candidates);
1041       return false;
1042     }
1043
1044   if (dump_file && (dump_flags & TDF_DETAILS))
1045     {
1046       fprintf (dump_file, "searching for un-distribute opportunities ");
1047       print_generic_expr (dump_file,
1048         VEC_index (operand_entry_t, *ops,
1049                    sbitmap_first_set_bit (candidates))->op, 0);
1050       fprintf (dump_file, " %d\n", nr_candidates);
1051     }
1052
1053   /* Build linearized sub-operand lists and the counting table.  */
1054   cvec = NULL;
1055   ctable = htab_create (15, oecount_hash, oecount_eq, NULL);
1056   subops = XCNEWVEC (VEC (operand_entry_t, heap) *,
1057                      VEC_length (operand_entry_t, *ops));
1058   EXECUTE_IF_SET_IN_SBITMAP (candidates, 0, i, sbi0)
1059     {
1060       gimple oedef;
1061       enum tree_code oecode;
1062       unsigned j;
1063
1064       oedef = SSA_NAME_DEF_STMT (VEC_index (operand_entry_t, *ops, i)->op);
1065       oecode = gimple_assign_rhs_code (oedef);
1066       linearize_expr_tree (&subops[i], oedef,
1067                            associative_tree_code (oecode), false);
1068
1069       FOR_EACH_VEC_ELT (operand_entry_t, subops[i], j, oe1)
1070         {
1071           oecount c;
1072           void **slot;
1073           size_t idx;
1074           c.oecode = oecode;
1075           c.cnt = 1;
1076           c.id = next_oecount_id++;
1077           c.op = oe1->op;
1078           VEC_safe_push (oecount, heap, cvec, &c);
1079           idx = VEC_length (oecount, cvec) + 41;
1080           slot = htab_find_slot (ctable, (void *)idx, INSERT);
1081           if (!*slot)
1082             {
1083               *slot = (void *)idx;
1084             }
1085           else
1086             {
1087               VEC_pop (oecount, cvec);
1088               VEC_index (oecount, cvec, (size_t)*slot - 42)->cnt++;
1089             }
1090         }
1091     }
1092   htab_delete (ctable);
1093
1094   /* Sort the counting table.  */
1095   VEC_qsort (oecount, cvec, oecount_cmp);
1096
1097   if (dump_file && (dump_flags & TDF_DETAILS))
1098     {
1099       oecount *c;
1100       fprintf (dump_file, "Candidates:\n");
1101       FOR_EACH_VEC_ELT (oecount, cvec, j, c)
1102         {
1103           fprintf (dump_file, "  %u %s: ", c->cnt,
1104                    c->oecode == MULT_EXPR
1105                    ? "*" : c->oecode == RDIV_EXPR ? "/" : "?");
1106           print_generic_expr (dump_file, c->op, 0);
1107           fprintf (dump_file, "\n");
1108         }
1109     }
1110
1111   /* Process the (operand, code) pairs in order of most occurence.  */
1112   candidates2 = sbitmap_alloc (length);
1113   while (!VEC_empty (oecount, cvec))
1114     {
1115       oecount *c = VEC_last (oecount, cvec);
1116       if (c->cnt < 2)
1117         break;
1118
1119       /* Now collect the operands in the outer chain that contain
1120          the common operand in their inner chain.  */
1121       sbitmap_zero (candidates2);
1122       nr_candidates2 = 0;
1123       EXECUTE_IF_SET_IN_SBITMAP (candidates, 0, i, sbi0)
1124         {
1125           gimple oedef;
1126           enum tree_code oecode;
1127           unsigned j;
1128           tree op = VEC_index (operand_entry_t, *ops, i)->op;
1129
1130           /* If we undistributed in this chain already this may be
1131              a constant.  */
1132           if (TREE_CODE (op) != SSA_NAME)
1133             continue;
1134
1135           oedef = SSA_NAME_DEF_STMT (op);
1136           oecode = gimple_assign_rhs_code (oedef);
1137           if (oecode != c->oecode)
1138             continue;
1139
1140           FOR_EACH_VEC_ELT (operand_entry_t, subops[i], j, oe1)
1141             {
1142               if (oe1->op == c->op)
1143                 {
1144                   SET_BIT (candidates2, i);
1145                   ++nr_candidates2;
1146                   break;
1147                 }
1148             }
1149         }
1150
1151       if (nr_candidates2 >= 2)
1152         {
1153           operand_entry_t oe1, oe2;
1154           tree tmpvar;
1155           gimple prod;
1156           int first = sbitmap_first_set_bit (candidates2);
1157
1158           /* Build the new addition chain.  */
1159           oe1 = VEC_index (operand_entry_t, *ops, first);
1160           if (dump_file && (dump_flags & TDF_DETAILS))
1161             {
1162               fprintf (dump_file, "Building (");
1163               print_generic_expr (dump_file, oe1->op, 0);
1164             }
1165           tmpvar = create_tmp_reg (TREE_TYPE (oe1->op), NULL);
1166           add_referenced_var (tmpvar);
1167           zero_one_operation (&oe1->op, c->oecode, c->op);
1168           EXECUTE_IF_SET_IN_SBITMAP (candidates2, first+1, i, sbi0)
1169             {
1170               gimple sum;
1171               oe2 = VEC_index (operand_entry_t, *ops, i);
1172               if (dump_file && (dump_flags & TDF_DETAILS))
1173                 {
1174                   fprintf (dump_file, " + ");
1175                   print_generic_expr (dump_file, oe2->op, 0);
1176                 }
1177               zero_one_operation (&oe2->op, c->oecode, c->op);
1178               sum = build_and_add_sum (tmpvar, oe1->op, oe2->op, opcode);
1179               oe2->op = build_zero_cst (TREE_TYPE (oe2->op));
1180               oe2->rank = 0;
1181               oe1->op = gimple_get_lhs (sum);
1182             }
1183
1184           /* Apply the multiplication/division.  */
1185           prod = build_and_add_sum (tmpvar, oe1->op, c->op, c->oecode);
1186           if (dump_file && (dump_flags & TDF_DETAILS))
1187             {
1188               fprintf (dump_file, ") %s ", c->oecode == MULT_EXPR ? "*" : "/");
1189               print_generic_expr (dump_file, c->op, 0);
1190               fprintf (dump_file, "\n");
1191             }
1192
1193           /* Record it in the addition chain and disable further
1194              undistribution with this op.  */
1195           oe1->op = gimple_assign_lhs (prod);
1196           oe1->rank = get_rank (oe1->op);
1197           VEC_free (operand_entry_t, heap, subops[first]);
1198
1199           changed = true;
1200         }
1201
1202       VEC_pop (oecount, cvec);
1203     }
1204
1205   for (i = 0; i < VEC_length (operand_entry_t, *ops); ++i)
1206     VEC_free (operand_entry_t, heap, subops[i]);
1207   free (subops);
1208   VEC_free (oecount, heap, cvec);
1209   sbitmap_free (candidates);
1210   sbitmap_free (candidates2);
1211
1212   return changed;
1213 }
1214
1215 /* If OPCODE is BIT_IOR_EXPR or BIT_AND_EXPR and CURR is a comparison
1216    expression, examine the other OPS to see if any of them are comparisons
1217    of the same values, which we may be able to combine or eliminate.
1218    For example, we can rewrite (a < b) | (a == b) as (a <= b).  */
1219
1220 static bool
1221 eliminate_redundant_comparison (enum tree_code opcode,
1222                                 VEC (operand_entry_t, heap) **ops,
1223                                 unsigned int currindex,
1224                                 operand_entry_t curr)
1225 {
1226   tree op1, op2;
1227   enum tree_code lcode, rcode;
1228   gimple def1, def2;
1229   int i;
1230   operand_entry_t oe;
1231
1232   if (opcode != BIT_IOR_EXPR && opcode != BIT_AND_EXPR)
1233     return false;
1234
1235   /* Check that CURR is a comparison.  */
1236   if (TREE_CODE (curr->op) != SSA_NAME)
1237     return false;
1238   def1 = SSA_NAME_DEF_STMT (curr->op);
1239   if (!is_gimple_assign (def1))
1240     return false;
1241   lcode = gimple_assign_rhs_code (def1);
1242   if (TREE_CODE_CLASS (lcode) != tcc_comparison)
1243     return false;
1244   op1 = gimple_assign_rhs1 (def1);
1245   op2 = gimple_assign_rhs2 (def1);
1246
1247   /* Now look for a similar comparison in the remaining OPS.  */
1248   for (i = currindex + 1;
1249        VEC_iterate (operand_entry_t, *ops, i, oe);
1250        i++)
1251     {
1252       tree t;
1253
1254       if (TREE_CODE (oe->op) != SSA_NAME)
1255         continue;
1256       def2 = SSA_NAME_DEF_STMT (oe->op);
1257       if (!is_gimple_assign (def2))
1258         continue;
1259       rcode = gimple_assign_rhs_code (def2);
1260       if (TREE_CODE_CLASS (rcode) != tcc_comparison)
1261         continue;
1262
1263       /* If we got here, we have a match.  See if we can combine the
1264          two comparisons.  */
1265       if (opcode == BIT_IOR_EXPR)
1266         t = maybe_fold_or_comparisons (lcode, op1, op2,
1267                                        rcode, gimple_assign_rhs1 (def2),
1268                                        gimple_assign_rhs2 (def2));
1269       else
1270         t = maybe_fold_and_comparisons (lcode, op1, op2,
1271                                         rcode, gimple_assign_rhs1 (def2),
1272                                         gimple_assign_rhs2 (def2));
1273       if (!t)
1274         continue;
1275
1276       /* maybe_fold_and_comparisons and maybe_fold_or_comparisons
1277          always give us a boolean_type_node value back.  If the original
1278          BIT_AND_EXPR or BIT_IOR_EXPR was of a wider integer type,
1279          we need to convert.  */
1280       if (!useless_type_conversion_p (TREE_TYPE (curr->op), TREE_TYPE (t)))
1281         t = fold_convert (TREE_TYPE (curr->op), t);
1282
1283       if (TREE_CODE (t) != INTEGER_CST
1284           && !operand_equal_p (t, curr->op, 0))
1285         {
1286           enum tree_code subcode;
1287           tree newop1, newop2;
1288           if (!COMPARISON_CLASS_P (t))
1289             continue;
1290           extract_ops_from_tree (t, &subcode, &newop1, &newop2);
1291           STRIP_USELESS_TYPE_CONVERSION (newop1);
1292           STRIP_USELESS_TYPE_CONVERSION (newop2);
1293           if (!is_gimple_val (newop1) || !is_gimple_val (newop2))
1294             continue;
1295         }
1296
1297       if (dump_file && (dump_flags & TDF_DETAILS))
1298         {
1299           fprintf (dump_file, "Equivalence: ");
1300           print_generic_expr (dump_file, curr->op, 0);
1301           fprintf (dump_file, " %s ", op_symbol_code (opcode));
1302           print_generic_expr (dump_file, oe->op, 0);
1303           fprintf (dump_file, " -> ");
1304           print_generic_expr (dump_file, t, 0);
1305           fprintf (dump_file, "\n");
1306         }
1307
1308       /* Now we can delete oe, as it has been subsumed by the new combined
1309          expression t.  */
1310       VEC_ordered_remove (operand_entry_t, *ops, i);
1311       reassociate_stats.ops_eliminated ++;
1312
1313       /* If t is the same as curr->op, we're done.  Otherwise we must
1314          replace curr->op with t.  Special case is if we got a constant
1315          back, in which case we add it to the end instead of in place of
1316          the current entry.  */
1317       if (TREE_CODE (t) == INTEGER_CST)
1318         {
1319           VEC_ordered_remove (operand_entry_t, *ops, currindex);
1320           add_to_ops_vec (ops, t);
1321         }
1322       else if (!operand_equal_p (t, curr->op, 0))
1323         {
1324           tree tmpvar;
1325           gimple sum;
1326           enum tree_code subcode;
1327           tree newop1;
1328           tree newop2;
1329           gcc_assert (COMPARISON_CLASS_P (t));
1330           tmpvar = create_tmp_var (TREE_TYPE (t), NULL);
1331           add_referenced_var (tmpvar);
1332           extract_ops_from_tree (t, &subcode, &newop1, &newop2);
1333           STRIP_USELESS_TYPE_CONVERSION (newop1);
1334           STRIP_USELESS_TYPE_CONVERSION (newop2);
1335           gcc_checking_assert (is_gimple_val (newop1)
1336                                && is_gimple_val (newop2));
1337           sum = build_and_add_sum (tmpvar, newop1, newop2, subcode);
1338           curr->op = gimple_get_lhs (sum);
1339         }
1340       return true;
1341     }
1342
1343   return false;
1344 }
1345
1346 /* Perform various identities and other optimizations on the list of
1347    operand entries, stored in OPS.  The tree code for the binary
1348    operation between all the operands is OPCODE.  */
1349
1350 static void
1351 optimize_ops_list (enum tree_code opcode,
1352                    VEC (operand_entry_t, heap) **ops)
1353 {
1354   unsigned int length = VEC_length (operand_entry_t, *ops);
1355   unsigned int i;
1356   operand_entry_t oe;
1357   operand_entry_t oelast = NULL;
1358   bool iterate = false;
1359
1360   if (length == 1)
1361     return;
1362
1363   oelast = VEC_last (operand_entry_t, *ops);
1364
1365   /* If the last two are constants, pop the constants off, merge them
1366      and try the next two.  */
1367   if (oelast->rank == 0 && is_gimple_min_invariant (oelast->op))
1368     {
1369       operand_entry_t oelm1 = VEC_index (operand_entry_t, *ops, length - 2);
1370
1371       if (oelm1->rank == 0
1372           && is_gimple_min_invariant (oelm1->op)
1373           && useless_type_conversion_p (TREE_TYPE (oelm1->op),
1374                                        TREE_TYPE (oelast->op)))
1375         {
1376           tree folded = fold_binary (opcode, TREE_TYPE (oelm1->op),
1377                                      oelm1->op, oelast->op);
1378
1379           if (folded && is_gimple_min_invariant (folded))
1380             {
1381               if (dump_file && (dump_flags & TDF_DETAILS))
1382                 fprintf (dump_file, "Merging constants\n");
1383
1384               VEC_pop (operand_entry_t, *ops);
1385               VEC_pop (operand_entry_t, *ops);
1386
1387               add_to_ops_vec (ops, folded);
1388               reassociate_stats.constants_eliminated++;
1389
1390               optimize_ops_list (opcode, ops);
1391               return;
1392             }
1393         }
1394     }
1395
1396   eliminate_using_constants (opcode, ops);
1397   oelast = NULL;
1398
1399   for (i = 0; VEC_iterate (operand_entry_t, *ops, i, oe);)
1400     {
1401       bool done = false;
1402
1403       if (eliminate_not_pairs (opcode, ops, i, oe))
1404         return;
1405       if (eliminate_duplicate_pair (opcode, ops, &done, i, oe, oelast)
1406           || (!done && eliminate_plus_minus_pair (opcode, ops, i, oe))
1407           || (!done && eliminate_redundant_comparison (opcode, ops, i, oe)))
1408         {
1409           if (done)
1410             return;
1411           iterate = true;
1412           oelast = NULL;
1413           continue;
1414         }
1415       oelast = oe;
1416       i++;
1417     }
1418
1419   length  = VEC_length (operand_entry_t, *ops);
1420   oelast = VEC_last (operand_entry_t, *ops);
1421
1422   if (iterate)
1423     optimize_ops_list (opcode, ops);
1424 }
1425
1426 /* Return true if OPERAND is defined by a PHI node which uses the LHS
1427    of STMT in it's operands.  This is also known as a "destructive
1428    update" operation.  */
1429
1430 static bool
1431 is_phi_for_stmt (gimple stmt, tree operand)
1432 {
1433   gimple def_stmt;
1434   tree lhs;
1435   use_operand_p arg_p;
1436   ssa_op_iter i;
1437
1438   if (TREE_CODE (operand) != SSA_NAME)
1439     return false;
1440
1441   lhs = gimple_assign_lhs (stmt);
1442
1443   def_stmt = SSA_NAME_DEF_STMT (operand);
1444   if (gimple_code (def_stmt) != GIMPLE_PHI)
1445     return false;
1446
1447   FOR_EACH_PHI_ARG (arg_p, def_stmt, i, SSA_OP_USE)
1448     if (lhs == USE_FROM_PTR (arg_p))
1449       return true;
1450   return false;
1451 }
1452
1453 /* Remove def stmt of VAR if VAR has zero uses and recurse
1454    on rhs1 operand if so.  */
1455
1456 static void
1457 remove_visited_stmt_chain (tree var)
1458 {
1459   gimple stmt;
1460   gimple_stmt_iterator gsi;
1461
1462   while (1)
1463     {
1464       if (TREE_CODE (var) != SSA_NAME || !has_zero_uses (var))
1465         return;
1466       stmt = SSA_NAME_DEF_STMT (var);
1467       if (!is_gimple_assign (stmt)
1468           || !gimple_visited_p (stmt))
1469         return;
1470       var = gimple_assign_rhs1 (stmt);
1471       gsi = gsi_for_stmt (stmt);
1472       gsi_remove (&gsi, true);
1473       release_defs (stmt);
1474     }
1475 }
1476
1477 /* Recursively rewrite our linearized statements so that the operators
1478    match those in OPS[OPINDEX], putting the computation in rank
1479    order.  */
1480
1481 static void
1482 rewrite_expr_tree (gimple stmt, unsigned int opindex,
1483                    VEC(operand_entry_t, heap) * ops, bool moved)
1484 {
1485   tree rhs1 = gimple_assign_rhs1 (stmt);
1486   tree rhs2 = gimple_assign_rhs2 (stmt);
1487   operand_entry_t oe;
1488
1489   /* If we have three operands left, then we want to make sure the one
1490      that gets the double binary op are the ones with the same rank.
1491
1492      The alternative we try is to see if this is a destructive
1493      update style statement, which is like:
1494      b = phi (a, ...)
1495      a = c + b;
1496      In that case, we want to use the destructive update form to
1497      expose the possible vectorizer sum reduction opportunity.
1498      In that case, the third operand will be the phi node.
1499
1500      We could, of course, try to be better as noted above, and do a
1501      lot of work to try to find these opportunities in >3 operand
1502      cases, but it is unlikely to be worth it.  */
1503   if (opindex + 3 == VEC_length (operand_entry_t, ops))
1504     {
1505       operand_entry_t oe1, oe2, oe3;
1506
1507       oe1 = VEC_index (operand_entry_t, ops, opindex);
1508       oe2 = VEC_index (operand_entry_t, ops, opindex + 1);
1509       oe3 = VEC_index (operand_entry_t, ops, opindex + 2);
1510
1511       if ((oe1->rank == oe2->rank
1512            && oe2->rank != oe3->rank)
1513           || (is_phi_for_stmt (stmt, oe3->op)
1514               && !is_phi_for_stmt (stmt, oe1->op)
1515               && !is_phi_for_stmt (stmt, oe2->op)))
1516         {
1517           struct operand_entry temp = *oe3;
1518           oe3->op = oe1->op;
1519           oe3->rank = oe1->rank;
1520           oe1->op = temp.op;
1521           oe1->rank= temp.rank;
1522         }
1523       else if ((oe1->rank == oe3->rank
1524                 && oe2->rank != oe3->rank)
1525                || (is_phi_for_stmt (stmt, oe2->op)
1526                    && !is_phi_for_stmt (stmt, oe1->op)
1527                    && !is_phi_for_stmt (stmt, oe3->op)))
1528         {
1529           struct operand_entry temp = *oe2;
1530           oe2->op = oe1->op;
1531           oe2->rank = oe1->rank;
1532           oe1->op = temp.op;
1533           oe1->rank= temp.rank;
1534         }
1535     }
1536
1537   /* The final recursion case for this function is that you have
1538      exactly two operations left.
1539      If we had one exactly one op in the entire list to start with, we
1540      would have never called this function, and the tail recursion
1541      rewrites them one at a time.  */
1542   if (opindex + 2 == VEC_length (operand_entry_t, ops))
1543     {
1544       operand_entry_t oe1, oe2;
1545
1546       oe1 = VEC_index (operand_entry_t, ops, opindex);
1547       oe2 = VEC_index (operand_entry_t, ops, opindex + 1);
1548
1549       if (rhs1 != oe1->op || rhs2 != oe2->op)
1550         {
1551           if (dump_file && (dump_flags & TDF_DETAILS))
1552             {
1553               fprintf (dump_file, "Transforming ");
1554               print_gimple_stmt (dump_file, stmt, 0, 0);
1555             }
1556
1557           gimple_assign_set_rhs1 (stmt, oe1->op);
1558           gimple_assign_set_rhs2 (stmt, oe2->op);
1559           update_stmt (stmt);
1560           if (rhs1 != oe1->op && rhs1 != oe2->op)
1561             remove_visited_stmt_chain (rhs1);
1562
1563           if (dump_file && (dump_flags & TDF_DETAILS))
1564             {
1565               fprintf (dump_file, " into ");
1566               print_gimple_stmt (dump_file, stmt, 0, 0);
1567             }
1568
1569         }
1570       return;
1571     }
1572
1573   /* If we hit here, we should have 3 or more ops left.  */
1574   gcc_assert (opindex + 2 < VEC_length (operand_entry_t, ops));
1575
1576   /* Rewrite the next operator.  */
1577   oe = VEC_index (operand_entry_t, ops, opindex);
1578
1579   if (oe->op != rhs2)
1580     {
1581       if (!moved)
1582         {
1583           gimple_stmt_iterator gsinow, gsirhs1;
1584           gimple stmt1 = stmt, stmt2;
1585           unsigned int count;
1586
1587           gsinow = gsi_for_stmt (stmt);
1588           count = VEC_length (operand_entry_t, ops) - opindex - 2;
1589           while (count-- != 0)
1590             {
1591               stmt2 = SSA_NAME_DEF_STMT (gimple_assign_rhs1 (stmt1));
1592               gsirhs1 = gsi_for_stmt (stmt2);
1593               gsi_move_before (&gsirhs1, &gsinow);
1594               gsi_prev (&gsinow);
1595               stmt1 = stmt2;
1596             }
1597           moved = true;
1598         }
1599
1600       if (dump_file && (dump_flags & TDF_DETAILS))
1601         {
1602           fprintf (dump_file, "Transforming ");
1603           print_gimple_stmt (dump_file, stmt, 0, 0);
1604         }
1605
1606       gimple_assign_set_rhs2 (stmt, oe->op);
1607       update_stmt (stmt);
1608
1609       if (dump_file && (dump_flags & TDF_DETAILS))
1610         {
1611           fprintf (dump_file, " into ");
1612           print_gimple_stmt (dump_file, stmt, 0, 0);
1613         }
1614     }
1615   /* Recurse on the LHS of the binary operator, which is guaranteed to
1616      be the non-leaf side.  */
1617   rewrite_expr_tree (SSA_NAME_DEF_STMT (rhs1), opindex + 1, ops, moved);
1618 }
1619
1620 /* Transform STMT, which is really (A +B) + (C + D) into the left
1621    linear form, ((A+B)+C)+D.
1622    Recurse on D if necessary.  */
1623
1624 static void
1625 linearize_expr (gimple stmt)
1626 {
1627   gimple_stmt_iterator gsinow, gsirhs;
1628   gimple binlhs = SSA_NAME_DEF_STMT (gimple_assign_rhs1 (stmt));
1629   gimple binrhs = SSA_NAME_DEF_STMT (gimple_assign_rhs2 (stmt));
1630   enum tree_code rhscode = gimple_assign_rhs_code (stmt);
1631   gimple newbinrhs = NULL;
1632   struct loop *loop = loop_containing_stmt (stmt);
1633
1634   gcc_assert (is_reassociable_op (binlhs, rhscode, loop)
1635               && is_reassociable_op (binrhs, rhscode, loop));
1636
1637   gsinow = gsi_for_stmt (stmt);
1638   gsirhs = gsi_for_stmt (binrhs);
1639   gsi_move_before (&gsirhs, &gsinow);
1640
1641   gimple_assign_set_rhs2 (stmt, gimple_assign_rhs1 (binrhs));
1642   gimple_assign_set_rhs1 (binrhs, gimple_assign_lhs (binlhs));
1643   gimple_assign_set_rhs1 (stmt, gimple_assign_lhs (binrhs));
1644
1645   if (TREE_CODE (gimple_assign_rhs2 (stmt)) == SSA_NAME)
1646     newbinrhs = SSA_NAME_DEF_STMT (gimple_assign_rhs2 (stmt));
1647
1648   if (dump_file && (dump_flags & TDF_DETAILS))
1649     {
1650       fprintf (dump_file, "Linearized: ");
1651       print_gimple_stmt (dump_file, stmt, 0, 0);
1652     }
1653
1654   reassociate_stats.linearized++;
1655   update_stmt (binrhs);
1656   update_stmt (binlhs);
1657   update_stmt (stmt);
1658
1659   gimple_set_visited (stmt, true);
1660   gimple_set_visited (binlhs, true);
1661   gimple_set_visited (binrhs, true);
1662
1663   /* Tail recurse on the new rhs if it still needs reassociation.  */
1664   if (newbinrhs && is_reassociable_op (newbinrhs, rhscode, loop))
1665     /* ??? This should probably be linearize_expr (newbinrhs) but I don't
1666            want to change the algorithm while converting to tuples.  */
1667     linearize_expr (stmt);
1668 }
1669
1670 /* If LHS has a single immediate use that is a GIMPLE_ASSIGN statement, return
1671    it.  Otherwise, return NULL.  */
1672
1673 static gimple
1674 get_single_immediate_use (tree lhs)
1675 {
1676   use_operand_p immuse;
1677   gimple immusestmt;
1678
1679   if (TREE_CODE (lhs) == SSA_NAME
1680       && single_imm_use (lhs, &immuse, &immusestmt)
1681       && is_gimple_assign (immusestmt))
1682     return immusestmt;
1683
1684   return NULL;
1685 }
1686
1687 /* Recursively negate the value of TONEGATE, and return the SSA_NAME
1688    representing the negated value.  Insertions of any necessary
1689    instructions go before GSI.
1690    This function is recursive in that, if you hand it "a_5" as the
1691    value to negate, and a_5 is defined by "a_5 = b_3 + b_4", it will
1692    transform b_3 + b_4 into a_5 = -b_3 + -b_4.  */
1693
1694 static tree
1695 negate_value (tree tonegate, gimple_stmt_iterator *gsi)
1696 {
1697   gimple negatedefstmt= NULL;
1698   tree resultofnegate;
1699
1700   /* If we are trying to negate a name, defined by an add, negate the
1701      add operands instead.  */
1702   if (TREE_CODE (tonegate) == SSA_NAME)
1703     negatedefstmt = SSA_NAME_DEF_STMT (tonegate);
1704   if (TREE_CODE (tonegate) == SSA_NAME
1705       && is_gimple_assign (negatedefstmt)
1706       && TREE_CODE (gimple_assign_lhs (negatedefstmt)) == SSA_NAME
1707       && has_single_use (gimple_assign_lhs (negatedefstmt))
1708       && gimple_assign_rhs_code (negatedefstmt) == PLUS_EXPR)
1709     {
1710       gimple_stmt_iterator gsi;
1711       tree rhs1 = gimple_assign_rhs1 (negatedefstmt);
1712       tree rhs2 = gimple_assign_rhs2 (negatedefstmt);
1713
1714       gsi = gsi_for_stmt (negatedefstmt);
1715       rhs1 = negate_value (rhs1, &gsi);
1716       gimple_assign_set_rhs1 (negatedefstmt, rhs1);
1717
1718       gsi = gsi_for_stmt (negatedefstmt);
1719       rhs2 = negate_value (rhs2, &gsi);
1720       gimple_assign_set_rhs2 (negatedefstmt, rhs2);
1721
1722       update_stmt (negatedefstmt);
1723       return gimple_assign_lhs (negatedefstmt);
1724     }
1725
1726   tonegate = fold_build1 (NEGATE_EXPR, TREE_TYPE (tonegate), tonegate);
1727   resultofnegate = force_gimple_operand_gsi (gsi, tonegate, true,
1728                                              NULL_TREE, true, GSI_SAME_STMT);
1729   return resultofnegate;
1730 }
1731
1732 /* Return true if we should break up the subtract in STMT into an add
1733    with negate.  This is true when we the subtract operands are really
1734    adds, or the subtract itself is used in an add expression.  In
1735    either case, breaking up the subtract into an add with negate
1736    exposes the adds to reassociation.  */
1737
1738 static bool
1739 should_break_up_subtract (gimple stmt)
1740 {
1741   tree lhs = gimple_assign_lhs (stmt);
1742   tree binlhs = gimple_assign_rhs1 (stmt);
1743   tree binrhs = gimple_assign_rhs2 (stmt);
1744   gimple immusestmt;
1745   struct loop *loop = loop_containing_stmt (stmt);
1746
1747   if (TREE_CODE (binlhs) == SSA_NAME
1748       && is_reassociable_op (SSA_NAME_DEF_STMT (binlhs), PLUS_EXPR, loop))
1749     return true;
1750
1751   if (TREE_CODE (binrhs) == SSA_NAME
1752       && is_reassociable_op (SSA_NAME_DEF_STMT (binrhs), PLUS_EXPR, loop))
1753     return true;
1754
1755   if (TREE_CODE (lhs) == SSA_NAME
1756       && (immusestmt = get_single_immediate_use (lhs))
1757       && is_gimple_assign (immusestmt)
1758       && (gimple_assign_rhs_code (immusestmt) == PLUS_EXPR
1759           ||  gimple_assign_rhs_code (immusestmt) == MULT_EXPR))
1760     return true;
1761   return false;
1762 }
1763
1764 /* Transform STMT from A - B into A + -B.  */
1765
1766 static void
1767 break_up_subtract (gimple stmt, gimple_stmt_iterator *gsip)
1768 {
1769   tree rhs1 = gimple_assign_rhs1 (stmt);
1770   tree rhs2 = gimple_assign_rhs2 (stmt);
1771
1772   if (dump_file && (dump_flags & TDF_DETAILS))
1773     {
1774       fprintf (dump_file, "Breaking up subtract ");
1775       print_gimple_stmt (dump_file, stmt, 0, 0);
1776     }
1777
1778   rhs2 = negate_value (rhs2, gsip);
1779   gimple_assign_set_rhs_with_ops (gsip, PLUS_EXPR, rhs1, rhs2);
1780   update_stmt (stmt);
1781 }
1782
1783 /* Recursively linearize a binary expression that is the RHS of STMT.
1784    Place the operands of the expression tree in the vector named OPS.  */
1785
1786 static void
1787 linearize_expr_tree (VEC(operand_entry_t, heap) **ops, gimple stmt,
1788                      bool is_associative, bool set_visited)
1789 {
1790   tree binlhs = gimple_assign_rhs1 (stmt);
1791   tree binrhs = gimple_assign_rhs2 (stmt);
1792   gimple binlhsdef, binrhsdef;
1793   bool binlhsisreassoc = false;
1794   bool binrhsisreassoc = false;
1795   enum tree_code rhscode = gimple_assign_rhs_code (stmt);
1796   struct loop *loop = loop_containing_stmt (stmt);
1797
1798   if (set_visited)
1799     gimple_set_visited (stmt, true);
1800
1801   if (TREE_CODE (binlhs) == SSA_NAME)
1802     {
1803       binlhsdef = SSA_NAME_DEF_STMT (binlhs);
1804       binlhsisreassoc = (is_reassociable_op (binlhsdef, rhscode, loop)
1805                          && !stmt_could_throw_p (binlhsdef));
1806     }
1807
1808   if (TREE_CODE (binrhs) == SSA_NAME)
1809     {
1810       binrhsdef = SSA_NAME_DEF_STMT (binrhs);
1811       binrhsisreassoc = (is_reassociable_op (binrhsdef, rhscode, loop)
1812                          && !stmt_could_throw_p (binrhsdef));
1813     }
1814
1815   /* If the LHS is not reassociable, but the RHS is, we need to swap
1816      them.  If neither is reassociable, there is nothing we can do, so
1817      just put them in the ops vector.  If the LHS is reassociable,
1818      linearize it.  If both are reassociable, then linearize the RHS
1819      and the LHS.  */
1820
1821   if (!binlhsisreassoc)
1822     {
1823       tree temp;
1824
1825       /* If this is not a associative operation like division, give up.  */
1826       if (!is_associative)
1827         {
1828           add_to_ops_vec (ops, binrhs);
1829           return;
1830         }
1831
1832       if (!binrhsisreassoc)
1833         {
1834           add_to_ops_vec (ops, binrhs);
1835           add_to_ops_vec (ops, binlhs);
1836           return;
1837         }
1838
1839       if (dump_file && (dump_flags & TDF_DETAILS))
1840         {
1841           fprintf (dump_file, "swapping operands of ");
1842           print_gimple_stmt (dump_file, stmt, 0, 0);
1843         }
1844
1845       swap_tree_operands (stmt,
1846                           gimple_assign_rhs1_ptr (stmt),
1847                           gimple_assign_rhs2_ptr (stmt));
1848       update_stmt (stmt);
1849
1850       if (dump_file && (dump_flags & TDF_DETAILS))
1851         {
1852           fprintf (dump_file, " is now ");
1853           print_gimple_stmt (dump_file, stmt, 0, 0);
1854         }
1855
1856       /* We want to make it so the lhs is always the reassociative op,
1857          so swap.  */
1858       temp = binlhs;
1859       binlhs = binrhs;
1860       binrhs = temp;
1861     }
1862   else if (binrhsisreassoc)
1863     {
1864       linearize_expr (stmt);
1865       binlhs = gimple_assign_rhs1 (stmt);
1866       binrhs = gimple_assign_rhs2 (stmt);
1867     }
1868
1869   gcc_assert (TREE_CODE (binrhs) != SSA_NAME
1870               || !is_reassociable_op (SSA_NAME_DEF_STMT (binrhs),
1871                                       rhscode, loop));
1872   linearize_expr_tree (ops, SSA_NAME_DEF_STMT (binlhs),
1873                        is_associative, set_visited);
1874   add_to_ops_vec (ops, binrhs);
1875 }
1876
1877 /* Repropagate the negates back into subtracts, since no other pass
1878    currently does it.  */
1879
1880 static void
1881 repropagate_negates (void)
1882 {
1883   unsigned int i = 0;
1884   tree negate;
1885
1886   FOR_EACH_VEC_ELT (tree, plus_negates, i, negate)
1887     {
1888       gimple user = get_single_immediate_use (negate);
1889
1890       if (!user || !is_gimple_assign (user))
1891         continue;
1892
1893       /* The negate operand can be either operand of a PLUS_EXPR
1894          (it can be the LHS if the RHS is a constant for example).
1895
1896          Force the negate operand to the RHS of the PLUS_EXPR, then
1897          transform the PLUS_EXPR into a MINUS_EXPR.  */
1898       if (gimple_assign_rhs_code (user) == PLUS_EXPR)
1899         {
1900           /* If the negated operand appears on the LHS of the
1901              PLUS_EXPR, exchange the operands of the PLUS_EXPR
1902              to force the negated operand to the RHS of the PLUS_EXPR.  */
1903           if (gimple_assign_rhs1 (user) == negate)
1904             {
1905               swap_tree_operands (user,
1906                                   gimple_assign_rhs1_ptr (user),
1907                                   gimple_assign_rhs2_ptr (user));
1908             }
1909
1910           /* Now transform the PLUS_EXPR into a MINUS_EXPR and replace
1911              the RHS of the PLUS_EXPR with the operand of the NEGATE_EXPR.  */
1912           if (gimple_assign_rhs2 (user) == negate)
1913             {
1914               tree rhs1 = gimple_assign_rhs1 (user);
1915               tree rhs2 = get_unary_op (negate, NEGATE_EXPR);
1916               gimple_stmt_iterator gsi = gsi_for_stmt (user);
1917               gimple_assign_set_rhs_with_ops (&gsi, MINUS_EXPR, rhs1, rhs2);
1918               update_stmt (user);
1919             }
1920         }
1921       else if (gimple_assign_rhs_code (user) == MINUS_EXPR)
1922         {
1923           if (gimple_assign_rhs1 (user) == negate)
1924             {
1925               /* We have
1926                    x = -a
1927                    y = x - b
1928                  which we transform into
1929                    x = a + b
1930                    y = -x .
1931                  This pushes down the negate which we possibly can merge
1932                  into some other operation, hence insert it into the
1933                  plus_negates vector.  */
1934               gimple feed = SSA_NAME_DEF_STMT (negate);
1935               tree a = gimple_assign_rhs1 (feed);
1936               tree rhs2 = gimple_assign_rhs2 (user);
1937               gimple_stmt_iterator gsi = gsi_for_stmt (feed), gsi2;
1938               gimple_replace_lhs (feed, negate);
1939               gimple_assign_set_rhs_with_ops (&gsi, PLUS_EXPR, a, rhs2);
1940               update_stmt (gsi_stmt (gsi));
1941               gsi2 = gsi_for_stmt (user);
1942               gimple_assign_set_rhs_with_ops (&gsi2, NEGATE_EXPR, negate, NULL);
1943               update_stmt (gsi_stmt (gsi2));
1944               gsi_move_before (&gsi, &gsi2);
1945               VEC_safe_push (tree, heap, plus_negates,
1946                              gimple_assign_lhs (gsi_stmt (gsi2)));
1947             }
1948           else
1949             {
1950               /* Transform "x = -a; y = b - x" into "y = b + a", getting
1951                  rid of one operation.  */
1952               gimple feed = SSA_NAME_DEF_STMT (negate);
1953               tree a = gimple_assign_rhs1 (feed);
1954               tree rhs1 = gimple_assign_rhs1 (user);
1955               gimple_stmt_iterator gsi = gsi_for_stmt (user);
1956               gimple_assign_set_rhs_with_ops (&gsi, PLUS_EXPR, rhs1, a);
1957               update_stmt (gsi_stmt (gsi));
1958             }
1959         }
1960     }
1961 }
1962
1963 /* Returns true if OP is of a type for which we can do reassociation.
1964    That is for integral or non-saturating fixed-point types, and for
1965    floating point type when associative-math is enabled.  */
1966
1967 static bool
1968 can_reassociate_p (tree op)
1969 {
1970   tree type = TREE_TYPE (op);
1971   if ((INTEGRAL_TYPE_P (type) && TYPE_OVERFLOW_WRAPS (type))
1972       || NON_SAT_FIXED_POINT_TYPE_P (type)
1973       || (flag_associative_math && FLOAT_TYPE_P (type)))
1974     return true;
1975   return false;
1976 }
1977
1978 /* Break up subtract operations in block BB.
1979
1980    We do this top down because we don't know whether the subtract is
1981    part of a possible chain of reassociation except at the top.
1982
1983    IE given
1984    d = f + g
1985    c = a + e
1986    b = c - d
1987    q = b - r
1988    k = t - q
1989
1990    we want to break up k = t - q, but we won't until we've transformed q
1991    = b - r, which won't be broken up until we transform b = c - d.
1992
1993    En passant, clear the GIMPLE visited flag on every statement.  */
1994
1995 static void
1996 break_up_subtract_bb (basic_block bb)
1997 {
1998   gimple_stmt_iterator gsi;
1999   basic_block son;
2000
2001   for (gsi = gsi_start_bb (bb); !gsi_end_p (gsi); gsi_next (&gsi))
2002     {
2003       gimple stmt = gsi_stmt (gsi);
2004       gimple_set_visited (stmt, false);
2005
2006       if (!is_gimple_assign (stmt)
2007           || !can_reassociate_p (gimple_assign_lhs (stmt)))
2008         continue;
2009
2010       /* Look for simple gimple subtract operations.  */
2011       if (gimple_assign_rhs_code (stmt) == MINUS_EXPR)
2012         {
2013           if (!can_reassociate_p (gimple_assign_rhs1 (stmt))
2014               || !can_reassociate_p (gimple_assign_rhs2 (stmt)))
2015             continue;
2016
2017           /* Check for a subtract used only in an addition.  If this
2018              is the case, transform it into add of a negate for better
2019              reassociation.  IE transform C = A-B into C = A + -B if C
2020              is only used in an addition.  */
2021           if (should_break_up_subtract (stmt))
2022             break_up_subtract (stmt, &gsi);
2023         }
2024       else if (gimple_assign_rhs_code (stmt) == NEGATE_EXPR
2025                && can_reassociate_p (gimple_assign_rhs1 (stmt)))
2026         VEC_safe_push (tree, heap, plus_negates, gimple_assign_lhs (stmt));
2027     }
2028   for (son = first_dom_son (CDI_DOMINATORS, bb);
2029        son;
2030        son = next_dom_son (CDI_DOMINATORS, son))
2031     break_up_subtract_bb (son);
2032 }
2033
2034 /* Reassociate expressions in basic block BB and its post-dominator as
2035    children.  */
2036
2037 static void
2038 reassociate_bb (basic_block bb)
2039 {
2040   gimple_stmt_iterator gsi;
2041   basic_block son;
2042
2043   for (gsi = gsi_last_bb (bb); !gsi_end_p (gsi); gsi_prev (&gsi))
2044     {
2045       gimple stmt = gsi_stmt (gsi);
2046
2047       if (is_gimple_assign (stmt)
2048           && !stmt_could_throw_p (stmt))
2049         {
2050           tree lhs, rhs1, rhs2;
2051           enum tree_code rhs_code = gimple_assign_rhs_code (stmt);
2052
2053           /* If this is not a gimple binary expression, there is
2054              nothing for us to do with it.  */
2055           if (get_gimple_rhs_class (rhs_code) != GIMPLE_BINARY_RHS)
2056             continue;
2057
2058           /* If this was part of an already processed statement,
2059              we don't need to touch it again. */
2060           if (gimple_visited_p (stmt))
2061             {
2062               /* This statement might have become dead because of previous
2063                  reassociations.  */
2064               if (has_zero_uses (gimple_get_lhs (stmt)))
2065                 {
2066                   gsi_remove (&gsi, true);
2067                   release_defs (stmt);
2068                   /* We might end up removing the last stmt above which
2069                      places the iterator to the end of the sequence.
2070                      Reset it to the last stmt in this case which might
2071                      be the end of the sequence as well if we removed
2072                      the last statement of the sequence.  In which case
2073                      we need to bail out.  */
2074                   if (gsi_end_p (gsi))
2075                     {
2076                       gsi = gsi_last_bb (bb);
2077                       if (gsi_end_p (gsi))
2078                         break;
2079                     }
2080                 }
2081               continue;
2082             }
2083
2084           lhs = gimple_assign_lhs (stmt);
2085           rhs1 = gimple_assign_rhs1 (stmt);
2086           rhs2 = gimple_assign_rhs2 (stmt);
2087
2088           /* For non-bit or min/max operations we can't associate
2089              all types.  Verify that here.  */
2090           if (rhs_code != BIT_IOR_EXPR
2091               && rhs_code != BIT_AND_EXPR
2092               && rhs_code != BIT_XOR_EXPR
2093               && rhs_code != MIN_EXPR
2094               && rhs_code != MAX_EXPR
2095               && (!can_reassociate_p (lhs)
2096                   || !can_reassociate_p (rhs1)
2097                   || !can_reassociate_p (rhs2)))
2098             continue;
2099
2100           if (associative_tree_code (rhs_code))
2101             {
2102               VEC(operand_entry_t, heap) *ops = NULL;
2103
2104               /* There may be no immediate uses left by the time we
2105                  get here because we may have eliminated them all.  */
2106               if (TREE_CODE (lhs) == SSA_NAME && has_zero_uses (lhs))
2107                 continue;
2108
2109               gimple_set_visited (stmt, true);
2110               linearize_expr_tree (&ops, stmt, true, true);
2111               VEC_qsort (operand_entry_t, ops, sort_by_operand_rank);
2112               optimize_ops_list (rhs_code, &ops);
2113               if (undistribute_ops_list (rhs_code, &ops,
2114                                          loop_containing_stmt (stmt)))
2115                 {
2116                   VEC_qsort (operand_entry_t, ops, sort_by_operand_rank);
2117                   optimize_ops_list (rhs_code, &ops);
2118                 }
2119
2120               if (VEC_length (operand_entry_t, ops) == 1)
2121                 {
2122                   if (dump_file && (dump_flags & TDF_DETAILS))
2123                     {
2124                       fprintf (dump_file, "Transforming ");
2125                       print_gimple_stmt (dump_file, stmt, 0, 0);
2126                     }
2127
2128                   rhs1 = gimple_assign_rhs1 (stmt);
2129                   gimple_assign_set_rhs_from_tree (&gsi,
2130                                                    VEC_last (operand_entry_t,
2131                                                              ops)->op);
2132                   update_stmt (stmt);
2133                   remove_visited_stmt_chain (rhs1);
2134
2135                   if (dump_file && (dump_flags & TDF_DETAILS))
2136                     {
2137                       fprintf (dump_file, " into ");
2138                       print_gimple_stmt (dump_file, stmt, 0, 0);
2139                     }
2140                 }
2141               else
2142                 rewrite_expr_tree (stmt, 0, ops, false);
2143
2144               VEC_free (operand_entry_t, heap, ops);
2145             }
2146         }
2147     }
2148   for (son = first_dom_son (CDI_POST_DOMINATORS, bb);
2149        son;
2150        son = next_dom_son (CDI_POST_DOMINATORS, son))
2151     reassociate_bb (son);
2152 }
2153
2154 void dump_ops_vector (FILE *file, VEC (operand_entry_t, heap) *ops);
2155 void debug_ops_vector (VEC (operand_entry_t, heap) *ops);
2156
2157 /* Dump the operand entry vector OPS to FILE.  */
2158
2159 void
2160 dump_ops_vector (FILE *file, VEC (operand_entry_t, heap) *ops)
2161 {
2162   operand_entry_t oe;
2163   unsigned int i;
2164
2165   FOR_EACH_VEC_ELT (operand_entry_t, ops, i, oe)
2166     {
2167       fprintf (file, "Op %d -> rank: %d, tree: ", i, oe->rank);
2168       print_generic_expr (file, oe->op, 0);
2169     }
2170 }
2171
2172 /* Dump the operand entry vector OPS to STDERR.  */
2173
2174 DEBUG_FUNCTION void
2175 debug_ops_vector (VEC (operand_entry_t, heap) *ops)
2176 {
2177   dump_ops_vector (stderr, ops);
2178 }
2179
2180 static void
2181 do_reassoc (void)
2182 {
2183   break_up_subtract_bb (ENTRY_BLOCK_PTR);
2184   reassociate_bb (EXIT_BLOCK_PTR);
2185 }
2186
2187 /* Initialize the reassociation pass.  */
2188
2189 static void
2190 init_reassoc (void)
2191 {
2192   int i;
2193   long rank = 2;
2194   tree param;
2195   int *bbs = XNEWVEC (int, last_basic_block + 1);
2196
2197   /* Find the loops, so that we can prevent moving calculations in
2198      them.  */
2199   loop_optimizer_init (AVOID_CFG_MODIFICATIONS);
2200
2201   memset (&reassociate_stats, 0, sizeof (reassociate_stats));
2202
2203   operand_entry_pool = create_alloc_pool ("operand entry pool",
2204                                           sizeof (struct operand_entry), 30);
2205   next_operand_entry_id = 0;
2206
2207   /* Reverse RPO (Reverse Post Order) will give us something where
2208      deeper loops come later.  */
2209   pre_and_rev_post_order_compute (NULL, bbs, false);
2210   bb_rank = XCNEWVEC (long, last_basic_block + 1);
2211   operand_rank = pointer_map_create ();
2212
2213   /* Give each argument a distinct rank.   */
2214   for (param = DECL_ARGUMENTS (current_function_decl);
2215        param;
2216        param = DECL_CHAIN (param))
2217     {
2218       if (gimple_default_def (cfun, param) != NULL)
2219         {
2220           tree def = gimple_default_def (cfun, param);
2221           insert_operand_rank (def, ++rank);
2222         }
2223     }
2224
2225   /* Give the chain decl a distinct rank. */
2226   if (cfun->static_chain_decl != NULL)
2227     {
2228       tree def = gimple_default_def (cfun, cfun->static_chain_decl);
2229       if (def != NULL)
2230         insert_operand_rank (def, ++rank);
2231     }
2232
2233   /* Set up rank for each BB  */
2234   for (i = 0; i < n_basic_blocks - NUM_FIXED_BLOCKS; i++)
2235     bb_rank[bbs[i]] = ++rank  << 16;
2236
2237   free (bbs);
2238   calculate_dominance_info (CDI_POST_DOMINATORS);
2239   plus_negates = NULL;
2240 }
2241
2242 /* Cleanup after the reassociation pass, and print stats if
2243    requested.  */
2244
2245 static void
2246 fini_reassoc (void)
2247 {
2248   statistics_counter_event (cfun, "Linearized",
2249                             reassociate_stats.linearized);
2250   statistics_counter_event (cfun, "Constants eliminated",
2251                             reassociate_stats.constants_eliminated);
2252   statistics_counter_event (cfun, "Ops eliminated",
2253                             reassociate_stats.ops_eliminated);
2254   statistics_counter_event (cfun, "Statements rewritten",
2255                             reassociate_stats.rewritten);
2256
2257   pointer_map_destroy (operand_rank);
2258   free_alloc_pool (operand_entry_pool);
2259   free (bb_rank);
2260   VEC_free (tree, heap, plus_negates);
2261   free_dominance_info (CDI_POST_DOMINATORS);
2262   loop_optimizer_finalize ();
2263 }
2264
2265 /* Gate and execute functions for Reassociation.  */
2266
2267 static unsigned int
2268 execute_reassoc (void)
2269 {
2270   init_reassoc ();
2271
2272   do_reassoc ();
2273   repropagate_negates ();
2274
2275   fini_reassoc ();
2276   return 0;
2277 }
2278
2279 static bool
2280 gate_tree_ssa_reassoc (void)
2281 {
2282   return flag_tree_reassoc != 0;
2283 }
2284
2285 struct gimple_opt_pass pass_reassoc =
2286 {
2287  {
2288   GIMPLE_PASS,
2289   "reassoc",                            /* name */
2290   gate_tree_ssa_reassoc,                /* gate */
2291   execute_reassoc,                      /* execute */
2292   NULL,                                 /* sub */
2293   NULL,                                 /* next */
2294   0,                                    /* static_pass_number */
2295   TV_TREE_REASSOC,                      /* tv_id */
2296   PROP_cfg | PROP_ssa,                  /* properties_required */
2297   0,                                    /* properties_provided */
2298   0,                                    /* properties_destroyed */
2299   0,                                    /* todo_flags_start */
2300   TODO_verify_ssa
2301     | TODO_verify_flow
2302     | TODO_dump_func
2303     | TODO_ggc_collect                  /* todo_flags_finish */
2304  }
2305 };
2306