]> git.ipfire.org Git - thirdparty/gcc.git/blame - gcc/tree-ssa-phiopt.c
* tree-flow-inline.h (set_default_def, default_def): Kill.
[thirdparty/gcc.git] / gcc / tree-ssa-phiopt.c
CommitLineData
4ee9c684 1/* Optimization of PHI nodes by converting them into straightline code.
20e5647c 2 Copyright (C) 2004, 2005 Free Software Foundation, Inc.
4ee9c684 3
4This file is part of GCC.
20e5647c 5
4ee9c684 6GCC is free software; you can redistribute it and/or modify it
7under the terms of the GNU General Public License as published by the
8Free Software Foundation; either version 2, or (at your option) any
9later version.
20e5647c 10
4ee9c684 11GCC is distributed in the hope that it will be useful, but WITHOUT
12ANY WARRANTY; without even the implied warranty of MERCHANTABILITY or
13FITNESS FOR A PARTICULAR PURPOSE. See the GNU General Public License
14for more details.
20e5647c 15
4ee9c684 16You should have received a copy of the GNU General Public License
17along with GCC; see the file COPYING. If not, write to the Free
67ce556b 18Software Foundation, 51 Franklin Street, Fifth Floor, Boston, MA
1902110-1301, USA. */
4ee9c684 20
21#include "config.h"
22#include "system.h"
23#include "coretypes.h"
24#include "tm.h"
4ee9c684 25#include "ggc.h"
26#include "tree.h"
27#include "rtl.h"
0beac6fc 28#include "flags.h"
4ee9c684 29#include "tm_p.h"
30#include "basic-block.h"
31#include "timevar.h"
32#include "diagnostic.h"
33#include "tree-flow.h"
34#include "tree-pass.h"
35#include "tree-dump.h"
36#include "langhooks.h"
37
38static void tree_ssa_phiopt (void);
a4844041 39static bool conditional_replacement (basic_block, basic_block,
33784d89 40 edge, edge, tree, tree, tree);
a4844041 41static bool value_replacement (basic_block, basic_block,
33784d89 42 edge, edge, tree, tree, tree);
a4844041 43static bool minmax_replacement (basic_block, basic_block,
194899bf 44 edge, edge, tree, tree, tree);
a4844041 45static bool abs_replacement (basic_block, basic_block,
33784d89 46 edge, edge, tree, tree, tree);
a4844041 47static void replace_phi_edge_with_variable (basic_block, edge, tree, tree);
194899bf 48static basic_block *blocks_in_phiopt_order (void);
902929aa 49
caac37c2 50/* This pass tries to replaces an if-then-else block with an
51 assignment. We have four kinds of transformations. Some of these
52 transformations are also performed by the ifcvt RTL optimizer.
53
54 Conditional Replacement
55 -----------------------
56
30c5ffd2 57 This transformation, implemented in conditional_replacement,
caac37c2 58 replaces
4ee9c684 59
60 bb0:
61 if (cond) goto bb2; else goto bb1;
62 bb1:
63 bb2:
caac37c2 64 x = PHI <0 (bb1), 1 (bb0), ...>;
4ee9c684 65
caac37c2 66 with
20e5647c 67
2ab0a163 68 bb0:
caac37c2 69 x' = cond;
70 goto bb2;
2ab0a163 71 bb2:
caac37c2 72 x = PHI <x' (bb0), ...>;
4ee9c684 73
caac37c2 74 We remove bb1 as it becomes unreachable. This occurs often due to
75 gimplification of conditionals.
20e5647c 76
caac37c2 77 Value Replacement
78 -----------------
79
80 This transformation, implemented in value_replacement, replaces
0beac6fc 81
82 bb0:
caac37c2 83 if (a != b) goto bb2; else goto bb1;
0beac6fc 84 bb1:
85 bb2:
caac37c2 86 x = PHI <a (bb1), b (bb0), ...>;
0beac6fc 87
caac37c2 88 with
0beac6fc 89
90 bb0:
0beac6fc 91 bb2:
caac37c2 92 x = PHI <b (bb0), ...>;
93
94 This opportunity can sometimes occur as a result of other
95 optimizations.
0beac6fc 96
caac37c2 97 ABS Replacement
98 ---------------
70512b93 99
caac37c2 100 This transformation, implemented in abs_replacement, replaces
70512b93 101
102 bb0:
caac37c2 103 if (a >= 0) goto bb2; else goto bb1;
70512b93 104 bb1:
caac37c2 105 x = -a;
70512b93 106 bb2:
caac37c2 107 x = PHI <x (bb1), a (bb0), ...>;
70512b93 108
caac37c2 109 with
70512b93 110
111 bb0:
caac37c2 112 x' = ABS_EXPR< a >;
70512b93 113 bb2:
caac37c2 114 x = PHI <x' (bb0), ...>;
115
116 MIN/MAX Replacement
117 -------------------
70512b93 118
caac37c2 119 This transformation, minmax_replacement replaces
194899bf 120
121 bb0:
caac37c2 122 if (a <= b) goto bb2; else goto bb1;
194899bf 123 bb1:
194899bf 124 bb2:
caac37c2 125 x = PHI <b (bb1), a (bb0), ...>;
194899bf 126
caac37c2 127 with
194899bf 128
caac37c2 129 bb0:
130 x' = MIN_EXPR (a, b)
131 bb2:
132 x = PHI <x' (bb0), ...>;
194899bf 133
30c5ffd2 134 A similar transformation is done for MAX_EXPR. */
70512b93 135
4ee9c684 136static void
137tree_ssa_phiopt (void)
138{
139 basic_block bb;
194899bf 140 basic_block *bb_order;
141 unsigned n, i;
142
143 /* Search every basic block for COND_EXPR we may be able to optimize.
144
145 We walk the blocks in order that guarantees that a block with
146 a single predecessor is processed before the predecessor.
147 This ensures that we collapse inner ifs before visiting the
148 outer ones, and also that we do not try to visit a removed
149 block. */
150 bb_order = blocks_in_phiopt_order ();
151 n = n_basic_blocks;
4ee9c684 152
194899bf 153 for (i = 0; i < n; i++)
4ee9c684 154 {
33784d89 155 tree cond_expr;
156 tree phi;
157 basic_block bb1, bb2;
158 edge e1, e2;
194899bf 159 tree arg0, arg1;
160
161 bb = bb_order[i];
20e5647c 162
33784d89 163 cond_expr = last_stmt (bb);
20e5647c 164 /* Check to see if the last statement is a COND_EXPR. */
33784d89 165 if (!cond_expr
166 || TREE_CODE (cond_expr) != COND_EXPR)
167 continue;
20e5647c 168
33784d89 169 e1 = EDGE_SUCC (bb, 0);
170 bb1 = e1->dest;
171 e2 = EDGE_SUCC (bb, 1);
172 bb2 = e2->dest;
20e5647c 173
33784d89 174 /* We cannot do the optimization on abnormal edges. */
175 if ((e1->flags & EDGE_ABNORMAL) != 0
176 || (e2->flags & EDGE_ABNORMAL) != 0)
177 continue;
20e5647c 178
33784d89 179 /* If either bb1's succ or bb2 or bb2's succ is non NULL. */
ea091dfd 180 if (EDGE_COUNT (bb1->succs) == 0
33784d89 181 || bb2 == NULL
ea091dfd 182 || EDGE_COUNT (bb2->succs) == 0)
33784d89 183 continue;
20e5647c 184
33784d89 185 /* Find the bb which is the fall through to the other. */
186 if (EDGE_SUCC (bb1, 0)->dest == bb2)
187 ;
188 else if (EDGE_SUCC (bb2, 0)->dest == bb1)
189 {
190 basic_block bb_tmp = bb1;
191 edge e_tmp = e1;
192 bb1 = bb2;
193 bb2 = bb_tmp;
194 e1 = e2;
195 e2 = e_tmp;
196 }
197 else
198 continue;
20e5647c 199
33784d89 200 e1 = EDGE_SUCC (bb1, 0);
20e5647c 201
33784d89 202 /* Make sure that bb1 is just a fall through. */
db5ba14c 203 if (!single_succ_p (bb1)
33784d89 204 || (e1->flags & EDGE_FALLTHRU) == 0)
205 continue;
20e5647c 206
3472707f 207 /* Also make sure that bb1 only have one predecessor and that it
208 is bb. */
ea091dfd 209 if (!single_pred_p (bb1)
210 || single_pred (bb1) != bb)
33784d89 211 continue;
20e5647c 212
33784d89 213 phi = phi_nodes (bb2);
4ee9c684 214
33784d89 215 /* Check to make sure that there is only one PHI node.
216 TODO: we could do it with more than one iff the other PHI nodes
217 have the same elements for these two edges. */
194899bf 218 if (!phi || PHI_CHAIN (phi) != NULL)
219 continue;
20e5647c 220
194899bf 221 arg0 = PHI_ARG_DEF_TREE (phi, e1->dest_idx);
222 arg1 = PHI_ARG_DEF_TREE (phi, e2->dest_idx);
20e5647c 223
3472707f 224 /* Something is wrong if we cannot find the arguments in the PHI
194899bf 225 node. */
226 gcc_assert (arg0 != NULL && arg1 != NULL);
20e5647c 227
194899bf 228 /* Do the replacement of conditional if it can be done. */
a4844041 229 if (conditional_replacement (bb, bb1, e1, e2, phi, arg0, arg1))
194899bf 230 ;
a4844041 231 else if (value_replacement (bb, bb1, e1, e2, phi, arg0, arg1))
194899bf 232 ;
a4844041 233 else if (abs_replacement (bb, bb1, e1, e2, phi, arg0, arg1))
194899bf 234 ;
235 else
a4844041 236 minmax_replacement (bb, bb1, e1, e2, phi, arg0, arg1);
194899bf 237 }
238
239 free (bb_order);
240}
241
242/* Returns the list of basic blocks in the function in an order that guarantees
243 that if a block X has just a single predecessor Y, then Y is after X in the
244 ordering. */
245
246static basic_block *
247blocks_in_phiopt_order (void)
248{
249 basic_block x, y;
250 basic_block *order = xmalloc (sizeof (basic_block) * n_basic_blocks);
251 unsigned n = n_basic_blocks, np, i;
252 sbitmap visited = sbitmap_alloc (last_basic_block + 2);
253
254#define MARK_VISITED(BB) (SET_BIT (visited, (BB)->index + 2))
255#define VISITED_P(BB) (TEST_BIT (visited, (BB)->index + 2))
256
257 sbitmap_zero (visited);
258
259 MARK_VISITED (ENTRY_BLOCK_PTR);
260 FOR_EACH_BB (x)
261 {
262 if (VISITED_P (x))
263 continue;
264
265 /* Walk the predecessors of x as long as they have precisely one
266 predecessor and add them to the list, so that they get stored
267 after x. */
268 for (y = x, np = 1;
269 single_pred_p (y) && !VISITED_P (single_pred (y));
270 y = single_pred (y))
271 np++;
272 for (y = x, i = n - np;
273 single_pred_p (y) && !VISITED_P (single_pred (y));
274 y = single_pred (y), i++)
275 {
276 order[i] = y;
277 MARK_VISITED (y);
2ab0a163 278 }
194899bf 279 order[i] = y;
280 MARK_VISITED (y);
281
282 gcc_assert (i == n - 1);
283 n -= np;
4ee9c684 284 }
194899bf 285
286 sbitmap_free (visited);
287 gcc_assert (n == 0);
288 return order;
289
290#undef MARK_VISITED
291#undef VISITED_P
4ee9c684 292}
293
70512b93 294/* Return TRUE if block BB has no executable statements, otherwise return
295 FALSE. */
c91e8223 296bool
70512b93 297empty_block_p (basic_block bb)
298{
299 block_stmt_iterator bsi;
300
301 /* BB must have no executable statements. */
302 bsi = bsi_start (bb);
303 while (!bsi_end_p (bsi)
304 && (TREE_CODE (bsi_stmt (bsi)) == LABEL_EXPR
305 || IS_EMPTY_STMT (bsi_stmt (bsi))))
306 bsi_next (&bsi);
20e5647c 307
70512b93 308 if (!bsi_end_p (bsi))
309 return false;
310
311 return true;
312}
313
fccee353 314/* Replace PHI node element whose edge is E in block BB with variable NEW.
33784d89 315 Remove the edge from COND_BLOCK which does not lead to BB (COND_BLOCK
902929aa 316 is known to have two edges, one of which must reach BB). */
317
318static void
a4844041 319replace_phi_edge_with_variable (basic_block cond_block,
33784d89 320 edge e, tree phi, tree new)
902929aa 321{
a4844041 322 basic_block bb = bb_for_stmt (phi);
0e1a77e1 323 basic_block block_to_remove;
33784d89 324 block_stmt_iterator bsi;
325
20e5647c 326 /* Change the PHI argument to new. */
22aa74c4 327 SET_USE (PHI_ARG_DEF_PTR (phi, e->dest_idx), new);
0e1a77e1 328
0e1a77e1 329 /* Remove the empty basic block. */
cd665a06 330 if (EDGE_SUCC (cond_block, 0)->dest == bb)
902929aa 331 {
cd665a06 332 EDGE_SUCC (cond_block, 0)->flags |= EDGE_FALLTHRU;
333 EDGE_SUCC (cond_block, 0)->flags &= ~(EDGE_TRUE_VALUE | EDGE_FALSE_VALUE);
81c5be57 334 EDGE_SUCC (cond_block, 0)->probability = REG_BR_PROB_BASE;
335 EDGE_SUCC (cond_block, 0)->count += EDGE_SUCC (cond_block, 1)->count;
0e1a77e1 336
cd665a06 337 block_to_remove = EDGE_SUCC (cond_block, 1)->dest;
902929aa 338 }
339 else
340 {
cd665a06 341 EDGE_SUCC (cond_block, 1)->flags |= EDGE_FALLTHRU;
342 EDGE_SUCC (cond_block, 1)->flags
902929aa 343 &= ~(EDGE_TRUE_VALUE | EDGE_FALSE_VALUE);
81c5be57 344 EDGE_SUCC (cond_block, 1)->probability = REG_BR_PROB_BASE;
345 EDGE_SUCC (cond_block, 1)->count += EDGE_SUCC (cond_block, 0)->count;
0e1a77e1 346
cd665a06 347 block_to_remove = EDGE_SUCC (cond_block, 0)->dest;
902929aa 348 }
0e1a77e1 349 delete_basic_block (block_to_remove);
20e5647c 350
902929aa 351 /* Eliminate the COND_EXPR at the end of COND_BLOCK. */
352 bsi = bsi_last (cond_block);
353 bsi_remove (&bsi);
20e5647c 354
902929aa 355 if (dump_file && (dump_flags & TDF_DETAILS))
356 fprintf (dump_file,
357 "COND_EXPR in block %d and PHI in block %d converted to straightline code.\n",
358 cond_block->index,
359 bb->index);
360}
361
362/* The function conditional_replacement does the main work of doing the
363 conditional replacement. Return true if the replacement is done.
364 Otherwise return false.
365 BB is the basic block where the replacement is going to be done on. ARG0
dac49aa5 366 is argument 0 from PHI. Likewise for ARG1. */
902929aa 367
368static bool
33784d89 369conditional_replacement (basic_block cond_bb, basic_block middle_bb,
a4844041 370 edge e0, edge e1, tree phi,
33784d89 371 tree arg0, tree arg1)
902929aa 372{
373 tree result;
374 tree old_result = NULL;
902929aa 375 tree new, cond;
376 block_stmt_iterator bsi;
377 edge true_edge, false_edge;
378 tree new_var = NULL;
33784d89 379 tree new_var1;
902929aa 380
381 /* The PHI arguments have the constants 0 and 1, then convert
382 it to the conditional. */
383 if ((integer_zerop (arg0) && integer_onep (arg1))
384 || (integer_zerop (arg1) && integer_onep (arg0)))
385 ;
386 else
387 return false;
20e5647c 388
33784d89 389 if (!empty_block_p (middle_bb))
902929aa 390 return false;
20e5647c 391
4ee9c684 392 /* If the condition is not a naked SSA_NAME and its type does not
2ab0a163 393 match the type of the result, then we have to create a new
394 variable to optimize this case as it would likely create
395 non-gimple code when the condition was converted to the
396 result's type. */
33784d89 397 cond = COND_EXPR_COND (last_stmt (cond_bb));
4ee9c684 398 result = PHI_RESULT (phi);
399 if (TREE_CODE (cond) != SSA_NAME
400 && !lang_hooks.types_compatible_p (TREE_TYPE (cond), TREE_TYPE (result)))
ae5a4794 401 {
b2a02a0e 402 tree tmp;
403
404 if (!COMPARISON_CLASS_P (cond))
405 return false;
406
407 tmp = create_tmp_var (TREE_TYPE (cond), NULL);
408 add_referenced_tmp_var (tmp);
409 new_var = make_ssa_name (tmp, NULL);
ae5a4794 410 old_result = cond;
411 cond = new_var;
412 }
20e5647c 413
4ee9c684 414 /* If the condition was a naked SSA_NAME and the type is not the
2ab0a163 415 same as the type of the result, then convert the type of the
416 condition. */
4ee9c684 417 if (!lang_hooks.types_compatible_p (TREE_TYPE (cond), TREE_TYPE (result)))
418 cond = fold_convert (TREE_TYPE (result), cond);
20e5647c 419
4ee9c684 420 /* We need to know which is the true edge and which is the false
2ab0a163 421 edge so that we know when to invert the condition below. */
33784d89 422 extract_true_false_edges_from_block (cond_bb, &true_edge, &false_edge);
20e5647c 423
1fa68a1f 424 /* Insert our new statement at the end of conditional block before the
33784d89 425 COND_EXPR. */
426 bsi = bsi_last (cond_bb);
427 bsi_insert_before (&bsi, build_empty_stmt (), BSI_NEW_STMT);
20e5647c 428
ae5a4794 429 if (old_result)
430 {
431 tree new1;
20e5647c 432
194899bf 433 new1 = build2 (TREE_CODE (old_result), TREE_TYPE (old_result),
434 TREE_OPERAND (old_result, 0),
435 TREE_OPERAND (old_result, 1));
20e5647c 436
194899bf 437 new1 = build2 (MODIFY_EXPR, TREE_TYPE (old_result), new_var, new1);
b2a02a0e 438 SSA_NAME_DEF_STMT (new_var) = new1;
439
ae5a4794 440 bsi_insert_after (&bsi, new1, BSI_NEW_STMT);
441 }
20e5647c 442
33784d89 443 new_var1 = duplicate_ssa_name (PHI_RESULT (phi), NULL);
20e5647c 444
445
4ee9c684 446 /* At this point we know we have a COND_EXPR with two successors.
2ab0a163 447 One successor is BB, the other successor is an empty block which
448 falls through into BB.
20e5647c 449
2ab0a163 450 There is a single PHI node at the join point (BB) and its arguments
451 are constants (0, 1).
20e5647c 452
2ab0a163 453 So, given the condition COND, and the two PHI arguments, we can
20e5647c 454 rewrite this PHI into non-branching code:
455
2ab0a163 456 dest = (COND) or dest = COND'
20e5647c 457
2ab0a163 458 We use the condition as-is if the argument associated with the
459 true edge has the value one or the argument associated with the
460 false edge as the value zero. Note that those conditions are not
461 the same since only one of the outgoing edges from the COND_EXPR
462 will directly reach BB and thus be associated with an argument. */
33784d89 463 if ((e0 == true_edge && integer_onep (arg0))
464 || (e0 == false_edge && integer_zerop (arg0))
465 || (e1 == true_edge && integer_onep (arg1))
466 || (e1 == false_edge && integer_zerop (arg1)))
4ee9c684 467 {
194899bf 468 new = build2 (MODIFY_EXPR, TREE_TYPE (new_var1), new_var1, cond);
4ee9c684 469 }
470 else
471 {
ae5a4794 472 tree cond1 = invert_truthvalue (cond);
20e5647c 473
ae5a4794 474 cond = cond1;
b2a02a0e 475
ae5a4794 476 /* If what we get back is a conditional expression, there is no
0beac6fc 477 way that it can be gimple. */
ae5a4794 478 if (TREE_CODE (cond) == COND_EXPR)
33784d89 479 {
480 release_ssa_name (new_var1);
20e5647c 481 return false;
33784d89 482 }
ae5a4794 483
b2a02a0e 484 /* If COND is not something we can expect to be reducible to a GIMPLE
485 condition, return early. */
486 if (is_gimple_cast (cond))
487 cond1 = TREE_OPERAND (cond, 0);
488 if (TREE_CODE (cond1) == TRUTH_NOT_EXPR
489 && !is_gimple_val (TREE_OPERAND (cond1, 0)))
490 {
491 release_ssa_name (new_var1);
492 return false;
493 }
494
ae5a4794 495 /* If what we get back is not gimple try to create it as gimple by
dac49aa5 496 using a temporary variable. */
4ee9c684 497 if (is_gimple_cast (cond)
498 && !is_gimple_val (TREE_OPERAND (cond, 0)))
2ab0a163 499 {
b2a02a0e 500 tree op0, tmp, cond_tmp;
20e5647c 501
b2a02a0e 502 /* Only "real" casts are OK here, not everything that is
503 acceptable to is_gimple_cast. Make sure we don't do
504 anything stupid here. */
505 gcc_assert (TREE_CODE (cond) == NOP_EXPR
506 || TREE_CODE (cond) == CONVERT_EXPR);
507
508 op0 = TREE_OPERAND (cond, 0);
509 tmp = create_tmp_var (TREE_TYPE (op0), NULL);
510 add_referenced_tmp_var (tmp);
511 cond_tmp = make_ssa_name (tmp, NULL);
512 new = build2 (MODIFY_EXPR, TREE_TYPE (cond_tmp), cond_tmp, op0);
513 SSA_NAME_DEF_STMT (cond_tmp) = new;
514
515 bsi_insert_after (&bsi, new, BSI_NEW_STMT);
516 cond = fold_convert (TREE_TYPE (result), cond_tmp);
33784d89 517 }
4ee9c684 518
194899bf 519 new = build2 (MODIFY_EXPR, TREE_TYPE (new_var1), new_var1, cond);
4ee9c684 520 }
20e5647c 521
33784d89 522 bsi_insert_after (&bsi, new, BSI_NEW_STMT);
20e5647c 523
33784d89 524 SSA_NAME_DEF_STMT (new_var1) = new;
20e5647c 525
a4844041 526 replace_phi_edge_with_variable (cond_bb, e1, phi, new_var1);
902929aa 527
4ee9c684 528 /* Note that we optimized this PHI. */
529 return true;
530}
531
0beac6fc 532/* The function value_replacement does the main work of doing the value
533 replacement. Return true if the replacement is done. Otherwise return
534 false.
535 BB is the basic block where the replacement is going to be done on. ARG0
dac49aa5 536 is argument 0 from the PHI. Likewise for ARG1. */
0beac6fc 537
538static bool
33784d89 539value_replacement (basic_block cond_bb, basic_block middle_bb,
a4844041 540 edge e0, edge e1, tree phi,
33784d89 541 tree arg0, tree arg1)
0beac6fc 542{
33784d89 543 tree cond;
0beac6fc 544 edge true_edge, false_edge;
545
546 /* If the type says honor signed zeros we cannot do this
dac49aa5 547 optimization. */
0beac6fc 548 if (HONOR_SIGNED_ZEROS (TYPE_MODE (TREE_TYPE (arg1))))
549 return false;
550
33784d89 551 if (!empty_block_p (middle_bb))
0beac6fc 552 return false;
553
33784d89 554 cond = COND_EXPR_COND (last_stmt (cond_bb));
0beac6fc 555
556 /* This transformation is only valid for equality comparisons. */
557 if (TREE_CODE (cond) != NE_EXPR && TREE_CODE (cond) != EQ_EXPR)
558 return false;
559
560 /* We need to know which is the true edge and which is the false
561 edge so that we know if have abs or negative abs. */
33784d89 562 extract_true_false_edges_from_block (cond_bb, &true_edge, &false_edge);
0beac6fc 563
564 /* At this point we know we have a COND_EXPR with two successors.
565 One successor is BB, the other successor is an empty block which
566 falls through into BB.
567
568 The condition for the COND_EXPR is known to be NE_EXPR or EQ_EXPR.
569
570 There is a single PHI node at the join point (BB) with two arguments.
571
572 We now need to verify that the two arguments in the PHI node match
573 the two arguments to the equality comparison. */
20e5647c 574
5373158f 575 if ((operand_equal_for_phi_arg_p (arg0, TREE_OPERAND (cond, 0))
576 && operand_equal_for_phi_arg_p (arg1, TREE_OPERAND (cond, 1)))
577 || (operand_equal_for_phi_arg_p (arg1, TREE_OPERAND (cond, 0))
578 && operand_equal_for_phi_arg_p (arg0, TREE_OPERAND (cond, 1))))
0beac6fc 579 {
580 edge e;
581 tree arg;
582
50737d20 583 /* For NE_EXPR, we want to build an assignment result = arg where
584 arg is the PHI argument associated with the true edge. For
585 EQ_EXPR we want the PHI argument associated with the false edge. */
0beac6fc 586 e = (TREE_CODE (cond) == NE_EXPR ? true_edge : false_edge);
50737d20 587
588 /* Unfortunately, E may not reach BB (it may instead have gone to
589 OTHER_BLOCK). If that is the case, then we want the single outgoing
590 edge from OTHER_BLOCK which reaches BB and represents the desired
591 path from COND_BLOCK. */
33784d89 592 if (e->dest == middle_bb)
ea091dfd 593 e = single_succ_edge (e->dest);
50737d20 594
595 /* Now we know the incoming edge to BB that has the argument for the
596 RHS of our new assignment statement. */
33784d89 597 if (e0 == e)
0beac6fc 598 arg = arg0;
599 else
600 arg = arg1;
601
a4844041 602 replace_phi_edge_with_variable (cond_bb, e1, phi, arg);
0beac6fc 603
604 /* Note that we optimized this PHI. */
605 return true;
606 }
607 return false;
608}
609
194899bf 610/* The function minmax_replacement does the main work of doing the minmax
611 replacement. Return true if the replacement is done. Otherwise return
612 false.
613 BB is the basic block where the replacement is going to be done on. ARG0
614 is argument 0 from the PHI. Likewise for ARG1. */
615
616static bool
617minmax_replacement (basic_block cond_bb, basic_block middle_bb,
a4844041 618 edge e0, edge e1, tree phi,
194899bf 619 tree arg0, tree arg1)
620{
621 tree result, type;
622 tree cond, new;
623 edge true_edge, false_edge;
624 enum tree_code cmp, minmax, ass_code;
625 tree smaller, larger, arg_true, arg_false;
626 block_stmt_iterator bsi, bsi_from;
627
628 type = TREE_TYPE (PHI_RESULT (phi));
629
630 /* The optimization may be unsafe due to NaNs. */
631 if (HONOR_NANS (TYPE_MODE (type)))
632 return false;
633
634 cond = COND_EXPR_COND (last_stmt (cond_bb));
635 cmp = TREE_CODE (cond);
636 result = PHI_RESULT (phi);
637
638 /* This transformation is only valid for order comparisons. Record which
639 operand is smaller/larger if the result of the comparison is true. */
640 if (cmp == LT_EXPR || cmp == LE_EXPR)
641 {
642 smaller = TREE_OPERAND (cond, 0);
643 larger = TREE_OPERAND (cond, 1);
644 }
645 else if (cmp == GT_EXPR || cmp == GE_EXPR)
646 {
647 smaller = TREE_OPERAND (cond, 1);
648 larger = TREE_OPERAND (cond, 0);
649 }
650 else
651 return false;
652
653 /* We need to know which is the true edge and which is the false
654 edge so that we know if have abs or negative abs. */
655 extract_true_false_edges_from_block (cond_bb, &true_edge, &false_edge);
656
657 /* Forward the edges over the middle basic block. */
658 if (true_edge->dest == middle_bb)
659 true_edge = EDGE_SUCC (true_edge->dest, 0);
660 if (false_edge->dest == middle_bb)
661 false_edge = EDGE_SUCC (false_edge->dest, 0);
662
663 if (true_edge == e0)
664 {
665 gcc_assert (false_edge == e1);
666 arg_true = arg0;
667 arg_false = arg1;
668 }
669 else
670 {
671 gcc_assert (false_edge == e0);
672 gcc_assert (true_edge == e1);
673 arg_true = arg1;
674 arg_false = arg0;
675 }
676
677 if (empty_block_p (middle_bb))
678 {
679 if (operand_equal_for_phi_arg_p (arg_true, smaller)
680 && operand_equal_for_phi_arg_p (arg_false, larger))
681 {
682 /* Case
683
684 if (smaller < larger)
685 rslt = smaller;
686 else
687 rslt = larger; */
688 minmax = MIN_EXPR;
689 }
690 else if (operand_equal_for_phi_arg_p (arg_false, smaller)
691 && operand_equal_for_phi_arg_p (arg_true, larger))
692 minmax = MAX_EXPR;
693 else
694 return false;
695 }
696 else
697 {
698 /* Recognize the following case, assuming d <= u:
699
700 if (a <= u)
701 b = MAX (a, d);
702 x = PHI <b, u>
703
704 This is equivalent to
705
706 b = MAX (a, d);
707 x = MIN (b, u); */
708
709 tree assign = last_and_only_stmt (middle_bb);
710 tree lhs, rhs, op0, op1, bound;
711
712 if (!assign
713 || TREE_CODE (assign) != MODIFY_EXPR)
714 return false;
715
716 lhs = TREE_OPERAND (assign, 0);
717 rhs = TREE_OPERAND (assign, 1);
718 ass_code = TREE_CODE (rhs);
719 if (ass_code != MAX_EXPR && ass_code != MIN_EXPR)
720 return false;
721 op0 = TREE_OPERAND (rhs, 0);
722 op1 = TREE_OPERAND (rhs, 1);
723
724 if (true_edge->src == middle_bb)
725 {
726 /* We got here if the condition is true, i.e., SMALLER < LARGER. */
727 if (!operand_equal_for_phi_arg_p (lhs, arg_true))
728 return false;
729
730 if (operand_equal_for_phi_arg_p (arg_false, larger))
731 {
732 /* Case
733
734 if (smaller < larger)
735 {
736 r' = MAX_EXPR (smaller, bound)
737 }
738 r = PHI <r', larger> --> to be turned to MIN_EXPR. */
739 if (ass_code != MAX_EXPR)
740 return false;
741
742 minmax = MIN_EXPR;
743 if (operand_equal_for_phi_arg_p (op0, smaller))
744 bound = op1;
745 else if (operand_equal_for_phi_arg_p (op1, smaller))
746 bound = op0;
747 else
748 return false;
749
750 /* We need BOUND <= LARGER. */
49d00087 751 if (!integer_nonzerop (fold_build2 (LE_EXPR, boolean_type_node,
752 bound, larger)))
194899bf 753 return false;
754 }
755 else if (operand_equal_for_phi_arg_p (arg_false, smaller))
756 {
757 /* Case
758
759 if (smaller < larger)
760 {
761 r' = MIN_EXPR (larger, bound)
762 }
763 r = PHI <r', smaller> --> to be turned to MAX_EXPR. */
764 if (ass_code != MIN_EXPR)
765 return false;
766
767 minmax = MAX_EXPR;
768 if (operand_equal_for_phi_arg_p (op0, larger))
769 bound = op1;
770 else if (operand_equal_for_phi_arg_p (op1, larger))
771 bound = op0;
772 else
773 return false;
774
775 /* We need BOUND >= SMALLER. */
49d00087 776 if (!integer_nonzerop (fold_build2 (GE_EXPR, boolean_type_node,
777 bound, smaller)))
194899bf 778 return false;
779 }
780 else
781 return false;
782 }
783 else
784 {
785 /* We got here if the condition is false, i.e., SMALLER > LARGER. */
786 if (!operand_equal_for_phi_arg_p (lhs, arg_false))
787 return false;
788
789 if (operand_equal_for_phi_arg_p (arg_true, larger))
790 {
791 /* Case
792
793 if (smaller > larger)
794 {
795 r' = MIN_EXPR (smaller, bound)
796 }
797 r = PHI <r', larger> --> to be turned to MAX_EXPR. */
798 if (ass_code != MIN_EXPR)
799 return false;
800
801 minmax = MAX_EXPR;
802 if (operand_equal_for_phi_arg_p (op0, smaller))
803 bound = op1;
804 else if (operand_equal_for_phi_arg_p (op1, smaller))
805 bound = op0;
806 else
807 return false;
808
809 /* We need BOUND >= LARGER. */
49d00087 810 if (!integer_nonzerop (fold_build2 (GE_EXPR, boolean_type_node,
811 bound, larger)))
194899bf 812 return false;
813 }
814 else if (operand_equal_for_phi_arg_p (arg_true, smaller))
815 {
816 /* Case
817
818 if (smaller > larger)
819 {
820 r' = MAX_EXPR (larger, bound)
821 }
822 r = PHI <r', smaller> --> to be turned to MIN_EXPR. */
823 if (ass_code != MAX_EXPR)
824 return false;
825
826 minmax = MIN_EXPR;
827 if (operand_equal_for_phi_arg_p (op0, larger))
828 bound = op1;
829 else if (operand_equal_for_phi_arg_p (op1, larger))
830 bound = op0;
831 else
832 return false;
833
834 /* We need BOUND <= SMALLER. */
49d00087 835 if (!integer_nonzerop (fold_build2 (LE_EXPR, boolean_type_node,
836 bound, smaller)))
194899bf 837 return false;
838 }
839 else
840 return false;
841 }
842
843 /* Move the statement from the middle block. */
844 bsi = bsi_last (cond_bb);
845 bsi_from = bsi_last (middle_bb);
846 bsi_move_before (&bsi_from, &bsi);
847 }
848
849 /* Emit the statement to compute min/max. */
850 result = duplicate_ssa_name (PHI_RESULT (phi), NULL);
851 new = build2 (MODIFY_EXPR, type, result,
852 build2 (minmax, type, arg0, arg1));
853 SSA_NAME_DEF_STMT (result) = new;
854 bsi = bsi_last (cond_bb);
855 bsi_insert_before (&bsi, new, BSI_NEW_STMT);
856
a4844041 857 replace_phi_edge_with_variable (cond_bb, e1, phi, result);
194899bf 858 return true;
859}
860
70512b93 861/* The function absolute_replacement does the main work of doing the absolute
862 replacement. Return true if the replacement is done. Otherwise return
863 false.
864 bb is the basic block where the replacement is going to be done on. arg0
f7f07c95 865 is argument 0 from the phi. Likewise for arg1. */
33784d89 866
70512b93 867static bool
33784d89 868abs_replacement (basic_block cond_bb, basic_block middle_bb,
a4844041 869 edge e0 ATTRIBUTE_UNUSED, edge e1,
20e5647c 870 tree phi, tree arg0, tree arg1)
70512b93 871{
872 tree result;
70512b93 873 tree new, cond;
874 block_stmt_iterator bsi;
875 edge true_edge, false_edge;
194899bf 876 tree assign;
70512b93 877 edge e;
194899bf 878 tree rhs, lhs;
70512b93 879 bool negate;
880 enum tree_code cond_code;
881
882 /* If the type says honor signed zeros we cannot do this
dac49aa5 883 optimization. */
70512b93 884 if (HONOR_SIGNED_ZEROS (TYPE_MODE (TREE_TYPE (arg1))))
885 return false;
886
70512b93 887 /* OTHER_BLOCK must have only one executable statement which must have the
888 form arg0 = -arg1 or arg1 = -arg0. */
70512b93 889
194899bf 890 assign = last_and_only_stmt (middle_bb);
70512b93 891 /* If we did not find the proper negation assignment, then we can not
892 optimize. */
893 if (assign == NULL)
894 return false;
194899bf 895
896 /* If we got here, then we have found the only executable statement
897 in OTHER_BLOCK. If it is anything other than arg = -arg1 or
898 arg1 = -arg0, then we can not optimize. */
899 if (TREE_CODE (assign) != MODIFY_EXPR)
900 return false;
901
902 lhs = TREE_OPERAND (assign, 0);
903 rhs = TREE_OPERAND (assign, 1);
904
905 if (TREE_CODE (rhs) != NEGATE_EXPR)
906 return false;
907
908 rhs = TREE_OPERAND (rhs, 0);
909
910 /* The assignment has to be arg0 = -arg1 or arg1 = -arg0. */
911 if (!(lhs == arg0 && rhs == arg1)
912 && !(lhs == arg1 && rhs == arg0))
913 return false;
70512b93 914
33784d89 915 cond = COND_EXPR_COND (last_stmt (cond_bb));
70512b93 916 result = PHI_RESULT (phi);
917
918 /* Only relationals comparing arg[01] against zero are interesting. */
919 cond_code = TREE_CODE (cond);
920 if (cond_code != GT_EXPR && cond_code != GE_EXPR
921 && cond_code != LT_EXPR && cond_code != LE_EXPR)
922 return false;
923
dac49aa5 924 /* Make sure the conditional is arg[01] OP y. */
70512b93 925 if (TREE_OPERAND (cond, 0) != rhs)
926 return false;
927
928 if (FLOAT_TYPE_P (TREE_TYPE (TREE_OPERAND (cond, 1)))
929 ? real_zerop (TREE_OPERAND (cond, 1))
930 : integer_zerop (TREE_OPERAND (cond, 1)))
931 ;
932 else
933 return false;
934
935 /* We need to know which is the true edge and which is the false
936 edge so that we know if have abs or negative abs. */
33784d89 937 extract_true_false_edges_from_block (cond_bb, &true_edge, &false_edge);
70512b93 938
939 /* For GT_EXPR/GE_EXPR, if the true edge goes to OTHER_BLOCK, then we
940 will need to negate the result. Similarly for LT_EXPR/LE_EXPR if
941 the false edge goes to OTHER_BLOCK. */
942 if (cond_code == GT_EXPR || cond_code == GE_EXPR)
943 e = true_edge;
944 else
945 e = false_edge;
20e5647c 946
33784d89 947 if (e->dest == middle_bb)
70512b93 948 negate = true;
949 else
950 negate = false;
20e5647c 951
33784d89 952 result = duplicate_ssa_name (result, NULL);
20e5647c 953
70512b93 954 if (negate)
b2a02a0e 955 {
956 tree tmp = create_tmp_var (TREE_TYPE (result), NULL);
957 add_referenced_tmp_var (tmp);
958 lhs = make_ssa_name (tmp, NULL);
959 }
70512b93 960 else
961 lhs = result;
962
dac49aa5 963 /* Build the modify expression with abs expression. */
194899bf 964 new = build2 (MODIFY_EXPR, TREE_TYPE (lhs),
965 lhs, build1 (ABS_EXPR, TREE_TYPE (lhs), rhs));
b2a02a0e 966 SSA_NAME_DEF_STMT (lhs) = new;
70512b93 967
33784d89 968 bsi = bsi_last (cond_bb);
969 bsi_insert_before (&bsi, new, BSI_NEW_STMT);
70512b93 970
971 if (negate)
972 {
20e5647c 973 /* Get the right BSI. We want to insert after the recently
70512b93 974 added ABS_EXPR statement (which we know is the first statement
975 in the block. */
194899bf 976 new = build2 (MODIFY_EXPR, TREE_TYPE (result),
977 result, build1 (NEGATE_EXPR, TREE_TYPE (lhs), lhs));
b2a02a0e 978 SSA_NAME_DEF_STMT (result) = new;
70512b93 979
980 bsi_insert_after (&bsi, new, BSI_NEW_STMT);
70512b93 981 }
20e5647c 982
a4844041 983 replace_phi_edge_with_variable (cond_bb, e1, phi, result);
70512b93 984
985 /* Note that we optimized this PHI. */
986 return true;
987}
988
4ee9c684 989
990/* Always do these optimizations if we have SSA
20e5647c 991 trees to work on. */
4ee9c684 992static bool
993gate_phiopt (void)
994{
995 return 1;
996}
20e5647c 997
4ee9c684 998struct tree_opt_pass pass_phiopt =
999{
1000 "phiopt", /* name */
1001 gate_phiopt, /* gate */
1002 tree_ssa_phiopt, /* execute */
1003 NULL, /* sub */
1004 NULL, /* next */
1005 0, /* static_pass_number */
1006 TV_TREE_PHIOPT, /* tv_id */
f45a1ca1 1007 PROP_cfg | PROP_ssa | PROP_alias, /* properties_required */
4ee9c684 1008 0, /* properties_provided */
1009 0, /* properties_destroyed */
1010 0, /* todo_flags_start */
88dbf20f 1011 TODO_cleanup_cfg
1012 | TODO_dump_func
1013 | TODO_ggc_collect
1014 | TODO_verify_ssa
88dbf20f 1015 | TODO_verify_flow
1016 | TODO_verify_stmts, /* todo_flags_finish */
0f9005dd 1017 0 /* letter */
4ee9c684 1018};