]> git.ipfire.org Git - thirdparty/gcc.git/blob - gcc/tree-if-conv.c
86e1bb0ce8b481d2240869201a3f72b482b4b0e8
[thirdparty/gcc.git] / gcc / tree-if-conv.c
1 /* If-conversion for vectorizer.
2 Copyright (C) 2004 Free Software Foundation, Inc.
3 Contributed by Devang Patel <dpatel@apple.com>
4
5 This file is part of GCC.
6
7 GCC is free software; you can redistribute it and/or modify it under
8 the terms of the GNU General Public License as published by the Free
9 Software Foundation; either version 2, or (at your option) any later
10 version.
11
12 GCC is distributed in the hope that it will be useful, but WITHOUT ANY
13 WARRANTY; without even the implied warranty of MERCHANTABILITY or
14 FITNESS FOR A PARTICULAR PURPOSE. See the GNU General Public License
15 for more details.
16
17 You should have received a copy of the GNU General Public License
18 along with GCC; see the file COPYING. If not, write to the Free
19 Software Foundation, 59 Temple Place - Suite 330, Boston, MA
20 02111-1307, USA. */
21
22 /* This pass implements tree level if-conversion transformation of loops.
23 Initial goal is to help vectorizer vectorize loops with conditions.
24
25 A short description of if-conversion:
26
27 o Decide if a loop is if-convertable or not.
28 o Walk all loop basic blocks in breadth first order (BFS order).
29 o Remove conditional statements (at the end of basic block)
30 and propagate condition into destination basic blocks'
31 predicate list.
32 o Replace modify expression with conditional modify expression
33 using current basic block's condition.
34 o Merge all basic blocks
35 o Replace phi nodes with conditional modify expr
36 o Merge all basic blocks into header
37
38 Sample transformation:
39
40 INPUT
41 -----
42
43 # i_23 = PHI <0(0), i_18(10)>;
44 <L0>:;
45 j_15 = A[i_23];
46 if (j_15 > 41) goto <L1>; else goto <L17>;
47
48 <L17>:;
49 goto <bb 3> (<L3>);
50
51 <L1>:;
52
53 # iftmp.2_4 = PHI <0(8), 42(2)>;
54 <L3>:;
55 A[i_23] = iftmp.2_4;
56 i_18 = i_23 + 1;
57 if (i_18 <= 15) goto <L19>; else goto <L18>;
58
59 <L19>:;
60 goto <bb 1> (<L0>);
61
62 <L18>:;
63
64 OUTPUT
65 ------
66
67 # i_23 = PHI <0(0), i_18(10)>;
68 <L0>:;
69 j_15 = A[i_23];
70
71 <L3>:;
72 iftmp.2_4 = j_15 > 41 ? 42 : 0;
73 A[i_23] = iftmp.2_4;
74 i_18 = i_23 + 1;
75 if (i_18 <= 15) goto <L19>; else goto <L18>;
76
77 <L19>:;
78 goto <bb 1> (<L0>);
79
80 <L18>:;
81 */
82
83 #include "config.h"
84 #include "system.h"
85 #include "coretypes.h"
86 #include "tm.h"
87 #include "errors.h"
88 #include "tree.h"
89 #include "c-common.h"
90 #include "flags.h"
91 #include "timevar.h"
92 #include "varray.h"
93 #include "rtl.h"
94 #include "basic-block.h"
95 #include "diagnostic.h"
96 #include "tree-flow.h"
97 #include "tree-dump.h"
98 #include "cfgloop.h"
99 #include "tree-chrec.h"
100 #include "tree-data-ref.h"
101 #include "tree-scalar-evolution.h"
102 #include "tree-pass.h"
103 #include "target.h"
104
105 /* local function prototypes */
106 static void main_tree_if_conversion (void);
107 static tree tree_if_convert_stmt (struct loop *loop, tree, tree,
108 block_stmt_iterator *);
109 static void tree_if_convert_cond_expr (struct loop *, tree, tree,
110 block_stmt_iterator *);
111 static bool if_convertable_phi_p (struct loop *, basic_block, tree);
112 static bool if_convertable_modify_expr_p (struct loop *, basic_block, tree);
113 static bool if_convertable_stmt_p (struct loop *, basic_block, tree);
114 static bool if_convertable_bb_p (struct loop *, basic_block, bool);
115 static bool if_convertable_loop_p (struct loop *, bool);
116 static void add_to_predicate_list (basic_block, tree);
117 static tree add_to_dst_predicate_list (struct loop * loop, tree, tree, tree,
118 block_stmt_iterator *);
119 static void clean_predicate_lists (struct loop *loop);
120 static bool find_phi_replacement_condition (basic_block, tree *,
121 block_stmt_iterator *);
122 static void replace_phi_with_cond_modify_expr (tree, tree, bool,
123 block_stmt_iterator *);
124 static void process_phi_nodes (struct loop *);
125 static void combine_blocks (struct loop *);
126 static tree ifc_temp_var (tree, tree);
127 static bool pred_blocks_visited_p (basic_block, bitmap *);
128 static basic_block * get_loop_body_in_if_conv_order (const struct loop *loop);
129 static bool bb_with_exit_edge_p (basic_block);
130
131 /* List of basic blocks in if-conversion-suitable order. */
132 static basic_block *ifc_bbs;
133
134 /* Main entry point.
135 Apply if-conversion to the LOOP. Return true if successful otherwise return
136 false. If false is returned then loop remains unchanged.
137 FOR_VECTORIZER is a boolean flag. It indicates whether if-conversion is used
138 for vectorizer or not. If it is used for vectorizer, additional checks are
139 used. (Vectorization checks are not yet implemented). */
140
141 bool
142 tree_if_conversion (struct loop *loop, bool for_vectorizer)
143 {
144 basic_block bb;
145 block_stmt_iterator itr;
146 tree cond;
147 unsigned int i;
148
149 ifc_bbs = NULL;
150
151 /* if-conversion is not appropriate for all loops. First, check if loop is
152 if-convertable or not. */
153 if (!if_convertable_loop_p (loop, for_vectorizer))
154 {
155 if (dump_file && (dump_flags & TDF_DETAILS))
156 fprintf (dump_file,"-------------------------\n");
157 if (ifc_bbs)
158 {
159 free (ifc_bbs);
160 ifc_bbs = NULL;
161 }
162 free_dominance_info (CDI_POST_DOMINATORS);
163 free_df ();
164 return false;
165 }
166
167 cond = NULL_TREE;
168
169 /* Do actual work now. */
170 for (i = 0; i < loop->num_nodes; i++)
171 {
172 bb = ifc_bbs [i];
173
174 /* Update condition using predicate list. */
175 cond = bb->aux;
176
177 /* Process all statements in this basic block.
178 Remove conditional expression, if any, and annotate
179 destination basic block(s) appropriately. */
180 for (itr = bsi_start (bb); !bsi_end_p (itr); /* empty */)
181 {
182 tree t = bsi_stmt (itr);
183 cond = tree_if_convert_stmt (loop, t, cond, &itr);
184 if (!bsi_end_p (itr))
185 bsi_next (&itr);
186 }
187
188 /* If current bb has only one successor, then consider it as an
189 unconditional goto. */
190 if (bb->succ && !bb->succ->succ_next)
191 {
192 basic_block bb_n = bb->succ->dest;
193 if (cond != NULL_TREE)
194 add_to_predicate_list (bb_n, cond);
195 cond = NULL_TREE;
196 }
197 }
198
199 /* Now, all statements are if-converted and basic blocks are
200 annotated appropriately. Combine all basic block into one huge
201 basic block. */
202 combine_blocks (loop);
203
204 /* clean up */
205 clean_predicate_lists (loop);
206 free (ifc_bbs);
207 ifc_bbs = NULL;
208 free_df ();
209
210 return true;
211 }
212
213 /* if-convert stmt T which is part of LOOP.
214 If T is a MODIFY_EXPR than it is converted into conditional modify
215 expression using COND. For conditional expressions, add condition in the
216 destination basic block's predicate list and remove conditional
217 expression itself. BSI is the iterator used to traverse statements of
218 loop. It is used here when it is required to delete current statement. */
219
220 static tree
221 tree_if_convert_stmt (struct loop * loop, tree t, tree cond,
222 block_stmt_iterator *bsi)
223 {
224 if (dump_file && (dump_flags & TDF_DETAILS))
225 {
226 fprintf (dump_file, "------if-convert stmt\n");
227 print_generic_stmt (dump_file, t, TDF_SLIM);
228 print_generic_stmt (dump_file, cond, TDF_SLIM);
229 }
230
231 switch (TREE_CODE (t))
232 {
233 /* Labels are harmless here. */
234 case LABEL_EXPR:
235 break;
236
237 case MODIFY_EXPR:
238 /* This modify_expr is killing previous value of LHS. Appropriate value will
239 be selected by PHI node based on condition. It is possible that before
240 this transformation, PHI nodes was selecting default value and now it will
241 use this new value. This is OK because it does not change validity the
242 program. */
243 break;
244
245 case GOTO_EXPR:
246 /* Unconditional goto */
247 add_to_predicate_list (bb_for_stmt (TREE_OPERAND (t, 1)), cond);
248 bsi_remove (bsi);
249 cond = NULL_TREE;
250 break;
251
252 case COND_EXPR:
253 /* Update destination blocks' predicate list and remove this
254 condition expression. */
255 tree_if_convert_cond_expr (loop, t, cond, bsi);
256 cond = NULL_TREE;
257 break;
258
259 default:
260 abort ();
261 break;
262 }
263 return cond;
264 }
265
266 /* STMT is COND_EXPR. Update two destination's predicate list.
267 Remove COND_EXPR, if it is not the loop exit condition. Otherwise
268 update loop exit condition appropriately. BSI is the iterator
269 used to traverse statement list. STMT is part of loop LOOP. */
270
271 static void
272 tree_if_convert_cond_expr (struct loop *loop, tree stmt, tree cond,
273 block_stmt_iterator *bsi)
274 {
275 tree then_clause, else_clause, c, new_cond;
276 new_cond = NULL_TREE;
277
278 #ifdef ENABLE_CHECKING
279 if (TREE_CODE (stmt) != COND_EXPR)
280 abort ();
281 #endif
282
283 c = TREE_OPERAND (stmt, 0);
284 then_clause = TREE_OPERAND (stmt, 1);
285 else_clause = TREE_OPERAND (stmt, 2);
286
287 /* Create temp. for condition. */
288 if (!is_gimple_reg (c))
289 {
290 tree new_stmt;
291 new_stmt = ifc_temp_var (TREE_TYPE (c), unshare_expr (c));
292 bsi_insert_before (bsi, new_stmt, BSI_SAME_STMT);
293 c = TREE_OPERAND (new_stmt, 0);
294 }
295
296 /* Add new condition into destination's predicate list. */
297 if (then_clause)
298 /* if 'c' is true then then_clause is reached. */
299 new_cond = add_to_dst_predicate_list (loop, then_clause, cond, c, bsi);
300
301 if (else_clause)
302 {
303 /* if 'c' is false then else_clause is reached. */
304 tree c2 = build1 (TRUTH_NOT_EXPR,
305 boolean_type_node,
306 unshare_expr (c));
307 add_to_dst_predicate_list (loop, else_clause, cond, c2, bsi);
308 }
309
310 /* Now this conditional statement is redundant. Remove it.
311 But, do not remove exit condition! Update exit condition
312 using new condition. */
313 if (!bb_with_exit_edge_p (bb_for_stmt (stmt)))
314 {
315 bsi_remove (bsi);
316 cond = NULL_TREE;
317 }
318 else if (new_cond != NULL_TREE)
319 {
320 TREE_OPERAND (stmt, 0) = new_cond;
321 modify_stmt (stmt);
322 }
323 return;
324 }
325
326 /* Return true, iff PHI is if-convertable. PHI is part of loop LOOP
327 and it belongs to basic block BB.
328 PHI is not if-convertable
329 - if it has more than 2 arguments.
330 - Virtual PHI is immediately used in another PHI node. */
331
332 static bool
333 if_convertable_phi_p (struct loop *loop, basic_block bb, tree phi)
334 {
335 if (dump_file && (dump_flags & TDF_DETAILS))
336 {
337 fprintf (dump_file, "-------------------------\n");
338 print_generic_stmt (dump_file, phi, TDF_SLIM);
339 }
340
341 if (bb != loop->header && PHI_NUM_ARGS (phi) != 2)
342 {
343 if (dump_file && (dump_flags & TDF_DETAILS))
344 fprintf (dump_file, "More than two phi node args.\n");
345 return false;
346 }
347
348 if (!is_gimple_reg (SSA_NAME_VAR (PHI_RESULT (phi))))
349 {
350 int j;
351 dataflow_t df = get_immediate_uses (phi);
352 int num_uses = num_immediate_uses (df);
353 for (j = 0; j < num_uses; j++)
354 {
355 tree use = immediate_use (df, j);
356 if (TREE_CODE (use) == PHI_NODE)
357 {
358 if (dump_file && (dump_flags & TDF_DETAILS))
359 fprintf (dump_file, "Difficult to handle this virtual phi.\n");
360 return false;
361 }
362 }
363 }
364
365 return true;
366 }
367
368 /* Return true, if M_EXPR is if-convertable.
369 MODIFY_EXPR is not if-convertable if,
370 - It is not movable.
371 - It could trap.
372 - LHS is not var decl.
373 MODIFY_EXPR is part of block BB, which is inside loop LOOP.
374 */
375
376 static bool
377 if_convertable_modify_expr_p (struct loop *loop, basic_block bb, tree m_expr)
378 {
379 if (dump_file && (dump_flags & TDF_DETAILS))
380 {
381 fprintf (dump_file, "-------------------------\n");
382 print_generic_stmt (dump_file, m_expr, TDF_SLIM);
383 }
384
385 /* Be conservative and do not handle immovable expressions. */
386 if (movement_possibility (m_expr) == MOVE_IMPOSSIBLE)
387 {
388 if (dump_file && (dump_flags & TDF_DETAILS))
389 fprintf (dump_file, "stmt is movable. Don't take risk\n");
390 return false;
391 }
392
393 /* See if it needs speculative loading or not. */
394 if (bb != loop->header
395 && tree_could_trap_p (TREE_OPERAND (m_expr, 1)))
396 {
397 if (dump_file && (dump_flags & TDF_DETAILS))
398 fprintf (dump_file, "tree could trap...\n");
399 return false;
400 }
401
402 if (TREE_CODE (TREE_OPERAND (m_expr, 1)) == CALL_EXPR)
403 {
404 if (dump_file && (dump_flags & TDF_DETAILS))
405 fprintf (dump_file, "CALL_EXPR \n");
406 return false;
407 }
408
409 if (TREE_CODE (TREE_OPERAND (m_expr, 0)) != SSA_NAME
410 && bb != loop->header
411 && !bb_with_exit_edge_p (bb))
412 {
413 if (dump_file && (dump_flags & TDF_DETAILS))
414 {
415 fprintf (dump_file, "LHS is not var\n");
416 print_generic_stmt (dump_file, m_expr, TDF_SLIM);
417 }
418 return false;
419 }
420
421
422 return true;
423 }
424
425 /* Return true, iff STMT is if-convertable.
426 Statement is if-convertable if,
427 - It is if-convertable MODIFY_EXPR
428 - IT is LABEL_EXPR, GOTO_EXPR or COND_EXPR.
429 STMT is inside block BB, which is inside loop LOOP. */
430
431 static bool
432 if_convertable_stmt_p (struct loop *loop, basic_block bb, tree stmt)
433 {
434 switch (TREE_CODE (stmt))
435 {
436 case LABEL_EXPR:
437 break;
438
439 case MODIFY_EXPR:
440
441 if (!if_convertable_modify_expr_p (loop, bb, stmt))
442 return false;
443 break;
444
445 case GOTO_EXPR:
446 case COND_EXPR:
447 break;
448
449 default:
450 /* Don't know what to do with 'em so don't do anything. */
451 if (dump_file && (dump_flags & TDF_DETAILS))
452 {
453 fprintf (dump_file, "don't know what to do\n");
454 print_generic_stmt (dump_file, stmt, TDF_SLIM);
455 }
456 return false;
457 break;
458 }
459
460 return true;
461 }
462
463 /* Return true, iff BB is if-convertable.
464 Note: This routine does _not_ check basic block statements and phis.
465 Basic block is not if-convertable if,
466 - Basic block is non-empty and it is after exit block (in BFS order).
467 - Basic block is after exit block but before latch.
468 - Basic block edge(s) is not normal.
469 EXIT_BB_SEEN is true if basic block with exit edge is already seen.
470 BB is inside loop LOOP. */
471
472 static bool
473 if_convertable_bb_p (struct loop *loop, basic_block bb, bool exit_bb_seen)
474 {
475 edge e;
476
477 if (dump_file && (dump_flags & TDF_DETAILS))
478 fprintf (dump_file, "----------[%d]-------------\n", bb->index);
479
480 if (exit_bb_seen)
481 {
482 if (bb != loop->latch)
483 {
484 if (dump_file && (dump_flags & TDF_DETAILS))
485 fprintf (dump_file, "basic block after exit bb but before latch\n");
486 return false;
487 }
488 else if (!empty_block_p (bb))
489 {
490 if (dump_file && (dump_flags & TDF_DETAILS))
491 fprintf (dump_file, "non empty basic block after exit bb\n");
492 return false;
493 }
494 }
495
496 /* Be less adventurous and handle only normal edges. */
497 for (e = bb->succ; e; e = e->succ_next)
498 if (e->flags &
499 (EDGE_ABNORMAL_CALL | EDGE_EH | EDGE_ABNORMAL | EDGE_IRREDUCIBLE_LOOP))
500 {
501 if (dump_file && (dump_flags & TDF_DETAILS))
502 fprintf (dump_file,"Difficult to handle edges\n");
503 return false;
504 }
505
506 return true;
507 }
508
509 /* Return true, iff LOOP is if-convertable.
510 LOOP is if-convertable if,
511 - It is innermost.
512 - It has two or more basic blocks.
513 - It has only one exit.
514 - Loop header is not the exit edge.
515 - If its basic blocks and phi nodes are if convertable. See above for
516 more info.
517 FOR_VECTORIZER enables vectorizer specific checks. For example, support
518 for vector conditions, data dependency checks etc.. (Not implemented yet). */
519
520 static bool
521 if_convertable_loop_p (struct loop *loop, bool for_vectorizer ATTRIBUTE_UNUSED)
522 {
523 tree phi;
524 basic_block bb;
525 block_stmt_iterator itr;
526 unsigned int i;
527 edge e;
528 bool exit_bb_seen = false;
529
530 /* Handle only inner most loop. */
531 if (!loop || loop->inner)
532 {
533 if (dump_file && (dump_flags & TDF_DETAILS))
534 fprintf (dump_file, "not inner most loop\n");
535 return false;
536 }
537
538 flow_loop_scan (loop, LOOP_ALL);
539
540 /* If only one block, no need for if-conversion. */
541 if (loop->num_nodes <= 2)
542 {
543 if (dump_file && (dump_flags & TDF_DETAILS))
544 fprintf (dump_file, "less than 2 basic blocks\n");
545 return false;
546 }
547
548 /* More than one loop exit is too much to handle. */
549 if (loop->num_exits > 1)
550 {
551 if (dump_file && (dump_flags & TDF_DETAILS))
552 fprintf (dump_file, "multiple exits\n");
553 return false;
554 }
555
556 /* ??? Check target's vector conditional operation support for vectorizer. */
557
558 /* If one of the loop header's edge is exit edge then do not apply
559 if-conversion. */
560 for (e = loop->header->succ; e; e = e->succ_next)
561 if ( e->flags & EDGE_LOOP_EXIT)
562 return false;
563
564 compute_immediate_uses (TDFA_USE_OPS|TDFA_USE_VOPS, NULL);
565
566 calculate_dominance_info (CDI_DOMINATORS);
567 calculate_dominance_info (CDI_POST_DOMINATORS);
568
569 /* Allow statements that can be handled during if-conversion. */
570 ifc_bbs = get_loop_body_in_if_conv_order (loop);
571 if (!ifc_bbs)
572 {
573 if (dump_file && (dump_flags & TDF_DETAILS))
574 fprintf (dump_file,"Irreducible loop\n");
575 free_dominance_info (CDI_POST_DOMINATORS);
576 return false;
577 }
578
579 for (i = 0; i < loop->num_nodes; i++)
580 {
581 bb = ifc_bbs[i];
582
583 if (!if_convertable_bb_p (loop, bb, exit_bb_seen))
584 return false;
585
586 /* Check statements. */
587 for (itr = bsi_start (bb); !bsi_end_p (itr); bsi_next (&itr))
588 if (!if_convertable_stmt_p (loop, bb, bsi_stmt (itr)))
589 return false;
590 /* ??? Check data dependency for vectorizer. */
591
592 /* What about phi nodes ? */
593 for (phi = phi_nodes (bb); phi; phi = TREE_CHAIN (phi))
594 if (!if_convertable_phi_p (loop, bb, phi))
595 return false;
596
597 if (bb_with_exit_edge_p (bb))
598 exit_bb_seen = true;
599 }
600
601 /* OK. Did not find any potential issues so go ahead in if-convert
602 this loop. Now there is no looking back. */
603 if (dump_file)
604 fprintf (dump_file,"Applying if-conversion\n");
605
606 free_dominance_info (CDI_POST_DOMINATORS);
607 return true;
608 }
609
610 /* Add condition COND into predicate list of basic block BB. */
611
612 static void
613 add_to_predicate_list (basic_block bb, tree new_cond)
614 {
615 tree cond = bb->aux;
616
617 if (cond)
618 cond = fold (build (TRUTH_OR_EXPR, boolean_type_node,
619 unshare_expr (cond), new_cond));
620 else
621 cond = new_cond;
622
623 bb->aux = cond;
624 }
625
626 /* Add condition COND into DST's predicate list. PREV_COND is
627 existing condition. */
628
629 static tree
630 add_to_dst_predicate_list (struct loop * loop, tree dst,
631 tree prev_cond, tree cond,
632 block_stmt_iterator *bsi)
633 {
634 basic_block bb;
635 tree new_cond = NULL_TREE;
636
637 #ifdef ENABLE_CHECKING
638 if (TREE_CODE (dst) != GOTO_EXPR)
639 abort ();
640 #endif
641 bb = label_to_block (TREE_OPERAND (dst, 0));
642 if (!flow_bb_inside_loop_p (loop, bb))
643 return NULL_TREE;
644
645 if (prev_cond == boolean_true_node || !prev_cond)
646 new_cond = unshare_expr (cond);
647 else
648 {
649 tree tmp_stmt;
650 /* new_cond == prev_cond AND cond */
651 tree tmp = build (TRUTH_AND_EXPR, boolean_type_node,
652 unshare_expr (prev_cond), cond);
653 tmp_stmt = ifc_temp_var (boolean_type_node, tmp);
654 bsi_insert_before (bsi, tmp_stmt, BSI_SAME_STMT);
655 new_cond = TREE_OPERAND (tmp_stmt, 0);
656 }
657 add_to_predicate_list (bb, new_cond);
658 return new_cond;
659 }
660
661 /* During if-conversion aux field from basic block is used to hold predicate
662 list. Clean each basic block's predicate list for the given LOOP. */
663
664 static void
665 clean_predicate_lists (struct loop *loop)
666 {
667 unsigned int i;
668
669 for (i = 0; i < loop->num_nodes; i++)
670 ifc_bbs[i]->aux = NULL;
671 }
672
673 /* Basic block BB has two predecessors. Using predecessor's aux field, set
674 appropriate condition COND for the PHI node replacement. Return true if
675 phi arguments are condition is selected from second predecessor. */
676
677 static bool
678 find_phi_replacement_condition (basic_block bb, tree *cond,
679 block_stmt_iterator *bsi)
680 {
681 edge e;
682 basic_block p1 = NULL;
683 basic_block p2 = NULL;
684 bool switch_args = false;
685 tree tmp_cond;
686
687 for (e = bb->pred; e; e = e->pred_next)
688 {
689 if (p1 == NULL)
690 p1 = e->src;
691 else if (p2 == NULL)
692 p2 = e->src;
693 else
694 /* More than two predecessors. This is not expected. */
695 abort ();
696 }
697
698 /* Use condition that is not TRUTH_NOT_EXPR in conditional modify expr. */
699 tmp_cond = p1->aux;
700 if (TREE_CODE (tmp_cond) == TRUTH_NOT_EXPR)
701 {
702 *cond = p2->aux;
703 switch_args = true;
704 }
705 else
706 {
707 *cond = p1->aux;
708 switch_args = false;
709 }
710
711 /* Create temp. for the condition. Vectorizer prefers to have gimple
712 value as condition. Various targets use different means to communicate
713 condition in vector compare operation. Using gimple value allows compiler
714 to emit vector compare and select RTL without exposing compare's result. */
715 if (!is_gimple_reg (*cond) && !is_gimple_condexpr (*cond))
716 {
717 tree new_stmt;
718
719 new_stmt = ifc_temp_var (TREE_TYPE (*cond), unshare_expr (*cond));
720 bsi_insert_after (bsi, new_stmt, BSI_SAME_STMT);
721 bsi_next (bsi);
722 *cond = TREE_OPERAND (new_stmt, 0);
723 }
724
725 #ifdef ENABLE_CHECKING
726 if (*cond == NULL_TREE)
727 abort ();
728 #endif
729
730 return switch_args;
731 }
732
733
734 /* Replace PHI node with conditional modify expr using COND.
735 This routine does not handle PHI nodes with more than two arguments.
736 For example,
737 S1: A = PHI <x1(1), x2(5)
738 is converted into,
739 S2: A = cond ? x1 : x2;
740 S2 is inserted at the top of basic block's statement list.
741 PHI arguments are switched if SWITCH_ARGS is true.
742 */
743
744 static void
745 replace_phi_with_cond_modify_expr (tree phi, tree cond, bool switch_args,
746 block_stmt_iterator *bsi)
747 {
748 tree new_stmt;
749 basic_block bb;
750 tree rhs;
751 tree arg_0, arg_1;
752
753 #ifdef ENABLE_CHECKING
754 if (TREE_CODE (phi) != PHI_NODE)
755 abort ();
756
757 /* If this is not filtered earlier, then now it is too late. */
758 if (PHI_NUM_ARGS (phi) != 2)
759 abort ();
760 #endif
761
762 /* Find basic block and initialize iterator. */
763 bb = bb_for_stmt (phi);
764
765 new_stmt = NULL_TREE;
766 arg_0 = NULL_TREE;
767 arg_1 = NULL_TREE;
768
769 /* Use condition that is not TRUTH_NOT_EXPR in conditional modify expr. */
770 if (switch_args)
771 {
772 arg_0 = PHI_ARG_DEF (phi, 1);
773 arg_1 = PHI_ARG_DEF (phi, 0);
774 }
775 else
776 {
777 arg_0 = PHI_ARG_DEF (phi, 0);
778 arg_1 = PHI_ARG_DEF (phi, 1);
779 }
780
781 /* Build new RHS using selected condition and arguments. */
782 rhs = build (COND_EXPR, TREE_TYPE (PHI_RESULT (phi)),
783 unshare_expr (cond), unshare_expr (arg_0),
784 unshare_expr (arg_1));
785
786 /* Create new MODIFY expression using RHS. */
787 new_stmt = build (MODIFY_EXPR, TREE_TYPE (PHI_RESULT (phi)),
788 unshare_expr (PHI_RESULT (phi)), rhs);
789
790 /* Make new statement definition of the original phi result. */
791 SSA_NAME_DEF_STMT (PHI_RESULT (phi)) = new_stmt;
792
793 /* Set basic block and insert using iterator. */
794 set_bb_for_stmt (new_stmt, bb);
795
796 bsi_insert_after (bsi, new_stmt, BSI_SAME_STMT);
797 bsi_next (bsi);
798
799 modify_stmt (new_stmt);
800
801 if (dump_file && (dump_flags & TDF_DETAILS))
802 {
803 fprintf (dump_file, "new phi replacement stmt\n");
804 print_generic_stmt (dump_file, new_stmt, TDF_SLIM);
805 }
806 }
807
808 /* Process phi nodes for the given LOOP. Replace phi nodes with cond
809 modify expr. */
810
811 static void
812 process_phi_nodes (struct loop *loop)
813 {
814 basic_block bb;
815 unsigned int orig_loop_num_nodes = loop->num_nodes;
816 unsigned int i;
817
818 /* Replace phi nodes with cond. modify expr. */
819 for (i = 1; i < orig_loop_num_nodes; i++)
820 {
821 tree phi, cond;
822 block_stmt_iterator bsi;
823 bool switch_args = false;
824 bb = ifc_bbs[i];
825
826 if (bb == loop->header || bb == loop->latch)
827 continue;
828
829 phi = phi_nodes (bb);
830 bsi = bsi_start (bb);
831
832 /* BB has two predecessors. Using predecessor's aux field, set
833 appropriate condition for the PHI node replacement. */
834 if (phi)
835 switch_args = find_phi_replacement_condition (bb, &cond, &bsi);
836
837 while (phi)
838 {
839 tree next = TREE_CHAIN (phi);
840 replace_phi_with_cond_modify_expr (phi, cond, switch_args, &bsi);
841 release_phi_node (phi);
842 phi = next;
843 }
844 bb_ann (bb)->phi_nodes = NULL;
845 }
846 return;
847 }
848
849 /* Combine all basic block from the given LOOP into one or two super
850 basic block. Replace PHI nodes with conditional modify expression. */
851
852 static void
853 combine_blocks (struct loop *loop)
854 {
855 basic_block bb, exit_bb, merge_target_bb;
856 unsigned int orig_loop_num_nodes = loop->num_nodes;
857 unsigned int i;
858
859 /* Process phi nodes to prepare blocks for merge. */
860 process_phi_nodes (loop);
861
862 exit_bb = NULL;
863
864 /* Merge basic blocks */
865 merge_target_bb = loop->header;
866 for (i = 1; i < orig_loop_num_nodes; i++)
867 {
868 edge e;
869 block_stmt_iterator bsi;
870 tree_stmt_iterator last;
871
872 bb = ifc_bbs[i];
873
874 if (bb == loop->latch)
875 continue;
876
877 if (!exit_bb && bb_with_exit_edge_p (bb))
878 exit_bb = bb;
879
880 if (bb == exit_bb)
881 {
882 edge new_e;
883
884 /* Connect this node with loop header. */
885 new_e = make_edge (ifc_bbs[0], bb, EDGE_FALLTHRU);
886 set_immediate_dominator (CDI_DOMINATORS, bb, ifc_bbs[0]);
887
888 if (exit_bb != loop->latch)
889 {
890 /* Redirect non-exit edge to loop->latch. */
891 for (e = bb->succ; e; e = e->succ_next)
892 if (!(e->flags & EDGE_LOOP_EXIT))
893 {
894 redirect_edge_and_branch (e, loop->latch);
895 set_immediate_dominator (CDI_DOMINATORS, loop->latch, bb);
896 }
897 }
898 continue;
899 }
900
901 /* It is time to remove this basic block. First remove edges. */
902 while (bb->succ != NULL)
903 ssa_remove_edge (bb->succ);
904 while (bb->pred != NULL)
905 ssa_remove_edge (bb->pred);
906
907 /* Remove labels and make stmts member of loop->header. */
908 for (bsi = bsi_start (bb); !bsi_end_p (bsi); )
909 {
910 if (TREE_CODE (bsi_stmt (bsi)) == LABEL_EXPR)
911 bsi_remove (&bsi);
912 else
913 {
914 set_bb_for_stmt (bsi_stmt (bsi), merge_target_bb);
915 bsi_next (&bsi);
916 }
917 }
918
919 /* Update stmt list. */
920 last = tsi_last (merge_target_bb->stmt_list);
921 tsi_link_after (&last, bb->stmt_list, TSI_NEW_STMT);
922 bb->stmt_list = NULL;
923
924 /* Update dominator info. */
925 if (dom_computed[CDI_DOMINATORS])
926 delete_from_dominance_info (CDI_DOMINATORS, bb);
927 if (dom_computed[CDI_POST_DOMINATORS])
928 delete_from_dominance_info (CDI_POST_DOMINATORS, bb);
929
930 /* Remove basic block. */
931 remove_bb_from_loops (bb);
932 expunge_block (bb);
933 }
934 }
935
936 /* Make new temp variable of type TYPE. Add MODIFY_EXPR to assign EXP
937 to the new variable. */
938
939 static tree
940 ifc_temp_var (tree type, tree exp)
941 {
942 const char *name = "_ifc_";
943 tree var, stmt, new_name;
944
945 if (is_gimple_reg (exp))
946 return exp;
947
948 /* Create new temporary variable. */
949 var = create_tmp_var (type, name);
950 add_referenced_tmp_var (var);
951
952 /* Build new statement to assign EXP to new variable. */
953 stmt = build (MODIFY_EXPR, type, var, exp);
954
955 /* Get SSA name for the new variable and set make new statement
956 its definition statment. */
957 new_name = make_ssa_name (var, stmt);
958 TREE_OPERAND (stmt, 0) = new_name;
959 SSA_NAME_DEF_STMT (new_name) = stmt;
960
961 return stmt;
962 }
963
964
965 /* Return TRUE iff, all pred blocks of BB are visited.
966 Bitmap VISITED keeps history of visited blocks. */
967
968 static bool
969 pred_blocks_visited_p (basic_block bb, bitmap *visited)
970 {
971 edge e;
972 for (e = bb->pred; e; e = e->pred_next)
973 if (!bitmap_bit_p (*visited, e->src->index))
974 return false;
975
976 return true;
977 }
978
979 /* Get body of a LOOP in suitable order for if-conversion.
980 It is caller's responsibility to deallocate basic block
981 list. If-conversion suitable order is, BFS order with one
982 additional constraint. Select block in BFS block, if all
983 pred are already selected. */
984
985 static basic_block *
986 get_loop_body_in_if_conv_order (const struct loop *loop)
987 {
988 basic_block *blocks, *blocks_in_bfs_order;
989 basic_block bb;
990 bitmap visited;
991 unsigned int index = 0;
992 unsigned int visited_count = 0;
993
994 if (!loop->num_nodes)
995 abort ();
996
997 if (loop->latch == EXIT_BLOCK_PTR)
998 abort ();
999
1000 blocks = xcalloc (loop->num_nodes, sizeof (basic_block));
1001 visited = BITMAP_XMALLOC ();
1002
1003 blocks_in_bfs_order = get_loop_body_in_bfs_order (loop);
1004
1005 index = 0;
1006 while (index < loop->num_nodes)
1007 {
1008 bb = blocks_in_bfs_order [index];
1009
1010 if (bb->flags & BB_IRREDUCIBLE_LOOP)
1011 {
1012 free (blocks_in_bfs_order);
1013 BITMAP_FREE (visited);
1014 free (blocks);
1015 return NULL;
1016 }
1017 if (!bitmap_bit_p (visited, bb->index))
1018 {
1019 if (pred_blocks_visited_p (bb, &visited)
1020 || bb == loop->header)
1021 {
1022 /* This block is now visited. */
1023 bitmap_set_bit (visited, bb->index);
1024 blocks[visited_count++] = bb;
1025 }
1026 }
1027 index++;
1028 if (index == loop->num_nodes
1029 && visited_count != loop->num_nodes)
1030 {
1031 /* Not done yet. */
1032 index = 0;
1033 }
1034 }
1035 free (blocks_in_bfs_order);
1036 BITMAP_XFREE (visited);
1037 return blocks;
1038 }
1039
1040 /* Return true if one of the basic block BB edge is loop exit. */
1041
1042 static bool
1043 bb_with_exit_edge_p (basic_block bb)
1044 {
1045 edge e;
1046 bool exit_edge_found = false;
1047
1048 for (e = bb->succ; e && !exit_edge_found ; e = e->succ_next)
1049 if (e->flags & EDGE_LOOP_EXIT)
1050 exit_edge_found = true;
1051
1052 return exit_edge_found;
1053 }
1054
1055 /* Tree if-conversion pass management. */
1056
1057 static void
1058 main_tree_if_conversion (void)
1059 {
1060 unsigned i, loop_num;
1061 struct loop *loop;
1062
1063 if (!current_loops)
1064 return;
1065
1066 loop_num = current_loops->num;
1067 for (i = 0; i < loop_num; i++)
1068 {
1069 loop = current_loops->parray[i];
1070 if (!loop)
1071 continue;
1072
1073 tree_if_conversion (loop, true);
1074 }
1075
1076 }
1077
1078 static bool
1079 gate_tree_if_conversion (void)
1080 {
1081 return flag_tree_vectorize != 0;
1082 }
1083
1084 struct tree_opt_pass pass_if_conversion =
1085 {
1086 "ifcvt", /* name */
1087 gate_tree_if_conversion, /* gate */
1088 main_tree_if_conversion, /* execute */
1089 NULL, /* sub */
1090 NULL, /* next */
1091 0, /* static_pass_number */
1092 0, /* tv_id */
1093 PROP_cfg | PROP_ssa | PROP_alias, /* properties_required */
1094 0, /* properties_provided */
1095 0, /* properties_destroyed */
1096 TODO_dump_func, /* todo_flags_start */
1097 TODO_dump_func
1098 | TODO_verify_ssa
1099 | TODO_verify_stmts
1100 | TODO_verify_flow /* todo_flags_finish */
1101 };