00001
00002
00003
00004
00005
00006
00007
00008
00009
00010
00011
00012
00013
00014
00015
00016
00017
00018
00019
00020
00021
00022
00023
00024
00025
00026
00027
00028
00029
00030
00031
00032
00033
00034
00035
00036
00037
00038
00039
00040
00041
00042
00043
00044
00045
00046
00047
00048
00049
00050
00051
00052
00053
00054
00055
00056
00057
00058
00059 #include <alloca.h>
00060 #include "defs.h"
00061 #include "config.h"
00062 #include "mempool.h"
00063 #include "tracing.h"
00064 #include "timing.h"
00065 #include "cgir.h"
00066 #include "pu_info.h"
00067 #include "cg.h"
00068 #include "cg_flags.h"
00069 #include "ttype.h"
00070 #include "targ_sim.h"
00071 #include "bb_set.h"
00072 #include "freq.h"
00073 #include "cgtarget.h"
00074 #include "whirl2ops.h"
00075 #include "dominate.h"
00076 #include "findloops.h"
00077 #include "cg_vector.h"
00078 #ifndef TARG_NVISA
00079 #include "gtn_universe.h"
00080 #include "gtn_set.h"
00081 #endif
00082 #include "data_layout.h"
00083
00084 #include "reg_live.h"
00085
00086 static BOOL Trace_Register_Liveness = FALSE;
00087
00088 static REGSET Register_Livein;
00089 static REGSET Register_Kill;
00090 static MEM_POOL Reg_Live_Pool;
00091 static BOOL pool_initialized = FALSE;
00092
00093 #define BB_Register_Livein(bb) \
00094 (Register_Livein + BB_id(bb)*ISA_REGISTER_CLASS_COUNT - ISA_REGISTER_CLASS_MIN)
00095 #define BB_Register_Kill(bb) \
00096 (Register_Kill + BB_id(bb)*ISA_REGISTER_CLASS_COUNT - ISA_REGISTER_CLASS_MIN)
00097
00098 static INT32 default_size;
00099
00100
00101
00102
00103
00104 void REGSET_Print (REGSET set)
00105 {
00106 ISA_REGISTER_CLASS rc;
00107 REGISTER reg;
00108 fprintf (TFile, "[");
00109 FOR_ALL_ISA_REGISTER_CLASS(rc) {
00110 FOR_ALL_REGISTER_SET_members (set[rc], reg) {
00111 fprintf (TFile, " %s", REGISTER_name (rc, reg));
00112 }
00113 }
00114 fprintf (TFile, " ]");
00115 }
00116
00117 void
00118 REGSET_ASSIGN (REGSET set1, REGSET set2)
00119 {
00120 ISA_REGISTER_CLASS rc;
00121 FOR_ALL_ISA_REGISTER_CLASS(rc) {
00122 set1[rc] = set2[rc];
00123 }
00124 }
00125
00126 void
00127 REGSET_CLEAR (REGSET set)
00128 {
00129 ISA_REGISTER_CLASS rc;
00130 FOR_ALL_ISA_REGISTER_CLASS(rc) {
00131 set[rc] = REGISTER_SET_EMPTY_SET;
00132 }
00133 }
00134
00135 void
00136 REGSET_OR (REGSET set1, REGSET set2)
00137 {
00138 ISA_REGISTER_CLASS rc;
00139 FOR_ALL_ISA_REGISTER_CLASS(rc) {
00140 set1[rc] = REGISTER_SET_Union(set1[rc], set2[rc]);
00141 }
00142 }
00143
00144 BOOL
00145 REGSET_EQUALS (REGSET set1, REGSET set2)
00146 {
00147 ISA_REGISTER_CLASS rc;
00148 FOR_ALL_ISA_REGISTER_CLASS(rc) {
00149 if (!REGISTER_SET_EqualP(set1[rc], set2[rc])) return FALSE;
00150 }
00151 return TRUE;
00152 }
00153
00154 BOOL
00155 REGSET_INTERSECT (REGSET set1, REGSET set2)
00156 {
00157 ISA_REGISTER_CLASS rc;
00158 FOR_ALL_ISA_REGISTER_CLASS(rc) {
00159 if (REGISTER_SET_IntersectsP(set1[rc], set2[rc])) return TRUE;
00160 }
00161 return FALSE;
00162 }
00163
00164 static void
00165 REGSET_UPDATE_LIVEIN ( REGSET livein, REGSET liveout, REGSET kill)
00166 {
00167 ISA_REGISTER_CLASS rc;
00168 FOR_ALL_ISA_REGISTER_CLASS(rc) {
00169 REGISTER_SET livein_set = REGISTER_SET_Difference(liveout[rc], kill[rc]);
00170 livein[rc] = REGISTER_SET_Union(livein[rc], livein_set);
00171 }
00172 }
00173
00174
00175 static void
00176 Add_PREG_To_REGSET (PREG_NUM preg, REGSET regset)
00177 {
00178 if (preg != 0) {
00179 ISA_REGISTER_CLASS cl;
00180 REGISTER reg;
00181
00182 #ifdef KEY
00183 if( !CGTARG_Preg_Register_And_Class(preg, &cl, ®) ){
00184 FmtAssert( FALSE, ("Don't know how to handle PREG%d", preg) );
00185 }
00186 #else
00187 FmtAssert(CGTARG_Preg_Register_And_Class(preg, &cl, ®),
00188 ("Don't know how to handle PREG%d", preg));
00189 #endif // KEY
00190
00191 regset[cl] = REGISTER_SET_Union1 (regset[cl], reg);
00192 }
00193 }
00194
00195
00196
00197
00198
00199 static void
00200 Compute_Parameter_Regs (TY_IDX call_ty, WN *call_wn, REGSET parms)
00201 {
00202 BOOL func_entry = WN_operator (call_wn) == OPR_FUNC_ENTRY;
00203 PLOC ploc;
00204 INT parm_count;
00205 if (func_entry) {
00206 parm_count = WN_num_formals(call_wn);
00207 ploc = Setup_Input_Parameter_Locations (call_ty);
00208 } else {
00209 parm_count = WN_num_actuals(call_wn);
00210 ploc = Setup_Output_Parameter_Locations (call_ty);
00211 }
00212
00213 for (INT i = 0; i < parm_count; i++) {
00214 TY_IDX parm_ty = TY_Of_Parameter(WN_actual(call_wn,i));
00215 if (func_entry) {
00216 ploc = Get_Input_Parameter_Location (parm_ty);
00217 ploc = First_Input_PLOC_Reg (ploc, parm_ty);
00218 } else {
00219 ploc = Get_Output_Parameter_Location (parm_ty);
00220 ploc = First_Output_PLOC_Reg (ploc, parm_ty);
00221 }
00222 while (PLOC_is_nonempty(ploc)) {
00223 if (PLOC_on_stack(ploc)) break;
00224 Add_PREG_To_REGSET (PLOC_reg(ploc), parms);
00225 #if defined(TARG_SL)
00226 if (MTYPE_byte_size(TY_mtype(parm_ty)) == 8) {
00227 Add_PREG_To_REGSET (PLOC_reg(ploc)+1, parms);
00228 }
00229 #endif
00230 ploc = func_entry ? Next_Input_PLOC_Reg (ploc)
00231 : Next_Output_PLOC_Reg (ploc);
00232 }
00233 }
00234
00235 #ifdef TARG_X8664
00236
00237 Add_PREG_To_REGSET( RAX, parms );
00238 #endif
00239 }
00240
00241 static void
00242 Compute_Return_Regs (ST *call_st, TY_IDX call_ty, REGSET return_regs)
00243 {
00244
00245 PREG_NUM retpreg[MAX_NUMBER_OF_REGISTERS_FOR_RETURN];
00246 TYPE_ID retmtype[MAX_NUMBER_OF_REGISTERS_FOR_RETURN];
00247 INT i;
00248
00249 if (WHIRL_Return_Info_On) {
00250
00251 RETURN_INFO return_info = Get_Return_Info (TY_ret_type(call_ty),
00252 No_Simulated
00253 #ifdef TARG_X8664
00254 , call_st ? PU_ff2c_abi(Pu_Table[ST_pu(call_st)]) : FALSE
00255 #endif
00256 );
00257 FmtAssert (RETURN_INFO_count(return_info) <= MAX_NUMBER_OF_REGISTERS_FOR_RETURN,
00258 ("Compute_Return_Regs: more return registers than can handle"));
00259
00260 for (i = 0; i < RETURN_INFO_count(return_info); i++) {
00261 retmtype[i] = RETURN_INFO_mtype (return_info, i);
00262 retpreg[i] = RETURN_INFO_preg (return_info, i);
00263 Add_PREG_To_REGSET (retpreg[i], return_regs);
00264 }
00265 #if defined(TARG_SL)
00266 FmtAssert(RETURN_INFO_count(return_info) <= 1, ("except 1 return register"));
00267 if (MTYPE_byte_size(TY_mtype(call_ty)) == 8) {
00268 Add_PREG_To_REGSET (RETURN_INFO_preg(return_info, 0)+1, return_regs);
00269 }
00270 #endif
00271 }
00272
00273 else {
00274 Get_Return_Mtypes (TY_ret_type(call_ty),
00275 No_Simulated, &retmtype[0], &retmtype[1]);
00276 Get_Return_Pregs (retmtype[0], retmtype[1], &retpreg[0], &retpreg[1]);
00277 Add_PREG_To_REGSET (retpreg[0], return_regs);
00278 Add_PREG_To_REGSET (retpreg[1], return_regs);
00279 }
00280 }
00281
00282
00283 static void Compute_PU_Regs (REGSET livein, REGSET liveout)
00284 {
00285 ST *pu_st = Get_Current_PU_ST ();
00286 ISA_REGISTER_CLASS rc;
00287
00288
00289 if (livein != NULL) {
00290
00291 Compute_Parameter_Regs (ST_pu_type(pu_st),
00292 PU_Info_tree_ptr(Current_PU_Info), livein);
00293 #ifndef TARG_NVISA
00294
00295 livein[REGISTER_CLASS_sp] =
00296 REGISTER_SET_Union1 (livein[REGISTER_CLASS_sp], REGISTER_sp);
00297 livein[REGISTER_CLASS_gp] =
00298 REGISTER_SET_Union1 (livein[REGISTER_CLASS_gp], REGISTER_gp);
00299 livein[REGISTER_CLASS_ep] =
00300 REGISTER_SET_Union1 (livein[REGISTER_CLASS_ep], REGISTER_ep);
00301 livein[REGISTER_CLASS_ra] =
00302 REGISTER_SET_Union1 (livein[REGISTER_CLASS_ra], REGISTER_ra);
00303
00304 FOR_ALL_ISA_REGISTER_CLASS(rc) {
00305 livein[rc] = REGISTER_SET_Union (livein[rc],
00306 REGISTER_CLASS_callee_saves(rc));
00307 }
00308 #endif
00309
00310
00311 if (PU_is_nested_func(Pu_Table[ST_pu(pu_st)])) {
00312 livein[REGISTER_CLASS_static_link] =
00313 REGISTER_SET_Union1 (livein[REGISTER_CLASS_static_link],
00314 REGISTER_static_link);
00315 }
00316 }
00317
00318
00319 if (liveout != NULL) {
00320 Compute_Return_Regs (pu_st, ST_pu_type(pu_st), liveout);
00321
00322
00323 if (PU_has_altentry(Get_Current_PU())) {
00324 BB_LIST *bbl;
00325 BB *bb;
00326 ANNOTATION *ant;
00327 for (bbl = Entry_BB_Head; bbl; bbl = BB_LIST_rest(bbl)) {
00328 bb = BB_LIST_first(bbl);
00329 ant = ANNOT_Get (BB_annotations(bb), ANNOT_ENTRYINFO);
00330 pu_st = ENTRYINFO_name(ANNOT_entryinfo(ant));
00331 Compute_Return_Regs(pu_st, ST_pu_type(pu_st), liveout);
00332 }
00333 }
00334
00335
00336 FOR_ALL_ISA_REGISTER_CLASS(rc) {
00337 liveout[rc] = REGISTER_SET_Union (liveout[rc],
00338 REGISTER_CLASS_callee_saves(rc));
00339 }
00340
00341
00342 if (REGISTER_sp != REGISTER_UNDEFINED)
00343 liveout[REGISTER_CLASS_sp] =
00344 REGISTER_SET_Union1 (liveout[REGISTER_CLASS_sp], REGISTER_sp);
00345 }
00346 }
00347
00348
00349
00350
00351
00352
00353
00354
00355
00356
00357
00358
00359
00360
00361 static void
00362 Compute_Call_Regs (BB *bb, REGSET livein, REGSET liveout, REGSET kill)
00363 {
00364 ANNOTATION *ant = ANNOT_Get (BB_annotations(bb), ANNOT_CALLINFO);
00365 WN *call_wn = CALLINFO_call_wn(ANNOT_callinfo(ant));
00366 INT num_parms = WN_num_actuals (call_wn);
00367 OPERATOR opr = WN_operator(call_wn);
00368 ST *call_st = (opr != OPR_ICALL) ? WN_st(call_wn) : NULL;
00369 TY_IDX call_ty = (call_st != NULL) ? ST_pu_type(call_st) : WN_ty(call_wn);
00370 ISA_REGISTER_CLASS cl;
00371
00372 if (livein != NULL) {
00373
00374 Compute_Parameter_Regs (call_ty, call_wn, livein);
00375
00376
00377
00378 if (call_st != NULL && PU_is_nested_func(Pu_Table[ST_pu(call_st)])) {
00379 livein[REGISTER_CLASS_static_link] =
00380 REGISTER_SET_Union1 (livein[REGISTER_CLASS_static_link],
00381 REGISTER_static_link);
00382 }
00383
00384
00385 if( REGISTER_gp != REGISTER_UNDEFINED ){
00386 livein[REGISTER_CLASS_gp] =
00387 REGISTER_SET_Union1 (livein[REGISTER_CLASS_gp], REGISTER_gp);
00388 }
00389 if (REGISTER_sp != REGISTER_UNDEFINED)
00390 livein[REGISTER_CLASS_sp] =
00391 REGISTER_SET_Union1 (livein[REGISTER_CLASS_sp], REGISTER_sp);
00392
00393
00394 if (opr != OPR_CALL && Gen_PIC_Calls) {
00395 livein[REGISTER_CLASS_ep] =
00396 REGISTER_SET_Union1 (livein[REGISTER_CLASS_ep], REGISTER_ep);
00397 }
00398
00399
00400 if (BB_tail_call(bb)) {
00401 if( REGISTER_ra != REGISTER_UNDEFINED ){
00402 livein[REGISTER_CLASS_ra] =
00403 REGISTER_SET_Union1 (livein[REGISTER_CLASS_ra], REGISTER_ra);
00404 }
00405
00406 FOR_ALL_ISA_REGISTER_CLASS(cl) {
00407 REGISTER_SET callee_saves = REGISTER_CLASS_callee_saves(cl);
00408 livein[cl] = REGISTER_SET_Union(livein[cl], callee_saves);
00409 }
00410 }
00411 }
00412
00413 if (liveout != NULL) {
00414 Compute_Return_Regs (call_st, call_ty, liveout);
00415 }
00416
00417 if (kill != NULL) {
00418
00419 ISA_REGISTER_CLASS rc;
00420 FOR_ALL_ISA_REGISTER_CLASS(rc) {
00421 kill[rc] = REGISTER_SET_Union (kill[rc], REGISTER_CLASS_caller_saves(rc));
00422 }
00423 }
00424 }
00425
00426
00427 static void
00428 Compute_Asm_Regs (BB *bb, REGSET livein, REGSET liveout, REGSET kill)
00429 {
00430 ANNOTATION *ant = ANNOT_Get (BB_annotations(bb), ANNOT_ASMINFO);
00431 Is_True(ant, ("ASMINFO annotation info not present"));
00432 ASMINFO *info = ANNOT_asminfo(ant);
00433 ISA_REGISTER_CLASS rc;
00434
00435 FOR_ALL_ISA_REGISTER_CLASS(rc) {
00436 if (livein) livein[rc] = ASMINFO_livein(info)[rc];
00437 if (liveout) liveout[rc] = ASMINFO_liveout(info)[rc];
00438 if (kill) kill[rc] = ASMINFO_kill(info)[rc];
00439 }
00440 }
00441
00442
00443
00444
00445
00446
00447
00448
00449 static void
00450 Compute_Rotating_Regs (BB *bb, REGSET livein, REGSET liveout, REGSET kill)
00451 {
00452 ANNOTATION *ant = ANNOT_Get (BB_annotations(bb), ANNOT_ROTATING_KERNEL);
00453 Is_True(ant, ("Rotating kernel annotation info not present"));
00454 ROTATING_KERNEL_INFO *info = ANNOT_rotating_kernel(ant);
00455
00456 ISA_REGISTER_CLASS rc;
00457 FOR_ALL_ISA_REGISTER_CLASS(rc) {
00458 livein[rc] = ROTATING_KERNEL_INFO_live_in(info)[rc];
00459 kill[rc] = ROTATING_KERNEL_INFO_kill(info)[rc];
00460 }
00461 }
00462
00463 static void
00464 Update_REGSETs_For_Tail_Call (BB *bb, REGSET livein, REGSET kill)
00465 {
00466 REGISTER_SET call_in[ISA_REGISTER_CLASS_MAX+1];
00467 REGSET_CLEAR (call_in);
00468 Compute_Call_Regs (bb, call_in, NULL, NULL);
00469 REGSET_UPDATE_LIVEIN (livein, call_in, kill);
00470 }
00471
00472 static void
00473 Update_REGSETs_For_Call (BB *bb, REGSET livein, REGSET kill)
00474 {
00475 REGISTER_SET call_in[ISA_REGISTER_CLASS_MAX+1];
00476 REGISTER_SET call_kill[ISA_REGISTER_CLASS_MAX+1];
00477 REGSET_CLEAR (call_in);
00478 REGSET_CLEAR (call_kill);
00479 Compute_Call_Regs (bb, call_in, NULL, call_kill);
00480 REGSET_UPDATE_LIVEIN (livein, call_in, kill);
00481 REGSET_OR (kill, call_kill);
00482 }
00483
00484 static void
00485 Update_REGSETs_For_Asm (BB *bb, REGSET livein, REGSET kill)
00486 {
00487 REGISTER_SET asm_in[ISA_REGISTER_CLASS_MAX+1];
00488 REGISTER_SET asm_kill[ISA_REGISTER_CLASS_MAX+1];
00489 REGSET_CLEAR (asm_in);
00490 REGSET_CLEAR (asm_kill);
00491 Compute_Asm_Regs (bb, asm_in, NULL, asm_kill);
00492 REGSET_UPDATE_LIVEIN (livein, asm_in, kill);
00493 REGSET_OR (kill, asm_kill);
00494 }
00495
00496 static void
00497 Update_REGSETs_For_Exit (REGSET livein, REGSET kill)
00498 {
00499 REGISTER_SET pu_liveout[ISA_REGISTER_CLASS_MAX+1];
00500 REGSET_CLEAR (pu_liveout);
00501
00502 Compute_PU_Regs (NULL, pu_liveout);
00503 REGSET_UPDATE_LIVEIN (livein, pu_liveout, kill);
00504 }
00505
00506 static void
00507 Update_REGSETs_For_Rotating_Kernel (BB *bb, REGSET livein, REGSET kill)
00508 {
00509 REGISTER_SET kernel_in[ISA_REGISTER_CLASS_MAX+1];
00510 REGISTER_SET kernel_kill[ISA_REGISTER_CLASS_MAX+1];
00511 REGSET_CLEAR (kernel_in);
00512 REGSET_CLEAR (kernel_kill);
00513 Compute_Rotating_Regs (bb, kernel_in, NULL, kernel_kill);
00514 REGSET_OR (livein, kernel_in);
00515 REGSET_OR (kill, kernel_kill);
00516 }
00517
00518 void REG_LIVE_Analyze_Region(void)
00519 {
00520 BB *bb;
00521 OP *op;
00522 BOOL changes;
00523 REGSET livein;
00524 REGSET kill;
00525 BB *last_bb = NULL;
00526
00527 Is_True(Register_Livein == FALSE,
00528 ("REG_LIVE_Analyze_Region called while facility is already in use"));
00529
00530 if (!pool_initialized) {
00531 MEM_POOL_Initialize(&Reg_Live_Pool, "CG_Reg_Live_Pool", TRUE);
00532 MEM_POOL_Push(&Reg_Live_Pool);
00533 pool_initialized = TRUE;
00534 }
00535
00536 Trace_Register_Liveness = Get_Trace (TP_GCM, 0x04);
00537
00538 default_size = PU_BB_Count + 2;
00539 Register_Livein =
00540 TYPE_MEM_POOL_ALLOC_N(REGISTER_SET, &Reg_Live_Pool,
00541 (PU_BB_Count+2)*ISA_REGISTER_CLASS_COUNT);
00542 Register_Kill =
00543 TYPE_MEM_POOL_ALLOC_N(REGISTER_SET, &Reg_Live_Pool,
00544 (PU_BB_Count+2)*ISA_REGISTER_CLASS_COUNT);
00545
00546
00547 for (bb = REGION_First_BB; bb != NULL; bb = BB_next(bb)) {
00548 livein = BB_Register_Livein(bb);
00549 kill = BB_Register_Kill(bb);
00550
00551 if (BB_rotating_kernel(bb)) {
00552 Update_REGSETs_For_Rotating_Kernel (bb, livein, kill);
00553 } else {
00554 FOR_ALL_BB_OPs_FWD (bb, op) {
00555 INT i;
00556 for (i = 0; i < OP_opnds(op); i++) {
00557 TN *opnd_tn = OP_opnd(op,i);
00558 if (TN_is_register(opnd_tn)) {
00559 ISA_REGISTER_CLASS cl = TN_register_class(opnd_tn);
00560 REGISTER reg = TN_register(opnd_tn);
00561 if ((reg != REGISTER_UNDEFINED) &&
00562 (!REGISTER_SET_MemberP (kill[cl], reg))) {
00563 livein[cl] = REGISTER_SET_Union1 (livein[cl], reg);
00564 }
00565 }
00566 }
00567
00568 if (!OP_cond_def(op)) {
00569 for (i = 0; i < OP_results(op); i++) {
00570 TN *result_tn = OP_result(op,i);
00571 if (TN_register(result_tn) != REGISTER_UNDEFINED) {
00572 ISA_REGISTER_CLASS cl = TN_register_class(result_tn);
00573 kill[cl] = REGISTER_SET_Union1 (kill[cl], TN_register(result_tn));
00574 }
00575 }
00576 }
00577 }
00578 }
00579
00580 if (BB_tail_call(bb)) {
00581 Update_REGSETs_For_Tail_Call (bb, livein, kill);
00582 }
00583 else if (BB_call(bb)) {
00584 Update_REGSETs_For_Call (bb, livein, kill);
00585 }
00586 else if (BB_asm(bb)) {
00587 Update_REGSETs_For_Asm (bb, livein, kill);
00588 }
00589 else if (BB_exit(bb)) {
00590 Update_REGSETs_For_Exit (livein, kill);
00591 }
00592 last_bb = bb;
00593 }
00594
00595
00596 REGISTER_SET tmp[ISA_REGISTER_CLASS_MAX+1];
00597 REGISTER_SET liveout[ISA_REGISTER_CLASS_MAX+1];
00598 do {
00599 changes = FALSE;
00600 for (bb = last_bb; bb != NULL; bb = BB_prev(bb)) {
00601 BBLIST *bl;
00602 livein = BB_Register_Livein(bb);
00603 kill = BB_Register_Kill(bb);
00604 REGSET_ASSIGN (tmp, livein);
00605 REGSET_CLEAR (liveout);
00606 FOR_ALL_BB_SUCCS (bb, bl) {
00607 BB *succ_bb = BBLIST_item(bl);
00608 REGSET succ_livein = BB_Register_Livein(succ_bb);
00609 REGSET_OR (liveout, succ_livein);
00610 }
00611 REGSET_UPDATE_LIVEIN (livein, liveout, kill);
00612 if (!REGSET_EQUALS (tmp, livein)) {
00613 changes = TRUE;
00614 }
00615 }
00616 } while (changes);
00617
00618 if (Trace_Register_Liveness) {
00619 #pragma mips_frequency_hint NEVER
00620 for (bb = REGION_First_BB; bb != NULL; bb = BB_next(bb)) {
00621 fprintf (TFile, "BB:%-3d livein: ", BB_id(bb));
00622 REGSET_Print (BB_Register_Livein (bb));
00623 fprintf (TFile, "\n kill: ");
00624 REGSET_Print (BB_Register_Kill (bb));
00625 fprintf (TFile, "\n");
00626 }
00627 }
00628 }
00629
00630 #ifndef TARG_NVISA
00631
00632
00633
00634
00635
00636
00637
00638
00639 void
00640 REG_LIVE_Prolog_Temps(
00641 BB *bb,
00642 OP *first,
00643 OP *last,
00644 REGISTER_SET *temps)
00645 {
00646 REGISTER_SET live[ISA_REGISTER_CLASS_MAX+1];
00647 ISA_REGISTER_CLASS cl;
00648 OP *op;
00649 TN *tn;
00650
00651
00652
00653
00654 FOR_ALL_ISA_REGISTER_CLASS(cl) {
00655 live[cl] = REGISTER_SET_EMPTY_SET;
00656 }
00657
00658
00659
00660
00661
00662 if (! CG_localize_tns ) {
00663 for (tn = GTN_SET_Choose(BB_live_out(bb));
00664 tn != GTN_SET_CHOOSE_FAILURE;
00665 tn = GTN_SET_Choose_Next(BB_live_out(bb), tn)
00666 ) {
00667 FmtAssert(TN_is_global_reg(tn),("TN%d is not global",TN_number(tn)));
00668 if (TN_register(tn) != REGISTER_UNDEFINED) {
00669 cl = TN_register_class(tn);
00670 live[cl] = REGISTER_SET_Union1(live[cl], TN_register(tn));
00671 }
00672 }
00673 }
00674
00675
00676
00677
00678
00679 for (op = BB_last_op(bb); op != last; op = OP_prev(op)) {
00680 INT k;
00681
00682 for (k = 0; k < OP_results(op); k++) {
00683 tn = OP_result(op,k);
00684 if (TN_register(tn) != REGISTER_UNDEFINED) {
00685 cl = TN_register_class(tn);
00686 live[cl] = REGISTER_SET_Difference1(live[cl], TN_register(tn));
00687 }
00688 }
00689
00690 for (k = 0; k < OP_opnds(op); k++) {
00691 tn = OP_opnd(op,k);
00692 if ((TN_is_register(tn)) && (TN_register(tn) != REGISTER_UNDEFINED)) {
00693 cl = TN_register_class(tn);
00694 live[cl] = REGISTER_SET_Union1(live[cl], TN_register(tn));
00695 }
00696 }
00697
00698
00699
00700
00701
00702
00703 if (OP_call(op)) {
00704 FOR_ALL_ISA_REGISTER_CLASS(cl) {
00705 live[cl] = REGISTER_SET_Union(live[cl], REGISTER_CLASS_function_argument(cl));
00706 }
00707 }
00708 }
00709
00710
00711
00712
00713 FOR_ALL_ISA_REGISTER_CLASS(cl) {
00714 temps[cl] = REGISTER_SET_Difference(REGISTER_CLASS_caller_saves(cl),
00715 live[cl]);
00716 }
00717
00718
00719
00720
00721 for (op = first; op != last; op = OP_next(op)) {
00722 INT k;
00723
00724 for (k = 0; k < OP_results(op); k++) {
00725 tn = OP_result(op,k);
00726 if (TN_register(tn) != REGISTER_UNDEFINED) {
00727 cl = TN_register_class(tn);
00728 temps[cl] = REGISTER_SET_Difference1(temps[cl], TN_register(tn));
00729 }
00730 }
00731
00732 for (k = 0; k < OP_opnds(op); k++) {
00733 tn = OP_opnd(op,k);
00734 if ((TN_is_register(tn)) && (TN_register(tn) != REGISTER_UNDEFINED)) {
00735 cl = TN_register_class(tn);
00736 temps[cl] = REGISTER_SET_Difference1(temps[cl], TN_register(tn));
00737 }
00738 }
00739 }
00740 }
00741
00742
00743
00744
00745
00746
00747
00748
00749
00750
00751 void
00752 REG_LIVE_Epilog_Temps(
00753 ST *pu_st,
00754 BB *bb,
00755 OP *adj_op,
00756 REGISTER_SET *temps)
00757 {
00758 ISA_REGISTER_CLASS cl;
00759 OP *op;
00760 TN *tn;
00761
00762
00763 REGSET_CLEAR(temps);
00764 Compute_Return_Regs (pu_st, ST_pu_type(pu_st), temps);
00765
00766
00767
00768
00769 FOR_ALL_ISA_REGISTER_CLASS(cl) {
00770 temps[cl] = REGISTER_SET_Difference(REGISTER_CLASS_caller_saves(cl),
00771 temps[cl]);
00772 }
00773
00774
00775
00776
00777
00778 for (op = BB_last_op(bb); op != OP_prev(adj_op); op = OP_prev(op)) {
00779 INT k;
00780
00781 for (k = 0; k < OP_results(op); k++) {
00782 tn = OP_result(op,k);
00783 if (TN_register(tn) != REGISTER_UNDEFINED) {
00784 cl = TN_register_class(tn);
00785 temps[cl] = REGISTER_SET_Union1(temps[cl], TN_register(tn));
00786 }
00787 }
00788
00789 for (k = 0; k < OP_opnds(op); k++) {
00790 tn = OP_opnd(op,k);
00791 if ((TN_is_register(tn)) && (TN_register(tn) != REGISTER_UNDEFINED)) {
00792 cl = TN_register_class(tn);
00793 temps[cl] = REGISTER_SET_Difference1(temps[cl], TN_register(tn));
00794 }
00795 }
00796 }
00797 }
00798 #endif // ! TARG_NVISA
00799
00800
00801
00802 BOOL REG_LIVE_Implicit_Use_Outof_BB (ISA_REGISTER_CLASS cl, REGISTER reg, BB *bb)
00803 {
00804 #ifdef TARG_X8664
00805 if( cl == ISA_REGISTER_CLASS_rflags ){
00806 return FALSE;
00807 }
00808 #endif
00809
00810
00811 if (!REGISTER_allocatable (cl, reg)) return TRUE;
00812
00813 REGISTER_SET use[ISA_REGISTER_CLASS_MAX+1];
00814
00815 REGSET_CLEAR(use);
00816 if (BB_tail_call(bb) || BB_call(bb)) {
00817 Compute_Call_Regs (bb, use, NULL, NULL);
00818 }
00819 else if (BB_asm(bb)) {
00820 Compute_Asm_Regs (bb, use, NULL, NULL);
00821 }
00822 else if (BB_exit(bb)) {
00823 Compute_PU_Regs (NULL, use);
00824 }
00825 return REGISTER_SET_MemberP (use[cl], reg);
00826 }
00827
00828
00829
00830
00831 BOOL REG_LIVE_Implicit_Def_Into_BB (ISA_REGISTER_CLASS cl, REGISTER reg, BB *bb)
00832 {
00833
00834
00835 if (!REGISTER_allocatable (cl, reg)) return TRUE;
00836
00837 REGISTER_SET def[ISA_REGISTER_CLASS_MAX+1];
00838 REGSET_CLEAR (def);
00839 INT32 num_preds = BB_preds_len(bb);
00840
00841 if (num_preds == 0) {
00842 Compute_PU_Regs (def, NULL);
00843 }
00844 else if (num_preds == 1) {
00845 BB *prev_bb = BB_Unique_Predecessor (bb);
00846 if (BB_call(prev_bb)) {
00847 Compute_Call_Regs (prev_bb, NULL, def, NULL);
00848 }
00849 else if (BB_asm(prev_bb)) {
00850 Compute_Asm_Regs (prev_bb, NULL, def, NULL);
00851 }
00852 }
00853 return REGISTER_SET_MemberP (def[cl], reg);
00854 }
00855
00856
00857
00858
00859 BOOL REG_LIVE_Into_BB(ISA_REGISTER_CLASS cl, REGISTER reg, BB *bb)
00860 {
00861
00862
00863 if (Register_Livein == NULL) return TRUE;
00864
00865 REGSET livein = BB_Register_Livein (bb);
00866 return REGISTER_SET_MemberP (livein[cl], reg);
00867 }
00868
00869
00870
00871 BOOL REG_LIVE_Outof_BB (ISA_REGISTER_CLASS cl, REGISTER reg, BB *bb)
00872 {
00873 BBLIST *succs;
00874
00875
00876
00877 if (Register_Livein == NULL) return TRUE;
00878
00879 FOR_ALL_BB_SUCCS(bb, succs) {
00880 REGSET livein = BB_Register_Livein (BBLIST_item(succs));
00881 if (REGISTER_SET_MemberP (livein[cl], reg))
00882 return TRUE;
00883 }
00884
00885 return REG_LIVE_Implicit_Use_Outof_BB (cl, reg, bb);
00886 }
00887
00888
00889
00890 void REG_LIVE_Update(ISA_REGISTER_CLASS cl, REGISTER reg, BB *bb)
00891 {
00892
00893 if (BB_id(bb) >= default_size) {
00894 INT32 old_size = default_size;
00895 INT32 new_size = MAX(default_size, 2 * old_size);
00896 Register_Livein = TYPE_MEM_POOL_REALLOC_N(REGISTER_SET, &Reg_Live_Pool,
00897 Register_Livein,
00898 old_size * ISA_REGISTER_CLASS_COUNT,
00899 new_size * ISA_REGISTER_CLASS_COUNT);
00900 default_size = new_size;
00901 }
00902
00903 REGSET livein = BB_Register_Livein (bb);
00904 if (reg != REGISTER_UNDEFINED)
00905 livein[cl] = REGISTER_SET_Union1 (livein[cl], reg);
00906 }
00907
00908
00909 void REG_LIVE_Finish(void)
00910 {
00911 MEM_POOL_Pop(&Reg_Live_Pool);
00912 MEM_POOL_Delete(&Reg_Live_Pool);
00913 pool_initialized = FALSE;
00914 Register_Livein = NULL;
00915 Register_Kill = NULL;
00916 }