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 #define __STDC_LIMIT_MACROS
00059 #include <stdint.h>
00060 #ifdef USE_PCH
00061 #include "cg_pch.h"
00062 #endif // USE_PCH
00063 #pragma hdrstop
00064
00065 #include "defs.h"
00066 #include "config.h"
00067 #include "config_list.h"
00068 #include "erglob.h"
00069 #include "xstats.h"
00070 #include "tracing.h"
00071
00072 #include "strtab.h"
00073 #include "tn.h"
00074 #include "tn_list.h"
00075 #include "ttype.h"
00076
00077 #include "const.h"
00078 #include "targ_const.h"
00079 #include "targ_sim.h"
00080
00081 #include "reg_live.h"
00082 #include "gra_live.h"
00083 #include "op_list.h"
00084 #include "hb_hazards.h"
00085 #include "register.h"
00086 #include "targ_isa_registers.h"
00087 #include "targ_proc_properties.h"
00088 #include "targ_isa_enums.h"
00089 #include "stblock.h"
00090 #include "data_layout.h"
00091 #include "findloops.h"
00092 #if defined(TARG_SL)
00093 #include <map>
00094 using std::map;
00095 #endif
00096
00097 #define DEFAULT_RCLASS_SIZE(rc) \
00098 (REGISTER_bit_size(rc, REGISTER_CLASS_last_register(rc))/8)
00099
00100
00101
00102
00103
00104
00105
00106
00107
00108 TN *RA_TN = NULL;
00109 TN *SP_TN = NULL;
00110 TN *FP_TN = NULL;
00111 TN *Ep_TN = NULL;
00112 TN *GP_TN = NULL;
00113 #if defined(TARG_IA64)
00114 TN *TP_TN = NULL;
00115 #endif
00116 TN *Zero_TN = NULL;
00117 TN *Pfs_TN = NULL;
00118 TN *True_TN = NULL;
00119 TN *FZero_TN = NULL;
00120 TN *FOne_TN = NULL;
00121 TN *LC_TN = NULL;
00122 #if defined(TARG_SL)
00123 TN *TMP1_TN = NULL;
00124 TN *TMP2_TN = NULL;
00125 TN *JA_TN = NULL;
00126 TN *LC0_TN = NULL;
00127 TN *LC1_TN = NULL;
00128 TN *LC2_TN = NULL;
00129 TN *LC3_TN = NULL;
00130 TN *HI_TN = NULL;
00131 TN *Acc0_TN = NULL;
00132 TN *Acc1_TN = NULL;
00133 TN *Acc2_TN = NULL;
00134 TN *Acc3_TN = NULL;
00135 TN *Addr0_TN = NULL;
00136 TN *Addr1_TN = NULL;
00137 TN *Addr2_TN = NULL;
00138 TN *Addr3_TN = NULL;
00139 TN *Addr4_TN = NULL;
00140 TN *Addr5_TN = NULL;
00141 TN *Addr6_TN = NULL;
00142 TN *Addr7_TN = NULL;
00143 TN *Addrsize0_TN = NULL;
00144 TN *Addrsize1_TN = NULL;
00145 TN *Addrsize2_TN = NULL;
00146 TN *Addrsize3_TN = NULL;
00147 TN *Addrsize4_TN = NULL;
00148 TN *Addrsize5_TN = NULL;
00149 TN *Addrsize6_TN = NULL;
00150 TN *Addrsize7_TN = NULL;
00151
00152 INT32 AccPregN = -1;
00153 INT32 AddPregN = -1;
00154 std::map<INT32, TN*> var2acc;
00155 std::map<INT32, TN*> var2addr;
00156 int ACCreg[4]= {0,0,0,0};
00157 int Addreg[8]= {0,0,0,0,0,0,0,0};
00158 #endif
00159
00160
00161
00162
00163
00164
00165
00166
00167
00168
00169
00170
00171 TN_NUM Last_TN = 0;
00172
00173
00174 TN_NUM Last_Dedicated_TN = 0;
00175
00176 TN_NUM First_Regular_TN = 0;
00177
00178 TN_NUM First_REGION_TN = 0;
00179
00180
00181 TN **TN_Vec = NULL;
00182 #define TN_VEC_INIT 999
00183 #define TN_VEC_INCR 499
00184
00185
00186
00187
00188
00189
00190
00191 #define HASH_TABLE_SIZE 512
00192 #define HASH_VALUE(ivalue) ((INT)(ivalue) & (HASH_TABLE_SIZE-1))
00193 #define HASH_SYMBOL(st, offset) ( ((INT)(INTPS)((st)+(offset))) & (HASH_TABLE_SIZE-1))
00194
00195
00196 static TN_LIST *Hash_Table[HASH_TABLE_SIZE];
00197
00198
00199
00200
00201
00202
00203
00204
00205
00206
00207
00208
00209
00210
00211 static INT64
00212 Targ_TN_Add( INT64 val1, INT16 size1, INT64 val2, INT16 size2 )
00213 {
00214 if ( size1 <= sizeof(mINT32) && size2 <= sizeof(mINT32) )
00215 return ( ((mINT32)val1) + ((mINT32)val2) );
00216 else
00217 return ( val1 + val2 );
00218 }
00219
00220
00221
00222
00223 static TN *
00224 Search_For_Previous_Constant (INT64 ivalue, INT size)
00225 {
00226 TN_LIST *p;
00227 INT hash_value;
00228 TN *tn;
00229
00230 hash_value = HASH_VALUE(ivalue);
00231 for(p = Hash_Table[hash_value]; p != NULL; p = TN_LIST_rest(p)) {
00232 tn = TN_LIST_first(p);
00233 if (TN_has_value(tn) &&
00234 TN_value(tn) == ivalue &&
00235 TN_size(tn) == size)
00236 {
00237 return tn;
00238 }
00239 }
00240 return NULL;
00241 }
00242
00243 static TN *
00244 Search_For_Previous_Enum (ISA_ENUM_CLASS_VALUE ecv)
00245 {
00246 TN_LIST *p;
00247 INT hash_value;
00248 TN *tn;
00249
00250 hash_value = HASH_VALUE(ecv);
00251 for(p = Hash_Table[hash_value]; p != NULL; p = TN_LIST_rest(p)) {
00252 tn = TN_LIST_first(p);
00253 if (TN_is_enum(tn) && TN_enum(tn) == ecv)
00254 {
00255 return tn;
00256 }
00257 }
00258 return NULL;
00259 }
00260
00261
00262 static TN *
00263 Search_For_Previous_Symbol (ST *st, INT64 offset, INT relocs)
00264 {
00265 TN_LIST *p;
00266 INT hash_value;
00267 TN *tn;
00268
00269 hash_value = HASH_SYMBOL(st, offset);
00270 for (p = Hash_Table[hash_value]; p != NULL; p = TN_LIST_rest(p)) {
00271 tn = TN_LIST_first(p);
00272 if (TN_is_symbol(tn) &&
00273 TN_var(tn) == st &&
00274 TN_offset(tn) == offset &&
00275 TN_relocs(tn) == relocs)
00276 {
00277 return tn;
00278 }
00279 }
00280 return NULL;
00281 }
00282
00283
00284
00285
00286
00287
00288
00289
00290
00291 static void
00292 Check_TN_Vec_Size ( void )
00293 {
00294 static TN_NUM TN_Count = 0;
00295
00296 if ( TN_Count <= Last_TN+2 ) {
00297 if (TN_Vec == NULL) {
00298 TN_Count = TN_VEC_INIT;
00299 TN_Vec = (TN **) calloc ( TN_Count+1, sizeof(TN *) );
00300 }
00301 else {
00302 TN_Count += TN_VEC_INCR;
00303 TN_Vec = (TN **) realloc ( TN_Vec, (TN_Count+1)*sizeof(TN *) );
00304 BZERO ( &TN_Vec[TN_Count-TN_VEC_INCR+1], (TN_VEC_INCR)*sizeof(TN *) );
00305 }
00306 }
00307 }
00308
00309
00310
00311
00312
00313
00314
00315
00316
00317
00318 static TN *
00319 Gen_TN ( void )
00320 {
00321
00322 TN *tn = TYPE_PU_ALLOC (TN);
00323 PU_TN_Cnt++;
00324 return tn;
00325 }
00326
00327
00328
00329
00330
00331
00332
00333
00334
00335
00336
00337
00338
00339
00340 TN *
00341 Dup_TN ( TN *tn )
00342 {
00343 TN *new_tn = Gen_TN();
00344
00345 Is_True(! TN_is_dedicated(tn),("Dup_TN of a dedicated TN: TN%d",
00346 TN_number(tn)));
00347
00348 *new_tn = *tn;
00349 if (!TN_is_constant(new_tn)) {
00350 Check_TN_Vec_Size ();
00351 Set_TN_number(new_tn,++Last_TN);
00352 Reset_TN_is_global_reg(new_tn);
00353 TN_Allocate_Register (new_tn, REGISTER_UNDEFINED);
00354 TNvec(Last_TN) = new_tn;
00355
00356 if (!TN_is_rematerializable(tn) && !TN_is_gra_homeable(tn)) {
00357 Set_TN_spill(new_tn, NULL);
00358 }
00359 }
00360
00361 return new_tn;
00362 }
00363
00364
00365
00366
00367
00368
00369
00370
00371
00372
00373
00374
00375
00376 TN*
00377 Dup_TN_Even_If_Dedicated(
00378 TN *tn
00379 )
00380 {
00381 TN tn_block;
00382
00383 if ( ! TN_is_dedicated(tn) )
00384 return Dup_TN(tn);
00385 else {
00386 tn_block = *tn;
00387
00388 Reset_TN_is_dedicated(&tn_block);
00389 TN_Allocate_Register (&tn_block, REGISTER_UNDEFINED);
00390
00391 return Dup_TN(&tn_block);
00392 }
00393 }
00394
00395
00396
00397
00398
00399
00400 static TN *ded_tns[ISA_REGISTER_CLASS_MAX + 1][REGISTER_MAX + 1];
00401 static TN *f4_ded_tns[REGISTER_MAX + 1];
00402 #ifdef TARG_IA64
00403 static TN *f10_ded_tns[REGISTER_MAX + 1];
00404 #endif
00405 #ifdef KEY
00406 #ifndef TARG_NVISA
00407 static TN *v16_ded_tns[REGISTER_MAX + 1];
00408 static TN *i1_ded_tns[REGISTER_MAX + 1];
00409 static TN *i2_ded_tns[REGISTER_MAX + 1];
00410 static TN *i4_ded_tns[REGISTER_MAX + 1];
00411 #endif
00412 #endif // KEY
00413 #if defined(TARG_SL)
00414 static TN *a4_ded_tns[REGISTER_MAX +1];
00415 #endif
00416 #if defined(TARG_SL)
00417 TN* C2_ACC_TN = NULL;
00418 TN* C2_COND_TN = NULL;
00419 TN* C2_MVSEL_TN = NULL;
00420 TN* C2_VLCS_TN = NULL;
00421 TN* C2_MOVPAT_TN = NULL;
00422 #endif
00423
00424
00425
00426
00427
00428
00429
00430
00431
00432 static TN *
00433 Create_Dedicated_TN (ISA_REGISTER_CLASS rclass, REGISTER reg)
00434 {
00435 INT size = REGISTER_bit_size(rclass, reg) / 8;
00436 #ifndef TARG_SL
00437 BOOL is_float = rclass == ISA_REGISTER_CLASS_float;
00438 #else
00439 BOOL is_float = FALSE;
00440 #endif
00441
00442 #ifdef TARG_X8664
00443 is_float |= ( rclass == ISA_REGISTER_CLASS_x87 );
00444 #endif
00445
00446
00447
00448
00449 TN *tn = TYPE_SRC_ALLOC (TN);
00450
00451 Check_TN_Vec_Size ();
00452 Set_TN_number(tn,++Last_TN);
00453 TNvec(Last_TN) = tn;
00454 Set_TN_is_dedicated(tn);
00455 Set_TN_register_class(tn, rclass);
00456 Set_TN_register(tn, reg);
00457 Set_TN_size(tn, size);
00458 if ( is_float ) Set_TN_is_float(tn);
00459 return(tn);
00460 }
00461
00462
00463
00464
00465
00466
00467
00468
00469
00470
00471 void
00472 Init_Dedicated_TNs (void)
00473 {
00474 ISA_REGISTER_CLASS rclass;
00475 REGISTER reg;
00476 TN_NUM tnum = 0;
00477
00478 FOR_ALL_ISA_REGISTER_CLASS(rclass) {
00479 for (reg = REGISTER_MIN;
00480 reg <= REGISTER_CLASS_last_register(rclass);
00481 reg++
00482 ) {
00483 #ifdef TARG_NVISA
00484
00485 if (REGISTER_allocatable (rclass, reg))
00486 continue;
00487 #endif
00488 ++tnum;
00489 ded_tns[rclass][reg] = Create_Dedicated_TN(rclass, reg);
00490 }
00491 }
00492
00493
00494 Zero_TN = ded_tns[REGISTER_CLASS_zero][REGISTER_zero];
00495 Ep_TN = ded_tns[REGISTER_CLASS_ep][REGISTER_ep];
00496 SP_TN = ded_tns[REGISTER_CLASS_sp][REGISTER_sp];
00497 FP_TN = ded_tns[REGISTER_CLASS_fp][REGISTER_fp];
00498 RA_TN = ded_tns[REGISTER_CLASS_ra][REGISTER_ra];
00499 Pfs_TN = ded_tns[REGISTER_CLASS_pfs][REGISTER_pfs];
00500 True_TN = ded_tns[REGISTER_CLASS_true][REGISTER_true];
00501 FZero_TN = ded_tns[REGISTER_CLASS_fzero][REGISTER_fzero];
00502 FOne_TN = ded_tns[REGISTER_CLASS_fone][REGISTER_fone];
00503 #ifdef ABI_PROPERTY_loop_count
00504 LC_TN = ded_tns[REGISTER_CLASS_lc][REGISTER_lc];
00505 #endif
00506 #if defined(TARG_SL)
00507 TMP1_TN = ded_tns[REGISTER_CLASS_k0][REGISTER_k0];
00508 TMP2_TN = ded_tns[REGISTER_CLASS_k1][REGISTER_k1];
00509 JA_TN = ded_tns[REGISTER_CLASS_ja][REGISTER_ja];
00510 LC0_TN = ded_tns[REGISTER_CLASS_lc0][REGISTER_lc0];
00511 LC1_TN = ded_tns[REGISTER_CLASS_lc1][REGISTER_lc1];
00512 LC2_TN = ded_tns[REGISTER_CLASS_lc2][REGISTER_lc2];
00513 LC3_TN = ded_tns[REGISTER_CLASS_lc3][REGISTER_lc3];
00514 HI_TN = ded_tns[REGISTER_CLASS_hi][REGISTER_hi];
00515 Acc0_TN = ded_tns[REGISTER_CLASS_acc0][REGISTER_acc0];
00516 Acc1_TN = ded_tns[REGISTER_CLASS_acc1][REGISTER_acc1];
00517 Acc2_TN = ded_tns[REGISTER_CLASS_acc2][REGISTER_acc2];
00518 Acc3_TN = ded_tns[REGISTER_CLASS_acc3][REGISTER_acc3];
00519 Addr0_TN = ded_tns[REGISTER_CLASS_add0][REGISTER_add0];
00520 Addr1_TN = ded_tns[REGISTER_CLASS_add1][REGISTER_add1];
00521 Addr2_TN = ded_tns[REGISTER_CLASS_add2][REGISTER_add2];
00522 Addr3_TN = ded_tns[REGISTER_CLASS_add3][REGISTER_add3];
00523 Addr4_TN = ded_tns[REGISTER_CLASS_add4][REGISTER_add4];
00524 Addr5_TN = ded_tns[REGISTER_CLASS_add5][REGISTER_add5];
00525 Addr6_TN = ded_tns[REGISTER_CLASS_add6][REGISTER_add6];
00526 Addr7_TN = ded_tns[REGISTER_CLASS_add7][REGISTER_add7];
00527 Addrsize0_TN = ded_tns[REGISTER_CLASS_addsize0][REGISTER_addsize0];
00528 Addrsize1_TN = ded_tns[REGISTER_CLASS_addsize1][REGISTER_addsize1];
00529 Addrsize2_TN = ded_tns[REGISTER_CLASS_addsize2][REGISTER_addsize2];
00530 Addrsize3_TN = ded_tns[REGISTER_CLASS_addsize3][REGISTER_addsize3];
00531 Addrsize4_TN = ded_tns[REGISTER_CLASS_addsize4][REGISTER_addsize4];
00532 Addrsize5_TN = ded_tns[REGISTER_CLASS_addsize5][REGISTER_addsize5];
00533 Addrsize6_TN = ded_tns[REGISTER_CLASS_addsize6][REGISTER_addsize6];
00534 Addrsize7_TN = ded_tns[REGISTER_CLASS_addsize7][REGISTER_addsize7];
00535 #endif
00536 #if defined(TARG_SL)
00537 C2_ACC_TN = ded_tns[REGISTER_CLASS_c2acc][REGISTER_c2acc];
00538 C2_COND_TN = ded_tns[REGISTER_CLASS_c2cond][REGISTER_c2cond];
00539 C2_MVSEL_TN = ded_tns[REGISTER_CLASS_c2mvsel][REGISTER_c2mvsel];
00540 C2_VLCS_TN = ded_tns[REGISTER_CLASS_c2vlcs][REGISTER_c2vlcs];
00541 C2_MOVPAT_TN = ded_tns[REGISTER_CLASS_c2movpat][REGISTER_c2movpat];
00542 #endif
00543
00544 #if defined(TARG_PR)
00545 LC_TN = ded_tns[REGISTER_CLASS_lc][REGISTER_lc];
00546 RA_TN = ded_tns[REGISTER_CLASS_ra][REGISTER_ra];
00547 #endif
00548
00549
00550
00551
00552 #ifdef ABI_PROPERTY_global_ptr
00553 GP_TN = Create_Dedicated_TN (REGISTER_CLASS_gp, REGISTER_gp);
00554 tnum++;
00555 #endif
00556 #ifdef TARG_IA64
00557 TP_TN = Create_Dedicated_TN (REGISTER_CLASS_tp, REGISTER_tp);
00558 tnum++;
00559 #endif
00560
00561
00562 #ifndef TARG_NVISA
00563 for (reg = REGISTER_MIN;
00564 reg <= REGISTER_CLASS_last_register(ISA_REGISTER_CLASS_float);
00565 reg++
00566 ) {
00567 ++tnum;
00568 f4_ded_tns[reg] = Create_Dedicated_TN(ISA_REGISTER_CLASS_float, reg);
00569 Set_TN_size(f4_ded_tns[reg], 4);
00570 #if defined(TARG_IA64)
00571 ++tnum;
00572 f10_ded_tns[reg] = Create_Dedicated_TN(ISA_REGISTER_CLASS_float, reg);
00573 Set_TN_size(f10_ded_tns[reg], 16);
00574
00575 #endif
00576 #ifdef KEY
00577 v16_ded_tns[reg] = Create_Dedicated_TN(ISA_REGISTER_CLASS_float, reg);
00578 Set_TN_size(v16_ded_tns[reg], 16);
00579 #endif
00580 }
00581
00582 #ifdef KEY
00583 for (reg = REGISTER_MIN;
00584 reg <= REGISTER_CLASS_last_register(ISA_REGISTER_CLASS_integer);
00585 reg++
00586 ) {
00587 ++tnum;
00588 i1_ded_tns[reg] = Create_Dedicated_TN(ISA_REGISTER_CLASS_integer, reg);
00589 Set_TN_size(i1_ded_tns[reg], 1);
00590 ++tnum;
00591 i2_ded_tns[reg] = Create_Dedicated_TN(ISA_REGISTER_CLASS_integer, reg);
00592 Set_TN_size(i2_ded_tns[reg], 2);
00593 ++tnum;
00594 i4_ded_tns[reg] = Create_Dedicated_TN(ISA_REGISTER_CLASS_integer, reg);
00595 Set_TN_size(i4_ded_tns[reg], 4);
00596 }
00597 #endif // KEY
00598 #endif // ! NVISA
00599
00600 #if defined(TARG_SL)
00601 for (reg = REGISTER_MIN;
00602 reg <= REGISTER_CLASS_last_register(ISA_REGISTER_CLASS_accum);
00603 reg++
00604 ) {
00605 ++tnum;
00606 a4_ded_tns[reg] = Create_Dedicated_TN(ISA_REGISTER_CLASS_accum, reg);
00607 Set_TN_size(a4_ded_tns[reg], 4);
00608 }
00609 #endif
00610 Last_Dedicated_TN = tnum;
00611 }
00612
00613
00614
00615
00616
00617
00618
00619
00620
00621
00622 TN *
00623 Build_Dedicated_TN (ISA_REGISTER_CLASS rclass, REGISTER reg, INT size)
00624 {
00625 #if defined(TARG_IA64)
00626 if (rclass == ISA_REGISTER_CLASS_float) {
00627 if (size == 4)
00628 return f4_ded_tns[reg];
00629 if (size == 16)
00630 return f10_ded_tns[reg];
00631 }
00632 #elif defined(TARG_X8664) || defined(TARG_MIPS)
00633
00634 if (rclass == ISA_REGISTER_CLASS_float
00635 && size != DEFAULT_RCLASS_SIZE(rclass) )
00636 {
00637 switch(size) {
00638 case 4: return f4_ded_tns[reg];
00639 #if defined(TARG_X8664)
00640 case 16: return v16_ded_tns[reg];
00641 #endif // TARG_X8664
00642 }
00643 }
00644 #endif
00645
00646 #if defined(TARG_X8664) || defined(TARG_MIPS) || defined(TARG_SL)
00647
00648 if (rclass == ISA_REGISTER_CLASS_integer
00649 && size != DEFAULT_RCLASS_SIZE(rclass) )
00650 {
00651 switch(size) {
00652 case 1: return i1_ded_tns[reg];
00653 case 2: return i2_ded_tns[reg];
00654 case 4: return i4_ded_tns[reg];
00655 }
00656 }
00657 #endif
00658
00659 #if defined(TARG_SL)
00660 if (rclass == ISA_REGISTER_CLASS_accum && (size ==4)
00661 && size != DEFAULT_RCLASS_SIZE(rclass))
00662 {
00663 return a4_ded_tns[reg];
00664 }
00665 #endif // TARG_SL
00666
00667 return ded_tns[rclass][reg];
00668 }
00669
00670 TN *
00671 Gen_Register_TN (ISA_REGISTER_CLASS rclass, INT size)
00672 {
00673 Is_True(rclass != ISA_REGISTER_CLASS_UNDEFINED,
00674 ("Gen_Register_TN called with undefined reg class"));
00675
00676 if ( REGISTER_SET_EmptyP(REGISTER_CLASS_allocatable(rclass)) ) {
00677
00678 FmtAssert(REGISTER_CLASS_register_count(rclass) == 1,
00679 ("don't know how to make dedicated TN for class %s",
00680 REGISTER_CLASS_name(rclass)));
00681 return Build_Dedicated_TN(rclass, REGISTER_MIN, size);
00682 }
00683 else {
00684 TN *tn = Gen_TN();
00685 Check_TN_Vec_Size ();
00686 Set_TN_number(tn,++Last_TN);
00687 TNvec(Last_TN) = tn;
00688 if ( size > 16 ) ErrMsg ( EC_TN_Size, size );
00689 Set_TN_size(tn, size);
00690 #if !defined(TARG_SL)
00691 if ( rclass == ISA_REGISTER_CLASS_float) Set_TN_is_float(tn);
00692 #endif
00693 #ifdef TARG_X8664
00694 if ( rclass == ISA_REGISTER_CLASS_x87) Set_TN_is_float(tn);
00695 #endif
00696 Set_TN_register_class(tn, rclass);
00697 return tn;
00698 }
00699 }
00700
00701 #ifdef KEY
00702 TN *
00703 Gen_Typed_Register_TN (TYPE_ID mtype, INT size)
00704 {
00705 ISA_REGISTER_CLASS rclass = Register_Class_For_Mtype (mtype);
00706 TN* tn;
00707
00708 Is_True(rclass != ISA_REGISTER_CLASS_UNDEFINED,
00709 ("Gen_Typed_Register_TN encountered undefined reg class"));
00710
00711
00712
00713
00714 if ( REGISTER_SET_EmptyP(REGISTER_CLASS_allocatable(rclass)) &&
00715 (REGISTER_CLASS_register_count(rclass) == 1))
00716 {
00717 tn = Build_Dedicated_TN(rclass, REGISTER_MIN, size);
00718 }
00719 else {
00720 tn = Gen_TN();
00721 Check_TN_Vec_Size ();
00722 Set_TN_number(tn,++Last_TN);
00723 TNvec(Last_TN) = tn;
00724
00725 Set_TN_size(tn, size);
00726
00727 #if !defined(TARG_SL)
00728 if ( rclass == ISA_REGISTER_CLASS_float
00729 #ifdef TARG_X8664
00730 || rclass == ISA_REGISTER_CLASS_x87
00731 #endif
00732 )
00733 Set_TN_is_float(tn);
00734 #endif // TARG_SL
00735 Set_TN_register_class(tn, rclass);
00736 }
00737
00738 return tn;
00739 }
00740 #endif
00741
00742
00743 TN *
00744 Gen_Unique_Literal_TN (INT64 ivalue, INT size)
00745 {
00746 TN *tn = Gen_TN ();
00747 Set_TN_size(tn, size);
00748 Set_TN_is_constant(tn);
00749 Set_TN_has_value(tn);
00750 Set_TN_value(tn, ivalue);
00751 return tn;
00752 }
00753
00754
00755
00756
00757
00758
00759
00760
00761
00762
00763
00764 TN *
00765 Gen_Literal_TN ( INT64 ivalue, INT size )
00766 {
00767 INT hash_value;
00768 TN *tn;
00769
00770 Is_True(size != 4 || (ivalue >= -2147483648LL && ivalue <= 4294967295LL),
00771 ("Gen_Literal_TN: 4-byte literal 0x%016llx is out-of-range", ivalue));
00772
00773
00774
00775
00776 tn = Search_For_Previous_Constant (ivalue, size);
00777 if (tn == NULL) {
00778 tn = Gen_TN ();
00779 Set_TN_size(tn, size);
00780 Set_TN_is_constant(tn);
00781 Set_TN_has_value(tn);
00782 TN_value(tn) = ivalue;
00783
00784 hash_value = HASH_VALUE(ivalue);
00785 Hash_Table[hash_value] =
00786 TN_LIST_Push (tn, Hash_Table[hash_value], &MEM_pu_pool);
00787 }
00788 return tn;
00789 }
00790
00791 #if defined(TARG_NVISA)
00792 TN *
00793 Gen_Enum_TN (ISA_ENUM_CLASS_VALUE ecv)
00794 {
00795
00796
00797
00798 TN *tn = Search_For_Previous_Enum (ecv);
00799 if (tn == NULL) {
00800 INT hash_value;
00801 tn = Gen_TN ();
00802 Set_TN_size(tn, 2);
00803 Set_TN_is_constant(tn);
00804 Set_TN_is_enum(tn);
00805 Set_TN_enum(tn, ecv);
00806 hash_value = HASH_VALUE(ecv);
00807 Hash_Table[hash_value] =
00808 TN_LIST_Push (tn, Hash_Table[hash_value], &MEM_pu_pool);
00809 }
00810 return tn;
00811 }
00812 #else
00813 TN *
00814 Gen_Enum_TN (ISA_ENUM_CLASS_VALUE ecv)
00815 {
00816 TN *tn = Gen_TN ();
00817 Set_TN_size(tn, 2);
00818 Set_TN_is_constant(tn);
00819 Set_TN_is_enum(tn);
00820 Set_TN_enum(tn, ecv);
00821 return tn;
00822 }
00823 #endif
00824
00825
00826
00827
00828
00829
00830
00831
00832
00833
00834
00835
00836
00837 TN *
00838 Gen_Symbol_TN ( ST *st, INT64 offset, INT32 relocs)
00839 {
00840 TN *tn;
00841 INT hash_value;
00842
00843
00844 tn = Search_For_Previous_Symbol (st, offset, relocs);
00845 if (tn == NULL) {
00846 tn = Gen_TN ();
00847 Set_TN_size(tn, Pointer_Size);
00848 Set_TN_is_constant(tn);
00849 Set_TN_is_symbol(tn);
00850 Set_TN_var(tn, st);
00851 TN_offset(tn) = offset;
00852 TN_relocs(tn) = relocs;
00853
00854 hash_value = HASH_SYMBOL(st, offset);
00855 Hash_Table[hash_value] =
00856 TN_LIST_Push (tn, Hash_Table[hash_value], &MEM_pu_pool);
00857 }
00858 return tn;
00859 }
00860
00861
00862
00863
00864
00865
00866
00867
00868
00869
00870
00871
00872 TN *
00873 Gen_Label_TN ( LABEL_IDX lab, INT64 offset )
00874 {
00875 TN *tn;
00876
00877
00878 tn = Gen_TN ();
00879 Set_TN_size(tn, Pointer_Size);
00880 Set_TN_is_constant(tn);
00881 Set_TN_is_label(tn);
00882 TN_label(tn) = lab;
00883 TN_offset(tn) = offset;
00884 return tn;
00885 }
00886
00887 TN *
00888 Gen_Tag_TN ( LABEL_IDX tag)
00889 {
00890 TN *tn;
00891
00892
00893 tn = Gen_TN ();
00894 Set_TN_size(tn, Pointer_Size);
00895 Set_TN_is_constant(tn);
00896 Set_TN_is_tag(tn);
00897 TN_label(tn) = tag;
00898 return tn;
00899 }
00900
00901
00902
00903
00904
00905
00906
00907
00908
00909
00910
00911 TN *
00912 Gen_Adjusted_TN ( TN *tn, INT64 adjust )
00913 {
00914 TN *new_tn = NULL;
00915
00916 FmtAssert (TN_is_constant(tn), ("Gen_Adjusted_TN: not a constant TN"));
00917
00918 if (TN_has_value(tn)) {
00919 new_tn = Gen_Literal_TN (
00920 Targ_TN_Add(TN_value(tn),TN_size(tn),adjust,TN_size(tn)),
00921 TN_size(tn));
00922 }
00923 else if ( TN_is_symbol(tn) ) {
00924 new_tn = Gen_Symbol_TN(TN_var(tn), TN_offset(tn)+adjust, TN_relocs(tn));
00925 }
00926 else if (TN_is_label(tn)) {
00927 new_tn = Gen_Label_TN (TN_label(tn), TN_offset(tn)+adjust);
00928 }
00929 else {
00930 ErrMsg( EC_Unimplemented,
00931 "Gen_Adjusted_TN: Cannot handle this type of constant" );
00932 }
00933
00934 return new_tn;
00935 }
00936
00937
00938
00939
00940
00941
00942
00943
00944
00945
00946
00947
00948 #if !defined(TARG_IA64) && !defined(TARG_SL) && !defined(TARG_MIPS)
00949 static
00950 #endif
00951 char *
00952 sPrint_TN ( TN *tn, BOOL verbose, char *buf )
00953 {
00954 char *result = buf;
00955
00956 if (tn == NULL) {
00957 buf += sprintf ( buf, "--nil--");
00958 return result;
00959 }
00960
00961 if (TN_is_constant(tn)) {
00962 if ( TN_has_value(tn)) {
00963 buf += sprintf ( buf, "(0x%llx)", TN_value(tn) );
00964 if (TN_size(tn) == 4 &&
00965 TN_value(tn) >> 32 != 0 &&
00966 TN_value(tn) >> 31 != -1)
00967 buf += sprintf ( buf, "!!! TN_value=0x%llx is too big to fit in a word",
00968 TN_value(tn));
00969 }
00970 else if (TN_is_enum(tn)) {
00971 buf += sprintf ( buf, "(enum:%s)", ISA_ECV_Name(TN_enum(tn)) );
00972 }
00973 else if ( TN_is_label(tn) ) {
00974 LABEL_IDX lab = TN_label(tn);
00975 const char *name = LABEL_name(lab);
00976 INT64 offset = TN_offset(tn);
00977 if ( offset == 0 ) {
00978 buf += sprintf ( buf, "(lab:%s)", name );
00979 }
00980 else {
00981 buf += sprintf ( buf, "(lab:%s+%lld)", name, offset );
00982 }
00983 }
00984 else if ( TN_is_tag(tn) ) {
00985 LABEL_IDX lab = TN_label(tn);
00986 const char *name = LABEL_name(lab);
00987 buf += sprintf ( buf, "(tag:%s)", name );
00988 }
00989 else if ( TN_is_symbol(tn) ) {
00990 ST *var = TN_var(tn);
00991 buf += sprintf ( buf, "(sym" );
00992 switch (TN_relocs(tn)) {
00993 case TN_RELOC_NONE: break;
00994 case TN_RELOC_NEG: buf += sprintf ( buf, "-" ); break;
00995 case TN_RELOC_GPREL16: buf += sprintf (buf, "#gprel16"); break;
00996 case TN_RELOC_LOW16: buf += sprintf (buf, "#lo"); break;
00997 case TN_RELOC_HIGH16: buf += sprintf (buf, "#hi"); break;
00998 case TN_RELOC_HIGHER: buf += sprintf (buf, "#higher"); break;
00999 case TN_RELOC_HIGHEST: buf += sprintf (buf, "#highest"); break;
01000 case TN_RELOC_GOT_DISP: buf += sprintf (buf, "#got_disp"); break;
01001 case TN_RELOC_GOT_PAGE: buf += sprintf (buf, "#got_page"); break;
01002 case TN_RELOC_GOT_OFST: buf += sprintf (buf, "#got_ofst"); break;
01003 case TN_RELOC_CALL16: buf += sprintf (buf, "#call16"); break;
01004 case TN_RELOC_GOT_HI16: buf += sprintf (buf, "#got_hi16"); break;
01005 case TN_RELOC_GOT_LO16: buf += sprintf (buf, "#got_lo16"); break;
01006 case TN_RELOC_CALL_HI16: buf += sprintf (buf, "#call_hi16"); break;
01007 case TN_RELOC_CALL_LO16: buf += sprintf (buf, "#call_lo16"); break;
01008 case TN_RELOC_GPSUB: buf += sprintf (buf, "#gpsub"); break;
01009 case TN_RELOC_LO_GPSUB: buf += sprintf (buf, "#lo_gpsub"); break;
01010 case TN_RELOC_HI_GPSUB: buf += sprintf (buf, "#hi_gpsub"); break;
01011 case TN_RELOC_GPIDENT: buf += sprintf (buf, "#gpident"); break;
01012 case TN_RELOC_LO_GPIDENT: buf += sprintf (buf, "#lo_gpident"); break;
01013 case TN_RELOC_HI_GPIDENT: buf += sprintf (buf, "#hi_gpident"); break;
01014 case TN_RELOC_IA_GPREL22: buf += sprintf (buf, "#gprel22"); break;
01015 case TN_RELOC_IA_LTOFF22: buf += sprintf (buf, "#ltoff22"); break;
01016 case TN_RELOC_IA_LTOFF_FPTR: buf += sprintf (buf, "#ltoff_fptr"); break;
01017 }
01018 if (ST_class(var) == CLASS_CONST)
01019 buf += sprintf ( buf, ":%s)", Targ_Print(NULL, ST_tcon_val(var)));
01020 else
01021 buf += sprintf ( buf, ":%s%+lld)", ST_name(var), TN_offset(tn) );
01022 }
01023 else {
01024 ErrMsg (EC_Unimplemented, "sPrint_TN: illegal constant TN");
01025 }
01026 }
01027 else {
01028 if (TN_is_global_reg(tn)) {
01029 buf += sprintf ( buf, "GTN%d", TN_number(tn) );
01030 }
01031 else {
01032 buf += sprintf ( buf, "TN%d", TN_number(tn) );
01033 }
01034 if (TN_register(tn) != REGISTER_UNDEFINED) {
01035 if (TN_register(tn) <= REGISTER_CLASS_last_register(TN_register_class(tn))) {
01036 buf += sprintf (buf, "(%s)",
01037 (List_Software_Names ?
01038 ABI_PROPERTY_Reg_Name(TN_register_class(tn),
01039 REGISTER_machine_id(TN_register_class(tn), TN_register(tn)) )
01040 : REGISTER_name(TN_register_class(tn), TN_register(tn))));
01041 } else {
01042 buf += sprintf (buf, "(%d,%d)", TN_register_class(tn), TN_register(tn));
01043 }
01044 }
01045 if (TN_is_save_reg(tn)) {
01046 buf += sprintf (buf, "(sv:%s)",
01047 REGISTER_name(TN_save_rclass(tn), TN_save_reg(tn)));
01048 }
01049 #ifdef TARG_NVISA
01050 if (TN_has_memory_space(tn)) {
01051 buf += sprintf (buf, "(space:%d)", TN_memory_space(tn));
01052 }
01053 #endif
01054 }
01055 if (tn && Get_Trace(TP_CG, 8))
01056 buf += sprintf(buf, ":%d", TN_size(tn));
01057
01058 if ( verbose ) {
01059 buf += sprintf ( buf, "[f:0x%x s:%d]", TN_flags(tn), TN_size(tn) );
01060 }
01061 return result;
01062 }
01063
01064
01065
01066
01067
01068
01069
01070
01071
01072
01073
01074 void
01075 fPrint_TN ( FILE *f, const char *fmt, TN *tn)
01076 {
01077 char buf[1024];
01078 char *s = sPrint_TN (tn, FALSE, buf);
01079 Is_True(strlen(s) < 1024, ("fPrint_TN buf overflowed"));
01080 fprintf(f, fmt, s);
01081 }
01082
01083
01084
01085
01086
01087
01088
01089
01090
01091
01092
01093 void
01094 Print_TN ( TN *tn, BOOL verbose )
01095 {
01096 char buf[1024];
01097 char *s = sPrint_TN (tn, verbose, buf);
01098 Is_True(strlen(s) < 1024, ("Print_TN buf overflowed"));
01099 fprintf(TFile, "%s", s);
01100 }
01101
01102 void
01103 Print_TN_List(FILE *f, TN_LIST *tnl)
01104 {
01105 INT count = 0;
01106 if (tnl != NULL) {
01107 fprintf(f, "\t");
01108 for (TN_LIST *tmp=tnl; tmp; tmp=TN_LIST_rest(tmp)) {
01109 fPrint_TN(f, "%s ", TN_LIST_first(tmp));
01110 if (++count == 5) {
01111 count = 0;
01112 fprintf(f, "\n\t");
01113 }
01114 }
01115 fprintf(f, "\n");
01116 }
01117 }
01118
01119
01120 void
01121 dump_tn (TN *tn)
01122 {
01123 fPrint_TN (stdout, "%s\n", tn);
01124 }
01125
01126
01127
01128
01129
01130
01131
01132
01133
01134
01135 void
01136 Print_TNs ( void )
01137 {
01138 INT i;
01139 INT num_lits = 0;
01140
01141 fprintf ( TFile, "\n---------- TNs -------------\n" );
01142 fprintf ( TFile, "Last_Dedicated_TN = %d\n", Last_Dedicated_TN );
01143 fprintf ( TFile, "First_Regular_TN = %d\n", First_Regular_TN );
01144 fprintf ( TFile, "Last_TN \t = %d\n", Last_TN );
01145 for ( i=1; i<=Last_TN; i++ ) {
01146 if (TNvec(i) == NULL) continue;
01147 Print_TN (TNvec(i), TRUE);
01148 fprintf ( TFile, "\n" );
01149 }
01150
01151 fprintf ( TFile, "\n---------- Literal TNs -------------\n" );
01152 for ( i = 0; i < HASH_TABLE_SIZE; i++ ) {
01153 TN_LIST *p;
01154 for (p = Hash_Table[i]; p != NULL; p = TN_LIST_rest(p)) {
01155 Print_TN (TN_LIST_first(p), TRUE);
01156 fprintf ( TFile, "\n" );
01157 num_lits++;
01158 }
01159 }
01160 fprintf ( TFile, "Number of Literal TNs = %d\n", num_lits);
01161 }
01162
01163
01164
01165
01166
01167
01168
01169
01170
01171
01172 void
01173 Init_TNs_For_PU (void)
01174 {
01175 TN *tn;
01176 TN_NUM tnnum;
01177
01178
01179 for ( tnnum = 0; tnnum <= Last_Dedicated_TN; tnnum++ ) {
01180 if ((tn = TNvec(tnnum)) != NULL) {
01181 Reset_TN_is_global_reg (tn);
01182 Set_TN_spill(tn, NULL);
01183 }
01184 }
01185
01186
01187 BZERO(Hash_Table, sizeof(Hash_Table));
01188
01189
01190 Last_TN = Last_Dedicated_TN;
01191 First_Regular_TN = Last_Dedicated_TN + 1;
01192
01193 if( GP_TN != NULL ){
01194
01195
01196
01197
01198 Set_TN_register(GP_TN, REGISTER_gp);
01199 }
01200 }
01201
01202
01203
01204
01205
01206
01207
01208
01209
01210
01211
01212
01213
01214 void
01215 Init_TNs_For_REGION (void)
01216 {
01217 TN *tn;
01218 TN_NUM tnnum;
01219
01220
01221 for ( tnnum = 0; tnnum <= Last_Dedicated_TN; tnnum++ ) {
01222 if ((tn = TNvec(tnnum)) != NULL) {
01223
01224
01225
01226
01227 Reset_TN_is_global_reg (tn);
01228 Set_TN_spill(tn, NULL);
01229 }
01230 }
01231
01232 First_REGION_TN = Last_TN + 1;
01233 }
01234
01235
01236
01237
01238
01239
01240
01241
01242
01243 TN *
01244 Find_TN_with_Matching_Register( TN *tn0, TN_LIST *list )
01245 {
01246 TN_LIST *tnl;
01247 TN *tnx;
01248 REGISTER r0, rx;
01249 INT c0, cx;
01250
01251 r0 = TN_register( tn0 );
01252 c0 = TN_register_class( tn0 );
01253 for ( tnl = list; tnl != NULL; tnl = TN_LIST_rest( tnl ) ) {
01254 tnx = TN_LIST_first( tnl );
01255 rx = TN_register( tnx );
01256 cx = TN_register_class( tnx );
01257 if ( ( r0 == rx )
01258 && ( c0 == cx ) )
01259 return tnx;
01260 }
01261 return (TN *)NULL;
01262 }
01263
01264
01265 BOOL
01266 Is_OP_Cond(OP *op)
01267 {
01268
01269 if (OP_cond_def(op)) return TRUE;
01270
01271 BB *bb = OP_bb(op);
01272
01273
01274
01275
01276 if (PROC_has_branch_delay_slot()) {
01277 if (Is_Delay_Slot_Op(op, bb) && OP_likely(BB_branch_op(bb)))
01278 return TRUE;
01279 }
01280
01281 return FALSE;
01282
01283 }
01284
01285
01286
01287
01288
01289
01290
01291
01292
01293 OP *
01294 TN_Reaching_Value_At_Op(
01295 TN *tn,
01296 OP *op,
01297 DEF_KIND *kind,
01298 BOOL reaching_def
01299 )
01300 {
01301 OP *value_op;
01302 BB *bb;
01303 INT cnt;
01304
01305 #define MAX_BB_THRESHOLD 30 // Don't look beyond 30 predecessor blocks.
01306
01307
01308 if (TN_register(tn) != REGISTER_UNDEFINED) {
01309 REGISTER reg = TN_register(tn);
01310 ISA_REGISTER_CLASS rc = TN_register_class(tn);
01311 bb = OP_bb(op);
01312 value_op = (reaching_def) ? OP_prev(op) : OP_next(op);
01313 cnt = 0;
01314 do {
01315 while (value_op) {
01316 if (reaching_def) {
01317 if (OP_Defs_Reg(value_op, rc, reg)) {
01318 if (Is_OP_Cond(value_op)) {
01319 if (OP_has_predicate(value_op) && OP_has_predicate(op)) {
01320 TN *p1 = OP_opnd((OP*) value_op, OP_PREDICATE_OPND);
01321 TN *p2 = OP_opnd((OP*) op, OP_PREDICATE_OPND);
01322
01323 if (p1 == p2) {
01324 *kind = VAL_COND_DEF;
01325 return value_op;
01326 }
01327 }
01328
01329 *kind = VAL_COND_DEF;
01330 return NULL;
01331 } else {
01332 *kind = VAL_KNOWN;
01333 return value_op;
01334 }
01335 }
01336 } else {
01337 if (OP_Refs_Reg(value_op, rc, reg)) {
01338 if (Is_OP_Cond(value_op)) {
01339 if (OP_has_predicate(value_op) && OP_has_predicate(op)) {
01340 TN *p1 = OP_opnd((OP*) value_op, OP_PREDICATE_OPND);
01341 TN *p2 = OP_opnd((OP*) op, OP_PREDICATE_OPND);
01342
01343 if (p1 == p2) {
01344 *kind = VAL_COND_USE;
01345 return value_op;
01346 }
01347 }
01348
01349 *kind = VAL_COND_USE;
01350 return NULL;
01351 } else {
01352 *kind = VAL_KNOWN;
01353 return value_op;
01354 }
01355 }
01356 }
01357 value_op = (reaching_def) ? OP_prev(value_op) : OP_next(value_op);
01358 }
01359
01360 if (bb) {
01361 BBLIST *edge;
01362 INT val_cnt = 0;
01363 BB *cur_bb = NULL;
01364 BB *val_bb = NULL;
01365
01366 if (reaching_def) {
01367 FOR_ALL_BB_PREDS(bb, edge) {
01368 cur_bb = BBLIST_item(edge);
01369 #ifdef KEY
01370
01371
01372 if (cur_bb == bb) {
01373 OP *op;
01374 bool redefined = FALSE;
01375 FOR_ALL_BB_OPs(cur_bb, op) {
01376 if (OP_Defs_Reg(op, rc, reg)) {
01377 redefined = TRUE;
01378 break;
01379 }
01380 }
01381 if (!redefined) continue;
01382 }
01383 #else
01384 if (cur_bb == bb) continue;
01385 #endif
01386 BOOL live_out = REG_LIVE_Outof_BB(rc, reg, cur_bb);
01387 val_cnt += (live_out) ? 1 : 0;
01388 val_bb = (live_out) ? cur_bb : val_bb;
01389 }
01390 } else {
01391 FOR_ALL_BB_SUCCS(bb, edge) {
01392 cur_bb = BBLIST_item(edge);
01393 if (cur_bb == bb) continue;
01394 BOOL live_in = REG_LIVE_Into_BB(rc, reg, cur_bb);
01395 val_cnt += (live_in) ? 1 : 0;
01396 val_bb = (live_in) ? cur_bb : val_bb;
01397 }
01398 }
01399 bb = (val_cnt > 1) ? NULL : val_bb;
01400
01401 #ifdef TARG_IA64
01402 if (bb == NULL || BB_call(bb) || BB_rotating_kernel(bb)) break;
01403 #else
01404 if (bb == NULL || BB_call(bb)) break;
01405 #endif
01406
01407 value_op = (reaching_def) ? BB_last_op(bb) : BB_first_op(bb);
01408 }
01409 } while (++cnt < MAX_BB_THRESHOLD);
01410
01411 *kind = VAL_UNKNOWN;
01412 return NULL;
01413 }
01414
01415
01416
01417 bb = OP_bb(op);
01418 value_op = (reaching_def) ? OP_prev(op) : OP_next(op);
01419 cnt = 0;
01420 do {
01421 while (value_op) {
01422 if (reaching_def) {
01423 if (OP_Defs_TN(value_op, tn)) {
01424 if (Is_OP_Cond(value_op)) {
01425 if (OP_has_predicate(value_op) && OP_has_predicate(op)) {
01426 TN *p1 = OP_opnd((OP*) value_op, OP_PREDICATE_OPND);
01427 TN *p2 = OP_opnd((OP*) op, OP_PREDICATE_OPND);
01428
01429 if (p1 == p2) {
01430 *kind = VAL_COND_DEF;
01431 return value_op;
01432 }
01433 }
01434
01435 *kind = VAL_COND_DEF;
01436 return NULL;
01437 } else {
01438 *kind = VAL_KNOWN;
01439 return value_op;
01440 }
01441 }
01442 } else {
01443 if (OP_Refs_TN(value_op, tn)) {
01444 if (Is_OP_Cond(value_op)) {
01445 if (OP_has_predicate(value_op) && OP_has_predicate(op)) {
01446 TN *p1 = OP_opnd((OP*) value_op, OP_PREDICATE_OPND);
01447 TN *p2 = OP_opnd((OP*) op, OP_PREDICATE_OPND);
01448
01449 if (p1 == p2) {
01450 *kind = VAL_COND_USE;
01451 return value_op;
01452 }
01453 }
01454
01455 *kind = VAL_COND_USE;
01456 return NULL;
01457 } else {
01458 *kind = VAL_KNOWN;
01459 return value_op;
01460 }
01461 }
01462 }
01463 value_op = (reaching_def) ? OP_prev(value_op) : OP_next(value_op);
01464 }
01465
01466 if (bb) {
01467 BB *new_bb = NULL;
01468 if (GRA_LIVE_Phase_Invoked) {
01469 BBLIST *edge;
01470 INT val_cnt = 0;
01471 BB *val_bb = NULL;
01472 BB *cur_bb = NULL;
01473
01474 if (reaching_def) {
01475 FOR_ALL_BB_PREDS(bb, edge) {
01476 cur_bb = BBLIST_item(edge);
01477 #ifdef KEY
01478
01479
01480 if (cur_bb == bb) {
01481 OP *op;
01482 bool redefined = FALSE;
01483 FOR_ALL_BB_OPs(cur_bb, op) {
01484 if (OP_Defs_TN(op, tn)) {
01485 redefined = TRUE;
01486 break;
01487 }
01488 }
01489 if (!redefined) continue;
01490 }
01491 #else
01492 if (cur_bb == bb) continue;
01493 #endif
01494 BOOL live_out = GRA_LIVE_TN_Live_Outof_BB(tn, cur_bb);
01495 val_cnt += (live_out) ? 1 : 0;
01496 val_bb = (live_out) ? cur_bb : val_bb;
01497 }
01498 } else {
01499 FOR_ALL_BB_SUCCS(bb, edge) {
01500 cur_bb = BBLIST_item(edge);
01501 if (cur_bb == bb) continue;
01502 BOOL live_in = GRA_LIVE_TN_Live_Into_BB(tn, cur_bb);
01503 val_cnt += (live_in) ? 1 : 0;
01504 val_bb = (live_in) ? cur_bb : val_bb;
01505 }
01506 }
01507 new_bb = (val_cnt > 1) ? NULL : val_bb;
01508 }
01509
01510 if (new_bb == NULL) {
01511 if (reaching_def)
01512 new_bb = BB_Unique_Predecessor(bb);
01513 else
01514 new_bb = BB_Unique_Successor(bb);
01515 }
01516 bb = new_bb;
01517 }
01518 if (bb == NULL) break;
01519
01520 value_op = (reaching_def) ? BB_last_op(bb) : BB_first_op(bb);
01521 } while (++cnt < MAX_BB_THRESHOLD);
01522
01523 *kind = VAL_UNKNOWN;
01524 return NULL;
01525 }
01526
01527
01528 #if defined(TARG_NVISA)
01529
01530
01531
01532
01533
01534 static OP *
01535 Find_Reaching_Def_In_Pred (TN *tn, OP *use_op)
01536 {
01537 OP *op;
01538 BB *bb = OP_bb(use_op);
01539 REGISTER reg = TN_register(tn);
01540 ISA_REGISTER_CLASS rc = TN_register_class(tn);
01541 INT cnt = 0;
01542
01543 #define MAX_BB_THRESHOLD 30 // Don't look beyond 30 predecessor blocks.
01544
01545
01546 FmtAssert(TN_register(tn) != REGISTER_UNDEFINED, ("tn not a register"));
01547
01548 op = OP_prev(use_op);
01549 do {
01550
01551 while (op) {
01552 if (OP_Defs_Reg(op, rc, reg)) {
01553 return op;
01554 }
01555 op = OP_prev(op);
01556 }
01557
01558
01559 BBLIST *edge;
01560 BB *pred_bb = NULL;
01561 INT num_preds = 0;
01562
01563 FOR_ALL_BB_PREDS(bb, edge) {
01564 pred_bb = BBLIST_item(edge);
01565 num_preds++;
01566 }
01567 if (num_preds == 1) {
01568 if (REG_LIVE_Outof_BB(rc, reg, pred_bb))
01569 bb = pred_bb;
01570 else {
01571
01572 return NULL;
01573 }
01574 }
01575 else {
01576 BB_SET *bbset = NULL;
01577 if (LOOP_DESCR_Find_Loop(bb) != NULL)
01578 bbset = LOOP_DESCR_bbset(LOOP_DESCR_Find_Loop(bb));
01579 if (bbset) {
01580
01581
01582 BB *bbl;
01583 FOR_ALL_BB_SET_members(bbset, bbl) {
01584 FOR_ALL_BB_OPs(bbl, op) {
01585 if (OP_Defs_Reg(op, rc, reg)) {
01586
01587
01588
01589
01590 return NULL;
01591 }
01592 }
01593 }
01594 pred_bb = NULL;
01595 FOR_ALL_BB_PREDS(bb, edge) {
01596 if ( ! BB_SET_MemberP(bbset, BBLIST_item(edge)))
01597 pred_bb = BBLIST_item(edge);
01598 }
01599
01600
01601
01602 if (pred_bb == NULL) {
01603
01604 return NULL;
01605 }
01606 if ( ! REG_LIVE_Outof_BB(rc, reg, pred_bb)) {
01607
01608 return NULL;
01609 }
01610 bb = pred_bb;
01611 }
01612 else {
01613
01614
01615
01616
01617
01618
01619 return NULL;
01620 }
01621 }
01622 op = BB_last_op(bb);
01623 } while (++cnt < MAX_BB_THRESHOLD);
01624
01625
01626 return NULL;
01627 }
01628
01629 OP *
01630 Find_Reaching_Def (TN *tn, OP *use_op)
01631 {
01632 OP *op = Find_Reaching_Def_In_Pred (tn, use_op);
01633 if (op) return op;
01634
01635 #ifdef TARG_NVISA
01636
01637
01638
01639
01640
01641
01642
01643 if ( ! OP_Refs_TN(use_op, tn)) {
01644 return NULL;
01645 }
01646
01647
01648 if (TN_has_one_def(tn)) {
01649 BB *bb;
01650
01651 for (bb = REGION_First_BB; bb != NULL; bb = BB_next(bb)) {
01652 FOR_ALL_BB_OPs_FWD (bb, op) {
01653 if (OP_Defs_TN(op, tn)) {
01654 return op;
01655 }
01656 }
01657 }
01658 }
01659 #endif
01660 return NULL;
01661 }
01662
01663 #endif // TARG_NVISA
01664
01665
01666
01667
01668
01669
01670
01671
01672
01673
01674
01675
01676 static BOOL
01677 Rematerializable_IntConst(
01678 TN *tn,
01679 INT64 *val
01680 )
01681 {
01682 OPCODE opcode;
01683 OPERATOR opr;
01684 WN *home = TN_home(tn);
01685
01686 if (!TN_is_rematerializable(tn)) return FALSE;
01687
01688 if (!home) {
01689 DevWarn("No home for rematerializable TN%d", TN_number(tn));
01690 return FALSE;
01691 }
01692
01693 opcode = WN_opcode(home);
01694 opr = OPCODE_operator(opcode);
01695
01696 if (opr != OPR_INTCONST) return FALSE;
01697
01698 switch (opcode) {
01699 case OPC_I8INTCONST:
01700 case OPC_U8INTCONST:
01701 #ifdef TARG_X8664
01702
01703
01704
01705 case OPC_U4INTCONST:
01706 #endif
01707 *val = WN_const_val(home);
01708 break;
01709 case OPC_I4INTCONST:
01710 #ifndef TARG_X8664 // see above
01711 case OPC_U4INTCONST:
01712 #endif
01713
01714
01715
01716
01717 *val = (INT32)WN_const_val(home);
01718 break;
01719 default:
01720 return FALSE;
01721 }
01722
01723 return TRUE;
01724 }
01725
01726
01727
01728
01729
01730
01731
01732
01733
01734
01735 BOOL
01736 TN_Value_At_Op(
01737 TN *tn,
01738 OP *use_op,
01739 INT64 *val
01740 )
01741 {
01742 INT iters = 5;
01743
01744 do {
01745 OP *def_op;
01746
01747 DEF_KIND kind;
01748 if (TN_is_constant(tn)) {
01749 if (!TN_has_value(tn)) break;
01750 *val = TN_value(tn);
01751 return TRUE;
01752 } else if (TN_is_zero_reg(tn)) {
01753 *val = 0;
01754 return TRUE;
01755 } else if (TN_is_rematerializable(tn)) {
01756 return Rematerializable_IntConst(tn, val);
01757 } else if (use_op && (def_op = TN_Reaching_Value_At_Op(tn, use_op, &kind, TRUE)) && (kind == VAL_KNOWN)) {
01758 if ( (OP_iadd(def_op) || OP_ior(def_op))
01759 && TN_is_zero_reg(OP_opnd(def_op,0))
01760 && TN_has_value(OP_opnd(def_op,1))
01761 ) {
01762 tn = OP_opnd(def_op, 1);
01763 use_op = def_op;
01764 continue;
01765 } else if (OP_copy(def_op)) {
01766 tn = OP_opnd(def_op, OP_COPY_OPND);
01767 use_op = def_op;
01768 continue;
01769 }
01770 }
01771 return FALSE;
01772 } while (--iters);
01773
01774 Lmt_DevWarn(1,("TN_Value_At_Op exceeded max iterations to find reaching def"));
01775
01776 return FALSE;
01777 }
01778
01779
01780
01781
01782
01783
01784
01785
01786
01787
01788 #define HUGE_MIN (INT64_MIN/128+1)
01789 #define HUGE_MAX (INT64_MAX/128-1)
01790
01791
01792
01793
01794
01795
01796
01797
01798
01799
01800
01801
01802
01803
01804
01805
01806
01807
01808
01809
01810
01811
01812
01813
01814
01815
01816 static BOOL
01817 Get_TN_Range (
01818 TN *tn,
01819 INT64 *minval,
01820 INT64 *maxval )
01821 {
01822 ST *st;
01823 ST *base_st;
01824 INT64 ofst, base_ofst;
01825
01826
01827
01828
01829 if ( ! TN_is_constant(tn) ) {
01830 *minval = HUGE_MIN;
01831 *maxval = HUGE_MAX;
01832 return FALSE;
01833 }
01834
01835
01836 if ( TN_has_value(tn) ) {
01837
01838 *minval = *maxval = TN_value(tn);
01839 return TRUE;
01840 } else if ( TN_is_label(tn) || TN_is_tag(tn)) {
01841
01842 *minval = *maxval = 1;
01843 return FALSE;
01844 } else if ( ! TN_is_symbol(tn) ) {
01845
01846 *minval = HUGE_MIN;
01847 *maxval = HUGE_MAX;
01848 return FALSE;
01849 } else if (TN_relocs(tn) != 0) {
01850
01851
01852
01853 *minval = INT16_MIN;
01854 *maxval = INT16_MAX;
01855 return TRUE;
01856 }
01857
01858
01859 st = TN_var(tn);
01860 ofst = TN_offset(tn);
01861 Base_Symbol_And_Offset (st, &base_st, &base_ofst);
01862
01863 if ( ST_on_stack(st)) {
01864 *minval = *maxval = base_ofst + ofst;
01865 return TRUE;
01866 }
01867
01868
01869
01870 *minval = HUGE_MIN;
01871 *maxval = HUGE_MAX;
01872 return FALSE;
01873 }
01874
01875
01876
01877
01878
01879
01880
01881
01882
01883
01884
01885
01886
01887
01888
01889
01890
01891
01892
01893
01894
01895
01896
01897
01898
01899
01900
01901
01902
01903
01904
01905
01906
01907
01908
01909
01910 static BOOL
01911 Evaluate_Operand_Range (
01912 TN *tn1,
01913 INT32 disp,
01914 INT64 *minval,
01915 INT64 *maxval )
01916 {
01917 INT64 min1, max1;
01918 BOOL combine;
01919
01920 if (tn1 == NULL) {
01921 *minval = *maxval = disp;
01922 return TRUE;
01923 }
01924
01925
01926 combine = Get_TN_Range ( tn1, &min1, &max1 );
01927
01928
01929 if ( disp != 0 ) {
01930 if ( ! combine ) return FALSE;
01931 min1 += disp;
01932 max1 += disp;
01933 }
01934
01935
01936 *minval = min1;
01937 *maxval = max1;
01938 return TRUE;
01939 }
01940
01941
01942
01943
01944
01945
01946
01947
01948
01949
01950
01951
01952
01953
01954
01955 BOOL
01956 Potential_Immediate_TN_Expr (
01957 TOP opcode,
01958 TN *tn1,
01959 INT32 disp)
01960 {
01961 INT64 lbound, hbound;
01962
01963
01964 return Evaluate_Operand_Range ( tn1, disp, &lbound, &hbound )
01965 && TOP_Can_Have_Immediate ( lbound, opcode )
01966 && TOP_Can_Have_Immediate ( hbound, opcode );
01967 }