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
00042
00043
00044
00046
00047
00048
00049
00050
00051
00052
00053 #ifdef USE_PCH
00054 #include "cg_pch.h"
00055 #endif // USE_PCH
00056 #pragma hdrstop
00057
00058 #ifdef _KEEP_RCS_ID
00059 static char *rcs_id = "$Source: /scratch/mee/2.4-65/kpro64-pending/be/cg/gra_mon/SCCS/s.gra_lrange.cxx $ $Revision: 1.24 $";
00060 #endif
00061
00062 #if defined(__GNUC__)
00063 #if 0 // workaround at PathScale for build problem
00064 #include <math.h>
00065 #else
00066 #include <float.h>
00067 #endif
00068 #else
00069 #include <limits.h>
00070 #endif
00071 #include "defs.h"
00072 #include "errors.h"
00073 #include "cgir.h"
00074 #include "tn_map.h"
00075 #include "gtn_universe.h"
00076 #include "gtn_set.h"
00077 #include "cg_spill.h"
00078 #include "cg_flags.h"
00079
00080 #include "gra_bb.h"
00081 #include "gra_trace.h"
00082 #include "gra_lrange.h"
00083 #include "gra_lunit.h"
00084 #include "gra_region.h"
00085 #include "gra_lrange_subuniverse.h"
00086 #include "gra_grant.h"
00087 #include "gra_interfere.h"
00088
00089 #ifdef KEY
00090
00091 BOOL GRA_optimize_boundary = FALSE;
00092 BOOL GRA_optimize_boundary_set = FALSE;
00093
00094
00095
00096 BOOL GRA_prioritize_by_density = FALSE;
00097 BOOL GRA_prioritize_by_density_set = FALSE;
00098 #endif
00099
00100 LRANGE_MGR lrange_mgr;
00101
00102 static INT32 complement_lrange_count, region_lrange_count, local_lrange_count,
00103 duplicate_lrange_count;
00104
00105
00107
00108 void
00109 LRANGE_MGR::Initialize(void)
00110 {
00111 one_set_counter = 0;
00112 tn_map = TN_MAP_Create();
00113 complement_lrange_count = region_lrange_count = local_lrange_count = 0;
00114 duplicate_lrange_count = 0;
00115 }
00116
00118
00119 void
00120 LRANGE_MGR::Finalize(void)
00121 {
00122 TN_MAP_Delete(tn_map);
00123 GRA_Trace_LRANGE_Stats(complement_lrange_count,region_lrange_count,
00124 local_lrange_count,duplicate_lrange_count);
00125 }
00126
00128
00129
00130
00131
00132
00133 LRANGE*
00134 LRANGE_MGR::Create( LRANGE_TYPE type, ISA_REGISTER_CLASS rc, size_t size )
00135 {
00136 LRANGE* result = (LRANGE*) MEM_POOL_Alloc(GRA_pool,size);
00137 result->reg = 0;
00138 result->rc = rc;
00139 result->type = type;
00140 result->flags = (LR_FLAG) 0;
00141 result->mark = 0;
00142 result->pref = NULL;
00143 result->pref_priority = 0.0;
00144
00145 return result;
00146 }
00147
00149
00150
00151
00152
00153
00154 LRANGE*
00155 LRANGE_MGR::Create_Complement( TN* tn )
00156 {
00157 LRANGE* result = Create(LRANGE_TYPE_COMPLEMENT,
00158 TN_register_class(tn), sizeof(LRANGE));
00159
00160 DevAssert(TN_Is_Allocatable(tn),
00161 ("Invalid TN for register allocation"));
00162
00163 ++complement_lrange_count;
00164
00165 result->u.c.tn = tn;
00166 result->u.c.original_tn = tn;
00167 result->u.c.first_lunit = NULL;
00168
00169 result->u.c.live_bb_set = BB_SET_Create_Empty(PU_BB_Count+2,GRA_pool);
00170 #ifdef KEY
00171 result->u.c.internal_bb_set = BB_SET_Create_Empty(PU_BB_Count+2,GRA_pool);
00172 result->u.c.boundary_bbs = NULL;
00173 #endif
00174 result->u.c.global_pref_set = NULL;
00175 gra_region_mgr.Complement_Region()->Add_LRANGE(result);
00176 TN_MAP_Set(tn_map,tn,result);
00177 if (TN_is_save_reg(tn))
00178 result->Tn_Is_Save_Reg_Set();
00179 if (TN_is_gra_cannot_split(tn))
00180 result->Cannot_Split_Set();
00181 return result;
00182 }
00183
00185
00186
00187 LRANGE*
00188 LRANGE_MGR::Create_Region( TN* tn, GRA_REGION* region )
00189 {
00190 LRANGE* result = Create(LRANGE_TYPE_REGION,
00191 TN_register_class(tn), sizeof(LRANGE));
00192 ++region_lrange_count;
00193 result->u.r.tn = tn;
00194 result->u.r.region = region;
00195 result->u.r.complement_bbs = NULL;
00196 result->orig_reg = TN_register(tn);
00197 region->Add_LRANGE(result);
00198 TN_MAP_Set(tn_map,tn,result);
00199 return result;
00200 }
00201
00203
00204 LRANGE*
00205 LRANGE_MGR::Create_Local( GRA_BB* gbb, ISA_REGISTER_CLASS cl )
00206 {
00207 LRANGE* result = Create(LRANGE_TYPE_LOCAL, cl, sizeof(LRANGE) -
00208 sizeof(result->u.c) + sizeof(result->u.l));
00209 ++local_lrange_count;
00210 result->u.l.gbb = gbb;
00211 result->priority = gbb->Freq() * 2.0F;
00212 gra_region_mgr.Complement_Region()->Add_LRANGE(result);
00213 return result;
00214 }
00215
00217
00218
00219 LRANGE*
00220 LRANGE_MGR::Create_Duplicate( LRANGE* lrange )
00221 {
00222 TN* tn;
00223 LRANGE* result;
00224
00225 DevAssert(lrange->type == LRANGE_TYPE_COMPLEMENT,
00226 ("Duplicating a non-COMPLEMENT LRANGE"));
00227
00228 ++duplicate_lrange_count;
00229 tn = Dup_TN_Even_If_Dedicated(lrange->Tn());
00230
00231 Set_TN_spill(tn, TN_spill(lrange->Original_TN()));
00232
00233 GTN_UNIVERSE_Add_TN(tn);
00234 result = Create_Complement(tn);
00235 result->u.c.original_tn = lrange->u.c.original_tn;
00236 result->flags = (LR_FLAG)(result->flags | (lrange->flags & LRANGE_FLAGS_avoid_ra));
00237 return result;
00238 }
00239
00241
00242
00243
00244
00245 INT32
00246 LRANGE::Candidate_Reg_Count(void) {
00247 GRA_REGION *region;
00248 if ( Type() == LRANGE_TYPE_REGION )
00249 region = Region();
00250 else region = gra_region_mgr.Complement_Region();
00251 if ( Spans_A_Call() )
00252 return region->Callee_Saves_Registers_Available_Count(rc);
00253 else return REGISTER_SET_Size(region->Registers_Available(rc));
00254 }
00255
00257 void
00258 LRANGE::Add_Live_BB(GRA_BB *gbb) {
00259 if (Type() == LRANGE_TYPE_COMPLEMENT)
00260 u.c.live_bb_set = BB_SET_Union1D(u.c.live_bb_set, gbb->Bb(), GRA_pool);
00261 }
00262
00264 void
00265 LRANGE::Remove_Live_BB(GRA_BB *gbb) {
00266 if (Type() == LRANGE_TYPE_COMPLEMENT)
00267 u.c.live_bb_set = BB_SET_Difference1D(u.c.live_bb_set, gbb->Bb());
00268 }
00269
00271 BOOL
00272 LRANGE::Contains_BB(GRA_BB *gbb) {
00273 FmtAssert(Type() == LRANGE_TYPE_COMPLEMENT,
00274 ("LRANGE_Contains_BB: LRANGE not a complement LRANGE"));
00275 return BB_SET_MemberP(u.c.live_bb_set, gbb->Bb());
00276 }
00277
00278 #ifdef KEY
00280 void
00281 LRANGE::Add_Internal_BB(GRA_BB *gbb) {
00282 if (Type() == LRANGE_TYPE_COMPLEMENT)
00283 u.c.internal_bb_set = BB_SET_Union1D(u.c.internal_bb_set, gbb->Bb(), GRA_pool);
00284 }
00285
00287 void
00288 LRANGE::Remove_Internal_BB(GRA_BB *gbb) {
00289 if (Type() == LRANGE_TYPE_COMPLEMENT)
00290 u.c.internal_bb_set = BB_SET_Difference1D(u.c.internal_bb_set, gbb->Bb());
00291 }
00292
00294 BOOL
00295 LRANGE::Contains_Internal_BB(GRA_BB *gbb) {
00296 FmtAssert(Type() == LRANGE_TYPE_COMPLEMENT,
00297 ("LRANGE_Contains_BB: LRANGE not a complement LRANGE"));
00298 return BB_SET_MemberP(u.c.internal_bb_set, gbb->Bb());
00299 }
00300 #endif
00301
00303 void
00304 LRANGE::Add_Global_Pref(TN *tn) {
00305 if (u.c.global_pref_set == NULL) {
00306 u.c.global_pref_set = GTN_SET_Create_Empty(GTN_UNIVERSE_size,
00307 GRA_pool);
00308 }
00309 u.c.global_pref_set = GTN_SET_Union1D(u.c.global_pref_set, tn, GRA_pool);
00310 }
00311
00313 void
00314 LRANGE::Remove_Global_Pref(TN *tn) {
00315 u.c.global_pref_set = GTN_SET_Difference1D(u.c.global_pref_set, tn);
00316 }
00317
00319 BOOL
00320 LRANGE::Check_Global_Pref(TN *tn) {
00321 return Global_Pref_Set() != NULL && GTN_SET_MemberP(Global_Pref_Set(), tn);
00322 }
00323
00325
00326
00327 void
00328 LRANGE::Add_LUNIT( LUNIT* lunit ) {
00329 u.c.first_lunit = u.c.first_lunit->Lrange_List_Push(lunit);
00330 lunit->Lrange_Set(this);
00331 }
00332
00334
00335
00336
00337 void
00338 LRANGE_MGR::Begin_Complement_Interference(LRANGE *lrange) {
00339 Is_True(lrange->Type() == LRANGE_TYPE_COMPLEMENT,
00340 ("Not a complement LRANGE"));
00341 interference_creation_lrange = lrange;
00342 intf_mgr.Create_Begin(gra_region_mgr.Complement_Region()->Subuniverse(
00343 (ISA_REGISTER_CLASS)lrange->Rc()));
00344 }
00345
00347
00348
00349
00350
00351
00352 void
00353 LRANGE_MGR::Complement_Interference( LRANGE* neighbor ) {
00354 Is_True(neighbor->Type() == LRANGE_TYPE_COMPLEMENT,
00355 ("Not a complement LRANGE"));
00356 if ( neighbor != interference_creation_lrange )
00357 intf_mgr.Create_Add_Neighbor(neighbor);
00358 }
00359
00361
00362
00363 void
00364 LRANGE_MGR::End_Complement_Interference( void ) {
00365 interference_creation_lrange->u.c.neighbors = intf_mgr.Create_End();
00366 }
00367
00369
00370
00371
00372
00373
00374 void
00375 LRANGE::Initialize_Region_Inteference(GRA_REGION* region) {
00376 u.c.neighbors = intf_mgr.Create_Empty(region->Subuniverse(Rc()));
00377 }
00378
00380
00381
00382
00383 void
00384 LRANGE::Region_Interference( LRANGE* lrange1, GRA_REGION* region )
00385 {
00386 LRANGE_SUBUNIVERSE* su = region->Subuniverse(lrange1->Rc());
00387
00388 if ( this != lrange1 ) {
00389 u.c.neighbors = u.c.neighbors->Add_Neighbor(lrange1, su);
00390 lrange1->u.c.neighbors =
00391 lrange1->u.c.neighbors->Add_Neighbor(this, su);
00392 }
00393 }
00394
00396
00397
00398
00399 BOOL
00400 LRANGE::Find_LUNIT_For_GBB( const GRA_BB* gbb, LUNIT** lunitp )
00401 {
00402 LRANGE_LUNIT_ITER iter;
00403
00404 if ( Type() != LRANGE_TYPE_COMPLEMENT )
00405 return FALSE;
00406
00407 for (iter.Init(this); ! iter.Done(); iter.Step())
00408 {
00409 LUNIT* lunit = iter.Current();
00410
00411 if ( lunit->Gbb() == gbb ) {
00412 *lunitp = lunit;
00413 return TRUE;
00414 }
00415 }
00416
00417 return FALSE;
00418 }
00419
00421
00422
00423
00424
00425
00426
00427
00428
00429
00430
00431
00432
00433
00434
00435
00436
00437
00438
00439
00440 void
00441 LRANGE::Remove_Neighbor( LRANGE* neighbor, GRA_REGION* region )
00442 {
00443
00444
00445 if ( Type() != LRANGE_TYPE_LOCAL && neighbor->Type() != LRANGE_TYPE_LOCAL) {
00446 u.c.neighbors = u.c.neighbors->Remove_Neighbor(neighbor,
00447 region->Subuniverse(Rc()));
00448 }
00449 }
00450
00452
00453
00454
00455
00456 BOOL
00457 LRANGE::Interferes( LRANGE* lr1 )
00458 {
00459 DevAssert(Type() != LRANGE_TYPE_REGION && lr1->Type() != LRANGE_TYPE_REGION,
00460 ("LRANGE_Interferes not valid for REGION LRANGEs."));
00461
00462 if ( Type() == LRANGE_TYPE_COMPLEMENT ) {
00463 if ( lr1->Type() == LRANGE_TYPE_COMPLEMENT ) {
00464 #ifdef KEY
00465 if (GRA_optimize_boundary) {
00466
00467 if (!BB_SET_IntersectsP(u.c.live_bb_set, lr1->u.c.live_bb_set))
00468 return FALSE;
00469
00470
00471 if (BB_SET_IntersectsP(u.c.internal_bb_set, lr1->u.c.internal_bb_set))
00472 return TRUE;
00473
00474
00475
00476
00477
00478
00479 BB_SET* this_boundary_bbs = BB_SET_Difference(u.c.live_bb_set,
00480 u.c.internal_bb_set, &MEM_local_nz_pool);
00481 BB_SET* lr1_boundary_bbs = BB_SET_Difference(lr1->u.c.live_bb_set,
00482 lr1->u.c.internal_bb_set, &MEM_local_nz_pool);
00483
00484 BB *current =
00485 BB_SET_Intersection_Choose(this_boundary_bbs, lr1_boundary_bbs);
00486 while (current != BB_SET_CHOOSE_FAILURE) {
00487 LRANGE_BOUNDARY_BB *boundary_bb0 = Get_Boundary_Bb(current);
00488 LRANGE_BOUNDARY_BB *boundary_bb1 = lr1->Get_Boundary_Bb(current);
00489 Is_True(boundary_bb0 != NULL && boundary_bb1 != NULL,
00490 ("Boundary BB not found"));
00491 if (boundary_bb0->Interfere(boundary_bb1))
00492 return TRUE;
00493 current = BB_SET_Intersection_Choose_Next(this_boundary_bbs,
00494 lr1_boundary_bbs, current);
00495 }
00496
00497 return FALSE;
00498 } else
00499 #endif
00500 return BB_SET_IntersectsP(u.c.live_bb_set, lr1->u.c.live_bb_set);
00501 }
00502 else {
00503 return BB_SET_MemberP(u.c.live_bb_set, lr1->u.l.gbb->Bb());
00504 }
00505 }
00506 else if ( lr1->Type() == LRANGE_TYPE_COMPLEMENT ) {
00507 return BB_SET_MemberP(lr1->u.c.live_bb_set, u.l.gbb->Bb());
00508 }
00509 else
00510 return u.l.gbb->Bb() == lr1->u.l.gbb->Bb();
00511 }
00512
00514 void
00515 LRANGE::Calculate_Priority(void)
00517
00518
00519
00520
00521
00522
00523
00524
00525
00526
00527
00528
00529
00530
00531
00533 {
00534 if ( Must_Allocate() )
00535 priority = FLT_MAX;
00536 else if ( Type() == LRANGE_TYPE_LOCAL )
00537 priority = u.l.gbb->Freq() * 2.0F;
00538 else if ( Type() == LRANGE_TYPE_REGION )
00539 priority = 0.0;
00540 else {
00541 LRANGE_LUNIT_ITER iter;
00542 float value = 0;
00543 float sc, rc;
00544
00545 CGSPILL_Cost_Estimate(Tn(),NULL,&sc,&rc,CGSPILL_GRA);
00546
00547 for (iter.Init(this); ! iter.Done(); iter.Step())
00548 {
00549 LUNIT* lunit = iter.Current();
00550 float freq = lunit->Gbb()->Freq();
00551
00552
00553
00554
00555
00556
00557 if ( lunit->Has_Exposed_Use() && ! lunit->Restore_Above() ) {
00558 value += (freq * rc);
00559 GRA_Trace_Split_Add_Priority(lunit->Gbb(), FALSE);
00560 } else if (!lunit->Has_Exposed_Use() && lunit->Restore_Above() ){
00561 value -= (freq * rc);
00562 GRA_Trace_Split_Sub_Priority(lunit->Gbb(), FALSE);
00563 }
00564 if ( lunit->Has_Def() && lunit->Live_Out() &&
00565 !lunit->Spill_Below()) {
00566 value += (freq * sc);
00567 GRA_Trace_Split_Add_Priority(lunit->Gbb(), TRUE);
00568 } else if ( ! lunit->Has_Def() && lunit->Spill_Below() ) {
00569 value -= (freq * sc);
00570 GRA_Trace_Split_Sub_Priority(lunit->Gbb(), TRUE);
00571 }
00572 }
00573 priority = value;
00574 #ifdef KEY
00575
00576 if (GRA_prioritize_by_density) {
00577 UINT32 num_bbs = BB_SET_Size(this->Live_BB_Set());
00578 priority = priority / num_bbs;
00579 }
00580
00581
00582
00583 if ((GRA_exclude_callee_saved_regs ||
00584 GRA_eh_exclude_callee_saved_regs && PU_Has_Exc_Handler ||
00585 GRA_fp_exclude_callee_saved_regs && TN_is_float(Tn()))
00586 && Tn_Is_Save_Reg()) {
00587 priority = FLT_MAX;
00588 }
00589 #endif
00590 }
00591 }
00592
00594 #ifndef KEY
00595 static
00596 #endif
00597 REGISTER_SET
00598 Global_Preferenced_Regs(LRANGE* lrange, GRA_BB* gbb)
00600
00601
00602
00603
00605 {
00606 REGISTER_SET global_prefs = REGISTER_SET_EMPTY_SET;
00607 if (lrange->Global_Pref_Set()) {
00608 for (TN *tn = GTN_SET_Choose(lrange->Global_Pref_Set());
00609 tn != GTN_SET_CHOOSE_FAILURE;
00610 tn = GTN_SET_Choose_Next(lrange->Global_Pref_Set(), tn)) {
00611 LRANGE *plrange = lrange_mgr.Get(tn);
00612 #ifdef KEY
00613 if (GRA_optimize_boundary) {
00614
00615
00616
00617 if (plrange->Contains_BB(gbb) && plrange->Allocated()) {
00618 TN *lrange_tn = lrange->Tn();
00619 REGISTER reg = plrange->Reg();
00620 BOOL used_by_nonpreferenced_tn = FALSE;
00621 for (OP *op = BB_first_op(gbb->Bb());
00622 op != NULL && !used_by_nonpreferenced_tn;
00623 op = OP_next(op)) {
00624
00625 for (int i = OP_opnds(op) - 1; i >= 0; i--) {
00626 TN *opnd_tn = OP_opnd(op, i);
00627 if (opnd_tn != tn && opnd_tn != lrange_tn) {
00628 LRANGE *lr = lrange_mgr.Get(opnd_tn);
00629 if (lr != NULL && lr->Allocated() && lr->Reg() == reg) {
00630 used_by_nonpreferenced_tn = TRUE;
00631 break;
00632 }
00633 }
00634 }
00635
00636 for (int i = OP_results(op) - 1; i >= 0; i--) {
00637 TN *result_tn = OP_result(op, i);
00638 if (result_tn != tn && result_tn != lrange_tn) {
00639 LRANGE *lr = lrange_mgr.Get(result_tn);
00640 if (lr != NULL && lr->Allocated() && lr->Reg() == reg) {
00641 used_by_nonpreferenced_tn = TRUE;
00642 break;
00643 }
00644 }
00645 }
00646 }
00647 if (! used_by_nonpreferenced_tn)
00648 global_prefs = REGISTER_SET_Union1(global_prefs, reg);
00649 }
00650 } else
00651 #endif
00652 if (plrange->Contains_BB(gbb) && plrange->Allocated()) {
00653 global_prefs = REGISTER_SET_Union1(global_prefs, plrange->Reg());
00654 }
00655 }
00656 }
00657 return global_prefs;
00658 }
00659
00661
00662
00663
00664
00665 REGISTER_SET
00666 LRANGE::Allowed_Registers( GRA_REGION* region )
00667 {
00668 LRANGE_LIVE_GBB_ITER gbb_iter;
00669 LRANGE_LUNIT_ITER lunit_iter;
00670 INTERFERE_ITER int_iter;
00671 ISA_REGISTER_CLASS rc = Rc();
00672 REGISTER_SET allowed = REGISTER_CLASS_allocatable(rc);
00673
00674 #ifdef HAS_STACKED_REGISTERS
00675 if (REGISTER_Has_Stacked_Registers(rc)) {
00676 allowed = REGISTER_SET_Difference(allowed, REGISTER_CLASS_stacked(rc));
00677
00678
00679
00680
00681
00682
00683 if (Has_Wired_Register() &&
00684 REGISTER_Is_Stacked(rc, Reg())) {
00685 allowed = REGISTER_SET_Union1(allowed, Reg());
00686 } else if ( Spans_A_Setjmp() ) {
00687 } else if ( Spans_A_Call() ) {
00688 REGISTER_SET stacked =
00689 REGISTER_Get_Stacked_Avail_Set(ABI_PROPERTY_callee, rc);
00690 allowed = REGISTER_SET_Union(allowed, stacked);
00691 } else {
00692 REGISTER_SET stacked =
00693 REGISTER_Get_Stacked_Avail_Set(ABI_PROPERTY_stacked, rc);
00694 allowed = REGISTER_SET_Union(allowed, stacked);
00695 }
00696 }
00697 #endif
00698
00699
00700
00701 if (Spans_Rot_Reg_Clob())
00702 allowed = REGISTER_SET_Difference(allowed,
00703 REGISTER_CLASS_rotating(rc));
00704
00705
00706 if (Spans_A_Setjmp() && ! TN_is_save_reg(Tn()))
00707 allowed = REGISTER_SET_Difference(allowed,
00708 REGISTER_CLASS_callee_saves(rc));
00709
00710 #ifdef KEY
00711
00712 if (PU_Has_Nonlocal_Goto_Target)
00713 allowed = REGISTER_SET_Difference(allowed,
00714 REGISTER_CLASS_callee_saves(rc));
00715 #endif
00716
00717 #ifdef TARG_X8664
00718
00719 if (Spans_Savexmms() && rc == ISA_REGISTER_CLASS_float) {
00720 INT num_xmms = TN_value(OP_opnd(gra_savexmms_op, 1));
00721 for (INT i = 1; i <= num_xmms; i++)
00722 allowed = REGISTER_SET_Difference1(allowed, REGISTER_MIN+(8-i));
00723 }
00724
00725
00726 if (Spans_mmx_OP() && rc == ISA_REGISTER_CLASS_x87)
00727 return REGISTER_SET_EMPTY_SET;
00728
00729
00730 if (Spans_x87_OP() && rc == ISA_REGISTER_CLASS_mmx)
00731 return REGISTER_SET_EMPTY_SET;
00732 #endif
00733
00734 if ( Type() != LRANGE_TYPE_LOCAL && TN_is_save_reg(Tn())
00735 ) {
00736 #ifdef TARG_IA64
00737
00738
00739
00740
00741
00742 if (TN_save_rclass(Tn()) == REGISTER_CLASS_lc) {
00743 allowed = REGISTER_SET_Difference(allowed,
00744 REGISTER_CLASS_callee_saves(rc));
00745 }else {
00746 REGISTER sv_reg = TN_save_reg(Tn());
00747 REGISTER_SET singleton = REGISTER_SET_Union1(REGISTER_SET_EMPTY_SET,sv_reg);
00748 allowed = REGISTER_SET_Intersection(allowed,singleton);
00749 }
00750 #else
00751 REGISTER sv_reg = TN_save_reg(Tn());
00752 REGISTER_SET singleton = REGISTER_SET_Union1(REGISTER_SET_EMPTY_SET,sv_reg);
00753 allowed = REGISTER_SET_Intersection(allowed,singleton);
00754 #endif
00755 }
00756
00757 switch (Type()) {
00758
00759 case LRANGE_TYPE_LOCAL:
00760 return
00761 REGISTER_SET_Difference(allowed, Gbb()->Registers_Used(rc));
00762
00763 case LRANGE_TYPE_COMPLEMENT:
00764 gbb_mgr.Clear_One_Set();
00765
00766
00767
00768
00769
00770
00771
00772
00773
00774
00775
00776
00777 for (lunit_iter.Init(this); ! lunit_iter.Done(); lunit_iter.Step()) {
00778 LUNIT* lunit = lunit_iter.Current();
00779 GRA_BB* gbb = lunit->Gbb();
00780 REGISTER_SET used = gbb->Registers_Used(rc);
00781 #ifdef KEY
00782 if (GRA_optimize_boundary) {
00783
00784
00785 if (! Contains_Internal_BB(gbb)) {
00786 REGISTER reg;
00787 LRANGE_BOUNDARY_BB* boundary_bb = Get_Boundary_Bb(gbb->Bb());
00788 for (reg = REGISTER_SET_Choose(used);
00789 reg != REGISTER_UNDEFINED;
00790 reg = REGISTER_SET_Choose_Next(used, reg)) {
00791 if (! boundary_bb->Interfere(gbb, rc, reg)) {
00792 used = REGISTER_SET_Difference1(used, reg);
00793 }
00794 }
00795 }
00796 }
00797 #endif
00798 REGISTER_SET allowd_prefs = lunit->Allowed_Preferences();
00799
00800 allowd_prefs = REGISTER_SET_Union(allowd_prefs,
00801 Global_Preferenced_Regs(this, gbb));
00802 gbb_mgr.One_Set_Union1(gbb);
00803 allowed =
00804 REGISTER_SET_Difference(allowed,
00805 REGISTER_SET_Difference(used,allowd_prefs));
00806 }
00807
00808 for (gbb_iter.Init(this); ! gbb_iter.Done(); gbb_iter.Step()) {
00809 GRA_BB* gbb = gbb_iter.Current();
00810
00811 if ( ! gbb_mgr.One_Set_MemberP(gbb) ) {
00812 REGISTER_SET prefs = Global_Preferenced_Regs(this, gbb);
00813 REGISTER_SET used = gbb->Registers_Used(rc);
00814 allowed = REGISTER_SET_Difference(allowed,
00815 REGISTER_SET_Difference(used,
00816 prefs));
00817 }
00818 }
00819 if ( Avoid_RA() )
00820 allowed = REGISTER_SET_Difference1(allowed,TN_register(RA_TN));
00821
00822 if ( Spans_A_Call() ) {
00823 return REGISTER_SET_Difference(allowed,
00824 REGISTER_CLASS_caller_saves(rc));
00825 } else {
00826 return allowed;
00827 }
00828 case LRANGE_TYPE_REGION:
00829
00830
00831
00832
00833
00834 for (int_iter.Init(u.r.neighbors, region->Subuniverse(Rc()));
00835 ! int_iter.Done();
00836 int_iter.Step() ) {
00837 LRANGE* nlr = int_iter.Current();
00838
00839 if ( nlr->Allocated() )
00840 allowed = REGISTER_SET_Difference1(allowed, nlr->Reg());
00841 }
00842 if ( Spans_A_Call() ) {
00843 return REGISTER_SET_Difference(allowed,
00844 REGISTER_CLASS_caller_saves(rc));
00845 } else {
00846 return allowed;
00847 }
00848
00849 default:
00850 FmtAssert(FALSE,("Unknown type of LRANGE %d",Type()));
00851 return REGISTER_SET_EMPTY_SET;
00852 }
00853 }
00854
00855 #ifdef KEY
00857 // Return the set of registers that are reclaimable for <lrange>. This means
00858
00859
00860
00861 REGISTER_SET
00862 LRANGE::Reclaimable_Registers( GRA_REGION* region )
00863 {
00864 LRANGE_LIVE_GBB_ITER gbb_iter;
00865 LRANGE_LUNIT_ITER lunit_iter;
00866 INTERFERE_ITER int_iter;
00867 ISA_REGISTER_CLASS rc = Rc();
00868 REGISTER_SET reclaimable = REGISTER_CLASS_allocatable(rc);
00869
00870 #ifdef HAS_STACKED_REGISTERS
00871 FmtAssert(FALSE,("Reclaimable_Registers: stacked register not implemented"));
00872 #endif
00873
00874
00875
00876 if (Spans_Rot_Reg_Clob())
00877 reclaimable = REGISTER_SET_Difference(reclaimable,
00878 REGISTER_CLASS_rotating(rc));
00879
00880
00881 if (Spans_A_Setjmp() && ! TN_is_save_reg(Tn()))
00882 reclaimable = REGISTER_SET_Difference(reclaimable,
00883 REGISTER_CLASS_callee_saves(rc));
00884
00885 #ifdef TARG_X8664
00886
00887 if (Spans_Savexmms() && rc == ISA_REGISTER_CLASS_float) {
00888 INT num_xmms = TN_value(OP_opnd(gra_savexmms_op, 1));
00889 for (INT i = 1; i <= num_xmms; i++)
00890 reclaimable = REGISTER_SET_Difference1(reclaimable, REGISTER_MIN+(8-i));
00891 }
00892 #endif
00893
00894 if ( Type() != LRANGE_TYPE_LOCAL && TN_is_save_reg(Tn())
00895 ) {
00896 REGISTER sv_reg = TN_save_reg(Tn());
00897 REGISTER_SET singleton = REGISTER_SET_Union1(REGISTER_SET_EMPTY_SET,sv_reg);
00898 reclaimable = REGISTER_SET_Intersection(reclaimable, singleton);
00899 }
00900
00901 switch (Type()) {
00902
00903 case LRANGE_TYPE_LOCAL:
00904 FmtAssert(FALSE, ("Reclaimable_Registers: unexpected LRANGE_TYPE_LOCAL"));
00905 return REGISTER_SET_EMPTY_SET;
00906
00907 case LRANGE_TYPE_COMPLEMENT:
00908 for (gbb_iter.Init(this); ! gbb_iter.Done(); gbb_iter.Step()) {
00909 GRA_BB* gbb = gbb_iter.Current();
00910 REGISTER_SET used = gbb->Registers_Used(rc);
00911 REGISTER_SET referenced = gbb->Registers_Referenced(rc);
00912
00913
00914 reclaimable = REGISTER_SET_Intersection(reclaimable, used);
00915 reclaimable = REGISTER_SET_Difference(reclaimable, referenced);
00916 }
00917 if (Avoid_RA())
00918 reclaimable = REGISTER_SET_Difference1(reclaimable, TN_register(RA_TN));
00919
00920 if (Spans_A_Call())
00921 reclaimable = REGISTER_SET_Difference(reclaimable,
00922 REGISTER_CLASS_caller_saves(rc));
00923 return reclaimable;
00924
00925 case LRANGE_TYPE_REGION:
00926 FmtAssert(FALSE,
00927 ("Reclaimable_Registers: LRANGE_TYPE_REGION not implemented"));
00928 return REGISTER_SET_EMPTY_SET;
00929
00930 default:
00931 FmtAssert(FALSE,("Unknown type of LRANGE %d",Type()));
00932 return REGISTER_SET_EMPTY_SET;
00933 }
00934 }
00935 #endif
00936
00938
00939
00940
00941 void
00942 LRANGE::Allocate_Register( REGISTER r, BOOL reclaim )
00943 {
00944 LRANGE_LIVE_GBB_ITER live_gbb_iter;
00945 LRANGE_GLUE_REF_GBB_ITER glue_gbb_iter;
00946
00947 DevAssert(! Allocated(),("Reallocating a LRANGE register"));
00948 reg = r;
00949 flags = (LR_FLAG)(flags | LRANGE_FLAGS_allocated);
00950
00951 if ( Pref() != NULL )
00952 Pref()->Allocate_LRANGE(this);
00953
00954 switch ( Type() ) {
00955 case LRANGE_TYPE_LOCAL:
00956 GRA_GRANT_Local_Register(Gbb(),Rc(),r);
00957 Gbb()->Make_Register_Used((ISA_REGISTER_CLASS) Rc(), r, NULL, reclaim);
00958
00959 #ifdef KEY
00960
00961 if (GRA_reclaim_register) {
00962 Gbb()->Make_Register_Referenced(Rc(), r, this);
00963 }
00964 #endif
00965 break;
00966 case LRANGE_TYPE_REGION:
00967 #ifdef KEY
00968
00969 FmtAssert(!GRA_reclaim_register,
00970 ("Allocate_Register: register reclaiming not yet supported "
00971 "for LRANGE_TYPE_REGION"));
00972 #endif
00973 TN_Allocate_Register(Tn(),r);
00974 Region()->Make_Register_Used(Rc(), r);
00975 for (glue_gbb_iter.Init(this); ! glue_gbb_iter.Done(); glue_gbb_iter.Step())
00976 {
00977 GRA_BB* gbb = glue_gbb_iter.Current();
00978 gbb->Make_Glue_Register_Used(Rc(),r);
00979 }
00980 break;
00981 case LRANGE_TYPE_COMPLEMENT:
00982 TN_Allocate_Register(Tn(),r);
00983 for (live_gbb_iter.Init(this); ! live_gbb_iter.Done(); live_gbb_iter.Step())
00984 {
00985 GRA_BB* gbb = live_gbb_iter.Current();
00986 gbb->Make_Register_Used(Rc(), r, this, reclaim);
00987 }
00988 #ifdef KEY
00989
00990 if (GRA_reclaim_register) {
00991 LRANGE_LUNIT_ITER lunit_iter;
00992 for (lunit_iter.Init(this); !lunit_iter.Done(); lunit_iter.Step()) {
00993 LUNIT *lunit = lunit_iter.Current();
00994 if (Contains_BB(lunit->Gbb()))
00995 lunit->Gbb()->Make_Register_Referenced(Rc(), r, this);
00996 }
00997 }
00998 #endif
00999 }
01000
01001 GRA_Trace_LRANGE_Allocate(this);
01002 }
01003
01005
01006 INT32
01007 LRANGE::Neighbor_Count(void)
01008 {
01009 LRANGE_LIVE_GBB_ITER gbb_iter;
01010 INT32 result;
01011 ISA_REGISTER_CLASS rc = Rc();
01012
01013 switch ( Type() ) {
01014 case LRANGE_TYPE_REGION:
01015 return u.c.neighbors->Count();
01016 case LRANGE_TYPE_LOCAL:
01017 return Gbb()->Local_Lrange_Count(rc) + Gbb()->Global_Live_Lrange_Count(rc)
01018 - 1;
01019 case LRANGE_TYPE_COMPLEMENT:
01020 result = 0;
01021 for (gbb_iter.Init(this); ! gbb_iter.Done(); gbb_iter.Step()) {
01022 GRA_BB* gbb = gbb_iter.Current();
01023 if ( gbb->Region_Is_Complement() )
01024 result += gbb->Local_Lrange_Count(rc);
01025 else {
01026
01027
01028 result -= 300;
01029 }
01030 }
01031
01032 return result + u.c.neighbors->Count();
01033 default:
01034 FmtAssert(FALSE,("_Neighbor_Count of unknown type of LRANGE"));
01035 return UNDEFINED;
01036 }
01037 }
01038
01040
01041 GRA_BB *
01042 LRANGE_LIVE_GBB_ITER::Current(void)
01043 {
01044 return gbb_mgr.Get(current);
01045 }
01046
01047
01049
01050
01051
01052
01053
01054
01055
01056
01057
01058
01059
01060
01062
01064 static void
01065 LRANGE_NEIGHBOR_ITER_Complement_Local_Init( LRANGE_NEIGHBOR_ITER* iter )
01067
01068
01069
01070
01072 {
01073 LRANGE_LIVE_GBB_ITER* gbb_iter = &(iter->live_gbb_iter);
01074 GRA_BB_LOCAL_LRANGE_ITER* local_iter = &(iter->bb_local_iter);
01075
01076 for ( ; ! gbb_iter->Done(); gbb_iter->Step()) {
01077 GRA_BB* gbb = gbb_iter->Current();
01078
01079 if ( gbb->Region() == gra_region_mgr.Complement_Region() ) {
01080 local_iter->Init(gbb,iter->rc);
01081 if ( ! local_iter->Done() ) {
01082 iter->done = FALSE;
01083 iter->current = local_iter->Current();
01084 return;
01085 }
01086 }
01087 }
01088
01089
01090 iter->done = TRUE;
01091 }
01092
01094 static void
01095 LRANGE_NEIGHBOR_ITER_Complement_Local_Step( LRANGE_NEIGHBOR_ITER* iter )
01097
01098
01099
01100
01102 {
01103 GRA_BB_LOCAL_LRANGE_ITER* local_iter = &(iter->bb_local_iter);
01104
01105 local_iter->Step();
01106
01107 if ( ! local_iter->Done()) {
01108
01109 iter->current = local_iter->Current();
01110 }
01111 else {
01112
01113
01114 iter->live_gbb_iter.Step();
01115 LRANGE_NEIGHBOR_ITER_Complement_Local_Init(iter);
01116 }
01117 }
01118
01120 static void
01121 LRANGE_NEIGHBOR_ITER_Complement_Global_Step( LRANGE_NEIGHBOR_ITER* iter )
01123
01124
01125
01126
01128 {
01129 INTERFERE_ITER* neighbor_iter = &(iter->neighbor_iter);
01130
01131 neighbor_iter->Step();
01132
01133 if ( ! neighbor_iter->Done() )
01134 iter->current = neighbor_iter->Current();
01135 else {
01136
01137 iter->step = LRANGE_NEIGHBOR_ITER_Complement_Local_Step;
01138 LRANGE_NEIGHBOR_ITER_Complement_Local_Init(iter);
01139 }
01140 }
01141
01143 static void
01144 LRANGE_NEIGHBOR_ITER_Complement_Init( LRANGE_NEIGHBOR_ITER* iter,
01145 LRANGE* lrange,
01146 GRA_REGION* region )
01148
01149
01150
01151
01153 {
01154 LRANGE_LIVE_GBB_ITER* gbb_iter = &(iter->live_gbb_iter);
01155 INTERFERE c_neighbors = lrange->Neighbors();
01156 LRANGE_SUBUNIVERSE* su = region->Subuniverse(lrange->Rc());
01157
01158 iter->rc = lrange->Rc();
01159
01160 gbb_iter->Init(lrange);
01161
01162 if ( c_neighbors->Count() > 0 ) {
01163
01164
01165 iter->done = FALSE;
01166 iter->neighbor_iter.Init(c_neighbors,su);
01167 iter->current = iter->neighbor_iter.Current();
01168 iter->step = LRANGE_NEIGHBOR_ITER_Complement_Global_Step;
01169 }
01170 else {
01171
01172 iter->step = LRANGE_NEIGHBOR_ITER_Complement_Local_Step;
01173
01174
01175 LRANGE_NEIGHBOR_ITER_Complement_Local_Init(iter);
01176 }
01177 }
01178
01179
01180
01182
01184 static void
01185 LRANGE_NEIGHBOR_ITER_Region_Step( LRANGE_NEIGHBOR_ITER* iter )
01187
01189 {
01190 iter->neighbor_iter.Step();
01191 iter->done = iter->neighbor_iter.Done();
01192 if ( ! iter->done )
01193 iter->current = iter->neighbor_iter.Current();
01194 }
01195
01197 static void
01198 LRANGE_NEIGHBOR_ITER_Region_Init( LRANGE_NEIGHBOR_ITER* iter,
01199 LRANGE* lrange,
01200 GRA_REGION* region )
01202
01204 {
01205 LRANGE_SUBUNIVERSE* su = region->Subuniverse(lrange->Rc());
01206
01207 iter->step = LRANGE_NEIGHBOR_ITER_Region_Step;
01208 iter->neighbor_iter.Init(lrange->Neighbors(), su);
01209
01210 iter->done = iter->neighbor_iter.Done();
01211 if ( ! iter->done )
01212 iter->current = iter->neighbor_iter.Current();
01213 }
01214
01215
01216
01218
01219
01220
01221
01222
01224
01225
01227 static void
01228 LRANGE_NEIGHBOR_ITER_Local_Global_Step( LRANGE_NEIGHBOR_ITER* iter )
01230
01231
01232
01233
01234
01236 {
01237 INTERFERE_ITER* global_iter = &(iter->bb_live_global_iter);
01238
01239 global_iter->Step();
01240 iter->done = global_iter->Done();
01241 if ( ! iter->done )
01242 iter->current = global_iter->Current();
01243 }
01244
01246 inline void
01247 LRANGE_NEIGHBOR_ITER_Local_Global_Init( LRANGE_NEIGHBOR_ITER* iter,
01248 GRA_BB* gbb,
01249 ISA_REGISTER_CLASS rc )
01251
01252
01253
01255 {
01256 INTERFERE_ITER* bb_iter = &(iter->bb_live_global_iter);
01257
01258 bb_iter->Init(gbb->Global_Lranges(rc), gbb->Region()->Subuniverse(rc));
01259 iter->step = LRANGE_NEIGHBOR_ITER_Local_Global_Step;
01260 iter->done = bb_iter->Done();
01261 iter->current = bb_iter->Current();
01262 }
01263
01265 inline void
01266 Local_Skip_Self( LRANGE* self, LRANGE_NEIGHBOR_ITER* iter )
01268
01269
01270
01271
01273 {
01274 GRA_BB_LOCAL_LRANGE_ITER* local_iter = &(iter->bb_local_iter);
01275
01276 if (! local_iter->Done() && local_iter->Current() == self) {
01277 local_iter->Step();
01278 }
01279
01280 iter->done = local_iter->Done();
01281 }
01282
01283
01285 static void
01286 LRANGE_NEIGHBOR_ITER_Local_Local_Step( LRANGE_NEIGHBOR_ITER* iter )
01288
01289
01290
01291
01292
01294 {
01295 GRA_BB_LOCAL_LRANGE_ITER* local_iter = &(iter->bb_local_iter);
01296
01297 local_iter->Step();
01298 Local_Skip_Self(iter->u.l.lrange,iter);
01299
01300 if ( iter->done ) {
01301 LRANGE_NEIGHBOR_ITER_Local_Global_Init(iter,iter->u.l.lrange->Gbb(),
01302 iter->rc);
01303 }
01304 else
01305 iter->current = local_iter->Current();
01306 }
01307
01309
01310 static void
01311 LRANGE_NEIGHBOR_ITER_Local_Init( LRANGE_NEIGHBOR_ITER* iter,
01312 LRANGE* lrange,
01313 GRA_REGION* region )
01315
01316
01317
01319 {
01320 GRA_BB_LOCAL_LRANGE_ITER* local_iter = &(iter->bb_local_iter);
01321 GRA_BB* gbb = lrange->Gbb();
01322
01323 iter->rc = lrange->Rc();
01324 iter->u.l.lrange = lrange;
01325
01326 local_iter->Init(gbb,iter->rc);
01327 Local_Skip_Self(lrange,iter);
01328
01329 if ( local_iter->Done() ) {
01330
01331
01332
01333 LRANGE_NEIGHBOR_ITER_Local_Global_Init(iter,gbb,iter->rc);
01334 }
01335 else {
01336 iter->step = LRANGE_NEIGHBOR_ITER_Local_Local_Step;
01337 iter->done = FALSE;
01338 iter->current = local_iter->Current();
01339 }
01340 }
01341
01342
01344
01345
01346
01347 void
01348 LRANGE_NEIGHBOR_ITER::Init( LRANGE* lrange, GRA_REGION* region )
01349 {
01350 switch ( lrange->Type() ) {
01351 case LRANGE_TYPE_COMPLEMENT:
01352 LRANGE_NEIGHBOR_ITER_Complement_Init(this,lrange,region);
01353 return;
01354 case LRANGE_TYPE_REGION:
01355 LRANGE_NEIGHBOR_ITER_Region_Init(this,lrange,region);
01356 return;
01357 case LRANGE_TYPE_LOCAL:
01358 LRANGE_NEIGHBOR_ITER_Local_Init(this,lrange,region);
01359 return;
01360 default:
01361 FmtAssert(FALSE,("Unknown LRANGE type"));
01362 }
01363 }
01364
01366
01367
01368
01369
01370 void
01371 LRANGE_CLIST::Append( LRANGE_CLIST* clist1 )
01372 {
01373 if ( first == NULL )
01374 *this = *clist1;
01375 else if ( clist1->first == NULL )
01376 *clist1 = *this;
01377 else {
01378 last->clist_next = clist1->first;
01379 last = clist1->last;
01380 clist1->first = first;
01381 }
01382 }
01383
01385
01386
01387
01388
01389
01390
01391
01392
01393
01394 void
01395 LRANGE_CLIST_ITER::Replace_Current( LRANGE* lrange )
01396 {
01397 DevAssert(! Done(), ("Trying to splice into a _Done coloring."));
01398 if ( clist->first == Current() )
01399 clist->first = lrange;
01400 if ( clist->last == Current() )
01401 clist->last = lrange;
01402 lrange->clist_next = Current()->clist_next;
01403 prev->clist_next = lrange;
01404 }
01405
01407
01408
01409
01410
01411
01412 void
01413 LRANGE_CLIST_ITER::Splice( LRANGE* lrange )
01414 {
01415 DevAssert(! Done(), ("Trying to splice into a _Done coloring."));
01416 lrange->clist_next = Current()->clist_next;
01417 Current()->clist_next = lrange;
01418 if ( lrange->clist_next == NULL )
01419 clist->last = lrange;
01420 }
01421
01422 #ifdef KEY
01423
01424
01425 void
01426 LRANGE_CLIST_ITER::Push( LRANGE* lrange )
01427 {
01428 if (Done())
01429 clist->last = lrange;
01430 if (clist->first == Current() )
01431 clist->first = lrange;
01432 lrange->clist_next = Current();
01433 prev->clist_next = lrange;
01434 }
01435 #endif
01436
01438
01439
01440
01441 void
01442 LRANGE::Preference_Copy( LRANGE* lrange1, GRA_BB* gbb )
01443 {
01444 LUNIT* lunit;
01445 GRA_PREF* pref0 = Pref();
01446 GRA_PREF* pref1 = lrange1->Pref();
01447 GRA_PREF* pref_;
01448
01449 GRA_Trace_Preference_Copy(this,lrange1,gbb);
01450
01451 pref_priority += gbb->Freq();
01452 lrange1->pref_priority += gbb->Freq();
01453
01454 if ( Find_LUNIT_For_GBB(gbb,&lunit) )
01455 lunit->Preference_Copy(lrange1);
01456
01457 if ( lrange1->Find_LUNIT_For_GBB(gbb,&lunit) )
01458 lunit->Preference_Copy(this);
01459
01460 if ( pref0 != NULL ) {
01461 if ( pref1 != NULL )
01462 pref_ = gra_pref_mgr.UnionD(pref0,pref1);
01463 else
01464 pref_ = pref0;
01465 }
01466 else if ( pref1 != NULL )
01467 pref_ = pref1;
01468 else
01469 pref_ = gra_pref_mgr.Create();
01470
01471 pref = pref_;
01472 lrange1->pref = pref_;
01473
01474 if ( gbb->Region_Is_Complement() ) {
01475 if ( Type() == LRANGE_TYPE_REGION )
01476 lrange_mgr.Add_GBB_With_Glue_Reference(this,gbb);
01477 if ( lrange1->Type() == LRANGE_TYPE_REGION )
01478 lrange_mgr.Add_GBB_With_Glue_Reference(lrange1,gbb);
01479 }
01480 }
01481
01483
01484
01485 void
01486 LRANGE::Recompute_Preference(void)
01487 {
01488 LRANGE_LUNIT_ITER iter;
01489 float priority = 0.0;
01490
01491 for (iter.Init(this); ! iter.Done(); iter.Step()) {
01492 priority += iter.Current()->Pref_Priority();
01493 }
01494
01495 pref_priority = priority;
01496
01497 if ( priority == 0.0 )
01498 pref = NULL;
01499 }
01500
01501
01503
01504
01505 char *
01506 LRANGE::Format( char* buff )
01507 {
01508 INT count;
01509
01510 switch ( Type() ) {
01511 case LRANGE_TYPE_LOCAL:
01512 count = sprintf(buff,"[LRANGE L rc %d BB:%d", Rc(), BB_id(Gbb()->Bb()));
01513 break;
01514 case LRANGE_TYPE_REGION:
01515 count = sprintf(buff,"[LRANGE R rc %d TN%d", Rc(), TN_number(Tn()));
01516 break;
01517 case LRANGE_TYPE_COMPLEMENT:
01518 count = sprintf(buff,"[LRANGE C rc %d TN%d", Rc(), TN_number(Tn()));
01519 break;
01520 default:
01521 DevWarn("Invalid LRANGE_TYPE");
01522 return NULL;
01523 }
01524
01525
01526 if ( Allocated() ) {
01527 count += sprintf(buff+count," alloc %s",
01528 REGISTER_name(Rc(), Reg()));
01529 }
01530
01531 if ( Has_Wired_Register() ) {
01532 count += sprintf(buff+count," wired");
01533 if ( ! Allocated() ) {
01534 count += sprintf(buff+count, " %s", REGISTER_name(Rc(),Reg()));
01535 }
01536 }
01537
01538 if ( Tn_Is_Save_Reg() )
01539 count += sprintf(buff+count," save");
01540
01541 sprintf(buff+count,"]");
01542 return buff;
01543 }
01544
01545 #ifdef KEY
01547 // Add an already-built boundary BB to the boundary BBs list.
01548 void
01549 LRANGE::Boundary_BBs_Push( LRANGE_BOUNDARY_BB *boundary_bb)
01550 {
01551 boundary_bb->Next_Set(Boundary_BBs());
01552 Set_Boundary_BBs(boundary_bb);
01553
01554 boundary_bb->Lrange_Set(this);
01555 }
01556
01558
01559 void
01560 LRANGE::Add_Boundary_BB( GRA_BB* gbb)
01561 {
01562 LRANGE_BOUNDARY_BB *new_boundary_bb =
01563 (LRANGE_BOUNDARY_BB*) MEM_POOL_Alloc(GRA_pool, sizeof(LRANGE_BOUNDARY_BB));
01564
01565 new_boundary_bb->Init(gbb, this);
01566 new_boundary_bb->Next_Set(Boundary_BBs());
01567 Set_Boundary_BBs(new_boundary_bb);
01568 }
01569
01571
01572 void
01573 LRANGE::Update_Boundary_BBs(void)
01574 {
01575 LRANGE_BOUNDARY_BB* p;
01576
01577 for (p = Boundary_BBs(); p != NULL; p = p->Next()) {
01578 BOOL need_update = FALSE;
01579 BOOL new_live_in = p->Is_Live_In();
01580 BOOL new_live_out = p->Is_Live_Out();
01581
01582
01583
01584 if (new_live_in && !new_live_out) {
01585
01586 if (!(p->Start_Index() == 0 && p->End_Index() > 0))
01587 need_update = TRUE;
01588 } else if (!new_live_in && new_live_out) {
01589
01590 if (!(p->Start_Index() > 0 && p->End_Index() == 0))
01591 need_update = TRUE;
01592 } else if (!new_live_in && !new_live_out) {
01593 if (p->Start_Index() > 0 || p->End_Index() > 0) {
01594
01595 if (p->Start_Index() == 0 || p->End_Index() == 0)
01596 need_update = TRUE;
01597 } else {
01598
01599 }
01600 } else {
01601
01602 if (p->Start_Index() > 0 || p->End_Index() > 0) {
01603
01604 if (p->Start_Index() == 0 || p->End_Index() == 0)
01605 need_update = TRUE;
01606 } else {
01607
01608 }
01609 }
01610
01611
01612 if (need_update) {
01613 p->Init(p->Gbb(), this);
01614 }
01615 }
01616 }
01617
01619
01620 LRANGE_BOUNDARY_BB*
01621 LRANGE::Get_Boundary_Bb( BB *target_bb )
01622 {
01623 LRANGE_BOUNDARY_BB* p;
01624 for (p = Boundary_BBs(); p != NULL; p = p->Next()) {
01625 if (p->Gbb()->Bb() == target_bb) {
01626 Is_True(p->Lrange() == this, ("Boundary BB has wrong LRANGE"));
01627 return p;
01628 }
01629 }
01630 return NULL;
01631 }
01632
01634
01635 LRANGE_BOUNDARY_BB*
01636 LRANGE::Remove_Boundary_Bb( BB *target_bb )
01637 {
01638 LRANGE_BOUNDARY_BB *p, *prev;
01639
01640 p = Boundary_BBs();
01641 if (p == NULL)
01642 return NULL;
01643
01644
01645 if (p->Gbb()->Bb() == target_bb) {
01646 Set_Boundary_BBs(p->Next());
01647 return p;
01648 }
01649
01650
01651 prev = p;
01652 p = p->Next();
01653 for ( ; p != NULL; prev = p, p = p->Next()) {
01654 if (p->Gbb()->Bb() == target_bb) {
01655 prev->Next_Set(p->Next());
01656 return p;
01657 }
01658 }
01659 return NULL;
01660 }
01661
01663
01664 BOOL
01665 LRANGE_BOUNDARY_BB::Is_Live_In(void)
01666 {
01667 return gbb->Is_Live_In_LRANGE(lrange);
01668 }
01669
01671
01672 BOOL
01673 LRANGE_BOUNDARY_BB::Is_Live_Out(void)
01674 {
01675 return gbb->Is_Live_Out_LRANGE(lrange);
01676 }
01677
01679
01680
01681
01682
01683 BOOL
01684 LRANGE_BOUNDARY_BB::Interfere (BOOL other_live_in, BOOL other_live_out,
01685 mUINT16 other_start, mUINT16 other_end)
01686 {
01687
01688 #define IN_BETWEEN(x, a, b) (((a) <= (x)) && ((x) <= (b)))
01689
01690 const mUINT16 max_index = 0xffff;
01691 mUINT16 this_start, this_end, other_start1, other_end1;
01692 BOOL other_is_disjoint = FALSE;
01693
01694
01695 if (!other_live_in && !other_live_out && other_start == 0) {
01696 Is_True(other_end == 0, ("Bad OP end index in empty live range"));
01697 return FALSE;
01698 }
01699
01700 BOOL this_live_in = Is_Live_In();
01701 BOOL this_live_out = Is_Live_Out();
01702
01703
01704
01705 if (this_live_in && this_live_out) {
01706 return TRUE;
01707 }
01708
01709
01710
01711
01712
01713
01714
01715 if ((start_index == 0 && end_index == 0) &&
01716 ((!this_live_in && !this_live_out) ||
01717 (this_live_in && !this_live_out) ||
01718 (!this_live_in && this_live_out))) {
01719
01720 return TRUE;
01721 }
01722
01723
01724 if (other_live_in && other_live_out) {
01725 if (other_start == 0) {
01726
01727 Is_True(other_end == 0, ("pass-thru live range cannot have last-use"));
01728 return TRUE;
01729 } else if (other_start == other_end) {
01730
01731
01732 return TRUE;
01733 } else {
01734 Is_True(other_start > other_end, ("disjoint live range corrupted"));
01735
01736 other_is_disjoint = TRUE;
01737 other_start1 = other_start;
01738 other_end1 = max_index;
01739 other_start = 0;
01740 }
01741 }
01742
01743
01744
01745 this_start = start_index;
01746 this_end = this_live_out ? max_index : end_index;
01747
01748
01749
01750 if (!other_is_disjoint && other_live_out) {
01751 other_end = max_index;
01752 }
01753
01754
01755 if (IN_BETWEEN(this_start, other_start, other_end) ||
01756 IN_BETWEEN(this_end, other_start, other_end) ||
01757 IN_BETWEEN(other_start, this_start, this_end))
01758 return TRUE;
01759
01760
01761 if (other_is_disjoint) {
01762 if (IN_BETWEEN(this_start, other_start1, other_end1) ||
01763 IN_BETWEEN(this_end, other_start1, other_end1) ||
01764 IN_BETWEEN(other_start1, this_start, this_end))
01765 return TRUE;
01766 }
01767
01768
01769 return FALSE;
01770 }
01771
01773
01774 BOOL
01775 LRANGE_BOUNDARY_BB::Interfere (LRANGE_BOUNDARY_BB *bb1)
01776 {
01777 LRANGE_BOUNDARY_BB *live_in, *live_out;
01778
01779 Is_True(lrange->Type() == LRANGE_TYPE_COMPLEMENT,
01780 ("Not a complement LRANGE"));
01781 Is_True(bb1->Lrange()->Type() == LRANGE_TYPE_COMPLEMENT,
01782 ("Not a complement LRANGE"));
01783 Is_True(gbb == bb1->Gbb(),
01784 ("Cannot check boundary interference between two different boundary BBs"));
01785
01786 BOOL bb1_live_in = (bb1->start_index == 0 && bb1->end_index > 0);
01787 BOOL bb1_live_out = (bb1->start_index > 0 && bb1->end_index == 0);
01788
01789 return Interfere(bb1_live_in, bb1_live_out, bb1->start_index, bb1->end_index);
01790 }
01791
01793
01794 BOOL
01795 LRANGE_BOUNDARY_BB::Interfere (GRA_BB *gbb, ISA_REGISTER_CLASS rc, REGISTER reg)
01796 {
01797 Is_True(lrange->Type() == LRANGE_TYPE_COMPLEMENT,
01798 ("Not a complement LRANGE"));
01799 return Interfere(gbb->Is_Usage_Live_In(rc, reg),
01800 gbb->Is_Usage_Live_Out(rc, reg),
01801 gbb->Usage_Start_Index(rc, reg),
01802 gbb->Usage_End_Index(rc, reg));
01803 }
01804
01806
01807 void
01808 LRANGE_BOUNDARY_BB::Init (GRA_BB *the_gbb, LRANGE *the_lrange)
01809 {
01810 OP *op;
01811 mUINT16 op_index, first_ref_index, last_ref_index, *index_ptr;
01812 BOOL live_in, live_out;
01813 int i, pass;
01814
01815
01816 BOOL find_first_ref = FALSE;
01817 BOOL find_last_ref = FALSE;
01818
01819 gbb = the_gbb;
01820 lrange = the_lrange;
01821 TN *tn = lrange->Tn();
01822 BB *bb = gbb->Bb();
01823 LUNIT* lunit = gbb_mgr.Split_LUNIT(gbb);
01824
01825 Is_True(! lrange->Contains_Internal_BB(gbb), ("BB is not a boundary BB"));
01826
01827 live_in = Is_Live_In();
01828 live_out = Is_Live_Out();
01829
01830
01831
01832 if (live_in && live_out) {
01833
01834
01835 start_index = 0;
01836 end_index = 0;
01837 return;
01838 } else if (live_in) {
01839 find_last_ref = TRUE;
01840 } else if (live_out) {
01841 find_first_ref = TRUE;
01842 } else {
01843
01844 find_first_ref = TRUE;
01845 find_last_ref = TRUE;
01846 }
01847
01848
01849
01850 first_ref_index = last_ref_index = 0;
01851 for (pass = 0; pass < 2; pass++) {
01852 if (pass == 0) {
01853 if (!find_first_ref)
01854 continue;
01855 op_index = 0;
01856 op = BB_first_op(bb);
01857 index_ptr = &first_ref_index;
01858 } else {
01859 if (!find_last_ref)
01860 break;
01861 op_index = gbb->OPs_Count() + 1;
01862 op = BB_last_op(bb);
01863 index_ptr = &last_ref_index;
01864 }
01865
01866 while (op != NULL) {
01867
01868 op_index = (pass == 0) ? op_index+1 : op_index-1;
01869
01870
01871 for (i = OP_opnds(op) - 1; i >= 0; i--) {
01872 TN *opnd_tn = OP_opnd(op, i);
01873 if (opnd_tn == tn) {
01874 *index_ptr = op_index;
01875 break;
01876 }
01877 }
01878 if (*index_ptr)
01879 break;
01880
01881
01882 for (i = OP_results(op) - 1; i >= 0; i--) {
01883 TN *result_tn = OP_result(op, i);
01884 if (result_tn == tn) {
01885 *index_ptr = op_index;
01886 break;
01887 }
01888 }
01889 if (*index_ptr)
01890 break;
01891
01892
01893 op = (pass == 0) ? OP_next(op) : OP_prev(op);
01894 }
01895
01896
01897 if (*index_ptr == 0)
01898 break;
01899 }
01900
01901
01902 Is_True(! (live_in && live_out),
01903 ("Live-in and live-out boundary BB currently not handled"));
01904
01905 if (live_in) {
01906 Is_True(last_ref_index > 0 || (lunit && lunit->Spill_Below()),
01907 ("Bad OP index in live-in BB"));
01908 start_index = 0;
01909
01910
01911 end_index = last_ref_index;
01912 } else if (live_out) {
01913 Is_True(first_ref_index > 0 || (lunit && lunit->Restore_Above()),
01914 ("Bad OP index in live-out BB"));
01915
01916
01917 start_index = first_ref_index;
01918 end_index = 0;
01919 } else {
01920
01921
01922
01923 Is_True((first_ref_index > 0 && last_ref_index > 0) ||
01924 (first_ref_index == 0 && last_ref_index == 0),
01925 ("Bad OP index for contained or empty live range."));
01926 start_index = first_ref_index;
01927 end_index = last_ref_index;
01928 }
01929 }
01930 #endif