]> git.ipfire.org Git - thirdparty/gcc.git/blame - gcc/tree-ssa-ifcombine.c
2015-07-07 Andrew MacLeod <amacleod@redhat.com>
[thirdparty/gcc.git] / gcc / tree-ssa-ifcombine.c
CommitLineData
8530c7be 1/* Combining of if-expressions on trees.
d353bf18 2 Copyright (C) 2007-2015 Free Software Foundation, Inc.
8530c7be 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
8c4c00c1 9the Free Software Foundation; either version 3, or (at your option)
8530c7be 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
8c4c00c1 18along with GCC; see the file COPYING3. If not see
19<http://www.gnu.org/licenses/>. */
8530c7be 20
21#include "config.h"
22#include "system.h"
23#include "coretypes.h"
9ef16211 24#include "backend.h"
25#include "tree.h"
26#include "gimple.h"
27#include "rtl.h"
28#include "ssa.h"
b4c65f30 29/* rtl is needed only because arm back-end requires it for
30 BRANCH_COST. */
b4c65f30 31#include "tm_p.h"
b20a8bb4 32#include "alias.h"
b20a8bb4 33#include "fold-const.h"
9ed99284 34#include "stor-layout.h"
94ea8568 35#include "cfganal.h"
ce084dfc 36#include "tree-pretty-print.h"
bc61cadb 37#include "internal-fn.h"
38#include "gimple-fold.h"
dcf1a1ec 39#include "gimple-iterator.h"
e795d6e1 40#include "gimplify-me.h"
073c1fd5 41#include "tree-cfg.h"
8530c7be 42#include "tree-pass.h"
8530c7be 43
b4c65f30 44#ifndef LOGICAL_OP_NON_SHORT_CIRCUIT
45#define LOGICAL_OP_NON_SHORT_CIRCUIT \
46 (BRANCH_COST (optimize_function_for_speed_p (cfun), \
47 false) >= 2)
48#endif
49
8530c7be 50/* This pass combines COND_EXPRs to simplify control flow. It
51 currently recognizes bit tests and comparisons in chains that
52 represent logical and or logical or of two COND_EXPRs.
53
54 It does so by walking basic blocks in a approximate reverse
55 post-dominator order and trying to match CFG patterns that
56 represent logical and or logical or of two COND_EXPRs.
57 Transformations are done if the COND_EXPR conditions match
58 either
59
60 1. two single bit tests X & (1 << Yn) (for logical and)
61
62 2. two bit tests X & Yn (for logical or)
63
64 3. two comparisons X OPn Y (for logical or)
65
66 To simplify this pass, removing basic blocks and dead code
67 is left to CFG cleanup and DCE. */
68
69
70/* Recognize a if-then-else CFG pattern starting to match with the
71 COND_BB basic-block containing the COND_EXPR. The recognized
72 then end else blocks are stored to *THEN_BB and *ELSE_BB. If
73 *THEN_BB and/or *ELSE_BB are already set, they are required to
74 match the then and else basic-blocks to make the pattern match.
75 Returns true if the pattern matched, false otherwise. */
76
77static bool
78recognize_if_then_else (basic_block cond_bb,
79 basic_block *then_bb, basic_block *else_bb)
80{
81 edge t, e;
82
83 if (EDGE_COUNT (cond_bb->succs) != 2)
84 return false;
85
86 /* Find the then/else edges. */
87 t = EDGE_SUCC (cond_bb, 0);
88 e = EDGE_SUCC (cond_bb, 1);
89 if (!(t->flags & EDGE_TRUE_VALUE))
a4f59596 90 std::swap (t, e);
8530c7be 91 if (!(t->flags & EDGE_TRUE_VALUE)
92 || !(e->flags & EDGE_FALSE_VALUE))
93 return false;
94
95 /* Check if the edge destinations point to the required block. */
96 if (*then_bb
97 && t->dest != *then_bb)
98 return false;
99 if (*else_bb
100 && e->dest != *else_bb)
101 return false;
102
103 if (!*then_bb)
104 *then_bb = t->dest;
105 if (!*else_bb)
106 *else_bb = e->dest;
107
108 return true;
109}
110
111/* Verify if the basic block BB does not have side-effects. Return
112 true in this case, else false. */
113
114static bool
115bb_no_side_effects_p (basic_block bb)
116{
75a70cf9 117 gimple_stmt_iterator gsi;
8530c7be 118
75a70cf9 119 for (gsi = gsi_start_bb (bb); !gsi_end_p (gsi); gsi_next (&gsi))
8530c7be 120 {
75a70cf9 121 gimple stmt = gsi_stmt (gsi);
8530c7be 122
ab8f103c 123 if (is_gimple_debug (stmt))
124 continue;
125
b523dd6d 126 if (gimple_has_side_effects (stmt)
ab8f103c 127 || gimple_could_trap_p (stmt)
dd277d48 128 || gimple_vuse (stmt))
8530c7be 129 return false;
130 }
131
132 return true;
133}
134
9202fd6a 135/* Return true if BB is an empty forwarder block to TO_BB. */
136
137static bool
138forwarder_block_to (basic_block bb, basic_block to_bb)
139{
140 return empty_block_p (bb)
141 && single_succ_p (bb)
142 && single_succ (bb) == to_bb;
143}
144
8530c7be 145/* Verify if all PHI node arguments in DEST for edges from BB1 or
146 BB2 to DEST are the same. This makes the CFG merge point
147 free from side-effects. Return true in this case, else false. */
148
149static bool
150same_phi_args_p (basic_block bb1, basic_block bb2, basic_block dest)
151{
152 edge e1 = find_edge (bb1, dest);
153 edge e2 = find_edge (bb2, dest);
1a91d914 154 gphi_iterator gsi;
155 gphi *phi;
8530c7be 156
75a70cf9 157 for (gsi = gsi_start_phis (dest); !gsi_end_p (gsi); gsi_next (&gsi))
158 {
1a91d914 159 phi = gsi.phi ();
75a70cf9 160 if (!operand_equal_p (PHI_ARG_DEF_FROM_EDGE (phi, e1),
161 PHI_ARG_DEF_FROM_EDGE (phi, e2), 0))
162 return false;
163 }
8530c7be 164
165 return true;
166}
167
c9686d06 168/* Return the best representative SSA name for CANDIDATE which is used
169 in a bit test. */
170
171static tree
172get_name_for_bit_test (tree candidate)
173{
174 /* Skip single-use names in favor of using the name from a
175 non-widening conversion definition. */
176 if (TREE_CODE (candidate) == SSA_NAME
177 && has_single_use (candidate))
178 {
75a70cf9 179 gimple def_stmt = SSA_NAME_DEF_STMT (candidate);
180 if (is_gimple_assign (def_stmt)
854e8953 181 && CONVERT_EXPR_CODE_P (gimple_assign_rhs_code (def_stmt)))
c9686d06 182 {
75a70cf9 183 if (TYPE_PRECISION (TREE_TYPE (candidate))
184 <= TYPE_PRECISION (TREE_TYPE (gimple_assign_rhs1 (def_stmt))))
185 return gimple_assign_rhs1 (def_stmt);
c9686d06 186 }
187 }
188
189 return candidate;
190}
191
75a70cf9 192/* Recognize a single bit test pattern in GIMPLE_COND and its defining
8530c7be 193 statements. Store the name being tested in *NAME and the bit
75a70cf9 194 in *BIT. The GIMPLE_COND computes *NAME & (1 << *BIT).
8530c7be 195 Returns true if the pattern matched, false otherwise. */
196
197static bool
1a91d914 198recognize_single_bit_test (gcond *cond, tree *name, tree *bit, bool inv)
8530c7be 199{
75a70cf9 200 gimple stmt;
8530c7be 201
202 /* Get at the definition of the result of the bit test. */
6e6b952b 203 if (gimple_cond_code (cond) != (inv ? EQ_EXPR : NE_EXPR)
75a70cf9 204 || TREE_CODE (gimple_cond_lhs (cond)) != SSA_NAME
205 || !integer_zerop (gimple_cond_rhs (cond)))
8530c7be 206 return false;
75a70cf9 207 stmt = SSA_NAME_DEF_STMT (gimple_cond_lhs (cond));
208 if (!is_gimple_assign (stmt))
8530c7be 209 return false;
8530c7be 210
211 /* Look at which bit is tested. One form to recognize is
212 D.1985_5 = state_3(D) >> control1_4(D);
213 D.1986_6 = (int) D.1985_5;
214 D.1987_7 = op0 & 1;
215 if (D.1987_7 != 0) */
75a70cf9 216 if (gimple_assign_rhs_code (stmt) == BIT_AND_EXPR
217 && integer_onep (gimple_assign_rhs2 (stmt))
218 && TREE_CODE (gimple_assign_rhs1 (stmt)) == SSA_NAME)
8530c7be 219 {
75a70cf9 220 tree orig_name = gimple_assign_rhs1 (stmt);
d9022390 221
222 /* Look through copies and conversions to eventually
223 find the stmt that computes the shift. */
75a70cf9 224 stmt = SSA_NAME_DEF_STMT (orig_name);
225
226 while (is_gimple_assign (stmt)
854e8953 227 && ((CONVERT_EXPR_CODE_P (gimple_assign_rhs_code (stmt))
228 && (TYPE_PRECISION (TREE_TYPE (gimple_assign_lhs (stmt)))
48331bf4 229 <= TYPE_PRECISION (TREE_TYPE (gimple_assign_rhs1 (stmt))))
230 && TREE_CODE (gimple_assign_rhs1 (stmt)) == SSA_NAME)
854e8953 231 || gimple_assign_ssa_name_copy_p (stmt)))
232 stmt = SSA_NAME_DEF_STMT (gimple_assign_rhs1 (stmt));
8530c7be 233
d9022390 234 /* If we found such, decompose it. */
75a70cf9 235 if (is_gimple_assign (stmt)
236 && gimple_assign_rhs_code (stmt) == RSHIFT_EXPR)
8530c7be 237 {
238 /* op0 & (1 << op1) */
75a70cf9 239 *bit = gimple_assign_rhs2 (stmt);
240 *name = gimple_assign_rhs1 (stmt);
8530c7be 241 }
242 else
243 {
244 /* t & 1 */
d9022390 245 *bit = integer_zero_node;
c9686d06 246 *name = get_name_for_bit_test (orig_name);
8530c7be 247 }
248
249 return true;
250 }
251
252 /* Another form is
253 D.1987_7 = op0 & (1 << CST)
254 if (D.1987_7 != 0) */
75a70cf9 255 if (gimple_assign_rhs_code (stmt) == BIT_AND_EXPR
256 && TREE_CODE (gimple_assign_rhs1 (stmt)) == SSA_NAME
257 && integer_pow2p (gimple_assign_rhs2 (stmt)))
8530c7be 258 {
75a70cf9 259 *name = gimple_assign_rhs1 (stmt);
8530c7be 260 *bit = build_int_cst (integer_type_node,
75a70cf9 261 tree_log2 (gimple_assign_rhs2 (stmt)));
8530c7be 262 return true;
263 }
264
265 /* Another form is
266 D.1986_6 = 1 << control1_4(D)
267 D.1987_7 = op0 & D.1986_6
268 if (D.1987_7 != 0) */
75a70cf9 269 if (gimple_assign_rhs_code (stmt) == BIT_AND_EXPR
270 && TREE_CODE (gimple_assign_rhs1 (stmt)) == SSA_NAME
271 && TREE_CODE (gimple_assign_rhs2 (stmt)) == SSA_NAME)
8530c7be 272 {
75a70cf9 273 gimple tmp;
8530c7be 274
275 /* Both arguments of the BIT_AND_EXPR can be the single-bit
276 specifying expression. */
75a70cf9 277 tmp = SSA_NAME_DEF_STMT (gimple_assign_rhs1 (stmt));
278 if (is_gimple_assign (tmp)
279 && gimple_assign_rhs_code (tmp) == LSHIFT_EXPR
280 && integer_onep (gimple_assign_rhs1 (tmp)))
8530c7be 281 {
75a70cf9 282 *name = gimple_assign_rhs2 (stmt);
283 *bit = gimple_assign_rhs2 (tmp);
8530c7be 284 return true;
285 }
286
75a70cf9 287 tmp = SSA_NAME_DEF_STMT (gimple_assign_rhs2 (stmt));
288 if (is_gimple_assign (tmp)
289 && gimple_assign_rhs_code (tmp) == LSHIFT_EXPR
290 && integer_onep (gimple_assign_rhs1 (tmp)))
8530c7be 291 {
75a70cf9 292 *name = gimple_assign_rhs1 (stmt);
293 *bit = gimple_assign_rhs2 (tmp);
8530c7be 294 return true;
295 }
296 }
297
298 return false;
299}
300
75a70cf9 301/* Recognize a bit test pattern in a GIMPLE_COND and its defining
8530c7be 302 statements. Store the name being tested in *NAME and the bits
303 in *BITS. The COND_EXPR computes *NAME & *BITS.
304 Returns true if the pattern matched, false otherwise. */
305
306static bool
1a91d914 307recognize_bits_test (gcond *cond, tree *name, tree *bits, bool inv)
8530c7be 308{
75a70cf9 309 gimple stmt;
8530c7be 310
311 /* Get at the definition of the result of the bit test. */
6e6b952b 312 if (gimple_cond_code (cond) != (inv ? EQ_EXPR : NE_EXPR)
75a70cf9 313 || TREE_CODE (gimple_cond_lhs (cond)) != SSA_NAME
314 || !integer_zerop (gimple_cond_rhs (cond)))
8530c7be 315 return false;
75a70cf9 316 stmt = SSA_NAME_DEF_STMT (gimple_cond_lhs (cond));
317 if (!is_gimple_assign (stmt)
318 || gimple_assign_rhs_code (stmt) != BIT_AND_EXPR)
8530c7be 319 return false;
320
75a70cf9 321 *name = get_name_for_bit_test (gimple_assign_rhs1 (stmt));
322 *bits = gimple_assign_rhs2 (stmt);
8530c7be 323
324 return true;
325}
326
327/* If-convert on a and pattern with a common else block. The inner
328 if is specified by its INNER_COND_BB, the outer by OUTER_COND_BB.
6e6b952b 329 inner_inv, outer_inv and result_inv indicate whether the conditions
330 are inverted.
8530c7be 331 Returns true if the edges to the common else basic-block were merged. */
332
333static bool
6e6b952b 334ifcombine_ifandif (basic_block inner_cond_bb, bool inner_inv,
335 basic_block outer_cond_bb, bool outer_inv, bool result_inv)
8530c7be 336{
75a70cf9 337 gimple_stmt_iterator gsi;
1a91d914 338 gimple inner_stmt, outer_stmt;
339 gcond *inner_cond, *outer_cond;
6e6b952b 340 tree name1, name2, bit1, bit2, bits1, bits2;
8530c7be 341
1a91d914 342 inner_stmt = last_stmt (inner_cond_bb);
343 if (!inner_stmt
344 || gimple_code (inner_stmt) != GIMPLE_COND)
8530c7be 345 return false;
1a91d914 346 inner_cond = as_a <gcond *> (inner_stmt);
8530c7be 347
1a91d914 348 outer_stmt = last_stmt (outer_cond_bb);
349 if (!outer_stmt
350 || gimple_code (outer_stmt) != GIMPLE_COND)
8530c7be 351 return false;
1a91d914 352 outer_cond = as_a <gcond *> (outer_stmt);
8530c7be 353
354 /* See if we test a single bit of the same name in both tests. In
355 that case remove the outer test, merging both else edges,
356 and change the inner one to test for
357 name & (bit1 | bit2) == (bit1 | bit2). */
6e6b952b 358 if (recognize_single_bit_test (inner_cond, &name1, &bit1, inner_inv)
359 && recognize_single_bit_test (outer_cond, &name2, &bit2, outer_inv)
8530c7be 360 && name1 == name2)
361 {
362 tree t, t2;
363
364 /* Do it. */
75a70cf9 365 gsi = gsi_for_stmt (inner_cond);
8530c7be 366 t = fold_build2 (LSHIFT_EXPR, TREE_TYPE (name1),
9289fc25 367 build_int_cst (TREE_TYPE (name1), 1), bit1);
8530c7be 368 t2 = fold_build2 (LSHIFT_EXPR, TREE_TYPE (name1),
9289fc25 369 build_int_cst (TREE_TYPE (name1), 1), bit2);
8530c7be 370 t = fold_build2 (BIT_IOR_EXPR, TREE_TYPE (name1), t, t2);
75a70cf9 371 t = force_gimple_operand_gsi (&gsi, t, true, NULL_TREE,
372 true, GSI_SAME_STMT);
8530c7be 373 t2 = fold_build2 (BIT_AND_EXPR, TREE_TYPE (name1), name1, t);
75a70cf9 374 t2 = force_gimple_operand_gsi (&gsi, t2, true, NULL_TREE,
375 true, GSI_SAME_STMT);
6e6b952b 376 t = fold_build2 (result_inv ? NE_EXPR : EQ_EXPR,
377 boolean_type_node, t2, t);
b611dd5f 378 t = canonicalize_cond_expr_cond (t);
379 if (!t)
380 return false;
75a70cf9 381 gimple_cond_set_condition_from_tree (inner_cond, t);
8530c7be 382 update_stmt (inner_cond);
383
384 /* Leave CFG optimization to cfg_cleanup. */
6e6b952b 385 gimple_cond_set_condition_from_tree (outer_cond,
386 outer_inv ? boolean_false_node : boolean_true_node);
8530c7be 387 update_stmt (outer_cond);
388
389 if (dump_file)
390 {
391 fprintf (dump_file, "optimizing double bit test to ");
392 print_generic_expr (dump_file, name1, 0);
393 fprintf (dump_file, " & T == T\nwith temporary T = (1 << ");
394 print_generic_expr (dump_file, bit1, 0);
395 fprintf (dump_file, ") | (1 << ");
396 print_generic_expr (dump_file, bit2, 0);
397 fprintf (dump_file, ")\n");
398 }
399
400 return true;
401 }
402
8530c7be 403 /* See if we have two bit tests of the same name in both tests.
404 In that case remove the outer test and change the inner one to
405 test for name & (bits1 | bits2) != 0. */
6e6b952b 406 else if (recognize_bits_test (inner_cond, &name1, &bits1, !inner_inv)
407 && recognize_bits_test (outer_cond, &name2, &bits2, !outer_inv))
8530c7be 408 {
75a70cf9 409 gimple_stmt_iterator gsi;
8530c7be 410 tree t;
411
412 /* Find the common name which is bit-tested. */
413 if (name1 == name2)
414 ;
415 else if (bits1 == bits2)
416 {
dfcf26a5 417 std::swap (name2, bits2);
418 std::swap (name1, bits1);
8530c7be 419 }
420 else if (name1 == bits2)
dfcf26a5 421 std::swap (name2, bits2);
8530c7be 422 else if (bits1 == name2)
dfcf26a5 423 std::swap (name1, bits1);
8530c7be 424 else
425 return false;
426
2a8d660d 427 /* As we strip non-widening conversions in finding a common
428 name that is tested make sure to end up with an integral
429 type for building the bit operations. */
430 if (TYPE_PRECISION (TREE_TYPE (bits1))
431 >= TYPE_PRECISION (TREE_TYPE (bits2)))
432 {
433 bits1 = fold_convert (unsigned_type_for (TREE_TYPE (bits1)), bits1);
434 name1 = fold_convert (TREE_TYPE (bits1), name1);
435 bits2 = fold_convert (unsigned_type_for (TREE_TYPE (bits2)), bits2);
436 bits2 = fold_convert (TREE_TYPE (bits1), bits2);
437 }
438 else
439 {
440 bits2 = fold_convert (unsigned_type_for (TREE_TYPE (bits2)), bits2);
441 name1 = fold_convert (TREE_TYPE (bits2), name1);
442 bits1 = fold_convert (unsigned_type_for (TREE_TYPE (bits1)), bits1);
443 bits1 = fold_convert (TREE_TYPE (bits2), bits1);
444 }
445
8530c7be 446 /* Do it. */
75a70cf9 447 gsi = gsi_for_stmt (inner_cond);
8530c7be 448 t = fold_build2 (BIT_IOR_EXPR, TREE_TYPE (name1), bits1, bits2);
75a70cf9 449 t = force_gimple_operand_gsi (&gsi, t, true, NULL_TREE,
450 true, GSI_SAME_STMT);
8530c7be 451 t = fold_build2 (BIT_AND_EXPR, TREE_TYPE (name1), name1, t);
75a70cf9 452 t = force_gimple_operand_gsi (&gsi, t, true, NULL_TREE,
453 true, GSI_SAME_STMT);
6e6b952b 454 t = fold_build2 (result_inv ? NE_EXPR : EQ_EXPR, boolean_type_node, t,
75a70cf9 455 build_int_cst (TREE_TYPE (t), 0));
b611dd5f 456 t = canonicalize_cond_expr_cond (t);
457 if (!t)
458 return false;
75a70cf9 459 gimple_cond_set_condition_from_tree (inner_cond, t);
8530c7be 460 update_stmt (inner_cond);
461
462 /* Leave CFG optimization to cfg_cleanup. */
6e6b952b 463 gimple_cond_set_condition_from_tree (outer_cond,
464 outer_inv ? boolean_false_node : boolean_true_node);
8530c7be 465 update_stmt (outer_cond);
466
467 if (dump_file)
468 {
469 fprintf (dump_file, "optimizing bits or bits test to ");
470 print_generic_expr (dump_file, name1, 0);
471 fprintf (dump_file, " & T != 0\nwith temporary T = ");
472 print_generic_expr (dump_file, bits1, 0);
473 fprintf (dump_file, " | ");
474 print_generic_expr (dump_file, bits2, 0);
475 fprintf (dump_file, "\n");
476 }
477
478 return true;
479 }
480
6e6b952b 481 /* See if we have two comparisons that we can merge into one. */
482 else if (TREE_CODE_CLASS (gimple_cond_code (inner_cond)) == tcc_comparison
c82d157a 483 && TREE_CODE_CLASS (gimple_cond_code (outer_cond)) == tcc_comparison)
8530c7be 484 {
8530c7be 485 tree t;
6e6b952b 486 enum tree_code inner_cond_code = gimple_cond_code (inner_cond);
487 enum tree_code outer_cond_code = gimple_cond_code (outer_cond);
488
489 /* Invert comparisons if necessary (and possible). */
490 if (inner_inv)
491 inner_cond_code = invert_tree_comparison (inner_cond_code,
93633022 492 HONOR_NANS (gimple_cond_lhs (inner_cond)));
6e6b952b 493 if (inner_cond_code == ERROR_MARK)
494 return false;
495 if (outer_inv)
496 outer_cond_code = invert_tree_comparison (outer_cond_code,
93633022 497 HONOR_NANS (gimple_cond_lhs (outer_cond)));
6e6b952b 498 if (outer_cond_code == ERROR_MARK)
499 return false;
500 /* Don't return false so fast, try maybe_fold_or_comparisons? */
8530c7be 501
6e6b952b 502 if (!(t = maybe_fold_and_comparisons (inner_cond_code,
503 gimple_cond_lhs (inner_cond),
504 gimple_cond_rhs (inner_cond),
505 outer_cond_code,
506 gimple_cond_lhs (outer_cond),
507 gimple_cond_rhs (outer_cond))))
b4c65f30 508 {
509 tree t1, t2;
510 gimple_stmt_iterator gsi;
511 if (!LOGICAL_OP_NON_SHORT_CIRCUIT)
512 return false;
513 /* Only do this optimization if the inner bb contains only the conditional. */
514 if (!gsi_one_before_end_p (gsi_start_nondebug_after_labels_bb (inner_cond_bb)))
515 return false;
516 t1 = fold_build2_loc (gimple_location (inner_cond),
517 inner_cond_code,
518 boolean_type_node,
519 gimple_cond_lhs (inner_cond),
520 gimple_cond_rhs (inner_cond));
521 t2 = fold_build2_loc (gimple_location (outer_cond),
522 outer_cond_code,
523 boolean_type_node,
524 gimple_cond_lhs (outer_cond),
525 gimple_cond_rhs (outer_cond));
526 t = fold_build2_loc (gimple_location (inner_cond),
527 TRUTH_AND_EXPR, boolean_type_node, t1, t2);
528 if (result_inv)
529 {
530 t = fold_build1 (TRUTH_NOT_EXPR, TREE_TYPE (t), t);
531 result_inv = false;
532 }
533 gsi = gsi_for_stmt (inner_cond);
534 t = force_gimple_operand_gsi_1 (&gsi, t, is_gimple_condexpr, NULL, true,
535 GSI_SAME_STMT);
536 }
6e6b952b 537 if (result_inv)
538 t = fold_build1 (TRUTH_NOT_EXPR, TREE_TYPE (t), t);
a7392604 539 t = canonicalize_cond_expr_cond (t);
540 if (!t)
541 return false;
75a70cf9 542 gimple_cond_set_condition_from_tree (inner_cond, t);
8530c7be 543 update_stmt (inner_cond);
544
545 /* Leave CFG optimization to cfg_cleanup. */
6e6b952b 546 gimple_cond_set_condition_from_tree (outer_cond,
547 outer_inv ? boolean_false_node : boolean_true_node);
8530c7be 548 update_stmt (outer_cond);
549
550 if (dump_file)
551 {
552 fprintf (dump_file, "optimizing two comparisons to ");
553 print_generic_expr (dump_file, t, 0);
554 fprintf (dump_file, "\n");
555 }
556
557 return true;
558 }
559
560 return false;
561}
562
9202fd6a 563/* Helper function for tree_ssa_ifcombine_bb. Recognize a CFG pattern and
564 dispatch to the appropriate if-conversion helper for a particular
565 set of INNER_COND_BB, OUTER_COND_BB, THEN_BB and ELSE_BB.
566 PHI_PRED_BB should be one of INNER_COND_BB, THEN_BB or ELSE_BB. */
567
568static bool
569tree_ssa_ifcombine_bb_1 (basic_block inner_cond_bb, basic_block outer_cond_bb,
570 basic_block then_bb, basic_block else_bb,
571 basic_block phi_pred_bb)
572{
573 /* The && form is characterized by a common else_bb with
574 the two edges leading to it mergable. The latter is
575 guaranteed by matching PHI arguments in the else_bb and
576 the inner cond_bb having no side-effects. */
577 if (phi_pred_bb != else_bb
578 && recognize_if_then_else (outer_cond_bb, &inner_cond_bb, &else_bb)
579 && same_phi_args_p (outer_cond_bb, phi_pred_bb, else_bb)
580 && bb_no_side_effects_p (inner_cond_bb))
581 {
582 /* We have
583 <outer_cond_bb>
584 if (q) goto inner_cond_bb; else goto else_bb;
585 <inner_cond_bb>
586 if (p) goto ...; else goto else_bb;
587 ...
588 <else_bb>
589 ...
590 */
591 return ifcombine_ifandif (inner_cond_bb, false, outer_cond_bb, false,
592 false);
593 }
594
595 /* And a version where the outer condition is negated. */
596 if (phi_pred_bb != else_bb
597 && recognize_if_then_else (outer_cond_bb, &else_bb, &inner_cond_bb)
598 && same_phi_args_p (outer_cond_bb, phi_pred_bb, else_bb)
599 && bb_no_side_effects_p (inner_cond_bb))
600 {
601 /* We have
602 <outer_cond_bb>
603 if (q) goto else_bb; else goto inner_cond_bb;
604 <inner_cond_bb>
605 if (p) goto ...; else goto else_bb;
606 ...
607 <else_bb>
608 ...
609 */
610 return ifcombine_ifandif (inner_cond_bb, false, outer_cond_bb, true,
611 false);
612 }
613
614 /* The || form is characterized by a common then_bb with the
615 two edges leading to it mergable. The latter is guaranteed
616 by matching PHI arguments in the then_bb and the inner cond_bb
617 having no side-effects. */
618 if (phi_pred_bb != then_bb
619 && recognize_if_then_else (outer_cond_bb, &then_bb, &inner_cond_bb)
620 && same_phi_args_p (outer_cond_bb, phi_pred_bb, then_bb)
621 && bb_no_side_effects_p (inner_cond_bb))
622 {
623 /* We have
624 <outer_cond_bb>
625 if (q) goto then_bb; else goto inner_cond_bb;
626 <inner_cond_bb>
627 if (q) goto then_bb; else goto ...;
628 <then_bb>
629 ...
630 */
631 return ifcombine_ifandif (inner_cond_bb, true, outer_cond_bb, true,
632 true);
633 }
634
635 /* And a version where the outer condition is negated. */
636 if (phi_pred_bb != then_bb
637 && recognize_if_then_else (outer_cond_bb, &inner_cond_bb, &then_bb)
638 && same_phi_args_p (outer_cond_bb, phi_pred_bb, then_bb)
639 && bb_no_side_effects_p (inner_cond_bb))
640 {
641 /* We have
642 <outer_cond_bb>
643 if (q) goto inner_cond_bb; else goto then_bb;
644 <inner_cond_bb>
645 if (q) goto then_bb; else goto ...;
646 <then_bb>
647 ...
648 */
649 return ifcombine_ifandif (inner_cond_bb, true, outer_cond_bb, false,
650 true);
651 }
652
653 return false;
654}
655
8530c7be 656/* Recognize a CFG pattern and dispatch to the appropriate
657 if-conversion helper. We start with BB as the innermost
658 worker basic-block. Returns true if a transformation was done. */
659
660static bool
661tree_ssa_ifcombine_bb (basic_block inner_cond_bb)
662{
663 basic_block then_bb = NULL, else_bb = NULL;
664
665 if (!recognize_if_then_else (inner_cond_bb, &then_bb, &else_bb))
666 return false;
667
668 /* Recognize && and || of two conditions with a common
669 then/else block which entry edges we can merge. That is:
670 if (a || b)
671 ;
672 and
673 if (a && b)
674 ;
675 This requires a single predecessor of the inner cond_bb. */
676 if (single_pred_p (inner_cond_bb))
677 {
678 basic_block outer_cond_bb = single_pred (inner_cond_bb);
679
9202fd6a 680 if (tree_ssa_ifcombine_bb_1 (inner_cond_bb, outer_cond_bb,
681 then_bb, else_bb, inner_cond_bb))
682 return true;
6e6b952b 683
9202fd6a 684 if (forwarder_block_to (else_bb, then_bb))
6e6b952b 685 {
9202fd6a 686 /* Other possibilities for the && form, if else_bb is
687 empty forwarder block to then_bb. Compared to the above simpler
688 forms this can be treated as if then_bb and else_bb were swapped,
689 and the corresponding inner_cond_bb not inverted because of that.
690 For same_phi_args_p we look at equality of arguments between
691 edge from outer_cond_bb and the forwarder block. */
692 if (tree_ssa_ifcombine_bb_1 (inner_cond_bb, outer_cond_bb, else_bb,
693 then_bb, else_bb))
694 return true;
8530c7be 695 }
9202fd6a 696 else if (forwarder_block_to (then_bb, else_bb))
6e6b952b 697 {
9202fd6a 698 /* Other possibilities for the || form, if then_bb is
699 empty forwarder block to else_bb. Compared to the above simpler
700 forms this can be treated as if then_bb and else_bb were swapped,
701 and the corresponding inner_cond_bb not inverted because of that.
702 For same_phi_args_p we look at equality of arguments between
703 edge from outer_cond_bb and the forwarder block. */
704 if (tree_ssa_ifcombine_bb_1 (inner_cond_bb, outer_cond_bb, else_bb,
705 then_bb, then_bb))
706 return true;
8530c7be 707 }
708 }
709
710 return false;
711}
712
713/* Main entry for the tree if-conversion pass. */
714
65b0537f 715namespace {
716
717const pass_data pass_data_tree_ifcombine =
718{
719 GIMPLE_PASS, /* type */
720 "ifcombine", /* name */
721 OPTGROUP_NONE, /* optinfo_flags */
65b0537f 722 TV_TREE_IFCOMBINE, /* tv_id */
723 ( PROP_cfg | PROP_ssa ), /* properties_required */
724 0, /* properties_provided */
725 0, /* properties_destroyed */
726 0, /* todo_flags_start */
8b88439e 727 TODO_update_ssa, /* todo_flags_finish */
65b0537f 728};
729
730class pass_tree_ifcombine : public gimple_opt_pass
731{
732public:
733 pass_tree_ifcombine (gcc::context *ctxt)
734 : gimple_opt_pass (pass_data_tree_ifcombine, ctxt)
735 {}
736
737 /* opt_pass methods: */
738 virtual unsigned int execute (function *);
739
740}; // class pass_tree_ifcombine
741
742unsigned int
743pass_tree_ifcombine::execute (function *fun)
8530c7be 744{
745 basic_block *bbs;
746 bool cfg_changed = false;
747 int i;
748
ba4d2b2f 749 bbs = single_pred_before_succ_order ();
8a245b9d 750 calculate_dominance_info (CDI_DOMINATORS);
8530c7be 751
b4c65f30 752 /* Search every basic block for COND_EXPR we may be able to optimize.
753
754 We walk the blocks in order that guarantees that a block with
755 a single predecessor is processed after the predecessor.
756 This ensures that we collapse outter ifs before visiting the
757 inner ones, and also that we do not try to visit a removed
758 block. This is opposite of PHI-OPT, because we cascade the
759 combining rather than cascading PHIs. */
65b0537f 760 for (i = n_basic_blocks_for_fn (fun) - NUM_FIXED_BLOCKS - 1; i >= 0; i--)
8530c7be 761 {
762 basic_block bb = bbs[i];
75a70cf9 763 gimple stmt = last_stmt (bb);
8530c7be 764
765 if (stmt
75a70cf9 766 && gimple_code (stmt) == GIMPLE_COND)
8530c7be 767 cfg_changed |= tree_ssa_ifcombine_bb (bb);
768 }
769
770 free (bbs);
771
772 return cfg_changed ? TODO_cleanup_cfg : 0;
773}
774
cbe8bda8 775} // anon namespace
776
777gimple_opt_pass *
778make_pass_tree_ifcombine (gcc::context *ctxt)
779{
780 return new pass_tree_ifcombine (ctxt);
781}