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 #define __STDC_LIMIT_MACROS
00042 #include <stdint.h>
00043 #include <alloca.h>
00044 #include "defs.h"
00045 #include "tracing.h"
00046 #include "cgir.h"
00047 #include "cg_loop.h"
00048 #include "cg_flags.h"
00049 #include "cg_sched_est.h"
00050 #include "cxx_memory.h"
00051 #include "hb_sched.h"
00052
00053 BOOL CG_SCHED_EST_calc_dep_graph = FALSE;
00054 BOOL CG_SCHED_EST_use_locs = FALSE;
00055 INT32 CG_SCHED_EST_call_cost = 100;
00056
00057 inline BOOL tracing(void) { return Get_Trace(TP_SCHED, 0x100); }
00058
00059 #define LATENCY_NOT_COMPUTED ((UINT32)-1)
00060 #define LATENCY_IGNORE ((UINT32)-2)
00061
00062
00063
00064
00065 static inline
00066 UINT32 Get_Latency_To(CG_SCHED_EST *se, OP *op)
00067 {
00068 void *entry = BB_MAP_Get(se->latency_to_map, OP_bb(op));
00069 DevAssert(entry, ("missing latency_to map for BB:%d", BB_id(OP_bb(op))));
00070 return (UINT32)(BB_OP_MAP32_Get((BB_OP_MAP)entry, op) - 1);
00071 }
00072
00073
00074
00075
00076 static inline
00077 void Set_Latency_To(CG_SCHED_EST *se, OP *op, UINT32 latency)
00078
00079 {
00080 void *entry = BB_MAP_Get(se->latency_to_map, OP_bb(op));
00081 DevAssert(entry, ("missing latency_to map for BB:%d", BB_id(OP_bb(op))));
00082 BB_OP_MAP32_Set((BB_OP_MAP)entry, op, (INT32)(latency + 1));
00083 }
00084
00085
00086
00087
00088
00089
00090 static
00091 OP* Find_Reaching_Def(CG_SCHED_EST *se, OP *op, UINT8 i)
00092 {
00093 TN *opnd = OP_opnd(op, i);
00094 BB *bb = OP_bb(op);
00095
00096 if (!TN_is_constant(opnd)) {
00097 INT32 bb_order = BB_MAP32_Get(se->order, bb);
00098 DEF_KIND kind;
00099 OP *defop = TN_Reaching_Value_At_Op(opnd, op, &kind, TRUE);
00100 if (defop) {
00101 BB *def_bb = OP_bb(defop);
00102 INT32 def_order = BB_MAP32_Get(se->order, def_bb);
00103
00104 if (def_order && def_order <= bb_order &&
00105 (def_bb != bb ||
00106 OP_Precedes(defop, op))) {
00107 return defop;
00108 }
00109 }
00110 }
00111
00112 return NULL;
00113 }
00114
00115
00116 static UINT32 Calc_Latency_To(CG_SCHED_EST *se, OP *op);
00117
00118
00119
00120
00121
00122
00123 static inline
00124 UINT32 Latency_Thru(CG_SCHED_EST *se, OP *op, INT32 latency)
00125 {
00126 UINT32 entry = Get_Latency_To(se, op);
00127 if (entry == LATENCY_IGNORE)
00128 return 0;
00129 if (entry == LATENCY_NOT_COMPUTED)
00130 entry = Calc_Latency_To(se, op);
00131 if (OP_call(op))
00132 entry += CG_SCHED_EST_call_cost;
00133 return entry + latency;
00134 }
00135
00136
00137
00138
00139
00140 static UINT32
00141 Calc_Latency_To(CG_SCHED_EST *se, OP *op)
00142 {
00143 UINT32 old_entry = Get_Latency_To(se, op);
00144 UINT32 new_entry = old_entry;
00145
00146 if (old_entry != LATENCY_IGNORE) {
00147 UINT8 i;
00148 INT op_opnds = OP_opnds(op);
00149 mBOOL *found_pred_for_opnd = (mBOOL *)alloca(op_opnds * sizeof(mBOOL));
00150 bzero(found_pred_for_opnd, op_opnds * sizeof(mBOOL));
00151
00152 new_entry = 0;
00153 if (CG_SCHED_EST_calc_dep_graph || se->use_dep_graph)
00154 {
00155
00156
00157
00158 ARC_LIST *preds;
00159 for (preds = OP_preds(op); preds; preds = ARC_LIST_rest(preds)) {
00160 ARC *pred_arc = ARC_LIST_first(preds);
00161 if (ARC_omega(pred_arc) == 0) {
00162 OP *pred = ARC_pred(pred_arc);
00163 UINT32 latency = ARC_latency(pred_arc);
00164 if (ARC_has_opnd(pred_arc)) {
00165 INT iopnd = ARC_opnd(pred_arc);
00166 Is_True(iopnd < op_opnds, ("found_pred_for_opnd alloca too small"));
00167 found_pred_for_opnd[iopnd] = TRUE;
00168 }
00169 new_entry = umax(new_entry, Latency_Thru(se, pred, latency));
00170 }
00171 }
00172 }
00173
00174
00175
00176
00177
00178 for (i = 0; i < op_opnds; i++) {
00179 if (!found_pred_for_opnd[i]) {
00180 OP *pred = Find_Reaching_Def(se, op, i);
00181 if (pred) {
00182 UINT32 latency = CG_DEP_Latency(pred, op, CG_DEP_REGIN, i);
00183 new_entry = umax(new_entry, Latency_Thru(se, pred, latency));
00184 }
00185 }
00186 }
00187 Set_Latency_To(se, op, new_entry);
00188 }
00189 return new_entry;
00190 }
00191
00192
00193
00194
00195
00196 static UINT32
00197 Critical_Path_Len(CG_SCHED_EST *se)
00198 {
00199 UINT32 max_latency_to = 0;
00200 BB *bb;
00201
00202 if (se->latency_to_map_dirty) {
00203 FOR_ALL_BB_SET_members(se->contents, bb) {
00204 OP *op;
00205 BB_OP_MAP lt_map = (BB_OP_MAP)BB_MAP_Get(se->latency_to_map, bb);
00206 FOR_ALL_BB_OPs(bb, op) {
00207
00208
00209
00210 if (BB_OP_MAP32_Get(lt_map, op)-1 != LATENCY_IGNORE)
00211 BB_OP_MAP32_Set(lt_map, op, LATENCY_NOT_COMPUTED+1);
00212 }
00213 }
00214 se->latency_to_map_dirty = FALSE;
00215 }
00216
00217 FOR_ALL_BB_SET_members(se->contents, bb) {
00218 OP *op;
00219
00220 if (CG_SCHED_EST_calc_dep_graph && !se->use_dep_graph)
00221 CG_DEP_Compute_Graph(bb,
00222 NO_ASSIGNED_REG_DEPS,
00223 NON_CYCLIC,
00224 NO_MEMREAD_ARCS,
00225 INCLUDE_MEMIN_ARCS,
00226 NO_CONTROL_ARCS,
00227 NULL);
00228
00229 FOR_ALL_BB_OPs(bb, op)
00230 max_latency_to = umax(max_latency_to, Latency_Thru(se, op, 0));
00231
00232 if (CG_SCHED_EST_calc_dep_graph && !se->use_dep_graph)
00233 CG_DEP_Delete_Graph(bb);
00234 }
00235
00236 if (tracing()) {
00237 fprintf(TFile, "<sched_est> critical_path_len(BBs ");
00238 BB_SET_Print(se->contents, TFile);
00239 fprintf(TFile, ") = %d cycles\n", max_latency_to);
00240 }
00241
00242 return max_latency_to;
00243 }
00244
00245
00246
00247
00248 static UINT32
00249 Resource_Min_Cycles(CG_SCHED_EST *se)
00250 {
00251 UINT32 result = (UINT32)(TI_RES_COUNT_Min_Cycles(se->res_count) + 0.99);
00252 if (tracing()) {
00253 fprintf(TFile, "<sched_est> resource_min_cycles(BBs ");
00254 BB_SET_Print(se->contents, TFile);
00255 fprintf(TFile, ") = %d cycles\n", result);
00256 }
00257 return result;
00258 }
00259
00260
00261
00262
00263 void
00264 CG_SCHED_EST_Print(FILE *fp, CG_SCHED_EST *se)
00265 {
00266 fprintf(fp, "SCHED_EST(BBs ");
00267 BB_SET_Print(se->contents, fp);
00268 if (se->cached_crit_path_len)
00269 fprintf(fp, ", crit path %d", se->cached_crit_path_len);
00270 fprintf(fp, ", ");
00271 TI_RES_COUNT_Print(fp, se->res_count);
00272 if (se->cached_resource_cycles)
00273 fprintf(fp, ", res cycles %d", se->cached_resource_cycles);
00274 fprintf(fp, ", ");
00275 if (se->sched_cycles)
00276 fprintf(fp, ", sched cycles %d", se->sched_cycles);
00277 fprintf(fp, ")");
00278 }
00279
00280
00281
00282
00283 CG_SCHED_EST*
00284 CG_SCHED_EST_Create_Empty(MEM_POOL *pool, SCHED_EST_TYPE type)
00285 {
00286 CG_SCHED_EST *se = (CG_SCHED_EST *) MEM_POOL_Alloc(pool,
00287 sizeof(CG_SCHED_EST));
00288
00289 se->contents = BB_SET_Create_Empty(PU_BB_Count+1, pool);
00290 se->res_count = TI_RES_COUNT_Alloc(pool);
00291 se->latency_to_map = BB_MAP_Create();
00292 se->order = BB_MAP32_Create();
00293 se->use_dep_graph = (type & SCHED_EST_USE_DEP_GRAPH) ? TRUE : FALSE;
00294 se->latency_to_map_dirty = FALSE;
00295 se->sched_cycles = 0;
00296
00297 return se;
00298 }
00299
00300 CG_SCHED_EST *CG_SCHED_EST_Path_Create(BB_SET *path, BB_MAP bb_ests,
00301 MEM_POOL *pool, SCHED_EST_TYPE type)
00302
00303
00304
00305 {
00306 BB *bb;
00307 CG_SCHED_EST *path_se = CG_SCHED_EST_Create_Empty(pool, type);
00308
00309 FOR_ALL_BB_SET_members(path, bb) {
00310 CG_SCHED_EST *se = (CG_SCHED_EST *)BB_MAP_Get(bb_ests, bb);
00311 if (!se) {
00312 se = CG_SCHED_EST_Create(bb, pool, type);
00313 BB_MAP_Set(bb_ests,bb,se);
00314 }
00315 TI_RES_COUNT_Add(path_se->res_count, path_se->res_count, se->res_count);
00316 if (type == SCHED_EST_FOR_HB) {
00317 path_se->sched_cycles = (INT)TI_RES_COUNT_Min_Cycles(path_se->res_count);
00318 } else {
00319 path_se->sched_cycles += se->sched_cycles;
00320 }
00321 }
00322 return path_se;
00323 }
00324
00325 CG_SCHED_EST *CG_SCHED_EST_Create(BB *bb, MEM_POOL *pool,
00326 SCHED_EST_TYPE type)
00327
00328
00329
00330 {
00331 OP *op;
00332 CG_SCHED_EST* se = CG_SCHED_EST_Create_Empty(pool, type);
00333 BB_MAP_Set(se->latency_to_map, bb, BB_OP_MAP32_Create(bb, pool));
00334 se->contents = BB_SET_Union1D(se->contents, bb, NULL);
00335 BB_MAP32_Set(se->order, bb, 1);
00336
00337 if (CG_SCHED_EST_use_locs && LOCS_Enable_Scheduling &&
00338 type != SCHED_EST_FOR_HB) {
00339
00340 HB_Schedule *Sched = CXX_NEW(HB_Schedule(), pool);
00341 Sched->Init(bb,
00342 HBS_BEFORE_GRA | HBS_FROM_CGPREP,
00343 INT32_MAX,
00344 NULL,
00345 NULL);
00346 Sched->Schedule_BB(bb, NULL);
00347
00348 if (BB_last_op(bb))
00349 se->sched_cycles = OP_scycle(BB_last_op(bb)) + 1;
00350 } else {
00351
00352 FOR_ALL_BB_OPs(bb, op) {
00353 BOOL acct_res = TRUE;
00354
00355 if (type & SCHED_EST_IGNORE_PREFETCH)
00356 if (OP_prefetch(op))
00357 acct_res = FALSE;
00358
00359 if (type & SCHED_EST_IGNORE_COPY)
00360 if (OP_copy(op))
00361 acct_res = FALSE;
00362
00363 if (type & SCHED_EST_IGNORE_BRANCH)
00364 if (OP_br(op))
00365 acct_res = FALSE;
00366
00367 if (type & SCHED_EST_IGNORE_INT_OPS)
00368 if (!OP_memory(op) && !OP_flop(op))
00369 acct_res = FALSE;
00370
00371 if (type & SCHED_EST_IGNORE_LOH_OPS)
00372 if (OP_loh(op))
00373 acct_res = FALSE;
00374
00375 if (acct_res)
00376 TI_RES_COUNT_Add_Op_Resources(se->res_count, OP_code(op));
00377
00378 }
00379 }
00380
00381 se->cached_crit_path_len = 0;
00382 se->cached_resource_cycles = 0;
00383 if (tracing()) {
00384 fprintf(TFile, "<sched_est> creating ");
00385 CG_SCHED_EST_Print(TFile, se);
00386 fprintf(TFile, "\n");
00387 }
00388
00389 return se;
00390 }
00391
00392
00393
00394
00395 void CG_SCHED_EST_Delete(CG_SCHED_EST *se)
00396 {
00397 BB_MAP_Delete(se->latency_to_map);
00398 BB_MAP_Delete(se->order);
00399 }
00400
00401
00402
00403
00404
00405 static void
00406 Clone_Mappings(CG_SCHED_EST *to, CG_SCHED_EST *from, MEM_POOL *pool)
00407 {
00408 BB *bb;
00409 INT32 num_bbs_before = BB_SET_Size(to->contents);
00410 FOR_ALL_BB_SET_members(from->contents, bb) {
00411 BB_OP_MAP lt_map = (BB_OP_MAP)BB_MAP_Get(from->latency_to_map, bb);
00412 INT32 order = BB_MAP32_Get(from->order, bb);
00413 BB_OP_MAP to_lt_map = BB_OP_MAP32_Create(bb, pool);
00414 OP *op;
00415 DevAssert(lt_map, ("missing latency_to map for BB:%d", BB_id(bb)));
00416 DevAssert(order, ("missing order for BB:%d", BB_id(bb)));
00417 FOR_ALL_BB_OPs(bb, op)
00418 BB_OP_MAP32_Set(to_lt_map, op, BB_OP_MAP32_Get(lt_map, op));
00419 BB_MAP_Set(to->latency_to_map, bb, to_lt_map);
00420 BB_MAP32_Set(to->order, bb, order);
00421 }
00422 }
00423
00424
00425
00426
00427 CG_SCHED_EST*
00428 CG_SCHED_EST_Clone(CG_SCHED_EST *se, MEM_POOL *pool)
00429 {
00430 CG_SCHED_EST *clone = (CG_SCHED_EST *)MEM_POOL_Alloc(pool, sizeof(CG_SCHED_EST));
00431 clone->contents = BB_SET_Copy(se->contents, pool);
00432 clone->res_count = TI_RES_COUNT_Alloc(pool);
00433 TI_RES_COUNT_Add(clone->res_count, se->res_count, clone->res_count);
00434 clone->latency_to_map = BB_MAP_Create();
00435 clone->order = BB_MAP32_Create();
00436 Clone_Mappings(clone, se, pool);
00437 clone->latency_to_map_dirty = se->latency_to_map_dirty;
00438 clone->cached_crit_path_len = se->cached_crit_path_len;
00439 clone->sched_cycles = se->sched_cycles;
00440 clone->cached_resource_cycles = se->cached_resource_cycles;
00441 clone->use_dep_graph = se->use_dep_graph;
00442 return clone;
00443 }
00444
00445
00446
00447 inline BB_MAP
00448 BB_MAPfloat_Create(void) { return BB_MAP32_Create(); }
00449
00450 inline float
00451 BB_MAPfloat_Get(BB_MAP map, BB *bb)
00452 {
00453 INT32 entry = BB_MAP32_Get(map, bb);
00454 return *(float *)(&entry);
00455 }
00456
00457 inline void
00458 BB_MAPfloat_Set(BB_MAP map, BB *bb, float val)
00459 {
00460 BB_MAP32_Set(map, bb, *(INT32 *)(&val));
00461 }
00462
00463
00464
00465
00466 static BOOL
00467 Is_Region(BB_SET *bbs, BB *entry, BOOL recursive)
00468 {
00469 static BB_SET *visiting, *not_visited;
00470 static BB *orig_entry;
00471 BBLIST *succs;
00472 BOOL disqualified = FALSE;
00473
00474 if (!recursive) {
00475 MEM_POOL_Push(&MEM_local_nz_pool);
00476 visiting = BB_SET_Create_Empty(PU_BB_Count+1, &MEM_local_nz_pool);
00477 not_visited = BB_SET_Copy(bbs, &MEM_local_nz_pool);
00478 orig_entry = entry;
00479 if (tracing()) {
00480 fprintf(TFile, "<sched_est> looking at BBs ");
00481 BB_SET_Print(bbs, TFile);
00482 fprintf(TFile, " entry BB:%d\n", BB_id(entry));
00483 }
00484 } else {
00485 BBLIST *preds;
00486 if (entry == orig_entry) return TRUE;
00487 FOR_ALL_BB_PREDS(entry, preds) {
00488 BB *pred = BBLIST_item(preds);
00489 if (!BB_SET_MemberP(bbs, pred)) {
00490 if (tracing())
00491 fprintf(TFile, "<sched_est> not a region: "
00492 "BB:%d has non-region pred BB:%d\n",
00493 BB_id(entry), BB_id(pred));
00494 return FALSE;
00495 }
00496 }
00497 if (BB_SET_MemberP(visiting, entry)) {
00498 if (tracing())
00499 fprintf(TFile, "<sched_est> not a region: "
00500 "internal cycle to BB:%d\n", BB_id(entry));
00501 return FALSE;
00502 }
00503 }
00504
00505 visiting = BB_SET_Union1D(visiting, entry, NULL);
00506
00507 FOR_ALL_BB_SUCCS(entry, succs) {
00508 BB *succ = BBLIST_item(succs);
00509 if (BB_SET_MemberP(not_visited, succ) && !Is_Region(bbs, succ, TRUE)) {
00510 disqualified = TRUE;
00511 break;
00512 }
00513 }
00514
00515 not_visited = BB_SET_Difference1D(not_visited, entry);
00516 visiting = BB_SET_Difference1D(visiting, entry);
00517
00518 if (!recursive) {
00519 if (!disqualified && BB_SET_Size(not_visited) > 0) {
00520 if (tracing()) {
00521 fprintf(TFile, "<sched_est> not a region: has disconnected BBs ");
00522 BB_SET_Print(not_visited, TFile);
00523 fprintf(TFile, "\n");
00524 }
00525 disqualified = TRUE;
00526 }
00527 MEM_POOL_Pop(&MEM_local_nz_pool);
00528 }
00529
00530 return !disqualified;
00531 }
00532
00533
00534
00535
00536 BOOL
00537 CG_SCHED_EST_Is_Region(BB_SET *region, BB *entry)
00538 {
00539 return Is_Region(region, entry, FALSE);
00540 }
00541
00542
00543
00544
00545
00546
00547
00548
00549
00550 static float
00551 Avg_Cost_Path(BB_SET *region, BB *entry, BB_MAP ests, SCHED_EST_TYPE type)
00552 {
00553 float avg_cost = 0.0;
00554
00555 BB *cur_bb;
00556 FOR_ALL_BB_SET_members(region, cur_bb) {
00557 CG_SCHED_EST *se = (CG_SCHED_EST *)BB_MAP_Get(ests, cur_bb);
00558 float local_cost;
00559
00560
00561 if ((type & SCHED_EST_FOR_SWP) && Enable_SWP) {
00562
00563 UINT32 res_cost = CG_SCHED_EST_Resource_Cycles(se);
00564 UINT32 critical_len = CG_SCHED_EST_Critical_Length(se);
00565 UINT32 diff = abs(critical_len - res_cost);
00566 UINT32 num_bbs = BB_SET_Size(region);
00567
00568
00569
00570
00571
00572 float bias_factor= (num_bbs > 1) ? (num_bbs - 1.0)/(num_bbs + 7.0) : 0.0;
00573 local_cost = umax(res_cost, critical_len) - bias_factor * diff;
00574
00575 } else {
00576
00577
00578 local_cost = (se) ? (float) CG_SCHED_EST_Cycles(se) : 0.0F;
00579 }
00580
00581
00582 avg_cost += BB_freq(cur_bb)/BB_freq(entry) * local_cost;
00583
00584 }
00585 if (tracing()) {
00586 fprintf(TFile, "<sched_est> avg_cost_path(BBs ");
00587 BB_SET_Print(region, TFile);
00588 fprintf(TFile, "entry BB:%d) = %g\n", BB_id(entry), avg_cost);
00589 }
00590
00591 return avg_cost;
00592 }
00593
00594
00595
00596
00597 float
00598 CG_SCHED_EST_Avg_Cycles_Thru(BB_SET *region, BB *entry, BB_MAP ests,
00599 SCHED_EST_TYPE type)
00600 {
00601 return Avg_Cost_Path(region, entry, ests, type);
00602 }
00603
00604
00605
00606
00607 void
00608 CG_SCHED_EST_Ignore_Op(CG_SCHED_EST *se, OP *op)
00609 {
00610 TOP opc = OP_code(op);
00611 if (tracing()) {
00612 fprintf(TFile, "<sched_est> ignoring OP:\n ");
00613 Print_OP_No_SrcLine(op);
00614 fprintf(TFile, " in ");
00615 CG_SCHED_EST_Print(TFile, se);
00616 fprintf(TFile, "\n");
00617 }
00618 if (OP_prefetch(op))
00619 TI_RES_COUNT_Subtract_Op_Resources(se->res_count, opc);
00620 Set_Latency_To(se, op, LATENCY_IGNORE);
00621 se->cached_resource_cycles = 0;
00622 se->cached_crit_path_len = 0;
00623 se->latency_to_map_dirty = TRUE;
00624 }
00625
00626
00627
00628
00629 UINT32
00630 CG_SCHED_EST_Resource_Cycles(CG_SCHED_EST *se)
00631 {
00632 if (!se->cached_resource_cycles)
00633 se->cached_resource_cycles = Resource_Min_Cycles(se);
00634 return se->cached_resource_cycles;
00635 }
00636
00637
00638
00639
00640 UINT32
00641 CG_SCHED_EST_Critical_Length(CG_SCHED_EST *se)
00642 {
00643 if (!se->cached_crit_path_len)
00644 se->cached_crit_path_len = Critical_Path_Len(se);
00645 return se->cached_crit_path_len;
00646 }
00647
00648
00649
00650
00651 UINT32
00652 CG_SCHED_EST_Cycles(CG_SCHED_EST *se)
00653 {
00654 if (CG_SCHED_EST_use_locs) {
00655 return se->sched_cycles;
00656 } else {
00657 if (!se->cached_resource_cycles)
00658 se->cached_resource_cycles = Resource_Min_Cycles(se);
00659
00660 if (!se->cached_crit_path_len)
00661 se->cached_crit_path_len = Critical_Path_Len(se);
00662
00663 return umax(se->cached_resource_cycles, se->cached_crit_path_len);
00664 }
00665 }
00666
00667
00668
00669
00670 UINT32
00671 CG_SCHED_EST_BB_Cycles(BB *bb, SCHED_EST_TYPE type)
00672 {
00673 UINT32 cycles;
00674 CG_SCHED_EST *se;
00675
00676 MEM_POOL_Push(&MEM_local_nz_pool);
00677 se = CG_SCHED_EST_Create(bb, &MEM_local_nz_pool, type);
00678 cycles = CG_SCHED_EST_Cycles(se);
00679 CG_SCHED_EST_Delete(se);
00680 MEM_POOL_Pop(&MEM_local_nz_pool);
00681
00682 return cycles;
00683 }
00684
00685
00686
00687
00688
00689
00690
00691 static void
00692 Append_Mappings(CG_SCHED_EST *to, CG_SCHED_EST *from)
00693 {
00694 BB *bb;
00695 INT32 num_bbs_before = BB_SET_Size(to->contents);
00696 FOR_ALL_BB_SET_members(from->contents, bb) {
00697 void *lt_map = BB_MAP_Get(from->latency_to_map, bb);
00698 INT32 order = BB_MAP32_Get(from->order, bb);
00699 DevAssert(lt_map, ("missing latency_to map for BB:%d", BB_id(bb)));
00700 DevAssert(order, ("missing order for BB:%d", BB_id(bb)));
00701 BB_MAP_Set(to->latency_to_map, bb, lt_map);
00702 BB_MAP32_Set(to->order, bb, order + num_bbs_before);
00703 }
00704 }
00705
00706
00707
00708
00709 void
00710 CG_SCHED_EST_Append_Scheds(CG_SCHED_EST *se, CG_SCHED_EST *other_se)
00711 {
00712
00713
00714
00715
00716
00717
00718
00719
00720
00721 if (tracing()) {
00722 fprintf(TFile, "<sched_est> appending sched from ");
00723 CG_SCHED_EST_Print(TFile, other_se);
00724 fprintf(TFile, "\n onto sched from ");
00725 CG_SCHED_EST_Print(TFile, se);
00726 fprintf(TFile, "\n");
00727 }
00728
00729 if (!CG_SCHED_EST_use_locs) {
00730 TI_RES_COUNT_Add(se->res_count, se->res_count, other_se->res_count);
00731 } else {
00732
00733
00734
00735 se->sched_cycles = se->sched_cycles + other_se->sched_cycles;
00736 }
00737
00738 Append_Mappings(se, other_se);
00739 se->contents = BB_SET_UnionD(se->contents, other_se->contents, NULL);
00740 se->use_dep_graph = se->use_dep_graph && other_se->use_dep_graph;
00741 se->latency_to_map_dirty = TRUE;
00742 se->cached_resource_cycles = 0;
00743 se->cached_crit_path_len = 0;
00744 if (tracing()) {
00745 fprintf(TFile, " yielding ");
00746 CG_SCHED_EST_Print(TFile, se);
00747 fprintf(TFile, "\n");
00748 }
00749 }
00750
00751
00752
00753
00754 float
00755 CG_SCHED_EST_Region_Cycles(BB_SET *region, BB *entry, BOOL merged,
00756 SCHED_EST_TYPE type)
00757 {
00758 BB_MAP sched_ests = BB_MAP_Create();
00759 float avg_cycles;
00760 BB *bb;
00761
00762 MEM_POOL_Push(&MEM_local_nz_pool);
00763
00764 if (merged) {
00765 CG_SCHED_EST *merged_se = CG_SCHED_EST_Create(entry, &MEM_local_nz_pool,
00766 SCHED_EST_FOR_IF_CONV);
00767 FOR_ALL_BB_SET_members(region, bb) {
00768 if (bb != entry) {
00769 CG_SCHED_EST *se;
00770 se = CG_SCHED_EST_Create(bb, &MEM_local_nz_pool,
00771 SCHED_EST_FOR_IF_CONV);
00772 CG_SCHED_EST_Append_Scheds(merged_se, se);
00773 CG_SCHED_EST_Delete(se);
00774 }
00775 }
00776 avg_cycles = CG_SCHED_EST_Cycles(merged_se);
00777 CG_SCHED_EST_Delete(merged_se);
00778 } else {
00779 FOR_ALL_BB_SET_members(region, bb)
00780 BB_MAP_Set(sched_ests, bb,
00781 CG_SCHED_EST_Create(bb, &MEM_local_nz_pool,
00782 SCHED_EST_FOR_IF_CONV));
00783 avg_cycles = CG_SCHED_EST_Avg_Cycles_Thru(region, entry, sched_ests, type);
00784 FOR_ALL_BB_SET_members(region, bb)
00785 CG_SCHED_EST_Delete((CG_SCHED_EST *)BB_MAP_Get(sched_ests, bb));
00786 }
00787
00788 MEM_POOL_Pop(&MEM_local_nz_pool);
00789 BB_MAP_Delete(sched_ests);
00790
00791 return avg_cycles;
00792 }
00793
00794
00795
00796
00797
00798