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 #include "tracing.h"
00051 #include "errors.h"
00052
00053 #include "reg_live.h"
00054 #include "gra_live.h"
00055
00056 #include "region.h"
00057 #include "sched_util.h"
00058 #include "sched_cand.h"
00059 #include "sched_dflow.h"
00060 #include "sched_cflow.h"
00061 #include "sched_rgn_info.h"
00062 #include "sched_path.h"
00063
00064
00065 SCHED_DFLOW_MGR :: SCHED_DFLOW_MGR (void) {
00066 }
00067
00068 SCHED_DFLOW_MGR :: ~SCHED_DFLOW_MGR (void) {}
00069
00070
00071
00072
00073
00074
00075
00076
00077
00078
00079
00080
00081 BOOL
00082 SCHED_DFLOW_MGR :: Are_Defs_Live_In (OP* op, BB* bb) {
00083
00084 for (INT i = OP_results (op) - 1; i >= 0 ; i --) {
00085 if (GRA_LIVE_TN_Live_Into_BB (OP_result(op, i), bb)) {
00086 return TRUE;
00087 }
00088 }
00089
00090 return FALSE ;
00091 }
00092
00093 BOOL
00094 SCHED_DFLOW_MGR :: Are_Defs_Live_In (OP* op, REGION* r) {
00095
00096 switch (r->Region_Type()) {
00097 case SEME :
00098 case LOOP :
00099 break;
00100 default:
00101 return TRUE;
00102 }
00103
00104 NODE_VECTOR entries = r->Entries () ;
00105 if (entries.size () != 1) return TRUE;
00106
00107 return Are_Defs_Live_In (op,entries[0]);
00108 }
00109
00110
00111
00112
00113
00114
00115
00116
00117
00118
00119
00120 BOOL
00121 SCHED_DFLOW_MGR::Are_Defs_Live_Out (OP* op, BB* bb) {
00122
00123 for (INT i = 0; i < OP_results(op); ++i) {
00124
00125 TN *result_tn = OP_result(op,i);
00126 if (GTN_SET_Intersection_MemberP(BB_live_out(bb),
00127 BB_defreach_out(bb), result_tn)) {
00128 return TRUE;
00129 }
00130
00131 if (TN_is_dedicated (result_tn) &&
00132 REG_LIVE_Implicit_Use_Outof_BB (TN_register_class(result_tn),
00133 TN_register(result_tn), bb)) {
00134 return TRUE ;
00135 }
00136 }
00137
00138 return FALSE;
00139 }
00140
00141 BOOL
00142 SCHED_DFLOW_MGR :: Are_Defs_Live_Out (OP* op, REGION*r) {
00143 FmtAssert (FALSE, ("Not yet implemented"));
00144 return TRUE;
00145 }
00146
00147
00148
00149
00150
00151
00152
00153
00154
00155 BOOL
00156 SCHED_DFLOW_MGR::Are_Defs_Live_Out (OP* op, BB_VECTOR *bbv) {
00157
00158 for (BB_VECTOR_ITER iter = bbv->begin () ;
00159 iter != bbv->end () ; iter++) {
00160
00161 if (Are_Defs_Live_Out (op, *iter)) {
00162 return TRUE ;
00163 }
00164 }
00165
00166 return FALSE;
00167 }
00168
00169
00170
00171
00172
00173
00174
00175
00176
00177 void
00178 SCHED_DFLOW_MGR::Add_Defs_Live_In (OP* op, BB* bb) {
00179
00180 for (INT i = OP_results(op) - 1 ; i >= 0 ; --i) {
00181
00182 TN *result_tn = OP_result(op,i);
00183
00184 Set_TN_is_global_reg (result_tn) ;
00185 GTN_UNIVERSE_Add_TN (result_tn) ;
00186
00187 GRA_LIVE_Add_Defreach_In_GTN (bb,result_tn);
00188 GRA_LIVE_Add_Live_In_GTN (bb,result_tn);
00189 }
00190 }
00191
00192
00193
00194
00195
00196
00197
00198
00199
00200 void
00201 SCHED_DFLOW_MGR::Add_Defs_Live_In (OP* op, REGION*rgn) {
00202
00203 NODE_VECTOR entries = rgn->Entries () ;
00204
00205 for (NODE_VECTOR_ITER iter = entries.begin () ;
00206 iter != entries.end () ;
00207 iter ++) {
00208
00209 REGIONAL_CFG_NODE* n = *iter ;
00210 if (n->Is_Region ()) {
00211 Add_Defs_Live_In (op, n->Region_Node());
00212 } else {
00213 Add_Defs_Live_In (op, n->BB_Node());
00214 }
00215 }
00216 }
00217
00218
00219
00220
00221
00222
00223
00224
00225
00226 void
00227 SCHED_DFLOW_MGR::Add_Defs_Live_Out (OP * op, BB * bb) {
00228
00229 for (INT i = OP_results(op) - 1 ; i >= 0 ; --i) {
00230
00231 TN *result_tn = OP_result(op,i);
00232
00233 Set_TN_is_global_reg(result_tn) ;
00234 GTN_UNIVERSE_Add_TN (result_tn) ;
00235 GRA_LIVE_Add_Defreach_Out_GTN (bb,result_tn);
00236 GRA_LIVE_Add_Live_Out_GTN (bb,result_tn);
00237 }
00238 }
00239
00240
00241
00242
00243
00244
00245
00246
00247
00248 void
00249 SCHED_DFLOW_MGR::Add_Defs_Live_Out (OP * op, REGION *rgn) {
00250
00251 NODE_VECTOR exits = rgn->Exits () ;
00252
00253 for (NODE_VECTOR_ITER iter = exits.begin () ;
00254 iter != exits.end () ;
00255 iter ++) {
00256
00257 REGIONAL_CFG_NODE * n = *iter ;
00258 if (n->Is_Region ()) {
00259 Add_Defs_Live_Out (op, n->Region_Node());
00260 } else {
00261 Add_Defs_Live_Out (op, n->BB_Node ());
00262 }
00263 }
00264 }
00265
00266
00267
00268
00269
00270
00271
00272
00273
00274 BOOL
00275 SCHED_DFLOW_MGR :: P_Ready_Moving_Against_These_Path_Kill_Live_Defs
00276 (CANDIDATE* cand, SRC_BB_INFO* bb_info, BB* to,
00277 EXEC_PATH_SET* move_against, RGN_CFLOW_MGR* cflow_info) {
00278
00279 Is_True (cand->Is_P_Ready (),
00280 ("this routine is expected to be called when"
00281 "candidate is a P-ready one"));
00282
00283 REGION* scope = cflow_info -> Scope ();
00284 OP* def = cand->Op ();
00285 BB* home_bb = bb_info->Source_BB ();
00286
00287 BBLIST* succs;
00288 FOR_ALL_BB_SUCCS(to, succs) {
00289
00290 BB* succ = BBLIST_item(succs);
00291 if (!Are_Defs_Live_In (def, succ)) {
00292 continue;
00293 }
00294
00295 REGION* homer = Home_Region (succ);
00296 if (homer != scope) { return TRUE; }
00297
00298 EXEC_PATH_SET* eps = cflow_info->Get_Path_Flow_Thru (succ);
00299 if (!eps->Is_Subset_Of (move_against) ||
00300 !BB1_Postdominate_BB2 (home_bb, succ)) {
00301 return TRUE;
00302 }
00303 }
00304
00305 return FALSE;
00306 }
00307
00308
00309
00310
00311
00312
00313
00314
00315
00316 BOOL
00317 SCHED_DFLOW_MGR::Upward_Sched_Kill_Def_LiveOut_Of_Target_BB
00318 (CANDIDATE* cand, SRC_BB_INFO* bb_info,RGN_CFLOW_MGR* cflow_info) {
00319
00320 OP* def = cand->Op ();
00321 BB* to = bb_info->Target_BB ();
00322
00323 if (!Are_Defs_Live_Out (def, to)) {
00324 return FALSE;
00325 }
00326
00327 if (cand->Is_M_Ready ()) {
00328
00329 BB* home_bb = OP_bb(cand->Op ());
00330 REGION* scope = ::Home_Region (home_bb);
00331
00332 BBLIST* succs;
00333 FOR_ALL_BB_SUCCS(to, succs) {
00334
00335 BB* succ = BBLIST_item(succs);
00336 if (!Are_Defs_Live_In (def, succ)) {
00337 continue;
00338 }
00339
00340 REGION* homer = Home_Region (succ);
00341 if (homer != scope) { return TRUE; }
00342
00343 if (!BB1_Postdominate_BB2 (home_bb, succ)) {
00344 return TRUE;
00345 }
00346 }
00347
00348 return FALSE;
00349 }
00350
00351 return P_Ready_Moving_Against_These_Path_Kill_Live_Defs
00352 (cand, bb_info, to,
00353 cand->Move_Against_Path_Set (),
00354 cflow_info);
00355 }
00356
00357
00358
00359
00360
00361
00362
00363
00364
00365 BOOL
00366 SCHED_DFLOW_MGR::Upward_Sched_Kill_Def_LiveOut_Of_Bookeeping_Place
00367 (CANDIDATE* cand, BOOKEEPING* bk,
00368 SRC_BB_INFO* bb_info, RGN_CFLOW_MGR* cflow_info) {
00369
00370 OP* def = cand->Op ();
00371 BB* place = bk->Get_Placement ();
00372
00373 if (!Are_Defs_Live_Out (def, place)) {
00374 return TRUE;
00375 }
00376
00377 BB* home_bb = OP_bb(cand->Op ());
00378 REGION* scope = ::Home_Region (home_bb);
00379
00380 if (cand->Is_M_Ready ()) {
00381
00382 BBLIST* succs;
00383 FOR_ALL_BB_SUCCS(place, succs) {
00384
00385 BB* succ = BBLIST_item(succs);
00386 if (!Are_Defs_Live_In (def, succ)) {
00387 continue;
00388 }
00389
00390 REGION* homer = Home_Region (succ);
00391 if (homer != scope) { return TRUE; }
00392
00393 if (!BB1_Postdominate_BB2 (home_bb, succ)) {
00394 return TRUE;
00395 }
00396 }
00397
00398 return FALSE;
00399 }
00400
00401 if (bk->Is_Dup_Bookeeping ()) {
00402
00403 return P_Ready_Moving_Against_These_Path_Kill_Live_Defs
00404 (cand, bb_info, place,
00405 cand->Move_Against_Path_Set (),
00406 cflow_info);
00407 }
00408
00409 Is_True (bk->Is_P_Ready_Bookeeping (),
00410 ("book keeping should be for the P_ready purpose"));
00411
00412 if (!BB1_Postdominate_BB2 (home_bb, place)) {
00413 EXEC_PATH_SET eps =
00414 *(cflow_info->Get_Path_Flow_Thru (home_bb));
00415
00416 eps -= *(cflow_info->Get_Path_Flow_Thru (place));
00417 return P_Ready_Moving_Against_These_Path_Kill_Live_Defs
00418 (cand, bb_info, place, &eps, cflow_info);
00419 }
00420
00421 return FALSE;
00422 }
00423
00424
00425
00426
00427
00428
00429
00430
00431
00432 BOOL
00433 SCHED_DFLOW_MGR::Upward_Sched_Kill_LiveOut_Defs
00434 (CANDIDATE* cand, SRC_BB_INFO* bb_info,
00435 RGN_CFLOW_MGR* cflow_info) {
00436
00437 OP* op = cand->Op ();
00438 BB* to = bb_info->Target_BB ();
00439 BB* home_bb = OP_bb(op);
00440 REGIONAL_CFG_NODE* home_nd = bb_info->Src_Node ();
00441
00442 if (home_bb == to ||
00443 (cand->Is_M_Ready () && bb_info->Is_Cntl_Equiv ())) {
00444 return FALSE;
00445 }
00446
00447
00448
00449
00450
00451 if (Upward_Sched_Kill_Def_LiveOut_Of_Target_BB
00452 (cand, bb_info, cflow_info)) {
00453 return TRUE;
00454 }
00455
00456
00457
00458
00459 BOOKEEPING_LST* bkl = cand->Bookeeping_Lst ();
00460 for (BOOKEEPING* bk = bkl->First_Item ();
00461 bk != NULL;
00462 bk = bkl->Next_Item (bk)) {
00463
00464 BB* place = bk->Get_Placement ();
00465 if (!Are_Defs_Live_Out (op, place)) {
00466 continue;
00467 }
00468
00469 if (Upward_Sched_Kill_Def_LiveOut_Of_Bookeeping_Place
00470 (cand, bk, bb_info, cflow_info)) {
00471 return TRUE;
00472 }
00473 }
00474
00475 return FALSE;
00476 }
00477
00478
00479
00480
00481
00482
00483
00484
00485
00486 BOOL SCHED_DFLOW_MGR :: Downard_Sched_Kill_LiveIn_Defs
00487 (CANDIDATE* cand, SRC_BB_INFO* src_bb_info,
00488 RGN_CFLOW_MGR* cflow_info) {
00489
00490 FmtAssert (FALSE,
00491 ("Downard_Sched_Kill_LiveIn_Defs has yet implemented"));
00492
00493 return TRUE;
00494 }
00495
00496
00497
00498
00499
00500
00501
00502
00503
00504 BOOL
00505 SCHED_DFLOW_MGR :: Upward_Sched_Interfere_Nested_Rgns_LiveRanges
00506 (CANDIDATE* cand, SRC_BB_INFO* bb_info) {
00507
00508 REGION_VECTOR* rv = cand->Move_Across_Rgns ();
00509 OP* op = cand->Op ();
00510
00511 for (REGION_VECTOR_ITER iter = rv->begin ();
00512 iter != rv->end ();
00513 iter ++) {
00514
00515 REGION* r = *iter;
00516 RGN_SUMMARY* rs = Get_Region_Summary (r);
00517
00518 if (rs->Has_Call ()) { return TRUE; }
00519 if (rs->Has_Rotating_Kernel ()) { return TRUE; }
00520
00521 TN_SET* def = rs->Killed_Def ();
00522 TN_SET* use = rs->TN_Used ();
00523
00524
00525
00526 for (INT i = OP_results(op) - 1 ; i >= 0 ; i--) {
00527 TN * result = OP_result(op,i);
00528
00529 if (!TN_is_register(result) || TN_is_const_reg(result)) {
00530 continue ;
00531 }
00532
00533 if (TN_SET_MemberP(def, result) ||
00534 TN_SET_MemberP(use, result)) {
00535 return TRUE;
00536 }
00537 }
00538
00539
00540
00541 for (INT i = OP_opnds(op) - 1 ; i >= 0 ; i --) {
00542 TN * opnd = OP_opnd(op,i) ;
00543
00544 if (!TN_is_register(opnd) || TN_is_const_reg(opnd)) {
00545 continue ;
00546 }
00547
00548 if (TN_SET_MemberP (def, opnd)) {
00549 return TRUE;
00550 }
00551 }
00552
00553 if (!rs->Has_Mem_OP ()) { return TRUE ; }
00554
00555 if (OP_load (op) && rs->Has_Store() || OP_like_store(op)) {
00556 return TRUE;
00557 }
00558
00559 }
00560
00561 return FALSE;
00562 }
00563
00564
00565
00566
00567
00568
00569
00570
00571
00572 BOOL
00573 SCHED_DFLOW_MGR :: Downward_Sched_Interfere_Nested_Rgns_LiveRanges
00574 (CANDIDATE* cand, SRC_BB_INFO* src_bb_info) {
00575
00576 FmtAssert (FALSE,
00577 ("Downward_Sched_Interfere_Nested_Rgns_LiveRanges has yet implemented"));
00578
00579 return TRUE;
00580 }
00581
00582
00583
00584
00585
00586
00587
00588
00589
00590
00591 void
00592 SCHED_DFLOW_MGR::Update_Liveness_After_Upward_Sched
00593 (CANDIDATE* cand, SRC_BB_INFO* src_info, RGN_CFLOW_MGR* cflow_info) {
00594
00595 BB* targ = src_info->Target_BB ();
00596 BB* src = src_info->Source_BB ();
00597 OP* op = cand->Op ();
00598
00599 if (targ == src || !OP_results (op)) {
00600 return ;
00601 }
00602
00603
00604
00605 Add_Defs_Live_Out (op, src_info->Target_BB ());
00606
00607
00608
00609
00610 BOOKEEPING_LST* bkl = cand->Bookeeping_Lst ();
00611 for (BOOKEEPING* bk = bkl->First_Item ();
00612 bk != NULL;
00613 bk = bkl->Next_Item (bk)) {
00614 Add_Defs_Live_Out (op, bk->Get_Placement ());
00615 }
00616
00617
00618
00619
00620
00621 Add_Defs_Live_In (op, src_info->Source_BB ()) ;
00622
00623
00624
00625
00626
00627 BOOL is_m_ready = cand->Is_M_Ready ();
00628 BB_VECTOR* bbv = src_info->Move_Across_Or_Around_BBs ();
00629 for (BB_VECTOR_ITER iter = bbv->begin ();
00630 iter != bbv->end ();
00631 iter ++) {
00632
00633 BB* b = *iter;
00634
00635 BOOL btmp;
00636 if (is_m_ready) {
00637 btmp = TRUE;
00638 } else {
00639 EXEC_PATH_SET* eps = cflow_info->Get_Path_Flow_Thru (b);
00640 btmp = !(cand->Move_Against_Path_Set()->
00641 Intersection_Is_Empty (eps));
00642 }
00643
00644 if (btmp) {
00645 Add_Defs_Live_In (op, b);
00646 Add_Defs_Live_Out (op, b);
00647 }
00648 }
00649
00650
00651 REGION_VECTOR* rv = src_info->Move_Across_Or_Around_Nested_Rgns ();
00652 for (REGION_VECTOR_ITER iter = rv->begin ();
00653 iter != rv->end ();
00654 iter ++) {
00655
00656 BOOL btmp;
00657 REGION* r = *iter;
00658
00659 if (is_m_ready) {
00660 btmp = TRUE;
00661 } else {
00662 EXEC_PATH_SET* eps = cflow_info->Get_Path_Flow_Thru (r);
00663 btmp = !(cand->Move_Against_Path_Set()->
00664 Intersection_Is_Empty (eps));
00665 }
00666
00667 if (btmp) {
00668 Add_Defs_Live_In (op, r);
00669 Add_Defs_Live_Out (op, r);
00670 }
00671 }
00672 }
00673
00674
00675
00676
00677
00678
00679
00680
00681
00682
00683
00684 void
00685 SCHED_DFLOW_MGR::Update_Liveness_After_Downward_Sched
00686 (CANDIDATE* cand,
00687 SRC_BB_INFO * src_info,
00688 RGN_CFLOW_MGR* cflow_info) {
00689
00690
00691
00692 FmtAssert (FALSE,
00693 ("Update_Liveness_After_Downward_Sched has not been implemented"));
00694
00695 }
00696
00697
00698
00699
00700
00701
00702
00703
00704
00705
00706
00707 BOOL
00708 SCHED_DFLOW_MGR::Upward_Sched_Violate_Dflow_Constrait
00709 (CANDIDATE* cand, SRC_BB_INFO* bb_info) {
00710
00711 FmtAssert (FALSE, ("has yet implemented"));
00712 return FALSE;
00713 }
00714
00715
00716
00717
00718
00719
00720
00721
00722
00723 BOOL
00724 SCHED_DFLOW_MGR::Downward_Sched_Violate_Dflow_Constrait
00725 (CANDIDATE* cand, SRC_BB_INFO* bb_info) {
00726
00727 FmtAssert (FALSE,("Downward_Sched_Violate_Dflow_Constrait "
00728 "has not been implemented"));
00729 return FALSE;
00730 }
00731