00001
00002
00003
00004
00005
00006
00007
00008
00009
00010
00011
00012
00013
00014
00015
00016
00017
00018
00019
00020
00021
00022
00023
00024
00025
00026
00027
00028
00029
00030
00031
00032
00033
00034
00035
00036
00037
00038
00039
00040
00041
00042
00043
00044
00045
00046
00047
00048
00049
00050
00051
00052 #include "cg.h"
00053 #include "cg_dep_graph.h"
00054
00055 #include "ipfec_options.h"
00056
00057 #include "sched_rgn_info.h"
00058 #include "sched_util.h"
00059 #include "sched_cand.h"
00060 #include "sched_heur.h"
00061
00062
00063 UNRESOLVED_DEP_LST&
00064 UNRESOLVED_DEP_LST :: operator = (const UNRESOLVED_DEP_LST& urds) {
00065
00066 FmtAssert (FALSE, ("Copy is prohibit"));
00067 return *this;
00068 }
00069
00070
00071 void
00072 UNRESOLVED_DEP_LST :: Delete_Item (UNRESOLVED_DEP* dep) {
00073
00074 Is_True (dep->Get_List () == this,
00075 ("item is not in this list"));
00076
00077 Is_True (dep->Is_Alloc_By_Cand_Mgr (),
00078 ("UNRESOLVED_DEP_LST is not allocated by CAND_MGR"));
00079
00080 UNRESOLVED_DEP* prev = dep->_prev;
00081 UNRESOLVED_DEP* next = dep->_next;
00082
00083 if (prev) {
00084 prev->_next = next;
00085 } else {
00086 _header = next;
00087 }
00088
00089 if (next) {
00090 next->_prev = prev;
00091 } else {
00092 _tail = prev;
00093 }
00094
00095 _cand_mgr->Free_Unresolved_Dep (dep);
00096 }
00097
00098 void
00099 UNRESOLVED_DEP_LST :: Prepend (UNRESOLVED_DEP* dep) {
00100
00101 dep->_next = _header;
00102 dep->_prev = NULL;
00103
00104 if (_header) { _header -> _prev = dep; }
00105 _header = dep;
00106
00107 if (!_tail) { _tail = dep; }
00108 dep->_lst = this;
00109 }
00110
00111 void
00112 UNRESOLVED_DEP_LST :: Append (UNRESOLVED_DEP* dep) {
00113
00114 dep->_prev = _tail;
00115 dep->_next = NULL;
00116
00117 if (_tail) { _tail -> _next = dep; }
00118 _tail = dep;
00119
00120 if (!_header) { _header = dep; }
00121
00122 dep->_lst = this;
00123 }
00124
00125
00126 void
00127 BOOKEEPING_LST :: Delete_Item (BOOKEEPING* item) {
00128
00129 Is_True (item->Get_List () == this,
00130 ("item is not in this list"));
00131
00132 Is_True (item->Is_Alloc_By_Cand_Mgr (),
00133 ("BOOKEEPING structure is not allocated by CAND_MGR"));
00134
00135 BOOKEEPING* prev = item->_prev;
00136 BOOKEEPING* next = item->_next;
00137
00138 if (prev) {
00139 prev->_next = next;
00140 } else {
00141 _header = next;
00142 }
00143
00144 if (next) {
00145 next->_prev = prev;
00146 } else {
00147 _tail = prev;
00148 }
00149
00150 _cand_mgr->Free_Bookeeping (item);
00151 }
00152
00153 void
00154 BOOKEEPING_LST :: Append (BOOKEEPING* item) {
00155
00156 item->_prev = _tail;
00157 if (_tail) { _tail->_next = item; }
00158 _tail = item;
00159
00160 if (!_header) { _header = item; }
00161 item->_bklst = this;
00162 }
00163
00164 void
00165 BOOKEEPING_LST :: Prepend (BOOKEEPING* item) {
00166
00167 item->_next = _header;
00168 if (_header) { _header->_prev = item; }
00169 _header = item;
00170
00171 if (!_tail) { _tail = item; }
00172 item->_bklst = this;
00173 }
00174
00175
00176
00177
00178
00179
00180
00181
00182
00183
00184
00185
00186
00187 void
00188 CANDIDATE :: Init (void) {
00189
00190 _try_ver = 0 ;
00191 _prev = _next = NULL ;
00192 _op = NULL ;
00193 _spec_type = SPEC_NONE ;
00194 _flags = 0;
00195 _if_converted = FALSE;
00196 _move_against_paths.Clear ();
00197 _move_across_rgns.clear ();
00198
00199 Free_Unresolved_Dep_Lst ();
00200 Free_Bookeeping_Lst ();
00201 }
00202
00203 CANDIDATE :: CANDIDATE (CAND_MGR* cand_mgr, MEM_POOL* mp)
00204 : _mp(mp),
00205 _cand_mgr (cand_mgr),
00206 _violated_deps (cand_mgr),
00207 _bookeepings (cand_mgr),
00208 _move_across_rgns (mp),
00209 _move_against_paths(mp),
00210 _pready_bookeeping_paths(mp) {
00211
00212 Init ();
00213 }
00214
00215
00216 CANDIDATE :: ~CANDIDATE (void) {
00217 Free_Unresolved_Dep_Lst ();
00218 Free_Bookeeping_Lst ();
00219 }
00220
00221
00222
00223
00224
00225
00226
00227
00228
00229
00230
00231
00232
00233
00234
00235
00236
00237
00238
00239
00240
00241
00242
00243
00244
00245
00246
00247 SPEC_TYPE
00248 CANDIDATE :: Get_Up_to_Date_Spec_Type (void) {
00249
00250 if (_violated_deps.Is_Empty () ||
00251 Is_P_Ready ()) {
00252
00253 return _spec_type ;
00254 }
00255
00256 SPEC_TYPE spec_type = SPEC_NONE;
00257 for (UNRESOLVED_DEP* dep = _violated_deps.First_Item ();
00258 dep != NULL;
00259 dep = _violated_deps.Next_Item (dep)) {
00260
00261 if (OP_Scheduled(dep->Pred ()) &&
00262 !OP_xfer(dep->Pred ())) {
00263 continue ;
00264 }
00265
00266 spec_type = SPEC_TYPE(spec_type|dep->Spec_Type ());
00267 }
00268
00269 return _spec_type = spec_type ;
00270 }
00271
00272
00273
00274
00275
00276
00277
00278
00279
00280 BOOL
00281 CANDIDATE :: Shadowed_By_P_Ready_Bookeeping
00282 (BB* b, RGN_CFLOW_MGR* cflow_info) {
00283
00284 if (Is_M_Ready ()) { return FALSE; }
00285
00286 EXEC_PATH_SET* eps = cflow_info->Get_Path_Flow_Thru (b);
00287 return eps->Is_Subset_Of (&_pready_bookeeping_paths);
00288 }
00289
00290 BOOL
00291 CANDIDATE :: Shadowed_By_P_Ready_Bookeeping
00292 (REGION* r, RGN_CFLOW_MGR* cflow_info) {
00293
00294 if (Is_M_Ready ()) { return FALSE; }
00295
00296 EXEC_PATH_SET* eps = cflow_info->Get_Path_Flow_Thru (r);
00297 return eps->Is_Subset_Of (&_pready_bookeeping_paths);
00298 }
00299
00300
00301
00302
00303
00304
00305
00306
00307
00308 INT32
00309 Determine_Cand_Init_Etime (BB* targ, OP* cand) {
00310 }
00311
00312
00313
00314
00315
00316
00317
00318
00319
00320
00321 void
00322 CAND_LIST :: Init (void) {
00323
00324 _total = 0 ;
00325 _tried_cand_num = 0 ;
00326 _try_version = MIN_TRY_VERSION ;
00327
00328
00329
00330 _cand_lst_head._prev = _cand_lst_tail._next = NULL ;
00331 _cand_lst_head._next = &_cand_lst_tail ;
00332 _cand_lst_tail._prev = &_cand_lst_head ;
00333
00334
00335 _op_map_idx = BS_Create_Empty (DEF_BBLENGTH,
00336 _mp);
00337 }
00338
00339 CAND_LIST :: CAND_LIST
00340 (MEM_POOL *mp, CAND_MGR* cand_mgr,BOOL host_m_ready_cand):
00341 _mp(mp),
00342 _cand_lst_head (cand_mgr,mp),
00343 _cand_lst_tail (cand_mgr,mp) {
00344
00345 _host_m_ready_cand = host_m_ready_cand;
00346 _cand_mgr = cand_mgr;
00347
00348 Init () ;
00349 }
00350
00351
00352
00353
00354
00355
00356
00357
00358
00359
00360
00361 void
00362 CAND_LIST :: Set_Cand_Has_Been_Tried (CANDIDATE* cand) {
00363
00364 if (!Cand_Has_Been_Tried (cand)) {
00365
00366 cand->_try_ver = _try_version + 1 ;
00367 ++ _tried_cand_num ;
00368 Is_True (_tried_cand_num <= _total,
00369 ("tried candidate exceed total number!"));
00370
00371 }
00372 }
00373
00374
00375
00376
00377
00378
00379
00380
00381
00382 void
00383 CAND_LIST :: Erase_All_Cand (void) {
00384 while (_total > 0) {
00385 Erase_Cand (_cand_lst_head._next);
00386 }
00387
00388 Is_True (_cand_lst_head._next == &_cand_lst_tail,
00389 ("candidate list should be empty!"));
00390 }
00391
00392
00393
00394
00395
00396
00397
00398
00399
00400 void
00401 CAND_LIST :: Clear_Cand_Tried_Mark (CANDIDATE *cand) {
00402
00403 if (Cand_Has_Been_Tried (cand)) {
00404
00405 cand->_try_ver = _try_version ;
00406 -- _tried_cand_num ;
00407
00408 Is_True (_tried_cand_num >= 0,
00409 ("tried candidate can not be a negative"));
00410
00411 }
00412 }
00413
00414
00415
00416
00417
00418
00419
00420
00421
00422 BOOL
00423 CAND_LIST :: OP_Is_In_Cand_List (OP* op) {
00424
00425 if (!BS_MemberP (_op_map_idx, OP_map_idx(op))) {
00426 return FALSE;
00427 }
00428
00429 for (CAND_LIST_ITER iter(this); ! iter.done () ; iter.step ()) {
00430 if (iter.cur()->Op () == op) return TRUE;
00431 }
00432 return FALSE;
00433 }
00434
00435
00436
00437
00438
00439
00440
00441
00442
00443
00444
00445 CANDIDATE *
00446 CAND_LIST :: Get_Candidate (OP* op) {
00447
00448 for (CAND_LIST_ITER iter(this); ! iter.done() ; iter.step ()) {
00449 CANDIDATE * cand = iter.cur();
00450 if (cand->Op () == op) return cand ;
00451 }
00452 return NULL;
00453 }
00454
00455
00456
00457
00458
00459
00460
00461
00462
00463 void
00464 CAND_LIST :: Add_Candidate (CANDIDATE * cand) {
00465
00466
00467
00468
00469
00470 Append (cand) ;
00471 ++ _total ;
00472 cand->_try_ver = _try_version ;
00473
00474 _op_map_idx = BS_Union1D (_op_map_idx,
00475 OP_map_idx(cand->_op),_mp);
00476
00477 cand->Set_Cand_Attached ();
00478 }
00479
00480
00481
00482
00483
00484
00485
00486
00487
00488
00489
00490 void
00491 CAND_LIST :: Erase_Cand (CANDIDATE* cand) {
00492
00493 Is_True (cand->Is_Attached_To_Cand_Lst() &&
00494 ((cand->Is_M_Ready () && _host_m_ready_cand) ||
00495 (cand->Is_P_Ready () && !_host_m_ready_cand)),
00496 ("canidate list does not take control of this cand"));
00497
00498 if (Cand_Has_Been_Tried (cand)) { -- _tried_cand_num ; }
00499 -- _total ;
00500
00501 cand->Set_Cand_Detached ();
00502 Detach (cand);
00503
00504 _cand_mgr->Reclaim_Free_Cand (cand);
00505 }
00506
00507 void
00508 CAND_LIST :: Erase_Cand (OP *op, BOOL abort_if_not_belong_lst) {
00509
00510 for (CAND_LIST_ITER iter(this) ; !iter.done() ; ) {
00511
00512 CANDIDATE * cand = iter.cur();
00513
00514 if (cand->Op() == op) {
00515 iter.erase_cur_and_advance ();
00516 return ;
00517 }
00518
00519 iter.step ();
00520 }
00521
00522 if (abort_if_not_belong_lst) {
00523 FmtAssert (FALSE,
00524 ("OP[%d] of BB:%d is not in %c-Ready-Candidate list!\n",
00525 OP_map_idx(op),
00526 BB_id(OP_bb(op)),
00527 _host_m_ready_cand ? 'M' : 'P'));
00528 }
00529 }
00530
00531
00532
00533
00534
00535
00536
00537
00538
00539
00540
00541 CANDIDATE *
00542 CAND_LIST :: Create_Empty_Cand (void) {
00543
00544 return _cand_mgr->Alloc_Cand () ;
00545 }
00546
00547
00548
00549
00550
00551
00552
00553
00554
00555
00556 void
00557 CAND_LIST :: Clear_All_Cands_Tried_Mark (void) {
00558
00559 _tried_cand_num = 0 ;
00560
00561 if (_try_version < MAX_TRY_VERSION) {
00562
00563 ++ _try_version ;
00564 return ;
00565
00566 } else {
00567
00568 _try_version = MIN_TRY_VERSION ;
00569
00570 for (CAND_LIST_ITER iter(this) ; ! iter.done(); iter.step ()) {
00571 iter.cur ()->_try_ver = MIN_TRY_VERSION;
00572 }
00573 }
00574 }
00575
00576
00577
00578
00579
00580
00581
00582
00583
00584
00585
00586 INT16
00587 CAND_LIST :: Evict_Unqualified_Cands (
00588 CAND_QUALIFICATION_CHECK * quaf_func, void* parm)
00589 {
00590 INT16 evict_num = 0 ;
00591
00592 for (CANDIDATE * tmp = _cand_lst_head._next ;
00593 tmp != &_cand_lst_tail ; ) {
00594
00595 if (!(*quaf_func)(tmp, parm)) {
00596 CANDIDATE * cand = tmp ;
00597 tmp = tmp -> _next ;
00598 Erase_Cand (cand);
00599 evict_num ++ ;
00600 } else {
00601 tmp = tmp -> _next ;
00602 }
00603 }
00604
00605 return evict_num ;
00606 }
00607
00608
00609
00610
00611
00612
00613
00614
00615
00616
00617
00618
00619 CAND_MGR :: CAND_MGR (MEM_POOL* mp) :
00620 _mp(mp),
00621 _m_ready_cands(mp,this,TRUE),
00622 _p_ready_cands(mp,this,FALSE) {
00623
00624 _free_cand = NULL ;
00625 _free_unresolved_deps = NULL;
00626 _free_bookeepings = NULL;
00627 }
00628
00629
00630
00631
00632
00633
00634
00635
00636
00637
00638 #define UNRESOLVED_DEP_INC (64)
00639 UNRESOLVED_DEP*
00640 CAND_MGR :: New_Unresolved_Dep (void) {
00641
00642 UNRESOLVED_DEP* t;
00643 if (!_free_unresolved_deps) {
00644 t = TYPE_MEM_POOL_ALLOC_N (UNRESOLVED_DEP, _mp, UNRESOLVED_DEP_INC);
00645
00646 for (INT i = 0; i < UNRESOLVED_DEP_INC; i++) {
00647 t[i].Set_Alloc_By_Cand_Mgr ();
00648 t[i]._next = &t[i+1];
00649 }
00650 t[UNRESOLVED_DEP_INC-1]._next = NULL;
00651 _free_unresolved_deps = t;
00652 }
00653
00654 t = _free_unresolved_deps;
00655 _free_unresolved_deps = t->_next ;
00656
00657 t->Init ();
00658 t->Set_Alloc_By_Cand_Mgr ();
00659
00660 return t;
00661 }
00662
00663 void
00664 CAND_MGR :: Free_Unresolved_Dep (UNRESOLVED_DEP* item) {
00665
00666 if (item && item->Is_Alloc_By_Cand_Mgr ()) {
00667 item->_next = _free_unresolved_deps;
00668 _free_unresolved_deps = item ;
00669 }
00670 }
00671
00672
00673
00674
00675
00676
00677
00678
00679
00680 #define BOOKEEPING_ALLOC_INC (64)
00681 BOOKEEPING*
00682 CAND_MGR :: New_Empty_Bookeeping (void) {
00683
00684 BOOKEEPING* t;
00685 if (_free_bookeepings) {
00686
00687 t = _free_bookeepings;
00688 _free_bookeepings = _free_bookeepings->Next ();
00689
00690 t->Init ();
00691 t->Set_Alloc_By_Cand_Mgr ();
00692
00693 return t;
00694 }
00695
00696 t = TYPE_MEM_POOL_ALLOC_N
00697 (BOOKEEPING, _mp,BOOKEEPING_ALLOC_INC);
00698
00699 _free_bookeepings = t;
00700 for (INT i = 0; i < BOOKEEPING_ALLOC_INC; i++) {
00701 t[i]._next = &t[i+1];
00702 t[i].Set_Alloc_By_Cand_Mgr ();
00703 }
00704 t[BOOKEEPING_ALLOC_INC-1]._next = NULL;
00705
00706 return New_Empty_Bookeeping ();
00707 }
00708
00709
00710
00711
00712
00713
00714
00715
00716
00717 void
00718 CANDIDATE :: Calc_Useful_Exec_Prob
00719 (BB* targ, RGN_CFLOW_MGR* cflow_info) {
00720
00721 BB* home = OP_bb(Op ());
00722
00723 _useful_exec_prob =
00724 cflow_info->Reachable_Prob (targ, home);
00725
00726 if (Is_M_Ready ()) return ;
00727
00728 float prob = 0.0f;
00729 for (BOOKEEPING* bk = _bookeepings.First_Item ();
00730 bk;
00731 bk = _bookeepings.Next_Item (bk)) {
00732
00733
00734 if (bk->Is_P_Ready_Bookeeping ()) {
00735
00736 BB* b = bk->Get_Placement ();
00737 prob += cflow_info->Reachable_Prob (targ,b) *
00738 cflow_info->Reachable_Prob (b, home) /
00739 (float)REACH_PROB_SCALE;
00740 }
00741 }
00742
00743 _useful_exec_prob -= (PROBABILITY)prob;
00744 }
00745
00746
00747
00748
00749
00750
00751
00752
00753
00754 OP*
00755 CANDIDATE :: Get_Cmp_OP_Of_If_Converted_Code(void) {
00756 OP* cmp_op = NULL;
00757
00758 for (ARC_LIST* arcs = OP_preds(_op);
00759 arcs != NULL;
00760 arcs = ARC_LIST_rest(arcs)) {
00761
00762 ARC* arc = ARC_LIST_first(arcs) ;
00763 if (ARC_kind(arc) == CG_DEP_CTLSPEC) {
00764 cmp_op = ARC_pred(arc);
00765 if (!OP_ANNOT_Is_Compensation(cmp_op) && !OP_Scheduled(cmp_op)) {
00766 break;
00767 }
00768 }
00769 }
00770 return cmp_op;
00771 }
00772
00773
00774
00775
00776
00777
00778
00779
00780
00781
00782
00783 void
00784 CAND_MGR :: Free_Bookeeping (BOOKEEPING* bk) {
00785
00786 if (!bk->Is_Alloc_By_Cand_Mgr ()) {
00787 DevWarn ("BOOKEEPING struct is not allocated by CAND_MGR");
00788 return;
00789 }
00790
00791 bk->_next = _free_bookeepings;
00792 _free_bookeepings = bk;
00793 }
00794
00795
00796
00797
00798
00799
00800
00801
00802
00803
00804
00805 void
00806 CAND_MGR :: Reclaim_Free_Cand (CANDIDATE* cand) {
00807
00808 if (cand->Alloc_By_Cand_Mgr ()) {
00809 cand->_next = _free_cand ;
00810 _free_cand = cand ;
00811 }
00812
00813 cand->Free_Unresolved_Dep_Lst ();
00814 cand->Free_Bookeeping_Lst ();
00815 }
00816
00817 #define CAND_ALLOC_INC (8)
00818 CANDIDATE*
00819 CAND_MGR :: Alloc_Cand (void) {
00820
00821 CANDIDATE* t;
00822
00823 if (!_free_cand) {
00824
00825 CANDIDATE* t = CXX_NEW (CANDIDATE(this,_mp), _mp) ;
00826 t->Set_Alloc_By_Cand_Mgr ();
00827 Reclaim_Free_Cand (t);
00828 }
00829
00830 t = _free_cand;
00831 _free_cand = t->_next;
00832
00833 t->Init ();
00834 t->Set_Alloc_By_Cand_Mgr ();
00835
00836 return t;
00837 }
00838
00839 void
00840 CAND_MGR :: Erase_Cand (CANDIDATE* cand) {
00841
00842 if (cand->Is_Attached_To_Cand_Lst ()) {
00843 if (cand->Is_M_Ready ()) {
00844 _m_ready_cands.Erase_Cand(cand);
00845 } else {
00846 _p_ready_cands.Erase_Cand (cand);
00847 }
00848 } else {
00849 Reclaim_Free_Cand (cand);
00850 }
00851 }
00852
00853
00854
00855
00856 BOOL
00857 Can_BB_Potentially_Donate_P_Ready_Cands
00858 (BB * src, BB * targ, RGN_CFLOW_MGR * cflow_info) {
00859
00860 return FALSE;
00861 }
00862
00863
00864
00865
00866
00867
00868
00869
00870
00871
00872 SRC_BB_MGR::SRC_BB_MGR (MEM_POOL *mp) :
00873 _mp(mp),
00874 _src_bbs_vect(BB_ALLOC(mp)),
00875 _src_info_vect (SRC_BB_INFO_ALLOC(mp)) {
00876
00877 _src_bbs_set = BB_SET_Create (PU_BB_Count+2, _mp);
00878 _targ = NULL;
00879 _scope = NULL;
00880 _prepass = FALSE;
00881
00882 _find_src_bbs_access_bbs = BB_SET_Create_Empty (PU_BB_Count + 2, _mp);
00883 _find_src_bbs_access_rgns = BS_Create_Empty (64, _mp);
00884 }
00885
00886 SRC_BB_MGR :: ~SRC_BB_MGR (void) {
00887 }
00888
00889
00890
00891
00892
00893
00894
00895
00896
00897
00898 BOOL
00899 SRC_BB_MGR :: _src_bb_is_qualified (BB* src, SRC_BB_INFO* its_info,
00900 RGN_CFLOW_MGR* cflow_info) {
00901 if (src != _targ) {
00902
00903 BB_VECTOR* bb_vect ;
00904
00905 bb_vect = its_info->Get_Cutting_Set ();
00906 for (BB_VECTOR_ITER iter = bb_vect->begin() ;
00907 iter != bb_vect->end (); iter++) {
00908
00909 if (!IPFEC_Glos_Motion_Across_Calls &&
00910 BB_call(*iter)) {
00911 return FALSE ;
00912 }
00913 }
00914
00915 bb_vect = its_info->Move_Across_Or_Around_BBs ();
00916 for (BB_VECTOR_ITER iter = bb_vect->begin () ;
00917 iter != bb_vect->end () ; iter ++) {
00918
00919 if (!IPFEC_Glos_Motion_Across_Calls &&
00920 BB_call(*iter) &&
00921
00922
00923
00924 !IPFEC_Glos_Enable_P_Ready_Code_Motion) {
00925 return FALSE ;
00926 }
00927 }
00928
00929
00930
00931
00932
00933
00934 REACH_PROB rp = cflow_info->Reachable_Prob (_targ,src);
00935 if (rp < SAFE_CNTL_SPEC_PROB &&
00936 rp < UNSAFE_CNTL_SPEC_PROB) {
00937 return FALSE;
00938 }
00939
00940
00941 }
00942
00943 return TRUE ;
00944 }
00945
00946
00947
00948
00949
00950
00951
00952
00953
00954
00955
00956
00957
00958
00959 void
00960 SRC_BB_MGR :: _find_src_bbs (REGION* rgn,
00961 REGIONAL_CFG_NODE* n,
00962 RGN_CFLOW_MGR* cflow_info) {
00963
00964 Is_True (n->Region_Node () == rgn,
00965 ("n->Region_Node and rgn(%d) does not match !",rgn->Id()));
00966
00967 if (BS_MemberP (_find_src_bbs_access_rgns, rgn->Id())) {
00968 return ;
00969 }
00970
00971 _find_src_bbs_access_rgns =
00972 BS_Union1D (_find_src_bbs_access_rgns, rgn->Id(), _mp);
00973
00974 for (CFG_SUCC_NODE_ITER succ_iter(n);
00975 succ_iter != 0;
00976 ++succ_iter) {
00977
00978 if ((*succ_iter)->Is_Region ()) {
00979 REGION* r = (*succ_iter)->Region_Node ();
00980 _find_src_bbs(r, *succ_iter, cflow_info);
00981 } else {
00982 _find_src_bbs ((*succ_iter)->BB_Node (),cflow_info);
00983 }
00984 }
00985 }
00986
00987
00988
00989
00990
00991
00992
00993
00994
00995
00996
00997 void
00998 SRC_BB_MGR :: _find_src_bbs (BB* src, RGN_CFLOW_MGR* cflow_info) {
00999
01000 _find_src_bbs_access_bbs =
01001 BB_SET_Union1D (_find_src_bbs_access_bbs, src,_mp);
01002
01003
01004 if (_prepass) {
01005 if (BB_entry (src) || BB_exit(src)) {
01006 return ;
01007 }
01008 }
01009
01010
01011
01012
01013 if (BB_Is_Isolated_From_Sched (src)) return ;
01014
01015 SRC_BB_INFO* bb_info = CXX_NEW (SRC_BB_INFO(_mp), _mp);
01016 bb_info->Set_Src_BB (src);
01017 bb_info->Set_Target_BB (_targ);
01018
01019 if (!_compute_cutting_set (src, bb_info,cflow_info) ||
01020 !_src_bb_is_qualified (src, bb_info,cflow_info)) {
01021 return ;
01022 }
01023
01024
01025
01026
01027
01028 if (src != _targ) {
01029
01030 Determine_BB_Can_Donate_P_Ready_Cand_Or_Not
01031 (bb_info,cflow_info) ;
01032
01033 }
01034
01035 _src_bbs_set = BB_SET_Union1D (_src_bbs_set, src,_mp);
01036 _src_bbs_vect.push_back (src);
01037 _src_info_vect.push_back (bb_info);
01038
01039 if (!_scope) {
01040
01041
01042
01043
01044
01045
01046 Is_True (src == _targ,
01047 ("BB:%d should not donate candidte to BB:%d!",
01048 BB_id(src), BB_id(_targ)));
01049 return ;
01050 }
01051
01052
01053
01054
01055
01056 for (CFG_SUCC_NODE_ITER succ_iter(Regional_Cfg_Node(src));
01057 succ_iter != 0;
01058 ++succ_iter)
01059 {
01060 if ((*succ_iter)->Is_Region()) {
01061
01062 REGION * r = (*succ_iter)->Region_Node ();
01063 _find_src_bbs(r, *succ_iter, cflow_info);
01064 _find_src_bbs_access_rgns =
01065 BS_Union1D (_find_src_bbs_access_rgns, r->Id(), _mp);
01066
01067 } else {
01068
01069 BB * succ_bb = (*succ_iter)->BB_Node();
01070 if (BB_SET_MemberP (_find_src_bbs_access_bbs, succ_bb)) {
01071 continue ;
01072 }
01073
01074 _find_src_bbs_access_bbs =
01075 BB_SET_Union1D (_find_src_bbs_access_bbs, succ_bb,_mp);
01076
01077 if (BB_exit (succ_bb) || BB_Is_Isolated_From_Sched (succ_bb)) {
01078 continue ;
01079 }
01080
01081 _find_src_bbs (succ_bb, cflow_info) ;
01082 }
01083 }
01084 }
01085
01086
01087
01088
01089
01090
01091
01092
01093
01094
01095
01096 const BB_VECTOR *
01097 SRC_BB_MGR::Find_Src_BBs (REGION * scope , BB* targ,
01098 RGN_CFLOW_MGR * cflow_info,
01099 BOOL prepass)
01100 {
01101 Is_True (!BB_Is_Isolated_From_Sched (targ),
01102 ("BB:%d is isolated from schedule", BB_id(targ)));
01103
01104 _src_bbs_vect.clear ();
01105 _src_info_vect.clear ();
01106 _src_bbs_set = BB_SET_ClearD (_src_bbs_set);
01107
01108 _targ = targ ;
01109 _scope = scope ;
01110 _prepass = prepass;
01111
01112 _find_src_bbs_access_bbs = BB_SET_ClearD (_find_src_bbs_access_bbs);
01113 _find_src_bbs_access_rgns = BS_ClearD (_find_src_bbs_access_rgns);
01114
01115 _find_src_bbs (targ, cflow_info);
01116
01117 return &_src_bbs_vect;
01118 }
01119
01120
01121
01122
01123
01124
01125
01126
01127
01128
01129
01130
01131
01132
01133 inline BS *
01134 SRC_BB_MGR :: _ubs_union1d (BS * Bitset, BB * bb) {
01135 return BS_Union1D (Bitset, BB_id(bb),_mp);
01136 }
01137
01138 inline BS *
01139 SRC_BB_MGR :: _ubs_union1d (BS * Bitset, REGION *r, INT32 rgn_id_base) {
01140 return BS_Union1D (Bitset, r->Id () + rgn_id_base,_mp);
01141 }
01142
01143 inline BS *
01144 SRC_BB_MGR :: _ubs_union1d
01145 (BS *Bitset, REGIONAL_CFG_NODE *n, INT32 rgn_base_id) {
01146
01147 if (n->Is_Region ()) {
01148 return _ubs_union1d (Bitset, n->Region_Node(),
01149 rgn_base_id);
01150 }
01151
01152 return _ubs_union1d (Bitset, n->BB_Node()) ;
01153 }
01154
01155
01156 inline BS *
01157 SRC_BB_MGR :: _ubs_diff1d (BS * Bitset, BB * bb) {
01158 return BS_Difference1D (Bitset, BB_id(bb)) ;
01159 }
01160
01161 inline BS *
01162 SRC_BB_MGR :: _ubs_diff1d (BS * Bitset, REGION *r,
01163 INT32 rgn_id_base) {
01164 return BS_Difference1D (Bitset, r->Id () + rgn_id_base);
01165 }
01166
01167 inline BS *
01168 SRC_BB_MGR :: _ubs_diff1d (BS * Bitset, REGIONAL_CFG_NODE *n,
01169 INT32 rgn_id_base) {
01170
01171 if (n->Is_Region ()) {
01172 return _ubs_diff1d (Bitset, n->Region_Node (), rgn_id_base);
01173 }
01174
01175 return _ubs_diff1d (Bitset, n->BB_Node());
01176 }
01177
01178
01179 inline BOOL
01180 SRC_BB_MGR :: _ubs_memberp (BS * Bitset, BB *b) {
01181 return BS_MemberP (Bitset, BB_id(b));
01182 }
01183
01184 inline BOOL
01185 SRC_BB_MGR :: _ubs_memberp (BS * Bitset, REGION *r, INT32 rgn_id_base) {
01186 return BS_MemberP (Bitset, r->Id() + rgn_id_base);
01187 }
01188
01189 inline BOOL
01190 SRC_BB_MGR :: _ubs_memberp (BS *Bitset, REGIONAL_CFG_NODE *n,
01191 INT32 rgn_base_id) {
01192
01193 if (n->Is_Region ()) {
01194 return _ubs_memberp (Bitset, n->Region_Node(), rgn_base_id);
01195 }
01196
01197 return _ubs_memberp (Bitset, n->BB_Node());
01198 }
01199
01200
01201
01202
01203
01204
01205
01206
01207
01208
01209
01210
01211
01212
01213
01214
01215 BOOL
01216 SRC_BB_MGR::_compute_cutting_set (BB * src, SRC_BB_INFO *src_info,
01217 RGN_CFLOW_MGR * cflow_info) {
01218 src_info->Get_Cutting_Set () -> clear () ;
01219 src_info->Move_Across_Or_Around_BBs () -> clear ();
01220 src_info->Move_Across_Or_Around_Nested_Rgns ()->clear ();
01221
01222 if (_targ == src) {
01223
01224 src_info->Set_Src_BB (src) ;
01225 src_info->Get_Cutting_Set ()->push_back (src);
01226
01227 return TRUE;
01228 }
01229
01230
01231 const INT32 rgn_id_base = cflow_info->Max_BB_Id () + 1;
01232
01233
01234
01235 NODE_VECTOR visited_nodes_v(_mp);
01236 BS * visited_nodes_bs = BS_Create_Empty (
01237 cflow_info->Max_BB_Id () +
01238 cflow_info->Max_Rgn_Id () + 2,
01239 _mp);
01240
01241
01242
01243 BB_VECTOR across_bbs (_mp);
01244 REGION_VECTOR across_rgns (_mp);
01245
01246
01247
01248
01249 BS* siss_node_set = BS_Create_Empty (
01250 cflow_info->Max_BB_Id () +
01251 cflow_info->Max_Rgn_Id () + 2,
01252 _mp);
01253
01254
01255 visited_nodes_v.push_back (::Regional_Cfg_Node(src));
01256 visited_nodes_bs = _ubs_union1d (visited_nodes_bs, src);
01257
01258
01259 siss_node_set = _ubs_union1d (siss_node_set, src);
01260
01261 while (!_ubs_memberp (siss_node_set, _targ)) {
01262
01263 BOOL changed = TRUE;
01264 while (changed) {
01265
01266
01267
01268 changed = FALSE ;
01269
01270 for (INT32 vect_idx = 0 ;
01271 vect_idx < visited_nodes_v.size() ;
01272 vect_idx ++) {
01273
01274 REGIONAL_CFG_NODE * member = visited_nodes_v[vect_idx];
01275 if (!_ubs_memberp(siss_node_set, member, rgn_id_base)) {
01276
01277
01278
01279
01280
01281
01282
01283
01284 continue ;
01285 }
01286
01287 if (!member->Is_Region ()) {
01288
01289 BB * b = member->BB_Node ();
01290
01291 if (b == _targ) { continue ; }
01292
01293 if (!cflow_info->BB1_Reachable_From_BB2(b,_targ) &&
01294 !BB_Is_Isolated_From_Sched (b)) {
01295 continue ;
01296 }
01297 }
01298
01299
01300
01301
01302 siss_node_set = _ubs_diff1d(siss_node_set,
01303 member,
01304 rgn_id_base);
01305 changed = TRUE;
01306
01307
01308 for (CFG_PRED_NODE_ITER pred_iter(member);
01309 pred_iter != 0;
01310 ++pred_iter) {
01311
01312 if (_ubs_memberp (visited_nodes_bs,
01313 *pred_iter,
01314 rgn_id_base)) {
01315 continue ;
01316 }
01317
01318 visited_nodes_bs =
01319 _ubs_union1d (visited_nodes_bs, *pred_iter,rgn_id_base);
01320
01321 visited_nodes_v.push_back (*pred_iter);
01322 siss_node_set = _ubs_union1d (siss_node_set,
01323 *pred_iter,
01324 rgn_id_base);
01325
01326 if ((*pred_iter)->Is_Region ()) {
01327
01328
01329
01330 REGION * r = (*pred_iter)->Region_Node () ;
01331
01332 if (!IPFEC_Glos_Code_Motion_Across_Nested_Rgn ||
01333 No_OP_Can_be_Moved_Across_Region (r)) {
01334 return FALSE;
01335 }
01336
01337
01338
01339
01340 if (cflow_info->BB_Reachable_From_RGN (_targ, r)) {
01341 return FALSE ;
01342 }
01343
01344 across_rgns.push_back ((*pred_iter)->Region_Node());
01345
01346 } else {
01347
01348 BB * pred_bb = (*pred_iter)->BB_Node () ;
01349 if (BB_Is_Isolated_From_Sched (pred_bb)) {
01350 return FALSE;
01351 }
01352
01353 across_bbs.push_back ((*pred_iter)->BB_Node());
01354 }
01355
01356 }
01357
01358 }
01359
01360 }
01361
01362 }
01363
01364
01365
01366 BB_VECTOR * siss_p = src_info->Get_Cutting_Set ();
01367 BB_VECTOR * across_bbs_p= src_info->Move_Across_Or_Around_BBs ();
01368
01369 for (BB_VECTOR_ITER iter = across_bbs.begin() ;
01370 iter != across_bbs.end () ;
01371 iter ++) {
01372
01373 BB * b = *iter ;
01374 if (_ubs_memberp(siss_node_set, b)) {
01375 siss_p->push_back (b);
01376 } else if (b != src) {
01377 across_bbs_p->push_back (b);
01378 }
01379 }
01380
01381 *(src_info->Move_Across_Or_Around_Nested_Rgns ()) = across_rgns ;
01382
01383 return TRUE;
01384
01385 }
01386
01387
01388
01389
01390
01391
01392
01393
01394
01395
01396
01397 const BB_VECTOR *
01398 SRC_BB_MGR :: Cutting_Set (BB * src) {
01399
01400 Is_True (BB_SET_MemberP (_src_bbs_set, src),
01401 ("BB:%d is not candidate BB of BB:%d", BB_id(src), BB_id(_targ)));
01402
01403 for (SRC_BB_INFO_ITER iter = _src_info_vect.begin () ;
01404 iter != _src_info_vect.end () ; iter ++) {
01405 SRC_BB_INFO * info = *iter ;
01406 if (info->Source_BB () == src) {
01407 return info->Get_Cutting_Set ();
01408 }
01409 }
01410
01411 Is_True (FALSE, ("Fail to find BB-info for BB:%d", BB_id(src)));
01412
01413 }
01414
01415
01416
01417
01418
01419
01420
01421
01422
01423 const BB_VECTOR *
01424 SRC_BB_MGR :: BBs_Between_Cutting_Set_and_Src (BB * src) {
01425
01426 Is_True (BB_SET_MemberP (_src_bbs_set, src),
01427 ("BB:%d is not candidate BB of BB:%d", BB_id(src), BB_id(_targ)));
01428
01429 for (SRC_BB_INFO_ITER iter = _src_info_vect.begin () ;
01430 iter != _src_info_vect.end () ; iter ++) {
01431
01432 SRC_BB_INFO* info = *iter ;
01433 if (info->Source_BB () == src) {
01434 return info->Move_Across_Or_Around_BBs ();
01435 }
01436
01437 }
01438
01439 Is_True (FALSE, ("Fail to find BB-info for BB:%d", BB_id(src)));
01440
01441 }
01442
01443
01444
01445
01446
01447
01448
01449
01450
01451
01452
01453 const REGION_VECTOR*
01454 SRC_BB_MGR :: Move_Across_Or_Around_Rgns (BB *src) {
01455
01456 Is_True (BB_SET_MemberP (_src_bbs_set, src),
01457 ("BB:%d is not candidate BB of BB:%d", BB_id(src), BB_id(_targ)));
01458
01459 for (SRC_BB_INFO_ITER iter = _src_info_vect.begin () ;
01460 iter != _src_info_vect.end () ; iter++) {
01461
01462 SRC_BB_INFO * info = *iter ;
01463 if (info->Source_BB () == src) {
01464 return info->Move_Across_Or_Around_Nested_Rgns ();
01465 }
01466 }
01467
01468 Is_True (FALSE, ("Fail to find BB-info for BB:%d", BB_id(src)));
01469 }
01470
01471
01472
01473
01474
01475
01476
01477
01478
01479 SRC_BB_INFO *
01480 SRC_BB_MGR::Get_Src_Info (BB * bb) {
01481
01482 Is_True (Is_Src_BB (bb), ("BB:%d is not Soruce-BB", BB_id(bb)));
01483
01484 for (SRC_BB_INFO_ITER iter = _src_info_vect.begin() ;
01485 iter != _src_info_vect.end() ; iter++) {
01486 if ((*iter)->Source_BB () == bb) {
01487 return *iter;
01488 }
01489 }
01490
01491 Is_True (FALSE, ("fail to find SRC_BB_INFO for BB:%d", BB_id(bb)));
01492 return NULL;
01493
01494 }
01495
01496
01497
01498
01499
01500
01501
01502
01503
01504
01505 BOOL
01506 SRC_BB_MGR::Calc_Cutting_Set_Between_Src_And_Targ
01507 (BB_VECTOR* bbv, BB* src,RGN_CFLOW_MGR* cflow_info) {
01508
01509 bbv->clear ();
01510
01511 if (src == _targ) { return FALSE ;}
01512 Is_True (cflow_info->BB1_Reachable_From_BB2 (src, _targ),
01513 ("BB:%d is not reachable from BB:%d",
01514 BB_id(src), BB_id(_targ)));
01515
01516 REGIONAL_CFG_NODE* node = Regional_Cfg_Node (src);
01517 REGIONAL_CFG_NODE* targ_node = Regional_Cfg_Node (_targ);
01518
01519 while (TRUE) {
01520
01521 REGIONAL_CFG_NODE* t = node->Unique_Pred ();
01522 if (!t) {
01523 for (CFG_PRED_NODE_ITER iter(node); iter != 0; ++iter) {
01524 if ((*iter)->Is_Region ()) {
01525 return FALSE;
01526 }
01527
01528 BB* b = (*iter)->BB_Node ();
01529 if (BB_call(b) || BB_Is_Isolated_From_Sched (b)) {
01530 return FALSE;
01531 }
01532
01533 bbv->push_back (b);
01534 }
01535
01536 return bbv->size() ? TRUE : FALSE;
01537
01538 } else {
01539
01540 node = t;
01541 if (node == targ_node) { return FALSE; }
01542
01543 }
01544
01545 }
01546
01547 FmtAssert (FALSE, ("We should not reach here"));
01548 return FALSE;
01549 }
01550
01551 void
01552 SRC_BB_MGR :: Determine_BB_Can_Donate_P_Ready_Cand_Or_Not
01553 (SRC_BB_INFO* bb_info,
01554 RGN_CFLOW_MGR* cflow_info) {
01555
01556 BB* dest = bb_info->Target_BB ();
01557 BB* src = bb_info->Source_BB ();
01558
01559 bb_info->Set_Cannot_Donate_P_Ready_Cand ();
01560
01561 if (cflow_info->Reachable_Prob (dest, src) <
01562 DONATE_P_READY_CAND_BB_REACH_PROB ||
01563 dest == src) {
01564 return;
01565 }
01566
01567 BB_VECTOR* bv = bb_info->Get_P_Ready_Bookeeping_Blks ();
01568 if (!Calc_Cutting_Set_Between_Src_And_Targ
01569 (bv,bb_info->Source_BB (), cflow_info)) {
01570
01571 return;
01572 }
01573
01574 if (!cflow_info->Path_Info_Is_Valid ()) {
01575 return;
01576 }
01577
01578 if (!IPFEC_Glos_Enable_P_Ready_Code_Motion) {
01579 return;
01580 }
01581
01582 bb_info->Set_Can_Donate_P_Ready_Cand ();
01583 }
01584