]> git.ipfire.org Git - thirdparty/gcc.git/blame - gcc/tree-ssa-phiopt.c
* passes.c (rest_of_handle_branch_prob): Do not rebuild profiling info
[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);
0e1a77e1 334
cd665a06 335 block_to_remove = EDGE_SUCC (cond_block, 1)->dest;
902929aa 336 }
337 else
338 {
cd665a06 339 EDGE_SUCC (cond_block, 1)->flags |= EDGE_FALLTHRU;
340 EDGE_SUCC (cond_block, 1)->flags
902929aa 341 &= ~(EDGE_TRUE_VALUE | EDGE_FALSE_VALUE);
0e1a77e1 342
cd665a06 343 block_to_remove = EDGE_SUCC (cond_block, 0)->dest;
902929aa 344 }
0e1a77e1 345 delete_basic_block (block_to_remove);
20e5647c 346
902929aa 347 /* Eliminate the COND_EXPR at the end of COND_BLOCK. */
348 bsi = bsi_last (cond_block);
349 bsi_remove (&bsi);
20e5647c 350
902929aa 351 if (dump_file && (dump_flags & TDF_DETAILS))
352 fprintf (dump_file,
353 "COND_EXPR in block %d and PHI in block %d converted to straightline code.\n",
354 cond_block->index,
355 bb->index);
356}
357
358/* The function conditional_replacement does the main work of doing the
359 conditional replacement. Return true if the replacement is done.
360 Otherwise return false.
361 BB is the basic block where the replacement is going to be done on. ARG0
dac49aa5 362 is argument 0 from PHI. Likewise for ARG1. */
902929aa 363
364static bool
33784d89 365conditional_replacement (basic_block cond_bb, basic_block middle_bb,
a4844041 366 edge e0, edge e1, tree phi,
33784d89 367 tree arg0, tree arg1)
902929aa 368{
369 tree result;
370 tree old_result = NULL;
902929aa 371 tree new, cond;
372 block_stmt_iterator bsi;
373 edge true_edge, false_edge;
374 tree new_var = NULL;
33784d89 375 tree new_var1;
902929aa 376
377 /* The PHI arguments have the constants 0 and 1, then convert
378 it to the conditional. */
379 if ((integer_zerop (arg0) && integer_onep (arg1))
380 || (integer_zerop (arg1) && integer_onep (arg0)))
381 ;
382 else
383 return false;
20e5647c 384
33784d89 385 if (!empty_block_p (middle_bb))
902929aa 386 return false;
20e5647c 387
4ee9c684 388 /* If the condition is not a naked SSA_NAME and its type does not
2ab0a163 389 match the type of the result, then we have to create a new
390 variable to optimize this case as it would likely create
391 non-gimple code when the condition was converted to the
392 result's type. */
33784d89 393 cond = COND_EXPR_COND (last_stmt (cond_bb));
4ee9c684 394 result = PHI_RESULT (phi);
395 if (TREE_CODE (cond) != SSA_NAME
396 && !lang_hooks.types_compatible_p (TREE_TYPE (cond), TREE_TYPE (result)))
ae5a4794 397 {
398 new_var = make_rename_temp (TREE_TYPE (cond), NULL);
399 old_result = cond;
400 cond = new_var;
401 }
20e5647c 402
4ee9c684 403 /* If the condition was a naked SSA_NAME and the type is not the
2ab0a163 404 same as the type of the result, then convert the type of the
405 condition. */
4ee9c684 406 if (!lang_hooks.types_compatible_p (TREE_TYPE (cond), TREE_TYPE (result)))
407 cond = fold_convert (TREE_TYPE (result), cond);
20e5647c 408
4ee9c684 409 /* We need to know which is the true edge and which is the false
2ab0a163 410 edge so that we know when to invert the condition below. */
33784d89 411 extract_true_false_edges_from_block (cond_bb, &true_edge, &false_edge);
20e5647c 412
1fa68a1f 413 /* Insert our new statement at the end of conditional block before the
33784d89 414 COND_EXPR. */
415 bsi = bsi_last (cond_bb);
416 bsi_insert_before (&bsi, build_empty_stmt (), BSI_NEW_STMT);
20e5647c 417
ae5a4794 418 if (old_result)
419 {
420 tree new1;
ce45a448 421 if (!COMPARISON_CLASS_P (old_result))
2ab0a163 422 return false;
20e5647c 423
194899bf 424 new1 = build2 (TREE_CODE (old_result), TREE_TYPE (old_result),
425 TREE_OPERAND (old_result, 0),
426 TREE_OPERAND (old_result, 1));
20e5647c 427
194899bf 428 new1 = build2 (MODIFY_EXPR, TREE_TYPE (old_result), new_var, new1);
ae5a4794 429 bsi_insert_after (&bsi, new1, BSI_NEW_STMT);
430 }
20e5647c 431
33784d89 432 new_var1 = duplicate_ssa_name (PHI_RESULT (phi), NULL);
20e5647c 433
434
4ee9c684 435 /* At this point we know we have a COND_EXPR with two successors.
2ab0a163 436 One successor is BB, the other successor is an empty block which
437 falls through into BB.
20e5647c 438
2ab0a163 439 There is a single PHI node at the join point (BB) and its arguments
440 are constants (0, 1).
20e5647c 441
2ab0a163 442 So, given the condition COND, and the two PHI arguments, we can
20e5647c 443 rewrite this PHI into non-branching code:
444
2ab0a163 445 dest = (COND) or dest = COND'
20e5647c 446
2ab0a163 447 We use the condition as-is if the argument associated with the
448 true edge has the value one or the argument associated with the
449 false edge as the value zero. Note that those conditions are not
450 the same since only one of the outgoing edges from the COND_EXPR
451 will directly reach BB and thus be associated with an argument. */
33784d89 452 if ((e0 == true_edge && integer_onep (arg0))
453 || (e0 == false_edge && integer_zerop (arg0))
454 || (e1 == true_edge && integer_onep (arg1))
455 || (e1 == false_edge && integer_zerop (arg1)))
4ee9c684 456 {
194899bf 457 new = build2 (MODIFY_EXPR, TREE_TYPE (new_var1), new_var1, cond);
4ee9c684 458 }
459 else
460 {
ae5a4794 461 tree cond1 = invert_truthvalue (cond);
20e5647c 462
ae5a4794 463 cond = cond1;
464 /* If what we get back is a conditional expression, there is no
0beac6fc 465 way that it can be gimple. */
ae5a4794 466 if (TREE_CODE (cond) == COND_EXPR)
33784d89 467 {
468 release_ssa_name (new_var1);
20e5647c 469 return false;
33784d89 470 }
ae5a4794 471
472 /* If what we get back is not gimple try to create it as gimple by
dac49aa5 473 using a temporary variable. */
4ee9c684 474 if (is_gimple_cast (cond)
475 && !is_gimple_val (TREE_OPERAND (cond, 0)))
2ab0a163 476 {
477 tree temp = TREE_OPERAND (cond, 0);
478 tree new_var_1 = make_rename_temp (TREE_TYPE (temp), NULL);
194899bf 479 new = build2 (MODIFY_EXPR, TREE_TYPE (new_var_1), new_var_1, temp);
2ab0a163 480 bsi_insert_after (&bsi, new, BSI_NEW_STMT);
481 cond = fold_convert (TREE_TYPE (result), new_var_1);
482 }
20e5647c 483
4ee9c684 484 if (TREE_CODE (cond) == TRUTH_NOT_EXPR
2ab0a163 485 && !is_gimple_val (TREE_OPERAND (cond, 0)))
33784d89 486 {
487 release_ssa_name (new_var1);
488 return false;
489 }
4ee9c684 490
194899bf 491 new = build2 (MODIFY_EXPR, TREE_TYPE (new_var1), new_var1, cond);
4ee9c684 492 }
20e5647c 493
33784d89 494 bsi_insert_after (&bsi, new, BSI_NEW_STMT);
20e5647c 495
33784d89 496 SSA_NAME_DEF_STMT (new_var1) = new;
20e5647c 497
a4844041 498 replace_phi_edge_with_variable (cond_bb, e1, phi, new_var1);
902929aa 499
4ee9c684 500 /* Note that we optimized this PHI. */
501 return true;
502}
503
0beac6fc 504/* The function value_replacement does the main work of doing the value
505 replacement. Return true if the replacement is done. Otherwise return
506 false.
507 BB is the basic block where the replacement is going to be done on. ARG0
dac49aa5 508 is argument 0 from the PHI. Likewise for ARG1. */
0beac6fc 509
510static bool
33784d89 511value_replacement (basic_block cond_bb, basic_block middle_bb,
a4844041 512 edge e0, edge e1, tree phi,
33784d89 513 tree arg0, tree arg1)
0beac6fc 514{
33784d89 515 tree cond;
0beac6fc 516 edge true_edge, false_edge;
517
518 /* If the type says honor signed zeros we cannot do this
dac49aa5 519 optimization. */
0beac6fc 520 if (HONOR_SIGNED_ZEROS (TYPE_MODE (TREE_TYPE (arg1))))
521 return false;
522
33784d89 523 if (!empty_block_p (middle_bb))
0beac6fc 524 return false;
525
33784d89 526 cond = COND_EXPR_COND (last_stmt (cond_bb));
0beac6fc 527
528 /* This transformation is only valid for equality comparisons. */
529 if (TREE_CODE (cond) != NE_EXPR && TREE_CODE (cond) != EQ_EXPR)
530 return false;
531
532 /* We need to know which is the true edge and which is the false
533 edge so that we know if have abs or negative abs. */
33784d89 534 extract_true_false_edges_from_block (cond_bb, &true_edge, &false_edge);
0beac6fc 535
536 /* At this point we know we have a COND_EXPR with two successors.
537 One successor is BB, the other successor is an empty block which
538 falls through into BB.
539
540 The condition for the COND_EXPR is known to be NE_EXPR or EQ_EXPR.
541
542 There is a single PHI node at the join point (BB) with two arguments.
543
544 We now need to verify that the two arguments in the PHI node match
545 the two arguments to the equality comparison. */
20e5647c 546
5373158f 547 if ((operand_equal_for_phi_arg_p (arg0, TREE_OPERAND (cond, 0))
548 && operand_equal_for_phi_arg_p (arg1, TREE_OPERAND (cond, 1)))
549 || (operand_equal_for_phi_arg_p (arg1, TREE_OPERAND (cond, 0))
550 && operand_equal_for_phi_arg_p (arg0, TREE_OPERAND (cond, 1))))
0beac6fc 551 {
552 edge e;
553 tree arg;
554
50737d20 555 /* For NE_EXPR, we want to build an assignment result = arg where
556 arg is the PHI argument associated with the true edge. For
557 EQ_EXPR we want the PHI argument associated with the false edge. */
0beac6fc 558 e = (TREE_CODE (cond) == NE_EXPR ? true_edge : false_edge);
50737d20 559
560 /* Unfortunately, E may not reach BB (it may instead have gone to
561 OTHER_BLOCK). If that is the case, then we want the single outgoing
562 edge from OTHER_BLOCK which reaches BB and represents the desired
563 path from COND_BLOCK. */
33784d89 564 if (e->dest == middle_bb)
ea091dfd 565 e = single_succ_edge (e->dest);
50737d20 566
567 /* Now we know the incoming edge to BB that has the argument for the
568 RHS of our new assignment statement. */
33784d89 569 if (e0 == e)
0beac6fc 570 arg = arg0;
571 else
572 arg = arg1;
573
a4844041 574 replace_phi_edge_with_variable (cond_bb, e1, phi, arg);
0beac6fc 575
576 /* Note that we optimized this PHI. */
577 return true;
578 }
579 return false;
580}
581
194899bf 582/* The function minmax_replacement does the main work of doing the minmax
583 replacement. Return true if the replacement is done. Otherwise return
584 false.
585 BB is the basic block where the replacement is going to be done on. ARG0
586 is argument 0 from the PHI. Likewise for ARG1. */
587
588static bool
589minmax_replacement (basic_block cond_bb, basic_block middle_bb,
a4844041 590 edge e0, edge e1, tree phi,
194899bf 591 tree arg0, tree arg1)
592{
593 tree result, type;
594 tree cond, new;
595 edge true_edge, false_edge;
596 enum tree_code cmp, minmax, ass_code;
597 tree smaller, larger, arg_true, arg_false;
598 block_stmt_iterator bsi, bsi_from;
599
600 type = TREE_TYPE (PHI_RESULT (phi));
601
602 /* The optimization may be unsafe due to NaNs. */
603 if (HONOR_NANS (TYPE_MODE (type)))
604 return false;
605
606 cond = COND_EXPR_COND (last_stmt (cond_bb));
607 cmp = TREE_CODE (cond);
608 result = PHI_RESULT (phi);
609
610 /* This transformation is only valid for order comparisons. Record which
611 operand is smaller/larger if the result of the comparison is true. */
612 if (cmp == LT_EXPR || cmp == LE_EXPR)
613 {
614 smaller = TREE_OPERAND (cond, 0);
615 larger = TREE_OPERAND (cond, 1);
616 }
617 else if (cmp == GT_EXPR || cmp == GE_EXPR)
618 {
619 smaller = TREE_OPERAND (cond, 1);
620 larger = TREE_OPERAND (cond, 0);
621 }
622 else
623 return false;
624
625 /* We need to know which is the true edge and which is the false
626 edge so that we know if have abs or negative abs. */
627 extract_true_false_edges_from_block (cond_bb, &true_edge, &false_edge);
628
629 /* Forward the edges over the middle basic block. */
630 if (true_edge->dest == middle_bb)
631 true_edge = EDGE_SUCC (true_edge->dest, 0);
632 if (false_edge->dest == middle_bb)
633 false_edge = EDGE_SUCC (false_edge->dest, 0);
634
635 if (true_edge == e0)
636 {
637 gcc_assert (false_edge == e1);
638 arg_true = arg0;
639 arg_false = arg1;
640 }
641 else
642 {
643 gcc_assert (false_edge == e0);
644 gcc_assert (true_edge == e1);
645 arg_true = arg1;
646 arg_false = arg0;
647 }
648
649 if (empty_block_p (middle_bb))
650 {
651 if (operand_equal_for_phi_arg_p (arg_true, smaller)
652 && operand_equal_for_phi_arg_p (arg_false, larger))
653 {
654 /* Case
655
656 if (smaller < larger)
657 rslt = smaller;
658 else
659 rslt = larger; */
660 minmax = MIN_EXPR;
661 }
662 else if (operand_equal_for_phi_arg_p (arg_false, smaller)
663 && operand_equal_for_phi_arg_p (arg_true, larger))
664 minmax = MAX_EXPR;
665 else
666 return false;
667 }
668 else
669 {
670 /* Recognize the following case, assuming d <= u:
671
672 if (a <= u)
673 b = MAX (a, d);
674 x = PHI <b, u>
675
676 This is equivalent to
677
678 b = MAX (a, d);
679 x = MIN (b, u); */
680
681 tree assign = last_and_only_stmt (middle_bb);
682 tree lhs, rhs, op0, op1, bound;
683
684 if (!assign
685 || TREE_CODE (assign) != MODIFY_EXPR)
686 return false;
687
688 lhs = TREE_OPERAND (assign, 0);
689 rhs = TREE_OPERAND (assign, 1);
690 ass_code = TREE_CODE (rhs);
691 if (ass_code != MAX_EXPR && ass_code != MIN_EXPR)
692 return false;
693 op0 = TREE_OPERAND (rhs, 0);
694 op1 = TREE_OPERAND (rhs, 1);
695
696 if (true_edge->src == middle_bb)
697 {
698 /* We got here if the condition is true, i.e., SMALLER < LARGER. */
699 if (!operand_equal_for_phi_arg_p (lhs, arg_true))
700 return false;
701
702 if (operand_equal_for_phi_arg_p (arg_false, larger))
703 {
704 /* Case
705
706 if (smaller < larger)
707 {
708 r' = MAX_EXPR (smaller, bound)
709 }
710 r = PHI <r', larger> --> to be turned to MIN_EXPR. */
711 if (ass_code != MAX_EXPR)
712 return false;
713
714 minmax = MIN_EXPR;
715 if (operand_equal_for_phi_arg_p (op0, smaller))
716 bound = op1;
717 else if (operand_equal_for_phi_arg_p (op1, smaller))
718 bound = op0;
719 else
720 return false;
721
722 /* We need BOUND <= LARGER. */
723 if (!integer_nonzerop (fold (build2 (LE_EXPR, boolean_type_node,
724 bound, larger))))
725 return false;
726 }
727 else if (operand_equal_for_phi_arg_p (arg_false, smaller))
728 {
729 /* Case
730
731 if (smaller < larger)
732 {
733 r' = MIN_EXPR (larger, bound)
734 }
735 r = PHI <r', smaller> --> to be turned to MAX_EXPR. */
736 if (ass_code != MIN_EXPR)
737 return false;
738
739 minmax = MAX_EXPR;
740 if (operand_equal_for_phi_arg_p (op0, larger))
741 bound = op1;
742 else if (operand_equal_for_phi_arg_p (op1, larger))
743 bound = op0;
744 else
745 return false;
746
747 /* We need BOUND >= SMALLER. */
748 if (!integer_nonzerop (fold (build2 (GE_EXPR, boolean_type_node,
749 bound, smaller))))
750 return false;
751 }
752 else
753 return false;
754 }
755 else
756 {
757 /* We got here if the condition is false, i.e., SMALLER > LARGER. */
758 if (!operand_equal_for_phi_arg_p (lhs, arg_false))
759 return false;
760
761 if (operand_equal_for_phi_arg_p (arg_true, larger))
762 {
763 /* Case
764
765 if (smaller > larger)
766 {
767 r' = MIN_EXPR (smaller, bound)
768 }
769 r = PHI <r', larger> --> to be turned to MAX_EXPR. */
770 if (ass_code != MIN_EXPR)
771 return false;
772
773 minmax = MAX_EXPR;
774 if (operand_equal_for_phi_arg_p (op0, smaller))
775 bound = op1;
776 else if (operand_equal_for_phi_arg_p (op1, smaller))
777 bound = op0;
778 else
779 return false;
780
781 /* We need BOUND >= LARGER. */
782 if (!integer_nonzerop (fold (build2 (GE_EXPR, boolean_type_node,
783 bound, larger))))
784 return false;
785 }
786 else if (operand_equal_for_phi_arg_p (arg_true, smaller))
787 {
788 /* Case
789
790 if (smaller > larger)
791 {
792 r' = MAX_EXPR (larger, bound)
793 }
794 r = PHI <r', smaller> --> to be turned to MIN_EXPR. */
795 if (ass_code != MAX_EXPR)
796 return false;
797
798 minmax = MIN_EXPR;
799 if (operand_equal_for_phi_arg_p (op0, larger))
800 bound = op1;
801 else if (operand_equal_for_phi_arg_p (op1, larger))
802 bound = op0;
803 else
804 return false;
805
806 /* We need BOUND <= SMALLER. */
807 if (!integer_nonzerop (fold (build2 (LE_EXPR, boolean_type_node,
808 bound, smaller))))
809 return false;
810 }
811 else
812 return false;
813 }
814
815 /* Move the statement from the middle block. */
816 bsi = bsi_last (cond_bb);
817 bsi_from = bsi_last (middle_bb);
818 bsi_move_before (&bsi_from, &bsi);
819 }
820
821 /* Emit the statement to compute min/max. */
822 result = duplicate_ssa_name (PHI_RESULT (phi), NULL);
823 new = build2 (MODIFY_EXPR, type, result,
824 build2 (minmax, type, arg0, arg1));
825 SSA_NAME_DEF_STMT (result) = new;
826 bsi = bsi_last (cond_bb);
827 bsi_insert_before (&bsi, new, BSI_NEW_STMT);
828
a4844041 829 replace_phi_edge_with_variable (cond_bb, e1, phi, result);
194899bf 830 return true;
831}
832
70512b93 833/* The function absolute_replacement does the main work of doing the absolute
834 replacement. Return true if the replacement is done. Otherwise return
835 false.
836 bb is the basic block where the replacement is going to be done on. arg0
f7f07c95 837 is argument 0 from the phi. Likewise for arg1. */
33784d89 838
70512b93 839static bool
33784d89 840abs_replacement (basic_block cond_bb, basic_block middle_bb,
a4844041 841 edge e0 ATTRIBUTE_UNUSED, edge e1,
20e5647c 842 tree phi, tree arg0, tree arg1)
70512b93 843{
844 tree result;
70512b93 845 tree new, cond;
846 block_stmt_iterator bsi;
847 edge true_edge, false_edge;
194899bf 848 tree assign;
70512b93 849 edge e;
194899bf 850 tree rhs, lhs;
70512b93 851 bool negate;
852 enum tree_code cond_code;
853
854 /* If the type says honor signed zeros we cannot do this
dac49aa5 855 optimization. */
70512b93 856 if (HONOR_SIGNED_ZEROS (TYPE_MODE (TREE_TYPE (arg1))))
857 return false;
858
70512b93 859 /* OTHER_BLOCK must have only one executable statement which must have the
860 form arg0 = -arg1 or arg1 = -arg0. */
70512b93 861
194899bf 862 assign = last_and_only_stmt (middle_bb);
70512b93 863 /* If we did not find the proper negation assignment, then we can not
864 optimize. */
865 if (assign == NULL)
866 return false;
194899bf 867
868 /* If we got here, then we have found the only executable statement
869 in OTHER_BLOCK. If it is anything other than arg = -arg1 or
870 arg1 = -arg0, then we can not optimize. */
871 if (TREE_CODE (assign) != MODIFY_EXPR)
872 return false;
873
874 lhs = TREE_OPERAND (assign, 0);
875 rhs = TREE_OPERAND (assign, 1);
876
877 if (TREE_CODE (rhs) != NEGATE_EXPR)
878 return false;
879
880 rhs = TREE_OPERAND (rhs, 0);
881
882 /* The assignment has to be arg0 = -arg1 or arg1 = -arg0. */
883 if (!(lhs == arg0 && rhs == arg1)
884 && !(lhs == arg1 && rhs == arg0))
885 return false;
70512b93 886
33784d89 887 cond = COND_EXPR_COND (last_stmt (cond_bb));
70512b93 888 result = PHI_RESULT (phi);
889
890 /* Only relationals comparing arg[01] against zero are interesting. */
891 cond_code = TREE_CODE (cond);
892 if (cond_code != GT_EXPR && cond_code != GE_EXPR
893 && cond_code != LT_EXPR && cond_code != LE_EXPR)
894 return false;
895
dac49aa5 896 /* Make sure the conditional is arg[01] OP y. */
70512b93 897 if (TREE_OPERAND (cond, 0) != rhs)
898 return false;
899
900 if (FLOAT_TYPE_P (TREE_TYPE (TREE_OPERAND (cond, 1)))
901 ? real_zerop (TREE_OPERAND (cond, 1))
902 : integer_zerop (TREE_OPERAND (cond, 1)))
903 ;
904 else
905 return false;
906
907 /* We need to know which is the true edge and which is the false
908 edge so that we know if have abs or negative abs. */
33784d89 909 extract_true_false_edges_from_block (cond_bb, &true_edge, &false_edge);
70512b93 910
911 /* For GT_EXPR/GE_EXPR, if the true edge goes to OTHER_BLOCK, then we
912 will need to negate the result. Similarly for LT_EXPR/LE_EXPR if
913 the false edge goes to OTHER_BLOCK. */
914 if (cond_code == GT_EXPR || cond_code == GE_EXPR)
915 e = true_edge;
916 else
917 e = false_edge;
20e5647c 918
33784d89 919 if (e->dest == middle_bb)
70512b93 920 negate = true;
921 else
922 negate = false;
20e5647c 923
33784d89 924 result = duplicate_ssa_name (result, NULL);
20e5647c 925
70512b93 926 if (negate)
927 lhs = make_rename_temp (TREE_TYPE (result), NULL);
928 else
929 lhs = result;
930
dac49aa5 931 /* Build the modify expression with abs expression. */
194899bf 932 new = build2 (MODIFY_EXPR, TREE_TYPE (lhs),
933 lhs, build1 (ABS_EXPR, TREE_TYPE (lhs), rhs));
70512b93 934
33784d89 935 bsi = bsi_last (cond_bb);
936 bsi_insert_before (&bsi, new, BSI_NEW_STMT);
70512b93 937
938 if (negate)
939 {
20e5647c 940 /* Get the right BSI. We want to insert after the recently
70512b93 941 added ABS_EXPR statement (which we know is the first statement
942 in the block. */
194899bf 943 new = build2 (MODIFY_EXPR, TREE_TYPE (result),
944 result, build1 (NEGATE_EXPR, TREE_TYPE (lhs), lhs));
70512b93 945
946 bsi_insert_after (&bsi, new, BSI_NEW_STMT);
70512b93 947 }
20e5647c 948
33784d89 949 SSA_NAME_DEF_STMT (result) = new;
a4844041 950 replace_phi_edge_with_variable (cond_bb, e1, phi, result);
70512b93 951
952 /* Note that we optimized this PHI. */
953 return true;
954}
955
4ee9c684 956
957/* Always do these optimizations if we have SSA
20e5647c 958 trees to work on. */
4ee9c684 959static bool
960gate_phiopt (void)
961{
962 return 1;
963}
20e5647c 964
4ee9c684 965struct tree_opt_pass pass_phiopt =
966{
967 "phiopt", /* name */
968 gate_phiopt, /* gate */
969 tree_ssa_phiopt, /* execute */
970 NULL, /* sub */
971 NULL, /* next */
972 0, /* static_pass_number */
973 TV_TREE_PHIOPT, /* tv_id */
f45a1ca1 974 PROP_cfg | PROP_ssa | PROP_alias, /* properties_required */
4ee9c684 975 0, /* properties_provided */
976 0, /* properties_destroyed */
977 0, /* todo_flags_start */
88dbf20f 978 TODO_cleanup_cfg
979 | TODO_dump_func
980 | TODO_ggc_collect
981 | TODO_verify_ssa
982 | TODO_update_ssa
983 | TODO_verify_flow
984 | TODO_verify_stmts, /* todo_flags_finish */
0f9005dd 985 0 /* letter */
4ee9c684 986};