OSDN Git Service

* config/m68k/m68k.c (notice_update_cc): Use SET_DEST and
[pf3gnuchains/gcc-fork.git] / gcc / tree-ssa-phiopt.c
1 /* Optimization of PHI nodes by converting them into straightline code.
2    Copyright (C) 2004, 2005 Free Software Foundation, Inc.
3
4 This file is part of GCC.
5
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.
10
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.
15
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.  */
20
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"
37
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);
49
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.
53
54    Conditional Replacement
55    -----------------------
56
57    This transformation, implemented in conditional_replacement,
58    replaces
59
60      bb0:
61       if (cond) goto bb2; else goto bb1;
62      bb1:
63      bb2:
64       x = PHI <0 (bb1), 1 (bb0), ...>;
65
66    with
67
68      bb0:
69       x' = cond;
70       goto bb2;
71      bb2:
72       x = PHI <x' (bb0), ...>;
73
74    We remove bb1 as it becomes unreachable.  This occurs often due to
75    gimplification of conditionals.
76
77    Value Replacement
78    -----------------
79
80    This transformation, implemented in value_replacement, replaces
81
82      bb0:
83        if (a != b) goto bb2; else goto bb1;
84      bb1:
85      bb2:
86        x = PHI <a (bb1), b (bb0), ...>;
87
88    with
89
90      bb0:
91      bb2:
92        x = PHI <b (bb0), ...>;
93
94    This opportunity can sometimes occur as a result of other
95    optimizations.
96
97    ABS Replacement
98    ---------------
99
100    This transformation, implemented in abs_replacement, replaces
101
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), ...>;
108
109    with
110
111      bb0:
112        x' = ABS_EXPR< a >;
113      bb2:
114        x = PHI <x' (bb0), ...>;
115
116    MIN/MAX Replacement
117    -------------------
118
119    This transformation, minmax_replacement replaces
120
121      bb0:
122        if (a <= b) goto bb2; else goto bb1;
123      bb1:
124      bb2:
125        x = PHI <b (bb1), a (bb0), ...>;
126
127    with
128
129      bb0:
130        x' = MIN_EXPR (a, b)
131      bb2:
132        x = PHI <x' (bb0), ...>;
133
134    A similar transformation is done for MAX_EXPR.  */
135
136 static void
137 tree_ssa_phiopt (void)
138 {
139   basic_block bb;
140   basic_block *bb_order;
141   unsigned n, i;
142
143   /* Search every basic block for COND_EXPR we may be able to optimize.
144
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;
152
153   for (i = 0; i < n; i++)
154     {
155       tree cond_expr;
156       tree phi;
157       basic_block bb1, bb2;
158       edge e1, e2;
159       tree arg0, arg1;
160
161       bb = bb_order[i];
162
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;
168
169       e1 = EDGE_SUCC (bb, 0);
170       bb1 = e1->dest;
171       e2 = EDGE_SUCC (bb, 1);
172       bb2 = e2->dest;
173
174       /* We cannot do the optimization on abnormal edges.  */
175       if ((e1->flags & EDGE_ABNORMAL) != 0
176           || (e2->flags & EDGE_ABNORMAL) != 0)
177        continue;
178
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;
184
185       /* Find the bb which is the fall through to the other.  */
186       if (EDGE_SUCC (bb1, 0)->dest == bb2)
187         ;
188       else if (EDGE_SUCC (bb2, 0)->dest == bb1)
189         {
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;
196         }
197       else
198         continue;
199
200       e1 = EDGE_SUCC (bb1, 0);
201
202       /* Make sure that bb1 is just a fall through.  */
203       if (!single_succ_p (bb1)
204           || (e1->flags & EDGE_FALLTHRU) == 0)
205         continue;
206
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;
212
213       phi = phi_nodes (bb2);
214
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;
220
221       arg0 = PHI_ARG_DEF_TREE (phi, e1->dest_idx);
222       arg1 = PHI_ARG_DEF_TREE (phi, e2->dest_idx);
223
224       /* Something is wrong if we cannot find the arguments in the PHI
225          node.  */
226       gcc_assert (arg0 != NULL && arg1 != NULL);
227
228       /* Do the replacement of conditional if it can be done.  */
229       if (conditional_replacement (bb, bb1, e1, e2, phi, arg0, arg1))
230         ;
231       else if (value_replacement (bb, bb1, e1, e2, phi, arg0, arg1))
232         ;
233       else if (abs_replacement (bb, bb1, e1, e2, phi, arg0, arg1))
234         ;
235       else
236         minmax_replacement (bb, bb1, e1, e2, phi, arg0, arg1);
237     }
238
239   free (bb_order);
240 }
241
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.  */
245
246 static basic_block *
247 blocks_in_phiopt_order (void)
248 {
249   basic_block x, y;
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);
253
254 #define MARK_VISITED(BB) (SET_BIT (visited, (BB)->index + 2))
255 #define VISITED_P(BB) (TEST_BIT (visited, (BB)->index + 2))
256
257   sbitmap_zero (visited);
258
259   MARK_VISITED (ENTRY_BLOCK_PTR);
260   FOR_EACH_BB (x)
261     {
262       if (VISITED_P (x))
263         continue;
264
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
267          after x.  */
268       for (y = x, np = 1;
269            single_pred_p (y) && !VISITED_P (single_pred (y));
270            y = single_pred (y))
271         np++;
272       for (y = x, i = n - np;
273            single_pred_p (y) && !VISITED_P (single_pred (y));
274            y = single_pred (y), i++)
275         {
276           order[i] = y;
277           MARK_VISITED (y);
278         }
279       order[i] = y;
280       MARK_VISITED (y);
281
282       gcc_assert (i == n - 1);
283       n -= np;
284     }
285
286   sbitmap_free (visited);
287   gcc_assert (n == 0);
288   return order;
289
290 #undef MARK_VISITED
291 #undef VISITED_P
292 }
293
294 /* Return TRUE if block BB has no executable statements, otherwise return
295    FALSE.  */
296 bool
297 empty_block_p (basic_block bb)
298 {
299   block_stmt_iterator bsi;
300
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))))
306     bsi_next (&bsi);
307
308   if (!bsi_end_p (bsi))
309     return false;
310
311   return true;
312 }
313
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).  */
317
318 static void
319 replace_phi_edge_with_variable (basic_block cond_block,
320                                 edge e, tree phi, tree new)
321 {
322   basic_block bb = bb_for_stmt (phi);
323   basic_block block_to_remove;
324   block_stmt_iterator bsi;
325
326   /* Change the PHI argument to new.  */
327   SET_USE (PHI_ARG_DEF_PTR (phi, e->dest_idx), new);
328
329   /* Remove the empty basic block.  */
330   if (EDGE_SUCC (cond_block, 0)->dest == bb)
331     {
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;
336
337       block_to_remove = EDGE_SUCC (cond_block, 1)->dest;
338     }
339   else
340     {
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;
346
347       block_to_remove = EDGE_SUCC (cond_block, 0)->dest;
348     }
349   delete_basic_block (block_to_remove);
350
351   /* Eliminate the COND_EXPR at the end of COND_BLOCK.  */
352   bsi = bsi_last (cond_block);
353   bsi_remove (&bsi);
354
355   if (dump_file && (dump_flags & TDF_DETAILS))
356     fprintf (dump_file,
357               "COND_EXPR in block %d and PHI in block %d converted to straightline code.\n",
358               cond_block->index,
359               bb->index);
360 }
361
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.  */
367
368 static bool
369 conditional_replacement (basic_block cond_bb, basic_block middle_bb,
370                          edge e0, edge e1, tree phi,
371                          tree arg0, tree arg1)
372 {
373   tree result;
374   tree old_result = NULL;
375   tree new, cond;
376   block_stmt_iterator bsi;
377   edge true_edge, false_edge;
378   tree new_var = NULL;
379   tree new_var1;
380
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)))
385     ;
386   else
387     return false;
388
389   if (!empty_block_p (middle_bb))
390     return false;
391
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
396      result's type.  */
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)))
401     {
402       tree tmp;
403
404       if (!COMPARISON_CLASS_P (cond))
405         return false;
406
407       tmp = create_tmp_var (TREE_TYPE (cond), NULL);
408       add_referenced_tmp_var (tmp);
409       new_var = make_ssa_name (tmp, NULL);
410       old_result = cond;
411       cond = new_var;
412     }
413
414   /* If the condition was a naked SSA_NAME and the type is not the
415      same as the type of the result, then convert the type of the
416      condition.  */
417   if (!lang_hooks.types_compatible_p (TREE_TYPE (cond), TREE_TYPE (result)))
418     cond = fold_convert (TREE_TYPE (result), cond);
419
420   /* We need to know which is the true edge and which is the false
421      edge so that we know when to invert the condition below.  */
422   extract_true_false_edges_from_block (cond_bb, &true_edge, &false_edge);
423
424   /* Insert our new statement at the end of conditional block before the
425      COND_EXPR.  */
426   bsi = bsi_last (cond_bb);
427   bsi_insert_before (&bsi, build_empty_stmt (), BSI_NEW_STMT);
428
429   if (old_result)
430     {
431       tree new1;
432
433       new1 = build2 (TREE_CODE (old_result), TREE_TYPE (old_result),
434                      TREE_OPERAND (old_result, 0),
435                      TREE_OPERAND (old_result, 1));
436
437       new1 = build2 (MODIFY_EXPR, TREE_TYPE (old_result), new_var, new1);
438       SSA_NAME_DEF_STMT (new_var) = new1;
439
440       bsi_insert_after (&bsi, new1, BSI_NEW_STMT);
441     }
442
443   new_var1 = duplicate_ssa_name (PHI_RESULT (phi), NULL);
444
445
446   /* At this point we know we have a COND_EXPR with two successors.
447      One successor is BB, the other successor is an empty block which
448      falls through into BB.
449
450      There is a single PHI node at the join point (BB) and its arguments
451      are constants (0, 1).
452
453      So, given the condition COND, and the two PHI arguments, we can
454      rewrite this PHI into non-branching code:
455
456        dest = (COND) or dest = COND'
457
458      We use the condition as-is if the argument associated with the
459      true edge has the value one or the argument associated with the
460      false edge as the value zero.  Note that those conditions are not
461      the same since only one of the outgoing edges from the COND_EXPR
462      will directly reach BB and thus be associated with an argument.  */
463   if ((e0 == true_edge && integer_onep (arg0))
464       || (e0 == false_edge && integer_zerop (arg0))
465       || (e1 == true_edge && integer_onep (arg1))
466       || (e1 == false_edge && integer_zerop (arg1)))
467     {
468       new = build2 (MODIFY_EXPR, TREE_TYPE (new_var1), new_var1, cond);
469     }
470   else
471     {
472       tree cond1 = invert_truthvalue (cond);
473
474       cond = cond1;
475
476       /* If what we get back is a conditional expression, there is no
477           way that it can be gimple.  */
478       if (TREE_CODE (cond) == COND_EXPR)
479         {
480           release_ssa_name (new_var1);
481           return false;
482         }
483
484       /* If COND is not something we can expect to be reducible to a GIMPLE
485          condition, return early.  */
486       if (is_gimple_cast (cond))
487         cond1 = TREE_OPERAND (cond, 0);
488       if (TREE_CODE (cond1) == TRUTH_NOT_EXPR
489           && !is_gimple_val (TREE_OPERAND (cond1, 0)))
490         {
491           release_ssa_name (new_var1);
492           return false;
493         }
494
495       /* If what we get back is not gimple try to create it as gimple by
496          using a temporary variable.  */
497       if (is_gimple_cast (cond)
498           && !is_gimple_val (TREE_OPERAND (cond, 0)))
499         {
500           tree op0, tmp, cond_tmp;
501
502           /* Only "real" casts are OK here, not everything that is
503              acceptable to is_gimple_cast.  Make sure we don't do
504              anything stupid here.  */
505           gcc_assert (TREE_CODE (cond) == NOP_EXPR
506                       || TREE_CODE (cond) == CONVERT_EXPR);
507
508           op0 = TREE_OPERAND (cond, 0);
509           tmp = create_tmp_var (TREE_TYPE (op0), NULL);
510           add_referenced_tmp_var (tmp);
511           cond_tmp = make_ssa_name (tmp, NULL);
512           new = build2 (MODIFY_EXPR, TREE_TYPE (cond_tmp), cond_tmp, op0);
513           SSA_NAME_DEF_STMT (cond_tmp) = new;
514
515           bsi_insert_after (&bsi, new, BSI_NEW_STMT);
516           cond = fold_convert (TREE_TYPE (result), cond_tmp);
517         }
518
519       new = build2 (MODIFY_EXPR, TREE_TYPE (new_var1), new_var1, cond);
520     }
521
522   bsi_insert_after (&bsi, new, BSI_NEW_STMT);
523
524   SSA_NAME_DEF_STMT (new_var1) = new;
525
526   replace_phi_edge_with_variable (cond_bb, e1, phi, new_var1);
527
528   /* Note that we optimized this PHI.  */
529   return true;
530 }
531
532 /*  The function value_replacement does the main work of doing the value
533     replacement.  Return true if the replacement is done.  Otherwise return
534     false.
535     BB is the basic block where the replacement is going to be done on.  ARG0
536     is argument 0 from the PHI.  Likewise for ARG1.  */
537
538 static bool
539 value_replacement (basic_block cond_bb, basic_block middle_bb,
540                    edge e0, edge e1, tree phi,
541                    tree arg0, tree arg1)
542 {
543   tree cond;
544   edge true_edge, false_edge;
545
546   /* If the type says honor signed zeros we cannot do this
547      optimization.  */
548   if (HONOR_SIGNED_ZEROS (TYPE_MODE (TREE_TYPE (arg1))))
549     return false;
550
551   if (!empty_block_p (middle_bb))
552     return false;
553
554   cond = COND_EXPR_COND (last_stmt (cond_bb));
555
556   /* This transformation is only valid for equality comparisons.  */
557   if (TREE_CODE (cond) != NE_EXPR && TREE_CODE (cond) != EQ_EXPR)
558     return false;
559
560   /* We need to know which is the true edge and which is the false
561       edge so that we know if have abs or negative abs.  */
562   extract_true_false_edges_from_block (cond_bb, &true_edge, &false_edge);
563
564   /* At this point we know we have a COND_EXPR with two successors.
565      One successor is BB, the other successor is an empty block which
566      falls through into BB.
567
568      The condition for the COND_EXPR is known to be NE_EXPR or EQ_EXPR.
569
570      There is a single PHI node at the join point (BB) with two arguments.
571
572      We now need to verify that the two arguments in the PHI node match
573      the two arguments to the equality comparison.  */
574
575   if ((operand_equal_for_phi_arg_p (arg0, TREE_OPERAND (cond, 0))
576        && operand_equal_for_phi_arg_p (arg1, TREE_OPERAND (cond, 1)))
577       || (operand_equal_for_phi_arg_p (arg1, TREE_OPERAND (cond, 0))
578           && operand_equal_for_phi_arg_p (arg0, TREE_OPERAND (cond, 1))))
579     {
580       edge e;
581       tree arg;
582
583       /* For NE_EXPR, we want to build an assignment result = arg where
584          arg is the PHI argument associated with the true edge.  For
585          EQ_EXPR we want the PHI argument associated with the false edge.  */
586       e = (TREE_CODE (cond) == NE_EXPR ? true_edge : false_edge);
587
588       /* Unfortunately, E may not reach BB (it may instead have gone to
589          OTHER_BLOCK).  If that is the case, then we want the single outgoing
590          edge from OTHER_BLOCK which reaches BB and represents the desired
591          path from COND_BLOCK.  */
592       if (e->dest == middle_bb)
593         e = single_succ_edge (e->dest);
594
595       /* Now we know the incoming edge to BB that has the argument for the
596          RHS of our new assignment statement.  */
597       if (e0 == e)
598         arg = arg0;
599       else
600         arg = arg1;
601
602       replace_phi_edge_with_variable (cond_bb, e1, phi, arg);
603
604       /* Note that we optimized this PHI.  */
605       return true;
606     }
607   return false;
608 }
609
610 /*  The function minmax_replacement does the main work of doing the minmax
611     replacement.  Return true if the replacement is done.  Otherwise return
612     false.
613     BB is the basic block where the replacement is going to be done on.  ARG0
614     is argument 0 from the PHI.  Likewise for ARG1.  */
615
616 static bool
617 minmax_replacement (basic_block cond_bb, basic_block middle_bb,
618                     edge e0, edge e1, tree phi,
619                     tree arg0, tree arg1)
620 {
621   tree result, type;
622   tree cond, new;
623   edge true_edge, false_edge;
624   enum tree_code cmp, minmax, ass_code;
625   tree smaller, larger, arg_true, arg_false;
626   block_stmt_iterator bsi, bsi_from;
627
628   type = TREE_TYPE (PHI_RESULT (phi));
629
630   /* The optimization may be unsafe due to NaNs.  */
631   if (HONOR_NANS (TYPE_MODE (type)))
632     return false;
633
634   cond = COND_EXPR_COND (last_stmt (cond_bb));
635   cmp = TREE_CODE (cond);
636   result = PHI_RESULT (phi);
637
638   /* This transformation is only valid for order comparisons.  Record which
639      operand is smaller/larger if the result of the comparison is true.  */
640   if (cmp == LT_EXPR || cmp == LE_EXPR)
641     {
642       smaller = TREE_OPERAND (cond, 0);
643       larger = TREE_OPERAND (cond, 1);
644     }
645   else if (cmp == GT_EXPR || cmp == GE_EXPR)
646     {
647       smaller = TREE_OPERAND (cond, 1);
648       larger = TREE_OPERAND (cond, 0);
649     }
650   else
651     return false;
652
653   /* We need to know which is the true edge and which is the false
654       edge so that we know if have abs or negative abs.  */
655   extract_true_false_edges_from_block (cond_bb, &true_edge, &false_edge);
656
657   /* Forward the edges over the middle basic block.  */
658   if (true_edge->dest == middle_bb)
659     true_edge = EDGE_SUCC (true_edge->dest, 0);
660   if (false_edge->dest == middle_bb)
661     false_edge = EDGE_SUCC (false_edge->dest, 0);
662
663   if (true_edge == e0)
664     {
665       gcc_assert (false_edge == e1);
666       arg_true = arg0;
667       arg_false = arg1;
668     }
669   else
670     {
671       gcc_assert (false_edge == e0);
672       gcc_assert (true_edge == e1);
673       arg_true = arg1;
674       arg_false = arg0;
675     }
676
677   if (empty_block_p (middle_bb))
678     {
679       if (operand_equal_for_phi_arg_p (arg_true, smaller)
680           && operand_equal_for_phi_arg_p (arg_false, larger))
681         {
682           /* Case
683          
684              if (smaller < larger)
685              rslt = smaller;
686              else
687              rslt = larger;  */
688           minmax = MIN_EXPR;
689         }
690       else if (operand_equal_for_phi_arg_p (arg_false, smaller)
691                && operand_equal_for_phi_arg_p (arg_true, larger))
692         minmax = MAX_EXPR;
693       else
694         return false;
695     }
696   else
697     {
698       /* Recognize the following case, assuming d <= u:
699
700          if (a <= u)
701            b = MAX (a, d);
702          x = PHI <b, u>
703
704          This is equivalent to
705
706          b = MAX (a, d);
707          x = MIN (b, u);  */
708
709       tree assign = last_and_only_stmt (middle_bb);
710       tree lhs, rhs, op0, op1, bound;
711
712       if (!assign
713           || TREE_CODE (assign) != MODIFY_EXPR)
714         return false;
715
716       lhs = TREE_OPERAND (assign, 0);
717       rhs = TREE_OPERAND (assign, 1);
718       ass_code = TREE_CODE (rhs);
719       if (ass_code != MAX_EXPR && ass_code != MIN_EXPR)
720         return false;
721       op0 = TREE_OPERAND (rhs, 0);
722       op1 = TREE_OPERAND (rhs, 1);
723
724       if (true_edge->src == middle_bb)
725         {
726           /* We got here if the condition is true, i.e., SMALLER < LARGER.  */
727           if (!operand_equal_for_phi_arg_p (lhs, arg_true))
728             return false;
729
730           if (operand_equal_for_phi_arg_p (arg_false, larger))
731             {
732               /* Case
733
734                  if (smaller < larger)
735                    {
736                      r' = MAX_EXPR (smaller, bound)
737                    }
738                  r = PHI <r', larger>  --> to be turned to MIN_EXPR.  */
739               if (ass_code != MAX_EXPR)
740                 return false;
741
742               minmax = MIN_EXPR;
743               if (operand_equal_for_phi_arg_p (op0, smaller))
744                 bound = op1;
745               else if (operand_equal_for_phi_arg_p (op1, smaller))
746                 bound = op0;
747               else
748                 return false;
749
750               /* We need BOUND <= LARGER.  */
751               if (!integer_nonzerop (fold_build2 (LE_EXPR, boolean_type_node,
752                                                   bound, larger)))
753                 return false;
754             }
755           else if (operand_equal_for_phi_arg_p (arg_false, smaller))
756             {
757               /* Case
758
759                  if (smaller < larger)
760                    {
761                      r' = MIN_EXPR (larger, bound)
762                    }
763                  r = PHI <r', smaller>  --> to be turned to MAX_EXPR.  */
764               if (ass_code != MIN_EXPR)
765                 return false;
766
767               minmax = MAX_EXPR;
768               if (operand_equal_for_phi_arg_p (op0, larger))
769                 bound = op1;
770               else if (operand_equal_for_phi_arg_p (op1, larger))
771                 bound = op0;
772               else
773                 return false;
774
775               /* We need BOUND >= SMALLER.  */
776               if (!integer_nonzerop (fold_build2 (GE_EXPR, boolean_type_node,
777                                                   bound, smaller)))
778                 return false;
779             }
780           else
781             return false;
782         }
783       else
784         {
785           /* We got here if the condition is false, i.e., SMALLER > LARGER.  */
786           if (!operand_equal_for_phi_arg_p (lhs, arg_false))
787             return false;
788
789           if (operand_equal_for_phi_arg_p (arg_true, larger))
790             {
791               /* Case
792
793                  if (smaller > larger)
794                    {
795                      r' = MIN_EXPR (smaller, bound)
796                    }
797                  r = PHI <r', larger>  --> to be turned to MAX_EXPR.  */
798               if (ass_code != MIN_EXPR)
799                 return false;
800
801               minmax = MAX_EXPR;
802               if (operand_equal_for_phi_arg_p (op0, smaller))
803                 bound = op1;
804               else if (operand_equal_for_phi_arg_p (op1, smaller))
805                 bound = op0;
806               else
807                 return false;
808
809               /* We need BOUND >= LARGER.  */
810               if (!integer_nonzerop (fold_build2 (GE_EXPR, boolean_type_node,
811                                                   bound, larger)))
812                 return false;
813             }
814           else if (operand_equal_for_phi_arg_p (arg_true, smaller))
815             {
816               /* Case
817
818                  if (smaller > larger)
819                    {
820                      r' = MAX_EXPR (larger, bound)
821                    }
822                  r = PHI <r', smaller>  --> to be turned to MIN_EXPR.  */
823               if (ass_code != MAX_EXPR)
824                 return false;
825
826               minmax = MIN_EXPR;
827               if (operand_equal_for_phi_arg_p (op0, larger))
828                 bound = op1;
829               else if (operand_equal_for_phi_arg_p (op1, larger))
830                 bound = op0;
831               else
832                 return false;
833
834               /* We need BOUND <= SMALLER.  */
835               if (!integer_nonzerop (fold_build2 (LE_EXPR, boolean_type_node,
836                                                   bound, smaller)))
837                 return false;
838             }
839           else
840             return false;
841         }
842
843       /* Move the statement from the middle block.  */
844       bsi = bsi_last (cond_bb);
845       bsi_from = bsi_last (middle_bb);
846       bsi_move_before (&bsi_from, &bsi);
847     }
848
849   /* Emit the statement to compute min/max.  */
850   result = duplicate_ssa_name (PHI_RESULT (phi), NULL);
851   new = build2 (MODIFY_EXPR, type, result,
852                 build2 (minmax, type, arg0, arg1));
853   SSA_NAME_DEF_STMT (result) = new;
854   bsi = bsi_last (cond_bb);
855   bsi_insert_before (&bsi, new, BSI_NEW_STMT);
856
857   replace_phi_edge_with_variable (cond_bb, e1, phi, result);
858   return true;
859 }
860
861 /*  The function absolute_replacement does the main work of doing the absolute
862     replacement.  Return true if the replacement is done.  Otherwise return
863     false.
864     bb is the basic block where the replacement is going to be done on.  arg0
865     is argument 0 from the phi.  Likewise for arg1.  */
866
867 static bool
868 abs_replacement (basic_block cond_bb, basic_block middle_bb,
869                  edge e0 ATTRIBUTE_UNUSED, edge e1,
870                  tree phi, tree arg0, tree arg1)
871 {
872   tree result;
873   tree new, cond;
874   block_stmt_iterator bsi;
875   edge true_edge, false_edge;
876   tree assign;
877   edge e;
878   tree rhs, lhs;
879   bool negate;
880   enum tree_code cond_code;
881
882   /* If the type says honor signed zeros we cannot do this
883      optimization.  */
884   if (HONOR_SIGNED_ZEROS (TYPE_MODE (TREE_TYPE (arg1))))
885     return false;
886
887   /* OTHER_BLOCK must have only one executable statement which must have the
888      form arg0 = -arg1 or arg1 = -arg0.  */
889
890   assign = last_and_only_stmt (middle_bb);
891   /* If we did not find the proper negation assignment, then we can not
892      optimize.  */
893   if (assign == NULL)
894     return false;
895       
896   /* If we got here, then we have found the only executable statement
897      in OTHER_BLOCK.  If it is anything other than arg = -arg1 or
898      arg1 = -arg0, then we can not optimize.  */
899   if (TREE_CODE (assign) != MODIFY_EXPR)
900     return false;
901
902   lhs = TREE_OPERAND (assign, 0);
903   rhs = TREE_OPERAND (assign, 1);
904
905   if (TREE_CODE (rhs) != NEGATE_EXPR)
906     return false;
907
908   rhs = TREE_OPERAND (rhs, 0);
909               
910   /* The assignment has to be arg0 = -arg1 or arg1 = -arg0.  */
911   if (!(lhs == arg0 && rhs == arg1)
912       && !(lhs == arg1 && rhs == arg0))
913     return false;
914
915   cond = COND_EXPR_COND (last_stmt (cond_bb));
916   result = PHI_RESULT (phi);
917
918   /* Only relationals comparing arg[01] against zero are interesting.  */
919   cond_code = TREE_CODE (cond);
920   if (cond_code != GT_EXPR && cond_code != GE_EXPR
921       && cond_code != LT_EXPR && cond_code != LE_EXPR)
922     return false;
923
924   /* Make sure the conditional is arg[01] OP y.  */
925   if (TREE_OPERAND (cond, 0) != rhs)
926     return false;
927
928   if (FLOAT_TYPE_P (TREE_TYPE (TREE_OPERAND (cond, 1)))
929                ? real_zerop (TREE_OPERAND (cond, 1))
930                : integer_zerop (TREE_OPERAND (cond, 1)))
931     ;
932   else
933     return false;
934
935   /* We need to know which is the true edge and which is the false
936      edge so that we know if have abs or negative abs.  */
937   extract_true_false_edges_from_block (cond_bb, &true_edge, &false_edge);
938
939   /* For GT_EXPR/GE_EXPR, if the true edge goes to OTHER_BLOCK, then we
940      will need to negate the result.  Similarly for LT_EXPR/LE_EXPR if
941      the false edge goes to OTHER_BLOCK.  */
942   if (cond_code == GT_EXPR || cond_code == GE_EXPR)
943     e = true_edge;
944   else
945     e = false_edge;
946
947   if (e->dest == middle_bb)
948     negate = true;
949   else
950     negate = false;
951
952   result = duplicate_ssa_name (result, NULL);
953
954   if (negate)
955     {
956       tree tmp = create_tmp_var (TREE_TYPE (result), NULL);
957       add_referenced_tmp_var (tmp);
958       lhs = make_ssa_name (tmp, NULL);
959     }
960   else
961     lhs = result;
962
963   /* Build the modify expression with abs expression.  */
964   new = build2 (MODIFY_EXPR, TREE_TYPE (lhs),
965                 lhs, build1 (ABS_EXPR, TREE_TYPE (lhs), rhs));
966   SSA_NAME_DEF_STMT (lhs) = new;
967
968   bsi = bsi_last (cond_bb);
969   bsi_insert_before (&bsi, new, BSI_NEW_STMT);
970
971   if (negate)
972     {
973       /* Get the right BSI.  We want to insert after the recently
974          added ABS_EXPR statement (which we know is the first statement
975          in the block.  */
976       new = build2 (MODIFY_EXPR, TREE_TYPE (result),
977                     result, build1 (NEGATE_EXPR, TREE_TYPE (lhs), lhs));
978       SSA_NAME_DEF_STMT (result) = new;
979
980       bsi_insert_after (&bsi, new, BSI_NEW_STMT);
981     }
982
983   replace_phi_edge_with_variable (cond_bb, e1, phi, result);
984
985   /* Note that we optimized this PHI.  */
986   return true;
987 }
988
989
990 /* Always do these optimizations if we have SSA
991    trees to work on.  */
992 static bool
993 gate_phiopt (void)
994 {
995   return 1;
996 }
997
998 struct tree_opt_pass pass_phiopt =
999 {
1000   "phiopt",                             /* name */
1001   gate_phiopt,                          /* gate */
1002   tree_ssa_phiopt,                      /* execute */
1003   NULL,                                 /* sub */
1004   NULL,                                 /* next */
1005   0,                                    /* static_pass_number */
1006   TV_TREE_PHIOPT,                       /* tv_id */
1007   PROP_cfg | PROP_ssa | PROP_alias,     /* properties_required */
1008   0,                                    /* properties_provided */
1009   0,                                    /* properties_destroyed */
1010   0,                                    /* todo_flags_start */
1011   TODO_cleanup_cfg
1012     | TODO_dump_func
1013     | TODO_ggc_collect
1014     | TODO_verify_ssa
1015     | TODO_verify_flow
1016     | TODO_verify_stmts,                /* todo_flags_finish */
1017   0                                     /* letter */
1018 };