* arm.c (FL_WBUF): Define.
[official-gcc.git] / gcc / tree-ssa-phiopt.c
blobe9db4c0ae2fe93e095ec9f3352b5e9408ba2c084
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, 59 Temple Place - Suite 330, Boston, MA
19 02111-1307, USA. */
21 #include "config.h"
22 #include "system.h"
23 #include "coretypes.h"
24 #include "tm.h"
25 #include "errors.h"
26 #include "ggc.h"
27 #include "tree.h"
28 #include "rtl.h"
29 #include "flags.h"
30 #include "tm_p.h"
31 #include "basic-block.h"
32 #include "timevar.h"
33 #include "diagnostic.h"
34 #include "tree-flow.h"
35 #include "tree-pass.h"
36 #include "tree-dump.h"
37 #include "langhooks.h"
39 static void tree_ssa_phiopt (void);
40 static bool conditional_replacement (basic_block, basic_block, basic_block,
41 edge, edge, tree, tree, tree);
42 static bool value_replacement (basic_block, basic_block, basic_block,
43 edge, edge, tree, tree, tree);
44 static bool minmax_replacement (basic_block, basic_block, basic_block,
45 edge, edge, tree, tree, tree);
46 static bool abs_replacement (basic_block, basic_block, basic_block,
47 edge, edge, tree, tree, tree);
48 static void replace_phi_edge_with_variable (basic_block, basic_block, edge,
49 tree, tree);
50 static basic_block *blocks_in_phiopt_order (void);
52 /* This pass eliminates PHI nodes which can be trivially implemented as
53 an assignment from a conditional expression. i.e. if we have something
54 like:
56 bb0:
57 if (cond) goto bb2; else goto bb1;
58 bb1:
59 bb2:
60 x = PHI (0 (bb1), 1 (bb0)
62 We can rewrite that as:
64 bb0:
65 bb1:
66 bb2:
67 x = cond;
69 bb1 will become unreachable and bb0 and bb2 will almost always
70 be merged into a single block. This occurs often due to gimplification
71 of conditionals.
73 Also done is the following optimization:
75 bb0:
76 if (a != b) goto bb2; else goto bb1;
77 bb1:
78 bb2:
79 x = PHI (a (bb1), b (bb0))
81 We can rewrite that as:
83 bb0:
84 bb1:
85 bb2:
86 x = b;
88 This can sometimes occur as a result of other optimizations. A
89 similar transformation is done by the ifcvt RTL optimizer.
91 This pass also eliminates PHI nodes which are really absolute
92 values. i.e. if we have something like:
94 bb0:
95 if (a >= 0) goto bb2; else goto bb1;
96 bb1:
97 x = -a;
98 bb2:
99 x = PHI (x (bb1), a (bb0));
101 We can rewrite that as:
103 bb0:
104 bb1:
105 bb2:
106 x = ABS_EXPR< a >;
108 Similarly,
110 bb0:
111 if (a <= b) goto bb2; else goto bb1;
112 bb1:
113 goto bb2;
114 bb2:
115 x = PHI (b (bb1), a (bb0));
117 Becomes
119 x = MIN_EXPR (a, b)
121 And the same transformation for MAX_EXPR.
123 bb1 will become unreachable and bb0 and bb2 will almost always be merged
124 into a single block. Similar transformations are done by the ifcvt
125 RTL optimizer. */
127 static void
128 tree_ssa_phiopt (void)
130 basic_block bb;
131 basic_block *bb_order;
132 unsigned n, i;
134 /* Search every basic block for COND_EXPR we may be able to optimize.
136 We walk the blocks in order that guarantees that a block with
137 a single predecessor is processed before the predecessor.
138 This ensures that we collapse inner ifs before visiting the
139 outer ones, and also that we do not try to visit a removed
140 block. */
141 bb_order = blocks_in_phiopt_order ();
142 n = n_basic_blocks;
144 for (i = 0; i < n; i++)
146 tree cond_expr;
147 tree phi;
148 basic_block bb1, bb2;
149 edge e1, e2;
150 tree arg0, arg1;
152 bb = bb_order[i];
154 cond_expr = last_stmt (bb);
155 /* Check to see if the last statement is a COND_EXPR. */
156 if (!cond_expr
157 || TREE_CODE (cond_expr) != COND_EXPR)
158 continue;
160 e1 = EDGE_SUCC (bb, 0);
161 bb1 = e1->dest;
162 e2 = EDGE_SUCC (bb, 1);
163 bb2 = e2->dest;
165 /* We cannot do the optimization on abnormal edges. */
166 if ((e1->flags & EDGE_ABNORMAL) != 0
167 || (e2->flags & EDGE_ABNORMAL) != 0)
168 continue;
170 /* If either bb1's succ or bb2 or bb2's succ is non NULL. */
171 if (EDGE_COUNT (bb1->succs) == 0
172 || bb2 == NULL
173 || EDGE_COUNT (bb2->succs) == 0)
174 continue;
176 /* Find the bb which is the fall through to the other. */
177 if (EDGE_SUCC (bb1, 0)->dest == bb2)
179 else if (EDGE_SUCC (bb2, 0)->dest == bb1)
181 basic_block bb_tmp = bb1;
182 edge e_tmp = e1;
183 bb1 = bb2;
184 bb2 = bb_tmp;
185 e1 = e2;
186 e2 = e_tmp;
188 else
189 continue;
191 e1 = EDGE_SUCC (bb1, 0);
193 /* Make sure that bb1 is just a fall through. */
194 if (!single_succ_p (bb1) > 1
195 || (e1->flags & EDGE_FALLTHRU) == 0)
196 continue;
198 /* Also make that bb1 only have one pred and it is bb. */
199 if (!single_pred_p (bb1)
200 || single_pred (bb1) != bb)
201 continue;
203 phi = phi_nodes (bb2);
205 /* Check to make sure that there is only one PHI node.
206 TODO: we could do it with more than one iff the other PHI nodes
207 have the same elements for these two edges. */
208 if (!phi || PHI_CHAIN (phi) != NULL)
209 continue;
211 arg0 = PHI_ARG_DEF_TREE (phi, e1->dest_idx);
212 arg1 = PHI_ARG_DEF_TREE (phi, e2->dest_idx);
214 /* We know something is wrong if we cannot find the edges in the PHI
215 node. */
216 gcc_assert (arg0 != NULL && arg1 != NULL);
218 /* Do the replacement of conditional if it can be done. */
219 if (conditional_replacement (bb, bb1, bb2, e1, e2, phi, arg0, arg1))
221 else if (value_replacement (bb, bb1, bb2, e1, e2, phi, arg0, arg1))
223 else if (abs_replacement (bb, bb1, bb2, e1, e2, phi, arg0, arg1))
225 else
226 minmax_replacement (bb, bb1, bb2, e1, e2, phi, arg0, arg1);
229 free (bb_order);
232 /* Returns the list of basic blocks in the function in an order that guarantees
233 that if a block X has just a single predecessor Y, then Y is after X in the
234 ordering. */
236 static basic_block *
237 blocks_in_phiopt_order (void)
239 basic_block x, y;
240 basic_block *order = xmalloc (sizeof (basic_block) * n_basic_blocks);
241 unsigned n = n_basic_blocks, np, i;
242 sbitmap visited = sbitmap_alloc (last_basic_block + 2);
244 #define MARK_VISITED(BB) (SET_BIT (visited, (BB)->index + 2))
245 #define VISITED_P(BB) (TEST_BIT (visited, (BB)->index + 2))
247 sbitmap_zero (visited);
249 MARK_VISITED (ENTRY_BLOCK_PTR);
250 FOR_EACH_BB (x)
252 if (VISITED_P (x))
253 continue;
255 /* Walk the predecessors of x as long as they have precisely one
256 predecessor and add them to the list, so that they get stored
257 after x. */
258 for (y = x, np = 1;
259 single_pred_p (y) && !VISITED_P (single_pred (y));
260 y = single_pred (y))
261 np++;
262 for (y = x, i = n - np;
263 single_pred_p (y) && !VISITED_P (single_pred (y));
264 y = single_pred (y), i++)
266 order[i] = y;
267 MARK_VISITED (y);
269 order[i] = y;
270 MARK_VISITED (y);
272 gcc_assert (i == n - 1);
273 n -= np;
276 sbitmap_free (visited);
277 gcc_assert (n == 0);
278 return order;
280 #undef MARK_VISITED
281 #undef VISITED_P
284 /* Return TRUE if block BB has no executable statements, otherwise return
285 FALSE. */
286 bool
287 empty_block_p (basic_block bb)
289 block_stmt_iterator bsi;
291 /* BB must have no executable statements. */
292 bsi = bsi_start (bb);
293 while (!bsi_end_p (bsi)
294 && (TREE_CODE (bsi_stmt (bsi)) == LABEL_EXPR
295 || IS_EMPTY_STMT (bsi_stmt (bsi))))
296 bsi_next (&bsi);
298 if (!bsi_end_p (bsi))
299 return false;
301 return true;
304 /* Replace PHI node element whoes edge is E in block BB with variable NEW.
305 Remove the edge from COND_BLOCK which does not lead to BB (COND_BLOCK
306 is known to have two edges, one of which must reach BB). */
308 static void
309 replace_phi_edge_with_variable (basic_block cond_block, basic_block bb,
310 edge e, tree phi, tree new)
312 basic_block block_to_remove;
313 block_stmt_iterator bsi;
315 /* Change the PHI argument to new. */
316 SET_USE (PHI_ARG_DEF_PTR (phi, e->dest_idx), new);
318 /* Remove the empty basic block. */
319 if (EDGE_SUCC (cond_block, 0)->dest == bb)
321 EDGE_SUCC (cond_block, 0)->flags |= EDGE_FALLTHRU;
322 EDGE_SUCC (cond_block, 0)->flags &= ~(EDGE_TRUE_VALUE | EDGE_FALSE_VALUE);
324 block_to_remove = EDGE_SUCC (cond_block, 1)->dest;
326 else
328 EDGE_SUCC (cond_block, 1)->flags |= EDGE_FALLTHRU;
329 EDGE_SUCC (cond_block, 1)->flags
330 &= ~(EDGE_TRUE_VALUE | EDGE_FALSE_VALUE);
332 block_to_remove = EDGE_SUCC (cond_block, 0)->dest;
334 delete_basic_block (block_to_remove);
336 /* Eliminate the COND_EXPR at the end of COND_BLOCK. */
337 bsi = bsi_last (cond_block);
338 bsi_remove (&bsi);
340 if (dump_file && (dump_flags & TDF_DETAILS))
341 fprintf (dump_file,
342 "COND_EXPR in block %d and PHI in block %d converted to straightline code.\n",
343 cond_block->index,
344 bb->index);
347 /* The function conditional_replacement does the main work of doing the
348 conditional replacement. Return true if the replacement is done.
349 Otherwise return false.
350 BB is the basic block where the replacement is going to be done on. ARG0
351 is argument 0 from PHI. Likewise for ARG1. */
353 static bool
354 conditional_replacement (basic_block cond_bb, basic_block middle_bb,
355 basic_block phi_bb, edge e0, edge e1, tree phi,
356 tree arg0, tree arg1)
358 tree result;
359 tree old_result = NULL;
360 tree new, cond;
361 block_stmt_iterator bsi;
362 edge true_edge, false_edge;
363 tree new_var = NULL;
364 tree new_var1;
366 /* The PHI arguments have the constants 0 and 1, then convert
367 it to the conditional. */
368 if ((integer_zerop (arg0) && integer_onep (arg1))
369 || (integer_zerop (arg1) && integer_onep (arg0)))
371 else
372 return false;
374 if (!empty_block_p (middle_bb))
375 return false;
377 /* If the condition is not a naked SSA_NAME and its type does not
378 match the type of the result, then we have to create a new
379 variable to optimize this case as it would likely create
380 non-gimple code when the condition was converted to the
381 result's type. */
382 cond = COND_EXPR_COND (last_stmt (cond_bb));
383 result = PHI_RESULT (phi);
384 if (TREE_CODE (cond) != SSA_NAME
385 && !lang_hooks.types_compatible_p (TREE_TYPE (cond), TREE_TYPE (result)))
387 new_var = make_rename_temp (TREE_TYPE (cond), NULL);
388 old_result = cond;
389 cond = new_var;
392 /* If the condition was a naked SSA_NAME and the type is not the
393 same as the type of the result, then convert the type of the
394 condition. */
395 if (!lang_hooks.types_compatible_p (TREE_TYPE (cond), TREE_TYPE (result)))
396 cond = fold_convert (TREE_TYPE (result), cond);
398 /* We need to know which is the true edge and which is the false
399 edge so that we know when to invert the condition below. */
400 extract_true_false_edges_from_block (cond_bb, &true_edge, &false_edge);
402 /* Insert our new statement at the end of conditional block before the
403 COND_EXPR. */
404 bsi = bsi_last (cond_bb);
405 bsi_insert_before (&bsi, build_empty_stmt (), BSI_NEW_STMT);
407 if (old_result)
409 tree new1;
410 if (!COMPARISON_CLASS_P (old_result))
411 return false;
413 new1 = build2 (TREE_CODE (old_result), TREE_TYPE (old_result),
414 TREE_OPERAND (old_result, 0),
415 TREE_OPERAND (old_result, 1));
417 new1 = build2 (MODIFY_EXPR, TREE_TYPE (old_result), new_var, new1);
418 bsi_insert_after (&bsi, new1, BSI_NEW_STMT);
421 new_var1 = duplicate_ssa_name (PHI_RESULT (phi), NULL);
424 /* At this point we know we have a COND_EXPR with two successors.
425 One successor is BB, the other successor is an empty block which
426 falls through into BB.
428 There is a single PHI node at the join point (BB) and its arguments
429 are constants (0, 1).
431 So, given the condition COND, and the two PHI arguments, we can
432 rewrite this PHI into non-branching code:
434 dest = (COND) or dest = COND'
436 We use the condition as-is if the argument associated with the
437 true edge has the value one or the argument associated with the
438 false edge as the value zero. Note that those conditions are not
439 the same since only one of the outgoing edges from the COND_EXPR
440 will directly reach BB and thus be associated with an argument. */
441 if ((e0 == true_edge && integer_onep (arg0))
442 || (e0 == false_edge && integer_zerop (arg0))
443 || (e1 == true_edge && integer_onep (arg1))
444 || (e1 == false_edge && integer_zerop (arg1)))
446 new = build2 (MODIFY_EXPR, TREE_TYPE (new_var1), new_var1, cond);
448 else
450 tree cond1 = invert_truthvalue (cond);
452 cond = cond1;
453 /* If what we get back is a conditional expression, there is no
454 way that it can be gimple. */
455 if (TREE_CODE (cond) == COND_EXPR)
457 release_ssa_name (new_var1);
458 return false;
461 /* If what we get back is not gimple try to create it as gimple by
462 using a temporary variable. */
463 if (is_gimple_cast (cond)
464 && !is_gimple_val (TREE_OPERAND (cond, 0)))
466 tree temp = TREE_OPERAND (cond, 0);
467 tree new_var_1 = make_rename_temp (TREE_TYPE (temp), NULL);
468 new = build2 (MODIFY_EXPR, TREE_TYPE (new_var_1), new_var_1, temp);
469 bsi_insert_after (&bsi, new, BSI_NEW_STMT);
470 cond = fold_convert (TREE_TYPE (result), new_var_1);
473 if (TREE_CODE (cond) == TRUTH_NOT_EXPR
474 && !is_gimple_val (TREE_OPERAND (cond, 0)))
476 release_ssa_name (new_var1);
477 return false;
480 new = build2 (MODIFY_EXPR, TREE_TYPE (new_var1), new_var1, cond);
483 bsi_insert_after (&bsi, new, BSI_NEW_STMT);
485 SSA_NAME_DEF_STMT (new_var1) = new;
487 replace_phi_edge_with_variable (cond_bb, phi_bb, e1, phi, new_var1);
489 /* Note that we optimized this PHI. */
490 return true;
493 /* The function value_replacement does the main work of doing the value
494 replacement. Return true if the replacement is done. Otherwise return
495 false.
496 BB is the basic block where the replacement is going to be done on. ARG0
497 is argument 0 from the PHI. Likewise for ARG1. */
499 static bool
500 value_replacement (basic_block cond_bb, basic_block middle_bb,
501 basic_block phi_bb, edge e0, edge e1, tree phi,
502 tree arg0, tree arg1)
504 tree cond;
505 edge true_edge, false_edge;
507 /* If the type says honor signed zeros we cannot do this
508 optimization. */
509 if (HONOR_SIGNED_ZEROS (TYPE_MODE (TREE_TYPE (arg1))))
510 return false;
512 if (!empty_block_p (middle_bb))
513 return false;
515 cond = COND_EXPR_COND (last_stmt (cond_bb));
517 /* This transformation is only valid for equality comparisons. */
518 if (TREE_CODE (cond) != NE_EXPR && TREE_CODE (cond) != EQ_EXPR)
519 return false;
521 /* We need to know which is the true edge and which is the false
522 edge so that we know if have abs or negative abs. */
523 extract_true_false_edges_from_block (cond_bb, &true_edge, &false_edge);
525 /* At this point we know we have a COND_EXPR with two successors.
526 One successor is BB, the other successor is an empty block which
527 falls through into BB.
529 The condition for the COND_EXPR is known to be NE_EXPR or EQ_EXPR.
531 There is a single PHI node at the join point (BB) with two arguments.
533 We now need to verify that the two arguments in the PHI node match
534 the two arguments to the equality comparison. */
536 if ((operand_equal_for_phi_arg_p (arg0, TREE_OPERAND (cond, 0))
537 && operand_equal_for_phi_arg_p (arg1, TREE_OPERAND (cond, 1)))
538 || (operand_equal_for_phi_arg_p (arg1, TREE_OPERAND (cond, 0))
539 && operand_equal_for_phi_arg_p (arg0, TREE_OPERAND (cond, 1))))
541 edge e;
542 tree arg;
544 /* For NE_EXPR, we want to build an assignment result = arg where
545 arg is the PHI argument associated with the true edge. For
546 EQ_EXPR we want the PHI argument associated with the false edge. */
547 e = (TREE_CODE (cond) == NE_EXPR ? true_edge : false_edge);
549 /* Unfortunately, E may not reach BB (it may instead have gone to
550 OTHER_BLOCK). If that is the case, then we want the single outgoing
551 edge from OTHER_BLOCK which reaches BB and represents the desired
552 path from COND_BLOCK. */
553 if (e->dest == middle_bb)
554 e = single_succ_edge (e->dest);
556 /* Now we know the incoming edge to BB that has the argument for the
557 RHS of our new assignment statement. */
558 if (e0 == e)
559 arg = arg0;
560 else
561 arg = arg1;
563 replace_phi_edge_with_variable (cond_bb, phi_bb, e1, phi, arg);
565 /* Note that we optimized this PHI. */
566 return true;
568 return false;
571 /* The function minmax_replacement does the main work of doing the minmax
572 replacement. Return true if the replacement is done. Otherwise return
573 false.
574 BB is the basic block where the replacement is going to be done on. ARG0
575 is argument 0 from the PHI. Likewise for ARG1. */
577 static bool
578 minmax_replacement (basic_block cond_bb, basic_block middle_bb,
579 basic_block phi_bb, edge e0, edge e1, tree phi,
580 tree arg0, tree arg1)
582 tree result, type;
583 tree cond, new;
584 edge true_edge, false_edge;
585 enum tree_code cmp, minmax, ass_code;
586 tree smaller, larger, arg_true, arg_false;
587 block_stmt_iterator bsi, bsi_from;
589 type = TREE_TYPE (PHI_RESULT (phi));
591 /* The optimization may be unsafe due to NaNs. */
592 if (HONOR_NANS (TYPE_MODE (type)))
593 return false;
595 cond = COND_EXPR_COND (last_stmt (cond_bb));
596 cmp = TREE_CODE (cond);
597 result = PHI_RESULT (phi);
599 /* This transformation is only valid for order comparisons. Record which
600 operand is smaller/larger if the result of the comparison is true. */
601 if (cmp == LT_EXPR || cmp == LE_EXPR)
603 smaller = TREE_OPERAND (cond, 0);
604 larger = TREE_OPERAND (cond, 1);
606 else if (cmp == GT_EXPR || cmp == GE_EXPR)
608 smaller = TREE_OPERAND (cond, 1);
609 larger = TREE_OPERAND (cond, 0);
611 else
612 return false;
614 /* We need to know which is the true edge and which is the false
615 edge so that we know if have abs or negative abs. */
616 extract_true_false_edges_from_block (cond_bb, &true_edge, &false_edge);
618 /* Forward the edges over the middle basic block. */
619 if (true_edge->dest == middle_bb)
620 true_edge = EDGE_SUCC (true_edge->dest, 0);
621 if (false_edge->dest == middle_bb)
622 false_edge = EDGE_SUCC (false_edge->dest, 0);
624 if (true_edge == e0)
626 gcc_assert (false_edge == e1);
627 arg_true = arg0;
628 arg_false = arg1;
630 else
632 gcc_assert (false_edge == e0);
633 gcc_assert (true_edge == e1);
634 arg_true = arg1;
635 arg_false = arg0;
638 if (empty_block_p (middle_bb))
640 if (operand_equal_for_phi_arg_p (arg_true, smaller)
641 && operand_equal_for_phi_arg_p (arg_false, larger))
643 /* Case
645 if (smaller < larger)
646 rslt = smaller;
647 else
648 rslt = larger; */
649 minmax = MIN_EXPR;
651 else if (operand_equal_for_phi_arg_p (arg_false, smaller)
652 && operand_equal_for_phi_arg_p (arg_true, larger))
653 minmax = MAX_EXPR;
654 else
655 return false;
657 else
659 /* Recognize the following case, assuming d <= u:
661 if (a <= u)
662 b = MAX (a, d);
663 x = PHI <b, u>
665 This is equivalent to
667 b = MAX (a, d);
668 x = MIN (b, u); */
670 tree assign = last_and_only_stmt (middle_bb);
671 tree lhs, rhs, op0, op1, bound;
673 if (!assign
674 || TREE_CODE (assign) != MODIFY_EXPR)
675 return false;
677 lhs = TREE_OPERAND (assign, 0);
678 rhs = TREE_OPERAND (assign, 1);
679 ass_code = TREE_CODE (rhs);
680 if (ass_code != MAX_EXPR && ass_code != MIN_EXPR)
681 return false;
682 op0 = TREE_OPERAND (rhs, 0);
683 op1 = TREE_OPERAND (rhs, 1);
685 if (true_edge->src == middle_bb)
687 /* We got here if the condition is true, i.e., SMALLER < LARGER. */
688 if (!operand_equal_for_phi_arg_p (lhs, arg_true))
689 return false;
691 if (operand_equal_for_phi_arg_p (arg_false, larger))
693 /* Case
695 if (smaller < larger)
697 r' = MAX_EXPR (smaller, bound)
699 r = PHI <r', larger> --> to be turned to MIN_EXPR. */
700 if (ass_code != MAX_EXPR)
701 return false;
703 minmax = MIN_EXPR;
704 if (operand_equal_for_phi_arg_p (op0, smaller))
705 bound = op1;
706 else if (operand_equal_for_phi_arg_p (op1, smaller))
707 bound = op0;
708 else
709 return false;
711 /* We need BOUND <= LARGER. */
712 if (!integer_nonzerop (fold (build2 (LE_EXPR, boolean_type_node,
713 bound, larger))))
714 return false;
716 else if (operand_equal_for_phi_arg_p (arg_false, smaller))
718 /* Case
720 if (smaller < larger)
722 r' = MIN_EXPR (larger, bound)
724 r = PHI <r', smaller> --> to be turned to MAX_EXPR. */
725 if (ass_code != MIN_EXPR)
726 return false;
728 minmax = MAX_EXPR;
729 if (operand_equal_for_phi_arg_p (op0, larger))
730 bound = op1;
731 else if (operand_equal_for_phi_arg_p (op1, larger))
732 bound = op0;
733 else
734 return false;
736 /* We need BOUND >= SMALLER. */
737 if (!integer_nonzerop (fold (build2 (GE_EXPR, boolean_type_node,
738 bound, smaller))))
739 return false;
741 else
742 return false;
744 else
746 /* We got here if the condition is false, i.e., SMALLER > LARGER. */
747 if (!operand_equal_for_phi_arg_p (lhs, arg_false))
748 return false;
750 if (operand_equal_for_phi_arg_p (arg_true, larger))
752 /* Case
754 if (smaller > larger)
756 r' = MIN_EXPR (smaller, bound)
758 r = PHI <r', larger> --> to be turned to MAX_EXPR. */
759 if (ass_code != MIN_EXPR)
760 return false;
762 minmax = MAX_EXPR;
763 if (operand_equal_for_phi_arg_p (op0, smaller))
764 bound = op1;
765 else if (operand_equal_for_phi_arg_p (op1, smaller))
766 bound = op0;
767 else
768 return false;
770 /* We need BOUND >= LARGER. */
771 if (!integer_nonzerop (fold (build2 (GE_EXPR, boolean_type_node,
772 bound, larger))))
773 return false;
775 else if (operand_equal_for_phi_arg_p (arg_true, smaller))
777 /* Case
779 if (smaller > larger)
781 r' = MAX_EXPR (larger, bound)
783 r = PHI <r', smaller> --> to be turned to MIN_EXPR. */
784 if (ass_code != MAX_EXPR)
785 return false;
787 minmax = MIN_EXPR;
788 if (operand_equal_for_phi_arg_p (op0, larger))
789 bound = op1;
790 else if (operand_equal_for_phi_arg_p (op1, larger))
791 bound = op0;
792 else
793 return false;
795 /* We need BOUND <= SMALLER. */
796 if (!integer_nonzerop (fold (build2 (LE_EXPR, boolean_type_node,
797 bound, smaller))))
798 return false;
800 else
801 return false;
804 /* Move the statement from the middle block. */
805 bsi = bsi_last (cond_bb);
806 bsi_from = bsi_last (middle_bb);
807 bsi_move_before (&bsi_from, &bsi);
810 /* Emit the statement to compute min/max. */
811 result = duplicate_ssa_name (PHI_RESULT (phi), NULL);
812 new = build2 (MODIFY_EXPR, type, result,
813 build2 (minmax, type, arg0, arg1));
814 SSA_NAME_DEF_STMT (result) = new;
815 bsi = bsi_last (cond_bb);
816 bsi_insert_before (&bsi, new, BSI_NEW_STMT);
818 replace_phi_edge_with_variable (cond_bb, phi_bb, e1, phi, result);
819 return true;
822 /* The function absolute_replacement does the main work of doing the absolute
823 replacement. Return true if the replacement is done. Otherwise return
824 false.
825 bb is the basic block where the replacement is going to be done on. arg0
826 is argument 0 from the phi. Likewise for arg1. */
828 static bool
829 abs_replacement (basic_block cond_bb, basic_block middle_bb,
830 basic_block phi_bb, edge e0 ATTRIBUTE_UNUSED, edge e1,
831 tree phi, tree arg0, tree arg1)
833 tree result;
834 tree new, cond;
835 block_stmt_iterator bsi;
836 edge true_edge, false_edge;
837 tree assign;
838 edge e;
839 tree rhs, lhs;
840 bool negate;
841 enum tree_code cond_code;
843 /* If the type says honor signed zeros we cannot do this
844 optimization. */
845 if (HONOR_SIGNED_ZEROS (TYPE_MODE (TREE_TYPE (arg1))))
846 return false;
848 /* OTHER_BLOCK must have only one executable statement which must have the
849 form arg0 = -arg1 or arg1 = -arg0. */
851 assign = last_and_only_stmt (middle_bb);
852 /* If we did not find the proper negation assignment, then we can not
853 optimize. */
854 if (assign == NULL)
855 return false;
857 /* If we got here, then we have found the only executable statement
858 in OTHER_BLOCK. If it is anything other than arg = -arg1 or
859 arg1 = -arg0, then we can not optimize. */
860 if (TREE_CODE (assign) != MODIFY_EXPR)
861 return false;
863 lhs = TREE_OPERAND (assign, 0);
864 rhs = TREE_OPERAND (assign, 1);
866 if (TREE_CODE (rhs) != NEGATE_EXPR)
867 return false;
869 rhs = TREE_OPERAND (rhs, 0);
871 /* The assignment has to be arg0 = -arg1 or arg1 = -arg0. */
872 if (!(lhs == arg0 && rhs == arg1)
873 && !(lhs == arg1 && rhs == arg0))
874 return false;
876 cond = COND_EXPR_COND (last_stmt (cond_bb));
877 result = PHI_RESULT (phi);
879 /* Only relationals comparing arg[01] against zero are interesting. */
880 cond_code = TREE_CODE (cond);
881 if (cond_code != GT_EXPR && cond_code != GE_EXPR
882 && cond_code != LT_EXPR && cond_code != LE_EXPR)
883 return false;
885 /* Make sure the conditional is arg[01] OP y. */
886 if (TREE_OPERAND (cond, 0) != rhs)
887 return false;
889 if (FLOAT_TYPE_P (TREE_TYPE (TREE_OPERAND (cond, 1)))
890 ? real_zerop (TREE_OPERAND (cond, 1))
891 : integer_zerop (TREE_OPERAND (cond, 1)))
893 else
894 return false;
896 /* We need to know which is the true edge and which is the false
897 edge so that we know if have abs or negative abs. */
898 extract_true_false_edges_from_block (cond_bb, &true_edge, &false_edge);
900 /* For GT_EXPR/GE_EXPR, if the true edge goes to OTHER_BLOCK, then we
901 will need to negate the result. Similarly for LT_EXPR/LE_EXPR if
902 the false edge goes to OTHER_BLOCK. */
903 if (cond_code == GT_EXPR || cond_code == GE_EXPR)
904 e = true_edge;
905 else
906 e = false_edge;
908 if (e->dest == middle_bb)
909 negate = true;
910 else
911 negate = false;
913 result = duplicate_ssa_name (result, NULL);
915 if (negate)
916 lhs = make_rename_temp (TREE_TYPE (result), NULL);
917 else
918 lhs = result;
920 /* Build the modify expression with abs expression. */
921 new = build2 (MODIFY_EXPR, TREE_TYPE (lhs),
922 lhs, build1 (ABS_EXPR, TREE_TYPE (lhs), rhs));
924 bsi = bsi_last (cond_bb);
925 bsi_insert_before (&bsi, new, BSI_NEW_STMT);
927 if (negate)
929 /* Get the right BSI. We want to insert after the recently
930 added ABS_EXPR statement (which we know is the first statement
931 in the block. */
932 new = build2 (MODIFY_EXPR, TREE_TYPE (result),
933 result, build1 (NEGATE_EXPR, TREE_TYPE (lhs), lhs));
935 bsi_insert_after (&bsi, new, BSI_NEW_STMT);
938 SSA_NAME_DEF_STMT (result) = new;
939 replace_phi_edge_with_variable (cond_bb, phi_bb, e1, phi, result);
941 /* Note that we optimized this PHI. */
942 return true;
946 /* Always do these optimizations if we have SSA
947 trees to work on. */
948 static bool
949 gate_phiopt (void)
951 return 1;
954 struct tree_opt_pass pass_phiopt =
956 "phiopt", /* name */
957 gate_phiopt, /* gate */
958 tree_ssa_phiopt, /* execute */
959 NULL, /* sub */
960 NULL, /* next */
961 0, /* static_pass_number */
962 TV_TREE_PHIOPT, /* tv_id */
963 PROP_cfg | PROP_ssa | PROP_alias, /* properties_required */
964 0, /* properties_provided */
965 0, /* properties_destroyed */
966 0, /* todo_flags_start */
967 TODO_cleanup_cfg
968 | TODO_dump_func
969 | TODO_ggc_collect
970 | TODO_verify_ssa
971 | TODO_update_ssa
972 | TODO_verify_flow
973 | TODO_verify_stmts, /* todo_flags_finish */
974 0 /* letter */