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 "ipfec_options.h"
00049 #include "sched_util.h"
00050 #include "sched_path.h"
00051 #include "sched_cflow.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
01555
01556
01557
01558
01559
01560
01561
01562
01563
01564
01565
01566
01567
01568
01569
01570
01571
01572
01573 inline BS *
01574 RGN_CFLOW_MGR::_add_reachable_bbs (BB *from, BS * reach_bbs) {
01575 BS * reach_info = _reach_info_vect (from) ;
01576 Is_True (reach_info, ("reachable info is not available!"));
01577
01578 return BS_UnionD (reach_info, reach_bbs, &_mem_pool) ;
01579 }
01580
01581 inline BS *
01582 RGN_CFLOW_MGR::_add_reachable_bbs (REGION* rgn, BS * reach_bbs) {
01583 BS * reach_info = _reach_info_vect (rgn) ;
01584 Is_True (reach_info, ("reachable info is not available!"));
01585
01586 return BS_UnionD (reach_info, reach_bbs, &_mem_pool) ;
01587 }
01588
01589 inline BS *
01590 RGN_CFLOW_MGR::_add_reachable_bbs (
01591 REGIONAL_CFG_NODE * node, BS * reach_bbs) {
01592
01593 return node->Is_Region () ?
01594 _add_reachable_bbs (node->Region_Node(), reach_bbs) :
01595 _add_reachable_bbs (node->BB_Node () , reach_bbs);
01596 }
01597
01598 inline BS *
01599 RGN_CFLOW_MGR::_set_bb_is_reachable (BS* reach_vect, BB * bb,MEM_POOL* p) {
01600
01601 return BS_Union1D (reach_vect, _bb_2_map_idx(bb),p);
01602 }
01603
01604 inline BOOL
01605 RGN_CFLOW_MGR::_is_bb_reachable (BS *reach_vect, BB *bb) {
01606
01607 return BS_MemberP (reach_vect, _bb_2_map_idx(bb));
01608 }
01609
01610
01611 inline void
01612 RGN_CFLOW_MGR::_set_bb_reach_prob (REACH_PROB_VECT* prob_vect,
01613 BB* src_bb, REACH_PROB prob) {
01614
01615 INT32 map_idx = _bb_2_map_idx(src_bb);
01616 Is_True (map_idx < prob_vect->elem_num,
01617 ("map idx out of range"));
01618 prob_vect->reach_prob_vect[map_idx] = prob ;
01619
01620 }
01621
01622 inline void
01623 RGN_CFLOW_MGR::_set_bb_reach_prob (BB *from, BB* to,REACH_PROB prob) {
01624
01625 REACH_PROB_VECT * vect = _reach_prob_vect (from);
01626 Is_True (vect, ("reachable prob is NULL")) ;
01627
01628 INT32 map_idx = _bb_2_map_idx(to) ;
01629 Is_True (map_idx < vect->elem_num, ("map idx out of range"));
01630 vect->reach_prob_vect[map_idx] = prob ;
01631 }
01632
01633
01634 REACH_PROB
01635 RGN_CFLOW_MGR::_bb_reach_prob (REGION * from,BB *to) {
01636 REACH_PROB_VECT * vect = _reach_prob_vect(from);
01637 Is_True (vect, ("reachable prob is NULL")) ;
01638
01639 INT32 map_idx = _bb_2_map_idx(to) ;
01640 Is_True (map_idx < vect->elem_num, ("map idx out of range"));
01641
01642 return vect->reach_prob_vect[map_idx];
01643 }
01644
01645 REACH_PROB
01646 RGN_CFLOW_MGR::_bb_reach_prob (BB * from,BB *to) {
01647 REACH_PROB_VECT * vect = _reach_prob_vect(from);
01648 Is_True (vect, ("reachable prob is NULL"));
01649
01650 INT32 map_idx = _bb_2_map_idx(to) ;
01651 Is_True (map_idx < vect->elem_num, ("map idx out of range"));
01652
01653 return vect->reach_prob_vect[map_idx];
01654 }
01655
01656 REACH_PROB
01657 RGN_CFLOW_MGR::_bb_reach_prob (REGIONAL_CFG_NODE * node,BB *to) {
01658 return node->Is_Region () ?
01659 _bb_reach_prob (node->Region_Node(), to) :
01660 _bb_reach_prob (node->BB_Node () , to);
01661 }
01662
01663
01664 void
01665 RGN_CFLOW_MGR::_fused_mult_add (REACH_PROB_VECT * dest, REACH_PROB_VECT *src,
01666 float mult_by) {
01667
01668 Is_True (dest->elem_num == src->elem_num, ("mismatch vector!"));
01669
01670 for (INT32 i = dest->elem_num - 1 ; i >= 1 ; i --) {
01671 dest->reach_prob_vect[i] =
01672 INT32(dest->reach_prob_vect[i] + src->reach_prob_vect[i] * mult_by) ;
01673 }
01674 }
01675
01676
01677
01678
01679
01680
01681
01682
01683 void
01684 RGN_CFLOW_MGR::_acquire_cflow_info (void) {
01685
01686 _acquire_basic_cflow_info ();
01687
01688 _setup_map_array () ;
01689 _setup_node_cflow_info_array () ;
01690
01691
01692
01693
01694
01695
01696
01697 UINT32 next_bb_map_idx = ID_MAP_BASE ;
01698 UINT32 next_rgn_map_idx = ID_MAP_BASE ;
01699
01700 INT32 max_leaf_node_level = 0 ;
01701
01702 for (TOPOLOGICAL_REGIONAL_CFG_ITER iter (_scope->Regional_Cfg()) ;
01703 iter != 0 ; ++iter) {
01704
01705 BB * b ; REGION * r;
01706
01707 if (!(*iter)->Is_Region()) {
01708 b = (*iter)->BB_Node () ;
01709 _bb_id_2_map_idx_vect [BB_id(b)] = next_bb_map_idx ;
01710 _map_idx_2_bb_vect [next_bb_map_idx++] = b ;
01711
01712 _node_cflow_info(b).node.bb = b;
01713
01714 } else {
01715 r = (*iter)->Region_Node() ;
01716 _rgn_id_2_map_idx_vect [r->Id()] = next_rgn_map_idx ;
01717 _map_idx_2_rgn_vect [next_rgn_map_idx++] = r ;
01718
01719 _node_cflow_info(r).node.rgn = r ;
01720 }
01721
01722 UINT32 level = Min_Level (*iter) ;
01723 for (CFG_PRED_NODE_ITER preds(*iter) ; preds != 0 ; ++preds) {
01724 UINT32 l = Min_Level (*preds) ;
01725 level = max (level,l+1) ;
01726 }
01727
01728 _NODE_CFLOW_INFO& info = _node_cflow_info (*iter);
01729 info.min_level = level ;
01730 info.max_level = _bb_num + _rgn_num + 1;
01731
01732 if (!(*iter)->Succ_Num()) {
01733 max_leaf_node_level = max(max_leaf_node_level, level);
01734 }
01735 }
01736
01737
01738
01739
01740 for (REVERSE_TOPO_REGIONAL_CFG_ITER iter (_scope->Regional_Cfg()) ;
01741 iter != 0 ; ++iter) {
01742
01743 if (!(*iter)->Succ_Num()) {
01744 _node_cflow_info(*iter).max_level = max_leaf_node_level ;
01745 }
01746
01747 UINT32 level = _node_cflow_info(*iter).max_level ;
01748
01749 for (CFG_PRED_NODE_ITER preds(*iter) ; preds != 0 ; ++preds) {
01750 UINT32 l = Max_Level (*preds) ;
01751 _node_cflow_info (*preds).max_level = min(l, level-1);
01752 }
01753 }
01754
01755 _acquire_reachable_info () ;
01756 _acquire_reach_prob_info () ;
01757
01758 _exec_path_mgr.Acquire_Path_Info (Scope ());
01759 }
01760
01761 void
01762 RGN_CFLOW_MGR::_acquire_reachable_info (void) {
01763
01764 if (_bb_num) {
01765 Is_True (!_bb_node_cflow_info.empty (),
01766 ("_bb_node_cflow_info has not built up!")) ;
01767
01768 for (INT32 i = ID_MAP_BASE; i <= _bb_num ; i++) {
01769 _bb_node_cflow_info[i].reach_bb =
01770 _create_empty_reach_bb_vect ();
01771 }
01772 }
01773
01774 if (_rgn_num) {
01775 Is_True (!_rgn_node_cflow_info.empty (),
01776 ("_rgn_node_cflow_info has not built up!")) ;
01777 for (INT32 i = ID_MAP_BASE ; i <= _rgn_num ; i ++) {
01778 _rgn_node_cflow_info[i].reach_bb =
01779 _create_empty_reach_bb_vect ();
01780 }
01781 }
01782
01783 for (REVERSE_TOPO_REGIONAL_CFG_ITER iter(_scope->Regional_Cfg()) ;
01784 iter != 0 ; ++iter) {
01785 REACH_INFO_VECT * reach_bb = (_node_cflow_info(*iter)).reach_bb;
01786
01787 for (CFG_SUCC_NODE_ITER succs(*iter) ; succs != 0 ; ++succs) {
01788 REACH_INFO_VECT * succ_reach_bb =
01789 _node_cflow_info (*succs).reach_bb;
01790 Is_True (succ_reach_bb, ("succs reachable vector has not built up!"));
01791
01792 reach_bb = _add_reachable_bbs (*iter,succ_reach_bb);
01793 if ((*succs)->Is_Region()) continue ;
01794 reach_bb = _set_bb_is_reachable (reach_bb, (*succs)->BB_Node(),&_mem_pool);
01795 }
01796
01797 _node_cflow_info (*iter).reach_bb = reach_bb ;
01798 }
01799 }
01800
01801 void
01802 RGN_CFLOW_MGR::_acquire_reach_prob_info (void) {
01803 if (_bb_num == 0) return ;
01804
01805 if (_bb_num) {
01806
01807 for (INT32 i = ID_MAP_BASE ;
01808 i <= _bb_num + ID_MAP_BASE - 1 ; i++) {
01809
01810 _bb_node_cflow_info[i].reach_prob.elem_num =
01811 _max_bb_map_idx() + 1;
01812 _bb_node_cflow_info[i].reach_prob.vect_size =
01813 _max_bb_map_idx() + 1;
01814 _bb_node_cflow_info[i].reach_prob.reach_prob_vect =
01815 TYPE_MEM_POOL_ALLOC_N (REACH_PROB,
01816 &_mem_pool,_max_bb_map_idx() + 1);
01817 }
01818 }
01819
01820 if (_rgn_num) {
01821
01822 for (INT32 i = ID_MAP_BASE;
01823 i <= _rgn_num + ID_MAP_BASE - 1; i++) {
01824
01825 _rgn_node_cflow_info[i].reach_prob.elem_num =
01826 _max_bb_map_idx() + 1;
01827
01828 _rgn_node_cflow_info[i].reach_prob.vect_size =
01829 _max_bb_map_idx() + 1 ;
01830
01831 _rgn_node_cflow_info[i].reach_prob.reach_prob_vect =
01832 TYPE_MEM_POOL_ALLOC_N (REACH_PROB,
01833 &_mem_pool,_max_bb_map_idx() + 1);
01834 }
01835 }
01836
01837 REGIONAL_CFG * cfg = _scope -> Regional_Cfg();
01838
01839 for (REVERSE_TOPO_REGIONAL_CFG_ITER iter (cfg); iter != 0 ; ++iter) {
01840 if (!(*iter)->Is_Region()) {
01841 BB *bb = (*iter)->BB_Node() ;
01842 _set_bb_reach_prob (bb,bb,(UINT32)(1.0 * REACH_PROB_SCALE)) ;
01843 }
01844
01845 REACH_PROB_VECT * dest = _reach_prob_vect (*iter) ;
01846
01847 for (REGIONAL_CFG_EDGE * edges = (*iter)->First_Succ() ;
01848 edges != NULL ; edges = edges->Next_Succ()) {
01849 REACH_PROB_VECT * src = _reach_prob_vect (edges->Dest()) ;
01850 _fused_mult_add (dest, src, cfg->Edge_Prob(edges)) ;
01851 }
01852 }
01853 }
01854
01855
01856 UINT16
01857 RGN_CFLOW_MGR::bb_node_succ_num (REGIONAL_CFG_NODE * node) {
01858 REGIONAL_CFG_EDGE * edge ;
01859 INT icount = 0 ;
01860 for (edge = node->First_Succ() ; edge ; edge = edge->Next_Succ())
01861 if (!edge->Dest()->Is_Region()) ++ icount ;
01862 return icount ;
01863 }
01864
01865 UINT16
01866 RGN_CFLOW_MGR::bb_node_pred_num (REGIONAL_CFG_NODE * node) {
01867 REGIONAL_CFG_EDGE * edge ;
01868 INT icount = 0 ;
01869 for (edge = node->First_Pred() ; edge ; edge = edge->Next_Pred())
01870 if (!edge->Dest()->Is_Region()) ++ icount ;
01871 return icount ;
01872 }
01873
01874 BOOL
01875 RGN_CFLOW_MGR::Has_Scheduled_Preds (BB* bb) {
01876 BBLIST *pred ;
01877 FOR_ALL_BB_PREDS (bb,pred)
01878 if (BB_scheduled (pred->item)) return TRUE;
01879
01880 return FALSE ;
01881 }
01882
01883 BOOL
01884 RGN_CFLOW_MGR::Critical_Edge_Present (REGION *rgn) {
01885
01886 REGIONAL_CFG *cfg = rgn->Regional_Cfg() ;
01887
01888 for (TOPOLOGICAL_REGIONAL_CFG_ITER iter(cfg); iter!=0;++iter){
01889
01890 REGIONAL_CFG_NODE *node = *iter;
01891 if(node->Is_Region()) continue;
01892 if(node->Succ_Num()<=1) continue;
01893
01894 INT succ_bb_num , pred_bb_num ;
01895
01896 succ_bb_num = bb_node_succ_num (node) ;
01897 if (succ_bb_num <= 1) continue ;
01898
01899 for(REGIONAL_CFG_EDGE *edge = node->First_Succ(); edge!=NULL; edge = edge->Next_Succ()){
01900 REGIONAL_CFG_NODE *succ_node = edge->Dest();
01901 if(succ_node->Is_Region()) continue;
01902 if (bb_node_pred_num (succ_node) > 1)
01903 return TRUE ;
01904 }
01905 }
01906
01907 return FALSE ;
01908
01909 }
01910
01911
01912 void
01913 RGN_CFLOW_MGR::_compute_node_level () {
01914
01915 for (TOPOLOGICAL_REGIONAL_CFG_ITER iter(_scope->Regional_Cfg()) ;
01916 iter != 0 ; ++iter) {
01917
01918 _NODE_CFLOW_INFO& cflow_info = _node_cflow_info (*iter) ;
01919 cflow_info.min_level = 1 ;
01920 cflow_info.max_level = 1 ;
01921
01922 }
01923
01924
01925 for (TOPOLOGICAL_REGIONAL_CFG_ITER iter(_scope->Regional_Cfg()) ;
01926 iter != 0 ; ++iter) {
01927 INT32 level ;
01928
01929 _NODE_CFLOW_INFO& cflow_info = _node_cflow_info (*iter);
01930 level = cflow_info.min_level - 1;
01931
01932 for (CFG_PRED_NODE_ITER preds(*iter) ; preds != 0 ; ++preds) {
01933 INT32 L = Min_Level (*preds);
01934 level = (level > L) ? level : L ;
01935 }
01936
01937 cflow_info.min_level = cflow_info.max_level = level + 1 ;
01938 }
01939
01940
01941 for (REVERSE_TOPO_REGIONAL_CFG_ITER iter (_scope->Regional_Cfg()) ;
01942 iter != 0 ; ++iter) {
01943
01944 INT32 level ;
01945
01946 _NODE_CFLOW_INFO& cflow_info = _node_cflow_info (*iter);
01947 level = cflow_info.max_level + 1;
01948
01949 for (CFG_SUCC_NODE_ITER succs(*iter) ; succs != 0 ; ++succs) {
01950 INT32 L = Max_Level(*succs);
01951 level = (level > L) ? level : L ;
01952 }
01953
01954 cflow_info.max_level = level - 1 ;
01955 }
01956 }
01957
01958 INT32
01959 RGN_CFLOW_MGR::Across_Node_Num (BB * from , BB * to) {
01960
01961 if (from == to) return 0 ;
01962
01963 BB * ance , * desc ;
01964 if (BB1_Reachable_From_BB2 (to, from)) {
01965 ance = from ; desc = to ;
01966 } else {
01967 ance = to ; desc = from ;
01968 }
01969
01970 if (!BB1_Reachable_From_BB2(desc, ance)) return 0 ;
01971
01972 INT32 d1 = Max_Level (desc) - Max_Level (ance);
01973
01974 INT32 d2 = Min_Level (desc) - Min_Level (ance);
01975
01976 return d1 < d2 ? d1 : d2 ;
01977 }
01978
01979
01980
01981
01982
01983
01984
01985
01986
01987
01988
01989
01990
01991 static BB_VECTOR _splitted_pu_boundary_bbs ;
01992
01993
01994
01995
01996
01997
01998
01999
02000
02001
02002
02003
02004
02005
02006 static BOOL
02007 BB_Has_Already_Been_Splitted (BB * bb) {
02008
02009 Is_True (BB_entry(bb) || BB_exit(bb),
02010 ("BB:%d is neither entry- nor exit-BB", BB_id(bb)));
02011
02012 for (BB_VECTOR_ITER iter = _splitted_pu_boundary_bbs.begin() ;
02013 iter != _splitted_pu_boundary_bbs.end () ; iter ++) {
02014
02015 if (*iter == bb) return TRUE;
02016 }
02017
02018 return FALSE ;
02019 }
02020
02021
02022
02023
02024
02025
02026
02027
02028
02029
02030
02031 void
02032 Init_Split_PU_Entry_Or_Exit_BB (void) {
02033 _splitted_pu_boundary_bbs.clear () ;
02034
02035
02036
02037
02038
02039 if (!BB_exit (REGION_First_BB) ||
02040 !IPFEC_Glos_Split_Entry_BB || !IPFEC_Glos_Split_Exit_BB) {
02041 return ;
02042 }
02043
02044
02045
02046
02047
02048
02049
02050
02051
02052 OP* exit_boundary_op = NULL, *entry_boundary_op = NULL, *op;
02053 FOR_ALL_BB_OPs_FWD (REGION_First_BB, op) {
02054 if (OP_no_move_before_gra (op) && OP_Is_Copy_From_Save_TN (op)) {
02055 exit_boundary_op = op; break;
02056 }
02057 }
02058 while (exit_boundary_op &&
02059 (exit_boundary_op = OP_prev(exit_boundary_op)) &&
02060 OP_no_move_before_gra (exit_boundary_op)) {
02061 }
02062
02063
02064
02065
02066 FOR_ALL_BB_OPs_REV (REGION_First_BB, op) {
02067 if (OP_no_move_before_gra (op) && OP_Is_Copy_To_Save_TN (op)) {
02068 entry_boundary_op = op;
02069 break;
02070 }
02071 }
02072 while (entry_boundary_op &&
02073 (entry_boundary_op = OP_next(entry_boundary_op)) &&
02074 OP_no_move_before_gra (entry_boundary_op)) {
02075 }
02076
02077 if (!entry_boundary_op || !exit_boundary_op) {
02078 return;
02079 }
02080
02081
02082
02083
02084 INT insn_cnt = 0;
02085 OP* t = entry_boundary_op;
02086 for (; t && t != exit_boundary_op; t = OP_next(t)) {
02087 insn_cnt ++;
02088 }
02089 if (t != exit_boundary_op) {
02090
02091 return;
02092 }
02093
02094 if (insn_cnt < 4) {
02095
02096
02097
02098 return;
02099 }
02100
02101 RGN_Divide_BB (REGION_First_BB, exit_boundary_op);
02102 RGN_Divide_BB (REGION_First_BB, OP_prev(entry_boundary_op));
02103 }
02104
02105
02106
02107
02108
02109
02110
02111
02112 static void
02113 Add_Splitted_Entry_Exit_BB (BB *bb) {
02114
02115 Is_True (BB_entry (bb) || BB_exit (bb),
02116 ("BB:%d is neither entry- nor exit-BB",
02117 BB_id(bb)));
02118 Is_True (!BB_Has_Already_Been_Splitted (bb),
02119 ("BB:%d has already splitted", BB_id(bb)));
02120
02121 _splitted_pu_boundary_bbs.push_back (bb);
02122 }
02123
02124
02125
02126
02127
02128
02129
02130
02131 void
02132 Remove_Splitted_Entry_Exit_BB (BB * bb) {
02133
02134 for (BB_VECTOR_ITER iter = _splitted_pu_boundary_bbs.begin () ;
02135 iter != _splitted_pu_boundary_bbs.end () ; iter ++) {
02136
02137 if (*iter == bb) {
02138 _splitted_pu_boundary_bbs.erase (iter) ;
02139 return ;
02140 }
02141 }
02142 }
02143
02144
02145
02146
02147
02148
02149
02150
02151
02152
02153 static void
02154 Copy_Entry_BB_Annotation (BB* entry_bb, BB* splitted_bb) {
02155
02156 for (ANNOTATION * annot = BB_annotations (entry_bb) ; annot ;
02157 annot = ANNOT_next (annot)) {
02158
02159 switch (ANNOT_kind(annot)) {
02160
02161 case ANNOT_LABEL:
02162 case ANNOT_ENTRYINFO :
02163 case ANNOT_EXITINFO :
02164 break ;
02165
02166 case ANNOT_PRAGMA :
02167 case ANNOT_CALLINFO :
02168 case ANNOT_NOTE :
02169 case ANNOT_LOOPINFO :
02170 case ANNOT_SWITCH :
02171 case ANNOT_ROTATING_KERNEL :
02172 case ANNOT_ASMINFO :
02173 BB_Add_Annotation (splitted_bb,ANNOT_kind (annot),ANNOT_info(annot));
02174 break ;
02175
02176 default :
02177 Is_True (FALSE , ("unknow annotation \n")) ;
02178 }
02179 }
02180 }
02181
02182
02183
02184
02185
02186
02187
02188
02189
02190
02191 BB *
02192 Split_PU_Entry_BB (BB * entry_bb) {
02193
02194 Is_True (BB_entry (entry_bb),
02195 ("BB:%d is not entry BB", BB_id(entry_bb)));
02196 Is_True (!BB_Has_Already_Been_Splitted (entry_bb),
02197 ("BB:%d has already been splitted", BB_id(entry_bb)));
02198
02199 if (BB_handler(entry_bb)) return NULL;
02200
02201 OP * last_op, *boundary_op, * sp_adj;
02202 sp_adj = BB_entry_sp_adj_op (entry_bb);
02203
02204 for (boundary_op = BB_last_op (entry_bb);
02205 boundary_op && boundary_op != sp_adj ;
02206 boundary_op = OP_prev(boundary_op)) {
02207
02208 if (OP_glue(boundary_op) ||
02209 OP_no_move_before_gra(boundary_op) ||
02210 OP_access_reg_bank(boundary_op)) {
02211 break ;
02212 }
02213 }
02214
02215 Is_True (boundary_op , ("boundary_op can't be null\n"));
02216 if (boundary_op == BB_last_op(entry_bb)) {
02217 return NULL;
02218 }
02219
02220
02221
02222
02223
02224 REGION * home_rgn = Home_Region (entry_bb);
02225 REGIONAL_CFG * rgn_cfg = home_rgn->Regional_Cfg();
02226
02227 BB * split_bb =
02228 RGN_Gen_And_Insert_BB_After (entry_bb, home_rgn->Regional_Cfg()) ;
02229 BB_freq (split_bb) = BB_freq (entry_bb);
02230
02231 BBLIST * nxt, * succ;
02232 for (succ = BB_succs (entry_bb); succ; succ = nxt) {
02233
02234 BB* bb_succ = BBLIST_item(succ);
02235 nxt = BBLIST_next(succ);
02236 RGN_Link_Pred_Succ_With_Prob(split_bb, bb_succ, BBLIST_prob(succ));
02237 RGN_Unlink_Pred_Succ(entry_bb, bb_succ);
02238
02239 }
02240
02241 RGN_Link_Pred_Succ_With_Prob (entry_bb, split_bb, 1.0f);
02242
02243
02244
02245 while (OP_next(boundary_op)) {
02246
02247 BB_Move_Op_To_End (split_bb, entry_bb, OP_next(boundary_op)) ;
02248
02249 }
02250
02251
02252
02253
02254 BB_bbregs (split_bb) = BB_bbregs (entry_bb);
02255
02256
02257
02258 BB_flag (split_bb) = BB_flag (entry_bb) ;
02259 Reset_BB_entry (split_bb) ;
02260
02261 Copy_Entry_BB_Annotation (entry_bb,split_bb);
02262
02263 if (entry_bb) { Add_Splitted_Entry_Exit_BB (entry_bb) ; }
02264
02265 return entry_bb ;
02266 }
02267
02268
02269
02270
02271
02272
02273
02274
02275
02276
02277 BB *
02278 Split_PU_Entry_BB (REGION * rgn) {
02279
02280 NODE_VECTOR rgn_entry = rgn->Entries () ;
02281
02282 Is_True (rgn_entry.size() == 1 ,
02283 ("Split_PU_Entry_BB() region has more than one entries\n"));
02284
02285 REGIONAL_CFG_NODE * cfg_node = *(rgn_entry.begin());
02286
02287 BB * entry_bb ;
02288
02289 if (cfg_node->Is_Region() ||
02290 (entry_bb = cfg_node->BB_Node()) && !BB_entry(entry_bb)) {
02291 return NULL;
02292 }
02293
02294 return !BB_exit(entry_bb) ? Split_PU_Entry_BB (entry_bb) : NULL;
02295 }
02296
02297
02298
02299
02300
02301
02302
02303
02304
02305
02306
02307
02308
02309
02310
02311
02312
02313
02314
02315
02316
02317
02318
02319
02320
02321
02322
02323 static void
02324 Sink_Return_Val_OP (BB * split, BB * exit) {
02325
02326 Is_True (BB_exit(exit) &&
02327 BB_Unique_Predecessor(exit) == split &&
02328 !BB_xfer_op(split),
02329 ("BB:%d is not splited from BB:%d",
02330 BB_id(split), BB_id(exit)));
02331
02332 if (BB_length(split) <= 0) return ;
02333
02334 CG_DEP_Compute_Graph (
02335 split,
02336 INCLUDE_ASSIGNED_REG_DEPS,
02337 NON_CYCLIC,
02338 INCLUDE_MEMREAD_ARCS,
02339 INCLUDE_MEMIN_ARCS,
02340 NO_CONTROL_ARCS,
02341 NULL);
02342
02343 Reset_BB_scheduled (split) ;
02344 Reset_BB_scheduled (exit) ;
02345
02346 #define OP_Should_Sink(o) OP_Scheduled((o))
02347 #define Set_OP_Should_Sink(o) Set_OP_Scheduled((o))
02348 #define Reset_OP_Should_Sink(o) Reset_OP_Scheduled((o))
02349
02350 OP * op ;
02351 FOR_ALL_BB_OPs (split, op) {
02352 Reset_OP_Should_Sink(op);
02353 }
02354
02355 FOR_ALL_BB_OPs (split, op) {
02356 if (OP_def_return_value(op) || OP_use_return_value(op)) {
02357 Set_OP_Should_Sink(op);
02358 }
02359
02360 if (OP_Should_Sink(op)) {
02361 for (ARC_LIST * arcs = OP_succs(op) ;
02362 arcs != NULL;
02363 arcs = ARC_LIST_rest(arcs)) {
02364
02365 ARC * arc = ARC_LIST_first(arcs);
02366 OP * succ = ARC_succ(arc);
02367
02368 if (OP_bb(succ) == split) {
02369 Set_OP_Should_Sink (succ);
02370 }
02371 }
02372 }
02373 }
02374
02375 OP * prev_op ;
02376 for (op = BB_last_op(split); op ; op = prev_op) {
02377
02378 prev_op = OP_prev(op);
02379
02380 if (OP_Should_Sink(op)) {
02381 BB_Move_Op_To_Start (exit, split, op);
02382 Reset_OP_Should_Sink(op);
02383 }
02384 }
02385
02386 CG_DEP_Delete_Graph (split);
02387
02388 #undef OP_Should_Sink
02389 #undef Set_OP_Should_Sink
02390 #undef Reset_OP_Should_Sink
02391
02392 }
02393
02394
02395
02396 static void
02397 Copy_Exit_BB_Annot (BB * exit_bb, BB * splitted_exit) {
02398
02399 for (ANNOTATION * ant = BB_annotations (exit_bb) ;
02400 ant ;
02401 ant = ANNOT_next (ant)) {
02402
02403 BOOL add_annot ;
02404 add_annot = TRUE;
02405
02406 switch (ANNOT_kind(ant)) {
02407 case ANNOT_LABEL:
02408 Set_BB_has_label (splitted_exit); break;
02409
02410 case ANNOT_PRAGMA:
02411 Set_BB_has_pragma (splitted_exit); break;
02412
02413 case ANNOT_ENTRYINFO:
02414 case ANNOT_EXITINFO:
02415 add_annot = FALSE; break ;
02416
02417 case ANNOT_NOTE:
02418 Set_BB_has_note(splitted_exit); break;
02419
02420 case ANNOT_LOOPINFO:
02421 FmtAssert (FALSE,
02422 ("Exit block BB:%d should not has loop-info annotation",
02423 BB_id(exit_bb)));
02424 add_annot = FALSE; break ;
02425
02426 case ANNOT_CALLINFO:
02427 FmtAssert (FALSE,
02428 ("Exit block BB:%d should not has call-info annotation",
02429 BB_id(exit_bb)));
02430 add_annot = FALSE; break ;
02431 continue;
02432
02433 case ANNOT_ASMINFO:
02434 Set_BB_asm(exit_bb); break;
02435
02436 case ANNOT_SWITCH:
02437
02438 FmtAssert (FALSE,
02439 ("Exit block BB:%d should not has switch annotation",
02440 BB_id(exit_bb)));
02441 add_annot = FALSE; break ;
02442
02443 case ANNOT_ROTATING_KERNEL:
02444 FmtAssert (FALSE,
02445 ("Exit block BB:%d cannot be a rotating kernel",
02446 BB_id(exit_bb)));
02447 add_annot = FALSE; break ;
02448
02449 default:
02450 FmtAssert(FALSE,
02451 ("unexpected annotation kind: %d", ANNOT_kind(ant)));
02452 }
02453
02454
02455 if (add_annot) {
02456 BB_Add_Annotation
02457 (splitted_exit, ANNOT_kind(ant), ANNOT_info(ant));
02458 }
02459 }
02460 }
02461
02462
02463
02464
02465
02466
02467
02468
02469
02470
02471
02472
02473 BB *
02474 Split_PU_Exit_BB (BB * epi) {
02475
02476 Is_True (BB_exit(epi), ("BB:%d is not exit BB", BB_id(epi)));
02477
02478 Is_True (!BB_Has_Already_Been_Splitted (epi),
02479 ("BB:%d has already been splitted", BB_id(epi)));
02480
02481 if (BB_entry(epi)) {
02482
02483
02484
02485
02486 return NULL;
02487 }
02488
02489 OP * sp_adj = BB_exit_sp_adj_op (epi);
02490 OP * op_tmp, * op_boundary = NULL;
02491
02492 for (op_tmp = BB_first_op (epi) ;
02493 op_tmp && op_tmp != sp_adj ;
02494 op_tmp = OP_next(op_tmp)) {
02495
02496 if (OP_glue(op_tmp) ||
02497 OP_no_move_before_gra(op_tmp) ||
02498 OP_access_reg_bank(op_tmp)) {
02499
02500 op_boundary = OP_prev(op_tmp);
02501 break ;
02502
02503 }
02504 }
02505
02506 if (!op_boundary) { return NULL; }
02507
02508
02509
02510 REGION * home_rgn = Home_Region (epi);
02511 REGIONAL_CFG * rgn_cfg = home_rgn->Regional_Cfg();
02512
02513 BB * split_bb =
02514 RGN_Gen_And_Insert_BB_Before (epi, home_rgn->Regional_Cfg());
02515 BB_freq (split_bb) = BB_freq (epi);
02516
02517
02518
02519 while (BBLIST * pred_item = BB_preds(epi)) {
02520
02521 BB* pred_bb = BBLIST_item (pred_item);
02522
02523
02524
02525
02526 float prob = BBLIST_prob (BB_Find_Succ(pred_bb,epi));
02527
02528 RGN_Link_Pred_Succ_With_Prob(pred_bb, split_bb, prob);
02529 RGN_Unlink_Pred_Succ(pred_bb,epi);
02530
02531 }
02532
02533 RGN_Link_Pred_Succ_With_Prob (split_bb, epi, 1.0f);
02534
02535
02536
02537
02538
02539 for (; op_boundary ; op_boundary = op_tmp) {
02540 op_tmp = OP_prev(op_boundary);
02541 BB_Move_Op_To_Start (split_bb, epi, op_boundary) ;
02542 }
02543
02544
02545
02546
02547 BB_bbregs (split_bb) = BB_bbregs (epi);
02548
02549
02550
02551 BB_flag (split_bb) = BB_flag (epi) ;
02552 Reset_BB_exit (split_bb) ;
02553 Reset_BB_call (split_bb);
02554
02555 Add_Splitted_Entry_Exit_BB (epi) ;
02556
02557 Copy_Exit_BB_Annot (epi, split_bb);
02558
02559
02560
02561
02562 Sink_Return_Val_OP (split_bb, epi);
02563
02564 return epi;
02565 }
02566
02567
02568
02569
02570
02571
02572
02573
02574
02575
02576
02577
02578
02579 void
02580 Split_PU_Exit_BB (REGION * rgn) {
02581
02582 NODE_VECTOR rgn_exits = rgn->Exits () ;
02583
02584 for (NODE_VECTOR_ITER iter = rgn_exits.begin () ;
02585 iter != rgn_exits.end () ;
02586 iter ++) {
02587
02588 REGIONAL_CFG_NODE * cfg_node = *iter;
02589 if (cfg_node->Is_Region()) continue ;
02590
02591 BB * epi = cfg_node->BB_Node () ;
02592 if (BB_exit (epi)) {
02593 epi = Split_PU_Exit_BB (epi);
02594 }
02595 }
02596
02597 }
02598
02599
02600
02601
02602
02603
02604
02605
02606
02607
02608 void
02609 Merge_Splitted_PU_Entry_BB (BB * splitted_entry) {
02610
02611 Is_True (BB_entry (splitted_entry),
02612 ("BB:%d is not entry-BB", BB_id(splitted_entry)));
02613
02614 BB* split = BB_Unique_Successor (splitted_entry) ;
02615 Is_True (split && !BB_xfer_op(splitted_entry),
02616 ("BB:%d is not splitted entry BB %d\n",
02617 BB_id(splitted_entry)));
02618
02619
02620 BBLIST * nxt, *succ;
02621 for (succ = BB_succs(split); succ; succ = nxt) {
02622
02623 BB* bb_succ = BBLIST_item(succ);
02624 nxt = BBLIST_next(succ);
02625 RGN_Link_Pred_Succ_With_Prob (splitted_entry, bb_succ,
02626 BBLIST_prob(succ));
02627 RGN_Unlink_Pred_Succ(split, bb_succ);
02628
02629 }
02630
02631 RGN_Unlink_Pred_Succ (splitted_entry, split);
02632
02633
02634 BB_Append_All (splitted_entry, split);
02635 BB_bbregs (split) = NULL ;
02636
02637 if (BB_call (splitted_entry)) {
02638
02639 OP * op = BB_xfer_op (splitted_entry) ;
02640
02641 if (!op || !OP_call (op)) {
02642
02643 Reset_BB_call (splitted_entry) ;
02644
02645 ANNOTATION * bb_annot = BB_annotations (splitted_entry) ;
02646 ANNOTATION * call_annot ;
02647
02648 if (bb_annot &&
02649 (call_annot = ANNOT_Get (bb_annot,ANNOT_CALLINFO)))
02650 ANNOT_Unlink (bb_annot,call_annot) ;
02651
02652 }
02653 }
02654
02655 extern void Clean_Up (BB *bb);
02656 Clean_Up (splitted_entry);
02657
02658 RGN_Remove_BB_And_Edges (split);
02659
02660 Remove_Splitted_Entry_Exit_BB (splitted_entry);
02661 }
02662
02663
02664
02665
02666
02667
02668
02669
02670
02671 void
02672 Merge_Splitted_PU_Exit_BB (BB * exit_block) {
02673
02674 Is_True (BB_exit (exit_block),
02675 ("BB:%d is not exit-block", BB_id(exit_block)));
02676
02677 BB* split = BB_Unique_Predecessor (exit_block);
02678 Is_True (split && !BB_xfer_op(split),
02679 ("BB:%d is not splitted exit BB %d\n", BB_id(exit_block)));
02680
02681 while (BBLIST * pred_item = BB_preds(split)) {
02682
02683 BB* p = BBLIST_item(pred_item);
02684 float prob = BBLIST_prob (BB_Find_Succ(p,split));
02685
02686 RGN_Link_Pred_Succ_With_Prob (p, exit_block, prob);
02687 RGN_Unlink_Pred_Succ(p,split);
02688 }
02689
02690 RGN_Unlink_Pred_Succ (split, exit_block);
02691
02692
02693 BB_Prepend_All (exit_block, split);
02694 BB_bbregs (split) = NULL ;
02695
02696 extern void Clean_Up (BB *bb);
02697 Clean_Up (exit_block);
02698
02699 RGN_Remove_BB_And_Edges (split);
02700
02701 Remove_Splitted_Entry_Exit_BB (exit_block);
02702 }
02703
02704
02705
02706
02707
02708
02709
02710
02711
02712
02713
02714 void
02715 Merge_All_Splitted_Entry_and_Exit_BB (void) {
02716
02717 while (!_splitted_pu_boundary_bbs.empty ()) {
02718
02719
02720
02721 BB * bb = _splitted_pu_boundary_bbs.back () ;
02722 if (BB_entry(bb)) {
02723 Merge_Splitted_PU_Entry_BB (bb) ;
02724 } else if (BB_exit(bb)) {
02725 Merge_Splitted_PU_Exit_BB (bb);
02726 } else {
02727 FmtAssert (FALSE,
02728 ("BB:%d is neither entry- nor exit-BB\n", BB_id(bb)));
02729 }
02730
02731 Is_True (_splitted_pu_boundary_bbs.empty () ||
02732 bb != _splitted_pu_boundary_bbs.back (),
02733
02734 ("Merge_Splitted_PU_{Entry|Exit}_BB has not erase"
02735 " BB:%d from _splitted_pu_boundary_bbs",
02736 BB_id (bb))) ;
02737 }
02738 }
02739
02740
02741
02742
02743
02744
02745
02746
02747
02748
02749
02750 void
02751 Calculate_Dominator_Info (REGION_TREE *rgn_tree) {
02752
02753 Calculate_Dominators () ;
02754
02755 BS* empty_BB_set = BS_Create_Empty (PU_BB_Count + 2,
02756 &MEM_phase_pool);
02757
02758 typedef std::queue<REGION * > _RGN_QUEUE;
02759 _RGN_QUEUE rgn_queue ;
02760
02761 extern BOOL Is_Abnormal_Loop (REGION* region);
02762 extern BOOL Is_In_Infinite_Loop (REGION* region);
02763
02764 #define SET_RGN_IN_ABNORMAL_LOOP(x) { x = (REGION*)((INTPTR)(x) | 1); }
02765 #define GET_RGN(x) ((REGION*)(((INTPTR)(x)) & ~1))
02766 #define RGN_IN_ABNORMAL_LOOP(x) ((INTPTR)(x) & 1)
02767
02768 REGION * rgn = rgn_tree->Root();
02769 if (Is_Abnormal_Loop (rgn) || Is_In_Infinite_Loop (rgn)) {
02770 SET_RGN_IN_ABNORMAL_LOOP(rgn);
02771 }
02772
02773 rgn_queue.push (rgn);
02774
02775
02776 while (!rgn_queue.empty ()) {
02777
02778 REGION * tmp = rgn_queue.front();
02779 rgn_queue.pop () ;
02780
02781 if (RGN_IN_ABNORMAL_LOOP(tmp)) {
02782
02783 for (TOPOLOGICAL_REGIONAL_CFG_ITER
02784 iter ((GET_RGN(tmp))->Regional_Cfg());
02785 iter != 0; ++ iter) {
02786
02787 if ((*iter)->Is_Region ()) continue ;
02788
02789 BB * b = (*iter)->BB_Node ();
02790
02791
02792
02793
02794 Set_BB_pdom_set (b, empty_BB_set);
02795 }
02796 }
02797
02798 for (REGION_KID_ITER kids_iter(GET_RGN(tmp)) ;
02799 kids_iter != 0 ; ++kids_iter) {
02800
02801 REGION * nested_rgn = *kids_iter ;
02802 if (Is_Abnormal_Loop (nested_rgn) || Is_In_Infinite_Loop(nested_rgn)) {
02803 SET_RGN_IN_ABNORMAL_LOOP(nested_rgn);
02804 }
02805
02806 rgn_queue.push (nested_rgn);
02807 }
02808 }
02809 }
02810
02811 BOOL
02812 BB1_Postdominate_BB2 (BB * bb1, BB* bb2) {
02813 BOOL b = BB_SET_MemberP (BB_pdom_set(bb2), bb1);
02814
02815
02816
02817
02818
02819
02820
02821
02822
02823 if (!b) {
02824 if (bb1 == bb2) return TRUE;
02825
02826 INT visit_count = 0;
02827 for (BB* bb = BB_Unique_Successor(bb2);
02828 bb != NULL;
02829 bb = BB_Unique_Successor (bb),visit_count++) {
02830 if (bb == bb1) { return TRUE; }
02831 if (visit_count >= 200) {
02832
02833
02834
02835
02836
02837 break;
02838 }
02839 }
02840 }
02841
02842 return b;
02843 }
02844
02845
02846
02847
02848
02849
02850
02851
02852
02853
02854 BB_POS
02855 BB_Pos_Analysis
02856 (BB* bb, BB_VECTOR* cutting_set, RGN_CFLOW_MGR * cflow_info) {
02857
02858 for (BB_VECTOR_CONST_ITER iter = cutting_set->begin () ;
02859 iter != cutting_set->end() ;
02860 iter++) {
02861
02862 BB * tmp = *iter ;
02863 if (tmp == bb) return IN_SISS ;
02864
02865 if (cflow_info->BB1_Reachable_From_BB2 (tmp,bb)) {
02866 return ABOVE_SISS ;
02867 }
02868
02869 if (cflow_info->BB1_Reachable_From_BB2 (bb,tmp)) {
02870 return BELOW_SISS;
02871 }
02872 }
02873
02874 return OTHER;
02875 }
02876
02877
02878
02879
02880
02881
02882
02883
02884
02885 void
02886 RGN_CFLOW_MGR::Dump (FILE *f, BOOL verbose) {
02887
02888 if (verbose) {
02889 fprintf (f, "%s\t\tRGN_CFLOW_MGR status\n%s\n", DBar, DBar);
02890 }
02891
02892 if (!Valid ()) {
02893 if (verbose) { fputs ("Invalid!\n",f); }
02894 return ;
02895 }
02896
02897 char * prompt = "BBS REACHABLE FROM " ;
02898 INT num = 0, prompt_len = strlen(prompt);
02899
02900 for (TOPOLOGICAL_REGIONAL_CFG_ITER iter(_scope->Regional_Cfg());
02901 iter != 0 ; ++iter) {
02902
02903 BS * reach_info = _reach_info_vect (*iter);
02904 Is_True (reach_info,("fail to get reachable-BB"));
02905
02906 fprintf (f, "%s\t\t%s:%3d min-level %3d max-leve %3d\n",
02907 SBar,
02908 (*iter)->Is_Region () ? "RGN" : "BB",
02909 (*iter)->Is_Region () ? (*iter)->Region_Node()->Id() :
02910 BB_id((*iter)->BB_Node()),
02911 Min_Level(*iter),
02912 Max_Level(*iter)) ;
02913
02914 if (!(*iter)->Succ_Num()) {
02915 fputc ('\n', f);
02916 } else {
02917 fputs ("reachable nodes:", f);
02918 }
02919
02920 BS_ELT elt = BS_Choose(reach_info);
02921 if (elt == BS_CHOOSE_FAILURE ) {
02922 continue ;
02923 }
02924
02925 INT elem_count = -1;
02926 do {
02927 ++ elem_count ; if (!(elem_count % 5)) fprintf (f,"\n");
02928
02929 BB * bb = _map_idx_2_bb ((INT32)elt);
02930 mBB_NUM bb_id = BB_id (bb);
02931
02932 fprintf (f, "BB:%3d(p:%4.2f) ", (INT32)(BS_ELT)bb_id,
02933 (float)(_bb_reach_prob
02934 (*iter,bb)/(float)REACH_PROB_SCALE));
02935
02936 } while ((elt = BS_Choose_Next(reach_info,elt)) != BS_CHOOSE_FAILURE);
02937
02938 fputc ('\n', f);
02939 }
02940 }
02941
02942 #ifdef Is_True_On
02943 void
02944 RGN_CFLOW_MGR :: gdb_dump (void) {
02945 Dump (stderr); fflush (stderr);
02946 }
02947 #endif
02948
02949
02950
02951
02952
02953
02954
02955
02956 void
02957 Workaround_Dom_Info_For_In_Abnormal_Loop_Rgn (REGION * r) {
02958
02959 BS* empty_BB_set = BS_Create_Empty (1, &MEM_phase_pool);
02960
02961 for (TOPOLOGICAL_REGIONAL_CFG_ITER iter (r->Regional_Cfg ()) ;
02962 iter != 0 ; ++iter) {
02963
02964 if ((*iter)->Is_Region ()) {
02965 continue ;
02966 }
02967
02968 BB* b = (*iter)->BB_Node () ;
02969 Set_BB_dom_set (b,empty_BB_set);
02970 Set_BB_pdom_set (b, empty_BB_set);
02971 }
02972 }