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
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
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
23 #include "coretypes.h"
30 #include "basic-block.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 unsigned int 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,
61 if (cond) goto bb2; else goto bb1;
64 x = PHI <0 (bb1), 1 (bb0), ...>;
72 x = PHI <x' (bb0), ...>;
74 We remove bb1 as it becomes unreachable. This occurs often due to
75 gimplification of conditionals.
80 This transformation, implemented in value_replacement, replaces
83 if (a != b) goto bb2; else goto bb1;
86 x = PHI <a (bb1), b (bb0), ...>;
92 x = PHI <b (bb0), ...>;
94 This opportunity can sometimes occur as a result of other
100 This transformation, implemented in abs_replacement, replaces
103 if (a >= 0) goto bb2; else goto bb1;
107 x = PHI <x (bb1), a (bb0), ...>;
114 x = PHI <x' (bb0), ...>;
119 This transformation, minmax_replacement replaces
122 if (a <= b) goto bb2; else goto bb1;
125 x = PHI <b (bb1), a (bb0), ...>;
132 x = PHI <x' (bb0), ...>;
134 A similar transformation is done for MAX_EXPR. */
137 tree_ssa_phiopt (void)
140 basic_block *bb_order;
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
150 bb_order = blocks_in_phiopt_order ();
151 n = n_basic_blocks - NUM_FIXED_BLOCKS;
153 for (i = 0; i < n; i++)
157 basic_block bb1, bb2;
163 cond_expr = last_stmt (bb);
164 /* Check to see if the last statement is a COND_EXPR. */
166 || TREE_CODE (cond_expr) != COND_EXPR)
169 e1 = EDGE_SUCC (bb, 0);
171 e2 = EDGE_SUCC (bb, 1);
174 /* We cannot do the optimization on abnormal edges. */
175 if ((e1->flags & EDGE_ABNORMAL) != 0
176 || (e2->flags & EDGE_ABNORMAL) != 0)
179 /* If either bb1's succ or bb2 or bb2's succ is non NULL. */
180 if (EDGE_COUNT (bb1->succs) == 0
182 || EDGE_COUNT (bb2->succs) == 0)
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;
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)
207 /* Also make sure that bb1 only have one predecessor and that it
209 if (!single_pred_p (bb1)
210 || single_pred (bb1) != bb)
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)
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
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))
236 minmax_replacement (bb, bb1, e1, e2, phi, arg0, arg1);
243 /* Returns the list of basic blocks in the function in an order that guarantees
244 that if a block X has just a single predecessor Y, then Y is after X in the
248 blocks_in_phiopt_order (void)
251 basic_block *order = XNEWVEC (basic_block, n_basic_blocks);
252 unsigned n = n_basic_blocks - NUM_FIXED_BLOCKS;
254 sbitmap visited = sbitmap_alloc (last_basic_block);
256 #define MARK_VISITED(BB) (SET_BIT (visited, (BB)->index))
257 #define VISITED_P(BB) (TEST_BIT (visited, (BB)->index))
259 sbitmap_zero (visited);
261 MARK_VISITED (ENTRY_BLOCK_PTR);
267 /* Walk the predecessors of x as long as they have precisely one
268 predecessor and add them to the list, so that they get stored
271 single_pred_p (y) && !VISITED_P (single_pred (y));
274 for (y = x, i = n - np;
275 single_pred_p (y) && !VISITED_P (single_pred (y));
276 y = single_pred (y), i++)
284 gcc_assert (i == n - 1);
288 sbitmap_free (visited);
296 /* Return TRUE if block BB has no executable statements, otherwise return
299 empty_block_p (basic_block bb)
301 block_stmt_iterator bsi;
303 /* BB must have no executable statements. */
304 bsi = bsi_start (bb);
305 while (!bsi_end_p (bsi)
306 && (TREE_CODE (bsi_stmt (bsi)) == LABEL_EXPR
307 || IS_EMPTY_STMT (bsi_stmt (bsi))))
310 if (!bsi_end_p (bsi))
316 /* Replace PHI node element whose edge is E in block BB with variable NEW.
317 Remove the edge from COND_BLOCK which does not lead to BB (COND_BLOCK
318 is known to have two edges, one of which must reach BB). */
321 replace_phi_edge_with_variable (basic_block cond_block,
322 edge e, tree phi, tree new)
324 basic_block bb = bb_for_stmt (phi);
325 basic_block block_to_remove;
326 block_stmt_iterator bsi;
328 /* Change the PHI argument to new. */
329 SET_USE (PHI_ARG_DEF_PTR (phi, e->dest_idx), new);
331 /* Remove the empty basic block. */
332 if (EDGE_SUCC (cond_block, 0)->dest == bb)
334 EDGE_SUCC (cond_block, 0)->flags |= EDGE_FALLTHRU;
335 EDGE_SUCC (cond_block, 0)->flags &= ~(EDGE_TRUE_VALUE | EDGE_FALSE_VALUE);
336 EDGE_SUCC (cond_block, 0)->probability = REG_BR_PROB_BASE;
337 EDGE_SUCC (cond_block, 0)->count += EDGE_SUCC (cond_block, 1)->count;
339 block_to_remove = EDGE_SUCC (cond_block, 1)->dest;
343 EDGE_SUCC (cond_block, 1)->flags |= EDGE_FALLTHRU;
344 EDGE_SUCC (cond_block, 1)->flags
345 &= ~(EDGE_TRUE_VALUE | EDGE_FALSE_VALUE);
346 EDGE_SUCC (cond_block, 1)->probability = REG_BR_PROB_BASE;
347 EDGE_SUCC (cond_block, 1)->count += EDGE_SUCC (cond_block, 0)->count;
349 block_to_remove = EDGE_SUCC (cond_block, 0)->dest;
351 delete_basic_block (block_to_remove);
353 /* Eliminate the COND_EXPR at the end of COND_BLOCK. */
354 bsi = bsi_last (cond_block);
355 bsi_remove (&bsi, true);
357 if (dump_file && (dump_flags & TDF_DETAILS))
359 "COND_EXPR in block %d and PHI in block %d converted to straightline code.\n",
364 /* The function conditional_replacement does the main work of doing the
365 conditional replacement. Return true if the replacement is done.
366 Otherwise return false.
367 BB is the basic block where the replacement is going to be done on. ARG0
368 is argument 0 from PHI. Likewise for ARG1. */
371 conditional_replacement (basic_block cond_bb, basic_block middle_bb,
372 edge e0, edge e1, tree phi,
373 tree arg0, tree arg1)
376 tree old_result = NULL;
378 block_stmt_iterator bsi;
379 edge true_edge, false_edge;
383 /* The PHI arguments have the constants 0 and 1, then convert
384 it to the conditional. */
385 if ((integer_zerop (arg0) && integer_onep (arg1))
386 || (integer_zerop (arg1) && integer_onep (arg0)))
391 if (!empty_block_p (middle_bb))
394 /* If the condition is not a naked SSA_NAME and its type does not
395 match the type of the result, then we have to create a new
396 variable to optimize this case as it would likely create
397 non-gimple code when the condition was converted to the
399 cond = COND_EXPR_COND (last_stmt (cond_bb));
400 result = PHI_RESULT (phi);
401 if (TREE_CODE (cond) != SSA_NAME
402 && !lang_hooks.types_compatible_p (TREE_TYPE (cond), TREE_TYPE (result)))
406 if (!COMPARISON_CLASS_P (cond))
409 tmp = create_tmp_var (TREE_TYPE (cond), NULL);
410 add_referenced_tmp_var (tmp);
411 new_var = make_ssa_name (tmp, NULL);
416 /* If the condition was a naked SSA_NAME and the type is not the
417 same as the type of the result, then convert the type of the
419 if (!lang_hooks.types_compatible_p (TREE_TYPE (cond), TREE_TYPE (result)))
420 cond = fold_convert (TREE_TYPE (result), cond);
422 /* We need to know which is the true edge and which is the false
423 edge so that we know when to invert the condition below. */
424 extract_true_false_edges_from_block (cond_bb, &true_edge, &false_edge);
426 /* Insert our new statement at the end of conditional block before the
428 bsi = bsi_last (cond_bb);
429 bsi_insert_before (&bsi, build_empty_stmt (), BSI_NEW_STMT);
435 new1 = build2 (TREE_CODE (old_result), TREE_TYPE (old_result),
436 TREE_OPERAND (old_result, 0),
437 TREE_OPERAND (old_result, 1));
439 new1 = build2 (MODIFY_EXPR, TREE_TYPE (old_result), new_var, new1);
440 SSA_NAME_DEF_STMT (new_var) = new1;
442 bsi_insert_after (&bsi, new1, BSI_NEW_STMT);
445 new_var1 = duplicate_ssa_name (PHI_RESULT (phi), NULL);
448 /* At this point we know we have a COND_EXPR with two successors.
449 One successor is BB, the other successor is an empty block which
450 falls through into BB.
452 There is a single PHI node at the join point (BB) and its arguments
453 are constants (0, 1).
455 So, given the condition COND, and the two PHI arguments, we can
456 rewrite this PHI into non-branching code:
458 dest = (COND) or dest = COND'
460 We use the condition as-is if the argument associated with the
461 true edge has the value one or the argument associated with the
462 false edge as the value zero. Note that those conditions are not
463 the same since only one of the outgoing edges from the COND_EXPR
464 will directly reach BB and thus be associated with an argument. */
465 if ((e0 == true_edge && integer_onep (arg0))
466 || (e0 == false_edge && integer_zerop (arg0))
467 || (e1 == true_edge && integer_onep (arg1))
468 || (e1 == false_edge && integer_zerop (arg1)))
470 new = build2 (MODIFY_EXPR, TREE_TYPE (new_var1), new_var1, cond);
474 tree cond1 = invert_truthvalue (cond);
478 /* If what we get back is a conditional expression, there is no
479 way that it can be gimple. */
480 if (TREE_CODE (cond) == COND_EXPR)
482 release_ssa_name (new_var1);
486 /* If COND is not something we can expect to be reducible to a GIMPLE
487 condition, return early. */
488 if (is_gimple_cast (cond))
489 cond1 = TREE_OPERAND (cond, 0);
490 if (TREE_CODE (cond1) == TRUTH_NOT_EXPR
491 && !is_gimple_val (TREE_OPERAND (cond1, 0)))
493 release_ssa_name (new_var1);
497 /* If what we get back is not gimple try to create it as gimple by
498 using a temporary variable. */
499 if (is_gimple_cast (cond)
500 && !is_gimple_val (TREE_OPERAND (cond, 0)))
502 tree op0, tmp, cond_tmp;
504 /* Only "real" casts are OK here, not everything that is
505 acceptable to is_gimple_cast. Make sure we don't do
506 anything stupid here. */
507 gcc_assert (TREE_CODE (cond) == NOP_EXPR
508 || TREE_CODE (cond) == CONVERT_EXPR);
510 op0 = TREE_OPERAND (cond, 0);
511 tmp = create_tmp_var (TREE_TYPE (op0), NULL);
512 add_referenced_tmp_var (tmp);
513 cond_tmp = make_ssa_name (tmp, NULL);
514 new = build2 (MODIFY_EXPR, TREE_TYPE (cond_tmp), cond_tmp, op0);
515 SSA_NAME_DEF_STMT (cond_tmp) = new;
517 bsi_insert_after (&bsi, new, BSI_NEW_STMT);
518 cond = fold_convert (TREE_TYPE (result), cond_tmp);
521 new = build2 (MODIFY_EXPR, TREE_TYPE (new_var1), new_var1, cond);
524 bsi_insert_after (&bsi, new, BSI_NEW_STMT);
526 SSA_NAME_DEF_STMT (new_var1) = new;
528 replace_phi_edge_with_variable (cond_bb, e1, phi, new_var1);
530 /* Note that we optimized this PHI. */
534 /* The function value_replacement does the main work of doing the value
535 replacement. Return true if the replacement is done. Otherwise return
537 BB is the basic block where the replacement is going to be done on. ARG0
538 is argument 0 from the PHI. Likewise for ARG1. */
541 value_replacement (basic_block cond_bb, basic_block middle_bb,
542 edge e0, edge e1, tree phi,
543 tree arg0, tree arg1)
546 edge true_edge, false_edge;
548 /* If the type says honor signed zeros we cannot do this
550 if (HONOR_SIGNED_ZEROS (TYPE_MODE (TREE_TYPE (arg1))))
553 if (!empty_block_p (middle_bb))
556 cond = COND_EXPR_COND (last_stmt (cond_bb));
558 /* This transformation is only valid for equality comparisons. */
559 if (TREE_CODE (cond) != NE_EXPR && TREE_CODE (cond) != EQ_EXPR)
562 /* We need to know which is the true edge and which is the false
563 edge so that we know if have abs or negative abs. */
564 extract_true_false_edges_from_block (cond_bb, &true_edge, &false_edge);
566 /* At this point we know we have a COND_EXPR with two successors.
567 One successor is BB, the other successor is an empty block which
568 falls through into BB.
570 The condition for the COND_EXPR is known to be NE_EXPR or EQ_EXPR.
572 There is a single PHI node at the join point (BB) with two arguments.
574 We now need to verify that the two arguments in the PHI node match
575 the two arguments to the equality comparison. */
577 if ((operand_equal_for_phi_arg_p (arg0, TREE_OPERAND (cond, 0))
578 && operand_equal_for_phi_arg_p (arg1, TREE_OPERAND (cond, 1)))
579 || (operand_equal_for_phi_arg_p (arg1, TREE_OPERAND (cond, 0))
580 && operand_equal_for_phi_arg_p (arg0, TREE_OPERAND (cond, 1))))
585 /* For NE_EXPR, we want to build an assignment result = arg where
586 arg is the PHI argument associated with the true edge. For
587 EQ_EXPR we want the PHI argument associated with the false edge. */
588 e = (TREE_CODE (cond) == NE_EXPR ? true_edge : false_edge);
590 /* Unfortunately, E may not reach BB (it may instead have gone to
591 OTHER_BLOCK). If that is the case, then we want the single outgoing
592 edge from OTHER_BLOCK which reaches BB and represents the desired
593 path from COND_BLOCK. */
594 if (e->dest == middle_bb)
595 e = single_succ_edge (e->dest);
597 /* Now we know the incoming edge to BB that has the argument for the
598 RHS of our new assignment statement. */
604 replace_phi_edge_with_variable (cond_bb, e1, phi, arg);
606 /* Note that we optimized this PHI. */
612 /* The function minmax_replacement does the main work of doing the minmax
613 replacement. Return true if the replacement is done. Otherwise return
615 BB is the basic block where the replacement is going to be done on. ARG0
616 is argument 0 from the PHI. Likewise for ARG1. */
619 minmax_replacement (basic_block cond_bb, basic_block middle_bb,
620 edge e0, edge e1, tree phi,
621 tree arg0, tree arg1)
625 edge true_edge, false_edge;
626 enum tree_code cmp, minmax, ass_code;
627 tree smaller, larger, arg_true, arg_false;
628 block_stmt_iterator bsi, bsi_from;
630 type = TREE_TYPE (PHI_RESULT (phi));
632 /* The optimization may be unsafe due to NaNs. */
633 if (HONOR_NANS (TYPE_MODE (type)))
636 cond = COND_EXPR_COND (last_stmt (cond_bb));
637 cmp = TREE_CODE (cond);
638 result = PHI_RESULT (phi);
640 /* This transformation is only valid for order comparisons. Record which
641 operand is smaller/larger if the result of the comparison is true. */
642 if (cmp == LT_EXPR || cmp == LE_EXPR)
644 smaller = TREE_OPERAND (cond, 0);
645 larger = TREE_OPERAND (cond, 1);
647 else if (cmp == GT_EXPR || cmp == GE_EXPR)
649 smaller = TREE_OPERAND (cond, 1);
650 larger = TREE_OPERAND (cond, 0);
655 /* We need to know which is the true edge and which is the false
656 edge so that we know if have abs or negative abs. */
657 extract_true_false_edges_from_block (cond_bb, &true_edge, &false_edge);
659 /* Forward the edges over the middle basic block. */
660 if (true_edge->dest == middle_bb)
661 true_edge = EDGE_SUCC (true_edge->dest, 0);
662 if (false_edge->dest == middle_bb)
663 false_edge = EDGE_SUCC (false_edge->dest, 0);
667 gcc_assert (false_edge == e1);
673 gcc_assert (false_edge == e0);
674 gcc_assert (true_edge == e1);
679 if (empty_block_p (middle_bb))
681 if (operand_equal_for_phi_arg_p (arg_true, smaller)
682 && operand_equal_for_phi_arg_p (arg_false, larger))
686 if (smaller < larger)
692 else if (operand_equal_for_phi_arg_p (arg_false, smaller)
693 && operand_equal_for_phi_arg_p (arg_true, larger))
700 /* Recognize the following case, assuming d <= u:
706 This is equivalent to
711 tree assign = last_and_only_stmt (middle_bb);
712 tree lhs, rhs, op0, op1, bound;
715 || TREE_CODE (assign) != MODIFY_EXPR)
718 lhs = TREE_OPERAND (assign, 0);
719 rhs = TREE_OPERAND (assign, 1);
720 ass_code = TREE_CODE (rhs);
721 if (ass_code != MAX_EXPR && ass_code != MIN_EXPR)
723 op0 = TREE_OPERAND (rhs, 0);
724 op1 = TREE_OPERAND (rhs, 1);
726 if (true_edge->src == middle_bb)
728 /* We got here if the condition is true, i.e., SMALLER < LARGER. */
729 if (!operand_equal_for_phi_arg_p (lhs, arg_true))
732 if (operand_equal_for_phi_arg_p (arg_false, larger))
736 if (smaller < larger)
738 r' = MAX_EXPR (smaller, bound)
740 r = PHI <r', larger> --> to be turned to MIN_EXPR. */
741 if (ass_code != MAX_EXPR)
745 if (operand_equal_for_phi_arg_p (op0, smaller))
747 else if (operand_equal_for_phi_arg_p (op1, smaller))
752 /* We need BOUND <= LARGER. */
753 if (!integer_nonzerop (fold_build2 (LE_EXPR, boolean_type_node,
757 else if (operand_equal_for_phi_arg_p (arg_false, smaller))
761 if (smaller < larger)
763 r' = MIN_EXPR (larger, bound)
765 r = PHI <r', smaller> --> to be turned to MAX_EXPR. */
766 if (ass_code != MIN_EXPR)
770 if (operand_equal_for_phi_arg_p (op0, larger))
772 else if (operand_equal_for_phi_arg_p (op1, larger))
777 /* We need BOUND >= SMALLER. */
778 if (!integer_nonzerop (fold_build2 (GE_EXPR, boolean_type_node,
787 /* We got here if the condition is false, i.e., SMALLER > LARGER. */
788 if (!operand_equal_for_phi_arg_p (lhs, arg_false))
791 if (operand_equal_for_phi_arg_p (arg_true, larger))
795 if (smaller > larger)
797 r' = MIN_EXPR (smaller, bound)
799 r = PHI <r', larger> --> to be turned to MAX_EXPR. */
800 if (ass_code != MIN_EXPR)
804 if (operand_equal_for_phi_arg_p (op0, smaller))
806 else if (operand_equal_for_phi_arg_p (op1, smaller))
811 /* We need BOUND >= LARGER. */
812 if (!integer_nonzerop (fold_build2 (GE_EXPR, boolean_type_node,
816 else if (operand_equal_for_phi_arg_p (arg_true, smaller))
820 if (smaller > larger)
822 r' = MAX_EXPR (larger, bound)
824 r = PHI <r', smaller> --> to be turned to MIN_EXPR. */
825 if (ass_code != MAX_EXPR)
829 if (operand_equal_for_phi_arg_p (op0, larger))
831 else if (operand_equal_for_phi_arg_p (op1, larger))
836 /* We need BOUND <= SMALLER. */
837 if (!integer_nonzerop (fold_build2 (LE_EXPR, boolean_type_node,
845 /* Move the statement from the middle block. */
846 bsi = bsi_last (cond_bb);
847 bsi_from = bsi_last (middle_bb);
848 bsi_move_before (&bsi_from, &bsi);
851 /* Emit the statement to compute min/max. */
852 result = duplicate_ssa_name (PHI_RESULT (phi), NULL);
853 new = build2 (MODIFY_EXPR, type, result,
854 build2 (minmax, type, arg0, arg1));
855 SSA_NAME_DEF_STMT (result) = new;
856 bsi = bsi_last (cond_bb);
857 bsi_insert_before (&bsi, new, BSI_NEW_STMT);
859 replace_phi_edge_with_variable (cond_bb, e1, phi, result);
863 /* The function absolute_replacement does the main work of doing the absolute
864 replacement. Return true if the replacement is done. Otherwise return
866 bb is the basic block where the replacement is going to be done on. arg0
867 is argument 0 from the phi. Likewise for arg1. */
870 abs_replacement (basic_block cond_bb, basic_block middle_bb,
871 edge e0 ATTRIBUTE_UNUSED, edge e1,
872 tree phi, tree arg0, tree arg1)
876 block_stmt_iterator bsi;
877 edge true_edge, false_edge;
882 enum tree_code cond_code;
884 /* If the type says honor signed zeros we cannot do this
886 if (HONOR_SIGNED_ZEROS (TYPE_MODE (TREE_TYPE (arg1))))
889 /* OTHER_BLOCK must have only one executable statement which must have the
890 form arg0 = -arg1 or arg1 = -arg0. */
892 assign = last_and_only_stmt (middle_bb);
893 /* If we did not find the proper negation assignment, then we can not
898 /* If we got here, then we have found the only executable statement
899 in OTHER_BLOCK. If it is anything other than arg = -arg1 or
900 arg1 = -arg0, then we can not optimize. */
901 if (TREE_CODE (assign) != MODIFY_EXPR)
904 lhs = TREE_OPERAND (assign, 0);
905 rhs = TREE_OPERAND (assign, 1);
907 if (TREE_CODE (rhs) != NEGATE_EXPR)
910 rhs = TREE_OPERAND (rhs, 0);
912 /* The assignment has to be arg0 = -arg1 or arg1 = -arg0. */
913 if (!(lhs == arg0 && rhs == arg1)
914 && !(lhs == arg1 && rhs == arg0))
917 cond = COND_EXPR_COND (last_stmt (cond_bb));
918 result = PHI_RESULT (phi);
920 /* Only relationals comparing arg[01] against zero are interesting. */
921 cond_code = TREE_CODE (cond);
922 if (cond_code != GT_EXPR && cond_code != GE_EXPR
923 && cond_code != LT_EXPR && cond_code != LE_EXPR)
926 /* Make sure the conditional is arg[01] OP y. */
927 if (TREE_OPERAND (cond, 0) != rhs)
930 if (FLOAT_TYPE_P (TREE_TYPE (TREE_OPERAND (cond, 1)))
931 ? real_zerop (TREE_OPERAND (cond, 1))
932 : integer_zerop (TREE_OPERAND (cond, 1)))
937 /* We need to know which is the true edge and which is the false
938 edge so that we know if have abs or negative abs. */
939 extract_true_false_edges_from_block (cond_bb, &true_edge, &false_edge);
941 /* For GT_EXPR/GE_EXPR, if the true edge goes to OTHER_BLOCK, then we
942 will need to negate the result. Similarly for LT_EXPR/LE_EXPR if
943 the false edge goes to OTHER_BLOCK. */
944 if (cond_code == GT_EXPR || cond_code == GE_EXPR)
949 if (e->dest == middle_bb)
954 result = duplicate_ssa_name (result, NULL);
958 tree tmp = create_tmp_var (TREE_TYPE (result), NULL);
959 add_referenced_tmp_var (tmp);
960 lhs = make_ssa_name (tmp, NULL);
965 /* Build the modify expression with abs expression. */
966 new = build2 (MODIFY_EXPR, TREE_TYPE (lhs),
967 lhs, build1 (ABS_EXPR, TREE_TYPE (lhs), rhs));
968 SSA_NAME_DEF_STMT (lhs) = new;
970 bsi = bsi_last (cond_bb);
971 bsi_insert_before (&bsi, new, BSI_NEW_STMT);
975 /* Get the right BSI. We want to insert after the recently
976 added ABS_EXPR statement (which we know is the first statement
978 new = build2 (MODIFY_EXPR, TREE_TYPE (result),
979 result, build1 (NEGATE_EXPR, TREE_TYPE (lhs), lhs));
980 SSA_NAME_DEF_STMT (result) = new;
982 bsi_insert_after (&bsi, new, BSI_NEW_STMT);
985 replace_phi_edge_with_variable (cond_bb, e1, phi, result);
987 /* Note that we optimized this PHI. */
992 /* Always do these optimizations if we have SSA
1000 struct tree_opt_pass pass_phiopt =
1002 "phiopt", /* name */
1003 gate_phiopt, /* gate */
1004 tree_ssa_phiopt, /* execute */
1007 0, /* static_pass_number */
1008 TV_TREE_PHIOPT, /* tv_id */
1009 PROP_cfg | PROP_ssa | PROP_alias, /* properties_required */
1010 0, /* properties_provided */
1011 0, /* properties_destroyed */
1012 0, /* todo_flags_start */
1018 | TODO_verify_stmts, /* todo_flags_finish */