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