00001
00002
00003
00004
00005
00006
00007
00008
00009
00010
00011
00012
00013
00014
00015
00016
00017
00018
00019
00020
00021
00022
00023
00024
00025
00026
00027
00028
00029
00030
00031
00032
00033
00034
00035
00036
00037
00038
00039
00040
00041
00042
00043
00044
00045
00046
00047
00048
00049
00050
00051
00052
00053
00054
00055
00056
00057
00058
00059
00060
00061
00062
00063
00064
00065
00066
00067
00068
00069
00070
00071
00072
00073
00074
00075
00076
00077
00078
00079
00080
00081
00082
00083 #include "config.h"
00084 #include "system.h"
00085 #include "coretypes.h"
00086 #include "tm.h"
00087 #include "errors.h"
00088 #include "tree.h"
00089 #include "c-common.h"
00090 #include "flags.h"
00091 #include "timevar.h"
00092 #include "varray.h"
00093 #include "rtl.h"
00094 #include "basic-block.h"
00095 #include "diagnostic.h"
00096 #include "tree-flow.h"
00097 #include "tree-dump.h"
00098 #include "cfgloop.h"
00099 #include "tree-chrec.h"
00100 #include "tree-data-ref.h"
00101 #include "tree-scalar-evolution.h"
00102 #include "tree-pass.h"
00103 #include "target.h"
00104
00105
00106 static void main_tree_if_conversion (void);
00107 static tree tree_if_convert_stmt (struct loop *loop, tree, tree,
00108 block_stmt_iterator *);
00109 static void tree_if_convert_cond_expr (struct loop *, tree, tree,
00110 block_stmt_iterator *);
00111 static bool if_convertible_phi_p (struct loop *, basic_block, tree);
00112 static bool if_convertible_modify_expr_p (struct loop *, basic_block, tree);
00113 static bool if_convertible_stmt_p (struct loop *, basic_block, tree);
00114 static bool if_convertible_bb_p (struct loop *, basic_block, bool);
00115 static bool if_convertible_loop_p (struct loop *, bool);
00116 static void add_to_predicate_list (basic_block, tree);
00117 static tree add_to_dst_predicate_list (struct loop * loop, basic_block, tree, tree,
00118 block_stmt_iterator *);
00119 static void clean_predicate_lists (struct loop *loop);
00120 static basic_block find_phi_replacement_condition (basic_block, tree *,
00121 block_stmt_iterator *);
00122 static void replace_phi_with_cond_modify_expr (tree, tree, basic_block,
00123 block_stmt_iterator *);
00124 static void process_phi_nodes (struct loop *);
00125 static void combine_blocks (struct loop *);
00126 static tree ifc_temp_var (tree, tree);
00127 static bool pred_blocks_visited_p (basic_block, bitmap *);
00128 static basic_block * get_loop_body_in_if_conv_order (const struct loop *loop);
00129 static bool bb_with_exit_edge_p (basic_block);
00130
00131
00132 static basic_block *ifc_bbs;
00133
00134
00135
00136
00137
00138
00139
00140
00141 static bool
00142 tree_if_conversion (struct loop *loop, bool for_vectorizer)
00143 {
00144 basic_block bb;
00145 block_stmt_iterator itr;
00146 tree cond;
00147 unsigned int i;
00148
00149 ifc_bbs = NULL;
00150
00151
00152
00153 if (!if_convertible_loop_p (loop, for_vectorizer))
00154 {
00155 if (dump_file && (dump_flags & TDF_DETAILS))
00156 fprintf (dump_file,"-------------------------\n");
00157 if (ifc_bbs)
00158 {
00159 free (ifc_bbs);
00160 ifc_bbs = NULL;
00161 }
00162 free_dominance_info (CDI_POST_DOMINATORS);
00163 free_df ();
00164 return false;
00165 }
00166
00167 cond = NULL_TREE;
00168
00169
00170 for (i = 0; i < loop->num_nodes; i++)
00171 {
00172 bb = ifc_bbs [i];
00173
00174
00175 cond = bb->aux;
00176
00177
00178
00179
00180 for (itr = bsi_start (bb); !bsi_end_p (itr); )
00181 {
00182 tree t = bsi_stmt (itr);
00183 cond = tree_if_convert_stmt (loop, t, cond, &itr);
00184 if (!bsi_end_p (itr))
00185 bsi_next (&itr);
00186 }
00187
00188
00189
00190 if (EDGE_COUNT (bb->succs) == 1)
00191 {
00192 basic_block bb_n = EDGE_SUCC (bb, 0)->dest;
00193 if (cond != NULL_TREE)
00194 add_to_predicate_list (bb_n, cond);
00195 cond = NULL_TREE;
00196 }
00197 }
00198
00199
00200
00201
00202 combine_blocks (loop);
00203
00204
00205 clean_predicate_lists (loop);
00206 free (ifc_bbs);
00207 ifc_bbs = NULL;
00208 free_df ();
00209
00210 return true;
00211 }
00212
00213
00214
00215
00216
00217
00218
00219
00220 static tree
00221 tree_if_convert_stmt (struct loop * loop, tree t, tree cond,
00222 block_stmt_iterator *bsi)
00223 {
00224 if (dump_file && (dump_flags & TDF_DETAILS))
00225 {
00226 fprintf (dump_file, "------if-convert stmt\n");
00227 print_generic_stmt (dump_file, t, TDF_SLIM);
00228 print_generic_stmt (dump_file, cond, TDF_SLIM);
00229 }
00230
00231 switch (TREE_CODE (t))
00232 {
00233
00234 case LABEL_EXPR:
00235 break;
00236
00237 case MODIFY_EXPR:
00238
00239
00240
00241
00242
00243 break;
00244
00245 case GOTO_EXPR:
00246
00247 add_to_predicate_list (bb_for_stmt (TREE_OPERAND (t, 1)), cond);
00248 bsi_remove (bsi);
00249 cond = NULL_TREE;
00250 break;
00251
00252 case COND_EXPR:
00253
00254
00255 tree_if_convert_cond_expr (loop, t, cond, bsi);
00256 cond = NULL_TREE;
00257 break;
00258
00259 default:
00260 gcc_unreachable ();
00261 }
00262 return cond;
00263 }
00264
00265
00266
00267
00268
00269
00270 static void
00271 tree_if_convert_cond_expr (struct loop *loop, tree stmt, tree cond,
00272 block_stmt_iterator *bsi)
00273 {
00274 tree c, c2, new_cond;
00275 edge true_edge, false_edge;
00276 new_cond = NULL_TREE;
00277
00278 gcc_assert (TREE_CODE (stmt) == COND_EXPR);
00279
00280 c = COND_EXPR_COND (stmt);
00281
00282
00283 if (!is_gimple_condexpr (c))
00284 {
00285 tree new_stmt;
00286 new_stmt = ifc_temp_var (TREE_TYPE (c), unshare_expr (c));
00287 bsi_insert_before (bsi, new_stmt, BSI_SAME_STMT);
00288 c = TREE_OPERAND (new_stmt, 0);
00289 }
00290
00291 extract_true_false_edges_from_block (bb_for_stmt (stmt),
00292 &true_edge, &false_edge);
00293
00294
00295
00296
00297 new_cond = add_to_dst_predicate_list (loop, true_edge->dest, cond,
00298 unshare_expr (c), bsi);
00299
00300 if (!is_gimple_reg(c) && is_gimple_condexpr (c))
00301 {
00302 tree new_stmt;
00303 new_stmt = ifc_temp_var (TREE_TYPE (c), unshare_expr (c));
00304 bsi_insert_before (bsi, new_stmt, BSI_SAME_STMT);
00305 c = TREE_OPERAND (new_stmt, 0);
00306 }
00307
00308
00309 c2 = invert_truthvalue (unshare_expr (c));
00310 add_to_dst_predicate_list (loop, false_edge->dest, cond, c2, bsi);
00311
00312
00313
00314
00315 if (!bb_with_exit_edge_p (bb_for_stmt (stmt)))
00316 {
00317 bsi_remove (bsi);
00318 cond = NULL_TREE;
00319 }
00320 return;
00321 }
00322
00323
00324
00325
00326
00327
00328
00329 static bool
00330 if_convertible_phi_p (struct loop *loop, basic_block bb, tree phi)
00331 {
00332 if (dump_file && (dump_flags & TDF_DETAILS))
00333 {
00334 fprintf (dump_file, "-------------------------\n");
00335 print_generic_stmt (dump_file, phi, TDF_SLIM);
00336 }
00337
00338 if (bb != loop->header && PHI_NUM_ARGS (phi) != 2)
00339 {
00340 if (dump_file && (dump_flags & TDF_DETAILS))
00341 fprintf (dump_file, "More than two phi node args.\n");
00342 return false;
00343 }
00344
00345 if (!is_gimple_reg (SSA_NAME_VAR (PHI_RESULT (phi))))
00346 {
00347 int j;
00348 dataflow_t df = get_immediate_uses (phi);
00349 int num_uses = num_immediate_uses (df);
00350 for (j = 0; j < num_uses; j++)
00351 {
00352 tree use = immediate_use (df, j);
00353 if (TREE_CODE (use) == PHI_NODE)
00354 {
00355 if (dump_file && (dump_flags & TDF_DETAILS))
00356 fprintf (dump_file, "Difficult to handle this virtual phi.\n");
00357 return false;
00358 }
00359 }
00360 }
00361
00362 return true;
00363 }
00364
00365
00366
00367
00368
00369
00370
00371
00372
00373 static bool
00374 if_convertible_modify_expr_p (struct loop *loop, basic_block bb, tree m_expr)
00375 {
00376 if (dump_file && (dump_flags & TDF_DETAILS))
00377 {
00378 fprintf (dump_file, "-------------------------\n");
00379 print_generic_stmt (dump_file, m_expr, TDF_SLIM);
00380 }
00381
00382
00383 if (movement_possibility (m_expr) == MOVE_IMPOSSIBLE)
00384 {
00385 if (dump_file && (dump_flags & TDF_DETAILS))
00386 fprintf (dump_file, "stmt is movable. Don't take risk\n");
00387 return false;
00388 }
00389
00390
00391 if (bb != loop->header
00392 && tree_could_trap_p (TREE_OPERAND (m_expr, 1)))
00393 {
00394 if (dump_file && (dump_flags & TDF_DETAILS))
00395 fprintf (dump_file, "tree could trap...\n");
00396 return false;
00397 }
00398
00399 if (TREE_CODE (TREE_OPERAND (m_expr, 1)) == CALL_EXPR)
00400 {
00401 if (dump_file && (dump_flags & TDF_DETAILS))
00402 fprintf (dump_file, "CALL_EXPR \n");
00403 return false;
00404 }
00405
00406 if (TREE_CODE (TREE_OPERAND (m_expr, 0)) != SSA_NAME
00407 && bb != loop->header
00408 && !bb_with_exit_edge_p (bb))
00409 {
00410 if (dump_file && (dump_flags & TDF_DETAILS))
00411 {
00412 fprintf (dump_file, "LHS is not var\n");
00413 print_generic_stmt (dump_file, m_expr, TDF_SLIM);
00414 }
00415 return false;
00416 }
00417
00418
00419 return true;
00420 }
00421
00422
00423
00424
00425
00426
00427
00428 static bool
00429 if_convertible_stmt_p (struct loop *loop, basic_block bb, tree stmt)
00430 {
00431 switch (TREE_CODE (stmt))
00432 {
00433 case LABEL_EXPR:
00434 break;
00435
00436 case MODIFY_EXPR:
00437
00438 if (!if_convertible_modify_expr_p (loop, bb, stmt))
00439 return false;
00440 break;
00441
00442 case GOTO_EXPR:
00443 case COND_EXPR:
00444 break;
00445
00446 default:
00447
00448 if (dump_file && (dump_flags & TDF_DETAILS))
00449 {
00450 fprintf (dump_file, "don't know what to do\n");
00451 print_generic_stmt (dump_file, stmt, TDF_SLIM);
00452 }
00453 return false;
00454 break;
00455 }
00456
00457 return true;
00458 }
00459
00460
00461
00462
00463
00464
00465
00466
00467
00468
00469 static bool
00470 if_convertible_bb_p (struct loop *loop, basic_block bb, bool exit_bb_seen)
00471 {
00472 edge e;
00473 edge_iterator ei;
00474
00475 if (dump_file && (dump_flags & TDF_DETAILS))
00476 fprintf (dump_file, "----------[%d]-------------\n", bb->index);
00477
00478 if (exit_bb_seen)
00479 {
00480 if (bb != loop->latch)
00481 {
00482 if (dump_file && (dump_flags & TDF_DETAILS))
00483 fprintf (dump_file, "basic block after exit bb but before latch\n");
00484 return false;
00485 }
00486 else if (!empty_block_p (bb))
00487 {
00488 if (dump_file && (dump_flags & TDF_DETAILS))
00489 fprintf (dump_file, "non empty basic block after exit bb\n");
00490 return false;
00491 }
00492 }
00493
00494
00495 FOR_EACH_EDGE (e, ei, bb->succs)
00496 if (e->flags &
00497 (EDGE_ABNORMAL_CALL | EDGE_EH | EDGE_ABNORMAL | EDGE_IRREDUCIBLE_LOOP))
00498 {
00499 if (dump_file && (dump_flags & TDF_DETAILS))
00500 fprintf (dump_file,"Difficult to handle edges\n");
00501 return false;
00502 }
00503
00504 return true;
00505 }
00506
00507
00508
00509
00510
00511
00512
00513
00514
00515
00516
00517
00518 static bool
00519 if_convertible_loop_p (struct loop *loop, bool for_vectorizer ATTRIBUTE_UNUSED)
00520 {
00521 tree phi;
00522 basic_block bb;
00523 block_stmt_iterator itr;
00524 unsigned int i;
00525 edge e;
00526 edge_iterator ei;
00527 bool exit_bb_seen = false;
00528
00529
00530 if (!loop || loop->inner)
00531 {
00532 if (dump_file && (dump_flags & TDF_DETAILS))
00533 fprintf (dump_file, "not inner most loop\n");
00534 return false;
00535 }
00536
00537 flow_loop_scan (loop, LOOP_ALL);
00538
00539
00540 if (loop->num_nodes <= 2)
00541 {
00542 if (dump_file && (dump_flags & TDF_DETAILS))
00543 fprintf (dump_file, "less than 2 basic blocks\n");
00544 return false;
00545 }
00546
00547
00548 if (loop->num_exits > 1)
00549 {
00550 if (dump_file && (dump_flags & TDF_DETAILS))
00551 fprintf (dump_file, "multiple exits\n");
00552 return false;
00553 }
00554
00555
00556
00557
00558
00559 FOR_EACH_EDGE (e, ei, loop->header->succs)
00560 if ( e->flags & EDGE_LOOP_EXIT)
00561 return false;
00562
00563 compute_immediate_uses (TDFA_USE_OPS|TDFA_USE_VOPS, NULL);
00564
00565 calculate_dominance_info (CDI_DOMINATORS);
00566 calculate_dominance_info (CDI_POST_DOMINATORS);
00567
00568
00569 ifc_bbs = get_loop_body_in_if_conv_order (loop);
00570 if (!ifc_bbs)
00571 {
00572 if (dump_file && (dump_flags & TDF_DETAILS))
00573 fprintf (dump_file,"Irreducible loop\n");
00574 free_dominance_info (CDI_POST_DOMINATORS);
00575 return false;
00576 }
00577
00578 for (i = 0; i < loop->num_nodes; i++)
00579 {
00580 bb = ifc_bbs[i];
00581
00582 if (!if_convertible_bb_p (loop, bb, exit_bb_seen))
00583 return false;
00584
00585
00586 for (itr = bsi_start (bb); !bsi_end_p (itr); bsi_next (&itr))
00587 if (!if_convertible_stmt_p (loop, bb, bsi_stmt (itr)))
00588 return false;
00589
00590
00591
00592 for (phi = phi_nodes (bb); phi; phi = PHI_CHAIN (phi))
00593 if (!if_convertible_phi_p (loop, bb, phi))
00594 return false;
00595
00596 if (bb_with_exit_edge_p (bb))
00597 exit_bb_seen = true;
00598 }
00599
00600
00601
00602 if (dump_file)
00603 fprintf (dump_file,"Applying if-conversion\n");
00604
00605 free_dominance_info (CDI_POST_DOMINATORS);
00606 return true;
00607 }
00608
00609
00610
00611 static void
00612 add_to_predicate_list (basic_block bb, tree new_cond)
00613 {
00614 tree cond = bb->aux;
00615
00616 if (cond)
00617 cond = fold (build (TRUTH_OR_EXPR, boolean_type_node,
00618 unshare_expr (cond), new_cond));
00619 else
00620 cond = new_cond;
00621
00622 bb->aux = cond;
00623 }
00624
00625
00626
00627
00628 static tree
00629 add_to_dst_predicate_list (struct loop * loop, basic_block bb,
00630 tree prev_cond, tree cond,
00631 block_stmt_iterator *bsi)
00632 {
00633 tree new_cond = NULL_TREE;
00634
00635 if (!flow_bb_inside_loop_p (loop, bb))
00636 return NULL_TREE;
00637
00638 if (prev_cond == boolean_true_node || !prev_cond)
00639 new_cond = unshare_expr (cond);
00640 else
00641 {
00642 tree tmp;
00643 tree tmp_stmt = NULL_TREE;
00644 tree tmp_stmts1 = NULL_TREE;
00645 tree tmp_stmts2 = NULL_TREE;
00646 prev_cond = force_gimple_operand (unshare_expr (prev_cond),
00647 &tmp_stmts1, true, NULL);
00648 if (tmp_stmts1)
00649 bsi_insert_before (bsi, tmp_stmts1, BSI_SAME_STMT);
00650
00651 cond = force_gimple_operand (unshare_expr (cond),
00652 &tmp_stmts2, true, NULL);
00653 if (tmp_stmts2)
00654 bsi_insert_before (bsi, tmp_stmts2, BSI_SAME_STMT);
00655
00656
00657 tmp = build (TRUTH_AND_EXPR, boolean_type_node,
00658 unshare_expr (prev_cond), cond);
00659 tmp_stmt = ifc_temp_var (boolean_type_node, tmp);
00660 bsi_insert_before (bsi, tmp_stmt, BSI_SAME_STMT);
00661 new_cond = TREE_OPERAND (tmp_stmt, 0);
00662 }
00663 add_to_predicate_list (bb, new_cond);
00664 return new_cond;
00665 }
00666
00667
00668
00669
00670 static void
00671 clean_predicate_lists (struct loop *loop)
00672 {
00673 basic_block *bb;
00674 unsigned int i;
00675 bb = get_loop_body (loop);
00676 for (i = 0; i < loop->num_nodes; i++)
00677 bb[i]->aux = NULL;
00678
00679 free (bb);
00680 }
00681
00682
00683
00684
00685
00686 static basic_block
00687 find_phi_replacement_condition (basic_block bb, tree *cond,
00688 block_stmt_iterator *bsi)
00689 {
00690 edge e;
00691 basic_block p1 = NULL;
00692 basic_block p2 = NULL;
00693 basic_block true_bb = NULL;
00694 tree tmp_cond;
00695 edge_iterator ei;
00696
00697 FOR_EACH_EDGE (e, ei, bb->preds)
00698 {
00699 if (p1 == NULL)
00700 p1 = e->src;
00701 else
00702 {
00703 gcc_assert (!p2);
00704 p2 = e->src;
00705 }
00706 }
00707
00708
00709 tmp_cond = p1->aux;
00710 if (TREE_CODE (tmp_cond) == TRUTH_NOT_EXPR)
00711 {
00712 *cond = p2->aux;
00713 true_bb = p2;
00714 }
00715 else
00716 {
00717 *cond = p1->aux;
00718 true_bb = p1;
00719 }
00720
00721
00722
00723
00724
00725 if (!is_gimple_reg (*cond) && !is_gimple_condexpr (*cond))
00726 {
00727 tree new_stmt;
00728
00729 new_stmt = ifc_temp_var (TREE_TYPE (*cond), unshare_expr (*cond));
00730 bsi_insert_after (bsi, new_stmt, BSI_SAME_STMT);
00731 bsi_next (bsi);
00732 *cond = TREE_OPERAND (new_stmt, 0);
00733 }
00734
00735 gcc_assert (*cond);
00736
00737 return true_bb;
00738 }
00739
00740
00741
00742
00743
00744
00745
00746
00747
00748
00749
00750
00751 static void
00752 replace_phi_with_cond_modify_expr (tree phi, tree cond, basic_block true_bb,
00753 block_stmt_iterator *bsi)
00754 {
00755 tree new_stmt;
00756 basic_block bb;
00757 tree rhs;
00758 tree arg_0, arg_1;
00759
00760 gcc_assert (TREE_CODE (phi) == PHI_NODE);
00761
00762
00763 gcc_assert (PHI_NUM_ARGS (phi) == 2);
00764
00765
00766 bb = bb_for_stmt (phi);
00767
00768 new_stmt = NULL_TREE;
00769 arg_0 = NULL_TREE;
00770 arg_1 = NULL_TREE;
00771
00772
00773 if (EDGE_PRED (bb, 1)->src == true_bb)
00774 {
00775 arg_0 = PHI_ARG_DEF (phi, 1);
00776 arg_1 = PHI_ARG_DEF (phi, 0);
00777 }
00778 else
00779 {
00780 arg_0 = PHI_ARG_DEF (phi, 0);
00781 arg_1 = PHI_ARG_DEF (phi, 1);
00782 }
00783
00784
00785 rhs = build (COND_EXPR, TREE_TYPE (PHI_RESULT (phi)),
00786 unshare_expr (cond), unshare_expr (arg_0),
00787 unshare_expr (arg_1));
00788
00789
00790 new_stmt = build (MODIFY_EXPR, TREE_TYPE (PHI_RESULT (phi)),
00791 unshare_expr (PHI_RESULT (phi)), rhs);
00792
00793
00794 SSA_NAME_DEF_STMT (PHI_RESULT (phi)) = new_stmt;
00795
00796
00797 set_bb_for_stmt (new_stmt, bb);
00798
00799 bsi_insert_after (bsi, new_stmt, BSI_SAME_STMT);
00800 bsi_next (bsi);
00801
00802 modify_stmt (new_stmt);
00803
00804 if (dump_file && (dump_flags & TDF_DETAILS))
00805 {
00806 fprintf (dump_file, "new phi replacement stmt\n");
00807 print_generic_stmt (dump_file, new_stmt, TDF_SLIM);
00808 }
00809 }
00810
00811
00812
00813
00814 static void
00815 process_phi_nodes (struct loop *loop)
00816 {
00817 basic_block bb;
00818 unsigned int orig_loop_num_nodes = loop->num_nodes;
00819 unsigned int i;
00820
00821
00822 for (i = 1; i < orig_loop_num_nodes; i++)
00823 {
00824 tree phi, cond;
00825 block_stmt_iterator bsi;
00826 basic_block true_bb = NULL;
00827 bb = ifc_bbs[i];
00828
00829 if (bb == loop->header)
00830 continue;
00831
00832 phi = phi_nodes (bb);
00833 bsi = bsi_after_labels (bb);
00834
00835
00836
00837 if (phi)
00838 true_bb = find_phi_replacement_condition (bb, &cond, &bsi);
00839
00840 while (phi)
00841 {
00842 tree next = PHI_CHAIN (phi);
00843 replace_phi_with_cond_modify_expr (phi, cond, true_bb, &bsi);
00844 release_phi_node (phi);
00845 phi = next;
00846 }
00847 bb_ann (bb)->phi_nodes = NULL;
00848 }
00849 return;
00850 }
00851
00852
00853
00854
00855 static void
00856 combine_blocks (struct loop *loop)
00857 {
00858 basic_block bb, exit_bb, merge_target_bb;
00859 unsigned int orig_loop_num_nodes = loop->num_nodes;
00860 unsigned int i;
00861 unsigned int n_exits;
00862 edge *exits = get_loop_exit_edges (loop, &n_exits);
00863
00864 process_phi_nodes (loop);
00865
00866 exit_bb = NULL;
00867
00868
00869 merge_target_bb = loop->header;
00870 for (i = 1; i < orig_loop_num_nodes; i++)
00871 {
00872 edge e;
00873 block_stmt_iterator bsi;
00874 tree_stmt_iterator last;
00875
00876 bb = ifc_bbs[i];
00877
00878 if (!exit_bb && bb_with_exit_edge_p (bb))
00879 exit_bb = bb;
00880
00881 if (bb == exit_bb)
00882 {
00883 edge new_e;
00884 edge_iterator ei;
00885
00886
00887 new_e = make_edge (ifc_bbs[0], bb, EDGE_FALLTHRU);
00888 set_immediate_dominator (CDI_DOMINATORS, bb, ifc_bbs[0]);
00889
00890 if (exit_bb != loop->latch)
00891 {
00892
00893 FOR_EACH_EDGE (e, ei, bb->succs)
00894 if (!(e->flags & EDGE_LOOP_EXIT))
00895 {
00896 redirect_edge_and_branch (e, loop->latch);
00897 set_immediate_dominator (CDI_DOMINATORS, loop->latch, bb);
00898 }
00899 }
00900 continue;
00901 }
00902
00903 if (bb == loop->latch && empty_block_p (bb))
00904 continue;
00905
00906
00907 while (EDGE_COUNT (bb->preds) > 0)
00908 remove_edge (EDGE_PRED (bb, 0));
00909
00910
00911
00912
00913 if (bb == loop->latch && n_exits == 0)
00914 {
00915 exits = NULL;
00916 make_edge (loop->header, loop->latch, EDGE_FALLTHRU);
00917 set_immediate_dominator (CDI_DOMINATORS, loop->latch, loop->header);
00918 continue;
00919 }
00920
00921 while (EDGE_COUNT (bb->succs) > 0)
00922 remove_edge (EDGE_SUCC (bb, 0));
00923
00924
00925 for (bsi = bsi_start (bb); !bsi_end_p (bsi); )
00926 {
00927 if (TREE_CODE (bsi_stmt (bsi)) == LABEL_EXPR)
00928 bsi_remove (&bsi);
00929 else
00930 {
00931 set_bb_for_stmt (bsi_stmt (bsi), merge_target_bb);
00932 bsi_next (&bsi);
00933 }
00934 }
00935
00936
00937 last = tsi_last (merge_target_bb->stmt_list);
00938 tsi_link_after (&last, bb->stmt_list, TSI_NEW_STMT);
00939 bb->stmt_list = NULL;
00940
00941
00942 if (dom_computed[CDI_DOMINATORS])
00943 delete_from_dominance_info (CDI_DOMINATORS, bb);
00944 if (dom_computed[CDI_POST_DOMINATORS])
00945 delete_from_dominance_info (CDI_POST_DOMINATORS, bb);
00946
00947
00948 if (bb == loop->latch)
00949 loop->latch = merge_target_bb;
00950 remove_bb_from_loops (bb);
00951 expunge_block (bb);
00952 }
00953
00954
00955
00956
00957 if (exit_bb
00958 && loop->header != loop->latch
00959 && exit_bb != loop->latch
00960 && empty_block_p (loop->latch))
00961 {
00962 if (can_merge_blocks_p (loop->header, exit_bb))
00963 {
00964 remove_bb_from_loops (exit_bb);
00965 merge_blocks (loop->header, exit_bb);
00966 }
00967 }
00968 }
00969
00970
00971
00972
00973 static tree
00974 ifc_temp_var (tree type, tree exp)
00975 {
00976 const char *name = "_ifc_";
00977 tree var, stmt, new_name;
00978
00979 if (is_gimple_reg (exp))
00980 return exp;
00981
00982
00983 var = create_tmp_var (type, name);
00984 add_referenced_tmp_var (var);
00985
00986
00987 stmt = build (MODIFY_EXPR, type, var, exp);
00988
00989
00990
00991 new_name = make_ssa_name (var, stmt);
00992 TREE_OPERAND (stmt, 0) = new_name;
00993 SSA_NAME_DEF_STMT (new_name) = stmt;
00994
00995 return stmt;
00996 }
00997
00998
00999
01000
01001
01002 static bool
01003 pred_blocks_visited_p (basic_block bb, bitmap *visited)
01004 {
01005 edge e;
01006 edge_iterator ei;
01007 FOR_EACH_EDGE (e, ei, bb->preds)
01008 if (!bitmap_bit_p (*visited, e->src->index))
01009 return false;
01010
01011 return true;
01012 }
01013
01014
01015
01016
01017
01018
01019
01020 static basic_block *
01021 get_loop_body_in_if_conv_order (const struct loop *loop)
01022 {
01023 basic_block *blocks, *blocks_in_bfs_order;
01024 basic_block bb;
01025 bitmap visited;
01026 unsigned int index = 0;
01027 unsigned int visited_count = 0;
01028
01029 gcc_assert (loop->num_nodes);
01030 gcc_assert (loop->latch != EXIT_BLOCK_PTR);
01031
01032 blocks = xcalloc (loop->num_nodes, sizeof (basic_block));
01033 visited = BITMAP_ALLOC (NULL);
01034
01035 blocks_in_bfs_order = get_loop_body_in_bfs_order (loop);
01036
01037 index = 0;
01038 while (index < loop->num_nodes)
01039 {
01040 bb = blocks_in_bfs_order [index];
01041
01042 if (bb->flags & BB_IRREDUCIBLE_LOOP)
01043 {
01044 free (blocks_in_bfs_order);
01045 BITMAP_FREE (visited);
01046 free (blocks);
01047 return NULL;
01048 }
01049 if (!bitmap_bit_p (visited, bb->index))
01050 {
01051 if (pred_blocks_visited_p (bb, &visited)
01052 || bb == loop->header)
01053 {
01054
01055 bitmap_set_bit (visited, bb->index);
01056 blocks[visited_count++] = bb;
01057 }
01058 }
01059 index++;
01060 if (index == loop->num_nodes
01061 && visited_count != loop->num_nodes)
01062 {
01063
01064 index = 0;
01065 }
01066 }
01067 free (blocks_in_bfs_order);
01068 BITMAP_FREE (visited);
01069 return blocks;
01070 }
01071
01072
01073
01074 static bool
01075 bb_with_exit_edge_p (basic_block bb)
01076 {
01077 edge e;
01078 edge_iterator ei;
01079 bool exit_edge_found = false;
01080
01081 FOR_EACH_EDGE (e, ei, bb->succs)
01082 if (e->flags & EDGE_LOOP_EXIT)
01083 {
01084 exit_edge_found = true;
01085 break;
01086 }
01087
01088 return exit_edge_found;
01089 }
01090
01091
01092
01093 static void
01094 main_tree_if_conversion (void)
01095 {
01096 unsigned i, loop_num;
01097 struct loop *loop;
01098
01099 if (!current_loops)
01100 return;
01101
01102 loop_num = current_loops->num;
01103 for (i = 0; i < loop_num; i++)
01104 {
01105 loop = current_loops->parray[i];
01106 if (!loop)
01107 continue;
01108
01109 tree_if_conversion (loop, true);
01110 }
01111
01112 }
01113
01114 static bool
01115 gate_tree_if_conversion (void)
01116 {
01117 return flag_tree_vectorize != 0;
01118 }
01119
01120 struct tree_opt_pass pass_if_conversion =
01121 {
01122 "ifcvt",
01123 gate_tree_if_conversion,
01124 main_tree_if_conversion,
01125 NULL,
01126 NULL,
01127 0,
01128 0,
01129 PROP_cfg | PROP_ssa | PROP_alias,
01130 0,
01131 0,
01132 TODO_dump_func,
01133 TODO_dump_func
01134 | TODO_verify_ssa
01135 | TODO_verify_stmts
01136 | TODO_verify_flow,
01137 0
01138 };