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
00052
00053
00054
00055
00056
00057 #include <alloca.h>
00058 #include <math.h>
00059 #include "defs.h"
00060 #include "config.h"
00061 #include "config_targ_opt.h"
00062 #include "mempool.h"
00063 #include "bb.h"
00064 #include "bb_set.h"
00065 #include "tracing.h"
00066 #include "timing.h"
00067 #include "cgir.h"
00068 #include "glob.h"
00069 #include "tn_map.h"
00070 #include "cg.h"
00071 #include "cg_flags.h"
00072 #include "ercg.h"
00073 #include "cgtarget.h"
00074 #include "cg_vector.h"
00075 #include "dominate.h"
00076 #include "findloops.h"
00077 #include "note.h"
00078 #include "lra.h"
00079 #include "gcm.h"
00080 #include "ti_res.h"
00081 #include "ti_res_res.h"
00082 #include "ti_latency.h"
00083 #include "ti_errors.h"
00084 #include "cg_region.h"
00085 #include "gtn_universe.h"
00086 #include "gtn_set.h"
00087 #include "cxx_memory.h"
00088 #include "hb_sched.h"
00089 #include "hb_hazards.h"
00090 #include "targ_proc_properties.h"
00091 #include "targ_isa_bundle.h"
00092 #include "ti_bundle.h"
00093 #include "whirl2ops.h"
00094 #include "tag.h"
00095 #ifdef KEY
00096 #include <float.h>
00097 #include "opsch_set.h"
00098 #endif
00099
00100
00101
00102
00103 #ifdef KEY
00104 OPSCH_SET *fp_opschs = NULL;
00105 static int OPSCH_count = 0;
00106 static int unsched_prefetch_count = 0;
00107 static int deleted_prefetch_count = 0;
00108
00109 OPSCH **OPSCH_Vec;
00110 int OPSCH_Vec_Count;
00111 #endif
00112
00113 BOOL Trace_HB = FALSE;
00114
00115 static INT BBs_Processed = 0;
00116
00117
00118 static INT Clock;
00119 static INT MAX_Clock;
00120
00121 static void
00122 Print_OPSCH (OP *op, BB_MAP value_map)
00123 {
00124 OPSCH *opsch = OP_opsch(op, value_map);
00125 Print_OP_No_SrcLine (op);
00126 fprintf (TFile, "\t<dfs:%3d cyc:%2d reg:%2d est:%2d lst:%2d succs:%d preds:%d>\n",
00127 OPSCH_dfsnum(opsch), OPSCH_scycle(opsch), OPSCH_regcost(opsch),
00128 OPSCH_estart(opsch), OPSCH_lstart(opsch),
00129 OPSCH_num_succs(opsch), OPSCH_num_preds(opsch));
00130
00131 #ifdef KEY
00132 if (OPSCH_least_constrained_int(opsch) != NULL) {
00133 fprintf(TFile, " int:%d",
00134 OPSCH_num_blockers(OPSCH_least_constrained_int(opsch)));
00135 }
00136 if (OPSCH_least_constrained_fp(opsch) != NULL) {
00137 fprintf(TFile, " fp:%d",
00138 OPSCH_num_blockers(OPSCH_least_constrained_fp(opsch)));
00139 }
00140 #endif
00141 fprintf (TFile, ">\n");
00142 }
00143
00144 static void
00145 Print_BB_For_HB (BB *bb, BB_MAP value_map)
00146 {
00147 OP *op;
00148
00149 fprintf (TFile, "*************** BB:%d ******************\n", BB_id(bb));
00150 FOR_ALL_BB_OPs_FWD (bb, op) {
00151 Print_OPSCH (op, value_map);
00152 }
00153 fprintf (TFile, "****************************************\n");
00154 }
00155
00156 void
00157 Print_BB_For_HB (std::list<BB*> bblist, BB_MAP value_map)
00158 {
00159 std::list<BB*>::iterator bbiter;
00160
00161 fprintf (TFile, "\n********** HyperBlock (HB) ******************\n");
00162 fprintf (TFile, "******* Contains :");
00163 FOR_ALL_BB_STLLIST_ITEMS_FWD(bblist, bbiter) {
00164 fprintf (TFile, " BB:%d ", BB_id(*bbiter));
00165 }
00166 fprintf (TFile, "**********\n");
00167
00168 CG_DEP_Trace_HB_Graph (bblist);
00169 FOR_ALL_BB_STLLIST_ITEMS_FWD(bblist, bbiter) {
00170 Print_BB_For_HB(*bbiter, value_map);
00171 }
00172 fprintf (TFile, "****************************************\n");
00173
00174 }
00175
00176
00177
00178
00179
00180
00181
00182 BOOL
00183 Reschedule_BB(BB *bb)
00184 {
00185
00186
00187 if (BB_loop_head_bb(bb) == bb) {
00188 BBLIST *succ_list;
00189 FOR_ALL_BB_SUCCS (bb, succ_list) {
00190 BB *succ_bb = BBLIST_item(succ_list);
00191 if (succ_bb == bb) return TRUE;
00192 }
00193 }
00194
00195 return FALSE;
00196 }
00197
00198
00199
00200
00201 BOOL
00202 Can_Schedule_HB(std::list<BB*> hb_blocks)
00203 {
00204
00205 std::list<BB*>::iterator bb_iter;
00206 FOR_ALL_BB_STLLIST_ITEMS_FWD (hb_blocks, bb_iter) {
00207
00208 if (BB_scheduled(*bb_iter) && !BB_scheduled_hbs(*bb_iter)) return FALSE;
00209 }
00210
00211 return TRUE;
00212 }
00213
00214 INT
00215 Memory_OP_Base_Opndnum (OP *op)
00216 {
00217 #ifdef TARG_X8664
00218 return TOP_Find_Operand_Use( OP_code(op), OU_base );
00219 #else
00220 INT opnd_num;
00221 if (OP_store(op) || OP_prefetch(op)) {
00222 opnd_num = 1;
00223 }
00224 else {
00225 Is_True (OP_load(op), ("OP not a memory OP."));
00226 opnd_num = 0;
00227 }
00228 return opnd_num;
00229 #endif
00230 }
00231
00232
00233 INT
00234 Memory_OP_Offset_Opndnum (OP *op)
00235 {
00236 #ifdef TARG_X8664
00237 return TOP_Find_Operand_Use( OP_code(op), OU_offset );
00238 #else
00239 INT opnd_num;
00240
00241 if (OP_store(op) || OP_prefetch(op)) {
00242 opnd_num = 2;
00243 }
00244 else {
00245 Is_True (OP_load(op), ("OP not a memory OP."));
00246 opnd_num = 1;
00247 }
00248 return opnd_num;
00249 #endif
00250 }
00251
00252
00253
00254
00255
00256
00257 void HB_Schedule::Init_Register_Map (BB *bb)
00258 {
00259 OP *op;
00260
00261 _regs_map = hTN_MAP_Create (&_hb_pool);
00262 FOR_ALL_BB_OPs_FWD (bb, op) {
00263 INT i;
00264 for (i = 0; i < OP_results(op); i++) {
00265 TN *result_tn = OP_result(op, i);
00266 REG_ENTRY reginfo;
00267 REG_ENTRY_ptr(reginfo) = hTN_MAP_Get (_regs_map, result_tn);
00268 REG_ENTRY_def_count(reginfo)++;
00269 if (TN_is_global_reg(result_tn) || TN_is_dedicated(result_tn))
00270 REG_ENTRY_reg_assigned(reginfo) = TRUE;
00271 hTN_MAP_Set (_regs_map, result_tn, REG_ENTRY_ptr(reginfo));
00272 }
00273 for (i = 0; i < OP_opnds(op); i++) {
00274 TN *opnd_tn = OP_opnd(op,i);
00275 if (TN_is_constant(opnd_tn)) continue;
00276 if (TN_is_global_reg(opnd_tn) || TN_is_dedicated(opnd_tn)) {
00277 REG_ENTRY reginfo;
00278 REG_ENTRY_ptr(reginfo) = hTN_MAP_Get (_regs_map, opnd_tn);
00279 REG_ENTRY_reg_assigned(reginfo) = TRUE;
00280 hTN_MAP_Set (_regs_map, opnd_tn, REG_ENTRY_ptr(reginfo));
00281 }
00282 }
00283 }
00284 }
00285
00286
00287
00288
00289
00290
00291
00292
00293 void
00294 HB_Schedule::Estimate_Reg_Cost_For_OP (OP *op)
00295 {
00296 INT cost = 0;
00297 INT32 local_regs_avail[ISA_REGISTER_CLASS_MAX+1];
00298 ISA_REGISTER_CLASS cl;
00299 REG_ENTRY reginfo;
00300
00301 FOR_ALL_ISA_REGISTER_CLASS(cl) {
00302 local_regs_avail[cl] = _Cur_Regs_Avail[cl];
00303 }
00304
00305 INT i;
00306 for (i = 0; i < OP_results(op); i++) {
00307 TN *result_tn = OP_result(op, i);
00308
00309
00310 if (!OP_Refs_TN (op, result_tn)) {
00311 REG_ENTRY_ptr(reginfo) = hTN_MAP_Get (_regs_map, result_tn);
00312 if (REG_ENTRY_def_count(reginfo) == 1 &&
00313 REG_ENTRY_reg_assigned(reginfo))
00314 {
00315 cl = TN_register_class(result_tn);
00316 INT reg_pressure = (2 - local_regs_avail[cl]);
00317 if (reg_pressure > 0) {
00318 cost -= reg_pressure;
00319 }
00320 local_regs_avail[cl]++;
00321 }
00322 }
00323 }
00324 for (i = 0; i < OP_opnds(op); i++) {
00325 TN *opnd_tn = OP_opnd(op,i);
00326 if (TN_is_constant(opnd_tn)) continue;
00327 REG_ENTRY_ptr(reginfo) = hTN_MAP_Get (_regs_map, opnd_tn);
00328 if (!REG_ENTRY_reg_assigned(reginfo)) {
00329
00330 BOOL reg_handled = FALSE;
00331 for (INT j = 0; j < i; j++) {
00332 if (OP_opnd(op,j) == opnd_tn)
00333 reg_handled = TRUE;
00334 }
00335 if (!reg_handled) {
00336 cl = TN_register_class(opnd_tn);
00337 local_regs_avail[cl]--;
00338 INT reg_pressure = (2 - local_regs_avail[cl]);
00339 if (reg_pressure > 0) {
00340 cost += reg_pressure;
00341 }
00342 }
00343 }
00344 }
00345 OPSCH *opsch = OP_opsch(op, _hb_map);
00346 OPSCH_regcost(opsch) = cost;
00347 }
00348
00349
00350
00351
00352
00353 void
00354 HB_Schedule::Update_Regs_For_OP (OP *op)
00355 {
00356 REG_ENTRY reginfo;
00357
00358 INT i;
00359 for (i = 0; i < OP_results(op); i++) {
00360 TN *result_tn = OP_result(op, i);
00361 REG_ENTRY_ptr(reginfo) = hTN_MAP_Get (_regs_map, result_tn);
00362 REG_ENTRY_def_count(reginfo)--;
00363 if (REG_ENTRY_def_count(reginfo) == 0 &&
00364 REG_ENTRY_reg_assigned(reginfo))
00365 {
00366 ISA_REGISTER_CLASS cl = TN_register_class(result_tn);
00367 _Cur_Regs_Avail[cl]++;
00368 REG_ENTRY_reg_assigned(reginfo) = FALSE;
00369 }
00370 hTN_MAP_Set (_regs_map, result_tn, REG_ENTRY_ptr(reginfo));
00371 }
00372 for (i = 0; i < OP_opnds(op); i++) {
00373 TN *opnd_tn = OP_opnd(op,i);
00374 if (TN_is_constant(opnd_tn)) continue;
00375 REG_ENTRY_ptr(reginfo) = hTN_MAP_Get (_regs_map, opnd_tn);
00376 if (!REG_ENTRY_reg_assigned(reginfo)) {
00377 ISA_REGISTER_CLASS cl = TN_register_class(opnd_tn);
00378 _Cur_Regs_Avail[cl]--;
00379 REG_ENTRY_reg_assigned(reginfo) = TRUE;
00380 hTN_MAP_Set (_regs_map, opnd_tn, REG_ENTRY_ptr(reginfo));
00381 }
00382 }
00383 }
00384
00385
00386
00387
00388
00389 BOOL
00390 Is_Ldst_Addiu_Pair (OPSCH *opsch1, OPSCH *opsch2, OP *op1,OP *op2)
00391 {
00392 OP *addiu_op;
00393 OP *ldst_op;
00394 INT64 multiplier;
00395
00396 if (((OPSCH_flags(opsch1) | OPSCH_flags(opsch2)) & OPSCH_ADDIU_LDST_PAIR) !=
00397 OPSCH_ADDIU_LDST_PAIR)
00398 {
00399 return FALSE;
00400 }
00401
00402 if (OPSCH_addiu(opsch1)) {
00403 addiu_op = op1;
00404 ldst_op = op2;
00405 multiplier = 1;
00406 }
00407 else {
00408 addiu_op = op2;
00409 ldst_op = op1;
00410 multiplier = -1;
00411 }
00412
00413
00414
00415
00416 INT base_opndnum = Memory_OP_Base_Opndnum(ldst_op);
00417 #if defined(TARG_X8664) || defined(TARG_SL)
00418 if( base_opndnum < 0 ){
00419 return FALSE;
00420 }
00421 #endif
00422 if (OP_result(addiu_op,0 ) != OP_opnd(ldst_op,base_opndnum) ||
00423 (OP_store(ldst_op) &&
00424 OP_result(addiu_op,0 ) == OP_opnd(ldst_op,0)))
00425 {
00426 return FALSE;
00427 }
00428
00429 INT64 addiu_const = TN_value (OP_opnd(addiu_op, 1));
00430 INT offset_opndnum = Memory_OP_Offset_Opndnum(ldst_op);
00431 #if defined(TARG_SL)
00432 if( offset_opndnum < 0 )
00433 return FALSE;
00434 #endif
00435 INT64 ldst_const = TN_value (OP_opnd(ldst_op, offset_opndnum));
00436
00437 return TOP_Can_Have_Immediate (ldst_const + addiu_const*multiplier, OP_code(ldst_op));
00438 }
00439
00440
00441
00442
00443
00444
00445 void
00446 Fixup_Ldst_Offset (OP *ldst_op, INT64 addiu_const, INT64 multiplier,
00447 HBS_TYPE type)
00448 {
00449 TN *old_ofst_tn, *ofst_tn;
00450 INT index;
00451
00452 index = Memory_OP_Offset_Opndnum (ldst_op);
00453 if( index < 0 )
00454 return;
00455 old_ofst_tn = OP_opnd(ldst_op, index);
00456
00457 if (Trace_HB) {
00458 #pragma mips_frequency_hint NEVER
00459 fprintf (TFile, "old: %lld, new: %lld\n", TN_value(old_ofst_tn),
00460 TN_value(old_ofst_tn) + addiu_const * multiplier);
00461 fprintf (TFile, "offset changed:");
00462 Print_OP_No_SrcLine (ldst_op);
00463 }
00464
00465 ofst_tn = Gen_Literal_TN (TN_value(old_ofst_tn) + addiu_const * multiplier,
00466 TN_size(old_ofst_tn));
00467 Set_OP_opnd (ldst_op, index, ofst_tn);
00468
00469 }
00470
00471
00472
00473
00474
00475
00476 void
00477 HB_Schedule::Adjust_Ldst_Offsets (void)
00478 {
00479 for (INT i = VECTOR_count(_sched_vector)-1; i >= 0; i--) {
00480 OP *op = OP_VECTOR_element(_sched_vector, i);
00481 OPSCH *opsch = OP_opsch(op, _hb_map);
00482 Set_OPSCH_visited (opsch);
00483 if (!OPSCH_addiu (opsch)) continue;
00484 INT64 addiu_const = TN_value (OP_opnd(op,1));
00485 ARC_LIST *arcs;
00486 for (arcs = OP_succs(op); arcs != NULL; arcs = ARC_LIST_rest(arcs)) {
00487 ARC *arc = ARC_LIST_first(arcs);
00488 #ifdef KEY
00489 if( ARC_kind(arc) != CG_DEP_REGIN ){
00490 continue;
00491 }
00492 #endif
00493 OP *succ_op = ARC_succ(arc);
00494 OPSCH *succ_opsch = OP_opsch (succ_op, _hb_map);
00495 if (OPSCH_ldst (succ_opsch) && OPSCH_visited (succ_opsch)) {
00496 Fixup_Ldst_Offset (succ_op, addiu_const, +1, type());
00497 }
00498 }
00499 for (arcs = OP_preds(op); arcs != NULL; arcs = ARC_LIST_rest(arcs)) {
00500 ARC *arc = ARC_LIST_first(arcs);
00501 OP *pred_op = ARC_pred(arc);
00502 #ifdef KEY
00503 if (ARC_kind(arc) != CG_DEP_REGANTI){
00504
00505
00506
00507
00508 continue;
00509 }
00510 #endif
00511 OPSCH *pred_opsch = OP_opsch (pred_op, _hb_map);
00512 if (OPSCH_ldst (pred_opsch) && !OPSCH_visited (pred_opsch)) {
00513 Fixup_Ldst_Offset (pred_op, addiu_const, -1, type());
00514 }
00515 }
00516 }
00517 }
00518
00519 #ifdef KEY
00520
00521 void HB_Schedule::Adjust_Ldst_Offsets( BOOL is_fwd )
00522 {
00523 for( INT i = is_fwd ? 0 : VECTOR_count(_sched_vector) - 1;
00524 is_fwd ? i < VECTOR_count(_sched_vector) : i >= 0;
00525 is_fwd ? i++ : i-- ){
00526
00527 OP *op = OP_VECTOR_element(_sched_vector, i);
00528 OPSCH *opsch = OP_opsch(op, _hb_map);
00529 Set_OPSCH_visited (opsch);
00530 if (!OPSCH_addiu (opsch)) continue;
00531 INT64 addiu_const = TN_value (OP_opnd(op,1));
00532 ARC_LIST *arcs;
00533
00534 for (arcs = OP_succs(op); arcs != NULL; arcs = ARC_LIST_rest(arcs)) {
00535 ARC *arc = ARC_LIST_first(arcs);
00536 if( ARC_kind(arc) != CG_DEP_REGIN ){
00537 continue;
00538 }
00539
00540 OP *succ_op = ARC_succ(arc);
00541 OPSCH *succ_opsch = OP_opsch (succ_op, _hb_map);
00542 if (OPSCH_ldst (succ_opsch) && OPSCH_visited (succ_opsch)) {
00543 Fixup_Ldst_Offset (succ_op, addiu_const, +1, type());
00544 }
00545 }
00546
00547 for (arcs = OP_preds(op); arcs != NULL; arcs = ARC_LIST_rest(arcs)) {
00548 ARC *arc = ARC_LIST_first(arcs);
00549 OP *pred_op = ARC_pred(arc);
00550
00551 if (ARC_kind(arc) != CG_DEP_REGANTI){
00552
00553
00554
00555
00556 continue;
00557 }
00558
00559 OPSCH *pred_opsch = OP_opsch (pred_op, _hb_map);
00560 if (OPSCH_ldst (pred_opsch) && !OPSCH_visited (pred_opsch)) {
00561 Fixup_Ldst_Offset (pred_op, addiu_const, -1, type());
00562 }
00563 }
00564 }
00565 }
00566
00567 #endif
00568
00569
00570
00571
00572
00573
00574
00575
00576 void
00577 HB_Schedule::Set_Resource_Usage (OP *op)
00578 {
00579 INT cycle = OPSCH_scycle (OP_opsch(op, _hb_map));
00580
00581 TI_RES_RES_Reserve_Resources(_rr_tab, OP_code(op), cycle);
00582 Clock = cycle;
00583 }
00584
00585
00586
00587
00588
00589
00590
00591 INT
00592 HB_Schedule::Find_Schedule_Cycle (OP *op, BOOL is_fwd)
00593 {
00594 OPSCH *opsch = OP_opsch(op, _hb_map);
00595 INT cycle = OPSCH_scycle(opsch);
00596 INT cyc;
00597
00598 if (is_fwd) {
00599
00600 for (cyc = cycle; cyc <= MAX_Clock; cyc++) {
00601 if (Check_Resource_Usage (op, cyc)) break;
00602 }
00603 FmtAssert (cyc <= MAX_Clock, ("HB_SCHED: no valid cycle for scheduling"));
00604 } else {
00605
00606 for (cyc = cycle; cyc >= 0; cyc--) {
00607 if (Check_Resource_Usage (op, cyc)) break;
00608 }
00609 FmtAssert (cyc >= 0, ("HB_SCHED: no valid cycle for scheduling"));
00610 }
00611
00612
00613 OPSCH_scycle(opsch) = cyc;
00614 return cyc;
00615 }
00616
00617 static INT cur_dfsnum;
00618
00619
00620
00621
00622
00623 static void
00624 Init_OPSCH_For_BB (BB *bb, BB_MAP value_map, BOOL compute_bitsets,
00625 MEM_POOL *pool)
00626 {
00627 OP *op;
00628 ARC_LIST *arcs;
00629 ARC *arc;
00630 OPSCH *opsch;
00631
00632 #ifdef KEY
00633 OPSCH_count = 0;
00634 OPSCH_Vec_Count = BB_length(bb);
00635 OPSCH_Vec = TYPE_MEM_POOL_ALLOC_N(OPSCH *, pool, OPSCH_Vec_Count + 1);
00636 fp_opschs = compute_bitsets ?
00637 OPSCH_SET_Create_Empty(BB_length(bb), pool) : NULL;
00638 unsched_prefetch_count = 0;
00639 deleted_prefetch_count = 0;
00640 #endif
00641
00642 FOR_ALL_BB_OPs_FWD (bb, op) {
00643 opsch = TYPE_MEM_POOL_ALLOC (OPSCH, pool);
00644 BZERO (opsch, sizeof (OPSCH));
00645 OPSCH_lstart(opsch) = 0x7fff;
00646 BB_OP_MAP bb_map = (BB_OP_MAP) BB_MAP_Get(value_map, bb);
00647 BB_OP_MAP_Set (bb_map, op, opsch);
00648 #ifdef KEY
00649 OPSCH_op(opsch) = op;
00650 OPSCH_id(opsch) = ++OPSCH_count;
00651 OPSCH_Vec[OPSCH_id(opsch)] = opsch;
00652 if (compute_bitsets) {
00653 OPSCH_ancestors(opsch) = OPSCH_SET_Create_Empty(BB_length(bb), pool);
00654 OPSCH_descendants(opsch) = OPSCH_SET_Create_Empty(BB_length(bb), pool);
00655 if (OP_flop(op))
00656 fp_opschs = OPSCH_SET_Union1D(fp_opschs, opsch, pool);
00657 }
00658
00659
00660 if (OP_prefetch(op))
00661 unsched_prefetch_count++;
00662 #endif
00663 }
00664
00665 FOR_ALL_BB_OPs_FWD (bb, op) {
00666 opsch = OP_opsch(op, value_map);
00667
00668 if (CGTARG_Is_OP_Addr_Incr(op) &&
00669 !TN_is_sp_reg(OP_result(op,0 ))) {
00670
00671 BOOL addiu_ok = TRUE;
00672 for (arcs = OP_succs(op); arcs != NULL; arcs = ARC_LIST_rest(arcs)) {
00673 arc = ARC_LIST_first(arcs);
00674 if (ARC_kind(arc) == CG_DEP_REGOUT) {
00675 addiu_ok = FALSE;
00676 break;
00677 }
00678 }
00679 for (arcs = OP_preds(op); arcs != NULL; arcs = ARC_LIST_rest(arcs)) {
00680 arc = ARC_LIST_first(arcs);
00681 if (ARC_kind(arc) == CG_DEP_REGIN) {
00682 addiu_ok = FALSE;
00683 break;
00684 }
00685 }
00686 if (addiu_ok) Set_OPSCH_addiu (opsch);
00687 }
00688 else if (OP_memory(op)) {
00689
00690
00691 INT offset_opndnum = Memory_OP_Offset_Opndnum (op);
00692 if ( offset_opndnum >= 0 &&
00693 TN_has_value(OP_opnd(op,offset_opndnum)) ) {
00694 Set_OPSCH_ldst (opsch);
00695 }
00696 }
00697 #ifdef TARG_MIPS
00698 if (Is_Target_T5() && OP_xfer(op) && Get_Trace (TP_SCHED, 0x1000)) {
00699 for (arcs = OP_preds(op); arcs != NULL; arcs = ARC_LIST_rest(arcs)) {
00700 arc = ARC_LIST_first(arcs);
00701 if (ARC_kind(arc) == CG_DEP_REGIN) {
00702 OP *pred_op = ARC_pred(arc);
00703 OPSCH *pred_opsch = OP_opsch(pred_op, value_map);
00704 Set_OPSCH_def_xfer_opnd(pred_opsch);
00705 }
00706 }
00707 }
00708 #endif
00709 }
00710 }
00711
00712
00713
00714
00715 static BOOL
00716 sort_by_estart (const void *opsch1, const void *opsch2)
00717 {
00718 return (OPSCH_estart((OPSCH*) opsch1) > OPSCH_estart((OPSCH*) opsch2));
00719 }
00720
00721
00722
00723
00724 static BOOL
00725 sort_by_slack (const void *opsch1, const void *opsch2)
00726 {
00727 INT slack1 = OPSCH_lstart((OPSCH*) opsch1) - OPSCH_estart((OPSCH*) opsch1);
00728 INT slack2 = OPSCH_lstart((OPSCH*) opsch2) - OPSCH_estart((OPSCH*) opsch2);
00729
00730 return ((OPSCH*)(INTPTR) slack1 < (OPSCH*)(INTPTR) slack2);
00731 }
00732
00733 #ifdef KEY
00734
00735
00736
00737
00738 static void
00739 Compute_Depth (OP *op, BB_MAP value_map)
00740 {
00741 OPSCH *opsch = OP_opsch(op, value_map);
00742 ARC_LIST *arcs;
00743 INT max_depth = 0;
00744
00745 Is_True(OPSCH_depth(opsch) <= BB_length(OP_bb(op)),
00746 ("Compute_Depth: illegal OP depth value"));
00747
00748 if (OPSCH_depth(opsch) > 0)
00749 return;
00750
00751
00752 for (arcs = OP_preds(op); arcs != NULL; arcs = ARC_LIST_rest(arcs)) {
00753 ARC *arc = ARC_LIST_first(arcs);
00754 OP *pred_op = ARC_pred(arc);
00755 OPSCH *pred_opsch = OP_opsch(pred_op, value_map);
00756 INT pred_depth = OPSCH_depth(pred_opsch);
00757 if (pred_depth == 0) {
00758 return;
00759 } else {
00760 max_depth = (pred_depth > max_depth) ? pred_depth : max_depth;
00761 }
00762 }
00763
00764 OPSCH_depth(opsch) = max_depth + 1;
00765
00766
00767 for (arcs = OP_succs(op); arcs != NULL; arcs = ARC_LIST_rest(arcs)) {
00768 ARC *arc = ARC_LIST_first(arcs);
00769 OP *succ_op = ARC_succ(arc);
00770 Compute_Depth(succ_op, value_map);
00771 }
00772 }
00773
00774
00775
00776
00777
00778
00779 static INT
00780 Compare_Depths (const void *p1, const void *p2)
00781 {
00782 enum {
00783 sort_1_before_2 = -1,
00784 sort_1_after_2 = 1,
00785 sort_1_same_2 = 0
00786 };
00787
00788 INT depth1 = OPSCH_depth(*(OPSCH **)p1);
00789 INT depth2 = OPSCH_depth(*(OPSCH **)p2);
00790 Is_True(depth1 > 0 && depth2 > 0, ("Compare_Depths: OP has depth 0"));
00791 if (depth1 < depth2)
00792 return sort_1_before_2;
00793 else if (depth1 > depth2)
00794 return sort_1_after_2;
00795 else
00796 return sort_1_same_2;
00797 }
00798
00799
00800
00801
00802
00803
00804 static void
00805 Update_Blocker_Info (OPSCH *blocker, OPSCH *blockee)
00806 {
00807
00808 if (OP_flop(OPSCH_op(blockee))) {
00809 if (OPSCH_least_constrained_fp(blocker) == NULL ||
00810 (OPSCH_num_blockers(OPSCH_least_constrained_fp(blocker)) >
00811 OPSCH_num_blockers(blockee)))
00812 OPSCH_least_constrained_fp(blocker) = blockee;
00813 } else {
00814 if (OPSCH_least_constrained_int(blocker) == NULL ||
00815 (OPSCH_num_blockers(OPSCH_least_constrained_int(blocker)) >
00816 OPSCH_num_blockers(blockee)))
00817 OPSCH_least_constrained_int(blocker) = blockee;
00818 }
00819
00820
00821 if (OPSCH_least_constrained_fp(blocker) == NULL ||
00822 (OPSCH_least_constrained_fp(blockee) != NULL &&
00823 OPSCH_num_blockers(OPSCH_least_constrained_fp(blocker)) >
00824 OPSCH_num_blockers(OPSCH_least_constrained_fp(blockee)))) {
00825 OPSCH_least_constrained_fp(blocker) = OPSCH_least_constrained_fp(blockee);
00826 }
00827 if (OPSCH_least_constrained_int(blocker) == NULL ||
00828 (OPSCH_least_constrained_int(blockee) != NULL &&
00829 OPSCH_num_blockers(OPSCH_least_constrained_int(blocker)) >
00830 OPSCH_num_blockers(OPSCH_least_constrained_int(blockee)))) {
00831 OPSCH_least_constrained_int(blocker) = OPSCH_least_constrained_int(blockee);
00832 }
00833 }
00834 #endif
00835
00836
00837
00838
00839
00840 static void
00841 DFS_Search (OP *op, BB_MAP value_map, BOOL is_fwd)
00842 {
00843 OPSCH *opsch = OP_opsch (op, value_map);
00844 ARC_LIST *arcs;
00845
00846 if (OPSCH_visited(opsch)) return;
00847
00848 #ifdef KEY
00849 OPSCH *least_constrained_int = NULL;
00850 OPSCH *least_constrained_fp = NULL;
00851 #endif
00852
00853 OPSCH_dfsnum(opsch) = cur_dfsnum;
00854 Set_OPSCH_visited(opsch);
00855 cur_dfsnum++;
00856
00857 if (is_fwd) {
00858
00859 for (arcs = OP_succs(op); arcs != NULL; arcs = ARC_LIST_rest(arcs)) {
00860 ARC *arc = ARC_LIST_first(arcs);
00861 OP *succ_op = ARC_succ(arc);
00862 OPSCH *succ_opsch = OP_opsch (succ_op, value_map);
00863 if (!OPSCH_visited(succ_opsch))
00864 DFS_Search (succ_op, value_map, TRUE);
00865 #ifdef KEY
00866 Update_Blocker_Info(opsch, succ_opsch);
00867 #endif
00868 }
00869 } else {
00870
00871 #ifdef KEY
00872
00873
00874
00875
00876
00877
00878
00879
00880 if (LOCS_Shallow_Depth) {
00881 int i = 0;
00882 OPSCH **opsch_list = (OPSCH **) alloca(OPSCH_num_preds(opsch) *
00883 sizeof(OPSCH *));
00884 for (arcs = OP_preds(op); arcs != NULL; arcs = ARC_LIST_rest(arcs)) {
00885 ARC *arc = ARC_LIST_first(arcs);
00886 OP *pred_op = ARC_pred(arc);
00887 OPSCH *pred_opsch = OP_opsch(pred_op, value_map);
00888
00889 if (!Is_Ldst_Addiu_Pair(pred_opsch, opsch, pred_op, op))
00890 opsch_list[i++] = pred_opsch;
00891 }
00892 Is_True(i == OPSCH_num_preds(opsch),
00893 ("DFS_Search: incorrect number of preds"));
00894
00895 qsort(opsch_list, OPSCH_num_preds(opsch), sizeof(OPSCH *),
00896 Compare_Depths);
00897
00898 for (i = 0; i < OPSCH_num_preds(opsch); i++) {
00899 OPSCH *pred_opsch = opsch_list[i];
00900 OP *pred_op = OPSCH_op(pred_opsch);
00901 if (!Is_Ldst_Addiu_Pair (pred_opsch, opsch, pred_op, op)) {
00902 if (!OPSCH_visited(pred_opsch))
00903 DFS_Search(pred_op, value_map, FALSE);
00904 #ifdef KEY
00905 Update_Blocker_Info(opsch, pred_opsch);
00906 #endif
00907 }
00908 }
00909 } else
00910 #endif
00911 for (arcs = OP_preds(op); arcs != NULL; arcs = ARC_LIST_rest(arcs)) {
00912 ARC *arc = ARC_LIST_first(arcs);
00913 OP *pred_op = ARC_pred(arc);
00914 OPSCH *pred_opsch = OP_opsch (pred_op, value_map);
00915 if (!Is_Ldst_Addiu_Pair (pred_opsch, opsch, pred_op, op)) {
00916 if (!OPSCH_visited(pred_opsch))
00917 DFS_Search (pred_op, value_map, FALSE);
00918 #ifdef KEY
00919 Update_Blocker_Info(opsch, pred_opsch);
00920 #endif
00921 }
00922 }
00923 }
00924 }
00925
00926
00927
00928
00929 static void
00930 Compute_DFO (HB_Schedule *sched, BB_MAP value_map, BOOL is_fwd)
00931 {
00932 INT i;
00933
00934 #ifdef KEY
00935 OP *op;
00936 BB *bb = OP_bb(OP_VECTOR_element(sched->ready_vector(), 0));
00937 FOR_ALL_BB_OPs_FWD(bb, op) {
00938 if (OP_preds(op) == NULL)
00939 Compute_Depth(op, value_map);
00940 }
00941 #endif
00942
00943 cur_dfsnum = 1;
00944 for (i = 0; i < VECTOR_count(sched->ready_vector()); i++) {
00945 DFS_Search (OP_VECTOR_element(sched->ready_vector(), i), value_map,is_fwd);
00946 }
00947 }
00948
00949
00950
00951
00952
00953
00954 void
00955 Priority_Selector::Add_Element_Sorted (VECTOR vector, void *element, VECTOR_ELEMENT_COMPARE comp_func)
00956 {
00957 INT i;
00958 INT count = VECTOR_count(vector);
00959 FmtAssert (count < VECTOR_size(vector), ("VECTOR overflow"));
00960 for (i = count; i > 0; i--) {
00961 void *cur_element = VECTOR_element(vector, i - 1);
00962 void *cur_opsch = OP_opsch((OP*) cur_element, _cur_sched->hb_map());
00963 void *opsch = OP_opsch((OP*) element, _cur_sched->hb_map());
00964 if (comp_func(cur_opsch, opsch)) break;
00965 VECTOR_element(vector, i) = cur_element;
00966 }
00967 VECTOR_element(vector, i) = element;
00968 count++;
00969 VECTOR_count(vector) = count;
00970 }
00971
00972
00973
00974
00975
00976
00977 void
00978 Priority_Selector::Build_Ready_Vector (BB* bb, BOOL is_fwd)
00979 {
00980 OP *op;
00981
00982 if (is_fwd) {
00983 FOR_ALL_BB_OPs_FWD (bb, op) {
00984 OPSCH *opsch = OP_opsch(op, _cur_sched->hb_map());
00985
00986 if (OPSCH_num_preds(opsch) == 0) {
00987 Add_Element_Sorted (_cur_sched->ready_vector(), op, sort_by_slack);
00988 }
00989 }
00990 } else {
00991 FOR_ALL_BB_OPs_REV (bb, op) {
00992 OPSCH *opsch = OP_opsch(op, _cur_sched->hb_map());
00993
00994 if (OPSCH_num_succs(opsch) == 0) {
00995 Add_Element_Sorted (_cur_sched->ready_vector(), op, sort_by_estart);
00996 }
00997 }
00998 }
00999 }
01000
01001
01002
01003
01004
01005
01006 void
01007 Priority_Selector::Build_Ready_Vector (std::list<BB*> bblist, BOOL is_fwd)
01008 {
01009
01010 std::list<BB*>::iterator bb_iter;
01011 FOR_ALL_BB_STLLIST_ITEMS_FWD (bblist, bb_iter) {
01012 Build_Ready_Vector (*bb_iter, is_fwd);
01013 }
01014 }
01015
01016
01017
01018
01019
01020
01021
01022 inline INT
01023 Resource_Cycles_For_OP (OP *op)
01024 {
01025 return TI_RES_Cycle_Count(OP_code(op));
01026 }
01027
01028
01029
01030
01031
01032 static inline INT
01033 Calculate_Adjust_Latency (ARC *arc)
01034 {
01035 INT adjust_latency;
01036
01037 BOOL ooo_adjust = (PROC_is_out_of_order() && CG_DEP_Adjust_OOO_Latency);
01038
01039
01040
01041
01042
01043 adjust_latency = (ooo_adjust && ARC_is_mem(arc) &&
01044 !ARC_is_definite(arc)) ? 0 : ARC_latency(arc);
01045
01046
01047
01048
01049 adjust_latency = (ooo_adjust && ARC_is_reg(arc) &&
01050 (ARC_is_anti(arc) || ARC_is_output(arc))) ?
01051 0 : adjust_latency;
01052
01053 return adjust_latency;
01054 }
01055
01056
01057
01058
01059 static void
01060 Compute_Fwd_OPSCH (BB *bb, BB_MAP value_map, INT *max_lstart,
01061 BOOL compute_bitsets, MEM_POOL *pool)
01062 {
01063 OP *op;
01064
01065
01066
01067 #ifdef KEY
01068
01069 #endif
01070 FOR_ALL_BB_OPs_FWD (bb, op) {
01071 OPSCH *opsch = OP_opsch(op, value_map);
01072 INT op_estart = OPSCH_estart(opsch);
01073 ARC_LIST *arcs;
01074 for (arcs = OP_succs(op); arcs != NULL; arcs = ARC_LIST_rest(arcs)) {
01075 ARC *arc = ARC_LIST_first(arcs);
01076 OP *succ_op = ARC_succ(arc);
01077 OPSCH *succ_opsch = OP_opsch(succ_op, value_map);
01078 if (!Is_Ldst_Addiu_Pair (opsch, succ_opsch, op, succ_op)) {
01079 INT cur_estart = Calculate_Adjust_Latency(arc) + op_estart;
01080 if (OPSCH_estart(succ_opsch) < cur_estart) {
01081 OPSCH_estart(succ_opsch) = cur_estart;
01082 }
01083 OPSCH_num_succs(opsch)++;
01084 #ifdef KEY
01085
01086 if (compute_bitsets) {
01087 OPSCH_ancestors(succ_opsch) =
01088 OPSCH_SET_UnionD(OPSCH_ancestors(succ_opsch),
01089 OPSCH_ancestors(opsch), pool);
01090 OPSCH_ancestors(succ_opsch) =
01091 OPSCH_SET_Union1D(OPSCH_ancestors(succ_opsch), opsch, pool);
01092 }
01093 #endif
01094 }
01095 }
01096 *max_lstart = MAX (*max_lstart, op_estart);
01097 }
01098 }
01099
01100
01101
01102
01103 static void
01104 Compute_Bkwd_OPSCH (BB *bb, BB_MAP value_map, INT max_lstart,
01105 BOOL compute_bitsets, MEM_POOL *pool)
01106 {
01107 OP *op;
01108
01109
01110
01111 #ifdef KEY
01112
01113 #endif
01114 FOR_ALL_BB_OPs_REV (bb, op) {
01115 OPSCH *opsch = OP_opsch(op, value_map);
01116 ARC_LIST *arcs;
01117 OPSCH_scycle(opsch) = Clock;
01118 if (OPSCH_lstart(opsch) > max_lstart) OPSCH_lstart(opsch) = max_lstart;
01119 for (arcs = OP_preds(op); arcs != NULL; arcs = ARC_LIST_rest(arcs)) {
01120 ARC *arc = ARC_LIST_first(arcs);
01121 OP *pred_op = ARC_pred(arc);
01122 OPSCH *pred_opsch = OP_opsch(pred_op, value_map);
01123 if (!Is_Ldst_Addiu_Pair (pred_opsch, opsch, pred_op, op)) {
01124 INT cur_lstart = OPSCH_lstart(opsch) - Calculate_Adjust_Latency(arc);
01125 if (OPSCH_lstart(pred_opsch) > cur_lstart) {
01126 OPSCH_lstart(pred_opsch) = cur_lstart;
01127 }
01128 OPSCH_num_preds(opsch)++;
01129 #ifdef KEY
01130 if (compute_bitsets) {
01131
01132 OPSCH_descendants(pred_opsch) =
01133 OPSCH_SET_UnionD(OPSCH_descendants(pred_opsch),
01134 OPSCH_descendants(opsch), pool);
01135 OPSCH_descendants(pred_opsch) =
01136 OPSCH_SET_Union1D(OPSCH_descendants(pred_opsch), opsch, pool);
01137 }
01138 #endif
01139 }
01140 }
01141 }
01142 }
01143
01144 #ifdef KEY
01145
01146
01147
01148 static void
01149 Compute_OPSCH_Blockers (BB *bb, BB_MAP value_map, BOOL is_fwd, MEM_POOL *pool)
01150 {
01151 OP *op;
01152
01153 FOR_ALL_BB_OPs_FWD (bb, op) {
01154 OPSCH *opsch = OP_opsch(op, value_map);
01155 if (is_fwd) {
01156 OPSCH_num_blockers(opsch) = OPSCH_SET_Size(OPSCH_ancestors(opsch));
01157 } else {
01158 OPSCH_num_blockers(opsch) = OPSCH_SET_Size(OPSCH_descendants(opsch));
01159 }
01160 }
01161 }
01162 #endif
01163
01164
01165
01166
01167 void
01168 Compute_OPSCH (BB *bb, BB_MAP value_map, MEM_POOL *pool, BOOL compute_bitsets,
01169 BOOL is_fwd)
01170 {
01171 INT max_lstart = 0;
01172
01173 Init_OPSCH_For_BB (bb, value_map, compute_bitsets, pool);
01174
01175 Compute_Fwd_OPSCH (bb, value_map, &max_lstart, compute_bitsets, pool);
01176
01177 Compute_Bkwd_OPSCH (bb, value_map, max_lstart, compute_bitsets, pool);
01178
01179 #ifdef KEY
01180 if (compute_bitsets)
01181 Compute_OPSCH_Blockers(bb, value_map, is_fwd, pool);
01182 #endif
01183 }
01184
01185
01186
01187
01188
01189 void
01190 Compute_OPSCHs (std::list<BB*> bblist, BB_MAP value_map, MEM_POOL *pool,
01191 BOOL compute_bitsets, BOOL is_fwd)
01192 {
01193 std::list<BB*>::iterator bb_iter;
01194
01195
01196 FOR_ALL_BB_STLLIST_ITEMS_FWD(bblist, bb_iter) {
01197 Init_OPSCH_For_BB (*bb_iter, value_map, compute_bitsets, pool);
01198 }
01199
01200
01201 INT max_lstart = 0;
01202 FOR_ALL_BB_STLLIST_ITEMS_FWD(bblist, bb_iter) {
01203 Compute_Fwd_OPSCH (*bb_iter, value_map, &max_lstart, compute_bitsets, pool);
01204 }
01205
01206
01207 std::list<BB*>::reverse_iterator bb_riter;
01208 FOR_ALL_BB_STLLIST_ITEMS_BKWD(bblist, bb_riter) {
01209 Compute_Bkwd_OPSCH(*bb_riter, value_map, max_lstart, compute_bitsets, pool);
01210 }
01211 }
01212
01213
01214
01215
01216 void
01217 HB_Schedule::Compute_BBSCH (BB *bb, BBSCH *bbsch)
01218 {
01219 INT critical_length = 0;
01220
01221 BBSCH_schedule_length (bbsch) = OP_scycle(BB_last_op(bb)) + 1;
01222
01223
01224 for (INT i = 0; i < VECTOR_count(_sched_vector); i++) {
01225 OP *op = OP_VECTOR_element(_sched_vector, i);
01226 OPSCH *opsch = OP_opsch(op, _hb_map);
01227 if (!critical_length &&
01228 (OPSCH_lstart(opsch) - OPSCH_estart(opsch)) == 0) {
01229 critical_length = OPSCH_scycle(opsch) - Clock;
01230 }
01231 if (CGTARG_Is_OP_Barrier(op)) {
01232 Set_BB_MEM_BARRIER(bbsch);
01233 if (critical_length) break;
01234 }
01235 }
01236
01237
01238
01239
01240
01241 BBSCH_block_parallelism (bbsch) = (INT)(VECTOR_count(_sched_vector) != 0) ?
01242 (mINT16)ceil(VECTOR_count(_sched_vector) / (critical_length + 1.)) : -1;
01243
01244 if (Cur_Gcm_Type & GCM_MINIMIZE_REGS) {
01245
01246 GTN_SET *local_set = GTN_SET_Intersection(BB_live_in(bb), BB_live_out(bb),
01247 &_hb_pool);
01248 local_set = GTN_SET_Union(local_set, BB_live_in(bb), &_hb_pool);
01249 local_set = GTN_SET_Intersection(local_set, BB_live_def(bb),
01250 &_hb_pool);
01251
01252 BBSCH_global_regcost (bbsch) = GTN_SET_Alloc_Size(local_set);
01253 }
01254
01255 }
01256
01257 #ifdef KEY
01258
01259
01260
01261
01262 void
01263 HB_Schedule::Drop_Remaining_Prefetches (BB *bb)
01264 {
01265 OP *op;
01266
01267 FOR_ALL_BB_OPs_FWD(bb, op) {
01268 if (OP_prefetch(op)) {
01269 OPSCH *opsch = OP_opsch(op, _hb_map);
01270 if (!OPSCH_scheduled(opsch)) {
01271 Set_OPSCH_scheduled(opsch);
01272 OPSCH_scycle(opsch) = Clock;
01273 VECTOR_Add_Element(_sched_vector, op);
01274 deleted_prefetch_count++;
01275 }
01276 }
01277 }
01278 }
01279
01280
01281
01282
01283 void
01284 HB_Schedule::DFS_Update_Least_Constrained(OPSCH *opsch, BOOL is_fwd)
01285 {
01286 if (One_Set_MemberP(opsch))
01287 return;
01288
01289 One_Set_Union1(opsch);
01290
01291 ARC_LIST *arcs;
01292 for (arcs = is_fwd ? OP_succs(OPSCH_op(opsch)) : OP_preds(OPSCH_op(opsch));
01293 arcs != NULL;
01294 arcs = ARC_LIST_rest(arcs)) {
01295 ARC *arc = ARC_LIST_first(arcs);
01296 OP *blocked_op = is_fwd ? ARC_succ(arc) : ARC_pred(arc);
01297 OPSCH *blocked_opsch = OP_opsch(blocked_op, _hb_map);
01298 DFS_Update_Least_Constrained(blocked_opsch, is_fwd);
01299 Update_Blocker_Info(opsch, blocked_opsch);
01300 }
01301 }
01302
01303
01304
01305
01306
01307
01308 void
01309 HB_Schedule::Update_Least_Constrained (OPSCH *opsch, BOOL is_fwd)
01310 {
01311 int i;
01312 OPSCH *blocked_opsch;
01313 OPSCH_SET *blockees = is_fwd ? OPSCH_descendants(opsch) :
01314 OPSCH_ancestors(opsch);
01315
01316 for (blocked_opsch = OPSCH_SET_Choose(blockees);
01317 blocked_opsch != OPSCH_SET_CHOOSE_FAILURE;
01318 blocked_opsch = OPSCH_SET_Choose_Next(blockees, blocked_opsch)) {
01319 OPSCH_num_blockers(blocked_opsch)--;
01320 Is_True(OPSCH_num_blockers(blocked_opsch) >= 0,
01321 ("Update_Least_Constrained: incorrect num_blockers"));
01322 }
01323
01324 Clear_One_Set();
01325 for (i = 0; i < VECTOR_count(_ready_vector); i++) {
01326 op *ready_op = OP_VECTOR_element(_ready_vector, i);
01327 OPSCH *ready_opsch = OP_opsch(ready_op, _hb_map);
01328 DFS_Update_Least_Constrained(ready_opsch, is_fwd);
01329 }
01330 }
01331
01332
01333
01334
01335 INT32
01336 HB_Schedule::Ready_Vector_Fp_Count ()
01337 {
01338 int i, count;
01339
01340 count = 0;
01341 for (i = 0; i < VECTOR_count(_ready_vector); i++) {
01342 op *ready_op = OP_VECTOR_element(_ready_vector, i);
01343 if (OP_flop(ready_op))
01344 count++;
01345 }
01346 return count;
01347 }
01348
01349
01350
01351
01352
01353 void
01354 HB_Schedule::Update_Schedule_Parameters()
01355 {
01356 _ready_count = VECTOR_count(_ready_vector);
01357 if (_ready_count == 0)
01358 return;
01359
01360 #if defined(TARG_X8664)
01361 if (_scheduled_opschs != NULL)
01362 _unsched_count = OPSCH_count - OPSCH_SET_Size(_scheduled_opschs);
01363 #endif
01364
01365
01366 if (HBS_Balance_Ready_Types()) {
01367 int ready_fp_count = Ready_Vector_Fp_Count();
01368 _ready_fp_percentage = (ready_fp_count * 100) / _ready_count;
01369 }
01370
01371
01372 if (HBS_Balance_Unsched_Types()) {
01373 OPSCH_SET *unsched_fp_opschs = OPSCH_SET_Difference(fp_opschs,
01374 _scheduled_opschs,
01375 &_hb_pool);
01376 int unsched_fp_count = OPSCH_SET_Size(unsched_fp_opschs);
01377 #if ! defined(TARG_X8664)
01378 _unsched_count = OPSCH_count - OPSCH_SET_Size(_scheduled_opschs);
01379 #endif
01380 _unsched_fp_percentage = (unsched_fp_count * 100) / _unsched_count;
01381 }
01382 }
01383 #endif
01384
01385
01386
01387
01388
01389 void
01390 HB_Schedule::Add_OP_To_Sched_Vector (OP *op, BOOL is_fwd)
01391 {
01392 ARC_LIST *arcs;
01393 OPSCH *opsch = OP_opsch (op, _hb_map);
01394
01395 Set_OPSCH_scheduled (opsch);
01396
01397 #ifdef KEY
01398 if (OP_prefetch(op))
01399 unsched_prefetch_count--;
01400
01401 if (_scheduled_opschs != NULL)
01402 _scheduled_opschs = OPSCH_SET_Union1D(_scheduled_opschs, opsch, &_hb_pool);
01403 #endif
01404
01405
01406
01407 if (!OP_dummy(op)) Set_Resource_Usage (op);
01408
01409 if (HBS_Minimize_Regs() && !OP_dummy(op)) {
01410 Update_Regs_For_OP (op);
01411 }
01412
01413
01414 VECTOR_Delete_Element (_ready_vector, op);
01415
01416 #ifdef KEY
01417 if (HBS_Balance_Ready_Types() ||
01418 HBS_Balance_Unsched_Types())
01419 Update_Least_Constrained(opsch, is_fwd);
01420 #endif
01421
01422 INT count = VECTOR_count(_ready_vector);
01423
01424
01425 for (INT i = 0; i < count; i++) {
01426 OP *ready_op = OP_VECTOR_element(_ready_vector,i);
01427 OPSCH *ready_opsch = OP_opsch (ready_op, _hb_map);
01428 if (is_fwd) {
01429 OPSCH_scycle(ready_opsch) = MAX (Clock, OPSCH_scycle(ready_opsch));
01430 } else {
01431 OPSCH_scycle(ready_opsch) = MIN (Clock, OPSCH_scycle(ready_opsch));
01432 }
01433 }
01434
01435 if (is_fwd) {
01436
01437 for (arcs = OP_succs(op); arcs != NULL; arcs = ARC_LIST_rest(arcs)) {
01438 ARC *arc = ARC_LIST_first(arcs);
01439 OP *succ_op = ARC_succ(arc);
01440 OPSCH *succ_opsch = OP_opsch (succ_op, _hb_map);
01441
01442
01443
01444 if (!OPSCH_scheduled(succ_opsch)) {
01445 INT scycle = Clock + ARC_latency(arc);
01446
01447 OPSCH_scycle(succ_opsch) = MAX (scycle, OPSCH_scycle(succ_opsch));
01448
01449 #ifdef TARG_IA64
01450 OPSCH_num_preds(succ_opsch)--;
01451 if (OPSCH_num_preds(succ_opsch) == 0) {
01452 VECTOR_Add_Element (_ready_vector, succ_op);
01453 }
01454 #else // TARG_IA64
01455
01456 if( !Is_Ldst_Addiu_Pair( opsch, succ_opsch, op, succ_op ) ){
01457 FmtAssert( OPSCH_num_preds(succ_opsch) > 0,
01458 ("HBS: invalid count of succs"));
01459
01460 OPSCH_num_preds(succ_opsch)--;
01461 if( OPSCH_num_preds(succ_opsch) == 0 ){
01462 VECTOR_Add_Element (_ready_vector, succ_op);
01463 }
01464 }
01465
01466 if (PROC_has_branch_delay_slot() && OP_br(succ_op)) {
01467
01468
01469
01470
01471
01472
01473
01474 if (OPSCH_num_preds(succ_opsch) == 1) {
01475 ARC_LIST *arcs_tmp;
01476 for (arcs_tmp = OP_succs(succ_op);
01477 arcs_tmp != NULL;
01478 arcs_tmp = ARC_LIST_rest(arcs_tmp)) {
01479 ARC *arc_tmp = ARC_LIST_first(arcs_tmp);
01480 OP *succ_succ_op = ARC_succ(arc_tmp);
01481 if (succ_succ_op &&
01482 (OP_bb(succ_op) == OP_bb(succ_succ_op))) {
01483 if (OP_results(succ_succ_op)) {
01484 if (TN_is_register(OP_result(succ_succ_op, 0)) &&
01485 TN_is_register(OP_result(succ_succ_op, 0))) {
01486 if (TN_register(OP_result(succ_succ_op, 0)) ==
01487 TN_register(OP_result(succ_succ_op, 0))) {
01488 OPSCH_num_preds(succ_opsch)--;
01489 VECTOR_Add_Element (_ready_vector, succ_op);
01490 break;
01491 }
01492 }
01493 }
01494 }
01495 }
01496 }
01497 }
01498 #endif
01499 }
01500 }
01501
01502 #ifdef KEY
01503
01504
01505
01506 if (OPSCH_ldst(opsch)) {
01507 for (arcs = OP_preds(op); arcs != NULL; arcs = ARC_LIST_rest(arcs)) {
01508 ARC *arc = ARC_LIST_first(arcs);
01509 OP *pred_op = ARC_pred(arc);
01510 OPSCH *pred_opsch = OP_opsch (pred_op, _hb_map);
01511 if (!OPSCH_scheduled(pred_opsch)) {
01512 INT opndnum = Memory_OP_Base_Opndnum (op);
01513 if( opndnum < 0 ){
01514 continue;
01515 }
01516 INT scycle = Clock + CG_DEP_Latency (pred_op, op, CG_DEP_REGIN, opndnum);
01517 OPSCH_scycle(pred_opsch) = MAX (scycle, OPSCH_scycle(pred_opsch));
01518 }
01519 }
01520 }
01521 #endif
01522
01523 } else {
01524
01525 for (arcs = OP_preds(op); arcs != NULL; arcs = ARC_LIST_rest(arcs)) {
01526 ARC *arc = ARC_LIST_first(arcs);
01527 OP *pred_op = ARC_pred(arc);
01528 OPSCH *pred_opsch = OP_opsch (pred_op, _hb_map);
01529
01530
01531
01532 if (!OPSCH_scheduled(pred_opsch)) {
01533 INT scycle = Clock - ARC_latency(arc);
01534
01535 OPSCH_scycle(pred_opsch) = MIN (scycle, OPSCH_scycle(pred_opsch));
01536 if (!Is_Ldst_Addiu_Pair (pred_opsch, opsch, pred_op, op)) {
01537 FmtAssert (OPSCH_num_succs(pred_opsch) != 0,
01538 ("HBS: invalid count of succs"));
01539
01540 OPSCH_num_succs(pred_opsch)--;
01541 if (OPSCH_num_succs(pred_opsch) == 0) {
01542 VECTOR_Add_Element (_ready_vector, pred_op);
01543 }
01544 }
01545 }
01546 }
01547
01548
01549
01550
01551 if (OPSCH_ldst(opsch)) {
01552 for (arcs = OP_succs(op); arcs != NULL; arcs = ARC_LIST_rest(arcs)) {
01553 ARC *arc = ARC_LIST_first(arcs);
01554 OP *succ_op = ARC_succ(arc);
01555 OPSCH *succ_opsch = OP_opsch (succ_op, _hb_map);
01556 if (!OPSCH_scheduled(succ_opsch)) {
01557 INT opndnum = Memory_OP_Base_Opndnum (op);
01558 #if defined(TARG_X8664) || defined(TARG_SL)
01559 if( opndnum < 0 ){
01560 continue;
01561 }
01562 #endif
01563 INT scycle = Clock - CG_DEP_Latency (succ_op, op, CG_DEP_REGIN, opndnum);
01564 OPSCH_scycle(succ_opsch) = MIN (scycle, OPSCH_scycle(succ_opsch));
01565 }
01566 }
01567 }
01568 }
01569
01570 VECTOR_Add_Element (_sched_vector, op);
01571
01572 if (Trace_HB) {
01573 #pragma mips_frequency_hint NEVER
01574 fprintf (TFile, "Cycle: %d :: ", Clock);
01575 Print_OP_No_SrcLine (op);
01576 }
01577 #ifdef KEY
01578
01579
01580 Update_Schedule_Parameters();
01581 #endif
01582 }
01583
01584 #ifdef KEY
01585
01586
01587
01588
01589 static int
01590 Is_OP_Better_For_Balance_Ready_Types(OPSCH *cur_opsch, OPSCH *best_opsch,
01591 int ready_count, int ready_fp_percentage)
01592 {
01593 OPSCH *cur_least_constrained = NULL;
01594 OPSCH *best_least_constrained = NULL;
01595
01596 if (ready_count < 4)
01597 return 0;
01598
01599 int ready_int_percentage = 100 - ready_fp_percentage;
01600
01601 if (ready_int_percentage > LOCS_Balance_Ready_Int) {
01602 cur_least_constrained = OPSCH_least_constrained_int(cur_opsch);
01603 best_least_constrained = OPSCH_least_constrained_int(best_opsch);
01604 } else if (ready_fp_percentage > LOCS_Balance_Ready_Fp) {
01605 cur_least_constrained = OPSCH_least_constrained_fp(cur_opsch);
01606 best_least_constrained = OPSCH_least_constrained_fp(best_opsch);
01607 } else {
01608 return 0;
01609 }
01610
01611 if (cur_least_constrained == NULL || best_least_constrained == NULL)
01612 return 0;
01613
01614
01615
01616 int cur_num = OPSCH_num_blockers(cur_least_constrained);
01617 int best_num = OPSCH_num_blockers(best_least_constrained);
01618 if (cur_num < best_num)
01619 return 1;
01620 if (cur_num > best_num)
01621 return -1;
01622 return 0;
01623 }
01624
01625
01626
01627
01628
01629
01630 static int
01631 Is_OP_Better_For_Balance_Unsched_Types(OPSCH *cur_opsch, OPSCH *best_opsch,
01632 int unsched_count,
01633 int unsched_fp_percentage)
01634 {
01635 OPSCH *cur_least_constrained = NULL;
01636 OPSCH *best_least_constrained = NULL;
01637
01638 if (unsched_count < 10)
01639 return 0;
01640
01641 int unsched_int_percentage = 100 - unsched_fp_percentage;
01642
01643 if (unsched_int_percentage > LOCS_Balance_Unsched_Int) {
01644 cur_least_constrained = OPSCH_least_constrained_int(cur_opsch);
01645 best_least_constrained = OPSCH_least_constrained_int(best_opsch);
01646 } else if (unsched_fp_percentage > LOCS_Balance_Unsched_Fp) {
01647 cur_least_constrained = OPSCH_least_constrained_fp(cur_opsch);
01648 best_least_constrained = OPSCH_least_constrained_fp(best_opsch);
01649 } else {
01650 return 0;
01651 }
01652
01653 if (cur_least_constrained == NULL || best_least_constrained == NULL)
01654 return 0;
01655
01656
01657
01658 int cur_num = OPSCH_num_blockers(cur_least_constrained);
01659 int best_num = OPSCH_num_blockers(best_least_constrained);
01660 Is_True(cur_num < unsched_count,
01661 ("Is_OP_Better_For_Balance_Unsched_Types: illegal blocker count"));
01662 Is_True(best_num < unsched_count,
01663 ("Is_OP_Better_For_Balance_Unsched_Types: illegal blocker count"));
01664 if (cur_num < best_num)
01665 return 1;
01666 if (cur_num > best_num)
01667 return -1;
01668 return 0;
01669 }
01670 #endif
01671
01672
01673
01674
01675 BOOL
01676 Priority_Selector::Is_OP_Better (OP *cur_op, OP *best_op)
01677 {
01678 OPSCH *cur_opsch = OP_opsch(cur_op, _cur_sched->hb_map());
01679 OPSCH *best_opsch = OP_opsch(best_op, _cur_sched->hb_map());
01680 INT cur_scycle = OPSCH_scycle(cur_opsch);
01681 INT best_scycle = OPSCH_scycle(best_opsch);
01682
01683 #ifdef KEY
01684
01685 if (_cur_sched->HBS_Drop_Unsched_Prefetches()) {
01686 if (OP_prefetch(cur_op) && !OP_prefetch(best_op) &&
01687 cur_scycle <= best_scycle)
01688 return FALSE;
01689 if (!OP_prefetch(cur_op) && OP_prefetch(best_op) &&
01690 cur_scycle >= best_scycle)
01691 return TRUE;
01692 }
01693 #endif
01694
01695 #if defined(TARG_MIPS) && !(TARG_SL)
01696
01697
01698
01699 if (cur_scycle >= best_scycle &&
01700 OP_results(cur_op) == 1 &&
01701 TN_register_class(OP_result(cur_op, 0)) == ISA_REGISTER_CLASS_fcc)
01702 return TRUE;
01703 if (best_scycle >= cur_scycle &&
01704 OP_results(best_op) == 1 &&
01705 TN_register_class(OP_result(best_op, 0)) == ISA_REGISTER_CLASS_fcc)
01706 return FALSE;
01707 #endif
01708
01709 if (_hbs_type & HBS_MINIMIZE_REGS) {
01710 INT cur_op_better = 0;
01711 cur_op_better = (cur_scycle - best_scycle);
01712 if (cur_op_better == 0) {
01713 cur_op_better = (OPSCH_dfsnum(cur_opsch) < OPSCH_dfsnum(best_opsch));
01714 }
01715 cur_op_better += (OPSCH_regcost(best_opsch) - OPSCH_regcost(cur_opsch));
01716 return (cur_op_better > 0);
01717 }
01718
01719 BOOL manual_pref = FALSE;
01720 if (OP_prefetch(cur_op)) {
01721 WN *pref_wn = Get_WN_From_Memory_OP(cur_op);
01722 if (pref_wn && WN_pf_manual(pref_wn)) manual_pref = TRUE;
01723 }
01724
01725 if (cur_scycle > best_scycle) {
01726
01727
01728 if (manual_pref) return FALSE;
01729 else return TRUE;
01730 }
01731
01732 if (cur_scycle < best_scycle) return FALSE;
01733
01734 if (manual_pref) return FALSE;
01735
01736
01737
01738 if (OPSCH_def_xfer_opnd(cur_opsch) ^ OPSCH_def_xfer_opnd(best_opsch)) {
01739 return OPSCH_def_xfer_opnd(best_opsch);
01740 }
01741
01742 #ifdef TARG_X8664
01743
01744
01745
01746
01747
01748
01749
01750
01751 if( TOP_is_vector_op( OP_code(cur_op ) ) &&
01752 TOP_is_vector_op( OP_code(best_op ) ) ){
01753 if( ( OP_load( cur_op ) && OP_load( best_op ) ) ||
01754 ( OP_store( cur_op ) && OP_store( best_op ) ) ){
01755 TN* cur_base = NULL;
01756 TN* cur_ofst = NULL;
01757 TN* best_base = NULL;
01758 TN* best_ofst = NULL;
01759
01760 OP_Base_Offset_TNs( cur_op, &cur_base, &cur_ofst );
01761 OP_Base_Offset_TNs( best_op, &best_base, &best_ofst );
01762
01763 if( cur_base == best_base &&
01764 ( cur_ofst != NULL && best_ofst != NULL ) ){
01765 if( TN_has_value( cur_ofst ) &&
01766 TN_has_value( best_ofst ) ){
01767 const bool cur_is_better = TN_value(cur_ofst) < TN_value(best_ofst );
01768 return Is_Fwd_Schedule() ? cur_is_better : !cur_is_better;
01769 }
01770
01771 if( TN_is_symbol( cur_ofst ) &&
01772 TN_is_symbol( best_ofst ) &&
01773 TN_var(cur_ofst) == TN_var(best_ofst) ){
01774 const bool cur_is_better = TN_offset( cur_ofst) < TN_offset( best_ofst );
01775 return Is_Fwd_Schedule() ? cur_is_better : !cur_is_better;
01776 }
01777 }
01778 }
01779 }
01780 #endif
01781
01782 #ifdef KEY
01783 if (_hbs_type & HBS_BALANCE_UNSCHED_TYPES) {
01784 int status =
01785 Is_OP_Better_For_Balance_Unsched_Types(cur_opsch, best_opsch,
01786 _cur_sched->Unsched_Count(),
01787 _cur_sched->Unsched_Fp_Percentage());
01788 if (status == 1) return TRUE;
01789 if (status == -1) return FALSE;
01790 }
01791 #endif
01792
01793 if (_hbs_type & HBS_DEPTH_FIRST) {
01794 return (OPSCH_dfsnum(cur_opsch) < OPSCH_dfsnum(best_opsch));
01795 }
01796
01797 if (_hbs_type & HBS_CRITICAL_PATH) {
01798 INT cur_slack, best_slack;
01799 cur_slack = OPSCH_lstart(cur_opsch) - OPSCH_estart(cur_opsch);
01800 best_slack = OPSCH_lstart(best_opsch) - OPSCH_estart(best_opsch);
01801 if (cur_slack < best_slack) return TRUE;
01802 if (cur_slack > best_slack) return FALSE;
01803
01804 if (OPSCH_estart(cur_opsch) > OPSCH_estart(best_opsch)) return TRUE;
01805 if (OPSCH_estart(cur_opsch) < OPSCH_estart(best_opsch)) return FALSE;
01806 }
01807
01808 #ifdef KEY
01809 if (_hbs_type & HBS_BALANCE_READY_TYPES) {
01810 int status =
01811 Is_OP_Better_For_Balance_Ready_Types(cur_opsch, best_opsch,
01812 _cur_sched->Ready_Count(),
01813 _cur_sched->Ready_Fp_Percentage());
01814 if (status == 1) return TRUE;
01815 if (status == -1) return FALSE;
01816 }
01817 #endif
01818
01819 return FALSE;
01820 }
01821
01822
01823
01824
01825 OP*
01826 Priority_Selector::Select_OP_For_Delay_Slot (OP *xfer_op)
01827 {
01828
01829
01830
01831 OPSCH *opsch = OP_opsch(xfer_op, _cur_sched->hb_map());
01832 if (OPSCH_num_succs(opsch) != 0) {
01833 ARC_LIST *arcs = OP_succs(xfer_op);
01834 ARC *first_arc = ARC_LIST_first(arcs);
01835 if (OPSCH_num_succs(opsch) > 1) {
01836 ARC *second_arc = ARC_LIST_first(ARC_LIST_rest(arcs));
01837 DevAssert (ARC_succ(first_arc) == ARC_succ(second_arc),
01838 ("More than 1 successor for xfer_op"));
01839 }
01840 return ARC_succ(first_arc);
01841 }
01842
01843
01844
01845
01846
01847 if (!Enable_Fill_Delay_Slots ||
01848 (_hbs_type & HBS_MINIMIZE_REGS)) return NULL;
01849
01850 OP *best_op = NULL;
01851
01852 for (INT i = VECTOR_count(_cur_sched->ready_vector())-1; i >= 0; i--)
01853 {
01854 OP *cur_op = OP_VECTOR_element (_cur_sched->ready_vector(), i);
01855
01856
01857
01858 if (OP_xfer(cur_op) || OP_Real_Ops(cur_op) != 1) continue;
01859
01860
01861 if (OP_has_hazard(cur_op)) continue;
01862
01863 #ifndef KEY
01864
01865
01866 if (OP_uncond(xfer_op) && (OP_imul(cur_op) || OP_idiv(cur_op)))
01867 continue;
01868 #endif
01869
01870
01871 if (OP_prefetch(cur_op)) {
01872 WN *pref_wn = Get_WN_From_Memory_OP(cur_op);
01873 if (pref_wn && WN_pf_manual(pref_wn)) continue;
01874 }
01875
01876
01877
01878
01879 if ((_hbs_type & HBS_FROM_GCM) && OP_moved(cur_op)) continue;
01880
01881 if (best_op == NULL || Is_OP_Better(cur_op, best_op)) {
01882 best_op = cur_op;
01883 }
01884 }
01885 return best_op;
01886 }
01887
01888 #ifdef TARG_X8664
01889
01890
01891
01892
01893
01894 int
01895 Priority_Selector::Sched_OP_With_Preallocated_TN (OP *op)
01896 {
01897
01898
01899
01900
01901
01902
01903
01904
01905
01906
01907
01908 for (int opndnum = 0; opndnum < OP_opnds(op); opndnum++) {
01909 TN *op_opnd_tn = OP_opnd(op, opndnum);
01910 if (TN_is_register(op_opnd_tn) &&
01911 TN_is_preallocated(op_opnd_tn)) {
01912 ARC_LIST *arcs1, *arcs2;
01913 for (arcs1 = OP_preds(op); arcs1 != NULL; arcs1 = ARC_LIST_rest(arcs1)) {
01914 ARC *arc1 = ARC_LIST_first(arcs1);
01915 OP *pred_op = ARC_pred(arc1);
01916 if (!OP_Defs_TN(pred_op, op_opnd_tn))
01917 continue;
01918
01919 for (int i = 0; i < OP_results(pred_op); i++) {
01920 TN *pred_result_tn = OP_result(pred_op, i);
01921 if (TN_is_register(pred_result_tn) &&
01922 TN_is_preallocated(pred_result_tn)) {
01923
01924
01925
01926 for (arcs2 = OP_succs(pred_op);
01927 arcs2 != NULL;
01928 arcs2 = ARC_LIST_rest(arcs2)) {
01929 ARC *arc2 = ARC_LIST_first(arcs2);
01930 OP *sib_op = ARC_succ(arc2);
01931
01932 if (op != sib_op &&
01933 OP_Refs_TN(sib_op, pred_result_tn)) {
01934 OPSCH *sib_opsch = OP_opsch(sib_op, _cur_sched->hb_map());
01935 if (OPSCH_scheduled(sib_opsch))
01936 return 1;
01937 if (!VECTOR_Member_Element(_cur_sched->ready_vector(),
01938 (void*) sib_op))
01939 return -1;
01940
01941 }
01942 }
01943 }
01944 }
01945 }
01946 }
01947 }
01948 return 0;
01949 }
01950 #endif
01951
01952
01953
01954
01955
01956
01957 void
01958 HB_Schedule::Put_Sched_Vector_Into_BB (BB *bb, BBSCH *bbsch, BOOL is_fwd)
01959 {
01960 INT i;
01961 INT32 cur_cycle = 0;
01962 INT prefetches_to_delete = 0;
01963 #ifdef KEY
01964 INT *old_scycle = (INT *) alloca(VECTOR_count(_sched_vector) * sizeof(INT));
01965
01966
01967
01968 if (HBS_Drop_Unsched_Prefetches()) {
01969 Is_True(!is_fwd, ("Put_Sched_Vector_Into_BB: prefetch deletion not supported under forward scheduling"));
01970
01971 OPSCH *prev_prefetch_opsch = NULL;
01972 for (i = VECTOR_count(_sched_vector) - 1; i >= 0; i--) {
01973 OP *op = OP_VECTOR_element(_sched_vector, i);
01974 OPSCH *opsch = OP_opsch(op, _hb_map);
01975 if (prev_prefetch_opsch != NULL &&
01976 OPSCH_scycle(opsch) != OPSCH_scycle(prev_prefetch_opsch)) {
01977 prefetches_to_delete++;
01978 }
01979 if (!OP_prefetch(op))
01980 break;
01981 prev_prefetch_opsch = opsch;
01982 }
01983 }
01984 #endif
01985
01986
01987
01988 for (i = VECTOR_count(_sched_vector) - 1; i >= 0; i--) {
01989 OP *op = OP_VECTOR_element(_sched_vector, i);
01990 OPSCH *opsch = OP_opsch(op, _hb_map);
01991 Reset_OPSCH_visited (opsch);
01992 #ifdef KEY
01993 old_scycle[i] = OP_scycle(op);
01994 #endif
01995 #if ! defined(TARG_X8664)
01996 OP_scycle(op) = (is_fwd) ? OPSCH_scycle(opsch) : OPSCH_scycle(opsch) - Clock;
01997 #else
01998 OP_scycle(op) = (is_fwd) ?
01999 OPSCH_scycle(opsch) :
02000 OPSCH_scycle(opsch) - Clock - prefetches_to_delete;
02001 if (OP_scycle(op) < 0) {
02002 Is_True(OP_prefetch(op),
02003 ("Put_Sched_Vector_Into_BB: incorrect clock calculation"));
02004 OP_scycle(op) = 0;
02005 }
02006 if (OP_scycle(op) > cur_cycle)
02007 cur_cycle = OP_scycle(op);
02008 #endif
02009 }
02010
02011 cur_cycle = OP_scycle(BB_last_op(bb)) + 1;
02012
02013
02014
02015
02016 if (cur_cycle < _max_sched) {
02017 #ifdef KEY
02018 Adjust_Ldst_Offsets( is_fwd );
02019 #else
02020 Adjust_Ldst_Offsets ();
02021 #endif
02022
02023 if (bbsch != NULL) {
02024 Compute_BBSCH (bb, bbsch);
02025 }
02026
02027 BB_Remove_All(bb);
02028
02029
02030
02031 for (i = (is_fwd) ? 0 : VECTOR_count(_sched_vector) - 1;
02032 (is_fwd) ? i < VECTOR_count(_sched_vector) : i >= 0;
02033 (is_fwd) ? i++ : i--) {
02034 OP *op = OP_VECTOR_element(_sched_vector, i);
02035 BB_Append_Op(bb, op);
02036 #ifdef KEY
02037
02038 if (OP_prefetch(op)) {
02039 if (prefetches_to_delete > 0) {
02040 Set_OP_prefetch_deleted(op);
02041 prefetches_to_delete--;
02042 } else {
02043 Reset_OP_prefetch_deleted(op);
02044 }
02045 }
02046 #endif
02047 }
02048 }
02049 #ifdef KEY
02050
02051
02052 else {
02053 for (i = VECTOR_count(_sched_vector) - 1; i >= 0; i--) {
02054 OP *op = OP_VECTOR_element(_sched_vector, i);
02055 OP_scycle(op) = old_scycle[i];
02056 }
02057 }
02058 #endif
02059 }
02060
02061
02062
02063
02064
02065
02066 void
02067 HB_Schedule::Put_Sched_Vector_Into_HB (std::list<BB*>& bblist)
02068 {
02069 INT i;
02070
02071
02072
02073 for (i = VECTOR_count(_sched_vector)-1; i >= 0; i--) {
02074 OP *op = OP_VECTOR_element(_sched_vector, i);
02075 OPSCH *opsch = OP_opsch(op, _hb_map);
02076 Reset_OPSCH_visited (opsch);
02077 OP_scycle(op) = OPSCH_scycle(opsch);
02078 }
02079
02080 std::list<BB*>::iterator bb_iter;
02081 FOR_ALL_BB_STLLIST_ITEMS_FWD(bblist, bb_iter) {
02082 BB_Remove_All(*bb_iter);
02083 }
02084
02085 bb_iter = bblist.begin();
02086 for (i = 0; i < VECTOR_count(_sched_vector); i++) {
02087 OP *op = OP_VECTOR_element(_sched_vector, i);
02088 FmtAssert (bb_iter != bblist.end(), ("bb_iter is NULL info"));
02089 BB_Append_Op(*bb_iter, op);
02090
02091
02092 if (OP_xfer(op)) { bb_iter++; }
02093 }
02094 }
02095
02096
02097
02098
02099 void
02100 HB_Schedule::Init_RFlag_Table (std::list<BB*>& bblist, BOOL is_fwd)
02101 {
02102 INT rtable_size = 0;
02103 INT max_resource_cycles = 0;
02104
02105 _rr_tab = TI_RES_RES_Alloc(FALSE, &_hb_pool);
02106
02107 std::list<BB*>::iterator bbi;
02108 FOR_ALL_BB_STLLIST_ITEMS_FWD(bblist, bbi) {
02109 OP *op;
02110 FOR_ALL_BB_OPs_FWD (*bbi, op) {
02111 INT cur_resource_cycles = Resource_Cycles_For_OP (op);
02112 if (cur_resource_cycles > max_resource_cycles) {
02113 max_resource_cycles = cur_resource_cycles;
02114 }
02115 INT op_latency = cur_resource_cycles;
02116 ARC_LIST *arcs;
02117 for (arcs = OP_succs(op); arcs != NULL; arcs = ARC_LIST_rest(arcs)) {
02118 ARC *arc = ARC_LIST_first(arcs);
02119 if (ARC_latency(arc) > op_latency) {
02120 op_latency = ARC_latency(arc);
02121 }
02122 }
02123 rtable_size += op_latency;
02124 }
02125 }
02126
02127
02128 Clock = (is_fwd) ? 0 : rtable_size;
02129 MAX_Clock = rtable_size;
02130
02131
02132
02133 rtable_size += max_resource_cycles;
02134
02135 TI_RES_RES_Set_BB_Cycle_Count(_rr_tab, rtable_size);
02136 }
02137
02138 List_Based_Bkwd::List_Based_Bkwd (BB *bb, HB_Schedule *sched, HBS_TYPE type,
02139 MEM_POOL *pool) :
02140 Priority_Selector(bb, sched, type, pool)
02141 {
02142
02143
02144 Build_Ready_Vector (bb, this->Is_Fwd_Schedule());
02145
02146 BOOL traverse_dag = sched->HBS_Depth_First();
02147 #ifdef KEY
02148 traverse_dag |= sched->HBS_Balance_Ready_Types();
02149 traverse_dag |= sched->HBS_Balance_Unsched_Types();
02150 #endif
02151
02152 if (traverse_dag)
02153 Compute_DFO (sched, sched->hb_map(), this->Is_Fwd_Schedule());
02154
02155 if (Trace_HB) Print_BB_For_HB (bb, sched->hb_map());
02156
02157 }
02158
02159 List_Based_Bkwd::List_Based_Bkwd (std::list<BB*> bblist, HB_Schedule *sched,
02160 HBS_TYPE type, MEM_POOL *pool) :
02161 Priority_Selector(bblist, sched, type, pool)
02162 {
02163
02164
02165 Build_Ready_Vector (bblist, this->Is_Fwd_Schedule());
02166
02167 BOOL traverse_dag = sched->HBS_Depth_First();
02168 #ifdef KEY
02169 traverse_dag |= sched->HBS_Balance_Ready_Types();
02170 traverse_dag |= sched->HBS_Balance_Unsched_Types();
02171 #endif
02172
02173 if (traverse_dag)
02174 Compute_DFO(sched, sched->hb_map(), this->Is_Fwd_Schedule());
02175
02176 if (Trace_HB) Print_BB_For_HB (bblist, sched->hb_map());
02177
02178 }
02179
02180
02181
02182
02183 void*
02184 Priority_Selector::Get_Next_Element(HB_Schedule *Cur_Sched)
02185 {
02186 #ifdef TARG_X8664
02187 OP *last_choice_op = NULL;
02188 #endif
02189 _best_op = NULL;
02190
02191 if (Trace_HB) {
02192 #pragma mips_frequency_hint NEVER
02193 fprintf (TFile, "-------------------------------------------\n");
02194 #ifdef KEY
02195 if (Cur_Sched->HBS_Balance_Ready_Types()) {
02196 fprintf(TFile, "Ready vector OPs:%d (%d%% fp)\n",
02197 Cur_Sched->Ready_Count(), Cur_Sched->Ready_Fp_Percentage());
02198 }
02199 if (Cur_Sched->HBS_Balance_Unsched_Types()) {
02200 fprintf(TFile, "Unscheduled OPs:%d (%d%% fp)\n",
02201 Cur_Sched->Unsched_Count(), Cur_Sched->Unsched_Fp_Percentage());
02202 }
02203 #endif
02204 fprintf (TFile, "Candidates for Scheduling:\n");
02205 fprintf (TFile, "-------------------------------------------\n");
02206 }
02207
02208 for (INT i = VECTOR_count(Cur_Sched->ready_vector())-1; i >= 0; i--)
02209 {
02210 OP *cur_op = OP_VECTOR_element (Cur_Sched->ready_vector(), i);
02211
02212
02213 if (!OP_dummy(cur_op)) Cur_Sched->Find_Schedule_Cycle (cur_op, FALSE);
02214
02215 if (Cur_Sched->HBS_Minimize_Regs() && !OP_dummy(cur_op)) {
02216 Cur_Sched->Estimate_Reg_Cost_For_OP (cur_op);
02217 }
02218
02219 if (Trace_HB) {
02220 #pragma mips_frequency_hint NEVER
02221 Print_OPSCH (cur_op, Cur_Sched->hb_map());
02222 }
02223
02224 #ifdef TARG_X8664_TODO
02225
02226
02227 const bool is_fwd = Is_Fwd_Schedule();
02228
02229 if( ( is_fwd && TOP_is_vector_high_loadstore( OP_code(cur_op) ) ) ||
02230 ( !is_fwd && TOP_is_vector_lo_loadstore( OP_code(cur_op) ) ) ){
02231 for( ARC_LIST* arcs = is_fwd ? OP_preds(cur_op) : OP_succs(cur_op);
02232 arcs != NULL;
02233 arcs = ARC_LIST_rest(arcs) ){
02234 const ARC* arc = ARC_LIST_first(arcs);
02235 OP* couple = is_fwd ? ARC_pred(arc) : ARC_succ(arc);
02236
02237 if( ( couple == _last_sched_op ) &&
02238 ( ARC_kind(arc) == CG_DEP_MEMOUT ||
02239 ARC_kind(arc) == CG_DEP_REGOUT ) ){
02240 _last_sched_op = _best_op = cur_op;
02241 return (void*)_best_op;
02242 }
02243 }
02244 }
02245 #endif
02246
02247 #ifdef TARG_X8664
02248
02249
02250
02251
02252
02253 if (Cur_Sched->HBS_Minimize_Regs()) {
02254 INT status = Sched_OP_With_Preallocated_TN(cur_op);
02255 if (status == 1) {
02256 _best_op = cur_op;
02257 break;
02258 } else if (status == -1) {
02259 last_choice_op = cur_op;
02260 continue;
02261 }
02262 }
02263 #endif
02264
02265
02266
02267
02268 if (_best_op == NULL || Is_OP_Better (cur_op, _best_op)) {
02269 _best_op = cur_op;
02270 }
02271 }
02272
02273 #ifdef TARG_X8664
02274
02275 if (_best_op == NULL)
02276 _best_op = last_choice_op;
02277
02278 _last_sched_op = _best_op;
02279 #endif // KEY
02280
02281 return (void *) _best_op;
02282 }
02283
02284
02285
02286
02287 BOOL
02288 List_Based_Fwd::Is_OP_Better (OP *cur_op, OP *best_op)
02289 {
02290 OPSCH *cur_opsch = OP_opsch(cur_op, _cur_sched->hb_map());
02291 OPSCH *best_opsch = OP_opsch(best_op, _cur_sched->hb_map());
02292 INT cur_scycle = OPSCH_scycle(cur_opsch);
02293 INT best_scycle = OPSCH_scycle(best_opsch);
02294
02295 #if defined(TARG_MIPS) && !defined(TARG_SL)
02296
02297
02298
02299 if (cur_scycle <= best_scycle) {
02300 for (int opndnum = 0; opndnum < OP_opnds(cur_op); opndnum++) {
02301 TN *tn = OP_opnd(cur_op, opndnum);
02302 if (TN_is_register(tn) &&
02303 TN_register_class(tn) == ISA_REGISTER_CLASS_fcc)
02304 return TRUE;
02305 }
02306 }
02307 if (best_scycle <= cur_scycle) {
02308 for (int opndnum = 0; opndnum < OP_opnds(best_op); opndnum++) {
02309 TN *tn = OP_opnd(best_op, opndnum);
02310 if (TN_is_register(tn) &&
02311 TN_register_class(tn) == ISA_REGISTER_CLASS_fcc)
02312 return FALSE;
02313 }
02314 }
02315 #endif
02316
02317 if (_hbs_type & HBS_MINIMIZE_REGS) {
02318 INT cur_op_better = (best_scycle - cur_scycle);
02319 if (cur_op_better == 0) {
02320 cur_op_better = (OPSCH_dfsnum(cur_opsch) < OPSCH_dfsnum(best_opsch));
02321 }
02322 cur_op_better += (OPSCH_regcost(cur_opsch) - OPSCH_regcost(best_opsch));
02323 return (cur_op_better > 0);
02324 }
02325
02326 if (cur_scycle < best_scycle) return TRUE;
02327
02328 if (cur_scycle > best_scycle) return FALSE;
02329
02330
02331
02332
02333
02334
02335 if (OP_branch_predict(cur_op) &&
02336 ((BB_length(OP_bb(cur_op)) * 1.3 * INST_BYTES)
02337 < DEFAULT_BRP_BRANCH_LIMIT))
02338 return TRUE;
02339
02340 #ifdef KEY
02341 if (_hbs_type & HBS_BALANCE_UNSCHED_TYPES) {
02342 int status =
02343 Is_OP_Better_For_Balance_Unsched_Types(cur_opsch, best_opsch,
02344 _cur_sched->Unsched_Count(),
02345 _cur_sched->Unsched_Fp_Percentage());
02346 if (status == 1) return TRUE;
02347 if (status == -1) return FALSE;
02348 }
02349 #endif
02350
02351 if (_hbs_type & HBS_DEPTH_FIRST) {
02352 return (OPSCH_dfsnum(cur_opsch) < OPSCH_dfsnum(best_opsch));
02353 }
02354
02355 if (_hbs_type & HBS_CRITICAL_PATH) {
02356 INT cur_slack, best_slack;
02357 cur_slack = OPSCH_lstart(cur_opsch) - OPSCH_estart(cur_opsch);
02358 best_slack = OPSCH_lstart(best_opsch) - OPSCH_estart(best_opsch);
02359 if (cur_slack < best_slack) return TRUE;
02360 if (cur_slack > best_slack) return FALSE;
02361
02362 if (OPSCH_estart(cur_opsch) > OPSCH_estart(best_opsch)) return TRUE;
02363 if (OPSCH_estart(cur_opsch) < OPSCH_estart(best_opsch)) return FALSE;
02364 }
02365
02366 #ifdef TARG_X8664
02367
02368
02369
02370
02371
02372
02373
02374 if( OP_memory(cur_op) && OP_prefetch(best_op) ){
02375 return Is_Fwd_Schedule() ? TRUE : FALSE;
02376 }
02377
02378 if( OP_memory(best_op) && OP_prefetch(cur_op) ){
02379 return Is_Fwd_Schedule() ? FALSE : TRUE;
02380 }
02381
02382
02383
02384
02385
02386 if( ( OP_load( cur_op ) && OP_load( best_op ) ) ||
02387 ( OP_store( cur_op ) && OP_store( best_op ) ) ){
02388 TN* cur_base = NULL;
02389 TN* cur_ofst = NULL;
02390 TN* best_base = NULL;
02391 TN* best_ofst = NULL;
02392
02393 OP_Base_Offset_TNs( cur_op, &cur_base, &cur_ofst );
02394 OP_Base_Offset_TNs( best_op, &best_base, &best_ofst );
02395
02396 if( cur_base == best_base &&
02397 ( cur_ofst != NULL && best_ofst != NULL ) ){
02398 if( TN_has_value( cur_ofst ) &&
02399 TN_has_value( best_ofst ) ){
02400 const bool cur_is_better = TN_value(cur_ofst) < TN_value(best_ofst );
02401 return Is_Fwd_Schedule() ? cur_is_better : !cur_is_better;
02402 }
02403
02404 if( TN_is_symbol( cur_ofst ) &&
02405 TN_is_symbol( best_ofst ) &&
02406 TN_var(cur_ofst) == TN_var(best_ofst) ){
02407 const bool cur_is_better = TN_offset( cur_ofst) < TN_offset( best_ofst );
02408 return Is_Fwd_Schedule() ? cur_is_better : !cur_is_better;
02409 }
02410 }
02411 }
02412 #endif
02413
02414 #ifdef KEY
02415 if (_hbs_type & HBS_BALANCE_READY_TYPES) {
02416 int status =
02417 Is_OP_Better_For_Balance_Ready_Types(cur_opsch, best_opsch,
02418 _cur_sched->Ready_Count(),
02419 _cur_sched->Ready_Fp_Percentage());
02420 if (status == 1) return TRUE;
02421 if (status == -1) return FALSE;
02422 }
02423 #endif
02424
02425 return FALSE;
02426 }
02427
02428 List_Based_Fwd::List_Based_Fwd (BB *bb, HB_Schedule *sched, HBS_TYPE type,
02429 MEM_POOL *pool) :
02430 Priority_Selector(bb, sched, type, pool)
02431 {
02432
02433
02434 Build_Ready_Vector (bb, this->Is_Fwd_Schedule());
02435
02436 BOOL traverse_dag = sched->HBS_Depth_First();
02437 #ifdef KEY
02438 traverse_dag |= sched->HBS_Balance_Ready_Types();
02439 traverse_dag |= sched->HBS_Balance_Unsched_Types();
02440 #endif
02441
02442 if (traverse_dag)
02443 Compute_DFO(sched, sched->hb_map(), this->Is_Fwd_Schedule());
02444
02445 if (Trace_HB) Print_BB_For_HB (bb, sched->hb_map());
02446
02447 }
02448
02449 List_Based_Fwd::List_Based_Fwd (std::list<BB*> bblist, HB_Schedule *sched,
02450 HBS_TYPE type, MEM_POOL *pool) :
02451 Priority_Selector(bblist, sched, type, pool)
02452 {
02453
02454
02455 Build_Ready_Vector (bblist, this->Is_Fwd_Schedule());
02456
02457 BOOL traverse_dag = sched->HBS_Depth_First();
02458 #ifdef KEY
02459 traverse_dag |= sched->HBS_Balance_Ready_Types();
02460 traverse_dag |= sched->HBS_Balance_Unsched_Types();
02461 #endif
02462
02463 if (traverse_dag)
02464 Compute_DFO(sched, sched->hb_map(), this->Is_Fwd_Schedule());
02465
02466 if (Trace_HB) Print_BB_For_HB (bblist, sched->hb_map());
02467
02468 }
02469
02470
02471
02472
02473 void*
02474 List_Based_Fwd::Get_Next_Element(HB_Schedule *Cur_Sched)
02475 {
02476 _best_op = NULL;
02477
02478 if (Trace_HB) {
02479 #pragma mips_frequency_hint NEVER
02480 fprintf (TFile, "-------------------------------------------\n");
02481 #ifdef KEY
02482 if (Cur_Sched->HBS_Balance_Ready_Types()) {
02483 fprintf(TFile, "Ready vector OPs:%d (%d%% fp)\n",
02484 Cur_Sched->Ready_Count(), Cur_Sched->Ready_Fp_Percentage());
02485 }
02486 if (Cur_Sched->HBS_Balance_Unsched_Types()) {
02487 fprintf(TFile, "Unscheduled OPs:%d (%d%% fp)\n",
02488 Cur_Sched->Unsched_Count(), Cur_Sched->Unsched_Fp_Percentage());
02489 }
02490 #endif
02491 fprintf (TFile, "Candidates for Scheduling:\n");
02492 fprintf (TFile, "-------------------------------------------\n");
02493 }
02494
02495 for (INT i = VECTOR_count(Cur_Sched->ready_vector())-1; i >= 0; i--)
02496 {
02497 OP *cur_op = OP_VECTOR_element (Cur_Sched->ready_vector(), i);
02498
02499
02500 if (!OP_dummy(cur_op)) Cur_Sched->Find_Schedule_Cycle (cur_op, TRUE);
02501
02502 if (Cur_Sched->HBS_Minimize_Regs() && !OP_dummy(cur_op)) {
02503 Cur_Sched->Estimate_Reg_Cost_For_OP (cur_op);
02504 }
02505
02506 if (Trace_HB) {
02507 #pragma mips_frequency_hint NEVER
02508 Print_OPSCH (cur_op, Cur_Sched->hb_map());
02509 }
02510
02511
02512
02513
02514 if (_best_op == NULL || Is_OP_Better (cur_op, _best_op)) {
02515 _best_op = cur_op;
02516 }
02517 }
02518
02519 #ifdef KEY
02520 _last_sched_op = _best_op;
02521 #endif // KEY
02522
02523 return (void *) _best_op;
02524 }
02525
02526
02527
02528
02529
02530
02531
02532 void
02533 HB_Schedule::Invoke_Pre_HBS_Phase(BB* bb)
02534 {
02535
02536 OP *op, *prev_op;
02537 OP *next_op;
02538
02539 #if defined(TARG_X8664) || defined(TARG_SL)
02540 op = BB_last_op( bb );
02541 if( op != NULL && OP_cond(op) ){
02542
02543
02544
02545
02546
02547 for( op = OP_prev(op); op != NULL; op = OP_prev(op) ){
02548 #ifdef TARG_X8664
02549 if( TOP_is_change_rflags( OP_code(op) ) ){
02550 #else
02551 if (1) {
02552 #endif
02553 if( !OP_icmp( op ) )
02554 return;
02555 break;
02556 }
02557 }
02558 }
02559 #endif
02560
02561
02562
02563
02564
02565
02566
02567
02568
02569 if (HBS_Before_LRA()) {
02570 if (BB_entry(bb)) {
02571 _prolog_bb = Gen_BB_Like (bb);
02572 for (op = BB_entry_sp_adj_op (bb); op != NULL; op = prev_op) {
02573 prev_op = OP_prev(op);
02574 BB_Move_Op_To_Start (_prolog_bb, bb, op);
02575 }
02576 }
02577 if (BB_exit(bb)) {
02578 _epilog_bb = Gen_BB_Like (bb);
02579 for (op = BB_exit_sp_adj_op (bb); op != NULL; op = next_op) {
02580 next_op = OP_next(op);
02581 BB_Move_Op_To_End (_epilog_bb, bb, op);
02582 }
02583 }
02584 for (op = BB_first_op(bb); op != NULL; op = next_op) {
02585 if (!OP_copy(op) && !OP_glue(op) && !OP_no_move_before_gra(op) && !OP_access_reg_bank(op)) break;
02586 next_op = OP_next(op);
02587 if (_prolog_bb == NULL) {
02588 _prolog_bb = Gen_BB_Like (bb);
02589 }
02590 BB_Move_Op_To_End (_prolog_bb, bb, op);
02591 }
02592 for (op = BB_last_op(bb); op != NULL; op = prev_op) {
02593 prev_op = OP_prev(op);
02594 if (!OP_copy(op) && !OP_glue(op) && !OP_no_move_before_gra(op) && !OP_access_reg_bank(op)) {
02595
02596 if (!OP_xfer(op) ||
02597 prev_op == NULL ||
02598 (!OP_copy(prev_op) && !OP_glue(prev_op) && !OP_no_move_before_gra(op)))
02599 break;
02600 }
02601 if (_epilog_bb == NULL) {
02602 _epilog_bb = Gen_BB_Like (bb);
02603 }
02604 BB_Move_Op_To_Start (_epilog_bb, bb, op);
02605
02606
02607
02608
02609 if (prev_op && OP_xfer(prev_op))
02610 BB_Move_Op_To_Start (_epilog_bb, bb, prev_op);
02611 }
02612 }
02613 else {
02614
02615
02616 for (op = BB_first_op(bb); op != NULL; op = next_op) {
02617 if (!OP_side_effects(op)) break;
02618 next_op = OP_next(op);
02619 if (_prolog_bb == NULL) {
02620 _prolog_bb = Gen_BB_Like (bb);
02621 }
02622 BB_Move_Op_To_End (_prolog_bb, bb, op);
02623 }
02624
02625
02626 if (BB_rid(bb) != NULL && RID_cginfo(BB_rid(bb)) != NULL) {
02627 CGRIN *cgrin = RID_cginfo(BB_rid(bb));
02628 if (CGRIN_first_bb(cgrin) != NULL &&
02629 BB_next(CGRIN_first_bb(cgrin)) == NULL) {
02630
02631
02632 for (op = BB_first_op(bb); op != NULL; op = next_op) {
02633 if (OP_code(op) != TOP_begin_pregtn) break;
02634 next_op = OP_next(op);
02635 if (_prolog_bb == NULL) {
02636 _prolog_bb = Gen_BB_Like (bb);
02637 }
02638 BB_Move_Op_To_End (_prolog_bb, bb, op);
02639 }
02640
02641 for (op = BB_last_op(bb); op != NULL; op = prev_op) {
02642 prev_op = OP_prev(op);
02643 if (OP_code(op) != TOP_end_pregtn) {
02644
02645 if (!OP_xfer(op) || prev_op == NULL ||
02646 (OP_code(prev_op) != TOP_end_pregtn))
02647 break;
02648 }
02649 if (_epilog_bb == NULL) {
02650 _epilog_bb = Gen_BB_Like (bb);
02651 }
02652 BB_Move_Op_To_Start (_epilog_bb, bb, op);
02653 }
02654 }
02655 }
02656 }
02657 }
02658
02659
02660
02661
02662
02663
02664
02665
02666 void
02667 HB_Schedule::Invoke_Pre_HBB_Phase(std::list<BB*> bblist)
02668 {
02669
02670 std::list<BB*>::iterator bb_iter;
02671 std::list<BB*>::reverse_iterator bb_riter;
02672
02673 bb_iter = bblist.begin();
02674 bb_riter = bblist.rbegin();
02675
02676 BB *first_bb = *bb_iter; BB *last_bb = *bb_riter;
02677
02678 OP *op, *prev_op;
02679 OP *next_op;
02680
02681
02682
02683
02684
02685
02686
02687 if (HBS_Before_LRA()) {
02688 if (BB_entry(first_bb)) {
02689 _prolog_bb = Gen_BB_Like (first_bb);
02690 for (op = BB_entry_sp_adj_op (first_bb); op != NULL; op = prev_op) {
02691 prev_op = OP_prev(op);
02692 BB_Move_Op_To_Start (_prolog_bb, first_bb, op);
02693 }
02694 }
02695 if (BB_exit(last_bb)) {
02696 _epilog_bb = Gen_BB_Like (last_bb);
02697 for (op = BB_exit_sp_adj_op (last_bb); op != NULL; op = next_op) {
02698 next_op = OP_next(op);
02699 BB_Move_Op_To_End (_epilog_bb, last_bb, op);
02700 }
02701 }
02702 }
02703
02704 for (op = BB_first_op(first_bb); op != NULL; op = next_op) {
02705 if (!OP_side_effects(op)) break;
02706 next_op = OP_next(op);
02707 if (_prolog_bb == NULL) {
02708 _prolog_bb = Gen_BB_Like (first_bb);
02709 }
02710 BB_Move_Op_To_End (_prolog_bb, first_bb, op);
02711 }
02712 }
02713
02714 void
02715 HB_Schedule::Invoke_Post_HBS_Phase(BB* bb)
02716 {
02717
02718
02719
02720 if (_prolog_bb != NULL) {
02721 BB_Prepend_All (bb, _prolog_bb);
02722 if (HBS_Before_LRA()) Reset_BB_scheduled (bb);
02723 }
02724
02725 if (_epilog_bb != NULL) {
02726 BB_Append_All(bb, _epilog_bb);
02727 if (HBS_Before_LRA()) Reset_BB_scheduled (bb);
02728 }
02729
02730 }
02731
02732 void
02733 HB_Schedule::Invoke_Post_HBB_Phase(std::list<BB*> bblist)
02734 {
02735
02736 std::list<BB*>::iterator bb_iter;
02737 std::list<BB*>::reverse_iterator bb_riter;
02738
02739 bb_iter = bblist.begin();
02740 bb_riter = bblist.rbegin();
02741
02742 BB *first_bb = *bb_iter; BB *last_bb = *bb_riter;
02743
02744
02745
02746 if (_prolog_bb != NULL) {
02747 BB_Prepend_All (first_bb, _prolog_bb);
02748 if (HBS_Before_LRA()) Reset_BB_scheduled (first_bb);
02749 }
02750
02751 if (_epilog_bb != NULL) {
02752 BB_Append_All(last_bb, _epilog_bb);
02753 if (HBS_Before_LRA()) Reset_BB_scheduled (last_bb);
02754 }
02755
02756 }
02757
02758 INT
02759 HB_Schedule::Calculate_Etime(OP *op)
02760 {
02761 OPSCH *opsch = OP_opsch(op, _hb_map);
02762 return OPSCH_estart(opsch);
02763 }
02764
02765 INT
02766 HB_Schedule::Calculate_Ltime(OP *op)
02767 {
02768 OPSCH *opsch = OP_opsch(op, _hb_map);
02769 return OPSCH_lstart(opsch);
02770 }
02771
02772 BOOL
02773 HB_Schedule::Can_Schedule_Op (OP *cur_op, INT cur_time)
02774 {
02775 if (Check_Resource_Usage (cur_op, cur_time)) return TRUE;
02776
02777 return FALSE;
02778 }
02779
02780
02781 void
02782 HB_Schedule::Schedule_Block (BB *bb, BBSCH *bbsch, int scheduling_algorithm)
02783 {
02784 _sched_vector = VECTOR_Init (BB_length(bb), &_hb_pool);
02785
02786 #ifdef KEY
02787 _scheduled_opschs = NULL;
02788 if (HBS_Balance_Unsched_Types() ||
02789 HBS_Drop_Unsched_Prefetches()) {
02790 _scheduled_opschs = OPSCH_SET_Create_Empty(BB_length(bb), &_hb_pool);
02791 }
02792 #endif
02793
02794 std::list<BB*> blocks;
02795 blocks.push_back(bb);
02796
02797 #if defined (TARG_X8664)
02798 Is_True(scheduling_algorithm == 0 || scheduling_algorithm == 1,
02799 ("Schedule_Block: illegal scheduling_algorithm"));
02800 Init_RFlag_Table( blocks, scheduling_algorithm);
02801 #elif defined (TARG_SL)
02802 const BOOL org_LOCS_Fwd_Scheduling = LOCS_Fwd_Scheduling;
02803 if( _hbs_type & HBS_MINIMIZE_REGS ){
02804 LOCS_Fwd_Scheduling = FALSE;
02805 }
02806 Init_RFlag_Table( blocks, LOCS_Fwd_Scheduling );
02807 #elif defined (TARG_IA64)
02808 Init_RFlag_Table (blocks, TRUE);
02809 #else
02810 Init_RFlag_Table (blocks, FALSE);
02811 #endif
02812
02813 Compute_OPSCH(bb, _hb_map, &_hb_pool,
02814 HBS_Balance_Ready_Types() || HBS_Balance_Unsched_Types(),
02815 scheduling_algorithm );
02816
02817 if (HBS_Minimize_Regs()) {
02818 Init_Register_Map (bb);
02819 }
02820
02821 Priority_Selector *priority_fn;
02822 Cycle_Selector *cycle_fn;
02823
02824 #if defined(TARG_X8664) || defined(TARG_SL) || defined(TARG_MIPS)
02825 #if defined(TARG_SL) || defined(TARG_MIPS)
02826 if( LOCS_Fwd_Scheduling ){
02827 #else
02828 if (scheduling_algorithm == 1) {
02829 #endif
02830 priority_fn = CXX_NEW( List_Based_Fwd(bb, this, _hbs_type, &_hb_pool),
02831 &_hb_pool );
02832 cycle_fn = CXX_NEW( Fwd_Cycle_Sel(), &_hb_pool );
02833
02834 } else {
02835 priority_fn = CXX_NEW( List_Based_Bkwd(bb, this, _hbs_type, &_hb_pool),
02836 &_hb_pool );
02837 cycle_fn = CXX_NEW( Bkwd_Cycle_Sel(), &_hb_pool );
02838 }
02839 #else // TARG_X8664 || TARG_SL || TARG_MIPS
02840 #ifndef TARG_IA64
02841 if( LOCS_Scheduling_Algorithm == 1 ){
02842 priority_fn = CXX_NEW( List_Based_Fwd(bb, this, _hbs_type, &_hb_pool),
02843 &_hb_pool );
02844 cycle_fn = CXX_NEW( Fwd_Cycle_Sel(), &_hb_pool );
02845
02846 } else {
02847 priority_fn = CXX_NEW( List_Based_Bkwd(bb, this, _hbs_type, &_hb_pool),
02848 &_hb_pool );
02849 cycle_fn = CXX_NEW( Bkwd_Cycle_Sel(), &_hb_pool );
02850 }
02851 #else
02852
02853 priority_fn =
02854 CXX_NEW(List_Based_Fwd(bb, this, _hbs_type, &_hb_pool), &_hb_pool);
02855 cycle_fn = CXX_NEW(Fwd_Cycle_Sel(), &_hb_pool);
02856 #endif
02857 #endif
02858
02859
02860
02861 OP *cur_op;
02862 OP *xfer_op = BB_xfer_op(bb);
02863
02864
02865
02866
02867
02868 if (!priority_fn->Is_Fwd_Schedule()) {
02869 if (xfer_op) {
02870 if (PROC_has_branch_delay_slot()) {
02871 cur_op = priority_fn->Select_OP_For_Delay_Slot (xfer_op);
02872 if (cur_op) {
02873 Add_OP_To_Sched_Vector(cur_op, priority_fn->Is_Fwd_Schedule());
02874 #ifdef TARG_MIPS
02875
02876 Clock--;
02877 OPSCH *xfer_opsch = OP_opsch(xfer_op, _hb_map);
02878 OPSCH_scycle(xfer_opsch) = MIN(Clock, OPSCH_scycle(xfer_opsch));
02879 #endif
02880 }
02881 }
02882 Add_OP_To_Sched_Vector(xfer_op, priority_fn->Is_Fwd_Schedule());
02883 }
02884 }
02885
02886 INT cur_time;
02887
02888 for (cur_op = (OP*) priority_fn->Get_Next_Element(this); cur_op != NULL;
02889 cur_op = (OP*) priority_fn->Get_Next_Element(this)) {
02890
02891 if (!OP_dummy(cur_op)) {
02892 INT etime = Calculate_Etime(cur_op);
02893 INT ltime = Calculate_Ltime(cur_op);
02894 cycle_fn->Init(cur_op, etime, ltime);
02895
02896 for (cur_time = cycle_fn->Get_Cycle(); cur_time >= cycle_fn->Bound();
02897 cur_time = cycle_fn->Next_Cycle()) {
02898 if (Can_Schedule_Op(cur_op, cur_time)) break;
02899 }
02900 }
02901
02902
02903
02904 Add_OP_To_Sched_Vector(cur_op, priority_fn->Is_Fwd_Schedule());
02905 }
02906
02907 if( BB_length(bb) != VECTOR_count(_sched_vector) ){
02908 if( Trace_HB )
02909 Print_BB_For_HB( bb, hb_map() );
02910 FmtAssert( false, ("Some ops are not scheduled yet") );
02911 }
02912
02913
02914 Put_Sched_Vector_Into_BB (bb, bbsch, priority_fn->Is_Fwd_Schedule() );
02915 #if defined (TARG_SL)
02916 LOCS_Fwd_Scheduling = org_LOCS_Fwd_Scheduling;
02917 #endif
02918 }
02919
02920 void
02921 HB_Schedule::Schedule_Blocks (std::list<BB*>& bblist)
02922 {
02923 std::list<BB*>::iterator bbi;
02924 UINT32 length = 0;
02925
02926 FOR_ALL_BB_STLLIST_ITEMS_FWD(bblist, bbi) {
02927 length += BB_length(*bbi);
02928 }
02929
02930 _sched_vector = VECTOR_Init (length, &_hb_pool);
02931
02932 #if defined (TARG_X8664)
02933 _scheduled_opschs = NULL;
02934 if (HBS_Balance_Unsched_Types() ||
02935 HBS_Drop_Unsched_Prefetches()) {
02936 _scheduled_opschs = OPSCH_SET_Create_Empty(length, &_hb_pool);
02937 }
02938 #else
02939 _scheduled_opschs = (_hbs_type & HBS_BALANCE_UNSCHED_TYPES) ?
02940 OPSCH_SET_Create_Empty(length, &_hb_pool) : NULL;
02941 #endif
02942
02943 Init_RFlag_Table (bblist, TRUE);
02944 Compute_OPSCHs (bblist, _hb_map, &_hb_pool,
02945 HBS_Balance_Ready_Types() || HBS_Balance_Unsched_Types(),
02946 TRUE );
02947
02948
02949
02950
02951
02952
02953
02954 List_Based_Fwd *priority_fn =
02955 CXX_NEW(List_Based_Fwd(bblist, this, _hbs_type, &_hb_pool), &_hb_pool);
02956
02957 Fwd_Cycle_Sel *cycle_fn = CXX_NEW(Fwd_Cycle_Sel(), &_hb_pool);
02958
02959 OP *cur_op;
02960 INT cur_time;
02961
02962
02963 for (cur_op = (OP*) priority_fn->Get_Next_Element(this); cur_op != NULL;
02964 cur_op = (OP*) priority_fn->Get_Next_Element(this)) {
02965
02966 if (!OP_dummy(cur_op)) {
02967 INT etime = Calculate_Etime(cur_op);
02968 INT ltime = Calculate_Ltime(cur_op);
02969 cycle_fn->Init(cur_op, etime, ltime);
02970
02971 for (cur_time = cycle_fn->Get_Cycle(); cur_time != cycle_fn->Bound();
02972 cur_time = cycle_fn->Next_Cycle()) {
02973
02974 if (Can_Schedule_Op(cur_op, cur_time)) break;
02975 }
02976 }
02977
02978
02979
02980 Add_OP_To_Sched_Vector(cur_op, priority_fn->Is_Fwd_Schedule());
02981 }
02982
02983
02984 Put_Sched_Vector_Into_HB (bblist);
02985
02986 }
02987
02988
02989
02990
02991
02992
02993
02994
02995
02996
02997
02998
02999
03000
03001
03002
03003 HB_Schedule::HB_Schedule()
03004 {
03005 _prolog_bb = NULL;
03006 _epilog_bb = NULL;
03007
03008
03009 MEM_POOL_Initialize (&_hb_pool, "HB_pool", FALSE);
03010 MEM_POOL_Initialize (&_hb_map_pool, "HB_map_pool", FALSE);
03011 MEM_POOL_Push(&_hb_pool);
03012 MEM_POOL_Push (&_hb_map_pool);
03013
03014 _hb_map = BB_MAP_Create ();
03015 Trace_HB = Get_Trace (TP_SCHED, 1);
03016 }
03017
03018 void
03019 HB_Schedule::Init(BB *bb, HBS_TYPE hbs_type, INT32 max_sched,
03020 BBSCH *bbsch, mINT8 *regs_avail)
03021 {
03022 _hbs_type = hbs_type;
03023 _max_sched = max_sched;
03024 if (regs_avail) {
03025 for (INT i = ISA_REGISTER_CLASS_MIN;i <= ISA_REGISTER_CLASS_MAX; i++)
03026 _Cur_Regs_Avail[i] = regs_avail[i];
03027 }
03028
03029 BB_OP_MAP omap = BB_OP_MAP_Create(bb, &_hb_map_pool);
03030 BB_MAP_Set(_hb_map, bb, omap);
03031
03032 _ready_vector = VECTOR_Init (BB_length(bb), &_hb_pool);
03033
03034 #ifdef KEY
03035 _one_set_counter = 0;
03036 #endif
03037 }
03038
03039 void
03040 HB_Schedule::Init(std::list<BB*> bblist, HBS_TYPE hbs_type, mINT8 *regs_avail)
03041 {
03042 _hbs_type = hbs_type;
03043 if (regs_avail) {
03044 for (INT i = ISA_REGISTER_CLASS_MIN;i <= ISA_REGISTER_CLASS_MAX; i++)
03045 _Cur_Regs_Avail[i] = regs_avail[i];
03046 }
03047
03048 UINT32 length = 0;
03049 std::list<BB*>::iterator bbi;
03050
03051 FOR_ALL_BB_STLLIST_ITEMS_FWD(bblist, bbi) {
03052 BB_OP_MAP omap = BB_OP_MAP_Create(*bbi, &_hb_map_pool);
03053 BB_MAP_Set(_hb_map, *bbi, omap);
03054 length += BB_length(*bbi);
03055 }
03056
03057 _ready_vector = VECTOR_Init (length, &_hb_pool);
03058
03059 #ifdef KEY
03060 _one_set_counter = 0;
03061 #endif
03062 }
03063
03064 void
03065 HB_Schedule::Schedule_BB (BB *bb, BBSCH *bbsch, int scheduling_algorithm)
03066 {
03067
03068 if( BB_length(bb) == 0 )
03069 return;
03070
03071 Invoke_Pre_HBS_Phase(bb);
03072
03073 std::list<BB*> bblist;
03074 bblist.push_back(bb);
03075
03076 if (CG_DEP_Prune_Dependence &&
03077 CGTARG_Can_Predicate() &&
03078 !BB_predicate_promote(bb))
03079 {
03080 CG_DEP_Prune_Dependence_Arcs(bblist, PRUNE_PREDICATE_ARCS, FALSE);
03081 Set_BB_predicate_promote(bb);
03082 }
03083
03084
03085
03086 BOOL skip_sched = FALSE;;
03087 if (CG_skip_local_sched) {
03088 BBs_Processed++;
03089 skip_sched = (BBs_Processed < CG_local_skip_before ||
03090 BBs_Processed > CG_local_skip_after ||
03091 BBs_Processed == CG_local_skip_equal);
03092 if (skip_sched)
03093 fprintf (TFile, "[%d] BB:%d was skipped in HB_Schedule_BB\n",
03094 BBs_Processed, BB_id(bb));
03095 if (!skip_sched)
03096 fprintf (TFile, "[%d] BB:%d processed in HB_Schedule_BB\n",
03097 BBs_Processed, BB_id(bb));
03098 }
03099
03100 #ifdef KEY
03101
03102
03103 if (scheduling_algorithm == -1)
03104 scheduling_algorithm = LOCS_Scheduling_Algorithm;
03105
03106 if (_hbs_type & HBS_MINIMIZE_REGS ||
03107
03108
03109
03110 scheduling_algorithm > 1) {
03111 scheduling_algorithm = 0;
03112 }
03113 #endif
03114
03115 if (BB_length(bb) > 0 && !skip_sched) {
03116 if (BB_length(bb) > 1) {
03117
03118 CG_DEP_Compute_Graph (
03119 bb,
03120 (this->HBS_From_CGPREP()) ? NO_ASSIGNED_REG_DEPS :
03121 INCLUDE_ASSIGNED_REG_DEPS,
03122 NON_CYCLIC,
03123 INCLUDE_MEMREAD_ARCS,
03124 INCLUDE_MEMIN_ARCS,
03125 #ifdef TARG_IA64
03126 Is_Target_Itanium() ? INCLUDE_CONTROL_ARCS : NO_CONTROL_ARCS,
03127 #else
03128 #if defined(TARG_MIPS) && !defined(TARG_SL)
03129
03130
03131
03132 scheduling_algorithm == 0 ? NO_CONTROL_ARCS : INCLUDE_CONTROL_ARCS,
03133 #else
03134 INCLUDE_CONTROL_ARCS,
03135 #endif
03136 #endif
03137 NULL);
03138
03139 if (Trace_HB) CG_DEP_Trace_Graph (bb);
03140
03141 Schedule_Block (bb, bbsch, scheduling_algorithm);
03142
03143 CG_DEP_Delete_Graph (bb);
03144 }
03145 Set_BB_scheduled (bb);
03146 Set_BB_scheduled_hbs (bb);
03147 if (Assembly) Add_Scheduling_Note (bb, (void*) bbsch);
03148 }
03149
03150 Invoke_Post_HBS_Phase(bb);
03151
03152
03153
03154
03155
03156
03157 if (HBS_Before_GRA() && !HBS_From_CGPREP()) {
03158
03159 if (!Get_Trace (TP_SCHED, 0x2000)) {
03160
03161
03162 mINT8 *fatpoint = (_hbs_type & HBS_FROM_PRE_GCM_SCHED_AGAIN) ?
03163 BBSCH_local_regcost(bbsch) : LRA_Compute_Register_Request(bb, &_hb_pool);
03164 if (HBS_From_Pre_GCM_Sched()) {
03165 Set_BB_local_regcost(bbsch, fatpoint);
03166 }
03167 }
03168 }
03169
03170 }
03171
03172 void
03173 HB_Schedule::Schedule_HB (std::list<BB*> bblist)
03174 {
03175
03176 Invoke_Pre_HBB_Phase(bblist);
03177
03178 if (CG_DEP_Prune_Dependence &&
03179 CGTARG_Can_Predicate())
03180 {
03181 CG_DEP_Prune_Dependence_Arcs(bblist, PRUNE_PREDICATE_ARCS, FALSE);
03182 }
03183
03184 CG_DEP_Compute_Region_Graph(bblist,
03185 (this->HBS_From_CGPREP()) ?
03186 NO_ASSIGNED_REG_DEPS : INCLUDE_ASSIGNED_REG_DEPS,
03187 INCLUDE_MEMREAD_ARCS,
03188 INCLUDE_CONTROL_ARCS);
03189
03190 Schedule_Blocks (bblist);
03191
03192 CG_DEP_Delete_Graph (&bblist);
03193
03194 Invoke_Post_HBB_Phase(bblist);
03195 std::list<BB*>::iterator bbi;
03196 FOR_ALL_BB_STLLIST_ITEMS_FWD(bblist, bbi) {
03197 Set_BB_scheduled (*bbi);
03198 Set_BB_scheduled_hbs (*bbi);
03199 }
03200
03201
03202
03203 }
03204
03205 HB_Schedule::~HB_Schedule()
03206 {
03207 BB_MAP_Delete (_hb_map);
03208
03209 MEM_POOL_Pop (&_hb_pool);
03210 MEM_POOL_Pop (&_hb_map_pool);
03211 MEM_POOL_Delete (&_hb_pool);
03212 MEM_POOL_Delete (&_hb_map_pool);
03213 }