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 #ifdef TARG_IA64
00066 #include "speculation.h"
00067 #include "prdb_util.h"
00068 #include "pqs_cg.h"
00069 #endif
00070 #include "sched_spec_itf.h"
00071
00072 #include "sched_util.h"
00073 #include "sched_cflow.h"
00074 #include "sched_dflow.h"
00075 #include "sched_cand.h"
00076 #include "sched_rgn_info.h"
00077 #include "sched_seq.h"
00078 #include "sched_spec_itf.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
00095 #include <stdarg.h>
00096 #include <tlog.h>
00097 #include "whirl2ops.h"
00098
00099 #if defined(TARG_SL)
00100 #include "tag.h"
00101 #include "hb_sched.h"
00102 #endif
00103
00104 static char* _Global_Insn_Sched_Phase_Name = "ORC:Global code motion" ;
00105 static char* _Local_Insn_Sched_Phase_Name = "ORC:Local code motion" ;
00106 static char* _Cur_Phase_Name = NULL ;
00107 static int _Local_Insn_Op_id = 0;
00108
00109 #ifndef TARG_SL
00110 void
00111 Clean_Up (BB* bb) {
00112 OP *op, *next_op;
00113
00114 Reset_BB_scheduled (bb);
00115 for (op = BB_first_op(bb); op; op = next_op) {
00116
00117 next_op = OP_next(op);
00118
00119 if (OP_noop(op)) {
00120 BB_Remove_Op(bb, op);
00121 } else {
00122 Reset_OP_Scheduled (op);
00123 #ifdef TARG_IA64
00124 Reset_OP_start_bundle(op);
00125 Reset_OP_end_group(op);
00126 Reset_OP_bundled(op);
00127 Reset_OP_m_unit(op);
00128 #endif
00129 }
00130 }
00131 }
00132 #endif
00133
00134
00135
00136
00137
00138
00139
00140
00141
00142
00143
00144
00145
00146
00147
00148
00149
00150
00151
00152 void
00153 SCHEDULER::Cycle_Advance (void) {
00154
00155 _cand_mgr.M_Ready_Cand_List ()->Clear_All_Cands_Tried_Mark ();
00156 _cand_mgr.P_Ready_Cand_List ()->Clear_All_Cands_Tried_Mark ();
00157
00158
00159
00160 CGGRP_Cycle_Advance();
00161
00162
00163
00164 Update_Cand_Lst_After_Cycle_Advancing ();
00165 _heur_mgr.Adjust_Heur_After_Sched_One_Cyc
00166 (_ops_in_cur_cyc,_cur_cyc);
00167
00168
00169 if (SCHED_TF_SUMMARY_DUMP) {
00170 fprintf(TFile, "\n Cycle: %d\n", _cur_cyc);
00171 }
00172
00173
00174
00175 _ops_in_cur_cyc.clear ();
00176
00177
00178
00179 ++_cur_cyc ;
00180 }
00181
00182
00183
00184
00185
00186
00187
00188
00189
00190
00191 BOOL
00192 SCHEDULER::OP_Cannot_be_Candidate_Since_Obvious_Reason (OP* op) {
00193
00194 if (OP_Scheduled(op)) return TRUE;
00195
00196 if (_prepass&&
00197 (OP_glue(op) || OP_no_move_before_gra(op) ||
00198 OP_chk(op) ||
00199 OP_access_reg_bank (op)) &&
00200 OP_bb(op) != _target_bb) {
00201
00202 return TRUE;
00203 }
00204
00205 if (OP_bb (op) != _target_bb) {
00206 if (OP_Cannot_Be_Moved_Outof_HomeBB (op) ||
00207 !BB1_Dominate_BB2 (_target_bb, OP_bb(op)) &&
00208 !CGTARG_Can_Be_Speculative (op)) {
00209 return TRUE;
00210 }
00211 }
00212
00213 return _cand_mgr.OP_Is_In_Cand_List (op);
00214 }
00215
00216
00217
00218
00219
00220
00221
00222
00223
00224 BOOL
00225 SCHEDULER::Succ_Pred_Transposed_If_Sched
00226 (ARC* arc, BB_VECTOR* cutting_set) {
00227
00228 OP* pred = ARC_pred(arc);
00229 BB* pred_home = OP_bb(pred);
00230
00231 if (OP_Scheduled(pred)) {
00232 if (pred_home != _target_bb || !OP_xfer(pred)) {
00233 return FALSE;
00234 } else {
00235 return TRUE;
00236 }
00237 }
00238
00239 BB_POS pos = BB_Pos_Analysis (pred_home, cutting_set, &_cflow_mgr);
00240
00241 BOOL transposed = FALSE;
00242 switch (pos) {
00243 case ABOVE_SISS:
00244 break;
00245
00246 case IN_SISS:
00247 transposed = (pred_home == _target_bb || OP_xfer(pred));
00248 break;
00249
00250 case BELOW_SISS:
00251 transposed = TRUE ;
00252 break ;
00253
00254 default :
00255 Is_True (FALSE, ("fail to analysis src position for BB:%d!",
00256 BB_id(OP_bb(pred))));
00257 }
00258
00259 return transposed;
00260 }
00261
00262
00263
00264
00265
00266
00267
00268
00269
00270
00271
00272
00273
00274
00275
00276
00277
00278
00279
00280
00281
00282
00283
00284
00285
00286
00287
00288
00289
00290
00291
00292
00293
00294
00295
00296
00297
00298
00299
00300
00301
00302 BOOL
00303 SCHEDULER::Collect_And_Analyse_Unresolved_Dep
00304 (CANDIDATE* cand, SRC_BB_INFO* bb_info) {
00305
00306
00307
00308 BOOL donate_p_ready = bb_info->Can_Donate_P_Ready_Cand ();
00309 OP* cand_op = cand->Op ();
00310 BB* home_bb = OP_bb(cand->Op ());
00311
00312 cand->Free_Bookeeping_Lst ();
00313 cand->Move_Across_Rgns()->clear ();
00314 BB_VECTOR* cs_between_targ_src = NULL;
00315 EXEC_PATH_SET move_around_paths(&_mem_pool);
00316
00317 if (donate_p_ready) {
00318 cand->Move_Against_Path_Set ()->Clear ();
00319 cs_between_targ_src = bb_info->Get_P_Ready_Bookeeping_Blks ();
00320 move_around_paths.Resize
00321 (_cflow_mgr.Get_Exec_Path_Mgr()->Path_In_Total ());
00322 }
00323
00324
00325
00326
00327
00328
00329
00330 for (ARC_LIST* arcs = OP_preds(cand_op);
00331 arcs != NULL;
00332 arcs = ARC_LIST_rest(arcs)) {
00333
00334 ARC* arc = ARC_LIST_first(arcs) ;
00335 OP* pred = ARC_pred(arc) ;
00336
00337 if (!_prepass && !_global) {
00338
00339
00340
00341
00342
00343
00344 if (OP_Scheduled(pred)) {
00345 continue;
00346 } else {
00347 return FALSE;
00348 }
00349 }
00350
00351 if (!Succ_Pred_Transposed_If_Sched
00352 (arc, bb_info->Get_Cutting_Set ())) {
00353
00354
00355
00356 continue;
00357 }
00358
00359
00360 SPEC_TYPE spec_tmp = Derive_Spec_Type_If_Violate_Dep (arc);
00361 if (spec_tmp == SPEC_NONE) {
00362
00363
00364 continue;
00365 }
00366
00367
00368
00369
00370
00371
00372
00373 if (spec_tmp == SPEC_DATA || spec_tmp == SPEC_CNTL ||
00374 spec_tmp == SPEC_COMB) {
00375
00376 cand->Add_Spec (spec_tmp);
00377
00378
00379
00380 UNRESOLVED_DEP* t = _cand_mgr.New_Unresolved_Dep ();
00381 t->Set_Arc (arc);
00382 t->Set_Spec_Type (spec_tmp);
00383 cand->Unresolved_Dep_List ()->Prepend (t);
00384
00385 continue;
00386 }
00387
00388
00389
00390 BB* pred_bb = OP_bb(pred);
00391 if (spec_tmp == SPEC_DISABLED) {
00392 if (!donate_p_ready || pred_bb == _target_bb) {
00393
00394
00395
00396 return FALSE;
00397 }
00398
00399 BB_POS pos = BB_Pos_Analysis (pred_bb,
00400 cs_between_targ_src,
00401 &_cflow_mgr);
00402
00403 if (pos == BELOW_SISS) { return FALSE ; }
00404
00405 if (pos == IN_SISS || pos == ABOVE_SISS) {
00406
00407 cand->Set_P_ready ();
00408
00409 for (BB_VECTOR_ITER iter = cs_between_targ_src->begin();
00410 iter != cs_between_targ_src->end (); iter++) {
00411
00412 BB* bk_blk = *iter;
00413
00414 if (!(cand->Bookeeping_Lst ()->Retrieve (bk_blk)) &&
00415 (bk_blk == pred_bb ||
00416 _cflow_mgr.BB1_Reachable_From_BB2 (bk_blk,pred_bb))) {
00417
00418 EXEC_PATH_SET* eps_tmp =
00419 _cflow_mgr.Get_Path_Flow_Thru (bk_blk);
00420
00421 BOOKEEPING* bk = _cand_mgr.New_Empty_Bookeeping ();
00422 bk -> Set_Placement (bk_blk);
00423 bk -> Set_P_Ready_Bookeeping ();
00424 cand->Bookeeping_Lst () -> Prepend (bk);
00425
00426 move_around_paths += *eps_tmp;
00427 }
00428 }
00429
00430 } else {
00431 FmtAssert (FALSE, ("Unknown BB_POS(%d)", pos));
00432 return FALSE;
00433 }
00434
00435 }
00436
00437 }
00438
00439
00440 if (!_global) { return TRUE; }
00441
00442 if (cand->Is_P_Ready ()) {
00443
00444
00445
00446 EXEC_PATH_SET* eps = cand->Move_Against_Path_Set();
00447 *eps = *_cflow_mgr.Get_Path_Flow_Thru (OP_bb(cand->Op()));
00448 *eps -= move_around_paths;
00449 if (eps->Is_Empty ()) {
00450
00451
00452
00453 return FALSE;
00454 }
00455
00456 eps = cand->P_Ready_Bookeeping_Path_Set ();
00457 *eps = move_around_paths;
00458
00459
00460
00461
00462
00463
00464
00465
00466
00467
00468
00469 UNRESOLVED_DEP* dep, *next_dep;
00470 UNRESOLVED_DEP_LST* deplst = cand->Unresolved_Dep_List ();
00471
00472 for (dep = deplst->First_Item (); dep; dep = next_dep) {
00473
00474 next_dep = deplst->Next_Item(dep);
00475 if (cand->Shadowed_By_P_Ready_Bookeeping
00476 (OP_bb(dep->Pred()), &_cflow_mgr)) {
00477 deplst->Delete_Item (dep);
00478 }
00479
00480 }
00481 }
00482
00483
00484
00485 Determine_Non_P_Ready_Bookeeping_Places (cand, bb_info);
00486
00487 cand->Calc_Useful_Exec_Prob (_target_bb,&_cflow_mgr);
00488
00489
00490
00491
00492
00493
00494 if (cand->Is_P_Ready ()) {
00495
00496
00497 cand->Add_Spec (SPEC_CNTL);
00498
00499
00500
00501
00502
00503
00504 if (cand->Useful_Exec_Prob () <
00505 DONATE_P_READY_CAND_BB_REACH_PROB) {
00506 return FALSE;
00507 }
00508 } else if (!(cand->Spec_Type () & SPEC_CNTL)) {
00509
00510 BOOKEEPING_LST* bkl = cand->Bookeeping_Lst ();
00511
00512 for (BOOKEEPING* bk = bkl->First_Item ();
00513 bk != NULL;
00514 bk = bkl->Next_Item (bk)) {
00515
00516 if (!BB1_Postdominate_BB2 (home_bb, bk->Get_Placement ())) {
00517 cand->Add_Spec (SPEC_CNTL);
00518 break;
00519 }
00520 }
00521 }
00522
00523 return TRUE;
00524 }
00525
00526
00527
00528
00529
00530
00531
00532
00533
00534
00535
00536
00537
00538
00539
00540
00541 void
00542 SCHEDULER::Determine_Non_P_Ready_Bookeeping_Places
00543 (CANDIDATE* cand, SRC_BB_INFO* bb_info) {
00544
00545 BB_VECTOR* cs = bb_info->Get_Cutting_Set ();
00546 BB* home_bb = OP_bb(cand->Op ());
00547
00548 if (!cand->Is_P_Ready ()) {
00549
00550 for (BB_VECTOR_ITER iter = cs->begin ();
00551 iter != cs->end (); iter ++) {
00552
00553 BB* bk_blk = *iter;
00554 if (bk_blk == _target_bb) { continue; }
00555
00556 BOOKEEPING* bk = _cand_mgr.New_Empty_Bookeeping ();
00557 bk->Set_Placement (bk_blk);
00558 bk->Set_Dup_Bookeeping ();
00559
00560 cand->Bookeeping_Lst () -> Append (bk);
00561 }
00562
00563 return;
00564 }
00565
00566 for (BB_VECTOR_ITER iter = cs->begin ();
00567 iter != cs->end (); iter++) {
00568
00569 BB* b = *iter;
00570 if (b == _target_bb) { continue; }
00571
00572 if (!cand->Shadowed_By_P_Ready_Bookeeping (b,&_cflow_mgr)) {
00573
00574 BOOKEEPING* bk = _cand_mgr.New_Empty_Bookeeping ();
00575 bk->Set_Placement (b);
00576 bk->Set_Dup_Bookeeping ();
00577
00578 cand->Bookeeping_Lst () -> Append (bk);
00579 }
00580 }
00581 }
00582
00583
00584
00585
00586
00587
00588
00589
00590
00591 BOOL
00592 SCHEDULER::Collect_And_Analyse_Other_Than_Dep_Constraints
00593 (CANDIDATE* cand, SRC_BB_INFO* bb_info) {
00594
00595 if (!_global && !_prepass) {
00596
00597
00598
00599
00600
00601
00602 return TRUE;
00603 }
00604
00605 OP* op = cand->Op ();
00606
00607
00608
00609
00610
00611
00612
00613 SPEC_TYPE spec_type = cand->Spec_Type ();
00614 if ((spec_type & SPEC_DATA) && OP_ANNOT_Cannot_Data_Spec (op) ||
00615 (spec_type & SPEC_CNTL) && OP_ANNOT_Cannot_Cntl_Spec (op)) {
00616 return FALSE;
00617 }
00618
00619 if (SCHED_SPEC_HANDSHAKE::OP_Can_not_be_Candidate (op, spec_type)) {
00620
00621
00622 return FALSE;
00623 }
00624
00625 if (OP_bb(op) == _target_bb) {
00626 return TRUE;
00627 }
00628
00629
00630
00631 if (_dflow_mgr.Upward_Sched_Kill_LiveOut_Defs
00632 (cand, bb_info, &_cflow_mgr)) {
00633
00634
00635
00636 if (OP_results(op) != 1) {
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 #if defined(TARG_SL)
00713
00714
00715 if( cand && ((cand->Spec_Type()!=SPEC_NONE) || cand->Is_P_Ready())) {
00716 _cand_mgr.Erase_Cand (cand);
00717 return FALSE;
00718 }
00719 #endif
00720
00721
00722
00723 CAND_LIST* cand_lst = cand->Is_M_Ready () ?
00724 _cand_mgr.M_Ready_Cand_List () :
00725 _cand_mgr.P_Ready_Cand_List () ;
00726
00727 cand_lst->Add_Candidate (cand);
00728
00729 return TRUE;
00730
00731 }
00732
00733
00734
00735
00736
00737
00738
00739
00740 void
00741 SCHEDULER::Find_All_Candidates (void) {
00742
00743 _cand_mgr.M_Ready_Cand_List ()-> Erase_All_Cand ();
00744 _cand_mgr.P_Ready_Cand_List ()-> Erase_All_Cand ();
00745
00746 if (_global) {
00747 Determine_P_Ready_is_Profitable_or_not () ;
00748 } else {
00749 Disable_P_Pready_Cand () ;
00750 }
00751
00752 const BB_VECTOR* src_bbs = _src_bb_mgr.Src_BBs () ;
00753
00754 for (BB_VECTOR_CONST_ITER iter = src_bbs->begin();
00755 iter != src_bbs->end(); iter++) {
00756
00757 OP* op;
00758 BB* b = *iter;
00759 FOR_ALL_BB_OPs(b, op) {
00760 Try_Add_OP_to_Candidate_List (op);
00761 }
00762 }
00763
00764
00765
00766 Is_True (!_cand_mgr.M_Ready_Cand_List ()-> Cand_Lst_Is_Empty () ||
00767 !BB_length(_target_bb),
00768 ("Fail to find any candidate!"));
00769
00770 }
00771
00772
00773
00774
00775
00776
00777
00778
00779
00780
00781
00782
00783
00784
00785
00786
00787
00788
00789
00790
00791 void
00792 SCHEDULER::Update_Cand_Lst_During_Sched_Cyc (CANDIDATE& cand) {
00793
00794 OP* op = cand.Op ();
00795 OP* succ;
00796
00797 for (ARC_LIST* arcs = OP_succs(op);
00798 arcs != NULL; arcs = ARC_LIST_rest(arcs)) {
00799
00800 ARC *arc = ARC_LIST_first(arcs);
00801 OP *succ = ARC_succ(arc);
00802
00803 if (!_src_bb_mgr.Is_Src_BB (OP_bb(succ))) {
00804
00805
00806
00807
00808
00809 continue;
00810 }
00811
00812 INT32 latency = ARC_latency(arc) ;
00813
00814 if (latency > 0) {
00815
00816
00817
00818
00819
00820
00821
00822 continue ;
00823 } else if (latency < 0) {
00824
00825
00826
00827 FmtAssert (FALSE,
00828 ("Latency of dep between OP[%d](BB:%d) and OP[%d](BB:%d)"
00829 " should not be a negative %d\n",
00830 OP_map_idx(op), BB_id(OP_bb(op)),
00831 OP_map_idx(succ), BB_id(OP_bb(succ)),
00832 latency)) ;
00833
00834 }
00835
00836
00837
00838
00839
00840
00841 CAND_LIST* cand_lst = _cand_mgr.P_Ready_Cand_List ();
00842 if (cand_lst->Cand_In_Total ()) {
00843 cand_lst-> Erase_Cand (succ,FALSE);
00844 }
00845
00846 if (Try_Add_OP_to_Candidate_List (succ) &&
00847 SCHED_TF_SUMMARY_DUMP) {
00848
00849 fprintf (TFile, "%d ", OP_map_idx(succ));
00850 }
00851 }
00852
00853 _heur_mgr.Adjust_Heur_After_Cand_Sched (op, _cur_cyc);
00854 if (SCHED_TF_SUMMARY_DUMP) { fprintf(TFile, "\n"); }
00855
00856
00857
00858 if (!cand.Is_P_Ready ()) {
00859 _cand_mgr.M_Ready_Cand_List () -> Erase_Cand (&cand) ;
00860 } else {
00861 _cand_mgr.P_Ready_Cand_List () -> Erase_Cand (&cand) ;
00862 }
00863 }
00864
00865
00866
00867
00868
00869
00870
00871
00872
00873
00874 void
00875 SCHEDULER::Update_Cand_Lst_After_Cycle_Advancing (void) {
00876
00877 for (OP_Vector_Iter iter = _ops_in_cur_cyc.begin () ;
00878 iter != _ops_in_cur_cyc.end () ; iter ++) {
00879
00880 OP * op = *iter ;
00881
00882 for (ARC_LIST* arcs = OP_succs(op);
00883 arcs != NULL; arcs = ARC_LIST_rest(arcs)) {
00884
00885 ARC *arc = ARC_LIST_first(arcs);
00886 OP *succ = ARC_succ(arc);
00887
00888 INT32 latency = ARC_latency(arc) ;
00889
00890 if (!latency) continue ;
00891 if (!_src_bb_mgr.Is_Src_BB (OP_bb(succ))) continue;
00892
00893
00894 CAND_LIST* cand_lst = _cand_mgr.P_Ready_Cand_List ();
00895 if (cand_lst->Cand_In_Total ()) {
00896 cand_lst-> Erase_Cand (succ,FALSE);
00897 }
00898
00899 if (Try_Add_OP_to_Candidate_List(succ) &&
00900 SCHED_TF_SUMMARY_DUMP) {
00901 fprintf(TFile, "%d ", OP_map_idx(succ));
00902 }
00903 }
00904
00905 if (SCHED_TF_SUMMARY_DUMP) {
00906 fprintf(TFile, "\n");
00907 }
00908 }
00909 }
00910
00911
00912 inline BOOL
00913 SCHEDULER::OP_Cannot_Be_Moved_Outof_HomeBB (OP* op) {
00914 return OP_xfer (op) ||
00915 OP_call (op) ||
00916 OP_chk (op) ||
00917 OP_ANNOT_OP_Def_Actual_Para (op)
00918 ;
00919 }
00920
00921 SPEC_TYPE
00922 SCHEDULER::Get_OP_Prohibited_Spec_Type (OP *op) {
00923
00924
00925
00926
00927 if (OP_Is_Float_Mem(op) || OP_ANNOT_OP_Def_Actual_Para (op)) {
00928 return SPEC_COMB ;
00929 }
00930
00931
00932
00933
00934 if (!_prepass) { return SPEC_COMB ; }
00935
00936 TOP opcode = OP_code(op);
00937
00938 if (OP_xfer(op) || OP_like_store(op) ||
00939 TOP_is_ftrap(opcode)|| TOP_is_itrap(opcode) ||
00940 TOP_is_fdiv(opcode) || OP_idiv (op) ||
00941 OP_sqrt (op)) {
00942
00943
00944
00945 return SPEC_CNTL ;
00946 }
00947
00948 if (OP_volatile(op)) { return SPEC_COMB ; }
00949
00950
00951
00952
00953
00954
00955 if (OP_load (op)) {
00956
00957 for (INT i = OP_results(op) - 1 ; i >= 0 ; --i) {
00958
00959 TN * result_tn = OP_result (op,i) ;
00960 for (INT j = OP_opnds(op) - 1 ; j >= 0 ; --j) {
00961
00962 if (result_tn == OP_opnd(op,j)) {
00963 return SPEC_COMB ;
00964 }
00965 }
00966 }
00967 }
00968
00969 SPEC_TYPE spec_type = IPFEC_Enable_Speculation ? SPEC_NONE : SPEC_COMB ;
00970
00971 if (!IPFEC_Enable_Data_Speculation) {
00972 spec_type = SPEC_TYPE(spec_type | SPEC_DATA);
00973 }
00974
00975 if (!IPFEC_Enable_Cntl_Speculation) {
00976 spec_type = SPEC_TYPE(spec_type | SPEC_CNTL);
00977 }
00978
00979
00980 if (spec_type != SPEC_COMB && (
00981 IPFEC_Query_Skiplist (spec_skip_bb, (INT32)BB_id(OP_bb(op)),
00982 (INT32)Current_PU_Count()) ||
00983 IPFEC_Query_Skiplist (spec_skip_op, (INT32)OP_map_idx(op),
00984 (INT32)BB_id(OP_bb(op))))) {
00985 fprintf (stderr, "BB:%d OP:%d is skipped\n", BB_id(OP_bb(op)),
00986 OP_map_idx(op));
00987 spec_type = SPEC_COMB ;
00988 }
00989
00990 return spec_type ;
00991 }
00992
00993
00994
00995
00996
00997
00998
00999
01000
01001
01002
01003
01004
01005
01006 void
01007 SCHEDULER::Identify_Cannot_Spec_OPs (BB *bb) {
01008
01009 OP * op;
01010 FOR_ALL_BB_OPs(bb, op) {
01011
01012 SPEC_TYPE spec_type = Get_OP_Prohibited_Spec_Type (op);
01013
01014 if (spec_type == SPEC_NONE) continue ;
01015
01016 if (spec_type & SPEC_CNTL) {
01017 OP_ANNOT_Set_Cannot_Cntl_Spec (op) ;
01018 }
01019
01020 if (spec_type & SPEC_DATA) {
01021 OP_ANNOT_Set_Cannot_Data_Spec (op) ;
01022 }
01023 }
01024 }
01025
01026
01027
01028
01029
01030
01031
01032
01033
01034
01035 void
01036 SCHEDULER::Identify_Cannot_Spec_OPs (REGION *rgn) {
01037
01038 for (TOPOLOGICAL_REGIONAL_CFG_ITER
01039 iter (rgn->Regional_Cfg()) ; iter != 0 ; ++ iter) {
01040
01041 if ((*iter)->Is_Region()) continue ;
01042 Identify_Cannot_Spec_OPs ((*iter)->BB_Node());
01043 }
01044 }
01045
01046
01047 void
01048 SCHEDULER::Init_Sched_Status (void) {
01049
01050 _cur_cyc = (CYCLE)0 ;
01051
01052 _ops_in_cur_cyc.clear ();
01053 _frontier_op = BB_length(_target_bb) ?
01054 BB_first_op (_target_bb) : NULL;
01055
01056 _upward_motion_num = _downward_motion_num = 0;
01057 _sched_times = 0;
01058 }
01059
01060 void
01061 SCHEDULER::Adjust_Status_For_Resched (void) {
01062
01063 _cur_cyc = (CYCLE)0;
01064 _ops_in_cur_cyc.clear ();
01065
01066 _upward_motion_num = _downward_motion_num = 0;
01067 _sched_times ++;
01068
01069 Clean_Up (_target_bb);
01070 _frontier_op = BB_first_op(_target_bb);
01071
01072
01073
01074
01075 _heur_mgr.Adjust_Heur_Stuff_When_BB_Changed (_target_bb,_src_bb_mgr);
01076
01077
01078
01079 OP_Vector opv(&_mem_pool);
01080 for (CAND_LIST_ITER iter(_cand_mgr.M_Ready_Cand_List ());
01081 !iter.done();) {
01082
01083 opv.push_back (iter.cur()->Op ());
01084 iter.erase_cur_and_advance ();
01085
01086 }
01087
01088 if(_global) {
01089 for (CAND_LIST_ITER iter(_cand_mgr.P_Ready_Cand_List ());
01090 !iter.done();) {
01091
01092 opv.push_back (iter.cur()->Op ());
01093 iter.erase_cur_and_advance ();
01094
01095 }
01096 }
01097 OP* op;
01098 FOR_ALL_BB_OPs (_target_bb,op) {
01099 Try_Add_OP_to_Candidate_List (op);
01100 }
01101 if(_global)
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 #ifdef TARG_IA64
01109
01110 for (BB_VECTOR_ITER iter = _multiway_br_span_bbs.begin ();
01111 iter != _multiway_br_span_bbs.end ();
01112 iter ++) {
01113
01114 BB* b = *iter;
01115 _multiway_br_candidates = BB_SET_Difference1D
01116 (_multiway_br_candidates, b);
01117 }
01118 _multiway_br_span_bbs.clear ();
01119 #endif
01120 }
01121
01122
01123
01124
01125
01126
01127
01128
01129
01130
01131 #ifdef TARG_IA64
01132
01133
01134
01135
01136
01137
01138
01139
01140
01141
01142
01143
01144
01145
01146
01147
01148 OP*
01149 SCHEDULER::Insert_Check (OP * ld, BB * home_bb, OP* pos) {
01150
01151 Is_True (OP_load(ld), ("OP is not load!")) ;
01152 Is_True (!OP_Is_Float_Mem(ld),
01153 ("floating-point load shouldn't be spec now"));
01154
01155 vector<OP*> dup_ops;
01156 OP *chk_op = ::Insert_CHK (ld, dup_ops, home_bb, pos,
01157 OP_opnd(ld, OP_PREDICATE_OPND));
01158
01159
01160
01161
01162
01163 for (ARC_LIST * arcs = OP_succs(chk_op) ;
01164 arcs != NULL ; arcs = ARC_LIST_rest (arcs)) {
01165
01166 ARC* arc = ARC_LIST_first (arcs) ;
01167 OP* succ = ARC_succ (arc);
01168
01169 CAND_LIST * cand_list = NULL ;
01170 CANDIDATE * cand = NULL;
01171
01172 cand = _cand_mgr.Get_Candidate (succ);
01173 if (!cand) {
01174 continue;
01175 } else {
01176 cand_list = cand->Is_M_Ready () ?
01177 _cand_mgr.M_Ready_Cand_List ():
01178 _cand_mgr.P_Ready_Cand_List ();
01179
01180 }
01181
01182
01183
01184
01185 BB* b = OP_bb(ARC_pred(arc));
01186 if (!cand->Shadowed_By_P_Ready_Bookeeping (b,&_cflow_mgr)) {
01187
01188 if ((!ARC_is_dotted (arc) || OP_baneful(succ))) {
01189
01190
01191
01192
01193
01194
01195
01196 cand_list->Erase_Cand (cand);
01197
01198 } else {
01199
01200 if (OP_ANNOT_Cannot_Cntl_Spec (cand->Op())) {
01201 cand_list->Erase_Cand (cand);
01202 } else {
01203 cand->Add_Spec (SPEC_CNTL);
01204 }
01205 }
01206 }
01207
01208 }
01209
01210
01211
01212 SCHED_BB_ANNOT* bb_annot = sched_annot.Get_BB_Annot (home_bb);
01213 bb_annot->Init_New_OP_Annot (chk_op);
01214
01215
01216
01217 _heur_mgr.Compute_Heur_Data_For_Inserted_OP (chk_op);
01218
01219
01220
01221 OP_ANNOT_Set_Cannot_Spec (chk_op);
01222
01223 if (BB_call(OP_bb(chk_op))) {
01224
01225 for (OP * op = chk_op ; op ; op = OP_next(op)) {
01226 if (OP_ANNOT_OP_Def_Actual_Para (op)) {
01227 new_arc_with_latency(CG_DEP_POSTCHK, chk_op,
01228 op, 0, 0, 0, FALSE);
01229 }
01230 }
01231 }
01232
01233 return chk_op ;
01234 }
01235 #endif
01236
01237
01238
01239 #if defined(TARG_SL2)
01240
01241
01242
01243
01244
01245 static BOOL
01246 Can_OP_Move(OP *cur_op, OP* point, BOOL fwd = TRUE)
01247 {
01248 REGISTER_SET mid_reg_defs[ISA_REGISTER_CLASS_MAX+1],
01249 mid_reg_uses[ISA_REGISTER_CLASS_MAX+1];
01250 GTN_SET *mid_gtn_defs, *mid_gtn_uses;
01251 TN_SET *mid_tn_defs, *mid_tn_uses;
01252
01253 REGSET_CLEAR(mid_reg_defs);
01254 REGSET_CLEAR(mid_reg_uses);
01255
01256 OP* op;
01257 OP* prev_op;
01258
01259 if(fwd)
01260 op = OP_next(cur_op);
01261 else
01262 op = OP_prev(cur_op);
01263
01264 for (; op != point; prev_op = op , op = fwd ? OP_next(op) : OP_prev(op))
01265 {
01266 Is_True(op, ("op is null"));
01267 if (OP_dummy(op)) {
01268 if (!CGTARG_Is_OP_Barrier(op)) continue;
01269 }
01270
01271
01272 for ( INT i = 0; i < OP_results(op); ++i) {
01273 TN *result_tn = OP_result(op,i);
01274 REGISTER result_reg = TN_register (result_tn);
01275 ISA_REGISTER_CLASS cl = TN_register_class (result_tn);
01276 mid_reg_defs[cl] = REGISTER_SET_Union1(mid_reg_defs[cl],result_reg);
01277 }
01278
01279
01280 for (INT i = 0; i < OP_opnds(op); ++i) {
01281 TN *opnd_tn = OP_opnd(op,i);
01282 if (TN_is_constant(opnd_tn)) continue;
01283
01284 REGISTER opnd_reg = TN_register (opnd_tn);
01285 ISA_REGISTER_CLASS cl = TN_register_class (opnd_tn);
01286 mid_reg_uses[cl] = REGISTER_SET_Union1(mid_reg_uses[cl], opnd_reg);
01287 }
01288 }
01289
01290 Is_True(op==point, ("op will stop at point op"));
01291
01292 for(INT i = 0; i < OP_results(point); ++i)
01293 {
01294 TN *result_tn = OP_result(point, i);
01295 REGISTER result_reg = TN_register (result_tn);
01296 ISA_REGISTER_CLASS cl = TN_register_class (result_tn);
01297 mid_reg_defs[cl] = REGISTER_SET_Union1(mid_reg_defs[cl],result_reg);
01298 }
01299
01300 for (INT i = 0; i < OP_opnds(point); ++i) {
01301 TN *opnd_tn = OP_opnd(point, i);
01302
01303 if (TN_is_constant(opnd_tn)) continue;
01304
01305 REGISTER opnd_reg = TN_register (opnd_tn);
01306
01307 ISA_REGISTER_CLASS cl = TN_register_class (opnd_tn);
01308
01309 mid_reg_uses[cl] = REGISTER_SET_Union1(mid_reg_uses[cl], opnd_reg);
01310
01311 }
01312
01313 for( INT i =0; i < OP_results(cur_op); i++)
01314 {
01315 TN* result_tn = OP_result(cur_op, i);
01316 ISA_REGISTER_CLASS cl = TN_register_class(result_tn);
01317 REGISTER result_reg = TN_register(result_tn);
01318 if( REGISTER_SET_Intersection1(mid_reg_uses[cl], result_reg) ||
01319 REGISTER_SET_Intersection1(mid_reg_defs[cl], result_reg)) return FALSE;
01320 }
01321
01322 for( INT i =0; i < OP_opnds(cur_op); i++)
01323 {
01324 TN* opnd_tn = OP_opnd(cur_op, i);
01325
01326 if(TN_is_constant(opnd_tn)) continue;
01327
01328 ISA_REGISTER_CLASS cl = TN_register_class(opnd_tn);
01329
01330 REGISTER opnd_reg = TN_register(opnd_tn);
01331
01332 if( REGISTER_SET_Intersection1(mid_reg_defs[cl], opnd_reg)) return FALSE;
01333 }
01334 return TRUE;
01335 }
01336
01337
01338
01339
01340
01341
01342
01343
01344
01345
01346
01347
01348
01349
01350
01351
01352 typedef mUINT16 MOTION_BOUND;
01353
01354 class SATD_NODE {
01355 OP* _op;
01356 BOOL combined;
01357 vector<SATD_NODE*> _neighbors;
01358 MOTION_BOUND _lower_bound;
01359 MOTION_BOUND _upper_bound;
01360 OP* _lower_bound_op;
01361 OP* _upper_bound_op;
01362 static std::map<OP*, INT> _map_op_to_gid;
01363 static std::map<INT, OP* > _map_gid_to_op;
01364 public:
01365 SATD_NODE() {_lower_bound = 0; _upper_bound = 0; _op = NULL; _neighbors.clear(); };
01366 SATD_NODE(OP* op) { _op = op; _lower_bound = 0; _upper_bound = 0; _neighbors.clear(); }
01367 ~SATD_NODE() {};
01368 MOTION_BOUND Get_Lower_Bound() { return _lower_bound; }
01369 MOTION_BOUND Get_Upper_Bound() { return _upper_bound; }
01370 void Set_Lower_Bound(MOTION_BOUND bound ) { _lower_bound = bound; }
01371 void Set_Upper_Bound(MOTION_BOUND bound) { _upper_bound = bound; }
01372 OP* Get_Lower_Bound_OP() { return _lower_bound_op; }
01373 OP* Get_Upper_Bound_OP() { return _upper_bound_op; }
01374 void Set_Lower_Bound_OP(OP* bound_op ) { _lower_bound_op = bound_op; }
01375 void Set_Upper_Bound_OP(OP* bound_op) { _upper_bound_op = bound_op; }
01376 void Set_Node_Combined() { combined = TRUE; }
01377 BOOL Node_Combined() { return (combined == TRUE); }
01378 void Reset_Node_Combined() { combined = FALSE; }
01379 OP* Get_OP() {return _op; }
01380 BB* Get_BB() { return OP_bb(_op); }
01381 void Add_To_Neighbors( SATD_NODE *neighbor);
01382 void Clear_Neighbors() { _neighbors.clear(); }
01383 vector<SATD_NODE*> * Get_Neighbors() {return &_neighbors; }
01384 UINT Number_Of_Neighbors() {return _neighbors.size(); }
01385 static OP* Get_OP_From_Gid(INT gid) { return _map_gid_to_op[gid]; }
01386 static INT Get_Gid_From_OP(OP* op) {return _map_op_to_gid[op]; }
01387 static void Set_Gid_To_OP(INT gid, OP* op) { _map_op_to_gid[op] = gid;}
01388 static void Set_OP_To_Gid(OP* op, INT gid) { _map_gid_to_op[gid] = op;}
01389 BOOL Has_Interference(SATD_NODE* node);
01390
01391 };
01392
01393 std::map<OP*, INT> SATD_NODE::_map_op_to_gid;
01394 std::map<INT, OP*> SATD_NODE::_map_gid_to_op;
01395
01396 void
01397 SATD_NODE::Add_To_Neighbors(SATD_NODE *neighbor)
01398 {
01399 _neighbors.push_back(neighbor);
01400 }
01401
01402 BOOL
01403 SATD_NODE::Has_Interference(SATD_NODE * node)
01404 {
01405
01406
01407
01408 MOTION_BOUND upper_bound = node->Get_Upper_Bound();
01409 MOTION_BOUND lower_bound = node->Get_Lower_Bound();
01410
01411 if(((upper_bound > _lower_bound) && (upper_bound <= _upper_bound)) ||
01412 ((_upper_bound > lower_bound) && (_upper_bound <= upper_bound)))
01413 return TRUE;
01414
01415 return FALSE;
01416 }
01417
01418 inline bool
01419 less_than( SATD_NODE* node1, SATD_NODE* node2)
01420 {
01421 if((node1->Get_Neighbors())->size() < (node2->Get_Neighbors())->size())
01422 return TRUE;
01423 else if((node1->Get_Lower_Bound()) < (node2->Get_Lower_Bound()))
01424 return TRUE;
01425 else
01426 return FALSE;
01427 }
01428
01429 void
01430 Collect_SATD_In_BB(BB* bb, vector < SATD_NODE* > & satd_nodes)
01431 {
01432 for(OP* op = BB_first_op(bb); op; op= OP_next(op))
01433 {
01434 if(OP_code(op) == TOP_c2_satd) {
01435 SATD_NODE* satd_node = new SATD_NODE(op);
01436 satd_nodes.push_back(satd_node);
01437 }
01438 }
01439 return;
01440 }
01441
01442 void
01443 Valid_Neighbors(vector<SATD_NODE*> &satd_nodes)
01444 {
01445 vector<SATD_NODE*>::iterator iter;
01446 vector<SATD_NODE*>* neighbors;
01447 vector<SATD_NODE*>::iterator neighbor_iter;
01448 INT upper_bound;
01449 INT lower_bound;
01450 INT neighbor_upper_bound;
01451 INT neighbor_lower_bound;
01452 for(iter = satd_nodes.begin(); iter !=satd_nodes.end(); iter++)
01453 {
01454 neighbors = (*iter)->Get_Neighbors();
01455 lower_bound = (*iter)->Get_Lower_Bound();
01456 upper_bound = (*iter)->Get_Upper_Bound();
01457 for(neighbor_iter = (*neighbors).begin(); neighbor_iter != (*neighbors).end(); neighbor_iter++)
01458 {
01459 neighbor_lower_bound = (*neighbor_iter)->Get_Lower_Bound();
01460 neighbor_upper_bound = (*neighbor_iter)->Get_Upper_Bound();
01461 if( (upper_bound < neighbor_lower_bound) || lower_bound > neighbor_upper_bound)
01462 Fail_FmtAssertion("is not a valid neighbor");
01463 }
01464 }
01465 return;
01466 }
01467
01468 void
01469 Build_Interference_Graph_For_SATD(
01470 vector<SATD_NODE * > & satd_nodes)
01471 {
01472 vector<SATD_NODE*>::iterator iter1;
01473 vector<SATD_NODE*>::iterator iter2;
01474 for(iter1 = satd_nodes.begin(); iter1 != satd_nodes.end(); iter1++)
01475 (*iter1)->Clear_Neighbors();
01476
01477 for(iter1 = satd_nodes.begin(); iter1 != satd_nodes.end() ; iter1++)
01478 {
01479 for(iter2 = satd_nodes.begin(); iter2 != satd_nodes.end(); iter2++)
01480 {
01481 if((*iter1) == (*iter2)) continue;
01482
01483 if((*iter1)->Has_Interference(*iter2))
01484 {
01485 (*iter1)->Add_To_Neighbors(*iter2);
01486 }
01487 }
01488 }
01489 Valid_Neighbors(satd_nodes);
01490 return;
01491 }
01492
01493
01494 void
01495 Calculate_Boundary_For_Each_SATD(vector<SATD_NODE*> &satd_nodes)
01496 {
01497 OP *satd_op, *tmp;
01498 vector< SATD_NODE*>::iterator iter1;
01499 vector< SATD_NODE*>::iterator iter2;
01500
01501
01502 for(iter1 = satd_nodes.begin(); iter1 != satd_nodes.end(); iter1++)
01503 {
01504 satd_op =(*iter1)->Get_OP();
01505 BB* bb = (*iter1)->Get_BB();
01506 for(tmp = OP_prev(satd_op); tmp != BB_first_op(bb); tmp = OP_prev(tmp))
01507 {
01508
01509 if( !tmp ) {
01510 Is_True((satd_op == BB_first_op(bb)), ("satd_op must be the first op in bb"));
01511 (*iter1)->Set_Lower_Bound_OP(satd_op);
01512 (*iter1)->Set_Lower_Bound(SATD_NODE::Get_Gid_From_OP(satd_op));
01513 break;
01514 }
01515
01516 if(!Can_OP_Move(satd_op, tmp, FALSE)) {
01517 (*iter1)->Set_Lower_Bound_OP(tmp);
01518 (*iter1)->Set_Lower_Bound(SATD_NODE::Get_Gid_From_OP(tmp));
01519 break;
01520 }
01521 }
01522 if(tmp == BB_first_op(bb)) {
01523 (*iter1)->Set_Lower_Bound_OP(tmp);
01524 (*iter1)->Set_Lower_Bound(SATD_NODE::Get_Gid_From_OP(tmp));
01525 }
01526
01527
01528 for(tmp = OP_next(satd_op); tmp != BB_last_op(bb); tmp = OP_next(tmp))
01529 {
01530
01531 if(!tmp) {
01532 Is_True((satd_op == BB_last_op(bb)), ("satd_op must be the last op in bb"));
01533 (*iter1)->Set_Upper_Bound_OP(satd_op);
01534 (*iter1)->Set_Upper_Bound(SATD_NODE::Get_Gid_From_OP(satd_op));
01535 break;
01536 }
01537 if(!Can_OP_Move(satd_op, tmp)) {
01538 (*iter1)->Set_Upper_Bound_OP(tmp);
01539 (*iter1)->Set_Upper_Bound(SATD_NODE::Get_Gid_From_OP(tmp));
01540 break;
01541 }
01542 }
01543 if(tmp == BB_last_op(bb)) {
01544 (*iter1)->Set_Upper_Bound_OP(tmp);
01545 (*iter1)->Set_Upper_Bound(SATD_NODE::Get_Gid_From_OP(BB_last_op(bb)));
01546 }
01547 }
01548 return;
01549 }
01550
01551 void
01552 Dump_BB(BB* bb, char *output_msg, SATD_NODE* satd_node1, SATD_NODE* satd_node2, OP* point_op)
01553 {
01554 OP * tmp;
01555 OP *op1 = satd_node1->Get_OP();
01556 OP* op2 = satd_node2->Get_OP();
01557
01558 fprintf(TFile, "%s %s %s", DBar, output_msg, DBar);
01559 for(tmp = BB_first_op(bb); tmp; tmp = OP_next(tmp)) {
01560
01561 if(tmp == op1 || tmp == op2)
01562 fprintf(TFile, "===>");
01563
01564 Print_OP_No_SrcLine(tmp);
01565 }
01566 fprintf(TFile, "point op is:");
01567 Print_OP_No_SrcLine(point_op);
01568 fprintf(TFile, "lower_bound of op1:");
01569 Print_OP_No_SrcLine(satd_node1->Get_Lower_Bound_OP());
01570 fprintf(TFile, "upper_bound of op1:");
01571 Print_OP_No_SrcLine(satd_node1->Get_Upper_Bound_OP());
01572 fprintf(TFile, "lower_bound of op2:");
01573 Print_OP_No_SrcLine(satd_node2->Get_Lower_Bound_OP());
01574 fprintf(TFile, "upper_bound of op2:");
01575 Print_OP_No_SrcLine(satd_node2->Get_Upper_Bound_OP());
01576
01577 return;
01578 }
01579
01580
01581
01582
01583 void
01584 Numbering_BB_OPs(BB* bb)
01585 {
01586 INT index = 0;
01587 for(OP* op = BB_first_op(bb); op ; op = OP_next(op), index++)
01588 {
01589 SATD_NODE::Set_Gid_To_OP(index, op);
01590 SATD_NODE::Set_OP_To_Gid(op, index);
01591 }
01592 }
01593
01594 void
01595 Check_Combination(BB* bb, vector<SATD_NODE*> & satd_nodes)
01596 {
01597 vector<SATD_NODE*>::iterator iter;
01598
01599 Numbering_BB_OPs(bb);
01600
01601 for(iter = satd_nodes.begin(); iter != satd_nodes.end(); iter++)
01602 {
01603 OP* op = (*iter)->Get_OP();
01604 OP* lower_bound_op = (*iter)->Get_Lower_Bound_OP();
01605 OP* upper_bound_op = (*iter)->Get_Upper_Bound_OP();
01606 INT gid = SATD_NODE::Get_Gid_From_OP(op);
01607 INT lower_bound = SATD_NODE::Get_Gid_From_OP(lower_bound_op);
01608 INT upper_bound = SATD_NODE::Get_Gid_From_OP(upper_bound_op);
01609 if(lower_bound > gid || upper_bound < gid )
01610 Fail_FmtAssertion("Move op across bound op");
01611 }
01612 }
01613
01614
01615
01616
01617
01618
01619
01620
01621
01622
01623
01624
01625
01626
01627
01628
01629
01630
01631
01632 void
01633 Do_Combination(SATD_NODE * node1, SATD_NODE * node2)
01634 {
01635
01636 MOTION_BOUND lower_bound1, lower_bound2;
01637 MOTION_BOUND upper_bound1, upper_bound2;
01638 OP* lower_bound_op, *upper_bound_op;
01639 OP* point_op;
01640
01641 lower_bound1 = node1->Get_Lower_Bound();
01642 lower_bound2 = node2->Get_Lower_Bound();
01643 upper_bound1 = node1->Get_Upper_Bound();
01644 upper_bound2 = node2->Get_Upper_Bound();
01645
01646 Is_True((upper_bound1 >= lower_bound2), ("two node has no intersection region for combination"));
01647
01648
01649 if(lower_bound1 <= lower_bound2)
01650 lower_bound_op = SATD_NODE::Get_OP_From_Gid(lower_bound2);
01651 else
01652 lower_bound_op = SATD_NODE::Get_OP_From_Gid(lower_bound1);
01653
01654 if(upper_bound1 <= upper_bound2)
01655 upper_bound_op = SATD_NODE::Get_OP_From_Gid(upper_bound1);
01656 else
01657 upper_bound_op = SATD_NODE::Get_OP_From_Gid(upper_bound2);
01658
01659 if(lower_bound_op == upper_bound_op)
01660 point_op = lower_bound_op;
01661 else
01662 point_op = OP_next(lower_bound_op);
01663
01664 OP* satd_op1 = node1->Get_OP();
01665
01666 OP* satd_op2 = node2->Get_OP();
01667
01668 if(SCHED_TF_DUMP_SATD_COMB) {
01669 fprintf(TFile, "before node1 combined = %d\n", node1->Node_Combined());
01670 fprintf(TFile, "before node2 combined = %d\n", node2->Node_Combined());
01671 }
01672
01673 node1->Set_Node_Combined();
01674 node2->Set_Node_Combined();
01675
01676
01677 if((OP_next(satd_op1) ==satd_op2) ||
01678 (OP_next(satd_op2) == satd_op1))
01679 return;
01680 if(SCHED_TF_DUMP_SATD_COMB)
01681 Dump_BB(OP_bb(satd_op1), "Before Combination", node1, node2, point_op);
01682
01683
01684
01685
01686
01687
01688
01689
01690
01691 INT gid1 = SATD_NODE::Get_Gid_From_OP(satd_op1);
01692 INT gid2 = SATD_NODE::Get_Gid_From_OP(satd_op2);
01693
01694 if(satd_op1 != point_op) {
01695 BB_Move_Op_Before(OP_bb(point_op), point_op, OP_bb(point_op), satd_op1);
01696 }
01697 if(satd_op2 != point_op) {
01698 if(gid1 > gid2) {
01699 BB_Move_Op_Before(OP_bb(point_op), satd_op1, OP_bb(point_op), satd_op2);
01700 }
01701 else {
01702 BB_Move_Op_Before(OP_bb(point_op), point_op, OP_bb(point_op), satd_op2);
01703 }
01704 }
01705
01706 if(SCHED_TF_DUMP_SATD_COMB) {
01707 fprintf(TFile, "node1 combined = %d\n", node1->Node_Combined());
01708 fprintf(TFile, "node2 combined = %d\n", node2->Node_Combined());
01709 Dump_BB(OP_bb(satd_op1), "After Combination", node1, node2, point_op);
01710 }
01711 return;
01712 }
01713
01714 SATD_NODE*
01715 Find_One_Neighbor(SATD_NODE* node)
01716 {
01717 vector<SATD_NODE*> * neighbors = node->Get_Neighbors();
01718 vector<SATD_NODE*>::iterator neighbor_iter;
01719
01720 for(neighbor_iter = neighbors->begin(); neighbor_iter != neighbors->end(); neighbor_iter++)
01721 {
01722
01723
01724 if((*neighbor_iter)->Node_Combined())
01725 continue;
01726 else {
01727 return (*neighbor_iter);
01728 }
01729 }
01730 return NULL;
01731 }
01732
01733 void
01734 Combine_SATD_In_Pair(vector<SATD_NODE*> &satd_nodes)
01735 {
01736 vector<SATD_NODE*>::iterator iter;
01737 vector<SATD_NODE*> zero_neighbor_nodes;
01738
01739
01740 if(satd_nodes.size() < 2)
01741 return;
01742
01743 for(iter = satd_nodes.begin(); iter != satd_nodes.end(); iter++)
01744 {
01745 if((*iter)->Number_Of_Neighbors() == 0 )
01746 continue;
01747 else if((*iter)->Node_Combined())
01748 continue;
01749 else
01750 {
01751 SATD_NODE* neighbor = Find_One_Neighbor(*iter);
01752
01753
01754 if(neighbor == NULL)
01755 continue;
01756 else {
01757 Do_Combination(*iter, neighbor);
01758 Numbering_BB_OPs((*iter)->Get_BB());
01759 Calculate_Boundary_For_Each_SATD(satd_nodes);
01760 Build_Interference_Graph_For_SATD(satd_nodes);
01761 }
01762
01763
01764
01765 }
01766 }
01767 return;
01768 }
01769
01770
01771 void
01772 Find_Zero_Neighbor_Nodes(vector<SATD_NODE*> &satd_nodes, vector < SATD_NODE*> &zero_neighbor_nodes)
01773 {
01774 vector<SATD_NODE*>::iterator iter;
01775 for(iter = satd_nodes.begin(); iter != satd_nodes.end(); iter++)
01776 {
01777 if((*iter)->Number_Of_Neighbors() == 0)
01778 zero_neighbor_nodes.push_back(*iter);
01779 }
01780 return;
01781 }
01782
01783
01784
01785
01786
01787
01788
01789
01790
01791
01792
01793
01794
01795
01796
01797
01798
01799
01800
01801
01802 void
01803 Expand_Motion_Space(vector<SATD_NODE*> & satd_nodes)
01804 {
01805 vector< SATD_NODE *> zero_neighbor_nodes;
01806 vector< SATD_NODE *> processed;
01807 vector< SATD_NODE *>::iterator iter;
01808 vector< SATD_NODE *>::iterator iter2;
01809 Find_Zero_Neighbor_Nodes(satd_nodes, zero_neighbor_nodes);
01810
01811 for(iter = zero_neighbor_nodes.begin(); iter != zero_neighbor_nodes.end(); iter++)
01812 {
01813 for(iter2 = zero_neighbor_nodes.begin(); iter2 != zero_neighbor_nodes.end(); iter2++)
01814 {
01815 if(iter2 == iter)
01816 continue;
01817
01818 if(find(processed.begin(), processed.end(), *iter) != processed.end())
01819 continue;
01820
01821 MOTION_BOUND lower_bound1 = (*iter)->Get_Lower_Bound();
01822 MOTION_BOUND upper_bound1 = (*iter)->Get_Upper_Bound();
01823 MOTION_BOUND lower_bound2 = (*iter2)->Get_Lower_Bound();
01824 MOTION_BOUND upper_bound2 = (*iter2)->Get_Upper_Bound();
01825
01826 if( upper_bound1 < lower_bound2)
01827 {
01828 OP* upper_bound_op = (*iter)->Get_Upper_Bound_OP();
01829 OP* lower_bound_op = (*iter2) ->Get_Lower_Bound_OP();
01830 OP* tmp = OP_next(upper_bound_op);
01831 while(tmp != lower_bound_op) {
01832 OP* next = OP_next(tmp);
01833 if(Can_OP_Move(tmp, upper_bound_op, FALSE))
01834 {
01835 BB_Move_Op_Before(OP_bb(tmp), upper_bound_op, OP_bb(tmp), tmp);
01836 }
01837 tmp = next;
01838 }
01839 if(tmp == lower_bound_op && Can_OP_Move(tmp, upper_bound_op, FALSE)) {
01840 BB_Move_Op_Before(OP_bb(tmp), upper_bound_op, OP_bb(tmp), tmp);
01841 processed.push_back(*iter);
01842 processed.push_back(*iter2);
01843 }
01844 }
01845 else if(lower_bound1 > upper_bound2)
01846 {
01847 OP* upper_bound_op = (*iter2)->Get_Upper_Bound_OP();
01848 OP* lower_bound_op = (*iter) ->Get_Lower_Bound_OP();
01849 OP* tmp = OP_next(upper_bound_op);
01850 while(tmp != lower_bound_op) {
01851 OP* next = OP_next(tmp);
01852 if(Can_OP_Move(tmp, upper_bound_op, FALSE))
01853 {
01854 BB_Move_Op_Before(OP_bb(tmp), upper_bound_op, OP_bb(tmp), tmp);
01855 }
01856 tmp = next;
01857 }
01858 if(tmp == lower_bound_op && Can_OP_Move(tmp, upper_bound_op, FALSE)) {
01859 BB_Move_Op_Before(OP_bb(tmp), upper_bound_op, OP_bb(tmp), tmp);
01860 processed.push_back(*iter);
01861 processed.push_back(*iter2);
01862 }
01863 }
01864 }
01865 }
01866 }
01867
01868 void
01869 Pairwise_SATD_OP(BB* bb)
01870 {
01871 vector <SATD_NODE*> satd_nodes ;
01872 vector < OP* >::iterator iter;
01873 vector < SATD_NODE*>::iterator node_iter;
01874
01875
01876
01877 Numbering_BB_OPs(bb);
01878
01879
01880 Collect_SATD_In_BB(bb, satd_nodes);
01881
01882
01883 if(satd_nodes.empty()) return;
01884
01885
01886 Calculate_Boundary_For_Each_SATD(satd_nodes);
01887
01888
01889 Build_Interference_Graph_For_SATD(satd_nodes);
01890
01891 Expand_Motion_Space(satd_nodes);
01892
01893
01894
01895
01896 Numbering_BB_OPs(bb);
01897
01898
01899 Calculate_Boundary_For_Each_SATD(satd_nodes);
01900
01901
01902 Build_Interference_Graph_For_SATD(satd_nodes);
01903
01904 Valid_Neighbors(satd_nodes);
01905
01906 std::stable_sort(satd_nodes.begin(), satd_nodes.end(), less_than);
01907
01908 Valid_Neighbors(satd_nodes);
01909
01910 if(SCHED_TF_DUMP_SATD_COMB)
01911 {
01912 vector<class SATD_NODE*>::iterator iter;
01913
01914 fprintf(TFile, "%s BB:%d SATD_COMBINATION Start \n", DBar, BB_id(bb));
01915
01916 for( iter = satd_nodes.begin(); iter != satd_nodes.end(); iter++) {
01917 fprintf(TFile, "satd_nodes neighbours number: %d\n", ((*iter)->Get_Neighbors())->size());
01918 fprintf(TFile, "lower bound is : %d\n" , ((*iter)->Get_Lower_Bound()));
01919 fprintf(TFile, "upper bound is: %d\n", ((*iter)->Get_Upper_Bound()));
01920 }
01921
01922 fprintf(TFile, "%s, SATD_COMBINATION END %s\n", DBar, DBar);
01923 }
01924
01925 Valid_Neighbors(satd_nodes);
01926
01927 Combine_SATD_In_Pair(satd_nodes);
01928
01929 Valid_Neighbors(satd_nodes);
01930
01931 Check_Combination(bb, satd_nodes);
01932
01933 return;
01934 }
01935
01936 void
01937 Move_Macro_Insn_Together()
01938 {
01939 for (BB* bb = REGION_First_BB; bb != NULL; bb = BB_next(bb)) {
01940 Pairwise_SATD_OP(bb);
01941 }
01942 return;
01943 }
01944 #endif
01945
01946
01947
01948
01949
01950
01951
01952
01953
01954
01955
01956 void
01957 SCHEDULER::BB_Move_Op_Before (BB *to_bb, OP *point, BB *from_bb, OP *op) {
01958
01959
01960
01961
01962
01963 SCHED_BB_ANNOT * bb_annot ;
01964 SCHED_OP_ANNOT * op_annot ;
01965 void * op_heur ;
01966
01967 BB_OP_MAP omap
01968 = (BB_OP_MAP) BB_MAP_Get(_cg_dep_op_info, OP_bb(op));
01969 _CG_DEP_OP_INFO *dep_info =
01970 (_CG_DEP_OP_INFO *) BB_OP_MAP_Get(omap, op);
01971
01972 bb_annot = sched_annot.Get_BB_Annot (from_bb);
01973 op_annot = bb_annot->Detach_OP_Annot (op);
01974 op_heur = _heur_mgr.Detach_OP_Heur_Info (op);
01975
01976 if (point) {
01977 ::BB_Move_Op_Before (to_bb, point, from_bb, op);
01978 } else {
01979
01980
01981
01982 #if defined(TARG_SL)
01983 OP* last_op = BB_last_op (to_bb) ;
01984 if (last_op && TOP_is_xfer (OP_code(last_op))) {
01985 ::BB_Move_Op_Before (to_bb, last_op, from_bb, op);
01986 } else {
01987
01988
01989
01990 ::BB_Move_Op_To_End (to_bb, from_bb, op);
01991 }
01992 #else
01993 ::BB_Move_Op_To_End (to_bb, from_bb, op);
01994 #endif
01995 }
01996
01997 omap = (BB_OP_MAP) BB_MAP_Get(_cg_dep_op_info, OP_bb(op));
01998 BB_OP_MAP_Set (omap, op, dep_info);
01999
02000 bb_annot = sched_annot.Get_BB_Annot (to_bb);
02001 bb_annot->Attach_OP_Annot (op, op_annot) ;
02002 _heur_mgr.Attach_OP_Heur_Info (op,op_heur);
02003 }
02004
02005 #if defined(TARG_SL) || defined(TARG_SL2)
02006
02007
02008
02009
02010
02011
02012
02013
02014
02015
02016
02017 void
02018 SCHEDULER::BB_Move_Op_After (BB *to_bb, OP *point, BB *from_bb, OP *op)
02019 {
02020
02021
02022
02023
02024
02025 SCHED_BB_ANNOT * bb_annot ;
02026 SCHED_OP_ANNOT * op_annot ;
02027 void * op_heur ;
02028
02029 BB_OP_MAP omap
02030 = (BB_OP_MAP) BB_MAP_Get(_cg_dep_op_info, OP_bb(op));
02031 _CG_DEP_OP_INFO *dep_info =
02032 (_CG_DEP_OP_INFO *) BB_OP_MAP_Get(omap, op);
02033
02034 bb_annot = sched_annot.Get_BB_Annot (from_bb);
02035 op_annot = bb_annot->Detach_OP_Annot (op);
02036 op_heur = _heur_mgr.Detach_OP_Heur_Info (op);
02037
02038 if (point) {
02039 ::BB_Move_Op_After (to_bb, point, from_bb, op);
02040 } else {
02041
02042
02043
02044 OP* last_op = BB_last_op (to_bb) ;
02045 if (last_op && TOP_is_xfer (OP_code(last_op))) {
02046 ::BB_Move_Op_Before (to_bb, last_op, from_bb, op);
02047 } else {
02048
02049
02050
02051 ::BB_Move_Op_To_End (to_bb, from_bb, op);
02052 }
02053 }
02054
02055 omap = (BB_OP_MAP) BB_MAP_Get(_cg_dep_op_info, OP_bb(op));
02056 BB_OP_MAP_Set (omap, op, dep_info);
02057
02058 bb_annot = sched_annot.Get_BB_Annot (to_bb);
02059 bb_annot->Attach_OP_Annot (op, op_annot) ;
02060 _heur_mgr.Attach_OP_Heur_Info (op,op_heur);
02061 }
02062 #endif
02063
02064
02065
02066
02067
02068
02069
02070
02071
02072
02073 void
02074 SCHEDULER :: Gen_Bookeeping_OP_DAG
02075 (CANDIDATE& cand, OP* compensate, BOOKEEPING* bk) {
02076
02077
02078 BOOL p_ready_bookeeping = bk->Is_P_Ready_Bookeeping ();
02079
02080 OP* model = cand.Op ();
02081 BB* place = bk->Get_Placement ();
02082
02083 BB_OP_MAP_Set (
02084 (BB_OP_MAP) BB_MAP_Get(_cg_dep_op_info,place),
02085 compensate, new_op_info ());
02086
02087
02088
02089 ARC_LIST* dep_lst ;
02090 for (dep_lst = OP_succs(model);
02091 dep_lst != NULL;
02092 dep_lst = ARC_LIST_rest(dep_lst)) {
02093
02094 ARC* tmp = ARC_LIST_first(dep_lst);
02095
02096 if (!tmp || ARC_is_br(tmp)) continue ;
02097 new_arc_with_latency
02098 (ARC_kind(tmp),
02099 compensate,
02100 ARC_succ(tmp),
02101 ARC_latency(tmp),
02102 ARC_omega(tmp),
02103 ARC_opnd(tmp),
02104 ARC_is_definite(tmp));
02105 }
02106
02107
02108
02109 for (dep_lst = OP_preds(model);
02110 dep_lst != NULL;
02111 dep_lst = ARC_LIST_rest(dep_lst)) {
02112
02113 ARC* tmp = ARC_LIST_first(dep_lst);
02114 if (!tmp || ARC_is_br(tmp)) {
02115
02116
02117
02118 continue ;
02119 }
02120
02121 BB* pred_bb = OP_bb(ARC_pred(tmp));
02122
02123 if (pred_bb == place||
02124 _cflow_mgr.BB1_Reachable_From_BB2 (place,pred_bb)) {
02125
02126 new_arc_with_latency (ARC_kind(tmp),
02127 ARC_pred(tmp), compensate,
02128 ARC_latency(tmp), ARC_omega(tmp),
02129 ARC_opnd(tmp), ARC_is_definite(tmp));
02130
02131 } else if (_cflow_mgr.BB1_Reachable_From_BB2 (pred_bb,place)) {
02132 Gen_Inverted_Arc (&cand, tmp,
02133 compensate,
02134 ARC_pred(tmp) );
02135 }
02136 }
02137
02138 _dag_constructor.Build_Branch_Arcs (compensate, INCLUDE_CONTROL_ARCS);
02139 }
02140
02141
02142
02143
02144
02145
02146
02147
02148
02149
02150
02151 OP*
02152 SCHEDULER::Gen_Compensation_Code
02153 (CANDIDATE& model_cand, BB* org_home,
02154 BOOKEEPING* bk, BOOL append) {
02155
02156 BB* place = bk->Get_Placement ();
02157 Is_True (!BB_Is_Isolated_From_Sched (place),
02158 ("Cannot prepend or append compensation code to a isolated BB:%d",
02159 BB_id(place)));
02160
02161
02162
02163
02164 OP* model = model_cand.Op ();
02165 OP* op = Dup_OP (model) ;
02166 OP_srcpos (op) = OP_srcpos(model);
02167
02168
02169
02170 SCHED_BB_ANNOT* annot = sched_annot.Get_BB_Annot (place);
02171
02172
02173
02174 BOOL insert_op = FALSE;
02175 if (append) {
02176
02177
02178
02179 OP* last_op = BB_last_op (place) ;
02180 if (last_op && TOP_is_xfer (OP_code(last_op))) {
02181 BB_Insert_Op_Before (place, last_op, op) ;
02182 insert_op = TRUE;
02183 } else {
02184
02185
02186
02187 BB_Append_Op (place, op) ;
02188 }
02189 } else {
02190 FmtAssert (FALSE,
02191 ("OP[%d] which is now in BB:%d is moved downward,however downward code has yet implemented",
02192 OP_map_idx(model),BB_id(place)));
02193 }
02194
02195
02196
02197 if (OP_memory(op)) {
02198 Copy_WN_For_Memory_OP (op,model);
02199 }
02200
02201
02202
02203 SCHED_OP_ANNOT* op_annot = annot->Init_New_OP_Annot (op) ;
02204 SCHED_OP_ANNOT* model_annot = sched_annot.Get_OP_Annot (model) ;
02205
02206 op_annot->_ext_flags = model_annot->_ext_flags &
02207 (OP_EXT_MASK_NO_CNTL_SPEC |
02208 OP_EXT_MASK_NO_DATA_SPEC |
02209 OP_EXT_MASK_ACTUAL) |
02210 OP_EXT_MASK_COMPENSATION;
02211
02212 op_annot->_op = op ;
02213 op_annot->_org_home_bb = org_home;
02214
02215
02216
02217
02218 Gen_Bookeeping_OP_DAG (model_cand,op,bk);
02219
02220
02221
02222
02223
02224 if (append) {
02225 if (insert_op) {
02226 _heur_mgr.Compute_Heur_Data_For_Inserted_OP (op);
02227 } else {
02228 _heur_mgr.Compute_Heur_Data_For_Appended_OP (op);
02229 }
02230 } else {
02231 FmtAssert (FALSE,("Downward code motion has yet implemented\n"));
02232 }
02233
02234
02235
02236 SPEC_TYPE spec_type = model_cand.Spec_Type ();
02237 if (spec_type & SPEC_DATA) {
02238 Set_OP_data_spec (op);
02239 Set_OP_orig_bb_id (op,BB_id(org_home));
02240 }
02241
02242 if (spec_type & SPEC_CNTL) {
02243 Set_OP_cntl_spec (op);
02244 Set_OP_orig_bb_id (op,BB_id(org_home));
02245 }
02246
02247 return op ;
02248 }
02249
02250
02251
02252
02253
02254
02255
02256
02257
02258
02259 void
02260 SCHEDULER::Gen_Inverted_Arc
02261 (CANDIDATE* cand, ARC* ref_arc, OP* pred, OP* succ) {
02262
02263 CG_DEP_KIND arc_kind;
02264 INT16 arc_opnd = 0;
02265 TN* arc_opnd_tn;
02266
02267 OP* arc_pred = ARC_pred(ref_arc);
02268 OP* arc_succ = ARC_succ(ref_arc);
02269
02270
02271 switch (ARC_kind(ref_arc)) {
02272 case CG_DEP_REGIN:
02273 arc_kind = CG_DEP_REGANTI;
02274
02275 arc_opnd_tn = OP_opnd(arc_succ,ARC_opnd(ref_arc));
02276 for (arc_opnd = OP_results(arc_succ) - 1;
02277 arc_opnd >= 0;
02278 arc_opnd--) {
02279 if (OP_result(arc_pred, arc_opnd) == arc_opnd_tn) {
02280 break;
02281 }
02282 }
02283
02284 arc_opnd = (arc_opnd >= 0) ? arc_opnd : 0;
02285 break;
02286
02287
02288 case CG_DEP_REGOUT:
02289 arc_kind = CG_DEP_REGIN;
02290 break;
02291
02292
02293 case CG_DEP_REGANTI:
02294 arc_kind = CG_DEP_REGIN;
02295 arc_opnd_tn = OP_result(arc_succ, ARC_opnd(ref_arc));
02296 for (arc_opnd = OP_opnds (arc_pred) - 1;
02297 arc_opnd >= 0;
02298 arc_opnd --) {
02299 if (OP_opnd(arc_pred, arc_opnd) == arc_opnd_tn) { break; }
02300 }
02301
02302 arc_opnd = (arc_opnd >= 0) ? arc_opnd : 0;
02303 break;
02304
02305 case CG_DEP_MEMOUT:
02306 arc_kind = CG_DEP_MEMOUT; break;
02307
02308 case CG_DEP_MEMANTI:
02309 arc_kind = CG_DEP_MEMIN; break;
02310
02311 case CG_DEP_MEMVOL:
02312 arc_kind = CG_DEP_MEMVOL; break;
02313
02314 case CG_DEP_MEMREAD:
02315 arc_kind = CG_DEP_MEMREAD; break;
02316
02317 case CG_DEP_SPILLIN:
02318 case CG_DEP_PREFIN:
02319 case CG_DEP_PREFOUT:
02320 case CG_DEP_SCC:
02321 case CG_DEP_MISC:
02322 arc_kind = CG_DEP_MISC; break;
02323
02324 case CG_DEP_MEMIN:
02325 arc_kind = CG_DEP_MEMANTI; break;
02326
02327 case CG_DEP_PREBR:
02328 arc_kind = CG_DEP_POSTBR; break;
02329
02330 #ifdef TARG_IA64
02331 case CG_DEP_PRECHK:
02332 arc_kind = CG_DEP_POSTCHK; break;
02333
02334 case CG_DEP_POSTCHK:
02335 arc_kind = CG_DEP_PRECHK; break;
02336 break;
02337 #endif
02338
02339 case CG_DEP_POSTBR:
02340 arc_kind = CG_DEP_PREBR; break;
02341
02342 default:
02343 FmtAssert (FALSE, ("unknown CG_DEP_KIND %X\n", ARC_kind(ref_arc)));
02344 break;
02345 }
02346
02347
02348
02349
02350
02351 ARC* New_Arc;
02352 switch (ARC_kind(ref_arc)) {
02353 case CG_DEP_PREBR:
02354 case CG_DEP_POSTBR:
02355 #ifdef TRAG_IA64
02356 case CG_DEP_PRECHK:
02357 case CG_DEP_POSTCHK:
02358 #endif
02359 New_Arc = new_arc_with_latency
02360 (arc_kind,
02361 pred, succ,
02362 0, 0 ,
02363 arc_opnd, TRUE);
02364 break;
02365 default:
02366 New_Arc = new_arc (arc_kind, pred, succ, 0, arc_opnd, TRUE);
02367 }
02368
02369 Is_True (ARC_latency(New_Arc) >= 0,
02370 ("Negative latency (%d)", ARC_latency(New_Arc)));
02371 }
02372
02373
02374
02375
02376
02377
02378
02379
02380
02381
02382
02383
02384 void
02385 SCHEDULER::Maintain_Dep_Arcs_After_Sched (CANDIDATE* cand) {
02386
02387 OP* op = cand->Op ();
02388
02389
02390
02391 Is_True (OP_Scheduled(op),
02392 ("OP:%d(BB:%d) must be scheduled",
02393 OP_map_idx(op), BB_id(OP_bb(op))));
02394
02395
02396
02397 for (ARC_LIST* arcs = OP_preds(op); arcs ;) {
02398
02399 ARC *arc = ARC_LIST_first(arcs);
02400 arcs = ARC_LIST_rest(arcs);
02401 OP* pred = ARC_pred (arc);
02402
02403 if (OP_Scheduled(pred)) {
02404
02405
02406
02407
02408
02409
02410
02411
02412
02413
02414 if (!OP_xfer(pred) || OP_bb(pred) != OP_bb(op)) {
02415 continue;
02416 }
02417 }
02418
02419
02420
02421
02422
02423
02424
02425
02426
02427
02428
02429 if (!_cflow_mgr.BB1_Reachable_From_BB2 (OP_bb(op),OP_bb(pred)) &&
02430 !_cflow_mgr.BB1_Reachable_From_BB2 (OP_bb(pred),OP_bb(op)) &&
02431 OP_bb(op) != OP_bb(pred)) {
02432
02433 CG_DEP_Detach_Arc (arc);
02434 continue;
02435
02436 }
02437
02438
02439
02440 Gen_Inverted_Arc (cand, arc,
02441 ARC_succ(arc),
02442 ARC_pred(arc) );
02443
02444 CG_DEP_Detach_Arc (arc);
02445
02446 }
02447 }
02448
02449 INT32 moved_op_num = 0;
02450
02451
02452
02453
02454
02455
02456
02457
02458
02459
02460
02461
02462
02463
02464
02465
02466
02467
02468
02469
02470
02471
02472
02473
02474
02475
02476
02477
02478
02479
02480
02481
02482
02483
02484 BOOL
02485 SCHEDULER::Commit_Schedule (CANDIDATE& cand) {
02486
02487 moved_op_num++;
02488
02489 OP* op = cand.Op ();
02490 BB* home_bb = OP_bb(op);
02491 OP* cmp_op = NULL;
02492 TN* op_qp_bak = NULL;
02493
02494 BOOL insert_chk = FALSE ;
02495 BOOL cntl_spec_if_converted_code = FALSE;
02496 SRC_BB_INFO * src_info = _src_bb_mgr.Get_Src_Info (OP_bb(cand.Op()));
02497
02498
02499
02500
02501 if (OP_load(op) && cand.Is_Spec ()) {
02502 cand.Get_Up_to_Date_Spec_Type ();
02503 }
02504
02505
02506
02507
02508
02509 if (op != _frontier_op) {
02510
02511 OP* pos = OP_prev(op);
02512 OP* chk_op = NULL;
02513
02514 BB_VECTOR* cutting_set = src_info->Get_Cutting_Set ();
02515 SCHED_SPEC_HANDSHAKE::Change_Load_Spec_Form
02516 (&cand, cutting_set->size(),&insert_chk, this);
02517
02518 BB_Move_Op_Before (_target_bb, _frontier_op, OP_bb(op), op) ;
02519
02520 #ifdef TARG_IA64
02521 if (insert_chk) { chk_op = Insert_Check (op, home_bb, pos); }
02522 #endif
02523 BOOKEEPING_LST* bkl = cand.Bookeeping_Lst ();
02524
02525 for (BOOKEEPING* bk = bkl->First_Item ();
02526 bk != NULL;
02527 bk = bkl->Next_Item (bk)) {
02528
02529 OP* bookeeping_op = Gen_Compensation_Code (cand, home_bb, bk);
02530 #ifdef TARG_IA64
02531 if (insert_chk && bk->Is_P_Ready_Bookeeping ()) {
02532 Set_Speculative_Chain_Begin_Point (chk_op,bookeeping_op);
02533 }
02534 #endif
02535 }
02536 } else {
02537 _frontier_op = OP_next(_frontier_op);
02538 }
02539
02540 Set_OP_Scheduled (op);
02541 OP_scycle(op) = (mINT16)_cur_cyc ;
02542
02543
02544 SPEC_TYPE spec_type = cand.Spec_Type ();
02545 if (spec_type & SPEC_DATA) { Set_OP_data_spec(op); }
02546 if (spec_type & SPEC_CNTL) { Set_OP_cntl_spec(op); }
02547 if (spec_type & (SPEC_DATA | SPEC_CNTL)) {
02548 Set_OP_orig_bb_id (op,BB_id(home_bb));
02549 }
02550
02551 if (cand.Spec_Type () != SPEC_NONE ||
02552 home_bb != _target_bb) {
02553
02554 _upward_motion_num ++;
02555
02556
02557 Maintain_Dep_Arcs_After_Sched (&cand);
02558 }
02559
02560
02561 if (home_bb != _target_bb) {
02562 _dflow_mgr.Update_Liveness_After_Upward_Sched
02563 (&cand,src_info, &_cflow_mgr) ;
02564 }
02565
02566
02567
02568
02569
02570 Update_Cand_Lst_During_Sched_Cyc (cand);
02571
02572
02573
02574 _ops_in_cur_cyc.push_back(op) ;
02575
02576 BOOL retcode = CGGRP_Issue_OP(op, TRUE);
02577 Is_True (retcode, ("fail to issue op"));
02578
02579 return OP_xfer (op);
02580 }
02581
02582
02583
02584
02585
02586
02587
02588 void
02589 SCHEDULER::Verify (void) {
02590
02591 OP* op;
02592
02593 FOR_ALL_BB_OPs(_target_bb, op) {
02594 Is_True(OP_Scheduled(op),
02595 ("Not all ops scheduled: %d 0x%x\tin BB: %d",
02596 OP_map_idx(op), op, BB_id(OP_bb(op))));
02597 }
02598
02599 }
02600
02601 void
02602 SCHEDULER::Identify_Actual_Argument_Defs (BB* bb) {
02603
02604 if (!BB_call (bb)) return ;
02605
02606 OP * call_op = BB_xfer_op(bb) ;
02607 Is_True (OP_call(call_op), ("OP is not a call!"));
02608
02609 OP * op ;
02610 FOR_ALL_BB_OPs(bb, op) {
02611 OP_ANNOT_Set_OP_Def_Actual_Para (op);
02612 }
02613
02614 OP_ANNOT_Reset_OP_Def_Actual_Para (call_op);
02615
02616
02617 FOR_ALL_BB_OPs_REV (bb,op) {
02618 if (OP_store(op) || OP_prefetch(op)) {
02619 OP_ANNOT_Reset_OP_Def_Actual_Para (op);
02620 }
02621
02622 BOOL safe_move_across_bb = FALSE ;
02623
02624 if (safe_move_across_bb) {
02625 OP_ANNOT_Reset_OP_Def_Actual_Para (op);
02626 }
02627
02628 for (ARC_LIST * list = OP_preds(op); list ;
02629 list = ARC_LIST_rest(list)) {
02630
02631 ARC * arc = ARC_LIST_first (list) ;
02632 if (ARC_kind(arc) == CG_DEP_REGIN &&
02633 OP_bb (ARC_pred(arc)) == bb) {
02634
02635 OP_ANNOT_Reset_OP_Def_Actual_Para (ARC_pred(arc));
02636 }
02637 }
02638 }
02639
02640 OP_ANNOT_Reset_OP_Def_Actual_Para (call_op);
02641
02642 BOOL find_first_def = FALSE ;
02643 FOR_ALL_BB_OPs (bb,op) {
02644 if (OP_ANNOT_OP_Def_Actual_Para (op)) find_first_def = TRUE ;
02645 if (OP_load (op) && find_first_def ) {
02646 OP_ANNOT_Set_OP_Def_Actual_Para (op) ;
02647 };
02648 }
02649
02650 }
02651
02652
02653
02654
02655
02656
02657
02658
02659
02660
02661 BOOL
02662 SCHEDULER::Sched_Rgn_Preproc (void) {
02663
02664
02665 if (_cflow_mgr.Critical_Edge_Present(_region)) {
02666
02667
02668
02669
02670 return FALSE;
02671 }
02672
02673 if (!_cflow_mgr.BB_Node_Num()) {
02674
02675
02676
02677
02678
02679 return FALSE;
02680 }
02681
02682
02683
02684 sched_annot.Init (_region);
02685
02686
02687
02688
02689
02690 Start_Timer (T_Ipfec_DAG_CU);
02691 _dag_constructor.Build_DAG();
02692 Stop_Timer (T_Ipfec_DAG_CU);
02693 if (SCHED_TF_DUMP_DAG) { Dump_DAG(); fprintf(TFile, "\n"); }
02694
02695 CGGRP_Init (_region);
02696 _heur_mgr.Initialize (_region,&_cflow_mgr);
02697
02698 for (TOPOLOGICAL_REGIONAL_CFG_ITER iter(_region->Regional_Cfg());
02699 iter != 0; ++iter) {
02700
02701 if ((*iter)->Is_Region()) continue ;
02702 BB * bb = (*iter)->BB_Node();
02703 if (BB_entry(bb) || BB_exit(bb)) continue ;
02704
02705 Identify_Actual_Argument_Defs (bb);
02706 }
02707
02708 Identify_Cannot_Spec_OPs (_region);
02709
02710 return TRUE;
02711 }
02712
02713
02714
02715
02716
02717
02718
02719
02720
02721 void
02722 SCHEDULER::Sched_Rgn_Postproc (void) {
02723 Build_Region_Summary (_region, &_cflow_mgr) ;
02724 }
02725
02726
02727
02728
02729
02730
02731
02732
02733
02734
02735
02736
02737
02738
02739
02740
02741
02742
02743
02744
02745
02746
02747
02748
02749
02750 void
02751 SCHEDULER::Preprocess_GP_def_op (void) {
02752
02753 _gp_def_op = NULL ;
02754
02755 if (!BB_length(_target_bb) ||
02756 !OP_def_GP (BB_first_op(_target_bb))) {
02757 return ;
02758 }
02759
02760 _gp_def_op = BB_first_op(_target_bb);
02761 }
02762
02763 void
02764 SCHEDULER::Postprocess_GP_def_op (void) {
02765
02766 if (_gp_def_op && BB_first_op(_target_bb) != _gp_def_op) {
02767
02768 BB_Move_Op_Before (_target_bb,
02769 BB_first_op(_target_bb),
02770 _target_bb, _gp_def_op) ;
02771 Reset_BB_scheduled (_target_bb);
02772 }
02773
02774 _gp_def_op = NULL;
02775 }
02776
02777 inline BOOL
02778 SCHEDULER::OP_def_GP (OP* op) {
02779 if (OP_results (op) != 1) return FALSE;
02780
02781 return OP_result(op,0) == GP_TN ;
02782 }
02783
02784 inline void
02785 SCHEDULER::Bug_Workaround_Before_Schedule_BB (void) {
02786 if (_prepass) {
02787 Preprocess_GP_def_op ();
02788 }
02789 }
02790
02791 inline void
02792 SCHEDULER::Bug_Workaround_After_Schedule_BB (void) {
02793
02794 if (_prepass) {
02795 Postprocess_GP_def_op ();
02796 }
02797 }
02798
02799 void
02800 SCHEDULER::Glos_Sched_BB_Preproc (void) {
02801
02802 if (_global) {
02803 Determine_P_Ready_is_Profitable_or_not () ;
02804 }
02805
02806 #ifdef TARG_IA64
02807 _multiway_br_span_bbs.clear ();
02808 #endif
02809
02810 Init_Sched_Status () ;
02811
02812
02813 CGGRP_Begin_BB (_target_bb);
02814
02815
02816
02817
02818
02819 _src_bb_mgr.Find_Src_BBs (_region, _target_bb, &_cflow_mgr,
02820 TRUE );
02821
02822
02823
02824
02825
02826
02827
02828
02829 _heur_mgr.Adjust_Heur_Stuff_When_BB_Changed (_target_bb,_src_bb_mgr);
02830
02831
02832 Find_All_Candidates ();
02833 }
02834
02835
02836
02837
02838
02839
02840
02841
02842
02843
02844 void
02845 SCHEDULER::Glos_Sched_BB_Postproc (void) {
02846
02847
02848
02849 CGGRP_End_BB();
02850 Set_BB_scheduled (_target_bb);
02851 Isolate_BB_From_Sched_Scope (_target_bb);
02852
02853
02854
02855 BB_cycle(_target_bb) =
02856 BB_length(_target_bb) ? _cur_cyc : 0 ;
02857
02858 Verify();
02859 }
02860
02861
02862
02863
02864
02865
02866
02867
02868
02869 BOOL
02870 SCHEDULER::Glos_Should_Sched_This_BB (BB* b) {
02871
02872 if (BB_Is_Isolated_From_Sched (b)) {
02873 return FALSE;
02874 }
02875
02876 INT32 len = BB_length(b);
02877 if (len > 1) { return TRUE; }
02878 if (len == 0) { return FALSE; }
02879
02880
02881
02882
02883
02884
02885 if (len == 1 && BB_branch_op (b)) {
02886 if (BB_edge_splitting (b)) {
02887 return FALSE;
02888 }
02889
02890 #ifdef TARG_IA64
02891 if (BB_SET_MemberP (_multiway_br_candidates, b)) {
02892 return FALSE;
02893 }
02894 #endif
02895 }
02896
02897 if (BB_entry(b) || BB_exit(b)) {
02898 return FALSE;
02899 }
02900
02901 return TRUE;
02902 }
02903
02904
02905
02906
02907
02908
02909
02910
02911 void
02912 SCHEDULER::Schedule_Cycle (void) {
02913
02914
02915
02916
02917 _cand_mgr.Clear_All_Cands_Tried_Mark ();
02918
02919 BOOL commit_br = FALSE;
02920 while (!_cand_mgr.Cand_Lst_Is_Empty ()) {
02921
02922
02923
02924
02925 if (CGGRP_Cycle_Full() ||
02926 _cand_mgr.All_Cands_Have_Been_Tried ()) {
02927 return ;
02928 }
02929
02930
02931
02932 E_Time_Constraint etime_constraint;
02933
02934 etime_constraint.threshold = _cur_cyc;
02935 etime_constraint.constraint =
02936 _ops_in_cur_cyc.empty() ? AS_EARLY_AS_POSSIBLE :
02937 NO_LATER;
02938
02939 CANDIDATE* cand =
02940 _heur_mgr.Select_Best_Candidate (
02941 *_cand_mgr.M_Ready_Cand_List (),
02942 *_cand_mgr.P_Ready_Cand_List (),
02943 _target_bb,
02944 &etime_constraint);
02945
02946 if (!cand) { return ; }
02947
02948 if (!CGGRP_Issue_OP(cand->Op())) {
02949
02950
02951
02952
02953 if (_heur_mgr.Trace_Cand_Sel_Enabled ()) {
02954 _heur_mgr.Trace_Cand_Sel_Process (
02955 "\tDiscard best candidate: structual hazard!!\n");
02956 }
02957
02958 _cand_mgr.Get_Cand_List (cand)->Set_Cand_Has_Been_Tried (cand);
02959 continue;
02960 }
02961
02962
02963
02964
02965
02966
02967
02968
02969
02970
02971
02972
02973
02974
02975
02976
02977 BB *cand_home_bb = OP_bb (cand->Op()) ;
02978
02979 SRC_BB_INFO* src_info = _src_bb_mgr.Get_Src_Info (cand_home_bb);
02980 if (cand_home_bb != _target_bb &&
02981 _dflow_mgr.Upward_Sched_Kill_LiveOut_Defs (
02982 cand, src_info, &_cflow_mgr)) {
02983
02984 if ( IPFEC_Glos_Enable_Renaming &&
02985 !IPFEC_Query_Skiplist (glos_rename_skip_bb, BB_id(cand_home_bb), Current_PU_Count()) &&
02986 !IPFEC_Query_Skiplist (glos_rename_skip_op, OP_map_idx(cand->Op()), BB_id(cand_home_bb)) &&
02987 _heur_mgr.Renaming_Is_Profitable(cand)) {
02988
02989 Renaming(cand);
02990 } else {
02991
02992 _cand_mgr.Get_Cand_List (cand)-> Erase_Cand (cand);
02993 if (_heur_mgr.Trace_Cand_Sel_Enabled ()) {
02994 _heur_mgr.Trace_Cand_Sel_Process(
02995 "\tDiscard best candidate since it kill some live out TN");
02996 }
02997
02998 continue ;
02999 }
03000 }
03001
03002 #ifdef Is_True_On
03003
03004 if (!_ops_in_cur_cyc.empty ()) {
03005 Is_True (_cur_cyc == etime_constraint.threshold ,
03006 ("best candidate [OP%3d][BB%3d] should be issued exactly"
03007 " at cycle %d",
03008 OP_map_idx(cand->Op()),
03009 BB_id(OP_bb(cand->Op())),
03010 _cur_cyc));
03011 } else {
03012 Is_True (_cur_cyc <= etime_constraint.threshold,
03013 ("best candidate [OP%3d][BB%3d] should be issued"
03014 " before cycle %d",
03015 OP_map_idx(cand->Op()),
03016 BB_id(OP_bb(cand->Op())),
03017 _cur_cyc));
03018 }
03019 #endif
03020
03021 _cur_cyc = etime_constraint.threshold ;
03022
03023
03024
03025 OP* op = cand->Op ();
03026 if (OP_br(op)) { commit_br = TRUE; }
03027
03028 Commit_Schedule (*cand);
03029
03030 if (OP_call(op) &&
03031 !IPFEC_Glos_Motion_Across_Calls) {
03032 return;
03033 }
03034 }
03035
03036
03037 if (commit_br && _prepass) {
03038
03039 BB* b;
03040 BB_VECTOR bbs(&_mem_pool);
03041
03042 for (b = BB_Fall_Thru_Successor (_target_bb); b ;
03043 b = BB_Fall_Thru_Successor (b)) {
03044
03045 if (!BB_Unique_Predecessor (b)) {
03046 b = NULL; break;
03047 }
03048
03049
03050 if (!BB_length(b)) { continue ; }
03051
03052
03053 if (BB_length(b) == 1 && BB_branch_op (b)) {
03054 bbs.push_back (b);
03055 if (BB_edge_splitting(b)) { continue; } else break ;
03056 }
03057
03058 b = NULL; break;
03059 }
03060
03061 #ifdef TARG_IA64
03062 if (b && BB_length(b) == 1 && BB_branch_op(b)) {
03063 if (::Home_Region (b) == _region) {
03064 OP* br = BB_branch_op(b);
03065 if (br && CGGRP_Issue_OP (br, FALSE)) {
03066
03067 for (BB_VECTOR_ITER iter = bbs.begin () ;
03068 iter != bbs.end () ; iter++) {
03069
03070 _multiway_br_candidates = BB_SET_Union1D
03071 (_multiway_br_candidates, *iter, &_mem_pool);
03072
03073 _multiway_br_span_bbs.push_back (*iter);
03074 }
03075 }
03076 }
03077 }
03078 #endif
03079 }
03080 }
03081
03082
03083
03084
03085
03086
03087
03088
03089
03090
03091
03092 BOOL
03093 SCHEDULER :: No_New_Cycle (void) {
03094
03095 BOOL no_new_cyc = FALSE ;
03096
03097 if (BB_length(_target_bb) == 0 ||
03098 OP_Scheduled(BB_last_op(_target_bb))) {
03099 no_new_cyc = TRUE;
03100 }
03101
03102 #ifdef Is_True_On
03103 if (!no_new_cyc) {
03104 Is_True (!_cand_mgr.Cand_Lst_Is_Empty (),
03105 ("Candidate list is Empty!"));
03106 }
03107 #endif
03108
03109 return no_new_cyc;
03110
03111 }
03112
03113
03114
03115
03116
03117
03118
03119
03120
03121
03122 BOOL
03123 SCHEDULER::Need_Resched_To_Obtain_Better_Performance (void) {
03124
03125
03126
03127 if (_sched_times >= (MAX_SCHED_TIMES - 1)) { return FALSE ; }
03128
03129 if (_src_bb_mgr.Src_BBs ()->size () <= 1) {
03130 return FALSE ;
03131 }
03132
03133 if (_cand_mgr.Cand_Lst_Is_Empty ()) {
03134 return FALSE;
03135 }
03136
03137 if (_upward_motion_num <= 0) {
03138 return FALSE;
03139 }
03140
03141 return TRUE;
03142 }
03143
03144
03145
03146
03147
03148
03149
03150
03151 BOOL Should_Skip( int before, int after, int equal, int id )
03152 {
03153 if( equal >= 0 )
03154 if( id == equal )
03155 return TRUE;
03156
03157 if( (before == -1) && (after == -1) )
03158 return FALSE;
03159
03160
03161 if( before == -1 )
03162 if( id > after )
03163 return TRUE;
03164 else
03165 return FALSE;
03166
03167
03168 if( after == -1 )
03169 if( id < before )
03170 return TRUE;
03171 else
03172 return FALSE;
03173
03174
03175
03176
03177 if( before <= after ){
03178
03179 if( (id < before) || (id > after) )
03180 return TRUE;
03181 else
03182 return FALSE;
03183 }else{
03184 if( (id < before) && (id > after) )
03185 return TRUE;
03186 else
03187 return FALSE;
03188 }
03189 }
03190
03191 static BOOL Local_Sched_PU_Should_Skip(int pu_id)
03192 {
03193 BOOL skip = Should_Skip( CG_local_sched_pu_skip_before,
03194 CG_local_sched_pu_skip_after,
03195 CG_local_sched_pu_skip_equal,
03196 pu_id );
03197 return skip;
03198 }
03199
03200 static BOOL Local_Sched_OP_Should_Skip()
03201 {
03202 if(CG_local_sched_op_skip_after==-1)
03203 return FALSE;
03204
03205 return _Local_Insn_Op_id > CG_local_sched_op_skip_after? TRUE:FALSE;
03206 }
03207
03208 static void Local_Sched_Opid_Incr()
03209 {
03210 _Local_Insn_Op_id++;
03211 }
03212
03213 static BOOL BB_Should_Skip(BB* bb)
03214 {
03215 int id = BB_id(bb);
03216 BOOL skip = Should_Skip( CG_local_sched_bb_skip_before,
03217 CG_local_sched_bb_skip_after,
03218 CG_local_sched_bb_skip_equal,
03219 id );
03220 return skip;
03221 }
03222
03223
03224
03225
03226
03227
03228
03229
03230
03231
03232
03233
03234 void
03235 SCHEDULER::Schedule_Region (void) {
03236
03237 if (!Sched_Rgn_Preproc ()) return;
03238
03239 TOPDOWN_SCHED_SEQ seq (_region, &_mem_pool);
03240 for (_target_bb = seq.First ();
03241 _target_bb ;
03242 _target_bb = seq.Next()) {
03243
03244 if (!Glos_Should_Sched_This_BB (_target_bb)) {
03245 Isolate_BB_From_Sched_Scope (_target_bb);
03246 continue ;
03247 }
03248
03249 Bug_Workaround_Before_Schedule_BB ();
03250 Glos_Sched_BB_Preproc ();
03251
03252 BOOL no_new_cycle = FALSE;
03253 OP * xfer_op = BB_xfer_op(_target_bb);
03254
03255 do {
03256 do {
03257 Schedule_Cycle ();
03258 Cycle_Advance ();
03259 } while (!No_New_Cycle ());
03260
03261 Glos_Sched_BB_Postproc ();
03262
03263 if (Need_Resched_To_Obtain_Better_Performance ()) {
03264 Adjust_Status_For_Resched ();
03265
03266 CGGRP_Begin_BB (_target_bb);
03267 } else {
03268 break ;
03269 }
03270 } while (TRUE);
03271
03272 Bug_Workaround_After_Schedule_BB ();
03273
03274 }
03275
03276 Sched_Rgn_Postproc ();
03277 }
03278
03279
03280 #if defined(TARG_SL) || defined(TARG_SL2)
03281
03282
03283
03284
03285
03286
03287
03288
03289 void
03290 SCHEDULER::Schedule_BB_Driver()
03291 {
03292 if (BB_length(_target_bb) == 0) { return; }
03293
03294 _src_bb_mgr.Find_Src_BBs (_region, _target_bb,
03295 &_cflow_mgr, _prepass);
03296
03297
03298 _dag_constructor.Build_DAG ();
03299
03300
03301
03302 if (SCHED_TF_DUMP_DAG) {
03303 Dump_DAG(); fprintf(TFile, "\n");
03304 }
03305
03306 CGGRP_Init (_target_bb);
03307 _heur_mgr.Initialize (_target_bb,&_cflow_mgr);
03308
03309 Schedule_BB();
03310
03311 if (BB_length(_target_bb)) CGGRP_End_BB();
03312
03313 #ifndef TARG_SL
03314
03315 Verify();
03316 #endif
03317
03318 if (_prepass) Postprocess_GP_def_op ();
03319
03320 CG_DEP_Delete_Graph (_target_bb) ;
03321
03322 return;
03323 }
03324 #endif
03325
03326
03327
03328
03329
03330
03331
03332
03333
03334
03335
03336
03337
03338
03339
03340
03341
03342 #if defined (TARG_SL2)
03343 void
03344 SCHEDULER::Schedule_BB (BOOL reschd) {
03345 #else
03346 void
03347 SCHEDULER::Schedule_BB (void) {
03348 #endif
03349
03350 _heur_mgr.Adjust_Heur_Stuff_When_BB_Changed (_target_bb,_src_bb_mgr);
03351
03352
03353 if (_prepass) {
03354 Identify_Cannot_Spec_OPs (_target_bb);
03355 Preprocess_GP_def_op () ;
03356 }
03357 #if defined(TARG_SL)
03358 moved_op_num = 0;
03359 #endif
03360 #if defined(TARG_SL)
03361 if ((!_prepass) && (!_global) &&
03362 CG_Gen_16bit && ((CG_localsch_pre_size > 1) || ((CG_localsch_pre_size == 1) && !BB_loop_head_bb(_target_bb))))
03363 {
03364 _heur_mgr.Set_Sched_For_CodeSize_Spec();
03365 _heur_mgr.Reset_prev_unpaired_16bit();
03366 }
03367 #endif
03368
03369
03370 Find_All_Candidates ();
03371
03372 Init_Sched_Status () ;
03373
03374 CGGRP_Begin_BB (_target_bb);
03375
03376 BOOL last_op_sched = FALSE ;
03377
03378 CAND_LIST *m_ready_cand = _cand_mgr.M_Ready_Cand_List ();
03379 CAND_LIST *p_ready_cand = _cand_mgr.P_Ready_Cand_List ();
03380
03381 while (TRUE) {
03382 while (!m_ready_cand->Cand_Lst_Is_Empty ()) {
03383
03384 if(CGGRP_Cycle_Full() || m_ready_cand->All_Cands_Have_Been_Tried() )
03385 Cycle_Advance();
03386
03387 E_Time_Constraint etime_constraint;
03388 etime_constraint.threshold = _cur_cyc;
03389 etime_constraint.constraint = _ops_in_cur_cyc.empty() ?
03390 AS_EARLY_AS_POSSIBLE :
03391 NO_LATER;
03392 CANDIDATE* cand = _heur_mgr.Select_Best_Candidate (
03393 *m_ready_cand,
03394 *p_ready_cand,
03395 _target_bb,
03396 &etime_constraint);
03397
03398 if (!cand) continue ;
03399
03400 if (!CGGRP_Issue_OP(cand->Op())) {
03401 _cand_mgr.Get_Cand_List(cand)->Set_Cand_Has_Been_Tried (cand);
03402
03403 if (_heur_mgr.Trace_Cand_Sel_Enabled ()) {
03404 _heur_mgr.Trace_Cand_Sel_Process (
03405 "\tDiscard best candidate due to structual hazard\n");
03406 }
03407
03408 continue;
03409
03410 }
03411
03412 #ifdef Is_True_On
03413
03414 if (!_ops_in_cur_cyc.empty ()) {
03415 Is_True (_cur_cyc == etime_constraint.threshold ,
03416 ("best candidate [OP%3d][BB%3d] should be issued exactly"
03417 " at cycle %d",
03418 OP_map_idx(cand->Op()),
03419 BB_id(OP_bb(cand->Op())),
03420 _cur_cyc));
03421 } else {
03422 Is_True (_cur_cyc <= etime_constraint.threshold,
03423 ("best candidate [OP%3d][BB%3d] should be issued"
03424 " before cycle %d",
03425 OP_map_idx(cand->Op()),
03426 BB_id(OP_bb(cand->Op())),
03427 _cur_cyc));
03428 }
03429 #endif
03430
03431 _cur_cyc = etime_constraint.threshold ;
03432
03433 Commit_Schedule(*cand);
03434
03435 #if defined(TARG_SL)
03436 if(_heur_mgr.Sched_For_Codesize_Spec()) {
03437 if (!_heur_mgr.Prev_unpaired_16bit() && OP_16bit_op(cand->Op()))
03438 _heur_mgr.Set_prev_unpaired_16bit();
03439 else
03440 _heur_mgr.Reset_prev_unpaired_16bit();
03441
03442 if (SCHED_TF_DUMP_CS_PROCESS) {
03443 fprintf(TFile, "commit sched: (%d)\t", _cur_cyc);
03444 Print_OP_No_SrcLine(cand->Op());
03445 }
03446 }
03447 #endif
03448
03449 Local_Sched_Opid_Incr();
03450 if(Local_Sched_OP_Should_Skip()) {
03451 last_op_sched=TRUE;
03452 break;
03453 }
03454
03455 last_op_sched |= OP_Scheduled (BB_last_op(_target_bb)) ;
03456
03457 #if defined(TARG_SL) || defined(TARG_SL2)
03458 if(CG_bb_sched_op_num_max) {
03459 if(moved_op_num == CG_bb_sched_op_num_max) {
03460 last_op_sched = TRUE;
03461 fprintf(TFile, "last moved op is \n");
03462 Print_OP_No_SrcLine(cand->Op());
03463 break;
03464 }
03465 }
03466
03467 if( _heur_mgr.Round_Robin_Cand_Sel() && cand->Match_Model() )
03468 _heur_mgr.Update_Cand_Sel_Model_Status();
03469 #endif
03470 }
03471
03472 if (last_op_sched) break ;
03473
03474 Cycle_Advance () ;
03475 }
03476
03477
03478 BB_cycle(_target_bb) = BB_length(_target_bb) ? _cur_cyc + 1 : 0;
03479
03480
03481
03482 return;
03483 }
03484
03485
03486
03487
03488
03489
03490
03491
03492
03493
03494 void
03495 SCHEDULER::Renaming (CANDIDATE* cand)
03496 {
03497 OP* op = cand->Op();
03498 BB* home_bb = OP_bb(op);
03499 OP* copy_op = NULL;
03500 TN *orig_tn = OP_result(op, 0);
03501 TN* new_tn = Dup_TN(orig_tn);
03502
03503 FmtAssert(OP_results(op) == 1,
03504 ("We don't do renaming for a multi-assignment OP: [OP:%3d][BB:%3d]\n",
03505 OP_map_idx(op), BB_id(OP_bb(op))));
03506
03507
03508
03509 for (OP* tmp_op = OP_next(op); tmp_op; tmp_op = OP_next(tmp_op)) {
03510 for (INT i = 0; i < OP_opnds(tmp_op); i++) {
03511 if (orig_tn == OP_opnd(tmp_op, i))
03512 Set_OP_opnd(tmp_op, i, new_tn);
03513 }
03514 for (INT i = 0; i < OP_results(tmp_op); i++) {
03515 if (orig_tn == OP_result(tmp_op, i))
03516 Set_OP_result(tmp_op, i, new_tn);
03517 }
03518 }
03519
03520
03521
03522 if (_dflow_mgr.Are_Defs_Live_Out(op, home_bb)) {
03523 #ifdef TARG_SL
03524 copy_op = Mk_OP((TN_is_float(orig_tn) ? TOP_mov_s : TOP_or), orig_tn, new_tn, Zero_TN);
03525 #else
03526 copy_op = Mk_OP(CGTARG_Copy_Op(TN_size(orig_tn), TN_is_float(orig_tn)),
03527 orig_tn, OP_opnd(op, OP_PREDICATE_OPND), new_tn);
03528 #endif
03529 BB_Insert_Op_After(home_bb, op, copy_op);
03530 }
03531
03532
03533
03534 Maintain_Dep_Arcs_After_Renaming(op, copy_op);
03535
03536
03537
03538 if(copy_op) {
03539 SCHED_BB_ANNOT* bb_annot = sched_annot.Get_BB_Annot (home_bb);
03540 bb_annot->Init_New_OP_Annot (copy_op);
03541 _heur_mgr.Compute_Heur_Data_For_Inserted_OP (copy_op);
03542 Set_OP_renamed(copy_op);
03543 }
03544
03545
03546
03547 Set_OP_result(op, 0, new_tn);
03548 Set_OP_renamed(op);
03549
03550 }
03551
03552
03553
03554
03555
03556
03557
03558
03559
03560 void
03561 SCHEDULER::Maintain_Dep_Arcs_After_Renaming (OP* renamed_op, OP* copy_op)
03562 {
03563 for (ARC_LIST* arcs = OP_succs(renamed_op); arcs; ) {
03564 ARC *arc = ARC_LIST_first(arcs);
03565 arcs = ARC_LIST_rest(arcs);
03566 OP* succ = ARC_succ (arc);
03567 switch (ARC_kind(arc)) {
03568 case CG_DEP_REGOUT:
03569 if (copy_op) {
03570 if (OP_bb(renamed_op) != OP_bb(succ)) {
03571 new_arc_with_latency(ARC_kind(arc), copy_op, succ, ARC_latency(arc),
03572 ARC_omega(arc), ARC_opnd(arc), ARC_is_definite(arc));
03573 CG_DEP_Detach_Arc(arc);
03574 } else {
03575 new_arc(CG_DEP_REGIN, succ, copy_op, 0, 0, TRUE);
03576 }
03577 }
03578 break;
03579 case CG_DEP_REGIN:
03580 if (copy_op && OP_bb(renamed_op) != OP_bb(succ)) {
03581 new_arc_with_latency(CG_DEP_REGIN, copy_op, succ, ARC_latency(arc),
03582 ARC_omega(arc), ARC_opnd(arc), ARC_is_definite(arc));
03583 CG_DEP_Detach_Arc(arc);
03584 }
03585 break;
03586 case CG_DEP_PREBR:
03587 case CG_DEP_POSTBR:
03588 #ifdef TARG_IA64
03589 case CG_DEP_PRECHK:
03590 case CG_DEP_POSTCHK:
03591 #endif
03592 case CG_DEP_SCC:
03593 case CG_DEP_MISC:
03594 if (copy_op) {
03595 new_arc_with_latency(ARC_kind(arc), copy_op, succ, ARC_latency(arc),
03596 ARC_omega(arc), ARC_opnd(arc), ARC_is_definite(arc));
03597 }
03598 break;
03599 default:
03600 break;
03601 }
03602 }
03603
03604 for (ARC_LIST* arcs = OP_preds(renamed_op); arcs; ) {
03605 ARC *arc = ARC_LIST_first(arcs);
03606 arcs = ARC_LIST_rest(arcs);
03607 OP* pred = ARC_pred (arc);
03608 switch (ARC_kind(arc)) {
03609 case CG_DEP_REGOUT:
03610 if (copy_op) {
03611 new_arc_with_latency(ARC_kind(arc), pred, copy_op, ARC_latency(arc),
03612 ARC_omega(arc), ARC_opnd(arc), ARC_is_definite(arc));
03613 CG_DEP_Detach_Arc(arc);
03614 }
03615 break;
03616 default:
03617 break;
03618 }
03619 }
03620
03621 if (copy_op) {
03622 new_arc(CG_DEP_REGIN, renamed_op, copy_op, 0, 0, TRUE);
03623 }
03624 }
03625
03626
03627
03628
03629
03630
03631
03632
03633
03634
03635 void
03636 SCHEDULER::Clean_Up (BB* bb) {
03637 OP *op, *next_op;
03638
03639 Reset_BB_scheduled (bb);
03640 for (op = BB_first_op(bb); op; op = next_op) {
03641
03642 next_op = OP_next(op);
03643
03644 if (OP_noop(op)) {
03645 BB_Remove_Op(bb, op);
03646 } else {
03647 Reset_OP_Scheduled (op);
03648 #ifdef TARG_IA64
03649 Reset_OP_start_bundle(op);
03650 Reset_OP_end_group(op);
03651 Reset_OP_bundled(op);
03652 Reset_OP_m_unit(op);
03653 #endif
03654 }
03655 }
03656 }
03657
03658
03659
03660
03661
03662
03663
03664
03665 #ifdef TARG_IA64
03666 SCHEDULER::SCHEDULER (BB* bb, BOOL prepass ,PRDB_GEN *prdb) :
03667 _dag_constructor (bb,prdb),
03668 _cand_mgr(&_mem_pool),
03669 _heur_mgr(&_mem_pool),
03670 _src_bb_mgr(&_mem_pool),
03671 _ops_in_cur_cyc(OP_ALLOC(&_mem_pool)),
03672 _multiway_br_span_bbs(&_mem_pool),
03673 _global(FALSE), _prepass(prepass)
03674 #else
03675 SCHEDULER::SCHEDULER (BB* bb, BOOL prepass) :
03676 _dag_constructor (bb),
03677 _cand_mgr(&_mem_pool),
03678 _heur_mgr(&_mem_pool),
03679 _src_bb_mgr(&_mem_pool),
03680 _ops_in_cur_cyc(OP_ALLOC(&_mem_pool)),
03681 _global(FALSE), _prepass(prepass)
03682 #endif
03683 {
03684 _region = NULL;
03685 _target_bb = bb,
03686
03687 Get_Sched_Opts (prepass);
03688 Clean_Up(bb);
03689
03690 #ifdef TARG_IA64
03691
03692 _multiway_br_candidates = NULL;
03693 #endif
03694
03695 _cflow_mgr.Init (_target_bb);
03696 sched_annot.Init (_target_bb);
03697
03698 }
03699
03700 #ifdef TARG_IA64
03701 SCHEDULER::SCHEDULER (struct tagRGN_INFO * rgn_info, BOOL prepass,
03702 PRDB_GEN * prdb) :
03703 _dag_constructor (rgn_info->rgn, prdb,
03704 INCLUDE_ASSIGNED_REG_DEPS,
03705 INCLUDE_MEMREAD_ARCS,
03706 NO_MEMIN_ARCS,
03707 INCLUDE_CONTROL_ARCS),
03708 _cand_mgr(&_mem_pool),
03709 _src_bb_mgr(&_mem_pool),
03710 _ops_in_cur_cyc(OP_ALLOC(&_mem_pool)),
03711 _heur_mgr(&_mem_pool),
03712 _multiway_br_span_bbs(&_mem_pool),
03713 _global (TRUE), _prepass(TRUE)
03714 #else
03715 SCHEDULER::SCHEDULER (struct tagRGN_INFO * rgn_info, BOOL prepass) :
03716 _dag_constructor (rgn_info->rgn,
03717 INCLUDE_ASSIGNED_REG_DEPS,
03718 INCLUDE_MEMREAD_ARCS,
03719 NO_MEMIN_ARCS,
03720 INCLUDE_CONTROL_ARCS),
03721 _cand_mgr(&_mem_pool),
03722 _src_bb_mgr(&_mem_pool),
03723 _ops_in_cur_cyc(OP_ALLOC(&_mem_pool)),
03724 _heur_mgr(&_mem_pool),
03725 _global (TRUE), _prepass(TRUE)
03726 #endif
03727 {
03728 _region = rgn_info->rgn ;
03729 _target_bb = NULL ;
03730
03731 Get_Sched_Opts (prepass);
03732 _cflow_mgr.Init (_region) ;
03733 sched_annot.Init (_region);
03734
03735 for (TOPOLOGICAL_REGIONAL_CFG_ITER cfg_iter(_region->Regional_Cfg());
03736 cfg_iter != 0; ++cfg_iter) {
03737
03738 if ((*cfg_iter)->Is_Region()) {
03739 continue;
03740 } else {
03741 Clean_Up((*cfg_iter)->BB_Node());
03742 }
03743 }
03744
03745 #ifdef TARG_IA64
03746
03747 _multiway_br_candidates = BB_SET_Create_Empty (PU_BB_Count, &_mem_pool);
03748 #endif
03749
03750 }
03751
03752 SCHEDULER::~SCHEDULER () {
03753 _heur_mgr.Finialize ();
03754 CGGRP_Fini ();
03755 }
03756
03757
03758
03759
03760
03761
03762
03763
03764
03765
03766
03767
03768
03769
03770
03771
03772
03773
03774
03775
03776
03777
03778
03779
03780
03781
03782
03783
03784
03785 void
03786 Global_Insn_Sched_Preproc (
03787 REGION_TREE * rgn_tree,
03788 INT& how_many_rgn_need_sched) {
03789
03790 how_many_rgn_need_sched = 0 ;
03791
03792 Init_Split_PU_Entry_Or_Exit_BB ();
03793
03794 Acquire_Region_Info (rgn_tree);
03795
03796 for (INNERMOST_REGION_FIRST_ITER iter(rgn_tree);
03797 iter != 0 ; ++iter) {
03798
03799 RGN_INFO* rgn_info = Get_Region_Info (*iter);
03800
03801 #ifdef Is_True_On
03802 if (rgn_info->skip_reason == SKIP_RGN_DEBUG) {
03803 DevWarn ("Skip schedule RGN:%d of PU:%d",
03804 rgn_info->rgn->Id (), Current_PU_Count ());
03805 }
03806 #endif
03807
03808 if (rgn_info->skip_reason != SKIP_RGN_NONE) { continue ; }
03809
03810
03811
03812 rgn_info->rgn->Edge_Splitting () ;
03813
03814 if (RGN_CFLOW_MGR::Critical_Edge_Present(rgn_info->rgn)) {
03815
03816
03817
03818
03819
03820
03821 rgn_info->skip_reason = SKIP_RGN_CRITICAL_EDGE;
03822 continue ;
03823 }
03824
03825 ++ how_many_rgn_need_sched ;
03826
03827
03828
03829 if (IPFEC_Glos_Split_Entry_BB) {
03830 Split_PU_Entry_BB (rgn_info->rgn);
03831 }
03832
03833
03834
03835 if (IPFEC_Glos_Split_Exit_BB) {
03836 Split_PU_Exit_BB (rgn_info->rgn);
03837 }
03838 }
03839
03840
03841 GRA_LIVE_Init (NULL);
03842 }
03843
03844 void
03845 Global_Insn_Sched_Postproc (void) {
03846
03847
03848
03849 Merge_All_Splitted_Entry_and_Exit_BB ();
03850
03851
03852
03853
03854 GRA_LIVE_Init (NULL);
03855
03856 Free_Region_Info_Memory () ;
03857 }
03858
03859
03860
03861
03862
03863
03864
03865
03866
03867
03868
03869
03870
03871
03872
03873
03874
03875
03876
03877
03878
03879
03880
03881
03882
03883
03884
03885
03886 extern void SCHED_Dump_IR (BOOL prepass,
03887 BOOL bef_sched,
03888 BOOL gcm,FILE *f=stderr) ;
03889
03890
03891
03892
03893
03894
03895
03896
03897
03898
03899
03900
03901
03902
03903
03904 void
03905 Local_Insn_Sched (BOOL prepass)
03906 {
03907 int pu_id = Current_PU_Count();
03908 if( Local_Sched_PU_Should_Skip(pu_id) ){
03909 printf(" .. current pu is skipped by LIS, %s\n",
03910 prepass ? "Prepasss" : "Postpass" );
03911 return;
03912 }
03913
03914 Set_Error_Phase (_Cur_Phase_Name = _Local_Insn_Sched_Phase_Name);
03915 #ifdef TARG_IA64
03916 Start_Timer(T_Ipfec_LOCS_CU);
03917 #endif
03918 Get_Sched_Opts (prepass);
03919 if (SCHED_TF_DUMP_IR) SCHED_Dump_IR (prepass,
03920 TRUE,
03921 FALSE,
03922 TFile) ;
03923
03924 for (BB* bb = REGION_First_BB; bb != NULL; bb = BB_next(bb)) {
03925
03926
03927 if (BB_length(bb) == 0) { continue; }
03928
03929
03930 if (prepass) {
03931 #ifdef TARG_SL
03932 if (!BB_Should_Skip(bb) && !BB_scheduled(bb) && !BB_reg_alloc(bb) &&
03933 !BB_entry(bb) && !BB_exit(bb)) {
03934 #else
03935 if (!BB_scheduled(bb) && !BB_reg_alloc(bb)) {
03936 #endif
03937 SCHEDULER local_scheduler(bb, prepass);
03938 local_scheduler.Schedule_BB_Driver();
03939 }
03940 } else {
03941
03942 #ifdef TARG_IA64
03943 if (BB_chk_split_head(bb)){
03944 bb = Handle_Chk_Split_Bunch(bb);
03945 continue;
03946 }
03947 #endif
03948 #ifdef TARG_SL
03949 if (!CG_Gen_16bit) {
03950 extern void Repl_Tmp_TN(BB *bb);
03951 Repl_Tmp_TN(bb);
03952 }
03953
03954 if( ! BB_Should_Skip(bb)
03955 && ( !BB_scheduled(bb)
03956 || ( !BB_scheduled(bb) && BB_scheduled_hbs(bb) )
03957 || ( !prepass
03958 && CG_Gen_16bit
03959 && CG_localsch_pre_size > 0
03960 && !BB_SCHED_SIZE(bb) )
03961 || BB_entry(bb)
03962 || BB_exit(bb)
03963 )
03964 ) {
03965 #else
03966 if (!BB_scheduled(bb) || BB_scheduled_hbs(bb) || BB_entry(bb) ||
03967 BB_exit(bb)){
03968 #endif
03969
03970 if (IPFEC_Query_Skiplist(locs_skip_bb,
03971 BB_id(bb),
03972 Current_PU_Count ())) {
03973
03974 DevWarn ("Skip local schedule BB:%d of PU:%d",
03975 BB_id(bb),
03976 Current_PU_Count ());
03977
03978 SCHEDULER::Clean_Up(bb);
03979 Handle_All_Hazards (bb);
03980
03981 } else {
03982 SCHEDULER local_scheduler(bb, prepass);
03983 local_scheduler.Schedule_BB_Driver();
03984
03985
03986 }
03987 }
03988 }
03989 Set_BB_scheduled(bb);
03990
03991 #ifdef TARG_SL
03992 if (!prepass && CG_Gen_16bit && (CG_localsch_pre_size > 0)) {
03993 Set_BB_sched_size(bb);
03994 }
03995 #endif
03996
03997 }
03998
03999 if (SCHED_TF_DUMP_IR) SCHED_Dump_IR (prepass,
04000 FALSE,
04001 FALSE,
04002 TFile) ;
04003
04004
04005 for (BB *bp = REGION_First_BB; bp; bp = BB_next(bp)) {
04006 BB_Update_OP_Order(bp);
04007 }
04008 #ifdef TARG_IA64
04009 Stop_Timer(T_Ipfec_LOCS_CU);
04010 #endif
04011 }
04012
04013
04014
04015
04016
04017
04018
04019
04020
04021
04022
04023 static MEM_POOL loop_descr_pool;
04024 static MEM_POOL bb_cand_pool;
04025 static MEM_POOL op_sch_pool;
04026 void
04027 Perform_Global_Schedule (BOOL prepass) {
04028 #if 1
04029 BB* cand_bb;
04030 BB* bb;
04031 VECTOR cand_bbs;
04032 MEM_POOL_Initialize (&loop_descr_pool, "LOOP_DESCR_pool", FALSE);
04033 MEM_POOL_Push(&loop_descr_pool);
04034 MEM_POOL_Initialize (&bb_cand_pool, "BB_CAND_pool", FALSE);
04035 MEM_POOL_Push(&bb_cand_pool);
04036 MEM_POOL_Initialize (&op_sch_pool, "OPSCH_pool", FALSE);
04037 MEM_POOL_Push(&op_sch_pool);
04038
04039
04040 Calculate_Dominators();
04041 L_Save();
04042 LOOP_DESCR *loop_list;
04043 loop_list = LOOP_DESCR_Detect_Loops (&loop_descr_pool);
04044 cand_bbs = VECTOR_Init(PU_BB_Count+2, &bb_cand_pool);
04045
04046 for( bb = REGION_First_BB; bb!=NULL; bb = BB_next(bb))
04047 {
04048
04049 if(BB_entry(bb) || BB_exit(bb) || BB_scheduled(bb))
04050 continue;
04051
04052
04053
04054 BB_MAP bb_map;
04055 bb_map = BB_MAP_Create();
04056 _cg_dep_op_info = BB_MAP_Create();
04057 BB_OP_MAP omap = BB_OP_MAP_Create(bb, &op_sch_pool);
04058 BB_MAP_Set(_cg_dep_op_info, bb, omap);
04059
04060
04061 Compute_OPSCH (bb, _cg_dep_op_info, &op_sch_pool);
04062
04063
04064 for(cand_bb = REGION_First_BB; cand_bb != NULL; cand_bb=BB_next(cand_bb))
04065
04066 if(bb != cand_bb && BB1_BB2_Cntl_Equiv(bb, cand_bb)) {
04067 if(VECTOR_Member_Element(cand_bbs, cand_bb)) continue;
04068 VECTOR_Add_Element(cand_bbs, (void*) cand_bb);
04069 }
04070
04071
04072
04073
04074 #if 0
04075 for(INT i =0; i < BB_length(cand_bb); i++)
04076 {
04077 OP* op = Select_Best_Op(cand_bb);
04078
04079
04080
04081
04082 if(Can_OP_Move(from_bb, to_bb)) {
04083 BB_Remove_Op(from_bb, op);
04084 BB_Append_Op(to_bb, op);
04085 SCHEDULER local_scheduler(from_bb, prepass);
04086 local_scheduler.Schedule_BB();
04087 SCHEDULER local_scheduler(to_bb, prepass);
04088 local_scheduler.Schedule_BB();
04089 }
04090 }
04091 #endif
04092 }
04093 Free_Dominator_Info_Memory () ;
04094 MEM_POOL_Pop (&loop_descr_pool);
04095 MEM_POOL_Delete (&loop_descr_pool);
04096 MEM_POOL_Pop (&bb_cand_pool);
04097 MEM_POOL_Delete (&bb_cand_pool);
04098 MEM_POOL_Pop (&op_sch_pool);
04099 MEM_POOL_Delete (&op_sch_pool);
04100 L_Free();
04101
04102
04103 #else
04104 Is_True (prepass,
04105 ("Perform_Global_Schedule can't perform global sched after "
04106 "register allocation since the DAG constructio can't be "
04107 "properly be built with after register allocation"));
04108
04109 Get_Sched_Opts (prepass);
04110
04111 if (SCHED_TF_DUMP_IR) {
04112 SCHED_Dump_IR (prepass, TRUE,
04113 TRUE,
04114 TFile) ;
04115 }
04116
04117 Set_Error_Phase (_Cur_Phase_Name = _Global_Insn_Sched_Phase_Name);
04118 Start_Timer (T_Ipfec_GLOS_CU);
04119
04120
04121 INT32 sched_rgn_num = 0 ;
04122 REGION_TREE* rgn_tree = REGION_Get_Region_Tree ();
04123 Is_True (rgn_tree,
04124 ("NULL REGION tree, REGION_Form_Region_Tree() should be"
04125 " called before global instruction scheduling"));
04126
04127 Global_Insn_Sched_Preproc (rgn_tree, sched_rgn_num);
04128
04129 if (sched_rgn_num != 0) {
04130
04131 #ifdef TARG_IA64
04132 PRDB_GEN * prdb = NULL ;
04133 if (IPFEC_Enable_PRDB) {
04134 prdb = PRDB_Init(rgn_tree);
04135 }
04136 #endif
04137 Calculate_Dominator_Info (rgn_tree);
04138
04139 for (INNERMOST_REGION_FIRST_ITER iter(rgn_tree) ;
04140 iter != 0; ++iter) {
04141
04142 RGN_INFO* rgn_info = Get_Region_Info (*iter);
04143
04144 if (rgn_info->Skip_Sched_Reason () == SKIP_RGN_NONE) {
04145
04146 if (rgn_info->In_Abnormal_Loop ()) {
04147 Workaround_Dom_Info_For_In_Abnormal_Loop_Rgn
04148 (rgn_info->Region ()) ;
04149 }
04150
04151 #ifdef TARG_IA64
04152 SCHEDULER scheduler (rgn_info, TRUE, prdb);
04153 #else
04154 SCHEDULER scheduler (rgn_info, TRUE);
04155 #endif
04156 scheduler.Schedule_Region ();
04157
04158 } else if (rgn_info->Skip_Sched_Reason () ==
04159 SKIP_RGN_NO_FURTHER_OPT &&
04160 IPFEC_Glos_Code_Motion_Across_Nested_Rgn) {
04161
04162
04163
04164 if (rgn_info->Region ()->Entries ().size () == 1) {
04165 RGN_CFLOW_MGR rgn_cflow_mgr ;
04166 rgn_cflow_mgr.Init (rgn_info->Region ());
04167
04168 ::Build_Region_Summary (rgn_info->Region (),
04169 &rgn_cflow_mgr) ;
04170 }
04171 }
04172 }
04173
04174 #ifdef TARG_IA64
04175 if (prdb) { Delete_PRDB () ; prdb = NULL ; } ;
04176 #endif
04177 Free_Dominator_Info_Memory () ;
04178 }
04179
04180 Global_Insn_Sched_Postproc ();
04181
04182 if (SCHED_TF_DUMP_IR) SCHED_Dump_IR (prepass,
04183 FALSE,
04184 TRUE,
04185 TFile) ;
04186
04187 Stop_Timer(T_Ipfec_GLOS_CU);
04188
04189 GRA_LIVE_Recalc_Liveness (NULL);
04190 #endif // if 0
04191 }