OSDN Git Service

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