00001
00002
00003
00004
00005
00006
00007
00008
00009
00010
00011
00012
00013
00014
00015
00016
00017
00018
00019
00020
00021
00022
00023
00024
00025
00026
00027
00028
00029
00030
00031
00032
00033
00034
00035
00036
00037
00038
00039
00040
00041
00042
00043
00044
00045
00046
00047
00048
00049
00050
00051
00052 #include "defs.h"
00053 #include "ipfec_defs.h"
00054 #include "ipfec_options.h"
00055
00056 #include "tracing.h"
00057 #include "errors.h"
00058
00059 #include "be_util.h"
00060
00061 #include "register.h"
00062
00063 #include "sched_rgn_info.h"
00064 #include "tn_set.h"
00065
00066 void
00067 RGN_CFG_PATH_INFO :: Derive_RGN_CFG_PATH_INFO_from_REGION_Node
00068 (RGN_SUMMARY * sum) {
00069
00070 if (!sum->Summary_Is_Valid ()) {
00071
00072
00073
00074
00075
00076
00077
00078
00079
00080 _summary_unknown = TRUE ;
00081 return ;
00082 }
00083
00084 _rgn_num = 1 ;
00085 _has_call = sum->Has_Call ();
00086 _has_load = sum->Has_Load ();
00087 _has_store = sum->Has_Store ();
00088 _has_rotating_kernel = sum->Has_Rotating_Kernel ();
00089
00090 _summary_unknown = FALSE ;
00091
00092 _killed_def = TN_SET_CopyD (_killed_def, sum->Killed_Def(), _mp);
00093 _tn_used = TN_SET_CopyD (_tn_used, sum->TN_Used (), _mp);
00094 }
00095
00096 void
00097 RGN_CFG_PATH_INFO :: Derive_RGN_CFG_PATH_INFO_from_BB_Node (BB * bb) {
00098
00099 _killed_def = TN_SET_ClearD (_killed_def);
00100 _tn_used = TN_SET_ClearD (_tn_used);
00101
00102 if (!(_has_call = BB_call(bb))) {
00103
00104
00105
00106
00107
00108
00109 OP * op ;
00110 FOR_ALL_BB_OPs (bb, op) {
00111
00112 if (OP_load (op)) { _has_load = TRUE ; }
00113 if (!_has_store && OP_like_store(op)) {
00114 _has_store = TRUE ;
00115 }
00116
00117 for (INT i = OP_results(op) - 1 ; i >= 0 ; --i) {
00118 TN * result_tn = OP_result(op,i);
00119
00120 if (TN_is_register(result_tn) &&
00121 !TN_is_const_reg(result_tn)) {
00122 _killed_def =
00123 TN_SET_Union1D (_killed_def, result_tn, _mp);
00124 }
00125
00126 }
00127
00128 for (INT i = OP_opnds(op) - 1 ; i >= 0 ; --i) {
00129 TN * opnd = OP_opnd(op,i);
00130
00131 if (TN_is_register(opnd) && !TN_is_const_reg(opnd)) {
00132 _tn_used =
00133 TN_SET_Union1D (_tn_used, opnd, _mp);
00134 }
00135 }
00136
00137 }
00138
00139 _has_rotating_kernel = BB_rotating_kernel (bb) ? TRUE : FALSE;
00140
00141 }
00142
00143 _bb_num = 1;
00144 _rgn_num = 0;
00145 _summary_unknown = FALSE ;
00146 }
00147
00148
00149
00150 class RGN_SUM_LEAF_NODE {
00151 private :
00152 BB * _bb ;
00153 RGN_SUM_LEAF_NODE * _next ;
00154 MEM_POOL * _mp ;
00155
00156 public:
00157 RGN_SUM_LEAF_NODE (MEM_POOL * mp);
00158 ~RGN_SUM_LEAF_NODE (void);
00159
00160 BB * Associated_BB (void) { return _bb ; }
00161 void Set_Associated_BB (BB * bb) { _bb = bb ;}
00162 };
00163
00164 class RGN_SUM_PATH {
00165 private :
00166 RGN_SUM_ROOT_NODE * _from ;
00167 RGN_SUM_LEAF_NODE * _to ;
00168
00169 MEM_POOL * _mp;
00170
00171 mINT16 _bb_num ;
00172 TN_SET* _killed_defs ;
00173
00174 BOOL _has_call ;
00175 BOOL _has_cannot_move_across_RGN ;
00176
00177 public :
00178
00179 RGN_SUM_PATH (MEM_POOL *mp) ;
00180 ~RGN_SUM_PATH (void) ;
00181
00182 RGN_SUM_ROOT_NODE * From (void) { return _from ; }
00183 RGN_SUM_LEAF_NODE * To (void) { return _to ; }
00184
00185 BOOL Path_Has_Call (void) { return _has_call ; }
00186 BOOL Path_Has_Cannot_Move_Across_Rgn (void) {
00187 return _has_cannot_move_across_RGN ;
00188 }
00189
00190 BOOL Can_OP_be_Hoisted_Along_Path (OP *op) ;
00191 };
00192
00193
00194 class RGN_SUM_ROOT_NODE {
00195 private :
00196 RGN_SUM_ROOT_NODE * _next ;
00197 RGN_SUM_LEAF_NODE * _leaf_nodes ;
00198 BB * _bb ;
00199 MEM_POOL * _mp ;
00200
00201 public:
00202 RGN_SUM_ROOT_NODE (MEM_POOL *mp) ;
00203 ~RGN_SUM_ROOT_NODE (void) ;
00204
00205 RGN_SUM_ROOT_NODE * Next_Root_Node (void) { return _next ; }
00206 RGN_SUM_LEAF_NODE * First_Leaf_Node (void) { _leaf_nodes ; }
00207
00208 BB * Associated_BB (void) { return _bb ; }
00209 void Set_Associated_BB (BB * bb) { _bb = bb ;}
00210 };
00211
00212
00213
00214
00215
00216
00217
00218
00219
00220
00221
00222 RGN_SUM_LEAF_NODE :: RGN_SUM_LEAF_NODE (MEM_POOL *mp) {
00223 _bb = NULL;
00224 _next = NULL;
00225 _mp = mp ;
00226 }
00227
00228 RGN_SUM_LEAF_NODE :: ~RGN_SUM_LEAF_NODE (void) {
00229 }
00230
00231
00232
00233
00234
00235
00236
00237
00238
00239 RGN_SUM_PATH :: RGN_SUM_PATH (MEM_POOL *mp) {
00240
00241 _from = NULL ;
00242 _to = NULL ;
00243 _bb_num = 0 ;
00244 _mp = mp;
00245 _killed_defs = TN_SET_Create_Empty (Last_TN,mp);
00246 _has_call = TRUE;
00247 _has_cannot_move_across_RGN = TRUE;
00248 }
00249
00250 RGN_SUM_PATH :: ~RGN_SUM_PATH (void) {}
00251
00252
00253
00254
00255
00256
00257
00258
00259
00260 RGN_SUM_ROOT_NODE :: RGN_SUM_ROOT_NODE (MEM_POOL *mp) {
00261 _next = NULL;
00262 _leaf_nodes = NULL;
00263 _bb = NULL;
00264 _mp = mp ;
00265 }
00266
00267 RGN_SUM_ROOT_NODE :: ~RGN_SUM_ROOT_NODE (void) {}
00268
00269
00270
00271
00272
00273
00274
00275
00276
00277
00278
00279 RGN_SUMMARY :: RGN_SUMMARY (REGION *rgn,MEM_POOL *mp) {
00280
00281 _rgn = rgn ; _mp = mp ; _forest = NULL;
00282 _rgn_type = rgn->Region_Type ();
00283
00284 _tree_num = 0;
00285 _summary_is_valid = FALSE ;
00286
00287 _killed_def = NULL;
00288 _tn_used = NULL;
00289 _has_call = TRUE;
00290 _has_nested_rgn = TRUE;
00291 _has_cannot_move_across_RGN = TRUE ;
00292 }
00293
00294 RGN_SUMMARY :: ~RGN_SUMMARY (void) {}
00295
00296
00297
00298
00299
00300
00301
00302
00303
00304
00305
00306 REGION_INFO_MGR * _rgn_info_mgr = NULL;
00307
00308
00309
00310
00311
00312
00313
00314
00315
00316
00317 RGN_CFG_PATH_INFO *
00318 REGION_INFO_MGR :: New_RGN_CFG_PATH_INFO (void) {
00319
00320 if (_free_rgn_cfg_path_info_lnk) {
00321 RGN_CFG_PATH_INFO * t = _free_rgn_cfg_path_info_lnk;
00322
00323 _free_rgn_cfg_path_info_lnk = t->Next ();
00324 t->Set_Next (NULL);
00325
00326 t->Clear () ;
00327
00328 return t ;
00329 }
00330
00331 return CXX_NEW(RGN_CFG_PATH_INFO(&_mem_pool), &_mem_pool);
00332 }
00333
00334
00335
00336
00337
00338
00339
00340
00341 void
00342 REGION_INFO_MGR :: Free_RGN_CFG_PATH_INFO (RGN_CFG_PATH_INFO * info) {
00343
00344 Is_True (!info->Next (), ("the next field is non-null"));
00345
00346 info->Set_Next (_free_rgn_cfg_path_info_lnk) ;
00347 _free_rgn_cfg_path_info_lnk = info ;
00348 }
00349
00350
00351
00352 REGION_INFO_MGR :: REGION_INFO_MGR (REGION_TREE *rgn_tree):
00353 _rgn_tree (rgn_tree) {
00354
00355 INT32 SIZE = 128;
00356
00357
00358
00359
00360
00361 _rgn_2_rgn_info = REGION_MAP_Create (SIZE);
00362
00363
00364
00365 _free_rgn_cfg_path_info_lnk = NULL;
00366 #define NODE_INFO_NUM (64)
00367 for (INT i = 0 ; i < NODE_INFO_NUM ; i++) {
00368 Free_RGN_CFG_PATH_INFO (
00369 CXX_NEW(RGN_CFG_PATH_INFO(&_mem_pool), &_mem_pool));
00370 }
00371
00372 Acquire_Rgn_Info ();
00373 }
00374
00375
00376
00377 REGION_INFO_MGR :: ~REGION_INFO_MGR (void) {
00378 _rgn_tree = NULL;
00379
00380 if (_rgn_2_rgn_info) {
00381 REGION_MAP_Delete (_rgn_2_rgn_info);
00382 _rgn_2_rgn_info = NULL;
00383 }
00384 }
00385
00386
00387
00388
00389
00390
00391
00392
00393
00394
00395
00396
00397
00398
00399
00400
00401
00402
00403
00404
00405
00406
00407
00408
00409 void
00410 REGION_INFO_MGR :: Acquire_Rgn_Info (void) {
00411
00412 RGN_INFO * rgn_info = CXX_NEW (RGN_INFO, &_mem_pool) ;
00413 rgn_info->skip_reason = SKIP_RGN_NONE ;
00414 rgn_info->rgn = _rgn_tree->Root ();
00415 rgn_info->summary = NULL;
00416
00417 extern BOOL Is_Abnormal_Loop (REGION* region) ;
00418 rgn_info->in_abnormal_loop = Is_Abnormal_Loop (rgn_info->rgn);
00419
00420 std::list<RGN_INFO *,mempool_allocator<RGN_INFO *> > queue(&_mem_pool) ;
00421 queue.push_back (rgn_info);
00422
00423 while (!queue.empty ()) {
00424
00425 RGN_INFO * tmp = *(queue.begin());
00426 queue.erase (queue.begin());
00427
00428
00429
00430
00431 REGION * rgn = tmp -> rgn ;
00432 SKIP_SCHED_RGN_REASON skip_reason = SKIP_RGN_NONE ;
00433
00434 if (IPFEC_Query_Skiplist(glos_skip_rgn, rgn->Id(), Current_PU_Count())) {
00435 skip_reason = SKIP_RGN_DEBUG ;
00436 fprintf (stdout, "skip rgn %d\n", rgn->Id ());
00437 } else if (rgn->Region_Type() == IMPROPER) {
00438 skip_reason = SKIP_RGN_IMPROPER;
00439 } else if (rgn->Is_No_Further_Opt()) {
00440 skip_reason = SKIP_RGN_NO_FURTHER_OPT;
00441 } else if (rgn->Entries().size() != 1) {
00442 skip_reason = SKIP_RGN_NON_SEME;
00443 }
00444
00445 tmp->Set_Skip_Sched_Reason (skip_reason);
00446
00447 REGION_MAP_Set (_rgn_2_rgn_info, rgn, tmp);
00448
00449
00450
00451
00452 for (REGION_KID_ITER kids_iter(rgn) ; kids_iter != 0 ; ++kids_iter) {
00453
00454 RGN_INFO * kid_info = CXX_NEW(RGN_INFO, &MEM_phase_pool) ;
00455
00456 kid_info->Set_Region (*kids_iter);
00457
00458
00459
00460 kid_info->Set_In_Abnormal_Loop (tmp->in_abnormal_loop ?
00461 TRUE :
00462 Is_Abnormal_Loop (*kids_iter));
00463
00464
00465 queue.push_back (kid_info);
00466 }
00467
00468
00469
00470 RGN_SUMMARY * summary = CXX_NEW (RGN_SUMMARY(rgn,&_mem_pool),
00471 &_mem_pool);
00472 summary -> Set_Summary_Is_Invalid ();
00473 tmp->Set_Summary (summary);
00474 }
00475 }
00476
00477
00478
00479
00480
00481
00482
00483
00484 void
00485 REGION_INFO_MGR :: Build_Rgn_Summary (REGION *rgn,
00486 RGN_CFLOW_MGR * rgn_cflow_info) {
00487
00488 RGN_INFO * rgn_info = Get_Rgn_Info (rgn) ;
00489 Is_True (rgn_info, ("RGN_INFO associated with <rgn> does not exist!"));
00490
00491 BOOL can_not_build_summary =
00492 !rgn_cflow_info ||
00493 !rgn_cflow_info->Valid () ||
00494 (rgn->Region_Type () == MEME) ||
00495 (rgn->Region_Type () == IMPROPER);
00496
00497 RGN_SUMMARY * summary = rgn_info->Summary ();
00498 if (!summary) {
00499 summary = CXX_NEW(RGN_SUMMARY(rgn,&_mem_pool), &_mem_pool);
00500 rgn_info->Set_Summary (summary);
00501 }
00502
00503 if (can_not_build_summary) {
00504 summary->Set_Summary_Is_Invalid () ;
00505 return ;
00506 } else {
00507
00508 summary->Set_Summary_Is_Valid () ;
00509
00510
00511 }
00512
00513
00514
00515 CFG_NODE_MAP node_info_map (&_mem_pool);
00516 node_info_map.Initialize_Map (rgn);
00517
00518 for (TOPOLOGICAL_REGIONAL_CFG_ITER
00519 iter (rgn->Regional_Cfg()) ; iter != 0 ; ++ iter) {
00520
00521 RGN_CFG_PATH_INFO * info = New_RGN_CFG_PATH_INFO ();
00522
00523 if ((*iter)->Is_Region ()) {
00524 info -> Derive_RGN_CFG_PATH_INFO_from_REGION_Node
00525 (Get_Rgn_Info((*iter)->Region_Node())->Summary ());
00526 } else {
00527 info -> Derive_RGN_CFG_PATH_INFO_from_BB_Node
00528 ((*iter)->BB_Node());
00529 }
00530
00531 node_info_map.Set_Map (*iter, (void*)info);
00532 }
00533
00534
00535
00536
00537
00538 BB * bb_node = NULL ;
00539 REGION * nested_rgn = NULL;
00540
00541 summary -> Init_Def_Kill_Set () ;
00542 summary -> Init_Use_TN_Set () ;
00543 summary -> Clear_Has_Call () ;
00544 summary -> Clear_Has_Load () ;
00545 summary -> Clear_Has_Store () ;
00546 summary -> Clear_Has_Nested_Rgn () ;
00547 summary -> Clear_Has_Cannot_Move_Across_Rgn () ;
00548
00549 INT16 bb_num = 0, rgn_num = 0 ;
00550 for (TOPOLOGICAL_REGIONAL_CFG_ITER
00551 iter (rgn->Regional_Cfg()) ; iter != 0 ; ++ iter) {
00552
00553 RGN_CFG_PATH_INFO * info =
00554 (RGN_CFG_PATH_INFO *)node_info_map.Get_Map (*iter);
00555
00556 if (info->Rgn_Summary_Unknown ()) {
00557 summary->Set_Summary_Is_Invalid () ;
00558 break ;
00559 }
00560
00561 bb_num += info->BB_Num ();
00562 rgn_num += info->Rgn_Num ();
00563
00564 if (info->Has_Call ()) {
00565 summary->Set_Has_Call ();
00566 }
00567
00568 if (info->Has_Load ()) {
00569 summary->Set_Has_Load () ;
00570 }
00571
00572 if (info->Has_Store ()) {
00573 summary->Set_Has_Store () ;
00574 }
00575
00576 if (info->Has_has_rotating_kernel()) {
00577 summary->Set_Has_Rotating_Kernel ();
00578 }
00579
00580 summary->Union_Killed_Def (info->Killed_Def ());
00581 summary->Union_Use_TNs (info->TN_Used());
00582
00583 }
00584
00585 summary->Set_BB_Total_Num (bb_num);
00586
00587
00588
00589 for (TOPOLOGICAL_REGIONAL_CFG_ITER iter(rgn->Regional_Cfg()) ;
00590 iter != 0 ; ++iter) {
00591
00592 RGN_CFG_PATH_INFO * info =
00593 (RGN_CFG_PATH_INFO *)node_info_map.Get_Map (*iter);
00594 Free_RGN_CFG_PATH_INFO (info);
00595 }
00596 }
00597
00598
00599
00600
00601
00602
00603
00604
00605
00606
00607 void
00608 RGN_SUMMARY :: Adjust_Liveness_After_OP_Being_Moved_Across_Rgn (OP * op) {
00609
00610 }
00611
00612
00613
00614
00615
00616
00617
00618
00619
00620
00621
00622
00623
00624 #define LARGE_REGION_MUST_HOST_THIS_MANY_BB (3)
00625
00626 BOOL
00627 No_OP_Can_be_Moved_Across_Region (REGION *rgn) {
00628
00629 RGN_SUMMARY * sum = Get_Region_Summary (rgn) ;
00630
00631 Is_True (sum, ("fail to get region's summary for REGION%d", rgn->Id()));
00632 if (!sum->Summary_Is_Valid () ||
00633 sum->Has_Cannot_Move_Across_RGN () ||
00634 sum->Has_Call ()) {
00635 return TRUE;
00636 }
00637
00638
00639 switch (rgn->Region_Type ()) {
00640 case UNKNOWN:
00641 case MEME:
00642 case IMPROPER:
00643 return TRUE;
00644
00645 case ROOT:
00646 case SEME:
00647 case LOOP:
00648 return FALSE ;
00649
00650 default:
00651 FmtAssert (FALSE, ("Unknown region(RGN%d) type(%d)",
00652 rgn->Id(), rgn->Region_Type ()));
00653
00654 }
00655
00656 return FALSE;
00657 }
00658
00659 BOOL
00660 Is_Large_Region (REGION *rgn) {
00661
00662 RGN_SUMMARY * sum = Get_Region_Summary (rgn) ;
00663 Is_True (sum, ("Fail to get REGION%d's summary", sum->Region()->Id()));
00664
00665 return sum->Get_BB_Total_num () >=
00666 LARGE_REGION_MUST_HOST_THIS_MANY_BB;
00667 }
00668
00669 #undef LARGE_REGION_MUST_HOST_THIS_MANY_BB