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 #include "defs.h"
00032 #include "ipfec_defs.h"
00033 #include "ipfec_options.h"
00034
00035 #include "tracing.h"
00036 #include "errors.h"
00037
00038
00039 #include "op.h"
00040 #include "bb.h"
00041 #include "be_util.h"
00042
00043 #include "mtypes.h"
00044 #include "targ_sim.h"
00045
00046 #include "region.h"
00047
00048 #include "sched_util.h"
00049 #include "sched_path.h"
00050 #include "sched_cflow.h"
00051 #include "scheduler.h"
00052
00053
00054
00055
00056
00057
00058
00059
00060
00061
00062
00063
00064 EXEC_PATH :: EXEC_PATH (EXEC_PATH_ID id,MEM_POOL *mp) :
00065 _mp(mp), _path_node_seq(mp) {
00066
00067 _id = id;
00068 _has_call = _has_nested_rgn = FALSE ;
00069 _bb_num = _nested_rgn_num = 0;
00070 }
00071
00072 EXEC_PATH :: EXEC_PATH (const EXEC_PATH& ep, MEM_POOL *mp) :
00073 _mp(mp),
00074 _path_node_seq (mp) {
00075
00076 _path_node_seq = ep._path_node_seq ;
00077 Setup_Hash () ;
00078
00079 _has_call = ep.Path_Has_Call ();
00080 _has_nested_rgn = ep.Path_Has_Nested_Rgn ();
00081
00082 _bb_num = BB_Node_In_Total ();
00083 _nested_rgn_num = Rgn_Node_In_Total ();
00084 }
00085
00086
00087 EXEC_PATH&
00088 EXEC_PATH :: operator = (const EXEC_PATH& ep) {
00089
00090 FmtAssert (FALSE,("Has yet implemented!"));
00091 return *this ;
00092 }
00093
00094
00095
00096
00097
00098
00099
00100
00101
00102
00103
00104
00105 void
00106 EXEC_PATH :: Append_Path_Segment
00107 (REGIONAL_CFG_EDGE * in_edge, REGIONAL_CFG_NODE *node) {
00108
00109 REGIONAL_CFG_NODE* n = in_edge ? in_edge->Dest () : node ;
00110 float reach_prob ;
00111
00112 if (_path_node_seq.size ()) {
00113
00114 Is_True (node == n && node, ("incoming_edge->Dest () != n"));
00115
00116 reach_prob =
00117 _path_node_seq.back().Prob_From_Root () * in_edge->Prob();
00118
00119 } else {
00120
00121 Is_True (!in_edge, ("in_edge != NULL"));
00122 reach_prob = 1.0f;
00123 }
00124
00125 if (n->Is_Region ()) {
00126 Set_Has_Nested_Rgn ();
00127 Inc_Path_Nested_Rgn_Num ();
00128 } else {
00129 Inc_Path_BB_Num ();
00130 if (BB_call(n->BB_Node())) {
00131 Set_Has_Call ();
00132 }
00133 }
00134
00135 _path_node_seq.push_back (PATH_NODE_INFO(n,in_edge,reach_prob));
00136 Add_Hash (n, _path_node_seq.size() - 1);
00137 }
00138
00139
00140
00141
00142
00143
00144
00145
00146
00147
00148 EXEC_PATH_SET :: EXEC_PATH_SET (MEM_POOL *mp, mINT32 size) {
00149 _mp = mp ;
00150
00151 Is_True (size >= 0, ("size should greater than zero!"));
00152 _size = size;
00153
00154 _bv_words_num =
00155 (UINT32(_size + BV_WORD_SIZE - 1)) >> BV_WORD_SIZE_LOG_2;
00156
00157
00158 if (_bv_words_num <= sizeof(_bv_words)/sizeof(_bv_words[0])) {
00159 _bv = &_bv_words[0];
00160 } else {
00161 _bv = TYPE_MEM_POOL_ALLOC_N (BV_WORD,_mp,_bv_words_num);
00162 }
00163
00164 for (INT i = _bv_words_num - 1; i >= 0; i--) { _bv[i] = 0; }
00165
00166
00167
00168 _msw_mask = Pattern_Word (
00169 (_size % BV_WORD_SIZE) ?
00170 _size % BV_WORD_SIZE : BV_WORD_SIZE,
00171 0);
00172 }
00173
00174
00175
00176 void
00177 EXEC_PATH_SET :: Resize (INT32 new_size) {
00178
00179 Is_True (new_size >= 0, ("negative size(%d)", new_size));
00180
00181 mINT32 wc = (new_size + BV_WORD_SIZE - 1) / BV_WORD_SIZE;
00182 _size = new_size;
00183
00184 if (wc > _bv_words_num) {
00185
00186 BV_WORD * p = TYPE_MEM_POOL_ALLOC_N (BV_WORD,_mp, wc);
00187 for (mINT32 i = wc - 1; i >= 0; i--) {
00188 p[i] = 0 ;
00189 }
00190
00191 for (mINT32 i = _bv_words_num - 1; i >= 0; i--) {
00192 p[i] = _bv[i];
00193 }
00194
00195 _bv = p;
00196
00197 }
00198
00199 _bv_words_num = wc ;
00200
00201 _msw_mask = Pattern_Word (
00202 (_size % BV_WORD_SIZE) ?
00203 _size % BV_WORD_SIZE : BV_WORD_SIZE,
00204 0);
00205
00206 _bv[_bv_words_num - 1] &= _msw_mask ;
00207 }
00208
00209
00210 EXEC_PATH_SET&
00211 EXEC_PATH_SET :: operator = (const EXEC_PATH_SET& ps) {
00212
00213
00214
00215 _size = ps._size ;
00216
00217 _bv_words_num = ps._bv_words_num ;
00218 _bv = (_bv_words_num <= sizeof(_bv_words)/sizeof(_bv_words[0])) ?
00219 &_bv_words[0] :
00220 TYPE_MEM_POOL_ALLOC_N (BV_WORD, _mp, _bv_words_num);
00221
00222 for (INT i = _bv_words_num - 1 ; i >= 0; i--) {
00223 _bv[i] = ps._bv[i];
00224 }
00225
00226 return *this ;
00227 }
00228
00229
00230
00231
00232
00233
00234
00235
00236
00237 BOOL
00238 EXEC_PATH_SET :: Is_Member (EXEC_PATH_ID path) {
00239
00240 if (Path_Id_Is_Valid (path, FALSE)) return FALSE ;
00241
00242 }
00243
00244
00245
00246
00247
00248
00249
00250
00251
00252 void
00253 EXEC_PATH_SET :: Add_Path_Id (const EXEC_PATH_ID path_id) {
00254
00255 if (!Path_Id_Is_Valid (path_id)) return ;
00256
00257 INT32 word_idx, bit_pos;
00258 WordIdx_BitPos (path_id, word_idx, bit_pos);
00259
00260 BV_WORD_Set_Bit (_bv[word_idx], bit_pos);
00261 }
00262
00263 void
00264 EXEC_PATH_SET :: Del_Path_Id (const EXEC_PATH_ID path_id) {
00265
00266 if (!Path_Id_Is_Valid (path_id)) return ;
00267
00268 INT32 word_idx, bit_pos;
00269 WordIdx_BitPos (path_id, word_idx, bit_pos);
00270
00271 BV_WORD_Clear_Bit (_bv[word_idx], bit_pos);
00272 }
00273
00274
00275
00276 EXEC_PATH_SET&
00277 EXEC_PATH_SET :: operator & (const EXEC_PATH_SET& eps) {
00278
00279 Equal_Size (eps, TRUE);
00280
00281 EXEC_PATH_SET *p = CXX_NEW(EXEC_PATH_SET(_mp,_size), _mp);
00282
00283 for (mINT32 i = _bv_words_num - 1; i >= 0; i--) {
00284 p->_bv[i] &= eps._bv[i];
00285 }
00286
00287 return *p ;
00288 }
00289
00290 void
00291 EXEC_PATH_SET :: operator &= (const EXEC_PATH_SET& eps) {
00292
00293 Equal_Size (eps, TRUE);
00294
00295 for (mINT32 i = _bv_words_num - 1; i >= 0; i--) {
00296 _bv[i] &= eps._bv[i];
00297 }
00298 }
00299
00300 EXEC_PATH_SET&
00301 EXEC_PATH_SET :: operator ~ (void) {
00302
00303 EXEC_PATH_SET * p = CXX_NEW(EXEC_PATH_SET(_mp,_size), _mp);
00304
00305 for (mINT32 i = _bv_words_num - 1; i >= 0; i--) {
00306 p->_bv[i] = ~_bv[i];
00307 }
00308
00309 return * p;
00310 }
00311
00312
00313
00314
00315
00316
00317
00318
00319 void
00320 EXEC_PATH_SET :: Bitwise_Not (void) {
00321
00322 for (mINT32 i = _bv_words_num - 1; i >= 0; i--) {
00323 _bv[i] = ~_bv[i];
00324 }
00325
00326 _bv[_bv_words_num-1] &= _msw_mask ;
00327 }
00328
00329
00330
00331
00332
00333
00334
00335
00336
00337 EXEC_PATH_SET&
00338 EXEC_PATH_SET :: operator << (const UINT16 shift_l_by) {
00339
00340 UINT16 d = shift_l_by >> BV_WORD_SIZE_LOG_2;
00341 UINT16 r = shift_l_by % BV_WORD_SIZE;
00342
00343 EXEC_PATH_SET * p = CXX_NEW(EXEC_PATH_SET(_mp,_size), _mp);
00344 *p = *this ;
00345
00346 if (r > 0) {
00347 for (mINT32 i = _bv_words_num - 1; i >= 1 ; i--) {
00348 p->_bv[i] =
00349 (_bv[i] << r) | (_bv[i-1] >> (BV_WORD_SIZE - r));
00350 }
00351
00352 p->_bv[0] = _bv[0] << r;
00353 p->_bv[_bv_words_num - 1] =
00354 _bv[_bv_words_num - 1] & _msw_mask ;
00355 }
00356
00357 if (d == 0) { return * p; }
00358
00359 if (d >= _bv_words_num) {
00360 for (mINT32 i = _bv_words_num - 1; i >= d; i--) {
00361 p->_bv[i] = 0;
00362 }
00363 } else {
00364
00365 for (mINT32 i = _bv_words_num - 1; i >= d; i--) {
00366 p->_bv[i] = _bv[i-d];
00367 }
00368
00369 p->_bv[_bv_words_num - 1] &= _msw_mask ;
00370 }
00371
00372 return *p;
00373 }
00374
00375
00376
00377
00378
00379
00380
00381 void
00382 EXEC_PATH_SET :: operator <<= (const UINT16 shift_l_by) {
00383
00384 UINT16 d = shift_l_by >> BV_WORD_SIZE_LOG_2;
00385 UINT16 r = shift_l_by % BV_WORD_SIZE;
00386
00387 if (r > 0) {
00388 for (mINT32 i = _bv_words_num - 1; i >= 1 ; i--) {
00389 _bv[i] = BV_WORD_SHIFT_RIGHT(_bv[i],r) |
00390 BV_WORD_SHIFT_LEFT (_bv[i-1],BV_WORD_SIZE - r);
00391 }
00392
00393 _bv[0] = BV_WORD_SHIFT_LEFT (_bv[0],r);
00394 _bv[_bv_words_num - 1] &= _msw_mask ;
00395 }
00396
00397 if (d == 0) { return ; }
00398
00399 if (d >= _bv_words_num) {
00400 for (mINT32 i = _bv_words_num - 1; i >= d; i--) {
00401 _bv[i] = 0;
00402 }
00403 } else {
00404 for (mINT32 i = _bv_words_num - 1; i >= d; i--) {
00405 _bv[i] = _bv[i-d];
00406 }
00407 _bv[_bv_words_num - 1] &= _msw_mask ;
00408 }
00409
00410 }
00411
00412
00413
00414
00415
00416
00417
00418 EXEC_PATH_SET&
00419 EXEC_PATH_SET :: operator >> (const UINT16 shift_r_by) {
00420
00421 FmtAssert (FALSE,("Has not yet implemented!"));
00422 return *this;
00423 }
00424
00425 void
00426 EXEC_PATH_SET :: operator >>= (const UINT16 shift_r_by) {
00427 FmtAssert (FALSE,("Has not yet implemented!"));
00428 }
00429
00430
00431
00432
00433
00434
00435
00436 EXEC_PATH_SET&
00437 EXEC_PATH_SET :: operator | (const EXEC_PATH_SET& eps) {
00438
00439 Equal_Size (eps, TRUE);
00440
00441 EXEC_PATH_SET * p = CXX_NEW (EXEC_PATH_SET(_mp,_size), _mp);
00442
00443 for (mINT32 i = _bv_words_num - 1; i >= 0 ; i--) {
00444 p->_bv[i] = _bv[i] | eps._bv[i];
00445 }
00446
00447 return *p;
00448 }
00449
00450 void
00451 EXEC_PATH_SET :: operator |= (const EXEC_PATH_SET& eps) {
00452
00453 Equal_Size (eps, TRUE);
00454
00455 for (mINT32 i = _bv_words_num - 1; i >= 0 ; i--) {
00456 _bv[i] = _bv[i] | eps._bv[i];
00457 }
00458 }
00459
00460
00461
00462 EXEC_PATH_SET&
00463 EXEC_PATH_SET :: Universe (void) {
00464
00465 EXEC_PATH_SET * p = CXX_NEW(EXEC_PATH_SET(_mp,_size), _mp);
00466
00467 for (mINT32 i = _bv_words_num - 1; i >= 0; i--) {
00468 p->_bv[i] = (BV_WORD)(-1);
00469 }
00470
00471 p->_bv[0] &= _msw_mask ;
00472
00473 return *p ;
00474 }
00475
00476 void
00477 EXEC_PATH_SET :: Set_To_Be_Universe (void) {
00478
00479 for (mINT32 i = _bv_words_num - 1; i >= 0; i--) {
00480 _bv[i] = (BV_WORD)(-1);
00481 }
00482 _bv[_bv_words_num - 1] &= _msw_mask ;
00483 }
00484
00485
00486
00487
00488
00489
00490
00491
00492
00493 EXEC_PATH_SET&
00494 EXEC_PATH_SET :: Subset (EXEC_PATH_ID from, EXEC_PATH_ID to) {
00495
00496 Is_True (from <= to,
00497 ("Low-boudary(%d) > up-boundary(%d)", from, to));
00498
00499 from = min(from,_size-1);
00500 to = max(0, to);
00501
00502
00503
00504 EXEC_PATH_SET * p = CXX_NEW(EXEC_PATH_SET(_mp,_size),_mp);
00505
00506 for (mINT32 i = from/BV_WORD_SIZE - 1; i >= 0 ; i--) {
00507 p->_bv[i] = 0;
00508 }
00509 p->_bv[0] &= Pattern_Word (_size % BV_WORD_SIZE,0);
00510
00511
00512
00513 for (mINT32 i = to/BV_WORD_SIZE; i <= _bv_words_num - 1; i++) {
00514 p->_bv[i] = 0 ;
00515 }
00516 p->_bv[_bv_words_num-1] &=
00517 Pattern_Word (_size % BV_WORD_SIZE, 0);
00518
00519 return * p;
00520 }
00521
00522
00523
00524
00525
00526
00527
00528
00529
00530 BOOL
00531 EXEC_PATH_SET :: Is_Subset_Of (EXEC_PATH_SET* eps) {
00532
00533 Equal_Size (*eps, TRUE);
00534
00535 for (mINT32 i = _bv_words_num - 1; i >= 0; i--) {
00536 if ((_bv[i] & eps->_bv[i]) != _bv[i]) {
00537 return FALSE;
00538 }
00539 }
00540
00541 return TRUE;
00542 }
00543
00544
00545
00546
00547
00548
00549
00550
00551
00552
00553 BOOL
00554 EXEC_PATH_SET :: Intersection_Is_Empty (EXEC_PATH_SET* eps) {
00555
00556 Equal_Size (*eps, TRUE);
00557
00558 for (mINT32 i = _bv_words_num - 1; i >= 0; i--) {
00559 if (_bv[i] & eps->_bv[i]) {
00560 return FALSE;
00561 }
00562 }
00563
00564 return TRUE;
00565 }
00566
00567
00568
00569
00570
00571
00572
00573
00574
00575
00576
00577 EXEC_PATH_ID
00578 EXEC_PATH_SET :: First_Path_Id (void) {
00579
00580 mINT32 idx = -1;
00581 for (mINT32 i = 0 ; i < _bv_words_num ; i++) {
00582 if (_bv[i] != 0) { idx = i; break; }
00583 }
00584
00585 if (idx == _bv_words_num) return INVALID_EXEC_PATH_ID;
00586
00587 BV_WORD w = _bv[idx];
00588 EXEC_PATH_ID pos = idx * BV_WORD_SIZE;
00589
00590 while (!(w&1)) { w >>= 1; ++pos; }
00591 return pos;
00592 }
00593
00594
00595
00596
00597
00598
00599
00600
00601
00602
00603
00604
00605
00606
00607
00608 EXEC_PATH_ID
00609 EXEC_PATH_SET :: Next_Path_Id
00610 (EXEC_PATH_ID path, BOOL check_membership) {
00611
00612 if (!Path_Id_Is_Valid (path, check_membership)) {
00613 return INVALID_EXEC_PATH_ID;
00614 }
00615
00616 INT32 wd_idx, bp;
00617 WordIdx_BitPos (path, wd_idx,bp);
00618
00619
00620
00621 if (check_membership &&
00622 !BV_WORD_Test_Bit (_bv[wd_idx], bp)) {
00623
00624 FmtAssert (FALSE, ("path(%d) is not a member of this set", path));
00625
00626 }
00627
00628 BV_WORD w = BV_WORD_SHIFT_RIGHT(_bv[wd_idx], bp + 1);
00629
00630 if (w) {
00631 bp ++ ;
00632 } else {
00633
00634
00635
00636 if (_bv_words_num == wd_idx) {
00637
00638
00639
00640 return INVALID_EXEC_PATH_ID;
00641 }
00642
00643 bp = 0;
00644 for (wd_idx ++; wd_idx < _bv_words_num ; wd_idx ++) {
00645
00646 w = _bv[wd_idx];
00647 if (w) break ;
00648 }
00649
00650 if (wd_idx >= _bv_words_num) {
00651 return INVALID_EXEC_PATH_ID;
00652 }
00653 }
00654
00655
00656
00657 while (!(w&1)) { w >>= 1; ++ bp ; }
00658
00659 return wd_idx * BV_WORD_SIZE + bp;
00660 }
00661
00662
00663
00664
00665
00666
00667
00668
00669
00670 EXEC_PATH_ID
00671 EXEC_PATH_SET :: Last_Path_Id (void) {
00672
00673 FmtAssert (FALSE,("Sorry, this routines has yet been implemented"));
00674
00675 return 0;
00676 }
00677
00678
00679
00680
00681
00682
00683
00684
00685
00686 EXEC_PATH_ID
00687 EXEC_PATH_SET :: Prev_Path_Id
00688 (EXEC_PATH_ID path, BOOL check_membership) {
00689
00690 FmtAssert (FALSE,("Sorry, this routines has yet been implemented"));
00691
00692 return 0;
00693
00694 }
00695
00696
00697
00698
00699
00700
00701
00702
00703
00704
00705
00706 BOOL
00707 EXEC_PATH_SET::There_Are_Continguous_Path_Id
00708 (EXEC_PATH_ID begin_path_id, INT32 length) {
00709
00710 Is_True (length > 0,
00711 ("length(%d) should be no less than 1", length));
00712
00713 mINT32 start_wd_idx, start_bp;
00714 mINT32 end_wd_idx, end_bp;
00715
00716 WordIdx_BitPos (begin_path_id, start_wd_idx, start_bp);
00717 WordIdx_BitPos (begin_path_id + length - 1, end_wd_idx, end_bp);
00718
00719 BV_WORD w;
00720 if (start_wd_idx == end_wd_idx) {
00721 w = Pattern_Word (length, start_bp);
00722 return (_bv[end_wd_idx] & w) == w;
00723 }
00724
00725 w = Pattern_Word (BV_WORD_SIZE - start_bp, start_bp);
00726 if ((_bv[start_wd_idx] & w) != w) {
00727 return FALSE ;
00728 }
00729
00730 for (mINT32 i = start_wd_idx + 1; i < end_wd_idx ; i++) {
00731 if (_bv[i] != (BV_WORD)-1) return FALSE;
00732 }
00733
00734 w = Pattern_Word (end_bp + 1, 0);
00735
00736 return (_bv[end_wd_idx] & w) == w ;
00737 }
00738
00739
00740
00741
00742
00743
00744
00745
00746
00747
00748 void
00749 EXEC_PATH_SET :: Union_Range_Inclusively
00750 (EXEC_PATH_ID from, EXEC_PATH_ID to) {
00751
00752
00753
00754 Path_Id_Is_Valid (from, TRUE);
00755 Path_Id_Is_Valid (to, TRUE);
00756 Is_True (from <= to, ("from (%d) > to(%d)", from, to));
00757
00758 INT32 from_word_idx, to_word_idx, from_bitpos, to_bitpos;
00759
00760 WordIdx_BitPos (from, from_word_idx, from_bitpos);
00761 WordIdx_BitPos (to, to_word_idx, to_bitpos);
00762
00763 if (from_word_idx == to_word_idx) {
00764
00765 _bv[from_word_idx] |=
00766 Pattern_Word (to_bitpos - from_bitpos + 1, from_bitpos);
00767
00768 return ;
00769 }
00770
00771 _bv[from_word_idx] |=
00772 Pattern_Word (BV_WORD_SIZE - from_bitpos, from_bitpos);
00773
00774 for (mINT32 i = from_word_idx + 1 ; i < to_word_idx; i ++) {
00775 _bv[i] = (BV_WORD)(-1);
00776 }
00777
00778 _bv[to_word_idx] |= Pattern_Word (to_bitpos + 1, 0);
00779 }
00780
00781
00782
00783
00784
00785
00786
00787 EXEC_PATH_SET&
00788 EXEC_PATH_SET:: operator - (const EXEC_PATH_SET& eps) {
00789
00790 Equal_Size (eps, TRUE);
00791
00792 EXEC_PATH_SET * p = CXX_NEW(EXEC_PATH_SET(_mp,_size),_mp);
00793 * p = *this ;
00794
00795 p->Bitwise_Not ();
00796 *p &= *this;
00797
00798 return *p;
00799 }
00800
00801 void
00802 EXEC_PATH_SET :: operator -= (const EXEC_PATH_SET& eps) {
00803
00804 Equal_Size (eps, TRUE);
00805
00806 for (mINT32 i = _bv_words_num - 1; i >= 0 ; i--) {
00807 _bv[i] &= ~eps._bv[i];
00808 }
00809 }
00810
00811
00812
00813
00814
00815
00816
00817
00818
00819
00820
00821
00822 void
00823 EXEC_PATH_SET :: Union_Partioned_Path_Set
00824 (EXEC_PATH_SET& eps, INT32 pred_path_num,
00825 INT32 succ_path_num, INT32 base) {
00826
00827 EXEC_PATH_SET p = eps ;
00828 INT32 path_id = eps.First_Path_Id ();
00829
00830 while (!EXEC_PATH_ID_IS_INVALID(path_id)) {
00831
00832 #ifdef Is_True_On
00833 if (!eps.There_Are_Continguous_Path_Id (path_id, pred_path_num)) {
00834 Is_True (FALSE,
00835 ("There should be %d number of continous '1' bits",
00836 pred_path_num));
00837 }
00838 #endif
00839
00840 Union_Range_Inclusively
00841 (path_id + base, path_id + base + succ_path_num - 1);
00842
00843 path_id += (pred_path_num - 1);
00844 path_id = eps.Next_Path_Id (path_id, FALSE);
00845 }
00846 }
00847
00848
00849
00850
00851
00852
00853
00854
00855
00856 EXEC_PATH_MGR :: EXEC_PATH_MGR (MEM_POOL *mp) :
00857 _mp(mp), _pathv(mp),
00858 _ep_node_info (mp) {
00859
00860 _path_info_invalid = TRUE;
00861 _total_paths = 0;
00862 }
00863
00864
00865 EXEC_PATH_MGR&
00866 EXEC_PATH_MGR :: operator = (EXEC_PATH_MGR& epm) {
00867
00868
00869
00870 FmtAssert (FALSE,("Copying a 'manager' is not allowed"));
00871
00872 return *this ;
00873 }
00874
00875
00876
00877
00878
00879
00880
00881
00882
00883
00884
00885
00886
00887
00888
00889
00890
00891
00892
00893
00894
00895
00896
00897
00898
00899
00900
00901 INT32
00902 EXEC_PATH_MGR :: Calc_Subgraph_Path_Num (void) {
00903
00904 REGIONAL_CFG_NODE * n = NULL ;
00905 EP_NODE_INFO * ni = NULL ;
00906
00907 for (REVERSE_TOPO_REGIONAL_CFG_ITER riter(_region->Regional_Cfg());
00908 riter != 0 ;
00909 ++riter) {
00910 n = *riter ;
00911 ni = (EP_NODE_INFO *)_ep_node_info.Get_Map (n);
00912
00913 ni->subgraph_path_num = 0;
00914
00915 for (CFG_SUCC_NODE_ITER succs(n) ; succs != 0 ; ++succs) {
00916 REGIONAL_CFG_NODE * s = *succs ;
00917 EP_NODE_INFO * si = (EP_NODE_INFO*)_ep_node_info.Get_Map (s);
00918 ni->subgraph_path_num += si->subgraph_path_num;
00919 }
00920
00921 mINT32 tmp = ni->subgraph_path_num;
00922 if (!tmp) {
00923
00924
00925 ni->subgraph_path_num = 1;
00926 } else if (tmp > MAX_PATH_NUM) {
00927 _path_info_invalid = TRUE;
00928 return -1;
00929 }
00930 }
00931
00932
00933
00934 Is_True (ni, ("we got an empty REGION(%d)", _region->Id()));
00935 return ni->subgraph_path_num;
00936 }
00937
00938
00939
00940
00941
00942
00943
00944
00945
00946
00947 INT32
00948 EXEC_PATH_MGR :: Acquire_Path_Info (REGION *r) {
00949
00950 _region = r ;
00951 if (!r) { return 0 ; }
00952
00953
00954
00955
00956
00957
00958 _ep_node_info.Initialize_Map (_region);
00959 for (TOPOLOGICAL_REGIONAL_CFG_ITER iter(_region->Regional_Cfg()) ;
00960 iter != 0 ; ++iter) {
00961
00962 REGIONAL_CFG_NODE * n = *iter ;
00963 EP_NODE_INFO* t=CXX_NEW(EP_NODE_INFO(n,_mp),_mp);
00964 _ep_node_info.Set_Map (n,t);
00965
00966 }
00967
00968
00969
00970 mINT32 total_path_num = Calc_Subgraph_Path_Num ();
00971 if (total_path_num >= 0) {
00972 _total_paths = total_path_num;
00973 } else {
00974 _path_info_invalid = TRUE;
00975 return -1;
00976 }
00977
00978
00979
00980
00981
00982
00983
00984
00985 for (TOPOLOGICAL_REGIONAL_CFG_ITER iter(_region->Regional_Cfg()) ;
00986 iter != 0; ++iter) {
00987 EP_NODE_INFO * ni = (EP_NODE_INFO*) _ep_node_info.Get_Map (*iter);
00988 ni->eps.Resize (total_path_num);
00989 }
00990
00991
00992
00993 NODE_VECTOR rnv = _region->Entries () ;
00994 Is_True (rnv.size() == 1,
00995 ("_region(id:%d) has more than one entries!"));
00996 REGIONAL_CFG_NODE * unique_root = rnv[0];
00997
00998 ((EP_NODE_INFO*) _ep_node_info.Get_Map (unique_root))
00999 -> eps.Set_To_Be_Universe ();
01000
01001
01002
01003
01004 _pathv.resize (total_path_num);
01005 for (INT i = 0 ; i < total_path_num; i ++) {
01006 _pathv[i] = CXX_NEW(EXEC_PATH(EXEC_PATH_ID(i),_mp),_mp);
01007 _pathv[i] -> Append_Path_Segment (NULL, unique_root);
01008 }
01009
01010
01011
01012
01013
01014 for (TOPOLOGICAL_REGIONAL_CFG_ITER iter(_region->Regional_Cfg()) ;
01015 iter != 0 ; ++iter) {
01016
01017 INT32 alloc_base = 0;
01018 EP_NODE_INFO * nd_info =
01019 (EP_NODE_INFO*) _ep_node_info.Get_Map (*iter);
01020 EXEC_PATH_SET * nd_eps = &nd_info->eps;
01021
01022 for (REGIONAL_CFG_EDGE * e = (*iter)->First_Succ () ;
01023 NULL != e;
01024 e = e->Next_Succ ()) {
01025
01026 REGIONAL_CFG_NODE * succ = e->Dest ();
01027 EP_NODE_INFO * succ_info =
01028 (EP_NODE_INFO*) _ep_node_info.Get_Map (e->Dest ());
01029 EXEC_PATH_SET * succ_eps = &succ_info->eps;
01030
01031
01032
01033
01034 succ_eps->Union_Partioned_Path_Set (
01035 nd_info -> eps,
01036 nd_info -> subgraph_path_num,
01037 succ_info -> subgraph_path_num,
01038 alloc_base);
01039
01040
01041
01042
01043
01044
01045
01046
01047
01048
01049
01050
01051
01052
01053
01054
01055
01056
01057 alloc_base += succ_info -> subgraph_path_num;
01058 }
01059 }
01060
01061 _path_info_invalid = FALSE;
01062
01063 return total_path_num;
01064 }
01065
01066
01067
01068
01069
01070
01071
01072
01073
01074
01075 EXEC_PATH_SET*
01076 EXEC_PATH_MGR :: Get_Path_Flow_Thru (BB* bb) {
01077
01078 Is_True (!Path_Info_Is_Invalid (),
01079 ("execution path information does not collect properly"));
01080
01081 EP_NODE_INFO* t=(EP_NODE_INFO*) _ep_node_info.Get_Map (bb);
01082 return t ? &t->eps : NULL;
01083
01084 }
01085
01086 EXEC_PATH_SET*
01087 EXEC_PATH_MGR :: Get_Path_Flow_Thru (REGION* r) {
01088
01089 Is_True (!Path_Info_Is_Invalid (),
01090 ("execution path information does not collect properly"));
01091
01092 EP_NODE_INFO* t=(EP_NODE_INFO*) _ep_node_info.Get_Map (r);
01093 return t ? &t->eps : NULL;
01094 }
01095
01096
01097
01098
01099
01100
01101
01102
01103
01104
01105
01106 SUB_SEME_EXEC_PATH_MGR :: SUB_SEME_EXEC_PATH_MGR (MEM_POOL * mp) :
01107 _mp(mp), _paths(mp) {
01108
01109 _sub_SEME_root = NULL;
01110 _base_graph = NULL;
01111 }
01112
01113 SUB_SEME_EXEC_PATH_MGR :: ~SUB_SEME_EXEC_PATH_MGR (void) {
01114
01115 }
01116
01117
01118
01119
01120
01121
01122
01123
01124
01125
01126
01127 void
01128 SUB_SEME_EXEC_PATH_MGR :: Derive_Exec_Path_Info
01129 (EXEC_PATH_MGR * exec_path_mgr,
01130 REGIONAL_CFG_NODE* sub_SEME_root) {
01131
01132
01133 }
01134
01135
01136
01137
01138
01139
01140
01141
01142
01143 char * RGN_CFLOW_MGR::_invalid_prompt_msg =
01144 "control flow is invalid!";
01145
01146
01147
01148
01149
01150
01151
01152
01153
01154
01155 void
01156 RGN_CFLOW_MGR::_init_data_member (void) {
01157
01158 _cflow_info_valid = FALSE;
01159 _bb_num = _rgn_num = 0;
01160
01161 _max_bb_id = _min_bb_id = _max_rgn_id = _min_rgn_id = 0;
01162
01163 _scope = NULL ;
01164 _bb_scope = NULL;
01165
01166 _bb_id_2_map_idx_vect = NULL;
01167 _rgn_id_2_map_idx_vect = NULL;
01168 _map_idx_2_bb_vect = NULL;
01169 _map_idx_2_rgn_vect = NULL;
01170
01171 }
01172
01173
01174
01175
01176
01177
01178
01179
01180
01181 void
01182 RGN_CFLOW_MGR::Init (REGION *rgn) {
01183 _init_data_member ();
01184
01185 _scope = rgn ;
01186
01187 _cflow_info_valid = TRUE;
01188 _acquire_cflow_info () ;
01189 }
01190
01191
01192
01193
01194
01195
01196
01197
01198
01199
01200
01201
01202 void
01203 RGN_CFLOW_MGR::Init (BB * bb) {
01204 _init_data_member () ;
01205
01206 _scope = NULL;
01207 _bb_scope = bb ;
01208
01209 _max_bb_id = _min_bb_id = BB_id(bb);
01210 _bb_num = 1;
01211
01212 _cflow_info_valid = TRUE;
01213 }
01214
01215
01216
01217
01218
01219
01220
01221
01222
01223
01224 void
01225 RGN_CFLOW_MGR::_acquire_basic_cflow_info (void) {
01226
01227 _bb_num = _rgn_num = 0 ;
01228 _max_bb_id = _min_bb_id = 0 ;
01229 _max_rgn_id = _min_rgn_id = 0 ;
01230
01231 for (TOPOLOGICAL_REGIONAL_CFG_ITER iter(_scope->Regional_Cfg()) ;
01232 iter != 0 ; ++iter) {
01233 UINT32 node_id ;
01234
01235 if ((*iter)->Is_Region()) {
01236 ++ _rgn_num ;
01237 node_id = (UINT32) (*iter)->Region_Node()->Id() ;
01238 _max_rgn_id = max (_max_rgn_id, node_id) ;
01239 _min_rgn_id = min (_min_rgn_id, node_id) ;
01240 } else {
01241 ++ _bb_num ;
01242 node_id = (UINT32) BB_id((*iter)->BB_Node()) ;
01243 _max_bb_id = max (_max_bb_id, node_id) ;
01244 _min_bb_id = min (_min_bb_id, node_id) ;
01245 }
01246 }
01247 }
01248
01249
01250
01251
01252
01253
01254
01255
01256
01257
01258
01259
01260
01261
01262
01263 void
01264 RGN_CFLOW_MGR::_setup_map_array (void) {
01265
01266 _bb_id_2_map_idx_vect =
01267 _bb_num ? TYPE_MEM_POOL_ALLOC_N (UINT32, &_mem_pool,
01268 1 + _max_bb_id) :
01269 NULL;
01270
01271 _rgn_id_2_map_idx_vect =
01272 _rgn_num ? TYPE_MEM_POOL_ALLOC_N (UINT32, &_mem_pool,
01273 1 + _max_rgn_id) :
01274 NULL;
01275
01276 _map_idx_2_bb_vect =
01277 _bb_num ? TYPE_MEM_POOL_ALLOC_N (BB* , &_mem_pool,
01278 1 + _max_bb_map_idx()) :
01279 NULL;
01280
01281 _map_idx_2_rgn_vect =
01282 _rgn_num ? TYPE_MEM_POOL_ALLOC_N (REGION *, &_mem_pool,
01283 1 + _max_rgn_map_idx()) :
01284 NULL;
01285 }
01286
01287
01288
01289
01290
01291
01292
01293
01294
01295 void
01296 RGN_CFLOW_MGR::_setup_node_cflow_info_array (void) {
01297
01298 INT32 elem_num = _bb_num ? _max_bb_map_idx() + 1 : 0;
01299 if (elem_num) {
01300 _bb_node_cflow_info.resize (elem_num);
01301 } else {
01302 _bb_node_cflow_info.clear ();
01303 }
01304
01305 elem_num = _rgn_num ? _max_rgn_map_idx() + 1 : 0 ;
01306 if (elem_num) {
01307 _rgn_node_cflow_info.resize (elem_num);
01308 } else {
01309 _rgn_node_cflow_info.clear ();
01310 }
01311 }
01312
01313
01314
01315
01316
01317
01318
01319
01320
01321 inline RGN_CFLOW_MGR::_NODE_CFLOW_INFO&
01322 RGN_CFLOW_MGR::_node_cflow_info (BB *bb) {
01323
01324 if (_bb_2_map_idx(bb) >= _bb_node_cflow_info.size()) {
01325 FmtAssert (FALSE,
01326 ("BB:%d's node info has not set up properly",
01327 BB_id(bb)));
01328 }
01329
01330 return _bb_node_cflow_info[_bb_2_map_idx(bb)];
01331
01332 }
01333
01334
01335
01336
01337
01338
01339
01340
01341
01342 inline RGN_CFLOW_MGR::_NODE_CFLOW_INFO&
01343 RGN_CFLOW_MGR::_node_cflow_info (REGION *rgn) {
01344
01345 if (_rgn_2_map_idx(rgn) >= _rgn_node_cflow_info.size ()) {
01346 FmtAssert (FALSE,
01347 ("REGION:%d's node info has not set up properly",
01348 rgn->Id ()));
01349 }
01350
01351 return _rgn_node_cflow_info[_rgn_2_map_idx(rgn)];
01352 }
01353
01354
01355
01356
01357
01358
01359
01360
01361
01362 inline RGN_CFLOW_MGR::_NODE_CFLOW_INFO&
01363 RGN_CFLOW_MGR::_node_cflow_info (REGIONAL_CFG_NODE * node) {
01364
01365 return node->Is_Region () ?
01366 _node_cflow_info (node->Region_Node()) :
01367 _node_cflow_info (node->BB_Node()) ;
01368 }
01369
01370
01371
01372
01373
01374
01375
01376
01377
01378 INT32
01379 RGN_CFLOW_MGR::Max_Level (REGIONAL_CFG_NODE * node) {
01380 Is_True (Valid (), (_invalid_prompt_msg));
01381
01382 return (_node_cflow_info (node)).max_level ;
01383 }
01384
01385 INT32
01386 RGN_CFLOW_MGR::Max_Level (BB * bb) {
01387
01388 Is_True (Valid (), (_invalid_prompt_msg));
01389
01390 if (!_bb_scope) {
01391 return (_node_cflow_info (bb)).max_level ;
01392 } else {
01393 Is_True (bb == _bb_scope, ("not in this scope!"));
01394 return 1;
01395 }
01396 }
01397
01398 INT32
01399 RGN_CFLOW_MGR:: Min_Level (REGIONAL_CFG_NODE * node) {
01400
01401 Is_True (Valid (), (_invalid_prompt_msg));
01402
01403 return (_node_cflow_info (node)).min_level ;
01404 }
01405
01406 INT32
01407 RGN_CFLOW_MGR::Min_Level (BB * bb) {
01408
01409 Is_True (Valid (), (_invalid_prompt_msg));
01410
01411 if (!_bb_scope) {
01412 return (_node_cflow_info (bb)).min_level ;
01413 } else {
01414 Is_True (bb == _bb_scope, ("not in this scope!"));
01415 return 1 ;
01416 }
01417 }
01418
01419
01420
01421
01422
01423
01424
01425
01426
01427
01428 BOOL
01429 RGN_CFLOW_MGR::BB1_Reachable_From_BB2 (BB * bb1, BB* bb2) {
01430 if (bb1 == bb2) return TRUE;
01431
01432 BS * reach_info = _reach_info_vect (bb2) ;
01433 Is_True (reach_info, ("bb's reachable info is not available!")) ;
01434
01435 return BS_MemberP (reach_info, _bb_2_map_idx(bb1));
01436 }
01437
01438
01439
01440
01441
01442
01443
01444
01445
01446
01447
01448 BOOL
01449 RGN_CFLOW_MGR::BB_Reachable_From_RGN (BB * bb, REGION * rgn) {
01450 BS * reach_info = _reach_info_vect (rgn) ;
01451 Is_True (reach_info, ("rgn's reachable info is not available!"));
01452
01453 return BS_MemberP (reach_info, _bb_2_map_idx(bb));
01454 }
01455
01456
01457
01458
01459
01460
01461
01462
01463
01464
01465
01466 inline BS *
01467 RGN_CFLOW_MGR::_reach_info_vect (BB *bb) {
01468
01469 return _node_cflow_info (bb).reach_bb ;
01470 }
01471
01472
01473
01474
01475
01476
01477
01478
01479
01480
01481 inline BS *
01482 RGN_CFLOW_MGR::_reach_info_vect (REGION *rgn) {
01483
01484 return (_node_cflow_info (rgn)).reach_bb ;
01485 }
01486
01487
01488
01489
01490
01491
01492
01493
01494
01495
01496 inline BS *
01497 RGN_CFLOW_MGR::_reach_info_vect (REGIONAL_CFG_NODE *node) {
01498
01499 return (_node_cflow_info (node)).reach_bb ;
01500 }
01501
01502 inline RGN_CFLOW_MGR::REACH_PROB_VECT *
01503 RGN_CFLOW_MGR::_reach_prob_vect (BB *bb) {
01504
01505 return &((_node_cflow_info (bb)).reach_prob) ;
01506 }
01507
01508
01509 inline RGN_CFLOW_MGR::REACH_PROB_VECT *
01510 RGN_CFLOW_MGR::_reach_prob_vect (REGION *rgn) {
01511
01512 return &((_node_cflow_info (rgn)).reach_prob);
01513 }
01514
01515 inline RGN_CFLOW_MGR::REACH_PROB_VECT *
01516 RGN_CFLOW_MGR::_reach_prob_vect (REGIONAL_CFG_NODE * node) {
01517
01518 return &((_node_cflow_info (node)).reach_prob);
01519 }
01520
01521
01522
01523
01524
01525
01526
01527
01528 inline BS *
01529 RGN_CFLOW_MGR::_create_empty_reach_bb_vect (void) {
01530 return BS_Create_Empty (_max_bb_map_idx()+1 , &_mem_pool);
01531 }
01532
01533 inline BS *
01534 RGN_CFLOW_MGR::_add_reachable_bb (BB *from, BB* to) {
01535 BS * reach_info = _reach_info_vect (from) ;
01536 Is_True (reach_info, ("reachable info is not available!"));
01537
01538 return BS_Union1D (reach_info, _bb_2_map_idx (to), &_mem_pool) ;
01539 }
01540
01541 inline BS *
01542 RGN_CFLOW_MGR::_add_reachable_bb (REGION* rgn, BB* to) {
01543 BS * reach_info = _reach_info_vect (rgn) ;
01544 Is_True (reach_info, ("reachable info is not available!"));
01545
01546 return BS_Union1D (reach_info, _bb_2_map_idx (to), &_mem_pool) ;
01547 }
01548
01549 inline BS *
01550 RGN_CFLOW_MGR::_add_reachable_bb (BS * vect, BB* bb, MEM_POOL *mp) {
01551 return BS_Union1D (vect, _bb_2_map_idx(bb), mp) ;
01552 }
01553
01554 inline BS *
01555 RGN_CFLOW_MGR::_add_reachable_bbs (BB *from, BS * reach_bbs) {
01556 BS * reach_info = _reach_info_vect (from) ;
01557 Is_True (reach_info, ("reachable info is not available!"));
01558
01559 return BS_UnionD (reach_info, reach_bbs, &_mem_pool) ;
01560 }
01561
01562 inline BS *
01563 RGN_CFLOW_MGR::_add_reachable_bbs (REGION* rgn, BS * reach_bbs) {
01564 BS * reach_info = _reach_info_vect (rgn) ;
01565 Is_True (reach_info, ("reachable info is not available!"));
01566
01567 return BS_UnionD (reach_info, reach_bbs, &_mem_pool) ;
01568 }
01569
01570 inline BS *
01571 RGN_CFLOW_MGR::_add_reachable_bbs (
01572 REGIONAL_CFG_NODE * node, BS * reach_bbs) {
01573
01574 return node->Is_Region () ?
01575 _add_reachable_bbs (node->Region_Node(), reach_bbs) :
01576 _add_reachable_bbs (node->BB_Node () , reach_bbs);
01577 }
01578
01579 inline BS *
01580 RGN_CFLOW_MGR::_set_bb_is_reachable (BS* reach_vect, BB * bb,MEM_POOL* p) {
01581
01582 return BS_Union1D (reach_vect, _bb_2_map_idx(bb),p);
01583 }
01584
01585 inline BOOL
01586 RGN_CFLOW_MGR::_is_bb_reachable (BS *reach_vect, BB *bb) {
01587
01588 return BS_MemberP (reach_vect, _bb_2_map_idx(bb));
01589 }
01590
01591
01592 inline void
01593 RGN_CFLOW_MGR::_set_bb_reach_prob (REACH_PROB_VECT* prob_vect,
01594 BB* src_bb, REACH_PROB prob) {
01595
01596 INT32 map_idx = _bb_2_map_idx(src_bb);
01597 Is_True (map_idx < prob_vect->elem_num,
01598 ("map idx out of range"));
01599 prob_vect->reach_prob_vect[map_idx] = prob ;
01600
01601 }
01602
01603 inline void
01604 RGN_CFLOW_MGR::_set_bb_reach_prob (BB *from, BB* to,REACH_PROB prob) {
01605
01606 REACH_PROB_VECT * vect = _reach_prob_vect (from);
01607 Is_True (vect, ("reachable prob is NULL")) ;
01608
01609 INT32 map_idx = _bb_2_map_idx(to) ;
01610 Is_True (map_idx < vect->elem_num, ("map idx out of range"));
01611 vect->reach_prob_vect[map_idx] = prob ;
01612 }
01613
01614
01615 REACH_PROB
01616 RGN_CFLOW_MGR::_bb_reach_prob (REGION * from,BB *to) {
01617 REACH_PROB_VECT * vect = _reach_prob_vect(from);
01618 Is_True (vect, ("reachable prob is NULL")) ;
01619
01620 INT32 map_idx = _bb_2_map_idx(to) ;
01621 Is_True (map_idx < vect->elem_num, ("map idx out of range"));
01622
01623 return vect->reach_prob_vect[map_idx];
01624 }
01625
01626 REACH_PROB
01627 RGN_CFLOW_MGR::_bb_reach_prob (BB * from,BB *to) {
01628 REACH_PROB_VECT * vect = _reach_prob_vect(from);
01629 Is_True (vect, ("reachable prob is NULL"));
01630
01631 INT32 map_idx = _bb_2_map_idx(to) ;
01632 Is_True (map_idx < vect->elem_num, ("map idx out of range"));
01633
01634 return vect->reach_prob_vect[map_idx];
01635 }
01636
01637 REACH_PROB
01638 RGN_CFLOW_MGR::_bb_reach_prob (REGIONAL_CFG_NODE * node,BB *to) {
01639 return node->Is_Region () ?
01640 _bb_reach_prob (node->Region_Node(), to) :
01641 _bb_reach_prob (node->BB_Node () , to);
01642 }
01643
01644
01645 void
01646 RGN_CFLOW_MGR::_fused_mult_add (REACH_PROB_VECT * dest, REACH_PROB_VECT *src,
01647 float mult_by) {
01648
01649 Is_True (dest->elem_num == src->elem_num, ("mismatch vector!"));
01650
01651 for (INT32 i = dest->elem_num - 1 ; i >= 1 ; i --) {
01652 dest->reach_prob_vect[i] =
01653 INT32(dest->reach_prob_vect[i] + src->reach_prob_vect[i] * mult_by) ;
01654 }
01655 }
01656
01657
01658
01659
01660
01661
01662
01663
01664 void
01665 RGN_CFLOW_MGR::_acquire_cflow_info (void) {
01666
01667 _acquire_basic_cflow_info ();
01668
01669 _setup_map_array () ;
01670 _setup_node_cflow_info_array () ;
01671
01672
01673
01674
01675
01676
01677
01678 UINT32 next_bb_map_idx = ID_MAP_BASE ;
01679 UINT32 next_rgn_map_idx = ID_MAP_BASE ;
01680
01681 INT32 max_leaf_node_level = 0 ;
01682
01683 for (TOPOLOGICAL_REGIONAL_CFG_ITER iter (_scope->Regional_Cfg()) ;
01684 iter != 0 ; ++iter) {
01685
01686 BB * b ; REGION * r;
01687
01688 if (!(*iter)->Is_Region()) {
01689 b = (*iter)->BB_Node () ;
01690 _bb_id_2_map_idx_vect [BB_id(b)] = next_bb_map_idx ;
01691 _map_idx_2_bb_vect [next_bb_map_idx++] = b ;
01692
01693 _node_cflow_info(b).node.bb = b;
01694
01695 } else {
01696 r = (*iter)->Region_Node() ;
01697 _rgn_id_2_map_idx_vect [r->Id()] = next_rgn_map_idx ;
01698 _map_idx_2_rgn_vect [next_rgn_map_idx++] = r ;
01699
01700 _node_cflow_info(r).node.rgn = r ;
01701 }
01702
01703 UINT32 level = Min_Level (*iter) ;
01704 for (CFG_PRED_NODE_ITER preds(*iter) ; preds != 0 ; ++preds) {
01705 UINT32 l = Min_Level (*preds) ;
01706 level = max (level,l+1) ;
01707 }
01708
01709 _NODE_CFLOW_INFO& info = _node_cflow_info (*iter);
01710 info.min_level = level ;
01711 info.max_level = _bb_num + _rgn_num + 1;
01712
01713 if (!(*iter)->Succ_Num()) {
01714 max_leaf_node_level = max(max_leaf_node_level, level);
01715 }
01716 }
01717
01718
01719
01720
01721 for (REVERSE_TOPO_REGIONAL_CFG_ITER iter (_scope->Regional_Cfg()) ;
01722 iter != 0 ; ++iter) {
01723
01724 if (!(*iter)->Succ_Num()) {
01725 _node_cflow_info(*iter).max_level = max_leaf_node_level ;
01726 }
01727
01728 UINT32 level = _node_cflow_info(*iter).max_level ;
01729
01730 for (CFG_PRED_NODE_ITER preds(*iter) ; preds != 0 ; ++preds) {
01731 UINT32 l = Max_Level (*preds) ;
01732 _node_cflow_info (*preds).max_level = min(l, level-1);
01733 }
01734 }
01735
01736 _acquire_reachable_info () ;
01737 _acquire_reach_prob_info () ;
01738
01739 _exec_path_mgr.Acquire_Path_Info (Scope ());
01740 }
01741
01742 void
01743 RGN_CFLOW_MGR::_acquire_reachable_info (void) {
01744
01745 if (_bb_num) {
01746 Is_True (!_bb_node_cflow_info.empty (),
01747 ("_bb_node_cflow_info has not built up!")) ;
01748
01749 for (INT32 i = ID_MAP_BASE; i <= _bb_num ; i++) {
01750 _bb_node_cflow_info[i].reach_bb =
01751 _create_empty_reach_bb_vect ();
01752 }
01753 }
01754
01755 if (_rgn_num) {
01756 Is_True (!_rgn_node_cflow_info.empty (),
01757 ("_rgn_node_cflow_info has not built up!")) ;
01758 for (INT32 i = ID_MAP_BASE ; i <= _rgn_num ; i ++) {
01759 _rgn_node_cflow_info[i].reach_bb =
01760 _create_empty_reach_bb_vect ();
01761 }
01762 }
01763
01764 for (REVERSE_TOPO_REGIONAL_CFG_ITER iter(_scope->Regional_Cfg()) ;
01765 iter != 0 ; ++iter) {
01766 REACH_INFO_VECT * reach_bb = (_node_cflow_info(*iter)).reach_bb;
01767
01768 for (CFG_SUCC_NODE_ITER succs(*iter) ; succs != 0 ; ++succs) {
01769 REACH_INFO_VECT * succ_reach_bb =
01770 _node_cflow_info (*succs).reach_bb;
01771 Is_True (succ_reach_bb, ("succs reachable vector has not built up!"));
01772
01773 reach_bb = _add_reachable_bbs (*iter,succ_reach_bb);
01774 if ((*succs)->Is_Region()) continue ;
01775 reach_bb = _set_bb_is_reachable (reach_bb, (*succs)->BB_Node(),&_mem_pool);
01776 }
01777
01778 _node_cflow_info (*iter).reach_bb = reach_bb ;
01779 }
01780 }
01781
01782 void
01783 RGN_CFLOW_MGR::_acquire_reach_prob_info (void) {
01784 if (_bb_num == 0) return ;
01785
01786 if (_bb_num) {
01787
01788 for (INT32 i = ID_MAP_BASE ;
01789 i <= _bb_num + ID_MAP_BASE - 1 ; i++) {
01790
01791 _bb_node_cflow_info[i].reach_prob.elem_num =
01792 _max_bb_map_idx() + 1;
01793 _bb_node_cflow_info[i].reach_prob.vect_size =
01794 _max_bb_map_idx() + 1;
01795 _bb_node_cflow_info[i].reach_prob.reach_prob_vect =
01796 TYPE_MEM_POOL_ALLOC_N (REACH_PROB,
01797 &_mem_pool,_max_bb_map_idx() + 1);
01798 }
01799 }
01800
01801 if (_rgn_num) {
01802
01803 for (INT32 i = ID_MAP_BASE;
01804 i <= _rgn_num + ID_MAP_BASE - 1; i++) {
01805
01806 _rgn_node_cflow_info[i].reach_prob.elem_num =
01807 _max_bb_map_idx() + 1;
01808
01809 _rgn_node_cflow_info[i].reach_prob.vect_size =
01810 _max_bb_map_idx() + 1 ;
01811
01812 _rgn_node_cflow_info[i].reach_prob.reach_prob_vect =
01813 TYPE_MEM_POOL_ALLOC_N (REACH_PROB,
01814 &_mem_pool,_max_bb_map_idx() + 1);
01815 }
01816 }
01817
01818 REGIONAL_CFG * cfg = _scope -> Regional_Cfg();
01819
01820 for (REVERSE_TOPO_REGIONAL_CFG_ITER iter (cfg); iter != 0 ; ++iter) {
01821 if (!(*iter)->Is_Region()) {
01822 BB *bb = (*iter)->BB_Node() ;
01823 _set_bb_reach_prob (bb,bb,(UINT32)(1.0 * REACH_PROB_SCALE)) ;
01824 }
01825
01826 REACH_PROB_VECT * dest = _reach_prob_vect (*iter) ;
01827
01828 for (REGIONAL_CFG_EDGE * edges = (*iter)->First_Succ() ;
01829 edges != NULL ; edges = edges->Next_Succ()) {
01830 REACH_PROB_VECT * src = _reach_prob_vect (edges->Dest()) ;
01831 _fused_mult_add (dest, src, cfg->Edge_Prob(edges)) ;
01832 }
01833 }
01834 }
01835
01836
01837 UINT16
01838 RGN_CFLOW_MGR::bb_node_succ_num (REGIONAL_CFG_NODE * node) {
01839 REGIONAL_CFG_EDGE * edge ;
01840 INT icount = 0 ;
01841 for (edge = node->First_Succ() ; edge ; edge = edge->Next_Succ())
01842 if (!edge->Dest()->Is_Region()) ++ icount ;
01843 return icount ;
01844 }
01845
01846 UINT16
01847 RGN_CFLOW_MGR::bb_node_pred_num (REGIONAL_CFG_NODE * node) {
01848 REGIONAL_CFG_EDGE * edge ;
01849 INT icount = 0 ;
01850 for (edge = node->First_Pred() ; edge ; edge = edge->Next_Pred())
01851 if (!edge->Dest()->Is_Region()) ++ icount ;
01852 return icount ;
01853 }
01854
01855 BOOL
01856 RGN_CFLOW_MGR::Has_Scheduled_Preds (BB* bb) {
01857 BBLIST *pred ;
01858 FOR_ALL_BB_PREDS (bb,pred)
01859 if (BB_scheduled (pred->item)) return TRUE;
01860
01861 return FALSE ;
01862 }
01863
01864 BOOL
01865 RGN_CFLOW_MGR::Critical_Edge_Present (REGION *rgn) {
01866
01867 REGIONAL_CFG *cfg = rgn->Regional_Cfg() ;
01868
01869 for (TOPOLOGICAL_REGIONAL_CFG_ITER iter(cfg); iter!=0;++iter){
01870
01871 REGIONAL_CFG_NODE *node = *iter;
01872 if(node->Is_Region()) continue;
01873 if(node->Succ_Num()<=1) continue;
01874
01875 INT succ_bb_num , pred_bb_num ;
01876
01877 succ_bb_num = bb_node_succ_num (node) ;
01878 if (succ_bb_num <= 1) continue ;
01879
01880 for(REGIONAL_CFG_EDGE *edge = node->First_Succ(); edge!=NULL; edge = edge->Next_Succ()){
01881 REGIONAL_CFG_NODE *succ_node = edge->Dest();
01882 if(succ_node->Is_Region()) continue;
01883 if (bb_node_pred_num (succ_node) > 1)
01884 return TRUE ;
01885 }
01886 }
01887
01888 return FALSE ;
01889
01890 }
01891
01892
01893 void
01894 RGN_CFLOW_MGR::_compute_node_level () {
01895
01896 for (TOPOLOGICAL_REGIONAL_CFG_ITER iter(_scope->Regional_Cfg()) ;
01897 iter != 0 ; ++iter) {
01898
01899 _NODE_CFLOW_INFO& cflow_info = _node_cflow_info (*iter) ;
01900 cflow_info.min_level = 1 ;
01901 cflow_info.max_level = 1 ;
01902
01903 }
01904
01905
01906 for (TOPOLOGICAL_REGIONAL_CFG_ITER iter(_scope->Regional_Cfg()) ;
01907 iter != 0 ; ++iter) {
01908 INT32 level ;
01909
01910 _NODE_CFLOW_INFO& cflow_info = _node_cflow_info (*iter);
01911 level = cflow_info.min_level - 1;
01912
01913 for (CFG_PRED_NODE_ITER preds(*iter) ; preds != 0 ; ++preds) {
01914 INT32 L = Min_Level (*preds);
01915 level = (level > L) ? level : L ;
01916 }
01917
01918 cflow_info.min_level = cflow_info.max_level = level + 1 ;
01919 }
01920
01921
01922 for (REVERSE_TOPO_REGIONAL_CFG_ITER iter (_scope->Regional_Cfg()) ;
01923 iter != 0 ; ++iter) {
01924
01925 INT32 level ;
01926
01927 _NODE_CFLOW_INFO& cflow_info = _node_cflow_info (*iter);
01928 level = cflow_info.max_level + 1;
01929
01930 for (CFG_SUCC_NODE_ITER succs(*iter) ; succs != 0 ; ++succs) {
01931 INT32 L = Max_Level(*succs);
01932 level = (level > L) ? level : L ;
01933 }
01934
01935 cflow_info.max_level = level - 1 ;
01936 }
01937 }
01938
01939 INT32
01940 RGN_CFLOW_MGR::Across_Node_Num (BB * from , BB * to) {
01941
01942 if (from == to) return 0 ;
01943
01944 BB * ance , * desc ;
01945 if (BB1_Reachable_From_BB2 (to, from)) {
01946 ance = from ; desc = to ;
01947 } else {
01948 ance = to ; desc = from ;
01949 }
01950
01951 if (!BB1_Reachable_From_BB2(desc, ance)) return 0 ;
01952
01953 INT32 d1 = Max_Level (desc) - Max_Level (ance);
01954
01955 INT32 d2 = Min_Level (desc) - Min_Level (ance);
01956
01957 return d1 < d2 ? d1 : d2 ;
01958 }
01959
01960
01961
01962
01963
01964
01965
01966
01967
01968
01969
01970
01971
01972 static BB_VECTOR _splitted_pu_boundary_bbs ;
01973
01974
01975
01976
01977
01978
01979
01980
01981
01982
01983
01984
01985
01986
01987 static BOOL
01988 BB_Has_Already_Been_Splitted (BB * bb) {
01989
01990 Is_True (BB_entry(bb) || BB_exit(bb),
01991 ("BB:%d is neither entry- nor exit-BB", BB_id(bb)));
01992
01993 for (BB_VECTOR_ITER iter = _splitted_pu_boundary_bbs.begin() ;
01994 iter != _splitted_pu_boundary_bbs.end () ; iter ++) {
01995
01996 if (*iter == bb) return TRUE;
01997 }
01998
01999 return FALSE ;
02000 }
02001
02002
02003
02004
02005
02006
02007
02008
02009
02010
02011
02012 void
02013 Init_Split_PU_Entry_Or_Exit_BB (void) {
02014 _splitted_pu_boundary_bbs.clear () ;
02015
02016
02017
02018
02019
02020 if (!BB_exit (REGION_First_BB) ||
02021 !IPFEC_Glos_Split_Entry_BB || !IPFEC_Glos_Split_Exit_BB) {
02022 return ;
02023 }
02024
02025
02026
02027
02028
02029
02030
02031
02032
02033 OP* exit_boundary_op = NULL, *entry_boundary_op = NULL, *op;
02034 FOR_ALL_BB_OPs_FWD (REGION_First_BB, op) {
02035 if (OP_no_move_before_gra (op) && OP_Is_Copy_From_Save_TN (op)) {
02036 exit_boundary_op = op; break;
02037 }
02038 }
02039 while (exit_boundary_op &&
02040 (exit_boundary_op = OP_prev(exit_boundary_op)) &&
02041 OP_no_move_before_gra (exit_boundary_op)) {
02042 }
02043
02044
02045
02046
02047 FOR_ALL_BB_OPs_REV (REGION_First_BB, op) {
02048 if (OP_no_move_before_gra (op) && OP_Is_Copy_To_Save_TN (op)) {
02049 entry_boundary_op = op;
02050 break;
02051 }
02052 }
02053 while (entry_boundary_op &&
02054 (entry_boundary_op = OP_next(entry_boundary_op)) &&
02055 OP_no_move_before_gra (entry_boundary_op)) {
02056 }
02057
02058 if (!entry_boundary_op || !exit_boundary_op) {
02059 return;
02060 }
02061
02062
02063
02064
02065 INT insn_cnt = 0;
02066 OP* t = entry_boundary_op;
02067 for (; t && t != exit_boundary_op; t = OP_next(t)) {
02068 insn_cnt ++;
02069 }
02070 if (t != exit_boundary_op) {
02071
02072 return;
02073 }
02074
02075 if (insn_cnt < 4) {
02076
02077
02078
02079 return;
02080 }
02081
02082 RGN_Divide_BB (REGION_First_BB, exit_boundary_op);
02083 RGN_Divide_BB (REGION_First_BB, OP_prev(entry_boundary_op));
02084 }
02085
02086
02087
02088
02089
02090
02091
02092
02093 static void
02094 Add_Splitted_Entry_Exit_BB (BB *bb) {
02095
02096 Is_True (BB_entry (bb) || BB_exit (bb),
02097 ("BB:%d is neither entry- nor exit-BB",
02098 BB_id(bb)));
02099 Is_True (!BB_Has_Already_Been_Splitted (bb),
02100 ("BB:%d has already splitted", BB_id(bb)));
02101
02102 _splitted_pu_boundary_bbs.push_back (bb);
02103 }
02104
02105
02106
02107
02108
02109
02110
02111
02112 void
02113 Remove_Splitted_Entry_Exit_BB (BB * bb) {
02114
02115 for (BB_VECTOR_ITER iter = _splitted_pu_boundary_bbs.begin () ;
02116 iter != _splitted_pu_boundary_bbs.end () ; iter ++) {
02117
02118 if (*iter == bb) {
02119 _splitted_pu_boundary_bbs.erase (iter) ;
02120 return ;
02121 }
02122 }
02123 }
02124
02125
02126
02127
02128
02129
02130
02131
02132
02133
02134 static void
02135 Copy_Entry_BB_Annotation (BB* entry_bb, BB* splitted_bb) {
02136
02137 for (ANNOTATION * annot = BB_annotations (entry_bb) ; annot ;
02138 annot = ANNOT_next (annot)) {
02139
02140 switch (ANNOT_kind(annot)) {
02141
02142 case ANNOT_LABEL:
02143 case ANNOT_ENTRYINFO :
02144 case ANNOT_EXITINFO :
02145 break ;
02146
02147 case ANNOT_PRAGMA :
02148 case ANNOT_CALLINFO :
02149 case ANNOT_NOTE :
02150 case ANNOT_LOOPINFO :
02151 case ANNOT_SWITCH :
02152 case ANNOT_ROTATING_KERNEL :
02153 #if defined(TARG_SL)
02154 case ANNOT_ASMINFO:
02155 #endif
02156 BB_Add_Annotation (splitted_bb,ANNOT_kind (annot),ANNOT_info(annot));
02157 break ;
02158
02159 default :
02160 Is_True (FALSE , ("unknow annotation \n")) ;
02161 }
02162 }
02163 }
02164
02165
02166
02167
02168
02169
02170
02171
02172
02173
02174 BB *
02175 Split_PU_Entry_BB (BB * entry_bb) {
02176
02177 Is_True (BB_entry (entry_bb),
02178 ("BB:%d is not entry BB", BB_id(entry_bb)));
02179 Is_True (!BB_Has_Already_Been_Splitted (entry_bb),
02180 ("BB:%d has already been splitted", BB_id(entry_bb)));
02181
02182 OP * last_op, *boundary_op, * sp_adj;
02183 sp_adj = BB_entry_sp_adj_op (entry_bb);
02184
02185 for (boundary_op = BB_last_op (entry_bb);
02186 boundary_op && boundary_op != sp_adj ;
02187 boundary_op = OP_prev(boundary_op)) {
02188
02189 if (OP_glue(boundary_op) ||
02190 OP_no_move_before_gra(boundary_op) ||
02191 OP_access_reg_bank(boundary_op)) {
02192 break ;
02193 }
02194 }
02195
02196 Is_True (boundary_op , ("boundary_op can't be null\n"));
02197 if (boundary_op == BB_last_op(entry_bb)) {
02198 return NULL;
02199 }
02200
02201
02202
02203
02204
02205 REGION * home_rgn = Home_Region (entry_bb);
02206 REGIONAL_CFG * rgn_cfg = home_rgn->Regional_Cfg();
02207
02208 BB * split_bb =
02209 RGN_Gen_And_Insert_BB_After (entry_bb, home_rgn->Regional_Cfg()) ;
02210 BB_freq (split_bb) = BB_freq (entry_bb);
02211
02212 BBLIST * nxt, * succ;
02213 for (succ = BB_succs (entry_bb); succ; succ = nxt) {
02214
02215 BB* bb_succ = BBLIST_item(succ);
02216 nxt = BBLIST_next(succ);
02217 RGN_Link_Pred_Succ_With_Prob(split_bb, bb_succ, BBLIST_prob(succ));
02218 RGN_Unlink_Pred_Succ(entry_bb, bb_succ);
02219
02220 }
02221
02222 RGN_Link_Pred_Succ_With_Prob (entry_bb, split_bb, 1.0f);
02223
02224
02225
02226 while (OP_next(boundary_op)) {
02227
02228 BB_Move_Op_To_End (split_bb, entry_bb, OP_next(boundary_op)) ;
02229
02230 }
02231
02232
02233
02234
02235 BB_bbregs (split_bb) = BB_bbregs (entry_bb);
02236
02237
02238
02239 BB_flag (split_bb) = BB_flag (entry_bb) ;
02240 Reset_BB_entry (split_bb) ;
02241
02242 Copy_Entry_BB_Annotation (entry_bb,split_bb);
02243
02244 if (entry_bb) { Add_Splitted_Entry_Exit_BB (entry_bb) ; }
02245
02246 return entry_bb ;
02247 }
02248
02249
02250
02251
02252
02253
02254
02255
02256
02257
02258 BB *
02259 Split_PU_Entry_BB (REGION * rgn) {
02260
02261 NODE_VECTOR rgn_entry = rgn->Entries () ;
02262
02263 Is_True (rgn_entry.size() == 1 ,
02264 ("Split_PU_Entry_BB() region has more than one entries\n"));
02265
02266 REGIONAL_CFG_NODE * cfg_node = *(rgn_entry.begin());
02267
02268 BB * entry_bb ;
02269
02270 if (cfg_node->Is_Region() ||
02271 (entry_bb = cfg_node->BB_Node()) && !BB_entry(entry_bb)) {
02272 return NULL;
02273 }
02274
02275 return !BB_exit(entry_bb) ? Split_PU_Entry_BB (entry_bb) : NULL;
02276 }
02277
02278
02279
02280
02281
02282
02283
02284
02285
02286 static void
02287 Sink_Return_Val_OP (BB * split, BB * exit) {
02288
02289 Is_True (BB_exit(exit) &&
02290 BB_Unique_Predecessor(exit) == split &&
02291 !BB_xfer_op(split),
02292 ("BB:%d is not splited from BB:%d",
02293 BB_id(split), BB_id(exit)));
02294
02295 if (BB_length(split) <= 0) return ;
02296
02297 CG_DEP_Compute_Graph (
02298 split,
02299 INCLUDE_ASSIGNED_REG_DEPS,
02300 NON_CYCLIC,
02301 INCLUDE_MEMREAD_ARCS,
02302 INCLUDE_MEMIN_ARCS,
02303 NO_CONTROL_ARCS,
02304 NULL);
02305
02306 Reset_BB_scheduled (split) ;
02307 Reset_BB_scheduled (exit) ;
02308
02309 #define OP_Should_Sink(o) OP_Scheduled((o))
02310 #define Set_OP_Should_Sink(o) Set_OP_Scheduled((o))
02311 #define Reset_OP_Should_Sink(o) Reset_OP_Scheduled((o))
02312
02313 OP * op ;
02314 FOR_ALL_BB_OPs (split, op) {
02315 Reset_OP_Should_Sink(op);
02316 }
02317
02318 FOR_ALL_BB_OPs (split, op) {
02319 if (OP_def_return_value(op)) {
02320 Set_OP_Should_Sink(op);
02321 }
02322
02323 if (OP_Should_Sink(op)) {
02324 for (ARC_LIST * arcs = OP_succs(op) ;
02325 arcs != NULL;
02326 arcs = ARC_LIST_rest(arcs)) {
02327
02328 ARC * arc = ARC_LIST_first(arcs);
02329 OP * succ = ARC_succ(arc);
02330
02331 if (OP_bb(succ) == split) {
02332 Set_OP_Should_Sink (succ);
02333 }
02334 }
02335 }
02336 }
02337
02338 OP * prev_op ;
02339 for (op = BB_last_op(split); op ; op = prev_op) {
02340
02341 prev_op = OP_prev(op);
02342
02343 if (OP_Should_Sink(op)) {
02344 BB_Move_Op_To_Start (exit, split, op);
02345 Reset_OP_Should_Sink(op);
02346 }
02347 }
02348
02349 CG_DEP_Delete_Graph (split);
02350
02351 #undef OP_Should_Sink
02352 #undef Set_OP_Should_Sink
02353 #undef Reset_OP_Should_Sink
02354
02355 }
02356
02357
02358
02359 static void
02360 Copy_Exit_BB_Annot (BB * exit_bb, BB * splitted_exit) {
02361
02362 for (ANNOTATION* ant = BB_annotations (exit_bb) ;
02363 ant ;
02364 ant = ANNOT_next (ant)) {
02365
02366 BOOL add_annot ;
02367 add_annot = TRUE;
02368
02369 switch (ANNOT_kind(ant)) {
02370 case ANNOT_LABEL:
02371 Set_BB_has_label (splitted_exit); break;
02372
02373 case ANNOT_PRAGMA:
02374 Set_BB_has_pragma (splitted_exit); break;
02375
02376 case ANNOT_ENTRYINFO:
02377 case ANNOT_EXITINFO:
02378 add_annot = FALSE; break ;
02379
02380 case ANNOT_NOTE:
02381 Set_BB_has_note(splitted_exit); break;
02382
02383 case ANNOT_LOOPINFO:
02384 FmtAssert (FALSE,
02385 ("Exit block BB:%d should not has loop-info annotation",
02386 BB_id(exit_bb)));
02387 add_annot = FALSE; break ;
02388
02389 case ANNOT_CALLINFO:
02390 Is_True (BB_tail_call(exit_bb), ("it should be a tail call"));
02391 add_annot = FALSE;
02392 break;
02393
02394 case ANNOT_ASMINFO:
02395 Set_BB_asm(exit_bb); break;
02396
02397 case ANNOT_SWITCH:
02398
02399 FmtAssert (FALSE,
02400 ("Exit block BB:%d should not has switch annotation",
02401 BB_id(exit_bb)));
02402 add_annot = FALSE; break ;
02403
02404 case ANNOT_ROTATING_KERNEL:
02405 FmtAssert (FALSE,
02406 ("Exit block BB:%d cannot be a rotating kernel",
02407 BB_id(exit_bb)));
02408 add_annot = FALSE; break ;
02409
02410 default:
02411 FmtAssert(FALSE,
02412 ("unexpected annotation kind: %d", ANNOT_kind(ant)));
02413 }
02414
02415
02416 if (add_annot) {
02417 BB_Add_Annotation
02418 (splitted_exit, ANNOT_kind(ant), ANNOT_info(ant));
02419 }
02420 }
02421 }
02422
02423
02424
02425
02426
02427
02428
02429
02430
02431
02432
02433
02434 BB *
02435 Split_PU_Exit_BB (BB * epi) {
02436
02437 Is_True (BB_exit(epi), ("BB:%d is not exit BB", BB_id(epi)));
02438
02439 Is_True (!BB_Has_Already_Been_Splitted (epi),
02440 ("BB:%d has already been splitted", BB_id(epi)));
02441
02442 if (BB_entry(epi)) {
02443
02444
02445
02446
02447 return NULL;
02448 }
02449
02450 OP * sp_adj = BB_exit_sp_adj_op (epi);
02451 OP * op_tmp, * op_boundary = NULL;
02452
02453 for (op_tmp = BB_first_op (epi) ;
02454 op_tmp && op_tmp != sp_adj ;
02455 op_tmp = OP_next(op_tmp)) {
02456
02457 if (OP_glue(op_tmp) ||
02458 OP_no_move_before_gra(op_tmp) ||
02459 OP_access_reg_bank(op_tmp)) {
02460
02461 op_boundary = OP_prev(op_tmp);
02462 break ;
02463
02464 }
02465 }
02466
02467 if (!op_boundary) { return NULL; }
02468
02469
02470
02471 REGION * home_rgn = Home_Region (epi);
02472 REGIONAL_CFG * rgn_cfg = home_rgn->Regional_Cfg();
02473
02474 BB * split_bb =
02475 RGN_Gen_And_Insert_BB_Before (epi, home_rgn->Regional_Cfg());
02476 BB_freq (split_bb) = BB_freq (epi);
02477
02478
02479
02480 while (BBLIST * pred_item = BB_preds(epi)) {
02481
02482 BB* pred_bb = BBLIST_item (pred_item);
02483
02484
02485
02486
02487 float prob = BBLIST_prob (BB_Find_Succ(pred_bb,epi));
02488
02489 RGN_Link_Pred_Succ_With_Prob(pred_bb, split_bb, prob);
02490 RGN_Unlink_Pred_Succ(pred_bb,epi);
02491
02492 }
02493
02494 RGN_Link_Pred_Succ_With_Prob (split_bb, epi, 1.0f);
02495
02496
02497
02498
02499
02500 for (; op_boundary ; op_boundary = op_tmp) {
02501 op_tmp = OP_prev(op_boundary);
02502 BB_Move_Op_To_Start (split_bb, epi, op_boundary) ;
02503 }
02504
02505
02506
02507
02508 BB_bbregs (split_bb) = BB_bbregs (epi);
02509
02510
02511
02512 BB_flag (split_bb) = BB_flag (epi) ;
02513 Reset_BB_exit (split_bb) ;
02514 Reset_BB_call (split_bb);
02515
02516 Add_Splitted_Entry_Exit_BB (epi) ;
02517
02518 Copy_Exit_BB_Annot (epi, split_bb);
02519
02520
02521
02522
02523 Sink_Return_Val_OP (split_bb, epi);
02524
02525 return epi;
02526 }
02527
02528
02529
02530
02531
02532
02533
02534
02535
02536
02537
02538
02539
02540 void
02541 Split_PU_Exit_BB (REGION * rgn) {
02542
02543 NODE_VECTOR rgn_exits = rgn->Exits () ;
02544
02545 for (NODE_VECTOR_ITER iter = rgn_exits.begin () ;
02546 iter != rgn_exits.end () ;
02547 iter ++) {
02548
02549 REGIONAL_CFG_NODE * cfg_node = *iter;
02550 if (cfg_node->Is_Region()) continue ;
02551
02552 BB * epi = cfg_node->BB_Node () ;
02553 if (BB_exit (epi)) {
02554 epi = Split_PU_Exit_BB (epi);
02555 }
02556 }
02557
02558 }
02559
02560
02561
02562
02563
02564
02565
02566
02567
02568
02569 void
02570 Merge_Splitted_PU_Entry_BB (BB * splitted_entry) {
02571
02572 Is_True (BB_entry (splitted_entry),
02573 ("BB:%d is not entry-BB", BB_id(splitted_entry)));
02574
02575 BB* split = BB_Unique_Successor (splitted_entry) ;
02576 Is_True (split && !BB_xfer_op(splitted_entry),
02577 ("BB:%d is not splitted entry BB %d\n",
02578 BB_id(splitted_entry)));
02579
02580
02581 BBLIST * nxt, *succ;
02582 for (succ = BB_succs(split); succ; succ = nxt) {
02583
02584 BB* bb_succ = BBLIST_item(succ);
02585 nxt = BBLIST_next(succ);
02586 RGN_Link_Pred_Succ_With_Prob (splitted_entry, bb_succ,
02587 BBLIST_prob(succ));
02588 RGN_Unlink_Pred_Succ(split, bb_succ);
02589
02590 }
02591
02592 RGN_Unlink_Pred_Succ (splitted_entry, split);
02593
02594
02595 BB_Append_All (splitted_entry, split);
02596 BB_bbregs (split) = NULL ;
02597
02598 if (BB_call (splitted_entry)) {
02599
02600 OP * op = BB_xfer_op (splitted_entry) ;
02601
02602 if (!op || !OP_call (op)) {
02603
02604 Reset_BB_call (splitted_entry) ;
02605
02606 ANNOTATION * bb_annot = BB_annotations (splitted_entry) ;
02607 ANNOTATION * call_annot ;
02608
02609 if (bb_annot &&
02610 (call_annot = ANNOT_Get (bb_annot,ANNOT_CALLINFO)))
02611 ANNOT_Unlink (bb_annot,call_annot) ;
02612
02613 }
02614 }
02615
02616 SCHEDULER::Clean_Up (splitted_entry);
02617 RGN_Remove_BB_And_Edges (split);
02618
02619 Remove_Splitted_Entry_Exit_BB (splitted_entry);
02620 }
02621
02622
02623
02624
02625
02626
02627
02628
02629
02630 void
02631 Merge_Splitted_PU_Exit_BB (BB * exit_block) {
02632
02633 Is_True (BB_exit (exit_block),
02634 ("BB:%d is not exit-block", BB_id(exit_block)));
02635
02636 BB* split = BB_Unique_Predecessor (exit_block);
02637 Is_True (split && !BB_xfer_op(split),
02638 ("BB:%d is not splitted exit BB %d\n", BB_id(exit_block)));
02639
02640 while (BBLIST * pred_item = BB_preds(split)) {
02641
02642 BB* p = BBLIST_item(pred_item);
02643 float prob = BBLIST_prob (BB_Find_Succ(p,split));
02644
02645 RGN_Link_Pred_Succ_With_Prob (p, exit_block, prob);
02646 RGN_Unlink_Pred_Succ(p,split);
02647 }
02648
02649 RGN_Unlink_Pred_Succ (split, exit_block);
02650
02651
02652 BB_Prepend_All (exit_block, split);
02653 BB_bbregs (split) = NULL ;
02654
02655 SCHEDULER::Clean_Up (exit_block);
02656
02657 RGN_Remove_BB_And_Edges (split);
02658
02659 Remove_Splitted_Entry_Exit_BB (exit_block);
02660 }
02661
02662
02663
02664
02665
02666
02667
02668
02669
02670
02671
02672 void
02673 Merge_All_Splitted_Entry_and_Exit_BB (void) {
02674
02675 while (!_splitted_pu_boundary_bbs.empty ()) {
02676
02677
02678
02679 BB * bb = _splitted_pu_boundary_bbs.back () ;
02680 if (BB_entry(bb)) {
02681 Merge_Splitted_PU_Entry_BB (bb) ;
02682 } else if (BB_exit(bb)) {
02683 Merge_Splitted_PU_Exit_BB (bb);
02684 } else {
02685 FmtAssert (FALSE,
02686 ("BB:%d is neither entry- nor exit-BB\n", BB_id(bb)));
02687 }
02688
02689 Is_True (_splitted_pu_boundary_bbs.empty () ||
02690 bb != _splitted_pu_boundary_bbs.back (),
02691
02692 ("Merge_Splitted_PU_{Entry|Exit}_BB has not erase"
02693 " BB:%d from _splitted_pu_boundary_bbs",
02694 BB_id (bb))) ;
02695 }
02696 }
02697
02698
02699
02700
02701
02702
02703
02704
02705
02706
02707
02708 void
02709 Calculate_Dominator_Info (REGION_TREE *rgn_tree) {
02710
02711 Calculate_Dominators () ;
02712
02713 BS* empty_BB_set = BS_Create_Empty (PU_BB_Count + 2,
02714 &MEM_phase_pool);
02715
02716 extern BOOL Is_Abnormal_Loop (REGION* region) ;
02717
02718 typedef std::queue<REGION * > _RGN_QUEUE;
02719 _RGN_QUEUE rgn_queue ;
02720
02721 #define SET_RGN_IN_ABNORMAL_LOOP(x) { x = (REGION*)((INTPTR)(x) | 1); }
02722 #define GET_RGN(x) ((REGION*)(((INTPTR)(x)) & ~1))
02723 #define RGN_IN_ABNORMAL_LOOP(x) ((INTPTR)(x) & 1)
02724
02725 REGION * rgn = rgn_tree->Root();
02726 if (Is_Abnormal_Loop (rgn)) {
02727 SET_RGN_IN_ABNORMAL_LOOP(rgn);
02728 }
02729
02730 rgn_queue.push (rgn);
02731
02732
02733 while (!rgn_queue.empty ()) {
02734
02735 REGION * tmp = rgn_queue.front();
02736 rgn_queue.pop () ;
02737
02738 if (RGN_IN_ABNORMAL_LOOP(tmp)) {
02739
02740 for (TOPOLOGICAL_REGIONAL_CFG_ITER
02741 iter ((GET_RGN(tmp))->Regional_Cfg());
02742 iter != 0; ++ iter) {
02743
02744 if ((*iter)->Is_Region ()) continue ;
02745
02746 BB * b = (*iter)->BB_Node ();
02747
02748
02749
02750
02751 Set_BB_pdom_set (b, empty_BB_set);
02752 }
02753 }
02754
02755 for (REGION_KID_ITER kids_iter(GET_RGN(tmp)) ;
02756 kids_iter != 0 ; ++kids_iter) {
02757
02758 REGION * nested_rgn = *kids_iter ;
02759 if (Is_Abnormal_Loop (nested_rgn)) {
02760 SET_RGN_IN_ABNORMAL_LOOP(nested_rgn);
02761 }
02762
02763 rgn_queue.push (nested_rgn);
02764 }
02765 }
02766 }
02767
02768 BOOL
02769 BB1_Postdominate_BB2 (BB * bb1, BB* bb2) {
02770 BOOL b = BB_SET_MemberP (BB_pdom_set(bb2), bb1);
02771 if (!b) {
02772 if (bb1 == bb2) return TRUE;
02773 for (BB* bb = BB_Unique_Successor(bb2);
02774 bb != NULL;
02775 bb = BB_Unique_Successor (bb)) {
02776 if (bb == bb1) { return TRUE; }
02777 }
02778 }
02779
02780 return b;
02781 }
02782
02783
02784
02785
02786
02787
02788
02789
02790
02791
02792 BB_POS
02793 BB_Pos_Analysis
02794 (BB* bb, BB_VECTOR* cutting_set, RGN_CFLOW_MGR * cflow_info) {
02795
02796 for (BB_VECTOR_CONST_ITER iter = cutting_set->begin () ;
02797 iter != cutting_set->end() ;
02798 iter++) {
02799
02800 BB * tmp = *iter ;
02801 if (tmp == bb) return IN_SISS ;
02802
02803 if (cflow_info->BB1_Reachable_From_BB2 (tmp,bb)) {
02804 return ABOVE_SISS ;
02805 }
02806
02807 if (cflow_info->BB1_Reachable_From_BB2 (bb,tmp)) {
02808 return BELOW_SISS;
02809 }
02810 }
02811
02812 return OTHER;
02813 }
02814
02815
02816
02817
02818
02819
02820
02821
02822
02823 void
02824 RGN_CFLOW_MGR::Dump (FILE *f, BOOL verbose) {
02825
02826 if (verbose) {
02827 fprintf (f, "%s\t\tRGN_CFLOW_MGR status\n%s\n", DBar, DBar);
02828 }
02829
02830 if (!Valid ()) {
02831 if (verbose) { fputs ("Invalid!\n",f); }
02832 return ;
02833 }
02834
02835 char * prompt = "BBS REACHABLE FROM " ;
02836 INT num = 0, prompt_len = strlen(prompt);
02837
02838 for (TOPOLOGICAL_REGIONAL_CFG_ITER iter(_scope->Regional_Cfg());
02839 iter != 0 ; ++iter) {
02840
02841 BS * reach_info = _reach_info_vect (*iter);
02842 Is_True (reach_info,("fail to get reachable-BB"));
02843
02844 fprintf (f, "%s\t\t%s:%3d min-level %3d max-leve %3d\n",
02845 SBar,
02846 (*iter)->Is_Region () ? "RGN" : "BB",
02847 (*iter)->Is_Region () ? (*iter)->Region_Node()->Id() :
02848 BB_id((*iter)->BB_Node()),
02849 Min_Level(*iter),
02850 Max_Level(*iter)) ;
02851
02852 if (!(*iter)->Succ_Num()) {
02853 fputc ('\n', f);
02854 } else {
02855 fputs ("reachable nodes:", f);
02856 }
02857
02858 BS_ELT elt = BS_Choose(reach_info);
02859 if (elt == BS_CHOOSE_FAILURE ) {
02860 continue ;
02861 }
02862
02863 INT elem_count = -1;
02864 do {
02865 ++ elem_count ; if (!(elem_count % 5)) fprintf (f,"\n");
02866
02867 BB * bb = _map_idx_2_bb ((INT32)elt);
02868 mBB_NUM bb_id = BB_id (bb);
02869
02870 fprintf (f, "BB:%3d(p:%4.2f) ", (INT32)(BS_ELT)bb_id,
02871 (float)(_bb_reach_prob
02872 (*iter,bb)/(float)REACH_PROB_SCALE));
02873
02874 } while ((elt = BS_Choose_Next(reach_info,elt)) != BS_CHOOSE_FAILURE);
02875
02876 fputc ('\n', f);
02877 }
02878 }
02879
02880 #ifdef Is_True_On
02881 void
02882 RGN_CFLOW_MGR :: gdb_dump (void) {
02883 Dump (stderr); fflush (stderr);
02884 }
02885 #endif
02886
02887
02888
02889
02890
02891
02892
02893
02894 void
02895 Workaround_Dom_Info_For_In_Abnormal_Loop_Rgn (REGION * r) {
02896
02897 BS* empty_BB_set = BS_Create_Empty (1, &MEM_phase_pool);
02898
02899 for (TOPOLOGICAL_REGIONAL_CFG_ITER iter (r->Regional_Cfg ()) ;
02900 iter != 0 ; ++iter) {
02901
02902 if ((*iter)->Is_Region ()) {
02903 continue ;
02904 }
02905
02906 BB* b = (*iter)->BB_Node () ;
02907 Set_BB_dom_set (b,empty_BB_set);
02908 Set_BB_pdom_set (b, empty_BB_set);
02909 }
02910 }