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 #ifdef USE_PCH
00046 #include "common_com_pch.h"
00047 #endif
00048 #pragma hdrstop
00049 #include <stdio.h>
00050 #include <alloca.h>
00051
00052 #include <ext/hash_map>
00053 #include <ext/algorithm>
00054
00055 #include "defs.h"
00056 #include "config.h"
00057 #include "tracing.h"
00058 #include "cxx_memory.h"
00059
00060 #include "symtab.h"
00061 #include "irbdata.h"
00062 #include "const.h"
00063 #include "ttype.h"
00064 #include "targ_sim.h"
00065 #include "config_asm.h"
00066
00067
00068 FILE_INFO File_info;
00069 SCOPE *Scope_tab;
00070 PU_TAB Pu_Table;
00071 SYMBOL_TABLE St_Table;
00072 TY_TAB Ty_tab;
00073 TYPE_TABLE Ty_Table;
00074 FLD_TAB Fld_Table;
00075 TYLIST_TAB Tylist_Table;
00076 ARB_TAB Arb_Table;
00077 TCON_TAB Tcon_Table;
00078 INITV_TAB Initv_Table;
00079 INITO_TABLE Inito_Table;
00080 PREG_TABLE Preg_Table;
00081 LABEL_TABLE Label_Table;
00082 BLK_TAB Blk_Table;
00083 ST_ATTR_TABLE St_Attr_Table;
00084
00085 SYMTAB_IDX Current_scope;
00086 PU *Current_pu;
00087
00088
00089
00090
00091
00092 INT64
00093 ST_size (const ST *st)
00094 {
00095 switch (ST_class(st)) {
00096 case CLASS_BLOCK:
00097 return STB_size(st);
00098 case CLASS_VAR:
00099 case CLASS_PREG:
00100 return TY_size(ST_type(st));
00101 case CLASS_CONST:
00102 if (TCON_ty(STC_val(st)) == MTYPE_STR)
00103 return Targ_String_Length (STC_val(st))
00104 + (TCON_add_null(STC_val(st)) ? 1 : 0);
00105 else
00106 return TY_size(ST_type(st));
00107 case CLASS_FUNC:
00108 return 0;
00109 }
00110 FmtAssert(FALSE, ("ST_size: unexpected CLASS"));
00111
00112 return 0;
00113 }
00114
00115
00116 ST *
00117 Copy_ST (ST *st)
00118 {
00119 if (ST_sym_class (st) == CLASS_PREG)
00120 return st;
00121
00122 SYMTAB_IDX level = ST_IDX_level (ST_st_idx (st));
00123
00124 ST_TAB *st_tab = Scope_tab[level].st_tab;
00125 ST_IDX st_idx = make_ST_IDX (st_tab->Insert (*st), level);
00126 ST& copy = St_Table[st_idx];
00127 Set_ST_st_idx (copy, st_idx);
00128 if (ST_base_idx (st) == ST_st_idx (st))
00129 Set_ST_base_idx (copy, st_idx);
00130 return ©
00131 }
00132
00133
00134 ST *
00135 Copy_ST (ST *st, SYMTAB_IDX scope)
00136 {
00137 if (scope == ST_level (st))
00138 return Copy_ST (st);
00139
00140 ST_TAB *st_tab = Scope_tab[scope].st_tab;
00141 ST_IDX st_idx = make_ST_IDX (st_tab->Insert (*st), scope);
00142 ST& copy = St_Table[st_idx];
00143 Set_ST_st_idx (copy, st_idx);
00144 if (ST_base_idx (st) == ST_st_idx (st))
00145 Set_ST_base_idx (copy, st_idx);
00146 else if (scope != ST_IDX_level (ST_base_idx (st))) {
00147 ST *base_st = Copy_ST (&St_Table[ST_base_idx (st)], scope);
00148 Set_ST_base_idx (copy, ST_st_idx (base_st));
00149 }
00150 return ©
00151 }
00152
00153 ST *
00154 Copy_ST_No_Base (ST *st, SYMTAB_IDX scope)
00155 {
00156 static INT Temp_Index = 0;
00157 STR_IDX new_name;
00158 if (scope == GLOBAL_SYMTAB)
00159 #ifdef TARG_NVISA
00160 new_name = Save_Str2i(ST_name(st),"__", Temp_Index++);
00161 #else
00162 new_name = Save_Str2i(ST_name(st),"..", Temp_Index++);
00163 #endif
00164 else
00165 new_name = ST_name_idx(st);
00166
00167 if (scope == ST_level (st)) {
00168 ST* new_st = Copy_ST (st);
00169 Set_ST_name_idx (*new_st, new_name);
00170 return new_st;
00171 }
00172
00173 ST_TAB *st_tab = Scope_tab[scope].st_tab;
00174 ST_IDX st_idx = make_ST_IDX (st_tab->Insert (*st), scope);
00175 ST& copy = St_Table[st_idx];
00176 Set_ST_st_idx (copy, st_idx);
00177 Set_ST_name_idx (copy, new_name);
00178 if (ST_base_idx (st) == ST_st_idx (st)) {
00179 Set_ST_base_idx (copy, st_idx);
00180 }
00181 return ©
00182 }
00183
00184
00185
00186 BOOL
00187 ST_is_constant (const ST *st)
00188 {
00189 switch (ST_sym_class(st)) {
00190 case CLASS_CONST:
00191 return TRUE;
00192 case CLASS_VAR:
00193 return ST_is_const_var(st);
00194 default:
00195 return FALSE;
00196 }
00197 }
00198
00199
00200
00201
00202
00203
00204
00205 extern BOOL
00206 ST_is_private_local(const ST *st)
00207 {
00208 Is_True((PU_src_lang(Get_Current_PU()) &
00209 (PU_src_lang(Get_Current_PU()) - 1)) == 0,
00210 ("ST_is_private_local: Mixed-language inlining not "
00211 "allowed; need to know original PU language"));
00212
00213 if (ST_IDX_level(ST_st_idx(st)) != CURRENT_SYMTAB)
00214 return FALSE;
00215
00216
00217
00218
00219
00220
00221 if (LANG_Recursive_Set)
00222 return !LANG_Recursive;
00223
00224
00225
00226 switch (PU_src_lang(Get_Current_PU())) {
00227 case PU_F77_LANG:
00228
00229 return TRUE;
00230
00231 case PU_F90_LANG:
00232
00233 return (!PU_recursive(Get_Current_PU()));
00234 }
00235 return FALSE;
00236 }
00237
00238
00239
00240
00241
00242
00243 TY_IDX
00244 Copy_TY (TY_IDX ty)
00245 {
00246
00247 TY_IDX copy = ty;
00248 Set_TY_IDX_index (copy, Ty_tab.Insert (Ty_Table[ty]));
00249 return copy;
00250 }
00251
00252
00253
00254 UINT
00255 TY_log_base2 (UINT align)
00256 {
00257 UINT result = 0;
00258
00259 Is_True (align, ("Invalid alignment for TY"));
00260
00261 while ((align & 0x7) == 0) {
00262 result += 3;
00263 align >>= 3;
00264 }
00265
00266 return result + (align >> 1);
00267 }
00268
00269
00270
00271
00272
00273
00274
00275
00276
00277
00278
00279
00280
00281 FLD_HANDLE
00282 FLD_get_to_field (TY_IDX struct_ty_idx, UINT field_id, UINT &cur_field_id)
00283 {
00284 FLD_ITER fld_iter = Make_fld_iter(TY_fld(struct_ty_idx));
00285 do {
00286 FLD_HANDLE fld(fld_iter);
00287 cur_field_id++;
00288 if (cur_field_id == field_id)
00289 return fld;
00290 if (TY_kind(FLD_type(fld)) == KIND_STRUCT &&
00291 TY_fld(FLD_type(fld)) != FLD_HANDLE()) {
00292 fld = FLD_get_to_field(FLD_type(fld), field_id, cur_field_id);
00293 if (cur_field_id == field_id)
00294 return fld;
00295 }
00296 } while (!FLD_last_field(fld_iter++));
00297 return FLD_HANDLE();
00298 }
00299
00300
00301
00302
00303
00304
00305
00306
00307
00308
00309
00310 typedef std::pair<TY_IDX, UINT32> TY_POINTEE_KEY;
00311
00312 struct hash_pointee_key
00313 {
00314 UINT32 operator() (TY_POINTEE_KEY key) const {
00315 return (key.first | key.second);
00316 }
00317 };
00318
00319 typedef __gnu_cxx::hash_map<TY_POINTEE_KEY, TY_IDX, hash_pointee_key>
00320 TY_IDX_POINTER_MAP;
00321
00322 static TY_IDX_POINTER_MAP pointer_map;
00323 static std::pair<TY_POINTEE_KEY, TY_IDX> last_valid_map_entry;
00324
00325
00326
00327 static BOOL
00328 Invalid_Pointer_Map_Entry (const TY_IDX_POINTER_MAP::value_type& entry)
00329 {
00330 TY_IDX pointer = entry.second;
00331 TY_IDX pointee = entry.first.first;
00332
00333 if (TY_IDX_index (pointer) >= TY_Table_Size () ||
00334 TY_IDX_index (pointee) >= TY_Table_Size ())
00335 return TRUE;
00336
00337 const TY& ty = Ty_Table[pointer];
00338
00339 if (TY_kind (ty) != KIND_POINTER ||
00340 TY_pointed (ty) != pointee ||
00341 TY_flags (ty) != entry.first.second)
00342 return TRUE;
00343
00344 return FALSE;
00345 }
00346
00347
00348
00349
00350
00351 static void
00352 Validate_Pointer_Map ()
00353 {
00354 typedef TY_IDX_POINTER_MAP::iterator ITER;
00355 std::vector<ITER> invalid_entries;
00356 UINT last_valid = 0;
00357 last_valid_map_entry.second = 0;
00358
00359 for (ITER i = pointer_map.begin (); i != pointer_map.end (); ++i) {
00360 if (Invalid_Pointer_Map_Entry (*i))
00361 invalid_entries.push_back (i);
00362 else {
00363 if (last_valid < TY_IDX_index ((*i).second)) {
00364 last_valid = TY_IDX_index ((*i).second);
00365 last_valid_map_entry = *i;
00366 }
00367 }
00368 }
00369
00370 for (std::vector<ITER>::const_iterator first = invalid_entries.begin ();
00371 first != invalid_entries.end (); ++first)
00372 pointer_map.erase (*first);
00373 }
00374
00375
00376 struct update_pointer_map
00377 {
00378 void operator() (UINT32 idx, const TY* ty) const {
00379 if (TY_kind (*ty) != KIND_POINTER || TY_mtype (*ty) != Pointer_Mtype)
00380 return;
00381 TY_POINTEE_KEY key (TY_pointed (*ty), TY_flags (*ty));
00382 last_valid_map_entry = std::make_pair (key, make_TY_IDX (idx));
00383 pointer_map.insert (last_valid_map_entry);
00384 }
00385 };
00386
00387 static void
00388 Update_Pointer_Map ()
00389 {
00390 if (TY_IDX_index (last_valid_map_entry.second) != 0 &&
00391 Invalid_Pointer_Map_Entry (last_valid_map_entry)) {
00392 DevWarn ("Rehashing TY pointer map -- this should NOT happen often");
00393 Validate_Pointer_Map ();
00394 }
00395 For_all_entries (Ty_tab, update_pointer_map (),
00396 TY_IDX_index (last_valid_map_entry.second) + 1);
00397 }
00398
00399
00400 static inline TY_IDX
00401 Find_Ty_Pointer (TY_POINTEE_KEY key)
00402 {
00403 TY_IDX_POINTER_MAP::iterator result = pointer_map.find (key);
00404
00405 if (result == pointer_map.end ())
00406 return 0;
00407
00408 if (Invalid_Pointer_Map_Entry (*result)) {
00409 DevWarn ("Rehashing TY pointer map -- this should NOT happen often");
00410 Validate_Pointer_Map ();
00411 return 0;
00412 }
00413
00414 TY_IDX pointer = (*result).second;
00415 Set_TY_align (pointer, Pointer_Size);
00416 return pointer;
00417
00418 }
00419
00420
00421 TY_IDX
00422 TY_pointer (TY_IDX pointee, BOOL f90_pointer)
00423 {
00424 TY_POINTEE_KEY key (pointee, f90_pointer ? TY_IS_F90_POINTER : 0);
00425
00426 TY_IDX result = Find_Ty_Pointer (key);
00427
00428 if (result == 0) {
00429 Update_Pointer_Map ();
00430 return Find_Ty_Pointer (key);
00431 }
00432
00433 return result;
00434
00435 }
00436
00437
00438 TY_IDX
00439 make_ptr_type (TY_IDX ty_idx, BOOL f90_pointer)
00440 {
00441 TY_IDX ty_ptr = TY_pointer (ty_idx, f90_pointer);
00442
00443 if (ty_ptr != 0)
00444 return ty_ptr;
00445
00446 TY &ty = New_TY (ty_ptr);
00447 TY_Init (ty, Pointer_Size, KIND_POINTER, Pointer_Mtype,
00448 Save_Str ("anon_ptr."));
00449 Set_TY_pointed (ty, ty_idx);
00450 if (f90_pointer)
00451 Set_TY_is_f90_pointer (ty);
00452 Set_TY_align (ty_ptr, Pointer_Size);
00453
00454 return ty_ptr;
00455 }
00456
00457 TY_IDX
00458 Make_Pointer_Type (TY_IDX ty_idx, BOOL)
00459 {
00460
00461
00462
00463 return make_ptr_type (ty_idx, FALSE);
00464 }
00465
00466 TY_IDX
00467 Make_F90_Pointer_Type (TY_IDX ty_idx)
00468 {
00469
00470
00471
00472 return make_ptr_type (ty_idx, TRUE);
00473
00474 }
00475
00476
00477 TY_IDX
00478 Make_Function_Type(TY_IDX return_ty_idx)
00479 {
00480
00481
00482
00483
00484 #ifdef ROBERT
00485
00486
00487
00488
00489
00490
00491
00492 TY_ITER ty;
00493
00494
00495
00496
00497 ty = Ty_tab.begin();
00498 for (++ty;
00499 ty != Ty_tab.end();
00500 ty++) {
00501 TYLIST_IDX known_return_tylist;
00502 if (TY_kind(*ty) == KIND_FUNCTION &&
00503 (known_return_tylist = TY_tylist(*ty)) != (TYLIST_IDX) 0 &&
00504 TYLIST_type(known_return_tylist) == return_ty_idx &&
00505 (return_ty_idx == 0 ||
00506 TYLIST_type(known_return_tylist + 1) == (TY_IDX) 0)) {
00507 return ty.Index();
00508 }
00509 }
00510 TYLIST_IDX new_return_tylist_idx;
00511 TYLIST &new_return_tylist = New_TYLIST(new_return_tylist_idx);
00512 Set_TYLIST_type(new_return_tylist, return_ty_idx);
00513
00514 if (return_ty_idx != (TY_IDX) 0) {
00515 TYLIST_IDX tail_return_tylist_idx;
00516 new_return_tylist = New_TYLIST(tail_return_tylist_idx);
00517 Is_True(tail_return_tylist_idx == new_return_tylist_idx + 1,
00518 ("Make_Function_Type: TYLIST allocation messed up"));
00519 Set_TYLIST_type(new_return_tylist, (TY_IDX) 0);
00520 }
00521
00522 TY_IDX function_ty_idx;
00523 TY &function_ty = New_TY(function_ty_idx);
00524 static char buf[32];
00525 static INT32 tcount = 0;
00526
00527 ++tcount;
00528 sprintf(buf, ".anon_functype.%d", tcount);
00529 TY_Init(function_ty, (UINT64) 0, KIND_FUNCTION, MTYPE_UNKNOWN,
00530 Save_Str(buf));
00531 return function_ty_idx;
00532 #else
00533 TY_IDX ty_idx;
00534 TY& ty = New_TY (ty_idx);
00535
00536 TY_Init (ty, 0, KIND_FUNCTION, MTYPE_UNKNOWN, 0);
00537 Set_TY_align (ty_idx, 1);
00538
00539 TYLIST_IDX tylist_idx;
00540
00541 (void) New_TYLIST (tylist_idx);
00542 Tylist_Table [tylist_idx] = return_ty_idx;
00543 Set_TY_tylist (ty, tylist_idx);
00544
00545 (void) New_TYLIST (tylist_idx);
00546 Tylist_Table [tylist_idx] = 0;
00547
00548
00549 TY_IDX new_ty_idx = TY_is_unique (ty_idx);
00550 if (new_ty_idx != ty_idx && TY_IDX_index (ty_idx) == Ty_tab.Size () - 1) {
00551
00552
00553 Tylist_Table.Delete_last (2);
00554 Ty_tab.Delete_last ();
00555 ty_idx = new_ty_idx;
00556 }
00557 return ty_idx;
00558 #endif
00559 }
00560
00561 static std::vector<ST *> intrinsic_list;
00562
00563 struct matches_pu_ty_and_name {
00564 const TY_IDX ty;
00565 const char *const name;
00566
00567 matches_pu_ty_and_name(const TY_IDX type, const char *const func_name) :
00568 ty(type), name(func_name)
00569 { }
00570
00571 BOOL operator()(const ST *const st) {
00572 return (ST_pu_type(st) == ty &&
00573 strcmp(ST_name(st), name) == 0);
00574 }
00575 };
00576
00577 static void INTRINSIC_LIST_add(ST *st)
00578 {
00579 intrinsic_list.push_back(st);
00580 }
00581
00582 ST *
00583 INTRINSIC_LIST_lookup(TY_IDX ty,
00584 const char *function_name)
00585 {
00586 vector<ST *>::iterator result =
00587 std::find_if(intrinsic_list.begin(),
00588 intrinsic_list.end(),
00589 matches_pu_ty_and_name(ty, function_name));
00590 if (result == intrinsic_list.end()) {
00591 return NULL;
00592 }
00593 else {
00594 return *result;
00595 }
00596 }
00597
00598 ST *
00599 Gen_Intrinsic_Function(TY_IDX ty, const char *function_name)
00600 {
00601 ST *st = INTRINSIC_LIST_lookup(ty, function_name);
00602
00603 if (st == NULL) {
00604 st = New_ST(GLOBAL_SYMTAB);
00605
00606 PU_IDX pu_idx;
00607 PU& pu = New_PU (pu_idx);
00608
00609 PU_Init (pu, ty, CURRENT_SYMTAB);
00610
00611 ST_Init (st, Save_Str(function_name), CLASS_FUNC, SCLASS_EXTERN,
00612 EXPORT_PREEMPTIBLE, (TY_IDX) pu_idx);
00613
00614 #ifdef TARG_X8664
00615 if (Is_Target_32bit()) {
00616 if (Use_Sse_Reg_Parm)
00617 Set_TY_has_sseregister_parm (ty);
00618 if (Use_Reg_Parm)
00619 Set_TY_register_parm (ty, Use_Reg_Parm);
00620 }
00621 #endif
00622
00623 INTRINSIC_LIST_add(st);
00624 }
00625 return st;
00626 }
00627
00628
00629
00630 TY_IDX
00631 Make_Array_Type (TYPE_ID element, INT32 ndim, INT64 len)
00632 {
00633 FmtAssert(MTYPE_RegisterSize(element) > 0 && MTYPE_align_best(element) > 0,
00634 ("Cannot make an array of %s", MTYPE_name(element)));
00635 ARB_HANDLE arb,arb_first;
00636 for (UINT i = 0; i < ndim; ++i) {
00637 arb = New_ARB ();
00638 if (i==0) {
00639 arb_first = arb;
00640 }
00641 ARB_Init (arb, 0, len - 1, MTYPE_RegisterSize (element));
00642 Set_ARB_dimension (arb, ndim-i);
00643 }
00644
00645 Set_ARB_last_dimen (arb);
00646 Set_ARB_first_dimen (arb_first);
00647
00648 TY_IDX ty_idx;
00649 TY& ty = New_TY (ty_idx);
00650 TY_Init (ty, MTYPE_RegisterSize(element) * ndim * len, KIND_ARRAY,
00651 MTYPE_UNKNOWN, 0);
00652 Set_TY_align (ty_idx, MTYPE_align_best(element));
00653 Set_TY_etype (ty, MTYPE_To_TY (element));
00654 Set_TY_arb (ty, arb_first);
00655
00656 return ty_idx;
00657
00658 }
00659
00660
00661
00662
00663
00664
00665
00666
00667
00668
00669
00670
00671
00672
00673
00674
00675
00676
00677
00678
00679
00680
00681
00682
00683
00684
00685
00686
00687
00688
00689
00690 typedef TY_IDX HashKeyType;
00691
00692
00693
00694
00695
00696
00697
00698
00699
00700
00701
00702
00703
00704
00705
00706
00707
00708
00709
00710
00711 size_t
00712 TY_fun_hash (const TY& ty) {
00713 size_t value = 0;
00714
00715 TYLIST_ITER fn_iter = Make_tylist_iter(TY_tylist(ty));
00716
00717 while (*fn_iter) {
00718 value = MTYPE_LAST * value + TY_mtype(Ty_Table[*fn_iter++]);
00719 }
00720
00721 return value;
00722 }
00723
00724
00725
00726
00727
00728
00729
00730
00731
00732
00733
00734
00735 size_t
00736 TY_array_hash (const TY& ty) {
00737 return ARB_ubnd_val(TY_arb(ty)) +
00738 ARB_dimension(TY_arb(ty)) * TY_mtype(Ty_Table[TY_etype(ty)]) ;
00739
00740 }
00741
00742
00743
00744
00745
00746
00747
00748 inline size_t
00749 TY_struct_hash (const TY& ty) {
00750 return TY_name_idx(ty) ? TY_name_idx(ty) : TY_size(ty);
00751 }
00752
00753
00754 struct TY_hash {
00755 size_t operator()(TY_IDX ty_id) const {
00756 TY &ty = Ty_Table[ty_id];
00757 switch (TY_kind(ty)) {
00758 case KIND_SCALAR:
00759 case KIND_VOID:
00760 return TY_mtype(ty);
00761 case KIND_ARRAY:
00762 return TY_array_hash(ty);
00763 case KIND_POINTER:
00764 return TY_mtype(Ty_Table [TY_pointed(ty)]);
00765 case KIND_FUNCTION:
00766 return TY_fun_hash(ty);
00767 case KIND_STRUCT:
00768 return TY_struct_hash(ty);
00769 case KIND_INVALID:
00770 default:
00771 case KIND_LAST:
00772 Fail_FmtAssertion ("invalid TY_KIND in hash fn");
00773 return 0;
00774 }
00775 }
00776 };
00777
00778
00779
00780
00781
00782 struct TY_EQUIV
00783 {
00784 bool operator () ( TY_IDX k1, TY_IDX k2) const
00785 {
00786 return TY_are_equivalent(k1, k2);
00787 }
00788 };
00789
00790
00791
00792 typedef __gnu_cxx::hash_map<TY_IDX, TY_IDX, TY_hash, TY_EQUIV> HASH_TY_TABLE;
00793
00794
00795
00796
00797 HASH_TY_TABLE Hash_ty_scalar_table;
00798 HASH_TY_TABLE Hash_ty_array_table;
00799 HASH_TY_TABLE Hash_ty_struct_table;
00800 HASH_TY_TABLE Hash_ty_pointer_table;
00801 HASH_TY_TABLE Hash_ty_function_table;
00802
00803
00804
00805
00806
00807
00808
00809
00810
00811 typedef SEGMENTED_ARRAY<UINT32> TY_EQUIV_VISIT_ORDER;
00812 static TY_EQUIV_VISIT_ORDER Ty_Equiv_Visit1;
00813 static TY_EQUIV_VISIT_ORDER Ty_Equiv_Visit2;
00814 static UINT32 Ty_Equiv_Visit_Number = 0;
00815
00816 static BOOL
00817 Push_Equiv_Visit_Order(UINT32 ty_index1, UINT32 ty_index2, BOOL &are_equiv)
00818 {
00819 const UINT32 ty_tbl_size = TY_Table_Size();
00820 BOOL pushed = FALSE;
00821
00822
00823
00824
00825 for (UINT32 i = Ty_Equiv_Visit1.Size(); i < ty_tbl_size; i++)
00826 {
00827 UINT dummy;
00828 Ty_Equiv_Visit1.New_entry(dummy) = 0;
00829 Ty_Equiv_Visit2.New_entry(dummy) = 0;
00830 }
00831
00832 if (Ty_Equiv_Visit1[ty_index1] != Ty_Equiv_Visit2[ty_index2])
00833 are_equiv = FALSE;
00834 else if (Ty_Equiv_Visit1[ty_index1] > 0)
00835 are_equiv = TRUE;
00836 else
00837 {
00838 Ty_Equiv_Visit_Number++;
00839 Ty_Equiv_Visit1[ty_index1] = Ty_Equiv_Visit_Number;
00840 Ty_Equiv_Visit2[ty_index2] = Ty_Equiv_Visit_Number;
00841 are_equiv = FALSE;
00842 pushed = TRUE;
00843 }
00844 return pushed;
00845 }
00846
00847 static void
00848 Pop_Equiv_Visit_Order(UINT32 ty_index1, UINT32 ty_index2)
00849 {
00850 Ty_Equiv_Visit_Number--;
00851 Ty_Equiv_Visit1[ty_index1] = 0;
00852 Ty_Equiv_Visit2[ty_index2] = 0;
00853 }
00854
00855
00856
00857
00858
00859
00860
00861
00862
00863 BOOL
00864 ARB_are_equivalent(ARB_HANDLE arb_id1, ARB_HANDLE arb_id2, UINT32 flags)
00865 {
00866 if (arb_id1 == arb_id2)
00867 return TRUE;
00868
00869 ARB_HANDLE arb1=arb_id1;
00870 ARB_HANDLE arb2=arb_id2;
00871 BOOL keep_going;
00872
00873 do {
00874
00875 keep_going = ! ARB_last_dimen(arb1) && ! ARB_last_dimen(arb2);
00876
00877 if (ARB_dimension(arb1) != ARB_dimension(arb2))
00878 return FALSE;
00879
00880 if (ARB_flags(arb1) != ARB_flags( arb2))
00881 return FALSE;
00882
00883 if (ARB_const_lbnd(arb1)) {
00884 if (ARB_lbnd_val( arb1) != ARB_lbnd_val( arb2))
00885 return FALSE;
00886 } else {
00887 if (ARB_lbnd_var( arb1) != ARB_lbnd_var( arb2))
00888 return FALSE;
00889 }
00890
00891 if (ARB_const_ubnd(arb1)) {
00892 if (ARB_ubnd_val( arb1) != ARB_ubnd_val( arb2))
00893 return FALSE;
00894 } else {
00895 if (ARB_ubnd_var( arb1) != ARB_ubnd_var( arb2))
00896 return FALSE;
00897 }
00898
00899 if (ARB_const_stride(arb1)) {
00900 if (ARB_stride_val( arb1) != ARB_stride_val( arb2))
00901 return FALSE;
00902 } else {
00903 if (ARB_stride_var(arb1) != ARB_stride_var( arb2))
00904 return FALSE;
00905 }
00906
00907
00908 if (keep_going) {
00909 arb1 = arb1[1];
00910 arb2 = arb2[1];
00911 }
00912
00913 } while (keep_going);
00914
00915 if ( ARB_last_dimen(arb2) && ARB_last_dimen(arb1))
00916 return TRUE;
00917 else
00918 return FALSE;
00919
00920 }
00921
00922
00923 void
00924 ARB_swap(ARB_HANDLE arb1, ARB_HANDLE arb2)
00925 {
00926 ARB temp;
00927 temp = *(arb1.Entry());
00928 *(arb1.Entry()) = *(arb2.Entry());
00929 *(arb2.Entry()) = temp;
00930 }
00931
00932
00933
00934
00935
00936
00937
00938
00939 BOOL
00940 FLD_are_equivalent (FLD_HANDLE fld1, FLD_HANDLE fld2, UINT32 flags)
00941 {
00942 if (!(flags & TY_EQUIV_IGNORE_NAMES) &&
00943 FLD_name_idx(fld1) != FLD_name_idx(fld2))
00944 return FALSE;
00945
00946 if (FLD_ofst(fld1) != FLD_ofst(fld2) ||
00947 FLD_bsize(fld1) != FLD_bsize(fld2) ||
00948 FLD_bofst(fld1) != FLD_bofst(fld2) ||
00949 FLD_flags(fld1) != FLD_flags(fld2) ||
00950 FLD_st(fld1) != FLD_st(fld2))
00951 return FALSE;
00952
00953
00954
00955
00956
00957
00958
00959
00960
00961 TY_IDX ty_id1 = FLD_type(fld1);
00962 TY_IDX ty_id2 = FLD_type(fld2);
00963
00964 #ifdef FRONT_END
00965 if ( (ty_id1 == 0) || (ty_id2 == 0))
00966 return FALSE;
00967 #endif //FRONT_END
00968
00969
00970
00971 return TY_are_equivalent(ty_id1, ty_id2, flags);
00972
00973 }
00974
00975
00976
00977
00978 static BOOL
00979 Struct_are_equivalent (FLD_HANDLE fld_id1, FLD_HANDLE fld_id2, UINT32 flags)
00980 {
00981 if (fld_id1 == fld_id2)
00982 return TRUE;
00983
00984 FLD_ITER fld1_iter = Make_fld_iter (fld_id1);
00985 FLD_ITER fld2_iter = Make_fld_iter (fld_id2);
00986
00987 while (!FLD_last_field (fld1_iter) && !FLD_last_field (fld2_iter)) {
00988 if (! FLD_are_equivalent (fld1_iter, fld2_iter, flags))
00989 return FALSE;
00990 ++fld1_iter;
00991 ++fld2_iter;
00992 }
00993
00994 return FLD_are_equivalent (fld1_iter, fld2_iter, flags);
00995 }
00996
00997
00998
00999
01000
01001 BOOL
01002 TYLIST_are_equivalent (TYLIST_IDX tylist_id1,
01003 TYLIST_IDX tylist_id2,
01004 UINT32 flags)
01005 {
01006 if (tylist_id1 == tylist_id2)
01007 return TRUE;
01008
01009
01010
01011 TY_IDX ty_id1;
01012 TY_IDX ty_id2;
01013
01014 while (Tylist_Table[tylist_id1] != 0) {
01015
01016 ty_id1 = Tylist_Table[tylist_id1];
01017 ty_id2 = Tylist_Table[tylist_id2];
01018
01019 if ( !TY_are_equivalent(ty_id1, ty_id2, flags))
01020 return FALSE;
01021
01022 tylist_id1++;
01023 tylist_id2++;
01024 }
01025
01026 if (Tylist_Table[tylist_id2] == 0)
01027 return TRUE;
01028 else
01029 return FALSE;
01030 }
01031
01032
01033
01034
01035
01036
01037
01038 BOOL
01039 TY_are_equivalent (TY_IDX ty_id1, TY_IDX ty_id2, UINT32 flags)
01040 {
01041
01042
01043
01044
01045
01046 const UINT32 ty_index1 = TY_IDX_index(ty_id1);
01047 const UINT32 ty_index2 = TY_IDX_index(ty_id2);
01048
01049 if (ty_id1 == ty_id2)
01050 return TRUE;
01051 else if ((flags & TY_EQUIV_ALIGN) &&
01052 TY_align_exp(ty_id1) != TY_align_exp(ty_id2))
01053 return FALSE;
01054 else if ((flags & TY_EQUIV_QUALIFIER) &&
01055 (TY_is_const(ty_id1) != TY_is_const(ty_id2) ||
01056 TY_is_volatile(ty_id1) != TY_is_volatile(ty_id2) ||
01057 TY_is_restrict(ty_id1) != TY_is_restrict(ty_id2)))
01058 return FALSE;
01059 else if (ty_index1 == ty_index2)
01060 return TRUE;
01061
01062
01063
01064
01065
01066
01067 BOOL are_equiv = FALSE;
01068
01069 if (Push_Equiv_Visit_Order(ty_index1, ty_index2, are_equiv))
01070 {
01071
01072
01073 const TY &ty1 = Ty_Table[ty_id1];
01074 const TY &ty2 = Ty_Table[ty_id2];
01075
01076
01077
01078
01079 if ( TY_size(ty1) != TY_size(ty2) ||
01080 TY_kind(ty1) != TY_kind(ty2) ||
01081 TY_mtype(ty1)!= TY_mtype(ty2)||
01082 TY_flags(ty1)!= TY_flags(ty2) )
01083 {
01084
01085 are_equiv = FALSE;
01086 }
01087 else if (!(flags & TY_EQUIV_IGNORE_NAMES) &&
01088 TY_name_idx (ty1) != TY_name_idx (ty2))
01089 {
01090 are_equiv = FALSE;
01091 }
01092 else
01093 {
01094
01095
01096
01097
01098 flags |= (TY_EQUIV_ALIGN | TY_EQUIV_QUALIFIER);
01099
01100
01101
01102
01103 switch (TY_kind (ty1)) {
01104
01105 case KIND_SCALAR:
01106 case KIND_VOID:
01107 are_equiv = TRUE;
01108 break;
01109
01110 case KIND_ARRAY:
01111
01112 are_equiv = (ARB_are_equivalent(TY_arb(ty1), TY_arb(ty2), flags) &&
01113 TY_are_equivalent( TY_etype(ty1), TY_etype(ty2), flags));
01114 break;
01115
01116 case KIND_STRUCT:
01117
01118
01119
01120 are_equiv = Struct_are_equivalent(TY_fld(ty1), TY_fld(ty2), flags);
01121 #ifdef KEY
01122 are_equiv &= (TY_copy_constructor(ty1) == TY_copy_constructor(ty2));
01123 #endif
01124 break;
01125
01126 case KIND_POINTER:
01127
01128 are_equiv = TY_are_equivalent (TY_pointed(ty1),TY_pointed(ty2), flags);
01129 break;
01130
01131 case KIND_FUNCTION:
01132
01133 are_equiv = ( (ty1.Pu_flags() == ty2.Pu_flags()) &&
01134 (TYLIST_are_equivalent (TY_tylist(ty1),
01135 TY_tylist(ty2),
01136 flags)));
01137 break;
01138
01139 case KIND_INVALID:
01140 default:
01141
01142 are_equiv = FALSE;
01143 break;
01144 }
01145 }
01146 Pop_Equiv_Visit_Order(ty_index1, ty_index2);
01147 }
01148 return are_equiv;
01149 }
01150
01151
01152
01153
01154
01155
01156
01157 static inline TY_IDX
01158 TY_is_unique_op (const TY_IDX ty_idx, HASH_TY_TABLE& hash_ty_table)
01159 {
01160 TY_IDX return_idx = ty_idx;
01161 HASH_TY_TABLE::const_iterator hash_entry = hash_ty_table.find (ty_idx);
01162 if (hash_entry != hash_ty_table.end ())
01163
01164 Set_TY_IDX_index(return_idx, TY_IDX_index((*hash_entry).second));
01165 else
01166 hash_ty_table.insert (HASH_TY_TABLE::value_type(ty_idx, ty_idx));
01167 return return_idx;
01168 }
01169
01170
01171 TY_IDX
01172 TY_is_unique (const TY_IDX ty_idx)
01173 {
01174 TY &ty = Ty_Table[ty_idx];
01175
01176
01177
01178
01179
01180
01181
01182 switch (TY_kind(ty)) {
01183
01184 case KIND_SCALAR:
01185 case KIND_VOID:
01186 return TY_is_unique_op (ty_idx, Hash_ty_scalar_table);
01187
01188 case KIND_ARRAY:
01189 return TY_is_unique_op (ty_idx, Hash_ty_array_table);
01190
01191 case KIND_POINTER:
01192 return TY_is_unique_op (ty_idx, Hash_ty_pointer_table);
01193
01194 case KIND_FUNCTION:
01195 return TY_is_unique_op (ty_idx, Hash_ty_function_table);
01196
01197 case KIND_STRUCT:
01198 return TY_is_unique_op (ty_idx, Hash_ty_struct_table);
01199
01200 case KIND_INVALID:
01201 default:
01202 case KIND_LAST:
01203 Fail_FmtAssertion ("invalid TY_KIND in TY_is_unique");
01204 return ty_idx;
01205 };
01206 }
01207
01208
01209 BOOL
01210 TY_has_union (TY_IDX ty)
01211 {
01212 if (TY_kind(ty) != KIND_STRUCT)
01213 return FALSE;
01214 if (TY_is_union(ty))
01215 return TRUE;
01216
01217 FLD_HANDLE fld = TY_fld (ty);
01218 TY_IDX fty;
01219 do {
01220 fty = FLD_type(fld);
01221 if (TY_has_union(fty))
01222 return TRUE;
01223 fld = FLD_next (fld);
01224 } while (!fld.Is_Null ());
01225 return FALSE;
01226 }
01227
01228 #ifdef TARG_NVISA
01229
01230 UINT
01231 TY_vector_count (TY_IDX ty)
01232 {
01233 FmtAssert(TY_can_be_vector(ty), ("not a vector type"));
01234 FmtAssert(TY_kind(ty) == KIND_STRUCT, ("vector not a struct type"));
01235 INT count = 0;
01236 FLD_HANDLE fld = TY_fld (ty);
01237 do {
01238 ++count;
01239 fld = FLD_next (fld);
01240 } while (!fld.Is_Null ());
01241 return count;
01242 }
01243 #endif
01244
01245
01246 TYPE_ID
01247 Mtype_For_Type_Offset (TY_IDX ty, INT64 offset)
01248 {
01249 switch (TY_kind(ty)) {
01250 case KIND_STRUCT:
01251 {
01252
01253 FLD_ITER fld_iter = Make_fld_iter(TY_fld(ty));
01254 do {
01255 FLD_HANDLE fld(fld_iter);
01256 if (Is_Composite_Type(FLD_type(fld))
01257 && offset >= FLD_ofst(fld)
01258 && offset < FLD_ofst(fld) + TY_size(FLD_type(fld)))
01259 {
01260 return Mtype_For_Type_Offset (FLD_type(fld), offset - FLD_ofst(fld));
01261 }
01262 if (FLD_ofst(fld) == offset)
01263 return TY_mtype(FLD_type(fld));
01264 } while (!FLD_last_field(fld_iter++));
01265 FmtAssert(FALSE, ("couldn't find matching field"));
01266 }
01267 case KIND_ARRAY:
01268
01269 return Mtype_For_Type_Offset (TY_etype(ty),
01270 offset % TY_size(TY_etype(ty)));
01271 default:
01272 return TY_mtype(ty);
01273 }
01274 }
01275
01276
01277
01278
01279
01280 const char *
01281 Preg_Name (PREG_NUM i)
01282 {
01283 Is_True((i > Last_Dedicated_Preg_Offset),
01284 ("Preg_Name: not valid for dedicated preg"));
01285
01286 const PREG& preg = Preg_Table[i - Last_Dedicated_Preg_Offset];
01287
01288 if (PREG_name_idx (preg) == 0)
01289 return "<preg>";
01290 else
01291 return PREG_name (preg);
01292 }
01293
01294
01295
01296
01297 PREG_NUM
01298 Create_Preg_explicit(TYPE_ID mtype, const char *name,
01299 SCOPE *scope_tab, SYMTAB_IDX level)
01300 {
01301 PREG_IDX preg_idx;
01302 PREG_IDX preg_idx2;
01303 PREG &p = New_PREG_explicit (scope_tab, level, preg_idx);
01304 Set_PREG_name_idx (p, Save_Str(name));
01305
01306
01307 switch (mtype) {
01308 case MTYPE_C4:
01309 case MTYPE_C8:
01310 #ifdef TARG_IA64
01311 case MTYPE_C10:
01312 #endif
01313 case MTYPE_FQ:
01314
01315 (void) New_PREG_explicit (scope_tab, level, preg_idx2);
01316 Set_PREG_name_idx ((*scope_tab[level].preg_tab)[preg_idx2], 0);
01317 break;
01318 case MTYPE_CQ:
01319
01320 (void) New_PREG_explicit (scope_tab, level, preg_idx2);
01321 Set_PREG_name_idx ((*scope_tab[level].preg_tab)[preg_idx2], 0);
01322 (void) New_PREG_explicit (scope_tab, level, preg_idx2);
01323 Set_PREG_name_idx ((*scope_tab[level].preg_tab)[preg_idx2], 0);
01324 (void) New_PREG_explicit (scope_tab, level, preg_idx2);
01325 Set_PREG_name_idx ((*scope_tab[level].preg_tab)[preg_idx2], 0);
01326 break;
01327 case MTYPE_B:
01328
01329 (void) New_PREG_explicit (scope_tab, level, preg_idx2);
01330 Set_PREG_name_idx ((*scope_tab[level].preg_tab)[preg_idx2], 0);
01331 break;
01332 }
01333
01334 return (PREG_NUM) preg_idx + Last_Dedicated_Preg_Offset;
01335 }
01336
01337 PREG_NUM
01338 Create_Preg (TYPE_ID mtype, const char *name)
01339 {
01340 return Create_Preg_explicit(mtype, name, Scope_tab, CURRENT_SYMTAB);
01341 }
01342
01343
01344
01345 INT32
01346 Preg_Increment (TYPE_ID mtype)
01347 {
01348 switch (mtype) {
01349
01350 case MTYPE_C4:
01351 case MTYPE_C8:
01352 #ifdef TARG_IA64
01353 case MTYPE_C10:
01354 #endif
01355 #ifndef TARG_X8664
01356 case MTYPE_FQ:
01357 #endif
01358 return 2;
01359
01360 case MTYPE_CQ:
01361 return 4;
01362
01363 case MTYPE_I8:
01364 case MTYPE_U8:
01365 if (MTYPE_size_reg(MTYPE_I8) > MTYPE_size_reg(Spill_Int_Mtype))
01366 return 2;
01367 case MTYPE_B:
01368
01369
01370 return 2;
01371 }
01372 return 1;
01373 }
01374
01375
01376
01377
01378
01379
01380 BLK_IDX
01381 Copy_BLK (BLK_IDX b)
01382 {
01383 BLK_IDX copy = b;
01384 copy = Blk_Table.Insert (Blk_Table[b]);
01385 return copy;
01386 }
01387
01388
01389
01390
01391
01392
01393
01394
01395
01396
01397
01398 void
01399 Base_Symbol_And_Offset (ST *st,
01400 ST **base_symbol,
01401 INT64 *offset_from_base)
01402 {
01403 INT64 ofst = 0;
01404 ST *base = st;
01405
01406 while ( ST_base(base) != base ) {
01407 ofst += ST_ofst(base);
01408 base = ST_base(base);
01409 }
01410
01411 *base_symbol = base;
01412 *offset_from_base = ofst;
01413 }
01414
01415
01416
01417
01418
01419
01420
01421
01422
01423
01424
01425
01426
01427
01428
01429 const char *
01430 Class_Name (INT cl)
01431 {
01432 switch (cl) {
01433 case CLASS_UNK :
01434 return "CLASS_UNK";
01435 case CLASS_VAR :
01436 return "CLASS_VAR";
01437 case CLASS_FUNC :
01438 return "CLASS_FUNC";
01439 case CLASS_CONST :
01440 return "CLASS_CONST";
01441 case CLASS_PREG :
01442 return "CLASS_PREG";
01443 case CLASS_BLOCK :
01444 return "CLASS_BLOCK";
01445 case CLASS_NAME:
01446 return "CLASS_NAME";
01447 default:
01448 {
01449 static char buf[32];
01450 sprintf(buf, "Unknown_CLASS(%d)", cl);
01451 return buf;
01452 }
01453 }
01454 }
01455
01456
01457 const char *
01458 Sclass_Name (INT s)
01459 {
01460 switch (s) {
01461 case SCLASS_UNKNOWN:
01462 return "UNKNOWN";
01463 case SCLASS_AUTO:
01464 return "AUTO";
01465 case SCLASS_FORMAL:
01466 return "FORMAL";
01467 case SCLASS_FORMAL_REF:
01468 return "FORMAL_REF";
01469 case SCLASS_PSTATIC:
01470 return "PSTATIC";
01471 case SCLASS_FSTATIC:
01472 return "FSTATIC";
01473 case SCLASS_COMMON:
01474 return "COMMON";
01475 case SCLASS_EXTERN:
01476 return "EXTERN";
01477 case SCLASS_UGLOBAL:
01478 return "UGLOBAL";
01479 case SCLASS_DGLOBAL:
01480 return "DGLOBAL";
01481 case SCLASS_TEXT:
01482 return "TEXT";
01483 case SCLASS_REG:
01484 return "REG";
01485 case SCLASS_CPLINIT:
01486 return "CPLINIT";
01487 case SCLASS_EH_REGION:
01488 return "EH_REGION";
01489 case SCLASS_EH_REGION_SUPP:
01490 return "EH_REGION_SUPP";
01491 case SCLASS_DISTR_ARRAY:
01492 return "DISTR_ARRAY";
01493 case SCLASS_THREAD_PRIVATE_FUNCS:
01494 return "THREAD_PRIVATE_FUNCS";
01495 case SCLASS_COMMENT:
01496 return "COMMENT";
01497 default:
01498 {
01499 static char buf[32];
01500 sprintf(buf, "Unknown_SCLASS(%d)", s);
01501 return buf;
01502 }
01503 }
01504 }
01505
01506 const char *
01507 Export_Name (INT e)
01508 {
01509 switch (e) {
01510 case EXPORT_LOCAL:
01511 return "XLOCAL";
01512 case EXPORT_LOCAL_INTERNAL:
01513 return "XLOCAL_INTERNAL";
01514 case EXPORT_INTERNAL:
01515 return "XINTERNAL";
01516 case EXPORT_HIDDEN:
01517 return "XHIDDEN";
01518 case EXPORT_PROTECTED:
01519 return "XPROTECTED";
01520 case EXPORT_PREEMPTIBLE:
01521 return "XPREEMPTIBLE";
01522 case EXPORT_OPTIONAL:
01523 return "XOPTIONAL";
01524 default:
01525 {
01526 static char buf[32];
01527 sprintf(buf, "Unknown_Export_Scope(%d)", e);
01528 return buf;
01529 }
01530 }
01531 }
01532
01533 const char *
01534 Kind_Name (INT k)
01535 {
01536 struct knm {
01537 char name[32];
01538 };
01539 static struct knm knb[4];
01540 static INT16 knb_used;
01541 char *r;
01542
01543 switch ( k ) {
01544 case KIND_SCALAR:
01545 return "KIND_SCALAR";
01546 case KIND_ARRAY:
01547 return "KIND_ARRAY";
01548 case KIND_STRUCT:
01549 return "KIND_STRUCT";
01550 case KIND_POINTER:
01551 return "KIND_POINTER";
01552 case KIND_FUNCTION:
01553 return "KIND_FUNCTION";
01554 case KIND_VOID:
01555 return "KIND_VOID";
01556 }
01557
01558 r = knb[knb_used].name;
01559 knb_used = (knb_used + 1) % 4;
01560 sprintf ( r, "KIND_%1d", k );
01561 return r;
01562 }
01563
01564
01565 static void
01566 Print_type_attributes (FILE *f, TY_IDX ty)
01567 {
01568 if (TY_is_const (ty))
01569 fputs ("const ", f);
01570 if (TY_is_volatile (ty))
01571 fputs ("volatile ", f);
01572 if (TY_is_restrict (ty))
01573 fputs ("restrict ", f);
01574 }
01575
01576
01577 static void
01578 Print_TY_IDX_verbose (FILE *f, TY_IDX idx)
01579 {
01580 Print_type_attributes (f, idx);
01581 if (TY_IDX_index (idx) == 0) {
01582 fputs ("<NULL>", f);
01583 return;
01584 }
01585
01586 const TY& ty = Ty_Table[idx];
01587 const char *name = TY_name_idx (ty) == 0 ? "(anon)" : TY_name (ty);
01588 fprintf (f, "%s (#%d) align %d", name, TY_IDX_index (idx), TY_align (idx));
01589 }
01590
01591
01592 static const char *
01593 TY_kind_name (const TY& ty)
01594 {
01595 if (TY_kind (ty) == KIND_SCALAR && TY_mtype (ty) != MTYPE_UNKNOWN)
01596 return MTYPE_name (TY_mtype (ty));
01597 else
01598 return Kind_Name (TY_kind (ty));
01599 }
01600
01601 void
01602 ST::Print (FILE *f, BOOL verbose) const
01603 {
01604 const char *name_str = (sym_class == CLASS_CONST) ?
01605 "<constant>" : &Str_Table[u1.name_idx];
01606
01607 fprintf (f, "%-14s\t<%d,%d> ", name_str, ST_IDX_level (st_idx),
01608 ST_IDX_index (st_idx));
01609 if (strlen (name_str) > 20)
01610 fputs ("\n\t\t", f);
01611
01612 TY_IDX ty_idx = 0;
01613
01614 switch (sym_class) {
01615
01616 case CLASS_UNK:
01617 fputs ("Class unknown", f);
01618 break;
01619
01620 case CLASS_VAR:
01621 fputs ("Variable", f);
01622 ty_idx = u2.type;
01623 break;
01624
01625 case CLASS_FUNC:
01626 fputs ("Subprogram", f);
01627 ty_idx = PU_prototype (Pu_Table[u2.pu]);
01628 break;
01629
01630 case CLASS_CONST:
01631 fputs ("Constant", f);
01632 ty_idx = u2.type;
01633 break;
01634
01635 case CLASS_PREG:
01636 fputs ("Pseudo-Register", f);
01637 ty_idx = u2.type;
01638 break;
01639
01640 case CLASS_BLOCK:
01641 fputs ("Block", f);
01642 fprintf (f, " (#%d)", u2.blk);
01643 break;
01644
01645 case CLASS_NAME:
01646 fputs ("Name-only", f);
01647 break;
01648
01649 default:
01650 fprintf (f, "INVALID CLASS (%d)", sym_class);
01651 break;
01652 }
01653
01654 const TY& ty = Ty_Table [ty_idx];
01655
01656 if (ty_idx != 0) {
01657
01658 name_str = TY_name_idx (ty) == 0 ? NULL : TY_name (ty);
01659
01660 if (!(sym_class == CLASS_FUNC) || name_str != NULL) {
01661 fputs (" of type ", f);
01662
01663 Print_type_attributes (f, ty_idx);
01664
01665 fputs (name_str ? name_str : "(anon)", f);
01666
01667 const TY *pty = &ty;
01668 INT pcount = 0;
01669 while (TY_kind (*pty) == KIND_POINTER) {
01670 pty = &Ty_Table[TY_pointed (*pty)];
01671 ++pcount;
01672 }
01673
01674 if (verbose) {
01675 name_str = TY_kind_name (*pty);
01676 fprintf (f, " (#%d, %s", TY_IDX_index (ty_idx), name_str);
01677 while (pcount-- > 0)
01678 fputc ('*', f);
01679 fputc (')', f);
01680 } else
01681 fprintf (f, " (#%d)", TY_IDX_index (ty_idx));
01682 }
01683 }
01684
01685 if (!verbose) {
01686
01687 fprintf (f, " @ 0x%llx", offset);
01688 if (base_idx != 0)
01689 fprintf (f, "(%s)", ST_name (base_idx));
01690 }
01691 fputc ('\n', f);
01692
01693 if (sym_class == CLASS_FUNC && verbose) {
01694
01695
01696
01697 if (ty_idx != 0 && TY_tylist (ty) != 0) {
01698 TY_IDX rettype_idx = Tylist_Table[TY_tylist (ty)];
01699 const TY& rettype = Ty_Table[rettype_idx];
01700 fputs ("\t\tReturning ", f);
01701 Print_type_attributes (f, rettype_idx);
01702 fputs (TY_name (rettype), f);
01703 name_str = TY_kind_name (rettype);
01704 fprintf (f, " (#%d, %s) ", TY_IDX_index (rettype_idx), name_str);
01705
01706 fprintf (f, "PU[%d] ", u2.pu);
01707 if (Pu_Table[u2.pu].src_lang & PU_C_LANG) fprintf (f, "C ");
01708 if (Pu_Table[u2.pu].src_lang & PU_CXX_LANG) fprintf (f, "C++ ");
01709 if (Pu_Table[u2.pu].src_lang & PU_F77_LANG) fprintf (f, "F77 ");
01710 if (Pu_Table[u2.pu].src_lang & PU_F90_LANG) fprintf (f, "F90 ");
01711
01712 mUINT64 flags = Pu_Table[u2.pu].flags;
01713 fprintf (f, "flags:");
01714 if (flags & PU_IS_PURE) fprintf (f, " pure");
01715 if (flags & PU_NO_SIDE_EFFECTS) fprintf (f, " no_side_effects");
01716 if (flags & PU_IS_INLINE_FUNCTION) fprintf (f, " inline");
01717 if (flags & PU_NO_INLINE) fprintf (f, " no_inline");
01718 if (flags & PU_MUST_INLINE) fprintf (f, " must_inline");
01719 if (flags & PU_NO_DELETE) fprintf (f, " no_delete");
01720 if (flags & PU_HAS_EXC_SCOPES) fprintf (f, " exc_scopes");
01721 if (flags & PU_IS_NESTED_FUNC) fprintf (f, " nested_func");
01722 if (flags & PU_HAS_NON_MANGLED_CALL)fprintf (f, " non_mangled_call");
01723 if (flags & PU_ARGS_ALIASED) fprintf (f, " args_aliased");
01724 if (flags & PU_NEEDS_FILL_ALIGN_LOWERING)fprintf (f, " fill_align");
01725 if (flags & PU_NEEDS_T9) fprintf (f, " t9");
01726 if (flags & PU_HAS_VERY_HIGH_WHIRL) fprintf (f, " very_high_whirl");
01727 if (flags & PU_HAS_ALTENTRY) fprintf (f, " altentry");
01728 if (flags & PU_RECURSIVE) fprintf (f, " recursive");
01729 if (flags & PU_IS_MAINPU) fprintf (f, " main");
01730 if (flags & PU_UPLEVEL) fprintf (f, " uplevel");
01731 if (flags & PU_MP_NEEDS_LNO) fprintf (f, " mp_needs_lno");
01732 if (flags & PU_HAS_ALLOCA) fprintf (f, " alloca");
01733 if (flags & PU_IN_ELF_SECTION) fprintf (f, " in_elf_section");
01734 if (flags & PU_HAS_MP) fprintf (f, " has_mp");
01735 if (flags & PU_MP) fprintf (f, " mp");
01736 if (flags & PU_HAS_NAMELIST) fprintf (f, " namelist");
01737 if (flags & PU_HAS_RETURN_ADDRESS) fprintf (f, " return_address");
01738 if (flags & PU_HAS_REGION) fprintf (f, " has_region");
01739 if (flags & PU_HAS_INLINES) fprintf (f, " has_inlines");
01740 if (flags & PU_CALLS_SETJMP) fprintf (f, " calls_setjmp");
01741 if (flags & PU_CALLS_LONGJMP) fprintf (f, " calls_longjmp");
01742 if (flags & PU_IPA_ADDR_ANALYSIS) fprintf (f, " ipa_addr");
01743 if (flags & PU_SMART_ADDR_ANALYSIS) fprintf (f, " smart_addr");
01744 if (flags & PU_HAS_GLOBAL_PRAGMAS) fprintf (f, " global_pragmas");
01745 if (flags & PU_HAS_USER_ALLOCA) fprintf (f, " user_alloca");
01746 if (flags & PU_HAS_UNKNOWN_CONTROL_FLOW) fprintf (f, " unknown_control_flow");
01747 if (flags & PU_IS_THUNK) fprintf (f, " thunk");
01748 #ifdef KEY
01749 if (flags & PU_NEEDS_MANUAL_UNWINDING) fprintf (f, " needs_manual_unwinding");
01750 if (flags & PU_IS_EXTERN_INLINE) fprintf (f, " extern_inline");
01751 if (flags & PU_IS_MARKED_INLINE) fprintf (f, " inline_keyword");
01752 if (flags & PU_NO_INSTRUMENT) fprintf (f, " no_instrument");
01753 if (flags & PU_NEED_TRAMPOLINE) fprintf (f, " need_trampoline");
01754 #endif
01755 #ifdef TARG_X8664
01756 if (flags & PU_FF2C_ABI) fprintf (f, " ff2c_abi");
01757 #endif
01758 if (flags & PU_IS_CDECL) fprintf (f, " cdecl");
01759 if (TY_return_to_param(ty_idx)) fprintf (f, " return_to_param");
01760 if (TY_is_varargs(ty_idx)) fprintf (f, " varargs");
01761 if (TY_has_prototype(ty_idx)) fprintf (f, " prototype");
01762 #ifdef TARG_X8664
01763 if (TY_has_sseregister_parm(ty_idx)) fprintf (f, " sseregisterparm");
01764 INT register_parms = TY_register_parm(ty_idx);
01765 if (register_parms) fprintf (f, " %d-registerparm", register_parms);
01766 #endif
01767 fprintf (f, "\n");
01768 }
01769 }
01770
01771 if (sym_class == CLASS_CONST)
01772 fprintf (f, "\t\tvalue: %s\n", Targ_Print (NULL, Tcon_Table[u1.tcon]));
01773
01774 if (verbose) {
01775
01776 if (base_idx != 0) {
01777 const ST& base_st = St_Table[base_idx];
01778 fprintf (f, "\t\tAddress: %lld(%s<%d,%d>) ", offset,
01779 ST_class (base_st) == CLASS_CONST ? "" :
01780 ST_name (base_idx), ST_IDX_level (base_idx),
01781 ST_IDX_index (base_idx));
01782 }
01783
01784 if (ty_idx != 0) {
01785 if (base_idx == 0 && offset == 0)
01786 fputs ("\t\t", f);
01787 fprintf (f, "Alignment: %d bytes", TY_align (ty_idx));
01788 }
01789 fprintf (f, "\n");
01790
01791 fprintf (f, "\t\tFlags:\t0x%08x", flags);
01792 if (flags) {
01793 if (flags & ST_IS_WEAK_SYMBOL) fprintf (f, " weak");
01794 if (flags & ST_IS_SPLIT_COMMON) fprintf (f, " split_common");
01795 if (flags & ST_IS_NOT_USED) fprintf (f, " not_used");
01796 if (flags & ST_IS_INITIALIZED) fprintf (f, " initialized");
01797 if (flags & ST_IS_RETURN_VAR) fprintf (f, " return_var");
01798 if (flags & ST_IS_VALUE_PARM) fprintf (f, " value_parm");
01799 if (flags & ST_PROMOTE_PARM) fprintf (f, " promote_parm");
01800 if (flags & ST_KEEP_NAME_W2F) fprintf (f, " keep_name_w2f");
01801 if (flags & ST_IS_DATAPOOL) fprintf (f, " datapool");
01802 if (flags & ST_IS_RESHAPED) fprintf (f, " reshaped");
01803 if (flags & ST_EMIT_SYMBOL) fprintf (f, " emit_symbol");
01804 if (flags & ST_HAS_NESTED_REF) fprintf (f, " has_nested_ref");
01805 if (flags & ST_INIT_VALUE_ZERO) fprintf (f, " init_value_zero");
01806 if (flags & ST_GPREL) fprintf (f, " gprel");
01807 if (flags & ST_NOT_GPREL) fprintf (f, " not_gprel");
01808 if (flags & ST_IS_NAMELIST) fprintf (f, " namelist");
01809 if (flags & ST_IS_F90_TARGET) fprintf (f, " f90_target");
01810 if (flags & ST_DECLARED_STATIC) fprintf (f, " static");
01811 if (flags & ST_IS_EQUIVALENCED) fprintf (f, " equivalenced");
01812 if (flags & ST_IS_FILL_ALIGN) fprintf (f, " fill_align");
01813 if (flags & ST_IS_OPTIONAL_ARGUMENT)fprintf (f, " optional");
01814 if (flags & ST_PT_TO_UNIQUE_MEM) fprintf (f, " pt_to_unique_mem");
01815 if (flags & ST_IS_TEMP_VAR) fprintf (f, " temp");
01816 if (flags & ST_IS_CONST_VAR) fprintf (f, " const");
01817 if (flags & ST_ADDR_SAVED) fprintf (f, " addr_saved");
01818 if (flags & ST_ADDR_PASSED) fprintf (f, " addr_passed");
01819 if (flags & ST_IS_THREAD_PRIVATE) fprintf (f, " thread_private");
01820 if (flags & ST_ASSIGNED_TO_DEDICATED_PREG)
01821 fprintf (f, " assigned_to_dedicated_preg");
01822 }
01823
01824 #ifdef KEY
01825 if (flags_ext) {
01826 fprintf (f, "\t\tFlags_ext:\t0x%08x", flags_ext);
01827 if (flags_ext & ST_ONE_PER_PU)
01828 fprintf (f, " one_per_pu");
01829 if (flags_ext & ST_COPY_CONSTRUCTOR_ST)
01830 fprintf (f, " copy_constructor_st");
01831 if (flags_ext & ST_INITV_IN_OTHER_ST)
01832 fprintf (f, " st_used_as_initialization");
01833 if (flags_ext & ST_IS_THREAD_LOCAL)
01834 fprintf (f, " thread_local");
01835 }
01836 #endif
01837 #ifdef TARG_NVISA
01838 if (memory_space == MEMORY_GLOBAL)
01839 fprintf (f, " __global__");
01840 if (memory_space == MEMORY_SHARED)
01841 fprintf (f, " __shared__");
01842 if (memory_space == MEMORY_CONSTANT)
01843 fprintf (f, " __constant__");
01844 if (memory_space == MEMORY_LOCAL)
01845 fprintf (f, " __local__");
01846 if (memory_space == MEMORY_TEXTURE)
01847 fprintf (f, " __texture__");
01848 if (memory_space == MEMORY_PARAM)
01849 fprintf (f, " __param__");
01850 #endif
01851
01852 switch (export_class) {
01853
01854 case EXPORT_LOCAL:
01855 fputs (", XLOCAL", f);
01856 break;
01857
01858 case EXPORT_LOCAL_INTERNAL:
01859 fputs (", XLOCAL(INTERNAL)", f);
01860 break;
01861
01862 case EXPORT_INTERNAL:
01863 fputs (", XINTERNAL", f);
01864 break;
01865
01866 case EXPORT_HIDDEN:
01867 fputs (", XHIDDEN", f);
01868 break;
01869
01870 case EXPORT_PROTECTED:
01871 fputs (", XPROTECTED", f);
01872 break;
01873
01874 case EXPORT_PREEMPTIBLE:
01875 fputs (", XPREEMPTIBLE", f);
01876 break;
01877
01878 case EXPORT_OPTIONAL:
01879 fputs (", XOPTIONAL", f);
01880 break;
01881
01882 default:
01883 fputs (", Export class unknown", f);
01884 break;
01885 }
01886
01887 fprintf (f, "\n\t\tSclass: %s\n", Sclass_Name (storage_class));
01888 }
01889 }
01890
01891
01892 void
01893 FLD::Print (FILE *f) const
01894 {
01895 fprintf (f, "\t%6lld %-8s\t", ofst, &Str_Table[name_idx]);
01896 Print_TY_IDX_verbose (f, type);
01897 fprintf (f, "\n\t\tfl:0x%04x", flags);
01898 if (flags) {
01899 if (flags & FLD_LAST_FIELD) fprintf (f, " last_field");
01900 if (flags & FLD_EQUIVALENCE) fprintf (f, " equivalence");
01901 if (flags & FLD_BEGIN_UNION) fprintf (f, " begin_union");
01902 if (flags & FLD_END_UNION) fprintf (f, " end_union");
01903 if (flags & FLD_BEGIN_MAP) fprintf (f, " begin_map");
01904 if (flags & FLD_END_MAP) fprintf (f, " end_map");
01905 if (flags & FLD_IS_BIT_FIELD) fprintf (f, " bit_field");
01906 }
01907 if (st != 0)
01908 fprintf (f, " st (%d,%d)", ST_IDX_level (st), ST_IDX_index (st));
01909 if (flags & FLD_IS_BIT_FIELD)
01910 fprintf (f, " bit field size:%d ofst:%d", bsize, bofst);
01911 fputc ('\n', f);
01912 }
01913
01914
01915 void
01916 ARB::Print (FILE *f) const
01917 {
01918 if (flags & ARB_CONST_LBND)
01919 fprintf (f, "%lld:", Lbnd_val ());
01920 else
01921 fprintf (f, "st(%d):", ST_IDX_index (Lbnd_var ()));
01922
01923 if (flags & ARB_CONST_UBND)
01924 fprintf (f, "%lld:", Ubnd_val ());
01925 else
01926 fprintf (f, "st(%d):", ST_IDX_index (Ubnd_var ()));
01927
01928 if (flags & ARB_CONST_STRIDE)
01929 fprintf (f, "%lld:", Stride_val ());
01930 else
01931 fprintf (f, "st(%d):", ST_IDX_index (Stride_var ()));
01932
01933 }
01934
01935
01936 void
01937 TY::Print (FILE *f) const
01938 {
01939 fprintf (f, "%-14s:",
01940 name_idx ? &Str_Table[name_idx] : "(anon)");
01941
01942 fprintf (f, " (f: 0x%04x", flags);
01943 if (flags) {
01944 if (flags & TY_IS_CHARACTER) fprintf (f, " character");
01945 if (flags & TY_IS_LOGICAL) fprintf (f, " logical");
01946 if (flags & TY_IS_UNION) fprintf (f, " union");
01947 if (flags & TY_IS_PACKED) fprintf (f, " packed");
01948 if (flags & TY_PTR_AS_ARRAY) fprintf (f, " ptr_as_array");
01949 if (flags & TY_ANONYMOUS) fprintf (f, " anonymous");
01950 if (flags & TY_SPLIT) fprintf (f, " split");
01951 if (flags & TY_IS_F90_POINTER) fprintf (f, " f90_pointer");
01952 if (flags & TY_NOT_IN_UNION) fprintf (f, " not_in_union");
01953 if (flags & TY_NO_ANSI_ALIAS) fprintf (f, " no_ansi_alias");
01954 if (flags & TY_IS_NON_POD) fprintf (f, " non_pod");
01955 #ifdef KEY
01956 if (flags & TY_RETURN_IN_MEM) fprintf (f, " return_in_mem");
01957 if (flags & TY_CONTENT_SEEN) fprintf (f, " content_seen");
01958 if (flags & TY_IS_INCOMPLETE) fprintf (f, " incomplete");
01959 if (flags & TY_NO_SPLIT) fprintf (f, " no_split");
01960 #endif
01961 #ifdef TARG_NVISA
01962 if (flags & TY_CAN_BE_VECTOR) fprintf (f, " vector");
01963 #endif
01964 }
01965 fprintf (f, ")");
01966
01967 fprintf (f, " size %lld %s: ",
01968 size, (mtype != 0) ? Mtype_Name (mtype) : "");
01969
01970 switch (kind) {
01971 case KIND_SCALAR:
01972 fprintf (f, "SCALAR (%s)", Mtype_Name (mtype));
01973 fputc ('\n', f);
01974 break;
01975
01976 case KIND_ARRAY:
01977 fputs ("ARRAY of ", f);
01978 Print_TY_IDX_verbose (f, Etype ());
01979 if (Arb () != 0) {
01980 ARB_HANDLE arb(Arb());
01981 INT i,ndim;
01982
01983 ndim = ARB_dimension(arb);
01984 for (i = 0; i < ndim; i++) {
01985 fputs (" (", f);
01986 (*arb[i].Entry()).Print (f);
01987 fputc (')', f);
01988
01989 if (ARB_last_dimen(arb[i])) break;
01990 }
01991 }
01992 fputc ('\n', f);
01993 break;
01994
01995 case KIND_STRUCT:
01996 if (TY_is_packed (*this))
01997 fputs ("packed ", f);
01998 fputs (kind == KIND_STRUCT ? "STRUCT\n": "CLASS\n", f);
01999 if (Fld () != 0) {
02000 FLD_ITER iter = Make_fld_iter (FLD_HANDLE (Fld ()));
02001 do {
02002 (*iter).Print (f);
02003 } while (! FLD_last_field (iter++));
02004 } else
02005 fputc ('\n', f);
02006 break;
02007
02008 case KIND_POINTER:
02009 fputs ("-> ", f);
02010 Print_TY_IDX_verbose (f, Pointed ());
02011 fputc ('\n', f);
02012 break;
02013
02014 case KIND_FUNCTION:
02015 fprintf (f, "FUNCTION (f: 0x%04x)\n", Pu_flags());
02016 {
02017 TYLIST_IDX idx = Tylist ();
02018 fprintf (f, "\treturns ");
02019 Print_TY_IDX_verbose (f, Tylist_Table[idx]);
02020 if (Tylist_Table[idx] == 0) {
02021 fputc ('\n', f);
02022 break;
02023 }
02024 ++idx;
02025 while (Tylist_Table[idx] != 0) {
02026 fputs ("\n\tparameter ", f);
02027 Print_TY_IDX_verbose (f, Tylist_Table[idx]);
02028 ++idx;
02029 }
02030 fputc ('\n', f);
02031 }
02032 break;
02033
02034 case KIND_VOID:
02035 fputs ("VOID", f);
02036 fputc ('\n', f);
02037 break;
02038
02039 default:
02040 fprintf (f, "Unknown type (%d)", kind);
02041 fputc ('\n', f);
02042 break;
02043 }
02044 }
02045
02046
02047 void
02048 PU::Print (FILE *f) const
02049 {
02050 Print_TY_IDX_verbose (f, prototype);
02051 #ifdef KEY
02052 fprintf (f, ", flags 0x%016llx,\n"
02053 "\tlexical level %d, LANG 0x%02x, TARGET_INFO %d,\n"
02054 "\tMisc. Info (misc) %d\n",
02055 flags, lexical_level, src_lang, target_idx, (INT32)misc);
02056 #else
02057 fprintf (f, ", flags 0x%016llx,\n"
02058 "\tlexical level %d, LANG 0x%02x, TARGET_INFO %d\n",
02059 flags, lexical_level, src_lang, target_idx);
02060 #endif
02061 }
02062
02063 void
02064 BLK::Print (FILE *f) const
02065 {
02066 fprintf (f, "size %lld, align %d, flags 0x%04x, section %d, scninfo %d\n",
02067 size, align, flags, section_idx, scninfo_idx);
02068 }
02069
02070
02071 void
02072 LABEL::Print (FILE *f) const
02073 {
02074 const char *name_str = name_idx ? &Str_Table[name_idx] : "(anon)";
02075
02076 fprintf (f, "%s: kind = 0x%08x fl = 0x%08x", name_str, kind, flags);
02077 if (flags & LABEL_TARGET_OF_GOTO_OUTER_BLOCK)
02078 fprintf (f, " target_of_goto_outer_block");
02079 if (flags & LABEL_ADDR_SAVED) fprintf (f, " addr_saved");
02080 if (flags & LABEL_ADDR_PASSED) fprintf (f, " addr_passed");
02081 fprintf (f, "\n");
02082 }
02083
02084
02085 void
02086 PREG::Print (FILE *f) const
02087 {
02088 const char *name_str = name_idx ? &Str_Table[name_idx] : "(anon)";
02089
02090 fprintf (f, "%s\n", name_str);
02091 }
02092
02093
02094 void
02095 ST_ATTR::Print (FILE* f) const
02096 {
02097 fprintf (f, "0x%x (%s) --> ", st_idx, ST_name (st_idx));
02098 switch (kind) {
02099 case ST_ATTR_UNKNOWN:
02100 fprintf (f, "(NOT USED)\n");
02101 break;
02102 case ST_ATTR_DEDICATED_REGISTER:
02103 fprintf (f, "(DREG) %d\n", u.reg_id);
02104 break;
02105 case ST_ATTR_SECTION_NAME:
02106 fprintf (f, "(SECTION) %s\n", Index_To_Str (u.section_name));
02107 break;
02108 default:
02109 fprintf (f, "(UNKNOWN) 0x%x\n", u.value);
02110 break;
02111 }
02112 }
02113
02114 void
02115 FILE_INFO::Print (FILE *f) const
02116 {
02117 fprintf (f, "gp_group: %d, flags: 0x%08x", gp_group, flags);
02118 if (flags) {
02119 if (flags & FI_IPA) fputs (" IPA-generated", f);
02120 if (flags & FI_NEEDS_LNO) fputs (" needs_LNO", f);
02121 if (flags & FI_HAS_INLINES) fputs (" has_inlines", f);
02122 if (flags & FI_HAS_MP) fputs (" has_mp", f);
02123 }
02124
02125 fputs ("\n", f);
02126
02127 }
02128
02129
02130
02131 #if 1 // Fix 10-26-2002: Enhancement to reset addr_saved flag before Mainopt
02132 struct clear_addr_flag_op
02133 {
02134 clear_addr_flag_op() {};
02135
02136 void operator () (UINT idx, ST *entry) const {
02137 if( (ST_sclass(*entry) == SCLASS_AUTO) && ST_addr_saved(*entry))
02138 Clear_ST_addr_saved(*entry);
02139 } ;
02140 };
02141
02142 void
02143 Clear_local_symtab_addr_flags(const SCOPE& scope)
02144 {
02145 For_all_entries (*scope.st_tab, clear_addr_flag_op(), 1);
02146 }
02147 #endif
02148
02149
02150 template <class T>
02151 struct print_op
02152 {
02153 FILE *fid;
02154
02155 print_op (FILE *f) : fid (f) {}
02156
02157 void operator () (UINT idx, T *entry) const;
02158 };
02159
02160
02161 template <class T>
02162 inline void
02163 print_op<T>::operator () (UINT idx, T *entry) const {
02164 fprintf (fid, "[%d]: ", idx);
02165 entry->Print (fid);
02166 }
02167
02168
02169
02170 template<>
02171 inline void
02172 print_op<TCON>::operator () (UINT idx, TCON *c) const
02173 {
02174 fprintf (fid, "[%d] %s: %s\n", idx, MTYPE_name(TCON_ty(*c)),Targ_Print (NULL, *c));
02175 }
02176
02177
02178
02179 void
02180 Print_local_symtab (FILE *f, const SCOPE& scope)
02181 {
02182
02183
02184 fprintf (f, "\n%sSYMTAB for %s: level %d, st %d, label %d, preg %d,"
02185 " inito %d, st_attr %d\n%s\n", DBar, ST_name (scope.st),
02186 PU_lexical_level (scope.st), scope.st_tab->Size () - 1,
02187 scope.label_tab->Size () - 1, scope.preg_tab->Size () - 1,
02188 scope.inito_tab->Size () - 1, scope.st_attr_tab->Size () - 1, DBar);
02189
02190 fputs ("Symbols:\n", f);
02191 For_all_entries (*scope.st_tab, print_op<ST> (f), 1);
02192
02193 fprintf (f, "%sLabels:\n", DBar);
02194 For_all_entries (*scope.label_tab, print_op<LABEL> (f), 1);
02195
02196 fprintf (f, "%sPseudo-registers:\n", DBar);
02197 For_all_entries (*scope.preg_tab, print_op<PREG> (f), 1);
02198
02199 fprintf (f, "%sINITOs:\n", DBar);
02200 For_all_entries (*scope.inito_tab, print_op<INITO> (f), 1);
02201
02202 fprintf (f, "%sST_ATTRs:\n", DBar);
02203 For_all_entries (*scope.st_attr_tab, print_op<ST_ATTR> (f), 1);
02204
02205 fprintf (f, "%s\n", DBar);
02206
02207 }
02208
02209
02210 void
02211 Print_global_symtab (FILE *f)
02212 {
02213 fprintf(f,"%sGLOBAL SYMTAB:\n", DBar);
02214
02215 fprintf (f, "%sFile Info:\n", DBar);
02216 File_info.Print (f);
02217
02218 fprintf (f, "%sSymbols:\n", DBar);
02219 For_all (St_Table, GLOBAL_SYMTAB, print_op<ST> (f));
02220
02221 fprintf (f, "%sPUs:\n", DBar);
02222 For_all (Pu_Table, print_op<PU> (f));
02223
02224 fprintf (f, "%sTypes:\n", DBar);
02225 For_all (Ty_Table, print_op<TY> (f));
02226
02227 fprintf (f, "%sBlocks:\n", DBar);
02228 For_all (Blk_Table, print_op<BLK> (f));
02229
02230 fprintf (f, "%sTcons:\n", DBar);
02231 For_all (Tcon_Table, print_op<TCON> (f));
02232
02233 fprintf (f, "%sINITOs:\n", DBar);
02234 For_all (Inito_Table, GLOBAL_SYMTAB, print_op<INITO> (f));
02235
02236 fprintf (f, "%sST_ATTRs:\n", DBar);
02237 For_all (St_Attr_Table, GLOBAL_SYMTAB, print_op<ST_ATTR> (f));
02238
02239 fprintf (f, "%sString table size = %lld\n", DBar, STR_Table_Size());
02240 fprintf (f, "%s\n", DBar);
02241 }
02242
02243
02244
02245 void
02246 dump_st (ST *st)
02247 {
02248 st->Print(stdout);
02249 switch (st->sym_class) {
02250 case CLASS_BLOCK:
02251 Blk_Table[st->u2.blk].Print (stdout);
02252 break;
02253 case CLASS_FUNC:
02254 Pu_Table[st->u2.pu].Print (stdout);
02255 break;
02256 }
02257 }
02258
02259 void
02260 dump_st(ST_IDX st_idx)
02261 {
02262 ST *st = &St_Table[st_idx];
02263 dump_st(st);
02264 }
02265
02266
02267 void
02268 dump_st_idx (ST_IDX st)
02269 {
02270 dump_st(st);
02271 }
02272
02273
02274 void
02275 dump_ty (TY_IDX ty_idx)
02276 {
02277 TY& ty = Ty_Table[ty_idx];
02278 ty.Print(stdout);
02279 }
02280
02281
02282 void
02283 dump_ty_idx (TY_IDX ty_idx)
02284 {
02285 dump_ty (ty_idx);
02286 }
02287
02288 void
02289 dump_ty(const TY &ty)
02290 {
02291 ty.Print(stdout);
02292 }
02293
02294 void
02295 dump_label (LABEL_IDX idx)
02296 {
02297 Label_Table[idx].Print(stdout);
02298 }
02299
02300 void
02301 dump_inito(INITO_IDX idx)
02302 {
02303 Inito_Table[idx].Print(stdout);
02304 }
02305
02306 void
02307 dump_st_attr (ST_ATTR_IDX idx)
02308 {
02309 St_Attr_Table[idx].Print(stdout);
02310 }
02311
02312 #ifndef KEY
02313 static
02314 #endif // !KEY
02315 ST *
02316 Gen_Temp_Named_Symbol (TY_IDX ty, const char *rootname,
02317 ST_CLASS sym_class, ST_SCLASS storage_class)
02318 {
02319 static INT Temp_Index = 0;
02320 ST *st = New_ST(CURRENT_SYMTAB);
02321 STR_IDX str_idx = Save_Str2i(
02322
02323 (Temp_Symbol_Prefix),
02324 rootname, Temp_Index++);
02325 ST_Init(st, str_idx, sym_class, storage_class, EXPORT_LOCAL, ty);
02326 return st;
02327 }
02328
02329
02330 ST *
02331 Gen_Temp_Symbol (TY_IDX ty,
02332 const char *rootname)
02333 {
02334 ST *st = Gen_Temp_Named_Symbol(ty, rootname, CLASS_VAR, SCLASS_AUTO);
02335 Set_ST_is_temp_var(st);
02336 return st;
02337 }
02338
02339
02340
02341 ST *
02342 Gen_Read_Only_Symbol(TY_IDX ty, const char *rootname)
02343 {
02344 ST *st = Gen_Temp_Named_Symbol(ty, rootname, CLASS_VAR, SCLASS_FSTATIC);
02345 Set_ST_is_const_var(st);
02346 return st;
02347 }
02348
02349
02350
02351
02352 TY_IDX
02353 Promoted_Parm_Type(const ST *formal_parm)
02354 {
02355 TY_IDX ptype = ST_type(formal_parm);
02356 TY_IDX newtype;
02357 BOOL parm_float;
02358
02359 if ( ! ST_promote_parm(formal_parm) ) return ptype;
02360
02361
02362 ptype = ST_type(formal_parm);
02363 parm_float = ST_is_value_parm(formal_parm) &&
02364 (TY_kind(ptype) == KIND_SCALAR) &&
02365 (MTYPE_float(TY_mtype(ptype)));
02366 if ( parm_float ) {
02367
02368 newtype = MTYPE_To_TY(MTYPE_F8);
02369 } else {
02370
02371 newtype = MTYPE_To_TY(Integer_type);
02372 }
02373
02374
02375 Is_True(TY_size(newtype) >= TY_size(ptype),
02376 ("Nonsensical demotion of parameter type"));
02377 return newtype;
02378 }
02379
02380
02381
02382
02383
02384
02385 ST *MTYPE_TO_PREG_array[MTYPE_LAST+1];
02386
02387 ST *Int_Preg, *Float_Preg, *Return_Val_Preg;
02388
02389 ST *Branch_Preg;
02390 #ifdef TARG_X8664
02391 ST* X87_Preg = NULL;
02392 #endif
02393
02394 TY_IDX MTYPE_TO_TY_array[MTYPE_LAST+1];
02395
02396 TY_IDX Quad_Type, Void_Type, FE_int_Type, FE_double_Type;
02397 TY_IDX Spill_Int_Type, Spill_Float_Type;
02398 #ifdef KEY
02399 TY_IDX Spill_Int32_Type;
02400 TY_IDX Spill_Float32_Type;
02401 #endif
02402
02403 #if defined(FRONT_END) && !defined(FRONT_END_MFEF77)
02404 extern "C" TYPE_ID FE_int_To_Mtype (void);
02405 #endif
02406
02407 static INT Max_scope = 8;
02408
02409
02410 void
02411 New_Scope (SYMTAB_IDX level, MEM_POOL *pool, BOOL reserve_index_zero)
02412 {
02413 if (level >= Max_scope) {
02414 UINT size = Max_scope * sizeof(SCOPE);
02415 Max_scope *= 2;
02416 Scope_tab = (SCOPE *) MEM_POOL_Realloc (Malloc_Mem_Pool, Scope_tab,
02417 size, size * 2);
02418 }
02419
02420 Current_scope = level;
02421
02422 ST_TAB *st_tab = CXX_NEW (ST_TAB (pool), pool);
02423 INITO_TAB *inito_tab = CXX_NEW (INITO_TAB (pool), pool);
02424 ST_ATTR_TAB *st_attr_tab = CXX_NEW (ST_ATTR_TAB (pool), pool);
02425 LABEL_TAB *label_tab = NULL;
02426 PREG_TAB *preg_tab = NULL;
02427
02428 UINT32 dummy_idx;
02429 if (reserve_index_zero) {
02430 st_tab->New_entry ((ST_IDX&) dummy_idx);
02431 inito_tab->New_entry ((INITO_IDX&) dummy_idx);
02432 st_attr_tab->New_entry ((ST_ATTR_IDX&) dummy_idx);
02433 }
02434
02435 if (level > GLOBAL_SYMTAB) {
02436 label_tab = CXX_NEW (LABEL_TAB (pool), pool);
02437 preg_tab = CXX_NEW (PREG_TAB (pool), pool);
02438
02439 if (reserve_index_zero) {
02440 label_tab->New_entry ((LABEL_IDX&) dummy_idx);
02441 preg_tab->New_entry ((PREG_IDX&) dummy_idx);
02442 }
02443
02444 }
02445
02446
02447
02448 Scope_tab[level].Init (st_tab, label_tab, preg_tab, inito_tab,
02449 st_attr_tab, pool);
02450
02451 }
02452
02453
02454 void
02455 Delete_Scope (SYMTAB_IDX level)
02456 {
02457 SCOPE& scope = Scope_tab[level];
02458
02459 CXX_DELETE (scope.st_tab, scope.pool);
02460 CXX_DELETE (scope.label_tab, scope.pool);
02461 CXX_DELETE (scope.preg_tab, scope.pool);
02462 CXX_DELETE (scope.inito_tab, scope.pool);
02463 CXX_DELETE (scope.st_attr_tab, scope.pool);
02464
02465 }
02466
02467
02468 static void
02469 Setup_Preg_Pointers ()
02470 {
02471 for (TYPE_ID i = MTYPE_FIRST; i <= MTYPE_LAST; ++i) {
02472 if (MTYPE_To_PREG (i) != NULL || MTYPE_To_TY (i) == 0)
02473 continue;
02474 Is_True (MTYPE_byte_size (i) < 4, ("Invalid mtype"));
02475 MTYPE_To_PREG (i) = MTYPE_signed (i) ? MTYPE_To_PREG (MTYPE_I4) :
02476 MTYPE_To_PREG (MTYPE_U4);
02477 }
02478
02479 if (ST_type(Int64_Preg) == Spill_Int_Type)
02480 Int_Preg = Int64_Preg;
02481 else
02482 Int_Preg = Int32_Preg;
02483 if (ST_type(Float32_Preg) == Spill_Float_Type)
02484 Float_Preg = Float32_Preg;
02485 else
02486 Float_Preg = Float64_Preg;
02487
02488
02489 Branch_Preg = MTYPE_To_PREG(MTYPE_A8);
02490
02491 #ifdef TARG_X8664
02492 X87_Preg = MTYPE_To_PREG( MTYPE_FQ );
02493 #endif
02494 }
02495
02496
02497 static void
02498 Create_All_Preg_Symbols ()
02499 {
02500 for (TYPE_ID i = MTYPE_FIRST; i <= MTYPE_LAST; ++i) {
02501 if (MTYPE_To_TY (i) == 0)
02502 continue;
02503 if (MTYPE_To_PREG (i) != NULL)
02504 continue;
02505 if (MTYPE_byte_size(i) < 4) {
02506 #ifdef TARG_X8664
02507
02508
02509
02510 if ( i != MTYPE_B && !MTYPE_is_integral(i) ) continue;
02511 #else
02512
02513 if (i != MTYPE_B) continue;
02514 #endif
02515 }
02516
02517 ST *st = New_ST (GLOBAL_SYMTAB);
02518 ST_Init (st, Save_Str2 (".preg_", MTYPE_name(i)),
02519 CLASS_PREG, SCLASS_REG, EXPORT_LOCAL, MTYPE_To_TY (i));
02520 MTYPE_To_PREG(i) = st;
02521 }
02522
02523 if (Return_Val_Preg == NULL) {
02524
02525 ST *st = New_ST (GLOBAL_SYMTAB);
02526 ST_Init (st, Save_Str (".preg_return_val"),
02527 CLASS_PREG, SCLASS_REG, EXPORT_LOCAL, 0);
02528 Return_Val_Preg = st;
02529 }
02530
02531 Setup_Preg_Pointers ();
02532 }
02533
02534
02535
02536
02537
02538 static void
02539 Set_up_all_preg_symbols ()
02540 {
02541 UINT32 idx = 1;
02542
02543 UINT32 last = MIN (MTYPE_LAST + 1, ST_Table_Size (GLOBAL_SYMTAB));
02544
02545 for (INT i = MTYPE_FIRST; i < last; ++i) {
02546 ST_IDX st_idx = make_ST_IDX (idx++, GLOBAL_SYMTAB);
02547 ST& st = St_Table[st_idx];
02548 if (ST_sym_class (st) != CLASS_PREG)
02549 break;
02550
02551
02552 if (Return_Val_Preg == NULL) {
02553 if (strcmp (ST_name (&st), ".preg_return_val") == 0) {
02554 Return_Val_Preg = &st;
02555 continue;
02556 }
02557 }
02558
02559 TY_IDX ty_idx = ST_type (st);
02560 const TY& ty = Ty_Table[ty_idx];
02561 TYPE_ID mtype = TY_mtype (ty);
02562 if (ty_idx != MTYPE_To_TY (mtype))
02563 continue;
02564 MTYPE_To_PREG (mtype) = &st;
02565 }
02566
02567
02568 Create_All_Preg_Symbols ();
02569
02570 }
02571
02572
02573
02574
02575
02576
02577
02578
02579
02580 static inline STR_IDX
02581 Gen_predef_type_name (const char *basename)
02582 {
02583 return Save_Str2 (".predef_", basename);
02584 }
02585
02586
02587
02588
02589
02590
02591
02592
02593
02594
02595
02596
02597
02598
02599
02600 static void
02601 Create_Special_Global_Symbols ()
02602 {
02603 TY_IDX ty_idx;
02604 TY_KIND ty_kind = KIND_SCALAR;
02605
02606
02607 for (TYPE_ID i = MTYPE_FIRST; i <= MTYPE_LAST; ++i) {
02608
02609 if (MTYPE_To_TY (i) != 0)
02610 continue;
02611
02612 TY &ty = New_TY (ty_idx);
02613
02614 ty_kind = KIND_SCALAR;
02615 if (MTYPE_align_req (i))
02616 Set_TY_align (ty_idx, MTYPE_align_req(i));
02617
02618
02619 if ( i == Spill_Int_Mtype ) {
02620 Spill_Int_Type = ty_idx;
02621 } else if ( i == Spill_Float_Mtype ) {
02622 Spill_Float_Type = ty_idx;
02623 }
02624 if ( i == MTYPE_FQ )
02625 Quad_Type = ty_idx;
02626
02627 #if defined(FRONT_END_C) || defined(FRONT_END_CPLUSPLUS)
02628 #ifndef FRONT_END_MFEF77
02629 if ( i == FE_int_To_Mtype() )
02630 FE_int_Type = ty_idx;
02631 #endif
02632 if ( i == MTYPE_F8 )
02633 FE_double_Type = ty_idx;
02634 #endif
02635 if ( i == MTYPE_V ) {
02636 Void_Type = ty_idx;
02637 ty_kind = KIND_VOID;
02638 }
02639
02640 if (i == MTYPE_A4 || i == MTYPE_A8) {
02641 if (MTYPE_byte_size (i) != Pointer_Size) {
02642 Ty_tab.Delete_last ();
02643 MTYPE_To_TY (i) = 0;
02644 continue;
02645 }
02646
02647 ty_kind = KIND_POINTER;
02648 TY_Init (ty, MTYPE_byte_size (i), ty_kind, i,
02649 Gen_predef_type_name (MTYPE_name (i)));
02650 Is_True (i > MTYPE_V,
02651 ("Create_Special_Global_Symbols() assumes MTYPE_V < "
02652 "MTYPE_A4 and MTYPE_A8"));
02653 Set_TY_pointed (ty, MTYPE_To_TY (MTYPE_V));
02654 MTYPE_To_TY (i) = ty_idx;
02655 continue;
02656 }
02657
02658 TY_Init (ty, MTYPE_byte_size (i), ty_kind, i,
02659 Gen_predef_type_name (MTYPE_name (i)));
02660 MTYPE_To_TY (i) = ty_idx;
02661 }
02662
02663 }
02664
02665
02666 static inline BOOL
02667 Predefined_Void_Type (TY_IDX ty_idx)
02668 {
02669 const TY& ty = Ty_Table[ty_idx];
02670 return (ty_idx == make_TY_IDX (TY_IDX_index (ty_idx)) &&
02671 TY_mtype (ty) == MTYPE_V && TY_kind (ty) == KIND_VOID);
02672
02673 }
02674
02675
02676
02677
02678
02679
02680 void
02681 Initialize_Special_Global_Symbols ()
02682 {
02683
02684
02685 UINT32 last = MIN (MTYPE_LAST + 1, TY_Table_Size());
02686
02687
02688 for (UINT32 i = MTYPE_FIRST; i < last; ++i) {
02689 TY_IDX ty_idx = make_TY_IDX (i);
02690 const TY& ty = Ty_Table[ty_idx];
02691
02692 TYPE_ID mtype = TY_mtype (ty);
02693 if (MTYPE_byte_size (mtype) != TY_size (ty) ||
02694 TY_flags (ty) != 0)
02695 continue;
02696 switch (mtype) {
02697 case MTYPE_V:
02698 if (TY_kind (ty) != KIND_VOID)
02699 continue;
02700 break;
02701
02702 case MTYPE_A4:
02703 case MTYPE_A8:
02704 if (TY_kind (ty) != KIND_POINTER ||
02705 ! Predefined_Void_Type (TY_pointed (ty)))
02706 continue;
02707 break;
02708
02709 default:
02710 if (TY_kind (ty) != KIND_SCALAR)
02711 continue;
02712 break;
02713 }
02714 if (MTYPE_align_req (mtype))
02715 Set_TY_align (ty_idx, MTYPE_align_req (mtype));
02716 MTYPE_To_TY (mtype) = ty_idx;
02717 }
02718
02719
02720 Create_Special_Global_Symbols ();
02721
02722 Spill_Int_Type = MTYPE_To_TY (Spill_Int_Mtype);
02723 Spill_Float_Type = MTYPE_To_TY (Spill_Float_Mtype);
02724 #ifdef KEY
02725
02726
02727
02728 Quad_Type = MTYPE_To_TY (MTYPE_F16);
02729 #else
02730 Quad_Type = MTYPE_To_TY (MTYPE_FQ);
02731 #endif // KEY
02732 Void_Type = MTYPE_To_TY (MTYPE_V);
02733
02734 #if defined(TARG_X8664) || defined(TARG_MIPS)
02735 Spill_Int32_Type = MTYPE_To_TY (Spill_Int32_Mtype);
02736 Spill_Float32_Type = MTYPE_To_TY (Spill_Float32_Mtype);
02737 #endif
02738
02739 Set_up_all_preg_symbols ();
02740
02741 }
02742
02743
02744
02745
02746
02747 void
02748 Initialize_Symbol_Tables (BOOL reserve_index_zero)
02749 {
02750 if (Scope_tab != NULL)
02751 return;
02752
02753 Scope_tab = (SCOPE *) MEM_POOL_Alloc (Malloc_Mem_Pool,
02754 Max_scope * sizeof(SCOPE));
02755 BZERO(Scope_tab, Max_scope * sizeof(SCOPE));
02756
02757 BZERO (MTYPE_TO_PREG_array, sizeof(ST*) * (MTYPE_LAST + 1));
02758 BZERO (MTYPE_TO_TY_array, sizeof(TY_IDX) * (MTYPE_LAST + 1));
02759
02760 if (reserve_index_zero) {
02761
02762
02763 Initialize_Strtab (0x1000);
02764
02765 UINT dummy_idx;
02766 BZERO (&New_PU ((PU_IDX&) dummy_idx), sizeof(PU));
02767 BZERO (&New_TY ((TY_IDX&) dummy_idx), sizeof(TY));
02768 BZERO (New_FLD ().Entry(), sizeof(FLD));
02769 BZERO (&New_TYLIST ((TYLIST_IDX&) dummy_idx), sizeof(TYLIST));
02770 BZERO (New_ARB ().Entry(), sizeof(ARB));
02771 BZERO (&New_BLK ((BLK_IDX&) dummy_idx), sizeof(BLK));
02772 BZERO (&Initv_Table.New_entry ((INITV_IDX&) dummy_idx), sizeof(INITV));
02773 Init_Constab ();
02774 New_Scope (GLOBAL_SYMTAB, Malloc_Mem_Pool, TRUE);
02775 Create_Special_Global_Symbols ();
02776 Create_All_Preg_Symbols();
02777 }
02778 #ifdef BACK_END
02779 if (!Read_Global_Data) {
02780
02781 UINT blk_idx;
02782 BZERO (&New_BLK ((BLK_IDX&) blk_idx), sizeof(BLK));
02783 }
02784 #endif
02785 }
02786
02787
02788
02789
02790 TCON_IDX
02791 Enter_tcon (const TCON& tcon)
02792 {
02793 switch (TCON_ty (tcon)) {
02794 case MTYPE_F4:
02795 if (TCON_ival (tcon) == 0)
02796 return 1;
02797 case MTYPE_F8:
02798 if (TCON_k0 (tcon) == 0)
02799 return 2;
02800 default:
02801 return Tcon_Table.Insert (tcon);
02802 }
02803 }
02804
02805
02806 inline void
02807 Init_Constab ()
02808 {
02809 if (Tcon_Table.Size () == 0) {
02810 TCON Zero;
02811 UINT32 idx;
02812 BZERO (&Zero, sizeof(TCON));
02813 idx = Tcon_Table.Insert (Zero);
02814 Set_TCON_ty (Zero, MTYPE_F4);
02815 idx = Tcon_Table.Insert (Zero);
02816 Set_TCON_ty (Zero, MTYPE_F8);
02817 idx = Tcon_Table.Insert (Zero);
02818
02819 Is_True (idx == MAX_PREDEFINED_TCON_IDX,
02820 ("Number of predefined tcons incorrect"));
02821
02822 Initialize_TCON_strtab (1024);
02823 }
02824 }
02825
02826
02827
02828
02829
02830
02831
02832
02833 BOOL
02834
02835 ST::operator==( ST &st ) const
02836
02837 {
02838
02839 if (st.u1.name_idx == u1.name_idx &&
02840
02841 st.flags == flags &&
02842
02843 st.flags_ext == flags_ext &&
02844
02845 st.sym_class == sym_class &&
02846
02847 st.storage_class == storage_class &&
02848
02849 st.export_class == export_class &&
02850
02851 st.u2.type == u2.type &&
02852
02853 st.offset == offset &&
02854
02855 st.base_idx == base_idx &&
02856
02857 st.st_idx == st_idx)
02858
02859 return TRUE;
02860
02861
02862 return FALSE;
02863
02864 }
02865
02866
02867 #ifdef Is_True_On
02868
02869
02870
02871
02872
02873
02874 ST ST_from_IDX(ST_IDX x) {return St_Table[x];}
02875 TY TY_from_IDX(TY_IDX x) {return Ty_Table[x];}
02876 INITO INITO_from_IDX(INITO_IDX x) {return Inito_Table[x];}
02877 INITV INITV_from_IDX(INITV_IDX x) {return Initv_Table[x];}
02878 PU PU_from_IDX(PU_IDX x) {return Pu_Table[x];}
02879 ARB ARB_from_IDX(ARB_IDX x) {return Arb_Table[x];}
02880 TCON TCON_from_IDX(TCON_IDX x) {return Tcon_Table[x];}
02881 FLD FLD_from_IDX(FLD_IDX x) {return Fld_Table[x];}
02882 LABEL LABEL_from_IDX(LABEL_IDX x) {return Label_Table[x];}
02883 TYLIST TYLIST_from_IDX(TYLIST_IDX x) {return Tylist_Table[x];}
02884
02885 #endif // Is_True_On