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