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 #include "config.h"
00026 #include "system.h"
00027 #include "toplev.h"
00028 #include "rtl.h"
00029 #include "tm_p.h"
00030 #include "hard-reg-set.h"
00031 #include "basic-block.h"
00032 #include "regs.h"
00033 #include "function.h"
00034 #include "flags.h"
00035 #include "insn-config.h"
00036 #include "insn-attr.h"
00037 #include "except.h"
00038 #include "toplev.h"
00039 #include "recog.h"
00040 #include "sched-int.h"
00041 #include "params.h"
00042 #include "cselib.h"
00043
00044 extern char *reg_known_equiv_p;
00045 extern rtx *reg_known_value;
00046
00047 static regset_head reg_pending_sets_head;
00048 static regset_head reg_pending_clobbers_head;
00049 static regset_head reg_pending_uses_head;
00050
00051 static regset reg_pending_sets;
00052 static regset reg_pending_clobbers;
00053 static regset reg_pending_uses;
00054 static bool reg_pending_barrier;
00055
00056
00057
00058
00059
00060
00061
00062
00063
00064
00065
00066
00067
00068
00069 static sbitmap *true_dependency_cache;
00070 static sbitmap *anti_dependency_cache;
00071 static sbitmap *output_dependency_cache;
00072
00073
00074
00075
00076
00077 #ifdef ENABLE_CHECKING
00078 static sbitmap *forward_dependency_cache;
00079 #endif
00080
00081 static int deps_may_trap_p PARAMS ((rtx));
00082 static void add_dependence_list PARAMS ((rtx, rtx, enum reg_note));
00083 static void add_dependence_list_and_free PARAMS ((rtx, rtx *, enum reg_note));
00084 static void remove_dependence PARAMS ((rtx, rtx));
00085 static void set_sched_group_p PARAMS ((rtx));
00086
00087 static void flush_pending_lists PARAMS ((struct deps *, rtx, int, int));
00088 static void sched_analyze_1 PARAMS ((struct deps *, rtx, rtx));
00089 static void sched_analyze_2 PARAMS ((struct deps *, rtx, rtx));
00090 static void sched_analyze_insn PARAMS ((struct deps *, rtx, rtx, rtx));
00091 static rtx group_leader PARAMS ((rtx));
00092
00093 static rtx get_condition PARAMS ((rtx));
00094 static int conditions_mutex_p PARAMS ((rtx, rtx));
00095
00096
00097
00098 static int
00099 deps_may_trap_p (mem)
00100 rtx mem;
00101 {
00102 rtx addr = XEXP (mem, 0);
00103
00104 if (REG_P (addr)
00105 && REGNO (addr) >= FIRST_PSEUDO_REGISTER
00106 && reg_known_value[REGNO (addr)])
00107 addr = reg_known_value[REGNO (addr)];
00108 return rtx_addr_can_trap_p (addr);
00109 }
00110
00111
00112
00113
00114 rtx
00115 find_insn_list (insn, list)
00116 rtx insn;
00117 rtx list;
00118 {
00119 while (list)
00120 {
00121 if (XEXP (list, 0) == insn)
00122 return list;
00123 list = XEXP (list, 1);
00124 }
00125 return 0;
00126 }
00127
00128
00129
00130 static rtx
00131 get_condition (insn)
00132 rtx insn;
00133 {
00134 rtx pat = PATTERN (insn);
00135 rtx cond;
00136
00137 if (pat == 0)
00138 return 0;
00139 if (GET_CODE (pat) == COND_EXEC)
00140 return COND_EXEC_TEST (pat);
00141 if (GET_CODE (insn) != JUMP_INSN)
00142 return 0;
00143 if (GET_CODE (pat) != SET || SET_SRC (pat) != pc_rtx)
00144 return 0;
00145 if (GET_CODE (SET_DEST (pat)) != IF_THEN_ELSE)
00146 return 0;
00147 pat = SET_DEST (pat);
00148 cond = XEXP (pat, 0);
00149 if (GET_CODE (XEXP (cond, 1)) == LABEL_REF
00150 && XEXP (cond, 2) == pc_rtx)
00151 return cond;
00152 else if (GET_CODE (XEXP (cond, 2)) == LABEL_REF
00153 && XEXP (cond, 1) == pc_rtx)
00154 return gen_rtx_fmt_ee (reverse_condition (GET_CODE (cond)), GET_MODE (cond),
00155 XEXP (cond, 0), XEXP (cond, 1));
00156 else
00157 return 0;
00158 }
00159
00160
00161
00162 static int
00163 conditions_mutex_p (cond1, cond2)
00164 rtx cond1, cond2;
00165 {
00166 if (GET_RTX_CLASS (GET_CODE (cond1)) == '<'
00167 && GET_RTX_CLASS (GET_CODE (cond2)) == '<'
00168 && GET_CODE (cond1) == reverse_condition (GET_CODE (cond2))
00169 && XEXP (cond1, 0) == XEXP (cond2, 0)
00170 && XEXP (cond1, 1) == XEXP (cond2, 1))
00171 return 1;
00172 return 0;
00173 }
00174
00175
00176
00177
00178
00179
00180 int
00181 add_dependence (insn, elem, dep_type)
00182 rtx insn;
00183 rtx elem;
00184 enum reg_note dep_type;
00185 {
00186 rtx link, next;
00187 int present_p;
00188 rtx cond1, cond2;
00189
00190
00191 if (insn == elem)
00192 return 0;
00193
00194
00195
00196
00197 if (GET_CODE (elem) == NOTE)
00198 return 0;
00199
00200
00201
00202
00203
00204
00205 if (GET_CODE (insn) != CALL_INSN && GET_CODE (elem) != CALL_INSN)
00206 {
00207 cond1 = get_condition (insn);
00208 cond2 = get_condition (elem);
00209 if (cond1 && cond2
00210 && conditions_mutex_p (cond1, cond2)
00211
00212
00213 && !modified_in_p (cond1, elem)
00214
00215
00216 && !modified_in_p (cond2, insn))
00217 return 0;
00218 }
00219
00220
00221
00222
00223
00224
00225 next = next_nonnote_insn (elem);
00226 if (next && INSN_P (next) && SCHED_GROUP_P (next))
00227 {
00228
00229
00230
00231
00232
00233
00234
00235
00236 rtx nnext;
00237 while ((nnext = next_nonnote_insn (next)) != NULL
00238 && INSN_P (nnext)
00239 && SCHED_GROUP_P (nnext))
00240 next = nnext;
00241
00242
00243 if (insn == next)
00244 return 0;
00245
00246
00247
00248 elem = next;
00249 }
00250
00251 present_p = 1;
00252 #ifdef INSN_SCHEDULING
00253
00254
00255 #if 0
00256
00257
00258
00259
00260 if (GET_CODE (insn) == CALL_INSN
00261 && (INSN_BB (elem) != INSN_BB (insn)))
00262 return 0;
00263 #endif
00264
00265
00266
00267
00268 if (true_dependency_cache != NULL)
00269 {
00270 enum reg_note present_dep_type = 0;
00271
00272 if (anti_dependency_cache == NULL || output_dependency_cache == NULL)
00273 abort ();
00274 if (TEST_BIT (true_dependency_cache[INSN_LUID (insn)], INSN_LUID (elem)))
00275
00276 ;
00277 else if (TEST_BIT (anti_dependency_cache[INSN_LUID (insn)],
00278 INSN_LUID (elem)))
00279 present_dep_type = REG_DEP_ANTI;
00280 else if (TEST_BIT (output_dependency_cache[INSN_LUID (insn)],
00281 INSN_LUID (elem)))
00282 present_dep_type = REG_DEP_OUTPUT;
00283 else
00284 present_p = 0;
00285 if (present_p && (int) dep_type >= (int) present_dep_type)
00286 return 0;
00287 }
00288 #endif
00289
00290
00291 if (present_p)
00292 for (link = LOG_LINKS (insn); link; link = XEXP (link, 1))
00293 if (XEXP (link, 0) == elem)
00294 {
00295 #ifdef INSN_SCHEDULING
00296
00297
00298 if (true_dependency_cache != NULL)
00299 {
00300 if (REG_NOTE_KIND (link) == REG_DEP_ANTI)
00301 RESET_BIT (anti_dependency_cache[INSN_LUID (insn)],
00302 INSN_LUID (elem));
00303 else if (REG_NOTE_KIND (link) == REG_DEP_OUTPUT
00304 && output_dependency_cache)
00305 RESET_BIT (output_dependency_cache[INSN_LUID (insn)],
00306 INSN_LUID (elem));
00307 else
00308 abort ();
00309 }
00310 #endif
00311
00312
00313
00314 if ((int) dep_type < (int) REG_NOTE_KIND (link))
00315 PUT_REG_NOTE_KIND (link, dep_type);
00316
00317 #ifdef INSN_SCHEDULING
00318
00319
00320 if (true_dependency_cache != NULL)
00321 {
00322 if ((int) REG_NOTE_KIND (link) == 0)
00323 SET_BIT (true_dependency_cache[INSN_LUID (insn)],
00324 INSN_LUID (elem));
00325 else if (REG_NOTE_KIND (link) == REG_DEP_ANTI)
00326 SET_BIT (anti_dependency_cache[INSN_LUID (insn)],
00327 INSN_LUID (elem));
00328 else if (REG_NOTE_KIND (link) == REG_DEP_OUTPUT)
00329 SET_BIT (output_dependency_cache[INSN_LUID (insn)],
00330 INSN_LUID (elem));
00331 }
00332 #endif
00333 return 0;
00334 }
00335
00336
00337 link = alloc_INSN_LIST (elem, LOG_LINKS (insn));
00338 LOG_LINKS (insn) = link;
00339
00340
00341 PUT_REG_NOTE_KIND (link, dep_type);
00342
00343 #ifdef INSN_SCHEDULING
00344
00345
00346 if (true_dependency_cache != NULL)
00347 {
00348 if ((int) dep_type == 0)
00349 SET_BIT (true_dependency_cache[INSN_LUID (insn)], INSN_LUID (elem));
00350 else if (dep_type == REG_DEP_ANTI)
00351 SET_BIT (anti_dependency_cache[INSN_LUID (insn)], INSN_LUID (elem));
00352 else if (dep_type == REG_DEP_OUTPUT)
00353 SET_BIT (output_dependency_cache[INSN_LUID (insn)], INSN_LUID (elem));
00354 }
00355 #endif
00356 return 1;
00357 }
00358
00359
00360
00361 static void
00362 add_dependence_list (insn, list, dep_type)
00363 rtx insn, list;
00364 enum reg_note dep_type;
00365 {
00366 for (; list; list = XEXP (list, 1))
00367 add_dependence (insn, XEXP (list, 0), dep_type);
00368 }
00369
00370
00371
00372 static void
00373 add_dependence_list_and_free (insn, listp, dep_type)
00374 rtx insn;
00375 rtx *listp;
00376 enum reg_note dep_type;
00377 {
00378 rtx list, next;
00379 for (list = *listp, *listp = NULL; list ; list = next)
00380 {
00381 next = XEXP (list, 1);
00382 add_dependence (insn, XEXP (list, 0), dep_type);
00383 free_INSN_LIST_node (list);
00384 }
00385 }
00386
00387
00388
00389
00390 static void
00391 remove_dependence (insn, elem)
00392 rtx insn;
00393 rtx elem;
00394 {
00395 rtx prev, link, next;
00396 int found = 0;
00397
00398 for (prev = 0, link = LOG_LINKS (insn); link; link = next)
00399 {
00400 next = XEXP (link, 1);
00401 if (XEXP (link, 0) == elem)
00402 {
00403 if (prev)
00404 XEXP (prev, 1) = next;
00405 else
00406 LOG_LINKS (insn) = next;
00407
00408 #ifdef INSN_SCHEDULING
00409
00410
00411 if (true_dependency_cache != NULL)
00412 {
00413 if (REG_NOTE_KIND (link) == 0)
00414 RESET_BIT (true_dependency_cache[INSN_LUID (insn)],
00415 INSN_LUID (elem));
00416 else if (REG_NOTE_KIND (link) == REG_DEP_ANTI)
00417 RESET_BIT (anti_dependency_cache[INSN_LUID (insn)],
00418 INSN_LUID (elem));
00419 else if (REG_NOTE_KIND (link) == REG_DEP_OUTPUT)
00420 RESET_BIT (output_dependency_cache[INSN_LUID (insn)],
00421 INSN_LUID (elem));
00422 }
00423 #endif
00424
00425 free_INSN_LIST_node (link);
00426
00427 found = 1;
00428 }
00429 else
00430 prev = link;
00431 }
00432
00433 if (!found)
00434 abort ();
00435 return;
00436 }
00437
00438
00439
00440
00441 static rtx
00442 group_leader (insn)
00443 rtx insn;
00444 {
00445 rtx prev;
00446
00447 do
00448 {
00449 prev = insn;
00450 insn = next_nonnote_insn (insn);
00451 }
00452 while (insn && INSN_P (insn) && SCHED_GROUP_P (insn));
00453
00454 return prev;
00455 }
00456
00457
00458
00459
00460 static void
00461 set_sched_group_p (insn)
00462 rtx insn;
00463 {
00464 rtx link, prev;
00465
00466 SCHED_GROUP_P (insn) = 1;
00467
00468
00469
00470
00471 prev = prev_nonnote_insn (insn);
00472
00473
00474
00475
00476
00477
00478 if (find_insn_list (prev, LOG_LINKS (insn)))
00479 remove_dependence (insn, prev);
00480
00481 for (link = LOG_LINKS (prev); link; link = XEXP (link, 1))
00482 add_dependence (insn, XEXP (link, 0), REG_NOTE_KIND (link));
00483 }
00484
00485
00486
00487
00488
00489
00490
00491
00492
00493
00494
00495
00496
00497
00498
00499
00500 void
00501 add_insn_mem_dependence (deps, insn_list, mem_list, insn, mem)
00502 struct deps *deps;
00503 rtx *insn_list, *mem_list, insn, mem;
00504 {
00505 rtx link;
00506
00507 link = alloc_INSN_LIST (insn, *insn_list);
00508 *insn_list = link;
00509
00510 if (current_sched_info->use_cselib)
00511 {
00512 mem = shallow_copy_rtx (mem);
00513 XEXP (mem, 0) = cselib_subst_to_values (XEXP (mem, 0));
00514 }
00515 link = alloc_EXPR_LIST (VOIDmode, mem, *mem_list);
00516 *mem_list = link;
00517
00518 deps->pending_lists_length++;
00519 }
00520
00521
00522
00523
00524
00525 static void
00526 flush_pending_lists (deps, insn, for_read, for_write)
00527 struct deps *deps;
00528 rtx insn;
00529 int for_read, for_write;
00530 {
00531 if (for_write)
00532 {
00533 add_dependence_list_and_free (insn, &deps->pending_read_insns,
00534 REG_DEP_ANTI);
00535 free_EXPR_LIST_list (&deps->pending_read_mems);
00536 }
00537
00538 add_dependence_list_and_free (insn, &deps->pending_write_insns,
00539 for_read ? REG_DEP_ANTI : REG_DEP_OUTPUT);
00540 free_EXPR_LIST_list (&deps->pending_write_mems);
00541 deps->pending_lists_length = 0;
00542
00543 add_dependence_list_and_free (insn, &deps->last_pending_memory_flush,
00544 for_read ? REG_DEP_ANTI : REG_DEP_OUTPUT);
00545 deps->last_pending_memory_flush = alloc_INSN_LIST (insn, NULL_RTX);
00546 deps->pending_flush_length = 1;
00547 }
00548
00549
00550
00551
00552
00553 static void
00554 sched_analyze_1 (deps, x, insn)
00555 struct deps *deps;
00556 rtx x;
00557 rtx insn;
00558 {
00559 int regno;
00560 rtx dest = XEXP (x, 0);
00561 enum rtx_code code = GET_CODE (x);
00562
00563 if (dest == 0)
00564 return;
00565
00566 if (GET_CODE (dest) == PARALLEL)
00567 {
00568 int i;
00569
00570 for (i = XVECLEN (dest, 0) - 1; i >= 0; i--)
00571 if (XEXP (XVECEXP (dest, 0, i), 0) != 0)
00572 sched_analyze_1 (deps,
00573 gen_rtx_CLOBBER (VOIDmode,
00574 XEXP (XVECEXP (dest, 0, i), 0)),
00575 insn);
00576
00577 if (GET_CODE (x) == SET)
00578 sched_analyze_2 (deps, SET_SRC (x), insn);
00579 return;
00580 }
00581
00582 while (GET_CODE (dest) == STRICT_LOW_PART || GET_CODE (dest) == SUBREG
00583 || GET_CODE (dest) == ZERO_EXTRACT || GET_CODE (dest) == SIGN_EXTRACT)
00584 {
00585 if (GET_CODE (dest) == ZERO_EXTRACT || GET_CODE (dest) == SIGN_EXTRACT)
00586 {
00587
00588 sched_analyze_2 (deps, XEXP (dest, 1), insn);
00589 sched_analyze_2 (deps, XEXP (dest, 2), insn);
00590 }
00591 dest = XEXP (dest, 0);
00592 }
00593
00594 if (GET_CODE (dest) == REG)
00595 {
00596 regno = REGNO (dest);
00597
00598
00599
00600 if (regno < FIRST_PSEUDO_REGISTER)
00601 {
00602 int i = HARD_REGNO_NREGS (regno, GET_MODE (dest));
00603 if (code == SET)
00604 {
00605 while (--i >= 0)
00606 SET_REGNO_REG_SET (reg_pending_sets, regno + i);
00607 }
00608 else
00609 {
00610 while (--i >= 0)
00611 SET_REGNO_REG_SET (reg_pending_clobbers, regno + i);
00612 }
00613 }
00614
00615
00616
00617 else if (regno >= deps->max_reg)
00618 {
00619 if (GET_CODE (PATTERN (insn)) != USE
00620 && GET_CODE (PATTERN (insn)) != CLOBBER)
00621 abort ();
00622 }
00623 else
00624 {
00625 if (code == SET)
00626 SET_REGNO_REG_SET (reg_pending_sets, regno);
00627 else
00628 SET_REGNO_REG_SET (reg_pending_clobbers, regno);
00629
00630
00631
00632
00633 if (!reload_completed
00634 && reg_known_equiv_p[regno]
00635 && GET_CODE (reg_known_value[regno]) == MEM)
00636 sched_analyze_2 (deps, XEXP (reg_known_value[regno], 0), insn);
00637
00638
00639
00640 if (REG_N_CALLS_CROSSED (regno) == 0)
00641 add_dependence_list (insn, deps->last_function_call, REG_DEP_ANTI);
00642 }
00643 }
00644 else if (GET_CODE (dest) == MEM)
00645 {
00646
00647 rtx t = dest;
00648
00649 if (current_sched_info->use_cselib)
00650 {
00651 t = shallow_copy_rtx (dest);
00652 cselib_lookup (XEXP (t, 0), Pmode, 1);
00653 XEXP (t, 0) = cselib_subst_to_values (XEXP (t, 0));
00654 }
00655
00656 if (deps->pending_lists_length > MAX_PENDING_LIST_LENGTH)
00657 {
00658
00659
00660
00661
00662
00663 flush_pending_lists (deps, insn, false, true);
00664 }
00665 else
00666 {
00667 rtx pending, pending_mem;
00668
00669 pending = deps->pending_read_insns;
00670 pending_mem = deps->pending_read_mems;
00671 while (pending)
00672 {
00673 if (anti_dependence (XEXP (pending_mem, 0), t))
00674 add_dependence (insn, XEXP (pending, 0), REG_DEP_ANTI);
00675
00676 pending = XEXP (pending, 1);
00677 pending_mem = XEXP (pending_mem, 1);
00678 }
00679
00680 pending = deps->pending_write_insns;
00681 pending_mem = deps->pending_write_mems;
00682 while (pending)
00683 {
00684 if (output_dependence (XEXP (pending_mem, 0), t))
00685 add_dependence (insn, XEXP (pending, 0), REG_DEP_OUTPUT);
00686
00687 pending = XEXP (pending, 1);
00688 pending_mem = XEXP (pending_mem, 1);
00689 }
00690
00691 add_dependence_list (insn, deps->last_pending_memory_flush,
00692 REG_DEP_ANTI);
00693
00694 add_insn_mem_dependence (deps, &deps->pending_write_insns,
00695 &deps->pending_write_mems, insn, dest);
00696 }
00697 sched_analyze_2 (deps, XEXP (dest, 0), insn);
00698 }
00699
00700
00701 if (GET_CODE (x) == SET)
00702 sched_analyze_2 (deps, SET_SRC (x), insn);
00703 }
00704
00705
00706
00707 static void
00708 sched_analyze_2 (deps, x, insn)
00709 struct deps *deps;
00710 rtx x;
00711 rtx insn;
00712 {
00713 int i;
00714 int j;
00715 enum rtx_code code;
00716 const char *fmt;
00717
00718 if (x == 0)
00719 return;
00720
00721 code = GET_CODE (x);
00722
00723 switch (code)
00724 {
00725 case CONST_INT:
00726 case CONST_DOUBLE:
00727 case CONST_VECTOR:
00728 case SYMBOL_REF:
00729 case CONST:
00730 case LABEL_REF:
00731
00732
00733
00734 return;
00735
00736 #ifdef HAVE_cc0
00737 case CC0:
00738
00739 set_sched_group_p (insn);
00740 return;
00741 #endif
00742
00743 case REG:
00744 {
00745 int regno = REGNO (x);
00746 if (regno < FIRST_PSEUDO_REGISTER)
00747 {
00748 int i = HARD_REGNO_NREGS (regno, GET_MODE (x));
00749 while (--i >= 0)
00750 SET_REGNO_REG_SET (reg_pending_uses, regno + i);
00751 }
00752
00753
00754
00755 else if (regno >= deps->max_reg)
00756 {
00757 if (GET_CODE (PATTERN (insn)) != USE
00758 && GET_CODE (PATTERN (insn)) != CLOBBER)
00759 abort ();
00760 }
00761 else
00762 {
00763 SET_REGNO_REG_SET (reg_pending_uses, regno);
00764
00765
00766
00767
00768 if (!reload_completed
00769 && reg_known_equiv_p[regno]
00770 && GET_CODE (reg_known_value[regno]) == MEM)
00771 sched_analyze_2 (deps, XEXP (reg_known_value[regno], 0), insn);
00772
00773
00774
00775
00776 if (REG_N_CALLS_CROSSED (regno) == 0)
00777 deps->sched_before_next_call
00778 = alloc_INSN_LIST (insn, deps->sched_before_next_call);
00779 }
00780 return;
00781 }
00782
00783 case MEM:
00784 {
00785
00786 rtx u;
00787 rtx pending, pending_mem;
00788 rtx t = x;
00789
00790 if (current_sched_info->use_cselib)
00791 {
00792 t = shallow_copy_rtx (t);
00793 cselib_lookup (XEXP (t, 0), Pmode, 1);
00794 XEXP (t, 0) = cselib_subst_to_values (XEXP (t, 0));
00795 }
00796 pending = deps->pending_read_insns;
00797 pending_mem = deps->pending_read_mems;
00798 while (pending)
00799 {
00800 if (read_dependence (XEXP (pending_mem, 0), t))
00801 add_dependence (insn, XEXP (pending, 0), REG_DEP_ANTI);
00802
00803 pending = XEXP (pending, 1);
00804 pending_mem = XEXP (pending_mem, 1);
00805 }
00806
00807 pending = deps->pending_write_insns;
00808 pending_mem = deps->pending_write_mems;
00809 while (pending)
00810 {
00811 if (true_dependence (XEXP (pending_mem, 0), VOIDmode,
00812 t, rtx_varies_p))
00813 add_dependence (insn, XEXP (pending, 0), 0);
00814
00815 pending = XEXP (pending, 1);
00816 pending_mem = XEXP (pending_mem, 1);
00817 }
00818
00819 for (u = deps->last_pending_memory_flush; u; u = XEXP (u, 1))
00820 if (GET_CODE (XEXP (u, 0)) != JUMP_INSN
00821 || deps_may_trap_p (x))
00822 add_dependence (insn, XEXP (u, 0), REG_DEP_ANTI);
00823
00824
00825
00826 add_insn_mem_dependence (deps, &deps->pending_read_insns,
00827 &deps->pending_read_mems, insn, x);
00828
00829
00830 sched_analyze_2 (deps, XEXP (x, 0), insn);
00831 return;
00832 }
00833
00834
00835 case TRAP_IF:
00836 flush_pending_lists (deps, insn, true, false);
00837 break;
00838
00839 case ASM_OPERANDS:
00840 case ASM_INPUT:
00841 case UNSPEC_VOLATILE:
00842 {
00843
00844
00845
00846
00847
00848
00849
00850 if (code != ASM_OPERANDS || MEM_VOLATILE_P (x))
00851 reg_pending_barrier = true;
00852
00853
00854
00855
00856
00857
00858 if (code == ASM_OPERANDS)
00859 {
00860 for (j = 0; j < ASM_OPERANDS_INPUT_LENGTH (x); j++)
00861 sched_analyze_2 (deps, ASM_OPERANDS_INPUT (x, j), insn);
00862 return;
00863 }
00864 break;
00865 }
00866
00867 case PRE_DEC:
00868 case POST_DEC:
00869 case PRE_INC:
00870 case POST_INC:
00871
00872
00873
00874
00875
00876
00877 sched_analyze_2 (deps, XEXP (x, 0), insn);
00878 sched_analyze_1 (deps, x, insn);
00879 return;
00880
00881 case POST_MODIFY:
00882 case PRE_MODIFY:
00883
00884 sched_analyze_2 (deps, XEXP (x, 0), insn);
00885 sched_analyze_2 (deps, XEXP (x, 1), insn);
00886 sched_analyze_1 (deps, x, insn);
00887 return;
00888
00889 default:
00890 break;
00891 }
00892
00893
00894 fmt = GET_RTX_FORMAT (code);
00895 for (i = GET_RTX_LENGTH (code) - 1; i >= 0; i--)
00896 {
00897 if (fmt[i] == 'e')
00898 sched_analyze_2 (deps, XEXP (x, i), insn);
00899 else if (fmt[i] == 'E')
00900 for (j = 0; j < XVECLEN (x, i); j++)
00901 sched_analyze_2 (deps, XVECEXP (x, i, j), insn);
00902 }
00903 }
00904
00905
00906
00907 static void
00908 sched_analyze_insn (deps, x, insn, loop_notes)
00909 struct deps *deps;
00910 rtx x, insn;
00911 rtx loop_notes;
00912 {
00913 RTX_CODE code = GET_CODE (x);
00914 rtx link;
00915 int i;
00916
00917 if (code == COND_EXEC)
00918 {
00919 sched_analyze_2 (deps, COND_EXEC_TEST (x), insn);
00920
00921
00922
00923 x = COND_EXEC_CODE (x);
00924 code = GET_CODE (x);
00925 }
00926 if (code == SET || code == CLOBBER)
00927 {
00928 sched_analyze_1 (deps, x, insn);
00929
00930
00931
00932
00933 if (code == CLOBBER)
00934 add_dependence_list (insn, deps->last_function_call, REG_DEP_OUTPUT);
00935 }
00936 else if (code == PARALLEL)
00937 {
00938 int i;
00939 for (i = XVECLEN (x, 0) - 1; i >= 0; i--)
00940 {
00941 rtx sub = XVECEXP (x, 0, i);
00942 code = GET_CODE (sub);
00943
00944 if (code == COND_EXEC)
00945 {
00946 sched_analyze_2 (deps, COND_EXEC_TEST (sub), insn);
00947 sub = COND_EXEC_CODE (sub);
00948 code = GET_CODE (sub);
00949 }
00950 if (code == SET || code == CLOBBER)
00951 sched_analyze_1 (deps, sub, insn);
00952 else
00953 sched_analyze_2 (deps, sub, insn);
00954 }
00955 }
00956 else
00957 sched_analyze_2 (deps, x, insn);
00958
00959
00960 if (GET_CODE (insn) == CALL_INSN)
00961 {
00962 for (link = CALL_INSN_FUNCTION_USAGE (insn); link; link = XEXP (link, 1))
00963 {
00964 if (GET_CODE (XEXP (link, 0)) == CLOBBER)
00965 sched_analyze_1 (deps, XEXP (link, 0), insn);
00966 else
00967 sched_analyze_2 (deps, XEXP (link, 0), insn);
00968 }
00969 if (find_reg_note (insn, REG_SETJMP, NULL))
00970 reg_pending_barrier = true;
00971 }
00972
00973 if (GET_CODE (insn) == JUMP_INSN)
00974 {
00975 rtx next;
00976 next = next_nonnote_insn (insn);
00977 if (next && GET_CODE (next) == BARRIER)
00978 reg_pending_barrier = true;
00979 else
00980 {
00981 rtx pending, pending_mem;
00982 regset_head tmp_uses, tmp_sets;
00983 INIT_REG_SET (&tmp_uses);
00984 INIT_REG_SET (&tmp_sets);
00985
00986 (*current_sched_info->compute_jump_reg_dependencies)
00987 (insn, &deps->reg_conditional_sets, &tmp_uses, &tmp_sets);
00988 IOR_REG_SET (reg_pending_uses, &tmp_uses);
00989 IOR_REG_SET (reg_pending_sets, &tmp_sets);
00990
00991 CLEAR_REG_SET (&tmp_uses);
00992 CLEAR_REG_SET (&tmp_sets);
00993
00994
00995
00996
00997
00998 pending = deps->pending_write_insns;
00999 pending_mem = deps->pending_write_mems;
01000 while (pending)
01001 {
01002 add_dependence (insn, XEXP (pending, 0), REG_DEP_OUTPUT);
01003 pending = XEXP (pending, 1);
01004 pending_mem = XEXP (pending_mem, 1);
01005 }
01006
01007 pending = deps->pending_read_insns;
01008 pending_mem = deps->pending_read_mems;
01009 while (pending)
01010 {
01011 if (MEM_VOLATILE_P (XEXP (pending_mem, 0)))
01012 add_dependence (insn, XEXP (pending, 0), REG_DEP_OUTPUT);
01013 pending = XEXP (pending, 1);
01014 pending_mem = XEXP (pending_mem, 1);
01015 }
01016
01017 add_dependence_list (insn, deps->last_pending_memory_flush,
01018 REG_DEP_ANTI);
01019 }
01020 }
01021
01022
01023
01024
01025
01026 if (loop_notes)
01027 {
01028 rtx link;
01029
01030
01031
01032
01033 link = loop_notes;
01034 while (XEXP (link, 1))
01035 {
01036 if (INTVAL (XEXP (link, 0)) == NOTE_INSN_LOOP_BEG
01037 || INTVAL (XEXP (link, 0)) == NOTE_INSN_LOOP_END
01038 || INTVAL (XEXP (link, 0)) == NOTE_INSN_EH_REGION_BEG
01039 || INTVAL (XEXP (link, 0)) == NOTE_INSN_EH_REGION_END)
01040 reg_pending_barrier = true;
01041
01042 link = XEXP (link, 1);
01043 }
01044 XEXP (link, 1) = REG_NOTES (insn);
01045 REG_NOTES (insn) = loop_notes;
01046 }
01047
01048
01049
01050
01051 if (can_throw_internal (insn))
01052 reg_pending_barrier = true;
01053
01054
01055 if (reg_pending_barrier)
01056 {
01057 if (GET_CODE (PATTERN (insn)) == COND_EXEC)
01058 {
01059 EXECUTE_IF_SET_IN_REG_SET (&deps->reg_last_in_use, 0, i,
01060 {
01061 struct deps_reg *reg_last = &deps->reg_last[i];
01062 add_dependence_list (insn, reg_last->uses, REG_DEP_ANTI);
01063 add_dependence_list (insn, reg_last->sets, 0);
01064 add_dependence_list (insn, reg_last->clobbers, 0);
01065 });
01066 }
01067 else
01068 {
01069 EXECUTE_IF_SET_IN_REG_SET (&deps->reg_last_in_use, 0, i,
01070 {
01071 struct deps_reg *reg_last = &deps->reg_last[i];
01072 add_dependence_list_and_free (insn, ®_last->uses,
01073 REG_DEP_ANTI);
01074 add_dependence_list_and_free (insn, ®_last->sets, 0);
01075 add_dependence_list_and_free (insn, ®_last->clobbers, 0);
01076 reg_last->uses_length = 0;
01077 reg_last->clobbers_length = 0;
01078 });
01079 }
01080
01081 for (i = 0; i < deps->max_reg; i++)
01082 {
01083 struct deps_reg *reg_last = &deps->reg_last[i];
01084 reg_last->sets = alloc_INSN_LIST (insn, reg_last->sets);
01085 SET_REGNO_REG_SET (&deps->reg_last_in_use, i);
01086 }
01087
01088 flush_pending_lists (deps, insn, true, true);
01089 CLEAR_REG_SET (&deps->reg_conditional_sets);
01090 reg_pending_barrier = false;
01091 }
01092 else
01093 {
01094
01095
01096 if (GET_CODE (PATTERN (insn)) == COND_EXEC)
01097 {
01098 EXECUTE_IF_SET_IN_REG_SET (reg_pending_uses, 0, i,
01099 {
01100 struct deps_reg *reg_last = &deps->reg_last[i];
01101 add_dependence_list (insn, reg_last->sets, 0);
01102 add_dependence_list (insn, reg_last->clobbers, 0);
01103 reg_last->uses = alloc_INSN_LIST (insn, reg_last->uses);
01104 reg_last->uses_length++;
01105 });
01106 EXECUTE_IF_SET_IN_REG_SET (reg_pending_clobbers, 0, i,
01107 {
01108 struct deps_reg *reg_last = &deps->reg_last[i];
01109 add_dependence_list (insn, reg_last->sets, REG_DEP_OUTPUT);
01110 add_dependence_list (insn, reg_last->uses, REG_DEP_ANTI);
01111 reg_last->clobbers = alloc_INSN_LIST (insn, reg_last->clobbers);
01112 reg_last->clobbers_length++;
01113 });
01114 EXECUTE_IF_SET_IN_REG_SET (reg_pending_sets, 0, i,
01115 {
01116 struct deps_reg *reg_last = &deps->reg_last[i];
01117 add_dependence_list (insn, reg_last->sets, REG_DEP_OUTPUT);
01118 add_dependence_list (insn, reg_last->clobbers, REG_DEP_OUTPUT);
01119 add_dependence_list (insn, reg_last->uses, REG_DEP_ANTI);
01120 reg_last->sets = alloc_INSN_LIST (insn, reg_last->sets);
01121 SET_REGNO_REG_SET (&deps->reg_conditional_sets, i);
01122 });
01123 }
01124 else
01125 {
01126 EXECUTE_IF_SET_IN_REG_SET (reg_pending_uses, 0, i,
01127 {
01128 struct deps_reg *reg_last = &deps->reg_last[i];
01129 add_dependence_list (insn, reg_last->sets, 0);
01130 add_dependence_list (insn, reg_last->clobbers, 0);
01131 reg_last->uses_length++;
01132 reg_last->uses = alloc_INSN_LIST (insn, reg_last->uses);
01133 });
01134 EXECUTE_IF_SET_IN_REG_SET (reg_pending_clobbers, 0, i,
01135 {
01136 struct deps_reg *reg_last = &deps->reg_last[i];
01137 if (reg_last->uses_length > MAX_PENDING_LIST_LENGTH
01138 || reg_last->clobbers_length > MAX_PENDING_LIST_LENGTH)
01139 {
01140 add_dependence_list_and_free (insn, ®_last->sets,
01141 REG_DEP_OUTPUT);
01142 add_dependence_list_and_free (insn, ®_last->uses,
01143 REG_DEP_ANTI);
01144 add_dependence_list_and_free (insn, ®_last->clobbers,
01145 REG_DEP_OUTPUT);
01146 reg_last->sets = alloc_INSN_LIST (insn, reg_last->sets);
01147 reg_last->clobbers_length = 0;
01148 reg_last->uses_length = 0;
01149 }
01150 else
01151 {
01152 add_dependence_list (insn, reg_last->sets, REG_DEP_OUTPUT);
01153 add_dependence_list (insn, reg_last->uses, REG_DEP_ANTI);
01154 }
01155 reg_last->clobbers_length++;
01156 reg_last->clobbers = alloc_INSN_LIST (insn, reg_last->clobbers);
01157 });
01158 EXECUTE_IF_SET_IN_REG_SET (reg_pending_sets, 0, i,
01159 {
01160 struct deps_reg *reg_last = &deps->reg_last[i];
01161 add_dependence_list_and_free (insn, ®_last->sets,
01162 REG_DEP_OUTPUT);
01163 add_dependence_list_and_free (insn, ®_last->clobbers,
01164 REG_DEP_OUTPUT);
01165 add_dependence_list_and_free (insn, ®_last->uses,
01166 REG_DEP_ANTI);
01167 reg_last->sets = alloc_INSN_LIST (insn, reg_last->sets);
01168 reg_last->uses_length = 0;
01169 reg_last->clobbers_length = 0;
01170 CLEAR_REGNO_REG_SET (&deps->reg_conditional_sets, i);
01171 });
01172 }
01173
01174 IOR_REG_SET (&deps->reg_last_in_use, reg_pending_uses);
01175 IOR_REG_SET (&deps->reg_last_in_use, reg_pending_clobbers);
01176 IOR_REG_SET (&deps->reg_last_in_use, reg_pending_sets);
01177 }
01178 CLEAR_REG_SET (reg_pending_uses);
01179 CLEAR_REG_SET (reg_pending_clobbers);
01180 CLEAR_REG_SET (reg_pending_sets);
01181
01182
01183
01184
01185
01186 if (deps->libcall_block_tail_insn)
01187 {
01188 set_sched_group_p (insn);
01189 CANT_MOVE (insn) = 1;
01190 }
01191
01192
01193
01194
01195
01196
01197
01198
01199
01200
01201 if (deps->in_post_call_group_p)
01202 {
01203 rtx tmp, set = single_set (insn);
01204 int src_regno, dest_regno;
01205
01206 if (set == NULL)
01207 goto end_call_group;
01208
01209 tmp = SET_DEST (set);
01210 if (GET_CODE (tmp) == SUBREG)
01211 tmp = SUBREG_REG (tmp);
01212 if (GET_CODE (tmp) == REG)
01213 dest_regno = REGNO (tmp);
01214 else
01215 goto end_call_group;
01216
01217 tmp = SET_SRC (set);
01218 if (GET_CODE (tmp) == SUBREG)
01219 tmp = SUBREG_REG (tmp);
01220 if (GET_CODE (tmp) == REG)
01221 src_regno = REGNO (tmp);
01222 else
01223 goto end_call_group;
01224
01225 if (src_regno < FIRST_PSEUDO_REGISTER
01226 || dest_regno < FIRST_PSEUDO_REGISTER)
01227 {
01228 set_sched_group_p (insn);
01229 CANT_MOVE (insn) = 1;
01230 }
01231 else
01232 {
01233 end_call_group:
01234 deps->in_post_call_group_p = false;
01235 }
01236 }
01237 }
01238
01239
01240
01241
01242 void
01243 sched_analyze (deps, head, tail)
01244 struct deps *deps;
01245 rtx head, tail;
01246 {
01247 rtx insn;
01248 rtx loop_notes = 0;
01249
01250 if (current_sched_info->use_cselib)
01251 cselib_init ();
01252
01253 for (insn = head;; insn = NEXT_INSN (insn))
01254 {
01255 rtx link, end_seq, r0, set;
01256
01257 if (GET_CODE (insn) == INSN || GET_CODE (insn) == JUMP_INSN)
01258 {
01259
01260 free_INSN_LIST_list (&LOG_LINKS (insn));
01261
01262
01263
01264 if (GET_CODE (insn) == JUMP_INSN)
01265 {
01266
01267 if (deps->pending_flush_length++ > MAX_PENDING_LIST_LENGTH)
01268 flush_pending_lists (deps, insn, true, true);
01269 else
01270 deps->last_pending_memory_flush
01271 = alloc_INSN_LIST (insn, deps->last_pending_memory_flush);
01272 }
01273 sched_analyze_insn (deps, PATTERN (insn), insn, loop_notes);
01274 loop_notes = 0;
01275 }
01276 else if (GET_CODE (insn) == CALL_INSN)
01277 {
01278 int i;
01279
01280 CANT_MOVE (insn) = 1;
01281
01282
01283 free_INSN_LIST_list (&LOG_LINKS (insn));
01284
01285 if (find_reg_note (insn, REG_SETJMP, NULL))
01286 {
01287
01288
01289 reg_pending_barrier = true;
01290 }
01291 else
01292 {
01293 for (i = 0; i < FIRST_PSEUDO_REGISTER; i++)
01294
01295 if (global_regs[i])
01296 {
01297 SET_REGNO_REG_SET (reg_pending_sets, i);
01298 SET_REGNO_REG_SET (reg_pending_uses, i);
01299 }
01300
01301
01302
01303
01304 else if (HARD_REGNO_CALL_PART_CLOBBERED (i, reg_raw_mode[i])
01305 || TEST_HARD_REG_BIT (regs_invalidated_by_call, i))
01306 SET_REGNO_REG_SET (reg_pending_clobbers, i);
01307
01308
01309
01310 else if (fixed_regs[i])
01311 SET_REGNO_REG_SET (reg_pending_uses, i);
01312
01313
01314
01315
01316
01317 else if (i == FRAME_POINTER_REGNUM
01318 || (i == HARD_FRAME_POINTER_REGNUM
01319 && (! reload_completed || frame_pointer_needed)))
01320 SET_REGNO_REG_SET (reg_pending_uses, i);
01321 }
01322
01323
01324
01325 add_dependence_list_and_free (insn, &deps->sched_before_next_call,
01326 REG_DEP_ANTI);
01327
01328 sched_analyze_insn (deps, PATTERN (insn), insn, loop_notes);
01329 loop_notes = 0;
01330
01331
01332
01333
01334
01335 flush_pending_lists (deps, insn, true, !CONST_OR_PURE_CALL_P (insn));
01336
01337
01338 free_INSN_LIST_list (&deps->last_function_call);
01339 deps->last_function_call = alloc_INSN_LIST (insn, NULL_RTX);
01340
01341
01342
01343 if (! reload_completed)
01344 deps->in_post_call_group_p = true;
01345 }
01346
01347
01348
01349
01350 if (GET_CODE (insn) == NOTE
01351 && (NOTE_LINE_NUMBER (insn) == NOTE_INSN_LOOP_BEG
01352 || NOTE_LINE_NUMBER (insn) == NOTE_INSN_LOOP_END
01353 || NOTE_LINE_NUMBER (insn) == NOTE_INSN_EH_REGION_BEG
01354 || NOTE_LINE_NUMBER (insn) == NOTE_INSN_EH_REGION_END))
01355 {
01356 rtx rtx_region;
01357
01358 if (NOTE_LINE_NUMBER (insn) == NOTE_INSN_EH_REGION_BEG
01359 || NOTE_LINE_NUMBER (insn) == NOTE_INSN_EH_REGION_END)
01360 rtx_region = GEN_INT (NOTE_EH_HANDLER (insn));
01361 else
01362 rtx_region = GEN_INT (0);
01363
01364 loop_notes = alloc_EXPR_LIST (REG_SAVE_NOTE,
01365 rtx_region,
01366 loop_notes);
01367 loop_notes = alloc_EXPR_LIST (REG_SAVE_NOTE,
01368 GEN_INT (NOTE_LINE_NUMBER (insn)),
01369 loop_notes);
01370 CONST_OR_PURE_CALL_P (loop_notes) = CONST_OR_PURE_CALL_P (insn);
01371 }
01372
01373 if (current_sched_info->use_cselib)
01374 cselib_process_insn (insn);
01375
01376
01377
01378
01379
01380
01381
01382
01383
01384
01385
01386
01387 if (!reload_completed
01388
01389
01390 && deps->libcall_block_tail_insn == 0
01391
01392 && GET_CODE (insn) == INSN
01393 && GET_CODE (PATTERN (insn)) == CLOBBER
01394 && (r0 = XEXP (PATTERN (insn), 0), GET_CODE (r0) == REG)
01395 && GET_CODE (XEXP (PATTERN (insn), 0)) == REG
01396
01397 && (link = find_reg_note (insn, REG_LIBCALL, NULL_RTX)) != 0
01398 && (end_seq = XEXP (link, 0)) != 0
01399
01400
01401
01402 && (set = single_set (end_seq)) != 0
01403 && SET_DEST (set) == r0 && SET_SRC (set) == r0
01404
01405
01406 && find_reg_note (end_seq, REG_EQUAL, NULL_RTX) != 0
01407 && find_reg_note (end_seq, REG_RETVAL, NULL_RTX) != 0)
01408 deps->libcall_block_tail_insn = XEXP (link, 0);
01409
01410
01411
01412 if (deps->libcall_block_tail_insn == insn)
01413 deps->libcall_block_tail_insn = 0;
01414
01415 if (insn == tail)
01416 {
01417 if (current_sched_info->use_cselib)
01418 cselib_finish ();
01419 return;
01420 }
01421 }
01422 abort ();
01423 }
01424
01425
01426
01427
01428
01429 void
01430 add_forward_dependence (from, to, dep_type)
01431 rtx from;
01432 rtx to;
01433 enum reg_note dep_type;
01434 {
01435 rtx new_link;
01436
01437 #ifdef ENABLE_CHECKING
01438
01439
01440
01441
01442
01443
01444 if (GET_CODE (from) == NOTE
01445 || INSN_DELETED_P (from)
01446 || (forward_dependency_cache != NULL
01447 && TEST_BIT (forward_dependency_cache[INSN_LUID (from)],
01448 INSN_LUID (to)))
01449 || (forward_dependency_cache == NULL
01450 && find_insn_list (to, INSN_DEPEND (from))))
01451 abort ();
01452 if (forward_dependency_cache != NULL)
01453 SET_BIT (forward_dependency_cache[INSN_LUID (from)],
01454 INSN_LUID (to));
01455 #endif
01456
01457 new_link = alloc_INSN_LIST (to, INSN_DEPEND (from));
01458
01459 PUT_REG_NOTE_KIND (new_link, dep_type);
01460
01461 INSN_DEPEND (from) = new_link;
01462 INSN_DEP_COUNT (to) += 1;
01463 }
01464
01465
01466
01467
01468
01469 void
01470 compute_forward_dependences (head, tail)
01471 rtx head, tail;
01472 {
01473 rtx insn, link;
01474 rtx next_tail;
01475
01476 next_tail = NEXT_INSN (tail);
01477 for (insn = head; insn != next_tail; insn = NEXT_INSN (insn))
01478 {
01479 if (! INSN_P (insn))
01480 continue;
01481
01482 insn = group_leader (insn);
01483
01484 for (link = LOG_LINKS (insn); link; link = XEXP (link, 1))
01485 add_forward_dependence (group_leader (XEXP (link, 0)), insn,
01486 REG_NOTE_KIND (link));
01487 }
01488 }
01489
01490
01491
01492
01493 void
01494 init_deps (deps)
01495 struct deps *deps;
01496 {
01497 int max_reg = (reload_completed ? FIRST_PSEUDO_REGISTER : max_reg_num ());
01498
01499 deps->max_reg = max_reg;
01500 deps->reg_last = (struct deps_reg *)
01501 xcalloc (max_reg, sizeof (struct deps_reg));
01502 INIT_REG_SET (&deps->reg_last_in_use);
01503 INIT_REG_SET (&deps->reg_conditional_sets);
01504
01505 deps->pending_read_insns = 0;
01506 deps->pending_read_mems = 0;
01507 deps->pending_write_insns = 0;
01508 deps->pending_write_mems = 0;
01509 deps->pending_lists_length = 0;
01510 deps->pending_flush_length = 0;
01511 deps->last_pending_memory_flush = 0;
01512 deps->last_function_call = 0;
01513 deps->sched_before_next_call = 0;
01514 deps->in_post_call_group_p = false;
01515 deps->libcall_block_tail_insn = 0;
01516 }
01517
01518
01519
01520 void
01521 free_deps (deps)
01522 struct deps *deps;
01523 {
01524 int i;
01525
01526 free_INSN_LIST_list (&deps->pending_read_insns);
01527 free_EXPR_LIST_list (&deps->pending_read_mems);
01528 free_INSN_LIST_list (&deps->pending_write_insns);
01529 free_EXPR_LIST_list (&deps->pending_write_mems);
01530 free_INSN_LIST_list (&deps->last_pending_memory_flush);
01531
01532
01533
01534
01535 EXECUTE_IF_SET_IN_REG_SET (&deps->reg_last_in_use, 0, i,
01536 {
01537 struct deps_reg *reg_last = &deps->reg_last[i];
01538 if (reg_last->uses)
01539 free_INSN_LIST_list (®_last->uses);
01540 if (reg_last->sets)
01541 free_INSN_LIST_list (®_last->sets);
01542 if (reg_last->clobbers)
01543 free_INSN_LIST_list (®_last->clobbers);
01544 });
01545 CLEAR_REG_SET (&deps->reg_last_in_use);
01546 CLEAR_REG_SET (&deps->reg_conditional_sets);
01547
01548 free (deps->reg_last);
01549 }
01550
01551
01552
01553
01554
01555 void
01556 init_dependency_caches (luid)
01557 int luid;
01558 {
01559
01560
01561
01562
01563
01564
01565 if (luid / n_basic_blocks > 100 * 5)
01566 {
01567 true_dependency_cache = sbitmap_vector_alloc (luid, luid);
01568 sbitmap_vector_zero (true_dependency_cache, luid);
01569 anti_dependency_cache = sbitmap_vector_alloc (luid, luid);
01570 sbitmap_vector_zero (anti_dependency_cache, luid);
01571 output_dependency_cache = sbitmap_vector_alloc (luid, luid);
01572 sbitmap_vector_zero (output_dependency_cache, luid);
01573 #ifdef ENABLE_CHECKING
01574 forward_dependency_cache = sbitmap_vector_alloc (luid, luid);
01575 sbitmap_vector_zero (forward_dependency_cache, luid);
01576 #endif
01577 }
01578 }
01579
01580
01581
01582 void
01583 free_dependency_caches ()
01584 {
01585 if (true_dependency_cache)
01586 {
01587 sbitmap_vector_free (true_dependency_cache);
01588 true_dependency_cache = NULL;
01589 sbitmap_vector_free (anti_dependency_cache);
01590 anti_dependency_cache = NULL;
01591 sbitmap_vector_free (output_dependency_cache);
01592 output_dependency_cache = NULL;
01593 #ifdef ENABLE_CHECKING
01594 sbitmap_vector_free (forward_dependency_cache);
01595 forward_dependency_cache = NULL;
01596 #endif
01597 }
01598 }
01599
01600
01601
01602
01603 void
01604 init_deps_global ()
01605 {
01606 reg_pending_sets = INITIALIZE_REG_SET (reg_pending_sets_head);
01607 reg_pending_clobbers = INITIALIZE_REG_SET (reg_pending_clobbers_head);
01608 reg_pending_uses = INITIALIZE_REG_SET (reg_pending_uses_head);
01609 reg_pending_barrier = false;
01610 }
01611
01612
01613
01614 void
01615 finish_deps_global ()
01616 {
01617 FREE_REG_SET (reg_pending_sets);
01618 FREE_REG_SET (reg_pending_clobbers);
01619 FREE_REG_SET (reg_pending_uses);
01620 }