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