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
00041
00042
00043
00044
00045
00047
00048
00049
00050
00051
00052
00053
00054 #ifdef USE_PCH
00055 #include "cg_pch.h"
00056 #endif // USE_PCH
00057 #pragma hdrstop
00058
00059 #ifdef _KEEP_RCS_ID
00060 static char *rcs_id = "$Source: /scratch/mee/2.4-65/kpro64-pending/be/cg/gra_mon/SCCS/s.gra_color.cxx $ $Revision: 1.18 $";
00061 #endif
00062
00063 #include <limits.h>
00064 #include <float.h>
00065 #include "defs.h"
00066 #include "errors.h"
00067 #include "tracing.h"
00068 #include "mempool.h"
00069 #include "register.h"
00070 #include "priority_queue.h"
00071 #include "cg_flags.h"
00072 #include "gra_bb.h"
00073 #include "gra.h"
00074 #include "gra_region.h"
00075 #include "gra_trace.h"
00076 #include "gra_lrange.h"
00077 #include "gra_split.h"
00078 #include "gra_grant.h"
00079 #include "gra_spill.h"
00080 #include "gra_interfere.h"
00081 #ifdef TARG_IA64
00082 #include "op.h"
00083 #include "calls.h"
00084 #include "ipfec_options.h"
00085 #elif defined(TARG_SL) //minor_reg_alloc
00086 #include "gra_para_region.h"
00087 #endif
00088 #ifdef TARG_X8664
00089 #include "targ_sim.h"
00090 #include "whirl2ops.h"
00091 #endif
00092
00093 #ifdef KEY
00094 BOOL GRA_reclaim_register = FALSE;
00095 BOOL GRA_reclaim_register_set = FALSE;
00096 #endif
00097
00098 INT32 GRA_local_forced_max = DEFAULT_FORCED_LOCAL_MAX;
00099
00100
00101 #ifdef TARG_X8664
00102 BOOL GRA_grant_special_regs = FALSE;
00103 BOOL GRA_local_forced_max_set = FALSE;
00104 #endif
00105
00106 BOOL GRA_avoid_glue_references_for_locals = TRUE;
00107
00108
00109
00110 static REGISTER_SET non_prefrenced_regs[ISA_REGISTER_CLASS_MAX + 1];
00111
00112
00113 static REGISTER_SET callee_saves_used[ISA_REGISTER_CLASS_MAX + 1];
00114
00115
00116 static REGISTER_SET regs_used[ISA_REGISTER_CLASS_MAX + 1];
00117
00118 static MEM_POOL prq_pool;
00119
00120 static GRA_REGION *GRA_current_region;
00121
00122
00123 #ifdef TARG_IA64
00124 static BB_SET* pred_bb_set;
00125 extern char *Cur_PU_Name;
00126 extern BOOL fat_self_recursive;
00127 extern BOOL gra_self_recursive;
00128 extern INT32 rse_budget;
00129 INT32 first_callee_next;
00130 INT32 first_caller_next;
00131 BOOL high_freq;
00132 struct reg_feedback {
00133 char _func_name[120];
00134 INT32 _stacked_callee_used;
00135 INT32 _stacked_caller_used;
00136 float _cost[96];
00137 reg_feedback() : _stacked_callee_used(0),
00138 _stacked_caller_used(0)
00139 {
00140 for (INT32 i = 0; i < 96; i++) {
00141 _cost[i] = 0;
00142 }
00143 }
00144 };
00145
00146 struct reg_feedback reg_fb;
00147 static BOOL have_open_output_file = FALSE;
00148 static FILE *fout;
00149 static BOOL have_open_input_file = FALSE;
00150 static FILE *fin;
00151
00152
00153 BOOL can_use_stacked_reg;
00154
00155
00156 INT abi_property;
00157 ISA_REGISTER_CLASS reg_class;
00158 INT lunits_number;
00159 float density;
00160 BOOL need_buffer;
00161 INT32 current_lrange;
00162
00163 #endif
00164
00165
00166
00167
00168 class LRANGE_PREF_ITER: public GRA_PREF_LRANGE_ITER {
00169 public:
00170 LRANGE_PREF_ITER(void) {}
00171 ~LRANGE_PREF_ITER(void) {}
00172
00173 void Init(LRANGE *lrange) { GRA_PREF_LRANGE_ITER::Init(lrange->Pref()); }
00174 };
00175
00176
00177
00179
00180
00181
00182
00183
00184
00185
00186
00187
00188
00189
00190
00191
00192
00193
00194
00195
00197
00198 #ifdef TARG_IA64
00199 static void
00200 Update_Reg_Cost(LRANGE *lr,INT32 reg)
00201 {
00202 INT32 k = reg - 32;
00203 if (lr->Rc() == ISA_REGISTER_CLASS_integer) {
00204 if ((reg > first_callee_next)
00205 && (reg <= first_caller_next)) {
00206 lr->Calculate_Priority();
00207 reg_fb._cost[k] = reg_fb._cost[k] + lr->Priority();
00208 }
00209 }
00210 }
00211 #endif
00212
00214 static void
00215 Initialize(void)
00217
00218
00219
00221 {
00222 ISA_REGISTER_CLASS rc;
00223 static BOOL prq_initialized = FALSE;
00224
00225 if ( ! prq_initialized ) {
00226 prq_initialized = TRUE;
00227 MEM_POOL_Initialize(&prq_pool,"GRA LRANGE priority queue",FALSE);
00228 }
00229
00230 #ifdef TARG_SL //minor_reg_alloc
00231 gra_para_region_mgr.Build_Map_For_Pair_Region();
00232 gra_para_region_mgr.Pre_Reserve_Registers_For_Minor();
00233 #endif
00234
00235 FOR_ALL_ISA_REGISTER_CLASS( rc ) {
00236 non_prefrenced_regs[rc] = REGISTER_CLASS_allocatable(rc);
00237
00238 callee_saves_used[rc] = REGISTER_SET_EMPTY_SET;
00239
00240 regs_used[rc] = REGISTER_SET_EMPTY_SET;
00241 }
00242 #ifdef TARG_IA64
00243 pred_bb_set = BB_SET_Create_Empty(PU_BB_Count+2, GRA_pool);
00244 #endif
00245 }
00246
00247 #ifdef TARG_SL //minor_reg_alloc
00248 void
00249 Get_Rid_For_Lrange(LRANGE* lrange, vector <RID*> * rid_vec )
00250 {
00251
00252 LRANGE_LIVE_GBB_ITER live_gbb_iter;
00253 BB* bb;
00254 if(lrange->Type()== LRANGE_TYPE_REGION) {
00255 return;
00256 }
00257 if(lrange->Type() ==LRANGE_TYPE_LOCAL) {
00258 bb = lrange->Gbb()->Bb();
00259 RID* rid = BB_rid(bb);
00260 if(rid ) {
00261 if(RID_TYPE_major(rid))
00262 return;
00263 else {
00264 rid_vec->push_back(rid);
00265 return;
00266 }
00267 }
00268 }
00269 else {
00270 Is_True((lrange->Type()==LRANGE_TYPE_COMPLEMENT), ("unknown region type"));
00271 LRANGE_LUNIT_ITER lunit_iter;
00272 for (lunit_iter.Init(lrange); ! lunit_iter.Done(); lunit_iter.Step())
00273 {
00274 LUNIT* lunit = lunit_iter.Current();
00275 GRA_BB* gbb = lunit->Gbb();
00276 bb = gbb->Bb();
00277 if(BB_rid(bb) && (find(rid_vec->begin(), rid_vec->end(), BB_rid(bb)) == rid_vec->end())) {
00278 rid_vec->push_back(BB_rid(bb));
00279 }
00280 }
00281 }
00282 return;
00283 }
00284 #endif
00285
00287 static void
00288 Update_Register_Info( LRANGE* lrange, REGISTER reg, BOOL reclaim = FALSE )
00290
00291
00292
00293
00295 {
00296 ISA_REGISTER_CLASS rc = lrange->Rc();
00297
00298 lrange->Allocate_Register(reg, reclaim);
00299 #ifdef TARG_IA64
00300 Update_Reg_Cost(lrange,reg);
00301 #endif
00302
00303 if ( lrange->Has_Preference() ) {
00304 non_prefrenced_regs[rc] =
00305 REGISTER_SET_Difference1(non_prefrenced_regs[rc],reg);
00306 }
00307
00308 if (!lrange->Has_Wired_Register() && !lrange->Tn_Is_Save_Reg()) {
00309 regs_used[rc] = REGISTER_SET_Union1(regs_used[rc], reg);
00310 if ((REGISTER_SET_MemberP(REGISTER_CLASS_callee_saves(rc),reg)
00311 #ifdef HAS_STACKED_REGISTERS
00312 || REGISTER_Is_Stacked_Local(rc, reg)
00313 #endif
00314 )) {
00315 #ifdef TARG_IA64
00316 if(GRA_optimize_restore_pr && Is_Predicate_REGISTER_CLASS(rc)) {
00317 if(lrange->Type() == LRANGE_TYPE_LOCAL)
00318 pred_bb_set = BB_SET_Union1(pred_bb_set, lrange->Gbb()->Bb(), GRA_pool);
00319 else if(lrange->Type() == LRANGE_TYPE_COMPLEMENT)
00320 pred_bb_set = BB_SET_Union(pred_bb_set, lrange->Live_BB_Set(), GRA_pool);
00321 else {
00322 GRA_REGION* gra_region = lrange->Region();
00323 GRA_BB* g_bb = gra_region->First_Gbb();
00324 for(BB* live_bb = g_bb->Bb();g_bb != gra_region->Last_Gbb(); g_bb = g_bb->Region_Next())
00325 {
00326 pred_bb_set = BB_SET_Union1(pred_bb_set, live_bb, GRA_pool);
00327 live_bb = g_bb->Bb();
00328 }
00329 pred_bb_set = BB_SET_Union1(pred_bb_set, g_bb->Bb(), GRA_pool);
00330 }
00331 }
00332 #endif
00333 callee_saves_used[rc] = REGISTER_SET_Union1(callee_saves_used[rc],reg);
00334 }
00335 }
00336
00337 #ifdef TARG_SL //minor_reg_alloc
00338
00339 vector< RID* > rid_vec;
00340 vector<RID* >::iterator iter;
00341 Get_Rid_For_Lrange(lrange, &rid_vec);
00342 for(iter = rid_vec.begin(); iter != rid_vec.end(); iter++) {
00343 RID* rid = *iter;
00344 if(rid && RID_TYPE_minor(rid)) {
00345 RID * pair_rid = gra_para_region_mgr.Get_Pair_Rid(rid);
00346 Is_True((pair_rid), ("pair_rid is NULL"));
00347 GRA_PARA_REGION* pair_region = gra_para_region_mgr.Get(pair_rid);
00348 pair_region->Add_One_Exclude_Register(rc, reg);
00349 }
00350 }
00351
00352 #endif
00353
00354 }
00355
00357 static BOOL
00358 Choose_Best_Register(REGISTER* reg, ISA_REGISTER_CLASS rc,
00359 REGISTER_SET allowed , BOOL remove_global_callees,
00360 BOOL prefer_caller_stacked)
00362
00363
00364
00365
00366
00368 {
00369 if ( REGISTER_SET_EmptyP(allowed) )
00370 return FALSE;
00371
00372 #ifdef HAS_STACKED_REGISTERS
00373 if (! REGISTER_Has_Stacked_Registers(rc)) {
00374 #endif
00375 *reg = REGISTER_SET_Choose_Intersection(allowed,
00376 REGISTER_CLASS_caller_saves(rc));
00377 if ( *reg != REGISTER_UNDEFINED )
00378 return TRUE;
00379
00380 *reg = REGISTER_SET_Choose_Intersection(allowed,callee_saves_used[rc]);
00381 if ( *reg != REGISTER_UNDEFINED )
00382 return TRUE;
00383
00384 *reg = REGISTER_SET_Choose(allowed);
00385 if ( *reg != REGISTER_UNDEFINED )
00386 return TRUE;
00387
00388 return FALSE;
00389 #ifdef HAS_STACKED_REGISTERS
00390 }
00391 else {
00392
00393 REGISTER_SET callers =
00394 REGISTER_SET_Union(REGISTER_CLASS_caller_saves(rc),
00395 REGISTER_Get_Stacked_Avail_Set(ABI_PROPERTY_caller,
00396 rc));
00397 *reg = REGISTER_SET_Choose_Intersection(allowed, callers);
00398 if ( *reg != REGISTER_UNDEFINED )
00399 return TRUE;
00400
00401
00402
00403 if (prefer_caller_stacked) {
00404 *reg = REGISTER_Request_Stacked_Register(ABI_PROPERTY_caller, rc);
00405 if ( *reg != REGISTER_UNDEFINED )
00406 return TRUE;
00407 }
00408
00409
00410 *reg = REGISTER_SET_Choose_Intersection(allowed,callee_saves_used[rc]);
00411 if ( *reg != REGISTER_UNDEFINED )
00412 return TRUE;
00413
00414 if (remove_global_callees) {
00415 allowed = REGISTER_SET_Difference(allowed,REGISTER_CLASS_callee_saves(rc));
00416 }
00417
00418 *reg = REGISTER_SET_Choose(allowed);
00419 if ( *reg != REGISTER_UNDEFINED )
00420 return TRUE;
00421
00422
00423 *reg = REGISTER_Request_Stacked_Register(ABI_PROPERTY_callee, rc);
00424 if ( *reg != REGISTER_UNDEFINED )
00425 return TRUE;
00426
00427 return FALSE;
00428 }
00429 #endif
00430 }
00431
00433 static BOOL
00434 Choose_Preference( LRANGE* lrange, REGISTER_SET allowed, GRA_REGION* region
00435 #ifdef KEY
00436 , BOOL reclaim = FALSE
00437 #endif
00438 )
00440
00441
00442
00443
00445 {
00446 LRANGE_PREF_ITER iter;
00447
00448 for (iter.Init(lrange); ! iter.Done(); iter.Step()) {
00449 LRANGE* p_lrange = iter.Current();
00450
00451 if ( REGISTER_SET_MemberP(allowed,p_lrange->Reg()) ) {
00452 #ifdef KEY
00453 if (reclaim) {
00454 LRANGE_Split_Reclaimed_BBs(lrange, p_lrange->Reg());
00455 }
00456 Update_Register_Info(lrange, p_lrange->Reg(), reclaim);
00457 #else
00458 Update_Register_Info(lrange, p_lrange->Reg());
00459 #endif
00460 GRA_Trace_Preference_Attempt(lrange, p_lrange, region, TRUE);
00461 return TRUE;
00462 }
00463 GRA_Trace_Preference_Attempt(lrange, p_lrange, region, FALSE);
00464 }
00465
00466 return FALSE;
00467 }
00468
00470 static BOOL
00471 Choose_Avoiding_Neighbor_Preferences( LRANGE* lrange, REGISTER_SET allowed
00472 #ifdef KEY
00473 , BOOL reclaim = FALSE
00474 #endif
00475 )
00477
00478
00479
00480
00481
00482
00483
00485 {
00486 ISA_REGISTER_CLASS rc = lrange->Rc();
00487 REGISTER reg;
00488 LRANGE_PREF_ITER p_iter;
00489 LRANGE_NEIGHBOR_ITER n_iter;
00490
00491 for (n_iter.Init(lrange, GRA_current_region); ! n_iter.Done(); n_iter.Step()){
00492 LRANGE* nlr = n_iter.Current();
00493
00494 if ( nlr->Allocated() )
00495 continue;
00496
00497
00498
00499 if (nlr->Type() == LRANGE_TYPE_COMPLEMENT && TN_is_save_reg(nlr->Tn())
00500 ) {
00501 continue;
00502 }
00503
00504 for (p_iter.Init(nlr); ! p_iter.Done(); p_iter.Step()) {
00505 LRANGE* plr = p_iter.Current();
00506 REGISTER_SET new_allowed;
00507
00508 if ( plr->Allocated() && plr->Rc() == lrange->Rc() )
00509 new_allowed = REGISTER_SET_Difference1(allowed, plr->Reg());
00510 if ( !REGISTER_SET_EmptyP(new_allowed) ) {
00511 allowed = new_allowed;
00512 }
00513
00514 }
00515 }
00516
00517 if (Choose_Best_Register(®, rc, allowed,
00518 REGISTER_Has_Stacked_Registers(rc),
00519 !(lrange->Spans_A_Call() || lrange->Spans_Infreq_Call()))) {
00520 #ifdef KEY
00521 if (reclaim) {
00522 LRANGE_Split_Reclaimed_BBs(lrange, reg);
00523 }
00524 Update_Register_Info(lrange, reg, reclaim);
00525 #else
00526 Update_Register_Info(lrange,reg);
00527 #endif
00528 return TRUE;
00529 }
00530
00531 return FALSE;
00532 }
00533
00535 static BOOL
00536 Allocate_Stacked_Register(LRANGE* lrange)
00538
00539
00540
00541
00543 {
00544 #ifdef HAS_STACKED_REGISTERS
00545 if (!GRA_use_stacked_regs ||
00546 !REGISTER_Has_Stacked_Registers(lrange->Rc())) {
00547 return FALSE;
00548 }
00549 if (lrange->Spans_A_Setjmp())
00550 return FALSE;
00551
00552 INT abi_property;
00553 if (lrange->Spans_A_Call()) {
00554 abi_property = ABI_PROPERTY_callee;
00555 } else {
00556 abi_property = ABI_PROPERTY_caller;
00557 }
00558 REGISTER reg = REGISTER_Request_Stacked_Register(abi_property,
00559 lrange->Rc());
00560 if (reg != REGISTER_UNDEFINED) {
00561 Update_Register_Info(lrange, reg);
00562 return TRUE;
00563 }
00564
00565 #ifdef TARG_IA64
00566 if (abi_property == ABI_PROPERTY_caller)
00567 reg = REGISTER_Request_Stacked_Register(ABI_PROPERTY_callee,
00568 lrange->Rc());
00569
00570 if (reg != REGISTER_UNDEFINED) {
00571 Update_Register_Info(lrange, reg);
00572 return TRUE;
00573 }
00574 #endif // TARG_IA64
00575 #endif
00576 return FALSE;
00577 }
00578
00580 static BOOL
00581 Choose_Noones_Preference( LRANGE* lrange, REGISTER_SET allowed
00582 #ifdef KEY
00583 , BOOL reclaim = FALSE
00584 #endif
00585 )
00587
00588
00589
00590
00592 {
00593 ISA_REGISTER_CLASS rc = lrange->Rc();
00594 REGISTER reg;
00595 REGISTER_SET npr = non_prefrenced_regs[lrange->Rc()];
00596
00597 allowed = REGISTER_SET_Intersection(allowed,npr);
00598 if ( Choose_Best_Register(®,rc,allowed,
00599 REGISTER_Has_Stacked_Registers(rc),
00600 (lrange->Spans_A_Call() || lrange->Spans_Infreq_Call())) ) {
00601 #ifdef KEY
00602 if (reclaim) {
00603 LRANGE_Split_Reclaimed_BBs(lrange, reg);
00604 }
00605 Update_Register_Info(lrange, reg, reclaim);
00606 #else
00607 Update_Register_Info(lrange,reg);
00608 #endif
00609 return TRUE;
00610 }
00611 return FALSE;
00612 }
00613
00615 static BOOL
00616 Choose_Anything( LRANGE* lrange, REGISTER_SET allowed
00617 #ifdef KEY
00618 , BOOL reclaim = FALSE
00619 )
00620 #endif
00622 //
00623
00624
00625
00627 {
00628 REGISTER reg;
00629 ISA_REGISTER_CLASS rc = lrange->Rc();
00630 BOOL has_stacked = REGISTER_Has_Stacked_Registers(rc);
00631
00632 if ( Choose_Best_Register(®,rc,allowed, has_stacked,
00633 !(lrange->Spans_A_Call() || lrange->Spans_Infreq_Call())) ) {
00634 #ifdef KEY
00635 if (reclaim) {
00636 LRANGE_Split_Reclaimed_BBs(lrange, reg);
00637 }
00638 Update_Register_Info(lrange, reg, reclaim);
00639 #else
00640 Update_Register_Info(lrange,reg);
00641 #endif
00642 return TRUE;
00643 }
00644
00645
00646
00647
00648 #ifdef KEY
00649 if (!reclaim)
00650 #endif
00651 if (has_stacked && Allocate_Stacked_Register(lrange)) {
00652 return TRUE;
00653 }
00654
00655
00656
00657
00658
00659 if (Choose_Best_Register(®,rc,allowed, FALSE, FALSE)) {
00660 #ifdef KEY
00661 if (reclaim) {
00662 LRANGE_Split_Reclaimed_BBs(lrange, reg);
00663 }
00664 Update_Register_Info(lrange, reg, reclaim);
00665 #else
00666 Update_Register_Info(lrange,reg);
00667 #endif
00668 return TRUE;
00669 }
00670
00671 return FALSE;
00672 }
00673
00675 static BOOL
00676 Choose_Register( LRANGE* lrange, GRA_REGION* region )
00678
00679
00680
00682 {
00683 REGISTER_SET allowed = lrange->Allowed_Registers(GRA_current_region);
00684
00685 #ifdef TARG_IA64
00686 if (lrange->Type() == LRANGE_TYPE_COMPLEMENT)
00687 current_lrange = TN_number(lrange->Original_TN());
00688 else
00689 current_lrange = 0;
00690 #endif // TARG_IA64
00691 #ifdef TARG_SL //minor_reg_alloc
00692
00693
00694 vector< RID*> rid_vec;
00695 vector< RID* >::iterator iter;
00696 Get_Rid_For_Lrange(lrange, &rid_vec);
00697 for(iter=rid_vec.begin(); iter !=rid_vec.end(); iter++ ) {
00698 RID* rid = *iter;
00699 if(rid && RID_TYPE_minor(rid)) {
00700 GRA_PARA_REGION* region = gra_para_region_mgr.Get(rid);
00701 REGISTER_SET exclude_set = region->Registers_Exclude(lrange->Rc());
00702 allowed = REGISTER_SET_Difference(allowed, exclude_set);
00703 }
00704 }
00705
00706 #endif
00707
00708 if ( lrange->Has_Wired_Register() ) {
00709 #if defined(TARG_IA64)
00710 #ifdef KEY
00711
00712
00713
00714 #endif
00715
00716
00717 #endif
00718 #if defined(TARG_X8664)
00719 if (! PU_Has_Nonlocal_Goto_Target)
00720 DevAssert( REGISTER_SET_MemberP(allowed, lrange->Reg()),
00721 ("LRANGE not allowed its wired register"));
00722 #endif
00723 Update_Register_Info(lrange, lrange->Reg());
00724 return TRUE;
00725 }
00726 #ifdef TARG_IA64
00727
00728 can_use_stacked_reg = TRUE;
00729 need_buffer = FALSE;
00730 if ((fat_self_recursive) && (lrange->Type() == LRANGE_TYPE_COMPLEMENT)) {
00731 LRANGE_LUNIT_ITER iter;
00732 INT32 spill_num = 0;
00733 density = 0;
00734 for (iter.Init(lrange); ! iter.Done(); iter.Step()) {
00735 spill_num++;
00736 density += iter.Current()->Gbb()->Freq();
00737 }
00738
00739
00740
00741 can_use_stacked_reg = FALSE;
00742 lunits_number = spill_num;
00743 }
00744
00745 #else
00746 GRA_Trace_LRANGE_Choose(lrange, allowed);
00747 #endif
00748 #ifdef HAS_STACKED_REGISTERS
00749 if (REGISTER_SET_EmptyP(allowed) ) {
00750
00751
00752
00753 return Allocate_Stacked_Register(lrange);
00754 }
00755 #endif
00756 if ( Choose_Preference(lrange, allowed, region) )
00757 return TRUE;
00758 else if ( Choose_Avoiding_Neighbor_Preferences(lrange,allowed) )
00759 return TRUE;
00760 else if ( Choose_Noones_Preference(lrange,allowed) )
00761 return TRUE;
00762 else
00763 return Choose_Anything(lrange,allowed);
00764 }
00765
00766 #ifdef TARG_X8664
00768 static REGISTER_SET
00769 Find_Single_Register_Subclasses(GRA_BB *gbb)
00771
00772
00773
00774
00776 {
00777
00778 int rax = 0, rcx = 0, rdx = 0;
00779 REGISTER_SET grants = REGISTER_SET_EMPTY_SET;
00780 OP *op;
00781
00782 if (GRA_grant_special_regs) {
00783
00784 rax = rcx = rdx = 1;
00785 } else {
00786 FOR_ALL_BB_OPs (gbb->Bb(), op) {
00787 ASM_OP_ANNOT *asm_info = (OP_code(op) == TOP_asm) ?
00788 (ASM_OP_ANNOT*) OP_MAP_Get(OP_Asm_Map, op) : NULL;
00789 INT i;
00790 for (i = 0; i < OP_opnds(op); i++) {
00791 ISA_REGISTER_SUBCLASS subclass = asm_info ?
00792 ASM_OP_opnd_subclass(asm_info)[i] : OP_opnd_reg_subclass(op, i);
00793 rax |= (subclass == ISA_REGISTER_SUBCLASS_rax);
00794 rcx |= (subclass == ISA_REGISTER_SUBCLASS_rcx);
00795 rdx |= (subclass == ISA_REGISTER_SUBCLASS_rdx);
00796 }
00797 for (i = 0; i < OP_results(op); i++) {
00798 ISA_REGISTER_SUBCLASS subclass = asm_info ?
00799 ASM_OP_result_subclass(asm_info)[i] : OP_result_reg_subclass(op, i);
00800 rax |= (subclass == ISA_REGISTER_SUBCLASS_rax);
00801 rcx |= (subclass == ISA_REGISTER_SUBCLASS_rcx);
00802 rdx |= (subclass == ISA_REGISTER_SUBCLASS_rdx);
00803 }
00804 if (rax & rcx & rdx)
00805 break;
00806 }
00807 }
00808
00809
00810 if (rax)
00811 grants = REGISTER_SET_Union1(grants, RAX);
00812 if (rcx)
00813 grants = REGISTER_SET_Union1(grants, RCX);
00814 if (rdx)
00815 grants = REGISTER_SET_Union1(grants, RDX);
00816
00817
00818
00819
00820
00821 OP *last_op = BB_last_op(gbb->Bb());
00822 if (last_op) {
00823 switch (OP_code(last_op)) {
00824 case TOP_ijmpx:
00825 case TOP_ijmpxxx:
00826 case TOP_icallx:
00827 case TOP_icallxxx:
00828
00829 grants = REGISTER_SET_Union1(grants, Is_Target_32bit() ? RCX : R10);
00830 break;
00831 case TOP_ijmpxx:
00832 case TOP_icallxx:
00833
00834 grants = REGISTER_SET_Union1(grants, Is_Target_32bit() ? RCX : R10);
00835 grants = REGISTER_SET_Union1(grants, Is_Target_32bit() ? RDX : R11);
00836 break;
00837 }
00838 }
00839
00840 return grants;
00841 }
00842 #endif
00843
00845 static void
00846 Force_Color_Some_Locals( GRA_REGION* region, ISA_REGISTER_CLASS rc )
00848
00849
00850
00851
00852
00854 {
00855 GRA_REGION_GBB_ITER iter;
00856 INT rc_local_forced_max;
00857
00858
00859
00860
00861
00862
00863
00864
00865 if (GRA_LOCAL_FORCED_MAX(rc) == DEFAULT_FORCED_LOCAL_MAX) {
00866 INT rc_size = (REGISTER_CLASS_last_register(rc) - REGISTER_MIN) + 1;
00867 #ifndef TARG_IA64
00868 rc_local_forced_max = GRA_LOCAL_FORCED_MAX(rc);
00869 #else
00870 rc_local_forced_max = Min(GRA_LOCAL_FORCED_MAX(rc), rc_size/8);
00871 #endif
00872 } else {
00873 #ifndef KEY // cannot use this code because with user-assigned registers via
00874
00875
00876 INT rc_size = REGISTER_SET_Size(REGISTER_CLASS_allocatable(rc));
00877 if (rc_size <= 8) {
00878
00879 return;
00880 }
00881 if (rc_size < GRA_LOCAL_FORCED_MAX(rc)*2) {
00882
00883 rc_local_forced_max = rc_size/2;
00884 } else {
00885 #endif
00886 rc_local_forced_max = GRA_LOCAL_FORCED_MAX(rc);
00887 #ifndef KEY
00888 }
00889 #endif
00890 }
00891
00892 for (iter.Init(region); ! iter.Done(); iter.Step()) {
00893 INT i;
00894 GRA_BB* gbb = iter.Current();
00895 INT regs_to_grant = Min(gbb->Register_Girth(rc),rc_local_forced_max);
00896 #ifdef TARG_X8664
00897
00898
00899 if (rc == ISA_REGISTER_CLASS_integer) {
00900 REGISTER_SET special_regs = Find_Single_Register_Subclasses(gbb);
00901 for (REGISTER reg = REGISTER_SET_Choose(special_regs);
00902 reg != REGISTER_UNDEFINED;
00903 reg = REGISTER_SET_Choose_Next(special_regs, reg)) {
00904 gbb->Make_Register_Used(ISA_REGISTER_CLASS_integer, reg);
00905 if (GRA_reclaim_register)
00906 gbb->Make_Register_Referenced(ISA_REGISTER_CLASS_integer, reg);
00907 GRA_GRANT_Local_Register(gbb, ISA_REGISTER_CLASS_integer, reg);
00908 regs_to_grant--;
00909 }
00910 }
00911 #endif
00912 for ( i = regs_to_grant;
00913 i > 0;
00914 --i
00915 ) {
00916 REGISTER reg;
00917 REGISTER_SET allowed = REGISTER_CLASS_allocatable(rc);
00918
00919 #ifdef TARG_SL2 //minor_reg_alloc
00920 BB* bb = gbb->Bb();
00921 if(BB_rid(bb) && RID_TYPE_minor(BB_rid(bb))) {
00922 GRA_PARA_REGION* region = gra_para_region_mgr.Get(BB_rid(bb));
00923 REGISTER_SET exclude_set = region->Registers_Exclude(rc);
00924 allowed = REGISTER_SET_Difference(allowed, exclude_set);
00925 }
00926 #endif
00927
00928 #ifdef HAS_STACKED_REGISTERS
00929 if (REGISTER_Has_Stacked_Registers(rc)) {
00930 allowed = REGISTER_SET_Difference(allowed, REGISTER_CLASS_stacked(rc));
00931 allowed = REGISTER_SET_Union(allowed, regs_used[rc]);
00932 }
00933 #endif
00934 allowed = REGISTER_SET_Difference(allowed,
00935 gbb->Registers_Used(rc));
00936 #ifndef TARG_IA64 // this is needed to avoid insufficient regs granted to LRA
00937 allowed = REGISTER_SET_Difference(allowed,
00938 REGISTER_CLASS_function_value(rc));
00939 #endif
00940 BOOL non_glue_found = FALSE;
00941
00942 REGISTER_SET npr = non_prefrenced_regs[rc];
00943 REGISTER_SET gru = gbb->Glue_Registers_Used(rc);
00944
00945 if ( GRA_avoid_glue_references_for_locals ) {
00946 REGISTER_SET npr_gru = REGISTER_SET_Difference(npr, gru);
00947 if ( Choose_Best_Register(®,rc,
00948 REGISTER_SET_Intersection(allowed, npr_gru),
00949 FALSE, FALSE)
00950 || Choose_Best_Register(®,rc,
00951 REGISTER_SET_Difference(allowed, gru),
00952 FALSE, FALSE)) {
00953 non_glue_found = TRUE;
00954 }
00955 }
00956 if ( non_glue_found
00957 || Choose_Best_Register(®,rc,
00958 REGISTER_SET_Intersection(allowed, npr),
00959 FALSE, FALSE)
00960 || Choose_Best_Register(®,rc,allowed,FALSE,FALSE)
00961 ) {
00962 gbb->Make_Register_Used(rc,reg);
00963 #ifdef KEY
00964 if (GRA_reclaim_register)
00965 gbb->Make_Register_Referenced(rc, reg);
00966 #endif
00967 GRA_GRANT_Local_Register(gbb,rc,reg);
00968 #ifdef TARG_SL //minor_reg_alloc
00969 if(BB_rid(gbb->Bb()) && RID_TYPE_minor(BB_rid(gbb->Bb()))) {
00970 RID* rid = BB_rid(gbb->Bb());
00971 RID* pair_rid = gra_para_region_mgr.Get_Pair_Rid(rid);
00972 GRA_PARA_REGION * pair_region =
00973 gra_para_region_mgr.Get(pair_rid);
00974 pair_region->Add_One_Exclude_Register(rc, reg);
00975 }
00976 #endif
00977 }
00978 else {
00979 #ifdef TARG_X8664
00980 if( Is_Target_64bit() ){
00981 DevWarn("Couldn't force allocate %d registers in rc %d for BB:%d",
00982 i,rc,BB_id(gbb->Bb()));
00983 }
00984 #endif
00985 break;
00986 }
00987 }
00988 }
00989 }
00990
00991 #ifdef KEY
00992
00994
00995
00996
00997
00998
00999
01000
01001
01003
01004
01006 static BOOL
01007 Choose_Reclaimable_Register (LRANGE *lrange, GRA_REGION *region)
01009
01010
01011
01013 {
01014
01015 if (lrange->Type() == LRANGE_TYPE_LOCAL)
01016 return FALSE;
01017
01018 REGISTER_SET reclaimable = lrange->Reclaimable_Registers(GRA_current_region);
01019
01020
01021 Is_True(!lrange->Has_Wired_Register(),
01022 ("Choose_Reclaimable_Register: LRANGE has wired register"));
01023
01024 GRA_Trace_LRANGE_Choose_Reclaimable(lrange, reclaimable);
01025
01026 if (REGISTER_SET_EmptyP(reclaimable)) {
01027 return FALSE;
01028 }
01029
01030 if (Choose_Preference(lrange, reclaimable, region, TRUE))
01031 return TRUE;
01032 else if (Choose_Avoiding_Neighbor_Preferences(lrange, reclaimable, TRUE))
01033 return TRUE;
01034 else if (Choose_Noones_Preference(lrange, reclaimable, TRUE))
01035 return TRUE;
01036 else
01037 return Choose_Anything(lrange, reclaimable, TRUE);
01038 }
01039 #endif
01040
01041
01042
01044
01045
01046 TYPE_PRQ(LRANGE,LRPRQ)
01047
01048
01049
01050 static BOOL
01051 Compare_Priorities( LRANGE* lrange0, LRANGE* lrange1 )
01053
01054
01055
01057 {
01058 return lrange0->Priority() < lrange1->Priority();
01059 }
01060
01061
01063 static void
01064 Initialize_Priority_Queue( LRPRQ* q, GRA_REGION* region, ISA_REGISTER_CLASS cl )
01066
01067
01068
01069
01071 {
01072 LRPRQ_Initialize(q,Compare_Priorities,
01073 NULL,
01074 NULL,
01075 &prq_pool,
01076 region->Lrange_Count(cl),
01077 200);
01078 }
01079
01080
01081 void
01082 LRANGE_CLIST::Print_Clist(void)
01083 {
01084 LRANGE *lr;
01085 for (lr = first; lr != last; lr = lr->clist_next) {
01086 printf("%d ", lr->id);
01087 }
01088 if (lr != NULL) {
01089 printf("%d \n", lr->id);
01090 }
01091 }
01092
01094 static void
01095 Simplify_Initialize( GRA_REGION* region, ISA_REGISTER_CLASS rc,
01096 LRANGE_CLIST* cl,
01097 LRANGE_CLIST* pcl,
01098 LRPRQ* ready,
01099 LRPRQ* not_ready )
01101
01102
01103
01104
01105
01106
01107
01108
01109
01111 {
01112 GRA_REGION_RC_LRANGE_ITER iter;
01113 GRA_REGION_GBB_ITER gbb_iter;
01114
01115 cl->Initialize();
01116 pcl->Initialize();
01117 lrange_mgr.Clear_One_Set();
01118
01119 Initialize_Priority_Queue(ready,region,rc);
01120 Initialize_Priority_Queue(not_ready,region,rc);
01121
01122
01123
01124
01125
01126
01127 for (gbb_iter.Init(region); ! gbb_iter.Done(); gbb_iter.Step()) {
01128 GRA_BB* gbb = gbb_iter.Current();
01129 LRANGE_LIST *l;
01130
01131 for (l = gbb->Unpreferenced_Wired_LRANGEs(rc);
01132 l != NULL;
01133 l = LRANGE_LIST_rest(l)
01134 ) {
01135 pcl->Push(LRANGE_LIST_first(l));
01136 }
01137 }
01138
01139 for (iter.Init(region,rc); ! iter.Done(); iter.Step()) {
01140 LRANGE* lr = iter.Current();
01141
01142 if ( lr->Has_Wired_Register() ) {
01143
01144
01145
01146
01147
01148
01149
01150
01151
01152 if ( lr->Has_Preference() ) {
01153
01154 pcl->Push(lr);
01155 }
01156 }
01157 else if ( ! lr->Region_Invariant() ) {
01158 FmtAssert(! lr->Allocated(),("LRANGE already allocated"));
01159 lr->Neighbors_Left_Initialize();
01160 lr->Calculate_Priority();
01161
01162 #ifndef KEY // for key, leave ready queue empty; rank purely based on priority
01163 if ( lr->Neighbors_Left() < lr->Candidate_Reg_Count() ) {
01164 LRPRQ_Insert(ready,lr);
01165 lrange_mgr.One_Set_Union1(lr);
01166 }
01167 else
01168 #endif
01169 LRPRQ_Insert(not_ready,lr);
01170 }
01171 }
01172 }
01173
01174
01176 static void
01177 Simplify( GRA_REGION* region, ISA_REGISTER_CLASS rc, LRANGE_CLIST* cl )
01179
01180
01181
01182
01183
01184
01185
01187 {
01188 LRPRQ ready, not_ready;
01189 LRANGE* lr;
01190 LRANGE_NEIGHBOR_ITER iter;
01191 LRANGE_CLIST pcl;
01192
01193 MEM_POOL_Push(&prq_pool);
01194 Simplify_Initialize(region,rc,cl,&pcl,&ready,¬_ready);
01195
01196 #ifndef KEY // for key, leave ready queue empty; rank purely based on priority
01197 for (;;) {
01198 if ( LRPRQ_Size(&ready) != 0 )
01199 lr = LRPRQ_Delete_Top(&ready);
01200 else if ( LRPRQ_Size(¬_ready) != 0) {
01201
01202 lr = LRPRQ_Delete_Top(¬_ready);
01203 GRA_Trace_Color_LRANGE("Briggs point.",lr);
01204 }
01205 else
01206 break;
01207
01208 FmtAssert(! lr->Allocated(),("LRANGE already allocated"));
01209
01210 cl->Push(lr);
01211 GRA_Trace_Color_LRANGE("Listing.",lr);
01212 lr->Listed_Set();
01213
01214 for (iter.Init(lr, region); ! iter.Done(); iter.Step()) {
01215 LRANGE* nlr = iter.Current();
01216
01217 FmtAssert(! nlr->Allocated(),("LRANGE already allocated"));
01218
01219
01220
01221 if ( ! ( nlr->Listed() || nlr->Has_Wired_Register() ) &&
01222 nlr->Neighbors_Left_Decrement() == nlr->Candidate_Reg_Count() - 1) {
01223 LRPRQ_Remove(¬_ready,nlr);
01224
01225 DevAssert(! lrange_mgr.One_Set_MemberP(nlr),
01226 ("Adding a lrange to coloring ready queue twice"));
01227 lrange_mgr.One_Set_Union1(nlr);
01228
01229 LRPRQ_Insert(&ready,nlr);
01230
01231 }
01232 }
01233 }
01234 #else
01235 while (LRPRQ_Size(¬_ready) != 0) {
01236 lr = LRPRQ_Delete_Top(¬_ready);
01237
01238 FmtAssert(! lr->Allocated(),("LRANGE already allocated"));
01239
01240 cl->Push(lr);
01241 GRA_Trace_Color_LRANGE("Listing.",lr);
01242 lr->Listed_Set();
01243 }
01244 #endif
01245
01246
01247
01248
01249 pcl.Append(cl);
01250
01251 FmtAssert(LRPRQ_Size(&ready) == 0,
01252 ("Ready priority queue not empty after simplification"));
01253 FmtAssert(LRPRQ_Size(¬_ready) == 0,
01254 ("Not-ready priority queue not empty after simplification"));
01255
01256 MEM_POOL_Pop(&prq_pool);
01257 }
01258
01259
01260
01262
01263 static void
01264 Choose_Original_Registers( GRA_REGION* region, ISA_REGISTER_CLASS rc )
01266
01267
01268
01269
01271 {
01272 GRA_REGION_RC_LRANGE_ITER iter;
01273 GRA_Trace_Color(0,"Using original registers");
01274
01275 for (iter.Init(region,rc); ! iter.Done(); iter.Step()) {
01276 LRANGE* lr = iter.Current();
01277
01278 DevAssert(lr->Type() == LRANGE_TYPE_REGION,
01279 ("Choose_Original_Register for non-REGION LRANGE"));
01280 lr->Allocated_Reset();
01281 Update_Register_Info(lr, lr->Orig_Reg());
01282 }
01283 }
01284
01286 static BOOL
01287 Color_Region_With_Preferences( GRA_REGION *region, ISA_REGISTER_CLASS rc )
01289
01290
01291
01292
01294 {
01295 LRANGE_CLIST cl;
01296 LRANGE_CLIST_ITER iter;
01297
01298 GRA_Trace_Color(0,"Color with preferences...");
01299 Simplify(region,rc,&cl);
01300
01301 for (iter.Init(&cl); ! iter.Done(); iter.Step()) {
01302 if ( ! Choose_Register(iter.Current(), region) ) {
01303 GRA_Trace_Color(0,"Color with preferences failed.");
01304 return FALSE;
01305 }
01306 }
01307
01308 GRA_Trace_Color(0,"Color with preferences succeeded.");
01309 return TRUE;
01310 }
01311
01313 static void
01314 GRA_Color_Prev_Allocated_Region( GRA_REGION* region )
01316
01318 {
01319 ISA_REGISTER_CLASS rc;
01320
01321 GRA_Trace_Color_REGION(region);
01322 GRA_current_region = region;
01323
01324 FOR_ALL_ISA_REGISTER_CLASS( rc ) {
01325 if ( region->Prev_Alloc_By_GRA() )
01326 Choose_Original_Registers(region,rc);
01327 else if ( region->Lrange_Count(rc) == 0 )
01328 continue;
01329 else {
01330
01331 #if 0
01332 if ( ! Color_Region_With_Preferences(region,rc) ) {
01333
01334 DevWarn("Couldn't recolor a previously allocated region. "
01335 "Keeping original.");
01336 #endif
01337 Choose_Original_Registers(region,rc);
01338 }
01339 }
01340 region->Set_GRA_Colored();
01341 }
01342
01344 static BOOL
01345 Must_Split( LRANGE* lrange )
01347
01348
01349
01350
01351
01352
01353
01354
01355
01356
01357
01358
01359
01360
01361
01363 {
01364 return lrange->Type() == LRANGE_TYPE_COMPLEMENT
01365 && TN_is_save_reg(lrange->Tn()) && GRA_shrink_wrap;
01366 }
01367
01368 #ifdef TARG_IA64
01370 static void
01371 GRA_Optimize_Restore_Regs(BB* exit, BB_SET* call_set, BB_SET* pr_set, BB_SET* lc_set)
01373
01374
01375
01376
01377
01379 {
01380 Is_True(exit, ("NULL exit BB to optimize!"));
01381 BB_SET* parent_bbs = Find_BB_Parents(exit);
01382 BB_SET* ref_set = NULL;
01383 OP* op;
01384 if(call_set) {
01385 ref_set = BB_SET_Intersection(call_set, parent_bbs, GRA_pool);
01386 if(BB_SET_EmptyP(ref_set)) {
01387 Is_True(exit, ("exit BB in GRA should not be NULL!"));
01388 BOOL found_pfs = FALSE;
01389 BOOL found_b0 = FALSE;
01390 for (op = BB_last_op(exit); op; op = OP_prev(op)) {
01391 OP* tmp_op = NULL;
01392 if(!found_pfs && OP_restore_ar_pfs(op)) {
01393 tmp_op = BB_prev(op);
01394 BB_Remove_Op(exit, op);
01395 found_pfs = TRUE;
01396 op = tmp_op;
01397 }
01398 if (!found_b0 && OP_restore_b0(op)) {
01399 tmp_op = BB_prev(op);
01400 BB_Remove_Op(exit, op);
01401 found_b0 = TRUE;
01402 op = tmp_op;
01403 }
01404 if(found_pfs && found_b0) break;
01405 if(!op) break;
01406 }
01407 }
01408 }
01409
01410 if(pr_set) {
01411 ref_set = BB_SET_Intersection(pr_set, parent_bbs, GRA_pool);
01412 if(BB_SET_EmptyP(ref_set)) {
01413 for (op = BB_last_op(exit); op; op = OP_prev(op)) {
01414 if (OP_restore_predicates(op)) {
01415 BB_Remove_Op(exit, op);
01416 break;
01417 }
01418 }
01419 }
01420 }
01421
01422 if(lc_set) {
01423 ref_set = BB_SET_Intersection(lc_set, parent_bbs, GRA_pool);
01424 if(BB_SET_EmptyP(ref_set)) {
01425 Is_True(exit, ("exit BB in GRA should not be NULL!"));
01426 for (op = BB_last_op(exit); op; op = OP_prev(op)) {
01427 if (OP_def_ar_lc(op)) {
01428 BB_Remove_Op(exit, op);
01429 break;
01430 }
01431 }
01432 }
01433 }
01434
01435 }
01436 #endif
01437
01438
01439 #ifdef TARG_SL
01440
01441
01442
01443
01444
01445
01446
01447
01448
01449
01450
01451
01452
01453
01454
01455
01456
01457
01458
01459
01460 void
01461 Set_Children_GRA_Colored (RID * rid)
01462 {
01463 RID* kid;
01464
01465 if(rid == NULL) return;
01466
01467 RID_was_gra_Set(rid);
01468 RID_has_reg_alloc_Set(rid);
01469
01470 for(kid = RID_first_kid(rid); kid != NULL; kid = RID_next(kid))
01471 {
01472 Set_Children_GRA_Colored(kid);
01473 }
01474 return;
01475 }
01476 #endif // TARG_SL
01477
01478
01480 static void
01481 GRA_Color_Complement( GRA_REGION* region )
01483
01485 {
01486 ISA_REGISTER_CLASS rc;
01487 LRANGE_CLIST cl;
01488 LRANGE_CLIST_ITER iter;
01489 char buff[100];
01490
01491 priority_count = 0.0;
01492
01493 GRA_Trace_Color(0,"Coloring complement region...");
01494 GRA_current_region = gra_region_mgr.Complement_Region();
01495
01496 GRA_GRANT_Initialize();
01497
01498 FOR_ALL_ISA_REGISTER_CLASS_IN_REVERSE( rc ) {
01499 #ifdef TARG_IA64
01500 BUFFERED_LRANGE *first,*last;
01501
01502
01503 first = (BUFFERED_LRANGE *) malloc(sizeof(BUFFERED_LRANGE));
01504 last = (BUFFERED_LRANGE *) malloc(sizeof(BUFFERED_LRANGE));
01505 first->lunits_number = 10000;
01506 first->density = 900000000.0;
01507 last->lunits_number = -10000;
01508 last->density = -1000.0;
01509 last->next = NULL;
01510 last->prev = first;
01511 first->prev = NULL;
01512 first->next = last;
01513
01514 if (rc == ISA_REGISTER_CLASS_integer) {
01515 first_callee_next = Get_Stacked_Callee_Next();
01516 first_caller_next = Get_Stacked_Caller_Next();
01517 for (INT32 i = 32; i <= first_callee_next; i++) {
01518 INT32 k = i - 32;
01519 reg_fb._cost[k] = FLT_MAX;
01520 }
01521
01522 for (INT32 i = first_caller_next+1; i <= 128;i++) {
01523 INT32 k = i - 32;
01524 reg_fb._cost[k] = FLT_MAX;
01525 }
01526 }
01527 #endif
01528 BOOL forced_locals = FALSE;
01529
01530 if ( region->Lrange_Count(rc) == 0 ) {
01531 Force_Color_Some_Locals(region,rc);
01532 continue;
01533 }
01534 GRA_Init_Trace_Memory();
01535 Simplify(region,rc,&cl);
01536 GRA_Trace_Memory("Simplify()");
01537
01538 GRA_Init_Trace_Memory();
01539 for (iter.Init(&cl); ! iter.Done(); iter.Step()) {
01540 LRANGE* split_alloc_lr;
01541 LRANGE* lr = iter.Current();
01542
01543 if ( ! (forced_locals || lr->Has_Wired_Register()) ) {
01544 forced_locals = TRUE;
01545 Force_Color_Some_Locals(region,rc);
01546 }
01547
01548 GRA_Trace_Color_LRANGE("Coloring",lr);
01549 GRA_Trace_Complement_LRANGE_Neighbors(lr, region);
01550
01551 #ifdef TARG_IA64
01552
01553
01554
01555
01556 double total_def = 0.0;
01557 double total_use = 0.0;
01558 BOOL should_spill = FALSE;
01559 if ((CG_PU_Has_Feedback) && (lr->Type() == LRANGE_TYPE_COMPLEMENT)) {
01560 TN* tn_cur = lr->Tn();
01561 if (TN_is_rematerializable(tn_cur)) {
01562 LRANGE_LUNIT_ITER iter;
01563 for (iter.Init(lr); ! iter.Done(); iter.Step()) {
01564 LUNIT* unit = iter.Current();
01565 double freq = unit->Gbb()->Freq();
01566 if ((unit->Has_Exposed_Use()) && (!unit->Has_Def())) {
01567 total_use += freq;
01568 } else if (unit->Has_Def() && !unit->Has_Use()) {
01569 total_def += freq;
01570 }
01571 }
01572
01573 if (total_def > total_use*2) {
01574 should_spill = TRUE;
01575 }
01576 }
01577 }
01578
01579
01580 if (should_spill) {
01581 GRA_Note_Spill(lr);
01582 continue;
01583 }
01584 #endif // TARG_IA64
01585
01586 #ifdef TARG_X8664
01587
01588
01589
01590
01591 if ((rc == ISA_REGISTER_CLASS_x87 && lr->Spans_mmx_OP()) ||
01592 (rc == ISA_REGISTER_CLASS_mmx && lr->Spans_x87_OP())) {
01593 LRANGE_Split_Mixed_x87_MMX(lr, &iter, &split_alloc_lr);
01594
01595 GRA_Note_Spill(split_alloc_lr);
01596 continue;
01597 }
01598 #endif
01599
01600
01601
01602
01603
01604
01605
01606 #ifdef KEY
01607 if (lr->Priority() < 0.0F && !lr->Has_Wired_Register() && !Must_Split(lr)
01608 || lr->No_Appearance()) {
01609 GRA_Note_Spill(lr);
01610 } else if (lr->Spans_Infreq_Call() &&
01611 (!lr->Tn_Is_Save_Reg() ||
01612 !REGISTER_SET_MemberP(REGISTER_CLASS_callee_saves(lr->Rc()),TN_save_reg(lr->Tn()))) &&
01613 LRANGE_Split(lr, &iter, &split_alloc_lr)) {
01614 BOOL did_choose = Choose_Register(split_alloc_lr, region);
01615 FmtAssert(did_choose,("Failed to choose a register for a split across infreq call of %s",
01616 split_alloc_lr->Format(buff)));
01617 priority_count += split_alloc_lr->Priority();
01618 } else if (Choose_Register(lr, region)) {
01619 priority_count += lr->Priority();
01620 } else if (lr->Tn_Is_Save_Reg()) {
01621 GRA_Note_Spill(lr);
01622 } else if (LRANGE_Split(lr, &iter, &split_alloc_lr) &&
01623 (split_alloc_lr->Priority() >= 0.0F ||
01624 Must_Split(split_alloc_lr))) {
01625 BOOL did_choose = Choose_Register(split_alloc_lr, region);
01626 FmtAssert(did_choose,("Failed to choose a register for a split of %s",
01627 split_alloc_lr->Format(buff)));
01628 priority_count += split_alloc_lr->Priority();
01629 }
01630 #if 0
01631
01632
01633
01634
01635 else if (GRA_reclaim_register &&
01636 Choose_Reclaimable_Register(split_alloc_lr, region)) {
01637 priority_count += lr->Priority();
01638 }
01639 #endif
01640
01641 else if (GRA_reclaim_register &&
01642 LRANGE_Split(lr, &iter, &split_alloc_lr, TRUE) &&
01643 (split_alloc_lr->Priority() >= 0.0F ||
01644 Must_Split(split_alloc_lr))) {
01645 BOOL did_choose = Choose_Reclaimable_Register(split_alloc_lr, region);
01646 FmtAssert(did_choose,
01647 ("Failed to choose a reclaimable register for a split of %s",
01648 split_alloc_lr->Format(buff)));
01649 priority_count += split_alloc_lr->Priority();
01650 } else {
01651 GRA_Note_Spill(split_alloc_lr);
01652 }
01653 #else // KEY
01654 if (lr->Priority() < 0.0F && !lr->Has_Wired_Register() && !Must_Split(lr)
01655 || lr->No_Appearance()) {
01656 GRA_Note_Spill(lr);
01657 } else if (lr->Spans_Infreq_Call() &&
01658 (!lr->Tn_Is_Save_Reg() ||
01659 !REGISTER_SET_MemberP(REGISTER_CLASS_callee_saves(lr->Rc()),TN_save_reg(lr->Tn()))) &&
01660 LRANGE_Split(lr, &iter, &split_alloc_lr)) {
01661 BOOL did_choose = Choose_Register(split_alloc_lr, region);
01662 FmtAssert(did_choose,("Failed to choose a register for a split across infreq call of %s",
01663 split_alloc_lr->Format(buff)));
01664 priority_count += split_alloc_lr->Priority();
01665 } else if (!Choose_Register(lr, region)) {
01666 if (!LRANGE_Split(lr,&iter,&split_alloc_lr) ||
01667 (split_alloc_lr->Priority() < 0.0F &&
01668 !Must_Split(split_alloc_lr))) {
01669 GRA_Note_Spill(split_alloc_lr);
01670 } else {
01671 BOOL did_choose = Choose_Register(split_alloc_lr, region);
01672 FmtAssert(did_choose,("Failed to choose a register for a split of %s",
01673 split_alloc_lr->Format(buff)));
01674 priority_count += split_alloc_lr->Priority();
01675 }
01676 } else {
01677 priority_count += lr->Priority();
01678 }
01679 #endif // KEY
01680 }
01681
01682 #ifdef TARG_IA64
01683 if (FALSE) {
01684 if (rc == ISA_REGISTER_CLASS_integer) {
01685 INT32 stacked_callee_next = Get_Stacked_Callee_Next();
01686 INT32 stacked_caller_next = Get_Stacked_Caller_Next();
01687 strcpy(reg_fb._func_name,Cur_PU_Name);
01688 reg_fb._stacked_caller_used = Get_Stacked_Caller_Used();
01689 reg_fb._stacked_callee_used = Get_Stacked_Callee_Used();
01690 printf("FUNCTION NAME %s\n",reg_fb._func_name);
01691 for (INT32 i = 0; i < 96; i++) {
01692 printf("COST OF REG %d IS %f \n",i,reg_fb._cost[i]);
01693 }
01694 if (!have_open_output_file) {
01695 fout = fopen("struc_feedback","a");
01696 have_open_output_file = TRUE;
01697 }
01698
01699 fwrite(®_fb,1,sizeof(struct reg_feedback),fout);
01700 }
01701 }
01702
01703 BOOL temp = can_use_stacked_reg;
01704 can_use_stacked_reg = TRUE;
01705 INT32 size = 0;
01706 for (BUFFERED_LRANGE *begin = first;
01707 begin != NULL;begin = begin->next) {
01708 size++;
01709
01710
01711 if ((begin->lunits_number > 0) && (begin->lunits_number < 1000) && (size < 26)) {
01712 if ((fat_self_recursive) && (begin->density == 0.0)) {
01713 GRA_Note_Spill(begin->lrange);
01714 } else {
01715 REGISTER reg = REGISTER_Request_Stacked_Register(
01716 begin->abi_property,begin->lrange->Rc());
01717 if (reg != REGISTER_UNDEFINED) {
01718 Update_Register_Info(begin->lrange, reg);
01719 } else {
01720 DevWarn("Did not get a register!");
01721 GRA_Note_Spill(begin->lrange);
01722 }
01723 }
01724 } else if ((begin->lunits_number > -1) && (begin->lunits_number < 100)) {
01725 GRA_Note_Spill(begin->lrange);
01726 }
01727 }
01728 can_use_stacked_reg = temp;
01729 #endif // TARG_IA64
01730
01731 GRA_Trace_Memory("Complement coloring loop");
01732 GRA_Trace_Regs_Stats(rc, REGISTER_CLASS_allocatable(rc), regs_used[rc]);
01733
01734 if (! forced_locals)
01735 Force_Color_Some_Locals(region,rc);
01736
01737 #ifdef TARG_IA64
01738 if (Is_Predicate_REGISTER_CLASS(rc)) {
01739 if(REGISTER_SET_EmptyP(callee_saves_used[rc])) {
01740 GRA_optimize_restore_pr = FALSE;
01741 GRA_Remove_Predicates_Save_Restore();
01742 }
01743 }
01744 #else
01745 if (Is_Predicate_REGISTER_CLASS(rc) &&
01746 REGISTER_SET_EmptyP(callee_saves_used[rc]))
01747 GRA_Remove_Predicates_Save_Restore();
01748 #endif
01749 }
01750
01751 gra_region_mgr.Complement_Region()->Set_GRA_Colored();
01752
01753 #ifdef TARG_SL
01754 Set_Children_GRA_Colored(gra_region_mgr.Complement_Region()->Rid());
01755 #endif
01756
01757 }
01758
01759 #ifdef TARG_IA64
01761 void
01762 GRA_Optimize_Restore()
01764
01766 {
01767 GRA_optimize_restore_ar_lc = GRA_optimize_restore_ar_lc && !CG_localize_tns && LC_Used_In_PU && LC_TN;
01768 if(GRA_optimize_restore_pr) {
01769 BB_LIST *elist;
01770 for (elist = Exit_BB_Head; elist; elist = BB_LIST_rest(elist)) {
01771 GRA_Optimize_Restore_Regs(BB_LIST_first(elist), NULL, pred_bb_set, NULL);
01772 }
01773 }
01774 if(GRA_optimize_restore_b0_ar_pfs) {
01775 BB_LIST *elist;
01776 BB* bb;
01777 BB_SET* call_bb_set = BB_SET_Create_Empty(PU_BB_Count+2, GRA_pool);
01778 for(bb = REGION_First_BB; bb; bb = BB_next(bb)) {
01779 if(BB_exit(bb)) continue;
01780 if(BB_call_op(bb)) call_bb_set = BB_SET_Union1(call_bb_set, bb, GRA_pool);
01781 }
01782 for (elist = Exit_BB_Head; elist; elist = BB_LIST_rest(elist)) {
01783 GRA_Optimize_Restore_Regs(BB_LIST_first(elist), call_bb_set, NULL, NULL);
01784 }
01785 }
01786 if(GRA_optimize_restore_ar_lc) {
01787 BB_LIST *elist;
01788 BB* bb;
01789 OP* op;
01790 BB_SET* lc_bb_set = BB_SET_Create_Empty(PU_BB_Count+2, GRA_pool);
01791 for(bb = REGION_First_BB; bb; bb = BB_next(bb)) {
01792 if(BB_exit(bb)) continue;
01793 FOR_ALL_BB_OPs(bb, op) {
01794 if(OP_def_ar_lc(op)) {
01795 lc_bb_set = BB_SET_Union1(lc_bb_set, bb, GRA_pool);
01796 break;
01797 }
01798 }
01799 }
01800 for (elist = Exit_BB_Head; elist; elist = BB_LIST_rest(elist)) {
01801 GRA_Optimize_Restore_Regs(BB_LIST_first(elist), NULL, NULL, lc_bb_set);
01802 }
01803 }
01804
01805 }
01806 #endif
01807
01809 void
01810 GRA_Color(void)
01812
01814 {
01815 GRA_REGION_PREV_ALLOC_ITER iter;
01816
01817 Initialize();
01818
01819 GRA_Init_Trace_Memory();
01820 for (iter.Init(); ! iter.Done(); iter.Step()) {
01821 GRA_REGION *region = iter.Current();
01822 GRA_Color_Prev_Allocated_Region(region);
01823 }
01824 GRA_Trace_Memory("Gra_Color_Prev_Allocate_Region()");
01825
01826 GRA_Color_Complement(gra_region_mgr.Complement_Region());
01827 }