Merge from mainline
[official-gcc.git] / gcc / tree-ssa-phiopt.c
blob2b772db6873653476777b400ed56cab7a974e983
1 /* Optimization of PHI nodes by converting them into straightline code.
2 Copyright (C) 2004, 2005 Free Software Foundation, Inc.
4 This file is part of GCC.
6 GCC is free software; you can redistribute it and/or modify it
7 under the terms of the GNU General Public License as published by the
8 Free Software Foundation; either version 2, or (at your option) any
9 later version.
11 GCC is distributed in the hope that it will be useful, but WITHOUT
12 ANY WARRANTY; without even the implied warranty of MERCHANTABILITY or
13 FITNESS FOR A PARTICULAR PURPOSE. See the GNU General Public License
14 for more details.
16 You should have received a copy of the GNU General Public License
17 along with GCC; see the file COPYING. If not, write to the Free
18 Software Foundation, 51 Franklin Street, Fifth Floor, Boston, MA
19 02110-1301, USA. */
21 #include "config.h"
22 #include "system.h"
23 #include "coretypes.h"
24 #include "tm.h"
25 #include "ggc.h"
26 #include "tree.h"
27 #include "rtl.h"
28 #include "flags.h"
29 #include "tm_p.h"
30 #include "basic-block.h"
31 #include "timevar.h"
32 #include "diagnostic.h"
33 #include "tree-flow.h"
34 #include "tree-pass.h"
35 #include "tree-dump.h"
36 #include "langhooks.h"
38 static void tree_ssa_phiopt (void);
39 static bool conditional_replacement (basic_block, basic_block,
40 edge, edge, tree, tree, tree);
41 static bool value_replacement (basic_block, basic_block,
42 edge, edge, tree, tree, tree);
43 static bool minmax_replacement (basic_block, basic_block,
44 edge, edge, tree, tree, tree);
45 static bool abs_replacement (basic_block, basic_block,
46 edge, edge, tree, tree, tree);
47 static void replace_phi_edge_with_variable (basic_block, edge, tree, tree);
48 static basic_block *blocks_in_phiopt_order (void);
50 /* This pass tries to replaces an if-then-else block with an
51 assignment. We have four kinds of transformations. Some of these
52 transformations are also performed by the ifcvt RTL optimizer.
54 Conditional Replacement
55 -----------------------
57 This transformation, implemented in conditional_replacement,
58 replaces
60 bb0:
61 if (cond) goto bb2; else goto bb1;
62 bb1:
63 bb2:
64 x = PHI <0 (bb1), 1 (bb0), ...>;
66 with
68 bb0:
69 x' = cond;
70 goto bb2;
71 bb2:
72 x = PHI <x' (bb0), ...>;
74 We remove bb1 as it becomes unreachable. This occurs often due to
75 gimplification of conditionals.
77 Value Replacement
78 -----------------
80 This transformation, implemented in value_replacement, replaces
82 bb0:
83 if (a != b) goto bb2; else goto bb1;
84 bb1:
85 bb2:
86 x = PHI <a (bb1), b (bb0), ...>;
88 with
90 bb0:
91 bb2:
92 x = PHI <b (bb0), ...>;
94 This opportunity can sometimes occur as a result of other
95 optimizations.
97 ABS Replacement
98 ---------------
100 This transformation, implemented in abs_replacement, replaces
102 bb0:
103 if (a >= 0) goto bb2; else goto bb1;
104 bb1:
105 x = -a;
106 bb2:
107 x = PHI <x (bb1), a (bb0), ...>;
109 with
111 bb0:
112 x' = ABS_EXPR< a >;
113 bb2:
114 x = PHI <x' (bb0), ...>;
116 MIN/MAX Replacement
117 -------------------
119 This transformation, minmax_replacement replaces
121 bb0:
122 if (a <= b) goto bb2; else goto bb1;
123 bb1:
124 bb2:
125 x = PHI <b (bb1), a (bb0), ...>;
127 with
129 bb0:
130 x' = MIN_EXPR (a, b)
131 bb2:
132 x = PHI <x' (bb0), ...>;
134 A similar transformation is done for MAX_EXPR. */
136 static void
137 tree_ssa_phiopt (void)
139 basic_block bb;
140 basic_block *bb_order;
141 unsigned n, i;
143 /* Search every basic block for COND_EXPR we may be able to optimize.
145 We walk the blocks in order that guarantees that a block with
146 a single predecessor is processed before the predecessor.
147 This ensures that we collapse inner ifs before visiting the
148 outer ones, and also that we do not try to visit a removed
149 block. */
150 bb_order = blocks_in_phiopt_order ();
151 n = n_basic_blocks - NUM_FIXED_BLOCKS;
153 for (i = 0; i < n; i++)
155 tree cond_expr;
156 tree phi;
157 basic_block bb1, bb2;
158 edge e1, e2;
159 tree arg0, arg1;
161 bb = bb_order[i];
163 cond_expr = last_stmt (bb);
164 /* Check to see if the last statement is a COND_EXPR. */
165 if (!cond_expr
166 || TREE_CODE (cond_expr) != COND_EXPR)
167 continue;
169 e1 = EDGE_SUCC (bb, 0);
170 bb1 = e1->dest;
171 e2 = EDGE_SUCC (bb, 1);
172 bb2 = e2->dest;
174 /* We cannot do the optimization on abnormal edges. */
175 if ((e1->flags & EDGE_ABNORMAL) != 0
176 || (e2->flags & EDGE_ABNORMAL) != 0)
177 continue;
179 /* If either bb1's succ or bb2 or bb2's succ is non NULL. */
180 if (EDGE_COUNT (bb1->succs) == 0
181 || bb2 == NULL
182 || EDGE_COUNT (bb2->succs) == 0)
183 continue;
185 /* Find the bb which is the fall through to the other. */
186 if (EDGE_SUCC (bb1, 0)->dest == bb2)
188 else if (EDGE_SUCC (bb2, 0)->dest == bb1)
190 basic_block bb_tmp = bb1;
191 edge e_tmp = e1;
192 bb1 = bb2;
193 bb2 = bb_tmp;
194 e1 = e2;
195 e2 = e_tmp;
197 else
198 continue;
200 e1 = EDGE_SUCC (bb1, 0);
202 /* Make sure that bb1 is just a fall through. */
203 if (!single_succ_p (bb1)
204 || (e1->flags & EDGE_FALLTHRU) == 0)
205 continue;
207 /* Also make sure that bb1 only have one predecessor and that it
208 is bb. */
209 if (!single_pred_p (bb1)
210 || single_pred (bb1) != bb)
211 continue;
213 phi = phi_nodes (bb2);
215 /* Check to make sure that there is only one PHI node.
216 TODO: we could do it with more than one iff the other PHI nodes
217 have the same elements for these two edges. */
218 if (!phi || PHI_CHAIN (phi) != NULL)
219 continue;
221 arg0 = PHI_ARG_DEF_TREE (phi, e1->dest_idx);
222 arg1 = PHI_ARG_DEF_TREE (phi, e2->dest_idx);
224 /* Something is wrong if we cannot find the arguments in the PHI
225 node. */
226 gcc_assert (arg0 != NULL && arg1 != NULL);
228 /* Do the replacement of conditional if it can be done. */
229 if (conditional_replacement (bb, bb1, e1, e2, phi, arg0, arg1))
231 else if (value_replacement (bb, bb1, e1, e2, phi, arg0, arg1))
233 else if (abs_replacement (bb, bb1, e1, e2, phi, arg0, arg1))
235 else
236 minmax_replacement (bb, bb1, e1, e2, phi, arg0, arg1);
239 free (bb_order);
242 /* Returns the list of basic blocks in the function in an order that guarantees
243 that if a block X has just a single predecessor Y, then Y is after X in the
244 ordering. */
246 static basic_block *
247 blocks_in_phiopt_order (void)
249 basic_block x, y;
250 basic_block *order = XNEWVEC (basic_block, n_basic_blocks);
251 unsigned n = n_basic_blocks - NUM_FIXED_BLOCKS;
252 unsigned np, i;
253 sbitmap visited = sbitmap_alloc (last_basic_block);
255 #define MARK_VISITED(BB) (SET_BIT (visited, (BB)->index))
256 #define VISITED_P(BB) (TEST_BIT (visited, (BB)->index))
258 sbitmap_zero (visited);
260 MARK_VISITED (ENTRY_BLOCK_PTR);
261 FOR_EACH_BB (x)
263 if (VISITED_P (x))
264 continue;
266 /* Walk the predecessors of x as long as they have precisely one
267 predecessor and add them to the list, so that they get stored
268 after x. */
269 for (y = x, np = 1;
270 single_pred_p (y) && !VISITED_P (single_pred (y));
271 y = single_pred (y))
272 np++;
273 for (y = x, i = n - np;
274 single_pred_p (y) && !VISITED_P (single_pred (y));
275 y = single_pred (y), i++)
277 order[i] = y;
278 MARK_VISITED (y);
280 order[i] = y;
281 MARK_VISITED (y);
283 gcc_assert (i == n - 1);
284 n -= np;
287 sbitmap_free (visited);
288 gcc_assert (n == 0);
289 return order;
291 #undef MARK_VISITED
292 #undef VISITED_P
295 /* Return TRUE if block BB has no executable statements, otherwise return
296 FALSE. */
297 bool
298 empty_block_p (basic_block bb)
300 block_stmt_iterator bsi;
302 /* BB must have no executable statements. */
303 bsi = bsi_start (bb);
304 while (!bsi_end_p (bsi)
305 && (TREE_CODE (bsi_stmt (bsi)) == LABEL_EXPR
306 || IS_EMPTY_STMT (bsi_stmt (bsi))))
307 bsi_next (&bsi);
309 if (!bsi_end_p (bsi))
310 return false;
312 return true;
315 /* Replace PHI node element whose edge is E in block BB with variable NEW.
316 Remove the edge from COND_BLOCK which does not lead to BB (COND_BLOCK
317 is known to have two edges, one of which must reach BB). */
319 static void
320 replace_phi_edge_with_variable (basic_block cond_block,
321 edge e, tree phi, tree new)
323 basic_block bb = bb_for_stmt (phi);
324 basic_block block_to_remove;
325 block_stmt_iterator bsi;
327 /* Change the PHI argument to new. */
328 SET_USE (PHI_ARG_DEF_PTR (phi, e->dest_idx), new);
330 /* Remove the empty basic block. */
331 if (EDGE_SUCC (cond_block, 0)->dest == bb)
333 EDGE_SUCC (cond_block, 0)->flags |= EDGE_FALLTHRU;
334 EDGE_SUCC (cond_block, 0)->flags &= ~(EDGE_TRUE_VALUE | EDGE_FALSE_VALUE);
335 EDGE_SUCC (cond_block, 0)->probability = REG_BR_PROB_BASE;
336 EDGE_SUCC (cond_block, 0)->count += EDGE_SUCC (cond_block, 1)->count;
338 block_to_remove = EDGE_SUCC (cond_block, 1)->dest;
340 else
342 EDGE_SUCC (cond_block, 1)->flags |= EDGE_FALLTHRU;
343 EDGE_SUCC (cond_block, 1)->flags
344 &= ~(EDGE_TRUE_VALUE | EDGE_FALSE_VALUE);
345 EDGE_SUCC (cond_block, 1)->probability = REG_BR_PROB_BASE;
346 EDGE_SUCC (cond_block, 1)->count += EDGE_SUCC (cond_block, 0)->count;
348 block_to_remove = EDGE_SUCC (cond_block, 0)->dest;
350 delete_basic_block (block_to_remove);
352 /* Eliminate the COND_EXPR at the end of COND_BLOCK. */
353 bsi = bsi_last (cond_block);
354 bsi_remove (&bsi, true);
356 if (dump_file && (dump_flags & TDF_DETAILS))
357 fprintf (dump_file,
358 "COND_EXPR in block %d and PHI in block %d converted to straightline code.\n",
359 cond_block->index,
360 bb->index);
363 /* The function conditional_replacement does the main work of doing the
364 conditional replacement. Return true if the replacement is done.
365 Otherwise return false.
366 BB is the basic block where the replacement is going to be done on. ARG0
367 is argument 0 from PHI. Likewise for ARG1. */
369 static bool
370 conditional_replacement (basic_block cond_bb, basic_block middle_bb,
371 edge e0, edge e1, tree phi,
372 tree arg0, tree arg1)
374 tree result;
375 tree old_result = NULL;
376 tree new, cond;
377 block_stmt_iterator bsi;
378 edge true_edge, false_edge;
379 tree new_var = NULL;
380 tree new_var1;
382 /* The PHI arguments have the constants 0 and 1, then convert
383 it to the conditional. */
384 if ((integer_zerop (arg0) && integer_onep (arg1))
385 || (integer_zerop (arg1) && integer_onep (arg0)))
387 else
388 return false;
390 if (!empty_block_p (middle_bb))
391 return false;
393 /* If the condition is not a naked SSA_NAME and its type does not
394 match the type of the result, then we have to create a new
395 variable to optimize this case as it would likely create
396 non-gimple code when the condition was converted to the
397 result's type. */
398 cond = COND_EXPR_COND (last_stmt (cond_bb));
399 result = PHI_RESULT (phi);
400 if (TREE_CODE (cond) != SSA_NAME
401 && !lang_hooks.types_compatible_p (TREE_TYPE (cond), TREE_TYPE (result)))
403 tree tmp;
405 if (!COMPARISON_CLASS_P (cond))
406 return false;
408 tmp = create_tmp_var (TREE_TYPE (cond), NULL);
409 add_referenced_tmp_var (tmp);
410 new_var = make_ssa_name (tmp, NULL);
411 old_result = cond;
412 cond = new_var;
415 /* If the condition was a naked SSA_NAME and the type is not the
416 same as the type of the result, then convert the type of the
417 condition. */
418 if (!lang_hooks.types_compatible_p (TREE_TYPE (cond), TREE_TYPE (result)))
419 cond = fold_convert (TREE_TYPE (result), cond);
421 /* We need to know which is the true edge and which is the false
422 edge so that we know when to invert the condition below. */
423 extract_true_false_edges_from_block (cond_bb, &true_edge, &false_edge);
425 /* Insert our new statement at the end of conditional block before the
426 COND_EXPR. */
427 bsi = bsi_last (cond_bb);
428 bsi_insert_before (&bsi, build_empty_stmt (), BSI_NEW_STMT);
430 if (old_result)
432 tree new1;
434 new1 = build2 (TREE_CODE (old_result), TREE_TYPE (old_result),
435 TREE_OPERAND (old_result, 0),
436 TREE_OPERAND (old_result, 1));
438 new1 = build2 (MODIFY_EXPR, TREE_TYPE (old_result), new_var, new1);
439 SSA_NAME_DEF_STMT (new_var) = new1;
441 bsi_insert_after (&bsi, new1, BSI_NEW_STMT);
444 new_var1 = duplicate_ssa_name (PHI_RESULT (phi), NULL);
447 /* At this point we know we have a COND_EXPR with two successors.
448 One successor is BB, the other successor is an empty block which
449 falls through into BB.
451 There is a single PHI node at the join point (BB) and its arguments
452 are constants (0, 1).
454 So, given the condition COND, and the two PHI arguments, we can
455 rewrite this PHI into non-branching code:
457 dest = (COND) or dest = COND'
459 We use the condition as-is if the argument associated with the
460 true edge has the value one or the argument associated with the
461 false edge as the value zero. Note that those conditions are not
462 the same since only one of the outgoing edges from the COND_EXPR
463 will directly reach BB and thus be associated with an argument. */
464 if ((e0 == true_edge && integer_onep (arg0))
465 || (e0 == false_edge && integer_zerop (arg0))
466 || (e1 == true_edge && integer_onep (arg1))
467 || (e1 == false_edge && integer_zerop (arg1)))
469 new = build2 (MODIFY_EXPR, TREE_TYPE (new_var1), new_var1, cond);
471 else
473 tree cond1 = invert_truthvalue (cond);
475 cond = cond1;
477 /* If what we get back is a conditional expression, there is no
478 way that it can be gimple. */
479 if (TREE_CODE (cond) == COND_EXPR)
481 release_ssa_name (new_var1);
482 return false;
485 /* If COND is not something we can expect to be reducible to a GIMPLE
486 condition, return early. */
487 if (is_gimple_cast (cond))
488 cond1 = TREE_OPERAND (cond, 0);
489 if (TREE_CODE (cond1) == TRUTH_NOT_EXPR
490 && !is_gimple_val (TREE_OPERAND (cond1, 0)))
492 release_ssa_name (new_var1);
493 return false;
496 /* If what we get back is not gimple try to create it as gimple by
497 using a temporary variable. */
498 if (is_gimple_cast (cond)
499 && !is_gimple_val (TREE_OPERAND (cond, 0)))
501 tree op0, tmp, cond_tmp;
503 /* Only "real" casts are OK here, not everything that is
504 acceptable to is_gimple_cast. Make sure we don't do
505 anything stupid here. */
506 gcc_assert (TREE_CODE (cond) == NOP_EXPR
507 || TREE_CODE (cond) == CONVERT_EXPR);
509 op0 = TREE_OPERAND (cond, 0);
510 tmp = create_tmp_var (TREE_TYPE (op0), NULL);
511 add_referenced_tmp_var (tmp);
512 cond_tmp = make_ssa_name (tmp, NULL);
513 new = build2 (MODIFY_EXPR, TREE_TYPE (cond_tmp), cond_tmp, op0);
514 SSA_NAME_DEF_STMT (cond_tmp) = new;
516 bsi_insert_after (&bsi, new, BSI_NEW_STMT);
517 cond = fold_convert (TREE_TYPE (result), cond_tmp);
520 new = build2 (MODIFY_EXPR, TREE_TYPE (new_var1), new_var1, cond);
523 bsi_insert_after (&bsi, new, BSI_NEW_STMT);
525 SSA_NAME_DEF_STMT (new_var1) = new;
527 replace_phi_edge_with_variable (cond_bb, e1, phi, new_var1);
529 /* Note that we optimized this PHI. */
530 return true;
533 /* The function value_replacement does the main work of doing the value
534 replacement. Return true if the replacement is done. Otherwise return
535 false.
536 BB is the basic block where the replacement is going to be done on. ARG0
537 is argument 0 from the PHI. Likewise for ARG1. */
539 static bool
540 value_replacement (basic_block cond_bb, basic_block middle_bb,
541 edge e0, edge e1, tree phi,
542 tree arg0, tree arg1)
544 tree cond;
545 edge true_edge, false_edge;
547 /* If the type says honor signed zeros we cannot do this
548 optimization. */
549 if (HONOR_SIGNED_ZEROS (TYPE_MODE (TREE_TYPE (arg1))))
550 return false;
552 if (!empty_block_p (middle_bb))
553 return false;
555 cond = COND_EXPR_COND (last_stmt (cond_bb));
557 /* This transformation is only valid for equality comparisons. */
558 if (TREE_CODE (cond) != NE_EXPR && TREE_CODE (cond) != EQ_EXPR)
559 return false;
561 /* We need to know which is the true edge and which is the false
562 edge so that we know if have abs or negative abs. */
563 extract_true_false_edges_from_block (cond_bb, &true_edge, &false_edge);
565 /* At this point we know we have a COND_EXPR with two successors.
566 One successor is BB, the other successor is an empty block which
567 falls through into BB.
569 The condition for the COND_EXPR is known to be NE_EXPR or EQ_EXPR.
571 There is a single PHI node at the join point (BB) with two arguments.
573 We now need to verify that the two arguments in the PHI node match
574 the two arguments to the equality comparison. */
576 if ((operand_equal_for_phi_arg_p (arg0, TREE_OPERAND (cond, 0))
577 && operand_equal_for_phi_arg_p (arg1, TREE_OPERAND (cond, 1)))
578 || (operand_equal_for_phi_arg_p (arg1, TREE_OPERAND (cond, 0))
579 && operand_equal_for_phi_arg_p (arg0, TREE_OPERAND (cond, 1))))
581 edge e;
582 tree arg;
584 /* For NE_EXPR, we want to build an assignment result = arg where
585 arg is the PHI argument associated with the true edge. For
586 EQ_EXPR we want the PHI argument associated with the false edge. */
587 e = (TREE_CODE (cond) == NE_EXPR ? true_edge : false_edge);
589 /* Unfortunately, E may not reach BB (it may instead have gone to
590 OTHER_BLOCK). If that is the case, then we want the single outgoing
591 edge from OTHER_BLOCK which reaches BB and represents the desired
592 path from COND_BLOCK. */
593 if (e->dest == middle_bb)
594 e = single_succ_edge (e->dest);
596 /* Now we know the incoming edge to BB that has the argument for the
597 RHS of our new assignment statement. */
598 if (e0 == e)
599 arg = arg0;
600 else
601 arg = arg1;
603 replace_phi_edge_with_variable (cond_bb, e1, phi, arg);
605 /* Note that we optimized this PHI. */
606 return true;
608 return false;
611 /* The function minmax_replacement does the main work of doing the minmax
612 replacement. Return true if the replacement is done. Otherwise return
613 false.
614 BB is the basic block where the replacement is going to be done on. ARG0
615 is argument 0 from the PHI. Likewise for ARG1. */
617 static bool
618 minmax_replacement (basic_block cond_bb, basic_block middle_bb,
619 edge e0, edge e1, tree phi,
620 tree arg0, tree arg1)
622 tree result, type;
623 tree cond, new;
624 edge true_edge, false_edge;
625 enum tree_code cmp, minmax, ass_code;
626 tree smaller, larger, arg_true, arg_false;
627 block_stmt_iterator bsi, bsi_from;
629 type = TREE_TYPE (PHI_RESULT (phi));
631 /* The optimization may be unsafe due to NaNs. */
632 if (HONOR_NANS (TYPE_MODE (type)))
633 return false;
635 cond = COND_EXPR_COND (last_stmt (cond_bb));
636 cmp = TREE_CODE (cond);
637 result = PHI_RESULT (phi);
639 /* This transformation is only valid for order comparisons. Record which
640 operand is smaller/larger if the result of the comparison is true. */
641 if (cmp == LT_EXPR || cmp == LE_EXPR)
643 smaller = TREE_OPERAND (cond, 0);
644 larger = TREE_OPERAND (cond, 1);
646 else if (cmp == GT_EXPR || cmp == GE_EXPR)
648 smaller = TREE_OPERAND (cond, 1);
649 larger = TREE_OPERAND (cond, 0);
651 else
652 return false;
654 /* We need to know which is the true edge and which is the false
655 edge so that we know if have abs or negative abs. */
656 extract_true_false_edges_from_block (cond_bb, &true_edge, &false_edge);
658 /* Forward the edges over the middle basic block. */
659 if (true_edge->dest == middle_bb)
660 true_edge = EDGE_SUCC (true_edge->dest, 0);
661 if (false_edge->dest == middle_bb)
662 false_edge = EDGE_SUCC (false_edge->dest, 0);
664 if (true_edge == e0)
666 gcc_assert (false_edge == e1);
667 arg_true = arg0;
668 arg_false = arg1;
670 else
672 gcc_assert (false_edge == e0);
673 gcc_assert (true_edge == e1);
674 arg_true = arg1;
675 arg_false = arg0;
678 if (empty_block_p (middle_bb))
680 if (operand_equal_for_phi_arg_p (arg_true, smaller)
681 && operand_equal_for_phi_arg_p (arg_false, larger))
683 /* Case
685 if (smaller < larger)
686 rslt = smaller;
687 else
688 rslt = larger; */
689 minmax = MIN_EXPR;
691 else if (operand_equal_for_phi_arg_p (arg_false, smaller)
692 && operand_equal_for_phi_arg_p (arg_true, larger))
693 minmax = MAX_EXPR;
694 else
695 return false;
697 else
699 /* Recognize the following case, assuming d <= u:
701 if (a <= u)
702 b = MAX (a, d);
703 x = PHI <b, u>
705 This is equivalent to
707 b = MAX (a, d);
708 x = MIN (b, u); */
710 tree assign = last_and_only_stmt (middle_bb);
711 tree lhs, rhs, op0, op1, bound;
713 if (!assign
714 || TREE_CODE (assign) != MODIFY_EXPR)
715 return false;
717 lhs = TREE_OPERAND (assign, 0);
718 rhs = TREE_OPERAND (assign, 1);
719 ass_code = TREE_CODE (rhs);
720 if (ass_code != MAX_EXPR && ass_code != MIN_EXPR)
721 return false;
722 op0 = TREE_OPERAND (rhs, 0);
723 op1 = TREE_OPERAND (rhs, 1);
725 if (true_edge->src == middle_bb)
727 /* We got here if the condition is true, i.e., SMALLER < LARGER. */
728 if (!operand_equal_for_phi_arg_p (lhs, arg_true))
729 return false;
731 if (operand_equal_for_phi_arg_p (arg_false, larger))
733 /* Case
735 if (smaller < larger)
737 r' = MAX_EXPR (smaller, bound)
739 r = PHI <r', larger> --> to be turned to MIN_EXPR. */
740 if (ass_code != MAX_EXPR)
741 return false;
743 minmax = MIN_EXPR;
744 if (operand_equal_for_phi_arg_p (op0, smaller))
745 bound = op1;
746 else if (operand_equal_for_phi_arg_p (op1, smaller))
747 bound = op0;
748 else
749 return false;
751 /* We need BOUND <= LARGER. */
752 if (!integer_nonzerop (fold_build2 (LE_EXPR, boolean_type_node,
753 bound, larger)))
754 return false;
756 else if (operand_equal_for_phi_arg_p (arg_false, smaller))
758 /* Case
760 if (smaller < larger)
762 r' = MIN_EXPR (larger, bound)
764 r = PHI <r', smaller> --> to be turned to MAX_EXPR. */
765 if (ass_code != MIN_EXPR)
766 return false;
768 minmax = MAX_EXPR;
769 if (operand_equal_for_phi_arg_p (op0, larger))
770 bound = op1;
771 else if (operand_equal_for_phi_arg_p (op1, larger))
772 bound = op0;
773 else
774 return false;
776 /* We need BOUND >= SMALLER. */
777 if (!integer_nonzerop (fold_build2 (GE_EXPR, boolean_type_node,
778 bound, smaller)))
779 return false;
781 else
782 return false;
784 else
786 /* We got here if the condition is false, i.e., SMALLER > LARGER. */
787 if (!operand_equal_for_phi_arg_p (lhs, arg_false))
788 return false;
790 if (operand_equal_for_phi_arg_p (arg_true, larger))
792 /* Case
794 if (smaller > larger)
796 r' = MIN_EXPR (smaller, bound)
798 r = PHI <r', larger> --> to be turned to MAX_EXPR. */
799 if (ass_code != MIN_EXPR)
800 return false;
802 minmax = MAX_EXPR;
803 if (operand_equal_for_phi_arg_p (op0, smaller))
804 bound = op1;
805 else if (operand_equal_for_phi_arg_p (op1, smaller))
806 bound = op0;
807 else
808 return false;
810 /* We need BOUND >= LARGER. */
811 if (!integer_nonzerop (fold_build2 (GE_EXPR, boolean_type_node,
812 bound, larger)))
813 return false;
815 else if (operand_equal_for_phi_arg_p (arg_true, smaller))
817 /* Case
819 if (smaller > larger)
821 r' = MAX_EXPR (larger, bound)
823 r = PHI <r', smaller> --> to be turned to MIN_EXPR. */
824 if (ass_code != MAX_EXPR)
825 return false;
827 minmax = MIN_EXPR;
828 if (operand_equal_for_phi_arg_p (op0, larger))
829 bound = op1;
830 else if (operand_equal_for_phi_arg_p (op1, larger))
831 bound = op0;
832 else
833 return false;
835 /* We need BOUND <= SMALLER. */
836 if (!integer_nonzerop (fold_build2 (LE_EXPR, boolean_type_node,
837 bound, smaller)))
838 return false;
840 else
841 return false;
844 /* Move the statement from the middle block. */
845 bsi = bsi_last (cond_bb);
846 bsi_from = bsi_last (middle_bb);
847 bsi_move_before (&bsi_from, &bsi);
850 /* Emit the statement to compute min/max. */
851 result = duplicate_ssa_name (PHI_RESULT (phi), NULL);
852 new = build2 (MODIFY_EXPR, type, result,
853 build2 (minmax, type, arg0, arg1));
854 SSA_NAME_DEF_STMT (result) = new;
855 bsi = bsi_last (cond_bb);
856 bsi_insert_before (&bsi, new, BSI_NEW_STMT);
858 replace_phi_edge_with_variable (cond_bb, e1, phi, result);
859 return true;
862 /* The function absolute_replacement does the main work of doing the absolute
863 replacement. Return true if the replacement is done. Otherwise return
864 false.
865 bb is the basic block where the replacement is going to be done on. arg0
866 is argument 0 from the phi. Likewise for arg1. */
868 static bool
869 abs_replacement (basic_block cond_bb, basic_block middle_bb,
870 edge e0 ATTRIBUTE_UNUSED, edge e1,
871 tree phi, tree arg0, tree arg1)
873 tree result;
874 tree new, cond;
875 block_stmt_iterator bsi;
876 edge true_edge, false_edge;
877 tree assign;
878 edge e;
879 tree rhs, lhs;
880 bool negate;
881 enum tree_code cond_code;
883 /* If the type says honor signed zeros we cannot do this
884 optimization. */
885 if (HONOR_SIGNED_ZEROS (TYPE_MODE (TREE_TYPE (arg1))))
886 return false;
888 /* OTHER_BLOCK must have only one executable statement which must have the
889 form arg0 = -arg1 or arg1 = -arg0. */
891 assign = last_and_only_stmt (middle_bb);
892 /* If we did not find the proper negation assignment, then we can not
893 optimize. */
894 if (assign == NULL)
895 return false;
897 /* If we got here, then we have found the only executable statement
898 in OTHER_BLOCK. If it is anything other than arg = -arg1 or
899 arg1 = -arg0, then we can not optimize. */
900 if (TREE_CODE (assign) != MODIFY_EXPR)
901 return false;
903 lhs = TREE_OPERAND (assign, 0);
904 rhs = TREE_OPERAND (assign, 1);
906 if (TREE_CODE (rhs) != NEGATE_EXPR)
907 return false;
909 rhs = TREE_OPERAND (rhs, 0);
911 /* The assignment has to be arg0 = -arg1 or arg1 = -arg0. */
912 if (!(lhs == arg0 && rhs == arg1)
913 && !(lhs == arg1 && rhs == arg0))
914 return false;
916 cond = COND_EXPR_COND (last_stmt (cond_bb));
917 result = PHI_RESULT (phi);
919 /* Only relationals comparing arg[01] against zero are interesting. */
920 cond_code = TREE_CODE (cond);
921 if (cond_code != GT_EXPR && cond_code != GE_EXPR
922 && cond_code != LT_EXPR && cond_code != LE_EXPR)
923 return false;
925 /* Make sure the conditional is arg[01] OP y. */
926 if (TREE_OPERAND (cond, 0) != rhs)
927 return false;
929 if (FLOAT_TYPE_P (TREE_TYPE (TREE_OPERAND (cond, 1)))
930 ? real_zerop (TREE_OPERAND (cond, 1))
931 : integer_zerop (TREE_OPERAND (cond, 1)))
933 else
934 return false;
936 /* We need to know which is the true edge and which is the false
937 edge so that we know if have abs or negative abs. */
938 extract_true_false_edges_from_block (cond_bb, &true_edge, &false_edge);
940 /* For GT_EXPR/GE_EXPR, if the true edge goes to OTHER_BLOCK, then we
941 will need to negate the result. Similarly for LT_EXPR/LE_EXPR if
942 the false edge goes to OTHER_BLOCK. */
943 if (cond_code == GT_EXPR || cond_code == GE_EXPR)
944 e = true_edge;
945 else
946 e = false_edge;
948 if (e->dest == middle_bb)
949 negate = true;
950 else
951 negate = false;
953 result = duplicate_ssa_name (result, NULL);
955 if (negate)
957 tree tmp = create_tmp_var (TREE_TYPE (result), NULL);
958 add_referenced_tmp_var (tmp);
959 lhs = make_ssa_name (tmp, NULL);
961 else
962 lhs = result;
964 /* Build the modify expression with abs expression. */
965 new = build2 (MODIFY_EXPR, TREE_TYPE (lhs),
966 lhs, build1 (ABS_EXPR, TREE_TYPE (lhs), rhs));
967 SSA_NAME_DEF_STMT (lhs) = new;
969 bsi = bsi_last (cond_bb);
970 bsi_insert_before (&bsi, new, BSI_NEW_STMT);
972 if (negate)
974 /* Get the right BSI. We want to insert after the recently
975 added ABS_EXPR statement (which we know is the first statement
976 in the block. */
977 new = build2 (MODIFY_EXPR, TREE_TYPE (result),
978 result, build1 (NEGATE_EXPR, TREE_TYPE (lhs), lhs));
979 SSA_NAME_DEF_STMT (result) = new;
981 bsi_insert_after (&bsi, new, BSI_NEW_STMT);
984 replace_phi_edge_with_variable (cond_bb, e1, phi, result);
986 /* Note that we optimized this PHI. */
987 return true;
991 /* Always do these optimizations if we have SSA
992 trees to work on. */
993 static bool
994 gate_phiopt (void)
996 return 1;
999 struct tree_opt_pass pass_phiopt =
1001 "phiopt", /* name */
1002 gate_phiopt, /* gate */
1003 tree_ssa_phiopt, /* execute */
1004 NULL, /* sub */
1005 NULL, /* next */
1006 0, /* static_pass_number */
1007 TV_TREE_PHIOPT, /* tv_id */
1008 PROP_cfg | PROP_ssa | PROP_alias, /* properties_required */
1009 0, /* properties_provided */
1010 0, /* properties_destroyed */
1011 0, /* todo_flags_start */
1012 TODO_cleanup_cfg
1013 | TODO_dump_func
1014 | TODO_ggc_collect
1015 | TODO_verify_ssa
1016 | TODO_verify_flow
1017 | TODO_verify_stmts, /* todo_flags_finish */
1018 0 /* letter */