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 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,
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 ();
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
);
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
247 blocks_in_phiopt_order (void)
250 basic_block
*order
= xmalloc (sizeof (basic_block
) * n_basic_blocks
);
251 unsigned n
= n_basic_blocks
, np
, i
;
252 sbitmap visited
= sbitmap_alloc (last_basic_block
+ 2);
254 #define MARK_VISITED(BB) (SET_BIT (visited, (BB)->index + 2))
255 #define VISITED_P(BB) (TEST_BIT (visited, (BB)->index + 2))
257 sbitmap_zero (visited
);
259 MARK_VISITED (ENTRY_BLOCK_PTR
);
265 /* Walk the predecessors of x as long as they have precisely one
266 predecessor and add them to the list, so that they get stored
269 single_pred_p (y
) && !VISITED_P (single_pred (y
));
272 for (y
= x
, i
= n
- np
;
273 single_pred_p (y
) && !VISITED_P (single_pred (y
));
274 y
= single_pred (y
), i
++)
282 gcc_assert (i
== n
- 1);
286 sbitmap_free (visited
);
294 /* Return TRUE if block BB has no executable statements, otherwise return
297 empty_block_p (basic_block bb
)
299 block_stmt_iterator bsi
;
301 /* BB must have no executable statements. */
302 bsi
= bsi_start (bb
);
303 while (!bsi_end_p (bsi
)
304 && (TREE_CODE (bsi_stmt (bsi
)) == LABEL_EXPR
305 || IS_EMPTY_STMT (bsi_stmt (bsi
))))
308 if (!bsi_end_p (bsi
))
314 /* Replace PHI node element whose edge is E in block BB with variable NEW.
315 Remove the edge from COND_BLOCK which does not lead to BB (COND_BLOCK
316 is known to have two edges, one of which must reach BB). */
319 replace_phi_edge_with_variable (basic_block cond_block
,
320 edge e
, tree phi
, tree
new)
322 basic_block bb
= bb_for_stmt (phi
);
323 basic_block block_to_remove
;
324 block_stmt_iterator bsi
;
326 /* Change the PHI argument to new. */
327 SET_USE (PHI_ARG_DEF_PTR (phi
, e
->dest_idx
), new);
329 /* Remove the empty basic block. */
330 if (EDGE_SUCC (cond_block
, 0)->dest
== bb
)
332 EDGE_SUCC (cond_block
, 0)->flags
|= EDGE_FALLTHRU
;
333 EDGE_SUCC (cond_block
, 0)->flags
&= ~(EDGE_TRUE_VALUE
| EDGE_FALSE_VALUE
);
334 EDGE_SUCC (cond_block
, 0)->probability
= REG_BR_PROB_BASE
;
335 EDGE_SUCC (cond_block
, 0)->count
+= EDGE_SUCC (cond_block
, 1)->count
;
337 block_to_remove
= EDGE_SUCC (cond_block
, 1)->dest
;
341 EDGE_SUCC (cond_block
, 1)->flags
|= EDGE_FALLTHRU
;
342 EDGE_SUCC (cond_block
, 1)->flags
343 &= ~(EDGE_TRUE_VALUE
| EDGE_FALSE_VALUE
);
344 EDGE_SUCC (cond_block
, 1)->probability
= REG_BR_PROB_BASE
;
345 EDGE_SUCC (cond_block
, 1)->count
+= EDGE_SUCC (cond_block
, 0)->count
;
347 block_to_remove
= EDGE_SUCC (cond_block
, 0)->dest
;
349 delete_basic_block (block_to_remove
);
351 /* Eliminate the COND_EXPR at the end of COND_BLOCK. */
352 bsi
= bsi_last (cond_block
);
355 if (dump_file
&& (dump_flags
& TDF_DETAILS
))
357 "COND_EXPR in block %d and PHI in block %d converted to straightline code.\n",
362 /* The function conditional_replacement does the main work of doing the
363 conditional replacement. Return true if the replacement is done.
364 Otherwise return false.
365 BB is the basic block where the replacement is going to be done on. ARG0
366 is argument 0 from PHI. Likewise for ARG1. */
369 conditional_replacement (basic_block cond_bb
, basic_block middle_bb
,
370 edge e0
, edge e1
, tree phi
,
371 tree arg0
, tree arg1
)
374 tree old_result
= NULL
;
376 block_stmt_iterator bsi
;
377 edge true_edge
, false_edge
;
381 /* The PHI arguments have the constants 0 and 1, then convert
382 it to the conditional. */
383 if ((integer_zerop (arg0
) && integer_onep (arg1
))
384 || (integer_zerop (arg1
) && integer_onep (arg0
)))
389 if (!empty_block_p (middle_bb
))
392 /* If the condition is not a naked SSA_NAME and its type does not
393 match the type of the result, then we have to create a new
394 variable to optimize this case as it would likely create
395 non-gimple code when the condition was converted to the
397 cond
= COND_EXPR_COND (last_stmt (cond_bb
));
398 result
= PHI_RESULT (phi
);
399 if (TREE_CODE (cond
) != SSA_NAME
400 && !lang_hooks
.types_compatible_p (TREE_TYPE (cond
), TREE_TYPE (result
)))
402 new_var
= make_rename_temp (TREE_TYPE (cond
), NULL
);
407 /* If the condition was a naked SSA_NAME and the type is not the
408 same as the type of the result, then convert the type of the
410 if (!lang_hooks
.types_compatible_p (TREE_TYPE (cond
), TREE_TYPE (result
)))
411 cond
= fold_convert (TREE_TYPE (result
), cond
);
413 /* We need to know which is the true edge and which is the false
414 edge so that we know when to invert the condition below. */
415 extract_true_false_edges_from_block (cond_bb
, &true_edge
, &false_edge
);
417 /* Insert our new statement at the end of conditional block before the
419 bsi
= bsi_last (cond_bb
);
420 bsi_insert_before (&bsi
, build_empty_stmt (), BSI_NEW_STMT
);
425 if (!COMPARISON_CLASS_P (old_result
))
428 new1
= build2 (TREE_CODE (old_result
), TREE_TYPE (old_result
),
429 TREE_OPERAND (old_result
, 0),
430 TREE_OPERAND (old_result
, 1));
432 new1
= build2 (MODIFY_EXPR
, TREE_TYPE (old_result
), new_var
, new1
);
433 bsi_insert_after (&bsi
, new1
, BSI_NEW_STMT
);
436 new_var1
= duplicate_ssa_name (PHI_RESULT (phi
), NULL
);
439 /* At this point we know we have a COND_EXPR with two successors.
440 One successor is BB, the other successor is an empty block which
441 falls through into BB.
443 There is a single PHI node at the join point (BB) and its arguments
444 are constants (0, 1).
446 So, given the condition COND, and the two PHI arguments, we can
447 rewrite this PHI into non-branching code:
449 dest = (COND) or dest = COND'
451 We use the condition as-is if the argument associated with the
452 true edge has the value one or the argument associated with the
453 false edge as the value zero. Note that those conditions are not
454 the same since only one of the outgoing edges from the COND_EXPR
455 will directly reach BB and thus be associated with an argument. */
456 if ((e0
== true_edge
&& integer_onep (arg0
))
457 || (e0
== false_edge
&& integer_zerop (arg0
))
458 || (e1
== true_edge
&& integer_onep (arg1
))
459 || (e1
== false_edge
&& integer_zerop (arg1
)))
461 new = build2 (MODIFY_EXPR
, TREE_TYPE (new_var1
), new_var1
, cond
);
465 tree cond1
= invert_truthvalue (cond
);
468 /* If what we get back is a conditional expression, there is no
469 way that it can be gimple. */
470 if (TREE_CODE (cond
) == COND_EXPR
)
472 release_ssa_name (new_var1
);
476 /* If what we get back is not gimple try to create it as gimple by
477 using a temporary variable. */
478 if (is_gimple_cast (cond
)
479 && !is_gimple_val (TREE_OPERAND (cond
, 0)))
481 tree temp
= TREE_OPERAND (cond
, 0);
482 tree new_var_1
= make_rename_temp (TREE_TYPE (temp
), NULL
);
483 new = build2 (MODIFY_EXPR
, TREE_TYPE (new_var_1
), new_var_1
, temp
);
484 bsi_insert_after (&bsi
, new, BSI_NEW_STMT
);
485 cond
= fold_convert (TREE_TYPE (result
), new_var_1
);
488 if (TREE_CODE (cond
) == TRUTH_NOT_EXPR
489 && !is_gimple_val (TREE_OPERAND (cond
, 0)))
491 release_ssa_name (new_var1
);
495 new = build2 (MODIFY_EXPR
, TREE_TYPE (new_var1
), new_var1
, cond
);
498 bsi_insert_after (&bsi
, new, BSI_NEW_STMT
);
500 SSA_NAME_DEF_STMT (new_var1
) = new;
502 replace_phi_edge_with_variable (cond_bb
, e1
, phi
, new_var1
);
504 /* Note that we optimized this PHI. */
508 /* The function value_replacement does the main work of doing the value
509 replacement. Return true if the replacement is done. Otherwise return
511 BB is the basic block where the replacement is going to be done on. ARG0
512 is argument 0 from the PHI. Likewise for ARG1. */
515 value_replacement (basic_block cond_bb
, basic_block middle_bb
,
516 edge e0
, edge e1
, tree phi
,
517 tree arg0
, tree arg1
)
520 edge true_edge
, false_edge
;
522 /* If the type says honor signed zeros we cannot do this
524 if (HONOR_SIGNED_ZEROS (TYPE_MODE (TREE_TYPE (arg1
))))
527 if (!empty_block_p (middle_bb
))
530 cond
= COND_EXPR_COND (last_stmt (cond_bb
));
532 /* This transformation is only valid for equality comparisons. */
533 if (TREE_CODE (cond
) != NE_EXPR
&& TREE_CODE (cond
) != EQ_EXPR
)
536 /* We need to know which is the true edge and which is the false
537 edge so that we know if have abs or negative abs. */
538 extract_true_false_edges_from_block (cond_bb
, &true_edge
, &false_edge
);
540 /* At this point we know we have a COND_EXPR with two successors.
541 One successor is BB, the other successor is an empty block which
542 falls through into BB.
544 The condition for the COND_EXPR is known to be NE_EXPR or EQ_EXPR.
546 There is a single PHI node at the join point (BB) with two arguments.
548 We now need to verify that the two arguments in the PHI node match
549 the two arguments to the equality comparison. */
551 if ((operand_equal_for_phi_arg_p (arg0
, TREE_OPERAND (cond
, 0))
552 && operand_equal_for_phi_arg_p (arg1
, TREE_OPERAND (cond
, 1)))
553 || (operand_equal_for_phi_arg_p (arg1
, TREE_OPERAND (cond
, 0))
554 && operand_equal_for_phi_arg_p (arg0
, TREE_OPERAND (cond
, 1))))
559 /* For NE_EXPR, we want to build an assignment result = arg where
560 arg is the PHI argument associated with the true edge. For
561 EQ_EXPR we want the PHI argument associated with the false edge. */
562 e
= (TREE_CODE (cond
) == NE_EXPR
? true_edge
: false_edge
);
564 /* Unfortunately, E may not reach BB (it may instead have gone to
565 OTHER_BLOCK). If that is the case, then we want the single outgoing
566 edge from OTHER_BLOCK which reaches BB and represents the desired
567 path from COND_BLOCK. */
568 if (e
->dest
== middle_bb
)
569 e
= single_succ_edge (e
->dest
);
571 /* Now we know the incoming edge to BB that has the argument for the
572 RHS of our new assignment statement. */
578 replace_phi_edge_with_variable (cond_bb
, e1
, phi
, arg
);
580 /* Note that we optimized this PHI. */
586 /* The function minmax_replacement does the main work of doing the minmax
587 replacement. Return true if the replacement is done. Otherwise return
589 BB is the basic block where the replacement is going to be done on. ARG0
590 is argument 0 from the PHI. Likewise for ARG1. */
593 minmax_replacement (basic_block cond_bb
, basic_block middle_bb
,
594 edge e0
, edge e1
, tree phi
,
595 tree arg0
, tree arg1
)
599 edge true_edge
, false_edge
;
600 enum tree_code cmp
, minmax
, ass_code
;
601 tree smaller
, larger
, arg_true
, arg_false
;
602 block_stmt_iterator bsi
, bsi_from
;
604 type
= TREE_TYPE (PHI_RESULT (phi
));
606 /* The optimization may be unsafe due to NaNs. */
607 if (HONOR_NANS (TYPE_MODE (type
)))
610 cond
= COND_EXPR_COND (last_stmt (cond_bb
));
611 cmp
= TREE_CODE (cond
);
612 result
= PHI_RESULT (phi
);
614 /* This transformation is only valid for order comparisons. Record which
615 operand is smaller/larger if the result of the comparison is true. */
616 if (cmp
== LT_EXPR
|| cmp
== LE_EXPR
)
618 smaller
= TREE_OPERAND (cond
, 0);
619 larger
= TREE_OPERAND (cond
, 1);
621 else if (cmp
== GT_EXPR
|| cmp
== GE_EXPR
)
623 smaller
= TREE_OPERAND (cond
, 1);
624 larger
= TREE_OPERAND (cond
, 0);
629 /* We need to know which is the true edge and which is the false
630 edge so that we know if have abs or negative abs. */
631 extract_true_false_edges_from_block (cond_bb
, &true_edge
, &false_edge
);
633 /* Forward the edges over the middle basic block. */
634 if (true_edge
->dest
== middle_bb
)
635 true_edge
= EDGE_SUCC (true_edge
->dest
, 0);
636 if (false_edge
->dest
== middle_bb
)
637 false_edge
= EDGE_SUCC (false_edge
->dest
, 0);
641 gcc_assert (false_edge
== e1
);
647 gcc_assert (false_edge
== e0
);
648 gcc_assert (true_edge
== e1
);
653 if (empty_block_p (middle_bb
))
655 if (operand_equal_for_phi_arg_p (arg_true
, smaller
)
656 && operand_equal_for_phi_arg_p (arg_false
, larger
))
660 if (smaller < larger)
666 else if (operand_equal_for_phi_arg_p (arg_false
, smaller
)
667 && operand_equal_for_phi_arg_p (arg_true
, larger
))
674 /* Recognize the following case, assuming d <= u:
680 This is equivalent to
685 tree assign
= last_and_only_stmt (middle_bb
);
686 tree lhs
, rhs
, op0
, op1
, bound
;
689 || TREE_CODE (assign
) != MODIFY_EXPR
)
692 lhs
= TREE_OPERAND (assign
, 0);
693 rhs
= TREE_OPERAND (assign
, 1);
694 ass_code
= TREE_CODE (rhs
);
695 if (ass_code
!= MAX_EXPR
&& ass_code
!= MIN_EXPR
)
697 op0
= TREE_OPERAND (rhs
, 0);
698 op1
= TREE_OPERAND (rhs
, 1);
700 if (true_edge
->src
== middle_bb
)
702 /* We got here if the condition is true, i.e., SMALLER < LARGER. */
703 if (!operand_equal_for_phi_arg_p (lhs
, arg_true
))
706 if (operand_equal_for_phi_arg_p (arg_false
, larger
))
710 if (smaller < larger)
712 r' = MAX_EXPR (smaller, bound)
714 r = PHI <r', larger> --> to be turned to MIN_EXPR. */
715 if (ass_code
!= MAX_EXPR
)
719 if (operand_equal_for_phi_arg_p (op0
, smaller
))
721 else if (operand_equal_for_phi_arg_p (op1
, smaller
))
726 /* We need BOUND <= LARGER. */
727 if (!integer_nonzerop (fold_build2 (LE_EXPR
, boolean_type_node
,
731 else if (operand_equal_for_phi_arg_p (arg_false
, smaller
))
735 if (smaller < larger)
737 r' = MIN_EXPR (larger, bound)
739 r = PHI <r', smaller> --> to be turned to MAX_EXPR. */
740 if (ass_code
!= MIN_EXPR
)
744 if (operand_equal_for_phi_arg_p (op0
, larger
))
746 else if (operand_equal_for_phi_arg_p (op1
, larger
))
751 /* We need BOUND >= SMALLER. */
752 if (!integer_nonzerop (fold_build2 (GE_EXPR
, boolean_type_node
,
761 /* We got here if the condition is false, i.e., SMALLER > LARGER. */
762 if (!operand_equal_for_phi_arg_p (lhs
, arg_false
))
765 if (operand_equal_for_phi_arg_p (arg_true
, larger
))
769 if (smaller > larger)
771 r' = MIN_EXPR (smaller, bound)
773 r = PHI <r', larger> --> to be turned to MAX_EXPR. */
774 if (ass_code
!= MIN_EXPR
)
778 if (operand_equal_for_phi_arg_p (op0
, smaller
))
780 else if (operand_equal_for_phi_arg_p (op1
, smaller
))
785 /* We need BOUND >= LARGER. */
786 if (!integer_nonzerop (fold_build2 (GE_EXPR
, boolean_type_node
,
790 else if (operand_equal_for_phi_arg_p (arg_true
, smaller
))
794 if (smaller > larger)
796 r' = MAX_EXPR (larger, bound)
798 r = PHI <r', smaller> --> to be turned to MIN_EXPR. */
799 if (ass_code
!= MAX_EXPR
)
803 if (operand_equal_for_phi_arg_p (op0
, larger
))
805 else if (operand_equal_for_phi_arg_p (op1
, larger
))
810 /* We need BOUND <= SMALLER. */
811 if (!integer_nonzerop (fold_build2 (LE_EXPR
, boolean_type_node
,
819 /* Move the statement from the middle block. */
820 bsi
= bsi_last (cond_bb
);
821 bsi_from
= bsi_last (middle_bb
);
822 bsi_move_before (&bsi_from
, &bsi
);
825 /* Emit the statement to compute min/max. */
826 result
= duplicate_ssa_name (PHI_RESULT (phi
), NULL
);
827 new = build2 (MODIFY_EXPR
, type
, result
,
828 build2 (minmax
, type
, arg0
, arg1
));
829 SSA_NAME_DEF_STMT (result
) = new;
830 bsi
= bsi_last (cond_bb
);
831 bsi_insert_before (&bsi
, new, BSI_NEW_STMT
);
833 replace_phi_edge_with_variable (cond_bb
, e1
, phi
, result
);
837 /* The function absolute_replacement does the main work of doing the absolute
838 replacement. Return true if the replacement is done. Otherwise return
840 bb is the basic block where the replacement is going to be done on. arg0
841 is argument 0 from the phi. Likewise for arg1. */
844 abs_replacement (basic_block cond_bb
, basic_block middle_bb
,
845 edge e0 ATTRIBUTE_UNUSED
, edge e1
,
846 tree phi
, tree arg0
, tree arg1
)
850 block_stmt_iterator bsi
;
851 edge true_edge
, false_edge
;
856 enum tree_code cond_code
;
858 /* If the type says honor signed zeros we cannot do this
860 if (HONOR_SIGNED_ZEROS (TYPE_MODE (TREE_TYPE (arg1
))))
863 /* OTHER_BLOCK must have only one executable statement which must have the
864 form arg0 = -arg1 or arg1 = -arg0. */
866 assign
= last_and_only_stmt (middle_bb
);
867 /* If we did not find the proper negation assignment, then we can not
872 /* If we got here, then we have found the only executable statement
873 in OTHER_BLOCK. If it is anything other than arg = -arg1 or
874 arg1 = -arg0, then we can not optimize. */
875 if (TREE_CODE (assign
) != MODIFY_EXPR
)
878 lhs
= TREE_OPERAND (assign
, 0);
879 rhs
= TREE_OPERAND (assign
, 1);
881 if (TREE_CODE (rhs
) != NEGATE_EXPR
)
884 rhs
= TREE_OPERAND (rhs
, 0);
886 /* The assignment has to be arg0 = -arg1 or arg1 = -arg0. */
887 if (!(lhs
== arg0
&& rhs
== arg1
)
888 && !(lhs
== arg1
&& rhs
== arg0
))
891 cond
= COND_EXPR_COND (last_stmt (cond_bb
));
892 result
= PHI_RESULT (phi
);
894 /* Only relationals comparing arg[01] against zero are interesting. */
895 cond_code
= TREE_CODE (cond
);
896 if (cond_code
!= GT_EXPR
&& cond_code
!= GE_EXPR
897 && cond_code
!= LT_EXPR
&& cond_code
!= LE_EXPR
)
900 /* Make sure the conditional is arg[01] OP y. */
901 if (TREE_OPERAND (cond
, 0) != rhs
)
904 if (FLOAT_TYPE_P (TREE_TYPE (TREE_OPERAND (cond
, 1)))
905 ? real_zerop (TREE_OPERAND (cond
, 1))
906 : integer_zerop (TREE_OPERAND (cond
, 1)))
911 /* We need to know which is the true edge and which is the false
912 edge so that we know if have abs or negative abs. */
913 extract_true_false_edges_from_block (cond_bb
, &true_edge
, &false_edge
);
915 /* For GT_EXPR/GE_EXPR, if the true edge goes to OTHER_BLOCK, then we
916 will need to negate the result. Similarly for LT_EXPR/LE_EXPR if
917 the false edge goes to OTHER_BLOCK. */
918 if (cond_code
== GT_EXPR
|| cond_code
== GE_EXPR
)
923 if (e
->dest
== middle_bb
)
928 result
= duplicate_ssa_name (result
, NULL
);
931 lhs
= make_rename_temp (TREE_TYPE (result
), NULL
);
935 /* Build the modify expression with abs expression. */
936 new = build2 (MODIFY_EXPR
, TREE_TYPE (lhs
),
937 lhs
, build1 (ABS_EXPR
, TREE_TYPE (lhs
), rhs
));
939 bsi
= bsi_last (cond_bb
);
940 bsi_insert_before (&bsi
, new, BSI_NEW_STMT
);
944 /* Get the right BSI. We want to insert after the recently
945 added ABS_EXPR statement (which we know is the first statement
947 new = build2 (MODIFY_EXPR
, TREE_TYPE (result
),
948 result
, build1 (NEGATE_EXPR
, TREE_TYPE (lhs
), lhs
));
950 bsi_insert_after (&bsi
, new, BSI_NEW_STMT
);
953 SSA_NAME_DEF_STMT (result
) = new;
954 replace_phi_edge_with_variable (cond_bb
, e1
, phi
, result
);
956 /* Note that we optimized this PHI. */
961 /* Always do these optimizations if we have SSA
969 struct tree_opt_pass pass_phiopt
=
972 gate_phiopt
, /* gate */
973 tree_ssa_phiopt
, /* execute */
976 0, /* static_pass_number */
977 TV_TREE_PHIOPT
, /* tv_id */
978 PROP_cfg
| PROP_ssa
| PROP_alias
, /* properties_required */
979 0, /* properties_provided */
980 0, /* properties_destroyed */
981 0, /* todo_flags_start */
988 | TODO_verify_stmts
, /* todo_flags_finish */