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