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