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 #include "hb_hazards.h"
00052 #include "timing.h"
00053 #include "cg_dep_graph.h"
00054 #include "tracing.h"
00055 #include "errors.h"
00056 #include "be_util.h"
00057 #include "cg.h"
00058 #include "cgtarget.h"
00059 #include "targ_isa_enums.h"
00060 #include "ipfec_options.h"
00061 #include "region_bb_util.h"
00062
00063 #include "scheduler.h"
00064 #include "cggrp_microsched.h"
00065 #include "speculation.h"
00066 #include "sched_spec_itf.h"
00067
00068 #include "sched_util.h"
00069 #include "sched_cflow.h"
00070 #include "sched_dflow.h"
00071 #include "sched_cand.h"
00072 #include "sched_rgn_info.h"
00073 #include "sched_seq.h"
00074 #include "sched_spec_itf.h"
00075
00076
00077 #include "prdb_util.h"
00078 #include "pqs_cg.h"
00079
00080
00081 #include "cxx_memory.h"
00082
00083
00084 #include "cg_dep_graph.h"
00085 #include "dag.h"
00086 #include "reg_live.h"
00087 #include "gra_live.h"
00088
00089
00090 #include "dominate.h"
00091
00092
00093 #include "vt_region.h"
00094 #include "vt_dag.h"
00095
00096 #include "targ_sim.h"
00097 #include "ttype.h"
00098
00099 #include <stdarg.h>
00100 #include <tlog.h>
00101 #include "whirl2ops.h"
00102
00103 static char* _Global_Insn_Sched_Phase_Name = "ORC:Global code motion" ;
00104 static char* _Local_Insn_Sched_Phase_Name = "ORC:Local code motion" ;
00105 static char* _Cur_Phase_Name = NULL ;
00106
00107 #define MAX_BB_LENGTH (360)
00108
00109
00110
00111
00112
00113
00114
00115
00116
00117
00118
00119
00120
00121
00122
00123
00124
00125
00126
00127
00128 void
00129 SCHEDULER::Cycle_Advance (void) {
00130
00131 _cand_mgr.M_Ready_Cand_List ()->Clear_All_Cands_Tried_Mark ();
00132 _cand_mgr.P_Ready_Cand_List ()->Clear_All_Cands_Tried_Mark ();
00133
00134
00135
00136 CGGRP_Cycle_Advance();
00137
00138
00139
00140 Update_Cand_Lst_After_Cycle_Advancing ();
00141 _heur_mgr.Adjust_Heur_After_Sched_One_Cyc
00142 (_ops_in_cur_cyc,_cur_cyc);
00143
00144
00145 if (SCHED_TF_SUMMARY_DUMP) {
00146 fprintf(TFile, "\n Cycle: %d\n", _cur_cyc);
00147 }
00148
00149
00150
00151 _ops_in_cur_cyc.clear ();
00152
00153
00154
00155 ++_cur_cyc ;
00156 }
00157
00158
00159
00160
00161
00162
00163
00164
00165
00166
00167 BOOL
00168 SCHEDULER::OP_Cannot_be_Candidate_Since_Obvious_Reason (OP* op) {
00169
00170 if (OP_Scheduled(op)) return TRUE;
00171
00172 if (_prepass&&
00173 (OP_glue(op) || OP_chk(op) || OP_no_move_before_gra(op) ||
00174 OP_access_reg_bank (op)) &&
00175 OP_bb(op) != _target_bb) {
00176
00177 return TRUE;
00178 }
00179
00180 if (OP_bb (op) != _target_bb &&
00181 OP_Cannot_Be_Moved_Outof_HomeBB (op)) {
00182 return TRUE;
00183 }
00184
00185
00186 return _cand_mgr.OP_Is_In_Cand_List (op);
00187 }
00188
00189
00190
00191
00192
00193
00194
00195
00196
00197 BOOL
00198 SCHEDULER::Succ_Pred_Transposed_If_Sched
00199 (ARC* arc, BB_VECTOR* cutting_set) {
00200
00201 OP* pred = ARC_pred(arc);
00202 BB* pred_home = OP_bb(pred);
00203
00204 if (OP_Scheduled(pred)) {
00205 if (pred_home != _target_bb || !OP_xfer(pred) || ARC_kind(arc) == CG_DEP_CTLSPEC) {
00206 return FALSE;
00207 } else {
00208 return TRUE;
00209 }
00210 }
00211
00212 BB_POS pos = BB_Pos_Analysis (pred_home, cutting_set, &_cflow_mgr);
00213
00214 BOOL transposed = FALSE;
00215 switch (pos) {
00216 case ABOVE_SISS:
00217 break;
00218
00219 case IN_SISS:
00220 transposed = (pred_home == _target_bb || OP_xfer(pred));
00221 break;
00222
00223 case BELOW_SISS:
00224 transposed = TRUE ;
00225 break ;
00226
00227 default :
00228 Is_True (FALSE, ("fail to analysis src position for BB:%d!",
00229 BB_id(OP_bb(pred))));
00230 }
00231
00232 return transposed;
00233 }
00234
00235
00236
00237
00238
00239
00240
00241
00242
00243
00244
00245
00246
00247
00248
00249
00250
00251
00252
00253
00254
00255
00256
00257
00258
00259
00260
00261
00262
00263
00264
00265
00266
00267
00268
00269
00270
00271
00272
00273
00274
00275 BOOL
00276 SCHEDULER::Collect_And_Analyse_Unresolved_Dep
00277 (CANDIDATE* cand, SRC_BB_INFO* bb_info) {
00278
00279
00280
00281 BOOL donate_p_ready = bb_info->Can_Donate_P_Ready_Cand ();
00282 OP* cand_op = cand->Op ();
00283 BB* home_bb = OP_bb(cand->Op ());
00284
00285 cand->Free_Bookeeping_Lst ();
00286 cand->Move_Across_Rgns()->clear ();
00287 BB_VECTOR* cs_between_targ_src = NULL;
00288 EXEC_PATH_SET move_around_paths(&_mem_pool);
00289
00290 if (donate_p_ready) {
00291 cand->Move_Against_Path_Set ()->Clear ();
00292 cs_between_targ_src = bb_info->Get_P_Ready_Bookeeping_Blks ();
00293 move_around_paths.Resize
00294 (_cflow_mgr.Get_Exec_Path_Mgr()->Path_In_Total ());
00295 }
00296
00297 BOOL cannotspec = FALSE;
00298 for (OP* prev_op = OP_prev(cand_op); prev_op; prev_op = OP_prev(prev_op)){
00299 if (!OP_Scheduled(prev_op) && OP_ANNOT_OP_Def_Actual_Para (prev_op)){
00300 cannotspec = TRUE;
00301 break;
00302 }
00303 }
00304
00305
00306
00307
00308
00309
00310
00311 for (ARC_LIST* arcs = OP_preds(cand_op);
00312 arcs != NULL;
00313 arcs = ARC_LIST_rest(arcs)) {
00314
00315 ARC* arc = ARC_LIST_first(arcs) ;
00316 OP* pred = ARC_pred(arc) ;
00317
00318 if (!_prepass && !_global) {
00319
00320
00321
00322
00323
00324
00325 if (OP_Scheduled(pred)) {
00326 continue;
00327 } else {
00328 return FALSE;
00329 }
00330 }
00331
00332 if (!Succ_Pred_Transposed_If_Sched
00333 (arc, bb_info->Get_Cutting_Set ())) {
00334
00335
00336
00337 continue;
00338 }
00339
00340 if (ARC_kind(arc) == CG_DEP_CTLSPEC) {
00341 cand->Set_If_Converted(TRUE);
00342 }
00343
00344 SPEC_TYPE spec_tmp = Derive_Spec_Type_If_Violate_Dep (arc);
00345 if (cannotspec) spec_tmp = SPEC_DISABLED;
00346 if (spec_tmp == SPEC_NONE) {
00347
00348
00349 continue;
00350 }
00351
00352
00353
00354
00355
00356
00357
00358 if (spec_tmp == SPEC_DATA || spec_tmp == SPEC_CNTL ||
00359 spec_tmp == SPEC_COMB) {
00360
00361 cand->Add_Spec (spec_tmp);
00362
00363
00364
00365 UNRESOLVED_DEP* t = _cand_mgr.New_Unresolved_Dep ();
00366 t->Set_Arc (arc);
00367 t->Set_Spec_Type (spec_tmp);
00368 cand->Unresolved_Dep_List ()->Prepend (t);
00369
00370 continue;
00371 }
00372
00373
00374
00375 BB* pred_bb = OP_bb(pred);
00376 if (spec_tmp == SPEC_DISABLED) {
00377 if (!donate_p_ready || pred_bb == _target_bb) {
00378
00379
00380
00381 return FALSE;
00382 }
00383
00384 BB_POS pos = BB_Pos_Analysis (pred_bb,
00385 cs_between_targ_src,
00386 &_cflow_mgr);
00387
00388 if (pos == BELOW_SISS) { return FALSE ; }
00389
00390 if (pos == IN_SISS || pos == ABOVE_SISS) {
00391
00392 cand->Set_P_ready ();
00393
00394 for (BB_VECTOR_ITER iter = cs_between_targ_src->begin();
00395 iter != cs_between_targ_src->end (); iter++) {
00396
00397 BB* bk_blk = *iter;
00398
00399 if (!(cand->Bookeeping_Lst ()->Retrieve (bk_blk)) &&
00400 (bk_blk == pred_bb ||
00401 _cflow_mgr.BB1_Reachable_From_BB2 (bk_blk,pred_bb))) {
00402
00403 EXEC_PATH_SET* eps_tmp =
00404 _cflow_mgr.Get_Path_Flow_Thru (bk_blk);
00405
00406 BOOKEEPING* bk = _cand_mgr.New_Empty_Bookeeping ();
00407 bk -> Set_Placement (bk_blk);
00408 bk -> Set_P_Ready_Bookeeping ();
00409 cand->Bookeeping_Lst () -> Prepend (bk);
00410
00411 move_around_paths += *eps_tmp;
00412 }
00413 }
00414
00415 } else {
00416 FmtAssert (FALSE, ("Unknown BB_POS(%d)", pos));
00417 return FALSE;
00418 }
00419
00420 }
00421
00422 }
00423
00424
00425 if (!_global) { return TRUE; }
00426
00427 if (cand->Is_P_Ready ()) {
00428
00429
00430
00431 EXEC_PATH_SET* eps = cand->Move_Against_Path_Set();
00432 *eps = *_cflow_mgr.Get_Path_Flow_Thru (OP_bb(cand->Op()));
00433 *eps -= move_around_paths;
00434 if (eps->Is_Empty ()) {
00435
00436
00437
00438 return FALSE;
00439 }
00440
00441 eps = cand->P_Ready_Bookeeping_Path_Set ();
00442 *eps = move_around_paths;
00443
00444
00445
00446
00447
00448
00449
00450
00451
00452
00453
00454 UNRESOLVED_DEP* dep, *next_dep;
00455 UNRESOLVED_DEP_LST* deplst = cand->Unresolved_Dep_List ();
00456
00457 for (dep = deplst->First_Item (); dep; dep = next_dep) {
00458
00459 next_dep = deplst->Next_Item(dep);
00460 if (cand->Shadowed_By_P_Ready_Bookeeping
00461 (OP_bb(dep->Pred()), &_cflow_mgr)) {
00462 deplst->Delete_Item (dep);
00463 }
00464
00465 }
00466 }
00467
00468
00469
00470 Determine_Non_P_Ready_Bookeeping_Places (cand, bb_info);
00471
00472 cand->Calc_Useful_Exec_Prob (_target_bb,&_cflow_mgr);
00473
00474
00475
00476
00477
00478
00479 if (cand->Is_P_Ready ()) {
00480
00481
00482 cand->Add_Spec (SPEC_CNTL);
00483
00484
00485
00486
00487
00488
00489 if (cand->Useful_Exec_Prob () <
00490 DONATE_P_READY_CAND_BB_REACH_PROB) {
00491 return FALSE;
00492 }
00493 } else if (!(cand->Spec_Type () & SPEC_CNTL)) {
00494
00495 BOOKEEPING_LST* bkl = cand->Bookeeping_Lst ();
00496
00497 for (BOOKEEPING* bk = bkl->First_Item ();
00498 bk != NULL;
00499 bk = bkl->Next_Item (bk)) {
00500
00501 if (!BB1_Postdominate_BB2 (home_bb, bk->Get_Placement ())) {
00502 cand->Add_Spec (SPEC_CNTL);
00503 break;
00504 }
00505 }
00506 }
00507
00508 return TRUE;
00509 }
00510
00511
00512
00513
00514
00515
00516
00517
00518
00519
00520
00521
00522
00523
00524
00525
00526 void
00527 SCHEDULER::Determine_Non_P_Ready_Bookeeping_Places
00528 (CANDIDATE* cand, SRC_BB_INFO* bb_info) {
00529
00530 BB_VECTOR* cs = bb_info->Get_Cutting_Set ();
00531 BB* home_bb = OP_bb(cand->Op ());
00532
00533 if (!cand->Is_P_Ready ()) {
00534
00535 for (BB_VECTOR_ITER iter = cs->begin ();
00536 iter != cs->end (); iter ++) {
00537
00538 BB* bk_blk = *iter;
00539 if (bk_blk == _target_bb) { continue; }
00540
00541 BOOKEEPING* bk = _cand_mgr.New_Empty_Bookeeping ();
00542 bk->Set_Placement (bk_blk);
00543 bk->Set_Dup_Bookeeping ();
00544
00545 cand->Bookeeping_Lst () -> Append (bk);
00546 }
00547
00548 return;
00549 }
00550
00551 for (BB_VECTOR_ITER iter = cs->begin ();
00552 iter != cs->end (); iter++) {
00553
00554 BB* b = *iter;
00555 if (b == _target_bb) { continue; }
00556
00557 if (!cand->Shadowed_By_P_Ready_Bookeeping (b,&_cflow_mgr)) {
00558
00559 BOOKEEPING* bk = _cand_mgr.New_Empty_Bookeeping ();
00560 bk->Set_Placement (b);
00561 bk->Set_Dup_Bookeeping ();
00562
00563 cand->Bookeeping_Lst () -> Append (bk);
00564 }
00565 }
00566 }
00567
00568
00569
00570
00571
00572
00573
00574
00575
00576 BOOL
00577 SCHEDULER::Collect_And_Analyse_Other_Than_Dep_Constraints
00578 (CANDIDATE* cand, SRC_BB_INFO* bb_info) {
00579
00580 if (!_global && !_prepass) {
00581
00582
00583
00584
00585
00586
00587 return TRUE;
00588 }
00589
00590 OP* op = cand->Op ();
00591
00592
00593
00594
00595
00596
00597
00598 SPEC_TYPE spec_type = cand->Spec_Type ();
00599 if ((spec_type & SPEC_DATA) && OP_ANNOT_Cannot_Data_Spec (op) ||
00600 (spec_type & SPEC_CNTL) && OP_ANNOT_Cannot_Cntl_Spec (op)) {
00601 return FALSE;
00602 }
00603
00604 if (cand->Is_If_Converted()) {
00605 if (!IPFEC_Glos_Enable_Cntl_Spec_If_Converted_Code ||
00606 !Can_Cntl_Spec_If_Converted_Code(cand)) {
00607 return FALSE;
00608 }
00609 }
00610
00611 if (SCHED_SPEC_HANDSHAKE::OP_Can_not_be_Candidate (op, spec_type)) {
00612
00613
00614 return FALSE;
00615 }
00616
00617 if (OP_bb(op) == _target_bb) {
00618 return TRUE;
00619 }
00620
00621
00622
00623
00624 if (_dflow_mgr.Upward_Sched_Kill_LiveOut_Defs
00625 (cand, bb_info, &_cflow_mgr)) {
00626
00627
00628
00629
00630 if (OP_results(op) != 1) {
00631 return FALSE;
00632 }
00633
00634
00635
00636 if (TN_is_dedicated (OP_result(op,0))) {
00637 return FALSE;
00638 }
00639 }
00640
00641
00642
00643
00644 REGION_VECTOR* rv = cand->Move_Across_Rgns();
00645 rv->clear ();
00646
00647
00648 REGION_VECTOR* rv_tmp = bb_info->Move_Across_Or_Around_Nested_Rgns ();
00649 for (REGION_VECTOR_ITER iter = rv_tmp->begin ();
00650 iter != rv_tmp->end ();
00651 iter ++) {
00652
00653 REGION *r = *iter;
00654 if (cand->Is_M_Ready () ||
00655 !cand->Shadowed_By_P_Ready_Bookeeping (r, &_cflow_mgr)) {
00656 rv->push_back (r);
00657 }
00658 }
00659
00660
00661
00662 if (_dflow_mgr.Upward_Sched_Interfere_Nested_Rgns_LiveRanges
00663 (cand, bb_info)) {
00664 return FALSE;
00665 }
00666
00667 return TRUE;
00668 }
00669
00670
00671
00672
00673
00674
00675
00676
00677
00678 BOOL
00679 SCHEDULER::Try_Add_OP_to_Candidate_List (OP* op) {
00680
00681 if (OP_Cannot_be_Candidate_Since_Obvious_Reason (op)) {
00682 return FALSE;
00683 }
00684
00685 SRC_BB_INFO* bb_info = _src_bb_mgr.Get_Src_Info (OP_bb(op));
00686
00687 CANDIDATE* cand = _cand_mgr.Create_Empty_Cand ();
00688 cand->Set_OP (op);
00689
00690
00691 if (!Collect_And_Analyse_Unresolved_Dep (cand, bb_info) ||
00692 !Collect_And_Analyse_Other_Than_Dep_Constraints
00693 (cand, bb_info)) {
00694
00695 _cand_mgr.Erase_Cand (cand);
00696 return FALSE;
00697
00698 }
00699
00700
00701
00702
00703
00704 if (OP_bb(op) != _target_bb &&
00705 !_heur_mgr.Upward_Global_Sched_Is_Profitable
00706 (cand, bb_info, &_cflow_mgr)) {
00707
00708 _cand_mgr.Erase_Cand (cand);
00709 return FALSE;
00710 }
00711
00712
00713
00714 CAND_LIST* cand_lst = cand->Is_M_Ready () ?
00715 _cand_mgr.M_Ready_Cand_List () :
00716 _cand_mgr.P_Ready_Cand_List () ;
00717
00718 cand_lst->Add_Candidate (cand);
00719
00720 return TRUE;
00721
00722 }
00723
00724
00725
00726
00727
00728
00729
00730
00731
00732
00733 void
00734 SCHEDULER::Find_All_Candidates (void) {
00735
00736 _cand_mgr.M_Ready_Cand_List ()-> Erase_All_Cand ();
00737 _cand_mgr.P_Ready_Cand_List ()-> Erase_All_Cand ();
00738
00739 if (_global) {
00740 Determine_P_Ready_is_Profitable_or_not () ;
00741 } else {
00742 Disable_P_Pready_Cand () ;
00743 }
00744
00745 const BB_VECTOR* src_bbs = _src_bb_mgr.Src_BBs () ;
00746
00747 for (BB_VECTOR_CONST_ITER iter = src_bbs->begin();
00748 iter != src_bbs->end(); iter++) {
00749
00750 OP* op;
00751 BB* b = *iter;
00752 FOR_ALL_BB_OPs(b, op) {
00753 Try_Add_OP_to_Candidate_List (op);
00754 }
00755 }
00756
00757
00758
00759 Is_True (!_cand_mgr.M_Ready_Cand_List ()-> Cand_Lst_Is_Empty () ||
00760 !BB_length(_target_bb),
00761 ("Fail to find any candidate!"));
00762
00763 }
00764
00765
00766
00767
00768
00769
00770
00771
00772
00773
00774
00775
00776
00777
00778
00779
00780
00781
00782
00783
00784 void
00785 SCHEDULER::Update_Cand_Lst_During_Sched_Cyc (CANDIDATE& cand) {
00786
00787 OP* op = cand.Op ();
00788 OP* succ;
00789
00790 for (ARC_LIST* arcs = OP_succs(op);
00791 arcs != NULL; arcs = ARC_LIST_rest(arcs)) {
00792
00793 ARC *arc = ARC_LIST_first(arcs);
00794 OP *succ = ARC_succ(arc);
00795
00796 if (!_src_bb_mgr.Is_Src_BB (OP_bb(succ))) {
00797
00798
00799
00800
00801
00802 continue;
00803 }
00804
00805 INT32 latency = ARC_latency(arc) ;
00806
00807 if (latency > 0) {
00808
00809
00810
00811
00812
00813
00814
00815 continue ;
00816 } else if (latency < 0) {
00817
00818
00819
00820 FmtAssert (FALSE,
00821 ("Latency of dep between OP[%d](BB:%d) and OP[%d](BB:%d)"
00822 " should not be a negative %d\n",
00823 OP_map_idx(op), BB_id(OP_bb(op)),
00824 OP_map_idx(succ), BB_id(OP_bb(succ)),
00825 latency)) ;
00826
00827 }
00828
00829
00830
00831
00832
00833
00834 CAND_LIST* cand_lst = _cand_mgr.P_Ready_Cand_List ();
00835 if (cand_lst->Cand_In_Total ()) {
00836 cand_lst-> Erase_Cand (succ,FALSE);
00837 }
00838
00839 if (Try_Add_OP_to_Candidate_List (succ) &&
00840 SCHED_TF_SUMMARY_DUMP) {
00841
00842 fprintf (TFile, "%d ", OP_map_idx(succ));
00843 }
00844 }
00845
00846 _heur_mgr.Adjust_Heur_After_Cand_Sched (op, _cur_cyc);
00847 if (SCHED_TF_SUMMARY_DUMP) { fprintf(TFile, "\n"); }
00848
00849
00850
00851 if (!cand.Is_P_Ready ()) {
00852 _cand_mgr.M_Ready_Cand_List () -> Erase_Cand (&cand) ;
00853 } else {
00854 _cand_mgr.P_Ready_Cand_List () -> Erase_Cand (&cand) ;
00855 }
00856 }
00857
00858
00859
00860
00861
00862
00863
00864
00865
00866
00867 void
00868 SCHEDULER::Update_Cand_Lst_After_Cycle_Advancing (void) {
00869
00870 for (OP_Vector_Iter iter = _ops_in_cur_cyc.begin () ;
00871 iter != _ops_in_cur_cyc.end () ; iter ++) {
00872
00873 OP * op = *iter ;
00874
00875 for (ARC_LIST* arcs = OP_succs(op);
00876 arcs != NULL; arcs = ARC_LIST_rest(arcs)) {
00877
00878 ARC *arc = ARC_LIST_first(arcs);
00879 OP *succ = ARC_succ(arc);
00880
00881 INT32 latency = ARC_latency(arc) ;
00882
00883 if (!latency) continue ;
00884 if (!_src_bb_mgr.Is_Src_BB (OP_bb(succ))) continue;
00885
00886
00887 CAND_LIST* cand_lst = _cand_mgr.P_Ready_Cand_List ();
00888 if (cand_lst->Cand_In_Total ()) {
00889 cand_lst-> Erase_Cand (succ,FALSE);
00890 }
00891
00892 if (Try_Add_OP_to_Candidate_List(succ) &&
00893 SCHED_TF_SUMMARY_DUMP) {
00894 fprintf(TFile, "%d ", OP_map_idx(succ));
00895 }
00896 }
00897
00898 if (SCHED_TF_SUMMARY_DUMP) {
00899 fprintf(TFile, "\n");
00900 }
00901 }
00902 }
00903
00904
00905 inline BOOL
00906 SCHEDULER::OP_Cannot_Be_Moved_Outof_HomeBB (OP* op) {
00907
00908 return OP_xfer (op) ||
00909 OP_call (op) ||
00910 OP_chk (op) ||
00911 OP_ANNOT_OP_Def_Actual_Para (op);
00912 }
00913
00914 inline BOOL
00915 SCHEDULER::OP_QP_Cannot_Be_Removed_By_Cntl_Spec (OP* op) {
00916
00917 return OP_Cannot_Be_Moved_Outof_HomeBB(op)
00918
00919
00920 || OP_cmp_unc(op);
00921 }
00922
00923 SPEC_TYPE
00924 SCHEDULER::Get_OP_Prohibited_Spec_Type (OP *op) {
00925
00926
00927
00928
00929 if (OP_Is_Float_Mem(op) && !IPFEC_Enable_FP_Ld_Speculation ||
00930 OP_ANNOT_OP_Def_Actual_Para (op)) {
00931 return SPEC_COMB ;
00932 }
00933
00934
00935
00936
00937 if (!_prepass) { return SPEC_COMB ; }
00938
00939 TOP opcode = OP_code(op);
00940
00941 if (OP_xfer(op) || OP_like_store(op) ||
00942 TOP_is_ftrap(opcode)|| TOP_is_itrap(opcode) ||
00943 TOP_is_fdiv(opcode) || OP_idiv (op) ||
00944 OP_sqrt (op)) {
00945
00946
00947
00948 return SPEC_CNTL ;
00949 }
00950
00951 if (OP_volatile(op)) { return SPEC_COMB ; }
00952
00953
00954
00955
00956
00957
00958 if (OP_load (op)) {
00959
00960 for (INT i = OP_results(op) - 1 ; i >= 0 ; --i) {
00961
00962 TN * result_tn = OP_result (op,i) ;
00963 for (INT j = OP_opnds(op) - 1 ; j >= 0 ; --j) {
00964
00965 if (result_tn == OP_opnd(op,j)) {
00966 return SPEC_COMB ;
00967 }
00968 }
00969 }
00970 }
00971
00972 SPEC_TYPE spec_type = IPFEC_Enable_Speculation ? SPEC_NONE : SPEC_COMB ;
00973
00974 if (!IPFEC_Enable_Data_Speculation) {
00975 spec_type = SPEC_TYPE(spec_type | SPEC_DATA);
00976 }
00977
00978 if (!IPFEC_Enable_Cntl_Speculation) {
00979 spec_type = SPEC_TYPE(spec_type | SPEC_CNTL);
00980 }
00981
00982
00983 if (spec_type != SPEC_COMB && (
00984 IPFEC_Query_Skiplist (spec_skip_bb, (INT32)BB_id(OP_bb(op)),
00985 (INT32)Current_PU_Count()) ||
00986 IPFEC_Query_Skiplist (spec_skip_op, (INT32)OP_map_idx(op),
00987 (INT32)BB_id(OP_bb(op))))) {
00988 spec_type = SPEC_COMB ;
00989 }
00990
00991 return spec_type ;
00992 }
00993
00994
00995
00996
00997
00998
00999
01000
01001
01002
01003
01004
01005
01006
01007 void
01008 SCHEDULER::Identify_Cannot_Spec_OPs (BB *bb) {
01009
01010 OP * op;
01011 FOR_ALL_BB_OPs(bb, op) {
01012
01013 SPEC_TYPE spec_type = Get_OP_Prohibited_Spec_Type (op);
01014
01015 if (spec_type == SPEC_NONE) continue ;
01016
01017 if (spec_type & SPEC_CNTL) {
01018 OP_ANNOT_Set_Cannot_Cntl_Spec (op) ;
01019 }
01020
01021 if (spec_type & SPEC_DATA) {
01022 OP_ANNOT_Set_Cannot_Data_Spec (op) ;
01023 }
01024 }
01025 }
01026
01027
01028
01029
01030
01031
01032
01033
01034
01035
01036 void
01037 SCHEDULER::Identify_Cannot_Spec_OPs (REGION *rgn) {
01038
01039 for (TOPOLOGICAL_REGIONAL_CFG_ITER
01040 iter (rgn->Regional_Cfg()) ; iter != 0 ; ++ iter) {
01041
01042 if ((*iter)->Is_Region()) continue ;
01043 Identify_Cannot_Spec_OPs ((*iter)->BB_Node());
01044 }
01045 }
01046
01047
01048 void
01049 SCHEDULER::Init_Sched_Status (void) {
01050
01051 _cur_cyc = (CYCLE)0 ;
01052
01053 _ops_in_cur_cyc.clear ();
01054 _frontier_op = BB_length(_target_bb) ?
01055 BB_first_op (_target_bb) : NULL;
01056
01057 _upward_motion_num = _downward_motion_num = 0;
01058 _sched_times = 0;
01059
01060
01061 }
01062
01063 void
01064 SCHEDULER::Adjust_Status_For_Resched (void) {
01065
01066 _cur_cyc = (CYCLE)0;
01067 _ops_in_cur_cyc.clear ();
01068
01069 _upward_motion_num = _downward_motion_num = 0;
01070 _sched_times ++;
01071
01072 Clean_Up (_target_bb);
01073 _frontier_op = BB_first_op(_target_bb);
01074
01075
01076
01077 _heur_mgr.Adjust_Heur_Stuff_When_BB_Changed (_target_bb,_src_bb_mgr);
01078
01079
01080
01081 OP_Vector opv(&_mem_pool);
01082 for (CAND_LIST_ITER iter(_cand_mgr.M_Ready_Cand_List ());
01083 !iter.done();) {
01084
01085 opv.push_back (iter.cur()->Op ());
01086 iter.erase_cur_and_advance ();
01087
01088 }
01089
01090 for (CAND_LIST_ITER iter(_cand_mgr.P_Ready_Cand_List ());
01091 !iter.done();) {
01092
01093 opv.push_back (iter.cur()->Op ());
01094 iter.erase_cur_and_advance ();
01095
01096 }
01097
01098 OP* op;
01099 FOR_ALL_BB_OPs (_target_bb,op) {
01100 Try_Add_OP_to_Candidate_List (op);
01101 }
01102
01103 for (OP_Vector_Iter iter = opv.begin(); iter != opv.end(); iter++) {
01104 Try_Add_OP_to_Candidate_List (*iter);
01105 }
01106
01107
01108
01109 for (BB_VECTOR_ITER iter = _multiway_br_span_bbs.begin ();
01110 iter != _multiway_br_span_bbs.end ();
01111 iter ++) {
01112
01113 BB* b = *iter;
01114 _multiway_br_candidates = BB_SET_Difference1D
01115 (_multiway_br_candidates, b);
01116 }
01117
01118 _multiway_br_span_bbs.clear ();
01119 }
01120
01121
01122
01123
01124
01125
01126
01127
01128
01129
01130
01131
01132
01133
01134
01135
01136
01137
01138
01139
01140
01141
01142
01143
01144
01145
01146 OP*
01147 SCHEDULER::Insert_Check (OP * ld, BB * home_bb, OP* pos) {
01148
01149 Is_True (OP_load(ld), ("OP is not load!")) ;
01150
01151 std::vector<OP*> dup_ops;
01152 OP *chk_op = ::Insert_CHK (ld, dup_ops, home_bb, pos,
01153 OP_opnd(ld, OP_PREDICATE_OPND));
01154
01155
01156
01157
01158
01159 for (ARC_LIST * arcs = OP_succs(chk_op) ;
01160 arcs != NULL ; arcs = ARC_LIST_rest (arcs)) {
01161
01162 ARC* arc = ARC_LIST_first (arcs) ;
01163 OP* succ = ARC_succ (arc);
01164
01165 CAND_LIST * cand_list = NULL ;
01166 CANDIDATE * cand = NULL;
01167
01168 cand = _cand_mgr.Get_Candidate (succ);
01169 if (!cand) {
01170 continue;
01171 } else {
01172 cand_list = cand->Is_M_Ready () ?
01173 _cand_mgr.M_Ready_Cand_List ():
01174 _cand_mgr.P_Ready_Cand_List ();
01175
01176 }
01177
01178
01179
01180
01181 BB* b = OP_bb(ARC_pred(arc));
01182 if (!cand->Shadowed_By_P_Ready_Bookeeping (b,&_cflow_mgr)) {
01183
01184 if ((!ARC_is_dotted (arc) || OP_baneful(succ))) {
01185
01186
01187
01188
01189
01190
01191
01192 cand_list->Erase_Cand (cand);
01193
01194 } else {
01195
01196 if (OP_ANNOT_Cannot_Cntl_Spec (cand->Op())) {
01197 cand_list->Erase_Cand (cand);
01198 } else {
01199 cand->Add_Spec (SPEC_CNTL);
01200 }
01201 }
01202 }
01203
01204 }
01205
01206
01207
01208 SCHED_BB_ANNOT* bb_annot = sched_annot.Get_BB_Annot (home_bb);
01209 bb_annot->Init_New_OP_Annot (chk_op);
01210
01211
01212
01213 _heur_mgr.Compute_Heur_Data_For_Inserted_OP (chk_op);
01214
01215
01216
01217 OP_ANNOT_Set_Cannot_Spec (chk_op);
01218
01219 if (BB_call(OP_bb(chk_op))) {
01220
01221 for (CAND_LIST_ITER cand_iter(_cand_mgr.M_Ready_Cand_List ());
01222 !cand_iter.done ();) {
01223 CANDIDATE* cand = cand_iter.cur ();
01224 if (cand && OP_ANNOT_OP_Def_Actual_Para (cand->Op()))
01225 cand_iter.erase_cur_and_advance();
01226 else
01227 cand_iter.step();
01228 }
01229
01230 for (OP * op = chk_op ; op ; op = OP_next(op)) {
01231 if (OP_ANNOT_OP_Def_Actual_Para (op)) {
01232 new_arc_with_latency(CG_DEP_POSTCHK, chk_op,
01233 op, 0, 0, 0, FALSE);
01234 }
01235 }
01236 }
01237
01238
01239
01240
01241 if (OP_chk_a(chk_op) && IPFEC_Enable_Data_Spec_Res_Aware) {
01242 VIGILANT_PNT* vpld = _dsrmgr.Get_Vigilant_Point (ld);
01243 VIGILANT_PNT* vpchk = _dsrmgr.Add_Vigilant_Point (chk_op);
01244 vpchk->Set_Pending_Adv_Ld (vpld->Pending_Adv_Ld() + 1);
01245 }
01246
01247 return chk_op ;
01248 }
01249
01250
01251
01252
01253
01254
01255
01256
01257
01258
01259
01260
01261 void
01262 SCHEDULER::BB_Move_Op_Before (BB *to_bb, OP *point, BB *from_bb, OP *op) {
01263
01264
01265
01266
01267
01268 SCHED_BB_ANNOT * bb_annot ;
01269 SCHED_OP_ANNOT * op_annot ;
01270 void * op_heur ;
01271 VIGILANT_PNT* vgpnt = NULL;
01272
01273 BB_OP_MAP omap
01274 = (BB_OP_MAP) BB_MAP_Get(_cg_dep_op_info, OP_bb(op));
01275 _CG_DEP_OP_INFO *dep_info =
01276 (_CG_DEP_OP_INFO *) BB_OP_MAP_Get(omap, op);
01277
01278 bb_annot = sched_annot.Get_BB_Annot (from_bb);
01279 op_annot = bb_annot->Detach_OP_Annot (op);
01280 op_heur = _heur_mgr.Detach_OP_Heur_Info (op);
01281
01282
01283 if (_prepass && VIGILANT_PNT::Candidate (op) &&
01284 IPFEC_Enable_Data_Spec_Res_Aware) {
01285 vgpnt = _dsrmgr.Remove_Vigilant_Point (op);
01286 }
01287
01288 if (point) {
01289 ::BB_Move_Op_Before (to_bb, point, from_bb, op);
01290 } else {
01291
01292
01293
01294 ::BB_Move_Op_To_End (to_bb, from_bb, op);
01295 }
01296
01297 omap = (BB_OP_MAP) BB_MAP_Get(_cg_dep_op_info, OP_bb(op));
01298 BB_OP_MAP_Set (omap, op, dep_info);
01299
01300 bb_annot = sched_annot.Get_BB_Annot (to_bb);
01301 bb_annot->Attach_OP_Annot (op, op_annot) ;
01302 _heur_mgr.Attach_OP_Heur_Info (op,op_heur);
01303
01304
01305 if (vgpnt != NULL) {
01306 _dsrmgr.Add_Vigilant_Point (op, vgpnt);
01307 }
01308 }
01309
01310
01311
01312
01313
01314
01315
01316
01317
01318
01319
01320 void
01321 SCHEDULER :: Gen_Bookeeping_OP_DAG
01322 (CANDIDATE& cand, OP* compensate, BOOKEEPING* bk) {
01323
01324
01325 BOOL p_ready_bookeeping = bk->Is_P_Ready_Bookeeping ();
01326
01327 OP* model = cand.Op ();
01328 BB* place = bk->Get_Placement ();
01329
01330 BB_OP_MAP_Set (
01331 (BB_OP_MAP) BB_MAP_Get(_cg_dep_op_info,place),
01332 compensate, new_op_info ());
01333
01334
01335
01336 ARC_LIST* dep_lst ;
01337 for (dep_lst = OP_succs(model);
01338 dep_lst != NULL;
01339 dep_lst = ARC_LIST_rest(dep_lst)) {
01340
01341 ARC* tmp = ARC_LIST_first(dep_lst);
01342
01343 if (!tmp || ARC_is_br(tmp)) continue ;
01344 new_arc_with_latency
01345 (ARC_kind(tmp),
01346 compensate,
01347 ARC_succ(tmp),
01348 ARC_latency(tmp),
01349 ARC_omega(tmp),
01350 ARC_opnd(tmp),
01351 ARC_is_definite(tmp));
01352 }
01353
01354
01355
01356 for (dep_lst = OP_preds(model);
01357 dep_lst != NULL;
01358 dep_lst = ARC_LIST_rest(dep_lst)) {
01359
01360 ARC* tmp = ARC_LIST_first(dep_lst);
01361 if (!tmp || ARC_is_br(tmp)) {
01362
01363
01364
01365 continue ;
01366 }
01367
01368 BB* pred_bb = OP_bb(ARC_pred(tmp));
01369
01370 if (pred_bb == place||
01371 _cflow_mgr.BB1_Reachable_From_BB2 (place,pred_bb)) {
01372
01373 new_arc_with_latency (ARC_kind(tmp),
01374 ARC_pred(tmp), compensate,
01375 ARC_latency(tmp), ARC_omega(tmp),
01376 ARC_opnd(tmp), ARC_is_definite(tmp));
01377
01378 } else if (_cflow_mgr.BB1_Reachable_From_BB2 (pred_bb,place)) {
01379 Gen_Inverted_Arc (&cand, tmp,
01380 compensate,
01381 ARC_pred(tmp) );
01382 }
01383 }
01384
01385 _dag_constructor.Build_Branch_Arcs (compensate, INCLUDE_CONTROL_ARCS);
01386 }
01387
01388
01389
01390
01391
01392
01393
01394
01395
01396
01397
01398 OP*
01399 SCHEDULER::Gen_Compensation_Code
01400 (CANDIDATE& model_cand, BB* org_home,
01401 BOOKEEPING* bk, BOOL append) {
01402
01403 BB* place = bk->Get_Placement ();
01404 Is_True (!BB_Is_Isolated_From_Sched (place),
01405 ("Cannot prepend or append compensation code to a isolated BB:%d",
01406 BB_id(place)));
01407
01408
01409
01410
01411 OP* model = model_cand.Op ();
01412 OP* op = Dup_OP (model) ;
01413 OP_srcpos (op) = OP_srcpos(model);
01414
01415
01416
01417 SCHED_BB_ANNOT* annot = sched_annot.Get_BB_Annot (place);
01418
01419
01420
01421 BOOL insert_op = FALSE;
01422 if (append) {
01423
01424
01425
01426 OP* last_op = BB_last_op (place) ;
01427 if (last_op && TOP_is_xfer (OP_code(last_op))) {
01428 BB_Insert_Op_Before (place, last_op, op) ;
01429 insert_op = TRUE;
01430 } else {
01431
01432
01433
01434 BB_Append_Op (place, op) ;
01435 }
01436 } else {
01437 FmtAssert (FALSE,
01438 ("OP[%d] which is now in BB:%d is moved downward,however downward code has yet implemented",
01439 OP_map_idx(model),BB_id(place)));
01440 }
01441
01442
01443
01444 if (OP_memory(op)) {
01445 Copy_WN_For_Memory_OP (op,model);
01446 }
01447
01448
01449
01450 SCHED_OP_ANNOT* op_annot = annot->Init_New_OP_Annot (op) ;
01451 SCHED_OP_ANNOT* model_annot = sched_annot.Get_OP_Annot (model) ;
01452
01453 op_annot->_ext_flags = model_annot->_ext_flags &
01454 (OP_EXT_MASK_NO_CNTL_SPEC |
01455 OP_EXT_MASK_NO_DATA_SPEC |
01456 OP_EXT_MASK_ACTUAL) |
01457 OP_EXT_MASK_COMPENSATION;
01458
01459 op_annot->_op = op ;
01460 op_annot->_org_home_bb = org_home;
01461
01462
01463
01464
01465 Gen_Bookeeping_OP_DAG (model_cand,op,bk);
01466
01467
01468
01469
01470
01471 if (append) {
01472 if (insert_op) {
01473 _heur_mgr.Compute_Heur_Data_For_Inserted_OP (op);
01474 } else {
01475 _heur_mgr.Compute_Heur_Data_For_Appended_OP (op);
01476 }
01477 } else {
01478 FmtAssert (FALSE,("Downward code motion has yet implemented\n"));
01479 }
01480
01481
01482
01483 SPEC_TYPE spec_type = model_cand.Spec_Type ();
01484 if (spec_type & SPEC_DATA) {
01485 Set_OP_data_spec (op);
01486 Set_OP_orig_bb_id (op,BB_id(org_home));
01487 }
01488
01489 if (spec_type & SPEC_CNTL) {
01490 Set_OP_cntl_spec (op);
01491 Set_OP_orig_bb_id (op,BB_id(org_home));
01492 }
01493
01494 if (IPFEC_Enable_Data_Spec_Res_Aware) {
01495 _dsrmgr.Update_Vp_For_Compensation_Code (op, place);
01496 }
01497
01498 return op ;
01499 }
01500
01501
01502
01503
01504
01505
01506
01507
01508
01509
01510 void
01511 SCHEDULER::Gen_Inverted_Arc
01512 (CANDIDATE* cand, ARC* ref_arc, OP* pred, OP* succ) {
01513
01514 CG_DEP_KIND arc_kind;
01515 INT16 arc_opnd = 0;
01516 TN* arc_opnd_tn;
01517
01518 OP* arc_pred = ARC_pred(ref_arc);
01519 OP* arc_succ = ARC_succ(ref_arc);
01520
01521
01522 switch (ARC_kind(ref_arc)) {
01523 case CG_DEP_REGIN:
01524 arc_kind = CG_DEP_REGANTI;
01525
01526 arc_opnd_tn = OP_opnd(arc_succ,ARC_opnd(ref_arc));
01527 for (arc_opnd = OP_results(arc_succ) - 1;
01528 arc_opnd >= 0;
01529 arc_opnd--) {
01530 if (OP_result(arc_pred, arc_opnd) == arc_opnd_tn) {
01531 break;
01532 }
01533 }
01534
01535 arc_opnd = (arc_opnd >= 0) ? arc_opnd : 0;
01536 break;
01537
01538
01539 case CG_DEP_REGOUT:
01540 arc_kind = CG_DEP_REGIN;
01541 break;
01542
01543
01544 case CG_DEP_REGANTI:
01545 arc_kind = CG_DEP_REGIN;
01546 arc_opnd_tn = OP_result(arc_succ, ARC_opnd(ref_arc));
01547 for (arc_opnd = OP_opnds (arc_pred) - 1;
01548 arc_opnd >= 0;
01549 arc_opnd --) {
01550 if (OP_opnd(arc_pred, arc_opnd) == arc_opnd_tn) { break; }
01551 }
01552
01553 arc_opnd = (arc_opnd >= 0) ? arc_opnd : 0;
01554 break;
01555
01556 case CG_DEP_MEMOUT:
01557 arc_kind = CG_DEP_MEMOUT; break;
01558
01559 case CG_DEP_MEMANTI:
01560 arc_kind = CG_DEP_MEMIN; break;
01561
01562 case CG_DEP_MEMVOL:
01563 arc_kind = CG_DEP_MEMVOL; break;
01564
01565 case CG_DEP_MEMREAD:
01566 arc_kind = CG_DEP_MEMREAD; break;
01567
01568 case CG_DEP_SPILLIN:
01569 case CG_DEP_PREFIN:
01570 case CG_DEP_PREFOUT:
01571 case CG_DEP_SCC:
01572 case CG_DEP_MISC:
01573 case CG_DEP_CTLSPEC:
01574 arc_kind = CG_DEP_MISC; break;
01575
01576 case CG_DEP_MEMIN:
01577 arc_kind = CG_DEP_MEMANTI; break;
01578
01579 case CG_DEP_PREBR:
01580 arc_kind = CG_DEP_POSTBR; break;
01581
01582 case CG_DEP_PRECHK:
01583 arc_kind = CG_DEP_POSTCHK; break;
01584
01585 case CG_DEP_POSTBR:
01586 arc_kind = CG_DEP_PREBR; break;
01587
01588 case CG_DEP_POSTCHK:
01589 arc_kind = CG_DEP_PRECHK; break;
01590 break;
01591
01592 default:
01593 FmtAssert (FALSE, ("unknown CG_DEP_KIND %X\n", ARC_kind(ref_arc)));
01594 break;
01595 }
01596
01597
01598
01599
01600
01601 ARC* New_Arc;
01602 switch (ARC_kind(ref_arc)) {
01603 case CG_DEP_PREBR:
01604 case CG_DEP_POSTBR:
01605 case CG_DEP_PRECHK:
01606 case CG_DEP_POSTCHK:
01607 New_Arc = new_arc_with_latency
01608 (arc_kind,
01609 pred, succ,
01610 0, 0 ,
01611 arc_opnd, TRUE);
01612 break;
01613 default:
01614 New_Arc = new_arc (arc_kind, pred, succ, 0, arc_opnd, TRUE);
01615 }
01616
01617 Is_True (ARC_latency(New_Arc) >= 0,
01618 ("Negative latency (%d)", ARC_latency(New_Arc)));
01619 }
01620
01621
01622
01623
01624
01625
01626
01627
01628
01629
01630
01631
01632 void
01633 SCHEDULER::Maintain_Dep_Arcs_After_Sched (CANDIDATE* cand) {
01634
01635 OP* op = cand->Op ();
01636
01637
01638
01639 Is_True (OP_Scheduled(op),
01640 ("OP:%d(BB:%d) must be scheduled",
01641 OP_map_idx(op), BB_id(OP_bb(op))));
01642
01643
01644
01645 for (ARC_LIST* arcs = OP_preds(op); arcs ;) {
01646
01647 ARC *arc = ARC_LIST_first(arcs);
01648 arcs = ARC_LIST_rest(arcs);
01649 OP* pred = ARC_pred (arc);
01650
01651 if (OP_Scheduled(pred)) {
01652
01653
01654
01655
01656
01657
01658
01659
01660
01661
01662 if (!OP_xfer(pred) || OP_bb(pred) != OP_bb(op)) {
01663 continue;
01664 }
01665 }
01666
01667
01668
01669
01670
01671
01672
01673
01674
01675
01676
01677 if (!_cflow_mgr.BB1_Reachable_From_BB2 (OP_bb(op),OP_bb(pred)) &&
01678 !_cflow_mgr.BB1_Reachable_From_BB2 (OP_bb(pred),OP_bb(op)) &&
01679 OP_bb(op) != OP_bb(pred)) {
01680
01681 CG_DEP_Detach_Arc (arc);
01682 continue;
01683
01684 }
01685
01686
01687
01688 Gen_Inverted_Arc (cand, arc,
01689 ARC_succ(arc),
01690 ARC_pred(arc) );
01691
01692 CG_DEP_Detach_Arc (arc);
01693
01694 }
01695 }
01696
01697
01698
01699
01700
01701
01702
01703
01704
01705
01706
01707
01708
01709
01710
01711
01712
01713
01714
01715
01716
01717
01718
01719
01720
01721
01722
01723
01724
01725
01726
01727
01728
01729
01730
01731 BOOL
01732 SCHEDULER::Commit_Schedule (CANDIDATE& cand) {
01733
01734 OP* op = cand.Op ();
01735 BB* home_bb = OP_bb(op);
01736 OP* cmp_op = NULL;
01737 TN* op_qp_bak = NULL;
01738
01739 BOOL insert_chk = FALSE ;
01740 BOOL cntl_spec_if_converted_code = FALSE;
01741 SRC_BB_INFO * src_info = _src_bb_mgr.Get_Src_Info (OP_bb(cand.Op()));
01742
01743
01744 ISA_ENUM_CLASS_VALUE ldform = ECV_UNDEFINED;
01745 BOOL transform = FALSE;
01746 if (OP_load(op) && IPFEC_Enable_Data_Spec_Res_Aware) {
01747 transform = SCHED_SPEC_HANDSHAKE::Change_Load_Spec_Form
01748 (&cand, src_info->Get_Cutting_Set()->size(),
01749 &insert_chk, this, &ldform, TRUE);
01750 if (CGTARG_Is_OP_Advanced_Load(op) ||
01751 transform && CGTARG_Is_Form_For_Advanced_Load (ldform)) {
01752 if (_global &&
01753 !_dsrmgr.Check_Res_Constraint (_region, op, src_info) ||
01754 !_global &&
01755 !_dsrmgr.Check_Res_Constraint (_target_bb, op)) {
01756 _cand_mgr.Get_Cand_List (&cand)-> Erase_Cand (&cand);
01757 return FALSE;
01758 }
01759 }
01760 }
01761
01762 if (CGTARG_Is_OP_Advanced_Load (op) || OP_chk_a(op) ||
01763 transform && CGTARG_Is_Form_For_Advanced_Load (ldform) &&
01764 IPFEC_Enable_Data_Spec_Res_Aware) {
01765 _dsrmgr.Update_Pending_Adv_Ld_Info (src_info, op);
01766 }
01767
01768
01769
01770
01771 if ((OP_load(op) || cand.Is_If_Converted()) && cand.Is_Spec ()) {
01772 cand.Get_Up_to_Date_Spec_Type ();
01773 }
01774
01775 if (cand.Is_Spec() && cand.Is_If_Converted()) {
01776
01777
01778
01779
01780
01781
01782 cmp_op = cand.Get_Cmp_OP_Of_If_Converted_Code();
01783 if (!OP_Scheduled(cmp_op)) cntl_spec_if_converted_code = TRUE;
01784
01785
01786
01787 if (OP_opnd(op, OP_PREDICATE_OPND) == True_TN) {
01788 op_qp_bak = True_TN;
01789 } else {
01790 op_qp_bak = Dup_TN(OP_opnd(op, OP_PREDICATE_OPND));
01791 }
01792 }
01793
01794
01795
01796
01797
01798 if (op != _frontier_op) {
01799
01800 OP* pos = OP_prev(op);
01801 OP* chk_op = NULL;
01802
01803 BB_VECTOR* cutting_set = src_info->Get_Cutting_Set ();
01804 SCHED_SPEC_HANDSHAKE::Change_Load_Spec_Form
01805 (&cand, cutting_set->size(),&insert_chk, this);
01806
01807 BB_Move_Op_Before (_target_bb, _frontier_op, OP_bb(op), op) ;
01808 if (insert_chk) { chk_op = Insert_Check (op, home_bb, pos); }
01809
01810
01811
01812 if (cntl_spec_if_converted_code) {
01813 Set_OP_opnd(op, OP_PREDICATE_OPND, True_TN);
01814 }
01815
01816 BOOKEEPING_LST* bkl = cand.Bookeeping_Lst ();
01817
01818 for (BOOKEEPING* bk = bkl->First_Item ();
01819 bk != NULL;
01820 bk = bkl->Next_Item (bk)) {
01821
01822 OP* bookeeping_op = Gen_Compensation_Code (cand, home_bb, bk);
01823 if (insert_chk && bk->Is_P_Ready_Bookeeping ()) {
01824 Set_Speculative_Chain_Begin_Point (chk_op,bookeeping_op);
01825 }
01826 }
01827 } else {
01828
01829 _frontier_op = OP_next(_frontier_op);
01830
01831 }
01832
01833
01834 Set_OP_Scheduled (op);
01835 OP_scycle(op) = (mINT16)_cur_cyc ;
01836
01837
01838
01839 SPEC_TYPE spec_type = cand.Spec_Type ();
01840 if (spec_type & SPEC_DATA) { Set_OP_data_spec(op); }
01841 if (spec_type & SPEC_CNTL) { Set_OP_cntl_spec(op); }
01842 if (spec_type & (SPEC_DATA | SPEC_CNTL)) {
01843 Set_OP_orig_bb_id (op,BB_id(home_bb));
01844 }
01845 if (cntl_spec_if_converted_code) { Set_OP_if_converted(op); }
01846
01847 if (cand.Spec_Type () != SPEC_NONE ||
01848 home_bb != _target_bb) {
01849
01850 _upward_motion_num ++;
01851
01852
01853 Maintain_Dep_Arcs_After_Sched (&cand);
01854 }
01855
01856 if (cntl_spec_if_converted_code) {
01857 Maintain_Dep_Arcs_After_Cntl_Spec_If_Converted_Code(op, op_qp_bak, cmp_op);
01858 }
01859
01860
01861
01862 if (home_bb != _target_bb) {
01863 _dflow_mgr.Update_Liveness_After_Upward_Sched
01864 (&cand,src_info, &_cflow_mgr) ;
01865 }
01866
01867
01868
01869
01870
01871 Update_Cand_Lst_During_Sched_Cyc (cand);
01872
01873 if (cntl_spec_if_converted_code) {
01874 Update_Cand_Lst_After_Cntl_Spec_If_Converted_Code(op, op_qp_bak);
01875 }
01876
01877
01878
01879
01880 _ops_in_cur_cyc.push_back(op) ;
01881 BOOL retcode = CGGRP_Issue_OP(op, TRUE);
01882 Is_True (retcode, ("fail to issue op"));
01883
01884 return OP_xfer (op);
01885 }
01886
01887
01888
01889
01890
01891
01892
01893
01894
01895
01896
01897
01898
01899
01900
01901
01902
01903
01904
01905
01906
01907
01908
01909
01910
01911
01912 BOOL
01913 SCHEDULER::Can_Cntl_Spec_If_Converted_Code(CANDIDATE *cand) {
01914
01915 OP* cand_op = cand->Op();
01916 BB* home_bb = OP_bb(cand_op);
01917 OP* cmp_op = cand->Get_Cmp_OP_Of_If_Converted_Code();
01918
01919 if (OP_Scheduled(cmp_op)) return TRUE;
01920 if (OP_QP_Cannot_Be_Removed_By_Cntl_Spec(cand_op)) return FALSE;
01921
01922 BOOL killed = FALSE;
01923
01924
01925 if (home_bb == _target_bb) {
01926 for (OP* op = cmp_op; op; op = OP_next(op)) {
01927
01928
01929
01930
01931
01932
01933
01934
01935
01936
01937
01938
01939
01940
01941
01942
01943
01944
01945
01946
01947
01948 for (INT i = 0; i < OP_results(cand_op); i++) {
01949 if (OP_opnd(op, OP_PREDICATE_OPND) != True_TN &&
01950 OP_opnd(op, OP_PREDICATE_OPND) == OP_result(cand_op, i))
01951 return FALSE;
01952 }
01953
01954 if ( !OP_has_subset_predicate(cand_op, op) &&
01955 OP1_Defs_Are_Used_By_OP2(cand_op, op)){
01956 return FALSE;
01957 }
01958 }
01959 }
01960
01961
01962 if (!killed) {
01963 for (INT i = 0; i < OP_results(cand_op); i++) {
01964 if (GTN_SET_MemberP(BB_live_out(_target_bb), OP_result(cand_op, i))) {
01965 return FALSE;
01966 }
01967 }
01968 }
01969 return TRUE;
01970 }
01971
01972
01973
01974
01975
01976
01977
01978
01979
01980
01981
01982
01983
01984
01985 void
01986 SCHEDULER::Maintain_Dep_Arcs_After_Cntl_Spec_If_Converted_Code
01987 (OP* sched_op, TN* sched_qp, OP* cmp_op) {
01988
01989 for (OP* op = OP_next(cmp_op); op; op = OP_next(op)) {
01990 if (!OP_has_predicate(op) ||
01991 !PQSCG_is_subset_of(sched_qp, OP_opnd(op, OP_PREDICATE_OPND))) {
01992 if (OP1_Defs_Are_Killed_By_OP2(sched_op, op)) {
01993 new_arc(CG_DEP_MISC, cmp_op, op, 0, 0, TRUE);
01994 }
01995 }
01996 }
01997 }
01998
01999
02000
02001
02002
02003
02004
02005
02006
02007 void
02008 SCHEDULER::Update_Cand_Lst_After_Cntl_Spec_If_Converted_Code
02009 (OP* sched_op, TN* sched_qp) {
02010
02011 for (CAND_LIST_ITER cand_iter(_cand_mgr.M_Ready_Cand_List ());
02012 !cand_iter.done (); ) {
02013
02014 CANDIDATE* cand = cand_iter.cur ();
02015 OP* op = cand->Op();
02016 if (!OP_has_predicate(op) ||
02017 !PQSCG_is_subset_of(sched_qp, OP_opnd(op, OP_PREDICATE_OPND))) {
02018 if (OP1_Defs_Are_Killed_By_OP2(sched_op, op)) {
02019
02020 cand_iter.erase_cur_and_advance();
02021 if (_heur_mgr.Trace_Cand_Sel_Enabled ()) {
02022 _heur_mgr.Trace_Cand_Sel_Process(
02023 "\tDiscard a candidate since it kills some OPs just cntl speculated ");
02024 }
02025 continue;
02026 }
02027 }
02028 cand_iter.step ();
02029 }
02030 }
02031
02032
02033
02034
02035
02036
02037
02038 void
02039 SCHEDULER::Verify (void) {
02040
02041 OP* op;
02042
02043 FOR_ALL_BB_OPs(_target_bb, op) {
02044 Is_True(OP_Scheduled(op),
02045 ("Not all ops scheduled: %d 0x%x\tin BB: %d",
02046 OP_map_idx(op), op, BB_id(OP_bb(op))));
02047 }
02048
02049 }
02050
02051
02052 void
02053 SCHEDULER::Identify_Actual_Argument_Defs (BB* bb) {
02054 if (!BB_call (bb)) return ;
02055 PLOC ploc;
02056 TY_IDX func_type;
02057 ANNOTATION *ant;
02058 WN *call_wn;
02059 CALLINFO *call_info;
02060 ST *call_st;
02061 PREG_NUM *parm;
02062 INT i,j;
02063
02064 OP * call_op = BB_xfer_op(bb) ;
02065 Is_True (OP_call(call_op), ("OP is not a call!"));
02066
02067 ant = ANNOT_Get(BB_annotations(bb), ANNOT_CALLINFO);
02068 call_info = ANNOT_callinfo(ant);
02069 call_st = CALLINFO_call_st(call_info);
02070 call_wn = CALLINFO_call_wn(call_info);
02071
02072 func_type = call_st ? ST_pu_type(call_st) : WN_ty(call_wn);
02073 ploc = Setup_Output_Parameter_Locations(func_type);
02074
02075 INT num_parms = WN_num_actuals(call_wn);
02076 parm = new PREG_NUM[num_parms];
02077 for (i = 0; i < num_parms; i++) {
02078 ploc = Get_Output_Parameter_Location (TY_Of_Parameter(WN_actual(call_wn,i)));
02079 parm[i] = ploc.reg;
02080 }
02081
02082 if (!BB_call (bb)) return ;
02083
02084 OP * op ;
02085 FOR_ALL_BB_OPs(bb, op) {
02086 OP_ANNOT_Reset_OP_Def_Actual_Para (op);
02087 for (i=0; i < num_parms ; i++) {
02088 for (j=0; j < OP_results(op); j++) {
02089 TN* tn = OP_result(op, j);
02090 PREG_NUM tn_reg = REGISTER_machine_id(TN_register_class(tn), TN_register(tn));
02091 if (TN_register_class(tn) == 1){
02092 tn_reg = tn_reg;
02093 }
02094 else if (TN_register_class(tn) == 2){
02095 tn_reg += REGISTER_CLASS_register_count(1);
02096 }
02097 else{
02098 continue;
02099 }
02100 if (tn_reg == parm[i]){
02101 OP_ANNOT_Set_OP_Def_Actual_Para (op);
02102 i = num_parms;
02103 break;
02104 }
02105 }
02106 }
02107 }
02108
02109 OP_ANNOT_Reset_OP_Def_Actual_Para (call_op);
02110 delete parm;
02111 }
02112
02113
02114
02115
02116
02117
02118
02119
02120
02121 BOOL
02122 SCHEDULER::Sched_Rgn_Preproc (void) {
02123
02124
02125 if (_cflow_mgr.Critical_Edge_Present(_region)) {
02126
02127
02128
02129
02130 return FALSE;
02131 }
02132
02133 if (!_cflow_mgr.BB_Node_Num()) {
02134
02135
02136
02137
02138
02139 return FALSE;
02140 }
02141
02142
02143
02144 sched_annot.Init (_region);
02145
02146
02147
02148
02149
02150 Start_Timer (T_Ipfec_GLOS_MISC1_CU);
02151 _dag_constructor.Build_DAG();
02152 Stop_Timer (T_Ipfec_GLOS_MISC1_CU);
02153 if (SCHED_TF_DUMP_DAG) { Dump_DAG(); fprintf(TFile, "\n"); }
02154
02155 _heur_mgr.Initialize (_region,&_cflow_mgr);
02156
02157 for (TOPOLOGICAL_REGIONAL_CFG_ITER iter(_region->Regional_Cfg());
02158 iter != 0; ++iter) {
02159
02160 if ((*iter)->Is_Region()) continue ;
02161 BB * bb = (*iter)->BB_Node();
02162
02163 if (IPFEC_Query_Skiplist (glos_skip_bb, BB_id(bb), Current_PU_Count())) {
02164 Isolate_BB_From_Sched_Scope (bb);
02165 DevWarn ("BB:%d in PU%d is skipped\n", BB_id(bb), Current_PU_Count());
02166 }
02167
02168 if (BB_entry(bb) || BB_exit(bb)) continue ;
02169
02170 Identify_Actual_Argument_Defs (bb);
02171 }
02172
02173 Identify_Cannot_Spec_OPs (_region);
02174
02175 return TRUE;
02176 }
02177
02178
02179
02180
02181
02182
02183
02184
02185
02186 void
02187 SCHEDULER::Sched_Rgn_Postproc (void) {
02188 Build_Region_Summary (_region, &_cflow_mgr) ;
02189 }
02190
02191
02192
02193
02194
02195
02196
02197
02198
02199
02200
02201
02202
02203
02204
02205
02206
02207
02208
02209
02210
02211
02212
02213
02214
02215 void
02216 SCHEDULER::Preprocess_GP_def_op (void) {
02217
02218 _gp_def_op = NULL ;
02219
02220 if (!BB_length(_target_bb) ||
02221 !OP_def_GP (BB_first_op(_target_bb))) {
02222 return ;
02223 }
02224
02225 _gp_def_op = BB_first_op(_target_bb);
02226 }
02227
02228 void
02229 SCHEDULER::Postprocess_GP_def_op (void) {
02230
02231 if (_gp_def_op && BB_first_op(_target_bb) != _gp_def_op) {
02232
02233 BB_Move_Op_Before (_target_bb,
02234 BB_first_op(_target_bb),
02235 _target_bb, _gp_def_op) ;
02236 Reset_BB_scheduled (_target_bb);
02237 }
02238
02239 _gp_def_op = NULL;
02240 }
02241
02242 inline BOOL
02243 SCHEDULER::OP_def_GP (OP* op) {
02244 if (OP_results (op) != 1) return FALSE;
02245
02246 return OP_result(op,0) == GP_TN ;
02247 }
02248
02249 inline void
02250 SCHEDULER::Bug_Workaround_Before_Schedule_BB (void) {
02251 if (_prepass) {
02252 Preprocess_GP_def_op ();
02253 }
02254 }
02255
02256 inline void
02257 SCHEDULER::Bug_Workaround_After_Schedule_BB (void) {
02258
02259 if (_prepass) {
02260 Postprocess_GP_def_op ();
02261 }
02262 }
02263
02264 void
02265 SCHEDULER::Glos_Sched_BB_Preproc (void) {
02266
02267 if (_global) {
02268 Determine_P_Ready_is_Profitable_or_not () ;
02269 }
02270
02271 _multiway_br_span_bbs.clear ();
02272
02273 Init_Sched_Status () ;
02274
02275
02276
02277
02278
02279 _src_bb_mgr.Find_Src_BBs (_region, _target_bb, &_cflow_mgr,
02280 TRUE );
02281
02282
02283
02284
02285
02286
02287
02288
02289 _heur_mgr.Adjust_Heur_Stuff_When_BB_Changed (_target_bb,_src_bb_mgr);
02290
02291
02292
02293 Find_All_Candidates ();
02294 }
02295
02296
02297
02298
02299
02300
02301
02302
02303
02304
02305 void
02306 SCHEDULER::Glos_Sched_BB_Postproc (void) {
02307
02308
02309
02310 CGGRP_End_BB();
02311 Set_BB_scheduled (_target_bb);
02312 Isolate_BB_From_Sched_Scope (_target_bb);
02313
02314
02315
02316 BB_cycle(_target_bb) =
02317 BB_length(_target_bb) ? _cur_cyc : 0 ;
02318
02319 Verify();
02320 }
02321
02322
02323
02324
02325
02326
02327
02328
02329
02330 BOOL
02331 SCHEDULER::Glos_Should_Sched_This_BB (BB* b) {
02332
02333 if (BB_Is_Isolated_From_Sched (b)) {
02334 return FALSE;
02335 }
02336
02337
02338 INT32 len = BB_length(b);
02339 if (len > 1) { return TRUE; }
02340 if (len == 0) { return FALSE; }
02341
02342
02343
02344
02345
02346
02347 if (len == 1 && BB_branch_op (b)) {
02348
02349 if (BB_edge_splitting (b)) {
02350 return FALSE;
02351 }
02352
02353 if (BB_SET_MemberP (_multiway_br_candidates, b)) {
02354 return FALSE;
02355 }
02356 }
02357
02358 if (BB_entry(b) || BB_exit(b)) {
02359 return FALSE;
02360 }
02361
02362
02363 return TRUE;
02364 }
02365
02366
02367
02368
02369
02370
02371
02372
02373 void
02374 SCHEDULER::Schedule_Cycle (void) {
02375
02376
02377
02378
02379 _cand_mgr.Clear_All_Cands_Tried_Mark ();
02380
02381 BOOL commit_br = FALSE;
02382 while (!_cand_mgr.Cand_Lst_Is_Empty ()) {
02383
02384
02385
02386
02387 if (CGGRP_Cycle_Full() ||
02388 _cand_mgr.All_Cands_Have_Been_Tried ()) {
02389 return ;
02390 }
02391
02392
02393
02394 E_Time_Constraint etime_constraint;
02395
02396 etime_constraint.threshold = _cur_cyc;
02397 etime_constraint.constraint =
02398 _ops_in_cur_cyc.empty() ? AS_EARLY_AS_POSSIBLE :
02399 NO_LATER;
02400
02401 CANDIDATE* cand =
02402 _heur_mgr.Select_Best_Candidate (
02403 *_cand_mgr.M_Ready_Cand_List (),
02404 *_cand_mgr.P_Ready_Cand_List (),
02405 _target_bb,
02406 &etime_constraint);
02407
02408 if (!cand) { return ; }
02409
02410 if (BB_length (_target_bb) >= MAX_BB_LENGTH &&
02411 OP_bb(cand->Op ()) != _target_bb) {
02412 _cand_mgr.Get_Cand_List (cand)-> Erase_Cand (cand);
02413 continue;
02414 }
02415
02416 if (!CGGRP_Issue_OP(cand->Op())) {
02417
02418
02419
02420
02421 if (_heur_mgr.Trace_Cand_Sel_Enabled ()) {
02422 _heur_mgr.Trace_Cand_Sel_Process (
02423 "\tDiscard best candidate due to structual hazard\n");
02424 }
02425
02426 _cand_mgr.Get_Cand_List (cand)->Set_Cand_Has_Been_Tried (cand);
02427 continue;
02428 }
02429
02430
02431
02432
02433
02434
02435
02436
02437
02438
02439
02440
02441
02442
02443
02444
02445 BB *cand_home_bb = OP_bb (cand->Op()) ;
02446
02447 SRC_BB_INFO* src_info = _src_bb_mgr.Get_Src_Info (cand_home_bb);
02448 if (cand_home_bb != _target_bb &&
02449 _dflow_mgr.Upward_Sched_Kill_LiveOut_Defs (
02450 cand, src_info, &_cflow_mgr)) {
02451
02452 if ( IPFEC_Glos_Enable_Renaming &&
02453 !IPFEC_Query_Skiplist (glos_rename_skip_bb, BB_id(cand_home_bb), Current_PU_Count()) &&
02454 !IPFEC_Query_Skiplist (glos_rename_skip_op, OP_map_idx(cand->Op()), BB_id(cand_home_bb)) &&
02455 _heur_mgr.Renaming_Is_Profitable(cand)) {
02456
02457 Renaming(cand);
02458 } else {
02459
02460 _cand_mgr.Get_Cand_List (cand)-> Erase_Cand (cand);
02461 if (_heur_mgr.Trace_Cand_Sel_Enabled ()) {
02462 _heur_mgr.Trace_Cand_Sel_Process(
02463 "\tDiscard best candidate since it kill some live out TN");
02464 }
02465
02466 continue ;
02467 }
02468 }
02469
02470 #ifdef Is_True_On
02471
02472 if (!_ops_in_cur_cyc.empty ()) {
02473 Is_True (_cur_cyc == etime_constraint.threshold ,
02474 ("best candidate [OP%3d][BB%3d] should be issued exactly"
02475 " at cycle %d",
02476 OP_map_idx(cand->Op()),
02477 BB_id(OP_bb(cand->Op())),
02478 _cur_cyc));
02479 } else {
02480 Is_True (_cur_cyc <= etime_constraint.threshold,
02481 ("best candidate [OP%3d][BB%3d] should be issued"
02482 " before cycle %d",
02483 OP_map_idx(cand->Op()),
02484 BB_id(OP_bb(cand->Op())),
02485 _cur_cyc));
02486 }
02487 #endif
02488
02489 _cur_cyc = etime_constraint.threshold ;
02490
02491
02492
02493 OP* op = cand->Op ();
02494 if (OP_br(op)) { commit_br = TRUE; }
02495
02496 Commit_Schedule (*cand);
02497
02498 if (OP_call(op) &&
02499 !IPFEC_Glos_Motion_Across_Calls) {
02500 return;
02501 }
02502 }
02503
02504
02505
02506 if (commit_br && _prepass) {
02507
02508 BB* b;
02509 BB_VECTOR bbs(&_mem_pool);
02510
02511 for (b = BB_Fall_Thru_Successor (_target_bb); b ;
02512 b = BB_Fall_Thru_Successor (b)) {
02513
02514 if (!BB_Unique_Predecessor (b)) {
02515 b = NULL; break;
02516 }
02517
02518
02519
02520 if (!BB_length(b)) { continue ; }
02521
02522
02523
02524 if (BB_length(b) == 1 && BB_branch_op (b)) {
02525 bbs.push_back (b);
02526 if (BB_edge_splitting(b)) { continue; } else break ;
02527 }
02528
02529 b = NULL; break;
02530 }
02531
02532 if (b && BB_length(b) == 1 && BB_branch_op(b)) {
02533
02534 if (::Home_Region (b) == _region) {
02535 OP* br = BB_branch_op(b);
02536 if (br && CGGRP_Issue_OP (br, FALSE)) {
02537
02538 for (BB_VECTOR_ITER iter = bbs.begin () ;
02539 iter != bbs.end () ; iter++) {
02540
02541 _multiway_br_candidates = BB_SET_Union1D
02542 (_multiway_br_candidates, *iter, &_mem_pool);
02543
02544 _multiway_br_span_bbs.push_back (*iter);
02545 }
02546 }
02547 }
02548 }
02549 }
02550 }
02551
02552
02553
02554
02555
02556
02557
02558
02559
02560
02561
02562 BOOL
02563 SCHEDULER :: No_New_Cycle (void) {
02564
02565 BOOL no_new_cyc = FALSE ;
02566
02567 if (BB_length(_target_bb) == 0 ||
02568 OP_Scheduled(BB_last_op(_target_bb))) {
02569 no_new_cyc = TRUE;
02570 }
02571
02572 #ifdef Is_True_On
02573 if (!no_new_cyc) {
02574 Is_True (!_cand_mgr.Cand_Lst_Is_Empty (),
02575 ("Candidate list is Empty!"));
02576 }
02577 #endif
02578
02579 return no_new_cyc;
02580
02581 }
02582
02583
02584
02585
02586
02587
02588
02589
02590
02591
02592 BOOL
02593 SCHEDULER::Need_Resched_To_Obtain_Better_Performance (void) {
02594
02595
02596
02597 if (_sched_times >= (MAX_SCHED_TIMES - 1)) { return FALSE ; }
02598
02599 if (_src_bb_mgr.Src_BBs ()->size () <= 1) {
02600 return FALSE ;
02601 }
02602
02603 if (_cand_mgr.Cand_Lst_Is_Empty ()) {
02604 return FALSE;
02605 }
02606
02607 if (_upward_motion_num <= 0) {
02608 return FALSE;
02609 }
02610
02611 if (BB_length(_target_bb) >= MAX_BB_LENGTH) {
02612 return FALSE;
02613 }
02614
02615 return TRUE;
02616 }
02617
02618
02619
02620
02621
02622
02623
02624
02625
02626
02627
02628
02629 void
02630 SCHEDULER::Schedule_Region (void) {
02631
02632 if (!Sched_Rgn_Preproc ()) return;
02633
02634 TOPDOWN_SCHED_SEQ seq (_region, &_mem_pool);
02635 for (_target_bb = seq.First ();
02636 _target_bb ;
02637 _target_bb = seq.Next()) {
02638
02639 if (!Glos_Should_Sched_This_BB (_target_bb)) {
02640 Isolate_BB_From_Sched_Scope (_target_bb);
02641 continue ;
02642 }
02643
02644 Bug_Workaround_Before_Schedule_BB ();
02645 Glos_Sched_BB_Preproc ();
02646
02647 BOOL no_new_cycle = FALSE;
02648 OP * xfer_op = BB_xfer_op(_target_bb);
02649
02650 do {
02651 do {
02652 Schedule_Cycle ();
02653 Cycle_Advance ();
02654 } while (!No_New_Cycle ());
02655
02656 Glos_Sched_BB_Postproc ();
02657
02658 if (Need_Resched_To_Obtain_Better_Performance ()) {
02659 Adjust_Status_For_Resched ();
02660 } else {
02661 break ;
02662 }
02663
02664 } while (TRUE);
02665
02666 Bug_Workaround_After_Schedule_BB ();
02667
02668 }
02669
02670 Sched_Rgn_Postproc ();
02671 }
02672
02673
02674
02675
02676
02677
02678
02679
02680
02681
02682
02683
02684
02685
02686
02687
02688
02689
02690
02691
02692 void
02693 SCHEDULER::Schedule_BB (void) {
02694
02695 if (BB_length(_target_bb) == 0) return;
02696
02697 _src_bb_mgr.Find_Src_BBs (_region, _target_bb,
02698 &_cflow_mgr, _prepass);
02699
02700
02701
02702 _dag_constructor.Build_DAG ();
02703 if (SCHED_TF_DUMP_DAG) {
02704 Dump_DAG(); fprintf(TFile, "\n");
02705 }
02706
02707 _heur_mgr.Initialize (_target_bb,&_cflow_mgr);
02708 _heur_mgr.
02709 Adjust_Heur_Stuff_When_BB_Changed (_target_bb,_src_bb_mgr);
02710
02711
02712
02713 if (_prepass) {
02714 Identify_Cannot_Spec_OPs (_target_bb);
02715 Preprocess_GP_def_op () ;
02716 }
02717
02718
02719
02720 Find_All_Candidates ();
02721
02722
02723 Init_Sched_Status () ;
02724
02725
02726 BOOL last_op_sched = FALSE ;
02727
02728 CAND_LIST *m_ready_cand = _cand_mgr.M_Ready_Cand_List ();
02729 CAND_LIST *p_ready_cand = _cand_mgr.P_Ready_Cand_List ();
02730
02731 while (1) {
02732 while (!m_ready_cand->Cand_Lst_Is_Empty ()) {
02733
02734 if (CGGRP_Cycle_Full() ||
02735 m_ready_cand->All_Cands_Have_Been_Tried ()) {
02736 Cycle_Advance();
02737 }
02738
02739 E_Time_Constraint etime_constraint;
02740
02741 etime_constraint.threshold = _cur_cyc;
02742 etime_constraint.constraint = _ops_in_cur_cyc.empty() ?
02743 AS_EARLY_AS_POSSIBLE :
02744 NO_LATER;
02745 CANDIDATE* cand = _heur_mgr.Select_Best_Candidate (
02746 *m_ready_cand,
02747 *p_ready_cand,
02748 _target_bb,
02749 &etime_constraint);
02750
02751 if (!cand) continue ;
02752
02753 if (!CGGRP_Issue_OP(cand->Op())) {
02754
02755
02756 _cand_mgr.Get_Cand_List(cand)->Set_Cand_Has_Been_Tried (cand);
02757
02758 if (_heur_mgr.Trace_Cand_Sel_Enabled ()) {
02759 _heur_mgr.Trace_Cand_Sel_Process (
02760 "\tDiscard best candidate due to structual hazard\n");
02761 }
02762 continue;
02763 }
02764
02765 #ifdef Is_True_On
02766
02767 if (!_ops_in_cur_cyc.empty ()) {
02768 Is_True (_cur_cyc == etime_constraint.threshold ,
02769 ("best candidate [OP%3d][BB%3d] should be issued exactly"
02770 " at cycle %d",
02771 OP_map_idx(cand->Op()),
02772 BB_id(OP_bb(cand->Op())),
02773 _cur_cyc));
02774 } else {
02775 Is_True (_cur_cyc <= etime_constraint.threshold,
02776 ("best candidate [OP%3d][BB%3d] should be issued"
02777 " before cycle %d",
02778 OP_map_idx(cand->Op()),
02779 BB_id(OP_bb(cand->Op())),
02780 _cur_cyc));
02781 }
02782 #endif
02783
02784 _cur_cyc = etime_constraint.threshold ;
02785
02786 Commit_Schedule(*cand);
02787 last_op_sched |= OP_Scheduled (BB_last_op(_target_bb)) ;
02788 }
02789
02790 if (last_op_sched) break ;
02791 Cycle_Advance () ;
02792 }
02793
02794
02795
02796 BB_cycle(_target_bb) = BB_length(_target_bb) ? _cur_cyc + 1 : 0;
02797
02798
02799
02800 if (BB_length(_target_bb)) CGGRP_End_BB();
02801
02802 Verify();
02803
02804 if (_prepass) Postprocess_GP_def_op ();
02805
02806 CG_DEP_Delete_Graph (_target_bb) ;
02807 }
02808
02809
02810
02811
02812
02813
02814
02815
02816
02817
02818 void
02819 SCHEDULER::Renaming (CANDIDATE* cand)
02820 {
02821 OP* op = cand->Op();
02822 BB* home_bb = OP_bb(op);
02823 OP* copy_op = NULL;
02824 TN *orig_tn = OP_result(op, 0);
02825 TN* new_tn = Dup_TN(orig_tn);
02826
02827 FmtAssert(OP_results(op) == 1,
02828 ("We don't do renaming for a multi-assignment OP: [OP:%3d][BB:%3d]\n",
02829 OP_map_idx(op), BB_id(OP_bb(op))));
02830
02831
02832
02833 for (OP* tmp_op = OP_next(op); tmp_op; tmp_op = OP_next(tmp_op)) {
02834 for (INT i = 0; i < OP_opnds(tmp_op); i++) {
02835 if (orig_tn == OP_opnd(tmp_op, i))
02836 Set_OP_opnd(tmp_op, i, new_tn);
02837 }
02838 for (INT i = 0; i < OP_results(tmp_op); i++) {
02839 if (orig_tn == OP_result(tmp_op, i))
02840 Set_OP_result(tmp_op, i, new_tn);
02841 }
02842 }
02843
02844
02845
02846 if (_dflow_mgr.Are_Defs_Live_Out(op, home_bb)) {
02847 copy_op = Mk_OP(CGTARG_Copy_Op(TN_size(orig_tn), TN_is_float(orig_tn)),
02848 orig_tn, OP_opnd(op, OP_PREDICATE_OPND), new_tn);
02849 BB_Insert_Op_After(home_bb, op, copy_op);
02850 }
02851
02852
02853
02854 Maintain_Dep_Arcs_After_Renaming(op, copy_op);
02855
02856
02857
02858 if(copy_op) {
02859 SCHED_BB_ANNOT* bb_annot = sched_annot.Get_BB_Annot (home_bb);
02860 bb_annot->Init_New_OP_Annot (copy_op);
02861 _heur_mgr.Compute_Heur_Data_For_Inserted_OP (copy_op);
02862 Set_OP_renamed(copy_op);
02863 }
02864
02865
02866
02867 Set_OP_result(op, 0, new_tn);
02868 Set_OP_renamed(op);
02869
02870 }
02871
02872
02873
02874
02875
02876
02877
02878
02879
02880
02881 void
02882 SCHEDULER::Maintain_Dep_Arcs_After_Renaming (OP* renamed_op, OP* copy_op)
02883 {
02884 for (ARC_LIST* arcs = OP_succs(renamed_op); arcs; ) {
02885 ARC *arc = ARC_LIST_first(arcs);
02886 arcs = ARC_LIST_rest(arcs);
02887 OP* succ = ARC_succ (arc);
02888 switch (ARC_kind(arc)) {
02889 case CG_DEP_REGOUT:
02890 if (copy_op) {
02891 if (OP_bb(renamed_op) != OP_bb(succ)) {
02892 new_arc_with_latency(ARC_kind(arc), copy_op, succ, ARC_latency(arc),
02893 ARC_omega(arc), ARC_opnd(arc), ARC_is_definite(arc));
02894 CG_DEP_Detach_Arc(arc);
02895 } else {
02896 new_arc(CG_DEP_REGIN, succ, copy_op, 0, 0, TRUE);
02897 }
02898 }
02899 break;
02900 case CG_DEP_REGIN:
02901 if (copy_op && OP_bb(renamed_op) != OP_bb(succ)) {
02902 new_arc_with_latency(CG_DEP_REGIN, copy_op, succ, ARC_latency(arc),
02903 ARC_omega(arc), ARC_opnd(arc), ARC_is_definite(arc));
02904 CG_DEP_Detach_Arc(arc);
02905 }
02906 break;
02907 case CG_DEP_PREBR:
02908 case CG_DEP_POSTBR:
02909 case CG_DEP_PRECHK:
02910 case CG_DEP_POSTCHK:
02911 case CG_DEP_SCC:
02912 case CG_DEP_MISC:
02913 if (copy_op) {
02914 new_arc_with_latency(ARC_kind(arc), copy_op, succ, ARC_latency(arc),
02915 ARC_omega(arc), ARC_opnd(arc), ARC_is_definite(arc));
02916 }
02917 break;
02918 default:
02919 break;
02920 }
02921 }
02922
02923 for (ARC_LIST* arcs = OP_preds(renamed_op); arcs; ) {
02924 ARC *arc = ARC_LIST_first(arcs);
02925 arcs = ARC_LIST_rest(arcs);
02926 OP* pred = ARC_pred (arc);
02927 switch (ARC_kind(arc)) {
02928 case CG_DEP_REGOUT:
02929 if (copy_op) {
02930 new_arc_with_latency(ARC_kind(arc), pred, copy_op, ARC_latency(arc),
02931 ARC_omega(arc), ARC_opnd(arc), ARC_is_definite(arc));
02932 CG_DEP_Detach_Arc(arc);
02933 }
02934 break;
02935 default:
02936 break;
02937 }
02938 }
02939
02940 if (copy_op) {
02941 new_arc(CG_DEP_REGIN, renamed_op, copy_op, 0, 0, TRUE);
02942 }
02943 }
02944
02945
02946
02947
02948
02949
02950
02951
02952 SCHEDULER::SCHEDULER (BB* bb, BOOL prepass,PRDB_GEN *prdb) :
02953 _dag_constructor (bb,prdb),
02954 _cand_mgr(&_mem_pool),
02955 _heur_mgr(&_mem_pool),
02956 _src_bb_mgr(&_mem_pool),
02957 _ops_in_cur_cyc(OP_ALLOC(&_mem_pool)),
02958 _multiway_br_span_bbs(&_mem_pool),
02959 _global(FALSE), _prepass(prepass),
02960 _dsrmgr(&_mem_pool)
02961 {
02962
02963 _region = NULL;
02964 _target_bb = bb,
02965
02966 Get_Sched_Opts (prepass);
02967 Clean_Up(bb);
02968
02969
02970
02971 _multiway_br_candidates = NULL;
02972
02973 _cflow_mgr.Init (_target_bb);
02974 sched_annot.Init (_target_bb);
02975 _dsrmgr.Init (_target_bb);
02976 }
02977
02978 SCHEDULER::SCHEDULER (struct tagRGN_INFO * rgn_info, BOOL prepass, PRDB_GEN * prdb) :
02979 _dag_constructor (rgn_info->rgn, prdb,
02980 INCLUDE_ASSIGNED_REG_DEPS,
02981 INCLUDE_MEMREAD_ARCS,
02982 NO_MEMIN_ARCS,
02983 INCLUDE_CONTROL_ARCS),
02984 _cand_mgr(&_mem_pool),
02985 _src_bb_mgr(&_mem_pool),
02986 _ops_in_cur_cyc(OP_ALLOC(&_mem_pool)),
02987 _heur_mgr(&_mem_pool),
02988 _multiway_br_span_bbs(&_mem_pool),
02989 _global (TRUE), _prepass(TRUE),
02990 _dsrmgr(&_mem_pool)
02991 {
02992
02993 _region = rgn_info->rgn ;
02994
02995 _target_bb = NULL ;
02996
02997 Get_Sched_Opts (prepass);
02998 _cflow_mgr.Init (_region) ;
02999 sched_annot.Init (_region);
03000 _dsrmgr.Init (_region);
03001
03002 for (TOPOLOGICAL_REGIONAL_CFG_ITER cfg_iter(_region->Regional_Cfg());
03003 cfg_iter != 0; ++cfg_iter) {
03004
03005 if ((*cfg_iter)->Is_Region()) {
03006 continue;
03007 } else {
03008 Clean_Up((*cfg_iter)->BB_Node());
03009 }
03010 }
03011
03012
03013
03014 _multiway_br_candidates = BB_SET_Create_Empty (PU_BB_Count, &_mem_pool);
03015 }
03016
03017 SCHEDULER::~SCHEDULER () {
03018 _heur_mgr.Finialize ();
03019 }
03020
03021
03022
03023
03024
03025
03026
03027
03028
03029
03030
03031 void
03032 Clean_Up (BB* bb) {
03033
03034 OP *op, *next_op;
03035
03036 Reset_BB_scheduled (bb);
03037
03038 for (op = BB_first_op(bb); op; op = next_op) {
03039
03040 next_op = OP_next(op);
03041
03042 if (OP_noop(op)) {
03043 BB_Remove_Op(bb, op);
03044 } else {
03045
03046 Reset_OP_Scheduled (op);
03047 Reset_OP_start_bundle(op);
03048 Reset_OP_end_group(op);
03049 Reset_OP_bundled(op);
03050 Reset_OP_m_unit(op);
03051 }
03052 }
03053 }
03054
03055
03056
03057
03058
03059
03060
03061
03062
03063
03064
03065
03066
03067
03068
03069
03070
03071
03072
03073
03074
03075
03076
03077
03078
03079
03080
03081
03082 void
03083 Global_Insn_Sched_Preproc (
03084 REGION_TREE * rgn_tree,
03085 INT& how_many_rgn_need_sched) {
03086
03087 how_many_rgn_need_sched = 0 ;
03088
03089 Init_Split_PU_Entry_Or_Exit_BB ();
03090
03091 Acquire_Region_Info (rgn_tree);
03092
03093 for (INNERMOST_REGION_FIRST_ITER iter(rgn_tree);
03094 iter != 0 ; ++iter) {
03095
03096 RGN_INFO* rgn_info = Get_Region_Info (*iter);
03097
03098 #ifdef Is_True_On
03099 if (rgn_info->skip_reason == SKIP_RGN_DEBUG) {
03100 DevWarn ("Skip schedule RGN:%d of PU:%d",
03101 rgn_info->rgn->Id (), Current_PU_Count ());
03102 }
03103 #endif
03104
03105 if (rgn_info->skip_reason != SKIP_RGN_NONE) { continue ; }
03106
03107
03108
03109 rgn_info->rgn->Edge_Splitting () ;
03110
03111 if (RGN_CFLOW_MGR::Critical_Edge_Present(rgn_info->rgn)) {
03112
03113
03114
03115
03116
03117
03118 rgn_info->skip_reason = SKIP_RGN_CRITICAL_EDGE;
03119 continue ;
03120 }
03121
03122 ++ how_many_rgn_need_sched ;
03123
03124
03125
03126 if (IPFEC_Glos_Split_Entry_BB) {
03127 Split_PU_Entry_BB (rgn_info->rgn);
03128 }
03129
03130
03131
03132 if (IPFEC_Glos_Split_Exit_BB) {
03133 Split_PU_Exit_BB (rgn_info->rgn);
03134 }
03135 }
03136
03137
03138 GRA_LIVE_Init (NULL);
03139 }
03140
03141 void
03142 Global_Insn_Sched_Postproc (void) {
03143
03144
03145
03146 Merge_All_Splitted_Entry_and_Exit_BB ();
03147
03148
03149
03150
03151 GRA_LIVE_Init (NULL);
03152
03153 Free_Region_Info_Memory () ;
03154 }
03155
03156
03157
03158
03159
03160
03161
03162
03163
03164
03165
03166
03167
03168
03169
03170
03171
03172
03173
03174
03175
03176
03177
03178
03179
03180
03181
03182
03183 extern void SCHED_Dump_IR (BOOL prepass,
03184 BOOL bef_sched,
03185 BOOL gcm,FILE *f=stderr) ;
03186
03187 void
03188 Global_Insn_Sched (REGION_TREE* rgn_tree, BOOL prepass) {
03189
03190 Set_Error_Phase (_Cur_Phase_Name = _Global_Insn_Sched_Phase_Name);
03191
03192 Start_Timer (T_Ipfec_GLOS_CU);
03193 Get_Sched_Opts (prepass);
03194
03195 if (SCHED_TF_DRAW_GLBL_CFG) { draw_global_cfg(); }
03196 if (SCHED_TF_DUMP_IR) SCHED_Dump_IR (prepass,
03197 TRUE,
03198 TRUE,
03199 TFile) ;
03200
03201
03202 IPFEC_Glos_Code_Motion_Across_Nested_Rgn = TRUE;
03203
03204
03205
03206 INT32 sched_rgn_num = 0 ;
03207 Global_Insn_Sched_Preproc (rgn_tree, sched_rgn_num);
03208
03209 if (sched_rgn_num) {
03210
03211 PRDB_GEN * prdb = NULL ;
03212 if (IPFEC_Enable_PRDB) {
03213 prdb = PRDB_Init(rgn_tree);
03214 }
03215
03216 Calculate_Dominator_Info (rgn_tree);
03217
03218 for (INNERMOST_REGION_FIRST_ITER iter(rgn_tree) ;
03219 iter != 0; ++iter) {
03220
03221 RGN_INFO * rgn_info = Get_Region_Info (*iter);
03222
03223 if (rgn_info->Skip_Sched_Reason () == SKIP_RGN_NONE) {
03224
03225 if (rgn_info->In_Abnormal_Loop ()) {
03226 Workaround_Dom_Info_For_In_Abnormal_Loop_Rgn
03227 (rgn_info->Region ()) ;
03228 }
03229
03230 SCHEDULER scheduler (rgn_info, TRUE, prdb);
03231 scheduler.Schedule_Region ();
03232
03233 } else if (rgn_info->Skip_Sched_Reason () ==
03234 SKIP_RGN_NO_FURTHER_OPT &&
03235 IPFEC_Glos_Code_Motion_Across_Nested_Rgn) {
03236
03237
03238
03239
03240 if (rgn_info->Region ()->Entries ().size () == 1) {
03241 RGN_CFLOW_MGR rgn_cflow_mgr ;
03242 rgn_cflow_mgr.Init (rgn_info->Region ());
03243
03244 ::Build_Region_Summary (rgn_info->Region (),
03245 &rgn_cflow_mgr) ;
03246 }
03247 }
03248 }
03249
03250 if (prdb) { Delete_PRDB () ; prdb = NULL ; } ;
03251
03252 Free_Dominator_Info_Memory () ;
03253 }
03254
03255 Global_Insn_Sched_Postproc ();
03256
03257 if (SCHED_TF_DUMP_IR) SCHED_Dump_IR (prepass,
03258 FALSE,
03259 TRUE,
03260 TFile) ;
03261
03262
03263 for (BB *bp = REGION_First_BB; bp; bp = BB_next(bp)) {
03264 BB_Update_OP_Order(bp);
03265 }
03266 Stop_Timer(T_Ipfec_GLOS_CU);
03267 }
03268
03269
03270
03271
03272
03273
03274
03275
03276
03277
03278
03279
03280
03281 void
03282 Local_Insn_Sched (BOOL prepass) {
03283
03284 Set_Error_Phase (_Cur_Phase_Name = _Local_Insn_Sched_Phase_Name);
03285 Start_Timer(T_Ipfec_LOCS_CU);
03286
03287 Get_Sched_Opts (prepass);
03288 if (SCHED_TF_DUMP_IR) SCHED_Dump_IR (prepass,
03289 TRUE,
03290 FALSE,
03291 TFile) ;
03292
03293
03294 for (BB* bb = REGION_First_BB; bb != NULL; bb = BB_next(bb)) {
03295
03296 if (BB_length(bb) == 0) { continue; }
03297
03298
03299
03300
03301 if (prepass) {
03302 if (!BB_scheduled(bb) && !BB_reg_alloc(bb)) {
03303 SCHEDULER local_scheduler(bb, prepass);
03304 local_scheduler.Schedule_BB();
03305 }
03306 } else {
03307
03308
03309
03310 if (BB_chk_split_head(bb)){
03311 bb = Handle_Chk_Split_Bunch(bb);
03312 continue;
03313 }
03314
03315 if (!BB_scheduled(bb) || BB_scheduled_hbs(bb) || BB_entry(bb) ||
03316 BB_exit(bb)){
03317
03318 if (IPFEC_Query_Skiplist(locs_skip_bb,
03319 BB_id(bb),
03320 Current_PU_Count ())) {
03321
03322 DevWarn ("Skip local schedule BB:%d of PU:%d",
03323 BB_id(bb),
03324 Current_PU_Count ());
03325
03326 Clean_Up(bb);
03327 Handle_All_Hazards (bb);
03328
03329 } else {
03330 SCHEDULER local_scheduler(bb, prepass);
03331 local_scheduler.Schedule_BB();
03332 }
03333 }
03334 }
03335 Set_BB_scheduled(bb);
03336 }
03337
03338 if (SCHED_TF_DUMP_IR) SCHED_Dump_IR (prepass,
03339 FALSE,
03340 FALSE,
03341 TFile) ;
03342
03343 for (BB *bp = REGION_First_BB; bp; bp = BB_next(bp)) {
03344 BB_Update_OP_Order(bp);
03345 }
03346
03347 Stop_Timer(T_Ipfec_LOCS_CU);
03348 }
03349
03350