OSDN Git Service

* haifa-sched.c (extend_global): Split to extend_global_data and
[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 /* Perform various identities and other optimizations on the list of
731    operand entries, stored in OPS.  The tree code for the binary
732    operation between all the operands is OPCODE.  */
733
734 static void
735 optimize_ops_list (enum tree_code opcode,
736                    VEC (operand_entry_t, heap) **ops)
737 {
738   unsigned int length = VEC_length (operand_entry_t, *ops);
739   unsigned int i;
740   operand_entry_t oe;
741   operand_entry_t oelast = NULL;
742   bool iterate = false;
743
744   if (length == 1)
745     return;
746
747   oelast = VEC_last (operand_entry_t, *ops);
748
749   /* If the last two are constants, pop the constants off, merge them
750      and try the next two.  */
751   if (oelast->rank == 0 && is_gimple_min_invariant (oelast->op))
752     {
753       operand_entry_t oelm1 = VEC_index (operand_entry_t, *ops, length - 2);
754
755       if (oelm1->rank == 0
756           && is_gimple_min_invariant (oelm1->op)
757           && useless_type_conversion_p (TREE_TYPE (oelm1->op),
758                                        TREE_TYPE (oelast->op)))
759         {
760           tree folded = fold_binary (opcode, TREE_TYPE (oelm1->op),
761                                      oelm1->op, oelast->op);
762
763           if (folded && is_gimple_min_invariant (folded))
764             {
765               if (dump_file && (dump_flags & TDF_DETAILS))
766                 fprintf (dump_file, "Merging constants\n");
767
768               VEC_pop (operand_entry_t, *ops);
769               VEC_pop (operand_entry_t, *ops);
770
771               add_to_ops_vec (ops, folded);
772               reassociate_stats.constants_eliminated++;
773
774               optimize_ops_list (opcode, ops);
775               return;
776             }
777         }
778     }
779
780   eliminate_using_constants (opcode, ops);
781   oelast = NULL;
782
783   for (i = 0; VEC_iterate (operand_entry_t, *ops, i, oe);)
784     {
785       bool done = false;
786
787       if (eliminate_not_pairs (opcode, ops, i, oe))
788         return;
789       if (eliminate_duplicate_pair (opcode, ops, &done, i, oe, oelast)
790           || (!done && eliminate_plus_minus_pair (opcode, ops, i, oe)))
791         {
792           if (done)
793             return;
794           iterate = true;
795           oelast = NULL;
796           continue;
797         }
798       oelast = oe;
799       i++;
800     }
801
802   length  = VEC_length (operand_entry_t, *ops);
803   oelast = VEC_last (operand_entry_t, *ops);
804
805   if (iterate)
806     optimize_ops_list (opcode, ops);
807 }
808
809 /* Return true if OPERAND is defined by a PHI node which uses the LHS
810    of STMT in it's operands.  This is also known as a "destructive
811    update" operation.  */
812
813 static bool
814 is_phi_for_stmt (gimple stmt, tree operand)
815 {
816   gimple def_stmt;
817   tree lhs;
818   use_operand_p arg_p;
819   ssa_op_iter i;
820
821   if (TREE_CODE (operand) != SSA_NAME)
822     return false;
823
824   lhs = gimple_assign_lhs (stmt);
825
826   def_stmt = SSA_NAME_DEF_STMT (operand);
827   if (gimple_code (def_stmt) != GIMPLE_PHI)
828     return false;
829
830   FOR_EACH_PHI_ARG (arg_p, def_stmt, i, SSA_OP_USE)
831     if (lhs == USE_FROM_PTR (arg_p))
832       return true;
833   return false;
834 }
835
836 /* Recursively rewrite our linearized statements so that the operators
837    match those in OPS[OPINDEX], putting the computation in rank
838    order.  */
839
840 static void
841 rewrite_expr_tree (gimple stmt, unsigned int opindex,
842                    VEC(operand_entry_t, heap) * ops)
843 {
844   tree rhs1 = gimple_assign_rhs1 (stmt);
845   tree rhs2 = gimple_assign_rhs2 (stmt);
846   operand_entry_t oe;
847
848   /* If we have three operands left, then we want to make sure the one
849      that gets the double binary op are the ones with the same rank.
850
851      The alternative we try is to see if this is a destructive
852      update style statement, which is like:
853      b = phi (a, ...)
854      a = c + b;
855      In that case, we want to use the destructive update form to
856      expose the possible vectorizer sum reduction opportunity.
857      In that case, the third operand will be the phi node.
858
859      We could, of course, try to be better as noted above, and do a
860      lot of work to try to find these opportunities in >3 operand
861      cases, but it is unlikely to be worth it.  */
862   if (opindex + 3 == VEC_length (operand_entry_t, ops))
863     {
864       operand_entry_t oe1, oe2, oe3;
865
866       oe1 = VEC_index (operand_entry_t, ops, opindex);
867       oe2 = VEC_index (operand_entry_t, ops, opindex + 1);
868       oe3 = VEC_index (operand_entry_t, ops, opindex + 2);
869
870       if ((oe1->rank == oe2->rank
871            && oe2->rank != oe3->rank)
872           || (is_phi_for_stmt (stmt, oe3->op)
873               && !is_phi_for_stmt (stmt, oe1->op)
874               && !is_phi_for_stmt (stmt, oe2->op)))
875         {
876           struct operand_entry temp = *oe3;
877           oe3->op = oe1->op;
878           oe3->rank = oe1->rank;
879           oe1->op = temp.op;
880           oe1->rank= temp.rank;
881         }
882       else if ((oe1->rank == oe3->rank
883                 && oe2->rank != oe3->rank)
884                || (is_phi_for_stmt (stmt, oe2->op)
885                    && !is_phi_for_stmt (stmt, oe1->op)
886                    && !is_phi_for_stmt (stmt, oe3->op)))
887         {
888           struct operand_entry temp = *oe2;
889           oe2->op = oe1->op;
890           oe2->rank = oe1->rank;
891           oe1->op = temp.op;
892           oe1->rank= temp.rank;
893         }
894     }
895
896   /* The final recursion case for this function is that you have
897      exactly two operations left.
898      If we had one exactly one op in the entire list to start with, we
899      would have never called this function, and the tail recursion
900      rewrites them one at a time.  */
901   if (opindex + 2 == VEC_length (operand_entry_t, ops))
902     {
903       operand_entry_t oe1, oe2;
904
905       oe1 = VEC_index (operand_entry_t, ops, opindex);
906       oe2 = VEC_index (operand_entry_t, ops, opindex + 1);
907
908       if (rhs1 != oe1->op || rhs2 != oe2->op)
909         {
910           if (dump_file && (dump_flags & TDF_DETAILS))
911             {
912               fprintf (dump_file, "Transforming ");
913               print_gimple_stmt (dump_file, stmt, 0, 0);
914             }
915
916           gimple_assign_set_rhs1 (stmt, oe1->op);
917           gimple_assign_set_rhs2 (stmt, oe2->op);
918           update_stmt (stmt);
919
920           if (dump_file && (dump_flags & TDF_DETAILS))
921             {
922               fprintf (dump_file, " into ");
923               print_gimple_stmt (dump_file, stmt, 0, 0);
924             }
925
926         }
927       return;
928     }
929
930   /* If we hit here, we should have 3 or more ops left.  */
931   gcc_assert (opindex + 2 < VEC_length (operand_entry_t, ops));
932
933   /* Rewrite the next operator.  */
934   oe = VEC_index (operand_entry_t, ops, opindex);
935
936   if (oe->op != rhs2)
937     {
938
939       if (dump_file && (dump_flags & TDF_DETAILS))
940         {
941           fprintf (dump_file, "Transforming ");
942           print_gimple_stmt (dump_file, stmt, 0, 0);
943         }
944
945       gimple_assign_set_rhs2 (stmt, oe->op);
946       update_stmt (stmt);
947
948       if (dump_file && (dump_flags & TDF_DETAILS))
949         {
950           fprintf (dump_file, " into ");
951           print_gimple_stmt (dump_file, stmt, 0, 0);
952         }
953     }
954   /* Recurse on the LHS of the binary operator, which is guaranteed to
955      be the non-leaf side.  */
956   rewrite_expr_tree (SSA_NAME_DEF_STMT (rhs1), opindex + 1, ops);
957 }
958
959 /* Transform STMT, which is really (A +B) + (C + D) into the left
960    linear form, ((A+B)+C)+D.
961    Recurse on D if necessary.  */
962
963 static void
964 linearize_expr (gimple stmt)
965 {
966   gimple_stmt_iterator gsinow, gsirhs;
967   gimple binlhs = SSA_NAME_DEF_STMT (gimple_assign_rhs1 (stmt));
968   gimple binrhs = SSA_NAME_DEF_STMT (gimple_assign_rhs2 (stmt));
969   enum tree_code rhscode = gimple_assign_rhs_code (stmt);
970   gimple newbinrhs = NULL;
971   struct loop *loop = loop_containing_stmt (stmt);
972
973   gcc_assert (is_reassociable_op (binlhs, rhscode, loop)
974               && is_reassociable_op (binrhs, rhscode, loop));
975
976   gsinow = gsi_for_stmt (stmt);
977   gsirhs = gsi_for_stmt (binrhs);
978   gsi_move_before (&gsirhs, &gsinow);
979
980   gimple_assign_set_rhs2 (stmt, gimple_assign_rhs1 (binrhs));
981   gimple_assign_set_rhs1 (binrhs, gimple_assign_lhs (binlhs));
982   gimple_assign_set_rhs1 (stmt, gimple_assign_lhs (binrhs));
983
984   if (TREE_CODE (gimple_assign_rhs2 (stmt)) == SSA_NAME)
985     newbinrhs = SSA_NAME_DEF_STMT (gimple_assign_rhs2 (stmt));
986
987   if (dump_file && (dump_flags & TDF_DETAILS))
988     {
989       fprintf (dump_file, "Linearized: ");
990       print_gimple_stmt (dump_file, stmt, 0, 0);
991     }
992
993   reassociate_stats.linearized++;
994   update_stmt (binrhs);
995   update_stmt (binlhs);
996   update_stmt (stmt);
997
998   gimple_set_visited (stmt, true);
999   gimple_set_visited (binlhs, true);
1000   gimple_set_visited (binrhs, true);
1001
1002   /* Tail recurse on the new rhs if it still needs reassociation.  */
1003   if (newbinrhs && is_reassociable_op (newbinrhs, rhscode, loop))
1004     /* ??? This should probably be linearize_expr (newbinrhs) but I don't
1005            want to change the algorithm while converting to tuples.  */
1006     linearize_expr (stmt);
1007 }
1008
1009 /* If LHS has a single immediate use that is a GIMPLE_ASSIGN statement, return
1010    it.  Otherwise, return NULL.  */
1011
1012 static gimple
1013 get_single_immediate_use (tree lhs)
1014 {
1015   use_operand_p immuse;
1016   gimple immusestmt;
1017
1018   if (TREE_CODE (lhs) == SSA_NAME
1019       && single_imm_use (lhs, &immuse, &immusestmt)
1020       && is_gimple_assign (immusestmt))
1021     return immusestmt;
1022
1023   return NULL;
1024 }
1025
1026 static VEC(tree, heap) *broken_up_subtracts;
1027
1028 /* Recursively negate the value of TONEGATE, and return the SSA_NAME
1029    representing the negated value.  Insertions of any necessary
1030    instructions go before GSI.
1031    This function is recursive in that, if you hand it "a_5" as the
1032    value to negate, and a_5 is defined by "a_5 = b_3 + b_4", it will
1033    transform b_3 + b_4 into a_5 = -b_3 + -b_4.  */
1034
1035 static tree
1036 negate_value (tree tonegate, gimple_stmt_iterator *gsi)
1037 {
1038   gimple negatedefstmt= NULL;
1039   tree resultofnegate;
1040
1041   /* If we are trying to negate a name, defined by an add, negate the
1042      add operands instead.  */
1043   if (TREE_CODE (tonegate) == SSA_NAME)
1044     negatedefstmt = SSA_NAME_DEF_STMT (tonegate);
1045   if (TREE_CODE (tonegate) == SSA_NAME
1046       && is_gimple_assign (negatedefstmt)
1047       && TREE_CODE (gimple_assign_lhs (negatedefstmt)) == SSA_NAME
1048       && has_single_use (gimple_assign_lhs (negatedefstmt))
1049       && gimple_assign_rhs_code (negatedefstmt) == PLUS_EXPR)
1050     {
1051       gimple_stmt_iterator gsi;
1052       tree rhs1 = gimple_assign_rhs1 (negatedefstmt);
1053       tree rhs2 = gimple_assign_rhs2 (negatedefstmt);
1054
1055       gsi = gsi_for_stmt (negatedefstmt);
1056       rhs1 = negate_value (rhs1, &gsi);
1057       gimple_assign_set_rhs1 (negatedefstmt, rhs1);
1058
1059       gsi = gsi_for_stmt (negatedefstmt);
1060       rhs2 = negate_value (rhs2, &gsi);
1061       gimple_assign_set_rhs2 (negatedefstmt, rhs2);
1062
1063       update_stmt (negatedefstmt);
1064       return gimple_assign_lhs (negatedefstmt);
1065     }
1066
1067   tonegate = fold_build1 (NEGATE_EXPR, TREE_TYPE (tonegate), tonegate);
1068   resultofnegate = force_gimple_operand_gsi (gsi, tonegate, true,
1069                                              NULL_TREE, true, GSI_SAME_STMT);
1070   VEC_safe_push (tree, heap, broken_up_subtracts, resultofnegate);
1071   return resultofnegate;
1072 }
1073
1074 /* Return true if we should break up the subtract in STMT into an add
1075    with negate.  This is true when we the subtract operands are really
1076    adds, or the subtract itself is used in an add expression.  In
1077    either case, breaking up the subtract into an add with negate
1078    exposes the adds to reassociation.  */
1079
1080 static bool
1081 should_break_up_subtract (gimple stmt)
1082 {
1083   tree lhs = gimple_assign_lhs (stmt);
1084   tree binlhs = gimple_assign_rhs1 (stmt);
1085   tree binrhs = gimple_assign_rhs2 (stmt);
1086   gimple immusestmt;
1087   struct loop *loop = loop_containing_stmt (stmt);
1088
1089   if (TREE_CODE (binlhs) == SSA_NAME
1090       && is_reassociable_op (SSA_NAME_DEF_STMT (binlhs), PLUS_EXPR, loop))
1091     return true;
1092
1093   if (TREE_CODE (binrhs) == SSA_NAME
1094       && is_reassociable_op (SSA_NAME_DEF_STMT (binrhs), PLUS_EXPR, loop))
1095     return true;
1096
1097   if (TREE_CODE (lhs) == SSA_NAME
1098       && (immusestmt = get_single_immediate_use (lhs))
1099       && is_gimple_assign (immusestmt)
1100       && gimple_assign_rhs_code (immusestmt) == PLUS_EXPR)
1101     return true;
1102   return false;
1103 }
1104
1105 /* Transform STMT from A - B into A + -B.  */
1106
1107 static void
1108 break_up_subtract (gimple stmt, gimple_stmt_iterator *gsip)
1109 {
1110   tree rhs1 = gimple_assign_rhs1 (stmt);
1111   tree rhs2 = gimple_assign_rhs2 (stmt);
1112
1113   if (dump_file && (dump_flags & TDF_DETAILS))
1114     {
1115       fprintf (dump_file, "Breaking up subtract ");
1116       print_gimple_stmt (dump_file, stmt, 0, 0);
1117     }
1118
1119   rhs2 = negate_value (rhs2, gsip);
1120   gimple_assign_set_rhs_with_ops (gsip, PLUS_EXPR, rhs1, rhs2);
1121   update_stmt (stmt);
1122 }
1123
1124 /* Recursively linearize a binary expression that is the RHS of STMT.
1125    Place the operands of the expression tree in the vector named OPS.  */
1126
1127 static void
1128 linearize_expr_tree (VEC(operand_entry_t, heap) **ops, gimple stmt)
1129 {
1130   gimple_stmt_iterator gsinow, gsilhs;
1131   tree binlhs = gimple_assign_rhs1 (stmt);
1132   tree binrhs = gimple_assign_rhs2 (stmt);
1133   gimple binlhsdef, binrhsdef;
1134   bool binlhsisreassoc = false;
1135   bool binrhsisreassoc = false;
1136   enum tree_code rhscode = gimple_assign_rhs_code (stmt);
1137   struct loop *loop = loop_containing_stmt (stmt);
1138
1139   gimple_set_visited (stmt, true);
1140
1141   if (TREE_CODE (binlhs) == SSA_NAME)
1142     {
1143       binlhsdef = SSA_NAME_DEF_STMT (binlhs);
1144       binlhsisreassoc = is_reassociable_op (binlhsdef, rhscode, loop);
1145     }
1146
1147   if (TREE_CODE (binrhs) == SSA_NAME)
1148     {
1149       binrhsdef = SSA_NAME_DEF_STMT (binrhs);
1150       binrhsisreassoc = is_reassociable_op (binrhsdef, rhscode, loop);
1151     }
1152
1153   /* If the LHS is not reassociable, but the RHS is, we need to swap
1154      them.  If neither is reassociable, there is nothing we can do, so
1155      just put them in the ops vector.  If the LHS is reassociable,
1156      linearize it.  If both are reassociable, then linearize the RHS
1157      and the LHS.  */
1158
1159   if (!binlhsisreassoc)
1160     {
1161       tree temp;
1162
1163       if (!binrhsisreassoc)
1164         {
1165           add_to_ops_vec (ops, binrhs);
1166           add_to_ops_vec (ops, binlhs);
1167           return;
1168         }
1169
1170       if (dump_file && (dump_flags & TDF_DETAILS))
1171         {
1172           fprintf (dump_file, "swapping operands of ");
1173           print_gimple_stmt (dump_file, stmt, 0, 0);
1174         }
1175
1176       swap_tree_operands (stmt,
1177                           gimple_assign_rhs1_ptr (stmt),
1178                           gimple_assign_rhs2_ptr (stmt));
1179       update_stmt (stmt);
1180
1181       if (dump_file && (dump_flags & TDF_DETAILS))
1182         {
1183           fprintf (dump_file, " is now ");
1184           print_gimple_stmt (dump_file, stmt, 0, 0);
1185         }
1186
1187       /* We want to make it so the lhs is always the reassociative op,
1188          so swap.  */
1189       temp = binlhs;
1190       binlhs = binrhs;
1191       binrhs = temp;
1192     }
1193   else if (binrhsisreassoc)
1194     {
1195       linearize_expr (stmt);
1196       binlhs = gimple_assign_rhs1 (stmt);
1197       binrhs = gimple_assign_rhs2 (stmt);
1198     }
1199
1200   gcc_assert (TREE_CODE (binrhs) != SSA_NAME
1201               || !is_reassociable_op (SSA_NAME_DEF_STMT (binrhs),
1202                                       rhscode, loop));
1203   gsinow = gsi_for_stmt (stmt);
1204   gsilhs = gsi_for_stmt (SSA_NAME_DEF_STMT (binlhs));
1205   gsi_move_before (&gsilhs, &gsinow);
1206   linearize_expr_tree (ops, SSA_NAME_DEF_STMT (binlhs));
1207   add_to_ops_vec (ops, binrhs);
1208 }
1209
1210 /* Repropagate the negates back into subtracts, since no other pass
1211    currently does it.  */
1212
1213 static void
1214 repropagate_negates (void)
1215 {
1216   unsigned int i = 0;
1217   tree negate;
1218
1219   for (i = 0; VEC_iterate (tree, broken_up_subtracts, i, negate); i++)
1220     {
1221       gimple user = get_single_immediate_use (negate);
1222
1223       /* The negate operand can be either operand of a PLUS_EXPR
1224          (it can be the LHS if the RHS is a constant for example).
1225
1226          Force the negate operand to the RHS of the PLUS_EXPR, then
1227          transform the PLUS_EXPR into a MINUS_EXPR.  */
1228       if (user
1229           && is_gimple_assign (user)
1230           && gimple_assign_rhs_code (user) == PLUS_EXPR)
1231         {
1232           /* If the negated operand appears on the LHS of the
1233              PLUS_EXPR, exchange the operands of the PLUS_EXPR
1234              to force the negated operand to the RHS of the PLUS_EXPR.  */
1235           if (gimple_assign_rhs1 (user) == negate)
1236             {
1237               swap_tree_operands (user,
1238                                   gimple_assign_rhs1_ptr (user),
1239                                   gimple_assign_rhs2_ptr (user));
1240             }
1241
1242           /* Now transform the PLUS_EXPR into a MINUS_EXPR and replace
1243              the RHS of the PLUS_EXPR with the operand of the NEGATE_EXPR.  */
1244           if (gimple_assign_rhs2 (user) == negate)
1245             {
1246               tree rhs1 = gimple_assign_rhs1 (user);
1247               tree rhs2 = get_unary_op (negate, NEGATE_EXPR);
1248               gimple_stmt_iterator gsi = gsi_for_stmt (user);
1249               gimple_assign_set_rhs_with_ops (&gsi, MINUS_EXPR, rhs1, rhs2);
1250               update_stmt (user);
1251             }
1252         }
1253     }
1254 }
1255
1256 /* Break up subtract operations in block BB.
1257
1258    We do this top down because we don't know whether the subtract is
1259    part of a possible chain of reassociation except at the top.
1260  
1261    IE given
1262    d = f + g
1263    c = a + e
1264    b = c - d
1265    q = b - r
1266    k = t - q
1267    
1268    we want to break up k = t - q, but we won't until we've transformed q
1269    = b - r, which won't be broken up until we transform b = c - d.
1270
1271    En passant, clear the GIMPLE visited flag on every statement.  */
1272
1273 static void
1274 break_up_subtract_bb (basic_block bb)
1275 {
1276   gimple_stmt_iterator gsi;
1277   basic_block son;
1278
1279   for (gsi = gsi_start_bb (bb); !gsi_end_p (gsi); gsi_next (&gsi))
1280     {
1281       gimple stmt = gsi_stmt (gsi);
1282       gimple_set_visited (stmt, false);
1283
1284       /* Look for simple gimple subtract operations.  */
1285       if (is_gimple_assign (stmt)
1286           && gimple_assign_rhs_code (stmt) == MINUS_EXPR)
1287         {
1288           tree lhs = gimple_assign_lhs (stmt);
1289           tree rhs1 = gimple_assign_rhs1 (stmt);
1290           tree rhs2 = gimple_assign_rhs2 (stmt);
1291
1292           /* If associative-math we can do reassociation for
1293              non-integral types.  Or, we can do reassociation for
1294              non-saturating fixed-point types.  */
1295           if ((!INTEGRAL_TYPE_P (TREE_TYPE (lhs))
1296                || !INTEGRAL_TYPE_P (TREE_TYPE (rhs1))
1297                || !INTEGRAL_TYPE_P (TREE_TYPE (rhs2)))
1298               && (!SCALAR_FLOAT_TYPE_P (TREE_TYPE (lhs))
1299                   || !SCALAR_FLOAT_TYPE_P (TREE_TYPE(rhs1))
1300                   || !SCALAR_FLOAT_TYPE_P (TREE_TYPE(rhs2))
1301                   || !flag_associative_math)
1302               && (!NON_SAT_FIXED_POINT_TYPE_P (TREE_TYPE (lhs))
1303                   || !NON_SAT_FIXED_POINT_TYPE_P (TREE_TYPE(rhs1))
1304                   || !NON_SAT_FIXED_POINT_TYPE_P (TREE_TYPE(rhs2))))
1305             continue;
1306
1307           /* Check for a subtract used only in an addition.  If this
1308              is the case, transform it into add of a negate for better
1309              reassociation.  IE transform C = A-B into C = A + -B if C
1310              is only used in an addition.  */
1311           if (should_break_up_subtract (stmt))
1312             break_up_subtract (stmt, &gsi);
1313         }
1314     }
1315   for (son = first_dom_son (CDI_DOMINATORS, bb);
1316        son;
1317        son = next_dom_son (CDI_DOMINATORS, son))
1318     break_up_subtract_bb (son);
1319 }
1320
1321 /* Reassociate expressions in basic block BB and its post-dominator as
1322    children.  */
1323
1324 static void
1325 reassociate_bb (basic_block bb)
1326 {
1327   gimple_stmt_iterator gsi;
1328   basic_block son;
1329
1330   for (gsi = gsi_last_bb (bb); !gsi_end_p (gsi); gsi_prev (&gsi))
1331     {
1332       gimple stmt = gsi_stmt (gsi);
1333
1334       if (is_gimple_assign (stmt))
1335         {
1336           tree lhs, rhs1, rhs2;
1337           enum tree_code rhs_code = gimple_assign_rhs_code (stmt);
1338
1339           /* If this is not a gimple binary expression, there is
1340              nothing for us to do with it.  */
1341           if (get_gimple_rhs_class (rhs_code) != GIMPLE_BINARY_RHS)
1342             continue;
1343
1344           /* If this was part of an already processed statement,
1345              we don't need to touch it again. */
1346           if (gimple_visited_p (stmt))
1347             continue;
1348
1349           lhs = gimple_assign_lhs (stmt);
1350           rhs1 = gimple_assign_rhs1 (stmt);
1351           rhs2 = gimple_assign_rhs2 (stmt);
1352
1353           /* If associative-math we can do reassociation for
1354              non-integral types.  Or, we can do reassociation for
1355              non-saturating fixed-point types.  */
1356           if ((!INTEGRAL_TYPE_P (TREE_TYPE (lhs))
1357                || !INTEGRAL_TYPE_P (TREE_TYPE (rhs1))
1358                || !INTEGRAL_TYPE_P (TREE_TYPE (rhs2)))
1359               && (!SCALAR_FLOAT_TYPE_P (TREE_TYPE (lhs))
1360                   || !SCALAR_FLOAT_TYPE_P (TREE_TYPE(rhs1))
1361                   || !SCALAR_FLOAT_TYPE_P (TREE_TYPE(rhs2))
1362                   || !flag_associative_math)
1363               && (!NON_SAT_FIXED_POINT_TYPE_P (TREE_TYPE (lhs))
1364                   || !NON_SAT_FIXED_POINT_TYPE_P (TREE_TYPE(rhs1))
1365                   || !NON_SAT_FIXED_POINT_TYPE_P (TREE_TYPE(rhs2))))
1366             continue;
1367
1368           if (associative_tree_code (rhs_code))
1369             {
1370               VEC(operand_entry_t, heap) *ops = NULL;
1371
1372               /* There may be no immediate uses left by the time we
1373                  get here because we may have eliminated them all.  */
1374               if (TREE_CODE (lhs) == SSA_NAME && has_zero_uses (lhs))
1375                 continue;
1376
1377               gimple_set_visited (stmt, true);
1378               linearize_expr_tree (&ops, stmt);
1379               qsort (VEC_address (operand_entry_t, ops),
1380                      VEC_length (operand_entry_t, ops),
1381                      sizeof (operand_entry_t),
1382                      sort_by_operand_rank);
1383               optimize_ops_list (rhs_code, &ops);
1384
1385               if (VEC_length (operand_entry_t, ops) == 1)
1386                 {
1387                   if (dump_file && (dump_flags & TDF_DETAILS))
1388                     {
1389                       fprintf (dump_file, "Transforming ");
1390                       print_gimple_stmt (dump_file, stmt, 0, 0);
1391                     }
1392                   
1393                   gimple_assign_set_rhs_from_tree (&gsi,
1394                                                    VEC_last (operand_entry_t,
1395                                                              ops)->op);
1396                   update_stmt (stmt);
1397
1398                   if (dump_file && (dump_flags & TDF_DETAILS))
1399                     {
1400                       fprintf (dump_file, " into ");
1401                       print_gimple_stmt (dump_file, stmt, 0, 0);
1402                     }
1403                 }
1404               else
1405                 {
1406                   rewrite_expr_tree (stmt, 0, ops);
1407                 }
1408
1409               VEC_free (operand_entry_t, heap, ops);
1410             }
1411         }
1412     }
1413   for (son = first_dom_son (CDI_POST_DOMINATORS, bb);
1414        son;
1415        son = next_dom_son (CDI_POST_DOMINATORS, son))
1416     reassociate_bb (son);
1417 }
1418
1419 void dump_ops_vector (FILE *file, VEC (operand_entry_t, heap) *ops);
1420 void debug_ops_vector (VEC (operand_entry_t, heap) *ops);
1421
1422 /* Dump the operand entry vector OPS to FILE.  */
1423
1424 void
1425 dump_ops_vector (FILE *file, VEC (operand_entry_t, heap) *ops)
1426 {
1427   operand_entry_t oe;
1428   unsigned int i;
1429
1430   for (i = 0; VEC_iterate (operand_entry_t, ops, i, oe); i++)
1431     {
1432       fprintf (file, "Op %d -> rank: %d, tree: ", i, oe->rank);
1433       print_generic_expr (file, oe->op, 0);
1434     }
1435 }
1436
1437 /* Dump the operand entry vector OPS to STDERR.  */
1438
1439 void
1440 debug_ops_vector (VEC (operand_entry_t, heap) *ops)
1441 {
1442   dump_ops_vector (stderr, ops);
1443 }
1444
1445 static void
1446 do_reassoc (void)
1447 {
1448   break_up_subtract_bb (ENTRY_BLOCK_PTR);
1449   reassociate_bb (EXIT_BLOCK_PTR);
1450 }
1451
1452 /* Initialize the reassociation pass.  */
1453
1454 static void
1455 init_reassoc (void)
1456 {
1457   int i;
1458   long rank = 2;
1459   tree param;
1460   int *bbs = XNEWVEC (int, last_basic_block + 1);
1461
1462   /* Find the loops, so that we can prevent moving calculations in
1463      them.  */
1464   loop_optimizer_init (AVOID_CFG_MODIFICATIONS);
1465
1466   memset (&reassociate_stats, 0, sizeof (reassociate_stats));
1467
1468   operand_entry_pool = create_alloc_pool ("operand entry pool",
1469                                           sizeof (struct operand_entry), 30);
1470
1471   /* Reverse RPO (Reverse Post Order) will give us something where
1472      deeper loops come later.  */
1473   pre_and_rev_post_order_compute (NULL, bbs, false);
1474   bb_rank = XCNEWVEC (long, last_basic_block + 1);
1475   operand_rank = pointer_map_create ();
1476
1477   /* Give each argument a distinct rank.   */
1478   for (param = DECL_ARGUMENTS (current_function_decl);
1479        param;
1480        param = TREE_CHAIN (param))
1481     {
1482       if (gimple_default_def (cfun, param) != NULL)
1483         {
1484           tree def = gimple_default_def (cfun, param);
1485           insert_operand_rank (def, ++rank);
1486         }
1487     }
1488
1489   /* Give the chain decl a distinct rank. */
1490   if (cfun->static_chain_decl != NULL)
1491     {
1492       tree def = gimple_default_def (cfun, cfun->static_chain_decl);
1493       if (def != NULL)
1494         insert_operand_rank (def, ++rank);
1495     }
1496
1497   /* Set up rank for each BB  */
1498   for (i = 0; i < n_basic_blocks - NUM_FIXED_BLOCKS; i++)
1499     bb_rank[bbs[i]] = ++rank  << 16;
1500
1501   free (bbs);
1502   calculate_dominance_info (CDI_POST_DOMINATORS);
1503   broken_up_subtracts = NULL;
1504 }
1505
1506 /* Cleanup after the reassociation pass, and print stats if
1507    requested.  */
1508
1509 static void
1510 fini_reassoc (void)
1511 {
1512   statistics_counter_event (cfun, "Linearized",
1513                             reassociate_stats.linearized);
1514   statistics_counter_event (cfun, "Constants eliminated",
1515                             reassociate_stats.constants_eliminated);
1516   statistics_counter_event (cfun, "Ops eliminated",
1517                             reassociate_stats.ops_eliminated);
1518   statistics_counter_event (cfun, "Statements rewritten",
1519                             reassociate_stats.rewritten);
1520
1521   pointer_map_destroy (operand_rank);
1522   free_alloc_pool (operand_entry_pool);
1523   free (bb_rank);
1524   VEC_free (tree, heap, broken_up_subtracts);
1525   free_dominance_info (CDI_POST_DOMINATORS);
1526   loop_optimizer_finalize ();
1527 }
1528
1529 /* Gate and execute functions for Reassociation.  */
1530
1531 static unsigned int
1532 execute_reassoc (void)
1533 {
1534   init_reassoc ();
1535
1536   do_reassoc ();
1537   repropagate_negates ();
1538
1539   fini_reassoc ();
1540   return 0;
1541 }
1542
1543 static bool
1544 gate_tree_ssa_reassoc (void)
1545 {
1546   return flag_tree_reassoc != 0;
1547 }
1548
1549 struct gimple_opt_pass pass_reassoc =
1550 {
1551  {
1552   GIMPLE_PASS,
1553   "reassoc",                            /* name */
1554   gate_tree_ssa_reassoc,                /* gate */
1555   execute_reassoc,                      /* execute */
1556   NULL,                                 /* sub */
1557   NULL,                                 /* next */
1558   0,                                    /* static_pass_number */
1559   TV_TREE_REASSOC,                      /* tv_id */
1560   PROP_cfg | PROP_ssa | PROP_alias,     /* properties_required */
1561   0,                                    /* properties_provided */
1562   0,                                    /* properties_destroyed */
1563   0,                                    /* todo_flags_start */
1564   TODO_dump_func | TODO_ggc_collect | TODO_verify_ssa /* todo_flags_finish */
1565  }
1566 };
1567