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