Daily bump.
[official-gcc.git] / gcc / tree-ssa-phiopt.c
blob42e3bde82818e7d6a66937a07e18003b06d50751
1 /* Optimization of PHI nodes by converting them into straightline code.
2 Copyright (C) 2004, 2005 Free Software Foundation, Inc.
4 This file is part of GCC.
6 GCC is free software; you can redistribute it and/or modify it
7 under the terms of the GNU General Public License as published by the
8 Free Software Foundation; either version 2, or (at your option) any
9 later version.
11 GCC is distributed in the hope that it will be useful, but WITHOUT
12 ANY WARRANTY; without even the implied warranty of MERCHANTABILITY or
13 FITNESS FOR A PARTICULAR PURPOSE. See the GNU General Public License
14 for more details.
16 You should have received a copy of the GNU General Public License
17 along with GCC; see the file COPYING. If not, write to the Free
18 Software Foundation, 59 Temple Place - Suite 330, Boston, MA
19 02111-1307, USA. */
21 #include "config.h"
22 #include "system.h"
23 #include "coretypes.h"
24 #include "tm.h"
25 #include "errors.h"
26 #include "ggc.h"
27 #include "tree.h"
28 #include "rtl.h"
29 #include "flags.h"
30 #include "tm_p.h"
31 #include "basic-block.h"
32 #include "timevar.h"
33 #include "diagnostic.h"
34 #include "tree-flow.h"
35 #include "tree-pass.h"
36 #include "tree-dump.h"
37 #include "langhooks.h"
39 static void tree_ssa_phiopt (void);
40 static bool conditional_replacement (basic_block, basic_block, basic_block,
41 edge, edge, tree, tree, tree);
42 static bool value_replacement (basic_block, basic_block, basic_block,
43 edge, edge, tree, tree, tree);
44 static bool abs_replacement (basic_block, basic_block, basic_block,
45 edge, edge, tree, tree, tree);
46 static void replace_phi_edge_with_variable (basic_block, basic_block, edge,
47 tree, tree);
49 /* This pass eliminates PHI nodes which can be trivially implemented as
50 an assignment from a conditional expression. i.e. if we have something
51 like:
53 bb0:
54 if (cond) goto bb2; else goto bb1;
55 bb1:
56 bb2:
57 x = PHI (0 (bb1), 1 (bb0)
59 We can rewrite that as:
61 bb0:
62 bb1:
63 bb2:
64 x = cond;
66 bb1 will become unreachable and bb0 and bb2 will almost always
67 be merged into a single block. This occurs often due to gimplification
68 of conditionals.
70 Also done is the following optimization:
72 bb0:
73 if (a != b) goto bb2; else goto bb1;
74 bb1:
75 bb2:
76 x = PHI (a (bb1), b (bb0))
78 We can rewrite that as:
80 bb0:
81 bb1:
82 bb2:
83 x = b;
85 This can sometimes occur as a result of other optimizations. A
86 similar transformation is done by the ifcvt RTL optimizer.
88 This pass also eliminates PHI nodes which are really absolute
89 values. i.e. if we have something like:
91 bb0:
92 if (a >= 0) goto bb2; else goto bb1;
93 bb1:
94 x = -a;
95 bb2:
96 x = PHI (x (bb1), a (bb0));
98 We can rewrite that as:
100 bb0:
101 bb1:
102 bb2:
103 x = ABS_EXPR< a >;
105 bb1 will become unreachable and bb0 and bb2 will almost always be merged
106 into a single block. Similar transformations are done by the ifcvt
107 RTL optimizer. */
109 static void
110 tree_ssa_phiopt (void)
112 basic_block bb;
114 /* Search every basic block for COND_EXPR we may be able to optimize
115 in reverse order so we can find more. */
116 FOR_EACH_BB_REVERSE (bb)
118 tree cond_expr;
119 tree phi;
120 basic_block bb1, bb2;
121 edge e1, e2;
123 cond_expr = last_stmt (bb);
124 /* Check to see if the last statement is a COND_EXPR. */
125 if (!cond_expr
126 || TREE_CODE (cond_expr) != COND_EXPR)
127 continue;
129 e1 = EDGE_SUCC (bb, 0);
130 bb1 = e1->dest;
131 e2 = EDGE_SUCC (bb, 1);
132 bb2 = e2->dest;
134 /* We cannot do the optimization on abnormal edges. */
135 if ((e1->flags & EDGE_ABNORMAL) != 0
136 || (e2->flags & EDGE_ABNORMAL) != 0)
137 continue;
139 /* If either bb1's succ or bb2 or bb2's succ is non NULL. */
140 if (EDGE_COUNT (bb1->succs) == 0
141 || bb2 == NULL
142 || EDGE_COUNT (bb2->succs) == 0)
143 continue;
145 /* Find the bb which is the fall through to the other. */
146 if (EDGE_SUCC (bb1, 0)->dest == bb2)
148 else if (EDGE_SUCC (bb2, 0)->dest == bb1)
150 basic_block bb_tmp = bb1;
151 edge e_tmp = e1;
152 bb1 = bb2;
153 bb2 = bb_tmp;
154 e1 = e2;
155 e2 = e_tmp;
157 else
158 continue;
160 e1 = EDGE_SUCC (bb1, 0);
162 /* Make sure that bb1 is just a fall through. */
163 if (!single_succ_p (bb1) > 1
164 || (e1->flags & EDGE_FALLTHRU) == 0)
165 continue;
167 /* Also make that bb1 only have one pred and it is bb. */
168 if (!single_pred_p (bb1)
169 || single_pred (bb1) != bb)
170 continue;
172 phi = phi_nodes (bb2);
174 /* Check to make sure that there is only one PHI node.
175 TODO: we could do it with more than one iff the other PHI nodes
176 have the same elements for these two edges. */
177 if (phi && PHI_CHAIN (phi) == NULL)
179 tree arg0 = NULL, arg1 = NULL;
181 arg0 = PHI_ARG_DEF_TREE (phi, e1->dest_idx);
182 arg1 = PHI_ARG_DEF_TREE (phi, e2->dest_idx);
184 /* We know something is wrong if we cannot find the edges in the PHI
185 node. */
186 gcc_assert (arg0 != NULL && arg1 != NULL);
188 /* Do the replacement of conditional if it can be done. */
189 if (conditional_replacement (bb, bb1, bb2, e1, e2, phi, arg0, arg1)
190 || value_replacement (bb, bb1, bb2, e1, e2, phi, arg0, arg1)
191 || abs_replacement (bb, bb1, bb2, e1, e2, phi, arg0, arg1))
198 /* Return TRUE if block BB has no executable statements, otherwise return
199 FALSE. */
200 bool
201 empty_block_p (basic_block bb)
203 block_stmt_iterator bsi;
205 /* BB must have no executable statements. */
206 bsi = bsi_start (bb);
207 while (!bsi_end_p (bsi)
208 && (TREE_CODE (bsi_stmt (bsi)) == LABEL_EXPR
209 || IS_EMPTY_STMT (bsi_stmt (bsi))))
210 bsi_next (&bsi);
212 if (!bsi_end_p (bsi))
213 return false;
215 return true;
218 /* Replace PHI node element whoes edge is E in block BB with variable NEW.
219 Remove the edge from COND_BLOCK which does not lead to BB (COND_BLOCK
220 is known to have two edges, one of which must reach BB). */
222 static void
223 replace_phi_edge_with_variable (basic_block cond_block, basic_block bb,
224 edge e, tree phi, tree new)
226 basic_block block_to_remove;
227 block_stmt_iterator bsi;
229 /* Change the PHI argument to new. */
230 PHI_ARG_DEF_TREE (phi, e->dest_idx) = new;
232 /* Remove the empty basic block. */
233 if (EDGE_SUCC (cond_block, 0)->dest == bb)
235 EDGE_SUCC (cond_block, 0)->flags |= EDGE_FALLTHRU;
236 EDGE_SUCC (cond_block, 0)->flags &= ~(EDGE_TRUE_VALUE | EDGE_FALSE_VALUE);
238 block_to_remove = EDGE_SUCC (cond_block, 1)->dest;
240 else
242 EDGE_SUCC (cond_block, 1)->flags |= EDGE_FALLTHRU;
243 EDGE_SUCC (cond_block, 1)->flags
244 &= ~(EDGE_TRUE_VALUE | EDGE_FALSE_VALUE);
246 block_to_remove = EDGE_SUCC (cond_block, 0)->dest;
248 delete_basic_block (block_to_remove);
250 /* Eliminate the COND_EXPR at the end of COND_BLOCK. */
251 bsi = bsi_last (cond_block);
252 bsi_remove (&bsi);
254 if (dump_file && (dump_flags & TDF_DETAILS))
255 fprintf (dump_file,
256 "COND_EXPR in block %d and PHI in block %d converted to straightline code.\n",
257 cond_block->index,
258 bb->index);
261 /* The function conditional_replacement does the main work of doing the
262 conditional replacement. Return true if the replacement is done.
263 Otherwise return false.
264 BB is the basic block where the replacement is going to be done on. ARG0
265 is argument 0 from PHI. Likewise for ARG1. */
267 static bool
268 conditional_replacement (basic_block cond_bb, basic_block middle_bb,
269 basic_block phi_bb, edge e0, edge e1, tree phi,
270 tree arg0, tree arg1)
272 tree result;
273 tree old_result = NULL;
274 tree new, cond;
275 block_stmt_iterator bsi;
276 edge true_edge, false_edge;
277 tree new_var = NULL;
278 tree new_var1;
280 /* The PHI arguments have the constants 0 and 1, then convert
281 it to the conditional. */
282 if ((integer_zerop (arg0) && integer_onep (arg1))
283 || (integer_zerop (arg1) && integer_onep (arg0)))
285 else
286 return false;
288 if (!empty_block_p (middle_bb))
289 return false;
291 /* If the condition is not a naked SSA_NAME and its type does not
292 match the type of the result, then we have to create a new
293 variable to optimize this case as it would likely create
294 non-gimple code when the condition was converted to the
295 result's type. */
296 cond = COND_EXPR_COND (last_stmt (cond_bb));
297 result = PHI_RESULT (phi);
298 if (TREE_CODE (cond) != SSA_NAME
299 && !lang_hooks.types_compatible_p (TREE_TYPE (cond), TREE_TYPE (result)))
301 new_var = make_rename_temp (TREE_TYPE (cond), NULL);
302 old_result = cond;
303 cond = new_var;
306 /* If the condition was a naked SSA_NAME and the type is not the
307 same as the type of the result, then convert the type of the
308 condition. */
309 if (!lang_hooks.types_compatible_p (TREE_TYPE (cond), TREE_TYPE (result)))
310 cond = fold_convert (TREE_TYPE (result), cond);
312 /* We need to know which is the true edge and which is the false
313 edge so that we know when to invert the condition below. */
314 extract_true_false_edges_from_block (cond_bb, &true_edge, &false_edge);
316 /* Insert our new statement at the end of conditional block before the
317 COND_EXPR. */
318 bsi = bsi_last (cond_bb);
319 bsi_insert_before (&bsi, build_empty_stmt (), BSI_NEW_STMT);
321 if (old_result)
323 tree new1;
324 if (!COMPARISON_CLASS_P (old_result))
325 return false;
327 new1 = build (TREE_CODE (old_result), TREE_TYPE (old_result),
328 TREE_OPERAND (old_result, 0),
329 TREE_OPERAND (old_result, 1));
331 new1 = build (MODIFY_EXPR, TREE_TYPE (old_result), new_var, new1);
332 bsi_insert_after (&bsi, new1, BSI_NEW_STMT);
335 new_var1 = duplicate_ssa_name (PHI_RESULT (phi), NULL);
338 /* At this point we know we have a COND_EXPR with two successors.
339 One successor is BB, the other successor is an empty block which
340 falls through into BB.
342 There is a single PHI node at the join point (BB) and its arguments
343 are constants (0, 1).
345 So, given the condition COND, and the two PHI arguments, we can
346 rewrite this PHI into non-branching code:
348 dest = (COND) or dest = COND'
350 We use the condition as-is if the argument associated with the
351 true edge has the value one or the argument associated with the
352 false edge as the value zero. Note that those conditions are not
353 the same since only one of the outgoing edges from the COND_EXPR
354 will directly reach BB and thus be associated with an argument. */
355 if ((e0 == true_edge && integer_onep (arg0))
356 || (e0 == false_edge && integer_zerop (arg0))
357 || (e1 == true_edge && integer_onep (arg1))
358 || (e1 == false_edge && integer_zerop (arg1)))
360 new = build (MODIFY_EXPR, TREE_TYPE (new_var1), new_var1, cond);
362 else
364 tree cond1 = invert_truthvalue (cond);
366 cond = cond1;
367 /* If what we get back is a conditional expression, there is no
368 way that it can be gimple. */
369 if (TREE_CODE (cond) == COND_EXPR)
371 release_ssa_name (new_var1);
372 return false;
375 /* If what we get back is not gimple try to create it as gimple by
376 using a temporary variable. */
377 if (is_gimple_cast (cond)
378 && !is_gimple_val (TREE_OPERAND (cond, 0)))
380 tree temp = TREE_OPERAND (cond, 0);
381 tree new_var_1 = make_rename_temp (TREE_TYPE (temp), NULL);
382 new = build (MODIFY_EXPR, TREE_TYPE (new_var_1), new_var_1, temp);
383 bsi_insert_after (&bsi, new, BSI_NEW_STMT);
384 cond = fold_convert (TREE_TYPE (result), new_var_1);
387 if (TREE_CODE (cond) == TRUTH_NOT_EXPR
388 && !is_gimple_val (TREE_OPERAND (cond, 0)))
390 release_ssa_name (new_var1);
391 return false;
394 new = build (MODIFY_EXPR, TREE_TYPE (new_var1), new_var1, cond);
397 bsi_insert_after (&bsi, new, BSI_NEW_STMT);
399 SSA_NAME_DEF_STMT (new_var1) = new;
401 replace_phi_edge_with_variable (cond_bb, phi_bb, e1, phi, new_var1);
403 /* Note that we optimized this PHI. */
404 return true;
407 /* The function value_replacement does the main work of doing the value
408 replacement. Return true if the replacement is done. Otherwise return
409 false.
410 BB is the basic block where the replacement is going to be done on. ARG0
411 is argument 0 from the PHI. Likewise for ARG1. */
413 static bool
414 value_replacement (basic_block cond_bb, basic_block middle_bb,
415 basic_block phi_bb, edge e0, edge e1, tree phi,
416 tree arg0, tree arg1)
418 tree result;
419 tree cond;
420 edge true_edge, false_edge;
422 /* If the type says honor signed zeros we cannot do this
423 optimization. */
424 if (HONOR_SIGNED_ZEROS (TYPE_MODE (TREE_TYPE (arg1))))
425 return false;
427 if (!empty_block_p (middle_bb))
428 return false;
430 cond = COND_EXPR_COND (last_stmt (cond_bb));
431 result = PHI_RESULT (phi);
433 /* This transformation is only valid for equality comparisons. */
434 if (TREE_CODE (cond) != NE_EXPR && TREE_CODE (cond) != EQ_EXPR)
435 return false;
437 /* We need to know which is the true edge and which is the false
438 edge so that we know if have abs or negative abs. */
439 extract_true_false_edges_from_block (cond_bb, &true_edge, &false_edge);
441 /* At this point we know we have a COND_EXPR with two successors.
442 One successor is BB, the other successor is an empty block which
443 falls through into BB.
445 The condition for the COND_EXPR is known to be NE_EXPR or EQ_EXPR.
447 There is a single PHI node at the join point (BB) with two arguments.
449 We now need to verify that the two arguments in the PHI node match
450 the two arguments to the equality comparison. */
452 if ((operand_equal_for_phi_arg_p (arg0, TREE_OPERAND (cond, 0))
453 && operand_equal_for_phi_arg_p (arg1, TREE_OPERAND (cond, 1)))
454 || (operand_equal_for_phi_arg_p (arg1, TREE_OPERAND (cond, 0))
455 && operand_equal_for_phi_arg_p (arg0, TREE_OPERAND (cond, 1))))
457 edge e;
458 tree arg;
460 /* For NE_EXPR, we want to build an assignment result = arg where
461 arg is the PHI argument associated with the true edge. For
462 EQ_EXPR we want the PHI argument associated with the false edge. */
463 e = (TREE_CODE (cond) == NE_EXPR ? true_edge : false_edge);
465 /* Unfortunately, E may not reach BB (it may instead have gone to
466 OTHER_BLOCK). If that is the case, then we want the single outgoing
467 edge from OTHER_BLOCK which reaches BB and represents the desired
468 path from COND_BLOCK. */
469 if (e->dest == middle_bb)
470 e = single_succ_edge (e->dest);
472 /* Now we know the incoming edge to BB that has the argument for the
473 RHS of our new assignment statement. */
474 if (e0 == e)
475 arg = arg0;
476 else
477 arg = arg1;
479 replace_phi_edge_with_variable (cond_bb, phi_bb, e1, phi, arg);
481 /* Note that we optimized this PHI. */
482 return true;
484 return false;
487 /* The function absolute_replacement does the main work of doing the absolute
488 replacement. Return true if the replacement is done. Otherwise return
489 false.
490 bb is the basic block where the replacement is going to be done on. arg0
491 is argument 0 from the phi. Likewise for arg1. */
493 static bool
494 abs_replacement (basic_block cond_bb, basic_block middle_bb,
495 basic_block phi_bb, edge e0 ATTRIBUTE_UNUSED, edge e1,
496 tree phi, tree arg0, tree arg1)
498 tree result;
499 tree new, cond;
500 block_stmt_iterator bsi;
501 edge true_edge, false_edge;
502 tree assign = NULL;
503 edge e;
504 tree rhs = NULL, lhs = NULL;
505 bool negate;
506 enum tree_code cond_code;
508 /* If the type says honor signed zeros we cannot do this
509 optimization. */
510 if (HONOR_SIGNED_ZEROS (TYPE_MODE (TREE_TYPE (arg1))))
511 return false;
513 /* OTHER_BLOCK must have only one executable statement which must have the
514 form arg0 = -arg1 or arg1 = -arg0. */
515 bsi = bsi_start (middle_bb);
516 while (!bsi_end_p (bsi))
518 tree stmt = bsi_stmt (bsi);
520 /* Empty statements and labels are uninteresting. */
521 if (TREE_CODE (stmt) == LABEL_EXPR
522 || IS_EMPTY_STMT (stmt))
524 bsi_next (&bsi);
525 continue;
528 /* If we found the assignment, but it was not the only executable
529 statement in OTHER_BLOCK, then we can not optimize. */
530 if (assign)
531 return false;
533 /* If we got here, then we have found the first executable statement
534 in OTHER_BLOCK. If it is anything other than arg = -arg1 or
535 arg1 = -arg0, then we can not optimize. */
536 if (TREE_CODE (stmt) == MODIFY_EXPR)
538 lhs = TREE_OPERAND (stmt, 0);
539 rhs = TREE_OPERAND (stmt, 1);
541 if (TREE_CODE (rhs) == NEGATE_EXPR)
543 rhs = TREE_OPERAND (rhs, 0);
545 /* The assignment has to be arg0 = -arg1 or arg1 = -arg0. */
546 if ((lhs == arg0 && rhs == arg1)
547 || (lhs == arg1 && rhs == arg0))
549 assign = stmt;
550 bsi_next (&bsi);
552 else
553 return false;
555 else
556 return false;
558 else
559 return false;
562 /* If we did not find the proper negation assignment, then we can not
563 optimize. */
564 if (assign == NULL)
565 return false;
567 cond = COND_EXPR_COND (last_stmt (cond_bb));
568 result = PHI_RESULT (phi);
570 /* Only relationals comparing arg[01] against zero are interesting. */
571 cond_code = TREE_CODE (cond);
572 if (cond_code != GT_EXPR && cond_code != GE_EXPR
573 && cond_code != LT_EXPR && cond_code != LE_EXPR)
574 return false;
576 /* Make sure the conditional is arg[01] OP y. */
577 if (TREE_OPERAND (cond, 0) != rhs)
578 return false;
580 if (FLOAT_TYPE_P (TREE_TYPE (TREE_OPERAND (cond, 1)))
581 ? real_zerop (TREE_OPERAND (cond, 1))
582 : integer_zerop (TREE_OPERAND (cond, 1)))
584 else
585 return false;
587 /* We need to know which is the true edge and which is the false
588 edge so that we know if have abs or negative abs. */
589 extract_true_false_edges_from_block (cond_bb, &true_edge, &false_edge);
591 /* For GT_EXPR/GE_EXPR, if the true edge goes to OTHER_BLOCK, then we
592 will need to negate the result. Similarly for LT_EXPR/LE_EXPR if
593 the false edge goes to OTHER_BLOCK. */
594 if (cond_code == GT_EXPR || cond_code == GE_EXPR)
595 e = true_edge;
596 else
597 e = false_edge;
599 if (e->dest == middle_bb)
600 negate = true;
601 else
602 negate = false;
604 result = duplicate_ssa_name (result, NULL);
606 if (negate)
607 lhs = make_rename_temp (TREE_TYPE (result), NULL);
608 else
609 lhs = result;
611 /* Build the modify expression with abs expression. */
612 new = build (MODIFY_EXPR, TREE_TYPE (lhs),
613 lhs, build1 (ABS_EXPR, TREE_TYPE (lhs), rhs));
615 bsi = bsi_last (cond_bb);
616 bsi_insert_before (&bsi, new, BSI_NEW_STMT);
618 if (negate)
620 /* Get the right BSI. We want to insert after the recently
621 added ABS_EXPR statement (which we know is the first statement
622 in the block. */
623 new = build (MODIFY_EXPR, TREE_TYPE (result),
624 result, build1 (NEGATE_EXPR, TREE_TYPE (lhs), lhs));
626 bsi_insert_after (&bsi, new, BSI_NEW_STMT);
629 SSA_NAME_DEF_STMT (result) = new;
630 replace_phi_edge_with_variable (cond_bb, phi_bb, e1, phi, result);
632 /* Note that we optimized this PHI. */
633 return true;
637 /* Always do these optimizations if we have SSA
638 trees to work on. */
639 static bool
640 gate_phiopt (void)
642 return 1;
645 struct tree_opt_pass pass_phiopt =
647 "phiopt", /* name */
648 gate_phiopt, /* gate */
649 tree_ssa_phiopt, /* execute */
650 NULL, /* sub */
651 NULL, /* next */
652 0, /* static_pass_number */
653 TV_TREE_PHIOPT, /* tv_id */
654 PROP_cfg | PROP_ssa | PROP_alias, /* properties_required */
655 0, /* properties_provided */
656 0, /* properties_destroyed */
657 0, /* todo_flags_start */
658 TODO_cleanup_cfg | TODO_dump_func | TODO_ggc_collect /* todo_flags_finish */
659 | TODO_verify_ssa | TODO_rename_vars
660 | TODO_verify_flow | TODO_verify_stmts,
661 0 /* letter */