xref: /netbsd-src/external/gpl3/gcc.old/dist/gcc/tree-ssa-ifcombine.c (revision 07ece4eabb6d327c320416d49d51617a7c0fb3be)
1 /* Combining of if-expressions on trees.
2    Copyright (C) 2007, 2008 Free Software Foundation, Inc.
3    Contributed by Richard Guenther <rguenther@suse.de>
4 
5 This file is part of GCC.
6 
7 GCC is free software; you can redistribute it and/or modify
8 it under the terms of the GNU General Public License as published by
9 the Free Software Foundation; either version 3, or (at your option)
10 any later version.
11 
12 GCC is distributed in the hope that it will be useful,
13 but WITHOUT ANY WARRANTY; without even the implied warranty of
14 MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE.  See the
15 GNU General Public License for more details.
16 
17 You should have received a copy of the GNU General Public License
18 along with GCC; see the file COPYING3.  If not see
19 <http://www.gnu.org/licenses/>.  */
20 
21 #include "config.h"
22 #include "system.h"
23 #include "coretypes.h"
24 #include "tm.h"
25 #include "tree.h"
26 #include "basic-block.h"
27 #include "timevar.h"
28 #include "diagnostic.h"
29 #include "tree-flow.h"
30 #include "tree-pass.h"
31 #include "tree-dump.h"
32 
33 /* This pass combines COND_EXPRs to simplify control flow.  It
34    currently recognizes bit tests and comparisons in chains that
35    represent logical and or logical or of two COND_EXPRs.
36 
37    It does so by walking basic blocks in a approximate reverse
38    post-dominator order and trying to match CFG patterns that
39    represent logical and or logical or of two COND_EXPRs.
40    Transformations are done if the COND_EXPR conditions match
41    either
42 
43      1. two single bit tests X & (1 << Yn) (for logical and)
44 
45      2. two bit tests X & Yn (for logical or)
46 
47      3. two comparisons X OPn Y (for logical or)
48 
49    To simplify this pass, removing basic blocks and dead code
50    is left to CFG cleanup and DCE.  */
51 
52 
53 /* Recognize a if-then-else CFG pattern starting to match with the
54    COND_BB basic-block containing the COND_EXPR.  The recognized
55    then end else blocks are stored to *THEN_BB and *ELSE_BB.  If
56    *THEN_BB and/or *ELSE_BB are already set, they are required to
57    match the then and else basic-blocks to make the pattern match.
58    Returns true if the pattern matched, false otherwise.  */
59 
60 static bool
61 recognize_if_then_else (basic_block cond_bb,
62 			basic_block *then_bb, basic_block *else_bb)
63 {
64   edge t, e;
65 
66   if (EDGE_COUNT (cond_bb->succs) != 2)
67     return false;
68 
69   /* Find the then/else edges.  */
70   t = EDGE_SUCC (cond_bb, 0);
71   e = EDGE_SUCC (cond_bb, 1);
72   if (!(t->flags & EDGE_TRUE_VALUE))
73     {
74       edge tmp = t;
75       t = e;
76       e = tmp;
77     }
78   if (!(t->flags & EDGE_TRUE_VALUE)
79       || !(e->flags & EDGE_FALSE_VALUE))
80     return false;
81 
82   /* Check if the edge destinations point to the required block.  */
83   if (*then_bb
84       && t->dest != *then_bb)
85     return false;
86   if (*else_bb
87       && e->dest != *else_bb)
88     return false;
89 
90   if (!*then_bb)
91     *then_bb = t->dest;
92   if (!*else_bb)
93     *else_bb = e->dest;
94 
95   return true;
96 }
97 
98 /* Verify if the basic block BB does not have side-effects.  Return
99    true in this case, else false.  */
100 
101 static bool
102 bb_no_side_effects_p (basic_block bb)
103 {
104   gimple_stmt_iterator gsi;
105 
106   for (gsi = gsi_start_bb (bb); !gsi_end_p (gsi); gsi_next (&gsi))
107     {
108       gimple stmt = gsi_stmt (gsi);
109 
110       if (gimple_has_volatile_ops (stmt)
111 	  || gimple_vuse (stmt))
112 	return false;
113     }
114 
115   return true;
116 }
117 
118 /* Verify if all PHI node arguments in DEST for edges from BB1 or
119    BB2 to DEST are the same.  This makes the CFG merge point
120    free from side-effects.  Return true in this case, else false.  */
121 
122 static bool
123 same_phi_args_p (basic_block bb1, basic_block bb2, basic_block dest)
124 {
125   edge e1 = find_edge (bb1, dest);
126   edge e2 = find_edge (bb2, dest);
127   gimple_stmt_iterator gsi;
128   gimple phi;
129 
130   for (gsi = gsi_start_phis (dest); !gsi_end_p (gsi); gsi_next (&gsi))
131     {
132       phi = gsi_stmt (gsi);
133       if (!operand_equal_p (PHI_ARG_DEF_FROM_EDGE (phi, e1),
134 			    PHI_ARG_DEF_FROM_EDGE (phi, e2), 0))
135         return false;
136     }
137 
138   return true;
139 }
140 
141 /* Return the best representative SSA name for CANDIDATE which is used
142    in a bit test.  */
143 
144 static tree
145 get_name_for_bit_test (tree candidate)
146 {
147   /* Skip single-use names in favor of using the name from a
148      non-widening conversion definition.  */
149   if (TREE_CODE (candidate) == SSA_NAME
150       && has_single_use (candidate))
151     {
152       gimple def_stmt = SSA_NAME_DEF_STMT (candidate);
153       if (is_gimple_assign (def_stmt)
154 	  && CONVERT_EXPR_CODE_P (gimple_assign_rhs_code (def_stmt)))
155 	{
156 	  if (TYPE_PRECISION (TREE_TYPE (candidate))
157 	      <= TYPE_PRECISION (TREE_TYPE (gimple_assign_rhs1 (def_stmt))))
158 	    return gimple_assign_rhs1 (def_stmt);
159 	}
160     }
161 
162   return candidate;
163 }
164 
165 /* Recognize a single bit test pattern in GIMPLE_COND and its defining
166    statements.  Store the name being tested in *NAME and the bit
167    in *BIT.  The GIMPLE_COND computes *NAME & (1 << *BIT).
168    Returns true if the pattern matched, false otherwise.  */
169 
170 static bool
171 recognize_single_bit_test (gimple cond, tree *name, tree *bit)
172 {
173   gimple stmt;
174 
175   /* Get at the definition of the result of the bit test.  */
176   if (gimple_cond_code (cond) != NE_EXPR
177       || TREE_CODE (gimple_cond_lhs (cond)) != SSA_NAME
178       || !integer_zerop (gimple_cond_rhs (cond)))
179     return false;
180   stmt = SSA_NAME_DEF_STMT (gimple_cond_lhs (cond));
181   if (!is_gimple_assign (stmt))
182     return false;
183 
184   /* Look at which bit is tested.  One form to recognize is
185      D.1985_5 = state_3(D) >> control1_4(D);
186      D.1986_6 = (int) D.1985_5;
187      D.1987_7 = op0 & 1;
188      if (D.1987_7 != 0)  */
189   if (gimple_assign_rhs_code (stmt) == BIT_AND_EXPR
190       && integer_onep (gimple_assign_rhs2 (stmt))
191       && TREE_CODE (gimple_assign_rhs1 (stmt)) == SSA_NAME)
192     {
193       tree orig_name = gimple_assign_rhs1 (stmt);
194 
195       /* Look through copies and conversions to eventually
196 	 find the stmt that computes the shift.  */
197       stmt = SSA_NAME_DEF_STMT (orig_name);
198 
199       while (is_gimple_assign (stmt)
200 	     && ((CONVERT_EXPR_CODE_P (gimple_assign_rhs_code (stmt))
201 		  && (TYPE_PRECISION (TREE_TYPE (gimple_assign_lhs (stmt)))
202 		      <= TYPE_PRECISION (TREE_TYPE (gimple_assign_rhs1 (stmt)))))
203 		 || gimple_assign_ssa_name_copy_p (stmt)))
204 	stmt = SSA_NAME_DEF_STMT (gimple_assign_rhs1 (stmt));
205 
206       /* If we found such, decompose it.  */
207       if (is_gimple_assign (stmt)
208 	  && gimple_assign_rhs_code (stmt) == RSHIFT_EXPR)
209 	{
210 	  /* op0 & (1 << op1) */
211 	  *bit = gimple_assign_rhs2 (stmt);
212 	  *name = gimple_assign_rhs1 (stmt);
213 	}
214       else
215 	{
216 	  /* t & 1 */
217 	  *bit = integer_zero_node;
218 	  *name = get_name_for_bit_test (orig_name);
219 	}
220 
221       return true;
222     }
223 
224   /* Another form is
225      D.1987_7 = op0 & (1 << CST)
226      if (D.1987_7 != 0)  */
227   if (gimple_assign_rhs_code (stmt) == BIT_AND_EXPR
228       && TREE_CODE (gimple_assign_rhs1 (stmt)) == SSA_NAME
229       && integer_pow2p (gimple_assign_rhs2 (stmt)))
230     {
231       *name = gimple_assign_rhs1 (stmt);
232       *bit = build_int_cst (integer_type_node,
233 			    tree_log2 (gimple_assign_rhs2 (stmt)));
234       return true;
235     }
236 
237   /* Another form is
238      D.1986_6 = 1 << control1_4(D)
239      D.1987_7 = op0 & D.1986_6
240      if (D.1987_7 != 0)  */
241   if (gimple_assign_rhs_code (stmt) == BIT_AND_EXPR
242       && TREE_CODE (gimple_assign_rhs1 (stmt)) == SSA_NAME
243       && TREE_CODE (gimple_assign_rhs2 (stmt)) == SSA_NAME)
244     {
245       gimple tmp;
246 
247       /* Both arguments of the BIT_AND_EXPR can be the single-bit
248 	 specifying expression.  */
249       tmp = SSA_NAME_DEF_STMT (gimple_assign_rhs1 (stmt));
250       if (is_gimple_assign (tmp)
251 	  && gimple_assign_rhs_code (tmp) == LSHIFT_EXPR
252 	  && integer_onep (gimple_assign_rhs1 (tmp)))
253 	{
254 	  *name = gimple_assign_rhs2 (stmt);
255 	  *bit = gimple_assign_rhs2 (tmp);
256 	  return true;
257 	}
258 
259       tmp = SSA_NAME_DEF_STMT (gimple_assign_rhs2 (stmt));
260       if (is_gimple_assign (tmp)
261 	  && gimple_assign_rhs_code (tmp) == LSHIFT_EXPR
262 	  && integer_onep (gimple_assign_rhs1 (tmp)))
263 	{
264 	  *name = gimple_assign_rhs1 (stmt);
265 	  *bit = gimple_assign_rhs2 (tmp);
266 	  return true;
267 	}
268     }
269 
270   return false;
271 }
272 
273 /* Recognize a bit test pattern in a GIMPLE_COND and its defining
274    statements.  Store the name being tested in *NAME and the bits
275    in *BITS.  The COND_EXPR computes *NAME & *BITS.
276    Returns true if the pattern matched, false otherwise.  */
277 
278 static bool
279 recognize_bits_test (gimple cond, tree *name, tree *bits)
280 {
281   gimple stmt;
282 
283   /* Get at the definition of the result of the bit test.  */
284   if (gimple_cond_code (cond) != NE_EXPR
285       || TREE_CODE (gimple_cond_lhs (cond)) != SSA_NAME
286       || !integer_zerop (gimple_cond_rhs (cond)))
287     return false;
288   stmt = SSA_NAME_DEF_STMT (gimple_cond_lhs (cond));
289   if (!is_gimple_assign (stmt)
290       || gimple_assign_rhs_code (stmt) != BIT_AND_EXPR)
291     return false;
292 
293   *name = get_name_for_bit_test (gimple_assign_rhs1 (stmt));
294   *bits = gimple_assign_rhs2 (stmt);
295 
296   return true;
297 }
298 
299 /* If-convert on a and pattern with a common else block.  The inner
300    if is specified by its INNER_COND_BB, the outer by OUTER_COND_BB.
301    Returns true if the edges to the common else basic-block were merged.  */
302 
303 static bool
304 ifcombine_ifandif (basic_block inner_cond_bb, basic_block outer_cond_bb)
305 {
306   gimple_stmt_iterator gsi;
307   gimple inner_cond, outer_cond;
308   tree name1, name2, bit1, bit2;
309 
310   inner_cond = last_stmt (inner_cond_bb);
311   if (!inner_cond
312       || gimple_code (inner_cond) != GIMPLE_COND)
313     return false;
314 
315   outer_cond = last_stmt (outer_cond_bb);
316   if (!outer_cond
317       || gimple_code (outer_cond) != GIMPLE_COND)
318     return false;
319 
320   /* See if we test a single bit of the same name in both tests.  In
321      that case remove the outer test, merging both else edges,
322      and change the inner one to test for
323      name & (bit1 | bit2) == (bit1 | bit2).  */
324   if (recognize_single_bit_test (inner_cond, &name1, &bit1)
325       && recognize_single_bit_test (outer_cond, &name2, &bit2)
326       && name1 == name2)
327     {
328       tree t, t2;
329 
330       /* Do it.  */
331       gsi = gsi_for_stmt (inner_cond);
332       t = fold_build2 (LSHIFT_EXPR, TREE_TYPE (name1),
333 		       build_int_cst (TREE_TYPE (name1), 1), bit1);
334       t2 = fold_build2 (LSHIFT_EXPR, TREE_TYPE (name1),
335 		        build_int_cst (TREE_TYPE (name1), 1), bit2);
336       t = fold_build2 (BIT_IOR_EXPR, TREE_TYPE (name1), t, t2);
337       t = force_gimple_operand_gsi (&gsi, t, true, NULL_TREE,
338 				    true, GSI_SAME_STMT);
339       t2 = fold_build2 (BIT_AND_EXPR, TREE_TYPE (name1), name1, t);
340       t2 = force_gimple_operand_gsi (&gsi, t2, true, NULL_TREE,
341 				     true, GSI_SAME_STMT);
342       t = fold_build2 (EQ_EXPR, boolean_type_node, t2, t);
343       t = canonicalize_cond_expr_cond (t);
344       if (!t)
345 	return false;
346       gimple_cond_set_condition_from_tree (inner_cond, t);
347       update_stmt (inner_cond);
348 
349       /* Leave CFG optimization to cfg_cleanup.  */
350       gimple_cond_set_condition_from_tree (outer_cond, boolean_true_node);
351       update_stmt (outer_cond);
352 
353       if (dump_file)
354 	{
355 	  fprintf (dump_file, "optimizing double bit test to ");
356 	  print_generic_expr (dump_file, name1, 0);
357 	  fprintf (dump_file, " & T == T\nwith temporary T = (1 << ");
358 	  print_generic_expr (dump_file, bit1, 0);
359 	  fprintf (dump_file, ") | (1 << ");
360 	  print_generic_expr (dump_file, bit2, 0);
361 	  fprintf (dump_file, ")\n");
362 	}
363 
364       return true;
365     }
366 
367   /* See if we have two comparisons that we can merge into one.  */
368   else if (TREE_CODE_CLASS (gimple_cond_code (inner_cond)) == tcc_comparison
369 	   && TREE_CODE_CLASS (gimple_cond_code (outer_cond)) == tcc_comparison
370 	   && operand_equal_p (gimple_cond_lhs (inner_cond),
371 			       gimple_cond_lhs (outer_cond), 0)
372 	   && operand_equal_p (gimple_cond_rhs (inner_cond),
373 			       gimple_cond_rhs (outer_cond), 0))
374     {
375       enum tree_code code1 = gimple_cond_code (inner_cond);
376       enum tree_code code2 = gimple_cond_code (outer_cond);
377       tree t;
378 
379       if (!(t = combine_comparisons (UNKNOWN_LOCATION,
380 	      			     TRUTH_ANDIF_EXPR, code1, code2,
381 				     boolean_type_node,
382 				     gimple_cond_lhs (outer_cond),
383 				     gimple_cond_rhs (outer_cond))))
384 	return false;
385       t = canonicalize_cond_expr_cond (t);
386       if (!t)
387 	return false;
388       gimple_cond_set_condition_from_tree (inner_cond, t);
389       update_stmt (inner_cond);
390 
391       /* Leave CFG optimization to cfg_cleanup.  */
392       gimple_cond_set_condition_from_tree (outer_cond, boolean_true_node);
393       update_stmt (outer_cond);
394 
395       if (dump_file)
396 	{
397 	  fprintf (dump_file, "optimizing two comparisons to ");
398 	  print_generic_expr (dump_file, t, 0);
399 	  fprintf (dump_file, "\n");
400 	}
401 
402       return true;
403     }
404 
405   return false;
406 }
407 
408 /* If-convert on a or pattern with a common then block.  The inner
409    if is specified by its INNER_COND_BB, the outer by OUTER_COND_BB.
410    Returns true, if the edges leading to the common then basic-block
411    were merged.  */
412 
413 static bool
414 ifcombine_iforif (basic_block inner_cond_bb, basic_block outer_cond_bb)
415 {
416   gimple inner_cond, outer_cond;
417   tree name1, name2, bits1, bits2;
418 
419   inner_cond = last_stmt (inner_cond_bb);
420   if (!inner_cond
421       || gimple_code (inner_cond) != GIMPLE_COND)
422     return false;
423 
424   outer_cond = last_stmt (outer_cond_bb);
425   if (!outer_cond
426       || gimple_code (outer_cond) != GIMPLE_COND)
427     return false;
428 
429   /* See if we have two bit tests of the same name in both tests.
430      In that case remove the outer test and change the inner one to
431      test for name & (bits1 | bits2) != 0.  */
432   if (recognize_bits_test (inner_cond, &name1, &bits1)
433       && recognize_bits_test (outer_cond, &name2, &bits2))
434     {
435       gimple_stmt_iterator gsi;
436       tree t;
437 
438       /* Find the common name which is bit-tested.  */
439       if (name1 == name2)
440 	;
441       else if (bits1 == bits2)
442 	{
443 	  t = name2;
444 	  name2 = bits2;
445 	  bits2 = t;
446 	  t = name1;
447 	  name1 = bits1;
448 	  bits1 = t;
449 	}
450       else if (name1 == bits2)
451 	{
452 	  t = name2;
453 	  name2 = bits2;
454 	  bits2 = t;
455 	}
456       else if (bits1 == name2)
457 	{
458 	  t = name1;
459 	  name1 = bits1;
460 	  bits1 = t;
461 	}
462       else
463 	return false;
464 
465       /* As we strip non-widening conversions in finding a common
466          name that is tested make sure to end up with an integral
467 	 type for building the bit operations.  */
468       if (TYPE_PRECISION (TREE_TYPE (bits1))
469 	  >= TYPE_PRECISION (TREE_TYPE (bits2)))
470 	{
471 	  bits1 = fold_convert (unsigned_type_for (TREE_TYPE (bits1)), bits1);
472 	  name1 = fold_convert (TREE_TYPE (bits1), name1);
473 	  bits2 = fold_convert (unsigned_type_for (TREE_TYPE (bits2)), bits2);
474 	  bits2 = fold_convert (TREE_TYPE (bits1), bits2);
475 	}
476       else
477 	{
478 	  bits2 = fold_convert (unsigned_type_for (TREE_TYPE (bits2)), bits2);
479 	  name1 = fold_convert (TREE_TYPE (bits2), name1);
480 	  bits1 = fold_convert (unsigned_type_for (TREE_TYPE (bits1)), bits1);
481 	  bits1 = fold_convert (TREE_TYPE (bits2), bits1);
482 	}
483 
484       /* Do it.  */
485       gsi = gsi_for_stmt (inner_cond);
486       t = fold_build2 (BIT_IOR_EXPR, TREE_TYPE (name1), bits1, bits2);
487       t = force_gimple_operand_gsi (&gsi, t, true, NULL_TREE,
488 				    true, GSI_SAME_STMT);
489       t = fold_build2 (BIT_AND_EXPR, TREE_TYPE (name1), name1, t);
490       t = force_gimple_operand_gsi (&gsi, t, true, NULL_TREE,
491 				    true, GSI_SAME_STMT);
492       t = fold_build2 (NE_EXPR, boolean_type_node, t,
493 		       build_int_cst (TREE_TYPE (t), 0));
494       t = canonicalize_cond_expr_cond (t);
495       if (!t)
496 	return false;
497       gimple_cond_set_condition_from_tree (inner_cond, t);
498       update_stmt (inner_cond);
499 
500       /* Leave CFG optimization to cfg_cleanup.  */
501       gimple_cond_set_condition_from_tree (outer_cond, boolean_false_node);
502       update_stmt (outer_cond);
503 
504       if (dump_file)
505 	{
506 	  fprintf (dump_file, "optimizing bits or bits test to ");
507 	  print_generic_expr (dump_file, name1, 0);
508 	  fprintf (dump_file, " & T != 0\nwith temporary T = ");
509 	  print_generic_expr (dump_file, bits1, 0);
510 	  fprintf (dump_file, " | ");
511 	  print_generic_expr (dump_file, bits2, 0);
512 	  fprintf (dump_file, "\n");
513 	}
514 
515       return true;
516     }
517 
518   /* See if we have two comparisons that we can merge into one.
519      This happens for C++ operator overloading where for example
520      GE_EXPR is implemented as GT_EXPR || EQ_EXPR.  */
521   else if (TREE_CODE_CLASS (gimple_cond_code (inner_cond)) == tcc_comparison
522 	   && TREE_CODE_CLASS (gimple_cond_code (outer_cond)) == tcc_comparison
523 	   && operand_equal_p (gimple_cond_lhs (inner_cond),
524 			       gimple_cond_lhs (outer_cond), 0)
525 	   && operand_equal_p (gimple_cond_rhs (inner_cond),
526 			       gimple_cond_rhs (outer_cond), 0))
527     {
528       enum tree_code code1 = gimple_cond_code (inner_cond);
529       enum tree_code code2 = gimple_cond_code (outer_cond);
530       tree t;
531 
532       if (!(t = combine_comparisons (UNKNOWN_LOCATION,
533 	      			     TRUTH_ORIF_EXPR, code1, code2,
534 				     boolean_type_node,
535 				     gimple_cond_lhs (outer_cond),
536 				     gimple_cond_rhs (outer_cond))))
537 	return false;
538       t = canonicalize_cond_expr_cond (t);
539       if (!t)
540 	return false;
541       gimple_cond_set_condition_from_tree (inner_cond, t);
542       update_stmt (inner_cond);
543 
544       /* Leave CFG optimization to cfg_cleanup.  */
545       gimple_cond_set_condition_from_tree (outer_cond, boolean_false_node);
546       update_stmt (outer_cond);
547 
548       if (dump_file)
549 	{
550 	  fprintf (dump_file, "optimizing two comparisons to ");
551 	  print_generic_expr (dump_file, t, 0);
552 	  fprintf (dump_file, "\n");
553 	}
554 
555       return true;
556     }
557 
558   return false;
559 }
560 
561 /* Recognize a CFG pattern and dispatch to the appropriate
562    if-conversion helper.  We start with BB as the innermost
563    worker basic-block.  Returns true if a transformation was done.  */
564 
565 static bool
566 tree_ssa_ifcombine_bb (basic_block inner_cond_bb)
567 {
568   basic_block then_bb = NULL, else_bb = NULL;
569 
570   if (!recognize_if_then_else (inner_cond_bb, &then_bb, &else_bb))
571     return false;
572 
573   /* Recognize && and || of two conditions with a common
574      then/else block which entry edges we can merge.  That is:
575        if (a || b)
576 	 ;
577      and
578        if (a && b)
579 	 ;
580      This requires a single predecessor of the inner cond_bb.  */
581   if (single_pred_p (inner_cond_bb))
582     {
583       basic_block outer_cond_bb = single_pred (inner_cond_bb);
584 
585       /* The && form is characterized by a common else_bb with
586 	 the two edges leading to it mergable.  The latter is
587 	 guaranteed by matching PHI arguments in the else_bb and
588 	 the inner cond_bb having no side-effects.  */
589       if (recognize_if_then_else (outer_cond_bb, &inner_cond_bb, &else_bb)
590 	  && same_phi_args_p (outer_cond_bb, inner_cond_bb, else_bb)
591 	  && bb_no_side_effects_p (inner_cond_bb))
592 	{
593 	  /* We have
594 	       <outer_cond_bb>
595 		 if (q) goto inner_cond_bb; else goto else_bb;
596 	       <inner_cond_bb>
597 		 if (p) goto ...; else goto else_bb;
598 		 ...
599 	       <else_bb>
600 		 ...
601 	   */
602 	  return ifcombine_ifandif (inner_cond_bb, outer_cond_bb);
603 	}
604 
605       /* The || form is characterized by a common then_bb with the
606 	 two edges leading to it mergable.  The latter is guaranteed
607          by matching PHI arguments in the then_bb and the inner cond_bb
608 	 having no side-effects.  */
609       if (recognize_if_then_else (outer_cond_bb, &then_bb, &inner_cond_bb)
610 	  && same_phi_args_p (outer_cond_bb, inner_cond_bb, then_bb)
611 	  && bb_no_side_effects_p (inner_cond_bb))
612 	{
613 	  /* We have
614 	       <outer_cond_bb>
615 		 if (q) goto then_bb; else goto inner_cond_bb;
616 	       <inner_cond_bb>
617 		 if (q) goto then_bb; else goto ...;
618 	       <then_bb>
619 		 ...
620 	   */
621 	  return ifcombine_iforif (inner_cond_bb, outer_cond_bb);
622 	}
623     }
624 
625   return false;
626 }
627 
628 /* Main entry for the tree if-conversion pass.  */
629 
630 static unsigned int
631 tree_ssa_ifcombine (void)
632 {
633   basic_block *bbs;
634   bool cfg_changed = false;
635   int i;
636 
637   bbs = blocks_in_phiopt_order ();
638 
639   for (i = 0; i < n_basic_blocks - NUM_FIXED_BLOCKS; ++i)
640     {
641       basic_block bb = bbs[i];
642       gimple stmt = last_stmt (bb);
643 
644       if (stmt
645 	  && gimple_code (stmt) == GIMPLE_COND)
646 	cfg_changed |= tree_ssa_ifcombine_bb (bb);
647     }
648 
649   free (bbs);
650 
651   return cfg_changed ? TODO_cleanup_cfg : 0;
652 }
653 
654 static bool
655 gate_ifcombine (void)
656 {
657   return 1;
658 }
659 
660 struct gimple_opt_pass pass_tree_ifcombine =
661 {
662  {
663   GIMPLE_PASS,
664   "ifcombine",			/* name */
665   gate_ifcombine,		/* gate */
666   tree_ssa_ifcombine,		/* execute */
667   NULL,				/* sub */
668   NULL,				/* next */
669   0,				/* static_pass_number */
670   TV_TREE_IFCOMBINE,		/* tv_id */
671   PROP_cfg | PROP_ssa,		/* properties_required */
672   0,				/* properties_provided */
673   0,				/* properties_destroyed */
674   0,				/* todo_flags_start */
675   TODO_dump_func
676   | TODO_ggc_collect
677   | TODO_update_ssa
678   | TODO_verify_ssa		/* todo_flags_finish */
679  }
680 };
681