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
00084
00085
00086
00087
00088
00089
00090
00091
00092
00093
00094
00095
00096
00097
00098
00099
00100
00101
00102
00103
00104
00105
00106
00107
00108
00109
00110
00111
00112
00113
00114
00115
00116
00117
00118
00119
00120
00121
00122
00123 #include "config.h"
00124 #include "system.h"
00125 #include "coretypes.h"
00126 #include "tm.h"
00127 #include "errors.h"
00128 #include "ggc.h"
00129 #include "tree.h"
00130 #include "target.h"
00131 #include "rtl.h"
00132 #include "basic-block.h"
00133 #include "diagnostic.h"
00134 #include "tree-flow.h"
00135 #include "tree-dump.h"
00136 #include "timevar.h"
00137 #include "cfgloop.h"
00138 #include "cfglayout.h"
00139 #include "expr.h"
00140 #include "optabs.h"
00141 #include "toplev.h"
00142 #include "tree-chrec.h"
00143 #include "tree-data-ref.h"
00144 #include "tree-scalar-evolution.h"
00145 #include "input.h"
00146 #include "tree-vectorizer.h"
00147 #include "tree-pass.h"
00148
00149
00150
00151
00152 static struct loop *slpeel_tree_duplicate_loop_to_edge_cfg
00153 (struct loop *, struct loops *, edge);
00154 static void slpeel_update_phis_for_duplicate_loop
00155 (struct loop *, struct loop *, bool after);
00156 static void slpeel_update_phi_nodes_for_guard (edge, struct loop *, bool, bool);
00157 static edge slpeel_add_loop_guard (basic_block, tree, basic_block, basic_block);
00158
00159 static void allocate_new_names (bitmap);
00160 static void rename_use_op (use_operand_p);
00161 static void rename_def_op (def_operand_p, tree);
00162 static void rename_variables_in_bb (basic_block);
00163 static void free_new_names (bitmap);
00164 static void rename_variables_in_loop (struct loop *);
00165
00166
00167
00168
00169 static void vect_set_dump_settings (void);
00170 static bool need_imm_uses_for (tree);
00171
00172
00173 FILE *vect_dump;
00174
00175
00176
00177 enum verbosity_levels vect_verbosity_level = MAX_VERBOSITY_LEVEL;
00178
00179
00180
00181
00182
00183
00184
00185
00186
00187
00188
00189
00190
00191 static void
00192 allocate_new_names (bitmap definitions)
00193 {
00194 unsigned ver;
00195 bitmap_iterator bi;
00196
00197 EXECUTE_IF_SET_IN_BITMAP (definitions, 0, ver, bi)
00198 {
00199 tree def = ssa_name (ver);
00200 tree *new_name_ptr = xmalloc (sizeof (tree));
00201
00202 bool abnormal = SSA_NAME_OCCURS_IN_ABNORMAL_PHI (def);
00203
00204 *new_name_ptr = duplicate_ssa_name (def, SSA_NAME_DEF_STMT (def));
00205 SSA_NAME_OCCURS_IN_ABNORMAL_PHI (*new_name_ptr) = abnormal;
00206
00207 SSA_NAME_AUX (def) = new_name_ptr;
00208 }
00209 }
00210
00211
00212
00213
00214 static void
00215 rename_use_op (use_operand_p op_p)
00216 {
00217 tree *new_name_ptr;
00218
00219 if (TREE_CODE (USE_FROM_PTR (op_p)) != SSA_NAME)
00220 return;
00221
00222 new_name_ptr = SSA_NAME_AUX (USE_FROM_PTR (op_p));
00223
00224
00225 if (!new_name_ptr)
00226 return;
00227
00228
00229
00230 SET_USE (op_p, *new_name_ptr);
00231 }
00232
00233
00234
00235
00236 static void
00237 rename_def_op (def_operand_p op_p, tree stmt)
00238 {
00239 tree *new_name_ptr;
00240
00241 if (TREE_CODE (DEF_FROM_PTR (op_p)) != SSA_NAME)
00242 return;
00243
00244 new_name_ptr = SSA_NAME_AUX (DEF_FROM_PTR (op_p));
00245
00246
00247 if (!new_name_ptr)
00248 return;
00249
00250
00251
00252 SET_DEF (op_p, *new_name_ptr);
00253 SSA_NAME_DEF_STMT (DEF_FROM_PTR (op_p)) = stmt;
00254 }
00255
00256
00257
00258
00259 static void
00260 rename_variables_in_bb (basic_block bb)
00261 {
00262 tree phi;
00263 block_stmt_iterator bsi;
00264 tree stmt;
00265 stmt_ann_t ann;
00266 use_optype uses;
00267 vuse_optype vuses;
00268 def_optype defs;
00269 v_may_def_optype v_may_defs;
00270 v_must_def_optype v_must_defs;
00271 unsigned i;
00272 edge e;
00273 edge_iterator ei;
00274 struct loop *loop = bb->loop_father;
00275
00276 for (phi = phi_nodes (bb); phi; phi = PHI_CHAIN (phi))
00277 rename_def_op (PHI_RESULT_PTR (phi), phi);
00278
00279 for (bsi = bsi_start (bb); !bsi_end_p (bsi); bsi_next (&bsi))
00280 {
00281 stmt = bsi_stmt (bsi);
00282 get_stmt_operands (stmt);
00283 ann = stmt_ann (stmt);
00284
00285 uses = USE_OPS (ann);
00286 for (i = 0; i < NUM_USES (uses); i++)
00287 rename_use_op (USE_OP_PTR (uses, i));
00288
00289 defs = DEF_OPS (ann);
00290 for (i = 0; i < NUM_DEFS (defs); i++)
00291 rename_def_op (DEF_OP_PTR (defs, i), stmt);
00292
00293 vuses = VUSE_OPS (ann);
00294 for (i = 0; i < NUM_VUSES (vuses); i++)
00295 rename_use_op (VUSE_OP_PTR (vuses, i));
00296
00297 v_may_defs = V_MAY_DEF_OPS (ann);
00298 for (i = 0; i < NUM_V_MAY_DEFS (v_may_defs); i++)
00299 {
00300 rename_use_op (V_MAY_DEF_OP_PTR (v_may_defs, i));
00301 rename_def_op (V_MAY_DEF_RESULT_PTR (v_may_defs, i), stmt);
00302 }
00303
00304 v_must_defs = V_MUST_DEF_OPS (ann);
00305 for (i = 0; i < NUM_V_MUST_DEFS (v_must_defs); i++)
00306 {
00307 rename_use_op (V_MUST_DEF_KILL_PTR (v_must_defs, i));
00308 rename_def_op (V_MUST_DEF_RESULT_PTR (v_must_defs, i), stmt);
00309 }
00310 }
00311
00312 FOR_EACH_EDGE (e, ei, bb->succs)
00313 {
00314 if (!flow_bb_inside_loop_p (loop, e->dest))
00315 continue;
00316 for (phi = phi_nodes (e->dest); phi; phi = PHI_CHAIN (phi))
00317 rename_use_op (PHI_ARG_DEF_PTR_FROM_EDGE (phi, e));
00318 }
00319 }
00320
00321
00322
00323
00324 static void
00325 free_new_names (bitmap definitions)
00326 {
00327 unsigned ver;
00328 bitmap_iterator bi;
00329
00330 EXECUTE_IF_SET_IN_BITMAP (definitions, 0, ver, bi)
00331 {
00332 tree def = ssa_name (ver);
00333
00334 if (SSA_NAME_AUX (def))
00335 {
00336 free (SSA_NAME_AUX (def));
00337 SSA_NAME_AUX (def) = NULL;
00338 }
00339 }
00340 }
00341
00342
00343
00344
00345 static void
00346 rename_variables_in_loop (struct loop *loop)
00347 {
00348 unsigned i;
00349 basic_block *bbs;
00350
00351 bbs = get_loop_body (loop);
00352
00353 for (i = 0; i < loop->num_nodes; i++)
00354 rename_variables_in_bb (bbs[i]);
00355
00356 free (bbs);
00357 }
00358
00359
00360
00361
00362
00363
00364
00365
00366
00367 static void
00368 slpeel_update_phis_for_duplicate_loop (struct loop *orig_loop,
00369 struct loop *new_loop, bool after)
00370 {
00371 tree *new_name_ptr, new_ssa_name;
00372 tree phi_new, phi_orig;
00373 tree def;
00374 edge orig_loop_latch = loop_latch_edge (orig_loop);
00375 edge orig_entry_e = loop_preheader_edge (orig_loop);
00376 edge new_loop_exit_e = new_loop->exit_edges[0];
00377 edge new_loop_entry_e = loop_preheader_edge (new_loop);
00378 edge entry_arg_e = (after ? orig_loop_latch : orig_entry_e);
00379
00380
00381
00382
00383
00384
00385
00386
00387
00388
00389
00390
00391
00392
00393
00394
00395
00396
00397
00398
00399
00400
00401
00402
00403
00404
00405
00406
00407
00408
00409 for (phi_new = phi_nodes (new_loop->header),
00410 phi_orig = phi_nodes (orig_loop->header);
00411 phi_new && phi_orig;
00412 phi_new = PHI_CHAIN (phi_new), phi_orig = PHI_CHAIN (phi_orig))
00413 {
00414
00415 def = PHI_ARG_DEF_FROM_EDGE (phi_orig, entry_arg_e);
00416 add_phi_arg (phi_new, def, new_loop_entry_e);
00417
00418
00419 def = PHI_ARG_DEF_FROM_EDGE (phi_orig, orig_loop_latch);
00420 if (TREE_CODE (def) != SSA_NAME)
00421 continue;
00422
00423 new_name_ptr = SSA_NAME_AUX (def);
00424 if (!new_name_ptr)
00425
00426 continue;
00427
00428
00429 new_ssa_name = *new_name_ptr;
00430 add_phi_arg (phi_new, new_ssa_name, loop_latch_edge (new_loop));
00431
00432
00433 if (!after)
00434 {
00435 gcc_assert (new_loop_exit_e == orig_entry_e);
00436 SET_PHI_ARG_DEF (phi_orig,
00437 new_loop_exit_e->dest_idx,
00438 new_ssa_name);
00439 }
00440 }
00441 }
00442
00443
00444
00445
00446
00447
00448
00449
00450
00451
00452
00453
00454
00455
00456
00457
00458
00459
00460
00461
00462
00463
00464
00465
00466
00467
00468
00469
00470
00471
00472
00473
00474
00475
00476
00477
00478
00479
00480
00481
00482
00483
00484
00485
00486
00487
00488
00489
00490
00491
00492
00493
00494
00495 static void
00496 slpeel_update_phi_nodes_for_guard (edge guard_edge,
00497 struct loop *loop,
00498 bool entry_phis,
00499 bool is_new_loop)
00500 {
00501 tree orig_phi, new_phi, update_phi;
00502 tree guard_arg, loop_arg;
00503 basic_block new_merge_bb = guard_edge->dest;
00504 edge e = EDGE_SUCC (new_merge_bb, 0);
00505 basic_block update_bb = e->dest;
00506 basic_block orig_bb = (entry_phis ? loop->header : update_bb);
00507
00508 for (orig_phi = phi_nodes (orig_bb), update_phi = phi_nodes (update_bb);
00509 orig_phi && update_phi;
00510 orig_phi = PHI_CHAIN (orig_phi), update_phi = PHI_CHAIN (update_phi))
00511 {
00512
00513 new_phi = create_phi_node (SSA_NAME_VAR (PHI_RESULT (orig_phi)),
00514 new_merge_bb);
00515
00516
00517
00518 if (entry_phis)
00519 {
00520 loop_arg = PHI_ARG_DEF_FROM_EDGE (orig_phi,
00521 EDGE_SUCC (loop->latch, 0));
00522 guard_arg = PHI_ARG_DEF_FROM_EDGE (orig_phi, loop->entry_edges[0]);
00523 }
00524 else
00525 {
00526 tree orig_def = PHI_ARG_DEF_FROM_EDGE (orig_phi, e);
00527 tree *new_name_ptr = SSA_NAME_AUX (orig_def);
00528 tree new_name;
00529
00530 if (new_name_ptr)
00531 new_name = *new_name_ptr;
00532 else
00533
00534 new_name = orig_def;
00535
00536 if (is_new_loop)
00537 {
00538 guard_arg = orig_def;
00539 loop_arg = new_name;
00540 }
00541 else
00542 {
00543 guard_arg = new_name;
00544 loop_arg = orig_def;
00545 }
00546 }
00547 add_phi_arg (new_phi, loop_arg, loop->exit_edges[0]);
00548 add_phi_arg (new_phi, guard_arg, guard_edge);
00549
00550
00551 gcc_assert (PHI_ARG_DEF_FROM_EDGE (update_phi, e) == loop_arg
00552 || PHI_ARG_DEF_FROM_EDGE (update_phi, e) == guard_arg);
00553 SET_PHI_ARG_DEF (update_phi, e->dest_idx, PHI_RESULT (new_phi));
00554 }
00555
00556 set_phi_nodes (new_merge_bb, phi_reverse (phi_nodes (new_merge_bb)));
00557 }
00558
00559
00560
00561
00562
00563
00564
00565 void
00566 slpeel_make_loop_iterate_ntimes (struct loop *loop, tree niters)
00567 {
00568 tree indx_before_incr, indx_after_incr, cond_stmt, cond;
00569 tree orig_cond;
00570 edge exit_edge = loop->exit_edges[0];
00571 block_stmt_iterator loop_cond_bsi;
00572 block_stmt_iterator incr_bsi;
00573 bool insert_after;
00574 tree begin_label = tree_block_label (loop->latch);
00575 tree exit_label = tree_block_label (loop->single_exit->dest);
00576 tree init = build_int_cst (TREE_TYPE (niters), 0);
00577 tree step = build_int_cst (TREE_TYPE (niters), 1);
00578 tree then_label;
00579 tree else_label;
00580 LOC loop_loc;
00581
00582 orig_cond = get_loop_exit_condition (loop);
00583 #ifdef ENABLE_CHECKING
00584 gcc_assert (orig_cond);
00585 #endif
00586 loop_cond_bsi = bsi_for_stmt (orig_cond);
00587
00588 standard_iv_increment_position (loop, &incr_bsi, &insert_after);
00589 create_iv (init, step, NULL_TREE, loop,
00590 &incr_bsi, insert_after, &indx_before_incr, &indx_after_incr);
00591
00592 if (exit_edge->flags & EDGE_TRUE_VALUE)
00593 {
00594 cond = build2 (GE_EXPR, boolean_type_node, indx_after_incr, niters);
00595 then_label = build1 (GOTO_EXPR, void_type_node, exit_label);
00596 else_label = build1 (GOTO_EXPR, void_type_node, begin_label);
00597 }
00598 else
00599 {
00600 cond = build2 (LT_EXPR, boolean_type_node, indx_after_incr, niters);
00601 then_label = build1 (GOTO_EXPR, void_type_node, begin_label);
00602 else_label = build1 (GOTO_EXPR, void_type_node, exit_label);
00603 }
00604
00605 cond_stmt = build3 (COND_EXPR, TREE_TYPE (orig_cond), cond,
00606 then_label, else_label);
00607 bsi_insert_before (&loop_cond_bsi, cond_stmt, BSI_SAME_STMT);
00608
00609
00610 bsi_remove (&loop_cond_bsi);
00611
00612 loop_loc = find_loop_location (loop);
00613 if (dump_file && (dump_flags & TDF_DETAILS))
00614 {
00615 if (loop_loc != UNKNOWN_LOC)
00616 fprintf (dump_file, "\nloop at %s:%d: ",
00617 LOC_FILE (loop_loc), LOC_LINE (loop_loc));
00618 print_generic_expr (dump_file, cond_stmt, TDF_SLIM);
00619 }
00620
00621 loop->nb_iterations = niters;
00622 }
00623
00624
00625
00626
00627
00628 static struct loop *
00629 slpeel_tree_duplicate_loop_to_edge_cfg (struct loop *loop, struct loops *loops,
00630 edge e)
00631 {
00632 struct loop *new_loop;
00633 basic_block *new_bbs, *bbs;
00634 bool at_exit;
00635 bool was_imm_dom;
00636 basic_block exit_dest;
00637 tree phi, phi_arg;
00638
00639 at_exit = (e == loop->exit_edges[0]);
00640 if (!at_exit && e != loop_preheader_edge (loop))
00641 return NULL;
00642
00643 bbs = get_loop_body (loop);
00644
00645
00646 if (!can_copy_bbs_p (bbs, loop->num_nodes))
00647 {
00648 free (bbs);
00649 return NULL;
00650 }
00651
00652
00653 new_loop = duplicate_loop (loops, loop, loop->outer);
00654 if (!new_loop)
00655 {
00656 free (bbs);
00657 return NULL;
00658 }
00659
00660 exit_dest = loop->exit_edges[0]->dest;
00661 was_imm_dom = (get_immediate_dominator (CDI_DOMINATORS,
00662 exit_dest) == loop->header ?
00663 true : false);
00664
00665 new_bbs = xmalloc (sizeof (basic_block) * loop->num_nodes);
00666
00667 copy_bbs (bbs, loop->num_nodes, new_bbs, NULL, 0, NULL, NULL);
00668
00669
00670
00671 for (phi = phi_nodes (exit_dest); phi; phi = PHI_CHAIN (phi))
00672 {
00673 phi_arg = PHI_ARG_DEF_FROM_EDGE (phi, loop->exit_edges[0]);
00674 if (phi_arg)
00675 {
00676 edge new_loop_exit_edge;
00677
00678 if (EDGE_SUCC (new_loop->header, 0)->dest == new_loop->latch)
00679 new_loop_exit_edge = EDGE_SUCC (new_loop->header, 1);
00680 else
00681 new_loop_exit_edge = EDGE_SUCC (new_loop->header, 0);
00682
00683 add_phi_arg (phi, phi_arg, new_loop_exit_edge);
00684 }
00685 }
00686
00687 if (at_exit)
00688 {
00689 redirect_edge_and_branch_force (e, new_loop->header);
00690 set_immediate_dominator (CDI_DOMINATORS, new_loop->header, e->src);
00691 if (was_imm_dom)
00692 set_immediate_dominator (CDI_DOMINATORS, exit_dest, new_loop->header);
00693 }
00694 else
00695 {
00696 edge new_exit_e;
00697 edge entry_e = loop_preheader_edge (loop);
00698 basic_block preheader = entry_e->src;
00699
00700 if (!flow_bb_inside_loop_p (new_loop,
00701 EDGE_SUCC (new_loop->header, 0)->dest))
00702 new_exit_e = EDGE_SUCC (new_loop->header, 0);
00703 else
00704 new_exit_e = EDGE_SUCC (new_loop->header, 1);
00705
00706 redirect_edge_and_branch_force (new_exit_e, loop->header);
00707 set_immediate_dominator (CDI_DOMINATORS, loop->header,
00708 new_exit_e->src);
00709
00710
00711
00712 for (phi = phi_nodes (loop->header); phi; phi = PHI_CHAIN (phi))
00713 {
00714 phi_arg = PHI_ARG_DEF_FROM_EDGE (phi, entry_e);
00715 if (phi_arg)
00716 add_phi_arg (phi, phi_arg, new_exit_e);
00717 }
00718
00719 redirect_edge_and_branch_force (entry_e, new_loop->header);
00720 set_immediate_dominator (CDI_DOMINATORS, new_loop->header, preheader);
00721 }
00722
00723 flow_loop_scan (new_loop, LOOP_ALL);
00724 flow_loop_scan (loop, LOOP_ALL);
00725 free (new_bbs);
00726 free (bbs);
00727
00728 return new_loop;
00729 }
00730
00731
00732
00733
00734
00735
00736
00737 static edge
00738 slpeel_add_loop_guard (basic_block guard_bb, tree cond, basic_block exit_bb,
00739 basic_block dom_bb)
00740 {
00741 block_stmt_iterator bsi;
00742 edge new_e, enter_e;
00743 tree cond_stmt, then_label, else_label;
00744
00745 enter_e = EDGE_SUCC (guard_bb, 0);
00746 enter_e->flags &= ~EDGE_FALLTHRU;
00747 enter_e->flags |= EDGE_FALSE_VALUE;
00748 bsi = bsi_last (guard_bb);
00749
00750 then_label = build1 (GOTO_EXPR, void_type_node,
00751 tree_block_label (exit_bb));
00752 else_label = build1 (GOTO_EXPR, void_type_node,
00753 tree_block_label (enter_e->dest));
00754 cond_stmt = build3 (COND_EXPR, void_type_node, cond,
00755 then_label, else_label);
00756 bsi_insert_after (&bsi, cond_stmt, BSI_NEW_STMT);
00757
00758 new_e = make_edge (guard_bb, exit_bb, EDGE_TRUE_VALUE);
00759 set_immediate_dominator (CDI_DOMINATORS, exit_bb, dom_bb);
00760 return new_e;
00761 }
00762
00763
00764
00765
00766
00767
00768
00769
00770
00771
00772 bool
00773 slpeel_can_duplicate_loop_p (struct loop *loop, edge e)
00774 {
00775 edge exit_e = loop->exit_edges [0];
00776 edge entry_e = loop_preheader_edge (loop);
00777 tree orig_cond = get_loop_exit_condition (loop);
00778 block_stmt_iterator loop_exit_bsi = bsi_last (exit_e->src);
00779
00780 if (any_marked_for_rewrite_p ())
00781 return false;
00782
00783 if (loop->inner
00784
00785
00786 || !loop->outer
00787 || loop->num_nodes != 2
00788 || !empty_block_p (loop->latch)
00789 || loop->num_exits != 1
00790 || loop->num_entries != 1
00791
00792 || (!orig_cond || orig_cond != bsi_stmt (loop_exit_bsi))
00793 || (e != exit_e && e != entry_e))
00794 return false;
00795
00796 return true;
00797 }
00798
00799 #ifdef ENABLE_CHECKING
00800 void
00801 slpeel_verify_cfg_after_peeling (struct loop *first_loop,
00802 struct loop *second_loop)
00803 {
00804 basic_block loop1_exit_bb = first_loop->exit_edges[0]->dest;
00805 basic_block loop2_entry_bb = second_loop->pre_header;
00806 basic_block loop1_entry_bb = loop_preheader_edge (first_loop)->src;
00807
00808
00809
00810
00811
00812
00813 gcc_assert (EDGE_COUNT (loop1_exit_bb->succs) == 2);
00814
00815
00816
00817
00818
00819
00820
00821
00822 gcc_assert (EDGE_COUNT (loop2_entry_bb->preds) == 2
00823 && ((EDGE_PRED (loop2_entry_bb, 0)->src == loop1_exit_bb
00824 && EDGE_PRED (loop2_entry_bb, 1)->src == loop1_entry_bb)
00825 || (EDGE_PRED (loop2_entry_bb, 1)->src == loop1_exit_bb
00826 && EDGE_PRED (loop2_entry_bb, 0)->src == loop1_entry_bb)));
00827
00828
00829
00830
00831 }
00832 #endif
00833
00834
00835
00836
00837
00838
00839
00840
00841
00842
00843
00844
00845
00846
00847
00848
00849
00850
00851
00852
00853
00854
00855
00856
00857
00858
00859
00860
00861
00862
00863
00864
00865
00866
00867
00868
00869
00870
00871 struct loop*
00872 slpeel_tree_peel_loop_to_edge (struct loop *loop, struct loops *loops,
00873 edge e, tree first_niters,
00874 tree niters, bool update_first_loop_count)
00875 {
00876 struct loop *new_loop = NULL, *first_loop, *second_loop;
00877 edge skip_e;
00878 tree pre_condition;
00879 bitmap definitions;
00880 basic_block bb_before_second_loop, bb_after_second_loop;
00881 basic_block bb_before_first_loop;
00882 basic_block bb_between_loops;
00883 edge exit_e = loop->exit_edges [0];
00884 LOC loop_loc;
00885
00886 if (!slpeel_can_duplicate_loop_p (loop, e))
00887 return NULL;
00888
00889
00890
00891
00892
00893 tree_register_cfg_hooks ();
00894
00895
00896
00897
00898
00899
00900
00901
00902
00903
00904
00905
00906
00907
00908
00909
00910 if (!(new_loop = slpeel_tree_duplicate_loop_to_edge_cfg (loop, loops, e)))
00911 {
00912 loop_loc = find_loop_location (loop);
00913 if (dump_file && (dump_flags & TDF_DETAILS))
00914 {
00915 if (loop_loc != UNKNOWN_LOC)
00916 fprintf (dump_file, "\n%s:%d: note: ",
00917 LOC_FILE (loop_loc), LOC_LINE (loop_loc));
00918 fprintf (dump_file, "tree_duplicate_loop_to_edge_cfg failed.\n");
00919 }
00920 return NULL;
00921 }
00922
00923 if (e == exit_e)
00924 {
00925
00926 first_loop = loop;
00927 second_loop = new_loop;
00928 }
00929 else
00930 {
00931
00932 first_loop = new_loop;
00933 second_loop = loop;
00934 }
00935
00936 definitions = marked_ssa_names ();
00937 allocate_new_names (definitions);
00938 slpeel_update_phis_for_duplicate_loop (loop, new_loop, e == exit_e);
00939 rename_variables_in_loop (new_loop);
00940
00941
00942
00943
00944
00945
00946
00947
00948
00949
00950
00951
00952
00953
00954
00955
00956
00957
00958
00959
00960
00961
00962 bb_before_first_loop = split_edge (loop_preheader_edge (first_loop));
00963 add_bb_to_loop (bb_before_first_loop, first_loop->outer);
00964 bb_before_second_loop = split_edge (first_loop->exit_edges[0]);
00965 add_bb_to_loop (bb_before_second_loop, first_loop->outer);
00966 flow_loop_scan (first_loop, LOOP_ALL);
00967 flow_loop_scan (second_loop, LOOP_ALL);
00968
00969 pre_condition =
00970 build2 (LE_EXPR, boolean_type_node, first_niters, integer_zero_node);
00971 skip_e = slpeel_add_loop_guard (bb_before_first_loop, pre_condition,
00972 bb_before_second_loop, bb_before_first_loop);
00973 slpeel_update_phi_nodes_for_guard (skip_e, first_loop, true ,
00974 first_loop == new_loop);
00975
00976
00977
00978
00979
00980
00981
00982
00983
00984
00985
00986
00987
00988
00989
00990
00991
00992
00993
00994
00995
00996
00997
00998
00999
01000
01001
01002
01003 bb_between_loops = split_edge (first_loop->exit_edges[0]);
01004 add_bb_to_loop (bb_between_loops, first_loop->outer);
01005 bb_after_second_loop = split_edge (second_loop->exit_edges[0]);
01006 add_bb_to_loop (bb_after_second_loop, second_loop->outer);
01007 flow_loop_scan (first_loop, LOOP_ALL);
01008 flow_loop_scan (second_loop, LOOP_ALL);
01009
01010 pre_condition = build2 (EQ_EXPR, boolean_type_node, first_niters, niters);
01011 skip_e = slpeel_add_loop_guard (bb_between_loops, pre_condition,
01012 bb_after_second_loop, bb_before_first_loop);
01013 slpeel_update_phi_nodes_for_guard (skip_e, second_loop, false ,
01014 second_loop == new_loop);
01015
01016
01017 first_loop->single_exit = first_loop->exit_edges[0];
01018 second_loop->single_exit = second_loop->exit_edges[0];
01019
01020
01021
01022 if (update_first_loop_count)
01023 slpeel_make_loop_iterate_ntimes (first_loop, first_niters);
01024
01025 free_new_names (definitions);
01026 BITMAP_FREE (definitions);
01027 unmark_all_for_rewrite ();
01028
01029 return new_loop;
01030 }
01031
01032
01033
01034
01035
01036
01037
01038
01039 LOC
01040 find_loop_location (struct loop *loop)
01041 {
01042 tree node = NULL_TREE;
01043 basic_block bb;
01044 block_stmt_iterator si;
01045
01046 if (!loop)
01047 return UNKNOWN_LOC;
01048
01049 node = get_loop_exit_condition (loop);
01050
01051 if (node && EXPR_P (node) && EXPR_HAS_LOCATION (node)
01052 && EXPR_FILENAME (node) && EXPR_LINENO (node))
01053 return EXPR_LOC (node);
01054
01055
01056
01057
01058 if (!loop->header)
01059 return UNKNOWN_LOC;
01060
01061 bb = loop->header;
01062
01063 for (si = bsi_start (bb); !bsi_end_p (si); bsi_next (&si))
01064 {
01065 node = bsi_stmt (si);
01066 if (node && EXPR_P (node) && EXPR_HAS_LOCATION (node))
01067 return EXPR_LOC (node);
01068 }
01069
01070 return UNKNOWN_LOC;
01071 }
01072
01073
01074
01075
01076
01077
01078
01079
01080
01081
01082
01083 void
01084 vect_set_verbosity_level (const char *val)
01085 {
01086 unsigned int vl;
01087
01088 vl = atoi (val);
01089 if (vl < MAX_VERBOSITY_LEVEL)
01090 vect_verbosity_level = vl;
01091 else
01092 vect_verbosity_level = MAX_VERBOSITY_LEVEL - 1;
01093 }
01094
01095
01096
01097
01098
01099
01100
01101
01102
01103
01104
01105 static void
01106 vect_set_dump_settings (void)
01107 {
01108 vect_dump = dump_file;
01109
01110
01111 if (vect_verbosity_level != MAX_VERBOSITY_LEVEL)
01112 {
01113
01114 if (!dump_file)
01115 vect_dump = stderr;
01116 return;
01117 }
01118
01119
01120 if (dump_file && (dump_flags & TDF_DETAILS))
01121 vect_verbosity_level = REPORT_DETAILS;
01122 else if (dump_file && (dump_flags & TDF_STATS))
01123 vect_verbosity_level = REPORT_UNVECTORIZED_LOOPS;
01124 else
01125 vect_verbosity_level = REPORT_NONE;
01126
01127 gcc_assert (dump_file || vect_verbosity_level == REPORT_NONE);
01128 }
01129
01130
01131
01132
01133
01134
01135 bool
01136 vect_print_dump_info (enum verbosity_levels vl, LOC loc)
01137 {
01138 if (vl > vect_verbosity_level)
01139 return false;
01140
01141 if (loc == UNKNOWN_LOC)
01142 fprintf (vect_dump, "\n%s:%d: note: ",
01143 DECL_SOURCE_FILE (current_function_decl),
01144 DECL_SOURCE_LINE (current_function_decl));
01145 else
01146 fprintf (vect_dump, "\n%s:%d: note: ", LOC_FILE (loc), LOC_LINE (loc));
01147
01148
01149 return true;
01150 }
01151
01152
01153
01154
01155
01156
01157
01158
01159
01160
01161 stmt_vec_info
01162 new_stmt_vec_info (tree stmt, loop_vec_info loop_vinfo)
01163 {
01164 stmt_vec_info res;
01165 res = (stmt_vec_info) xcalloc (1, sizeof (struct _stmt_vec_info));
01166
01167 STMT_VINFO_TYPE (res) = undef_vec_info_type;
01168 STMT_VINFO_STMT (res) = stmt;
01169 STMT_VINFO_LOOP_VINFO (res) = loop_vinfo;
01170 STMT_VINFO_RELEVANT_P (res) = 0;
01171 STMT_VINFO_VECTYPE (res) = NULL;
01172 STMT_VINFO_VEC_STMT (res) = NULL;
01173 STMT_VINFO_DATA_REF (res) = NULL;
01174 STMT_VINFO_MEMTAG (res) = NULL;
01175 STMT_VINFO_VECT_DR_BASE_ADDRESS (res) = NULL;
01176 STMT_VINFO_VECT_INIT_OFFSET (res) = NULL_TREE;
01177 STMT_VINFO_VECT_STEP (res) = NULL_TREE;
01178 STMT_VINFO_VECT_BASE_ALIGNED_P (res) = false;
01179 STMT_VINFO_VECT_MISALIGNMENT (res) = NULL_TREE;
01180
01181 return res;
01182 }
01183
01184
01185
01186
01187
01188
01189
01190 loop_vec_info
01191 new_loop_vec_info (struct loop *loop)
01192 {
01193 loop_vec_info res;
01194 basic_block *bbs;
01195 block_stmt_iterator si;
01196 unsigned int i;
01197
01198 res = (loop_vec_info) xcalloc (1, sizeof (struct _loop_vec_info));
01199
01200 bbs = get_loop_body (loop);
01201
01202
01203 for (i = 0; i < loop->num_nodes; i++)
01204 {
01205 basic_block bb = bbs[i];
01206 for (si = bsi_start (bb); !bsi_end_p (si); bsi_next (&si))
01207 {
01208 tree stmt = bsi_stmt (si);
01209 stmt_ann_t ann;
01210
01211 get_stmt_operands (stmt);
01212 ann = stmt_ann (stmt);
01213 set_stmt_info (ann, new_stmt_vec_info (stmt, res));
01214 }
01215 }
01216
01217 LOOP_VINFO_LOOP (res) = loop;
01218 LOOP_VINFO_BBS (res) = bbs;
01219 LOOP_VINFO_EXIT_COND (res) = NULL;
01220 LOOP_VINFO_NITERS (res) = NULL;
01221 LOOP_VINFO_VECTORIZABLE_P (res) = 0;
01222 LOOP_DO_PEELING_FOR_ALIGNMENT (res) = false;
01223 LOOP_VINFO_VECT_FACTOR (res) = 0;
01224 VARRAY_GENERIC_PTR_INIT (LOOP_VINFO_DATAREF_WRITES (res), 20,
01225 "loop_write_datarefs");
01226 VARRAY_GENERIC_PTR_INIT (LOOP_VINFO_DATAREF_READS (res), 20,
01227 "loop_read_datarefs");
01228 LOOP_VINFO_UNALIGNED_DR (res) = NULL;
01229 LOOP_VINFO_LOC (res) = UNKNOWN_LOC;
01230
01231 return res;
01232 }
01233
01234
01235
01236
01237
01238
01239
01240 void
01241 destroy_loop_vec_info (loop_vec_info loop_vinfo)
01242 {
01243 struct loop *loop;
01244 basic_block *bbs;
01245 int nbbs;
01246 block_stmt_iterator si;
01247 int j;
01248
01249 if (!loop_vinfo)
01250 return;
01251
01252 loop = LOOP_VINFO_LOOP (loop_vinfo);
01253
01254 bbs = LOOP_VINFO_BBS (loop_vinfo);
01255 nbbs = loop->num_nodes;
01256
01257 for (j = 0; j < nbbs; j++)
01258 {
01259 basic_block bb = bbs[j];
01260 for (si = bsi_start (bb); !bsi_end_p (si); bsi_next (&si))
01261 {
01262 tree stmt = bsi_stmt (si);
01263 stmt_ann_t ann = stmt_ann (stmt);
01264 stmt_vec_info stmt_info = vinfo_for_stmt (stmt);
01265 free (stmt_info);
01266 set_stmt_info (ann, NULL);
01267 }
01268 }
01269
01270 free (LOOP_VINFO_BBS (loop_vinfo));
01271 varray_clear (LOOP_VINFO_DATAREF_WRITES (loop_vinfo));
01272 varray_clear (LOOP_VINFO_DATAREF_READS (loop_vinfo));
01273
01274 free (loop_vinfo);
01275 }
01276
01277
01278
01279
01280
01281
01282 tree
01283 vect_strip_conversion (tree expr)
01284 {
01285 tree to, ti, oprnd0;
01286
01287 while (TREE_CODE (expr) == NOP_EXPR || TREE_CODE (expr) == CONVERT_EXPR)
01288 {
01289 to = TREE_TYPE (expr);
01290 oprnd0 = TREE_OPERAND (expr, 0);
01291 ti = TREE_TYPE (oprnd0);
01292
01293 if (!INTEGRAL_TYPE_P (to) || !INTEGRAL_TYPE_P (ti))
01294 return NULL_TREE;
01295 if (GET_MODE_SIZE (TYPE_MODE (to)) < GET_MODE_SIZE (TYPE_MODE (ti)))
01296 return NULL_TREE;
01297
01298 expr = oprnd0;
01299 }
01300 return expr;
01301 }
01302
01303
01304
01305
01306
01307
01308
01309 bool
01310 vect_can_force_dr_alignment_p (tree decl, unsigned int alignment)
01311 {
01312 if (TREE_CODE (decl) != VAR_DECL)
01313 return false;
01314
01315 if (DECL_EXTERNAL (decl))
01316 return false;
01317
01318 if (TREE_ASM_WRITTEN (decl))
01319 return false;
01320
01321 if (TREE_STATIC (decl))
01322 return (alignment <= MAX_OFILE_ALIGNMENT);
01323 else
01324
01325
01326
01327
01328
01329 return (alignment <= PREFERRED_STACK_BOUNDARY);
01330 }
01331
01332
01333
01334
01335
01336
01337
01338 tree
01339 get_vectype_for_scalar_type (tree scalar_type)
01340 {
01341 enum machine_mode inner_mode = TYPE_MODE (scalar_type);
01342 int nbytes = GET_MODE_SIZE (inner_mode);
01343 int nunits;
01344 tree vectype;
01345
01346 if (nbytes == 0)
01347 return NULL_TREE;
01348
01349
01350
01351 nunits = UNITS_PER_SIMD_WORD / nbytes;
01352
01353 vectype = build_vector_type (scalar_type, nunits);
01354 if (vect_print_dump_info (REPORT_DETAILS, UNKNOWN_LOC))
01355 {
01356 fprintf (vect_dump, "get vectype with %d units of type ", nunits);
01357 print_generic_expr (vect_dump, scalar_type, TDF_SLIM);
01358 }
01359
01360 if (!vectype)
01361 return NULL_TREE;
01362
01363 if (vect_print_dump_info (REPORT_DETAILS, UNKNOWN_LOC))
01364 {
01365 fprintf (vect_dump, "vectype: ");
01366 print_generic_expr (vect_dump, vectype, TDF_SLIM);
01367 }
01368
01369 if (!VECTOR_MODE_P (TYPE_MODE (vectype)))
01370 {
01371
01372
01373
01374 if (vect_print_dump_info (REPORT_DETAILS, UNKNOWN_LOC))
01375 fprintf (vect_dump, "mode not supported by target.");
01376 return NULL_TREE;
01377 }
01378
01379 return vectype;
01380 }
01381
01382
01383
01384
01385
01386
01387
01388 enum dr_alignment_support
01389 vect_supportable_dr_alignment (struct data_reference *dr)
01390 {
01391 tree vectype = STMT_VINFO_VECTYPE (vinfo_for_stmt (DR_STMT (dr)));
01392 enum machine_mode mode = (int) TYPE_MODE (vectype);
01393
01394 if (aligned_access_p (dr))
01395 return dr_aligned;
01396
01397
01398
01399 if (DR_IS_READ (dr))
01400 {
01401 if (vec_realign_load_optab->handlers[mode].insn_code != CODE_FOR_nothing
01402 && (!targetm.vectorize.builtin_mask_for_load
01403 || targetm.vectorize.builtin_mask_for_load ()))
01404 return dr_unaligned_software_pipeline;
01405
01406 if (movmisalign_optab->handlers[mode].insn_code != CODE_FOR_nothing)
01407
01408 return dr_unaligned_supported;
01409 }
01410
01411
01412 return dr_unaligned_unsupported;
01413 }
01414
01415
01416
01417
01418
01419
01420
01421
01422
01423
01424
01425
01426
01427
01428
01429 bool
01430 vect_is_simple_use (tree operand, loop_vec_info loop_vinfo, tree *def)
01431 {
01432 tree def_stmt;
01433 basic_block bb;
01434 struct loop *loop = LOOP_VINFO_LOOP (loop_vinfo);
01435
01436 if (def)
01437 *def = NULL_TREE;
01438
01439 if (TREE_CODE (operand) == INTEGER_CST || TREE_CODE (operand) == REAL_CST)
01440 return true;
01441
01442 if (TREE_CODE (operand) != SSA_NAME)
01443 return false;
01444
01445 def_stmt = SSA_NAME_DEF_STMT (operand);
01446 if (def_stmt == NULL_TREE )
01447 {
01448 if (vect_print_dump_info (REPORT_DETAILS, UNKNOWN_LOC))
01449 fprintf (vect_dump, "no def_stmt.");
01450 return false;
01451 }
01452
01453
01454
01455 if (IS_EMPTY_STMT (def_stmt))
01456 {
01457 tree arg = TREE_OPERAND (def_stmt, 0);
01458 if (TREE_CODE (arg) == INTEGER_CST || TREE_CODE (arg) == REAL_CST)
01459 return true;
01460 if (vect_print_dump_info (REPORT_DETAILS, UNKNOWN_LOC))
01461 {
01462 fprintf (vect_dump, "Unexpected empty stmt: ");
01463 print_generic_expr (vect_dump, def_stmt, TDF_SLIM);
01464 }
01465 return false;
01466 }
01467
01468
01469
01470 bb = bb_for_stmt (def_stmt);
01471 if (TREE_CODE (def_stmt) == PHI_NODE && flow_bb_inside_loop_p (loop, bb))
01472 {
01473 if (vect_print_dump_info (REPORT_DETAILS, UNKNOWN_LOC))
01474 fprintf (vect_dump, "reduction/induction - unsupported.");
01475 return false;
01476 }
01477
01478
01479 if (TREE_CODE (def_stmt) == MODIFY_EXPR
01480 || TREE_CODE (def_stmt) == PHI_NODE)
01481 {
01482 if (def)
01483 *def = def_stmt;
01484 return true;
01485 }
01486
01487 return false;
01488 }
01489
01490
01491
01492
01493
01494
01495
01496 bool
01497 vect_is_simple_iv_evolution (unsigned loop_nb, tree access_fn, tree * init,
01498 tree * step)
01499 {
01500 tree init_expr;
01501 tree step_expr;
01502
01503 tree evolution_part = evolution_part_in_loop_num (access_fn, loop_nb);
01504
01505
01506
01507 if (evolution_part == NULL_TREE)
01508 return false;
01509
01510
01511
01512 if (tree_is_chrec (evolution_part))
01513 return false;
01514
01515 step_expr = evolution_part;
01516 init_expr = unshare_expr (initial_condition_in_loop_num (access_fn,
01517 loop_nb));
01518
01519 if (vect_print_dump_info (REPORT_DETAILS, UNKNOWN_LOC))
01520 {
01521 fprintf (vect_dump, "step: ");
01522 print_generic_expr (vect_dump, step_expr, TDF_SLIM);
01523 fprintf (vect_dump, ", init: ");
01524 print_generic_expr (vect_dump, init_expr, TDF_SLIM);
01525 }
01526
01527 *init = init_expr;
01528 *step = step_expr;
01529
01530 if (TREE_CODE (step_expr) != INTEGER_CST)
01531 {
01532 if (vect_print_dump_info (REPORT_DETAILS, UNKNOWN_LOC))
01533 fprintf (vect_dump, "step unknown.");
01534 return false;
01535 }
01536
01537 return true;
01538 }
01539
01540
01541
01542
01543
01544
01545
01546
01547 static bool
01548 need_imm_uses_for (tree var)
01549 {
01550 return is_gimple_reg (var);
01551 }
01552
01553
01554
01555
01556
01557
01558 void
01559 vectorize_loops (struct loops *loops)
01560 {
01561 unsigned int i, loops_num;
01562 unsigned int num_vectorized_loops = 0;
01563
01564
01565 vect_set_dump_settings ();
01566
01567
01568
01569 if (!UNITS_PER_SIMD_WORD)
01570 {
01571 if (vect_print_dump_info (REPORT_DETAILS, UNKNOWN_LOC))
01572 fprintf (vect_dump, "vectorizer: target vector size is not defined.");
01573 return;
01574 }
01575
01576 #ifdef ENABLE_CHECKING
01577 verify_loop_closed_ssa ();
01578 #endif
01579
01580 compute_immediate_uses (TDFA_USE_OPS, need_imm_uses_for);
01581
01582
01583
01584
01585
01586
01587 loops_num = loops->num;
01588 for (i = 1; i < loops_num; i++)
01589 {
01590 loop_vec_info loop_vinfo;
01591 struct loop *loop = loops->parray[i];
01592
01593 if (!loop)
01594 continue;
01595
01596 loop_vinfo = vect_analyze_loop (loop);
01597 loop->aux = loop_vinfo;
01598
01599 if (!loop_vinfo || !LOOP_VINFO_VECTORIZABLE_P (loop_vinfo))
01600 continue;
01601
01602 vect_transform_loop (loop_vinfo, loops);
01603 num_vectorized_loops++;
01604 }
01605
01606 if (vect_print_dump_info (REPORT_VECTORIZED_LOOPS, UNKNOWN_LOC))
01607 fprintf (vect_dump, "vectorized %u loops in function.\n",
01608 num_vectorized_loops);
01609
01610
01611
01612 free_df ();
01613 for (i = 1; i < loops_num; i++)
01614 {
01615 struct loop *loop = loops->parray[i];
01616 loop_vec_info loop_vinfo;
01617
01618 if (!loop)
01619 continue;
01620 loop_vinfo = loop->aux;
01621 destroy_loop_vec_info (loop_vinfo);
01622 loop->aux = NULL;
01623 }
01624
01625 rewrite_into_ssa (false);
01626 rewrite_into_loop_closed_ssa ();
01627 bitmap_clear (vars_to_rename);
01628 }