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 #include "defs.h"
00030
00031
00032 #include <list>
00033 #include <vector>
00034 #include <map>
00035
00036
00037 #include "mempool.h"
00038 #include "mempool_allocator.h"
00039
00040
00041 #include "topcode.h"
00042 #include "op.h"
00043
00044 #include "bb.h"
00045 #include "bb_set.h"
00046
00047 #include "cgtarget.h"
00048 #include "be_util.h"
00049
00050 #include "tracing.h"
00051 #include "error.h"
00052
00053 #include "ipfec_defs.h"
00054 #include "ipfec_options.h"
00055
00056
00057 #include "gra_live.h"
00058
00059 #include "sched_util.h"
00060 #include "sched_cflow.h"
00061 #include "sched_rgn_info.h"
00062
00063 #define ACROSS_NODE_THRESHOLD 3
00064
00065
00066
00067
00068
00069
00070
00071
00072
00073 BOOL SCHED_TF_DUMP_IR = FALSE ;
00074 BOOL SCHED_TF_DUMP_DAG = FALSE ;
00075 BOOL SCHED_TF_DUMP_CAND = FALSE ;
00076 BOOL SCHED_TF_SUMMARY_DUMP = FALSE ;
00077 BOOL SCHED_TF_VERBOSE_DUMP = FALSE ;
00078 BOOL SCHED_TF_DRAW_GLBL_CFG = FALSE ;
00079 BOOL SCHED_TF_DRAW_RGNL_CFG = FALSE ;
00080 BOOL SCHED_TF_DRAW_LOCAL_DAG = FALSE ;
00081 BOOL SCHED_TF_DRAW_RGNL_DAG = FALSE ;
00082 BOOL SCHED_TF_TEST_SPEC = FALSE ;
00083 BOOL SCHED_TF_CANDSEL_DUMP = FALSE ;
00084 #if defined(TARG_SL)
00085 BOOL SCHED_TF_DUMP_CS_PROCESS = FALSE;
00086 #endif
00087
00088 #if defined(TARG_SL2)
00089
00090 BOOL SCHED_TF_DUMP_MACRO_INSN_COMBINATION = FALSE;
00091
00092
00093 BOOL SCHED_TF_DUMP_SATD_COMB = FALSE;
00094
00095
00096 BOOL SCHED_TF_DUMP_OP_MOVE_IN_BB = FALSE;
00097
00098 BOOL SCHED_TF_DUMP_CAND_SELECTION_PROCESS = FALSE;
00099
00100 BOOL SCHED_TF_DUMP_COND_MV_COMBINE = FALSE;
00101 #endif
00102
00103
00104 INT32 SAFE_CNTL_SPEC_PROB = ((REACH_PROB)(REACH_PROB_SCALE * 0.20f)) ;
00105 INT32 UNSAFE_CNTL_SPEC_PROB = ((REACH_PROB)(REACH_PROB_SCALE * 0.40f)) ;
00106 INT32 SPEC_SAFE_LOAD_WITHOUT_TRANSFORM_REACH_PROB =
00107 ((REACH_PROB)(REACH_PROB_SCALE * 0.65f)) ;
00108 static void
00109 get_trace_flags (BOOL prepass) {
00110
00111 if (prepass) {
00112
00113 SCHED_TF_DUMP_IR = Get_Trace (TP_A_GSCHED,DUMP_IR) ||
00114 Get_Trace (TKIND_IR, TP_A_GSCHED) ;
00115 SCHED_TF_DUMP_DAG = Get_Trace (TP_A_GSCHED,DUMP_DAG) ;
00116 SCHED_TF_DUMP_CAND = Get_Trace (TP_A_GSCHED,DUMP_CAND) ;
00117 SCHED_TF_SUMMARY_DUMP = Get_Trace (TP_A_GSCHED,SUMMARY_DUMP) ;
00118 SCHED_TF_VERBOSE_DUMP = Get_Trace (TP_A_GSCHED,VERBOSE_DUMP) ;
00119 SCHED_TF_DRAW_GLBL_CFG = Get_Trace (TP_A_GSCHED,DRAW_GLBL_CFG) ;
00120 SCHED_TF_DRAW_RGNL_CFG = Get_Trace (TP_A_GSCHED,DRAW_RGNL_CFG) ;
00121 SCHED_TF_DRAW_LOCAL_DAG = FALSE ;
00122 SCHED_TF_DRAW_RGNL_DAG = Get_Trace (TP_A_GSCHED,DRAW_RGNL_DAG) ;
00123 SCHED_TF_TEST_SPEC = Get_Trace (TP_A_GSCHED,TEST_SPEC) ;
00124 SCHED_TF_CANDSEL_DUMP = Get_Trace (TP_A_GSCHED,CANDSEL_DUMP) ;
00125 #if defined(TARG_SL2)
00126 SCHED_TF_DUMP_COND_MV_COMBINE = Get_Trace(TP_A_GSCHED, DUMP_COND_MV_COMBINE);
00127 #endif
00128 } else {
00129
00130 SCHED_TF_DUMP_IR = Get_Trace (TP_A_LSCHED,DUMP_IR) ||
00131 Get_Trace (TKIND_IR, TP_A_LSCHED) ;
00132 SCHED_TF_DUMP_DAG = Get_Trace (TP_A_LSCHED,DUMP_DAG) ;
00133 SCHED_TF_DUMP_CAND = Get_Trace (TP_A_LSCHED,DUMP_CAND) ;
00134 SCHED_TF_SUMMARY_DUMP = Get_Trace (TP_A_LSCHED,SUMMARY_DUMP) ;
00135 SCHED_TF_VERBOSE_DUMP = Get_Trace (TP_A_LSCHED,VERBOSE_DUMP) ;
00136 SCHED_TF_DRAW_GLBL_CFG = Get_Trace (TP_A_LSCHED,DRAW_GLBL_CFG) ;
00137 SCHED_TF_DRAW_RGNL_CFG = Get_Trace (TP_A_LSCHED,DRAW_RGNL_CFG) ;
00138 SCHED_TF_DRAW_LOCAL_DAG = Get_Trace (TP_A_LSCHED,DRAW_LOCAL_DAG);
00139 SCHED_TF_DRAW_RGNL_DAG = Get_Trace (TP_A_LSCHED,DRAW_RGNL_DAG) ;
00140 SCHED_TF_TEST_SPEC = Get_Trace (TP_A_LSCHED,TEST_SPEC) ;
00141 SCHED_TF_CANDSEL_DUMP = Get_Trace (TP_A_LSCHED,CANDSEL_DUMP) ;
00142 #if defined(TARG_SL)
00143 SCHED_TF_DUMP_CS_PROCESS = Get_Trace(TP_A_LSCHED,DUMP_CS_PURPOSE_PROCESS);
00144 #endif
00145 #if defined(TARG_SL2)
00146 SCHED_TF_DUMP_MACRO_INSN_COMBINATION = Get_Trace(TP_A_LSCHED, DUMP_MACRO_INSN_COMBINATION);
00147 SCHED_TF_DUMP_OP_MOVE_IN_BB = Get_Trace(TP_A_LSCHED, DUMP_OP_MOVE_IN_TARGET_BB);
00148 SCHED_TF_DUMP_CAND_SELECTION_PROCESS = Get_Trace(TP_A_LSCHED, DUMP_CAND_SELECTION_PROCESS);
00149 SCHED_TF_DUMP_SATD_COMB = Get_Trace(TP_A_LSCHED, DUMP_SATD_COMB);
00150 SCHED_TF_DUMP_COND_MV_COMBINE = Get_Trace(TP_A_LSCHED, DUMP_COND_MV_COMBINE);
00151 #endif
00152 }
00153
00154 }
00155
00156
00157 static void
00158 get_spec_prob (void) {
00159
00160 float f_safe_cntl_spec_prob , f_unsafe_cntl_spec_prob ;
00161
00162 if (IPFEC_safe_cntl_spec_prob) {
00163 sscanf (IPFEC_safe_cntl_spec_prob,"%f", &f_safe_cntl_spec_prob) ;
00164 if (f_safe_cntl_spec_prob >= 0.0 && f_safe_cntl_spec_prob <= 1.0) {
00165 SAFE_CNTL_SPEC_PROB = INT32(f_safe_cntl_spec_prob * REACH_PROB_SCALE);
00166 }
00167 }
00168
00169 if (IPFEC_unsafe_cntl_spec_prob) {
00170 sscanf (IPFEC_unsafe_cntl_spec_prob,"%f", &f_unsafe_cntl_spec_prob) ;
00171 if (f_unsafe_cntl_spec_prob >= 0.0 && f_unsafe_cntl_spec_prob <= 1.0) {
00172 UNSAFE_CNTL_SPEC_PROB = INT32(f_unsafe_cntl_spec_prob * REACH_PROB_SCALE);
00173 }
00174 }
00175 }
00176
00177 void
00178 Get_Sched_Opts (BOOL prepass) {
00179
00180 get_trace_flags (prepass) ;
00181 get_spec_prob () ;
00182
00183
00184 IPFEC_Glos_Reg_Pressure_Aware = FALSE ;
00185 }
00186
00187
00188
00189
00190
00191
00192
00193
00194
00195
00196 void
00197 CFG_NODE_MAP::Initialize_Map (REGION *rgn) {
00198
00199 _bb_map_vect.clear () ;
00200 _rgn_map_vect.clear () ;
00201
00202 for (TOPOLOGICAL_REGIONAL_CFG_ITER iter(rgn->Regional_Cfg()) ;
00203 iter != 0 ; ++ iter) {
00204
00205 if ((*iter)->Is_Region()) {
00206 _rgn_map_vect.push_back (
00207 tagNODE_ID_VAL_PAIR(NULL,(*iter)->Region_Node()->Id()));
00208 } else {
00209 _bb_map_vect.push_back (
00210 tagNODE_ID_VAL_PAIR(NULL,BB_id((*iter)->BB_Node())));
00211 }
00212 }
00213
00214 INT32 upbound = _bb_map_vect.size() - 1;
00215 if (upbound > 0) _bubble_sort (_bb_map_vect,0,upbound) ;
00216
00217 upbound = _rgn_map_vect.size() - 1 ;
00218 if (upbound > 0) _bubble_sort (_rgn_map_vect,0,upbound);
00219 }
00220
00221
00222 void
00223 CFG_NODE_MAP::Initialize_Map (BB *bb) {
00224 _bb_map_vect.clear () ;
00225 _rgn_map_vect.clear () ;
00226
00227 _bb_map_vect.push_back (NODE_ID_VAL_PAIR(NULL,BB_id(bb)));
00228 }
00229
00230 void
00231 CFG_NODE_MAP::_bubble_sort (
00232 _PAIR_VECT& vect, INT32 low_idx, INT32 hign_idx)
00233 {
00234 INT32 last_elem_idx = vect.size () - 1;
00235 BOOL change = TRUE;
00236
00237 for (INT32 upbound = last_elem_idx;
00238 change && upbound > 0 ; upbound--) {
00239
00240 change = FALSE;
00241
00242 for (INT32 j = 0 ; j < upbound; j ++) {
00243 INT32 tmp = vect[j].node_id - vect[j+1].node_id ;
00244
00245 if (tmp < 0) { continue ; }
00246
00247 if (tmp > 0) {
00248 NODE_ID_VAL_PAIR p = vect[j+1] ;
00249 vect[j+1] = vect[j]; vect[j] = p;
00250 } else {
00251 FmtAssert (FALSE, ("two node with identical id %d",
00252 vect[j].node_id)) ;
00253 }
00254
00255 change = TRUE;
00256 }
00257 }
00258 }
00259
00260
00261 INT32
00262 CFG_NODE_MAP::_find_elem (_PAIR_VECT& vect, INT32 id) {
00263 INT32 low = 1, high = vect.size();
00264
00265 while (low < high) {
00266 INT32 mid = ((low + high) >> 1) ;
00267 INT32 diff = vect[mid-1].node_id - id;
00268
00269 if (diff < 0) { low = mid + 1 ; continue ; }
00270 if (diff > 0) { high = mid - 1 ; continue ; }
00271 else return mid - 1;
00272 }
00273
00274 if (low > high) return -1 ;
00275 return vect[low-1].node_id == id ? low - 1 : -1 ;
00276 }
00277
00278 void
00279 CFG_NODE_MAP::_set_map (_PAIR_VECT& vect, INT32 id, void* value) {
00280 INT32 pos = _find_elem (vect, id) ;
00281 if (pos < 0) {
00282 vect.push_back (tagNODE_ID_VAL_PAIR(value,id));
00283 _bubble_sort (vect,0,vect.size()-1) ;
00284 pos = _find_elem (vect, id);
00285 Is_True (pos >= 0, ("fail to find element"));
00286 }
00287
00288 vect[pos].value = value ;
00289 }
00290
00291
00292
00293
00294
00295
00296
00297
00298
00299
00300 #define OP_INC_NUM (20)
00301
00302 inline void
00303 SCHED_BB_ANNOT::_set_op_annot (OP * op, SCHED_OP_ANNOT * annot) {
00304 Is_True (OP_bb(op) == _bb,
00305 ("BB%d is not OP[BB:%d map%d]'s home BB",
00306 BB_id(_bb), BB_id(OP_bb(op)), OP_map_idx(op)));
00307
00308 _annot_inited_ops =
00309 BS_Union1D (_annot_inited_ops,OP_map_idx(op),_mem_pool);
00310 BB_OP_MAP_Set (_ops_annot_map, op, (void*)annot);
00311 }
00312
00313
00314 SCHED_BB_ANNOT::SCHED_BB_ANNOT (BB * bb, MEM_POOL *mp) :
00315 _bb(bb), _mem_pool(mp)
00316 {
00317 _ops_annot_map = BB_OP_MAP_Create (bb, _mem_pool);
00318
00319 _1st_append_op = _last_prepend_op = NULL;
00320 _xfer_op = BB_xfer_op (bb);
00321
00322 _annot_inited_ops =
00323 BS_Create_Empty (BB_next_op_map_idx(_bb) + OP_INC_NUM, _mem_pool);
00324 _init_ops_annot () ;
00325 }
00326
00327
00328 SCHED_OP_ANNOT*
00329 SCHED_BB_ANNOT::Detach_OP_Annot (OP* op) {
00330
00331 SCHED_OP_ANNOT * op_annot = Get_OP_Annot (op) ;
00332 _annot_inited_ops = BS_Difference1D (_annot_inited_ops,
00333 OP_map_idx(op));
00334 return op_annot ;
00335 }
00336
00337
00338 void
00339 SCHED_BB_ANNOT::Attach_OP_Annot (OP * op, SCHED_OP_ANNOT * annot) {
00340 _set_op_annot (op,annot) ;
00341 }
00342
00343
00344 void
00345 SCHED_BB_ANNOT::_init_ops_annot (void) {
00346
00347 INT32 size = BB_length (_bb) + OP_INC_NUM;
00348 _annot_inited_ops = BS_Create_Empty (size, _mem_pool);
00349
00350 OP * op;
00351 FOR_ALL_BB_OPs (_bb, op) {
00352
00353 SCHED_OP_ANNOT * op_annot =
00354 CXX_NEW (SCHED_OP_ANNOT(op),_mem_pool);
00355
00356 BB_OP_MAP_Set (_ops_annot_map, op, (void*)op_annot);
00357
00358 _annot_inited_ops =
00359 BS_Union1D(_annot_inited_ops, OP_map_idx(op), _mem_pool);
00360 }
00361 }
00362
00363 SCHED_OP_ANNOT *
00364 SCHED_BB_ANNOT::Init_New_OP_Annot (OP* op) {
00365
00366 _annot_inited_ops =
00367 BS_Union1D (_annot_inited_ops, OP_map_idx(op), _mem_pool);
00368
00369 SCHED_OP_ANNOT * op_annot =
00370 CXX_NEW (SCHED_OP_ANNOT(op),_mem_pool);
00371 Set_OP_Annot (op, op_annot);
00372
00373 return op_annot;
00374 }
00375
00376
00377
00378
00379
00380
00381
00382
00383
00384
00385
00386
00387
00388
00389
00390
00391
00392
00393
00394
00395
00396
00397
00398 #define OP_INC_NUM (20)
00399
00400
00401
00402
00403
00404
00405
00406
00407
00408
00409
00410 INT32 SCHED_ANNOT::_inst_num = 0 ;
00411 SCHED_ANNOT sched_annot ;
00412
00413 SCHED_ANNOT::SCHED_ANNOT (void) {
00414 _node_map = NULL;
00415
00416 if (_inst_num++) {
00417 Is_True (FALSE,
00418 ("two instances of class SCHED_ANNOT live simutaneously!"));
00419 }
00420
00421 _rgn_scope = NULL;
00422 _local_scope = NULL;
00423 }
00424
00425 void
00426 SCHED_ANNOT::Init (REGION *scope) {
00427
00428 MEM_POOL_Pop (&_mem_pool);
00429 MEM_POOL_Push (&_mem_pool);
00430
00431 _node_map = CXX_NEW(CFG_NODE_MAP(&_mem_pool),&_mem_pool);
00432 _node_map -> Initialize_Map (scope) ;
00433
00434 for (TOPOLOGICAL_REGIONAL_CFG_ITER iter = scope->Regional_Cfg() ;
00435 iter != 0 ; ++iter) {
00436
00437 if ((*iter)->Is_Region()) {
00438
00439 REGION * rgn = (*iter)->Region_Node();
00440 _node_map->Set_Map (rgn,
00441 CXX_NEW(SCHED_RGN_ANNOT(rgn,&_mem_pool), &_mem_pool));
00442
00443 } else {
00444
00445 BB * bb = (*iter)->BB_Node();
00446 _node_map->Set_Map (bb,
00447 CXX_NEW(SCHED_BB_ANNOT(bb,&_mem_pool),&_mem_pool));
00448
00449 }
00450 }
00451
00452 _isolated_bbs = BB_SET_Create_Empty (PU_BB_Count+2,&_mem_pool);
00453
00454 _rgn_scope = scope;
00455 _local_scope = NULL;
00456 }
00457
00458 void
00459 SCHED_ANNOT::Init (BB *scope) {
00460
00461 MEM_POOL_Pop (&_mem_pool) ;
00462 MEM_POOL_Push (&_mem_pool);
00463
00464 _node_map = CXX_NEW(CFG_NODE_MAP(&_mem_pool),&_mem_pool);
00465 _node_map->Initialize_Map (scope);
00466 _node_map->Set_Map (scope,
00467 CXX_NEW(SCHED_BB_ANNOT(scope,&_mem_pool),&_mem_pool));
00468
00469 _isolated_bbs = BB_SET_Create_Empty (PU_BB_Count+2, &_mem_pool);
00470
00471 _rgn_scope = NULL;
00472 _local_scope = scope;
00473 }
00474
00475
00476
00477
00478
00479
00480
00481
00482
00483 void
00484 SCHED_ANNOT::Dump (FILE *f) {
00485
00486 if (!_node_map) {
00487 fprintf (f, "NULL\n"); return ;
00488 }
00489
00490
00491 if (_rgn_scope) {
00492 for (TOPOLOGICAL_REGIONAL_CFG_ITER iter = _rgn_scope->Regional_Cfg() ;
00493 iter != 0 ; ++iter) {
00494 if ((*iter) -> Is_Region()) {
00495 REGION *rgn = (*iter)->Region_Node();
00496 SCHED_RGN_ANNOT * rgn_annot =
00497 (SCHED_RGN_ANNOT *)_node_map->Get_Map (rgn);
00498
00499 fprintf (f, "RGN:%d ", rgn->Id()) ;
00500 if (!rgn_annot) fprintf (f, "NULL\n");
00501 else rgn_annot->Dump (f);
00502 } else {
00503 BB * bb = (*iter)->BB_Node () ;
00504 SCHED_BB_ANNOT * bb_annot =
00505 (SCHED_BB_ANNOT *)_node_map->Get_Map (bb);
00506
00507 fprintf (f, "BB:%d ", BB_id(bb));
00508 if (!bb_annot) fprintf (f, "NULL \n");
00509 else bb_annot->Dump (f);
00510 }
00511 }
00512 } else {
00513 SCHED_BB_ANNOT * bb_annot =
00514 (SCHED_BB_ANNOT *)_node_map->Get_Map(_local_scope);
00515
00516 fprintf (f, "BB:%d ", BB_id(_local_scope));
00517 if (bb_annot) fprintf (f, "NULL \n");
00518 else bb_annot->Dump (f);
00519 }
00520 }
00521
00522
00523
00524
00525
00526
00527
00528
00529
00530
00531
00532
00533
00534
00535
00536 const char *spec_text[] = {
00537 "non-spec", "cntl-spec", "data-spec", "comb-spec", "can't spec"
00538 };
00539
00540
00541
00542
00543
00544
00545
00546
00547
00548
00549
00550 BOOL
00551 Load_Has_Valid_Vaddr (OP* ld) {
00552 return OP_load (ld) && CGTARG_Can_Be_Speculative(ld);
00553 }
00554
00555 #ifdef TARG_IA64
00556
00557
00558
00559
00560
00561
00562
00563
00564
00565
00566
00567
00568 INT32
00569 CGTARG_adjust_latency (ARC* arc, ISSUE_PORT pred_port, ISSUE_PORT succ_port) {
00570
00571 OP* pred = ARC_pred(arc);
00572 OP* succ = ARC_succ(arc);
00573
00574
00575
00576
00577
00578
00579
00580
00581
00582
00583 if (ARC_kind(arc) != CG_DEP_REGIN) {
00584 return 0;
00585 }
00586
00587 if (!EXEC_PROPERTY_is_I_Unit(OP_code(pred)) ||
00588 !EXEC_PROPERTY_is_M_Unit(OP_code(pred)) ||
00589 !OP_m_unit(pred)) {
00590
00591 return 0;
00592 }
00593
00594 if (OP_load(succ) || OP_store(succ)) {
00595
00596 if (ARC_opnd(arc) == OP_find_opnd_use (succ, OU_base)) {
00597 return -1;
00598 }
00599 }
00600
00601 return 0;
00602 }
00603 #endif
00604
00605
00606
00607
00608
00609
00610
00611
00612
00613
00614
00615
00616
00617
00618
00619
00620 SPEC_TYPE
00621 Derive_Spec_Type_If_Violate_Dep (ARC* Arc) {
00622
00623 if (!ARC_is_dotted(Arc)) { return SPEC_DISABLED; }
00624
00625 if (ARC_is_data_spec(Arc)) { return SPEC_DATA ; }
00626
00627 Is_True (ARC_is_control_spec(Arc), ("Arc is not control speculative!"));
00628
00629
00630 OP* pred = ARC_pred(Arc);
00631 OP* succ = ARC_succ(Arc);
00632
00633 BB* pred_home = OP_bb(pred);
00634 BB* succ_home = OP_bb(succ);
00635
00636 if (pred_home != succ_home && TOP_is_xfer (OP_code(pred)) &&
00637 !OP_call(pred) && !OP_chk(pred) &&
00638 BB1_Postdominate_BB2 (succ_home, pred_home)) {
00639
00640
00641
00642
00643 return SPEC_NONE ;
00644 }
00645
00646 if (OP_call(pred) && !IPFEC_Glos_Motion_Across_Calls) {
00647 return SPEC_DISABLED ;
00648 }
00649
00650 return SPEC_CNTL ;
00651 }
00652
00653 BOOL
00654 OP1_Defs_Are_Used_By_OP2 (OP* op1, OP* op2) {
00655
00656 for (INT16 i = 0; i < OP_results(op1); i++) {
00657 for (INT16 j = 0; j < OP_opnds(op2); j++) {
00658 if (OP_opnd(op2, j) == OP_result(op1, i)) return TRUE;
00659 }
00660 }
00661 return FALSE;
00662 }
00663
00664 BOOL
00665 OP1_Defs_Are_Killed_By_OP2 (OP* op1, OP* op2) {
00666
00667 BOOL killed;
00668 for (INT16 i = 0; i < OP_results(op1); i++) {
00669 killed = FALSE;
00670 for (INT16 j = 0; j < OP_results(op2); j++) {
00671 if (OP_result(op2, j) == OP_result(op1, i)) killed = TRUE;
00672 }
00673 if (!killed) return FALSE;
00674 }
00675 return TRUE;
00676 }