OSDN Git Service

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