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 "ggc.h"
00128 #include "tree.h"
00129 #include "target.h"
00130 #include "rtl.h"
00131 #include "basic-block.h"
00132 #include "diagnostic.h"
00133 #include "tree-flow.h"
00134 #include "tree-dump.h"
00135 #include "timevar.h"
00136 #include "cfgloop.h"
00137 #include "cfglayout.h"
00138 #include "expr.h"
00139 #include "optabs.h"
00140 #include "params.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_guard1
00157 (edge, struct loop *, bool, basic_block *, bitmap *);
00158 static void slpeel_update_phi_nodes_for_guard2
00159 (edge, struct loop *, bool, basic_block *);
00160 static edge slpeel_add_loop_guard (basic_block, tree, basic_block, basic_block);
00161
00162 static void rename_use_op (use_operand_p);
00163 static void rename_variables_in_bb (basic_block);
00164 static void rename_variables_in_loop (struct loop *);
00165
00166
00167
00168
00169 static void vect_set_dump_settings (void);
00170
00171
00172 FILE *vect_dump;
00173
00174
00175
00176 enum verbosity_levels vect_verbosity_level = MAX_VERBOSITY_LEVEL;
00177
00178
00179 unsigned int vect_loops_num;
00180
00181
00182 static LOC vect_loop_location;
00183
00184
00185 bitmap vect_vnames_to_rename;
00186
00187
00188
00189
00190
00191
00192
00193
00194
00195
00196 static void
00197 rename_use_op (use_operand_p op_p)
00198 {
00199 tree new_name;
00200
00201 if (TREE_CODE (USE_FROM_PTR (op_p)) != SSA_NAME)
00202 return;
00203
00204 new_name = get_current_def (USE_FROM_PTR (op_p));
00205
00206
00207 if (!new_name)
00208 return;
00209
00210
00211
00212 SET_USE (op_p, new_name);
00213 }
00214
00215
00216
00217
00218 static void
00219 rename_variables_in_bb (basic_block bb)
00220 {
00221 tree phi;
00222 block_stmt_iterator bsi;
00223 tree stmt;
00224 use_operand_p use_p;
00225 ssa_op_iter iter;
00226 edge e;
00227 edge_iterator ei;
00228 struct loop *loop = bb->loop_father;
00229
00230 for (bsi = bsi_start (bb); !bsi_end_p (bsi); bsi_next (&bsi))
00231 {
00232 stmt = bsi_stmt (bsi);
00233 FOR_EACH_SSA_USE_OPERAND (use_p, stmt, iter,
00234 (SSA_OP_ALL_USES | SSA_OP_ALL_KILLS))
00235 rename_use_op (use_p);
00236 }
00237
00238 FOR_EACH_EDGE (e, ei, bb->succs)
00239 {
00240 if (!flow_bb_inside_loop_p (loop, e->dest))
00241 continue;
00242 for (phi = phi_nodes (e->dest); phi; phi = PHI_CHAIN (phi))
00243 rename_use_op (PHI_ARG_DEF_PTR_FROM_EDGE (phi, e));
00244 }
00245 }
00246
00247
00248
00249
00250 static void
00251 rename_variables_in_loop (struct loop *loop)
00252 {
00253 unsigned i;
00254 basic_block *bbs;
00255
00256 bbs = get_loop_body (loop);
00257
00258 for (i = 0; i < loop->num_nodes; i++)
00259 rename_variables_in_bb (bbs[i]);
00260
00261 free (bbs);
00262 }
00263
00264
00265
00266
00267
00268
00269
00270
00271
00272 static void
00273 slpeel_update_phis_for_duplicate_loop (struct loop *orig_loop,
00274 struct loop *new_loop, bool after)
00275 {
00276 tree new_ssa_name;
00277 tree phi_new, phi_orig;
00278 tree def;
00279 edge orig_loop_latch = loop_latch_edge (orig_loop);
00280 edge orig_entry_e = loop_preheader_edge (orig_loop);
00281 edge new_loop_exit_e = new_loop->single_exit;
00282 edge new_loop_entry_e = loop_preheader_edge (new_loop);
00283 edge entry_arg_e = (after ? orig_loop_latch : orig_entry_e);
00284
00285
00286
00287
00288
00289
00290
00291
00292
00293
00294
00295
00296
00297
00298
00299
00300
00301
00302
00303
00304
00305
00306
00307
00308
00309
00310
00311
00312
00313
00314 for (phi_new = phi_nodes (new_loop->header),
00315 phi_orig = phi_nodes (orig_loop->header);
00316 phi_new && phi_orig;
00317 phi_new = PHI_CHAIN (phi_new), phi_orig = PHI_CHAIN (phi_orig))
00318 {
00319
00320 def = PHI_ARG_DEF_FROM_EDGE (phi_orig, entry_arg_e);
00321 add_phi_arg (phi_new, def, new_loop_entry_e);
00322
00323
00324 def = PHI_ARG_DEF_FROM_EDGE (phi_orig, orig_loop_latch);
00325 if (TREE_CODE (def) != SSA_NAME)
00326 continue;
00327
00328 new_ssa_name = get_current_def (def);
00329 if (!new_ssa_name)
00330 {
00331
00332
00333 new_ssa_name = PHI_RESULT (phi_new);
00334 }
00335
00336
00337 add_phi_arg (phi_new, new_ssa_name, loop_latch_edge (new_loop));
00338
00339
00340 if (!after)
00341 {
00342 gcc_assert (new_loop_exit_e == orig_entry_e);
00343 SET_PHI_ARG_DEF (phi_orig,
00344 new_loop_exit_e->dest_idx,
00345 new_ssa_name);
00346 }
00347 }
00348 }
00349
00350
00351
00352
00353
00354
00355
00356
00357
00358
00359
00360
00361
00362
00363
00364
00365
00366
00367
00368
00369
00370
00371
00372
00373
00374
00375
00376
00377
00378
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
00410
00411
00412
00413
00414
00415
00416
00417
00418
00419
00420
00421
00422
00423
00424
00425
00426
00427
00428
00429
00430
00431
00432
00433
00434
00435
00436
00437
00438
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
00496
00497
00498
00499
00500
00501
00502
00503
00504 static void
00505 slpeel_update_phi_nodes_for_guard1 (edge guard_edge, struct loop *loop,
00506 bool is_new_loop, basic_block *new_exit_bb,
00507 bitmap *defs)
00508 {
00509 tree orig_phi, new_phi;
00510 tree update_phi, update_phi2;
00511 tree guard_arg, loop_arg;
00512 basic_block new_merge_bb = guard_edge->dest;
00513 edge e = EDGE_SUCC (new_merge_bb, 0);
00514 basic_block update_bb = e->dest;
00515 basic_block orig_bb = loop->header;
00516 edge new_exit_e;
00517 tree current_new_name;
00518 tree name;
00519
00520
00521 *new_exit_bb = split_edge (loop->single_exit);
00522 add_bb_to_loop (*new_exit_bb, loop->outer);
00523
00524 new_exit_e = EDGE_SUCC (*new_exit_bb, 0);
00525
00526 for (orig_phi = phi_nodes (orig_bb), update_phi = phi_nodes (update_bb);
00527 orig_phi && update_phi;
00528 orig_phi = PHI_CHAIN (orig_phi), update_phi = PHI_CHAIN (update_phi))
00529 {
00530
00531
00532
00533
00534
00535 name = PHI_RESULT (orig_phi);
00536 if (!is_gimple_reg (SSA_NAME_VAR (name)))
00537 bitmap_set_bit (vect_vnames_to_rename, SSA_NAME_VERSION (name));
00538
00541
00542 new_phi = create_phi_node (SSA_NAME_VAR (PHI_RESULT (orig_phi)),
00543 new_merge_bb);
00544
00545
00546
00547 loop_arg = PHI_ARG_DEF_FROM_EDGE (orig_phi, EDGE_SUCC (loop->latch, 0));
00548 guard_arg = PHI_ARG_DEF_FROM_EDGE (orig_phi, loop_preheader_edge (loop));
00549
00550 add_phi_arg (new_phi, loop_arg, new_exit_e);
00551 add_phi_arg (new_phi, guard_arg, guard_edge);
00552
00553
00554 gcc_assert (PHI_ARG_DEF_FROM_EDGE (update_phi, e) == loop_arg
00555 || PHI_ARG_DEF_FROM_EDGE (update_phi, e) == guard_arg);
00556 SET_PHI_ARG_DEF (update_phi, e->dest_idx, PHI_RESULT (new_phi));
00557 update_phi2 = new_phi;
00558
00559
00562
00563 new_phi = create_phi_node (SSA_NAME_VAR (PHI_RESULT (orig_phi)),
00564 *new_exit_bb);
00565
00566
00567 add_phi_arg (new_phi, loop_arg, loop->single_exit);
00568
00569
00570 gcc_assert (PHI_ARG_DEF_FROM_EDGE (update_phi2, new_exit_e) == loop_arg);
00571 SET_PHI_ARG_DEF (update_phi2, new_exit_e->dest_idx, PHI_RESULT (new_phi));
00572
00573
00574
00575
00576
00577
00578
00579
00580
00581
00582
00583 if (is_new_loop)
00584 current_new_name = loop_arg;
00585 else
00586 {
00587 current_new_name = get_current_def (loop_arg);
00588
00589
00590
00591
00592 if (!current_new_name)
00593 continue;
00594 }
00595 gcc_assert (get_current_def (current_new_name) == NULL_TREE);
00596
00597 set_current_def (current_new_name, PHI_RESULT (new_phi));
00598 bitmap_set_bit (*defs, SSA_NAME_VERSION (current_new_name));
00599 }
00600
00601 set_phi_nodes (new_merge_bb, phi_reverse (phi_nodes (new_merge_bb)));
00602 }
00603
00604
00605
00606
00607
00608
00609
00610
00611
00612
00613
00614
00615
00616
00617
00618
00619
00620
00621
00622
00623
00624
00625
00626
00627
00628
00629
00630
00631 static void
00632 slpeel_update_phi_nodes_for_guard2 (edge guard_edge, struct loop *loop,
00633 bool is_new_loop, basic_block *new_exit_bb)
00634 {
00635 tree orig_phi, new_phi;
00636 tree update_phi, update_phi2;
00637 tree guard_arg, loop_arg;
00638 basic_block new_merge_bb = guard_edge->dest;
00639 edge e = EDGE_SUCC (new_merge_bb, 0);
00640 basic_block update_bb = e->dest;
00641 edge new_exit_e;
00642 tree orig_def, orig_def_new_name;
00643 tree new_name, new_name2;
00644 tree arg;
00645
00646
00647 *new_exit_bb = split_edge (loop->single_exit);
00648 add_bb_to_loop (*new_exit_bb, loop->outer);
00649
00650 new_exit_e = EDGE_SUCC (*new_exit_bb, 0);
00651
00652 for (update_phi = phi_nodes (update_bb); update_phi;
00653 update_phi = PHI_CHAIN (update_phi))
00654 {
00655 orig_phi = update_phi;
00656 orig_def = PHI_ARG_DEF_FROM_EDGE (orig_phi, e);
00657
00658
00659 if (TREE_CODE (orig_def) != SSA_NAME)
00660 continue;
00661 orig_def_new_name = get_current_def (orig_def);
00662 arg = NULL_TREE;
00663
00666
00667 new_phi = create_phi_node (SSA_NAME_VAR (PHI_RESULT (orig_phi)),
00668 new_merge_bb);
00669
00670
00671
00672 new_name = orig_def;
00673 new_name2 = NULL_TREE;
00674 if (orig_def_new_name)
00675 {
00676 new_name = orig_def_new_name;
00677
00678
00679
00680
00681 new_name2 = get_current_def (new_name);
00682 }
00683
00684 if (is_new_loop)
00685 {
00686 guard_arg = orig_def;
00687 loop_arg = new_name;
00688 }
00689 else
00690 {
00691 guard_arg = new_name;
00692 loop_arg = orig_def;
00693 }
00694 if (new_name2)
00695 guard_arg = new_name2;
00696
00697 add_phi_arg (new_phi, loop_arg, new_exit_e);
00698 add_phi_arg (new_phi, guard_arg, guard_edge);
00699
00700
00701 gcc_assert (PHI_ARG_DEF_FROM_EDGE (update_phi, e) == orig_def);
00702 SET_PHI_ARG_DEF (update_phi, e->dest_idx, PHI_RESULT (new_phi));
00703 update_phi2 = new_phi;
00704
00705
00708
00709 new_phi = create_phi_node (SSA_NAME_VAR (PHI_RESULT (orig_phi)),
00710 *new_exit_bb);
00711
00712
00713 add_phi_arg (new_phi, loop_arg, loop->single_exit);
00714
00715
00716 gcc_assert (PHI_ARG_DEF_FROM_EDGE (update_phi2, new_exit_e) == loop_arg);
00717 SET_PHI_ARG_DEF (update_phi2, new_exit_e->dest_idx, PHI_RESULT (new_phi));
00718
00719
00722
00723
00724
00725
00726
00727
00728
00729
00730
00731
00732
00733
00734
00735
00736
00737
00738 if (guard_arg == new_name2)
00739 continue;
00740 arg = guard_arg;
00741
00742
00743 new_phi = create_phi_node (SSA_NAME_VAR (PHI_RESULT (orig_phi)),
00744 guard_edge->src);
00745
00746
00747 gcc_assert (EDGE_COUNT (guard_edge->src->preds) == 1);
00748 add_phi_arg (new_phi, arg, EDGE_PRED (guard_edge->src, 0));
00749
00750
00751 gcc_assert (PHI_ARG_DEF_FROM_EDGE (update_phi2, guard_edge)
00752 == guard_arg);
00753 SET_PHI_ARG_DEF (update_phi2, guard_edge->dest_idx, PHI_RESULT (new_phi));
00754 }
00755
00756 set_phi_nodes (new_merge_bb, phi_reverse (phi_nodes (new_merge_bb)));
00757 }
00758
00759
00760
00761
00762
00763
00764
00765 void
00766 slpeel_make_loop_iterate_ntimes (struct loop *loop, tree niters)
00767 {
00768 tree indx_before_incr, indx_after_incr, cond_stmt, cond;
00769 tree orig_cond;
00770 edge exit_edge = loop->single_exit;
00771 block_stmt_iterator loop_cond_bsi;
00772 block_stmt_iterator incr_bsi;
00773 bool insert_after;
00774 tree begin_label = tree_block_label (loop->latch);
00775 tree exit_label = tree_block_label (loop->single_exit->dest);
00776 tree init = build_int_cst (TREE_TYPE (niters), 0);
00777 tree step = build_int_cst (TREE_TYPE (niters), 1);
00778 tree then_label;
00779 tree else_label;
00780 LOC loop_loc;
00781
00782 orig_cond = get_loop_exit_condition (loop);
00783 gcc_assert (orig_cond);
00784 loop_cond_bsi = bsi_for_stmt (orig_cond);
00785
00786 standard_iv_increment_position (loop, &incr_bsi, &insert_after);
00787 create_iv (init, step, NULL_TREE, loop,
00788 &incr_bsi, insert_after, &indx_before_incr, &indx_after_incr);
00789
00790 if (exit_edge->flags & EDGE_TRUE_VALUE)
00791 {
00792 cond = build2 (GE_EXPR, boolean_type_node, indx_after_incr, niters);
00793 then_label = build1 (GOTO_EXPR, void_type_node, exit_label);
00794 else_label = build1 (GOTO_EXPR, void_type_node, begin_label);
00795 }
00796 else
00797 {
00798 cond = build2 (LT_EXPR, boolean_type_node, indx_after_incr, niters);
00799 then_label = build1 (GOTO_EXPR, void_type_node, begin_label);
00800 else_label = build1 (GOTO_EXPR, void_type_node, exit_label);
00801 }
00802
00803 cond_stmt = build3 (COND_EXPR, TREE_TYPE (orig_cond), cond,
00804 then_label, else_label);
00805 bsi_insert_before (&loop_cond_bsi, cond_stmt, BSI_SAME_STMT);
00806
00807
00808 bsi_remove (&loop_cond_bsi, true);
00809
00810 loop_loc = find_loop_location (loop);
00811 if (dump_file && (dump_flags & TDF_DETAILS))
00812 {
00813 if (loop_loc != UNKNOWN_LOC)
00814 fprintf (dump_file, "\nloop at %s:%d: ",
00815 LOC_FILE (loop_loc), LOC_LINE (loop_loc));
00816 print_generic_expr (dump_file, cond_stmt, TDF_SLIM);
00817 }
00818
00819 loop->nb_iterations = niters;
00820 }
00821
00822
00823
00824
00825
00826 static struct loop *
00827 slpeel_tree_duplicate_loop_to_edge_cfg (struct loop *loop, struct loops *loops,
00828 edge e)
00829 {
00830 struct loop *new_loop;
00831 basic_block *new_bbs, *bbs;
00832 bool at_exit;
00833 bool was_imm_dom;
00834 basic_block exit_dest;
00835 tree phi, phi_arg;
00836
00837 at_exit = (e == loop->single_exit);
00838 if (!at_exit && e != loop_preheader_edge (loop))
00839 return NULL;
00840
00841 bbs = get_loop_body (loop);
00842
00843
00844 if (!can_copy_bbs_p (bbs, loop->num_nodes))
00845 {
00846 free (bbs);
00847 return NULL;
00848 }
00849
00850
00851 new_loop = duplicate_loop (loops, loop, loop->outer);
00852 if (!new_loop)
00853 {
00854 free (bbs);
00855 return NULL;
00856 }
00857
00858 exit_dest = loop->single_exit->dest;
00859 was_imm_dom = (get_immediate_dominator (CDI_DOMINATORS,
00860 exit_dest) == loop->header ?
00861 true : false);
00862
00863 new_bbs = XNEWVEC (basic_block, loop->num_nodes);
00864
00865 copy_bbs (bbs, loop->num_nodes, new_bbs,
00866 &loop->single_exit, 1, &new_loop->single_exit, NULL,
00867 e->src);
00868
00869
00870
00871 for (phi = phi_nodes (exit_dest); phi; phi = PHI_CHAIN (phi))
00872 {
00873 phi_arg = PHI_ARG_DEF_FROM_EDGE (phi, loop->single_exit);
00874 if (phi_arg)
00875 {
00876 edge new_loop_exit_edge;
00877
00878 if (EDGE_SUCC (new_loop->header, 0)->dest == new_loop->latch)
00879 new_loop_exit_edge = EDGE_SUCC (new_loop->header, 1);
00880 else
00881 new_loop_exit_edge = EDGE_SUCC (new_loop->header, 0);
00882
00883 add_phi_arg (phi, phi_arg, new_loop_exit_edge);
00884 }
00885 }
00886
00887 if (at_exit)
00888 {
00889 redirect_edge_and_branch_force (e, new_loop->header);
00890 set_immediate_dominator (CDI_DOMINATORS, new_loop->header, e->src);
00891 if (was_imm_dom)
00892 set_immediate_dominator (CDI_DOMINATORS, exit_dest, new_loop->header);
00893 }
00894 else
00895 {
00896 edge new_exit_e;
00897 edge entry_e = loop_preheader_edge (loop);
00898 basic_block preheader = entry_e->src;
00899
00900 if (!flow_bb_inside_loop_p (new_loop,
00901 EDGE_SUCC (new_loop->header, 0)->dest))
00902 new_exit_e = EDGE_SUCC (new_loop->header, 0);
00903 else
00904 new_exit_e = EDGE_SUCC (new_loop->header, 1);
00905
00906 redirect_edge_and_branch_force (new_exit_e, loop->header);
00907 set_immediate_dominator (CDI_DOMINATORS, loop->header,
00908 new_exit_e->src);
00909
00910
00911
00912 for (phi = phi_nodes (loop->header); phi; phi = PHI_CHAIN (phi))
00913 {
00914 phi_arg = PHI_ARG_DEF_FROM_EDGE (phi, entry_e);
00915 if (phi_arg)
00916 add_phi_arg (phi, phi_arg, new_exit_e);
00917 }
00918
00919 redirect_edge_and_branch_force (entry_e, new_loop->header);
00920 set_immediate_dominator (CDI_DOMINATORS, new_loop->header, preheader);
00921 }
00922
00923 free (new_bbs);
00924 free (bbs);
00925
00926 return new_loop;
00927 }
00928
00929
00930
00931
00932
00933
00934
00935 static edge
00936 slpeel_add_loop_guard (basic_block guard_bb, tree cond, basic_block exit_bb,
00937 basic_block dom_bb)
00938 {
00939 block_stmt_iterator bsi;
00940 edge new_e, enter_e;
00941 tree cond_stmt, then_label, else_label;
00942
00943 enter_e = EDGE_SUCC (guard_bb, 0);
00944 enter_e->flags &= ~EDGE_FALLTHRU;
00945 enter_e->flags |= EDGE_FALSE_VALUE;
00946 bsi = bsi_last (guard_bb);
00947
00948 then_label = build1 (GOTO_EXPR, void_type_node,
00949 tree_block_label (exit_bb));
00950 else_label = build1 (GOTO_EXPR, void_type_node,
00951 tree_block_label (enter_e->dest));
00952 cond_stmt = build3 (COND_EXPR, void_type_node, cond,
00953 then_label, else_label);
00954 bsi_insert_after (&bsi, cond_stmt, BSI_NEW_STMT);
00955
00956 new_e = make_edge (guard_bb, exit_bb, EDGE_TRUE_VALUE);
00957 set_immediate_dominator (CDI_DOMINATORS, exit_bb, dom_bb);
00958 return new_e;
00959 }
00960
00961
00962
00963
00964
00965
00966
00967
00968
00969
00970 bool
00971 slpeel_can_duplicate_loop_p (struct loop *loop, edge e)
00972 {
00973 edge exit_e = loop->single_exit;
00974 edge entry_e = loop_preheader_edge (loop);
00975 tree orig_cond = get_loop_exit_condition (loop);
00976 block_stmt_iterator loop_exit_bsi = bsi_last (exit_e->src);
00977
00978 if (need_ssa_update_p ())
00979 return false;
00980
00981 if (loop->inner
00982
00983
00984 || !loop->outer
00985 || loop->num_nodes != 2
00986 || !empty_block_p (loop->latch)
00987 || !loop->single_exit
00988
00989 || (!orig_cond || orig_cond != bsi_stmt (loop_exit_bsi))
00990 || (e != exit_e && e != entry_e))
00991 return false;
00992
00993 return true;
00994 }
00995
00996 #ifdef ENABLE_CHECKING
00997 void
00998 slpeel_verify_cfg_after_peeling (struct loop *first_loop,
00999 struct loop *second_loop)
01000 {
01001 basic_block loop1_exit_bb = first_loop->single_exit->dest;
01002 basic_block loop2_entry_bb = loop_preheader_edge (second_loop)->src;
01003 basic_block loop1_entry_bb = loop_preheader_edge (first_loop)->src;
01004
01005
01006
01007
01008
01009
01010 gcc_assert (EDGE_COUNT (loop1_exit_bb->succs) == 2);
01011
01012
01013
01014
01015
01016
01017
01018 gcc_assert (EDGE_COUNT (loop2_entry_bb->preds) == 2
01019 && ((EDGE_PRED (loop2_entry_bb, 0)->src == loop1_exit_bb
01020 && EDGE_PRED (loop2_entry_bb, 1)->src == loop1_entry_bb)
01021 || (EDGE_PRED (loop2_entry_bb, 1)->src == loop1_exit_bb
01022 && EDGE_PRED (loop2_entry_bb, 0)->src == loop1_entry_bb)));
01023
01024
01025
01026
01027 }
01028 #endif
01029
01030
01031
01032
01033
01034
01035
01036
01037
01038
01039
01040
01041
01042
01043
01044
01045
01046
01047
01048
01049
01050
01051
01052
01053
01054
01055
01056
01057
01058
01059
01060
01061
01062
01063
01064
01065
01066
01067 struct loop*
01068 slpeel_tree_peel_loop_to_edge (struct loop *loop, struct loops *loops,
01069 edge e, tree first_niters,
01070 tree niters, bool update_first_loop_count)
01071 {
01072 struct loop *new_loop = NULL, *first_loop, *second_loop;
01073 edge skip_e;
01074 tree pre_condition;
01075 bitmap definitions;
01076 basic_block bb_before_second_loop, bb_after_second_loop;
01077 basic_block bb_before_first_loop;
01078 basic_block bb_between_loops;
01079 basic_block new_exit_bb;
01080 edge exit_e = loop->single_exit;
01081 LOC loop_loc;
01082
01083 if (!slpeel_can_duplicate_loop_p (loop, e))
01084 return NULL;
01085
01086
01087
01088
01089
01090 tree_register_cfg_hooks ();
01091
01092
01093
01094
01095
01096
01097
01098
01099
01100
01101
01102
01103
01104
01105
01106
01107 if (!(new_loop = slpeel_tree_duplicate_loop_to_edge_cfg (loop, loops, e)))
01108 {
01109 loop_loc = find_loop_location (loop);
01110 if (dump_file && (dump_flags & TDF_DETAILS))
01111 {
01112 if (loop_loc != UNKNOWN_LOC)
01113 fprintf (dump_file, "\n%s:%d: note: ",
01114 LOC_FILE (loop_loc), LOC_LINE (loop_loc));
01115 fprintf (dump_file, "tree_duplicate_loop_to_edge_cfg failed.\n");
01116 }
01117 return NULL;
01118 }
01119
01120 if (e == exit_e)
01121 {
01122
01123 first_loop = loop;
01124 second_loop = new_loop;
01125 }
01126 else
01127 {
01128
01129 first_loop = new_loop;
01130 second_loop = loop;
01131 }
01132
01133 definitions = ssa_names_to_replace ();
01134 slpeel_update_phis_for_duplicate_loop (loop, new_loop, e == exit_e);
01135 rename_variables_in_loop (new_loop);
01136
01137
01138
01139
01140
01141
01142
01143
01144
01145
01146
01147
01148
01149
01150
01151
01152
01153
01154
01155
01156
01157
01158 bb_before_first_loop = split_edge (loop_preheader_edge (first_loop));
01159 add_bb_to_loop (bb_before_first_loop, first_loop->outer);
01160 bb_before_second_loop = split_edge (first_loop->single_exit);
01161 add_bb_to_loop (bb_before_second_loop, first_loop->outer);
01162
01163 pre_condition =
01164 fold_build2 (LE_EXPR, boolean_type_node, first_niters,
01165 build_int_cst (TREE_TYPE (first_niters), 0));
01166 skip_e = slpeel_add_loop_guard (bb_before_first_loop, pre_condition,
01167 bb_before_second_loop, bb_before_first_loop);
01168 slpeel_update_phi_nodes_for_guard1 (skip_e, first_loop,
01169 first_loop == new_loop,
01170 &new_exit_bb, &definitions);
01171
01172
01173
01174
01175
01176
01177
01178
01179
01180
01181
01182
01183
01184
01185
01186
01187
01188
01189
01190
01191
01192
01193
01194
01195
01196
01197
01198
01199 bb_between_loops = new_exit_bb;
01200 bb_after_second_loop = split_edge (second_loop->single_exit);
01201 add_bb_to_loop (bb_after_second_loop, second_loop->outer);
01202
01203 pre_condition =
01204 fold_build2 (EQ_EXPR, boolean_type_node, first_niters, niters);
01205 skip_e = slpeel_add_loop_guard (bb_between_loops, pre_condition,
01206 bb_after_second_loop, bb_before_first_loop);
01207 slpeel_update_phi_nodes_for_guard2 (skip_e, second_loop,
01208 second_loop == new_loop, &new_exit_bb);
01209
01210
01211
01212 if (update_first_loop_count)
01213 slpeel_make_loop_iterate_ntimes (first_loop, first_niters);
01214
01215 BITMAP_FREE (definitions);
01216 delete_update_ssa ();
01217
01218 return new_loop;
01219 }
01220
01221
01222
01223
01224
01225
01226
01227
01228 LOC
01229 find_loop_location (struct loop *loop)
01230 {
01231 tree node = NULL_TREE;
01232 basic_block bb;
01233 block_stmt_iterator si;
01234
01235 if (!loop)
01236 return UNKNOWN_LOC;
01237
01238 node = get_loop_exit_condition (loop);
01239
01240 if (node && EXPR_P (node) && EXPR_HAS_LOCATION (node)
01241 && EXPR_FILENAME (node) && EXPR_LINENO (node))
01242 return EXPR_LOC (node);
01243
01244
01245
01246
01247 if (!loop->header)
01248 return UNKNOWN_LOC;
01249
01250 bb = loop->header;
01251
01252 for (si = bsi_start (bb); !bsi_end_p (si); bsi_next (&si))
01253 {
01254 node = bsi_stmt (si);
01255 if (node && EXPR_P (node) && EXPR_HAS_LOCATION (node))
01256 return EXPR_LOC (node);
01257 }
01258
01259 return UNKNOWN_LOC;
01260 }
01261
01262
01263
01264
01265
01266
01267
01268
01269
01270
01271
01272 void
01273 vect_set_verbosity_level (const char *val)
01274 {
01275 unsigned int vl;
01276
01277 vl = atoi (val);
01278 if (vl < MAX_VERBOSITY_LEVEL)
01279 vect_verbosity_level = vl;
01280 else
01281 vect_verbosity_level = MAX_VERBOSITY_LEVEL - 1;
01282 }
01283
01284
01285
01286
01287
01288
01289
01290
01291
01292
01293
01294 static void
01295 vect_set_dump_settings (void)
01296 {
01297 vect_dump = dump_file;
01298
01299
01300 if (vect_verbosity_level != MAX_VERBOSITY_LEVEL)
01301 {
01302
01303 if (!dump_file)
01304 vect_dump = stderr;
01305 return;
01306 }
01307
01308
01309 if (dump_file && (dump_flags & TDF_DETAILS))
01310 vect_verbosity_level = REPORT_DETAILS;
01311 else if (dump_file && (dump_flags & TDF_STATS))
01312 vect_verbosity_level = REPORT_UNVECTORIZED_LOOPS;
01313 else
01314 vect_verbosity_level = REPORT_NONE;
01315
01316 gcc_assert (dump_file || vect_verbosity_level == REPORT_NONE);
01317 }
01318
01319
01320
01321
01322
01323
01324 bool
01325 vect_print_dump_info (enum verbosity_levels vl)
01326 {
01327 if (vl > vect_verbosity_level)
01328 return false;
01329
01330 if (!current_function_decl || !vect_dump)
01331 return false;
01332
01333 if (vect_loop_location == UNKNOWN_LOC)
01334 fprintf (vect_dump, "\n%s:%d: note: ",
01335 DECL_SOURCE_FILE (current_function_decl),
01336 DECL_SOURCE_LINE (current_function_decl));
01337 else
01338 fprintf (vect_dump, "\n%s:%d: note: ",
01339 LOC_FILE (vect_loop_location), LOC_LINE (vect_loop_location));
01340
01341 return true;
01342 }
01343
01344
01345
01346
01347
01348
01349
01350
01351
01352
01353 stmt_vec_info
01354 new_stmt_vec_info (tree stmt, loop_vec_info loop_vinfo)
01355 {
01356 stmt_vec_info res;
01357 res = (stmt_vec_info) xcalloc (1, sizeof (struct _stmt_vec_info));
01358
01359 STMT_VINFO_TYPE (res) = undef_vec_info_type;
01360 STMT_VINFO_STMT (res) = stmt;
01361 STMT_VINFO_LOOP_VINFO (res) = loop_vinfo;
01362 STMT_VINFO_RELEVANT_P (res) = 0;
01363 STMT_VINFO_LIVE_P (res) = 0;
01364 STMT_VINFO_VECTYPE (res) = NULL;
01365 STMT_VINFO_VEC_STMT (res) = NULL;
01366 STMT_VINFO_IN_PATTERN_P (res) = false;
01367 STMT_VINFO_RELATED_STMT (res) = NULL;
01368 STMT_VINFO_DATA_REF (res) = NULL;
01369 if (TREE_CODE (stmt) == PHI_NODE)
01370 STMT_VINFO_DEF_TYPE (res) = vect_unknown_def_type;
01371 else
01372 STMT_VINFO_DEF_TYPE (res) = vect_loop_def;
01373 STMT_VINFO_SAME_ALIGN_REFS (res) = VEC_alloc (dr_p, heap, 5);
01374
01375 return res;
01376 }
01377
01378
01379
01380
01381
01382
01383
01384 loop_vec_info
01385 new_loop_vec_info (struct loop *loop)
01386 {
01387 loop_vec_info res;
01388 basic_block *bbs;
01389 block_stmt_iterator si;
01390 unsigned int i;
01391
01392 res = (loop_vec_info) xcalloc (1, sizeof (struct _loop_vec_info));
01393
01394 bbs = get_loop_body (loop);
01395
01396
01397 for (i = 0; i < loop->num_nodes; i++)
01398 {
01399 basic_block bb = bbs[i];
01400 tree phi;
01401
01402 for (phi = phi_nodes (bb); phi; phi = PHI_CHAIN (phi))
01403 {
01404 stmt_ann_t ann = get_stmt_ann (phi);
01405 set_stmt_info (ann, new_stmt_vec_info (phi, res));
01406 }
01407
01408 for (si = bsi_start (bb); !bsi_end_p (si); bsi_next (&si))
01409 {
01410 tree stmt = bsi_stmt (si);
01411 stmt_ann_t ann;
01412
01413 ann = stmt_ann (stmt);
01414 set_stmt_info (ann, new_stmt_vec_info (stmt, res));
01415 }
01416 }
01417
01418 LOOP_VINFO_LOOP (res) = loop;
01419 LOOP_VINFO_BBS (res) = bbs;
01420 LOOP_VINFO_EXIT_COND (res) = NULL;
01421 LOOP_VINFO_NITERS (res) = NULL;
01422 LOOP_VINFO_VECTORIZABLE_P (res) = 0;
01423 LOOP_PEELING_FOR_ALIGNMENT (res) = 0;
01424 LOOP_VINFO_VECT_FACTOR (res) = 0;
01425 LOOP_VINFO_DATAREFS (res) = VEC_alloc (data_reference_p, heap, 10);
01426 LOOP_VINFO_DDRS (res) = VEC_alloc (ddr_p, heap, 10 * 10);
01427 LOOP_VINFO_UNALIGNED_DR (res) = NULL;
01428 LOOP_VINFO_MAY_MISALIGN_STMTS (res)
01429 = VEC_alloc (tree, heap, PARAM_VALUE (PARAM_VECT_MAX_VERSION_CHECKS));
01430
01431 return res;
01432 }
01433
01434
01435
01436
01437
01438
01439
01440 void
01441 destroy_loop_vec_info (loop_vec_info loop_vinfo)
01442 {
01443 struct loop *loop;
01444 basic_block *bbs;
01445 int nbbs;
01446 block_stmt_iterator si;
01447 int j;
01448
01449 if (!loop_vinfo)
01450 return;
01451
01452 loop = LOOP_VINFO_LOOP (loop_vinfo);
01453
01454 bbs = LOOP_VINFO_BBS (loop_vinfo);
01455 nbbs = loop->num_nodes;
01456
01457 for (j = 0; j < nbbs; j++)
01458 {
01459 basic_block bb = bbs[j];
01460 tree phi;
01461 stmt_vec_info stmt_info;
01462
01463 for (phi = phi_nodes (bb); phi; phi = PHI_CHAIN (phi))
01464 {
01465 stmt_ann_t ann = stmt_ann (phi);
01466
01467 stmt_info = vinfo_for_stmt (phi);
01468 free (stmt_info);
01469 set_stmt_info (ann, NULL);
01470 }
01471
01472 for (si = bsi_start (bb); !bsi_end_p (si); )
01473 {
01474 tree stmt = bsi_stmt (si);
01475 stmt_ann_t ann = stmt_ann (stmt);
01476 stmt_vec_info stmt_info = vinfo_for_stmt (stmt);
01477
01478 if (stmt_info)
01479 {
01480
01481
01482 bool remove_stmt_p = false;
01483 tree orig_stmt = STMT_VINFO_RELATED_STMT (stmt_info);
01484 if (orig_stmt)
01485 {
01486 stmt_vec_info orig_stmt_info = vinfo_for_stmt (orig_stmt);
01487 if (orig_stmt_info
01488 && STMT_VINFO_IN_PATTERN_P (orig_stmt_info))
01489 remove_stmt_p = true;
01490 }
01491
01492
01493 VEC_free (dr_p, heap, STMT_VINFO_SAME_ALIGN_REFS (stmt_info));
01494 free (stmt_info);
01495 set_stmt_info (ann, NULL);
01496
01497
01498 if (remove_stmt_p)
01499 bsi_remove (&si, true);
01500 }
01501 bsi_next (&si);
01502 }
01503 }
01504
01505 free (LOOP_VINFO_BBS (loop_vinfo));
01506 free_data_refs (LOOP_VINFO_DATAREFS (loop_vinfo));
01507 free_dependence_relations (LOOP_VINFO_DDRS (loop_vinfo));
01508 VEC_free (tree, heap, LOOP_VINFO_MAY_MISALIGN_STMTS (loop_vinfo));
01509
01510 free (loop_vinfo);
01511 }
01512
01513
01514
01515
01516
01517
01518
01519 bool
01520 vect_can_force_dr_alignment_p (tree decl, unsigned int alignment)
01521 {
01522 if (TREE_CODE (decl) != VAR_DECL)
01523 return false;
01524
01525 if (DECL_EXTERNAL (decl))
01526 return false;
01527
01528 if (TREE_ASM_WRITTEN (decl))
01529 return false;
01530
01531 if (TREE_STATIC (decl))
01532 return (alignment <= MAX_OFILE_ALIGNMENT);
01533 else
01534
01535
01536
01537
01538
01539 return (alignment <= PREFERRED_STACK_BOUNDARY);
01540 }
01541
01542
01543
01544
01545
01546
01547
01548 tree
01549 get_vectype_for_scalar_type (tree scalar_type)
01550 {
01551 enum machine_mode inner_mode = TYPE_MODE (scalar_type);
01552 int nbytes = GET_MODE_SIZE (inner_mode);
01553 int nunits;
01554 tree vectype;
01555
01556 if (nbytes == 0 || nbytes >= UNITS_PER_SIMD_WORD)
01557 return NULL_TREE;
01558
01559
01560
01561 nunits = UNITS_PER_SIMD_WORD / nbytes;
01562
01563 vectype = build_vector_type (scalar_type, nunits);
01564 if (vect_print_dump_info (REPORT_DETAILS))
01565 {
01566 fprintf (vect_dump, "get vectype with %d units of type ", nunits);
01567 print_generic_expr (vect_dump, scalar_type, TDF_SLIM);
01568 }
01569
01570 if (!vectype)
01571 return NULL_TREE;
01572
01573 if (vect_print_dump_info (REPORT_DETAILS))
01574 {
01575 fprintf (vect_dump, "vectype: ");
01576 print_generic_expr (vect_dump, vectype, TDF_SLIM);
01577 }
01578
01579 if (!VECTOR_MODE_P (TYPE_MODE (vectype))
01580 && !INTEGRAL_MODE_P (TYPE_MODE (vectype)))
01581 {
01582 if (vect_print_dump_info (REPORT_DETAILS))
01583 fprintf (vect_dump, "mode not supported by target.");
01584 return NULL_TREE;
01585 }
01586
01587 return vectype;
01588 }
01589
01590
01591
01592
01593
01594
01595
01596 enum dr_alignment_support
01597 vect_supportable_dr_alignment (struct data_reference *dr)
01598 {
01599 tree vectype = STMT_VINFO_VECTYPE (vinfo_for_stmt (DR_STMT (dr)));
01600 enum machine_mode mode = (int) TYPE_MODE (vectype);
01601
01602 if (aligned_access_p (dr))
01603 return dr_aligned;
01604
01605
01606
01607 if (DR_IS_READ (dr))
01608 {
01609 if (vec_realign_load_optab->handlers[mode].insn_code != CODE_FOR_nothing
01610 && (!targetm.vectorize.builtin_mask_for_load
01611 || targetm.vectorize.builtin_mask_for_load ()))
01612 return dr_unaligned_software_pipeline;
01613
01614 if (movmisalign_optab->handlers[mode].insn_code != CODE_FOR_nothing)
01615
01616 return dr_unaligned_supported;
01617 }
01618
01619
01620 return dr_unaligned_unsupported;
01621 }
01622
01623
01624
01625
01626
01627
01628
01629
01630
01631
01632
01633
01634
01635
01636
01637 bool
01638 vect_is_simple_use (tree operand, loop_vec_info loop_vinfo, tree *def_stmt,
01639 tree *def, enum vect_def_type *dt)
01640 {
01641 basic_block bb;
01642 stmt_vec_info stmt_vinfo;
01643 struct loop *loop = LOOP_VINFO_LOOP (loop_vinfo);
01644
01645 *def_stmt = NULL_TREE;
01646 *def = NULL_TREE;
01647
01648 if (vect_print_dump_info (REPORT_DETAILS))
01649 {
01650 fprintf (vect_dump, "vect_is_simple_use: operand ");
01651 print_generic_expr (vect_dump, operand, TDF_SLIM);
01652 }
01653
01654 if (TREE_CODE (operand) == INTEGER_CST || TREE_CODE (operand) == REAL_CST)
01655 {
01656 *dt = vect_constant_def;
01657 return true;
01658 }
01659
01660 if (TREE_CODE (operand) != SSA_NAME)
01661 {
01662 if (vect_print_dump_info (REPORT_DETAILS))
01663 fprintf (vect_dump, "not ssa-name.");
01664 return false;
01665 }
01666
01667 *def_stmt = SSA_NAME_DEF_STMT (operand);
01668 if (*def_stmt == NULL_TREE )
01669 {
01670 if (vect_print_dump_info (REPORT_DETAILS))
01671 fprintf (vect_dump, "no def_stmt.");
01672 return false;
01673 }
01674
01675 if (vect_print_dump_info (REPORT_DETAILS))
01676 {
01677 fprintf (vect_dump, "def_stmt: ");
01678 print_generic_expr (vect_dump, *def_stmt, TDF_SLIM);
01679 }
01680
01681
01682
01683 if (IS_EMPTY_STMT (*def_stmt))
01684 {
01685 tree arg = TREE_OPERAND (*def_stmt, 0);
01686 if (TREE_CODE (arg) == INTEGER_CST || TREE_CODE (arg) == REAL_CST)
01687 {
01688 *def = operand;
01689 *dt = vect_invariant_def;
01690 return true;
01691 }
01692
01693 if (vect_print_dump_info (REPORT_DETAILS))
01694 fprintf (vect_dump, "Unexpected empty stmt.");
01695 return false;
01696 }
01697
01698 bb = bb_for_stmt (*def_stmt);
01699 if (!flow_bb_inside_loop_p (loop, bb))
01700 *dt = vect_invariant_def;
01701 else
01702 {
01703 stmt_vinfo = vinfo_for_stmt (*def_stmt);
01704 *dt = STMT_VINFO_DEF_TYPE (stmt_vinfo);
01705 }
01706
01707 if (*dt == vect_unknown_def_type)
01708 {
01709 if (vect_print_dump_info (REPORT_DETAILS))
01710 fprintf (vect_dump, "Unsupported pattern.");
01711 return false;
01712 }
01713
01714
01715
01716 if (*dt == vect_reduction_def && TREE_CODE (*def_stmt) != PHI_NODE)
01717 {
01718 if (vect_print_dump_info (REPORT_DETAILS))
01719 fprintf (vect_dump, "reduction used in loop.");
01720 return false;
01721 }
01722
01723 if (vect_print_dump_info (REPORT_DETAILS))
01724 fprintf (vect_dump, "type of def: %d.",*dt);
01725
01726 switch (TREE_CODE (*def_stmt))
01727 {
01728 case PHI_NODE:
01729 *def = PHI_RESULT (*def_stmt);
01730 gcc_assert (*dt == vect_induction_def || *dt == vect_reduction_def
01731 || *dt == vect_invariant_def);
01732 break;
01733
01734 case MODIFY_EXPR:
01735 *def = TREE_OPERAND (*def_stmt, 0);
01736 gcc_assert (*dt == vect_loop_def || *dt == vect_invariant_def);
01737 break;
01738
01739 default:
01740 if (vect_print_dump_info (REPORT_DETAILS))
01741 fprintf (vect_dump, "unsupported defining stmt: ");
01742 return false;
01743 }
01744
01745 if (*dt == vect_induction_def)
01746 {
01747 if (vect_print_dump_info (REPORT_DETAILS))
01748 fprintf (vect_dump, "induction not supported.");
01749 return false;
01750 }
01751
01752 return true;
01753 }
01754
01755
01756
01757
01758
01759
01760
01761
01762
01763
01764
01765
01766
01767
01768 bool
01769 reduction_code_for_scalar_code (enum tree_code code,
01770 enum tree_code *reduc_code)
01771 {
01772 switch (code)
01773 {
01774 case MAX_EXPR:
01775 *reduc_code = REDUC_MAX_EXPR;
01776 return true;
01777
01778 case MIN_EXPR:
01779 *reduc_code = REDUC_MIN_EXPR;
01780 return true;
01781
01782 case PLUS_EXPR:
01783 *reduc_code = REDUC_PLUS_EXPR;
01784 return true;
01785
01786 default:
01787 return false;
01788 }
01789 }
01790
01791
01792
01793
01794
01795
01796
01797
01798
01799
01800
01801
01802
01803
01804
01805
01806
01807
01808
01809
01810
01811 tree
01812 vect_is_simple_reduction (struct loop *loop, tree phi)
01813 {
01814 edge latch_e = loop_latch_edge (loop);
01815 tree loop_arg = PHI_ARG_DEF_FROM_EDGE (phi, latch_e);
01816 tree def_stmt, def1, def2;
01817 enum tree_code code;
01818 int op_type;
01819 tree operation, op1, op2;
01820 tree type;
01821
01822 if (TREE_CODE (loop_arg) != SSA_NAME)
01823 {
01824 if (vect_print_dump_info (REPORT_DETAILS))
01825 {
01826 fprintf (vect_dump, "reduction: not ssa_name: ");
01827 print_generic_expr (vect_dump, loop_arg, TDF_SLIM);
01828 }
01829 return NULL_TREE;
01830 }
01831
01832 def_stmt = SSA_NAME_DEF_STMT (loop_arg);
01833 if (!def_stmt)
01834 {
01835 if (vect_print_dump_info (REPORT_DETAILS))
01836 fprintf (vect_dump, "reduction: no def_stmt.");
01837 return NULL_TREE;
01838 }
01839
01840 if (TREE_CODE (def_stmt) != MODIFY_EXPR)
01841 {
01842 if (vect_print_dump_info (REPORT_DETAILS))
01843 {
01844 print_generic_expr (vect_dump, def_stmt, TDF_SLIM);
01845 }
01846 return NULL_TREE;
01847 }
01848
01849 operation = TREE_OPERAND (def_stmt, 1);
01850 code = TREE_CODE (operation);
01851 if (!commutative_tree_code (code) || !associative_tree_code (code))
01852 {
01853 if (vect_print_dump_info (REPORT_DETAILS))
01854 {
01855 fprintf (vect_dump, "reduction: not commutative/associative: ");
01856 print_generic_expr (vect_dump, operation, TDF_SLIM);
01857 }
01858 return NULL_TREE;
01859 }
01860
01861 op_type = TREE_CODE_LENGTH (code);
01862 if (op_type != binary_op)
01863 {
01864 if (vect_print_dump_info (REPORT_DETAILS))
01865 {
01866 fprintf (vect_dump, "reduction: not binary operation: ");
01867 print_generic_expr (vect_dump, operation, TDF_SLIM);
01868 }
01869 return NULL_TREE;
01870 }
01871
01872 op1 = TREE_OPERAND (operation, 0);
01873 op2 = TREE_OPERAND (operation, 1);
01874 if (TREE_CODE (op1) != SSA_NAME || TREE_CODE (op2) != SSA_NAME)
01875 {
01876 if (vect_print_dump_info (REPORT_DETAILS))
01877 {
01878 fprintf (vect_dump, "reduction: uses not ssa_names: ");
01879 print_generic_expr (vect_dump, operation, TDF_SLIM);
01880 }
01881 return NULL_TREE;
01882 }
01883
01884
01885 type = TREE_TYPE (operation);
01886 if (TYPE_MAIN_VARIANT (type) != TYPE_MAIN_VARIANT (TREE_TYPE (op1))
01887 || TYPE_MAIN_VARIANT (type) != TYPE_MAIN_VARIANT (TREE_TYPE (op2)))
01888 {
01889 if (vect_print_dump_info (REPORT_DETAILS))
01890 {
01891 fprintf (vect_dump, "reduction: multiple types: operation type: ");
01892 print_generic_expr (vect_dump, type, TDF_SLIM);
01893 fprintf (vect_dump, ", operands types: ");
01894 print_generic_expr (vect_dump, TREE_TYPE (op1), TDF_SLIM);
01895 fprintf (vect_dump, ",");
01896 print_generic_expr (vect_dump, TREE_TYPE (op2), TDF_SLIM);
01897 }
01898 return NULL_TREE;
01899 }
01900
01901
01902 if (SCALAR_FLOAT_TYPE_P (type) && !flag_unsafe_math_optimizations)
01903 {
01904
01905 if (vect_print_dump_info (REPORT_DETAILS))
01906 {
01907 fprintf (vect_dump, "reduction: unsafe fp math optimization: ");
01908 print_generic_expr (vect_dump, operation, TDF_SLIM);
01909 }
01910 return NULL_TREE;
01911 }
01912 else if (INTEGRAL_TYPE_P (type) && TYPE_OVERFLOW_TRAPS (type))
01913 {
01914
01915 if (vect_print_dump_info (REPORT_DETAILS))
01916 {
01917 fprintf (vect_dump, "reduction: unsafe int math optimization: ");
01918 print_generic_expr (vect_dump, operation, TDF_SLIM);
01919 }
01920 return NULL_TREE;
01921 }
01922
01923
01924
01925
01926
01927 def1 = SSA_NAME_DEF_STMT (op1);
01928 def2 = SSA_NAME_DEF_STMT (op2);
01929 if (!def1 || !def2)
01930 {
01931 if (vect_print_dump_info (REPORT_DETAILS))
01932 {
01933 fprintf (vect_dump, "reduction: no defs for operands: ");
01934 print_generic_expr (vect_dump, operation, TDF_SLIM);
01935 }
01936 return NULL_TREE;
01937 }
01938
01939 if (TREE_CODE (def1) == MODIFY_EXPR
01940 && flow_bb_inside_loop_p (loop, bb_for_stmt (def1))
01941 && def2 == phi)
01942 {
01943 if (vect_print_dump_info (REPORT_DETAILS))
01944 {
01945 fprintf (vect_dump, "detected reduction:");
01946 print_generic_expr (vect_dump, operation, TDF_SLIM);
01947 }
01948 return def_stmt;
01949 }
01950 else if (TREE_CODE (def2) == MODIFY_EXPR
01951 && flow_bb_inside_loop_p (loop, bb_for_stmt (def2))
01952 && def1 == phi)
01953 {
01954
01955
01956
01957 if (vect_print_dump_info (REPORT_DETAILS))
01958 {
01959 fprintf (vect_dump, "detected reduction: need to swap operands:");
01960 print_generic_expr (vect_dump, operation, TDF_SLIM);
01961 }
01962 swap_tree_operands (def_stmt, &TREE_OPERAND (operation, 0),
01963 &TREE_OPERAND (operation, 1));
01964 return def_stmt;
01965 }
01966 else
01967 {
01968 if (vect_print_dump_info (REPORT_DETAILS))
01969 {
01970 fprintf (vect_dump, "reduction: unknown pattern.");
01971 print_generic_expr (vect_dump, operation, TDF_SLIM);
01972 }
01973 return NULL_TREE;
01974 }
01975 }
01976
01977
01978
01979
01980
01981
01982
01983 bool
01984 vect_is_simple_iv_evolution (unsigned loop_nb, tree access_fn, tree * init,
01985 tree * step)
01986 {
01987 tree init_expr;
01988 tree step_expr;
01989
01990 tree evolution_part = evolution_part_in_loop_num (access_fn, loop_nb);
01991
01992
01993
01994 if (evolution_part == NULL_TREE)
01995 return false;
01996
01997
01998
01999 if (tree_is_chrec (evolution_part))
02000 return false;
02001
02002 step_expr = evolution_part;
02003 init_expr = unshare_expr (initial_condition_in_loop_num (access_fn,
02004 loop_nb));
02005
02006 if (vect_print_dump_info (REPORT_DETAILS))
02007 {
02008 fprintf (vect_dump, "step: ");
02009 print_generic_expr (vect_dump, step_expr, TDF_SLIM);
02010 fprintf (vect_dump, ", init: ");
02011 print_generic_expr (vect_dump, init_expr, TDF_SLIM);
02012 }
02013
02014 *init = init_expr;
02015 *step = step_expr;
02016
02017 if (TREE_CODE (step_expr) != INTEGER_CST)
02018 {
02019 if (vect_print_dump_info (REPORT_DETAILS))
02020 fprintf (vect_dump, "step unknown.");
02021 return false;
02022 }
02023
02024 return true;
02025 }
02026
02027
02028
02029
02030
02031
02032 void
02033 vectorize_loops (struct loops *loops)
02034 {
02035 unsigned int i;
02036 unsigned int num_vectorized_loops = 0;
02037
02038
02039 vect_set_dump_settings ();
02040
02041
02042
02043 vect_vnames_to_rename = BITMAP_ALLOC (NULL);
02044
02045
02046
02047
02048
02049
02050 vect_loops_num = loops->num;
02051 for (i = 1; i < vect_loops_num; i++)
02052 {
02053 loop_vec_info loop_vinfo;
02054 struct loop *loop = loops->parray[i];
02055
02056 if (!loop)
02057 continue;
02058
02059 vect_loop_location = find_loop_location (loop);
02060 loop_vinfo = vect_analyze_loop (loop);
02061 loop->aux = loop_vinfo;
02062
02063 if (!loop_vinfo || !LOOP_VINFO_VECTORIZABLE_P (loop_vinfo))
02064 continue;
02065
02066 vect_transform_loop (loop_vinfo, loops);
02067 num_vectorized_loops++;
02068 }
02069 vect_loop_location = UNKNOWN_LOC;
02070
02071 if (vect_print_dump_info (REPORT_VECTORIZED_LOOPS))
02072 fprintf (vect_dump, "vectorized %u loops in function.\n",
02073 num_vectorized_loops);
02074
02075
02076
02077 BITMAP_FREE (vect_vnames_to_rename);
02078
02079 for (i = 1; i < vect_loops_num; i++)
02080 {
02081 struct loop *loop = loops->parray[i];
02082 loop_vec_info loop_vinfo;
02083
02084 if (!loop)
02085 continue;
02086 loop_vinfo = loop->aux;
02087 destroy_loop_vec_info (loop_vinfo);
02088 loop->aux = NULL;
02089 }
02090 }