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
00058
00059 #define __STDC_LIMIT_MACROS
00060 #include <stdint.h>
00061 #include <alloca.h>
00062 #include <math.h>
00063 #include "defs.h"
00064 #include "config.h"
00065 #include "config_targ_opt.h"
00066 #include "mempool.h"
00067 #include "bb.h"
00068 #include "bb_set.h"
00069 #include "tracing.h"
00070 #include "timing.h"
00071 #include "cgir.h"
00072 #include "glob.h"
00073 #include "tn_map.h"
00074 #include "cg.h"
00075 #include "cg_flags.h"
00076 #include "ercg.h"
00077 #include "cgtarget.h"
00078 #include "cg_vector.h"
00079 #include "dominate.h"
00080 #include "findloops.h"
00081 #include "note.h"
00082 #include "lra.h"
00083 #include "gcm.h"
00084 #include "ti_res.h"
00085 #include "ti_res_res.h"
00086 #include "ti_latency.h"
00087 #include "ti_errors.h"
00088 #include "cg_region.h"
00089 #include "gtn_universe.h"
00090 #include "gtn_set.h"
00091 #include "cxx_memory.h"
00092 #include "hb_sched.h"
00093 #include "hb_hazards.h"
00094 #include "targ_proc_properties.h"
00095 #include "be_util.h"
00096
00097 #ifdef TARG_IA64
00098 #include "bb.h"
00099 #include "op.h"
00100 #endif
00101
00102 #if defined (TARG_SL)
00103
00104
00105
00106 static bool GCM_Should_Skip( int puid )
00107 {
00108 if( puid == CG_GCM_skip_equal )
00109 return true;
00110
00111
00112
00113
00114 if( CG_GCM_skip_before < 0 && CG_GCM_skip_after < 0 )
00115 return false;
00116
00117
00118 if( CG_GCM_skip_before < 0 ) {
00119 if( puid > CG_GCM_skip_after )
00120 return true;
00121 }
00122
00123
00124 if( CG_GCM_skip_after < 0 ) {
00125 if( puid < CG_GCM_skip_before )
00126 return true;
00127 }
00128
00129
00130
00131
00132
00133
00134
00135 if( CG_GCM_skip_before <= CG_GCM_skip_after ) {
00136 if( puid < CG_GCM_skip_before || puid > CG_GCM_skip_after )
00137 return true;
00138 else
00139 return false;
00140 } else {
00141 if( puid < CG_GCM_skip_before && puid > CG_GCM_skip_after )
00142 return true;
00143 else
00144 return false;
00145 }
00146 }
00147 #endif
00148
00149 #ifdef KEY
00150
00151 static void
00152 Delete_Unscheduled_Prefetches (BB *bb)
00153 {
00154 OP *op, *next_op;
00155 int offset = -1;
00156
00157 for (op = BB_first_op(bb); op != NULL; op = next_op) {
00158 next_op = OP_next(op);
00159 if (OP_prefetch_deleted(op)) {
00160 FmtAssert(OP_prefetch(op),
00161 ("Delete_Unscheduled_Prefetches: OP not a prefetch"));
00162 BB_Remove_Op(bb, op);
00163 } else {
00164
00165 if (offset == -1) {
00166 offset = OP_scycle(op);
00167 }
00168
00169
00170 OP_scycle(op) = OP_scycle(op) - offset;
00171 }
00172 }
00173 }
00174
00175 static void
00176 Run_One_Sched (HB_Schedule *Sched, BOOL is_fwd, BB *bb, HBS_TYPE hbs_type,
00177 const char *name, INT32 *best_cycles, const char **best_name)
00178 {
00179 Sched->Init(bb, hbs_type, OP_scycle(BB_last_op(bb))+1, NULL, NULL);
00180 Sched->Schedule_BB(bb, NULL, is_fwd);
00181 if ((OP_scycle(BB_last_op(bb)) + 1) < *best_cycles) {
00182 *best_cycles = OP_scycle(BB_last_op(bb)) + 1;
00183 *best_name = name;
00184 }
00185 }
00186
00187
00188
00189 static void
00190 Run_Sched (HB_Schedule *Sched, BB *bb, HBS_TYPE hbs_type, INT32 max_sched)
00191 {
00192 INT32 best_cycles = INT32_MAX;
00193 const char *best_name = NULL;
00194
00195 if (LOCS_Best) {
00196
00197
00198
00199 HBS_TYPE base_hbs_type = hbs_type
00200 & ~HBS_BALANCE_READY_TYPES
00201 & ~HBS_BALANCE_UNSCHED_TYPES;
00202
00203 Sched->Init(bb, hbs_type, max_sched, NULL, NULL);
00204 Sched->Schedule_BB(bb, NULL, 0);
00205 best_name = "backward";
00206
00207 if (BB_length(bb) > 1) {
00208 best_cycles = OP_scycle(BB_last_op(bb)) + 1;
00209
00210
00211
00212 Run_One_Sched(Sched, 0, bb, base_hbs_type | HBS_BALANCE_READY_TYPES,
00213 "backward balance_ready_types",
00214 &best_cycles, &best_name);
00215
00216 Run_One_Sched(Sched, 0, bb, base_hbs_type | HBS_BALANCE_UNSCHED_TYPES,
00217 "backward balance_unsched_types",
00218 &best_cycles, &best_name);
00219
00220 Run_One_Sched(Sched, 0, bb,
00221 base_hbs_type | HBS_BALANCE_UNSCHED_TYPES |
00222 HBS_BALANCE_READY_TYPES,
00223 "backward balance_unsched_types balance_ready_types",
00224 &best_cycles, &best_name);
00225
00226
00227
00228 Run_One_Sched(Sched, 1, bb, base_hbs_type
00229 #if defined (KEY)
00230 & ~HBS_DROP_UNSCHED_PREFETCHES
00231 #endif
00232 , "forward", &best_cycles, &best_name);
00233 }
00234
00235 } else if (LOCS_Scheduling_Algorithm == 2) {
00236
00237
00238
00239 Sched->Init(bb, hbs_type, max_sched, NULL, NULL);
00240 Sched->Schedule_BB(bb, NULL, 0);
00241 best_name = "backward";
00242
00243 if (BB_length(bb) > 1) {
00244 best_cycles = OP_scycle(BB_last_op(bb)) + 1;
00245
00246 Run_One_Sched(Sched, 1, bb, hbs_type, "forward",
00247 &best_cycles, &best_name);
00248 }
00249
00250
00251 } else {
00252 Sched->Init(bb, hbs_type, max_sched, NULL, NULL);
00253 Sched->Schedule_BB(bb, NULL, LOCS_Scheduling_Algorithm);
00254 }
00255
00256 #ifdef KEY
00257
00258 if (hbs_type & HBS_DROP_UNSCHED_PREFETCHES)
00259 Delete_Unscheduled_Prefetches(bb);
00260 #endif
00261
00262 if (Trace_HB &&
00263 best_name != NULL) {
00264 fprintf(TFile, "Best scheduling heuristic: %s\n", best_name);
00265 }
00266 }
00267 #endif
00268
00269
00270
00271
00272
00273
00274
00275
00276
00277
00278
00279
00280
00281
00282
00283
00284
00285
00286
00287
00288
00289
00290
00291
00292
00293
00294 void
00295 IGLS_Schedule_Region (BOOL before_regalloc)
00296 {
00297 HBS_TYPE hbs_type;
00298
00299
00300
00301 #ifdef TARG_SL
00302
00303 int current_pu = Current_PU_Count();
00304 if( GCM_Should_Skip(current_pu) ){
00305 printf(" ... PU:%d is skipped by GCM\n", current_pu );
00306 return;
00307 }
00308
00309 if( before_regalloc ){
00310 hbs_type = HBS_BEFORE_GRA | HBS_BEFORE_LRA | HBS_DEPTH_FIRST;
00311 } else {
00312 hbs_type = HBS_CRITICAL_PATH;
00313 }
00314 GCM_Schedule_Region( hbs_type );
00315 return ;
00316 #endif
00317
00318 BB *bb;
00319 BOOL should_we_local_schedule;
00320 BOOL should_we_global_schedule;
00321 BOOL should_we_schedule;
00322 BOOL should_we_do_thr;
00323
00324 RID *rid;
00325 HB_Schedule *Sched = NULL;
00326 CG_THR *thr = NULL;
00327
00328 Set_Error_Phase ("Hyperlock Scheduler");
00329 Start_Timer (T_Sched_CU);
00330 Trace_HB = Get_Trace (TP_SCHED, 1);
00331 should_we_schedule = IGLS_Enable_All_Scheduling;
00332 should_we_do_thr = CG_enable_thr;
00333 L_Save();
00334
00335
00336
00337 if (!strcmp(Cur_PU_Name, "MAIN__") || !strcmp(Cur_PU_Name, "main")) {
00338 Set_BB_scheduled(REGION_First_BB);
00339 }
00340
00341 if (before_regalloc) {
00342
00343
00344
00345 should_we_local_schedule = ( CG_opt_level > 1
00346 && LOCS_Enable_Scheduling
00347 && LOCS_PRE_Enable_Scheduling);
00348
00349
00350
00351
00352 should_we_global_schedule = ( CG_opt_level > 2 &&
00353 ((IGLS_Enable_HB_Scheduling &&
00354 IGLS_Enable_PRE_HB_Scheduling) ||
00355 (GCM_PRE_Enable_Scheduling &&
00356 GCM_Enable_Scheduling)));
00357
00358 hbs_type = HBS_BEFORE_GRA | HBS_BEFORE_LRA | HBS_DEPTH_FIRST;
00359 #ifdef KEY
00360 if (LOCS_Balance_Ready_Types)
00361 hbs_type |= HBS_BALANCE_READY_TYPES;
00362 if (LOCS_Balance_Unsched_Types)
00363 hbs_type |= HBS_BALANCE_UNSCHED_TYPES;
00364 #endif
00365 if (Trace_HB) {
00366 #pragma mips_frequency_hint NEVER
00367 fprintf (TFile, "***** HYPERBLOCK SCHEDULER (before GRA) *****\n");
00368 }
00369 }
00370 else {
00371
00372
00373
00374 should_we_local_schedule = ( CG_opt_level > 0
00375 && LOCS_Enable_Scheduling
00376 && LOCS_POST_Enable_Scheduling);
00377
00378
00379
00380
00381 should_we_global_schedule = ( CG_opt_level > 1 &&
00382 ((IGLS_Enable_HB_Scheduling &&
00383 (IGLS_Enable_POST_HB_Scheduling ||
00384 IGLS_Enable_PRE_HB_Scheduling)) ||
00385 (GCM_Enable_Scheduling &&
00386 GCM_POST_Enable_Scheduling)));
00387 hbs_type = HBS_CRITICAL_PATH;
00388 if (PROC_has_bundles()) hbs_type |= HBS_MINIMIZE_BUNDLES;
00389
00390 #ifdef KEY
00391 if (LOCS_Balance_Ready_Types)
00392 hbs_type |= HBS_BALANCE_READY_TYPES;
00393 if (LOCS_Balance_Unsched_Types)
00394 hbs_type |= HBS_BALANCE_UNSCHED_TYPES;
00395 #endif
00396
00397
00398 should_we_do_thr = should_we_do_thr && (CG_opt_level > 1) && !OPT_Space;
00399
00400 if (Trace_HB) {
00401 #pragma mips_frequency_hint NEVER
00402 fprintf (TFile, "***** HYPERBLOCK SCHEDULER (after GRA) *****\n");
00403 }
00404 }
00405
00406
00407
00408
00409
00410
00411
00412
00413 if (before_regalloc) {
00414 if (!should_we_schedule) return;
00415
00416
00417 if (IGLS_Enable_HB_Scheduling && IGLS_Enable_PRE_HB_Scheduling &&
00418 should_we_global_schedule) {
00419 HB_Remove_Deleted_Blocks();
00420 std::list<HB*>::iterator hbi;
00421 FOR_ALL_BB_STLLIST_ITEMS_FWD(HB_list, hbi) {
00422 if (!Sched) {
00423 Sched = CXX_NEW(HB_Schedule(), &MEM_local_pool);
00424 }
00425
00426
00427 std::list<BB*> hb_blocks;
00428 Get_HB_Blocks_List(hb_blocks,*hbi);
00429 if (Can_Schedule_HB(hb_blocks)) {
00430 Sched->Init(hb_blocks, hbs_type, NULL);
00431 Sched->Schedule_HB(hb_blocks);
00432 }
00433 }
00434 }
00435
00436
00437 if (GCM_Enable_Scheduling && should_we_global_schedule) {
00438 Stop_Timer (T_Sched_CU);
00439
00440 GCM_Schedule_Region (hbs_type);
00441
00442 Set_Error_Phase ("Hyperblock Scheduler (HBS)");
00443 Start_Timer (T_Sched_CU);
00444 }
00445
00446 if (!should_we_local_schedule) return;
00447
00448
00449
00450 for (bb = REGION_First_BB; bb != NULL; bb = BB_next(bb)) {
00451
00452 if ( ( rid = BB_rid(bb) )
00453 && ( RID_level(rid) >= RL_CGSCHED ) )
00454 continue;
00455
00456 if (!BB_scheduled(bb)) {
00457 if (!Sched) {
00458 Sched = CXX_NEW(HB_Schedule(), &MEM_local_pool);
00459 }
00460 #ifdef KEY
00461 Run_Sched(Sched, bb, hbs_type, INT32_MAX);
00462 #else
00463 Sched->Init(bb, hbs_type, INT32_MAX, NULL, NULL);
00464 Sched->Schedule_BB(bb, NULL, LOCS_Scheduling_Algorithm);
00465 #endif
00466 }
00467 }
00468 }
00469 else {
00470
00471
00472
00473
00474
00475
00476
00477
00478
00479
00480
00481
00482
00483
00484
00485
00486 #ifdef KEY
00487
00488 if (LOCS_Reduce_Prefetch)
00489 hbs_type |= HBS_DROP_UNSCHED_PREFETCHES;
00490 #endif
00491
00492 if (should_we_do_thr) {
00493 Stop_Timer (T_Sched_CU);
00494 Set_Error_Phase ("Tree-Height Reduction (THR)");
00495 Start_Timer (T_THR_CU);
00496
00497 for (bb = REGION_First_BB; bb != NULL; bb = BB_next(bb)) {
00498 if ( ( rid = BB_rid(bb) )
00499 && ( RID_level(rid) >= RL_CGSCHED ) )
00500 continue;
00501
00502
00503
00504
00505
00506 if (BB_scheduled(bb) && !BB_scheduled_hbs(bb)) continue;
00507 if (!thr) {
00508 thr = CXX_NEW(CG_THR(), &MEM_local_pool);
00509 }
00510 thr->Init(bb, THR_DATA_SPECULATION_NO_RB, FALSE);
00511 thr->Perform_THR();
00512
00513 }
00514
00515 Stop_Timer (T_THR_CU);
00516 Check_for_Dump (TP_THR, NULL);
00517 Start_Timer (T_Sched_CU);
00518
00519 }
00520
00521
00522 if (IGLS_Enable_HB_Scheduling && IGLS_Enable_POST_HB_Scheduling &&
00523 should_we_schedule && should_we_global_schedule) {
00524
00525 HB_Remove_Deleted_Blocks();
00526 std::list<HB*>::iterator hbi;
00527 FOR_ALL_BB_STLLIST_ITEMS_FWD(HB_list, hbi) {
00528 if (!Sched) {
00529 Sched = CXX_NEW(HB_Schedule(), &MEM_local_pool);
00530 }
00531
00532 std::list<BB*> hb_blocks;
00533 Get_HB_Blocks_List(hb_blocks,*hbi);
00534 if (Can_Schedule_HB(hb_blocks)) {
00535 Sched->Init(hb_blocks, hbs_type, NULL);
00536 Sched->Schedule_HB(hb_blocks);
00537 }
00538 }
00539 }
00540
00541
00542 if (GCM_Enable_Scheduling && should_we_schedule &&
00543 should_we_global_schedule) {
00544 Stop_Timer (T_Sched_CU);
00545
00546 GCM_Schedule_Region (hbs_type);
00547
00548 Set_Error_Phase ("Hyperblock Scheduler (HBS)");
00549 Start_Timer (T_Sched_CU);
00550 }
00551
00552
00553
00554 for (bb = REGION_First_BB; bb != NULL; bb = BB_next(bb)) {
00555 if ( ( rid = BB_rid(bb) )
00556 && ( RID_level(rid) >= RL_CGSCHED ) )
00557 continue;
00558
00559 BOOL skip_bb = BB_scheduled(bb) && !BB_scheduled_hbs(bb);
00560
00561 if (should_we_do_thr && !skip_bb) Remove_Unnecessary_Check_Instrs(bb);
00562
00563 #ifdef KEY_1873
00564
00565
00566
00567 const BOOL resched = FALSE;
00568 #else
00569 BOOL resched = !skip_bb && Reschedule_BB(bb);
00570 #endif // KEY
00571 if (should_we_schedule && should_we_local_schedule &&
00572 (!skip_bb || resched)) {
00573 #ifdef TARG_IA64
00574 extern void Clean_Up (BB* bb);
00575 Clean_Up(bb);
00576 Reset_BB_scheduled(bb);
00577 #endif
00578
00579 INT32 max_sched = (resched) ? OP_scycle(BB_last_op(bb))+1 : INT32_MAX;
00580 #ifdef KEY
00581
00582
00583 if (max_sched < INT32_MAX) {
00584 OP *op;
00585 FOR_ALL_BB_OPs_FWD(bb, op) {
00586 if (OP_scycle(op) == 0) {
00587 max_sched = INT32_MAX;
00588 break;
00589 }
00590 }
00591 }
00592 #endif
00593 if (LOCS_Enable_Scheduling) {
00594 if (!Sched) {
00595 Sched = CXX_NEW(HB_Schedule(), &MEM_local_pool);
00596 }
00597 #ifdef KEY
00598 Run_Sched(Sched, bb, hbs_type, max_sched);
00599 #else
00600 Sched->Init(bb, hbs_type, max_sched, NULL, NULL);
00601 Sched->Schedule_BB(bb, NULL, LOCS_Scheduling_Algorithm);
00602 #endif
00603 }
00604 }
00605 Handle_All_Hazards (bb);
00606 }
00607
00608 #ifdef TARG_X8664
00609 {
00610 extern void CG_Sched( MEM_POOL*, BOOL );
00611 CG_Sched( &MEM_local_pool, Get_Trace( TP_SCHED, 1 ) );
00612 }
00613 #endif
00614
00615
00616 if (should_we_schedule && should_we_local_schedule) {
00617 if (GCM_Enable_Scheduling) GCM_Fill_Branch_Delay_Slots ();
00618 if (Assembly) Add_Scheduling_Notes_For_Loops ();
00619 }
00620 }
00621
00622
00623
00624 if (Sched) {
00625 CXX_DELETE(Sched, &MEM_local_pool);
00626 }
00627 if (thr) {
00628 CXX_DELETE(thr, &MEM_local_pool);
00629 }
00630 L_Free();
00631
00632 Check_for_Dump (TP_SCHED, NULL);
00633 Stop_Timer (T_Sched_CU);
00634 }
00635
00636