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 #include "config.h"
00049 #include "system.h"
00050 #include "coretypes.h"
00051 #include "tm.h"
00052 #include "toplev.h"
00053 #include "rtl.h"
00054 #include "tm_p.h"
00055 #include "hard-reg-set.h"
00056 #include "regs.h"
00057 #include "function.h"
00058 #include "flags.h"
00059 #include "insn-config.h"
00060 #include "insn-attr.h"
00061 #include "except.h"
00062 #include "toplev.h"
00063 #include "recog.h"
00064 #include "cfglayout.h"
00065 #include "params.h"
00066 #include "sched-int.h"
00067 #include "target.h"
00068 #include "timevar.h"
00069 #include "tree-pass.h"
00070
00071
00072
00073
00074
00075 #if !defined (HAVE_conditional_execution) && defined (ENABLE_CHECKING)
00076 #define CHECK_DEAD_NOTES 1
00077 #else
00078 #define CHECK_DEAD_NOTES 0
00079 #endif
00080
00081
00082 #ifdef INSN_SCHEDULING
00083
00084 #define INSN_REF_COUNT(INSN) (h_i_d[INSN_UID (INSN)].ref_count)
00085 #define FED_BY_SPEC_LOAD(insn) (h_i_d[INSN_UID (insn)].fed_by_spec_load)
00086 #define IS_LOAD_INSN(insn) (h_i_d[INSN_UID (insn)].is_load_insn)
00087
00088
00089 static int nr_inter, nr_spec;
00090
00091 static int is_cfg_nonregular (void);
00092 static bool sched_is_disabled_for_current_region_p (void);
00093
00094
00095
00096
00097 typedef struct
00098 {
00099
00100 int rgn_nr_blocks;
00101
00102 int rgn_blocks;
00103
00104
00105 unsigned int dont_calc_deps : 1;
00106
00107 unsigned int has_real_ebb : 1;
00108 }
00109 region;
00110
00111
00112 static int nr_regions;
00113
00114
00115 static region *rgn_table;
00116
00117
00118 static int *rgn_bb_table;
00119
00120
00121
00122
00123
00124 static int *block_to_bb;
00125
00126
00127 static int *containing_rgn;
00128
00129
00130
00131 static int min_spec_prob;
00132
00133 #define RGN_NR_BLOCKS(rgn) (rgn_table[rgn].rgn_nr_blocks)
00134 #define RGN_BLOCKS(rgn) (rgn_table[rgn].rgn_blocks)
00135 #define RGN_DONT_CALC_DEPS(rgn) (rgn_table[rgn].dont_calc_deps)
00136 #define RGN_HAS_REAL_EBB(rgn) (rgn_table[rgn].has_real_ebb)
00137 #define BLOCK_TO_BB(block) (block_to_bb[block])
00138 #define CONTAINING_RGN(block) (containing_rgn[block])
00139
00140 void debug_regions (void);
00141 static void find_single_block_region (void);
00142 static void find_rgns (void);
00143 static void extend_rgns (int *, int *, sbitmap, int *);
00144 static bool too_large (int, int *, int *);
00145
00146 extern void debug_live (int, int);
00147
00148
00149 static int current_nr_blocks;
00150 static int current_blocks;
00151
00152 static int rgn_n_insns;
00153
00154
00155
00156
00157
00158 #define BB_TO_BLOCK(ebb) (rgn_bb_table[ebb_head[ebb]])
00159 #define EBB_FIRST_BB(ebb) BASIC_BLOCK (BB_TO_BLOCK (ebb))
00160 #define EBB_LAST_BB(ebb) BASIC_BLOCK (rgn_bb_table[ebb_head[ebb + 1] - 1])
00161
00162
00163
00164
00165
00166
00167
00168 typedef struct
00169 {
00170 basic_block *first_member;
00171 int nr_members;
00172 }
00173 bblst;
00174
00175 typedef struct
00176 {
00177 char is_valid;
00178 char is_speculative;
00179 int src_prob;
00180 bblst split_bbs;
00181 bblst update_bbs;
00182 }
00183 candidate;
00184
00185 static candidate *candidate_table;
00186
00187
00188
00189
00190
00191
00192
00193
00194 static basic_block *bblst_table;
00195 static int bblst_size, bblst_last;
00196
00197 #define IS_VALID(src) ( candidate_table[src].is_valid )
00198 #define IS_SPECULATIVE(src) ( candidate_table[src].is_speculative )
00199 #define SRC_PROB(src) ( candidate_table[src].src_prob )
00200
00201
00202 static int target_bb;
00203
00204
00205 typedef struct
00206 {
00207 edge *first_member;
00208 int nr_members;
00209 }
00210 edgelst;
00211
00212 static edge *edgelst_table;
00213 static int edgelst_last;
00214
00215 static void extract_edgelst (sbitmap, edgelst *);
00216
00217
00218
00219 static void split_edges (int, int, edgelst *);
00220 static void compute_trg_info (int);
00221 void debug_candidate (int);
00222 void debug_candidates (int);
00223
00224
00225
00226 static sbitmap *dom;
00227
00228
00229 #define IS_RGN_ENTRY(bb) (!bb)
00230
00231
00232 #define IS_DOMINATED(bb_src, bb_trg) \
00233 ( TEST_BIT (dom[bb_src], bb_trg) )
00234
00235
00236
00237 static int *prob;
00238
00239
00240 typedef sbitmap edgeset;
00241
00242
00243 static int rgn_nr_edges;
00244
00245
00246 static edge *rgn_edges;
00247
00248
00249 #define EDGE_TO_BIT(edge) ((int)(size_t)(edge)->aux)
00250 #define SET_EDGE_TO_BIT(edge,nr) ((edge)->aux = (void *)(size_t)(nr))
00251
00252
00253
00254
00255
00256
00257
00258 static edgeset *pot_split;
00259
00260
00261 static edgeset *ancestor_edges;
00262
00263
00264
00265
00266
00267 static int *ebb_head;
00268
00269 static void compute_dom_prob_ps (int);
00270
00271 #define INSN_PROBABILITY(INSN) (SRC_PROB (BLOCK_TO_BB (BLOCK_NUM (INSN))))
00272 #define IS_SPECULATIVE_INSN(INSN) (IS_SPECULATIVE (BLOCK_TO_BB (BLOCK_NUM (INSN))))
00273 #define INSN_BB(INSN) (BLOCK_TO_BB (BLOCK_NUM (INSN)))
00274
00275
00276 static int check_live_1 (int, rtx);
00277 static void update_live_1 (int, rtx);
00278 static int check_live (rtx, int);
00279 static void update_live (rtx, int);
00280 static void set_spec_fed (rtx);
00281 static int is_pfree (rtx, int, int);
00282 static int find_conditional_protection (rtx, int);
00283 static int is_conditionally_protected (rtx, int, int);
00284 static int is_prisky (rtx, int, int);
00285 static int is_exception_free (rtx, int, int);
00286
00287 static bool sets_likely_spilled (rtx);
00288 static void sets_likely_spilled_1 (rtx, rtx, void *);
00289 static void add_branch_dependences (rtx, rtx);
00290 static void compute_block_backward_dependences (int);
00291 void debug_dependencies (void);
00292
00293 static void init_regions (void);
00294 static void schedule_region (int);
00295 static rtx concat_INSN_LIST (rtx, rtx);
00296 static void concat_insn_mem_list (rtx, rtx, rtx *, rtx *);
00297 static void propagate_deps (int, struct deps *);
00298 static void free_pending_lists (void);
00299
00300
00301
00302
00303
00304
00305
00306
00307
00308 static int
00309 is_cfg_nonregular (void)
00310 {
00311 basic_block b;
00312 rtx insn;
00313
00314
00315
00316 if (nonlocal_goto_handler_labels)
00317 return 1;
00318
00319
00320 if (forced_labels)
00321 return 1;
00322
00323
00324
00325
00326 if (current_function_has_exception_handlers ())
00327 return 1;
00328
00329
00330
00331 FOR_EACH_BB (b)
00332 FOR_BB_INSNS (b, insn)
00333 {
00334
00335 if (NONJUMP_INSN_P (insn) || CALL_P (insn))
00336 {
00337 rtx note = find_reg_note (insn, REG_LABEL, NULL_RTX);
00338 if (note
00339 && ! (JUMP_P (NEXT_INSN (insn))
00340 && find_reg_note (NEXT_INSN (insn), REG_LABEL,
00341 XEXP (note, 0))))
00342 return 1;
00343 }
00344
00345
00346 else if (JUMP_P (insn) && computed_jump_p (insn))
00347 return 1;
00348 }
00349
00350
00351
00352
00353
00354
00355
00356 FOR_EACH_BB (b)
00357 {
00358 if (EDGE_COUNT (b->preds) == 0
00359 || (single_pred_p (b)
00360 && single_pred (b) == b))
00361 return 1;
00362 }
00363
00364
00365 return 0;
00366 }
00367
00368
00369
00370 static void
00371 extract_edgelst (sbitmap set, edgelst *el)
00372 {
00373 unsigned int i = 0;
00374 sbitmap_iterator sbi;
00375
00376
00377 edgelst_last = 0;
00378
00379 el->first_member = &edgelst_table[edgelst_last];
00380 el->nr_members = 0;
00381
00382
00383 EXECUTE_IF_SET_IN_SBITMAP (set, 0, i, sbi)
00384 {
00385 edgelst_table[edgelst_last++] = rgn_edges[i];
00386 el->nr_members++;
00387 }
00388 }
00389
00390
00391
00392
00393
00394 void
00395 debug_regions (void)
00396 {
00397 int rgn, bb;
00398
00399 fprintf (sched_dump, "\n;; ------------ REGIONS ----------\n\n");
00400 for (rgn = 0; rgn < nr_regions; rgn++)
00401 {
00402 fprintf (sched_dump, ";;\trgn %d nr_blocks %d:\n", rgn,
00403 rgn_table[rgn].rgn_nr_blocks);
00404 fprintf (sched_dump, ";;\tbb/block: ");
00405
00406
00407
00408 current_blocks = RGN_BLOCKS (rgn);
00409
00410 for (bb = 0; bb < rgn_table[rgn].rgn_nr_blocks; bb++)
00411 fprintf (sched_dump, " %d/%d ", bb, rgn_bb_table[current_blocks + bb]);
00412
00413 fprintf (sched_dump, "\n\n");
00414 }
00415 }
00416
00417
00418
00419
00420
00421 static void
00422 find_single_block_region (void)
00423 {
00424 basic_block bb;
00425
00426 nr_regions = 0;
00427
00428 FOR_EACH_BB (bb)
00429 {
00430 rgn_bb_table[nr_regions] = bb->index;
00431 RGN_NR_BLOCKS (nr_regions) = 1;
00432 RGN_BLOCKS (nr_regions) = nr_regions;
00433 RGN_DONT_CALC_DEPS (nr_regions) = 0;
00434 RGN_HAS_REAL_EBB (nr_regions) = 0;
00435 CONTAINING_RGN (bb->index) = nr_regions;
00436 BLOCK_TO_BB (bb->index) = 0;
00437 nr_regions++;
00438 }
00439 }
00440
00441
00442
00443
00444
00445 static bool
00446 too_large (int block, int *num_bbs, int *num_insns)
00447 {
00448 (*num_bbs)++;
00449 (*num_insns) += (INSN_LUID (BB_END (BASIC_BLOCK (block)))
00450 - INSN_LUID (BB_HEAD (BASIC_BLOCK (block))));
00451
00452 return ((*num_bbs > PARAM_VALUE (PARAM_MAX_SCHED_REGION_BLOCKS))
00453 || (*num_insns > PARAM_VALUE (PARAM_MAX_SCHED_REGION_INSNS)));
00454 }
00455
00456
00457
00458
00459 #define UPDATE_LOOP_RELATIONS(blk, hdr) \
00460 { \
00461 if (max_hdr[blk] == -1) \
00462 max_hdr[blk] = hdr; \
00463 else if (dfs_nr[max_hdr[blk]] > dfs_nr[hdr]) \
00464 RESET_BIT (inner, hdr); \
00465 else if (dfs_nr[max_hdr[blk]] < dfs_nr[hdr]) \
00466 { \
00467 RESET_BIT (inner,max_hdr[blk]); \
00468 max_hdr[blk] = hdr; \
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 static void
00503 find_rgns (void)
00504 {
00505 int *max_hdr, *dfs_nr, *degree;
00506 char no_loops = 1;
00507 int node, child, loop_head, i, head, tail;
00508 int count = 0, sp, idx = 0;
00509 edge_iterator current_edge;
00510 edge_iterator *stack;
00511 int num_bbs, num_insns, unreachable;
00512 int too_large_failure;
00513 basic_block bb;
00514
00515
00516 sbitmap header;
00517
00518
00519 sbitmap inner;
00520
00521
00522 sbitmap in_queue;
00523
00524
00525 sbitmap in_stack;
00526
00527
00528
00529
00530
00531
00532
00533
00534
00535
00536
00537 max_hdr = XNEWVEC (int, last_basic_block);
00538 dfs_nr = XCNEWVEC (int, last_basic_block);
00539 stack = XNEWVEC (edge_iterator, n_edges);
00540
00541 inner = sbitmap_alloc (last_basic_block);
00542 sbitmap_ones (inner);
00543
00544 header = sbitmap_alloc (last_basic_block);
00545 sbitmap_zero (header);
00546
00547 in_queue = sbitmap_alloc (last_basic_block);
00548 sbitmap_zero (in_queue);
00549
00550 in_stack = sbitmap_alloc (last_basic_block);
00551 sbitmap_zero (in_stack);
00552
00553 for (i = 0; i < last_basic_block; i++)
00554 max_hdr[i] = -1;
00555
00556 #define EDGE_PASSED(E) (ei_end_p ((E)) || ei_edge ((E))->aux)
00557 #define SET_EDGE_PASSED(E) (ei_edge ((E))->aux = ei_edge ((E)))
00558
00559
00560
00561 current_edge = ei_start (single_succ (ENTRY_BLOCK_PTR)->succs);
00562 sp = -1;
00563
00564 while (1)
00565 {
00566 if (EDGE_PASSED (current_edge))
00567 {
00568
00569
00570
00571 while (sp >= 0 && EDGE_PASSED (current_edge))
00572 {
00573
00574 current_edge = stack[sp--];
00575 node = ei_edge (current_edge)->src->index;
00576 gcc_assert (node != ENTRY_BLOCK);
00577 child = ei_edge (current_edge)->dest->index;
00578 gcc_assert (child != EXIT_BLOCK);
00579 RESET_BIT (in_stack, child);
00580 if (max_hdr[child] >= 0 && TEST_BIT (in_stack, max_hdr[child]))
00581 UPDATE_LOOP_RELATIONS (node, max_hdr[child]);
00582 ei_next (¤t_edge);
00583 }
00584
00585
00586 if (sp < 0 && EDGE_PASSED (current_edge))
00587 break;
00588
00589
00590 continue;
00591 }
00592
00593
00594 node = ei_edge (current_edge)->src->index;
00595 gcc_assert (node != ENTRY_BLOCK);
00596 SET_BIT (in_stack, node);
00597 dfs_nr[node] = ++count;
00598
00599
00600 child = ei_edge (current_edge)->dest->index;
00601 if (child == EXIT_BLOCK)
00602 {
00603 SET_EDGE_PASSED (current_edge);
00604 ei_next (¤t_edge);
00605 continue;
00606 }
00607
00608
00609
00610
00611 if (TEST_BIT (in_stack, child))
00612 {
00613 no_loops = 0;
00614 SET_BIT (header, child);
00615 UPDATE_LOOP_RELATIONS (node, child);
00616 SET_EDGE_PASSED (current_edge);
00617 ei_next (¤t_edge);
00618 continue;
00619 }
00620
00621
00622
00623
00624 if (dfs_nr[child])
00625 {
00626 if (max_hdr[child] >= 0 && TEST_BIT (in_stack, max_hdr[child]))
00627 UPDATE_LOOP_RELATIONS (node, max_hdr[child]);
00628 SET_EDGE_PASSED (current_edge);
00629 ei_next (¤t_edge);
00630 continue;
00631 }
00632
00633
00634 stack[++sp] = current_edge;
00635 SET_EDGE_PASSED (current_edge);
00636 current_edge = ei_start (ei_edge (current_edge)->dest->succs);
00637 }
00638
00639
00640 FOR_ALL_BB (bb)
00641 {
00642 edge_iterator ei;
00643 edge e;
00644 FOR_EACH_EDGE (e, ei, bb->succs)
00645 e->aux = NULL;
00646 }
00647
00648
00649
00650
00651
00652
00653
00654
00655
00656 unreachable = 0;
00657 FOR_EACH_BB (bb)
00658 if (dfs_nr[bb->index] == 0)
00659 {
00660 unreachable = 1;
00661 break;
00662 }
00663
00664
00665
00666 degree = dfs_nr;
00667
00668 FOR_EACH_BB (bb)
00669 degree[bb->index] = EDGE_COUNT (bb->preds);
00670
00671
00672
00673 if (!unreachable)
00674 {
00675 int *queue, *degree1 = NULL;
00676
00677
00678
00679
00680 sbitmap extended_rgn_header = NULL;
00681 bool extend_regions_p;
00682
00683 if (no_loops)
00684 SET_BIT (header, 0);
00685
00686
00687
00688
00689 queue = XNEWVEC (int, n_basic_blocks);
00690
00691 extend_regions_p = PARAM_VALUE (PARAM_MAX_SCHED_EXTEND_REGIONS_ITERS) > 0;
00692 if (extend_regions_p)
00693 {
00694 degree1 = xmalloc (last_basic_block * sizeof (int));
00695 extended_rgn_header = sbitmap_alloc (last_basic_block);
00696 sbitmap_zero (extended_rgn_header);
00697 }
00698
00699
00700
00701 FOR_EACH_BB (bb)
00702 {
00703 if (TEST_BIT (header, bb->index) && TEST_BIT (inner, bb->index))
00704 {
00705 edge e;
00706 edge_iterator ei;
00707 basic_block jbb;
00708
00709
00710
00711
00712
00713
00714
00715
00716
00717
00718
00719
00720 FOR_EACH_BB (jbb)
00721 {
00722
00723
00724 if (bb->index == max_hdr[jbb->index] && bb != jbb)
00725 {
00726
00727
00728 if (!dominated_by_p (CDI_DOMINATORS, jbb, bb))
00729 break;
00730 }
00731 }
00732
00733
00734
00735
00736 if (jbb != EXIT_BLOCK_PTR)
00737 continue;
00738
00739
00740
00741 head = tail = -1;
00742 too_large_failure = 0;
00743 loop_head = max_hdr[bb->index];
00744
00745 if (extend_regions_p)
00746
00747
00748
00749 memcpy (degree1, degree, last_basic_block * sizeof (int));
00750
00751
00752
00753 FOR_EACH_EDGE (e, ei, bb->succs)
00754 if (e->dest != EXIT_BLOCK_PTR)
00755 --degree[e->dest->index];
00756
00757
00758 num_bbs = 1;
00759 num_insns = (INSN_LUID (BB_END (bb))
00760 - INSN_LUID (BB_HEAD (bb)));
00761
00762
00763
00764
00765
00766 if (no_loops)
00767 {
00768 FOR_EACH_BB (jbb)
00769
00770
00771 if (single_succ_p (jbb)
00772 && single_succ (jbb) == EXIT_BLOCK_PTR)
00773 {
00774 queue[++tail] = jbb->index;
00775 SET_BIT (in_queue, jbb->index);
00776
00777 if (too_large (jbb->index, &num_bbs, &num_insns))
00778 {
00779 too_large_failure = 1;
00780 break;
00781 }
00782 }
00783 }
00784 else
00785 {
00786 edge e;
00787
00788 FOR_EACH_EDGE (e, ei, bb->preds)
00789 {
00790 if (e->src == ENTRY_BLOCK_PTR)
00791 continue;
00792
00793 node = e->src->index;
00794
00795 if (max_hdr[node] == loop_head && node != bb->index)
00796 {
00797
00798 queue[++tail] = node;
00799 SET_BIT (in_queue, node);
00800
00801 if (too_large (node, &num_bbs, &num_insns))
00802 {
00803 too_large_failure = 1;
00804 break;
00805 }
00806 }
00807 }
00808 }
00809
00810
00811
00812
00813
00814
00815
00816
00817
00818
00819
00820
00821
00822
00823
00824
00825
00826
00827
00828
00829
00830
00831
00832
00833
00834
00835
00836
00837
00838
00839
00840 while (head < tail && !too_large_failure)
00841 {
00842 edge e;
00843 child = queue[++head];
00844
00845 FOR_EACH_EDGE (e, ei, BASIC_BLOCK (child)->preds)
00846 {
00847 node = e->src->index;
00848
00849
00850
00851 if (e->src == ENTRY_BLOCK_PTR
00852 || max_hdr[node] != loop_head)
00853 {
00854 tail = -1;
00855 break;
00856 }
00857 else if (!TEST_BIT (in_queue, node) && node != bb->index)
00858 {
00859 queue[++tail] = node;
00860 SET_BIT (in_queue, node);
00861
00862 if (too_large (node, &num_bbs, &num_insns))
00863 {
00864 too_large_failure = 1;
00865 break;
00866 }
00867 }
00868 }
00869 }
00870
00871 if (tail >= 0 && !too_large_failure)
00872 {
00873
00874 degree[bb->index] = -1;
00875 rgn_bb_table[idx] = bb->index;
00876 RGN_NR_BLOCKS (nr_regions) = num_bbs;
00877 RGN_BLOCKS (nr_regions) = idx++;
00878 RGN_DONT_CALC_DEPS (nr_regions) = 0;
00879 RGN_HAS_REAL_EBB (nr_regions) = 0;
00880 CONTAINING_RGN (bb->index) = nr_regions;
00881 BLOCK_TO_BB (bb->index) = count = 0;
00882
00883
00884
00885
00886
00887 while (tail >= 0)
00888 {
00889 if (head < 0)
00890 head = tail;
00891 child = queue[head];
00892 if (degree[child] == 0)
00893 {
00894 edge e;
00895
00896 degree[child] = -1;
00897 rgn_bb_table[idx++] = child;
00898 BLOCK_TO_BB (child) = ++count;
00899 CONTAINING_RGN (child) = nr_regions;
00900 queue[head] = queue[tail--];
00901
00902 FOR_EACH_EDGE (e, ei, BASIC_BLOCK (child)->succs)
00903 if (e->dest != EXIT_BLOCK_PTR)
00904 --degree[e->dest->index];
00905 }
00906 else
00907 --head;
00908 }
00909 ++nr_regions;
00910 }
00911 else if (extend_regions_p)
00912 {
00913
00914 int *t = degree;
00915
00916 degree = degree1;
00917 degree1 = t;
00918
00919
00920
00921
00922 FOR_EACH_EDGE (e, ei, bb->succs)
00923 if (e->dest != EXIT_BLOCK_PTR)
00924 SET_BIT (extended_rgn_header, e->dest->index);
00925 }
00926 }
00927 }
00928 free (queue);
00929
00930 if (extend_regions_p)
00931 {
00932 free (degree1);
00933
00934 sbitmap_a_or_b (header, header, extended_rgn_header);
00935 sbitmap_free (extended_rgn_header);
00936
00937 extend_rgns (degree, &idx, header, max_hdr);
00938 }
00939 }
00940
00941
00942
00943 FOR_EACH_BB (bb)
00944 if (degree[bb->index] >= 0)
00945 {
00946 rgn_bb_table[idx] = bb->index;
00947 RGN_NR_BLOCKS (nr_regions) = 1;
00948 RGN_BLOCKS (nr_regions) = idx++;
00949 RGN_DONT_CALC_DEPS (nr_regions) = 0;
00950 RGN_HAS_REAL_EBB (nr_regions) = 0;
00951 CONTAINING_RGN (bb->index) = nr_regions++;
00952 BLOCK_TO_BB (bb->index) = 0;
00953 }
00954
00955 free (max_hdr);
00956 free (degree);
00957 free (stack);
00958 sbitmap_free (header);
00959 sbitmap_free (inner);
00960 sbitmap_free (in_queue);
00961 sbitmap_free (in_stack);
00962 }
00963
00964 static int gather_region_statistics (int **);
00965 static void print_region_statistics (int *, int, int *, int);
00966
00967
00968
00969
00970 static int
00971 gather_region_statistics (int **rsp)
00972 {
00973 int i, *a = 0, a_sz = 0;
00974
00975
00976 for (i = 0; i < nr_regions; i++)
00977 {
00978 int nr_blocks = RGN_NR_BLOCKS (i);
00979
00980 gcc_assert (nr_blocks >= 1);
00981
00982 if (nr_blocks > a_sz)
00983 {
00984 a = xrealloc (a, nr_blocks * sizeof (*a));
00985 do
00986 a[a_sz++] = 0;
00987 while (a_sz != nr_blocks);
00988 }
00989
00990 a[nr_blocks - 1]++;
00991 }
00992
00993 *rsp = a;
00994 return a_sz;
00995 }
00996
00997
00998
00999 static void
01000 print_region_statistics (int *s1, int s1_sz, int *s2, int s2_sz)
01001 {
01002 int i;
01003
01004
01005
01006 for (i = 1; i < s2_sz; i++)
01007 {
01008 int n1, n2;
01009
01010 n2 = s2[i];
01011
01012 if (n2 == 0)
01013 continue;
01014
01015 if (i >= s1_sz)
01016 n1 = 0;
01017 else
01018 n1 = s1[i];
01019
01020 fprintf (sched_dump, ";; Region extension statistics: size %d: " \
01021 "was %d + %d more\n", i + 1, n1, n2 - n1);
01022 }
01023 }
01024
01025
01026
01027
01028
01029
01030
01031
01032
01033 static void
01034 extend_rgns (int *degree, int *idxp, sbitmap header, int *loop_hdr)
01035 {
01036 int *order, i, rescan = 0, idx = *idxp, iter = 0, max_iter, *max_hdr;
01037 int nblocks = n_basic_blocks - NUM_FIXED_BLOCKS;
01038
01039 max_iter = PARAM_VALUE (PARAM_MAX_SCHED_EXTEND_REGIONS_ITERS);
01040
01041 max_hdr = xmalloc (last_basic_block * sizeof (*max_hdr));
01042
01043 order = xmalloc (last_basic_block * sizeof (*order));
01044 post_order_compute (order, false);
01045
01046 for (i = nblocks - 1; i >= 0; i--)
01047 {
01048 int bbn = order[i];
01049 if (degree[bbn] >= 0)
01050 {
01051 max_hdr[bbn] = bbn;
01052 rescan = 1;
01053 }
01054 else
01055
01056 max_hdr[bbn] = -1;
01057 }
01058
01059
01060
01061
01062
01063
01064
01065
01066
01067
01068
01069 while (rescan && iter < max_iter)
01070 {
01071 rescan = 0;
01072
01073 for (i = nblocks - 1; i >= 0; i--)
01074 {
01075 edge e;
01076 edge_iterator ei;
01077 int bbn = order[i];
01078
01079 if (max_hdr[bbn] != -1 && !TEST_BIT (header, bbn))
01080 {
01081 int hdr = -1;
01082
01083 FOR_EACH_EDGE (e, ei, BASIC_BLOCK (bbn)->preds)
01084 {
01085 int predn = e->src->index;
01086
01087 if (predn != ENTRY_BLOCK
01088
01089 && max_hdr[predn] != -1
01090
01091
01092 && loop_hdr[bbn] == loop_hdr[predn])
01093 {
01094 if (hdr == -1)
01095
01096 hdr = max_hdr[predn];
01097 else if (hdr != max_hdr[predn])
01098
01099
01100
01101 {
01102 hdr = bbn;
01103 break;
01104 }
01105 }
01106 else
01107
01108 {
01109 hdr = bbn;
01110 break;
01111 }
01112 }
01113
01114 if (hdr == bbn)
01115 {
01116
01117
01118 SET_BIT (header, bbn);
01119 rescan = 1;
01120 }
01121 else
01122 gcc_assert (hdr != -1);
01123
01124 max_hdr[bbn] = hdr;
01125 }
01126 }
01127
01128 iter++;
01129 }
01130
01131
01132
01133
01134
01135
01136
01137
01138
01139
01140
01141
01142
01143
01144
01145
01146
01147
01148
01149
01150
01151
01152
01153 if (sched_verbose && iter != 0)
01154 fprintf (sched_dump, ";; Region extension iterations: %d%s\n", iter,
01155 rescan ? "... failed" : "");
01156
01157 if (!rescan && iter != 0)
01158 {
01159 int *s1 = NULL, s1_sz = 0;
01160
01161
01162 if (sched_verbose >= 6)
01163 s1_sz = gather_region_statistics (&s1);
01164
01165
01166 for (i = nblocks - 1; i >= 0; i--)
01167 {
01168 int bbn = order[i];
01169
01170 if (max_hdr[bbn] == bbn)
01171
01172 {
01173 edge e;
01174 edge_iterator ei;
01175 int num_bbs = 0, j, num_insns = 0, large;
01176
01177 large = too_large (bbn, &num_bbs, &num_insns);
01178
01179 degree[bbn] = -1;
01180 rgn_bb_table[idx] = bbn;
01181 RGN_BLOCKS (nr_regions) = idx++;
01182 RGN_DONT_CALC_DEPS (nr_regions) = 0;
01183 RGN_HAS_REAL_EBB (nr_regions) = 0;
01184 CONTAINING_RGN (bbn) = nr_regions;
01185 BLOCK_TO_BB (bbn) = 0;
01186
01187 FOR_EACH_EDGE (e, ei, BASIC_BLOCK (bbn)->succs)
01188 if (e->dest != EXIT_BLOCK_PTR)
01189 degree[e->dest->index]--;
01190
01191 if (!large)
01192
01193 for (j = i - 1; j >= 0; j--)
01194 {
01195 int succn = order[j];
01196 if (max_hdr[succn] == bbn)
01197 {
01198 if ((large = too_large (succn, &num_bbs, &num_insns)))
01199 break;
01200 }
01201 }
01202
01203 if (large)
01204
01205
01206
01207
01208 {
01209 RGN_NR_BLOCKS (nr_regions) = 1;
01210 nr_regions++;
01211 }
01212
01213 num_bbs = 1;
01214
01215 for (j = i - 1; j >= 0; j--)
01216 {
01217 int succn = order[j];
01218
01219 if (max_hdr[succn] == bbn)
01220
01221
01222
01223
01224 {
01225 gcc_assert (degree[succn] == 0);
01226
01227 degree[succn] = -1;
01228 rgn_bb_table[idx] = succn;
01229 BLOCK_TO_BB (succn) = large ? 0 : num_bbs++;
01230 CONTAINING_RGN (succn) = nr_regions;
01231
01232 if (large)
01233
01234 {
01235 RGN_BLOCKS (nr_regions) = idx;
01236 RGN_NR_BLOCKS (nr_regions) = 1;
01237 RGN_DONT_CALC_DEPS (nr_regions) = 0;
01238 RGN_HAS_REAL_EBB (nr_regions) = 0;
01239 nr_regions++;
01240 }
01241
01242 idx++;
01243
01244 FOR_EACH_EDGE (e, ei, BASIC_BLOCK (succn)->succs)
01245 if (e->dest != EXIT_BLOCK_PTR)
01246 degree[e->dest->index]--;
01247 }
01248 }
01249
01250 if (!large)
01251 {
01252 RGN_NR_BLOCKS (nr_regions) = num_bbs;
01253 nr_regions++;
01254 }
01255 }
01256 }
01257
01258 if (sched_verbose >= 6)
01259 {
01260 int *s2, s2_sz;
01261
01262
01263
01264 s2_sz = gather_region_statistics (&s2);
01265 print_region_statistics (s1, s1_sz, s2, s2_sz);
01266 free (s1);
01267 free (s2);
01268 }
01269 }
01270
01271 free (order);
01272 free (max_hdr);
01273
01274 *idxp = idx;
01275 }
01276
01277
01278
01279
01280
01281
01282 static void
01283 compute_dom_prob_ps (int bb)
01284 {
01285 edge_iterator in_ei;
01286 edge in_edge;
01287
01288
01289 gcc_assert (ebb_head [bb] == bb + current_blocks);
01290
01291 if (IS_RGN_ENTRY (bb))
01292 {
01293 SET_BIT (dom[bb], 0);
01294 prob[bb] = REG_BR_PROB_BASE;
01295 return;
01296 }
01297
01298 prob[bb] = 0;
01299
01300
01301 sbitmap_ones (dom[bb]);
01302
01303 FOR_EACH_EDGE (in_edge, in_ei, BASIC_BLOCK (BB_TO_BLOCK (bb))->preds)
01304 {
01305 int pred_bb;
01306 edge out_edge;
01307 edge_iterator out_ei;
01308
01309 if (in_edge->src == ENTRY_BLOCK_PTR)
01310 continue;
01311
01312 pred_bb = BLOCK_TO_BB (in_edge->src->index);
01313 sbitmap_a_and_b (dom[bb], dom[bb], dom[pred_bb]);
01314 sbitmap_a_or_b (ancestor_edges[bb],
01315 ancestor_edges[bb], ancestor_edges[pred_bb]);
01316
01317 SET_BIT (ancestor_edges[bb], EDGE_TO_BIT (in_edge));
01318
01319 sbitmap_a_or_b (pot_split[bb], pot_split[bb], pot_split[pred_bb]);
01320
01321 FOR_EACH_EDGE (out_edge, out_ei, in_edge->src->succs)
01322 SET_BIT (pot_split[bb], EDGE_TO_BIT (out_edge));
01323
01324 prob[bb] += ((prob[pred_bb] * in_edge->probability) / REG_BR_PROB_BASE);
01325 }
01326
01327 SET_BIT (dom[bb], bb);
01328 sbitmap_difference (pot_split[bb], pot_split[bb], ancestor_edges[bb]);
01329
01330 if (sched_verbose >= 2)
01331 fprintf (sched_dump, ";; bb_prob(%d, %d) = %3d\n", bb, BB_TO_BLOCK (bb),
01332 (100 * prob[bb]) / REG_BR_PROB_BASE);
01333 }
01334
01335
01336
01337
01338
01339
01340 static void
01341 split_edges (int bb_src, int bb_trg, edgelst *bl)
01342 {
01343 sbitmap src = sbitmap_alloc (pot_split[bb_src]->n_bits);
01344 sbitmap_copy (src, pot_split[bb_src]);
01345
01346 sbitmap_difference (src, src, pot_split[bb_trg]);
01347 extract_edgelst (src, bl);
01348 sbitmap_free (src);
01349 }
01350
01351
01352
01353
01354
01355 static void
01356 compute_trg_info (int trg)
01357 {
01358 candidate *sp;
01359 edgelst el;
01360 int i, j, k, update_idx;
01361 basic_block block;
01362 sbitmap visited;
01363 edge_iterator ei;
01364 edge e;
01365
01366
01367 sp = candidate_table + trg;
01368 sp->is_valid = 1;
01369 sp->is_speculative = 0;
01370 sp->src_prob = REG_BR_PROB_BASE;
01371
01372 visited = sbitmap_alloc (last_basic_block);
01373
01374 for (i = trg + 1; i < current_nr_blocks; i++)
01375 {
01376 sp = candidate_table + i;
01377
01378 sp->is_valid = IS_DOMINATED (i, trg);
01379 if (sp->is_valid)
01380 {
01381 int tf = prob[trg], cf = prob[i];
01382
01383
01384 sp->src_prob = (tf ? ((cf * REG_BR_PROB_BASE) / tf) : 0);
01385 sp->is_valid = (sp->src_prob >= min_spec_prob);
01386 }
01387
01388 if (sp->is_valid)
01389 {
01390 split_edges (i, trg, &el);
01391 sp->is_speculative = (el.nr_members) ? 1 : 0;
01392 if (sp->is_speculative && !flag_schedule_speculative)
01393 sp->is_valid = 0;
01394 }
01395
01396 if (sp->is_valid)
01397 {
01398
01399
01400 sp->split_bbs.first_member = &bblst_table[bblst_last];
01401 sp->split_bbs.nr_members = el.nr_members;
01402 for (j = 0; j < el.nr_members; bblst_last++, j++)
01403 bblst_table[bblst_last] = el.first_member[j]->dest;
01404 sp->update_bbs.first_member = &bblst_table[bblst_last];
01405
01406
01407
01408
01409
01410
01411
01412
01413 update_idx = 0;
01414 sbitmap_zero (visited);
01415 for (j = 0; j < el.nr_members; j++)
01416 {
01417 block = el.first_member[j]->src;
01418 FOR_EACH_EDGE (e, ei, block->succs)
01419 {
01420 if (!TEST_BIT (visited, e->dest->index))
01421 {
01422 for (k = 0; k < el.nr_members; k++)
01423 if (e == el.first_member[k])
01424 break;
01425
01426 if (k >= el.nr_members)
01427 {
01428 bblst_table[bblst_last++] = e->dest;
01429 SET_BIT (visited, e->dest->index);
01430 update_idx++;
01431 }
01432 }
01433 }
01434 }
01435 sp->update_bbs.nr_members = update_idx;
01436
01437
01438 gcc_assert (bblst_last <= bblst_size);
01439 }
01440 else
01441 {
01442 sp->split_bbs.nr_members = sp->update_bbs.nr_members = 0;
01443
01444 sp->is_speculative = 0;
01445 sp->src_prob = 0;
01446 }
01447 }
01448
01449 sbitmap_free (visited);
01450 }
01451
01452
01453
01454 void
01455 debug_candidate (int i)
01456 {
01457 if (!candidate_table[i].is_valid)
01458 return;
01459
01460 if (candidate_table[i].is_speculative)
01461 {
01462 int j;
01463 fprintf (sched_dump, "src b %d bb %d speculative \n", BB_TO_BLOCK (i), i);
01464
01465 fprintf (sched_dump, "split path: ");
01466 for (j = 0; j < candidate_table[i].split_bbs.nr_members; j++)
01467 {
01468 int b = candidate_table[i].split_bbs.first_member[j]->index;
01469
01470 fprintf (sched_dump, " %d ", b);
01471 }
01472 fprintf (sched_dump, "\n");
01473
01474 fprintf (sched_dump, "update path: ");
01475 for (j = 0; j < candidate_table[i].update_bbs.nr_members; j++)
01476 {
01477 int b = candidate_table[i].update_bbs.first_member[j]->index;
01478
01479 fprintf (sched_dump, " %d ", b);
01480 }
01481 fprintf (sched_dump, "\n");
01482 }
01483 else
01484 {
01485 fprintf (sched_dump, " src %d equivalent\n", BB_TO_BLOCK (i));
01486 }
01487 }
01488
01489
01490
01491 void
01492 debug_candidates (int trg)
01493 {
01494 int i;
01495
01496 fprintf (sched_dump, "----------- candidate table: target: b=%d bb=%d ---\n",
01497 BB_TO_BLOCK (trg), trg);
01498 for (i = trg + 1; i < current_nr_blocks; i++)
01499 debug_candidate (i);
01500 }
01501
01502
01503
01504
01505
01506
01507 static int
01508 check_live_1 (int src, rtx x)
01509 {
01510 int i;
01511 int regno;
01512 rtx reg = SET_DEST (x);
01513
01514 if (reg == 0)
01515 return 1;
01516
01517 while (GET_CODE (reg) == SUBREG
01518 || GET_CODE (reg) == ZERO_EXTRACT
01519 || GET_CODE (reg) == STRICT_LOW_PART)
01520 reg = XEXP (reg, 0);
01521
01522 if (GET_CODE (reg) == PARALLEL)
01523 {
01524 int i;
01525
01526 for (i = XVECLEN (reg, 0) - 1; i >= 0; i--)
01527 if (XEXP (XVECEXP (reg, 0, i), 0) != 0)
01528 if (check_live_1 (src, XEXP (XVECEXP (reg, 0, i), 0)))
01529 return 1;
01530
01531 return 0;
01532 }
01533
01534 if (!REG_P (reg))
01535 return 1;
01536
01537 regno = REGNO (reg);
01538
01539 if (regno < FIRST_PSEUDO_REGISTER && global_regs[regno])
01540 {
01541
01542 return 0;
01543 }
01544 else
01545 {
01546 if (regno < FIRST_PSEUDO_REGISTER)
01547 {
01548
01549 int j = hard_regno_nregs[regno][GET_MODE (reg)];
01550 while (--j >= 0)
01551 {
01552 for (i = 0; i < candidate_table[src].split_bbs.nr_members; i++)
01553 {
01554 basic_block b = candidate_table[src].split_bbs.first_member[i];
01555
01556
01557
01558 gcc_assert (glat_start[b->index]
01559 || CONTAINING_RGN (b->index)
01560 != CONTAINING_RGN (BB_TO_BLOCK (src)));
01561 if (!glat_start[b->index]
01562 || REGNO_REG_SET_P (glat_start[b->index],
01563 regno + j))
01564 {
01565 return 0;
01566 }
01567 }
01568 }
01569 }
01570 else
01571 {
01572
01573 for (i = 0; i < candidate_table[src].split_bbs.nr_members; i++)
01574 {
01575 basic_block b = candidate_table[src].split_bbs.first_member[i];
01576
01577 gcc_assert (glat_start[b->index]
01578 || CONTAINING_RGN (b->index)
01579 != CONTAINING_RGN (BB_TO_BLOCK (src)));
01580 if (!glat_start[b->index]
01581 || REGNO_REG_SET_P (glat_start[b->index], regno))
01582 {
01583 return 0;
01584 }
01585 }
01586 }
01587 }
01588
01589 return 1;
01590 }
01591
01592
01593
01594
01595 static void
01596 update_live_1 (int src, rtx x)
01597 {
01598 int i;
01599 int regno;
01600 rtx reg = SET_DEST (x);
01601
01602 if (reg == 0)
01603 return;
01604
01605 while (GET_CODE (reg) == SUBREG
01606 || GET_CODE (reg) == ZERO_EXTRACT
01607 || GET_CODE (reg) == STRICT_LOW_PART)
01608 reg = XEXP (reg, 0);
01609
01610 if (GET_CODE (reg) == PARALLEL)
01611 {
01612 int i;
01613
01614 for (i = XVECLEN (reg, 0) - 1; i >= 0; i--)
01615 if (XEXP (XVECEXP (reg, 0, i), 0) != 0)
01616 update_live_1 (src, XEXP (XVECEXP (reg, 0, i), 0));
01617
01618 return;
01619 }
01620
01621 if (!REG_P (reg))
01622 return;
01623
01624
01625
01626
01627 regno = REGNO (reg);
01628
01629 if (regno >= FIRST_PSEUDO_REGISTER || !global_regs[regno])
01630 {
01631 if (regno < FIRST_PSEUDO_REGISTER)
01632 {
01633 int j = hard_regno_nregs[regno][GET_MODE (reg)];
01634 while (--j >= 0)
01635 {
01636 for (i = 0; i < candidate_table[src].update_bbs.nr_members; i++)
01637 {
01638 basic_block b = candidate_table[src].update_bbs.first_member[i];
01639
01640 SET_REGNO_REG_SET (glat_start[b->index], regno + j);
01641 }
01642 }
01643 }
01644 else
01645 {
01646 for (i = 0; i < candidate_table[src].update_bbs.nr_members; i++)
01647 {
01648 basic_block b = candidate_table[src].update_bbs.first_member[i];
01649
01650 SET_REGNO_REG_SET (glat_start[b->index], regno);
01651 }
01652 }
01653 }
01654 }
01655
01656
01657
01658
01659
01660 static int
01661 check_live (rtx insn, int src)
01662 {
01663
01664 if (GET_CODE (PATTERN (insn)) == SET
01665 || GET_CODE (PATTERN (insn)) == CLOBBER)
01666 return check_live_1 (src, PATTERN (insn));
01667 else if (GET_CODE (PATTERN (insn)) == PARALLEL)
01668 {
01669 int j;
01670 for (j = XVECLEN (PATTERN (insn), 0) - 1; j >= 0; j--)
01671 if ((GET_CODE (XVECEXP (PATTERN (insn), 0, j)) == SET
01672 || GET_CODE (XVECEXP (PATTERN (insn), 0, j)) == CLOBBER)
01673 && !check_live_1 (src, XVECEXP (PATTERN (insn), 0, j)))
01674 return 0;
01675
01676 return 1;
01677 }
01678
01679 return 1;
01680 }
01681
01682
01683
01684
01685 static void
01686 update_live (rtx insn, int src)
01687 {
01688
01689 if (GET_CODE (PATTERN (insn)) == SET
01690 || GET_CODE (PATTERN (insn)) == CLOBBER)
01691 update_live_1 (src, PATTERN (insn));
01692 else if (GET_CODE (PATTERN (insn)) == PARALLEL)
01693 {
01694 int j;
01695 for (j = XVECLEN (PATTERN (insn), 0) - 1; j >= 0; j--)
01696 if (GET_CODE (XVECEXP (PATTERN (insn), 0, j)) == SET
01697 || GET_CODE (XVECEXP (PATTERN (insn), 0, j)) == CLOBBER)
01698 update_live_1 (src, XVECEXP (PATTERN (insn), 0, j));
01699 }
01700 }
01701
01702
01703 #define IS_REACHABLE(bb_from, bb_to) \
01704 (bb_from == bb_to \
01705 || IS_RGN_ENTRY (bb_from) \
01706 || (TEST_BIT (ancestor_edges[bb_to], \
01707 EDGE_TO_BIT (single_pred_edge (BASIC_BLOCK (BB_TO_BLOCK (bb_from)))))))
01708
01709
01710
01711 static void
01712 set_spec_fed (rtx load_insn)
01713 {
01714 rtx link;
01715
01716 for (link = INSN_DEPEND (load_insn); link; link = XEXP (link, 1))
01717 if (GET_MODE (link) == VOIDmode)
01718 FED_BY_SPEC_LOAD (XEXP (link, 0)) = 1;
01719 }
01720
01721
01722
01723
01724 static int
01725 find_conditional_protection (rtx insn, int load_insn_bb)
01726 {
01727 rtx link;
01728
01729
01730 for (link = INSN_DEPEND (insn); link; link = XEXP (link, 1))
01731 {
01732 rtx next = XEXP (link, 0);
01733 if ((CONTAINING_RGN (BLOCK_NUM (next)) ==
01734 CONTAINING_RGN (BB_TO_BLOCK (load_insn_bb)))
01735 && IS_REACHABLE (INSN_BB (next), load_insn_bb)
01736 && load_insn_bb != INSN_BB (next)
01737 && GET_MODE (link) == VOIDmode
01738 && (JUMP_P (next)
01739 || find_conditional_protection (next, load_insn_bb)))
01740 return 1;
01741 }
01742 return 0;
01743 }
01744
01745
01746
01747
01748
01749
01750
01751
01752
01753
01754
01755
01756
01757
01758
01759 static int
01760 is_conditionally_protected (rtx load_insn, int bb_src, int bb_trg)
01761 {
01762 rtx link;
01763
01764 for (link = LOG_LINKS (load_insn); link; link = XEXP (link, 1))
01765 {
01766 rtx insn1 = XEXP (link, 0);
01767
01768
01769 if (GET_MODE (link) != VOIDmode
01770 || JUMP_P (insn1))
01771 continue;
01772
01773
01774 if (INSN_BB (insn1) == bb_src
01775 || (CONTAINING_RGN (BLOCK_NUM (insn1))
01776 != CONTAINING_RGN (BB_TO_BLOCK (bb_src)))
01777 || (!IS_REACHABLE (bb_trg, INSN_BB (insn1))
01778 && !IS_REACHABLE (INSN_BB (insn1), bb_trg)))
01779 continue;
01780
01781
01782 if (find_conditional_protection (insn1, bb_src))
01783 return 1;
01784
01785
01786 return is_conditionally_protected (insn1, bb_src, bb_trg);
01787 }
01788
01789
01790 return 0;
01791 }
01792
01793
01794
01795
01796
01797
01798
01799
01800
01801
01802
01803
01804
01805
01806
01807
01808
01809 static int
01810 is_pfree (rtx load_insn, int bb_src, int bb_trg)
01811 {
01812 rtx back_link;
01813 candidate *candp = candidate_table + bb_src;
01814
01815 if (candp->split_bbs.nr_members != 1)
01816
01817 return 0;
01818
01819 for (back_link = LOG_LINKS (load_insn);
01820 back_link; back_link = XEXP (back_link, 1))
01821 {
01822 rtx insn1 = XEXP (back_link, 0);
01823
01824 if (GET_MODE (back_link) == VOIDmode)
01825 {
01826
01827 rtx fore_link;
01828
01829 for (fore_link = INSN_DEPEND (insn1);
01830 fore_link; fore_link = XEXP (fore_link, 1))
01831 {
01832 rtx insn2 = XEXP (fore_link, 0);
01833 if (GET_MODE (fore_link) == VOIDmode)
01834 {
01835
01836 if (haifa_classify_insn (insn2) != PFREE_CANDIDATE)
01837
01838 continue;
01839
01840 if (INSN_BB (insn2) == bb_trg)
01841
01842 return 1;
01843
01844 if (*(candp->split_bbs.first_member) == BLOCK_FOR_INSN (insn2))
01845
01846 return 1;
01847 }
01848 }
01849 }
01850 }
01851
01852
01853 return 0;
01854 }
01855
01856
01857
01858
01859
01860 static int
01861 is_prisky (rtx load_insn, int bb_src, int bb_trg)
01862 {
01863 if (FED_BY_SPEC_LOAD (load_insn))
01864 return 1;
01865
01866 if (LOG_LINKS (load_insn) == NULL)
01867
01868 return 1;
01869
01870 if (is_conditionally_protected (load_insn, bb_src, bb_trg))
01871 return 1;
01872
01873 return 0;
01874 }
01875
01876
01877
01878
01879
01880 static int
01881 is_exception_free (rtx insn, int bb_src, int bb_trg)
01882 {
01883 int insn_class = haifa_classify_insn (insn);
01884
01885
01886 switch (insn_class)
01887 {
01888 case TRAP_FREE:
01889 return 1;
01890 case TRAP_RISKY:
01891 return 0;
01892 default:;
01893 }
01894
01895
01896 if (!flag_schedule_speculative_load)
01897 return 0;
01898 IS_LOAD_INSN (insn) = 1;
01899 switch (insn_class)
01900 {
01901 case IFREE:
01902 return (1);
01903 case IRISKY:
01904 return 0;
01905 case PFREE_CANDIDATE:
01906 if (is_pfree (insn, bb_src, bb_trg))
01907 return 1;
01908
01909 case PRISKY_CANDIDATE:
01910 if (!flag_schedule_speculative_load_dangerous
01911 || is_prisky (insn, bb_src, bb_trg))
01912 return 0;
01913 break;
01914 default:;
01915 }
01916
01917 return flag_schedule_speculative_load_dangerous;
01918 }
01919
01920
01921 static int sched_target_n_insns;
01922
01923 static int target_n_insns;
01924
01925 static int sched_n_insns;
01926
01927
01928 static void init_ready_list (void);
01929 static int can_schedule_ready_p (rtx);
01930 static void begin_schedule_ready (rtx, rtx);
01931 static ds_t new_ready (rtx, ds_t);
01932 static int schedule_more_p (void);
01933 static const char *rgn_print_insn (rtx, int);
01934 static int rgn_rank (rtx, rtx);
01935 static int contributes_to_priority (rtx, rtx);
01936 static void compute_jump_reg_dependencies (rtx, regset, regset, regset);
01937
01938
01939 static void add_remove_insn (rtx, int);
01940 static void extend_regions (void);
01941 static void add_block1 (basic_block, basic_block);
01942 static void fix_recovery_cfg (int, int, int);
01943 static basic_block advance_target_bb (basic_block, rtx);
01944 static void check_dead_notes1 (int, sbitmap);
01945 #ifdef ENABLE_CHECKING
01946 static int region_head_or_leaf_p (basic_block, int);
01947 #endif
01948
01949
01950
01951 static int
01952 schedule_more_p (void)
01953 {
01954 return sched_target_n_insns < target_n_insns;
01955 }
01956
01957
01958
01959
01960 static void
01961 init_ready_list (void)
01962 {
01963 rtx prev_head = current_sched_info->prev_head;
01964 rtx next_tail = current_sched_info->next_tail;
01965 int bb_src;
01966 rtx insn;
01967
01968 target_n_insns = 0;
01969 sched_target_n_insns = 0;
01970 sched_n_insns = 0;
01971
01972
01973 if (sched_verbose >= 5)
01974 debug_dependencies ();
01975
01976
01977 if (current_nr_blocks > 1)
01978 {
01979 candidate_table = XNEWVEC (candidate, current_nr_blocks);
01980
01981 bblst_last = 0;
01982
01983
01984
01985
01986 bblst_size = (current_nr_blocks - target_bb) * rgn_nr_edges;
01987 bblst_table = XNEWVEC (basic_block, bblst_size);
01988
01989 edgelst_last = 0;
01990 edgelst_table = XNEWVEC (edge, rgn_nr_edges);
01991
01992 compute_trg_info (target_bb);
01993 }
01994
01995
01996
01997 for (insn = NEXT_INSN (prev_head); insn != next_tail; insn = NEXT_INSN (insn))
01998 {
01999 try_ready (insn);
02000 target_n_insns++;
02001
02002 gcc_assert (!(TODO_SPEC (insn) & BEGIN_CONTROL));
02003 }
02004
02005
02006
02007
02008 for (bb_src = target_bb + 1; bb_src < current_nr_blocks; bb_src++)
02009 if (IS_VALID (bb_src))
02010 {
02011 rtx src_head;
02012 rtx src_next_tail;
02013 rtx tail, head;
02014
02015 get_ebb_head_tail (EBB_FIRST_BB (bb_src), EBB_LAST_BB (bb_src),
02016 &head, &tail);
02017 src_next_tail = NEXT_INSN (tail);
02018 src_head = head;
02019
02020 for (insn = src_head; insn != src_next_tail; insn = NEXT_INSN (insn))
02021 if (INSN_P (insn))
02022 try_ready (insn);
02023 }
02024 }
02025
02026
02027
02028
02029 static int
02030 can_schedule_ready_p (rtx insn)
02031 {
02032
02033 if (INSN_BB (insn) != target_bb
02034 && IS_SPECULATIVE_INSN (insn)
02035 && !check_live (insn, INSN_BB (insn)))
02036 return 0;
02037 else
02038 return 1;
02039 }
02040
02041
02042
02043
02044
02045 static void
02046 begin_schedule_ready (rtx insn, rtx last ATTRIBUTE_UNUSED)
02047 {
02048
02049 if (INSN_BB (insn) != target_bb)
02050 {
02051 if (IS_SPECULATIVE_INSN (insn))
02052 {
02053 gcc_assert (check_live (insn, INSN_BB (insn)));
02054
02055 update_live (insn, INSN_BB (insn));
02056
02057
02058 if (IS_LOAD_INSN (insn) || FED_BY_SPEC_LOAD (insn))
02059 set_spec_fed (insn);
02060
02061 nr_spec++;
02062 }
02063 nr_inter++;
02064 }
02065 else
02066 {
02067
02068 sched_target_n_insns++;
02069 }
02070 sched_n_insns++;
02071 }
02072
02073
02074
02075
02076
02077 static ds_t
02078 new_ready (rtx next, ds_t ts)
02079 {
02080 if (INSN_BB (next) != target_bb)
02081 {
02082 int not_ex_free = 0;
02083
02084
02085
02086 if (!IS_VALID (INSN_BB (next))
02087 || CANT_MOVE (next)
02088 || (IS_SPECULATIVE_INSN (next)
02089 && ((recog_memoized (next) >= 0
02090 && min_insn_conflict_delay (curr_state, next, next)
02091 > PARAM_VALUE (PARAM_MAX_SCHED_INSN_CONFLICT_DELAY))
02092 || IS_SPECULATION_CHECK_P (next)
02093 || !check_live (next, INSN_BB (next))
02094 || (not_ex_free = !is_exception_free (next, INSN_BB (next),
02095 target_bb)))))
02096 {
02097 if (not_ex_free
02098
02099
02100 && current_sched_info->flags & DO_SPECULATION)
02101
02102 ts = set_dep_weak (ts, BEGIN_CONTROL, MAX_DEP_WEAK);
02103 else
02104 ts = (ts & ~SPECULATIVE) | HARD_DEP;
02105 }
02106 }
02107
02108 return ts;
02109 }
02110
02111
02112
02113
02114
02115
02116 static const char *
02117 rgn_print_insn (rtx insn, int aligned)
02118 {
02119 static char tmp[80];
02120
02121 if (aligned)
02122 sprintf (tmp, "b%3d: i%4d", INSN_BB (insn), INSN_UID (insn));
02123 else
02124 {
02125 if (current_nr_blocks > 1 && INSN_BB (insn) != target_bb)
02126 sprintf (tmp, "%d/b%d", INSN_UID (insn), INSN_BB (insn));
02127 else
02128 sprintf (tmp, "%d", INSN_UID (insn));
02129 }
02130 return tmp;
02131 }
02132
02133
02134
02135
02136
02137 static int
02138 rgn_rank (rtx insn1, rtx insn2)
02139 {
02140
02141 if (INSN_BB (insn1) != INSN_BB (insn2))
02142 {
02143 int spec_val, prob_val;
02144
02145
02146 if ((INSN_BB (insn2) == target_bb) && (INSN_BB (insn1) != target_bb))
02147 return 1;
02148 if ((INSN_BB (insn1) == target_bb) && (INSN_BB (insn2) != target_bb))
02149 return -1;
02150
02151
02152 spec_val = IS_SPECULATIVE_INSN (insn1) - IS_SPECULATIVE_INSN (insn2);
02153 if (spec_val)
02154 return spec_val;
02155
02156
02157 prob_val = INSN_PROBABILITY (insn2) - INSN_PROBABILITY (insn1);
02158 if (prob_val)
02159 return prob_val;
02160 }
02161 return 0;
02162 }
02163
02164
02165
02166
02167
02168 static int
02169 contributes_to_priority (rtx next, rtx insn)
02170 {
02171
02172 return BLOCK_TO_BB (BLOCK_NUM (next)) == BLOCK_TO_BB (BLOCK_NUM (insn));
02173 }
02174
02175
02176
02177
02178
02179
02180 static void
02181 compute_jump_reg_dependencies (rtx insn ATTRIBUTE_UNUSED,
02182 regset cond_exec ATTRIBUTE_UNUSED,
02183 regset used ATTRIBUTE_UNUSED,
02184 regset set ATTRIBUTE_UNUSED)
02185 {
02186
02187
02188 }
02189
02190
02191
02192
02193 static struct sched_info region_sched_info =
02194 {
02195 init_ready_list,
02196 can_schedule_ready_p,
02197 schedule_more_p,
02198 new_ready,
02199 rgn_rank,
02200 rgn_print_insn,
02201 contributes_to_priority,
02202 compute_jump_reg_dependencies,
02203
02204 NULL, NULL,
02205 NULL, NULL,
02206 0, 0, 0,
02207
02208 add_remove_insn,
02209 begin_schedule_ready,
02210 add_block1,
02211 advance_target_bb,
02212 fix_recovery_cfg,
02213 #ifdef ENABLE_CHECKING
02214 region_head_or_leaf_p,
02215 #endif
02216 SCHED_RGN | USE_GLAT
02217 #ifdef ENABLE_CHECKING
02218 | DETACH_LIFE_INFO
02219 #endif
02220 };
02221
02222
02223
02224 static bool
02225 sets_likely_spilled (rtx pat)
02226 {
02227 bool ret = false;
02228 note_stores (pat, sets_likely_spilled_1, &ret);
02229 return ret;
02230 }
02231
02232 static void
02233 sets_likely_spilled_1 (rtx x, rtx pat, void *data)
02234 {
02235 bool *ret = (bool *) data;
02236
02237 if (GET_CODE (pat) == SET
02238 && REG_P (x)
02239 && REGNO (x) < FIRST_PSEUDO_REGISTER
02240 && CLASS_LIKELY_SPILLED_P (REGNO_REG_CLASS (REGNO (x))))
02241 *ret = true;
02242 }
02243
02244
02245
02246
02247 static void
02248 add_branch_dependences (rtx head, rtx tail)
02249 {
02250 rtx insn, last;
02251
02252
02253
02254
02255
02256
02257
02258
02259
02260
02261
02262
02263
02264
02265
02266
02267
02268
02269
02270 insn = tail;
02271 last = 0;
02272 while (CALL_P (insn)
02273 || JUMP_P (insn)
02274 || (NONJUMP_INSN_P (insn)
02275 && (GET_CODE (PATTERN (insn)) == USE
02276 || GET_CODE (PATTERN (insn)) == CLOBBER
02277 || can_throw_internal (insn)
02278 #ifdef HAVE_cc0
02279 || sets_cc0_p (PATTERN (insn))
02280 #endif
02281 || (!reload_completed
02282 && sets_likely_spilled (PATTERN (insn)))))
02283 || NOTE_P (insn))
02284 {
02285 if (!NOTE_P (insn))
02286 {
02287 if (last != 0 && !find_insn_list (insn, LOG_LINKS (last)))
02288 {
02289 if (! sched_insns_conditions_mutex_p (last, insn))
02290 add_dependence (last, insn, REG_DEP_ANTI);
02291 INSN_REF_COUNT (insn)++;
02292 }
02293
02294 CANT_MOVE (insn) = 1;
02295
02296 last = insn;
02297 }
02298
02299
02300 if (insn == head)
02301 break;
02302
02303 insn = PREV_INSN (insn);
02304 }
02305
02306
02307 insn = last;
02308 if (insn != 0)
02309 while (insn != head)
02310 {
02311 insn = prev_nonnote_insn (insn);
02312
02313 if (INSN_REF_COUNT (insn) != 0)
02314 continue;
02315
02316 if (! sched_insns_conditions_mutex_p (last, insn))
02317 add_dependence (last, insn, REG_DEP_ANTI);
02318 INSN_REF_COUNT (insn) = 1;
02319 }
02320
02321 #ifdef HAVE_conditional_execution
02322
02323
02324
02325
02326
02327
02328
02329
02330
02331
02332
02333
02334
02335
02336
02337
02338
02339
02340
02341
02342
02343
02344
02345
02346
02347
02348
02349
02350
02351
02352
02353
02354
02355 if (!reload_completed || ! JUMP_P (tail))
02356 return;
02357
02358 insn = tail;
02359 while (insn != head)
02360 {
02361 insn = PREV_INSN (insn);
02362
02363
02364
02365
02366
02367 if (INSN_P (insn) && GET_CODE (PATTERN (insn)) == COND_EXEC)
02368 add_dependence (tail, insn, REG_DEP_ANTI);
02369 }
02370 #endif
02371 }
02372
02373
02374
02375
02376
02377
02378
02379 static struct deps *bb_deps;
02380
02381
02382
02383 static rtx
02384 concat_INSN_LIST (rtx copy, rtx old)
02385 {
02386 rtx new = old;
02387 for (; copy ; copy = XEXP (copy, 1))
02388 new = alloc_INSN_LIST (XEXP (copy, 0), new);
02389 return new;
02390 }
02391
02392 static void
02393 concat_insn_mem_list (rtx copy_insns, rtx copy_mems, rtx *old_insns_p,
02394 rtx *old_mems_p)
02395 {
02396 rtx new_insns = *old_insns_p;
02397 rtx new_mems = *old_mems_p;
02398
02399 while (copy_insns)
02400 {
02401 new_insns = alloc_INSN_LIST (XEXP (copy_insns, 0), new_insns);
02402 new_mems = alloc_EXPR_LIST (VOIDmode, XEXP (copy_mems, 0), new_mems);
02403 copy_insns = XEXP (copy_insns, 1);
02404 copy_mems = XEXP (copy_mems, 1);
02405 }
02406
02407 *old_insns_p = new_insns;
02408 *old_mems_p = new_mems;
02409 }
02410
02411
02412
02413 static void
02414 propagate_deps (int bb, struct deps *pred_deps)
02415 {
02416 basic_block block = BASIC_BLOCK (BB_TO_BLOCK (bb));
02417 edge_iterator ei;
02418 edge e;
02419
02420
02421 FOR_EACH_EDGE (e, ei, block->succs)
02422 {
02423 struct deps *succ_deps;
02424 unsigned reg;
02425 reg_set_iterator rsi;
02426
02427
02428 if (e->dest == EXIT_BLOCK_PTR
02429 || CONTAINING_RGN (block->index) != CONTAINING_RGN (e->dest->index)
02430 || BLOCK_TO_BB (e->dest->index) <= bb)
02431 continue;
02432
02433 succ_deps = bb_deps + BLOCK_TO_BB (e->dest->index);
02434
02435
02436 EXECUTE_IF_SET_IN_REG_SET (&pred_deps->reg_last_in_use, 0, reg, rsi)
02437 {
02438 struct deps_reg *pred_rl = &pred_deps->reg_last[reg];
02439 struct deps_reg *succ_rl = &succ_deps->reg_last[reg];
02440
02441 succ_rl->uses = concat_INSN_LIST (pred_rl->uses, succ_rl->uses);
02442 succ_rl->sets = concat_INSN_LIST (pred_rl->sets, succ_rl->sets);
02443 succ_rl->clobbers = concat_INSN_LIST (pred_rl->clobbers,
02444 succ_rl->clobbers);
02445 succ_rl->uses_length += pred_rl->uses_length;
02446 succ_rl->clobbers_length += pred_rl->clobbers_length;
02447 }
02448 IOR_REG_SET (&succ_deps->reg_last_in_use, &pred_deps->reg_last_in_use);
02449
02450
02451 concat_insn_mem_list (pred_deps->pending_read_insns,
02452 pred_deps->pending_read_mems,
02453 &succ_deps->pending_read_insns,
02454 &succ_deps->pending_read_mems);
02455 concat_insn_mem_list (pred_deps->pending_write_insns,
02456 pred_deps->pending_write_mems,
02457 &succ_deps->pending_write_insns,
02458 &succ_deps->pending_write_mems);
02459
02460 succ_deps->last_pending_memory_flush
02461 = concat_INSN_LIST (pred_deps->last_pending_memory_flush,
02462 succ_deps->last_pending_memory_flush);
02463
02464 succ_deps->pending_lists_length += pred_deps->pending_lists_length;
02465 succ_deps->pending_flush_length += pred_deps->pending_flush_length;
02466
02467
02468 succ_deps->last_function_call
02469 = concat_INSN_LIST (pred_deps->last_function_call,
02470 succ_deps->last_function_call);
02471
02472
02473 succ_deps->sched_before_next_call
02474 = concat_INSN_LIST (pred_deps->sched_before_next_call,
02475 succ_deps->sched_before_next_call);
02476 }
02477
02478
02479
02480 bb_deps[bb].pending_read_insns = pred_deps->pending_read_insns;
02481 bb_deps[bb].pending_read_mems = pred_deps->pending_read_mems;
02482 bb_deps[bb].pending_write_insns = pred_deps->pending_write_insns;
02483 bb_deps[bb].pending_write_mems = pred_deps->pending_write_mems;
02484
02485
02486 pred_deps->pending_read_insns = 0;
02487 pred_deps->pending_read_mems = 0;
02488 pred_deps->pending_write_insns = 0;
02489 pred_deps->pending_write_mems = 0;
02490 }
02491
02492
02493
02494
02495
02496
02497
02498
02499
02500
02501
02502
02503
02504
02505
02506
02507
02508
02509 static void
02510 compute_block_backward_dependences (int bb)
02511 {
02512 rtx head, tail;
02513 struct deps tmp_deps;
02514
02515 tmp_deps = bb_deps[bb];
02516
02517
02518 gcc_assert (EBB_FIRST_BB (bb) == EBB_LAST_BB (bb));
02519 get_ebb_head_tail (EBB_FIRST_BB (bb), EBB_LAST_BB (bb), &head, &tail);
02520 sched_analyze (&tmp_deps, head, tail);
02521 add_branch_dependences (head, tail);
02522
02523 if (current_nr_blocks > 1)
02524 propagate_deps (bb, &tmp_deps);
02525
02526
02527 free_deps (&tmp_deps);
02528 }
02529
02530
02531
02532
02533 static void
02534 free_pending_lists (void)
02535 {
02536 int bb;
02537
02538 for (bb = 0; bb < current_nr_blocks; bb++)
02539 {
02540 free_INSN_LIST_list (&bb_deps[bb].pending_read_insns);
02541 free_INSN_LIST_list (&bb_deps[bb].pending_write_insns);
02542 free_EXPR_LIST_list (&bb_deps[bb].pending_read_mems);
02543 free_EXPR_LIST_list (&bb_deps[bb].pending_write_mems);
02544 }
02545 }
02546
02547
02548
02549 void
02550 debug_dependencies (void)
02551 {
02552 int bb;
02553
02554 fprintf (sched_dump, ";; --------------- forward dependences: ------------ \n");
02555 for (bb = 0; bb < current_nr_blocks; bb++)
02556 {
02557 rtx head, tail;
02558 rtx next_tail;
02559 rtx insn;
02560
02561 gcc_assert (EBB_FIRST_BB (bb) == EBB_LAST_BB (bb));
02562 get_ebb_head_tail (EBB_FIRST_BB (bb), EBB_LAST_BB (bb), &head, &tail);
02563 next_tail = NEXT_INSN (tail);
02564 fprintf (sched_dump, "\n;; --- Region Dependences --- b %d bb %d \n",
02565 BB_TO_BLOCK (bb), bb);
02566
02567 fprintf (sched_dump, ";; %7s%6s%6s%6s%6s%6s%14s\n",
02568 "insn", "code", "bb", "dep", "prio", "cost",
02569 "reservation");
02570 fprintf (sched_dump, ";; %7s%6s%6s%6s%6s%6s%14s\n",
02571 "----", "----", "--", "---", "----", "----",
02572 "-----------");
02573
02574 for (insn = head; insn != next_tail; insn = NEXT_INSN (insn))
02575 {
02576 rtx link;
02577
02578 if (! INSN_P (insn))
02579 {
02580 int n;
02581 fprintf (sched_dump, ";; %6d ", INSN_UID (insn));
02582 if (NOTE_P (insn))
02583 {
02584 n = NOTE_LINE_NUMBER (insn);
02585 if (n < 0)
02586 fprintf (sched_dump, "%s\n", GET_NOTE_INSN_NAME (n));
02587 else
02588 {
02589 expanded_location xloc;
02590 NOTE_EXPANDED_LOCATION (xloc, insn);
02591 fprintf (sched_dump, "line %d, file %s\n",
02592 xloc.line, xloc.file);
02593 }
02594 }
02595 else
02596 fprintf (sched_dump, " {%s}\n", GET_RTX_NAME (GET_CODE (insn)));
02597 continue;
02598 }
02599
02600 fprintf (sched_dump,
02601 ";; %s%5d%6d%6d%6d%6d%6d ",
02602 (SCHED_GROUP_P (insn) ? "+" : " "),
02603 INSN_UID (insn),
02604 INSN_CODE (insn),
02605 INSN_BB (insn),
02606 INSN_DEP_COUNT (insn),
02607 INSN_PRIORITY (insn),
02608 insn_cost (insn, 0, 0));
02609
02610 if (recog_memoized (insn) < 0)
02611 fprintf (sched_dump, "nothing");
02612 else
02613 print_reservation (sched_dump, insn);
02614
02615 fprintf (sched_dump, "\t: ");
02616 for (link = INSN_DEPEND (insn); link; link = XEXP (link, 1))
02617 fprintf (sched_dump, "%d ", INSN_UID (XEXP (link, 0)));
02618 fprintf (sched_dump, "\n");
02619 }
02620 }
02621 fprintf (sched_dump, "\n");
02622 }
02623
02624
02625
02626 static bool
02627 sched_is_disabled_for_current_region_p (void)
02628 {
02629 int bb;
02630
02631 for (bb = 0; bb < current_nr_blocks; bb++)
02632 if (!(BASIC_BLOCK (BB_TO_BLOCK (bb))->flags & BB_DISABLE_SCHEDULE))
02633 return false;
02634
02635 return true;
02636 }
02637
02638
02639
02640
02641
02642 static void
02643 schedule_region (int rgn)
02644 {
02645 basic_block block;
02646 edge_iterator ei;
02647 edge e;
02648 int bb;
02649 int sched_rgn_n_insns = 0;
02650
02651 rgn_n_insns = 0;
02652
02653 current_nr_blocks = RGN_NR_BLOCKS (rgn);
02654 current_blocks = RGN_BLOCKS (rgn);
02655
02656
02657 ebb_head = xrealloc (ebb_head, (current_nr_blocks + 1) * sizeof (*ebb_head));
02658 for (bb = 0; bb <= current_nr_blocks; bb++)
02659 ebb_head[bb] = current_blocks + bb;
02660
02661
02662
02663 if (sched_is_disabled_for_current_region_p ())
02664 return;
02665
02666 if (!RGN_DONT_CALC_DEPS (rgn))
02667 {
02668 init_deps_global ();
02669
02670
02671 bb_deps = XNEWVEC (struct deps, current_nr_blocks);
02672 for (bb = 0; bb < current_nr_blocks; bb++)
02673 init_deps (bb_deps + bb);
02674
02675
02676 for (bb = 0; bb < current_nr_blocks; bb++)
02677 compute_block_backward_dependences (bb);
02678
02679
02680 for (bb = current_nr_blocks - 1; bb >= 0; bb--)
02681 {
02682 rtx head, tail;
02683
02684 gcc_assert (EBB_FIRST_BB (bb) == EBB_LAST_BB (bb));
02685 get_ebb_head_tail (EBB_FIRST_BB (bb), EBB_LAST_BB (bb), &head, &tail);
02686
02687 compute_forward_dependences (head, tail);
02688
02689 if (targetm.sched.dependencies_evaluation_hook)
02690 targetm.sched.dependencies_evaluation_hook (head, tail);
02691 }
02692
02693 free_pending_lists ();
02694
02695 finish_deps_global ();
02696
02697 free (bb_deps);
02698 }
02699 else
02700
02701 gcc_assert (current_nr_blocks == 1);
02702
02703
02704 current_sched_info->sched_max_insns_priority = 0;
02705 for (bb = 0; bb < current_nr_blocks; bb++)
02706 {
02707 rtx head, tail;
02708
02709 gcc_assert (EBB_FIRST_BB (bb) == EBB_LAST_BB (bb));
02710 get_ebb_head_tail (EBB_FIRST_BB (bb), EBB_LAST_BB (bb), &head, &tail);
02711
02712 rgn_n_insns += set_priorities (head, tail);
02713 }
02714 current_sched_info->sched_max_insns_priority++;
02715
02716
02717 if (current_nr_blocks > 1)
02718 {
02719 prob = XNEWVEC (int, current_nr_blocks);
02720
02721 dom = sbitmap_vector_alloc (current_nr_blocks, current_nr_blocks);
02722 sbitmap_vector_zero (dom, current_nr_blocks);
02723
02724
02725 rgn_nr_edges = 0;
02726 FOR_EACH_BB (block)
02727 {
02728 if (CONTAINING_RGN (block->index) != rgn)
02729 continue;
02730 FOR_EACH_EDGE (e, ei, block->succs)
02731 SET_EDGE_TO_BIT (e, rgn_nr_edges++);
02732 }
02733
02734 rgn_edges = XNEWVEC (edge, rgn_nr_edges);
02735 rgn_nr_edges = 0;
02736 FOR_EACH_BB (block)
02737 {
02738 if (CONTAINING_RGN (block->index) != rgn)
02739 continue;
02740 FOR_EACH_EDGE (e, ei, block->succs)
02741 rgn_edges[rgn_nr_edges++] = e;
02742 }
02743
02744
02745 pot_split = sbitmap_vector_alloc (current_nr_blocks, rgn_nr_edges);
02746 sbitmap_vector_zero (pot_split, current_nr_blocks);
02747 ancestor_edges = sbitmap_vector_alloc (current_nr_blocks, rgn_nr_edges);
02748 sbitmap_vector_zero (ancestor_edges, current_nr_blocks);
02749
02750
02751 for (bb = 0; bb < current_nr_blocks; bb++)
02752 compute_dom_prob_ps (bb);
02753
02754
02755
02756
02757 FOR_EACH_BB (block)
02758 {
02759 if (CONTAINING_RGN (block->index) != rgn)
02760 continue;
02761 FOR_EACH_EDGE (e, ei, block->succs)
02762 e->aux = NULL;
02763 }
02764 }
02765
02766
02767 for (bb = 0; bb < current_nr_blocks; bb++)
02768 {
02769 basic_block first_bb, last_bb, curr_bb;
02770 rtx head, tail;
02771 int b = BB_TO_BLOCK (bb);
02772
02773 first_bb = EBB_FIRST_BB (bb);
02774 last_bb = EBB_LAST_BB (bb);
02775
02776 get_ebb_head_tail (first_bb, last_bb, &head, &tail);
02777
02778 if (no_real_insns_p (head, tail))
02779 {
02780 gcc_assert (first_bb == last_bb);
02781 continue;
02782 }
02783
02784 current_sched_info->prev_head = PREV_INSN (head);
02785 current_sched_info->next_tail = NEXT_INSN (tail);
02786
02787 if (write_symbols != NO_DEBUG)
02788 {
02789 save_line_notes (b, head, tail);
02790 rm_line_notes (head, tail);
02791 }
02792
02793
02794
02795
02796
02797
02798
02799 if (INSN_P (head))
02800 {
02801 rtx note;
02802
02803 for (note = REG_NOTES (head); note; note = XEXP (note, 1))
02804 if (REG_NOTE_KIND (note) == REG_SAVE_NOTE)
02805 remove_note (head, note);
02806 }
02807 else
02808
02809
02810
02811 gcc_unreachable ();
02812
02813
02814
02815
02816 rm_other_notes (head, tail);
02817
02818 unlink_bb_notes (first_bb, last_bb);
02819
02820 target_bb = bb;
02821
02822 gcc_assert (flag_schedule_interblock || current_nr_blocks == 1);
02823 current_sched_info->queue_must_finish_empty = current_nr_blocks == 1;
02824
02825 curr_bb = first_bb;
02826 schedule_block (&curr_bb, rgn_n_insns);
02827 gcc_assert (EBB_FIRST_BB (bb) == first_bb);
02828 sched_rgn_n_insns += sched_n_insns;
02829
02830
02831 if (current_nr_blocks > 1)
02832 {
02833 free (candidate_table);
02834 free (bblst_table);
02835 free (edgelst_table);
02836 }
02837 }
02838
02839
02840 gcc_assert (sched_rgn_n_insns == rgn_n_insns);
02841
02842
02843 if (write_symbols != NO_DEBUG)
02844 {
02845 for (bb = 0; bb < current_nr_blocks; bb++)
02846 {
02847 rtx head, tail;
02848
02849 get_ebb_head_tail (EBB_FIRST_BB (bb), EBB_LAST_BB (bb), &head, &tail);
02850 restore_line_notes (head, tail);
02851 }
02852 }
02853
02854
02855
02856 if (current_nr_blocks > 1)
02857 {
02858 free (prob);
02859 sbitmap_vector_free (dom);
02860 sbitmap_vector_free (pot_split);
02861 sbitmap_vector_free (ancestor_edges);
02862 free (rgn_edges);
02863 }
02864 }
02865
02866
02867
02868 static int *deaths_in_region;
02869
02870
02871
02872 static void
02873 init_regions (void)
02874 {
02875 sbitmap blocks;
02876 int rgn;
02877
02878 nr_regions = 0;
02879 rgn_table = 0;
02880 rgn_bb_table = 0;
02881 block_to_bb = 0;
02882 containing_rgn = 0;
02883 extend_regions ();
02884
02885
02886 if (reload_completed
02887 || n_basic_blocks == NUM_FIXED_BLOCKS + 1
02888 || !flag_schedule_interblock
02889 || is_cfg_nonregular ())
02890 {
02891 find_single_block_region ();
02892 }
02893 else
02894 {
02895
02896 calculate_dominance_info (CDI_DOMINATORS);
02897
02898
02899 find_rgns ();
02900
02901 if (sched_verbose >= 3)
02902 debug_regions ();
02903
02904
02905
02906 free_dominance_info (CDI_DOMINATORS);
02907 }
02908 RGN_BLOCKS (nr_regions) = RGN_BLOCKS (nr_regions - 1) +
02909 RGN_NR_BLOCKS (nr_regions - 1);
02910
02911
02912 if (CHECK_DEAD_NOTES)
02913 {
02914 blocks = sbitmap_alloc (last_basic_block);
02915 deaths_in_region = XNEWVEC (int, nr_regions);
02916
02917 for (rgn = 0; rgn < nr_regions; rgn++)
02918 check_dead_notes1 (rgn, blocks);
02919
02920 sbitmap_free (blocks);
02921 }
02922 else
02923 count_or_remove_death_notes (NULL, 1);
02924 }
02925
02926
02927
02928 void
02929 schedule_insns (void)
02930 {
02931 sbitmap large_region_blocks, blocks;
02932 int rgn;
02933 int any_large_regions;
02934 basic_block bb;
02935
02936
02937
02938 if (n_basic_blocks == NUM_FIXED_BLOCKS)
02939 return;
02940
02941 nr_inter = 0;
02942 nr_spec = 0;
02943
02944
02945
02946 current_sched_info = ®ion_sched_info;
02947
02948 sched_init ();
02949
02950 min_spec_prob = ((PARAM_VALUE (PARAM_MIN_SPEC_PROB) * REG_BR_PROB_BASE)
02951 / 100);
02952
02953 init_regions ();
02954
02955
02956
02957 ebb_head = 0;
02958
02959
02960 for (rgn = 0; rgn < nr_regions; rgn++)
02961 schedule_region (rgn);
02962
02963 free(ebb_head);
02964
02965
02966
02967
02968
02969
02970
02971
02972
02973
02974
02975
02976
02977
02978 if (current_sched_info->flags & DETACH_LIFE_INFO)
02979
02980 attach_life_info ();
02981
02982 allocate_reg_life_data ();
02983
02984 any_large_regions = 0;
02985 large_region_blocks = sbitmap_alloc (last_basic_block);
02986 sbitmap_zero (large_region_blocks);
02987 FOR_EACH_BB (bb)
02988 SET_BIT (large_region_blocks, bb->index);
02989
02990 blocks = sbitmap_alloc (last_basic_block);
02991 sbitmap_zero (blocks);
02992
02993
02994
02995
02996
02997 for (rgn = 0; rgn < nr_regions; rgn++)
02998 if (RGN_NR_BLOCKS (rgn) > 1
02999
03000 || RGN_HAS_REAL_EBB (rgn)
03001
03002
03003 || !glat_start[rgn_bb_table[RGN_BLOCKS (rgn)]])
03004 any_large_regions = 1;
03005 else
03006 {
03007 SET_BIT (blocks, rgn_bb_table[RGN_BLOCKS (rgn)]);
03008 RESET_BIT (large_region_blocks, rgn_bb_table[RGN_BLOCKS (rgn)]);
03009 }
03010
03011
03012
03013 update_life_info (blocks, UPDATE_LIFE_LOCAL,
03014 (reload_completed ? PROP_DEATH_NOTES
03015 : (PROP_DEATH_NOTES | PROP_REG_INFO)));
03016 if (any_large_regions)
03017 {
03018 update_life_info (large_region_blocks, UPDATE_LIFE_GLOBAL,
03019 (reload_completed ? PROP_DEATH_NOTES
03020 : (PROP_DEATH_NOTES | PROP_REG_INFO)));
03021
03022 #ifdef ENABLE_CHECKING
03023 check_reg_live (true);
03024 #endif
03025 }
03026
03027 if (CHECK_DEAD_NOTES)
03028 {
03029
03030
03031 for (rgn = 0; rgn < nr_regions; rgn++)
03032 if (RGN_NR_BLOCKS (rgn) == 1)
03033 {
03034 sbitmap_zero (blocks);
03035 SET_BIT (blocks, rgn_bb_table[RGN_BLOCKS (rgn)]);
03036
03037 gcc_assert (deaths_in_region[rgn]
03038 == count_or_remove_death_notes (blocks, 0));
03039 }
03040 free (deaths_in_region);
03041 }
03042
03043
03044
03045 if (reload_completed)
03046 reposition_prologue_and_epilogue_notes (get_insns ());
03047
03048
03049 if (write_symbols != NO_DEBUG)
03050 rm_redundant_line_notes ();
03051
03052 if (sched_verbose)
03053 {
03054 if (reload_completed == 0 && flag_schedule_interblock)
03055 {
03056 fprintf (sched_dump,
03057 "\n;; Procedure interblock/speculative motions == %d/%d \n",
03058 nr_inter, nr_spec);
03059 }
03060 else
03061 gcc_assert (nr_inter <= 0);
03062 fprintf (sched_dump, "\n\n");
03063 }
03064
03065
03066 free (rgn_table);
03067 free (rgn_bb_table);
03068 free (block_to_bb);
03069 free (containing_rgn);
03070
03071 sched_finish ();
03072
03073 sbitmap_free (blocks);
03074 sbitmap_free (large_region_blocks);
03075 }
03076
03077
03078 static void
03079 add_remove_insn (rtx insn, int remove_p)
03080 {
03081 if (!remove_p)
03082 rgn_n_insns++;
03083 else
03084 rgn_n_insns--;
03085
03086 if (INSN_BB (insn) == target_bb)
03087 {
03088 if (!remove_p)
03089 target_n_insns++;
03090 else
03091 target_n_insns--;
03092 }
03093 }
03094
03095
03096 static void
03097 extend_regions (void)
03098 {
03099 rgn_table = XRESIZEVEC (region, rgn_table, n_basic_blocks);
03100 rgn_bb_table = XRESIZEVEC (int, rgn_bb_table, n_basic_blocks);
03101 block_to_bb = XRESIZEVEC (int, block_to_bb, last_basic_block);
03102 containing_rgn = XRESIZEVEC (int, containing_rgn, last_basic_block);
03103 }
03104
03105
03106 static void
03107 add_block1 (basic_block bb, basic_block after)
03108 {
03109 extend_regions ();
03110
03111 if (after == 0 || after == EXIT_BLOCK_PTR)
03112 {
03113 int i;
03114
03115 i = RGN_BLOCKS (nr_regions);
03116
03117
03118 rgn_bb_table[i] = bb->index;
03119 RGN_NR_BLOCKS (nr_regions) = 1;
03120 RGN_DONT_CALC_DEPS (nr_regions) = after == EXIT_BLOCK_PTR;
03121 RGN_HAS_REAL_EBB (nr_regions) = 0;
03122 CONTAINING_RGN (bb->index) = nr_regions;
03123 BLOCK_TO_BB (bb->index) = 0;
03124
03125 nr_regions++;
03126
03127 RGN_BLOCKS (nr_regions) = i + 1;
03128
03129 if (CHECK_DEAD_NOTES)
03130 {
03131 sbitmap blocks = sbitmap_alloc (last_basic_block);
03132 deaths_in_region = xrealloc (deaths_in_region, nr_regions *
03133 sizeof (*deaths_in_region));
03134
03135 check_dead_notes1 (nr_regions - 1, blocks);
03136
03137 sbitmap_free (blocks);
03138 }
03139 }
03140 else
03141 {
03142 int i, pos;
03143
03144
03145
03146
03147 BLOCK_TO_BB (bb->index) = BLOCK_TO_BB (after->index);
03148
03149
03150
03151
03152
03153
03154 i = BLOCK_TO_BB (after->index) + 1;
03155 pos = ebb_head[i] - 1;
03156
03157
03158
03159 for (; rgn_bb_table[pos] != after->index; pos--);
03160
03161 pos++;
03162 gcc_assert (pos > ebb_head[i - 1]);
03163
03164
03165
03166
03167
03168
03169
03170
03171
03172
03173
03174 memmove (rgn_bb_table + pos + 1,
03175 rgn_bb_table + pos,
03176 ((RGN_BLOCKS (nr_regions) - 1) - (pos) + 1)
03177 * sizeof (*rgn_bb_table));
03178
03179 rgn_bb_table[pos] = bb->index;
03180
03181 for (; i <= current_nr_blocks; i++)
03182 ebb_head [i]++;
03183
03184 i = CONTAINING_RGN (after->index);
03185 CONTAINING_RGN (bb->index) = i;
03186
03187 RGN_HAS_REAL_EBB (i) = 1;
03188
03189 for (++i; i <= nr_regions; i++)
03190 RGN_BLOCKS (i)++;
03191
03192
03193
03194 }
03195 }
03196
03197
03198
03199
03200 static void
03201 fix_recovery_cfg (int bbi, int check_bbi, int check_bb_nexti)
03202 {
03203 int old_pos, new_pos, i;
03204
03205 BLOCK_TO_BB (check_bb_nexti) = BLOCK_TO_BB (bbi);
03206
03207 for (old_pos = ebb_head[BLOCK_TO_BB (check_bbi) + 1] - 1;
03208 rgn_bb_table[old_pos] != check_bb_nexti;
03209 old_pos--);
03210 gcc_assert (old_pos > ebb_head[BLOCK_TO_BB (check_bbi)]);
03211
03212 for (new_pos = ebb_head[BLOCK_TO_BB (bbi) + 1] - 1;
03213 rgn_bb_table[new_pos] != bbi;
03214 new_pos--);
03215 new_pos++;
03216 gcc_assert (new_pos > ebb_head[BLOCK_TO_BB (bbi)]);
03217
03218 gcc_assert (new_pos < old_pos);
03219
03220 memmove (rgn_bb_table + new_pos + 1,
03221 rgn_bb_table + new_pos,
03222 (old_pos - new_pos) * sizeof (*rgn_bb_table));
03223
03224 rgn_bb_table[new_pos] = check_bb_nexti;
03225
03226 for (i = BLOCK_TO_BB (bbi) + 1; i <= BLOCK_TO_BB (check_bbi); i++)
03227 ebb_head[i]++;
03228 }
03229
03230
03231
03232 static basic_block
03233 advance_target_bb (basic_block bb, rtx insn)
03234 {
03235 if (insn)
03236 return 0;
03237
03238 gcc_assert (BLOCK_TO_BB (bb->index) == target_bb
03239 && BLOCK_TO_BB (bb->next_bb->index) == target_bb);
03240 return bb->next_bb;
03241 }
03242
03243
03244
03245 static void
03246 check_dead_notes1 (int rgn, sbitmap blocks)
03247 {
03248 int b;
03249
03250 sbitmap_zero (blocks);
03251 for (b = RGN_NR_BLOCKS (rgn) - 1; b >= 0; --b)
03252 SET_BIT (blocks, rgn_bb_table[RGN_BLOCKS (rgn) + b]);
03253
03254 deaths_in_region[rgn] = count_or_remove_death_notes (blocks, 1);
03255 }
03256
03257 #ifdef ENABLE_CHECKING
03258
03259
03260
03261 static int
03262 region_head_or_leaf_p (basic_block bb, int leaf_p)
03263 {
03264 if (!leaf_p)
03265 return bb->index == rgn_bb_table[RGN_BLOCKS (CONTAINING_RGN (bb->index))];
03266 else
03267 {
03268 int i;
03269 edge e;
03270 edge_iterator ei;
03271
03272 i = CONTAINING_RGN (bb->index);
03273
03274 FOR_EACH_EDGE (e, ei, bb->succs)
03275 if (e->dest != EXIT_BLOCK_PTR
03276 && CONTAINING_RGN (e->dest->index) == i
03277
03278 && e->dest != bb)
03279 return 0;
03280
03281 return 1;
03282 }
03283 }
03284 #endif
03285
03286 #endif
03287
03288 static bool
03289 gate_handle_sched (void)
03290 {
03291 #ifdef INSN_SCHEDULING
03292 return flag_schedule_insns;
03293 #else
03294 return 0;
03295 #endif
03296 }
03297
03298
03299 static unsigned int
03300 rest_of_handle_sched (void)
03301 {
03302 #ifdef INSN_SCHEDULING
03303
03304
03305
03306 schedule_insns ();
03307 #endif
03308 return 0;
03309 }
03310
03311 static bool
03312 gate_handle_sched2 (void)
03313 {
03314 #ifdef INSN_SCHEDULING
03315 return optimize > 0 && flag_schedule_insns_after_reload;
03316 #else
03317 return 0;
03318 #endif
03319 }
03320
03321
03322 static unsigned int
03323 rest_of_handle_sched2 (void)
03324 {
03325 #ifdef INSN_SCHEDULING
03326
03327
03328
03329 split_all_insns (1);
03330
03331 if (flag_sched2_use_superblocks || flag_sched2_use_traces)
03332 {
03333 schedule_ebbs ();
03334
03335
03336 count_or_remove_death_notes (NULL, 1);
03337 cleanup_cfg (CLEANUP_EXPENSIVE);
03338 }
03339 else
03340 schedule_insns ();
03341 #endif
03342 return 0;
03343 }
03344
03345 struct tree_opt_pass pass_sched =
03346 {
03347 "sched1",
03348 gate_handle_sched,
03349 rest_of_handle_sched,
03350 NULL,
03351 NULL,
03352 0,
03353 TV_SCHED,
03354 0,
03355 0,
03356 0,
03357 0,
03358 TODO_dump_func |
03359 TODO_ggc_collect,
03360 'S'
03361 };
03362
03363 struct tree_opt_pass pass_sched2 =
03364 {
03365 "sched2",
03366 gate_handle_sched2,
03367 rest_of_handle_sched2,
03368 NULL,
03369 NULL,
03370 0,
03371 TV_SCHED2,
03372 0,
03373 0,
03374 0,
03375 0,
03376 TODO_dump_func |
03377 TODO_ggc_collect,
03378 'R'
03379 };
03380