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
00045
00046
00047
00048
00049
00051
00052
00053
00054
00055
00056
00057
00058 #ifdef USE_PCH
00059 #include "cg_pch.h"
00060 #endif // USE_PCH
00061 #pragma hdrstop
00062
00063 #ifdef _KEEP_RCS_ID
00064 static char *rcs_id = "$Source: be/cg/gra_mon/SCCS/s.gra_bb.cxx $ $Revision: 1.15 $";
00065 #endif
00066
00067 #include "defs.h"
00068 #include "cg.h"
00069 #include "cg_region.h"
00070 #include "mempool.h"
00071 #include "cgir.h"
00072 #include "bb_set.h"
00073 #include "gra_live.h"
00074 #include "gra_bb.h"
00075 #include "gra_lrange.h"
00076 #include "gra_loop.h"
00077 #include "gtn_universe.h"
00078 #include "gtn_set.h"
00079 #include "gra_region.h"
00080 #include "util.h"
00081 #include "mempool.h"
00082 #include "lra.h"
00083 #include "gra.h"
00084 #include "gra_interfere.h"
00085 #include "gra_trace.h"
00086
00087 GBB_MGR gbb_mgr;
00088 #ifdef TARG_X8664
00089 OP *gra_savexmms_op;
00090 #endif
00091
00092
00094 INT
00095 GRA_BB::Register_Girth( ISA_REGISTER_CLASS rc )
00096 {
00097 INT rr = LRA_Register_Request(bb,rc);
00098 INT rs = REGISTER_SET_Size(REGISTER_CLASS_allocatable(rc));
00099 #ifndef TARG_X8664 // Don't understand why we should inflate register request.
00100 if ( rr < GRA_LOCAL_FORCED_MAX(rc) && rr != 0 )
00101 rr = GRA_LOCAL_FORCED_MAX(rc);
00102 #endif
00103 return rr <= rs ? rr : rs;
00104 }
00105
00107
00108 BOOL
00109 GRA_BB::Region_Is_Complement(void)
00110 {
00111 return region == gra_region_mgr.Complement_Region();
00112 }
00113
00115
00116 void
00117 GRA_BB::Add_LUNIT( LUNIT* lunit)
00118 {
00119 ISA_REGISTER_CLASS rc = lunit->Lrange()->Rc();
00120 lunits[rc] = lunits[rc]->BB_List_Push(lunit);
00121 }
00122
00124
00125 void
00126 GRA_BB::Make_Register_Used( ISA_REGISTER_CLASS rc, REGISTER reg,
00127 LRANGE* lrange, BOOL reclaim )
00128 {
00129 region-> Make_Register_Used(rc,reg);
00130 loop->Make_Register_Used(rc, reg, reclaim);
00131 registers_used[rc] = REGISTER_SET_Union1(registers_used[rc],reg);
00132
00133 #ifdef KEY
00134
00135 if (GRA_reclaim_register)
00136 Set_LRANGE_Owner(rc, reg, lrange);
00137
00138 if (! GRA_optimize_boundary)
00139 return;
00140
00141
00142 if (reclaim) {
00143 Usage_Start_Index_Set(rc, reg, 0);
00144 Usage_End_Index_Set(rc, reg, 0);
00145 Usage_Live_In_Clear(rc, reg);
00146 Usage_Live_Out_Clear(rc, reg);
00147 }
00148
00149 const mUINT16 max_OP_index = 0xffff;
00150
00151
00152
00153
00154 if (lrange == NULL) {
00155 Usage_Start_Index_Set(rc, reg, 1);
00156 Usage_End_Index_Set(rc, reg, max_OP_index);
00157 return;
00158 }
00159
00160
00161
00162
00163 if (lrange->Contains_Internal_BB(this)) {
00164
00165 Usage_Live_In_Set(rc, reg);
00166 Usage_Live_Out_Set(rc, reg);
00167 Usage_Start_Index_Set(rc, reg, 0);
00168 Usage_End_Index_Set(rc, reg, 0);
00169 } else {
00170
00171
00172
00173 typedef struct {
00174 mUINT16 index;
00175 BOOL is_start_index;
00176 } usage;
00177
00178 usage this_usage[4];
00179
00180
00181 int usage_segments = 0;
00182
00183
00184 usage boundary_usage[2];
00185 usage combined_usage[6];
00186
00187 BOOL is_preferenced = FALSE;
00188
00189 #ifdef Is_True_On
00190 LUNIT* lunit;
00191 Is_True(lrange->Find_LUNIT_For_GBB(this, &lunit),
00192 ("Make_Register_Used: cannot find LUNIT"));
00193 REGISTER_SET allowed_prefs =
00194 REGISTER_SET_Union(lunit->Allowed_Preferences(),
00195 Global_Preferenced_Regs(lrange, this));
00196 is_preferenced = REGISTER_SET_MemberP(allowed_prefs, reg);
00197 #endif
00198
00199
00200 if (BB_first_op(Bb()) == NULL) {
00201 Usage_Live_In_Set(rc, reg);
00202 Usage_Live_Out_Set(rc, reg);
00203 Usage_Start_Index_Set(rc, reg, 0);
00204 Usage_End_Index_Set(rc, reg, 0);
00205 return;
00206 }
00207
00208
00209 mUINT16 this_usage_start_index = Usage_Start_Index(rc, reg);
00210 mUINT16 this_usage_end_index = Usage_End_Index(rc, reg);
00211 if (Is_Usage_Live_In(rc, reg) && !Is_Usage_Live_Out(rc, reg)) {
00212
00213 Is_True(this_usage_start_index == 0 && this_usage_end_index > 0,
00214 ("Bad usage index for live-in live range"));
00215 this_usage[0].index = 0;
00216 this_usage[0].is_start_index = TRUE;
00217 this_usage[1].index = this_usage_end_index;
00218 this_usage[1].is_start_index = FALSE;
00219 usage_segments = 1;
00220 } else if (!Is_Usage_Live_In(rc, reg) && Is_Usage_Live_Out(rc, reg)) {
00221
00222 Is_True(this_usage_start_index > 0 && this_usage_end_index == 0,
00223 ("Bad usage index for live-out live range"));
00224 this_usage[0].index = this_usage_start_index;
00225 this_usage[0].is_start_index = TRUE;
00226 this_usage[1].index = max_OP_index;
00227 this_usage[1].is_start_index = FALSE;
00228 usage_segments = 1;
00229 } else if (Is_Usage_Live_In(rc, reg) && Is_Usage_Live_Out(rc, reg)) {
00230 if (this_usage_start_index > 0) {
00231
00232 Is_True(this_usage_end_index > 0 &&
00233 this_usage_start_index >= this_usage_end_index,
00234 ("Bad usage index for disjoint live range"));
00235 this_usage[0].index = 0;
00236 this_usage[0].is_start_index = TRUE;
00237 this_usage[1].index = this_usage_end_index;
00238 this_usage[1].is_start_index = FALSE;
00239
00240 this_usage[2].index = this_usage_start_index;
00241 this_usage[2].is_start_index = TRUE;
00242 this_usage[3].index = max_OP_index;
00243 this_usage[3].is_start_index = FALSE;
00244 usage_segments = 2;
00245 } else {
00246
00247 Is_True(this_usage_end_index == 0,
00248 ("Bad usage index for pass-thru live range"));
00249
00250
00251 Is_True(is_preferenced,
00252 ("Make_Register_Used: register is already used"));
00253 return;
00254 }
00255 } else if (!Is_Usage_Live_In(rc, reg) && !Is_Usage_Live_Out(rc, reg)) {
00256 if (this_usage_start_index > 0) {
00257
00258 Is_True(this_usage_end_index > 0 &&
00259 this_usage_start_index <= this_usage_end_index,
00260 ("Bad usage index for contained live range"));
00261 this_usage[0].index = this_usage_start_index;
00262 this_usage[0].is_start_index = TRUE;
00263 this_usage[1].index = this_usage_end_index;
00264 this_usage[1].is_start_index = FALSE;
00265 usage_segments = 1;
00266 } else {
00267
00268 }
00269 }
00270
00271
00272 LRANGE_BOUNDARY_BB* boundary_bb = lrange->Get_Boundary_Bb(Bb());
00273 if (boundary_bb->Is_Live_In() && !boundary_bb->Is_Live_Out()) {
00274
00275 boundary_usage[0].index = 0;
00276 boundary_usage[0].is_start_index = TRUE;
00277 if (boundary_bb->End_Index() == 0) {
00278
00279
00280 boundary_usage[1].index = 1;
00281 } else {
00282 boundary_usage[1].index = boundary_bb->End_Index();
00283 }
00284 Is_True(boundary_usage[1].index > 0, ("Bad OP index in live-in"));
00285 boundary_usage[1].is_start_index = FALSE;
00286 } else if (!boundary_bb->Is_Live_In() && boundary_bb->Is_Live_Out()) {
00287
00288 if (boundary_bb->Start_Index() == 0) {
00289
00290
00291
00292 boundary_usage[0].index = boundary_bb->Gbb()->OPs_Count();
00293 } else {
00294 boundary_usage[0].index = boundary_bb->Start_Index();
00295 }
00296 Is_True(boundary_usage[0].index > 0, ("Bad OP index in live-out"));
00297 boundary_usage[0].is_start_index = TRUE;
00298 boundary_usage[1].index = max_OP_index;
00299 boundary_usage[1].is_start_index = FALSE;
00300 } else if (!boundary_bb->Is_Live_In() && !boundary_bb->Is_Live_Out()) {
00301 if (boundary_bb->Start_Index() > 0) {
00302 Is_True(boundary_bb->End_Index() >= boundary_bb->Start_Index(),
00303 ("Bad usage index for contained live range"));
00304 boundary_usage[0].index = boundary_bb->Start_Index();
00305 boundary_usage[0].is_start_index = TRUE;
00306 boundary_usage[1].index = boundary_bb->End_Index();
00307 boundary_usage[1].is_start_index = FALSE;
00308 } else {
00309
00310 Is_True(boundary_bb->End_Index() == 0,
00311 ("Bad usage index for empty live range"));
00312 return;
00313 }
00314 } else {
00315
00316 #ifdef Is_True_On
00317
00318
00319 boundary_usage[0].index = 1;
00320 boundary_usage[0].is_start_index = TRUE;
00321 boundary_usage[1].index = max_OP_index;
00322 boundary_usage[1].is_start_index = FALSE;
00323 #else
00324
00325 Usage_Live_In_Set(rc, reg);
00326 Usage_Live_Out_Set(rc, reg);
00327 Usage_Start_Index_Set(rc, reg, 0);
00328 Usage_End_Index_Set(rc, reg, 0);
00329 return;
00330 #endif
00331 }
00332
00333
00334 int combined_i_max = 0;
00335 {
00336 int this_i, boundary_i, combined_i;
00337 int this_i_max = usage_segments * 2;
00338 int boundary_i_max = 2;
00339
00340 this_i = boundary_i = combined_i = 0;
00341 for ( ; this_i < this_i_max && boundary_i < boundary_i_max; ) {
00342 if (this_usage[this_i].index < boundary_usage[boundary_i].index)
00343 combined_usage[combined_i++] = this_usage[this_i++];
00344 else if (this_usage[this_i].index > boundary_usage[boundary_i].index)
00345 combined_usage[combined_i++] = boundary_usage[boundary_i++];
00346 else {
00347
00348
00349
00350 if (this_usage[this_i].is_start_index) {
00351 combined_usage[combined_i++] = boundary_usage[boundary_i++];
00352 combined_usage[combined_i++] = this_usage[this_i++];
00353 } else {
00354 combined_usage[combined_i++] = this_usage[this_i++];
00355 combined_usage[combined_i++] = boundary_usage[boundary_i++];
00356 }
00357 }
00358 }
00359
00360
00361
00362 while (this_i < this_i_max) {
00363 combined_usage[combined_i++] = this_usage[this_i++];
00364 }
00365 while (boundary_i < boundary_i_max) {
00366 combined_usage[combined_i++] = boundary_usage[boundary_i++];
00367 }
00368 combined_i_max = combined_i;
00369
00370 #ifdef Is_True_On
00371 Is_True(combined_i_max % 2 == 0,
00372 ("Make_Register_Used: error in combined usage"));
00373
00374
00375
00376 if (!is_preferenced) {
00377 for (combined_i = 0; combined_i < combined_i_max; combined_i++) {
00378
00379 Is_True(combined_usage[combined_i].is_start_index ==
00380 (combined_i % 2 == 0),
00381 ("Make_Register_Used: error in combined usage"));
00382 }
00383 }
00384 #endif
00385 }
00386
00387
00388 {
00389 BOOL live_in = FALSE;
00390 BOOL live_out = FALSE;
00391 mUINT16 start_index = 0;
00392 mUINT16 end_index = 0;
00393
00394 if (combined_i_max == 0) {
00395
00396 Is_True(Usage_Start_Index(rc, reg) == 0 &&
00397 Usage_End_Index(rc, reg) == 0 &&
00398 !Is_Usage_Live_Out(rc, reg) &&
00399 !Is_Usage_Live_In(rc, reg),
00400 ("Make_Register_Used: error in combined usage"));
00401 } else {
00402
00403 if (combined_usage[0].index == 0)
00404 live_in = TRUE;
00405 if (combined_usage[combined_i_max-1].index == max_OP_index)
00406 live_out = TRUE;
00407
00408
00409 if (live_in && !live_out) {
00410 start_index = 0;
00411 end_index = combined_usage[combined_i_max-1].index;
00412 } else if (!live_in && live_out) {
00413 start_index = combined_usage[0].index;
00414 end_index = 0;
00415 } else if (live_in && live_out) {
00416
00417 if (combined_i_max == 6) {
00418
00419
00420 int gap1_size = combined_usage[2].index - combined_usage[1].index;
00421 int gap2_size = combined_usage[4].index - combined_usage[3].index;
00422 if (gap1_size > gap2_size) {
00423 start_index = combined_usage[2].index;
00424 end_index = combined_usage[1].index;
00425 } else {
00426 start_index = combined_usage[4].index;
00427 end_index = combined_usage[3].index;
00428 }
00429 } else if (combined_i_max == 4) {
00430
00431 start_index = combined_usage[2].index;
00432 end_index = combined_usage[1].index;
00433 } else {
00434 Is_True(FALSE,
00435 ("Make_Register_Used: error in combined usage"));
00436 }
00437 } else {
00438
00439 start_index = combined_usage[0].index;
00440 end_index = combined_usage[combined_i_max-1].index;
00441 }
00442 }
00443 if (live_in)
00444 Usage_Live_In_Set(rc, reg);
00445 if (live_out)
00446 Usage_Live_Out_Set(rc, reg);
00447 Usage_Start_Index_Set(rc, reg, start_index);
00448 Usage_End_Index_Set(rc, reg, end_index);
00449 }
00450 }
00451 #endif
00452 }
00453
00454
00456 REGISTER_SET
00457 GRA_BB::Registers_Used( ISA_REGISTER_CLASS rc)
00458 {
00459 if ( region == gra_region_mgr.Complement_Region() )
00460 return registers_used[rc];
00461 else {
00462 REGISTER_SET used = region->Registers_Used(rc);
00463
00464 if ( region->Has_Call() )
00465 return REGISTER_SET_Union(used,REGISTER_CLASS_caller_saves(rc));
00466 else
00467 return used;
00468 }
00469 }
00470
00471 #ifdef KEY
00473 // Add <reg> to the set of registers referenced in the given <gbb> and <rc>.
00474 void
00475 GRA_BB::Make_Register_Referenced (ISA_REGISTER_CLASS rc, REGISTER reg,
00476 LRANGE* lrange )
00477 {
00478 registers_referenced[rc] = REGISTER_SET_Union1(registers_referenced[rc],reg);
00479 }
00480
00482 REGISTER_SET
00483 GRA_BB::Registers_Referenced( ISA_REGISTER_CLASS rc)
00484 {
00485 FmtAssert(region == gra_region_mgr.Complement_Region(),
00486 ("Registers_Referenced: lrange type not implemented"));
00487 return registers_referenced[rc];
00488 }
00489 #endif
00490
00492
00493 BOOL
00494 GRA_BB::Spill_Above_Check( LRANGE* lrange )
00495 {
00496 ISA_REGISTER_CLASS rc = lrange->Rc();
00497 if (spill_above[rc]) {
00498 LRANGE_SUBUNIVERSE *su = region->Subuniverse(rc);
00499 return(LRANGE_SET_MemberPS(spill_above[rc], lrange, su));
00500 }
00501 return FALSE;
00502 }
00503
00505
00506 void
00507 GRA_BB::Spill_Above_Set( LRANGE* lr )
00508 {
00509 ISA_REGISTER_CLASS rc = lr->Rc();
00510 LRANGE_SUBUNIVERSE *su = region->Subuniverse(rc);
00511 INT size = su->Count();
00512
00513 if (!spill_above[rc]) {
00514 spill_above[rc] = LRANGE_SET_Create_Empty(size, GRA_pool);
00515 }
00516 spill_above[rc] = LRANGE_SET_Union1S(spill_above[rc], lr, GRA_pool, su);
00517 }
00518
00520
00521 void
00522 GRA_BB::Spill_Above_Reset( LRANGE* lr )
00523 {
00524 ISA_REGISTER_CLASS rc = lr->Rc();
00525 LRANGE_SUBUNIVERSE *su = region->Subuniverse(rc);
00526
00527 spill_above[rc] = LRANGE_SET_Difference1DS(spill_above[rc], lr, su);
00528 }
00529
00530
00532
00533 BOOL
00534 GRA_BB::Restore_Below_Check( LRANGE* lr )
00535 {
00536 ISA_REGISTER_CLASS rc = lr->Rc();
00537 if (restore_below[rc]) {
00538 LRANGE_SUBUNIVERSE *su = region->Subuniverse(rc);
00539 return(LRANGE_SET_MemberPS(restore_below[rc], lr, su));
00540 }
00541 return FALSE;
00542 }
00543
00545
00546 void
00547 GRA_BB::Restore_Below_Set( LRANGE* lr )
00548 {
00549 ISA_REGISTER_CLASS rc = lr->Rc();
00550 LRANGE_SUBUNIVERSE *su = region->Subuniverse(rc);
00551 INT size = su->Count();
00552
00553 if (!restore_below[rc]) {
00554 restore_below[rc] = LRANGE_SET_Create_Empty(size, GRA_pool);
00555 }
00556 restore_below[rc] = LRANGE_SET_Union1S(restore_below[rc], lr,
00557 GRA_pool, su);
00558 }
00559
00561
00562
00563 void
00564 GRA_BB::Restore_Below_Reset( LRANGE* lr )
00565 {
00566 ISA_REGISTER_CLASS rc = lr->Rc();
00567 LRANGE_SUBUNIVERSE *su = region->Subuniverse(rc);
00568
00569 restore_below[rc] = LRANGE_SET_Difference1DS(restore_below[rc], lr, su);
00570 }
00571
00573
00574 void
00575 GBB_MGR::Initialize(void)
00576 {
00577 split_mark_counter = 0;
00578 one_set_counter = 0;
00579 wired_local_count = 0;
00580 alloc_count = 0;
00581 map = BB_MAP_Create();
00582 blocks_with_calls = BB_SET_Create_Empty(PU_BB_Count + 2,GRA_pool);
00583 blocks_with_rot_reg_clob = BB_SET_Create_Empty(PU_BB_Count + 2,GRA_pool);
00584 #ifdef TARG_X8664
00585 blocks_with_x87_OP = BB_SET_Create_Empty(PU_BB_Count + 2,GRA_pool);
00586 blocks_with_mmx_OP = BB_SET_Create_Empty(PU_BB_Count + 2,GRA_pool);
00587 #endif
00588 }
00589
00590
00592
00593 void
00594 GBB_MGR::Finalize(void)
00595 {
00596 BB_MAP_Delete(map);
00597 GRA_Trace_Wired_Local_Count(wired_local_count);
00598 }
00599
00600
00602
00603
00604 GRA_BB*
00605 GBB_MGR::Create(BB* bb, GRA_REGION* region)
00606 {
00607 ISA_REGISTER_CLASS rc;
00608 GRA_BB* gbb = TYPE_MEM_POOL_ALLOC(GRA_BB,GRA_pool);
00609
00610 gbb->bb = bb;
00611 gbb->region = region;
00612 gbb->split_mark = -1;
00613 gbb->one_set_mark = -1;
00614 gbb->Clear_Flags();
00615 alloc_count++;
00616
00617
00618
00619
00620 FOR_ALL_ISA_REGISTER_CLASS( rc ) {
00621 gbb->registers_used[rc] = REGISTER_SET_EMPTY_SET;
00622 gbb->glue_registers_used[rc] = REGISTER_SET_EMPTY_SET;
00623 gbb->lunits[rc] = NULL;
00624 gbb->local_lrange_count[rc] = 0;
00625 gbb->local_lranges[rc] = NULL;
00626 gbb->unpreferenced_wired_lranges[rc] = NULL;
00627 gbb->spill_above[rc] = NULL;
00628 gbb->restore_below[rc] = NULL;
00629 #ifdef KEY
00630 if (GRA_optimize_boundary) {
00631 gbb->usage_live_in[rc] = REGISTER_SET_EMPTY_SET;
00632 gbb->usage_live_out[rc] = REGISTER_SET_EMPTY_SET;
00633 for (int i = 0; i < REGISTER_MAX+1; i++) {
00634 gbb->usage_start_index[rc][i] = 0;
00635 gbb->usage_end_index[rc][i] = 0;
00636 }
00637 }
00638 if (GRA_reclaim_register) {
00639 for (int i = 0; i < REGISTER_MAX+1; i++) {
00640 gbb->lrange_owner[rc][i] = NULL;
00641 }
00642 }
00643 #endif
00644 }
00645
00646 BB_MAP_Set(map,bb,(void*) gbb);
00647 if ( BB_call(bb) ) {
00648 blocks_with_calls = BB_SET_Union1D(blocks_with_calls,bb,GRA_pool);
00649
00650
00651
00652
00653 ANNOTATION *callant = ANNOT_Get(BB_annotations(bb), ANNOT_CALLINFO);
00654 CALLINFO *callinfo = ANNOT_callinfo(callant);
00655 ST *st = CALLINFO_call_st(callinfo);
00656 if (st != NULL) {
00657 const char *name = ST_name(st);
00658 INT len = strlen(name);
00659 if ((len >= 6 && strcmp(name + len - 6, "setjmp") == 0) ||
00660 (len >= 10 && strcmp(name+len-10, "getcontext") == 0))
00661 gbb->Setjmp_Set();
00662 }
00663 }
00664 if (BB_mod_rotating_registers(bb) || BB_mod_pred_rotating_registers(bb))
00665 blocks_with_rot_reg_clob = BB_SET_Union1D(blocks_with_rot_reg_clob,bb,GRA_pool);
00666 #ifdef TARG_X8664
00667 if (BB_last_op(bb) && OP_code(BB_last_op(bb)) == TOP_savexmms) {
00668 gbb->Savexmms_Set();
00669 gra_savexmms_op = BB_last_op(bb);
00670 }
00671
00672 mUINT16 OPs_count = 0;
00673 for (OP *op = BB_first_op(bb); op != NULL; op = OP_next(op)) {
00674 OPs_count++;
00675 if (OP_x87(op))
00676 gbb->x87_OP_Set();
00677 else if (OP_mmx(op))
00678 gbb->mmx_OP_Set();
00679 }
00680 gbb->OPs_count = OPs_count;
00681 if (gbb->x87_OP())
00682 blocks_with_x87_OP = BB_SET_Union1D(blocks_with_x87_OP, bb, GRA_pool);
00683 if (gbb->mmx_OP())
00684 blocks_with_mmx_OP = BB_SET_Union1D(blocks_with_mmx_OP, bb, GRA_pool);
00685 #endif
00686
00687 return gbb;
00688 }
00689
00690
00692
00693
00694
00695 void
00696 GRA_BB::Create_Local_LRANGEs(ISA_REGISTER_CLASS rc, INT32 count)
00697 {
00698
00699
00700
00701
00702 count -= GRA_LOCAL_FORCED_MAX(rc);
00703 if ( count <= 0 )
00704 return;
00705
00706 local_lrange_count[rc] += count;
00707
00708 while ( count-- > 0 ) {
00709 LRANGE* new_local = lrange_mgr.Create_Local(this,rc);
00710
00711 local_lranges[rc] =
00712 local_lranges[rc]->BB_Local_List_Push(new_local);
00713 }
00714 }
00715
00716
00718
00719
00720 LRANGE*
00721 GRA_BB::Create_Wired_LRANGE(ISA_REGISTER_CLASS rc, REGISTER reg)
00722 {
00723 LRANGE* result = lrange_mgr.Create_Local(this,rc);
00724
00725 gbb_mgr.Incr_Wired_Local_Count();
00726 result->Wire_Register(reg);
00727 return result;
00728 }
00729
00731
00732
00733
00734
00735 void
00736 GRA_BB::Create_Global_Interferences(void)
00737 {
00738 TN* tn;
00739 ISA_REGISTER_CLASS rc;
00740 GTN_SET* live;
00741
00742 MEM_POOL_Push(&MEM_local_nz_pool);
00743
00744
00745 live = GTN_SET_Create(Max(GTN_SET_Alloc_Size(BB_live_in(bb)),
00746 GTN_SET_Alloc_Size(BB_live_out(bb))),
00747 &MEM_local_nz_pool);
00748
00749
00750
00751
00752 live = GTN_SET_CopyD(live,BB_live_in(bb),&MEM_local_nz_pool);
00753 live = GTN_SET_IntersectionD(live,BB_defreach_in(bb));
00754 live = GTN_SET_UnionD(live,BB_live_out(bb),&MEM_local_nz_pool);
00755 live = GTN_SET_IntersectionD(live,BB_defreach_out(bb));
00756
00757 FOR_ALL_ISA_REGISTER_CLASS( rc ) {
00758 intf_mgr.Create_Begin(region->Subuniverse(rc));
00759
00760 for ( tn = GTN_SET_Choose(live);
00761 tn != GTN_SET_CHOOSE_FAILURE;
00762 tn = GTN_SET_Choose_Next(live,tn)
00763 ) {
00764 if ( TN_register_class(tn) == rc && TN_Is_Allocatable(tn) ) {
00765 LRANGE* lrange = lrange_mgr.Get(tn);
00766
00767 if ( lrange->Type() == LRANGE_TYPE_COMPLEMENT ) {
00768
00769
00770 if ( lrange != NULL ) {
00771 intf_mgr.Create_Add_Neighbor(lrange_mgr.Get(tn));
00772 GTN_SET_Difference1D(live,tn);
00773 }
00774 }
00775 }
00776 }
00777 global_lranges[rc] = intf_mgr.Create_End();
00778 }
00779
00780 MEM_POOL_Pop(&MEM_local_nz_pool);
00781 }
00782
00784
00785
00786 void
00787 GRA_BB::Replace_Global_Interference(LRANGE* old_lr, LRANGE* new_lr )
00788 {
00789 ISA_REGISTER_CLASS rc = old_lr->Rc();
00790
00791 if (! Region_Is_Complement())
00792 return;
00793
00794 DevAssert(old_lr->Type() == LRANGE_TYPE_COMPLEMENT,
00795 ("Replacing non complement type in a BB's global interference"));
00796 DevAssert(new_lr->Type() == LRANGE_TYPE_COMPLEMENT,
00797 ("Replacing non complement type in a BB's global interference"));
00798
00799 global_lranges[rc] =
00800 global_lranges[rc]->Replace_Neighbor(old_lr, new_lr,
00801 region->Subuniverse(rc));
00802 }
00803
00804
00806
00807 void
00808 GRA_BB::Rename_TN_References(TN* orig_tn, TN* new_tn)
00809 {
00810 GRA_BB_OP_FORWARD_ITER iter;
00811
00812 for (iter.Init(this); ! iter.Done(); iter.Step()) {
00813 INT i;
00814 OP* op = iter.Current();
00815
00816 for ( i = OP_opnds(op) - 1; i >= 0; --i )
00817 if ( OP_opnd(op,i) == orig_tn) Set_OP_opnd(op, i, new_tn);
00818
00819 for ( i = OP_results(op) - 1; i >= 0; --i )
00820 if ( OP_result(op,i) == orig_tn) Set_OP_result(op, i, new_tn);
00821 }
00822 }
00823
00825
00826
00827 void
00828 GRA_BB::Add_Live_In_LRANGE(LRANGE* lrange)
00829 {
00830 GRA_LIVE_Add_Live_In_GTN(bb, lrange->Tn());
00831 }
00832
00834
00835
00836 void
00837 GRA_BB::Add_Live_Out_LRANGE(LRANGE* lrange)
00838 {
00839 GRA_LIVE_Add_Live_Out_GTN(bb, lrange->Tn());
00840 }
00841
00843
00844
00845 void
00846 GRA_BB::Remove_Live_In_LRANGE(LRANGE* lrange)
00847 {
00848 GRA_LIVE_Remove_Live_In_GTN(bb, lrange->Tn());
00849 }
00850
00852
00853
00854 void
00855 GRA_BB::Remove_Live_Out_LRANGE(LRANGE* lrange)
00856 {
00857 GRA_LIVE_Remove_Live_Out_GTN(bb, lrange->Tn());
00858 }
00859
00861
00862
00863 INT32
00864 GRA_BB::Global_Live_Lrange_Count(ISA_REGISTER_CLASS rc)
00865 {
00866 return global_lranges[rc]->Count();
00867 }
00868
00870
00871 BOOL
00872 GRA_BB::Has_Multiple_Predecessors(void)
00873 {
00874 GRA_BB_FLOW_NEIGHBOR_ITER iter;
00875 INT count = 0;
00876 for (iter.Preds_Init(this); ! iter.Done(); iter.Step()) {
00877 if ( ++count > 1 )
00878 return TRUE;
00879 }
00880 return FALSE;
00881 }
00882
00884
00885 BOOL
00886 GRA_BB::Is_Region_Block(BOOL swp_too)
00887 {
00888 RID* rid = Region()->Rid();
00889 if (rid && rid != Current_Rid &&
00890 (RID_type(rid) != RID_TYPE_swp || swp_too == TRUE)) {
00891 return TRUE;
00892 }
00893 return FALSE;
00894 }
00895
00897
00898 BOOL
00899 GRA_BB::Is_Region_Entry_Block(void)
00900 {
00901 RID* rid = Region()->Rid();
00902 if (Is_Region_Block(FALSE) && Bb() == CGRIN_entry(RID_cginfo(rid)))
00903 return TRUE;
00904 return FALSE;
00905 }
00906
00908
00909 void
00910 GRA_BB::Check_Loop_Border(void)
00911 {
00912 GRA_BB_FLOW_NEIGHBOR_ITER iter;
00913
00914
00915
00916
00917
00918
00919
00920
00921
00922
00923 if (Loop() != NULL) {
00924 return;
00925 }
00926
00927 for (iter.Preds_Init(this); ! iter.Done(); iter.Step()) {
00928 GRA_BB* pred = iter.Current();
00929 if (pred->Loop() != NULL) {
00930 Loop_Epilog_Set();
00931 }
00932 }
00933
00934
00935 for (iter.Succs_Init(this); ! iter.Done(); iter.Step()) {
00936 GRA_BB* succ = iter.Current();
00937 if (succ->Loop() != NULL) {
00938 Loop_Prolog_Set();
00939 }
00940 }
00941 }
00942