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