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
00060
00061
00062
00063
00064 #include "defs.h"
00065 #include "erglob.h"
00066 #include "erbe.h"
00067 #include "glob.h"
00068 #include "tracing.h"
00069 #include "config_targ.h"
00070 #include "config.h"
00071
00072 #include "symtab.h"
00073 #include "strtab.h"
00074 #include "be_symtab.h"
00075 #include "targ_isa_lits.h"
00076 #include "topcode.h"
00077 #include "cg.h"
00078 #include "cg_internal.h"
00079 #include "cg_flags.h"
00080 #include "register.h"
00081 #include "tn.h"
00082 #include "tn_set.h"
00083 #include "bb.h"
00084 #include "op.h"
00085 #include "tn_map.h"
00086
00087 #include "cgemit.h"
00088 #include "ttype.h"
00089 #include "calls.h"
00090 #include "const.h"
00091 #include "data_layout.h"
00092 #include "cgexp.h"
00093 #include "targ_sim.h"
00094 #include "whirl2ops.h"
00095 #include "cg_spill.h"
00096 #include "reg_live.h"
00097 #include "lra.h"
00098 #include "cgtarget.h"
00099 #include "entry_exit_targ.h"
00100 #include "targ_abi_properties.h"
00101 #include "cxx_template.h"
00102 #include "targ_isa_registers.h"
00103 #if defined(TARG_PR)
00104 #include "cgexp_Internals.h"
00105 #endif
00106 #ifdef KEY
00107 #include "gtn_universe.h"
00108 #include "gtn_set.h"
00109 #endif
00110 #ifdef TARG_SL
00111 #include "config_debug.h"
00112 #endif
00113
00114 INT64 Frame_Len;
00115 extern BOOL IPFEC_Enable_Edge_Profile;
00116 extern void Clean_Up(BB* bb);
00117
00118
00119 SAVE_REG *Callee_Saved_Regs;
00120 INT32 Callee_Saved_Regs_Count;
00121
00122 #ifdef KEY
00123 STACK<SAVE_REG_LOC> Saved_Callee_Saved_Regs(Malloc_Mem_Pool);
00124 #endif
00125
00126
00127 PREG_NUM *Callee_Saved_Pregs;
00128 PREG_NUM Caller_FP_Preg;
00129 PREG_NUM Caller_GP_Preg;
00130 PREG_NUM Return_Preg;
00131 PREG_NUM GP_Preg;
00132 PREG_NUM Return_Int_Preg[2];
00133 PREG_NUM Return_Float_Preg[2];
00134
00135
00136 static SAVE_REG Return_Address_Reg_Map;
00137 SAVE_REG *Return_Address_Reg = &Return_Address_Reg_Map;
00138
00139
00140 static enum {
00141 undefined_code,
00142 never_code,
00143 no_code,
00144 need_code,
00145 final_code
00146 } GP_Setup_Code = undefined_code;
00147
00148 BOOL LC_Used_In_PU;
00149
00150
00151 #ifdef TARG_IA64
00152 TN *Caller_GP_TN;
00153 TN *Caller_FP_TN;
00154 TN *Caller_Pfs_TN;
00155 TN *ra_intsave_tn;
00156 #else
00157 #ifdef TARG_MIPS
00158 TN *Caller_GP_TN;
00159 #else
00160 static TN *Caller_GP_TN;
00161 #endif
00162 static TN *Caller_FP_TN;
00163 static TN *Caller_Pfs_TN;
00164 static TN *ra_intsave_tn;
00165 #endif // TARG_IA64
00166
00167
00168
00169
00170 static TN *Frame_Len_TN;
00171 static TN *Neg_Frame_Len_TN;
00172
00173 BOOL Gen_Frame_Pointer;
00174
00175 void Split_BB_For_br(BB *bb);
00176
00177
00178 static BOOL Trace_EE = FALSE;
00179
00180 #if defined(TARG_SL)
00181 static BOOL Trace_Stack_Allocation = FALSE;
00182 #endif
00183
00184
00185
00186
00187 #define Use_Scratch_GP(need_gp_setup) \
00188 ((need_gp_setup) && !PU_Has_Calls && !PU_has_region(Get_Current_PU()))
00189
00190
00191
00192
00193
00194
00195
00196
00197
00198 static void
00199 Init_Pregs ( void )
00200 {
00201 INT i;
00202
00203 Caller_FP_Preg = Create_Preg( TY_mtype( Spill_Int_Type ), "caller_FP");
00204 Caller_GP_Preg = Create_Preg( TY_mtype( Spill_Int_Type ), "caller_GP");
00205
00206
00207 Return_Preg = Create_Preg( TY_mtype( Spill_Int_Type ), "return");
00208
00209 for ( i = 0; i < 2; i++ ) {
00210 Return_Int_Preg[i] = Create_Preg( TY_mtype( Spill_Int_Type ), "return_int");
00211 Return_Float_Preg[i] = Create_Preg( TY_mtype( Spill_Float_Type ), "return_float");
00212 }
00213
00214
00215 GP_Preg = Create_Preg( TY_mtype( Spill_Int_Type ), "GP");
00216 }
00217
00218
00219
00220
00221
00222
00223
00224
00225
00226
00227 #ifndef TARG_X8664
00228 static void
00229 Setup_GP_TN_For_PU( ST *pu)
00230 {
00231 REGISTER reg;
00232
00233 if (GP_Setup_Code != undefined_code) {
00234
00235
00236
00237
00238 ;
00239 }
00240 else if (Force_GP_Prolog) {
00241 GP_Setup_Code = need_code;
00242 }
00243 else if (!Is_Caller_Save_GP &&
00244 (Gen_PIC_Call_Shared || Gen_PIC_Shared) &&
00245 ST_visible_outside_dso(pu) )
00246 {
00247
00248
00249 if (PU_Has_Calls || PU_References_GP) {
00250 PU_References_GP = TRUE;
00251 GP_Setup_Code = need_code;
00252 }
00253 else {
00254
00255
00256
00257
00258
00259
00260 GP_Setup_Code = no_code;
00261 }
00262 }
00263 else {
00264 GP_Setup_Code = never_code;
00265 }
00266
00267
00268 TN_MAP_Set( TN_To_PREG_Map, GP_TN, (void *)(INTPTR)GP_Preg );
00269 PREG_To_TN_Array[ GP_Preg ] = GP_TN;
00270 PREG_To_TN_Mtype[ GP_Preg ] = TY_mtype(Spill_Int_Type);
00271
00272
00273
00274
00275
00276
00277
00278
00279
00280 #ifdef TARG_MIPS
00281 reg = REGISTER_gp;
00282 #else
00283 if ( Use_Scratch_GP(GP_Setup_Code == need_code) ) {
00284 REGISTER_SET caller_saves;
00285 REGISTER_SET func_val;
00286 REGISTER_SET func_arg;
00287
00288 REGISTER_Set_Allocatable(REGISTER_CLASS_gp, REGISTER_gp, TRUE);
00289
00290
00291 caller_saves = REGISTER_CLASS_caller_saves(REGISTER_CLASS_gp);
00292 func_val = REGISTER_CLASS_function_value(REGISTER_CLASS_gp);
00293 caller_saves = REGISTER_SET_Difference(caller_saves, func_val);
00294 func_arg = REGISTER_CLASS_function_argument(REGISTER_CLASS_gp);
00295 caller_saves = REGISTER_SET_Difference(caller_saves, func_arg);
00296
00297 reg = REGISTER_SET_Choose(caller_saves);
00298 if ( reg == REGISTER_UNDEFINED ) {
00299
00300
00301
00302
00303 DevWarn("No caller saved register to replace $gp in leaf routine.\n");
00304 reg = REGISTER_gp;
00305 }
00306 } else {
00307
00308 reg = REGISTER_gp;
00309 }
00310 #endif
00311 REGISTER_Set_Allocatable(REGISTER_CLASS_gp, reg, FALSE);
00312 Set_TN_register(GP_TN, reg);
00313 }
00314 #endif
00315
00316
00317
00318
00319
00320
00321
00322
00323
00324 void
00325 Init_Callee_Saved_Regs_for_REGION ( ST *pu, BOOL is_region )
00326 {
00327 INT i;
00328 ISA_REGISTER_CLASS cl;
00329 TN *stn;
00330
00331 #ifdef ABI_PROPERTY_global_ptr
00332 Setup_GP_TN_For_PU( pu );
00333 #endif
00334
00335 if (NULL != RA_TN ) {
00336
00337 if ( stn = PREG_To_TN_Array[ Return_Preg ] )
00338 SAVE_tn(Return_Address_Reg) = stn;
00339 else {
00340 #if 1 // this is left here for reference in case RA is a special register - SC
00341
00342
00343 SAVE_tn(Return_Address_Reg) = Build_RCLASS_TN(ISA_REGISTER_CLASS_integer);
00344 Set_TN_save_creg (SAVE_tn(Return_Address_Reg), TN_class_reg(RA_TN));
00345 #else
00346 SAVE_tn(Return_Address_Reg) = Build_TN_Like(RA_TN);
00347 Set_TN_save_creg (SAVE_tn(Return_Address_Reg), TN_class_reg(RA_TN));
00348 #endif
00349 TN_MAP_Set( TN_To_PREG_Map, SAVE_tn(Return_Address_Reg),
00350 (void *)(INTPTR)Return_Preg );
00351 PREG_To_TN_Array[ Return_Preg ] = SAVE_tn(Return_Address_Reg);
00352 PREG_To_TN_Mtype[ Return_Preg ] = Spill_Int_Mtype;
00353 }
00354 }
00355 ra_intsave_tn = NULL;
00356 Caller_GP_TN = NULL;
00357 Caller_FP_TN = NULL;
00358 Caller_Pfs_TN = NULL;
00359 if (Pfs_TN) {
00360 Caller_Pfs_TN = Gen_Register_TN (ISA_REGISTER_CLASS_integer, Pointer_Size);
00361 Set_TN_save_creg (Caller_Pfs_TN, TN_class_reg(Pfs_TN));
00362 }
00363
00364
00365
00366
00367 if (is_region) {
00368 return;
00369 }
00370
00371 #ifdef TARG_X8664
00372 if( CG_opt_level > 0 &&
00373 Is_Target_32bit() &&
00374 Gen_PIC_Shared &&
00375 !PU_References_GOT ){
00376 TN* ebx_tn = Ebx_TN();
00377 REGISTER_Set_Allocatable( TN_register_class(ebx_tn),
00378 TN_register(ebx_tn),
00379 TRUE );
00380 }
00381 #endif
00382
00383
00384 Callee_Saved_Regs = (SAVE_REG *)Pu_Alloc ( (ISA_REGISTER_CLASS_MAX + 1)
00385 * (REGISTER_MAX + 1)
00386 * sizeof(SAVE_REG) );
00387
00388
00389 Callee_Saved_Regs_Count = 0;
00390 i = 0;
00391 FOR_ALL_ISA_REGISTER_CLASS( cl ) {
00392 REGISTER reg;
00393 REGISTER_SET regset = REGISTER_CLASS_callee_saves(cl);
00394
00395 if (REGISTER_CLASS_multiple_save(cl)) continue;
00396
00397 for ( reg = REGISTER_SET_Choose(regset);
00398 reg != REGISTER_UNDEFINED;
00399 reg = REGISTER_SET_Choose_Next(regset, reg), ++i
00400 ) {
00401 TN *callee_tn;
00402 TN *ded_tn = Build_Dedicated_TN(cl, reg, 0);
00403 DevAssert(ded_tn, ("Missing dedicated TN for callee-saved register %s",
00404 REGISTER_name(cl, reg)));
00405 CALLEE_ded_tn(i) = ded_tn;
00406 callee_tn = Build_RCLASS_TN(cl);
00407 Set_TN_save_creg (callee_tn, TN_class_reg(ded_tn));
00408 CALLEE_tn(i) = callee_tn;
00409 }
00410
00411 }
00412 if (LC_TN) {
00413
00414
00415
00416
00417
00418
00419
00420
00421
00422
00423
00424
00425
00426
00427 TN *callee_tn = Build_RCLASS_TN (ISA_REGISTER_CLASS_integer);
00428 Set_TN_save_creg (callee_tn, TN_class_reg(LC_TN));
00429 CALLEE_tn(i) = callee_tn;
00430 CALLEE_ded_tn(i) = LC_TN;
00431 ++i;
00432 }
00433 Callee_Saved_Regs_Count = i;
00434 }
00435
00436
00437
00438
00439
00440
00441
00442
00443
00444
00445
00446
00447
00448 #ifdef TARG_IA64
00449 static void
00450 vararg_st8_2_st8_spill (BB * bb) {
00451
00452 OP * op ;
00453 FOR_ALL_BB_OPs_REV (bb,op) {
00454 if (!OP_store(op)) continue ;
00455
00456 TN * tn = OP_opnd(op,OP_find_opnd_use(op,OU_storeval));
00457 PREG_NUM preg = TN_To_PREG(tn);
00458
00459 if (preg == 0)
00460 continue;
00461
00462 if (preg < First_Int_Preg_Param_Offset ||
00463 preg > (First_Int_Preg_Param_Offset + MAX_NUMBER_OF_REGISTER_PARAMETERS))
00464 continue ;
00465
00466
00467 OP* new_op = Mk_OP(TOP_st8_spill,
00468 OP_opnd(op,OP_find_opnd_use(op,OU_predicate)),
00469 Gen_Enum_TN(ECV_sthint),
00470 OP_opnd(op,OP_find_opnd_use(op,OU_base)),
00471 OP_opnd(op,OP_find_opnd_use(op,OU_storeval)));
00472 BB_Insert_Op_Before (bb,op,new_op);
00473 BB_Remove_Op (bb,op);
00474 op=new_op;
00475 }
00476 }
00477 #endif
00478
00479 #if defined(KEY) && !defined(TARG_NVISA)
00480 struct Save_user_allocated_saved_regs
00481 {
00482 OPS *ops;
00483 BB *bb;
00484 Save_user_allocated_saved_regs(OPS *o, BB *b) : ops(o), bb(b) { }
00485 void operator() (UINT, ST_ATTR *st_attr) const {
00486 if (ST_ATTR_kind (*st_attr) != ST_ATTR_DEDICATED_REGISTER)
00487 return;
00488 PREG_NUM preg = ST_ATTR_reg_id(*st_attr);
00489 ISA_REGISTER_CLASS rclass;
00490 REGISTER reg;
00491 CGTARG_Preg_Register_And_Class(preg, &rclass, ®);
00492 if (! ABI_PROPERTY_Is_callee(rclass, preg-REGISTER_MIN))
00493 return;
00494 SAVE_REG_LOC sr;
00495 sr.ded_tn = Build_Dedicated_TN(rclass, reg, 0);
00496 DevAssert(sr.ded_tn, ("Missing dedicated TN for callee-saved register %s",
00497 REGISTER_name(rclass, reg)));
00498 if (Is_Unique_Callee_Saved_Reg (sr.ded_tn)) {
00499 sr.temp = CGSPILL_Get_TN_Spill_Location (sr.ded_tn, CGSPILL_LCL);
00500 sr.user_allocated = TRUE;
00501
00502 CGSPILL_Store_To_Memory (sr.ded_tn, sr.temp, ops, CGSPILL_LCL, bb);
00503 Set_OP_no_move_before_gra(OPS_last(ops));
00504 Saved_Callee_Saved_Regs.Push(sr);
00505 }
00506 }
00507 };
00508 #endif
00509
00510
00511
00512
00513
00514
00515
00516
00517
00518
00519
00520
00521
00522
00523
00524
00525
00526
00527
00528
00529
00530
00531
00532
00533 static void
00534 Generate_Entry (BB *bb, BOOL gra_run )
00535 {
00536 INT callee_num;
00537 TN *stn;
00538 OP *op;
00539 OPS ops = OPS_EMPTY;
00540 ANNOTATION *ant = ANNOT_Get (BB_annotations(bb), ANNOT_ENTRYINFO);
00541 ENTRYINFO *ent_info = ANNOT_entryinfo(ant);
00542 ST *st = ENTRYINFO_name(ent_info);
00543
00544 if ((BB_rid(bb) != NULL) && ( RID_level(BB_rid(bb)) >= RL_CGSCHED )) {
00545
00546 return;
00547 }
00548
00549 #ifdef TARG_IA64
00550
00551
00552
00553 if (BB_handler(bb)) {
00554 return;
00555 }
00556 #endif
00557 if ( Trace_EE ) {
00558 #pragma mips_frequency_hint NEVER
00559 fprintf ( TFile,
00560 "\n%s<calls> Generating entry for %s (BB:%d)\n",
00561 DBar, ST_name(st), BB_id(bb) );
00562
00563 }
00564
00565 if (!BB_handler(bb)) {
00566
00567 EETARG_Save_Pfs (Caller_Pfs_TN, &ops);
00568
00569 #ifdef ABI_PROPERTY_stack_ptr
00570 #ifdef TARG_X8664
00571
00572 if ( Gen_Frame_Pointer && PUSH_FRAME_POINTER_ON_STACK ) {
00573 Build_OP( Is_Target_64bit() ? TOP_pushq : TOP_pushl, SP_TN, FP_TN, SP_TN,
00574 &ops );
00575
00576 Exp_COPY( FP_TN, SP_TN, &ops );
00577 }
00578 #endif
00579
00580
00581
00582
00583
00584 Exp_Spadjust (SP_TN, Neg_Frame_Len_TN, V_NONE, &ops);
00585
00586
00587 if ( Gen_Frame_Pointer && !PUSH_FRAME_POINTER_ON_STACK ) {
00588
00589
00590
00591 if (ABI_PROPERTY_Is_callee (TN_register_class(FP_TN),
00592 REGISTER_machine_id(TN_register_class(FP_TN), TN_register(FP_TN)) ))
00593 {
00594
00595 if ( Caller_FP_TN == NULL ) {
00596
00597 if ( stn = PREG_To_TN_Array[ Caller_FP_Preg ] )
00598 Caller_FP_TN = stn;
00599 else {
00600
00601 Caller_FP_TN = Gen_Register_TN (
00602 ISA_REGISTER_CLASS_integer, TY_size(Spill_Int_Type));
00603 Set_TN_save_creg (Caller_FP_TN, TN_class_reg(FP_TN));
00604 TN_MAP_Set( TN_To_PREG_Map, Caller_FP_TN,
00605 (void *)(INTPTR)Caller_FP_Preg );
00606 PREG_To_TN_Array[ Caller_FP_Preg ] = Caller_FP_TN;
00607 PREG_To_TN_Mtype[ Caller_FP_Preg ] = TY_mtype(Spill_Int_Type);
00608 }
00609 }
00610
00611 Exp_COPY (Caller_FP_TN, FP_TN, &ops);
00612 Set_OP_no_move_before_gra(OPS_last(&ops));
00613 }
00614
00615
00616 Exp_Spadjust (FP_TN, Frame_Len_TN, V_NONE, &ops);
00617 }
00618 ENTRYINFO_sp_adj(ent_info) = OPS_last(&ops);
00619 #endif //ABI_PROPERTY_stack_ptr
00620
00621 #ifdef TARG_SL
00622
00623 if (DEBUG_Stack_Check & STACK_ENTRY_CHECK) {
00624 Build_OP(TOP_break, &ops);
00625 Set_OP_no_move_before_gra(OPS_last(&ops));
00626 Set_OP_volatile(OPS_last(&ops));
00627 }
00628 #endif
00629
00630 #if defined(KEY) && !defined(TARG_NVISA)
00631
00632
00633 for (INT i = 0; i < Saved_Callee_Saved_Regs.Elements(); i++) {
00634 SAVE_REG_LOC sr = Saved_Callee_Saved_Regs.Top_nth(i);
00635
00636 #ifdef TARG_X8664
00637 if (sr.temp == NULL)
00638 continue;
00639 #endif
00640 CGSPILL_Store_To_Memory (sr.ded_tn, sr.temp, &ops, CGSPILL_LCL, bb);
00641 Set_OP_no_move_before_gra(OPS_last(&ops));
00642 }
00643
00644
00645 if ( ST_ATTR_Table_Size (CURRENT_SYMTAB)) {
00646 For_all_entries(*Scope_tab[CURRENT_SYMTAB].st_attr_tab,
00647 Save_user_allocated_saved_regs(&ops, bb), 1);
00648 }
00649 #endif
00650 }
00651
00652 if ( gra_run ) {
00653 #ifdef TARG_IA64
00654
00655 FOR_ALL_BB_OPs (REGION_First_BB, op){
00656 for (INT i = 0; i < OP_opnds(op); i++) {
00657 TN* opnd = OP_opnd(op, i);
00658 if (!TN_is_register (opnd) || !TN_is_dedicated(opnd)) {
00659 continue;
00660 }
00661 PREG_NUM pnum = TN_To_PREG (opnd);
00662 if (Is_Formal_Preg (pnum)){
00663 Exp_COPY(opnd,opnd,&ops);
00664 Set_OP_no_move_before_gra(OPS_last(&ops));
00665 }
00666 }
00667 }
00668 #endif
00669
00670
00671 for ( callee_num = 0; callee_num < Callee_Saved_Regs_Count; ++callee_num ) {
00672 TN *callee_tn = CALLEE_tn(callee_num);
00673 if ( TN_is_save_reg(callee_tn)
00674 && !REGISTER_CLASS_multiple_save(TN_register_class(callee_tn)))
00675 {
00676 Exp_COPY ( callee_tn, CALLEE_ded_tn(callee_num), &ops );
00677 Set_OP_no_move_before_gra(OPS_last(&ops));
00678 }
00679 }
00680 }
00681
00682
00683
00684
00685
00686 if (NULL != RA_TN) {
00687 if ( PU_has_return_address(Get_Current_PU()) ) {
00688 #ifndef TARG_NVISA
00689
00690
00691
00692
00693 ST *ra_sv_sym = Find_Special_Return_Address_Symbol();
00694
00695
00696
00697
00698
00699
00700
00701 if ( gra_run ) {
00702 TN *ra_sv_tn = Build_TN_Like(RA_TN);
00703 Set_TN_save_creg (ra_sv_tn, TN_class_reg(RA_TN));
00704 Set_TN_spill(ra_sv_tn, ra_sv_sym);
00705 Exp_COPY (ra_sv_tn, RA_TN, &ops);
00706 if (MTYPE_byte_size(Pointer_Mtype) < MTYPE_byte_size(Spill_Int_Mtype) ) {
00707
00708
00709
00710 ra_sv_sym = ST_base(ra_sv_sym);
00711 Set_TN_spill(ra_sv_tn, ra_sv_sym);
00712 }
00713 CGSPILL_Store_To_Memory (ra_sv_tn, ra_sv_sym, &ops, CGSPILL_LCL, bb);
00714 } else {
00715 CGSPILL_Store_To_Memory (RA_TN, ra_sv_sym, &ops, CGSPILL_LCL, bb);
00716 }
00717 #endif // ! TARG_NVISA
00718 }
00719 #ifdef TARG_IA64
00720 else if (PU_Has_Calls || IPFEC_Enable_Edge_Profile){
00721
00722
00723
00724
00725
00726
00727
00728
00729
00730
00731
00732
00733
00734
00735
00736
00737
00738
00739
00740
00741
00742 if ( TN_register_class(RA_TN) != ISA_REGISTER_CLASS_integer)
00743 #else
00744 else {
00745 if (gra_run && PU_Has_Calls
00746 && TN_register_class(RA_TN) != ISA_REGISTER_CLASS_integer)
00747 #endif
00748 {
00749
00750
00751
00752
00753
00754
00755 if (ra_intsave_tn == NULL) {
00756 ra_intsave_tn = Build_RCLASS_TN (ISA_REGISTER_CLASS_integer);
00757 Set_TN_save_creg (ra_intsave_tn, TN_class_reg(RA_TN));
00758 }
00759 Exp_COPY (ra_intsave_tn, RA_TN, &ops );
00760 }
00761 #if defined(TARG_SL)
00762 else if (CG_opt_level <= 1) {
00763 #else
00764 else {
00765 #endif
00766 Exp_COPY (SAVE_tn(Return_Address_Reg), RA_TN, &ops );
00767 }
00768 Set_OP_no_move_before_gra(OPS_last(&ops));
00769 }
00770 }
00771
00772 if ( gra_run )
00773 EETARG_Save_Extra_Callee_Tns (&ops);
00774
00775 #ifdef ABI_PROPERTY_global_ptr // x86_64 does not use GP
00776
00777 if (GP_Setup_Code == need_code) {
00778
00779
00780
00781
00782
00783
00784
00785 if ( !Use_Scratch_GP( TRUE ) ) {
00786 if ( Caller_GP_TN == NULL ) {
00787 if ( stn = PREG_To_TN_Array[ Caller_GP_Preg ] )
00788 Caller_GP_TN = stn;
00789 else {
00790 Caller_GP_TN = Gen_Register_TN (
00791 ISA_REGISTER_CLASS_integer, Pointer_Size);
00792 Set_TN_save_creg (Caller_GP_TN, TN_class_reg(GP_TN));
00793 TN_MAP_Set( TN_To_PREG_Map, Caller_GP_TN, (void *)(INTPTR)Caller_GP_Preg );
00794 PREG_To_TN_Array[ Caller_GP_Preg ] = Caller_GP_TN;
00795 PREG_To_TN_Mtype[ Caller_GP_Preg ] = TY_mtype(Spill_Int_Type);
00796 }
00797 }
00798 Exp_COPY (Caller_GP_TN, GP_TN, &ops);
00799 }
00800
00801
00802
00803
00804 if (ST_is_not_used(st))
00805 ;
00806 else if (Gen_PIC_Call_Shared && CGEXP_gp_prolog_call_shared
00807 && (MTYPE_byte_size(Pointer_Mtype) == MTYPE_byte_size(MTYPE_I4)) )
00808 {
00809
00810
00811
00812 TN *gp_value_tn = Gen_Symbol_TN(st, 0, TN_RELOC_GPIDENT);
00813 Set_TN_size(gp_value_tn, 4);
00814 Exp_OP1 (OPC_I4INTCONST, GP_TN, gp_value_tn, &ops);
00815 }
00816 else {
00817
00818 TN *cur_pu_got_disp_tn = Gen_Symbol_TN(st, 0, TN_RELOC_GPSUB);
00819 TN *got_disp_tn = Gen_Register_TN (
00820 ISA_REGISTER_CLASS_integer, Pointer_Size);
00821
00822 Set_TN_size(cur_pu_got_disp_tn, 4);
00823 Exp_OP1 (OPC_I4INTCONST, got_disp_tn, cur_pu_got_disp_tn, &ops);
00824
00825
00826 Exp_ADD (Pointer_Mtype, GP_TN, Ep_TN, got_disp_tn, &ops);
00827 }
00828 }
00829 else if (Is_Caller_Save_GP && PU_Has_Calls && !Constant_GP
00830 && PREG_To_TN_Array[ Caller_GP_Preg ] != NULL)
00831 {
00832
00833
00834 Caller_GP_TN = PREG_To_TN_Array[ Caller_GP_Preg ];
00835 Exp_COPY (Caller_GP_TN, GP_TN, &ops);
00836 }
00837 #endif
00838
00839
00840 FOR_ALL_OPS_OPs(&ops, op)
00841 OP_srcpos(op) = ENTRYINFO_srcpos(ent_info);
00842
00843
00844 if ( Trace_EE ) {
00845 #pragma mips_frequency_hint NEVER
00846 Print_OPS (&ops);
00847 }
00848
00849 #ifdef TARG_X8664
00850 if( Is_Target_32bit() && Gen_PIC_Shared ){
00851 EETARG_Generate_PIC_Entry_Code( bb, &ops );
00852 }
00853 #endif
00854 #ifdef TARG_IA64
00855 if (TY_is_varargs(Ty_Table[PU_prototype(Get_Current_PU())])) {
00856 vararg_st8_2_st8_spill (bb);
00857 }
00858 #endif
00859
00860
00861 BB_Prepend_Ops(bb, &ops);
00862 }
00863
00864
00865
00866
00867
00868
00869
00870
00871
00872
00873 inline BOOL
00874 Is_Function_Value(TN *tn)
00875 {
00876 if (TN_is_dedicated(tn)) {
00877 REGISTER reg = TN_register(tn);
00878 ISA_REGISTER_CLASS rc = TN_register_class(tn);
00879 return REGISTER_SET_MemberP(REGISTER_CLASS_function_value(rc), reg);
00880 }
00881 return FALSE;
00882 }
00883
00884
00885
00886
00887
00888
00889
00890
00891
00892
00893
00894
00895 static OP *
00896 Find_Call_Addr_Load(BB *call_bb, INT *iopnd)
00897 {
00898 OP *op;
00899
00900 for (op = BB_last_op(call_bb); op; op = OP_prev(op)) {
00901 if (OP_results(op) == 1) {
00902 TN *tn = OP_result(op,0);
00903 if (TN_is_ep_reg(tn)) {
00904 INT i;
00905
00906 if (!OP_load(op)) break;
00907
00908 for (i = 0; i < OP_opnds(op); ++i) {
00909 tn = OP_opnd(op, i);
00910 if (TN_is_symbol(tn)) {
00911 *iopnd = i;
00912 return op;
00913 }
00914 }
00915
00916 break;
00917 }
00918 }
00919 }
00920
00921 return NULL;
00922 }
00923
00924
00925
00926
00927
00928
00929
00930
00931
00932
00933
00934
00935 static BB *
00936 Can_Be_Tail_Call(ST *pu_st, BB *exit_bb)
00937 {
00938 OP *op;
00939 hTN_MAP fvals;
00940 PLOC ploc;
00941 TY_IDX func_type;
00942 ST *st;
00943 INT addr_opnd;
00944 OP *addr_op;
00945 ANNOTATION *ant;
00946 CALLINFO *call_info;
00947 ST *call_st;
00948 WN *call_wn;
00949 BB *pred;
00950
00951
00952
00953 pred = BB_Unique_Predecessor(exit_bb);
00954 if (!pred || !BB_call(pred)) return NULL;
00955
00956
00957
00958
00959 if (BB_Has_Addr_Taken_Label(exit_bb)) return NULL;
00960
00961
00962
00963 ant = ANNOT_Get(BB_annotations(pred), ANNOT_CALLINFO);
00964 call_info = ANNOT_callinfo(ant);
00965 call_st = CALLINFO_call_st(call_info);
00966 call_wn = CALLINFO_call_wn(call_info);
00967
00968
00969
00970
00971
00972
00973
00974
00975
00976
00977
00978
00979
00980
00981 addr_op = NULL;
00982 if ( !Is_Caller_Save_GP
00983 && (Gen_PIC_Call_Shared || Gen_PIC_Shared)
00984 && ST_visible_outside_dso(pu_st))
00985 {
00986
00987
00988
00989 if (call_st == NULL) return NULL;
00990
00991
00992
00993
00994 if (!ST_visible_outside_dso(call_st)) return NULL;
00995
00996
00997
00998 if (ST_is_preemptible(call_st)) {
00999 TN *tn;
01000
01001 #ifdef TARG_X8664
01002 addr_op = BB_xfer_op( pred );
01003 addr_opnd = 0;
01004 if( addr_op == NULL ){
01005 return NULL;
01006 }
01007 #else
01008 addr_op = Find_Call_Addr_Load(pred, &addr_opnd);
01009 if (addr_op == NULL) return NULL;
01010 tn = OP_opnd(addr_op, addr_opnd);
01011 if (TN_is_reloc_call16(tn)) {
01012 #if 1
01013
01014
01015
01016
01017
01018
01019 return NULL;
01020 #else
01021 if (!Enable_GOT_Call_Conversion) return NULL;
01022 #endif
01023 } else if (TN_is_reloc_got_disp(tn)) {
01024
01025 addr_op = NULL;
01026 } else {
01027 return NULL;
01028 }
01029 #endif
01030 }
01031 }
01032
01033 #ifdef KEY
01034
01035
01036 if (call_st && PU_has_return_address(Pu_Table[ST_pu(call_st)]))
01037 return NULL;
01038 #endif
01039
01040
01041
01042
01043
01044 if (!BE_ST_pu_has_valid_addr_flags(Get_Current_PU_ST())) return NULL;
01045 INT i;
01046 FOREACH_SYMBOL (CURRENT_SYMTAB, st, i) {
01047 if (ST_class(st) != CLASS_VAR) continue;
01048 if (BE_ST_addr_used_locally(st) || BE_ST_addr_passed(st)) return NULL;
01049 }
01050
01051
01052
01053
01054
01055 func_type = call_st ? ST_pu_type(call_st) : WN_ty(call_wn);
01056 ploc = Setup_Output_Parameter_Locations(func_type);
01057 if (call_wn == NULL) {
01058 TYLIST_IDX tl;
01059 for (tl = TY_parms(func_type); tl != (TYLIST_IDX) NULL; tl = TYLIST_next(tl)) {
01060 ploc = Get_Output_Parameter_Location(TYLIST_item(tl));
01061 if (PLOC_on_stack(ploc)) return NULL;
01062 }
01063 } else {
01064 INT i;
01065 INT num_parms = WN_num_actuals(call_wn);
01066 for (i = 0; i < num_parms; i++) {
01067 ploc = Get_Output_Parameter_Location (TY_Of_Parameter(WN_actual(call_wn,i)));
01068 if (PLOC_on_stack(ploc)) return NULL;
01069 }
01070 }
01071
01072 #ifdef TARG_X8664
01073
01074
01075
01076 if( Is_Target_32bit() ){
01077 bool caller_uses_stack = false;
01078
01079 const RETURN_INFO caller_return_info =
01080 Get_Return_Info( TY_ret_type(ST_pu_type(pu_st)),
01081 No_Simulated,
01082 PU_ff2c_abi(Pu_Table[ST_pu(pu_st)]) );
01083
01084 for( int i = 0; i < RETURN_INFO_count(caller_return_info); i++ ){
01085 const TYPE_ID type = RETURN_INFO_mtype( caller_return_info, i );
01086 if( MTYPE_is_float( type ) ){
01087 caller_uses_stack = true;
01088 break;
01089 }
01090 }
01091
01092 const RETURN_INFO callee_return_info =
01093 Get_Return_Info( TY_ret_type(func_type),
01094 No_Simulated,
01095 call_st ? PU_ff2c_abi(Pu_Table[ST_pu(call_st)]) : FALSE );
01096
01097 for( int i = 0; i < RETURN_INFO_count(callee_return_info); i++ ){
01098 const TYPE_ID type = RETURN_INFO_mtype( callee_return_info, i );
01099 if( MTYPE_is_float( type ) ){
01100 if( !caller_uses_stack )
01101 return NULL;
01102 }
01103 }
01104 }
01105
01106
01107
01108
01109 if( Is_Target_32bit() &&
01110 PU_References_GOT ){
01111 return NULL;
01112 }
01113 #endif // TARG_X8664
01114
01115
01116
01117
01118
01119
01120
01121
01122
01123 MEM_POOL_Push(&MEM_local_pool);
01124 fvals = hTN_MAP_Create(&MEM_local_pool);
01125
01126 FOR_ALL_BB_OPs_FWD(exit_bb, op) {
01127 if (OP_copy(op)) {
01128 TN *src = OP_opnd(op,OP_COPY_OPND);
01129 TN *dst = OP_result(op,0);
01130 BOOL src_is_fval = Is_Function_Value(src);
01131 BOOL dst_is_fval = Is_Function_Value(dst);
01132
01133 if (!src_is_fval) {
01134 src = (TN *) hTN_MAP_Get(fvals, src);
01135 if (src) src_is_fval = TRUE;
01136 }
01137
01138 if (dst_is_fval) {
01139 if ( src_is_fval
01140 && (TN_register_and_class(src) == TN_register_and_class(dst))
01141 ) continue;
01142 } else if (src_is_fval) {
01143 hTN_MAP_Set(fvals, dst, src);
01144 continue;
01145 }
01146 }
01147
01148 MEM_POOL_Pop(&MEM_local_pool);
01149 return NULL;
01150 }
01151 MEM_POOL_Pop(&MEM_local_pool);
01152
01153 #ifndef TARG_X8664
01154
01155
01156
01157 if (addr_op) {
01158 TN *old_tn = OP_opnd(addr_op, addr_opnd);
01159 TN *new_tn = Dup_TN(old_tn);
01160 Set_TN_is_reloc_got_disp(new_tn);
01161 Set_OP_opnd(addr_op, addr_opnd, new_tn);
01162 EMT_Change_Symbol_To_Weak(call_st);
01163 Set_ST_is_weak_symbol(call_st);
01164 }
01165 #endif
01166
01167 return pred;
01168 }
01169
01170
01171
01172
01173
01174
01175
01176
01177 static BOOL Can_Do_Tail_Calls_For_PU ()
01178 {
01179
01180
01181 if (Current_PU_Stack_Model == SMODEL_DYNAMIC) return FALSE;
01182
01183
01184 if (PU_has_region(Get_Current_PU())) return FALSE;
01185
01186
01187
01188
01189 if (PU_has_unknown_control_flow (Get_Current_PU())) return FALSE;
01190
01191
01192
01193
01194
01195
01196
01197
01198 for (BB *bb = REGION_First_BB; bb; bb = BB_next(bb)) {
01199 if (BB_call(bb)) {
01200 const char *name;
01201 INT len;
01202 ANNOTATION *callant = ANNOT_Get(BB_annotations(bb), ANNOT_CALLINFO);
01203 CALLINFO *callinfo = ANNOT_callinfo(callant);
01204 ST *st = CALLINFO_call_st(callinfo);
01205 if (st == NULL) continue;
01206 name = ST_name(st);
01207 len = strlen(name);
01208 if (len >= 6 && strcmp(name + len - 6, "setjmp") == 0) return FALSE;
01209 if (len >= 10 && strcmp(name+len-10, "getcontext") == 0) return FALSE;
01210 }
01211 }
01212 return TRUE;
01213 }
01214
01215
01216
01217
01218
01219
01220
01221
01222
01223
01224
01225
01226
01227
01228
01229
01230 void
01231 Optimize_Tail_Calls(ST *pu)
01232 {
01233 BB_LIST *elist;
01234 BOOL have_tail_call = FALSE;
01235
01236
01237 if ( !CG_tail_call
01238 || CG_opt_level == 0
01239 || !Can_Do_Tail_Calls_For_PU ()) return;
01240
01241
01242
01243 for ( elist = Exit_BB_Head; elist; elist = BB_LIST_rest(elist) ) {
01244 BB *call_bb;
01245 BB *exit_bb = BB_LIST_first(elist);
01246
01247
01248
01249 if (call_bb = Can_Be_Tail_Call(pu, exit_bb)) {
01250 OP *jmp_op;
01251 OP *call_op = BB_last_op(call_bb);
01252 Is_True(OP_call(call_op), ("call block didn't end in a call inst"));
01253
01254 if (Trace_EE) {
01255 #pragma mips_frequency_hint NEVER
01256 fprintf(TFile, "%s<calls> call block before tail call optimization:\n",
01257 DBar);
01258 Print_BB(call_bb);
01259 fprintf(TFile, "\n<calls> exit block before tail call optimization:\n");
01260 Print_BB(exit_bb);
01261 }
01262
01263
01264
01265 jmp_op = EETARG_Build_Jump_Instead_Of_Call (call_op);
01266 Set_OP_tail_call(jmp_op);
01267 BB_Insert_Op_Before(call_bb, call_op, jmp_op);
01268 BB_Remove_Op(call_bb, call_op);
01269
01270
01271
01272
01273
01274 BB_Transfer_Exitinfo(exit_bb, call_bb);
01275 Unlink_Pred_Succ(call_bb, exit_bb);
01276 Exit_BB_Head = BB_LIST_Delete(exit_bb, Exit_BB_Head);
01277 Exit_BB_Head = BB_LIST_Push(call_bb, Exit_BB_Head, &MEM_pu_pool);
01278 Remove_BB(exit_bb);
01279
01280 if (Trace_EE) {
01281 #pragma mips_frequency_hint NEVER
01282 fprintf(TFile, "\n<calls> exit block after tail call optimization:\n");
01283 Print_BB(call_bb);
01284 }
01285
01286 have_tail_call = TRUE;
01287 }
01288 }
01289
01290
01291
01292
01293
01294
01295 if (have_tail_call) {
01296 BB *bb;
01297 for (bb = REGION_First_BB; bb; bb = BB_next(bb)) {
01298 if (BB_call(bb) && !BB_exit(bb)) goto done;
01299 }
01300 PU_Has_Calls = FALSE;
01301 done:
01302 ;
01303 }
01304 }
01305
01306
01307
01308
01309
01310
01311
01312
01313
01314
01315
01316
01317 static void
01318 Target_Unique_Exit (
01319 BB *bb,
01320 BB *unique_exit_bb,
01321 TN *rtn_tns[ISA_REGISTER_CLASS_MAX+1][REGISTER_MAX+1])
01322 {
01323 OP *op;
01324
01325
01326
01327
01328 FOR_ALL_BB_OPs_REV(bb, op) {
01329 INT i;
01330
01331
01332
01333 for (i = OP_results(op) - 1; i >= 0; --i) {
01334 TN *tn = OP_result(op,i);
01335 if ( Is_Function_Value(tn) ) {
01336 TN *new_tn;
01337 REGISTER reg = TN_register(tn);
01338 ISA_REGISTER_CLASS rc = TN_register_class(tn);
01339
01340
01341
01342
01343
01344 new_tn = rtn_tns[rc][reg];
01345 if ( new_tn == NULL ) {
01346 new_tn = Dup_TN_Even_If_Dedicated(tn);
01347 if (TN_is_float(tn)) {
01348
01349
01350
01351
01352 INT tn_size = OP_result_size(op,i) / 8;
01353 #ifdef KEY
01354
01355
01356
01357
01358
01359
01360
01361 if (OP_copy(op))
01362 tn_size = TN_size(OP_opnd(op, OP_COPY_OPND));
01363 #endif
01364 Set_TN_size(new_tn, tn_size);
01365 }
01366 }
01367
01368
01369
01370 Set_OP_result(op, i, new_tn);
01371
01372
01373
01374
01375
01376 if ( rtn_tns[rc][reg] == NULL ) {
01377 ANNOTATION *ant = ANNOT_Get (BB_annotations(unique_exit_bb),
01378 ANNOT_EXITINFO);
01379 EXITINFO *exit_info = ANNOT_exitinfo(ant);
01380 OPS ops = OPS_EMPTY;
01381 rtn_tns[rc][reg] = new_tn;
01382 Exp_COPY(tn, new_tn, &ops);
01383 OP_srcpos(OPS_last(&ops)) = EXITINFO_srcpos(exit_info);
01384 BB_Prepend_Ops(unique_exit_bb, &ops);
01385 }
01386
01387 #if defined(TARG_SL)
01388
01389
01390
01391
01392
01393
01394
01395
01396
01397
01398
01399 OP * opaf = OP_next(op);
01400 while (opaf != NULL) {
01401 for (int j = OP_opnds(opaf) - 1; j >= 0; --j) {
01402 TN * tnop = OP_opnd(opaf, j);
01403 if (tnop == tn) {
01404 if (Trace_EE) {
01405 #pragma mips_frequency_hint NEVER
01406 fprintf(TFile, "\nReplace TN %d with %d in Target_Unique_Exit line %d\n",
01407 TN_number(tnop), TN_number(new_tn), __LINE__);
01408 }
01409 Set_OP_opnd(opaf, j, new_tn);
01410 }
01411 }
01412 opaf = OP_next(opaf);
01413 }
01414 #endif
01415
01416 }
01417 }
01418
01419
01420
01421 if ( OP_same_res(op) ) {
01422 INT i;
01423
01424 for ( i = 0; i < OP_opnds(op); ++i ) {
01425 TN *tn = OP_opnd(op,i);
01426 if ( Is_Function_Value(tn) ) {
01427 REGISTER reg = TN_register(tn);
01428 ISA_REGISTER_CLASS rc = TN_register_class(tn);
01429 TN *new_tn = rtn_tns[rc][reg];
01430 FmtAssert(new_tn, ("use before def of return value TN in BB:%d",
01431 BB_id(bb)));
01432 Set_OP_opnd(op, i, new_tn);
01433 }
01434 }
01435 }
01436 }
01437
01438
01439
01440 if ( BB_next(bb) == unique_exit_bb ) {
01441 Target_Simple_Fall_Through_BB(bb, unique_exit_bb);
01442 } else {
01443 Add_Goto(bb, unique_exit_bb);
01444 }
01445 }
01446
01447
01448
01449
01450
01451
01452
01453
01454
01455
01456 static void
01457 Generate_Unique_Exit(void)
01458 {
01459 BB_LIST *elist;
01460 BB *unique_exit_bb;
01461 INT exits;
01462
01463
01464
01465
01466
01467 TN *rtn_tns[ISA_REGISTER_CLASS_MAX+1][REGISTER_MAX+1];
01468
01469
01470
01471 if ( !CG_unique_exit
01472 || PU_has_region(Get_Current_PU()))
01473
01474
01475 {
01476 return;
01477 }
01478
01479
01480
01481
01482 exits = 0;
01483 for ( elist = Exit_BB_Head; elist; elist = BB_LIST_rest(elist) ) {
01484 BB *bb = BB_LIST_first(elist);
01485 exits += !BB_call(bb);
01486 }
01487 if (exits < 2) return;
01488
01489
01490
01491 BZERO(rtn_tns, sizeof(rtn_tns));
01492 unique_exit_bb = NULL;
01493 for ( elist = Exit_BB_Head; elist; elist = BB_LIST_rest(elist) ) {
01494 BB *bb = BB_LIST_first(elist);
01495
01496
01497
01498 if (BB_call(bb)) continue;
01499
01500
01501
01502
01503
01504 if (unique_exit_bb == NULL) {
01505 unique_exit_bb = Gen_And_Insert_BB_After(bb);
01506 BB_rid(unique_exit_bb) = BB_rid(bb);
01507 BB_Transfer_Exitinfo(bb, unique_exit_bb);
01508 Exit_BB_Head = BB_LIST_Push(unique_exit_bb, Exit_BB_Head, &MEM_pu_pool);
01509 } else {
01510 ANNOTATION *ant = ANNOT_Get(BB_annotations(bb), ANNOT_EXITINFO);
01511 BB_annotations(bb) = ANNOT_Unlink(BB_annotations(bb), ant);
01512 Reset_BB_exit(bb);
01513 }
01514 Exit_BB_Head = BB_LIST_Delete(bb, Exit_BB_Head);
01515
01516
01517
01518 Target_Unique_Exit(bb, unique_exit_bb, rtn_tns);
01519 }
01520 }
01521
01522 #ifdef TARG_X8664 // do we need this for other processors? - SC
01523 void Adjust_SP_After_Call( BB* bb )
01524 {
01525 OP* op = BB_last_op(bb);
01526 if( op == NULL || !OP_call( op ) )
01527 return;
01528
01529 const ANNOTATION* ant = ANNOT_Get( BB_annotations(bb), ANNOT_CALLINFO );
01530 const CALLINFO* call_info = ANNOT_callinfo(ant);
01531 const ST* call_st = CALLINFO_call_st(call_info);
01532 const WN* call_wn = CALLINFO_call_wn(call_info);
01533 const TY_IDX call_ty = call_st != NULL ? ST_pu_type(call_st) : WN_ty(call_wn);
01534 const BOOL ff2c_abi =
01535 call_st != NULL ? PU_ff2c_abi( Pu_Table[ST_pu(call_st)] ) : FALSE;
01536 const RETURN_INFO return_info = Get_Return_Info( TY_ret_type(call_ty),
01537 No_Simulated,
01538 ff2c_abi );
01539
01540
01541
01542
01543 if( RETURN_INFO_return_via_first_arg(return_info) ||
01544 TY_return_to_param( call_ty ) ){
01545 if (call_st != NULL && strncmp(ST_name(call_st), "_TRANSFER", 9) == 0)
01546 return;
01547 OPS ops = OPS_EMPTY;
01548 Exp_SUB( Pointer_Mtype, SP_TN, SP_TN, Gen_Literal_TN(4,0), &ops );
01549 BB_Append_Ops( bb, &ops );
01550
01551 if( Trace_EE ){
01552 #pragma mips_frequency_hint NEVER
01553 fprintf( TFile, "%sDecrease SP by 4 bytes after call in BB:%d\n",
01554 DBar, BB_id(bb) );
01555 Print_OPS( &ops );
01556 }
01557 }
01558 }
01559 #endif
01560
01561
01562
01563
01564
01565
01566
01567
01568
01569
01570
01571
01572
01573
01574
01575
01576
01577
01578
01579 static void
01580 Generate_Exit (
01581 ST *st,
01582 BB *bb,
01583 BOOL gra_run,
01584 BOOL is_region)
01585
01586 {
01587 INT callee_num;
01588 TN *stn;
01589 OP *op;
01590 OPS ops = OPS_EMPTY;
01591 ANNOTATION *ant = ANNOT_Get (BB_annotations(bb), ANNOT_EXITINFO);
01592 EXITINFO *exit_info = ANNOT_exitinfo(ant);
01593 BB *bb_epi;
01594
01595 if ( is_region && gra_run ) {
01596
01597
01598
01599 return;
01600 }
01601
01602 if ((BB_rid(bb) != NULL) && ( RID_level(BB_rid(bb)) >= RL_CGSCHED )) {
01603 if (gra_run) {
01604
01605
01606
01607 bb_epi = Gen_And_Insert_BB_After(bb);
01608 BB_Transfer_Exitinfo(bb, bb_epi);
01609 Target_Simple_Fall_Through_BB(bb,bb_epi);
01610 BB_rid(bb_epi) = Current_Rid;
01611 Exit_BB_Head = BB_LIST_Delete(bb, Exit_BB_Head);
01612 Exit_BB_Head = BB_LIST_Push(bb_epi, Exit_BB_Head, &MEM_pu_pool);
01613 } else {
01614
01615
01616
01617 return;
01618 }
01619 } else {
01620 bb_epi = bb;
01621 }
01622
01623 if ( Trace_EE ) {
01624 #pragma mips_frequency_hint NEVER
01625 fprintf ( TFile,
01626 "\n%s<calls> Generating exit for %s (BB:%d)\n",
01627 DBar, ST_name(st), BB_id(bb_epi) );
01628 }
01629
01630
01631 if (GP_Setup_Code == need_code) {
01632
01633
01634
01635
01636
01637
01638
01639 if ( !Use_Scratch_GP( TRUE ) ) {
01640 if ( Caller_GP_TN == NULL ) {
01641 if ( stn = PREG_To_TN_Array[ Caller_GP_Preg ] )
01642 Caller_GP_TN = stn;
01643 else {
01644 Caller_GP_TN = Gen_Register_TN (
01645 ISA_REGISTER_CLASS_integer, Pointer_Size);
01646 TN_MAP_Set( TN_To_PREG_Map, Caller_GP_TN, (void *)(INTPTR)Caller_GP_Preg );
01647 PREG_To_TN_Array[ Caller_GP_Preg ] = Caller_GP_TN;
01648 PREG_To_TN_Mtype[ Caller_GP_Preg ] = TY_mtype(Spill_Int_Type);
01649 }
01650 }
01651 Exp_COPY (GP_TN, Caller_GP_TN, &ops);
01652 }
01653 }
01654
01655 if ( gra_run )
01656 EETARG_Restore_Extra_Callee_Tns (&ops);
01657
01658 #ifdef TARG_X8664
01659 if( Is_Target_32bit() && Gen_PIC_Shared ){
01660 EETARG_Generate_PIC_Exit_Code( bb_epi, &ops );
01661 }
01662 #endif
01663
01664 if (NULL != RA_TN) {
01665 if ( PU_has_return_address(Get_Current_PU()) ) {
01666 #ifndef TARG_NVISA
01667
01668
01669
01670 ST *ra_sv_sym = Find_Special_Return_Address_Symbol();
01671 TN *ra_sv_tn = Build_TN_Like(RA_TN);
01672 Set_TN_save_creg (ra_sv_tn, TN_class_reg(RA_TN));
01673 Set_TN_spill(ra_sv_tn, ra_sv_sym);
01674 if (MTYPE_byte_size(Pointer_Mtype) < MTYPE_byte_size(Spill_Int_Mtype) ) {
01675
01676
01677 ra_sv_sym = ST_base(ra_sv_sym);
01678 Set_TN_spill(ra_sv_tn, ra_sv_sym);
01679 }
01680 CGSPILL_Load_From_Memory (ra_sv_tn, ra_sv_sym, &ops, CGSPILL_LCL, bb_epi);
01681 Exp_COPY (RA_TN, ra_sv_tn, &ops);
01682 #endif
01683 }
01684 #ifdef TARG_IA64
01685 else if( PU_Has_Calls || IPFEC_Enable_Edge_Profile) {
01686
01687 if ( TN_register_class(RA_TN) != ISA_REGISTER_CLASS_integer)
01688 #else
01689 else {
01690 if (gra_run && PU_Has_Calls
01691 && TN_register_class(RA_TN) != ISA_REGISTER_CLASS_integer)
01692 #endif
01693 {
01694
01695
01696
01697
01698
01699
01700 Exp_COPY (RA_TN, ra_intsave_tn, &ops );
01701 Set_OP_no_move_before_gra(OPS_last(&ops));
01702 }
01703 #if defined(TARG_SL)
01704 else if (CG_opt_level <= 1) {
01705 #else
01706 else {
01707 #endif
01708
01709 Exp_COPY ( RA_TN, SAVE_tn(Return_Address_Reg), &ops );
01710 Set_OP_no_move_before_gra(OPS_last(&ops));
01711 }
01712 }
01713 }
01714
01715 if ( gra_run ) {
01716
01717 for ( callee_num = 0; callee_num < Callee_Saved_Regs_Count; ++callee_num ) {
01718 TN *callee_tn = CALLEE_tn(callee_num);
01719 if ( TN_is_save_reg(callee_tn)
01720 && !REGISTER_CLASS_multiple_save(TN_register_class(callee_tn)))
01721 {
01722 Exp_COPY ( CALLEE_ded_tn(callee_num), callee_tn, &ops );
01723 Set_OP_no_move_before_gra(OPS_last(&ops));
01724 }
01725 }
01726 }
01727
01728 #if defined(KEY) && !defined(TARG_NVISA)
01729
01730 for (INT i = 0; i < Saved_Callee_Saved_Regs.Elements(); i++) {
01731 SAVE_REG_LOC sr = Saved_Callee_Saved_Regs.Top_nth(i);
01732 #ifdef TARG_X8664
01733 if (sr.temp == NULL)
01734 continue;
01735 #endif
01736 if (! sr.user_allocated)
01737 continue;
01738
01739 CGSPILL_Load_From_Memory (sr.ded_tn, sr.temp, &ops, CGSPILL_LCL, bb_epi);
01740 Set_OP_no_move_before_gra(OPS_last(&ops));
01741 }
01742 #endif
01743
01744 if (PU_Has_Calls) {
01745 EETARG_Restore_Pfs (Caller_Pfs_TN, &ops);
01746 }
01747
01748 #ifdef ABI_PROPERTY_stack_ptr
01749
01750
01751 if ( Gen_Frame_Pointer && !PUSH_FRAME_POINTER_ON_STACK ) {
01752 Exp_COPY (SP_TN, FP_TN, &ops);
01753 }
01754 else {
01755
01756
01757
01758
01759 Exp_Spadjust (SP_TN, Frame_Len_TN, V_NONE, &ops);
01760 }
01761 EXITINFO_sp_adj(exit_info) = OPS_last(&ops);
01762
01763
01764 if ( Gen_Frame_Pointer
01765 && !PUSH_FRAME_POINTER_ON_STACK
01766 && ABI_PROPERTY_Is_callee (
01767 TN_register_class(FP_TN),
01768 REGISTER_machine_id(TN_register_class(FP_TN), TN_register(FP_TN)) ))
01769 {
01770 if ( Caller_FP_TN == NULL ) {
01771 if ( stn = PREG_To_TN_Array[ Caller_FP_Preg ] )
01772 Caller_FP_TN = stn;
01773 else {
01774
01775 Caller_FP_TN = Gen_Register_TN (
01776 ISA_REGISTER_CLASS_integer, TY_size(Spill_Int_Type));
01777 TN_MAP_Set( TN_To_PREG_Map, Caller_FP_TN, (void *)(INTPTR)Caller_FP_Preg );
01778 PREG_To_TN_Array[ Caller_FP_Preg ] = Caller_FP_TN;
01779 PREG_To_TN_Mtype[ Caller_FP_Preg ] = TY_mtype(Spill_Int_Type);
01780 }
01781 }
01782 Exp_COPY (FP_TN, Caller_FP_TN, &ops);
01783 Set_OP_no_move_before_gra(OPS_last(&ops));
01784 }
01785 #endif
01786
01787 #ifdef TARG_SL
01788
01789 if (DEBUG_Stack_Check & STACK_EXIT_CHECK) {
01790 Build_OP(TOP_break, &ops);
01791 Set_OP_no_move_before_gra(OPS_last(&ops));
01792 Set_OP_volatile(OPS_last(&ops));
01793 }
01794 #endif
01795
01796
01797
01798
01799 if (!BB_call(bb_epi)) {
01800 #ifdef TARG_X8664
01801 int sp_adjust = 0;
01802
01803 if( Is_Target_32bit() ){
01804 const TY_IDX call_ty = ST_pu_type(st);
01805 const BOOL ff2c_abi = PU_ff2c_abi(Pu_Table[ST_pu(st)]);
01806 const RETURN_INFO return_info = Get_Return_Info( TY_ret_type(call_ty),
01807 No_Simulated,
01808 ff2c_abi );
01809 if( RETURN_INFO_return_via_first_arg(return_info) ||
01810 TY_return_to_param( call_ty ) ){
01811 sp_adjust = Pointer_Size;
01812 }
01813 }
01814
01815 Exp_Return( RA_TN, sp_adjust, &ops );
01816 #else
01817 Exp_Return (RA_TN, &ops);
01818 #endif // TARG_X8664
01819 }
01820
01821
01822 FOR_ALL_OPS_OPs(&ops, op)
01823 OP_srcpos(op) = EXITINFO_srcpos(exit_info);
01824
01825
01826 if ( Trace_EE ) {
01827 #pragma mips_frequency_hint NEVER
01828 Print_OPS(&ops);
01829 }
01830
01831
01832 if (BB_call(bb_epi)) {
01833
01834
01835
01836
01837 OP *point = BB_last_op(bb_epi);
01838 Is_True(OP_br(point), ("last tail call OP of BB:%d not a jump", BB_id(bb_epi)));
01839 BB_Insert_Ops_Before(bb_epi, point, &ops);
01840 } else {
01841 BB_Append_Ops(bb_epi, &ops);
01842 }
01843 }
01844
01845
01846 extern void
01847 Set_Frame_Len (INT64 val)
01848 {
01849 #ifdef TARG_X8664
01850 if (CG_min_stack_size &&
01851 !Stack_Frame_Has_Calls()) {
01852 extern BOOL Is_Stack_Used();
01853 if( !Is_Stack_Used() )
01854 val = 0;
01855 }
01856 #endif
01857
01858 Frame_Len = val;
01859 Set_TN_value(Frame_Len_TN, val);
01860 Set_TN_value(Neg_Frame_Len_TN, -val);
01861 }
01862
01863
01864
01865 void
01866 Init_Entry_Exit_Code (WN *pu_wn)
01867 {
01868 Trace_EE = Get_Trace ( TP_CGEXP, 64 );
01869
01870 #if defined(TARG_SL)
01871 Trace_Stack_Allocation = Get_Trace(TP_CGEXP, 2048);
01872 #endif
01873
01874
01875 GP_Setup_Code = undefined_code;
01876 Caller_GP_TN = NULL;
01877 Caller_FP_TN = NULL;
01878
01879
01880 Frame_Len_TN = Gen_Unique_Literal_TN(0,8);
01881 Neg_Frame_Len_TN = Gen_Unique_Literal_TN(0,8);
01882
01883 Gen_Frame_Pointer = (Current_PU_Stack_Model != SMODEL_SMALL);
01884 #ifdef TARG_X8664
01885 if (Opt_Level == 0 || Force_Frame_Pointer || Call_Mcount ||
01886 Debug_Level > 0)
01887 Gen_Frame_Pointer = TRUE;
01888 #endif
01889 #ifdef KEY
01890 Saved_Callee_Saved_Regs.Clear();
01891 #endif
01892
01893
01894 EETARG_Init_Entry_Exit_Code (pu_wn, Gen_Frame_Pointer);
01895
01896 Init_Pregs ();
01897
01898 LC_Used_In_PU = FALSE;
01899 }
01900
01901
01902
01903
01904
01905
01906
01907
01908
01909
01910
01911
01912
01913 void
01914 Generate_Entry_Exit_Code ( ST *pu, BOOL is_region )
01915 {
01916 BB_LIST *elist;
01917 BOOL gra_run = ! CG_localize_tns;
01918
01919 Is_True(pu != NULL,("Generate_Entry_Exit_Code, null PU ST"));
01920
01921
01922 for ( elist = Entry_BB_Head; elist; elist = BB_LIST_rest(elist) ) {
01923 Generate_Entry (BB_LIST_first(elist), gra_run );
01924 }
01925
01926 Generate_Unique_Exit ();
01927
01928 for ( elist = Exit_BB_Head; elist; elist = BB_LIST_rest(elist) ) {
01929 Generate_Exit (pu, BB_LIST_first(elist), gra_run, is_region );
01930 }
01931
01932 if (GP_Setup_Code == need_code && !is_region)
01933
01934 GP_Setup_Code = final_code;
01935 }
01936
01937
01938 static void
01939 Adjust_GP_Entry(BB *bb)
01940 {
01941 if (GP_Setup_Code == need_code) {
01942
01943
01944
01945
01946 #ifdef TARG_NVISA
01947 FmtAssert(FALSE, ("NYI"));
01948 return;
01949 #endif
01950 ST *st = ENTRYINFO_name(
01951 ANNOT_entryinfo(ANNOT_Get(BB_annotations(bb),ANNOT_ENTRYINFO)));
01952 TN *got_disp_tn = Gen_Register_TN (
01953 ISA_REGISTER_CLASS_integer, Pointer_Size);
01954
01955 ST *mem_loc = CGSPILL_Get_TN_Spill_Location (GP_TN, CGSPILL_LCL);
01956 OPS ops = OPS_EMPTY;
01957 TN *cur_pu_got_disp_tn = Gen_Symbol_TN(st, 0, TN_RELOC_GPSUB);
01958
01959
01960 CGSPILL_Store_To_Memory (GP_TN, mem_loc, &ops, CGSPILL_LCL, bb);
01961
01962
01963 Set_TN_size(cur_pu_got_disp_tn, 4);
01964 Exp_OP1 (OPC_I4INTCONST, got_disp_tn, cur_pu_got_disp_tn, &ops);
01965
01966
01967 Exp_ADD (Pointer_Mtype, GP_TN, Ep_TN, got_disp_tn, &ops);
01968
01969
01970
01971
01972
01973 CGSPILL_Prepend_Ops (bb, &ops);
01974
01975 if (Trace_EE) {
01976 #pragma mips_frequency_hint NEVER
01977 fprintf(TFile, "%s<calls> Insert spill and setup of GP for BB:%d\n", DBar, BB_id(bb));
01978 Print_OPS(&ops);
01979 }
01980 }
01981 }
01982
01983 static void
01984 Adjust_GP_Exit (BB *bb)
01985 {
01986 if (GP_Setup_Code == need_code) {
01987
01988
01989 #ifdef TARG_NVISA
01990 FmtAssert(FALSE, ("NYI"));
01991 return;
01992 #endif
01993 ST *mem_loc = CGSPILL_Get_TN_Spill_Location (GP_TN, CGSPILL_LCL);
01994 OPS ops = OPS_EMPTY;
01995
01996
01997 CGSPILL_Load_From_Memory (GP_TN, mem_loc, &ops, CGSPILL_LCL, bb);
01998
01999
02000
02001
02002 CGSPILL_Append_Ops (bb, &ops);
02003
02004 if (Trace_EE) {
02005 #pragma mips_frequency_hint NEVER
02006 fprintf(TFile, "%s<calls> Insert restore of GP for BB:%d\n", DBar, BB_id(bb));
02007 Print_OPS (&ops);
02008 }
02009 }
02010 }
02011
02012
02013 void
02014 Adjust_GP_Setup_Code (ST *pu, BOOL allocate_registers)
02015 {
02016 BB_LIST *elist;
02017
02018 if (GP_Setup_Code == no_code && PU_References_GP) {
02019
02020
02021
02022
02023
02024
02025
02026
02027
02028
02029
02030
02031
02032
02033
02034
02035 FmtAssert(!allocate_registers, ("Created new GP reference during register allocation"));
02036
02037 GP_Setup_Code = need_code;
02038 }
02039 else return;
02040
02041 for (elist = Entry_BB_Head; elist; elist = BB_LIST_rest(elist)) {
02042 Adjust_GP_Entry(BB_LIST_first(elist));
02043 }
02044
02045 for (elist = Exit_BB_Head; elist; elist = BB_LIST_rest(elist)) {
02046 Adjust_GP_Exit(BB_LIST_first(elist));
02047 }
02048
02049 if (GP_Setup_Code == need_code)
02050 GP_Setup_Code = final_code;
02051 }
02052
02053
02054 static void
02055 Adjust_LC_Entry (BB *bb)
02056 {
02057 OP *op;
02058 INT i;
02059 FOR_ALL_BB_OPs_FWD(bb, op) {
02060 for ( i = 0; i < OP_opnds(op); ++i ) {
02061 if (OP_opnd(op,i) == LC_TN && OP_no_move_before_gra(op)) {
02062 BB_Remove_Op(bb, op);
02063 if (Trace_EE) {
02064 #pragma mips_frequency_hint NEVER
02065 fprintf(TFile, "<calls> remove save of LC in BB:%d\n", BB_id(bb));
02066 }
02067 }
02068 }
02069 }
02070 }
02071
02072 static void
02073 Adjust_LC_Exit (BB *bb)
02074 {
02075 OP *op;
02076 INT i;
02077 FOR_ALL_BB_OPs_FWD(bb, op) {
02078 for ( i = 0; i < OP_results(op); ++i ) {
02079 if (OP_result(op,i) == LC_TN && OP_no_move_before_gra(op)) {
02080 BB_Remove_Op(bb, op);
02081 if (Trace_EE) {
02082 #pragma mips_frequency_hint NEVER
02083 fprintf(TFile, "<calls> remove restore of LC in BB:%d\n", BB_id(bb));
02084 }
02085 }
02086 }
02087 }
02088 }
02089
02090
02091
02092 void
02093 Adjust_LC_Setup_Code (void)
02094 {
02095 if (LC_TN == NULL) return;
02096 if (LC_Used_In_PU) return;
02097 if (CG_localize_tns) return;
02098
02099 BB_LIST *elist;
02100 for (elist = Entry_BB_Head; elist; elist = BB_LIST_rest(elist)) {
02101 Adjust_LC_Entry(BB_LIST_first(elist));
02102 }
02103 for (elist = Exit_BB_Head; elist; elist = BB_LIST_rest(elist)) {
02104 Adjust_LC_Exit(BB_LIST_first(elist));
02105 }
02106 }
02107
02108
02109
02110
02111
02112
02113
02114
02115
02116
02117
02118
02119 static void
02120 Assign_Prolog_Temps(OP *first, OP *last, REGISTER_SET *temps)
02121 {
02122 OP *op;
02123 ISA_REGISTER_CLASS cl;
02124 REGISTER reg;
02125
02126
02127
02128
02129
02130 cl = TN_register_class(SP_TN);
02131 reg = REGISTER_SET_Choose(temps[cl]);
02132 FmtAssert(reg != REGISTER_UNDEFINED, ("no free temps"));
02133 temps[cl] = REGISTER_SET_Difference1(temps[cl], reg);
02134
02135
02136
02137 for (op = first; op != OP_next(last); op = OP_next(op)) {
02138 TN *tn;
02139 INT k;
02140
02141 REGISTER_CLASS_OP_Update_Mapping(op);
02142
02143 for (k = 0; k < OP_results(op); k++) {
02144 tn = OP_result(op,k);
02145 if (TN_register(tn) == REGISTER_UNDEFINED) {
02146 FmtAssert(TN_register_class(tn) == cl,
02147 ("unexpected register class for unallocated register"));
02148 TN_Allocate_Register(tn, reg);
02149 }
02150 }
02151
02152 for (k = 0; k < OP_opnds(op); k++) {
02153 tn = OP_opnd(op,k);
02154 if (TN_is_register(tn) && TN_register(tn) == REGISTER_UNDEFINED) {
02155 FmtAssert(TN_register_class(tn) == cl,
02156 ("unexpected register class for unallocated register"));
02157 TN_Allocate_Register(tn, reg);
02158 }
02159 }
02160 }
02161 }
02162
02163
02164
02165
02166
02167
02168
02169
02170
02171
02172 static TN *
02173 Gen_Prolog_LDIMM64(UINT64 val, OPS *ops)
02174 {
02175 TN *src = Gen_Literal_TN(val, 8);
02176 TN *result = Build_TN_Of_Mtype (MTYPE_I8);
02177
02178 Exp_Immediate (result, src, TRUE, ops);
02179
02180 return result;
02181 }
02182
02183
02184
02185
02186
02187
02188
02189
02190
02191
02192 static void
02193 Adjust_Entry(BB *bb)
02194 {
02195 UINT64 frame_len = Frame_Len;
02196 ANNOTATION *ant = ANNOT_Get(BB_annotations(bb), ANNOT_ENTRYINFO);
02197 ENTRYINFO *ent_info = ANNOT_entryinfo(ant);
02198 OP *ent_adj = ENTRYINFO_sp_adj(ent_info);
02199 OP *fp_adj;
02200 OP *sp_adj;
02201 TN *sp_incr;
02202 TN *fp_incr;
02203
02204 if (BB_handler(bb)) return;
02205 #if defined(TARG_SL)
02206 if (Trace_EE || Trace_Stack_Allocation) {
02207 #else
02208 if (Trace_EE) {
02209 #endif
02210 #pragma mips_frequency_hint NEVER
02211 fprintf(TFile,
02212 "\n%s<calls> Adjusting entry for %s (BB:%d)\n",
02213 DBar, ST_name(ENTRYINFO_name(ent_info)), BB_id(bb));
02214 fprintf(TFile, "\nFinal frame size: %llu (0x%llx)\n", frame_len, frame_len);
02215 }
02216
02217 #ifdef TARG_X8664
02218 if (CG_push_pop_int_saved_regs && ! Gen_Frame_Pointer) {
02219 OPS ops = OPS_EMPTY;
02220 for (INT i = 0; i < Saved_Callee_Saved_Regs.Elements(); i++) {
02221 SAVE_REG_LOC sr = Saved_Callee_Saved_Regs.Top_nth(i);
02222 if (sr.temp != NULL)
02223 continue;
02224 Build_OP(Is_Target_64bit() ? TOP_pushq : TOP_pushl, SP_TN, sr.ded_tn,
02225 SP_TN, &ops);
02226 }
02227 BB_Insert_Ops_Before(bb, ent_adj, &ops);
02228 }
02229 #endif
02230
02231
02232
02233
02234
02235
02236 sp_adj = ent_adj;
02237 fp_adj = sp_adj;
02238 if ( Gen_Frame_Pointer && !PUSH_FRAME_POINTER_ON_STACK ) {
02239 do {
02240 sp_adj = OP_prev(sp_adj);
02241
02242
02243
02244 } while (!OP_result(sp_adj, 0) || !TN_is_sp_reg(OP_result(sp_adj,0)));
02245 }
02246
02247
02248
02249 sp_incr = OP_opnd(sp_adj, OP_find_opnd_use(sp_adj, OU_opnd2));
02250 fp_incr = (fp_adj != sp_adj)
02251 ? OP_opnd(fp_adj, OP_find_opnd_use(fp_adj, OU_opnd2))
02252 : NULL;
02253
02254
02255
02256 if (Trace_EE) {
02257 #pragma mips_frequency_hint NEVER
02258 fprintf(TFile, "\nOld stack frame allocation:\n");
02259 Print_OP_No_SrcLine(sp_adj);
02260 if (fp_adj != sp_adj) Print_OP_No_SrcLine(fp_adj);
02261 }
02262
02263
02264
02265
02266
02267
02268 FmtAssert( OP_code(sp_adj) == TOP_spadjust
02269 && OP_results(sp_adj) == 1
02270 && TN_is_sp_reg(OP_result(sp_adj,0))
02271 && TN_is_sp_reg(OP_opnd(sp_adj,
02272 OP_find_opnd_use(sp_adj, OU_opnd1)))
02273 && sp_incr == Neg_Frame_Len_TN
02274 && ( ! OP_has_predicate(sp_adj)
02275 || OP_opnd(sp_adj, OP_PREDICATE_OPND) == True_TN),
02276 ("Unexpected form of entry SP-adjust OP"));
02277 if (fp_adj != sp_adj) {
02278 FmtAssert( OP_code(fp_adj) == TOP_spadjust
02279 && OP_results(fp_adj) == 1
02280
02281 && TN_is_dedicated_class_and_reg (OP_result(fp_adj,0),
02282 TN_register_and_class(FP_TN))
02283 && TN_is_sp_reg(OP_opnd(fp_adj,
02284 OP_find_opnd_use(fp_adj, OU_opnd1)))
02285 && fp_incr != NULL
02286 && fp_incr == Frame_Len_TN
02287 && ( ! OP_has_predicate(fp_adj)
02288 || OP_opnd(fp_adj, OP_PREDICATE_OPND) == True_TN),
02289 ("Unexpected form of entry FP-adjust OP"));
02290 }
02291
02292
02293
02294
02295 if (frame_len == 0) {
02296 BB_Remove_Op(bb, sp_adj);
02297
02298 if (sp_adj == fp_adj) {
02299 ent_adj = NULL;
02300 } else {
02301 OPS ops = OPS_EMPTY;
02302
02303
02304
02305
02306
02307
02308
02309 Exp_COPY(FP_TN, SP_TN, &ops);
02310 ent_adj = OPS_last(&ops);
02311 OP_srcpos(ent_adj) = OP_srcpos(fp_adj);
02312 BB_Insert_Ops_Before(bb, fp_adj, &ops);
02313 BB_Remove_Op(bb, fp_adj);
02314 }
02315
02316 if (Trace_EE) {
02317 #pragma mips_frequency_hint NEVER
02318 fprintf(TFile, "\nNew stack frame allocation:\n"
02319 "-- removed --\n");
02320 }
02321 } else {
02322 OPS ops = OPS_EMPTY;
02323 TN *incr;
02324 OP *op;
02325
02326
02327
02328
02329 if (!CGTARG_Can_Fit_Immediate_In_Add_Instruction (frame_len)) {
02330 REGISTER_SET temps[ISA_REGISTER_CLASS_MAX+1];
02331
02332
02333
02334 REG_LIVE_Prolog_Temps(bb, sp_adj, fp_adj, temps);
02335 if (Trace_EE) {
02336 #pragma mips_frequency_hint NEVER
02337 ISA_REGISTER_CLASS cl;
02338
02339 fprintf(TFile, "\nInteger temp register usage at prolog SP adjust:\n");
02340 FOR_ALL_ISA_REGISTER_CLASS(cl) {
02341 if (cl == TN_register_class(SP_TN)) {
02342 fprintf(TFile, " avail=");
02343 REGISTER_SET_Print(temps[cl], TFile);
02344 fprintf(TFile, "\n");
02345 }
02346 }
02347 }
02348
02349 incr = Gen_Prolog_LDIMM64(frame_len, &ops);
02350 Assign_Prolog_Temps(OPS_first(&ops), OPS_last(&ops), temps);
02351 } else {
02352
02353
02354
02355 incr = Frame_Len_TN;
02356 }
02357
02358
02359
02360
02361
02362 #if defined(TARG_PR)
02363 BOOL isAdd = TRUE;
02364 Expand_SR_Adj(isAdd, SP_TN, incr, &ops);
02365 #else
02366 Exp_SUB (Pointer_Mtype, SP_TN, SP_TN, incr, &ops);
02367 #endif
02368 FOR_ALL_OPS_OPs_FWD(&ops, op) OP_srcpos(op) = OP_srcpos(sp_adj);
02369 ent_adj = OPS_last(&ops);
02370 BB_Insert_Ops_Before(bb, sp_adj, &ops);
02371 BB_Remove_Op(bb, sp_adj);
02372 if (Trace_EE) {
02373 #pragma mips_frequency_hint NEVER
02374 fprintf(TFile, "\nNew stack frame allocation:\n");
02375 FOR_ALL_OPS_OPs_FWD(&ops, op) Print_OP_No_SrcLine(op);
02376 }
02377
02378 if (fp_adj != sp_adj) {
02379
02380
02381
02382 Exp_ADD (Pointer_Mtype, FP_TN, SP_TN, incr, OPS_Init(&ops));
02383 ent_adj = OPS_last(&ops);
02384 OP_srcpos(ent_adj) = OP_srcpos(fp_adj);
02385 BB_Insert_Ops_Before(bb, fp_adj, &ops);
02386 BB_Remove_Op(bb, fp_adj);
02387 if (Trace_EE) {
02388 #pragma mips_frequency_hint NEVER
02389 FOR_ALL_OPS_OPs_FWD(&ops, op) Print_OP_No_SrcLine(op);
02390 }
02391 }
02392 }
02393
02394
02395
02396 ENTRYINFO_sp_adj(ent_info) = ent_adj;
02397
02398
02399 EETARG_Fixup_Entry_Code (bb);
02400 }
02401
02402
02403
02404
02405
02406
02407
02408
02409
02410
02411
02412 static void
02413 Adjust_Exit(ST *pu_st, BB *bb)
02414 {
02415 ANNOTATION *ant = ANNOT_Get(BB_annotations(bb), ANNOT_EXITINFO);
02416 EXITINFO *exit_info = ANNOT_exitinfo(ant);
02417 OP *sp_adj = EXITINFO_sp_adj(exit_info);
02418 UINT64 frame_len = Frame_Len;
02419 TN *incr = NULL;
02420
02421
02422
02423 if (Trace_EE) {
02424 #pragma mips_frequency_hint NEVER
02425 fprintf(TFile,
02426 "\n%s<calls> Adjusting exit for %s (BB:%d)\n",
02427 DBar, ST_name(pu_st), BB_id(bb));
02428 fprintf(TFile, "\nFinal frame size: %llu (0x%llx)\n", frame_len, frame_len);
02429 fprintf(TFile, "\nOld stack frame de-allocation:\n");
02430 Print_OP_No_SrcLine(sp_adj);
02431 }
02432
02433
02434
02435 if ( !Gen_Frame_Pointer || PUSH_FRAME_POINTER_ON_STACK) {
02436 incr = OP_opnd(sp_adj, OP_find_opnd_use(sp_adj, OU_opnd2));
02437 }
02438
02439
02440
02441
02442
02443
02444
02445 if (Gen_Frame_Pointer && !PUSH_FRAME_POINTER_ON_STACK) {
02446 FmtAssert(OP_copy(sp_adj) &&
02447 TN_is_sp_reg(OP_result(sp_adj,0)),
02448 ("Unexpected exit SP adjust OP"));
02449 } else {
02450 FmtAssert( OP_code(sp_adj) == TOP_spadjust
02451 && OP_results(sp_adj) == 1
02452 && TN_is_sp_reg(OP_result(sp_adj,0))
02453 && TN_is_sp_reg(OP_opnd(sp_adj,
02454 OP_find_opnd_use(sp_adj, OU_opnd1)))
02455 && incr == Frame_Len_TN
02456 && ( ! OP_has_predicate(sp_adj)
02457 || OP_opnd(sp_adj, OP_PREDICATE_OPND) == True_TN),
02458 ("Unexpected form of exit SP-adjust OP"));
02459 }
02460
02461 #ifdef TARG_X8664
02462 if (CG_push_pop_int_saved_regs && ! Gen_Frame_Pointer) {
02463 OPS popops = OPS_EMPTY;
02464 for (INT i = Saved_Callee_Saved_Regs.Elements()-1; i >= 0; i--) {
02465 SAVE_REG_LOC sr = Saved_Callee_Saved_Regs.Top_nth(i);
02466 if (sr.temp != NULL)
02467 continue;
02468 Build_OP(Is_Target_64bit() ? TOP_popq : TOP_popl, sr.ded_tn, SP_TN, SP_TN, &popops);
02469 }
02470 BB_Insert_Ops_After(bb, sp_adj, &popops);
02471 }
02472 #endif
02473
02474
02475
02476
02477 if (Gen_Frame_Pointer && PUSH_FRAME_POINTER_ON_STACK) {
02478 OP* op = EETARG_High_Level_Procedure_Exit ();
02479 #ifdef KEY // bug 3600
02480 OP_srcpos(op) = OP_srcpos(sp_adj);
02481 #endif
02482 #ifdef TARG_X8664
02483 if (W2OPS_Pragma_Preamble_End_Seen())
02484 Set_OP_first_after_preamble_end(op);
02485 #endif
02486 BB_Insert_Op_After (bb, sp_adj, op);
02487 BB_Remove_Op (bb, sp_adj);
02488 sp_adj = op;
02489 } else if (Gen_Frame_Pointer) {
02490 if ( Trace_EE ) {
02491 #pragma mips_frequency_hint NEVER
02492 fprintf(TFile, "\nNew stack frame de-allocation:\n"
02493 "-- unchanged --\n");
02494 }
02495 } else if (frame_len == 0) {
02496 BB_Remove_Op(bb, sp_adj);
02497 sp_adj = NULL;
02498
02499 if (Trace_EE) {
02500 #pragma mips_frequency_hint NEVER
02501 fprintf(TFile, "\nNew stack frame de-allocation:\n"
02502 "-- removed --\n");
02503 }
02504 } else if (CGTARG_Can_Fit_Immediate_In_Add_Instruction (frame_len)) {
02505 OPS ops = OPS_EMPTY;
02506 OP *op;
02507
02508
02509
02510 #if defined(TARG_PR)
02511 BOOL isAdd = FALSE;
02512 Expand_SR_Adj(isAdd, SP_TN, incr, &ops);
02513 #else
02514 Exp_ADD (Pointer_Mtype, SP_TN, SP_TN, incr, &ops);
02515 #endif
02516 BB_Insert_Ops_Before(bb, sp_adj, &ops);
02517 BB_Remove_Op(bb, sp_adj);
02518 FOR_ALL_OPS_OPs_FWD(&ops, op) OP_srcpos(op) = OP_srcpos(sp_adj);
02519 sp_adj = OPS_last(&ops);
02520
02521 if ( Trace_EE ) {
02522 #pragma mips_frequency_hint NEVER
02523 fprintf(TFile, "\nNew stack frame de-allocation:\n");
02524 FOR_ALL_OPS_OPs_FWD(&ops, op) Print_OP_No_SrcLine(op);
02525 }
02526 } else {
02527 FmtAssert(FALSE, ("Can't handle stack de-allocation of 0x%llx", frame_len));
02528 }
02529
02530
02531
02532 EXITINFO_sp_adj(exit_info) = sp_adj;
02533 }
02534
02535 static void
02536 Adjust_Alloca_Code (void)
02537 {
02538 BB *bb;
02539 OP *op;
02540 OPS ops;
02541 OP *new_op;
02542 for (bb = REGION_First_BB; bb != NULL; bb = BB_next(bb)) {
02543
02544
02545
02546 op = BB_first_op(bb);
02547 while (op != NULL) {
02548 if (OP_code(op) != TOP_spadjust) {
02549 op = OP_next(op);
02550 continue;
02551 }
02552 OPS_Init(&ops);
02553 #if defined(TARG_IA64)
02554 if (OP_spadjust_plus(op)) {
02555 #else
02556 if (OP_variant(op) == V_ADJUST_PLUS) {
02557 #endif
02558
02559
02560 Exp_COPY (OP_result(op,0),
02561 OP_opnd(op, OP_find_opnd_use(op, OU_opnd2)),
02562 &ops);
02563 }
02564 #if defined(TARG_IA64)
02565 else if (OP_spadjust_minus(op)) {
02566 #else
02567 else if (OP_variant(op) == V_ADJUST_MINUS) {
02568 #endif
02569 Exp_SUB (Pointer_Mtype, OP_result(op,0),
02570 OP_opnd(op, OP_find_opnd_use(op, OU_opnd1)),
02571 OP_opnd(op, OP_find_opnd_use(op, OU_opnd2)),
02572 &ops);
02573 }
02574 else {
02575 FmtAssert(FALSE, ("non-alloca spadjust"));
02576 }
02577 FOR_ALL_OPS_OPs_FWD(&ops, new_op) {
02578 OP_srcpos(new_op) = OP_srcpos(op);
02579 Is_True(OP_has_predicate(new_op) == OP_has_predicate(op),
02580 ("spadjust can't copy predicates"));
02581
02582 if (OP_has_predicate(new_op))
02583 Set_OP_opnd (new_op, OP_PREDICATE_OPND,
02584 OP_opnd(op, OP_PREDICATE_OPND) );
02585 }
02586 BB_Insert_Ops_Before(bb, op, &ops);
02587 BB_Remove_Op(bb, op);
02588 op = OPS_last(&ops);
02589 #if defined(TARG_IA64)
02590 Reset_BB_scheduled(bb);
02591 #endif
02592 }
02593 }
02594 }
02595
02596
02597
02598
02599
02600
02601
02602
02603
02604
02605
02606
02607 void
02608 Adjust_Entry_Exit_Code( ST *pu )
02609 {
02610 BB_LIST *elist;
02611
02612 for (elist = Entry_BB_Head; elist; elist = BB_LIST_rest(elist)) {
02613 Adjust_Entry(BB_LIST_first(elist));
02614 }
02615
02616 for (elist = Exit_BB_Head; elist; elist = BB_LIST_rest(elist)) {
02617 Adjust_Exit(pu, BB_LIST_first(elist));
02618 }
02619
02620 FmtAssert (!(GP_Setup_Code == no_code && PU_References_GP),
02621 ("had gp reference without setting up new gp"));
02622
02623 if (PU_has_alloca(Get_Current_PU())) {
02624
02625 Adjust_Alloca_Code ();
02626 }
02627 }
02628
02629 #ifdef KEY
02630
02631
02632 BOOL Is_Unique_Callee_Saved_Reg (TN * new_tn)
02633 {
02634 for (INT i=0; i<Saved_Callee_Saved_Regs.Elements(); i++)
02635 if (TNs_Are_Equivalent (Saved_Callee_Saved_Regs.Top_nth(i).ded_tn,
02636 new_tn))
02637 return FALSE;
02638
02639 return TRUE;
02640 }
02641
02642 INT Cgdwarf_Num_Callee_Saved_Regs (void)
02643 {
02644 return Saved_Callee_Saved_Regs.Elements();
02645 }
02646
02647 struct tn* Cgdwarf_Nth_Callee_Saved_Reg (INT n)
02648 {
02649 return Saved_Callee_Saved_Regs.Top_nth(n).ded_tn;
02650 }
02651
02652 ST* Cgdwarf_Nth_Callee_Saved_Reg_Location (INT n)
02653 {
02654 return Saved_Callee_Saved_Regs.Top_nth(n).temp;
02655 }
02656 #endif
02657
02658 #ifdef TARG_X8664
02659 INT Push_Pop_Int_Saved_Regs(void)
02660 {
02661 INT size = 0;
02662 if (CG_push_pop_int_saved_regs && ! Gen_Frame_Pointer) {
02663 for (INT i=0; i<Saved_Callee_Saved_Regs.Elements(); i++) {
02664 SAVE_REG_LOC sr = Saved_Callee_Saved_Regs.Top_nth(i);
02665 if (sr.temp == NULL)
02666 size++;
02667 }
02668 }
02669 return size;
02670 }
02671 #endif
02672
02673
02674 #ifdef TARG_IA64
02675
02676
02677
02678
02679
02680
02681
02682
02683
02684
02685
02686
02687
02688
02689 #ifdef TARG_IA64
02690 void
02691 Instru_Call_Mcount(void)
02692 {
02693 BB_LIST *elist;
02694
02695 for (elist = Entry_BB_Head; elist; elist = BB_LIST_rest(elist)) {
02696 EETARG_Call_Mcount(BB_LIST_first(elist));
02697 }
02698 }
02699 #endif
02700
02701
02702 extern void Handle_All_Hazards(BB *bb);
02703 INT R32;
02704 REGISTER reg_value_alloc1;
02705 REGISTER reg_value_alloc2;
02706 #define AFTER TRUE
02707 #define BEFORE FALSE
02708 #define Set_TN_reg_value(tn, value) (tn->u1.reg_tn.class_reg.class_reg.reg = value)
02709 #define Cp_TN_reg_value(tn1, tn2) (tn1->u1.reg_tn.class_reg.class_reg.reg = tn2->u1.reg_tn.class_reg.class_reg.reg)
02710 #define TN_reg_value(tn) tn->u1.reg_tn.class_reg.class_reg.reg
02711 #define TN_immd_value(tn) tn->u1.value
02712 #define TO_SAVE_REGISTER 32
02713 #define PU_IN_ONE_FILE 1000
02714 #define BB_IN_ONE_PU 1000
02715
02716 typedef struct bb_symbol {
02717 mBB_NUM id;
02718 char * name;
02719 struct bb_symbol * next;
02720 ST * global_BB_st;
02721 TN* BB_var_name_tn;
02722 } BB_symbol;
02723 BB_symbol *BB_Symbol_Head;
02724 BB_symbol *BB_Symbol_Point;
02725
02726
02727
02728
02729 void Ld8_r_r(BB *new_bb, TN * src)
02730 {
02731 OP *Ld8_Op;
02732 TN *Enum_Op1;
02733 TN *Enum_Op2;
02734
02735
02736
02737 Enum_Op1 = Gen_Enum_TN(ECV_ldtype);
02738 Enum_Op2 = Gen_Enum_TN(ECV_ldhint);
02739 Ld8_Op = Mk_OP(TOP_ld8, src, True_TN, Enum_Op1, Enum_Op2, src);
02740 BB_Append_Op(new_bb, Ld8_Op);
02741 }
02742
02743
02744
02745
02746 void St8_spill_r(BB *new_bb, TN *src, TN *base)
02747 {
02748 OP *St8_Op;
02749 TN *Enum_Op2;
02750
02751
02752
02753 Enum_Op2 = Gen_Enum_TN(ECV_sthint);
02754 St8_Op = Mk_OP(TOP_st8_spill, True_TN, Enum_Op2, src, base);
02755 BB_Append_Op(new_bb, St8_Op);
02756 }
02757
02758
02759
02760
02761 void Ld8_fill_r(BB *new_bb, TN *src, TN *base)
02762 {
02763 OP *Ld8_Op;
02764 TN *Enum_Op2;
02765
02766
02767
02768 Enum_Op2 = Gen_Enum_TN(ECV_ldhint);
02769 Ld8_Op = Mk_OP(TOP_ld8_fill, base, True_TN, Enum_Op2, src);
02770 BB_Append_Op(new_bb, Ld8_Op);
02771 }
02772
02773
02774
02775
02776 void Addl(BB *new_bb, TN *src, TN *base)
02777 {
02778 OP *Addl_Op;
02779
02780
02781
02782 Addl_Op = Mk_OP(TOP_addl, src, True_TN, base, GP_TN);
02783 BB_Append_Op(new_bb, Addl_Op);
02784 }
02785
02786
02787
02788
02789 static void Cycle_Output_Func_Insert(BB *bb, int reg_num, TN **spill_tn, TN *gp_tn, TN *pr_tn, TN **rg_tn, int output_reg_num, char *output_func)
02790 {
02791 BB * new_bb;
02792 TY_IDX ty;
02793 ST *call_st;
02794 ST *Atexit_Fun;
02795 OP *Mv_Op, *Addl_Op, *Ld8_Op, *St8_Op, *Mov_Op, *Br_Call_Op;
02796 TN *var_name_tn;
02797 TN *src, *base, *target;
02798 TN *Enum_Op1, *Enum_Op2;
02799 INT reg_value;
02800 TN *ar_ec = Build_Dedicated_TN( ISA_REGISTER_CLASS_application, (REGISTER)(REGISTER_MIN + 66), 8);
02801 INT i;
02802
02803 reg_value = R32 + reg_num + 1;
02804 new_bb = Gen_And_Insert_BB_After(bb);
02805
02806
02807
02808 src = Gen_Register_TN(ISA_REGISTER_CLASS_integer, Pointer_Size);
02809 Set_TN_reg_value(src, reg_value + 1);
02810 Mov_Op = Mk_OP(TOP_mov_f_pr, src, True_TN);
02811 BB_Append_Op(new_bb, Mov_Op);
02812
02813
02814
02815 src = Gen_Register_TN(ISA_REGISTER_CLASS_integer, Pointer_Size);
02816 Set_TN_reg_value(src, reg_value);
02817 Addl(new_bb, src, pr_tn);
02818
02819
02820
02821 Ld8_r_r(new_bb, src);
02822
02823
02824
02825 base = Gen_Register_TN(ISA_REGISTER_CLASS_integer, Pointer_Size);
02826 Set_TN_reg_value(base, reg_value + 1);
02827 St8_spill_r(new_bb, src, base);
02828
02829
02830
02831 src = Gen_Register_TN(ISA_REGISTER_CLASS_integer, Pointer_Size);
02832 Set_TN_reg_value(src, reg_value);
02833 Addl(new_bb, src, gp_tn);
02834
02835
02836
02837 Ld8_r_r(new_bb, src);
02838
02839
02840
02841 base = Gen_Register_TN(ISA_REGISTER_CLASS_integer, Pointer_Size);
02842 Set_TN_reg_value(base, reg_value - output_reg_num - 1);
02843 St8_spill_r(new_bb, src, base);
02844
02845
02846
02847 src = Gen_Register_TN(ISA_REGISTER_CLASS_integer, Pointer_Size);
02848 Set_TN_reg_value(src, reg_value - output_reg_num - 1);
02849 Mov_Op = Mk_OP(TOP_mov, src, True_TN, GP_TN);
02850 BB_Append_Op(new_bb, Mov_Op);
02851
02852 for (i = 0; i < output_reg_num; i++) {
02853
02854
02855
02856 src = Gen_Register_TN(ISA_REGISTER_CLASS_integer, Pointer_Size);
02857 Set_TN_reg_value(src, reg_value);
02858 Addl(new_bb, src, spill_tn[i]);
02859
02860 Ld8_r_r(new_bb, src);
02861
02862
02863
02864 base = Gen_Register_TN(ISA_REGISTER_CLASS_integer, Pointer_Size);
02865 Set_TN_reg_value(base, reg_value - output_reg_num + i);
02866 St8_spill_r(new_bb, src, base);
02867 }
02868
02869 for (i = 0; i < TO_SAVE_REGISTER; i++) {
02870 src = Gen_Register_TN(ISA_REGISTER_CLASS_integer, Pointer_Size);
02871 Set_TN_reg_value(src, reg_value);
02872 Addl(new_bb, src, rg_tn[i]);
02873
02874 Ld8_r_r(new_bb, src);
02875 base = Gen_Register_TN(ISA_REGISTER_CLASS_integer, Pointer_Size);
02876 Set_TN_reg_value(base, i + 3);
02877 St8_spill_r(new_bb, src, base);
02878 }
02879
02880
02881
02882 ty = Make_Function_Type(MTYPE_To_TY(MTYPE_V));
02883 call_st = Gen_Intrinsic_Function(ty, output_func);
02884 Clear_PU_no_side_effects(Pu_Table[ST_pu(call_st)]);
02885 Clear_PU_is_pure(Pu_Table[ST_pu(call_st)]);
02886 Set_PU_no_delete(Pu_Table[ST_pu(call_st)]);
02887 INT64 offset = 0;
02888 INT32 relocs = TN_RELOC_IA_LTOFF_FPTR;
02889 var_name_tn = Gen_Symbol_TN(call_st, offset, relocs);
02890 src = Gen_Register_TN(ISA_REGISTER_CLASS_integer, Pointer_Size);
02891 Set_TN_reg_value(src, reg_value - output_reg_num);
02892 Addl_Op = Mk_OP(TOP_addl, src, True_TN, var_name_tn, GP_TN);
02893 BB_Append_Op(new_bb, Addl_Op);
02894
02895
02896
02897 Enum_Op1 = Gen_Enum_TN(ECV_ldtype);
02898 Enum_Op2 = Gen_Enum_TN(ECV_ldhint);
02899 Ld8_Op = Mk_OP(TOP_ld8, src, True_TN, Enum_Op1, Enum_Op2, src);
02900 BB_Append_Op(new_bb, Ld8_Op);
02901
02902
02903
02904 src = Gen_Register_TN(ISA_REGISTER_CLASS_branch, Pointer_Size);
02905 Set_TN_reg_value(src, 1);
02906 ty = Make_Function_Type(MTYPE_To_TY(MTYPE_V));
02907 Atexit_Fun = Gen_Intrinsic_Function(ty, "atexit");
02908 Clear_PU_no_side_effects(Pu_Table[ST_pu(Atexit_Fun)]);
02909 Clear_PU_is_pure(Pu_Table[ST_pu(Atexit_Fun)]);
02910 Set_PU_no_delete(Pu_Table[ST_pu(Atexit_Fun)]);
02911 target = Gen_Symbol_TN(Atexit_Fun, 0, 0);
02912 Br_Call_Op = Mk_OP (TOP_br_call, src, True_TN, Gen_Enum_TN(ECV_bwh_sptk), Gen_Enum_TN(ECV_ph_many), Gen_Enum_TN(ECV_dh), target, ar_ec);
02913 BB_Append_Op(new_bb, Br_Call_Op);
02914
02915 Handle_All_Hazards(new_bb);
02916
02917
02918
02919
02920 BB * back_bb;
02921 back_bb = Gen_And_Insert_BB_After(new_bb);
02922
02923
02924
02925 src = Gen_Register_TN(ISA_REGISTER_CLASS_integer, Pointer_Size);
02926 Set_TN_reg_value(src, reg_value - output_reg_num - 1);
02927 Mov_Op = Mk_OP(TOP_mov, GP_TN, True_TN, src);
02928 BB_Append_Op(back_bb, Mov_Op);
02929
02930
02931
02932 src = Gen_Register_TN(ISA_REGISTER_CLASS_integer, Pointer_Size);
02933 Set_TN_reg_value(src, reg_value);
02934 Addl(back_bb, src, gp_tn);
02935
02936
02937
02938 Ld8_r_r(back_bb, src);
02939
02940
02941
02942 base = Gen_Register_TN(ISA_REGISTER_CLASS_integer, Pointer_Size);
02943 Set_TN_reg_value(base, reg_value - output_reg_num - 1);
02944 Ld8_fill_r(back_bb, src, base);
02945
02946
02947
02948 src = Gen_Register_TN(ISA_REGISTER_CLASS_integer, Pointer_Size);
02949 Set_TN_reg_value(src, reg_value);
02950 Addl(back_bb, src, pr_tn);
02951
02952
02953
02954 Ld8_r_r(back_bb, src);
02955
02956
02957
02958 base = Gen_Register_TN(ISA_REGISTER_CLASS_integer, Pointer_Size);
02959 Set_TN_reg_value(base, reg_value + 1);
02960 Ld8_fill_r(back_bb, src, base);
02961
02962
02963
02964 src = Gen_Register_TN(ISA_REGISTER_CLASS_integer, Pointer_Size);
02965 Set_TN_reg_value(src, reg_value + 1);
02966 Mov_Op = Mk_OP(TOP_mov_t_pr, True_TN, src, Gen_Literal_TN(-1, 8));
02967 BB_Append_Op(back_bb, Mov_Op);
02968
02969
02970
02971 for (i = 0; i < output_reg_num; i++) {
02972 src = Gen_Register_TN(ISA_REGISTER_CLASS_integer, Pointer_Size);
02973 Set_TN_reg_value(src, reg_value);
02974 Addl(back_bb, src, spill_tn[i]);
02975
02976 Ld8_r_r(back_bb, src);
02977
02978
02979 base = Gen_Register_TN(ISA_REGISTER_CLASS_integer, Pointer_Size);
02980 Set_TN_reg_value(base, reg_value - output_reg_num + i);
02981 Ld8_fill_r(back_bb, src, base);
02982 }
02983
02984
02985
02986 for (i = 0; i < TO_SAVE_REGISTER; i++) {
02987 src = Gen_Register_TN(ISA_REGISTER_CLASS_integer, Pointer_Size);
02988 Set_TN_reg_value(src, reg_value);
02989 Addl(back_bb, src, rg_tn[i]);
02990
02991 Ld8_r_r(back_bb, src);
02992
02993 base = Gen_Register_TN(ISA_REGISTER_CLASS_integer, Pointer_Size);
02994 Set_TN_reg_value(base, 3 + i);
02995 Ld8_fill_r(back_bb, src, base);
02996 }
02997
02998 Handle_All_Hazards(back_bb);
02999 }
03000
03001 REGISTER Get_Value_Caller_GP(BB *bb)
03002 {
03003 OP *op;
03004 REGISTER reg_value;
03005
03006 FOR_ALL_BB_OPs_FWD(bb, op) {
03007 if ((op->opr == TOP_mov) && (op->res_opnd[2]->u1.reg_tn.class_reg.class_reg.reg == 2)){
03008 reg_value = op->res_opnd[1]->u1.reg_tn.class_reg.class_reg.reg;
03009 return reg_value;
03010 }
03011 }
03012 return 0;
03013 }
03014
03015
03016
03017
03018 static void Cycle_Count_Frag_Insert(BB *bb, INT reg_num, TN * var_name_tn, BOOL place, INT bb_cycle)
03019 {
03020 BB * new_bb;
03021 INT reg_value;
03022 TN *Enum_Op1, *Enum_Op2;
03023 TN *src, *base;
03024 OP *Addl_Op, *Ld8_Op, *Ld4_Op, *Adds_Op, *St4_Op, *Nop_Op, *Mov_Op;
03025 OP *Nop_op;
03026 REGISTER caller_gp_reg;
03027
03028 reg_value = R32 + reg_num + 1;
03029
03030
03031 FmtAssert (bb != NULL, ("Null bb during insert frag ins in cycle counting"));
03032 if (place)
03033 new_bb = Gen_And_Insert_BB_After(bb);
03034 else
03035 new_bb = Gen_And_Insert_BB_Before(bb);
03036
03037
03038
03039 if (!(Caller_GP_TN == NULL) && !(TN_reg_value(Caller_GP_TN) == 0) && BB_call(BB_prev(new_bb))) {
03040 src = Gen_Register_TN(ISA_REGISTER_CLASS_integer, Pointer_Size);
03041 caller_gp_reg = Get_Value_Caller_GP(BB_next(new_bb));
03042 if (caller_gp_reg)
03043 Set_TN_reg_value(src, caller_gp_reg);
03044 else
03045 Cp_TN_reg_value(src, Caller_GP_TN);
03046 Mov_Op = Mk_OP(TOP_mov, GP_TN, True_TN, src);
03047 BB_Append_Op(new_bb, Mov_Op);
03048 }
03049
03050
03051 src = Gen_Register_TN(ISA_REGISTER_CLASS_integer, Pointer_Size);
03052 Set_TN_reg_value(src, reg_value_alloc1);
03053 base = Gen_Register_TN(ISA_REGISTER_CLASS_integer, Pointer_Size);
03054 Set_TN_reg_value(base, reg_value_alloc2);
03055 Mov_Op = Mk_OP(TOP_mov, src, True_TN, base);
03056 BB_Append_Op(new_bb, Mov_Op);
03057 Mov_Op = Mk_OP(TOP_mov, base, True_TN, src);
03058 BB_Append_Op(new_bb, Mov_Op);
03059
03060 Nop_op = Mk_OP (TOP_nop_m, True_TN, Gen_Literal_TN(0, 4));
03061 BB_Append_Op(new_bb, Nop_op);
03062
03063
03064
03065 src = Gen_Register_TN(ISA_REGISTER_CLASS_integer, Pointer_Size);
03066 Set_TN_reg_value(src, reg_value_alloc1);
03067 Addl_Op = Mk_OP(TOP_addl, src, True_TN, var_name_tn, GP_TN);
03068 BB_Append_Op(new_bb, Addl_Op);
03069
03070 Nop_op = Mk_OP (TOP_nop_m, True_TN, Gen_Literal_TN(0, 4));
03071 BB_Append_Op(new_bb, Nop_op);
03072
03073
03074
03075 Enum_Op1 = Gen_Enum_TN(ECV_ldtype);
03076 Enum_Op2 = Gen_Enum_TN(ECV_ldhint);
03077 Ld8_Op = Mk_OP(TOP_ld8, src, True_TN, Enum_Op1, Enum_Op2, src);
03078 BB_Append_Op(new_bb, Ld8_Op);
03079
03080 Nop_op = Mk_OP (TOP_nop_m, True_TN, Gen_Literal_TN(0, 4));
03081 BB_Append_Op(new_bb, Nop_op);
03082
03083
03084
03085 base = Gen_Register_TN(ISA_REGISTER_CLASS_integer, Pointer_Size);
03086 Set_TN_reg_value(base, reg_value_alloc2);
03087 Ld4_Op = Mk_OP(TOP_ld4, base, True_TN, Enum_Op1, Enum_Op2, src);
03088 BB_Append_Op(new_bb, Ld4_Op);
03089
03090 Nop_op = Mk_OP (TOP_nop_m, True_TN, Gen_Literal_TN(0, 4));
03091 BB_Append_Op(new_bb, Nop_op);
03092
03093
03094
03095 Adds_Op = Mk_OP (TOP_adds, base, True_TN, Gen_Literal_TN(bb_cycle, 4), base);
03096 BB_Append_Op(new_bb, Adds_Op);
03097
03098
03099
03100 Enum_Op1 = Gen_Enum_TN(ECV_sttype);
03101 Enum_Op2 = Gen_Enum_TN(ECV_sthint);
03102 St4_Op = Mk_OP(TOP_st4, True_TN, Enum_Op1, Enum_Op2, src, base);
03103 BB_Append_Op(new_bb, St4_Op);
03104
03105 Handle_All_Hazards(new_bb);
03106 }
03107
03108
03109
03110 void Branch_Retarget(BB *bb)
03111 {
03112 BB *branch_bb;
03113 BB *temp_bb;
03114 OP *br;
03115 BBLIST *list;
03116
03117 for (list = bb->preds; list != NULL; list = BBLIST_next(list)) {
03118 temp_bb = list->item;
03119 BB_Retarget_Branch(temp_bb, bb, bb->prev);
03120 }
03121 }
03122
03123
03124
03125
03126 void Prepend_Nop_Op(BB *bb, TOP opr)
03127 {
03128 OP *op;
03129
03130 op = Mk_OP (opr, True_TN, Gen_Literal_TN(0, 4));
03131 BB_Prepend_Op(bb, op);
03132 }
03133
03134
03135
03136
03137
03138
03139 BB *Alloc_Inst_Insert_Before(BB *bb)
03140 {
03141 OP *Alloc_Op, *Last_Op, *Mov_Op;
03142 BB *new_bb, *Last_bb;
03143 TN *saved_pfs;
03144 REGISTER reg_value;
03145
03146 FmtAssert(bb != NULL, ("NULL input bb in Alloc_Inst_Insert_Before"));
03147 new_bb = Gen_And_Insert_BB_Before(bb);
03148 FmtAssert(new_bb != NULL, ("Failed to get new bb in Alloc_Inst_Insert_Before"));
03149 BB_Copy_Annotations(new_bb, bb, ANNOT_ENTRYINFO);
03150 REGION_First_BB = new_bb;
03151
03152
03153 reg_value = REGISTER_Request_Stacked_Register(ABI_PROPERTY_caller, ISA_REGISTER_CLASS_integer);
03154 saved_pfs = Gen_Register_TN(ISA_REGISTER_CLASS_integer, Pointer_Size);
03155 Set_TN_reg_value(saved_pfs, reg_value);
03156 Alloc_Op = Mk_OP(TOP_alloc, saved_pfs, Gen_Literal_TN(0, 4), Gen_Literal_TN(3, 4), Gen_Literal_TN(0, 4), Gen_Literal_TN(0, 4));
03157 Prepend_Nop_Op(new_bb, TOP_nop_i);
03158 Prepend_Nop_Op(new_bb, TOP_nop_m);
03159 BB_Prepend_Op(new_bb, Alloc_Op);
03160
03161
03162 new_bb->flags = new_bb->flags | BBM_ENTRY;
03163 bb->flags = bb->flags & ~BBM_ENTRY;
03164 Entry_BB_Head = BB_LIST_Delete(bb, Entry_BB_Head);
03165 Entry_BB_Head = BB_LIST_Push(new_bb, Entry_BB_Head, &MEM_pu_pool);
03166
03167 Handle_All_Hazards(new_bb);
03168
03169 if (BB_call(bb) || (BB_branch_op(bb))) {
03170 Split_BB_For_br(bb);
03171 Last_bb = bb->next;
03172 } else {
03173 FmtAssert(0, ("How can we see a pu that have no branch inst to finish itself "));
03174 }
03175
03176 Mov_Op = Mk_OP(TOP_mov_t_ar_r_i, Pfs_TN, True_TN, saved_pfs);
03177 BB_Prepend_Op(Last_bb, Mov_Op);
03178
03179 Handle_All_Hazards(Last_bb);
03180
03181 return new_bb;
03182 }
03183
03184
03185
03186
03187
03188 BB *Split_Entry_BB(BB *bb)
03189 {
03190 BB *new_bb;
03191 OP *op, *temp_op;
03192
03193
03194 new_bb = Gen_And_Insert_BB_Before(bb);
03195
03196 Clean_Up(bb);
03197 for (op = BB_first_op(bb); op != NULL; op = temp_op) {
03198 temp_op = OP_next(op);
03199 BB_Remove_Op(bb, op);
03200 BB_Append_Op(new_bb, op);
03201 if (OP_code(op) != TOP_alloc) {
03202 continue;
03203 } else {
03204 break;
03205 }
03206 }
03207
03208 FmtAssert( OP_code(op) == TOP_alloc, ("The BB has no 'alloc' instruction "));
03209
03210 BB_Copy_Annotations(new_bb, bb, ANNOT_ENTRYINFO);
03211 REGION_First_BB = new_bb;
03212 Set_BB_entry(new_bb);
03213 Entry_BB_Head = BB_LIST_Push(new_bb, Entry_BB_Head, &MEM_pu_pool);
03214
03215 Entry_BB_Head = BB_LIST_Delete(bb, Entry_BB_Head);
03216 Reset_BB_entry(bb);
03217
03218 Handle_All_Hazards(bb);
03219 Handle_All_Hazards(new_bb);
03220
03221 return new_bb;
03222 }
03223
03224 BOOL Selected_PU(char * PU_Name)
03225 {
03226 char *str_point;
03227 char *point;
03228 char *options;
03229 int str_length;
03230 int i;
03231
03232 str_length = strlen(Cycle_String);
03233 options = (char*)malloc(str_length + 1);
03234 strncpy(options, Cycle_String, str_length);
03235 options[str_length] = '\0';
03236
03237 point = str_point = options;
03238 i = 0;
03239
03240 while (*str_point == '"' || *str_point == ' ' || *str_point == '%'){
03241 str_point ++;
03242 point ++;
03243 i ++;
03244 }
03245 while(*str_point != '\0') {
03246 while (*point != ' ' && *point != '"' && *point != '\0' && *point != '%') {
03247 point ++;
03248 i ++;
03249 }
03250 *point = '\0';
03251
03252 if (strcmp(PU_Name, str_point) == 0){
03253 free(options);
03254 return TRUE;
03255 }
03256
03257 if (i >= str_length)
03258 break;
03259 point++;
03260 i ++;
03261 str_point=point;
03262 while(*str_point == '%' && *str_point != '\0') {
03263 str_point ++;
03264 point ++;
03265 i++;
03266 }
03267 }
03268 free(options);
03269 return FALSE;
03270 }
03271
03272
03273
03274
03275 void Pu_Cycle_Count_Func_Insert( ST* pu, BOOL is_region )
03276 {
03277 BB_LIST *elist;
03278 BOOL gra_run = ! CG_localize_tns;
03279 BB *bb, *temp_bb;
03280 OP *op, *br;
03281 char *PU_Name;
03282 char *PU_Temp_Name;
03283 INT num_input, num_local, num_output, num_rotating;
03284 char *PU_Symbol_Name;
03285 char *Spill_Symbol_Name[ISA_REGISTER_MAX];
03286 char *Register_Symbol_Name[TO_SAVE_REGISTER];
03287 char *GP_Symbol_Name;
03288 char *PR_Symbol_Name;
03289 INT i;
03290 TN *spill_var_name_tn[ISA_REGISTER_MAX];
03291 TN *register_var_name_tn[TO_SAVE_REGISTER];
03292 TN *gp_var_name_tn;
03293 TN *pr_var_name_tn;
03294
03295 INT max_used_register_stack = 0;
03296
03297 num_input = num_local = num_output = num_rotating = 0;
03298 FmtAssert(pu != NULL, ("pu to be null in Pu_Cycle_Count_Func_Insert\n"));
03299
03300
03301
03302
03303 for ( elist = Entry_BB_Head; elist; elist = BB_LIST_rest(elist) ) {
03304 bb = BB_LIST_first(elist);
03305
03306
03307
03308
03309
03310 FOR_ALL_BB_OPs_FWD(bb, op) {
03311 if (OP_code(op) != TOP_alloc)
03312 continue;
03313 num_input = TN_immd_value(op->res_opnd[0]);
03314 num_local = TN_immd_value(op->res_opnd[1]);
03315 num_output = TN_immd_value(op->res_opnd[2]);
03316 num_rotating = TN_immd_value(op->res_opnd[3]);
03317 max_used_register_stack = num_input + num_local + num_output;
03318
03319 Set_OP_opnd(op, 2, Gen_Literal_TN(num_output + 2, 4));
03320 }
03321 }
03322
03323
03324 reg_value_alloc1 = REGISTER_Request_Stacked_Register(ABI_PROPERTY_caller, ISA_REGISTER_CLASS_integer);
03325 reg_value_alloc2 = REGISTER_Request_Stacked_Register(ABI_PROPERTY_caller, ISA_REGISTER_CLASS_integer);
03326
03327 static MEM_POOL global_symbol_pool;
03328
03329 PU_Name = ST_name(pu);
03330 MEM_POOL_Initialize(&global_symbol_pool, "instrumentation global symbol pool", FALSE);
03331 MEM_POOL_Push(&global_symbol_pool);
03332
03333 PU_Symbol_Name = TYPE_MEM_POOL_ALLOC_N(char, &global_symbol_pool, sizeof(char) * (strlen(Src_File_Name) + strlen(PU_Name) + strlen("Cycle_Symbol") + 3));
03334 sprintf(PU_Symbol_Name, "%s_%s_%s", Src_File_Name, PU_Name, "Cycle_Symbol");
03335 while((PU_Temp_Name = strchr(PU_Symbol_Name, '.')) != NULL || (PU_Temp_Name = strchr(PU_Symbol_Name, '-')) != NULL)
03336 {
03337 *PU_Temp_Name = '_';
03338 }
03339
03340
03341 TY_IDX ty = MTYPE_To_TY(MTYPE_I8);
03342 ST *global_st = New_ST(GLOBAL_SYMTAB);
03343 ST_Init(global_st, Save_Str2(PU_Symbol_Name, ""), CLASS_VAR, SCLASS_UGLOBAL, EXPORT_PREEMPTIBLE, ty);
03344 Allocate_Object(global_st);
03345 INT64 offset = 0;
03346 INT32 relocs = TN_RELOC_IA_LTOFF22;
03347 TN *var_name_tn = Gen_Symbol_TN(global_st, offset, relocs);
03348
03349
03350
03351 if (Cycle_BB_Enable && Selected_PU(ST_name(pu))) {
03352 BB_Symbol_Point = BB_Symbol_Head = (BB_symbol *)malloc(sizeof(BB_symbol));
03353 BB_Symbol_Head->next = NULL;
03354 for (bb = REGION_First_BB; bb != NULL; bb = temp_bb) {
03355 BB_symbol *BB_Symbol_Name;
03356 char bb_id[10];
03357
03358 temp_bb = BB_next(bb);
03359 br= BB_branch_op(bb);
03360 if (!BB_call(bb) && !br && !BB_exit(bb) && BB_length(bb)) {
03361 sprintf(bb_id, "%d", bb->id);
03362 BB_Symbol_Point->name = (char *)malloc(sizeof(char)*(strlen(bb_id) + strlen(PU_Name) + 2));
03363 sprintf(BB_Symbol_Point->name, "%s_%d", PU_Name, bb->id);
03364 BB_Symbol_Name = (BB_symbol *)malloc(sizeof(BB_symbol));
03365 BB_Symbol_Point->id = bb->id;
03366 BB_Symbol_Point->next = BB_Symbol_Name;
03367 BB_Symbol_Name->next = NULL;
03368 BB_Symbol_Point = BB_Symbol_Name;
03369 }
03370 }
03371
03372
03373 TY_IDX BB_ty = MTYPE_To_TY(MTYPE_I8);
03374 BB_Symbol_Point = BB_Symbol_Head;
03375 do {
03376 BB_Symbol_Point->global_BB_st = New_ST(GLOBAL_SYMTAB);
03377 ST_Init(BB_Symbol_Point->global_BB_st, Save_Str2(BB_Symbol_Point->name, ""), CLASS_VAR, SCLASS_UGLOBAL, EXPORT_PREEMPTIBLE, BB_ty);
03378 Allocate_Object(BB_Symbol_Point->global_BB_st);
03379 BB_Symbol_Point->BB_var_name_tn = Gen_Symbol_TN(BB_Symbol_Point->global_BB_st, offset, relocs);
03380 BB_Symbol_Point = BB_Symbol_Point->next;
03381 } while (BB_Symbol_Point->next != NULL);
03382 }
03383
03384 if (strcmp(PU_Name, "main") == 0) {
03385 GP_Symbol_Name = TYPE_MEM_POOL_ALLOC_N(char, &global_symbol_pool, sizeof(char) * (strlen(PU_Name) + strlen("GP_Symbol") + 2));
03386 PR_Symbol_Name = TYPE_MEM_POOL_ALLOC_N(char, &global_symbol_pool, sizeof(char) * (strlen(PU_Name) + strlen("PR_Symbol") + 2));
03387
03388 sprintf(GP_Symbol_Name, "%s_%s", PU_Name, "GP_Symbol");
03389 sprintf(PR_Symbol_Name, "%s_%s", PU_Name, "PR_Symbol");
03390
03391 for (i = 0; i < num_output ; i++) {
03392 if (i > 9)
03393 Spill_Symbol_Name[i] = TYPE_MEM_POOL_ALLOC_N(char, &global_symbol_pool, sizeof(char) * (strlen(PU_Name) + strlen("Spill_Symbol") + 5));
03394 else
03395 Spill_Symbol_Name[i] = TYPE_MEM_POOL_ALLOC_N(char, &global_symbol_pool, sizeof(char) * (strlen(PU_Name) + strlen("Spill_Symbol") + 4));
03396 sprintf(Spill_Symbol_Name[i], "%s_%s_%d", PU_Name, "Spill_Symbol", i);
03397 }
03398
03399
03400
03401 for (i = 0; i < TO_SAVE_REGISTER; i++) {
03402 if (i > 9)
03403 Register_Symbol_Name[i] = TYPE_MEM_POOL_ALLOC_N(char, &global_symbol_pool, sizeof(char) * (strlen(PU_Name) + strlen("Register_Symbol") + 5));
03404 else
03405 Register_Symbol_Name[i] = TYPE_MEM_POOL_ALLOC_N(char, &global_symbol_pool, sizeof(char) * (strlen(PU_Name) + strlen("Register_Symbol") + 4));
03406 sprintf(Register_Symbol_Name[i], "%s_%s_%d", PU_Name, "Register_Symbol", i);
03407 }
03408
03409
03410
03411
03412
03413
03414 TY_IDX spill_ty = MTYPE_To_TY(MTYPE_I8);
03415 for (i = 0; i < num_output ; i++) {
03416 ST* global_spill_st = New_ST(GLOBAL_SYMTAB);
03417 ST_Init(global_spill_st, Save_Str2(Spill_Symbol_Name[i], ""), CLASS_VAR, SCLASS_UGLOBAL, EXPORT_PREEMPTIBLE, spill_ty);
03418 Allocate_Object(global_spill_st);
03419 spill_var_name_tn[i] = Gen_Symbol_TN(global_spill_st, offset, relocs);
03420 }
03421
03422
03423 TY_IDX register_ty = MTYPE_To_TY(MTYPE_I8);
03424 for (i = 0; i < TO_SAVE_REGISTER ; i++) {
03425 ST* global_register_st = New_ST(GLOBAL_SYMTAB);
03426 ST_Init(global_register_st, Save_Str2(Register_Symbol_Name[i], ""), CLASS_VAR, SCLASS_UGLOBAL, EXPORT_PREEMPTIBLE, register_ty);
03427 Allocate_Object(global_register_st);
03428 register_var_name_tn[i] = Gen_Symbol_TN(global_register_st, offset, relocs);
03429 }
03430
03431
03432 TY_IDX gp_ty = MTYPE_To_TY(MTYPE_I8);
03433 ST* gp_st = New_ST(GLOBAL_SYMTAB);
03434 ST_Init(gp_st, Save_Str2(GP_Symbol_Name, ""), CLASS_VAR, SCLASS_UGLOBAL, EXPORT_PREEMPTIBLE, gp_ty);
03435 Allocate_Object(gp_st);
03436 gp_var_name_tn = Gen_Symbol_TN(gp_st, offset, relocs);
03437
03438
03439 TY_IDX pr_ty = MTYPE_To_TY(MTYPE_I8);
03440 ST* pr_st = New_ST(GLOBAL_SYMTAB);
03441 ST_Init(pr_st, Save_Str2(PR_Symbol_Name, ""), CLASS_VAR, SCLASS_UGLOBAL, EXPORT_PREEMPTIBLE, pr_ty);
03442 Allocate_Object(pr_st);
03443 pr_var_name_tn = Gen_Symbol_TN(pr_st, offset, relocs);
03444 }
03445
03446
03447
03448
03449 fprintf(Output_h_File, "extern long int %s;\n", PU_Symbol_Name);
03450 pu_string[pu_number] = (char *)malloc(strlen(PU_Symbol_Name) + 1);
03451 sprintf(pu_string[pu_number], "%s", PU_Symbol_Name);
03452 pu_number ++;
03453
03454 if (pu_number > PU_IN_ONE_FILE)
03455 FmtAssert(FALSE, ("Too many pu in one file, Can't to handle file in which the number of pu great than 1000"));
03456
03457 if (Cycle_BB_Enable && Selected_PU(ST_name(pu))) {
03458 BB_Symbol_Point = BB_Symbol_Head;
03459 while (BB_Symbol_Point->next != NULL) {
03460 fprintf(Output_h_File, "extern long int %s;\n", BB_Symbol_Point->name);
03461 bb_string[bb_number] = (char *)malloc(strlen(BB_Symbol_Point->name) + 1);
03462 sprintf(bb_string[bb_number], "%s", BB_Symbol_Point->name);
03463 bb_number ++;
03464 BB_Symbol_Point = BB_Symbol_Point->next;
03465
03466 if (bb_number > BB_IN_ONE_PU)
03467 FmtAssert(FALSE, ("Can't handle the PU in which the number of bbs is larege than 1000"));
03468 }
03469 }
03470
03471 MEM_POOL_Pop(&global_symbol_pool);
03472 MEM_POOL_Delete(&global_symbol_pool);
03473
03474
03475
03476
03477
03478 for (bb = REGION_First_BB; bb != NULL; bb = temp_bb) {
03479 temp_bb = BB_next(bb);
03480 br= BB_branch_op(bb);
03481 if (!BB_call(bb) && !br && !BB_exit(bb) && BB_length(bb)) {
03482 Cycle_Count_Frag_Insert (bb, max_used_register_stack, var_name_tn, AFTER, BB_cycle(bb));
03483 if (Cycle_BB_Enable && Selected_PU(ST_name(pu))) {
03484 BB_Symbol_Point = BB_Symbol_Head;
03485 while (BB_Symbol_Point->next != NULL && BB_Symbol_Point->id != bb->id) {
03486 BB_Symbol_Point = BB_Symbol_Point->next;
03487 }
03488 if (BB_Symbol_Point != NULL)
03489 Cycle_Count_Frag_Insert (bb->next, max_used_register_stack, BB_Symbol_Point->BB_var_name_tn, AFTER, BB_cycle(bb));
03490 }
03491 }
03492 if (BB_exit(bb) && (!BB_entry(bb)) && BB_length(bb)) {
03493 Cycle_Count_Frag_Insert (bb, max_used_register_stack, var_name_tn, BEFORE, BB_cycle(bb));
03494 Branch_Retarget(bb);
03495 }
03496
03497 if (BB_exit(bb) && BB_entry(bb) && BB_length(bb)) {
03498 BOOL alloc_in = FALSE;
03499 BB *new_bb;
03500
03501 FOR_ALL_BB_OPs_FWD(bb, op) {
03502 if (OP_code(op) != TOP_alloc)
03503 continue;
03504 else
03505 alloc_in = TRUE;
03506 }
03507 if (alloc_in) {
03508 new_bb = Split_Entry_BB(bb);
03509 Cycle_Count_Frag_Insert (BB_next(new_bb), max_used_register_stack, var_name_tn, BEFORE, BB_cycle(BB_next(new_bb)));
03510 } else {
03511
03512 new_bb = Alloc_Inst_Insert_Before(bb);
03513 max_used_register_stack = 1;
03514 Cycle_Count_Frag_Insert (BB_next(new_bb), max_used_register_stack, var_name_tn, AFTER, BB_cycle(BB_next(new_bb)));
03515 }
03516 }
03517 }
03518
03519
03520
03521 if (strcmp(ST_name(pu), "main") == 0) {
03522 BB_LIST *entry_elist;
03523 for ( entry_elist = Entry_BB_Head; entry_elist;
03524 entry_elist = BB_LIST_rest(entry_elist) ) {
03525 Cycle_Output_Func_Insert( BB_LIST_first(entry_elist), max_used_register_stack, spill_var_name_tn, gp_var_name_tn, pr_var_name_tn, register_var_name_tn, num_output , "pu_output");
03526 }
03527 }
03528 if (Cycle_BB_Enable && Selected_PU(ST_name(pu))) {
03529 while (BB_Symbol_Head != NULL) {
03530 BB_Symbol_Point = BB_Symbol_Head;
03531 BB_Symbol_Head = BB_Symbol_Point->next;
03532 free(BB_Symbol_Point);
03533 }
03534 }
03535 }
03536
03537
03538
03539
03540 void Change_Succs(BB *bb, BB *last_bb)
03541 {
03542 BBLIST *list, *last_list, *temp_list, *preds_list;
03543 BB *temp_bb;
03544
03545 FmtAssert(bb != NULL || last_bb != NULL, ("Null BB during the Change_Succs "));
03546
03547 bb->succs = last_bb->succs;
03548 last_bb->succs = NULL;
03549
03550
03551
03552 for (list = bb->succs; list != NULL ; list = list->next) {
03553 temp_bb = list->item;
03554 temp_list = temp_bb->preds;
03555 last_list = NULL;
03556 for (preds_list = temp_bb->preds;
03557 (temp_list != last_list) && (temp_list != NULL); preds_list = temp_list) {
03558 last_list = preds_list;
03559 temp_list = preds_list->next;
03560 if (preds_list->item == last_bb)
03561 preds_list->item = bb;
03562 }
03563 }
03564 }
03565
03566
03567
03568
03569 int Check_Check(OP *op)
03570 {
03571 if (op->opr == TOP_chk_s_i || op->opr == TOP_chk_s_m ||
03572 op->opr == TOP_chk_f_s || op->opr == TOP_chk_a ||
03573 op->opr == TOP_chk_f_a || op->opr == TOP_chk_s )
03574 return 1;
03575 return 0;
03576 }
03577
03578
03579
03580
03581
03582 void Split_BB_For_br(BB *bb)
03583 {
03584 BB *new_bb;
03585 OP *last_op, *nop_op;
03586 INT op_index = 0;
03587 OP *br = BB_branch_op(bb);
03588
03589 FmtAssert(bb != NULL, ("Null bb during the Split_BB_For_br "));
03590
03591 last_op = BB_last_op(bb);
03592 FmtAssert(last_op!=NULL, ("To get the last op of the bb failed "));
03593 if (BB_call(bb)) {
03594 op_index = 1;
03595 BB_Remove_Op(bb, last_op);
03596 }
03597 if (br) {
03598 op_index = 2;
03599 BB_Remove_Op(bb, br);
03600 if (OP_noop(last_op)) {
03601 op_index = 3;
03602 BB_Remove_Op(bb, last_op);
03603 }
03604 }
03605
03606
03607 new_bb = Gen_And_Insert_BB_After(bb);
03608 switch(op_index) {
03609 case 1:
03610 Set_BB_call(new_bb);
03611 Reset_BB_call(bb);
03612 case 2:
03613
03614
03615
03616 Prepend_Nop_Op(new_bb, TOP_nop_i);
03617 Prepend_Nop_Op(new_bb, TOP_nop_m);
03618 BB_Append_Op(new_bb, last_op);
03619 if (Check_Check(last_op))
03620 nop_op = Mk_OP(TOP_nop_i, True_TN, Gen_Literal_TN(0, 4));
03621 else
03622 nop_op = Mk_OP(TOP_nop_b, True_TN, Gen_Literal_TN(0, 4));
03623 BB_Append_Op(bb, nop_op);
03624 break;
03625 case 3:
03626 BB_Append_Op(new_bb, br);
03627 BB_Append_Op(new_bb, last_op);
03628 Prepend_Nop_Op(new_bb, TOP_nop_m);
03629 nop_op = Mk_OP(TOP_nop_b, True_TN, Gen_Literal_TN(0, 4));
03630 BB_Append_Op(bb, nop_op);
03631 BB_Append_Op(bb, nop_op);
03632 break;
03633 case 0:
03634 default:
03635 FmtAssert(0, ("Fatal Error"));
03636 break;
03637 }
03638
03639
03640 Change_Succs(new_bb, bb);
03641 }
03642
03643
03644
03645
03646
03647
03648 void Split_BB()
03649 {
03650 BB_LIST *elist;
03651 BB *bb, *temp_bb;
03652 BOOL gra_run = !CG_localize_tns;
03653
03654 for (bb = REGION_First_BB; bb != NULL; bb = temp_bb) {
03655 temp_bb = BB_next(bb);
03656 if (!BB_cycle(bb) && BB_rotating_kernel(bb)) {
03657 ANNOTATION *annot = ANNOT_Get(BB_annotations(bb), ANNOT_ROTATING_KERNEL);
03658 ROTATING_KERNEL_INFO *info = ANNOT_rotating_kernel(annot);
03659 INT ii = info->ii;
03660 BB_cycle(bb) = OP_scycle(BB_last_op(bb))%ii;
03661 }
03662 if (BB_call(bb) || (BB_branch_op(bb) && !BB_exit(bb)))
03663 Split_BB_For_br(bb);
03664 }
03665 }
03666
03667
03668
03669
03670
03671 void Cycle_Count_Initialize ( ST *pu, BOOL is_region )
03672 {
03673 int reg_index;
03674 BB *bb, *temp_bb;
03675 OP *op;
03676
03677 FmtAssert(pu != NULL, ("Null pu during the initialize "));
03678
03679
03680 for(reg_index = ISA_REGISTER_FIRST; reg_index < ISA_REGISTER_MAX; reg_index ++){
03681 if (ABI_PROPERTY_Is_stacked(ISA_REGISTER_CLASS_integer, reg_index)) {
03682 R32 = reg_index;
03683 break;
03684 }
03685 }
03686
03687 FmtAssert(R32 != 0, ("Null pu during the initialize "));
03688 for (bb = REGION_First_BB; bb != NULL; bb = temp_bb) {
03689 temp_bb = BB_next(bb);
03690 Clean_Up(bb);
03691 Handle_All_Hazards (bb);
03692 }
03693
03694 Split_BB();
03695 Pu_Cycle_Count_Func_Insert(pu, is_region);
03696 }
03697 #endif