Open64 (mfef90, whirl2f, and IR tools)
TAG: version-openad; SVN changeset: 916
|
00001 /* 00002 00003 Copyright (C) 2000, 2001 Silicon Graphics, Inc. All Rights Reserved. 00004 00005 This program is free software; you can redistribute it and/or modify it 00006 under the terms of version 2 of the GNU General Public License as 00007 published by the Free Software Foundation. 00008 00009 This program is distributed in the hope that it would be useful, but 00010 WITHOUT ANY WARRANTY; without even the implied warranty of 00011 MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. 00012 00013 Further, this software is distributed without any warranty that it is 00014 free of the rightful claim of any third person regarding infringement 00015 or the like. Any license provided herein, whether implied or 00016 otherwise, applies only to this software file. Patent licenses, if 00017 any, provided herein do not apply to combinations of this program with 00018 other software, or any other product whatsoever. 00019 00020 You should have received a copy of the GNU General Public License along 00021 with this program; if not, write the Free Software Foundation, Inc., 59 00022 Temple Place - Suite 330, Boston MA 02111-1307, USA. 00023 00024 Contact information: Silicon Graphics, Inc., 1600 Amphitheatre Pky, 00025 Mountain View, CA 94043, or: 00026 00027 http://www.sgi.com 00028 00029 For further information regarding this notice, see: 00030 00031 http://oss.sgi.com/projects/GenInfo/NoticeExplan 00032 00033 */ 00034 00035 00036 00037 #ifdef USE_PCH 00038 #include "common_com_pch.h" 00039 #endif /* USE_PCH */ 00040 #pragma hdrstop 00041 #include <stdio.h> 00042 #include <alloca.h> 00043 00044 #include <algorithm> 00045 #include <string> 00046 #include <map> 00047 #include "HashTable.h" 00048 using namespace stlCompatibility; 00049 00050 #include "defs.h" 00051 #include "config.h" 00052 #include "tracing.h" // for DBar 00053 #include "cxx_memory.h" // for CXX_NEW 00054 00055 #include "symtab.h" 00056 #include "irbdata.h" // for INITO_st_idx 00057 #include "ir_a2b_util.h" // for b2a and a2b utilities 00058 #include "const.h" // for MAX_SYMBOLIC_CONST_NAME_LEN 00059 #include "ttype.h" 00060 #include "targ_sim.h" 00061 #include "upc_symtab_utils.h" 00062 00063 // global tables 00064 FILE_INFO File_info; 00065 SCOPE *Scope_tab; 00066 PU_TAB Pu_Table; 00067 SYMBOL_TABLE St_Table; 00068 TY_TAB Ty_tab; 00069 TYPE_TABLE Ty_Table; 00070 FLD_TAB Fld_Table; 00071 TYLIST_TAB Tylist_Table; 00072 ARB_TAB Arb_Table; 00073 TCON_TAB Tcon_Table; 00074 INITV_TAB Initv_Table; 00075 INITO_TABLE Inito_Table; 00076 PREG_TABLE Preg_Table; 00077 LABEL_TABLE Label_Table; 00078 BLK_TAB Blk_Table; 00079 ST_ATTR_TABLE St_Attr_Table; 00080 00081 SYMTAB_IDX Current_scope; // index to current scope 00082 PU *Current_pu; // ptr to current PU 00083 00084 //---------------------------------------------------------------------- 00085 // ST-related utilities 00086 //---------------------------------------------------------------------- 00087 00088 INT64 00089 ST_size (const ST *st) 00090 { 00091 switch (ST_class(st)) { 00092 case CLASS_BLOCK: 00093 return STB_size(st); 00094 case CLASS_VAR: 00095 case CLASS_PREG: 00096 case CLASS_PARAMETER: 00097 return TY_size(ST_type(st)); 00098 case CLASS_CONST: 00099 if (TCON_ty(STC_val(st)) == MTYPE_STR) 00100 return Targ_String_Length (STC_val(st)) 00101 + (TCON_add_null(STC_val(st)) ? 1 : 0); 00102 else 00103 return TY_size(ST_type(st)); 00104 case CLASS_FUNC: 00105 return 0; 00106 } 00107 FmtAssert(FALSE, ("ST_size: unexpected CLASS")); 00108 /* NOTREACHED */ 00109 return 0; 00110 } 00111 00112 // make a copy of a ST in the SAME ST table 00113 ST * 00114 Copy_ST (ST *st) 00115 { 00116 if (ST_sym_class (st) == CLASS_PREG) 00117 return st; 00118 00119 SYMTAB_IDX level = ST_IDX_level (ST_st_idx (st)); 00120 00121 ST_TAB *st_tab = Scope_tab[level].st_tab; 00122 ST_IDX st_idx = make_ST_IDX (st_tab->Insert (*st), level); 00123 ST& copy = St_Table[st_idx]; 00124 Set_ST_st_idx (copy, st_idx); 00125 if (ST_base_idx (st) == ST_st_idx (st)) 00126 Set_ST_base_idx (copy, st_idx); 00127 return © 00128 } // Copy_ST 00129 00130 00131 ST * 00132 Copy_ST (ST *st, SYMTAB_IDX scope) 00133 { 00134 if (scope == ST_level (st)) 00135 return Copy_ST (st); 00136 00137 ST_TAB *st_tab = Scope_tab[scope].st_tab; 00138 ST_IDX st_idx = make_ST_IDX (st_tab->Insert (*st), scope); 00139 ST& copy = St_Table[st_idx]; 00140 Set_ST_st_idx (copy, st_idx); 00141 if (ST_base_idx (st) == ST_st_idx (st)) 00142 Set_ST_base_idx (copy, st_idx); 00143 else if (scope != ST_IDX_level (ST_base_idx (st))) { 00144 ST *base_st = Copy_ST (&St_Table[ST_base_idx (st)], scope); 00145 Set_ST_base_idx (copy, ST_st_idx (base_st)); 00146 } 00147 return © 00148 } // Copy_ST 00149 00150 ST * 00151 Copy_ST_No_Base (ST *st, SYMTAB_IDX scope) 00152 { 00153 static INT Temp_Index = 0; 00154 STR_IDX new_name; 00155 if (scope == GLOBAL_SYMTAB) 00156 new_name = Save_Str2i(ST_name(st),"..", Temp_Index++); 00157 else 00158 new_name = ST_name_idx(st); 00159 00160 if (scope == ST_level (st)) { 00161 ST* new_st = Copy_ST (st); 00162 Set_ST_name_idx (*new_st, new_name); 00163 return new_st; 00164 } 00165 00166 ST_TAB *st_tab = Scope_tab[scope].st_tab; 00167 ST_IDX st_idx = make_ST_IDX (st_tab->Insert (*st), scope); 00168 ST& copy = St_Table[st_idx]; 00169 Set_ST_st_idx (copy, st_idx); 00170 Set_ST_name_idx (copy, new_name); 00171 if (ST_base_idx (st) == ST_st_idx (st)) { 00172 Set_ST_base_idx (copy, st_idx); 00173 } 00174 return © 00175 } // Copy_ST 00176 00177 00178 // Return TRUE if the ST is a constant literal or a const variable. 00179 BOOL 00180 ST_is_constant (const ST *st) 00181 { 00182 switch (ST_sym_class(st)) { 00183 case CLASS_CONST: 00184 return TRUE; 00185 case CLASS_VAR: 00186 return ST_is_const_var(st); 00187 default: 00188 return FALSE; 00189 } 00190 } 00191 00192 // ==================================================================== 00193 // Returns FALSE if the current PU is recursive or the ST is not in 00194 // the local symtab. May return TRUE otherwise; the more we return 00195 // TRUE, the better we optimize. 00196 // ==================================================================== 00197 00198 extern BOOL 00199 ST_is_private_local(const ST *st) 00200 { 00201 Is_True((PU_src_lang(Get_Current_PU()) & 00202 (PU_src_lang(Get_Current_PU()) - 1)) == 0, 00203 ("ST_is_private_local: Mixed-language inlining not " 00204 "allowed; need to know original PU language")); 00205 00206 if (ST_IDX_level(ST_st_idx(st)) != CURRENT_SYMTAB) 00207 return FALSE; 00208 00209 // Fix 643997: for F90, -LANG:recursive=on force the compiler 00210 // to assume every procedure is recursive. 00211 // 00212 // If -LANG:recursive=[on|off] is set by user 00213 // it overrides the language default. 00214 if (LANG_Recursive_Set) 00215 return !LANG_Recursive; 00216 00217 // TODO: should examine PU_recursive flag for all languages. 00218 // 00219 switch (PU_src_lang(Get_Current_PU())) { 00220 case PU_F77_LANG: 00221 // F77 default is to assume procedure are not recursive. 00222 return TRUE; 00223 00224 case PU_F90_LANG: 00225 // The default is to rely on the PU_recursive flag set by frontend. 00226 return (!PU_recursive(Get_Current_PU())); 00227 } 00228 return FALSE; 00229 } 00230 00231 //---------------------------------------------------------------------- 00232 // TY-related utilities 00233 //---------------------------------------------------------------------- 00234 00235 00236 TY_IDX 00237 Copy_TY (TY_IDX ty) 00238 { 00239 00240 TY_IDX copy = ty; 00241 Set_TY_IDX_index (copy, Ty_tab.Insert (Ty_Table[ty])); 00242 return copy; 00243 } 00244 00245 00246 // assume align is a power of 2. 00247 UINT 00248 TY_log_base2 (UINT align) 00249 { 00250 UINT result = 0; 00251 00252 Is_True (align, ("Invalid alignment for TY")); 00253 00254 while ((align & 0x7) == 0 && align!=0) {//fzhao May 00255 result += 3; 00256 align >>= 3; 00257 } 00258 00259 return result + (align >> 1); 00260 } // TY_log_base2 00261 00262 00263 /* ==================================================================== 00264 * 00265 * FLD_get_to_field 00266 * 00267 * Given the TY of a struct, get to the field corresponding to field_id. 00268 * cur_field_id gives the field_id of the struct itself. If the field is 00269 * found, cur_field_id is set equal to field_id. Otherwise, Is_Null() is 00270 * true for the field handle returned, and cur_field_id is set to 00271 * correspond to the last field of this struct. 00272 * 00273 * ==================================================================== */ 00274 FLD_HANDLE 00275 FLD_get_to_field (TY_IDX struct_ty_idx, UINT field_id, UINT &cur_field_id) 00276 { 00277 FLD_ITER fld_iter = Make_fld_iter(TY_fld(struct_ty_idx)); 00278 do { 00279 FLD_HANDLE fld(fld_iter); 00280 cur_field_id++; 00281 if (cur_field_id == field_id) 00282 return fld; 00283 //WEI: if the field is a {p}shared_ptr_t, make sure we don't try to traverse its fields 00284 if (TY_kind(FLD_type(fld)) == KIND_STRUCT && !is_upcr_ptr(FLD_type(fld)) && 00285 TY_fld(FLD_type(fld)) != FLD_HANDLE()) { 00286 fld = FLD_get_to_field(FLD_type(fld), field_id, cur_field_id); 00287 if (cur_field_id == field_id) 00288 return fld; 00289 } 00290 } while (!FLD_last_field(fld_iter++)); 00291 return FLD_HANDLE(); 00292 } // FLD_get_to_field 00293 00294 00295 // reverse map for getting the pointer TY given the pointee 00296 00297 00298 // Utility functions for mapping a TY to the one that points to it. 00299 // A hash_map is used because the number of pointer types should be small 00300 // compared to all TYs. 00301 00302 // we uniquely identify a pointee by it's TY_IDX and the TY_flags of the 00303 // pointer 00304 typedef std::pair<TY_IDX, UINT32> TY_POINTEE_KEY; 00305 00306 00307 // Solaris CC workaround 00308 // hash_pointee_key contains the hash function for hash_map, we should 00309 // no longer use it after replacing hash_map with map 00310 // 00311 struct hash_pointee_key 00312 { 00313 UINT32 operator() (TY_POINTEE_KEY key) const { 00314 return (key.first | key.second); 00315 } 00316 }; 00317 00318 typedef HashTable<TY_POINTEE_KEY, TY_IDX, hash_pointee_key> TY_IDX_POINTER_MAP; 00319 // pointer_map maps a pointee to its corresponding pointer 00320 static TY_IDX_POINTER_MAP pointer_map; 00321 static std::pair<TY_POINTEE_KEY, TY_IDX> last_valid_map_entry; 00322 00323 00324 static BOOL 00325 Invalid_Pointer_Map_Entry (const TY_IDX_POINTER_MAP::value_type& entry) 00326 { 00327 TY_IDX pointer = entry.second; 00328 TY_IDX pointee = entry.first.first; 00329 00330 if (TY_IDX_index (pointer) >= TY_Table_Size () || 00331 TY_IDX_index (pointee) >= TY_Table_Size ()) 00332 return TRUE; 00333 00334 const TY& ty = Ty_Table[pointer]; 00335 00336 if (TY_kind (ty) != KIND_POINTER || 00337 TY_pointed (ty) != pointee || 00338 TY_flags (ty) != entry.first.second) 00339 return TRUE; 00340 00341 return FALSE; 00342 } // Invalid_Pointer_Map_Entry 00343 00344 00345 // in case the pointer_map is corrupted, we need to delete all invalid 00346 // entries. This should rarely happen, but still possible if some pointer 00347 // types which have been inserted into the pointer_map are deleted. 00348 static void 00349 Validate_Pointer_Map () 00350 { 00351 typedef std::vector<TY_IDX_POINTER_MAP::KeyType> InvalidEntries; 00352 class FindInvalidEntries : public TY_IDX_POINTER_MAP::ForAllAction { 00353 TY_IDX_POINTER_MAP * map; 00354 InvalidEntries invalid_entries; 00355 00356 public: 00357 FindInvalidEntries(TY_IDX_POINTER_MAP& _map) : map(&_map) {} 00358 00359 void handle(const TY_IDX_POINTER_MAP::KeyType k, 00360 TY_IDX_POINTER_MAP::ValueType &v) { 00361 UINT last_valid = 0; 00362 TY_IDX_POINTER_MAP::value_type kv(k, v); 00363 if (Invalid_Pointer_Map_Entry (kv)) 00364 invalid_entries.push_back(k); 00365 else { 00366 if (last_valid < TY_IDX_index (v)) { 00367 last_valid = TY_IDX_index (v); 00368 last_valid_map_entry.first = k; 00369 last_valid_map_entry.second = v; 00370 } 00371 } 00372 } 00373 00374 void eraseInvalidEntries() { 00375 InvalidEntries::const_iterator ieIterator; 00376 for ( ieIterator = invalid_entries.begin(); 00377 ieIterator != invalid_entries.end(); 00378 ++ieIterator ) 00379 map->erase(*ieIterator); 00380 } 00381 }; // class FindInvalidEntries 00382 00383 FindInvalidEntries fie(pointer_map); 00384 pointer_map.forAll(fie); 00385 fie.eraseInvalidEntries(); 00386 } 00387 00388 struct update_pointer_map 00389 { 00390 void operator() (UINT32 idx, const TY* ty) const { 00391 if (TY_kind (*ty) != KIND_POINTER || TY_mtype (*ty) != Pointer_Mtype) 00392 return; 00393 TY_POINTEE_KEY key (TY_pointed (*ty), TY_flags (*ty)); 00394 last_valid_map_entry = std::make_pair (key, make_TY_IDX (idx)); 00395 pointer_map.insert (last_valid_map_entry); 00396 } 00397 }; 00398 00399 static void 00400 Update_Pointer_Map () 00401 { 00402 const TY_IDX_POINTER_MAP::value_type ss_entry( last_valid_map_entry.first, 00403 last_valid_map_entry.second); 00404 00405 if ( TY_IDX_index (last_valid_map_entry.second) != 0 && 00406 Invalid_Pointer_Map_Entry (ss_entry)) { 00407 00408 DevWarn ("Rehashing TY pointer map -- this should NOT happen often"); 00409 Validate_Pointer_Map (); 00410 } 00411 For_all_entries (Ty_tab, update_pointer_map (), 00412 TY_IDX_index (last_valid_map_entry.second) + 1); 00413 } 00414 00415 00416 static inline TY_IDX 00417 Find_Ty_Pointer (TY_POINTEE_KEY key) 00418 { 00419 TY_IDX_POINTER_MAP::ValueBoolPair result = pointer_map.find(key); 00420 00421 if (result.second == false) return 0; 00422 00423 TY_IDX_POINTER_MAP::value_type vt(key, result.first); 00424 if (Invalid_Pointer_Map_Entry (vt)) { 00425 DevWarn ("Rehashing TY pointer map -- this should NOT happen often"); 00426 Validate_Pointer_Map (); 00427 return 0; 00428 } 00429 00430 TY_IDX pointer = result.first; 00431 Set_TY_align (pointer, Pointer_Size); 00432 return pointer; 00433 } // Find_Ty_Pointer 00434 00435 00436 TY_IDX 00437 TY_pointer (TY_IDX pointee, BOOL f90_pointer) 00438 { 00439 TY_POINTEE_KEY key (pointee, f90_pointer ? TY_IS_F90_POINTER : 0); 00440 00441 TY_IDX result = Find_Ty_Pointer (key); 00442 00443 if (result == 0) { 00444 Update_Pointer_Map (); 00445 return Find_Ty_Pointer (key); 00446 } 00447 00448 return result; 00449 } // TY_pointer 00450 00451 static string utoa(UINT64 i) { 00452 00453 string val = ""; 00454 00455 while (i >= 10) { 00456 val = (char) ((i % 10) + '0') + val; 00457 i = i / 10; 00458 } 00459 return ((char) (i + '0')) + val; 00460 } 00461 00462 string get_TY_string(TY_IDX idx) { 00463 00464 switch (TY_kind(idx)) { 00465 case KIND_SCALAR: 00466 return utoa(TY_mtype(idx)); 00467 case KIND_POINTER: 00468 return "*" + utoa(TY_pointed(idx)); 00469 case KIND_ARRAY: { 00470 TY_IDX base; 00471 int dim; 00472 for (base = TY_etype(idx), dim = 1; TY_kind(base) == KIND_ARRAY; base = TY_etype(base), dim++); 00473 string res = utoa(base); 00474 for (int i = 0; i < dim; i++, res += "[]"); 00475 res += utoa(TY_size(idx)); 00476 return res; 00477 } 00478 case KIND_STRUCT: 00479 return utoa(TY_name_idx(idx)); 00480 case KIND_VOID: 00481 return "void"; 00482 } 00483 00484 FmtAssert(FALSE, ("TY_kind: unexpected KIND")); 00485 /* NOTREACHED */ 00486 return ""; 00487 } 00488 00489 class Idx_Pair { 00490 public: 00491 TY_IDX idx; 00492 int bsize; 00493 Idx_Pair(TY_IDX i, int b) {idx = i; bsize = b;} 00494 }; 00495 00496 struct Pair_Cmp { 00497 bool operator() (const Idx_Pair* t1, const Idx_Pair* t2) const { 00498 return t1->idx < t2->idx || (t1->idx == t2->idx && t1->bsize < t2->bsize); 00499 } 00500 }; 00501 00502 //map<Idx_Pair*, TY_IDX, Pair_Cmp> ty_map; 00503 map<string, TY_IDX> ty_map; 00504 00505 00510 TY_IDX Make_Shared_Type (TY_IDX ty_idx, int bsize, CONSISTENCY_class consistency) { 00511 00512 string key = get_TY_string(ty_idx) + "_" + utoa(bsize) + (consistency == STRICT_CONSISTENCY ? "s" : ""); 00513 00514 if (TY_is_shared(ty_idx)) { 00515 //if the type passed in is already shared, check if it has the same block size as the one given 00516 //if yes, we can safely use the same TY entry 00517 int ty_bsize; 00518 switch (TY_kind(ty_idx)) { 00519 case KIND_SCALAR: 00520 case KIND_POINTER: 00521 case KIND_STRUCT: 00522 ty_bsize = TY_block_size(ty_idx); 00523 break; 00524 case KIND_ARRAY: { 00525 TY_IDX base; 00526 for (base = TY_etype(ty_idx); TY_kind(base) == KIND_ARRAY; base = TY_etype(base)); 00527 ty_bsize = TY_block_size(base); 00528 break; 00529 } 00530 } 00531 if (ty_bsize == bsize && TY_is_strict(ty_idx) && consistency == STRICT_CONSISTENCY) { 00532 ty_map[key] = ty_idx; 00533 return ty_idx; 00534 } 00535 } 00536 00537 //create a new shared type 00538 TY_IDX res = ty_map[key]; 00539 if (res == 0) { 00540 TY& ty = New_TY(res); 00541 TY_Init (ty, TY_size(ty_idx), TY_kind(ty_idx), TY_mtype(ty_idx), 00542 Save_Str (TY_name(ty_idx))); 00543 Set_TY_flags(res, TY_flags(ty_idx)); 00544 Set_TY_align(res, TY_align(ty_idx)); 00545 00546 if(consistency == STRICT_CONSISTENCY) 00547 Set_TY_is_strict(ty_idx); 00548 00549 switch (TY_kind(ty_idx)) { 00550 case KIND_SCALAR: 00551 Set_TY_block_size(res, bsize); 00552 Set_TY_is_shared(res); 00553 break; 00554 case KIND_POINTER: 00555 Set_TY_block_size(res, bsize); 00556 Set_TY_is_shared(res); 00557 Set_TY_pointed(res, TY_pointed(ty_idx)); 00558 break; 00559 case KIND_STRUCT: 00560 Set_TY_block_size(res, bsize); 00561 Set_TY_is_shared(res); 00562 Set_TY_fld(res, TY_fld(ty_idx)); 00563 break; 00564 case KIND_ARRAY: 00565 Set_TY_arb(res, TY_arb(ty_idx)); 00566 Set_TY_etype(res, Make_Shared_Type(TY_etype(ty_idx), bsize, consistency)); 00567 break; 00568 } 00569 ty_map[key] = res; 00570 } 00571 //cout << "MAKING SHARED: " << TY_name(res) << " " << key << " bsize: " << bsize << endl; 00572 return res; 00573 } 00574 00575 TY_IDX 00576 make_ptr_type (TY_IDX ty_idx, BOOL f90_pointer) 00577 { 00578 TY_IDX ty_ptr = TY_pointer (ty_idx, f90_pointer); 00579 00580 if (ty_ptr != 0) 00581 return ty_ptr; 00582 00583 TY &ty = New_TY (ty_ptr); 00584 TY_Init (ty, Pointer_Size, KIND_POINTER, Pointer_Mtype, 00585 Save_Str ("anon_ptr.")); 00586 Set_TY_pointed (ty, ty_idx); 00587 if (f90_pointer) 00588 Set_TY_is_f90_pointer (ty); 00589 Set_TY_align (ty_ptr, Pointer_Size); 00590 00591 return ty_ptr; 00592 } 00593 00594 TY_IDX 00595 Make_Pointer_Type (TY_IDX ty_idx, BOOL) 00596 { 00597 // This now only returns non-f90 pointers. It ignores the second argument 00598 return make_ptr_type (ty_idx, FALSE); 00599 } // Make_Pointer_Type 00600 00601 TY_IDX 00602 Make_F90_Pointer_Type (TY_IDX ty_idx) 00603 { 00604 // This now only returns f90 pointers 00605 return make_ptr_type (ty_idx, TRUE); 00606 } // Make_F90_Pointer_Type 00607 00608 00609 TY_IDX 00610 Make_Function_Type(TY_IDX return_ty_idx) 00611 { 00612 // Return the type of a function with unspecified parameters and the 00613 // specified return type. First, iterate through the known types and 00614 // see if we can return an existing type. Then as a last resort, 00615 // create the new type if we didn't find it. 00616 #ifdef ROBERT 00617 // 00618 // Note: Check for duplicates only against functions of no 00619 // parameters. I believe functions that return values through their 00620 // first parameter have TY_arg_area_size != 0, and so are excluded 00621 // from being seen as duplicates. Wilson says we currently call 00622 // Make_Function_Type only for functions of no parameters. 00623 // -- RK 971013 00624 TY_ITER ty; 00625 // TODO: There should be some way to get at Ty_tab.begin() and 00626 // Ty_tab.end() through Ty_Table. In other words, Ty_Table should be 00627 // the only visible way of getting at the table of types. Having two 00628 // names for the same thing is nasty. -- RK 00629 ty = Ty_tab.begin(); 00630 for (++ty; 00631 ty != Ty_tab.end(); 00632 ty++) { 00633 TYLIST_IDX known_return_tylist; 00634 if (TY_kind(*ty) == KIND_FUNCTION && 00635 (known_return_tylist = TY_tylist(*ty)) != (TYLIST_IDX) 0 && 00636 TYLIST_type(known_return_tylist) == return_ty_idx && 00637 (return_ty_idx == 0 || 00638 TYLIST_type(known_return_tylist + 1) == (TY_IDX) 0)) { 00639 return ty.Index(); 00640 } 00641 } 00642 TYLIST_IDX new_return_tylist_idx; 00643 TYLIST &new_return_tylist = New_TYLIST(new_return_tylist_idx); 00644 Set_TYLIST_type(new_return_tylist, return_ty_idx); 00645 00646 if (return_ty_idx != (TY_IDX) 0) { 00647 TYLIST_IDX tail_return_tylist_idx; 00648 new_return_tylist = New_TYLIST(tail_return_tylist_idx); 00649 Is_True(tail_return_tylist_idx == new_return_tylist_idx + 1, 00650 ("Make_Function_Type: TYLIST allocation messed up")); 00651 Set_TYLIST_type(new_return_tylist, (TY_IDX) 0); 00652 } 00653 00654 TY_IDX function_ty_idx; 00655 TY &function_ty = New_TY(function_ty_idx); 00656 static char buf[32]; 00657 static INT32 tcount = 0; 00658 00659 ++tcount; 00660 sprintf(buf, ".anon_functype.%d", tcount); 00661 TY_Init(function_ty, (UINT64) 0, KIND_FUNCTION, MTYPE_UNKNOWN, 00662 Save_Str(buf)); 00663 return function_ty_idx; 00664 #else 00665 TY_IDX ty_idx; 00666 TY& ty = New_TY (ty_idx); 00667 00668 TY_Init (ty, 0, KIND_FUNCTION, MTYPE_UNKNOWN, 0); 00669 Set_TY_align (ty_idx, 1); 00670 00671 TYLIST_IDX tylist_idx; 00672 00673 (void) New_TYLIST (tylist_idx); 00674 Tylist_Table [tylist_idx] = return_ty_idx; 00675 Set_TY_tylist (ty, tylist_idx); 00676 00677 (void) New_TYLIST (tylist_idx); 00678 Tylist_Table [tylist_idx] = 0; 00679 00680 // check that TY is unique 00681 TY_IDX new_ty_idx = TY_is_unique (ty_idx); 00682 if (new_ty_idx != ty_idx && TY_IDX_index (ty_idx) == Ty_tab.Size () - 1) { 00683 // found duplicate 00684 // delete last two tylist entries 00685 Tylist_Table.Delete_last (2); 00686 Ty_tab.Delete_last (); 00687 ty_idx = new_ty_idx; 00688 } 00689 return ty_idx; 00690 #endif 00691 } 00692 00693 static std::vector<ST *> intrinsic_list; 00694 00695 struct matches_pu_ty_and_name { 00696 const TY_IDX ty; 00697 const char *const name; 00698 00699 matches_pu_ty_and_name(const TY_IDX type, const char *const func_name) : 00700 ty(type), name(func_name) 00701 { } 00702 00703 BOOL operator()(const ST *const st) { 00704 return (ST_pu_type(st) == ty && 00705 strcmp(ST_name(st), name) == 0); 00706 } 00707 }; 00708 00709 static void INTRINSIC_LIST_add(ST *st) 00710 { 00711 intrinsic_list.push_back(st); 00712 } 00713 00714 static ST * 00715 INTRINSIC_LIST_lookup(TY_IDX ty, 00716 const char *function_name) 00717 { 00718 /* 00719 * GNU g++-3.0 STL workaround 00720 * g++-3.0 has a new implementation of STL - a container's 00721 * iterator is no longer a simple pointer, but a smart pointer 00722 * defined as __normal_iterator<Pointer, Container> in stl_algo.h. 00723 * And begin() end() return the smart pointers. To ensure 00724 * compatibility, we use type "iterator" instead of an explicit 00725 * pointer. 00726 */ 00727 00728 std::vector<ST *>::iterator result = 00729 std::find_if(intrinsic_list.begin(), 00730 intrinsic_list.end(), 00731 matches_pu_ty_and_name(ty, function_name)); 00732 00733 if (result == intrinsic_list.end()) { 00734 return NULL; 00735 } 00736 else { 00737 return *result; // okay because stl_algo.h defined operator* 00738 } 00739 } 00740 00741 ST * 00742 Gen_Intrinsic_Function(TY_IDX ty, 00743 const char *function_name) 00744 { 00745 ST *st = INTRINSIC_LIST_lookup(ty, function_name); 00746 00747 if (st == NULL) { 00748 st = New_ST(GLOBAL_SYMTAB); 00749 00750 PU_IDX pu_idx; 00751 PU& pu = New_PU (pu_idx); 00752 00753 PU_Init (pu, ty, CURRENT_SYMTAB); 00754 00755 ST_Init (st, Save_Str(function_name), CLASS_FUNC, SCLASS_EXTERN, 00756 EXPORT_PREEMPTIBLE, (TY_IDX) pu_idx); 00757 00758 INTRINSIC_LIST_add(st); 00759 } 00760 return st; 00761 } 00762 00763 00764 // Make an array type of equal len in each dimension 00765 TY_IDX 00766 Make_Array_Type (TYPE_ID element, INT32 ndim, INT64 len) 00767 { 00768 FmtAssert(MTYPE_RegisterSize(element) > 0 && MTYPE_align_best(element) > 0, 00769 ("Cannot make an array of %s", MTYPE_name(element))); 00770 ARB_HANDLE arb,arb_first; 00771 for (UINT i = 0; i < ndim; ++i) { 00772 arb = New_ARB (); 00773 if (i==0) { 00774 arb_first = arb; 00775 } 00776 ARB_Init (arb, 0, len - 1, MTYPE_RegisterSize (element)); 00777 Set_ARB_dimension (arb, ndim-i); 00778 } 00779 00780 Set_ARB_last_dimen (arb); 00781 Set_ARB_first_dimen (arb_first); 00782 00783 TY_IDX ty_idx; 00784 TY& ty = New_TY (ty_idx); 00785 TY_Init (ty, MTYPE_RegisterSize(element) * ndim * len, KIND_ARRAY, 00786 MTYPE_UNKNOWN, 0); 00787 Set_TY_align (ty_idx, MTYPE_align_best(element)); 00788 Set_TY_etype (ty, MTYPE_To_TY (element)); 00789 Set_TY_arb (ty, arb_first); 00790 00791 return ty_idx; 00792 00793 } // Make_Array_Type 00794 00795 //------------------------------------------------------------------------- 00796 // The next few TY related functions allow us to check for TYPE_EQUIVALENCE 00797 //------------------------------------------------------------------------- 00798 00799 // Hash Map 00800 // ------------- 00801 // We keep a STL hash_map (see below) on the side to narrow down our search 00802 // for duplicate types. 00803 // 00804 // The hash_map maps all TY_IDXs that represent identical types, all present 00805 // in our global type tables, to ONE representative TY_IDX (first encountered). 00806 // In other words, we have a map from multiple TY_IDXs to one unique 00807 // representative. 00808 // 00809 // The hash_map stores the TY_IDX of every unique TY encountered so far. 00810 // To enter types into the hash-table, call TY_is_unique(); if an equivalent 00811 // type does not already exist the given TY_IDX will be entered into the 00812 // hash-table as a unique type; otherwise the equivalent TY_IDX is returned. 00813 // Note that both our hashing function and our "equal" function operate 00814 // on the TY, not just on the TY_IDX. 00815 00816 // Why multiple hash_maps? 00817 // ---------------------------- 00818 // Since the TY_are_equivalent function is fairly expensive we need good hash 00819 // functions to reduce the number of likely matches. To that end we define 00820 // five different hash multimaps (rather than one) depending on the TY_kind; 00821 // one map each for 00822 // (a) scalars (and void), (b) pointers, (c) functions, (d) arrays, (e) structs 00823 00824 // the type of the hash table key (i.e., what the hash function takes as input) 00825 typedef TY_IDX HashKeyType; 00826 00827 // Hash functions based on TY_Kind 00828 // ------------------------------- 00829 // We use TY_kind to determine an appropriate hash-function: 00830 // a For scalars (and void) we just use the "mtype", 00831 // b For pointers we use the mtype of what the pointer points to 00832 // c For functions we use a hash based on the function signature (TY_fun_hash) 00833 // d For arrays we use a hash function based on dim/base/bound (TY_array_hash) 00834 // e For structs we use a hash function based on the struct name/size 00835 // These hash functions are now defined 00836 00837 //---------------------------------------------------------------------- 00838 // TY_fun_hash : maps a function prototype into a size_t value 00839 // If the function has a signature: t1 * .. * tn -> t 00840 // then it is represented in the TYLIST_TABLE as <t,t1,...,tn> 00841 // We hash it in base MTYPE_LAST as the number <t_m,t1_m,...,tn_m> 00842 // We create an MTYPE_LAST-ary number by extracting the mtypes of 00843 // each ti denoted by ti_m i.e., (let ML denote MTYPE_LAST) 00844 // (((t_m *ML) + t1_m) * ML) + ... + tn_m 00845 //---------------------------------------------------------------------- 00846 size_t 00847 TY_fun_hash (const TY& ty) { 00848 size_t value = 0; 00849 00850 TYLIST_ITER fn_iter = Make_tylist_iter(TY_tylist(ty)); 00851 00852 while (*fn_iter) { 00853 value = MTYPE_LAST * value + TY_mtype(Ty_Table[*fn_iter++]); 00854 } 00855 00856 return value; 00857 } // TY_fun_hash 00858 00859 //---------------------------------------------------------------------- 00860 // TY_array_hash : hashes an array into a size_t value determined by 00861 // upper_bound_value (for first dim) + (#dimensions * mtype(array_elmt)) 00862 // if two arrays have the same base type, the same number of dimensions 00863 // and the same value for the upper bound of the first dimension then 00864 // they are likely the same and are hashed to the same bucket 00865 // eg int a[10][2] and int a[10][3] would be hashed to the same bucket 00866 // whereas int a[10] and double b[10] would be hashed to diff buckets 00867 // likewise int a[10] and int b[11] would be hashed to different buckets 00868 // just as int a[10] and int a[10][2] would be hashed to different buckets 00869 //---------------------------------------------------------------------- 00870 size_t 00871 TY_array_hash (const TY& ty) { 00872 return ARB_ubnd_val(TY_arb(ty)) + 00873 ARB_dimension(TY_arb(ty)) * TY_mtype(Ty_Table[TY_etype(ty)]) ; 00874 00875 } // TY_array_hash 00876 00877 //---------------------------------------------------------------------- 00878 // TY_struct_hash: maps a struct into a size_t value 00879 // Return the name_idx (if set) or the size 00880 // If the struct has a name use the unique Str_Table index as a hash 00881 // If the struct is anonymous, use its size as a distinguishing feature 00882 //---------------------------------------------------------------------- 00883 inline size_t 00884 TY_struct_hash (const TY& ty) { 00885 return TY_name_idx(ty) ? TY_name_idx(ty) : TY_size(ty); 00886 } // TY_struct_hash 00887 00888 00889 size_t TY_hash_func(const TY_IDX ty_id) { 00890 TY &ty = Ty_Table[ty_id]; 00891 switch (TY_kind(ty)) { 00892 case KIND_SCALAR: 00893 case KIND_VOID: 00894 return TY_mtype(ty); 00895 case KIND_ARRAY: 00896 return TY_array_hash(ty); 00897 case KIND_POINTER: 00898 return TY_mtype(Ty_Table [TY_pointed(ty)]); 00899 case KIND_FUNCTION: 00900 return TY_fun_hash(ty); 00901 case KIND_STRUCT: 00902 return TY_struct_hash(ty); 00903 case KIND_INVALID: 00904 default: 00905 case KIND_LAST: 00906 Fail_FmtAssertion ("invalid TY_KIND in hash fn"); 00907 return 0; 00908 } // switch 00909 } // TY_hash_func 00910 00911 struct TY_hash { 00912 size_t operator()(const TY_IDX ty_id) const { 00913 return TY_hash_func(ty_id); 00914 } // operator() 00915 }; // struct TY_hash 00916 00917 00918 struct TY_EQUIV 00919 { 00920 bool operator () ( const TY_IDX k1, const TY_IDX k2) const 00921 { 00922 return TY_are_equivalent(k1, k2); 00923 } 00924 }; 00925 00926 typedef HashTable<TY_IDX, TY_IDX, TY_hash, TY_EQUIV> HASH_TY_TABLE; 00927 00928 // The global Hash Table data structures 00929 // Depending on the TY_KIND we pick one of the five tables below. 00930 00931 HASH_TY_TABLE Hash_ty_scalar_table; 00932 HASH_TY_TABLE Hash_ty_array_table; 00933 HASH_TY_TABLE Hash_ty_struct_table; 00934 HASH_TY_TABLE Hash_ty_pointer_table; 00935 HASH_TY_TABLE Hash_ty_function_table; 00936 00937 // The following is necessary to handle recursively defined types, 00938 // such as struct with a pointer to itself as a member field. 00939 // We maintain a record of the order in which types are visited 00940 // in the global type table for each of the two types being compared. 00941 // The following datastructure should be initialized to zero between 00942 // top-level calls to TY_are_equivalent(), and Ty_Equiv_Visit_Number 00943 // should also be zero between such top-level calls. 00944 // 00945 typedef SEGMENTED_ARRAY<UINT32> TY_EQUIV_VISIT_ORDER; 00946 static TY_EQUIV_VISIT_ORDER Ty_Equiv_Visit1; 00947 static TY_EQUIV_VISIT_ORDER Ty_Equiv_Visit2; 00948 static UINT32 Ty_Equiv_Visit_Number = 0; 00949 00950 static BOOL 00951 Push_Equiv_Visit_Order(UINT32 ty_index1, UINT32 ty_index2, BOOL &are_equiv) 00952 { 00953 const UINT32 ty_tbl_size = TY_Table_Size(); 00954 BOOL pushed = FALSE; 00955 00956 // Make sure the number of entries match the number of types, 00957 // and that entries are initialized to zero. 00958 // 00959 for (UINT32 i = Ty_Equiv_Visit1.Size(); i < ty_tbl_size; i++) 00960 { 00961 UINT dummy; 00962 Ty_Equiv_Visit1.New_entry(dummy) = 0; 00963 Ty_Equiv_Visit2.New_entry(dummy) = 0; 00964 } 00965 00966 if (Ty_Equiv_Visit1[ty_index1] != Ty_Equiv_Visit2[ty_index2]) 00967 are_equiv = FALSE; 00968 else if (Ty_Equiv_Visit1[ty_index1] > 0) 00969 are_equiv = TRUE; 00970 else 00971 { 00972 Ty_Equiv_Visit_Number++; 00973 Ty_Equiv_Visit1[ty_index1] = Ty_Equiv_Visit_Number; 00974 Ty_Equiv_Visit2[ty_index2] = Ty_Equiv_Visit_Number; 00975 are_equiv = FALSE; 00976 pushed = TRUE; 00977 } 00978 return pushed; 00979 } // Push_Equiv_Visit_Order 00980 00981 static void 00982 Pop_Equiv_Visit_Order(UINT32 ty_index1, UINT32 ty_index2) 00983 { 00984 Ty_Equiv_Visit_Number--; 00985 Ty_Equiv_Visit1[ty_index1] = 0; 00986 Ty_Equiv_Visit2[ty_index2] = 0; 00987 } // Push_Equiv_Visit_Order 00988 00989 00990 // ARB_are_equivalent determines when two array types are equivalent? 00991 // ARB_are_equivalent is presumably called with indices for which 00992 // first_dim is set. 00993 // For each entry in the Arb_Table in the range 00994 // arb_id1 .. arb_id1'(for which last_dim is set) 00995 // ensure that Arb_Table[arb_id1++] == Arb_Table[arb_id2++] 00996 00997 BOOL 00998 ARB_are_equivalent(ARB_HANDLE arb_id1, ARB_HANDLE arb_id2, UINT32 flags) 00999 { 01000 if (arb_id1 == arb_id2) 01001 return TRUE; 01002 01003 ARB_HANDLE arb1=arb_id1; 01004 ARB_HANDLE arb2=arb_id2; 01005 BOOL keep_going; 01006 01007 do { 01008 01009 keep_going = ! ARB_last_dimen(arb1) && ! ARB_last_dimen(arb2); 01010 01011 if (ARB_dimension(arb1) != ARB_dimension(arb2)) 01012 return FALSE; 01013 01014 if (ARB_co_dimension(arb1) != ARB_co_dimension(arb2)) 01015 return FALSE; 01016 01017 if (ARB_flags(arb1) != ARB_flags( arb2)) 01018 return FALSE; 01019 01020 if (ARB_const_lbnd(arb1)) { 01021 if (ARB_lbnd_val( arb1) != ARB_lbnd_val( arb2)) 01022 return FALSE; 01023 } else { 01024 if (ARB_lbnd_var( arb1) != ARB_lbnd_var( arb2)) 01025 return FALSE; 01026 } 01027 01028 if (ARB_const_ubnd(arb1)) { 01029 if (ARB_ubnd_val( arb1) != ARB_ubnd_val( arb2)) 01030 return FALSE; 01031 } else { 01032 if (ARB_ubnd_var( arb1) != ARB_ubnd_var( arb2)) 01033 return FALSE; 01034 } 01035 01036 if (ARB_const_stride(arb1)) { 01037 if (ARB_stride_val( arb1) != ARB_stride_val( arb2)) 01038 return FALSE; 01039 } else { 01040 if (ARB_stride_var(arb1) != ARB_stride_var( arb2)) 01041 return FALSE; 01042 } 01043 01044 // All tests pass; continue until you reach "last Dimension" 01045 if (keep_going) { 01046 arb1 = arb1[1]; 01047 arb2 = arb2[1]; 01048 } 01049 01050 } while (keep_going); 01051 01052 if ( ARB_last_dimen(arb2) && ARB_last_dimen(arb1)) 01053 return TRUE; 01054 else 01055 return FALSE; 01056 01057 } // ARB_are_equivalent 01058 01059 // ARB_swap swaps the positions of two ARB's in the table 01060 void 01061 ARB_swap(ARB_HANDLE arb1, ARB_HANDLE arb2) 01062 { 01063 ARB temp; 01064 temp = *(arb1.Entry()); 01065 *(arb1.Entry()) = *(arb2.Entry()); 01066 *(arb2.Entry()) = temp; 01067 } 01068 01069 01070 01071 // FLD_are_equivalent determines when two struct fields are type equivalent 01072 // T1 fld_id1 == T2 fld_id2 (where fld_idi are struct fields) iff 01073 // a. T1 == T2 AND 01074 // b. FLD_name_idx for fld_id1 == FLD_name_idx for fld_id2 01075 // c. FLD_attribute for fld_id1 == FLD_attribute for fld_id2 01076 BOOL 01077 FLD_are_equivalent (FLD_HANDLE fld1, FLD_HANDLE fld2, UINT32 flags) 01078 { 01079 if (!(flags & TY_EQUIV_IGNORE_NAMES) && 01080 FLD_name_idx(fld1) != FLD_name_idx(fld2)) 01081 return FALSE; 01082 01083 if (FLD_ofst(fld1) != FLD_ofst(fld2) || 01084 FLD_bsize(fld1) != FLD_bsize(fld2) || 01085 FLD_bofst(fld1) != FLD_bofst(fld2) || 01086 FLD_flags(fld1) != FLD_flags(fld2) || 01087 FLD_st(fld1) != FLD_st(fld2)) 01088 return FALSE; 01089 01090 // For recursive type definitions, the front end may not YET have 01091 // set the TY_IDX (ie set it to 0) when it tries to do TY_are_equivalent 01092 // We have to special case this case and return FALSE (ie not duplicates) 01093 // Presumably this case should NOT arise in the backend and hence 01094 // the #if defined (FRONT_END) 01095 // TODO: should we restrict to NONF77 front ends? 01096 // If either ty_idx is 0 return FALSE 01097 01098 TY_IDX ty_id1 = FLD_type(fld1); 01099 TY_IDX ty_id2 = FLD_type(fld2); 01100 01101 #ifdef FRONT_END 01102 if ( (ty_id1 == 0) || (ty_id2 == 0)) 01103 return FALSE; 01104 #endif //FRONT_END 01105 01106 // All fields except type are equivalent; now do structural recursion 01107 01108 return TY_are_equivalent(ty_id1, ty_id2, flags); 01109 01110 } // FLD_are_equivalent 01111 01112 01113 // go through all members of a struct and return true if all of them are 01114 // equivalent 01115 static BOOL 01116 Struct_are_equivalent (FLD_HANDLE fld_id1, FLD_HANDLE fld_id2, UINT32 flags) 01117 { 01118 if (fld_id1 == fld_id2) 01119 return TRUE; 01120 01121 FLD_ITER fld1_iter = Make_fld_iter (fld_id1); 01122 FLD_ITER fld2_iter = Make_fld_iter (fld_id2); 01123 01124 while (!FLD_last_field (fld1_iter) && !FLD_last_field (fld2_iter)) { 01125 if (! FLD_are_equivalent (fld1_iter, fld2_iter, flags)) 01126 return FALSE; 01127 ++fld1_iter; 01128 ++fld2_iter; 01129 } 01130 01131 return FLD_are_equivalent (fld1_iter, fld2_iter, flags); 01132 } // Struct_are_equivalent 01133 01134 01135 // TYLIST_are_equivalent determines when two function prototypes are equivalent 01136 // does a pointwise comparison of component TYs (including return types) 01137 01138 BOOL 01139 TYLIST_are_equivalent (TYLIST_IDX tylist_id1, 01140 TYLIST_IDX tylist_id2, 01141 UINT32 flags) 01142 { 01143 if (tylist_id1 == tylist_id2) 01144 return TRUE; 01145 01146 // Function prototypes are lists of tys terminated with a "0" TY_IDX entry 01147 // 01148 TY_IDX ty_id1; 01149 TY_IDX ty_id2; 01150 01151 while (Tylist_Table[tylist_id1] != 0) { 01152 01153 ty_id1 = Tylist_Table[tylist_id1]; 01154 ty_id2 = Tylist_Table[tylist_id2]; 01155 01156 if ( !TY_are_equivalent(ty_id1, ty_id2, flags)) 01157 return FALSE; 01158 01159 tylist_id1++; 01160 tylist_id2++; 01161 } // end while 01162 01163 if (Tylist_Table[tylist_id2] == 0) 01164 return TRUE; 01165 else 01166 return FALSE; 01167 } // TYLIST_are_equivalent 01168 01169 01170 // TY_are_equivalent 01171 // Returns TRUE iff ty1 and ty2 are structurally equivalent 01172 // also checks that names of fields are identical 01173 // TODO: whether one COMMON block is a complete subset of the other 01174 01175 BOOL 01176 TY_are_equivalent (TY_IDX ty_id1, TY_IDX ty_id2, UINT32 flags) 01177 { 01178 01179 // The two types are equivalent when they have identical TY_IDX. 01180 // They are not necessarily equivalent if their alignments or 01181 // qualifiers are different. 01182 // 01183 const UINT32 ty_index1 = TY_IDX_index(ty_id1); 01184 const UINT32 ty_index2 = TY_IDX_index(ty_id2); 01185 01186 if (ty_id1 == ty_id2) 01187 return TRUE; 01188 else if ((flags & TY_EQUIV_ALIGN) && 01189 TY_align_exp(ty_id1) != TY_align_exp(ty_id2)) 01190 return FALSE; 01191 else if ((flags & TY_EQUIV_QUALIFIER) && 01192 (TY_is_const(ty_id1) != TY_is_const(ty_id2) || 01193 TY_is_volatile(ty_id1) != TY_is_volatile(ty_id2) || 01194 TY_is_restrict(ty_id1) != TY_is_restrict(ty_id2))) 01195 return FALSE; 01196 else if (ty_index1 == ty_index2) 01197 return TRUE; 01198 01199 // Handle nested structural equivalence. If either of these types were 01200 // encountered before, then consider the types equivalent only if they 01201 // were encountered in the same order in recursive applications of this 01202 // subroutine. 01203 // 01204 BOOL are_equiv = FALSE; 01205 01206 if (Push_Equiv_Visit_Order(ty_index1, ty_index2, are_equiv)) 01207 { 01208 // Not visited before. 01209 // 01210 const TY &ty1 = Ty_Table[ty_id1]; 01211 const TY &ty2 = Ty_Table[ty_id2]; 01212 01213 // Check attributes and names, and if they match, check for structural 01214 // equivalence. 01215 // 01216 if ( TY_size(ty1) != TY_size(ty2) || 01217 TY_kind(ty1) != TY_kind(ty2) || 01218 TY_mtype(ty1)!= TY_mtype(ty2)|| 01219 TY_flags(ty1)!= TY_flags(ty2) ) 01220 { 01221 // TODO: do we want to refine this to allow ignoring certain flags? 01222 are_equiv = FALSE; 01223 } 01224 else if (!(flags & TY_EQUIV_IGNORE_NAMES) && 01225 TY_name_idx (ty1) != TY_name_idx (ty2)) 01226 { 01227 are_equiv = FALSE; 01228 } 01229 else 01230 { 01231 // Set flags for recursive calls to this routine. We always check 01232 // that alignment and qualifiers are identical for nested type 01233 // references. 01234 // 01235 flags |= (TY_EQUIV_ALIGN | TY_EQUIV_QUALIFIER); 01236 01237 // At this point all the above attributes are equal, 01238 // so we are ready to do "structural equivalence" checks 01239 01240 switch (TY_kind (ty1)) { 01241 01242 case KIND_SCALAR: 01243 case KIND_VOID: 01244 are_equiv = TRUE; 01245 break; 01246 01247 case KIND_ARRAY: 01248 // array bounds check and structural recursion on base type 01249 are_equiv = (ARB_are_equivalent(TY_arb(ty1), TY_arb(ty2), flags) && 01250 TY_are_equivalent( TY_etype(ty1), TY_etype(ty2), flags)); 01251 break; 01252 01253 case KIND_STRUCT: 01254 // At this point both the ty have NON_ZERO FLD_IDX 01255 01256 // FLD equivalence check 01257 are_equiv = Struct_are_equivalent(TY_fld(ty1), TY_fld(ty2), flags); 01258 break; 01259 01260 case KIND_POINTER: 01261 // structural recursion 01262 are_equiv = TY_are_equivalent (TY_pointed(ty1),TY_pointed(ty2), flags); 01263 break; 01264 01265 case KIND_FUNCTION: 01266 // PU flags check and structural recursion on function prototype 01267 are_equiv = ( (ty1.Pu_flags() == ty2.Pu_flags()) && 01268 (TYLIST_are_equivalent (TY_tylist(ty1), 01269 TY_tylist(ty2), 01270 flags))); 01271 break; 01272 01273 case KIND_INVALID: 01274 default: 01275 // TODO: do we want to assert here instead of returning FALSE? 01276 are_equiv = FALSE; 01277 break; 01278 } 01279 } 01280 Pop_Equiv_Visit_Order(ty_index1, ty_index2); 01281 } 01282 return are_equiv; 01283 } // TY_are_equivalent 01284 01285 01286 // TY_is_unique: returns 01287 // a. the input TY_IDX if the input defines a unique ("new") TY. 01288 // b. TY_IDX with index of an existing type if the input defines a TY that 01289 // is equivalent to the existing TY (uses TY_are_equivalent for this purpose) 01290 01291 static inline TY_IDX 01292 TY_is_unique_op (const TY_IDX ty_idx, HASH_TY_TABLE& hash_ty_table) 01293 { 01294 TY_IDX return_idx = ty_idx; 01295 01296 HASH_TY_TABLE::ValueBoolPair isInserted = 01297 hash_ty_table.insert(HASH_TY_TABLE::KeyValuePair(ty_idx, return_idx)); 01298 01299 if (isInserted.second == false) { 01300 // match was found 01301 Set_TY_IDX_index(return_idx, TY_IDX_index(isInserted.first)); 01302 } 01303 return return_idx; 01304 01305 /* 01306 // HASH_TY_TABLE::const_iterator hash_entry = hash_ty_table.find (ty_idx); 01307 HASH_TY_TABLE::const_iterator hash_entry; 01308 for ( hash_entry = hash_ty_table.begin(); 01309 hash_entry != hash_ty_table.end(); 01310 hash_entry++ ) { 01311 if (TY_are_equivalent(ty_idx, hash_entry->first)) break; 01312 } 01313 01314 if (hash_entry != hash_ty_table.end ()) 01315 // step b: If found, return the TY_IDX of the duplicate 01316 Set_TY_IDX_index(return_idx, TY_IDX_index((*hash_entry).second)); 01317 else 01318 hash_ty_table.insert (HASH_TY_TABLE::value_type(ty_idx, ty_idx)); 01319 return return_idx; 01320 */ 01321 } 01322 01323 01324 extern TY_IDX 01325 TY_is_unique (const TY_IDX ty_idx) 01326 { 01327 TY &ty = Ty_Table[ty_idx]; 01328 01329 // search for the ty in the hash table determined by its TY_kind 01330 01331 // step a. Find "potential" matches (using hash tables). Note that 01332 // the hashing and equivalence functions ignore any alignment and 01333 // qualifiers in the ty_idx. 01334 // 01335 switch (TY_kind(ty)) { 01336 01337 case KIND_SCALAR: 01338 case KIND_VOID: 01339 return TY_is_unique_op (ty_idx, Hash_ty_scalar_table); 01340 01341 case KIND_ARRAY: 01342 return TY_is_unique_op (ty_idx, Hash_ty_array_table); 01343 01344 case KIND_POINTER: 01345 return TY_is_unique_op (ty_idx, Hash_ty_pointer_table); 01346 01347 case KIND_FUNCTION: 01348 return TY_is_unique_op (ty_idx, Hash_ty_function_table); 01349 01350 case KIND_STRUCT: 01351 return TY_is_unique_op (ty_idx, Hash_ty_struct_table); 01352 01353 case KIND_INVALID: 01354 default: 01355 case KIND_LAST: 01356 Fail_FmtAssertion ("invalid TY_KIND in TY_is_unique"); 01357 return ty_idx; // should never reach this 01358 }; 01359 } // TY_is_unique 01360 01361 //---------------------------------------------------------------------- 01362 // PREG-related utilities 01363 //---------------------------------------------------------------------- 01364 01365 const char * 01366 Preg_Name (PREG_NUM i) 01367 { 01368 Is_True((i > Last_Dedicated_Preg_Offset), 01369 ("Preg_Name: not valid for dedicated preg")); 01370 01371 const PREG& preg = Preg_Table[i - Last_Dedicated_Preg_Offset]; 01372 01373 if (PREG_name_idx (preg) == 0) 01374 return "<preg>"; 01375 else 01376 return PREG_name (preg); 01377 } // Preg_Name 01378 01379 01380 // PREG_IDX == PREG_NUM - Last_Dedicated_Preg_Offset 01381 01382 PREG_NUM 01383 Create_Preg_explicit(TYPE_ID mtype, const char *name, 01384 SCOPE *scope_tab, SYMTAB_IDX level) 01385 { 01386 PREG_IDX preg_idx; 01387 PREG_IDX preg_idx2; 01388 PREG &p = New_PREG_explicit (scope_tab, level, preg_idx); 01389 Set_PREG_name_idx (p, Save_Str(name)); 01390 // pregs of simulated types have to allocate space for 01391 // all the parts of the lowered types. 01392 switch (mtype) { 01393 case MTYPE_C4: 01394 case MTYPE_C8: 01395 case MTYPE_FQ: 01396 // reserve space for another preg 01397 (void) New_PREG_explicit (scope_tab, level, preg_idx2); 01398 Set_PREG_name_idx ((*scope_tab[level].preg_tab)[preg_idx2], 0); 01399 break; 01400 case MTYPE_CQ: 01401 // reserve space for 3 more pregs 01402 (void) New_PREG_explicit (scope_tab, level, preg_idx2); 01403 Set_PREG_name_idx ((*scope_tab[level].preg_tab)[preg_idx2], 0); 01404 (void) New_PREG_explicit (scope_tab, level, preg_idx2); 01405 Set_PREG_name_idx ((*scope_tab[level].preg_tab)[preg_idx2], 0); 01406 (void) New_PREG_explicit (scope_tab, level, preg_idx2); 01407 Set_PREG_name_idx ((*scope_tab[level].preg_tab)[preg_idx2], 0); 01408 break; 01409 case MTYPE_B: 01410 // bool needs 2 pregs cause can have complement predicate tn 01411 (void) New_PREG_explicit (scope_tab, level, preg_idx2); 01412 Set_PREG_name_idx ((*scope_tab[level].preg_tab)[preg_idx2], 0); 01413 break; 01414 } 01415 // return preg-num of first preg 01416 return (PREG_NUM) preg_idx + Last_Dedicated_Preg_Offset; 01417 } 01418 01419 PREG_NUM 01420 Create_Preg (TYPE_ID mtype, const char *name) 01421 { 01422 return Create_Preg_explicit(mtype, name, Scope_tab, CURRENT_SYMTAB); 01423 } 01424 01425 // uses the real preg size because simulated pregs might take more than one 01426 // preg number. 01427 INT32 01428 Preg_Increment (TYPE_ID mtype) 01429 { 01430 switch (mtype) { 01431 01432 case MTYPE_C4: 01433 case MTYPE_C8: 01434 case MTYPE_FQ: 01435 return 2; 01436 01437 case MTYPE_CQ: 01438 return 4; 01439 01440 case MTYPE_I8: 01441 case MTYPE_U8: 01442 if (MTYPE_size_reg(MTYPE_I8) > MTYPE_size_reg(Spill_Int_Mtype)) 01443 return 2; 01444 case MTYPE_B: 01445 // bool mtype not usually used, but if used, saves space for 01446 // complement preg. 01447 return 2; 01448 } 01449 return 1; 01450 } 01451 01452 01453 //---------------------------------------------------------------------- 01454 // BLK utilities 01455 //---------------------------------------------------------------------- 01456 01457 BLK_IDX 01458 Copy_BLK (BLK_IDX b) 01459 { 01460 BLK_IDX copy = b; 01461 copy = Blk_Table.Insert (Blk_Table[b]); 01462 return copy; 01463 } 01464 01465 /* ==================================================================== 01466 * 01467 * Base_Symbol_And_Offset 01468 * Input: ST *st Symbol to analyze 01469 * Result: ST **base_symbol primary base of st 01470 * Result: INT64 *offset_from_base offset from primary base 01471 * 01472 * 01473 * ==================================================================== 01474 */ 01475 void 01476 Base_Symbol_And_Offset (ST *st, 01477 ST **base_symbol, 01478 INT64 *offset_from_base) 01479 { 01480 INT64 ofst = 0; 01481 ST *base = st; 01482 01483 while ( ST_base(base) != base ) { 01484 ofst += ST_ofst(base); 01485 base = ST_base(base); 01486 } 01487 01488 *base_symbol = base; 01489 *offset_from_base = ofst; 01490 } 01491 01492 01493 //---------------------------------------------------------------------- 01494 // Printing routines 01495 //---------------------------------------------------------------------- 01496 01497 /* ==================================================================== 01498 * 01499 * Class_Name / Sclass_Name / Export_Name / Kind_Name 01500 * Given ST field values, convert to ASCII names. 01501 * 01502 * Name_To_Class / Name_To_Sclass / Name_To_Export / Name_To_Kind 01503 * Given ASCII names, convert to ST field values. 01504 * 01505 * ==================================================================== 01506 */ 01507 01508 // eraxxon (2005.01): Re-implement these routines to support 01509 // conversion in both directions. 01510 01511 // The type for enumeration value -> string tables 01512 struct EnumToStr_t : public ir_a2b::enum2str_tbl_entry_t { 01513 EnumToStr_t(INT val_ = 0, const char* str_ = 0) 01514 : val(val_), str(str_) { } 01515 01516 virtual ~EnumToStr_t() { } 01517 01518 virtual INT getEnumVal() const { return val; } 01519 virtual const char* getStr() const { return str; } 01520 01521 INT val; 01522 const char* str; 01523 }; 01524 01525 01526 // The data tables 01527 EnumToStr_t STClassToNameTbl[CLASS_COUNT] = { 01528 EnumToStr_t(CLASS_UNK, "C_UNK"), 01529 EnumToStr_t(CLASS_VAR, "C_VAR"), 01530 EnumToStr_t(CLASS_FUNC, "C_FUNC"), 01531 EnumToStr_t(CLASS_CONST, "C_CONST"), 01532 EnumToStr_t(CLASS_PREG, "C_PREG"), 01533 EnumToStr_t(CLASS_BLOCK, "C_BLOCK"), 01534 EnumToStr_t(CLASS_NAME, "C_NAME"), 01535 EnumToStr_t(CLASS_MODULE, "C_MODULE"), 01536 EnumToStr_t(CLASS_TYPE, "C_TYPE"), 01537 EnumToStr_t(CLASS_PARAMETER, "C_PARAMETER") 01538 }; 01539 01540 EnumToStr_t STSclassToNameTbl[SCLASS_COUNT] = { 01541 EnumToStr_t(SCLASS_UNKNOWN, "S_UNKNOWN"), 01542 EnumToStr_t(SCLASS_AUTO, "S_AUTO"), 01543 EnumToStr_t(SCLASS_FORMAL, "S_FORMAL"), 01544 EnumToStr_t(SCLASS_FORMAL_REF,"S_FORMAL_REF"), 01545 EnumToStr_t(SCLASS_PSTATIC, "S_PSTATIC"), 01546 EnumToStr_t(SCLASS_FSTATIC, "S_FSTATIC"), 01547 EnumToStr_t(SCLASS_COMMON, "S_COMMON"), 01548 EnumToStr_t(SCLASS_EXTERN, "S_EXTERN"), 01549 EnumToStr_t(SCLASS_UGLOBAL, "S_UGLOBAL"), 01550 EnumToStr_t(SCLASS_DGLOBAL, "S_DGLOBAL"), 01551 EnumToStr_t(SCLASS_TEXT, "S_TEXT"), 01552 EnumToStr_t(SCLASS_REG, "S_REG"), 01553 EnumToStr_t(SCLASS_CPLINIT, "S_CPLINIT"), 01554 EnumToStr_t(SCLASS_EH_REGION, "S_EH_REGION"), 01555 EnumToStr_t(SCLASS_EH_REGION_SUPP, "S_EH_REGION_SUPP"), 01556 EnumToStr_t(SCLASS_DISTR_ARRAY, "S_DISTR_ARRAY"), 01557 EnumToStr_t(SCLASS_COMMENT, "S_COMMENT"), 01558 EnumToStr_t(SCLASS_THREAD_PRIVATE_FUNCS, "S_THREAD_PRIVATE_FUNCS"), 01559 EnumToStr_t(SCLASS_MODULE, "S_MODULE"), 01560 EnumToStr_t(SCLASS_COMMON1, "S_COMMON1"), 01561 }; 01562 01563 EnumToStr_t STExportToNameTbl[EXPORT_COUNT] = { 01564 EnumToStr_t(EXPORT_LOCAL, "X_LOCAL"), 01565 EnumToStr_t(EXPORT_LOCAL_INTERNAL, "X_LOCAL_INTERNAL"), 01566 EnumToStr_t(EXPORT_INTERNAL, "X_INTERNAL"), 01567 EnumToStr_t(EXPORT_HIDDEN, "X_HIDDEN"), 01568 EnumToStr_t(EXPORT_PROTECTED, "X_PROTECTED"), 01569 EnumToStr_t(EXPORT_PREEMPTIBLE, "X_PREEMPTIBLE"), 01570 EnumToStr_t(EXPORT_OPTIONAL, "X_OPTIONAL"), 01571 EnumToStr_t(EXPORT_INTRINSIC, "X_INTRINSIC"), 01572 }; 01573 01574 EnumToStr_t TYKindToNameTbl[KIND_LAST] = { 01575 EnumToStr_t(KIND_INVALID, "INVALID"), 01576 EnumToStr_t(KIND_SCALAR, "SCALAR"), 01577 EnumToStr_t(KIND_ARRAY, "ARRAY"), 01578 EnumToStr_t(KIND_STRUCT, "STRUCT"), 01579 EnumToStr_t(KIND_POINTER, "POINTER"), 01580 EnumToStr_t(KIND_FUNCTION, "FUNCTION"), 01581 EnumToStr_t(KIND_VOID, "VOID"), 01582 }; 01583 01584 01585 #define STATTR_ToStrTblENTRY(flg) \ 01586 EnumToStr_t(flg, #flg) 01587 01588 EnumToStr_t STATTR_ToStrTbl[] = { 01589 STATTR_ToStrTblENTRY(ST_ATTR_UNKNOWN), 01590 STATTR_ToStrTblENTRY(ST_ATTR_DEDICATED_REGISTER), 01591 STATTR_ToStrTblENTRY(ST_ATTR_SECTION_NAME) 01592 }; 01593 01594 01595 #define LKIND_ToStrTblENTRY(flg) \ 01596 EnumToStr_t(flg, #flg) 01597 01598 EnumToStr_t LKIND_ToStrTbl[] = { 01599 LKIND_ToStrTblENTRY(LKIND_DEFAULT), 01600 LKIND_ToStrTblENTRY(LKIND_ASSIGNED), 01601 LKIND_ToStrTblENTRY(LKIND_BEGIN_EH_RANGE), 01602 LKIND_ToStrTblENTRY(LKIND_END_EH_RANGE), 01603 LKIND_ToStrTblENTRY(LKIND_BEGIN_HANDLER), 01604 LKIND_ToStrTblENTRY(LKIND_END_HANDLER), 01605 LKIND_ToStrTblENTRY(LKIND_TAG), 01606 LKIND_ToStrTblENTRY(LKIND_INTERNAL), 01607 LKIND_ToStrTblENTRY(LKIND_LOOP_GEN), 01608 LKIND_ToStrTblENTRY(LKIND_SELECT_GEN) 01609 }; 01610 01611 01612 const char * 01613 Class_Name (ST_CLASS cl) 01614 { 01615 using namespace ir_a2b; 01616 return MapEnumToStr<EnumToStr_t, STClassToNameTbl, 01617 CLASS_COUNT>("STClassToNameTbl", (INT)cl); 01618 } 01619 01620 ST_CLASS 01621 Name_To_Class (const char* nm) 01622 { 01623 using namespace ir_a2b; 01624 return (ST_CLASS)MapStrToEnum<EnumToStr_t, STClassToNameTbl, 01625 CLASS_COUNT>("STClassToNameTbl", nm); 01626 } 01627 01628 01629 const char * 01630 Sclass_Name (ST_SCLASS sc) 01631 { 01632 using namespace ir_a2b; 01633 return MapEnumToStr<EnumToStr_t, STSclassToNameTbl, 01634 SCLASS_COUNT>("STSclassToNameTbl", (INT)sc); 01635 } 01636 01637 ST_SCLASS 01638 Name_To_Sclass (const char* nm) 01639 { 01640 using namespace ir_a2b; 01641 return (ST_SCLASS)MapStrToEnum<EnumToStr_t, STSclassToNameTbl, 01642 SCLASS_COUNT>("STSclassToNameTbl", nm); 01643 } 01644 01645 01646 const char * 01647 Export_Name (ST_EXPORT ex) 01648 { 01649 using namespace ir_a2b; 01650 return MapEnumToStr<EnumToStr_t, STExportToNameTbl, 01651 EXPORT_COUNT>("STExportToNameTbl", (INT)ex); 01652 } 01653 01654 ST_EXPORT 01655 Name_To_Export (const char* nm) 01656 { 01657 using namespace ir_a2b; 01658 return (ST_EXPORT)MapStrToEnum<EnumToStr_t, STExportToNameTbl, 01659 EXPORT_COUNT>("STExportToNameTbl", nm); 01660 } 01661 01662 01663 const char * 01664 Kind_Name (TY_KIND k) 01665 { 01666 using namespace ir_a2b; 01667 return MapEnumToStr<EnumToStr_t, TYKindToNameTbl, 01668 KIND_LAST>("TYKindToNameTbl", (INT)k); 01669 } 01670 01671 TY_KIND 01672 Name_To_Kind (const char* nm) 01673 { 01674 using namespace ir_a2b; 01675 return (TY_KIND)MapStrToEnum<EnumToStr_t, TYKindToNameTbl, 01676 KIND_LAST>("TYKindToNameTbl", nm); 01677 } 01678 01679 01680 const char * 01681 LABEL_Kind_Name (LABEL_KIND k) 01682 { 01683 using namespace ir_a2b; 01684 return MapEnumToStr<EnumToStr_t, LKIND_ToStrTbl, 01685 LKIND_COUNT>("LKIND_ToStrTbl", (INT)k); 01686 } 01687 01688 LABEL_KIND 01689 Name_To_LABEL_Kind (const char* nm) 01690 { 01691 using namespace ir_a2b; 01692 return (LABEL_KIND)MapStrToEnum<EnumToStr_t, LKIND_ToStrTbl, 01693 LKIND_COUNT>("LKIND_ToStrTbl", nm); 01694 } 01695 01696 01697 const char * 01698 ST_ATTR_Kind_Name (ST_ATTR_KIND k) 01699 { 01700 using namespace ir_a2b; 01701 return MapEnumToStr<EnumToStr_t, STATTR_ToStrTbl, 01702 ST_ATTR_KIND_COUNT>("STATTR_ToStrTbl", (INT)k); 01703 } 01704 01705 ST_ATTR_KIND 01706 Name_To_ST_ATTR_Kind (const char* nm) 01707 { 01708 using namespace ir_a2b; 01709 return (ST_ATTR_KIND)MapStrToEnum<EnumToStr_t, STATTR_ToStrTbl, 01710 ST_ATTR_KIND_COUNT>("STATTR_ToStrTbl", nm); 01711 } 01712 01713 01714 /* ==================================================================== 01715 * 01716 * xxxFlag_Name 01717 * Given flag set, convert to a comma-separated flag string 01718 * 01719 * Name_To_xxxFlag 01720 * Given a comma-separated flag string, convert to a flags set 01721 * 01722 * ==================================================================== 01723 */ 01724 01725 // eraxxon (2005.01): Create these routines to support conversion in 01726 // both directions. 01727 01728 // The type for flag value -> string tables 01729 struct FlagToStr_t : public ir_a2b::flag2str_tbl_entry_t { 01730 FlagToStr_t(UINT64 val_ = 0, const char* str_ = 0) 01731 : val(val_), str(str_) { } 01732 01733 virtual ~FlagToStr_t() { } 01734 01735 virtual UINT64 getFlagVal() const { return val; } 01736 virtual const char* getStr() const { return str; } 01737 01738 UINT64 val; 01739 const char* str; 01740 }; 01741 01742 01743 // FILE_INFO_FLAGS 01744 #define FIFLAGS_ToStrTblENTRY(flg) \ 01745 FlagToStr_t(flg, #flg) 01746 01747 FlagToStr_t FIFLAGS_ToStrTbl[] = { 01748 FIFLAGS_ToStrTblENTRY(FI_IPA), 01749 FIFLAGS_ToStrTblENTRY(FI_NEEDS_LNO), 01750 FIFLAGS_ToStrTblENTRY(FI_HAS_INLINES), 01751 FIFLAGS_ToStrTblENTRY(FI_HAS_MP) 01752 }; 01753 01754 const UINT FIFLAGS_ToStrTblSZ = 01755 (sizeof(FIFLAGS_ToStrTbl) / sizeof(FlagToStr_t)); 01756 01757 01758 // ST_FLAGS 01759 #define STFLAGS_ToStrTblENTRY(flg) \ 01760 FlagToStr_t(flg, #flg) 01761 01762 FlagToStr_t STFLAGS_ToStrTbl[] = { 01763 STFLAGS_ToStrTblENTRY(ST_IS_WEAK_SYMBOL), 01764 STFLAGS_ToStrTblENTRY(ST_IS_SPLIT_COMMON), 01765 STFLAGS_ToStrTblENTRY(ST_IS_NOT_USED), 01766 STFLAGS_ToStrTblENTRY(ST_IS_INITIALIZED), 01767 STFLAGS_ToStrTblENTRY(ST_IS_RETURN_VAR), 01768 STFLAGS_ToStrTblENTRY(ST_IS_VALUE_PARM), 01769 STFLAGS_ToStrTblENTRY(ST_PROMOTE_PARM), 01770 STFLAGS_ToStrTblENTRY(ST_KEEP_NAME_W2F), 01771 STFLAGS_ToStrTblENTRY(ST_IS_DATAPOOL), 01772 STFLAGS_ToStrTblENTRY(ST_IS_RESHAPED), 01773 STFLAGS_ToStrTblENTRY(ST_EMIT_SYMBOL), 01774 STFLAGS_ToStrTblENTRY(ST_HAS_NESTED_REF), 01775 STFLAGS_ToStrTblENTRY(ST_INIT_VALUE_ZERO), 01776 STFLAGS_ToStrTblENTRY(ST_GPREL), 01777 STFLAGS_ToStrTblENTRY(ST_NOT_GPREL), 01778 STFLAGS_ToStrTblENTRY(ST_IS_NAMELIST), 01779 STFLAGS_ToStrTblENTRY(ST_IS_F90_TARGET), 01780 STFLAGS_ToStrTblENTRY(ST_DECLARED_STATIC), 01781 STFLAGS_ToStrTblENTRY(ST_IS_EQUIVALENCED), 01782 STFLAGS_ToStrTblENTRY(ST_IS_FILL_ALIGN), 01783 STFLAGS_ToStrTblENTRY(ST_IS_OPTIONAL_ARGUMENT), 01784 STFLAGS_ToStrTblENTRY(ST_PT_TO_UNIQUE_MEM), 01785 STFLAGS_ToStrTblENTRY(ST_IS_TEMP_VAR), 01786 STFLAGS_ToStrTblENTRY(ST_IS_CONST_VAR), 01787 STFLAGS_ToStrTblENTRY(ST_ADDR_SAVED), 01788 STFLAGS_ToStrTblENTRY(ST_ADDR_PASSED), 01789 STFLAGS_ToStrTblENTRY(ST_IS_THREAD_PRIVATE), 01790 STFLAGS_ToStrTblENTRY(ST_PT_TO_COMPILER_GENERATED_MEM), 01791 STFLAGS_ToStrTblENTRY(ST_IS_SHARED_AUTO), 01792 STFLAGS_ToStrTblENTRY(ST_ASSIGNED_TO_DEDICATED_PREG), 01793 STFLAGS_ToStrTblENTRY(ST_ASM_FUNCTION_ST), 01794 STFLAGS_ToStrTblENTRY(ST_HAS_NAMED_SECTION) 01795 }; 01796 01797 const UINT STFLAGS_ToStrTblSZ = 01798 (sizeof(STFLAGS_ToStrTbl) / sizeof(FlagToStr_t)); 01799 01800 01801 // ST_EXT_FLAGS 01802 #define STEXTFLAGS_ToStrTblENTRY(flg) \ 01803 FlagToStr_t(flg, #flg) 01804 01805 FlagToStr_t STEXTFLAGS_ToStrTbl[] = { 01806 STEXTFLAGS_ToStrTblENTRY(ST_IS_POINTER), 01807 STEXTFLAGS_ToStrTblENTRY(ST_IS_ALLOCATABLE), 01808 STEXTFLAGS_ToStrTblENTRY(ST_IS_IN_MODULE), 01809 STEXTFLAGS_ToStrTblENTRY(ST_IS_EXTERNAL), 01810 STEXTFLAGS_ToStrTblENTRY(ST_IS_BLOCK_DATA), 01811 STEXTFLAGS_ToStrTblENTRY(ST_IS_INTENT_IN_ARGUMENT), 01812 STEXTFLAGS_ToStrTblENTRY(ST_IS_INTENT_OUT_ARGUMENT), 01813 STEXTFLAGS_ToStrTblENTRY(ST_IS_ASSIGN_INTERFACE), 01814 STEXTFLAGS_ToStrTblENTRY(ST_IS_OPERATOR_INTERFACE), 01815 STEXTFLAGS_ToStrTblENTRY(ST_IS_U_OPERATOR_INTERFACE), 01816 STEXTFLAGS_ToStrTblENTRY(ST_IS_PRIVATE), 01817 STEXTFLAGS_ToStrTblENTRY(ST_IS_M_IMPORTED), 01818 STEXTFLAGS_ToStrTblENTRY(ST_IS_IMPLEM_LEVEL_TEMP), 01819 STEXTFLAGS_ToStrTblENTRY(ST_IS_PARAMETER), 01820 STEXTFLAGS_ToStrTblENTRY(ST_ONE_PER_PU), 01821 STEXTFLAGS_ToStrTblENTRY(ST_COPY_CONSTRUCTOR_ST), 01822 STEXTFLAGS_ToStrTblENTRY(ST_INITV_IN_OTHER_ST), 01823 STEXTFLAGS_ToStrTblENTRY(ST_IS_INITIALIZED_IN_F90), 01824 STEXTFLAGS_ToStrTblENTRY(ST_IS_DELETED), 01825 STEXTFLAGS_ToStrTblENTRY(ST_IS_COARRAY_CONCURRENT), 01826 STEXTFLAGS_ToStrTblENTRY(ST_KEEP_IN_OPENAD), 01827 }; 01828 01829 const UINT STEXTFLAGS_ToStrTblSZ = 01830 (sizeof(STEXTFLAGS_ToStrTbl) / sizeof(FlagToStr_t)); 01831 01832 01833 // FLD_FLAGS 01834 #define FLDFLAGS_ToStrTblENTRY(flg) \ 01835 FlagToStr_t(flg, #flg) 01836 01837 FlagToStr_t FLDFLAGS_ToStrTbl[] = { 01838 FLDFLAGS_ToStrTblENTRY(FLD_LAST_FIELD), 01839 FLDFLAGS_ToStrTblENTRY(FLD_EQUIVALENCE), 01840 FLDFLAGS_ToStrTblENTRY(FLD_BEGIN_UNION), 01841 FLDFLAGS_ToStrTblENTRY(FLD_END_UNION), 01842 FLDFLAGS_ToStrTblENTRY(FLD_BEGIN_MAP), 01843 FLDFLAGS_ToStrTblENTRY(FLD_END_MAP), 01844 FLDFLAGS_ToStrTblENTRY(FLD_IS_BIT_FIELD), 01845 FLDFLAGS_ToStrTblENTRY(FLD_IS_POINTER) 01846 }; 01847 01848 const UINT FLDFLAGS_ToStrTblSZ = 01849 (sizeof(FLDFLAGS_ToStrTbl) / sizeof(FlagToStr_t)); 01850 01851 01852 // ARB_FLAGS 01853 #define ARBFLAGS_ToStrTblENTRY(flg) \ 01854 FlagToStr_t(flg, #flg) 01855 01856 FlagToStr_t ARBFLAGS_ToStrTbl[] = { 01857 ARBFLAGS_ToStrTblENTRY(ARB_CONST_LBND), 01858 ARBFLAGS_ToStrTblENTRY(ARB_CONST_UBND), 01859 ARBFLAGS_ToStrTblENTRY(ARB_CONST_STRIDE), 01860 ARBFLAGS_ToStrTblENTRY(ARB_FIRST_DIMEN), 01861 ARBFLAGS_ToStrTblENTRY(ARB_LAST_DIMEN), 01862 ARBFLAGS_ToStrTblENTRY(ARB_EMPTY_LBND), 01863 ARBFLAGS_ToStrTblENTRY(ARB_EMPTY_UBND), 01864 ARBFLAGS_ToStrTblENTRY(ARB_STAR_UBND), 01865 ARBFLAGS_ToStrTblENTRY(ARB_EMPTY_STRIDE) 01866 }; 01867 01868 const UINT ARBFLAGS_ToStrTblSZ = 01869 (sizeof(ARBFLAGS_ToStrTbl) / sizeof(FlagToStr_t)); 01870 01871 01872 // LABEL_FLAGS 01873 #define LBLFLAGS_ToStrTblENTRY(flg) \ 01874 FlagToStr_t(flg, #flg) 01875 01876 FlagToStr_t LBLFLAGS_ToStrTbl[] = { 01877 LBLFLAGS_ToStrTblENTRY(LABEL_TARGET_OF_GOTO_OUTER_BLOCK), 01878 LBLFLAGS_ToStrTblENTRY(LABEL_ADDR_SAVED), 01879 LBLFLAGS_ToStrTblENTRY(LABEL_ADDR_PASSED) 01880 }; 01881 01882 const UINT LBLFLAGS_ToStrTblSZ = 01883 (sizeof(LBLFLAGS_ToStrTbl) / sizeof(FlagToStr_t)); 01884 01885 01886 // TY_FLAGS 01887 #define TYFLAGS_ToStrTblENTRY(flg) \ 01888 FlagToStr_t(flg, #flg) 01889 01890 FlagToStr_t TYFLAGS_ToStrTbl[] = { 01891 TYFLAGS_ToStrTblENTRY(TY_IS_CHARACTER), 01892 TYFLAGS_ToStrTblENTRY(TY_IS_LOGICAL), 01893 TYFLAGS_ToStrTblENTRY(TY_IS_UNION), 01894 TYFLAGS_ToStrTblENTRY(TY_IS_PACKED), 01895 TYFLAGS_ToStrTblENTRY(TY_PTR_AS_ARRAY), 01896 TYFLAGS_ToStrTblENTRY(TY_ANONYMOUS), 01897 TYFLAGS_ToStrTblENTRY(TY_SPLIT), 01898 TYFLAGS_ToStrTblENTRY(TY_IS_F90_POINTER), 01899 TYFLAGS_ToStrTblENTRY(TY_NOT_IN_UNION), 01900 TYFLAGS_ToStrTblENTRY(TY_NO_ANSI_ALIAS), 01901 TYFLAGS_ToStrTblENTRY(TY_IS_NON_POD), 01902 TYFLAGS_ToStrTblENTRY(TY_IS_F90_ASSUMED_SHAPE), 01903 TYFLAGS_ToStrTblENTRY(TY_IS_F90_ASSUMED_SIZE), 01904 TYFLAGS_ToStrTblENTRY(TY_IS_F90_DEFERRED_SHAPE), 01905 TYFLAGS_ToStrTblENTRY(TY_IS_EXTERNAL), 01906 TYFLAGS_ToStrTblENTRY(TY_IS_SEQUENCE), 01907 TYFLAGS_ToStrTblENTRY(TY_IS_SHARED), 01908 TYFLAGS_ToStrTblENTRY(TY_IS_STRICT), 01909 TYFLAGS_ToStrTblENTRY(TY_IS_RELAXED), 01910 TYFLAGS_ToStrTblENTRY(TY_IS_CO_ARRAY), 01911 TYFLAGS_ToStrTblENTRY(TY_IS_WRITTEN), 01912 TYFLAGS_ToStrTblENTRY(TY_RETURN_IN_MEM) 01913 }; 01914 01915 const UINT TYFLAGS_ToStrTblSZ = 01916 (sizeof(TYFLAGS_ToStrTbl) / sizeof(FlagToStr_t)); 01917 01918 01919 // TY_PU_FLAGS 01920 #define TYPUFLAGS_ToStrTblENTRY(flg) \ 01921 FlagToStr_t(flg, #flg) 01922 01923 FlagToStr_t TYPUFLAGS_ToStrTbl[] = { 01924 TYPUFLAGS_ToStrTblENTRY(TY_RETURN_TO_PARAM), 01925 TYPUFLAGS_ToStrTblENTRY(TY_IS_VARARGS), 01926 TYPUFLAGS_ToStrTblENTRY(TY_HAS_PROTOTYPE) 01927 }; 01928 01929 const UINT TYPUFLAGS_ToStrTblSZ = 01930 (sizeof(TYPUFLAGS_ToStrTbl) / sizeof(FlagToStr_t)); 01931 01932 01933 // PU_FLAGS 01934 #define PUFLAGS_ToStrTblENTRY(flg) \ 01935 FlagToStr_t(flg, #flg) 01936 01937 FlagToStr_t PUFLAGS_ToStrTbl[] = { 01938 PUFLAGS_ToStrTblENTRY(PU_IS_PURE), 01939 PUFLAGS_ToStrTblENTRY(PU_NO_SIDE_EFFECTS), 01940 PUFLAGS_ToStrTblENTRY(PU_IS_INLINE_FUNCTION), 01941 PUFLAGS_ToStrTblENTRY(PU_NO_INLINE), 01942 PUFLAGS_ToStrTblENTRY(PU_MUST_INLINE), 01943 PUFLAGS_ToStrTblENTRY(PU_NO_DELETE), 01944 PUFLAGS_ToStrTblENTRY(PU_HAS_EXC_SCOPES), 01945 PUFLAGS_ToStrTblENTRY(PU_IS_NESTED_FUNC), 01946 PUFLAGS_ToStrTblENTRY(PU_HAS_NON_MANGLED_CALL), 01947 PUFLAGS_ToStrTblENTRY(PU_ARGS_ALIASED), 01948 PUFLAGS_ToStrTblENTRY(PU_NEEDS_FILL_ALIGN_LOWERING), 01949 PUFLAGS_ToStrTblENTRY(PU_NEEDS_T9), 01950 PUFLAGS_ToStrTblENTRY(PU_HAS_VERY_HIGH_WHIRL), 01951 PUFLAGS_ToStrTblENTRY(PU_HAS_ALTENTRY), 01952 PUFLAGS_ToStrTblENTRY(PU_RECURSIVE), 01953 PUFLAGS_ToStrTblENTRY(PU_IS_MAINPU), 01954 PUFLAGS_ToStrTblENTRY(PU_UPLEVEL), 01955 PUFLAGS_ToStrTblENTRY(PU_MP_NEEDS_LNO), 01956 PUFLAGS_ToStrTblENTRY(PU_HAS_ALLOCA), 01957 PUFLAGS_ToStrTblENTRY(PU_IN_ELF_SECTION), 01958 PUFLAGS_ToStrTblENTRY(PU_HAS_MP), 01959 PUFLAGS_ToStrTblENTRY(PU_MP), 01960 PUFLAGS_ToStrTblENTRY(PU_HAS_NAMELIST), 01961 PUFLAGS_ToStrTblENTRY(PU_HAS_RETURN_ADDRESS), 01962 PUFLAGS_ToStrTblENTRY(PU_HAS_REGION), 01963 PUFLAGS_ToStrTblENTRY(PU_HAS_INLINES), 01964 PUFLAGS_ToStrTblENTRY(PU_CALLS_SETJMP), 01965 PUFLAGS_ToStrTblENTRY(PU_CALLS_LONGJMP), 01966 PUFLAGS_ToStrTblENTRY(PU_IPA_ADDR_ANALYSIS), 01967 PUFLAGS_ToStrTblENTRY(PU_SMART_ADDR_ANALYSIS), 01968 PUFLAGS_ToStrTblENTRY(PU_HAS_SYSCALL_LINKAGE), 01969 PUFLAGS_ToStrTblENTRY(PU_HAS_GLOBAL_PRAGMAS), 01970 PUFLAGS_ToStrTblENTRY(PU_HAS_USER_ALLOCA), 01971 PUFLAGS_ToStrTblENTRY(PU_HAS_UNKNOWN_CONTROL_FLOW), 01972 PUFLAGS_ToStrTblENTRY(PU_IS_THUNK), 01973 PUFLAGS_ToStrTblENTRY(PU_DECL_VIEW), 01974 PUFLAGS_ToStrTblENTRY(PU_NEED_UNPARSED), 01975 PUFLAGS_ToStrTblENTRY(PU_NEEDS_MANUAL_UNWINDING), 01976 #ifdef TARG_X8664 01977 PUFLAGS_ToStrTblENTRY(PU_FF2C_ABI) 01978 #endif 01979 }; 01980 01981 const UINT PUFLAGS_ToStrTblSZ = 01982 (sizeof(PUFLAGS_ToStrTbl) / sizeof(FlagToStr_t)); 01983 01984 01985 // PU_SRC_LANG_FLAGS 01986 #define PUSRCLANGFLAGS_ToStrTblENTRY(flg) \ 01987 FlagToStr_t(flg, #flg) 01988 01989 FlagToStr_t PUSRCLANGFLAGS_ToStrTbl[] = { 01990 PUSRCLANGFLAGS_ToStrTblENTRY(PU_UNKNOWN_LANG), 01991 PUSRCLANGFLAGS_ToStrTblENTRY(PU_MIXED_LANG), 01992 PUSRCLANGFLAGS_ToStrTblENTRY(PU_C_LANG), 01993 PUSRCLANGFLAGS_ToStrTblENTRY(PU_CXX_LANG), 01994 PUSRCLANGFLAGS_ToStrTblENTRY(PU_F77_LANG), 01995 PUSRCLANGFLAGS_ToStrTblENTRY(PU_F90_LANG), 01996 PUSRCLANGFLAGS_ToStrTblENTRY(PU_JAVA_LANG) 01997 }; 01998 01999 const UINT PUSRCLANGFLAGS_ToStrTblSZ = 02000 (sizeof(PUSRCLANGFLAGS_ToStrTbl) / sizeof(FlagToStr_t)); 02001 02002 02003 // BLK 02004 #define BLKFLAGS_ToStrTblENTRY(flg) \ 02005 FlagToStr_t(flg, #flg) 02006 02007 FlagToStr_t BLKFLAGS_ToStrTbl[] = { 02008 BLKFLAGS_ToStrTblENTRY(BLK_SECTION), 02009 BLKFLAGS_ToStrTblENTRY(BLK_ROOT_BASE), 02010 BLKFLAGS_ToStrTblENTRY(BLK_IS_BASEREG), 02011 BLKFLAGS_ToStrTblENTRY(BLK_DECREMENT), 02012 BLKFLAGS_ToStrTblENTRY(BLK_EXEC), 02013 BLKFLAGS_ToStrTblENTRY(BLK_NOBITS), 02014 BLKFLAGS_ToStrTblENTRY(BLK_MERGE), 02015 BLKFLAGS_ToStrTblENTRY(BLK_COMPILER_LAYOUT) 02016 }; 02017 02018 const UINT BLKFLAGS_ToStrTblSZ = 02019 (sizeof(BLKFLAGS_ToStrTbl) / sizeof(FlagToStr_t)); 02020 02021 02022 const char * 02023 FILE_INFO_FLAGS_To_Str (UINT64 flags) 02024 { 02025 using namespace ir_a2b; 02026 return MapFlagsToStr<FlagToStr_t, FIFLAGS_ToStrTbl, 02027 FIFLAGS_ToStrTblSZ>("FIFLAGS_ToStrTbl", flags); 02028 } 02029 02030 UINT64 02031 Str_To_FILE_INFO_FLAGS (const char* str) 02032 { 02033 using namespace ir_a2b; 02034 return MapStrToFlags<FlagToStr_t, FIFLAGS_ToStrTbl, 02035 FIFLAGS_ToStrTblSZ>("FIFLAGS_ToStrTbl", str); 02036 } 02037 02038 02039 const char * 02040 ST_FLAGS_To_Str (UINT64 flags) 02041 { 02042 using namespace ir_a2b; 02043 return MapFlagsToStr<FlagToStr_t, STFLAGS_ToStrTbl, 02044 STFLAGS_ToStrTblSZ>("STFLAGS_ToStrTbl", flags); 02045 } 02046 02047 UINT64 02048 Str_To_ST_FLAGS (const char* str) 02049 { 02050 using namespace ir_a2b; 02051 return MapStrToFlags<FlagToStr_t, STFLAGS_ToStrTbl, 02052 STFLAGS_ToStrTblSZ>("STFLAGS_ToStrTbl", str); 02053 } 02054 02055 02056 const char * 02057 ST_EXT_FLAGS_To_Str (UINT64 flags) 02058 { 02059 using namespace ir_a2b; 02060 return MapFlagsToStr<FlagToStr_t, STEXTFLAGS_ToStrTbl, 02061 STEXTFLAGS_ToStrTblSZ>("STEXTFLAGS_ToStrTbl", flags); 02062 } 02063 02064 UINT64 02065 Str_To_ST_EXT_FLAGS (const char* str) 02066 { 02067 using namespace ir_a2b; 02068 return MapStrToFlags<FlagToStr_t, STEXTFLAGS_ToStrTbl, 02069 STEXTFLAGS_ToStrTblSZ>("STEXTFLAGS_ToStrTbl", str); 02070 } 02071 02072 02073 const char * 02074 FLD_FLAGS_To_Str (UINT64 flags) 02075 { 02076 using namespace ir_a2b; 02077 return MapFlagsToStr<FlagToStr_t, FLDFLAGS_ToStrTbl, 02078 FLDFLAGS_ToStrTblSZ>("FLDFLAGS_ToStrTbl", flags); 02079 } 02080 02081 UINT64 02082 Str_To_FLD_FLAGS (const char* str) 02083 { 02084 using namespace ir_a2b; 02085 return MapStrToFlags<FlagToStr_t, FLDFLAGS_ToStrTbl, 02086 FLDFLAGS_ToStrTblSZ>("FLDFLAGS_ToStrTbl", str); 02087 } 02088 02089 02090 const char * 02091 ARB_FLAGS_To_Str (UINT64 flags) 02092 { 02093 using namespace ir_a2b; 02094 return MapFlagsToStr<FlagToStr_t, ARBFLAGS_ToStrTbl, 02095 ARBFLAGS_ToStrTblSZ>("ARBFLAGS_ToStrTbl", flags); 02096 } 02097 02098 UINT64 02099 Str_To_ARB_FLAGS (const char* str) 02100 { 02101 using namespace ir_a2b; 02102 return MapStrToFlags<FlagToStr_t, ARBFLAGS_ToStrTbl, 02103 ARBFLAGS_ToStrTblSZ>("ARBFLAGS_ToStrTbl", str); 02104 } 02105 02106 02107 const char * 02108 LABEL_FLAGS_To_Str (UINT64 flags) 02109 { 02110 using namespace ir_a2b; 02111 return MapFlagsToStr<FlagToStr_t, LBLFLAGS_ToStrTbl, 02112 LBLFLAGS_ToStrTblSZ>("LBLFLAGS_ToStrTbl", flags); 02113 } 02114 02115 UINT64 02116 Str_To_LABEL_FLAGS (const char* str) 02117 { 02118 using namespace ir_a2b; 02119 return MapStrToFlags<FlagToStr_t, LBLFLAGS_ToStrTbl, 02120 LBLFLAGS_ToStrTblSZ>("LBLFLAGS_ToStrTbl", str); 02121 } 02122 02123 02124 const char * 02125 TY_FLAGS_To_Str (UINT64 flags) 02126 { 02127 using namespace ir_a2b; 02128 return MapFlagsToStr<FlagToStr_t, TYFLAGS_ToStrTbl, 02129 TYFLAGS_ToStrTblSZ>("TYFLAGS_ToStrTbl", flags); 02130 } 02131 02132 UINT64 02133 Str_To_TY_FLAGS (const char* str) 02134 { 02135 using namespace ir_a2b; 02136 return MapStrToFlags<FlagToStr_t, TYFLAGS_ToStrTbl, 02137 TYFLAGS_ToStrTblSZ>("TYFLAGS_ToStrTbl", str); 02138 } 02139 02140 02141 const char * 02142 TY_PU_FLAGS_To_Str (UINT64 flags) 02143 { 02144 using namespace ir_a2b; 02145 return MapFlagsToStr<FlagToStr_t, TYPUFLAGS_ToStrTbl, 02146 TYPUFLAGS_ToStrTblSZ>("TYPUFLAGS_ToStrTbl", flags); 02147 } 02148 02149 UINT64 02150 Str_To_TY_PU_FLAGS (const char* str) 02151 { 02152 using namespace ir_a2b; 02153 return MapStrToFlags<FlagToStr_t, TYPUFLAGS_ToStrTbl, 02154 TYPUFLAGS_ToStrTblSZ>("TYPUFLAGS_ToStrTbl", str); 02155 } 02156 02157 02158 const char * 02159 PU_FLAGS_To_Str (UINT64 flags) 02160 { 02161 using namespace ir_a2b; 02162 return MapFlagsToStr<FlagToStr_t, PUFLAGS_ToStrTbl, 02163 PUFLAGS_ToStrTblSZ>("PUFLAGS_ToStrTbl", flags); 02164 } 02165 02166 UINT64 02167 Str_To_PU_FLAGS (const char* str) 02168 { 02169 using namespace ir_a2b; 02170 return MapStrToFlags<FlagToStr_t, PUFLAGS_ToStrTbl, 02171 PUFLAGS_ToStrTblSZ>("PUFLAGS_ToStrTbl", str); 02172 } 02173 02174 02175 const char * 02176 PU_SRC_LANG_FLAGS_To_Str (UINT64 flags) 02177 { 02178 using namespace ir_a2b; 02179 return MapFlagsToStr<FlagToStr_t, PUSRCLANGFLAGS_ToStrTbl, 02180 PUSRCLANGFLAGS_ToStrTblSZ>("PUSRCLANGFLAGS_ToStrTbl", 02181 flags); 02182 } 02183 02184 UINT64 02185 Str_To_PU_SRC_LANG_FLAGS (const char* str) 02186 { 02187 using namespace ir_a2b; 02188 return MapStrToFlags<FlagToStr_t, PUSRCLANGFLAGS_ToStrTbl, 02189 PUSRCLANGFLAGS_ToStrTblSZ>("PUSRCLANGFLAGS_ToStrTbl", 02190 str); 02191 } 02192 02193 02194 const char * 02195 BLK_FLAGS_To_Str (UINT64 flags) 02196 { 02197 using namespace ir_a2b; 02198 return MapFlagsToStr<FlagToStr_t, BLKFLAGS_ToStrTbl, 02199 BLKFLAGS_ToStrTblSZ>("BLKFLAGS_ToStrTbl", flags); 02200 } 02201 02202 UINT64 02203 Str_To_BLK_FLAGS (const char* str) 02204 { 02205 using namespace ir_a2b; 02206 return MapStrToFlags<FlagToStr_t, BLKFLAGS_ToStrTbl, 02207 BLKFLAGS_ToStrTblSZ>("BLKFLAGS_ToStrTbl", str); 02208 } 02209 02210 02211 /* ==================================================================== 02212 * 02213 * Print routines 02214 * 02215 * ==================================================================== 02216 */ 02217 02218 static void 02219 Print_type_attributes (FILE *f, TY_IDX ty) 02220 { 02221 if (TY_is_const (ty)) 02222 fputs ("const ", f); 02223 if (TY_is_volatile (ty)) 02224 fputs ("volatile ", f); 02225 if (TY_is_restrict (ty)) 02226 fputs ("restrict ", f); 02227 } // Print_type_attributes 02228 02229 02230 static void 02231 Print_TY_IDX_verbose (FILE *f, TY_IDX idx) 02232 { 02233 Print_type_attributes (f, idx); 02234 if (TY_IDX_index (idx) == 0) { 02235 fputs ("<NULL>", f); 02236 return; 02237 } 02238 02239 const TY& ty = Ty_Table[idx]; 02240 const char *name = TY_name_idx (ty) == 0 ? "(anon)" : TY_name (ty); 02241 fprintf (f, "%s (#%d) align %d", name, TY_IDX_index (idx), TY_align (idx)); 02242 } // Print_TY_IDX_verbose 02243 02244 02245 static const char * 02246 TY_kind_name (const TY& ty) 02247 { 02248 if (TY_kind (ty) == KIND_SCALAR && TY_mtype (ty) != MTYPE_UNKNOWN) 02249 return MTYPE_name (TY_mtype (ty)); 02250 else 02251 return Kind_Name (TY_kind (ty)); 02252 } 02253 02254 02255 void 02256 ST::Print (FILE *f, BOOL verbose) const 02257 { 02258 const char *name_str = (sym_class == CLASS_CONST) ? 02259 "<constant>" : &Str_Table[u1.name_idx]; 02260 02261 fprintf (f, "%-14s\t<%d,%d> ", name_str, ST_IDX_level (st_idx), 02262 ST_IDX_index (st_idx)); 02263 if (strlen (name_str) > 20) 02264 fputs ("\n\t\t", f); 02265 02266 fprintf (f, "%s", Class_Name(sym_class)); 02267 02268 TY_IDX ty_idx = 0; 02269 02270 switch (sym_class) { 02271 case CLASS_VAR: 02272 case CLASS_TYPE: 02273 ty_idx = u2.type; 02274 break; 02275 02276 case CLASS_FUNC: 02277 ty_idx = PU_prototype (Pu_Table[u2.pu]); 02278 break; 02279 02280 case CLASS_CONST: 02281 ty_idx = u2.type; 02282 break; 02283 02284 case CLASS_PREG: 02285 ty_idx = u2.type; 02286 break; 02287 02288 case CLASS_BLOCK: 02289 fprintf (f, " (#%d)", u2.blk); 02290 break; 02291 } 02292 02293 const TY& ty = Ty_Table [ty_idx]; 02294 02295 if (ty_idx != 0) { 02296 02297 name_str = TY_name_idx (ty) == 0 ? NULL : TY_name (ty); 02298 02299 if (!(sym_class == CLASS_FUNC) || name_str != NULL) { 02300 fputs (" of type ", f); 02301 02302 Print_type_attributes (f, ty_idx); 02303 02304 fputs (name_str ? name_str : "(anon)", f); 02305 02306 const TY *pty = &ty; 02307 INT pcount = 0; 02308 while (TY_kind (*pty) == KIND_POINTER) { 02309 pty = &Ty_Table[TY_pointed (*pty)]; 02310 ++pcount; 02311 } 02312 02313 if (verbose) { 02314 name_str = TY_kind_name (*pty); 02315 fprintf (f, " (#%d, %s", TY_IDX_index (ty_idx), name_str); 02316 while (pcount-- > 0) 02317 fputc ('*', f); 02318 fputc (')', f); 02319 } else 02320 fprintf (f, " (#%d)", TY_IDX_index (ty_idx)); 02321 } 02322 } 02323 02324 if (!verbose) { 02325 /* quick address */ 02326 fprintf (f, " @ 0x%llx", offset); 02327 if (base_idx != 0) 02328 fprintf (f, "(%s)", ST_name (base_idx)); 02329 } 02330 fputc ('\n', f); 02331 02332 if (sym_class == CLASS_FUNC && verbose) { 02333 /* Give info about the type being returned, which is different 02334 * than the type of the function. 02335 */ 02336 if (ty_idx != 0 && TY_tylist (ty) != 0) { 02337 TY_IDX rettype_idx = Tylist_Table[TY_tylist (ty)]; 02338 const TY& rettype = Ty_Table[rettype_idx]; 02339 fputs ("\t\tReturning ", f); 02340 Print_type_attributes (f, rettype_idx); 02341 fputs (TY_name (rettype), f); 02342 name_str = TY_kind_name (rettype); 02343 fprintf (f, " (#%d, %s) ", TY_IDX_index (rettype_idx), name_str); 02344 02345 fprintf (f, "PU[%d] ", u2.pu); 02346 const char* srclang = 02347 PU_SRC_LANG_FLAGS_To_Str(Pu_Table[u2.pu].src_lang); 02348 fprintf (f, "%s ", srclang); 02349 02350 mUINT64 flags = Pu_Table[u2.pu].flags; 02351 fprintf (f, "flags: %s", PU_FLAGS_To_Str(flags)); 02352 if (TY_return_to_param(ty_idx)) fprintf (f, " return_to_param"); 02353 if (TY_is_varargs(ty_idx)) fprintf (f, " varargs"); 02354 if (TY_has_prototype(ty_idx)) fprintf (f, " prototype"); 02355 fprintf (f, "\n"); 02356 } 02357 } 02358 02359 if (sym_class == CLASS_CONST) 02360 fprintf (f, "\t\tvalue: %s\n", Targ_Print (NULL, Tcon_Table[u1.tcon])); 02361 02362 if (verbose) { 02363 // Print address 02364 if (base_idx != 0) { 02365 const ST& base_st = St_Table[base_idx]; 02366 fprintf (f, "\t\tAddress: %lld(%s<%d,%d>) ", offset, 02367 ST_class (base_st) == CLASS_CONST ? "" : 02368 ST_name (base_idx), ST_IDX_level (base_idx), 02369 ST_IDX_index (base_idx)); 02370 } 02371 02372 if (ty_idx != 0) { 02373 if (base_idx == 0 && offset == 0) 02374 fputs ("\t\t", f); 02375 fprintf (f, "Alignment: %d bytes", TY_align (ty_idx)); 02376 } 02377 fprintf (f, "\n"); 02378 02379 fprintf (f, "\t\tFlags:\t0x%08x", flags); 02380 fprintf (f, " %s", ST_FLAGS_To_Str(flags)); 02381 02382 fprintf (f, ", %s", Export_Name(export_class)); 02383 02384 mUINT64 flags_ext = St_Table[st_idx].flags_ext; 02385 if (flags_ext) { 02386 const char* flgstr = ST_EXT_FLAGS_To_Str(flags_ext); 02387 fprintf (f, "\n\t\tFlags_ext:\t0x%016llx", flags_ext); 02388 fprintf (f, " %s", flgstr); 02389 } 02390 02391 fprintf (f, "\n\t\tSclass: %s\n", Sclass_Name (storage_class)); 02392 } 02393 } // ST::Print 02394 02395 02396 void 02397 FLD::Print (FILE *f) const 02398 { 02399 fprintf (f, "\t%6lld %-8s\t", ofst, &Str_Table[name_idx]); 02400 Print_TY_IDX_verbose (f, type); 02401 fprintf (f, "\n\t\tfl:0x%04x", flags); 02402 if (flags) { 02403 const char* flgstr = FLD_FLAGS_To_Str(flags); 02404 fprintf (f, " %s", flgstr); 02405 } 02406 if (st != 0) 02407 fprintf (f, " st (%d,%d)", ST_IDX_level (st), ST_IDX_index (st)); 02408 if (flags & FLD_IS_BIT_FIELD) 02409 fprintf (f, " bit field size:%d ofst:%d", bsize, bofst); 02410 fputc ('\n', f); 02411 } // FLD::Print 02412 02413 02414 void 02415 ARB::Print (FILE *f) const 02416 { 02417 if (flags & ARB_CONST_LBND) 02418 fprintf (f, "%lld:", Lbnd_val ()); 02419 else 02420 fprintf (f, "st(%d):", ST_IDX_index (Lbnd_var ())); 02421 02422 if (flags & ARB_CONST_UBND) 02423 fprintf (f, "%lld:", Ubnd_val ()); 02424 else 02425 fprintf (f, "st(%d):", ST_IDX_index (Ubnd_var ())); 02426 02427 if (flags & ARB_CONST_STRIDE) 02428 fprintf (f, "%lld:", Stride_val ()); 02429 else 02430 fprintf (f, "st(%d):", ST_IDX_index (Stride_var ())); 02431 02432 } // ARB::Print 02433 02434 02435 void 02436 TY::Print (FILE *f) const 02437 { 02438 fprintf (f, "%-14s:", 02439 name_idx ? &Str_Table[name_idx] : "(anon)"); 02440 02441 fprintf (f, " (f: 0x%08x", flags); 02442 if (flags) { 02443 const char* flgstr = TY_FLAGS_To_Str(flags); 02444 fprintf (f, " %s", flgstr); 02445 } 02446 fprintf (f, ")"); 02447 02448 fprintf (f, " size %lld %s: ", 02449 size, (mtype != 0) ? Mtype_Name (mtype) : ""); 02450 02451 switch (kind) { 02452 case KIND_SCALAR: 02453 fprintf (f, "SCALAR (%s)", Mtype_Name (mtype)); 02454 fputc ('\n', f); 02455 break; 02456 02457 case KIND_ARRAY: 02458 fputs ("ARRAY of ", f); 02459 Print_TY_IDX_verbose (f, Etype ()); 02460 if (Arb () != 0) { 02461 ARB_HANDLE arb(Arb()); 02462 INT i,ndim,co_dim,array_dim; 02463 02464 ndim = ARB_dimension(arb); 02465 co_dim = ARB_co_dimension(arb); 02466 array_dim = ndim-co_dim; 02467 02468 fprintf(f,"\n\t\t dimension (%d) ,co_dimension(%d) ",array_dim,co_dim); 02469 02470 for (i = 0; i < ndim; i++) { 02471 fputs (" (", f); 02472 (*arb[i].Entry()).Print (f); 02473 fputc (')', f); 02474 // possible early exit for broken tables 02475 if (ARB_last_dimen(arb[i])) break; 02476 } 02477 } 02478 fputc ('\n', f); 02479 break; 02480 02481 case KIND_STRUCT: 02482 if (TY_is_packed (*this)) 02483 fputs ("packed ", f); 02484 fputs (kind == KIND_STRUCT ? "STRUCT\n": "CLASS\n", f); 02485 if (Fld () != 0) { 02486 FLD_ITER iter = Make_fld_iter (FLD_HANDLE (Fld ())); 02487 do { 02488 (*iter).Print (f); 02489 } while (! FLD_last_field (iter++)); 02490 } else 02491 fputc ('\n', f); 02492 break; 02493 02494 case KIND_POINTER: 02495 fputs ("-> ", f); 02496 Print_TY_IDX_verbose (f, Pointed ()); 02497 fputc ('\n', f); 02498 break; 02499 02500 case KIND_FUNCTION: 02501 fprintf (f, "FUNCTION (f: 0x%04x)\n", Pu_flags()); 02502 { 02503 TYLIST_IDX idx = Tylist (); 02504 fprintf (f, "\treturns "); 02505 Print_TY_IDX_verbose (f, Tylist_Table[idx]); 02506 if (Tylist_Table[idx] == 0) { 02507 fputc ('\n', f); 02508 break; 02509 } 02510 ++idx; 02511 while (Tylist_Table[idx] != 0) { 02512 fputs ("\n\tparameter ", f); 02513 Print_TY_IDX_verbose (f, Tylist_Table[idx]); 02514 ++idx; 02515 } 02516 fputc ('\n', f); 02517 } 02518 break; 02519 02520 case KIND_VOID: 02521 fputs ("VOID", f); 02522 fputc ('\n', f); 02523 break; 02524 02525 default: 02526 fprintf (f, "Unknown type (%d)", kind); 02527 fputc ('\n', f); 02528 break; 02529 } 02530 02531 if (flags & TY_IS_SHARED) 02532 fprintf (f, "%s %d\n", "Block:", block_size); 02533 } // TY::Print 02534 02535 02536 void 02537 PU::Print (FILE *f) const 02538 { 02539 Print_TY_IDX_verbose (f, prototype); 02540 fprintf (f, ", flags 0x%016llx,\n" 02541 "\tlexical level %d, LANG 0x%02x, TARGET_INFO %d\n", 02542 flags, lexical_level, src_lang, target_idx); 02543 if (flags & PU_DECL_VIEW) { 02544 fprintf(f,"Attention!!!: Declaration only (PU_DECL_VIEW)!"); 02545 fprintf(f,"\n"); 02546 } 02547 02548 } // PU::Print 02549 02550 void 02551 BLK::Print (FILE *f) const 02552 { 02553 fprintf (f, "size %lld, align %d, flags 0x%04x, section %d, scninfo %d\n", 02554 size, align, flags, section_idx, scninfo_idx); 02555 } // BLK::Print 02556 02557 02558 void 02559 LABEL::Print (FILE *f) const 02560 { 02561 const char *name_str = name_idx ? &Str_Table[name_idx] : "(anon)"; 02562 fprintf (f, "%s: kind = 0x%08x fl = 0x%08x", name_str, kind, flags); 02563 02564 const char* flgstr = LABEL_FLAGS_To_Str(flags); 02565 fprintf (f, " %s\n", flgstr); 02566 } // LABEL::Print 02567 02568 02569 void 02570 PREG::Print (FILE *f) const 02571 { 02572 const char *name_str = name_idx ? &Str_Table[name_idx] : "(anon)"; 02573 02574 fprintf (f, "%s\n", name_str); 02575 } // PREG::Print 02576 02577 02578 void 02579 ST_ATTR::Print (FILE* f) const 02580 { 02581 fprintf (f, "0x%x (%s) --> ", st_idx, ST_name (st_idx)); 02582 switch (kind) { 02583 case ST_ATTR_UNKNOWN: 02584 fprintf (f, "(NOT USED)\n"); 02585 break; 02586 case ST_ATTR_DEDICATED_REGISTER: 02587 fprintf (f, "(DREG) %d\n", u.reg_id); 02588 break; 02589 case ST_ATTR_SECTION_NAME: 02590 fprintf (f, "(SECTION) %s\n", Index_To_Str (u.section_name)); 02591 break; 02592 default: 02593 fprintf (f, "(UNKNOWN) 0x%x\n", u.value); 02594 break; 02595 } 02596 } 02597 02598 void 02599 FILE_INFO::Print (FILE *f) const 02600 { 02601 fprintf (f, "gp_group: %d, flags: 0x%08x", gp_group, flags); 02602 if (flags) { 02603 const char* flgstr = FILE_INFO_FLAGS_To_Str(flags); 02604 fprintf (f, " %s", flgstr); 02605 } 02606 02607 fputs ("\n", f); 02608 02609 } // FILE_INFO::Print 02610 02611 02612 02613 // function object used in "For_all" 02614 template <class T> 02615 struct print_op 02616 { 02617 FILE *fid; 02618 02619 print_op (FILE *f) : fid (f) {} 02620 02621 void operator () (UINT idx, T *entry) const; 02622 }; // print_op 02623 02624 02625 template <class T> 02626 inline void 02627 print_op<T>::operator () (UINT idx, T *entry) const { 02628 fprintf (fid, "[%d]: ", idx); 02629 entry->Print (fid); 02630 } 02631 02632 02633 // specialization for printing TCONs 02634 template <> 02635 inline void 02636 print_op<TCON>::operator () (UINT idx, TCON *c) const { 02637 fprintf (fid, "[%d] %s: %s\n", idx, MTYPE_name(TCON_ty(*c)),Targ_Print (NULL, *c)); 02638 } // print_op<TCON>::operator () 02639 02640 02641 // Print all local symbol tables corresponding to a PU 02642 void 02643 Print_local_symtab (FILE *f, const SCOPE& scope) 02644 { 02645 // Print the function name 02646 02647 fprintf (f, "\n%sSYMTAB for %s: level %d, st %d, label %d, preg %d," 02648 " inito %d, st_attr %d\n%s\n", DBar, ST_name (scope.st), 02649 PU_lexical_level (scope.st), scope.st_tab->Size () - 1, 02650 scope.label_tab->Size () - 1, scope.preg_tab->Size () - 1, 02651 scope.inito_tab->Size () - 1, scope.st_attr_tab->Size () - 1, DBar); 02652 02653 fputs ("Symbols:\n", f); 02654 For_all_entries (*scope.st_tab, print_op<ST> (f), 1); 02655 02656 fprintf (f, "%sLabels:\n", DBar); 02657 For_all_entries (*scope.label_tab, print_op<LABEL> (f), 1); 02658 02659 fprintf (f, "%sPseudo-registers:\n", DBar); 02660 For_all_entries (*scope.preg_tab, print_op<PREG> (f), 1); 02661 02662 fprintf (f, "%sINITOs:\n", DBar); 02663 For_all_entries (*scope.inito_tab, print_op<INITO> (f), 1); 02664 02665 fprintf (f, "%sST_ATTRs:\n", DBar); 02666 For_all_entries (*scope.st_attr_tab, print_op<ST_ATTR> (f), 1); 02667 02668 fprintf (f, "%s\n", DBar); 02669 02670 } // Print_local_symtab 02671 02672 02673 void 02674 Print_global_symtab (FILE *f) 02675 { 02676 fprintf(f,"%sGLOBAL SYMTAB:\n", DBar); 02677 02678 fprintf (f, "%sFile Info:\n", DBar); 02679 File_info.Print (f); 02680 02681 fprintf (f, "%sSymbols:\n", DBar); 02682 For_all (St_Table, GLOBAL_SYMTAB, print_op<ST> (f)); 02683 02684 fprintf (f, "%sPUs:\n", DBar); 02685 For_all (Pu_Table, print_op<PU> (f)); 02686 02687 fprintf (f, "%sTypes:\n", DBar); 02688 For_all (Ty_Table, print_op<TY> (f)); 02689 02690 fprintf (f, "%sBlocks:\n", DBar); 02691 For_all (Blk_Table, print_op<BLK> (f)); 02692 02693 fprintf (f, "%sTcons:\n", DBar); 02694 For_all (Tcon_Table, print_op<TCON> (f)); 02695 02696 fprintf (f, "%sINITOs:\n", DBar); 02697 For_all (Inito_Table, GLOBAL_SYMTAB, print_op<INITO> (f)); 02698 02699 fprintf (f, "%sST_ATTRs:\n", DBar); 02700 For_all (St_Attr_Table, GLOBAL_SYMTAB, print_op<ST_ATTR> (f)); 02701 02702 fprintf (f, "%sString table size = %d\n", DBar, STR_Table_Size()); 02703 fprintf (f, "%s\n", DBar); 02704 } // Print_global_symtab 02705 02706 // for ease of debugging, because I don't know how to call Print 02707 // routines from dbx, add simple dump routines. 02708 void 02709 dump_st (ST *st) 02710 { 02711 st->Print(stdout); 02712 switch (st->sym_class) { 02713 case CLASS_BLOCK: 02714 Blk_Table[st->u2.blk].Print (stdout); 02715 break; 02716 case CLASS_FUNC: 02717 Pu_Table[st->u2.pu].Print (stdout); 02718 break; 02719 } 02720 } 02721 02722 void 02723 dump_st(ST_IDX st_idx) 02724 { 02725 ST *st = &St_Table[st_idx]; 02726 dump_st(st); 02727 } 02728 02729 // Since dbx cannot handle overloaded functions... 02730 void 02731 dump_st_idx (ST_IDX st) 02732 { 02733 dump_st(st); 02734 } 02735 02736 02737 void 02738 dump_ty (TY_IDX ty_idx) 02739 { 02740 TY& ty = Ty_Table[ty_idx]; 02741 ty.Print(stdout); 02742 } 02743 02744 // Since dbx cannot handle overloaded function... 02745 void 02746 dump_ty_idx (TY_IDX ty_idx) 02747 { 02748 dump_ty (ty_idx); 02749 } 02750 02751 void 02752 dump_ty(const TY &ty) 02753 { 02754 ty.Print(stdout); 02755 } 02756 02757 void 02758 dump_label (LABEL_IDX idx) 02759 { 02760 Label_Table[idx].Print(stdout); 02761 } 02762 02763 void 02764 dump_inito(INITO_IDX idx) 02765 { 02766 Inito_Table[idx].Print(stdout); 02767 } 02768 02769 void 02770 dump_st_attr (ST_ATTR_IDX idx) 02771 { 02772 St_Attr_Table[idx].Print(stdout); 02773 } 02774 02775 static ST * 02776 Gen_Temp_Named_Symbol (TY_IDX ty, const char *rootname, 02777 ST_CLASS sym_class, ST_SCLASS storage_class) 02778 { 02779 static INT Temp_Index = 0; 02780 ST *st = New_ST(CURRENT_SYMTAB); 02781 STR_IDX str_idx = Save_Str2i(rootname, "_temp_", Temp_Index++); 02782 ST_Init(st, str_idx, sym_class, storage_class, EXPORT_LOCAL, ty); 02783 return st; 02784 } 02785 02786 // Create stack symbol for temp var. 02787 ST * 02788 Gen_Temp_Symbol (TY_IDX ty, // type of the desired symbol 02789 const char *rootname) // root of the name to use 02790 { 02791 ST *st = Gen_Temp_Named_Symbol(ty, rootname, CLASS_VAR, SCLASS_AUTO); 02792 Set_ST_is_temp_var(st); 02793 return st; 02794 } 02795 02796 // Create a read-only file-level static symbol of the given type in 02797 // the current symbol table. 02798 ST * 02799 Gen_Read_Only_Symbol(TY_IDX ty, const char *rootname) 02800 { 02801 ST *st = Gen_Temp_Named_Symbol(ty, rootname, CLASS_VAR, SCLASS_FSTATIC); 02802 Set_ST_is_const_var(st); 02803 return st; 02804 } 02805 02806 //---------------------------------------------------------------------- 02807 //---------------------------------------------------------------------- 02808 02809 TY_IDX 02810 Promoted_Parm_Type(const ST *formal_parm) 02811 { 02812 TY_IDX ptype = ST_type(formal_parm); 02813 TY_IDX newtype; 02814 BOOL parm_float; 02815 02816 if ( ! ST_promote_parm(formal_parm) ) return ptype; 02817 02818 /* Otherwise, figure out the conversion: */ 02819 ptype = ST_type(formal_parm); 02820 parm_float = ST_is_value_parm(formal_parm) && 02821 (TY_kind(ptype) == KIND_SCALAR) && 02822 (MTYPE_float(TY_mtype(ptype))); 02823 if ( parm_float ) { 02824 /* Must be a promotion from float to double: */ 02825 newtype = MTYPE_To_TY(MTYPE_F8); 02826 } else { 02827 /* Must be a promotion to int: */ 02828 newtype = MTYPE_To_TY(Integer_type); 02829 } 02830 02831 /* For sanity, assert that we don't demote: */ 02832 Is_True(TY_size(newtype) >= TY_size(ptype), 02833 ("Nonsensical demotion of parameter type")); 02834 return newtype; 02835 } 02836 02837 //---------------------------------------------------------------------- 02838 // Initialization routines 02839 //---------------------------------------------------------------------- 02840 02841 // for fast conversion of predefined types and preg. 02842 ST *MTYPE_TO_PREG_array[MTYPE_LAST+1]; 02843 02844 ST *Int_Preg, *Float_Preg, *Return_Val_Preg; 02845 02846 TY_IDX MTYPE_TO_TY_array[MTYPE_LAST+1]; 02847 02848 TY_IDX Quad_Type, Void_Type, FE_int_Type, FE_double_Type; 02849 TY_IDX Spill_Int_Type, Spill_Float_Type; 02850 02851 #if defined(FRONT_END) && !defined(FRONT_END_MFEF77) 02852 extern "C" TYPE_ID FE_int_To_Mtype (void); 02853 #endif 02854 02855 static INT Max_scope = 8; 02856 02857 // Set reserve_index_zero to FALSE when reading the symtab from a file 02858 void 02859 New_Scope (SYMTAB_IDX level, MEM_POOL *pool, BOOL reserve_index_zero) 02860 { 02861 if (level >= Max_scope) { 02862 UINT size = Max_scope * sizeof(SCOPE); 02863 Max_scope *= 2; 02864 Scope_tab = (SCOPE *) MEM_POOL_Realloc (Malloc_Mem_Pool, Scope_tab, 02865 size, size * 2); 02866 } 02867 02868 Current_scope = level; 02869 02870 ST_TAB *st_tab = CXX_NEW (ST_TAB (pool), pool); 02871 INITO_TAB *inito_tab = CXX_NEW (INITO_TAB (pool), pool); 02872 ST_ATTR_TAB *st_attr_tab = CXX_NEW (ST_ATTR_TAB (pool), pool); 02873 LABEL_TAB *label_tab = NULL; 02874 PREG_TAB *preg_tab = NULL; 02875 02876 UINT32 dummy_idx; 02877 if (reserve_index_zero) { 02878 st_tab->New_entry ((ST_IDX&) dummy_idx); 02879 inito_tab->New_entry ((INITO_IDX&) dummy_idx); 02880 st_attr_tab->New_entry ((ST_ATTR_IDX&) dummy_idx); 02881 } 02882 02883 if (level > GLOBAL_SYMTAB) { 02884 label_tab = CXX_NEW (LABEL_TAB (pool), pool); 02885 preg_tab = CXX_NEW (PREG_TAB (pool), pool); 02886 02887 if (reserve_index_zero) { 02888 label_tab->New_entry ((LABEL_IDX&) dummy_idx); 02889 preg_tab->New_entry ((PREG_IDX&) dummy_idx); 02890 } 02891 02892 } 02893 02894 02895 // Allocate tables for STs, LABELS, PREGs and INITOs 02896 Scope_tab[level].Init (st_tab, label_tab, preg_tab, inito_tab, 02897 st_attr_tab, pool); 02898 02899 } // New_Scope 02900 02901 02902 void 02903 Delete_Scope (SYMTAB_IDX level) 02904 { 02905 SCOPE& scope = Scope_tab[level]; 02906 02907 CXX_DELETE (scope.st_tab, scope.pool); 02908 CXX_DELETE (scope.label_tab, scope.pool); 02909 CXX_DELETE (scope.preg_tab, scope.pool); 02910 CXX_DELETE (scope.inito_tab, scope.pool); 02911 CXX_DELETE (scope.st_attr_tab, scope.pool); 02912 02913 } // Delete_Scope 02914 02915 02916 static void 02917 Setup_Preg_Pointers () 02918 { 02919 for (TYPE_ID i = MTYPE_FIRST; i <= MTYPE_LAST; ++i) { 02920 if (MTYPE_To_PREG (i) != NULL || MTYPE_To_TY (i) == 0) 02921 continue; 02922 Is_True (MTYPE_byte_size (i) < 4, ("Invalid mtype")); 02923 MTYPE_To_PREG (i) = MTYPE_signed (i) ? MTYPE_To_PREG (MTYPE_I4) : 02924 MTYPE_To_PREG (MTYPE_U4); 02925 } 02926 02927 if (ST_type(Int64_Preg) == Spill_Int_Type) 02928 Int_Preg = Int64_Preg; 02929 else 02930 Int_Preg = Int32_Preg; 02931 if (ST_type(Float32_Preg) == Spill_Float_Type) 02932 Float_Preg = Float32_Preg; 02933 else 02934 Float_Preg = Float64_Preg; 02935 } // Setup_Preg_Pointers 02936 02937 02938 static void 02939 Create_All_Preg_Symbols () 02940 { 02941 for (TYPE_ID i = MTYPE_FIRST; i <= MTYPE_LAST; ++i) { 02942 if (MTYPE_To_TY (i) == 0) 02943 continue; 02944 if (MTYPE_To_PREG (i) != NULL) 02945 continue; 02946 if (MTYPE_byte_size(i) < 4) { 02947 // special case: allow mtype_B 02948 if (i != MTYPE_B) continue; 02949 } 02950 02951 ST *st = New_ST (GLOBAL_SYMTAB); 02952 ST_Init (st, Save_Str2 (".preg_", MTYPE_name(i)), 02953 CLASS_PREG, SCLASS_REG, EXPORT_LOCAL, MTYPE_To_TY (i)); 02954 MTYPE_To_PREG(i) = st; 02955 } 02956 02957 if (Return_Val_Preg == NULL) { 02958 02959 ST *st = New_ST (GLOBAL_SYMTAB); 02960 ST_Init (st, Save_Str (".preg_return_val"), 02961 CLASS_PREG, SCLASS_REG, EXPORT_LOCAL, 0); 02962 Return_Val_Preg = st; 02963 } 02964 02965 Setup_Preg_Pointers (); 02966 } // Create_All_Preg_Symbols 02967 02968 02969 // for phases other then the front end, we read in the global symtab from 02970 // file, so we don't create the preg sybmols. But we still need to intialize 02971 // the MTYPE_TO_PREG_array. 02972 static void 02973 Set_up_all_preg_symbols () 02974 { 02975 UINT32 idx = 1; 02976 02977 UINT32 last = MIN (MTYPE_LAST + 1, ST_Table_Size (GLOBAL_SYMTAB)); 02978 02979 for (INT i = MTYPE_FIRST; i < last; ++i) { 02980 ST_IDX st_idx = make_ST_IDX (idx++, GLOBAL_SYMTAB); 02981 ST& st = St_Table[st_idx]; 02982 if (ST_sym_class (st) != CLASS_PREG) 02983 break; // ASSUME all predefined pregs are 02984 // placed before all other symbols 02985 02986 if (Return_Val_Preg == NULL) { 02987 if (strcmp (ST_name (&st), ".preg_return_val") == 0) { 02988 Return_Val_Preg = &st; 02989 continue; 02990 } 02991 } 02992 02993 TY_IDX ty_idx = ST_type (st); 02994 const TY& ty = Ty_Table[ty_idx]; 02995 TYPE_ID mtype = TY_mtype (ty); 02996 if (ty_idx != MTYPE_To_TY (mtype)) 02997 continue; 02998 MTYPE_To_PREG (mtype) = &st; 02999 } 03000 03001 // create any missing preg 03002 Create_All_Preg_Symbols (); 03003 03004 } // Set_up_all_preg_symbols 03005 03006 /* ==================================================================== 03007 * 03008 * Gen_Predef_Type_Name 03009 * 03010 * Just allocate and create a predefined type name 03011 * 03012 * ==================================================================== 03013 */ 03014 static inline STR_IDX 03015 Gen_predef_type_name (const char *basename) 03016 { 03017 return Save_Str2 (".predef_", basename); 03018 } 03019 03020 03021 /* ==================================================================== 03022 * 03023 * Create_Special_Global_Symbols 03024 * 03025 * Create special global symbols and types. These are created before 03026 * the per-file initialization, because they are used for various 03027 * global purposes like initializing the segment descriptors. 03028 * 03029 * This should only be called once per execution. 03030 * 03031 * ==================================================================== 03032 */ 03033 03034 static void 03035 Create_Special_Global_Symbols () 03036 { 03037 TY_IDX ty_idx; 03038 TY_KIND ty_kind = KIND_SCALAR; 03039 03040 /* Make predefined types for the machine types: */ 03041 for (TYPE_ID i = MTYPE_FIRST; i <= MTYPE_LAST; ++i) { 03042 03043 if (MTYPE_To_TY (i) != 0) 03044 continue; 03045 03046 TY &ty = New_TY (ty_idx); 03047 03048 ty_kind = KIND_SCALAR; 03049 if (MTYPE_align_req (i)) 03050 Set_TY_align (ty_idx, MTYPE_align_req(i)); 03051 03052 /* If this is one of the basic spill types, remember it: */ 03053 if ( i == Spill_Int_Mtype ) { 03054 Spill_Int_Type = ty_idx; 03055 } else if ( i == Spill_Float_Mtype ) { 03056 Spill_Float_Type = ty_idx; 03057 } 03058 if ( i == MTYPE_FQ ) 03059 Quad_Type = ty_idx; 03060 03061 #if defined(FRONT_END_C) || defined(FRONT_END_CPLUSPLUS) 03062 #ifndef FRONT_END_MFEF77 03063 if ( i == FE_int_To_Mtype() ) 03064 FE_int_Type = ty_idx; 03065 #endif /* FRONT_END_MFEF77 */ 03066 if ( i == MTYPE_F8 ) 03067 FE_double_Type = ty_idx; 03068 #endif /* FRONT_END_C || FRONT_END_CPLUSPLUS */ 03069 if ( i == MTYPE_V ) { 03070 Void_Type = ty_idx; 03071 ty_kind = KIND_VOID; 03072 } 03073 03074 if (i == MTYPE_A4 || i == MTYPE_A8) { 03075 if (MTYPE_byte_size (i) != Pointer_Size) { 03076 Ty_tab.Delete_last (); 03077 MTYPE_To_TY (i) = 0; 03078 continue; 03079 } 03080 03081 ty_kind = KIND_POINTER; 03082 TY_Init (ty, MTYPE_byte_size (i), ty_kind, i, 03083 Gen_predef_type_name (MTYPE_name (i))); 03084 Is_True (i > MTYPE_V, 03085 ("Create_Special_Global_Symbols() assumes MTYPE_V < " 03086 "MTYPE_A4 and MTYPE_A8")); 03087 Set_TY_pointed (ty, MTYPE_To_TY (MTYPE_V)); 03088 MTYPE_To_TY (i) = ty_idx; 03089 continue; 03090 } 03091 03092 TY_Init (ty, MTYPE_byte_size (i), ty_kind, i, 03093 Gen_predef_type_name (MTYPE_name (i))); 03094 MTYPE_To_TY (i) = ty_idx; 03095 } 03096 03097 } // Create_Special_Global_Symbols 03098 03099 03100 static inline BOOL 03101 Predefined_Void_Type (TY_IDX ty_idx) 03102 { 03103 const TY& ty = Ty_Table[ty_idx]; 03104 return (ty_idx == make_TY_IDX (TY_IDX_index (ty_idx)) && 03105 TY_mtype (ty) == MTYPE_V && TY_kind (ty) == KIND_VOID); 03106 03107 } // Predefined_Void_Type 03108 03109 03110 // In phases other then the frontends, we read in the global symtab from the 03111 // file, and that includes all the predefined global symbols and types. We 03112 // don't need to create them again, but we still need to initialize the 03113 // MTYPE_TO_TY array. 03114 void 03115 Initialize_Special_Global_Symbols () 03116 { 03117 // ASSUME all mtype TYs, if defined, are placed before any other TY's 03118 03119 UINT32 last = MIN (MTYPE_LAST + 1, TY_Table_Size()); 03120 // for trivial program, the type table may have less entry than MTYPE_LAST 03121 03122 for (UINT32 i = MTYPE_FIRST; i < last; ++i) { 03123 TY_IDX ty_idx = make_TY_IDX (i); 03124 const TY& ty = Ty_Table[ty_idx]; 03125 03126 TYPE_ID mtype = TY_mtype (ty); 03127 if (MTYPE_byte_size (mtype) != TY_size (ty) || 03128 TY_flags (ty) != 0) 03129 continue; 03130 switch (mtype) { 03131 case MTYPE_V: 03132 if (TY_kind (ty) != KIND_VOID) 03133 continue; 03134 break; 03135 03136 case MTYPE_A4: 03137 case MTYPE_A8: 03138 if (TY_kind (ty) != KIND_POINTER || 03139 ! Predefined_Void_Type (TY_pointed (ty))) 03140 continue; 03141 break; 03142 03143 default: 03144 if (TY_kind (ty) != KIND_SCALAR) 03145 continue; 03146 break; 03147 } 03148 if (MTYPE_align_req (mtype)) 03149 Set_TY_align (ty_idx, MTYPE_align_req (mtype)); 03150 MTYPE_To_TY (mtype) = ty_idx; 03151 } 03152 03153 // create any missing predefined types 03154 Create_Special_Global_Symbols (); 03155 03156 Spill_Int_Type = MTYPE_To_TY (Spill_Int_Mtype); 03157 Spill_Float_Type = MTYPE_To_TY (Spill_Float_Mtype); 03158 Quad_Type = MTYPE_To_TY (MTYPE_FQ); 03159 Void_Type = MTYPE_To_TY (MTYPE_V); 03160 03161 Set_up_all_preg_symbols (); 03162 03163 } // Initialize_Special_Global_Symbols 03164 03165 03166 // Initialize all symbol tables. This function must be called before any 03167 // symbol table operation is performed. 03168 // If reading the symtab from a file, then reserve_index_zero should be FALSE 03169 void 03170 Initialize_Symbol_Tables (BOOL reserve_index_zero) 03171 { 03172 if (Scope_tab != NULL) 03173 return; 03174 03175 Scope_tab = (SCOPE *) MEM_POOL_Alloc (Malloc_Mem_Pool, 03176 Max_scope * sizeof(SCOPE)); 03177 memset(Scope_tab, '\0', Max_scope * sizeof(SCOPE)); 03178 03179 memset (MTYPE_TO_PREG_array, '\0', sizeof(ST*) * (MTYPE_LAST + 1)); 03180 memset (MTYPE_TO_TY_array, '\0', sizeof(TY_IDX) * (MTYPE_LAST + 1)); 03181 03182 if (reserve_index_zero) { 03183 // For producer, we reserve first entry for all global tables 03184 03185 Initialize_Strtab (0x1000); // start with 4Kbytes for strtab. 03186 03187 UINT dummy_idx; 03188 memset (&New_PU ((PU_IDX&) dummy_idx), '\0', sizeof(PU)); 03189 memset (&New_TY ((TY_IDX&) dummy_idx), '\0', sizeof(TY)); 03190 memset (New_FLD ().Entry(), '\0', sizeof(FLD)); 03191 memset (&New_TYLIST ((TYLIST_IDX&) dummy_idx), '\0', sizeof(TYLIST)); 03192 memset (New_ARB ().Entry(), '\0', sizeof(ARB)); 03193 memset (&New_BLK ((BLK_IDX&) dummy_idx), '\0', sizeof(BLK)); 03194 memset (&Initv_Table.New_entry ((INITV_IDX&) dummy_idx), '\0', 03195 sizeof(INITV)); 03196 Init_Constab (); 03197 New_Scope (GLOBAL_SYMTAB, Malloc_Mem_Pool, TRUE); 03198 03199 Create_Special_Global_Symbols (); 03200 Create_All_Preg_Symbols(); 03201 } 03202 #ifdef BACK_END 03203 if (!Read_Global_Data) { 03204 // reserve zero index in BLK table 03205 UINT blk_idx; 03206 memset (&New_BLK ((BLK_IDX&) blk_idx), '\0', sizeof(BLK)); 03207 } 03208 #endif 03209 } 03210 03211 //---------------------------------------------------------------------- 03212 // TCON 03213 //---------------------------------------------------------------------- 03214 TCON_IDX 03215 Enter_tcon (const TCON& tcon) 03216 { 03217 switch (TCON_ty (tcon)) { 03218 case MTYPE_F4: 03219 if (TCON_ival (tcon) == 0) 03220 return 1; 03221 case MTYPE_F8: 03222 if (TCON_k0 (tcon) == 0) 03223 return 2; 03224 default: 03225 return Tcon_Table.Insert (tcon); 03226 } 03227 } // Enter_tcon 03228 03229 03230 void 03231 Init_Constab () 03232 { 03233 if (Tcon_Table.Size () == 0) { 03234 TCON Zero; 03235 UINT32 idx; 03236 memset (&Zero, '\0', sizeof(TCON)); 03237 idx = Tcon_Table.Insert (Zero); // index 0: dummy 03238 Set_TCON_ty (Zero, MTYPE_F4); 03239 idx = Tcon_Table.Insert (Zero); // index 1: float (0.0) 03240 Set_TCON_ty (Zero, MTYPE_F8); 03241 idx = Tcon_Table.Insert (Zero); // index 2: double (0.0) 03242 03243 Is_True (idx == MAX_PREDEFINED_TCON_IDX, 03244 ("Number of predefined tcons incorrect")); 03245 03246 Initialize_TCON_strtab (1024); // string table for TCONs 03247 } 03248 } 03249 03250 03251 #ifdef Is_True_On 03252 03253 // 03254 // Additional debugging functions because Workshop can't deal with 03255 // the [] operator correctly. 03256 // 03257 03258 ST ST_from_IDX(ST_IDX x) {return St_Table[x];} 03259 TY TY_from_IDX(TY_IDX x) {return Ty_Table[x];} 03260 INITO INITO_from_IDX(INITO_IDX x) {return Inito_Table[x];} 03261 INITV INITV_from_IDX(INITV_IDX x) {return Initv_Table[x];} 03262 PU PU_from_IDX(PU_IDX x) {return Pu_Table[x];} 03263 ARB ARB_from_IDX(ARB_IDX x) {return Arb_Table[x];} 03264 TCON TCON_from_IDX(TCON_IDX x) {return Tcon_Table[x];} 03265 FLD FLD_from_IDX(FLD_IDX x) {return Fld_Table[x];} 03266 LABEL LABEL_from_IDX(LABEL_IDX x) {return Label_Table[x];} 03267 TYLIST TYLIST_from_IDX(TYLIST_IDX x) {return Tylist_Table[x];} 03268 03269 #endif // Is_True_On