00001
00002
00003
00004
00005
00006
00007
00008
00009
00010
00011
00012
00013
00014
00015
00016
00017
00018
00019
00020
00021
00022
00023
00024
00025
00026
00027
00028
00029
00030
00031
00032
00033
00034
00035
00036
00037
00038
00039
00040
00041
00042
00043
00044
00045
00046
00047
00048
00049
00050
00051
00052
00053
00054
00055
00056
00057
00058
00059
00060
00061
00062
00063
00064
00065
00066 #define __STDC_LIMIT_MACROS
00067 #include <stdint.h>
00068 #include "linker.h"
00069
00070 #include "defs.h"
00071 #include "cxx_memory.h"
00072 #include "errors.h"
00073 #include "irbdata.h"
00074 #include "strtab.h"
00075
00076 #include "ld_ipa_interface.h"
00077 #include "ipc_defs.h"
00078 #include "dwarf_DST_mem.h"
00079 #include "ipc_file.h"
00080 #include "ipc_weak.h"
00081 #include "ipa_option.h"
00082 #include "ipc_type_merge.h"
00083
00084 #include "ipc_symtab_merge.h"
00085
00086 AUX_ST_TAB Aux_St_Tab;
00087 AUX_ST_TABLE Aux_St_Table;
00088 static UINT32 num_predefined_st;
00089
00090
00091 AUX_PU_TAB Aux_Pu_Table;
00092
00093 static IP_FILE_HDR* current_file_hdr;
00094
00095 #include "ipc_ty_hash.h"
00096
00097
00098
00099
00100
00101
00102 typedef STR_IDX_MAP TCONSTR_IDX_MAP;
00103 typedef hash_map<UINT32,UINT32> ST_TO_INITO_MAP;
00104
00105
00106
00107
00108 struct eq_tcon
00109 {
00110 bool operator () (const TCON* t1, const TCON* t2) const {
00111 if (TCON_ty (*t1) != TCON_ty (*t2))
00112 return FALSE;
00113 if (t1->flags != t2->flags)
00114 return FALSE;
00115 switch (TCON_ty (*t1)) {
00116
00117 case MTYPE_I1:
00118 case MTYPE_I2:
00119 case MTYPE_I4:
00120 case MTYPE_I8:
00121 case MTYPE_U1:
00122 case MTYPE_U2:
00123 case MTYPE_U4:
00124 case MTYPE_U8:
00125 return TCON_i0 (*t1) == TCON_i0 (*t2);
00126
00127 case MTYPE_F4:
00128 return TCON_ival (*t1) == TCON_ival (*t2);
00129
00130 case MTYPE_F8:
00131 return TCON_k0 (*t1) == TCON_k0 (*t2);
00132
00133 case MTYPE_STR:
00134 return (TCON_str_idx (*t1) == TCON_str_idx (*t2) &&
00135 TCON_str_len (*t1) == TCON_str_len (*t2));
00136
00137 default:
00138 return memcmp (t1, t2, sizeof(TCON)) == 0;
00139 }
00140 }
00141 };
00142
00143
00144 struct tcon_hash
00145 {
00146 size_t operator() (const TCON* tcon) const {
00147 size_t val = TCON_ty (*tcon);
00148 val ^= TCON_ival (*tcon);
00149 return val;
00150 }
00151 };
00152
00153 typedef hash_map<const TCON*, TCON_IDX, tcon_hash, eq_tcon,
00154 mempool_allocator<TCON_IDX> > TCON_MERGE_MAP;
00155
00156 struct eq_const_st
00157 {
00158 bool operator() (const ST* st1, const ST* st2) const {
00159 return memcmp (st1, st2, sizeof(ST) - sizeof(ST_IDX) * 2) == 0;
00160 }
00161 };
00162
00163 struct const_st_hash
00164 {
00165 size_t operator() (const ST* st) const {
00166 Is_True (ST_class (st) == CLASS_CONST,
00167 ("cannot merge non-constant STs"));
00168 return ST_tcon (st);
00169 }
00170 };
00171
00172 typedef hash_map<const ST*, ST_IDX, const_st_hash, eq_const_st,
00173 mempool_allocator<ST_IDX> > ST_MERGE_MAP;
00174
00175 static TCON_MERGE_MAP* tcon_merge_map;
00176 static ST_MERGE_MAP* st_merge_map;
00177 static MEM_POOL merge_pool;
00178
00179
00180
00181
00182
00183 static SYMSTR_IDX_MAP *New_Symstr_Idx;
00184 static ST_IDX_MAP *New_St_Idx;
00185 static TY_IDX_MAP *New_Ty_Idx;
00186 static TCON_IDX_MAP *New_Tcon_Idx;
00187 static ST_TO_INITO_MAP *St_To_Inito_Map;
00188
00189
00190 ST_TO_INITO_MAP ST_To_INITO_Map;
00191
00192
00193 COMMON_BLOCK_ELEMENTS_MAP *Common_Block_Elements_Map = NULL;
00194 static MEM_POOL Common_map_pool;
00195
00196 #if (defined(_STANDALONE_INLINER) || defined(_LIGHTWEIGHT_INLINER))
00197
00198 static UINT32
00199 count_pregs()
00200 {
00201 int i;
00202 ST* s;
00203 UINT32 result=0;
00204 FOREACH_SYMBOL (GLOBAL_SYMTAB, s, i) {
00205 if (ST_class (s) == CLASS_PREG)
00206 ++result;
00207 }
00208 return result;
00209 }
00210
00211 static ST*
00212 get_global_st(char* symname)
00213 {
00214 int i;
00215 ST* s;
00216 FOREACH_SYMBOL (GLOBAL_SYMTAB, s, i) {
00217 if ((*ST_name(s) == *symname) && (strcmp(ST_name(s), symname) == 0))
00218 return s;
00219 }
00220 return NULL;
00221 }
00222 #endif // _STANDALONE_INLINER
00223
00224
00225
00226
00227 void
00228 Initialize_Auxiliary_Tables ()
00229 {
00230 const UINT32 st_size = ST_Table_Size (GLOBAL_SYMTAB);
00231 #if (defined(_STANDALONE_INLINER) || defined(_LIGHTWEIGHT_INLINER))
00232 num_predefined_st = count_pregs()+1;
00233 #else // _STANDALONE_INLINER
00234 num_predefined_st = st_size;
00235 #endif // _STANDALONE_INLINER
00236
00237 Scope_tab[GLOBAL_SYMTAB].st_tab->Register (Aux_St_Tab);
00238
00239 const AUX_PU aux_pu;
00240 Aux_Pu_Table.Insert (aux_pu);
00241
00242 MEM_POOL_Initialize (&merge_pool, "tcon merge pool", FALSE);
00243 tcon_merge_map = CXX_NEW (TCON_MERGE_MAP (1000, tcon_hash (),
00244 eq_tcon (), &merge_pool),
00245 &merge_pool);
00246 st_merge_map = CXX_NEW (ST_MERGE_MAP (1000, const_st_hash (),
00247 eq_const_st (), &merge_pool),
00248 &merge_pool);
00249
00250 MEM_POOL_Initialize (&Common_map_pool, "common map pool", FALSE);
00251 Common_Block_Elements_Map =
00252 CXX_NEW (COMMON_BLOCK_ELEMENTS_MAP (100, __gnu_cxx::hash<ST_IDX> (),
00253 std::equal_to<ST_IDX> (),
00254 &Common_map_pool),
00255 &Common_map_pool);
00256
00257 }
00258
00259 void
00260 Print_AUX_ST_flags ( FILE *fp, const mUINT32 flags )
00261 {
00262 char c = '(';
00263
00264 fprintf(fp, "\t\tAUX_ST_flag: %x ", flags );
00265 if ( !flags ) {
00266 fprintf(fp, "\n");
00267 return;
00268 }
00269 if ( flags & USED_IN_OBJ ) {
00270 fprintf(fp, "%cUSED_IN_OBJ", c);
00271 c = '|';
00272 }
00273 if ( flags & USED_IN_DSO ) {
00274 fprintf(fp, "%cUSED_IN_DSO", c);
00275 c = '|';
00276 }
00277 if ( flags & DEF_IN_OBJ ) {
00278 fprintf(fp, "%cDEF_IN_OBJ", c);
00279 c = '|';
00280 }
00281 if ( flags & DEF_IN_DSO ) {
00282 fprintf(fp, "%cDEF_IN_DSO", c);
00283 c = '|';
00284 }
00285 if ( flags & OBJ_COMMON ) {
00286 fprintf(fp, "%cOBJ_COMMON", c);
00287 c = '|';
00288 }
00289 if ( flags & ADDR_TAKEN_IN_OBJ ) {
00290 fprintf(fp, "%cADDR_TAKEN_IN_OBJ", c);
00291 c = '|';
00292 }
00293 if ( flags & COMMON_USED_IN_IO ) {
00294 fprintf(fp, "%cCOMMON_USED_IN_IO", c);
00295 c = '|';
00296 }
00297 fprintf(fp, ")\n");
00298 }
00299
00300
00301 void
00302 Clear_Extra_Auxiliary_Tables ()
00303 {
00304 MEM_POOL_Delete (&merge_pool);
00305 tcon_merge_map = NULL;
00306 st_merge_map = NULL;
00307 }
00308
00309 void
00310 Clear_Common_Block_Element_Map ()
00311 {
00312 if (Common_Block_Elements_Map) {
00313 MEM_POOL_Delete (&Common_map_pool);
00314 Common_Block_Elements_Map = NULL;
00315 }
00316 }
00317
00318
00319
00320
00321
00322
00323
00324
00325
00326 static inline
00327 void Set_INITV_next(INITV &inv, INITV_IDX next)
00328 {
00329 inv.next = next;
00330 }
00331
00332 static inline
00333 ST_IDX INITV_symoff_st( const INITV &inv)
00334 {
00335 return inv.u.sto.st;
00336 }
00337
00338 static inline
00339 void Set_INITV_symoff_st(INITV &inv, ST_IDX st_idx)
00340 {
00341 inv.u.sto.st = st_idx;
00342 }
00343
00344 static inline
00345 ST_IDX INITV_symdiff_st( const INITV &inv)
00346 {
00347 return inv.u.stdiff.st2;
00348 }
00349
00350 static inline
00351 void Set_INITV_symdiff_st(INITV &inv, ST_IDX st_idx)
00352 {
00353 inv.u.stdiff.st2 = st_idx;
00354 }
00355
00356 static inline
00357 INITV_IDX INITV_block_first( const INITV &inv)
00358 {
00359 return inv.u.blk.blk;
00360 }
00361
00362 static inline
00363 void Set_INITV_block_first(INITV &inv, INITV_IDX first_member)
00364 {
00365 inv.u.blk.blk = first_member;
00366 }
00367
00368
00369 static inline
00370 TCON_IDX INITV_tcon(const INITV &inv)
00371 {
00372 return inv.u.tcval.u.tc;
00373 }
00374
00375 static inline
00376 void Set_INITV_tcon(INITV &inv, TCON_IDX tcon_idx)
00377 {
00378 inv.u.tcval.u.tc = tcon_idx;
00379 }
00380
00381
00382 static inline
00383 void Set_TCON_string_ptr(TCON &tc, STR_IDX cp)
00384 {
00385 tc.vals.sval.cp = cp;
00386 }
00387
00388 static inline
00389 STR_IDX TCON_string_ptr(const TCON &tc)
00390 {
00391 return tc.vals.sval.cp;
00392 }
00393
00394 static inline ST_IDX
00395 ST_raw_base_idx (const ST& st)
00396 {
00397 return st.base_idx;
00398 }
00399 static inline void
00400 Set_ST_raw_base_idx (ST& st, ST_IDX base)
00401 {
00402 st.base_idx = base;
00403 }
00404
00405 static inline BOOL
00406 FLD_last_field (const FLD* fld)
00407 {
00408 return fld->flags & FLD_LAST_FIELD;
00409 }
00410
00411
00412
00413
00414
00415
00416 static ST_IDX
00417 Merge_Global_St(UINT idx,
00418 const IPC_GLOBAL_TABS& original_tabs);
00419
00420 static TY_IDX
00421 Merge_Global_Ty(TY_IDX ty_idx,
00422 const IPC_GLOBAL_TABS &original_tabs,
00423 BOOL &created_new,
00424 TY_INDEX &recursive_type);
00425
00426
00427
00428
00429 static void
00430 Reset_recursive_type_mapping (TY_INDEX orig_idx, TY_IDX new_ty_idx,
00431 const IPC_GLOBAL_TABS& original_tabs)
00432 {
00433 if (New_Ty_Idx->is_merging (orig_idx))
00434 return;
00435
00436 if (TY_IDX_index (New_Ty_Idx->map_[orig_idx]) == TY_IDX_index (new_ty_idx))
00437 return;
00438
00439 New_Ty_Idx->set_map (orig_idx, new_ty_idx);
00440 New_Ty_Idx->set_is_merging (orig_idx);
00441
00442 const TY& old_ty = original_tabs.ty_tab[orig_idx];
00443 const TY& new_ty = Ty_Table[new_ty_idx];
00444
00445 switch (TY_kind (old_ty)) {
00446
00447 case KIND_ARRAY:
00448 Reset_recursive_type_mapping (TY_IDX_index (TY_etype (old_ty)),
00449 TY_etype (new_ty), original_tabs);
00450 break;
00451
00452 case KIND_POINTER:
00453 Reset_recursive_type_mapping (TY_IDX_index (TY_pointed (old_ty)),
00454 TY_pointed (new_ty), original_tabs);
00455 break;
00456
00457 case KIND_FUNCTION:
00458 {
00459 TYLIST_IDX old_tylist_idx = TY_tylist (old_ty);
00460 TYLIST_IDX new_tylist_idx = TY_tylist (new_ty);
00461
00462 TYLIST old_tylist = original_tabs.tylist_tab[old_tylist_idx];
00463 TYLIST new_tylist = Tylist_Table[new_tylist_idx];
00464
00465 do {
00466
00467 TY_INDEX old_index = TY_IDX_index (TYLIST_type (old_tylist));
00468 TY_IDX new_index = TYLIST_type (new_tylist);
00469
00470 Reset_recursive_type_mapping (old_index, new_index,
00471 original_tabs);
00472
00473 ++old_tylist_idx;
00474 ++new_tylist_idx;
00475
00476 old_tylist = original_tabs.tylist_tab[old_tylist_idx];
00477 new_tylist = Tylist_Table[new_tylist_idx];
00478 } while (TYLIST_type (old_tylist) != 0);
00479
00480 break;
00481 }
00482
00483 case KIND_STRUCT:
00484 {
00485 FLD_IDX old_fld_idx = old_ty.Fld ();
00486 FLD_IDX new_fld_idx = new_ty.Fld ();
00487
00488 if (new_fld_idx == 0)
00489 break;
00490
00491 const FLD* old_fld;
00492 const FLD* new_fld;
00493
00494 do {
00495 old_fld = &original_tabs.fld_tab[old_fld_idx];
00496 new_fld = &Fld_Table[new_fld_idx];
00497
00498 TY_INDEX old_index = TY_IDX_index (old_fld->type);
00499 TY_IDX new_index = new_fld->type;
00500
00501 Reset_recursive_type_mapping (old_index, new_index,
00502 original_tabs);
00503 ++old_fld_idx;
00504 ++new_fld_idx;
00505 } while (!FLD_last_field (old_fld));
00506
00507 break;
00508 }
00509
00510 default:
00511 break;
00512 }
00513
00514 New_Ty_Idx->clear_all_index_flags (orig_idx);
00515
00516 }
00517
00518
00519 static ARB_IDX
00520 Merge_Arb(ARB_IDX arb_idx, ARB *arb_tab)
00521 {
00522
00523
00524
00525
00526
00527 ARB_IDX new_idx = Arb_Table.Insert (arb_tab[arb_idx]);
00528 ARB_IDX idx=new_idx;
00529
00530 while (!ARB_last_dimen (ARB_HANDLE(idx))) {
00531 ++arb_idx;
00532 idx = Arb_Table.Insert (arb_tab[arb_idx]);
00533 }
00534
00535 return new_idx;
00536 }
00537
00538
00539 static TYLIST_IDX
00540 Merge_Tylist(TYLIST_IDX tylist_idx,
00541 const IPC_GLOBAL_TABS &original_tabs,
00542 BOOL &created_new,
00543 TY_INDEX &recursive_type)
00544 {
00545 created_new = FALSE;
00546 recursive_type = 0;
00547
00548 if (tylist_idx == 0)
00549 return 0;
00550
00551 TYLIST_IDX result = TYLIST_Table_Size ();
00552
00553 TYLIST* orig_tylist = &(original_tabs.tylist_tab[tylist_idx]);
00554
00555
00556 do {
00557 (void) Tylist_Table.Insert (*orig_tylist);
00558 } while (TYLIST_type (*orig_tylist++) != 0);
00559
00560 orig_tylist = &(original_tabs.tylist_tab[tylist_idx]);
00561 TYLIST_IDX idx = result;
00562
00563 while (TYLIST_type (*orig_tylist) != 0) {
00564 BOOL ty_is_created;
00565 TY_INDEX ty_is_recursive;
00566 TY_IDX new_ty_idx =
00567 Merge_Global_Ty (TYLIST_type (*orig_tylist), original_tabs,
00568 ty_is_created, ty_is_recursive);
00569
00570
00571 Set_TYLIST_type (Tylist_Table[idx], new_ty_idx);
00572
00573 created_new = (created_new || ty_is_created);
00574 if (recursive_type == 0)
00575 recursive_type = ty_is_recursive;
00576 else if (recursive_type > ty_is_recursive)
00577 recursive_type = ty_is_recursive;
00578
00579 ++idx;
00580 ++orig_tylist;
00581 }
00582
00583 return result;
00584
00585 }
00586
00587
00588 static FLD_HANDLE
00589 Merge_Flds(FLD_IDX fld_idx,
00590 const IPC_GLOBAL_TABS &original_tabs,
00591 BOOL &created_new,
00592 TY_INDEX &recursive_type)
00593 {
00594 created_new = FALSE;
00595 recursive_type = 0;
00596
00597 if (fld_idx == 0)
00598 return FLD_HANDLE (0);
00599
00600 FLD_IDX result = FLD_Table_Size ();
00601
00602
00603 UINT count = 0;
00604 const FLD* orig_fld = original_tabs.fld_tab + fld_idx;
00605 do {
00606 (void) Fld_Table.Insert (*orig_fld);
00607 ++count;
00608 } while (!FLD_last_field (orig_fld++));
00609
00610 FLD_ITER iter = Make_fld_iter (FLD_HANDLE (result));
00611
00612 while (count--) {
00613 FLD_HANDLE fld (iter);
00614
00615 STR_IDX new_name_idx = (*New_Symstr_Idx)[FLD_name_idx (fld)];
00616 Set_FLD_name_idx (fld, new_name_idx);
00617
00618 BOOL ty_is_created;
00619 TY_INDEX ty_is_recursive;
00620
00621 TY_IDX new_ty_idx =
00622 Merge_Global_Ty (FLD_type (fld), original_tabs, ty_is_created,
00623 ty_is_recursive);
00624
00625 Set_FLD_type (fld, new_ty_idx);
00626
00627 created_new = (created_new || ty_is_created);
00628 if (ty_is_recursive) {
00629 if (recursive_type == 0)
00630 recursive_type = ty_is_recursive;
00631 else if (recursive_type > ty_is_recursive)
00632 recursive_type = ty_is_recursive;
00633 }
00634
00635
00636
00637 Set_FLD_st (fld, 0);
00638 ++iter;
00639 }
00640
00641 return FLD_HANDLE (result);
00642
00643 }
00644
00645
00646 struct CHECKPOINT
00647 {
00648 UINT32 ty_tab_idx;
00649 UINT32 fld_tab_idx;
00650 UINT32 arb_tab_idx;
00651 UINT32 tylist_tab_idx;
00652
00653 CHECKPOINT () {
00654 ty_tab_idx = TY_Table_Size ();
00655 fld_tab_idx = FLD_Table_Size ();
00656 arb_tab_idx = ARB_Table_Size ();
00657 tylist_tab_idx = TYLIST_Table_Size ();
00658 }
00659
00660 void restore () const {
00661 Ty_tab.Delete_down_to (ty_tab_idx);
00662 Fld_Table.Delete_down_to (fld_tab_idx);
00663 Arb_Table.Delete_down_to (arb_tab_idx);
00664 Tylist_Table.Delete_down_to (tylist_tab_idx);
00665 }
00666 };
00667
00668 struct merge_array
00669 {
00670 void operator() (const TY& orig_ty, TY& new_ty,
00671 const IPC_GLOBAL_TABS& original_tabs,
00672 BOOL& created_new, TY_INDEX& recursive_type) const {
00673
00674
00675
00676
00677
00678
00679 Set_TY_etype (new_ty, 0);
00680 Set_TY_arb (new_ty, ARB_HANDLE());
00681
00682 TY_IDX etype_idx = TY_etype (orig_ty);
00683 TY_IDX new_etype_idx =
00684 Merge_Global_Ty (etype_idx, original_tabs, created_new,
00685 recursive_type);
00686 Set_TY_etype (new_ty, Replace_TY_IDX_index (etype_idx,
00687 new_etype_idx));
00688
00689
00690
00691 ARB_IDX new_arb_idx = Merge_Arb (orig_ty.Arb (),
00692 original_tabs.arb_tab);
00693 Set_TY_arb(new_ty, ARB_HANDLE(new_arb_idx));
00694 }
00695
00696 };
00697
00698
00699 struct merge_pointer
00700 {
00701 void operator() (const TY& orig_ty, TY& new_ty,
00702 const IPC_GLOBAL_TABS &original_tabs,
00703 BOOL &created_new, TY_INDEX& recursive_type) const {
00704
00705 Set_TY_pointed (new_ty, 0);
00706
00707 TY_IDX pointed_idx = TY_pointed(orig_ty);
00708 TY_IDX new_pointed_idx =
00709 Merge_Global_Ty (pointed_idx, original_tabs, created_new,
00710 recursive_type);
00711 Set_TY_pointed (new_ty, Replace_TY_IDX_index (pointed_idx,
00712 new_pointed_idx));
00713 }
00714
00715 };
00716
00717
00718 struct merge_function
00719 {
00720 void operator() (const TY& orig_ty, TY& new_ty,
00721 const IPC_GLOBAL_TABS &original_tabs,
00722 BOOL &created_new, TY_INDEX& recursive_type) const {
00723
00724 Set_TY_tylist (new_ty, 0);
00725
00726 TYLIST_IDX tylist_idx = TY_tylist(orig_ty);
00727 TYLIST_IDX new_tylist_idx =
00728 Merge_Tylist (tylist_idx, original_tabs, created_new,
00729 recursive_type);
00730 Set_TY_tylist(new_ty, new_tylist_idx);
00731
00732 }
00733
00734 };
00735
00736
00737 struct merge_struct
00738 {
00739 void operator() (const TY& orig_ty, TY& new_ty,
00740 const IPC_GLOBAL_TABS &original_tabs,
00741 BOOL &created_new, TY_INDEX& recursive_type) const {
00742
00743 Set_TY_fld (new_ty, FLD_HANDLE (0));
00744
00745 FLD_HANDLE new_fld = Merge_Flds (orig_ty.Fld(), original_tabs,
00746 created_new, recursive_type);
00747 Set_TY_fld (new_ty, new_fld);
00748 }
00749
00750 };
00751
00752
00753 template <class MERGE_OPERATION>
00754 static TY_IDX
00755 merge_ty (TY_IDX ty_idx, const IPC_GLOBAL_TABS &original_tabs,
00756 BOOL& created_new, TY_INDEX& recursive_type,
00757 const MERGE_OPERATION& do_merge)
00758 {
00759
00760
00761
00762
00763
00764
00765 CHECKPOINT chkpt;
00766
00767 TY_INDEX idx = TY_IDX_index (ty_idx);
00768 TY &this_ty = original_tabs.ty_tab[idx];
00769 TY_INDEX new_idx = Ty_tab.Insert(this_ty);
00770 created_new = TRUE;
00771 TY &new_ty = Ty_tab[new_idx];
00772
00773
00774
00775
00776 TY_IDX new_ty_idx = make_TY_IDX (new_idx, ty_idx);
00777 New_Ty_Idx->set_map(idx, new_ty_idx);
00778 New_Ty_Idx->set_is_merging(idx);
00779
00780
00781
00782 Set_TY_name_idx(new_ty, (*New_Symstr_Idx)[TY_name_idx(this_ty)]);
00783
00784
00785
00786
00787 BOOL is_new = TRUE;
00788
00789 do_merge (this_ty, new_ty, original_tabs, is_new, recursive_type);
00790
00791 New_Ty_Idx->clear_all_index_flags (idx);
00792
00793
00794
00795
00796
00797
00798
00799 if (!is_new) {
00800
00801 Is_True (recursive_type <= new_idx, ("Invalid recursive type merge"));
00802
00803 if (recursive_type == 0 || recursive_type == new_idx) {
00804
00805 recursive_type = 0;
00806 TY_IDX unique_idx = TY_is_unique(new_ty_idx);
00807
00808 if (unique_idx != new_ty_idx) {
00809
00810
00811 new_ty_idx = unique_idx;
00812 Reset_recursive_type_mapping (idx, new_ty_idx, original_tabs);
00813
00814 chkpt.restore ();
00815 created_new = FALSE;
00816 }
00817 } else
00818 created_new = FALSE;
00819 } else {
00820
00821 TY_is_unique (new_ty_idx);
00822 }
00823 return new_ty_idx;
00824 }
00825
00826
00827 static TY_IDX
00828 Merge_Global_Ty(TY_IDX ty_idx,
00829 const IPC_GLOBAL_TABS &original_tabs,
00830 BOOL &created_new,
00831 TY_INDEX &recursive_type)
00832 {
00833
00834
00835
00836
00837
00838
00839
00840
00841
00842
00843
00844
00845
00846
00847
00848
00849
00850
00851
00852
00853
00854
00855
00856
00857
00858
00859
00860
00861
00862
00863
00864
00865
00866
00867
00868
00869
00870
00871 TY_INDEX idx = TY_IDX_index (ty_idx);
00872 TY_IDX new_idx = (*New_Ty_Idx)[ty_idx];
00873
00874 if (TY_IDX_index (new_idx) != 0) {
00875 created_new = FALSE;
00876 if (New_Ty_Idx->is_merging (idx)) {
00877 recursive_type = TY_IDX_index (new_idx);
00878 } else
00879 recursive_type = 0;
00880 } else {
00881
00882
00883
00884
00885 created_new = FALSE;
00886 recursive_type = 0;
00887
00888 const TY& ty = original_tabs.ty_tab[idx];
00889
00890 switch (TY_kind (ty)) {
00891 case KIND_SCALAR:
00892 case KIND_VOID:
00893 new_idx = MTYPE_To_TY(TY_mtype (ty));
00894 if (TY_flags(ty) != TY_flags (Ty_Table[new_idx])) {
00895 new_idx = make_TY_IDX (Ty_tab.Insert (ty), ty_idx);
00896 TY& new_ty = Ty_Table[new_idx];
00897 Set_TY_name_idx (new_ty, (*New_Symstr_Idx)[TY_name_idx(ty)]);
00898 }
00899 New_Ty_Idx->set_map(idx, new_idx);
00900 break;
00901
00902 case KIND_ARRAY:
00903 new_idx = merge_ty (ty_idx, original_tabs, created_new,
00904 recursive_type, merge_array ());
00905 break;
00906
00907 case KIND_POINTER:
00908 new_idx = merge_ty (ty_idx, original_tabs, created_new,
00909 recursive_type, merge_pointer ());
00910 break;
00911
00912 case KIND_FUNCTION:
00913 new_idx = merge_ty (ty_idx, original_tabs, created_new,
00914 recursive_type, merge_function ());
00915 break;
00916
00917 case KIND_STRUCT:
00918 new_idx = merge_ty (ty_idx, original_tabs, created_new,
00919 recursive_type, merge_struct ());
00920 break;
00921
00922 case KIND_INVALID:
00923 case KIND_LAST:
00924 default:
00925 Fail_FmtAssertion ("invalid TY_KIND in Merge_Global_Ty");
00926 break;
00927 }
00928
00929 }
00930
00931 return new_idx;
00932 }
00933
00934
00935
00936
00937
00938
00939 static inline void
00940 copy_tcon (TCON& dest, const TCON& src, const TCONSTR_IDX_MAP& tconstr_map)
00941 {
00942 dest.ty = src.ty;
00943 dest.flags = src.flags;
00944 switch (TCON_ty (src)) {
00945 case MTYPE_I1:
00946 case MTYPE_I2:
00947 case MTYPE_I4:
00948 case MTYPE_I8:
00949 case MTYPE_U1:
00950 case MTYPE_U2:
00951 case MTYPE_U4:
00952 case MTYPE_U8:
00953 dest.vals.i0 = TCON_i0 (src);
00954 break;
00955 case MTYPE_F4:
00956 dest.vals.fval = TCON_fval (src);
00957 break;
00958 case MTYPE_F8:
00959 dest.vals.dval = TCON_dval (src);
00960 break;
00961 case MTYPE_STR:
00962 Set_TCON_string_ptr (dest, tconstr_map[TCON_string_ptr(src)]);
00963 dest.vals.sval.len = TCON_str_len (src);
00964 break;
00965 default:
00966 dest.vals = src.vals;
00967 dest.cmplxval = src.cmplxval;
00968 }
00969 }
00970
00971
00972 static void
00973 Merge_Global_Tcon(const TCON* tcon_tab, UINT32 size,
00974 TCON_IDX_MAP& tcon_map, const TCONSTR_IDX_MAP& tconstr_map)
00975 {
00976
00977
00978
00979
00980
00981
00982
00983
00984
00985
00986
00987
00988 UINT32 idx;
00989 for (idx = 0; idx <= MAX_PREDEFINED_TCON_IDX; ++idx)
00990 tcon_map.set_map (idx, idx);
00991
00992 for (; idx < size; ++idx) {
00993
00994
00995
00996
00997
00998
00999
01000
01001 const TCON& this_tcon = tcon_tab[idx];
01002 TCON new_tcon = { 0 };
01003 copy_tcon (new_tcon, this_tcon, tconstr_map);
01004
01005 TCON_MERGE_MAP::const_iterator tc =
01006 tcon_merge_map->find (&new_tcon);
01007
01008 if (tc != tcon_merge_map->end ()) {
01009 tcon_map.set_map (idx, (*tc).second);
01010 continue;
01011 }
01012
01013 TCON_IDX new_idx = Tcon_Table.Insert(new_tcon);
01014 (*tcon_merge_map)[&Tcon_Table[new_idx]] = new_idx;
01015 tcon_map.set_map(idx, new_idx);
01016 }
01017 }
01018
01019
01020
01021
01022
01023
01024 static PU_IDX
01025 Merge_Global_Pu(UINT pu_idx, const IPC_GLOBAL_TABS& original_tabs)
01026 {
01027
01028
01029
01030
01031 Is_True (pu_idx != 0, ("Invalid pu_idx"));
01032
01033 PU &this_pu = original_tabs.pu_tab[pu_idx];
01034
01035 PU_IDX new_idx = Pu_Table.Insert(this_pu);
01036
01037
01038
01039
01040 TY_IDX prototype_idx = (*New_Ty_Idx)[PU_prototype(this_pu)];
01041 Set_PU_prototype(Pu_Table[new_idx], prototype_idx);
01042
01043
01044 if (PU_base_class(this_pu) != TY_IDX_ZERO) {
01045 TY_IDX base_class_idx = (*New_Ty_Idx)[PU_base_class(this_pu)];
01046 Set_PU_base_class(Pu_Table[new_idx], base_class_idx);
01047 }
01048
01049
01050 UINT32 aux_idx;
01051 AUX_PU& aux_pu = Aux_Pu_Table.New_entry (aux_idx);
01052 aux_pu.construct ();
01053
01054 Is_True (new_idx == aux_idx, ("Aux_PU_Table out of sync."));
01055
01056 return new_idx;
01057 }
01058
01059
01060 static inline void
01061 Invalidate_inito (const ST& st, INITO *inito_tab)
01062 {
01063 UINT32 st_index = ST_IDX_index(ST_st_idx(st));
01064 INITO_IDX inito_idx = (*St_To_Inito_Map)[st_index];
01065 INITO& inito = inito_tab[inito_idx];
01066
01067 Set_INITO_st_idx(inito, UNINITIALIZED_INDEX);
01068 }
01069
01070
01071 static void
01072 Resolve_Sclass(const IPC_GLOBAL_TABS &original_tabs,
01073 ST &merged_st,
01074 const ST &original_st)
01075 {
01076
01077
01078
01079
01080
01081
01082 ST_SCLASS merged_sclass = ST_storage_class(merged_st);
01083 const ST_SCLASS original_sclass = ST_storage_class(original_st);
01084
01085 switch (original_sclass) {
01086 case SCLASS_EXTERN:
01087 if (ST_is_weak_symbol (original_st) && merged_sclass == SCLASS_EXTERN) {
01088
01089
01090 Set_ST_is_weak_symbol (merged_st);
01091
01092
01093
01094
01095 if (ST_strong_idx (merged_st) == ST_st_idx (merged_st) &&
01096 ST_strong_idx (original_st) != ST_st_idx (original_st)) {
01097 ST_IDX st_idx =
01098 Merge_Global_St (ST_IDX_index (ST_strong_idx (original_st)),
01099 original_tabs);
01100 Set_ST_strong_idx (merged_st, st_idx);
01101 }
01102 }
01103 break;
01104
01105 case SCLASS_COMMON:
01106
01107 if (merged_sclass == SCLASS_EXTERN)
01108 Set_ST_storage_class (merged_st, SCLASS_COMMON);
01109 break;
01110
01111 case SCLASS_TEXT:
01112
01113 Set_AUX_PU_file_hdr (Aux_Pu_Table[ST_pu (merged_st)],
01114 current_file_hdr);
01115 if (IPA_Enable_Simple_Alias)
01116 Set_PU_ipa_addr_analysis (Pu_Table[ST_pu (merged_st)]);
01117
01118
01119 case SCLASS_UGLOBAL:
01120 case SCLASS_DGLOBAL:
01121
01122 Set_ST_storage_class (merged_st, original_sclass);
01123
01124 break;
01125 }
01126
01127 }
01128
01129
01130 static void
01131 Synch_Pu_With_Pu (PU& merged_pu, const PU& original_pu)
01132 {
01133
01134
01135
01136
01137
01138
01139
01140 const UINT64 pu_flags_and_mask = PU_IS_PURE | PU_NO_SIDE_EFFECTS;
01141
01142
01143 const UINT64 pu_flags_or_mask =
01144 PU_IS_INLINE_FUNCTION | PU_NO_INLINE | PU_MUST_INLINE |
01145 PU_NO_DELETE | PU_HAS_EXC_SCOPES | PU_HAS_NON_MANGLED_CALL |
01146 PU_ARGS_ALIASED | PU_NEEDS_FILL_ALIGN_LOWERING | PU_NEEDS_T9 |
01147 PU_HAS_VERY_HIGH_WHIRL | PU_HAS_ALTENTRY | PU_RECURSIVE |
01148 PU_IS_MAINPU | PU_UPLEVEL | PU_MP_NEEDS_LNO | PU_HAS_ALLOCA |
01149 PU_IN_ELF_SECTION | PU_HAS_MP | PU_MP | PU_HAS_NAMELIST |
01150 PU_HAS_RETURN_ADDRESS | PU_HAS_REGION | PU_HAS_INLINES |
01151 PU_CALLS_SETJMP | PU_CALLS_LONGJMP | PU_HAS_USER_ALLOCA;
01152
01153 const UINT64 original_flags = original_pu.flags;
01154 UINT64 merged_flags = merged_pu.flags;
01155
01156 merged_flags = (merged_flags & ~pu_flags_and_mask) |
01157 (merged_flags & original_flags & pu_flags_and_mask);
01158
01159 merged_flags |= (original_flags & pu_flags_or_mask);
01160
01161 merged_pu.flags = merged_flags;
01162
01163 merged_pu.src_lang |= original_pu.src_lang;
01164 #ifdef KEY
01165 if (!merged_pu.misc)
01166 merged_pu.misc = original_pu.misc;
01167
01168 merged_pu.unused = original_pu.unused;
01169 #endif
01170 }
01171
01172
01173 static inline TY_IDX
01174 Synch_TY_IDX (TY_IDX merged_ty_idx, TY_IDX original_ty_idx)
01175 {
01176 TY_IDX result = merged_ty_idx;
01177
01178 if (!TY_is_const (merged_ty_idx) || !TY_is_const (original_ty_idx))
01179 Clear_TY_is_const (result);
01180
01181 if (!TY_is_restrict (merged_ty_idx) || !TY_is_restrict (original_ty_idx))
01182 Clear_TY_is_restrict (result);
01183
01184 if (TY_is_volatile (merged_ty_idx) || TY_is_volatile (original_ty_idx))
01185 Set_TY_is_volatile (result);
01186
01187 #ifdef KEY
01188 Set_TY_align_exp (result, MAX (TY_align_exp (merged_ty_idx),
01189 TY_align_exp (original_ty_idx)));
01190 #else
01191 Set_TY_align_exp (result, max (TY_align_exp (merged_ty_idx),
01192 TY_align_exp (original_ty_idx)));
01193 #endif
01194 return result;
01195 }
01196
01197
01198 void
01199 Synch_ST_flags (ST& merged_st, const ST& original_st)
01200 {
01201
01202 const UINT32 st_flags_and_mask =
01203 ST_IS_NOT_USED | ST_IS_CONST_VAR | ST_PT_TO_UNIQUE_MEM;
01204
01205
01206 const UINT32 st_flags_or_mask =
01207 ST_KEEP_NAME_W2F | ST_IS_RESHAPED | ST_EMIT_SYMBOL | ST_GPREL |
01208 ST_NOT_GPREL | ST_IS_NAMELIST | ST_IS_F90_TARGET |
01209 ST_DECLARED_STATIC | ST_IS_THREAD_PRIVATE | ST_ADDR_SAVED |
01210 ST_ADDR_PASSED | ST_INIT_VALUE_ZERO | ST_IS_INITIALIZED |
01211 ST_HAS_NAMED_SECTION;
01212
01213 UINT32 original_flags = original_st.flags;
01214 UINT32 merged_flags = merged_st.flags;
01215
01216 merged_flags = (merged_flags & ~st_flags_and_mask) |
01217 (merged_flags & original_flags & st_flags_and_mask);
01218
01219 merged_flags |= original_flags & st_flags_or_mask;
01220
01221 merged_st.flags = merged_flags;
01222
01223
01224 if ((merged_flags & (ST_GPREL | ST_NOT_GPREL)) ==
01225 (ST_GPREL | ST_NOT_GPREL)) {
01226 Clear_ST_gprel (merged_st);
01227 }
01228 }
01229
01230
01231 static void
01232 Synch_St_With_St(const IPC_GLOBAL_TABS& original_tabs,
01233 ST& merged_st,
01234 const ST& original_st)
01235 {
01236
01237
01238
01239
01240
01241
01242
01243
01244 Resolve_Sclass (original_tabs, merged_st, original_st);
01245
01246
01247 switch (ST_sym_class (merged_st)) {
01248 case CLASS_FUNC:
01249 {
01250 PU& merged_pu = Pu_Table [ST_pu (merged_st)];
01251 const PU& original_pu = original_tabs.pu_tab[ST_pu (original_st)];
01252 TY_IDX new_ty_idx =
01253 Synch_TY_IDX (PU_prototype (merged_pu),
01254 (*New_Ty_Idx)[PU_prototype (original_pu)]);
01255 Set_PU_prototype (merged_pu, new_ty_idx);
01256 }
01257 break;
01258
01259 default:
01260 Set_ST_type (merged_st,
01261 Synch_TY_IDX (ST_type (merged_st),
01262 (*New_Ty_Idx)[ST_type (original_st)]));
01263 break;
01264 }
01265
01266 Synch_ST_flags (merged_st, original_st);
01267
01268 if (ST_sym_class (merged_st) == CLASS_FUNC)
01269 Synch_Pu_With_Pu (Pu_Table[ST_pu (merged_st)],
01270 original_tabs.pu_tab[ST_pu (original_st)]);
01271 }
01272
01273
01274 static ST_IDX
01275 Enter_Original_St(const IPC_GLOBAL_TABS& original_tabs,
01276 const ST& original_st)
01277 {
01278 if (ST_sym_class (original_st) == CLASS_CONST) {
01279 ST st = original_st;
01280 Set_ST_tcon(st, (*New_Tcon_Idx)[ST_tcon(original_st)]);
01281 Set_ST_type(st, (*New_Ty_Idx)[ST_type(original_st)]);
01282 ST_MERGE_MAP::const_iterator iter = st_merge_map->find (&st);
01283 if (iter != st_merge_map->end ()) {
01284
01285 (*New_St_Idx).set_map(ST_st_idx(original_st), (*iter).second);
01286 return (*iter).second;
01287 }
01288 }
01289
01290
01291
01292
01293
01294 ST_TAB &tab = *(Scope_tab[GLOBAL_SYMTAB].st_tab);
01295 UINT32 new_idx = tab.Insert(original_st);
01296 ST &new_st = tab[new_idx];
01297 ST_IDX new_st_idx = make_ST_IDX (new_idx, GLOBAL_SYMTAB);
01298
01299 (*New_St_Idx).set_map(ST_st_idx(original_st), new_st_idx);
01300
01301 Is_True (tab.Size () == Aux_St_Tab.Size (), ("Aux St Table out of sync"));
01302
01303
01304
01305 if (ST_sym_class(original_st) == CLASS_CONST) {
01306 Set_ST_tcon(new_st, (*New_Tcon_Idx)[ST_tcon(original_st)]);
01307 Set_ST_type(new_st, (*New_Ty_Idx)[ST_type(original_st)]);
01308 (*st_merge_map)[&new_st] = new_st_idx;
01309 } else {
01310 Set_ST_name_idx(new_st, (*New_Symstr_Idx)[ST_name_idx(original_st)]);
01311
01312 if (ST_sym_class(original_st) == CLASS_FUNC
01313 #ifdef KEY
01314
01315
01316
01317 || ST_sym_class(original_st) == CLASS_NAME
01318 #endif
01319 ) {
01320 PU_IDX new_pu_idx =
01321 Merge_Global_Pu (ST_pu(original_st), original_tabs);
01322
01323 Set_ST_pu(new_st, new_pu_idx);
01324 if (ST_storage_class (new_st) != SCLASS_EXTERN) {
01325
01326 Set_AUX_PU_file_hdr (Aux_Pu_Table[new_pu_idx],
01327 current_file_hdr);
01328 if (IPA_Enable_Simple_Alias)
01329 Set_PU_ipa_addr_analysis (Pu_Table[new_pu_idx]);
01330 }
01331 } else if (ST_sym_class(original_st) == CLASS_BLOCK) {
01332 Fail_FmtAssertion("invalid ST_sym_class in Merge_Global_St");
01333 } else {
01334 Set_ST_type(new_st, (*New_Ty_Idx)[ST_type(original_st)]);
01335 }
01336 }
01337 Set_ST_st_idx(new_st, new_st_idx);
01338
01339 ST_IDX base_idx =
01340 ST_raw_base_idx (original_st) == ST_st_idx (original_st) ?
01341 new_st_idx :
01342 Merge_Global_St (ST_IDX_index (ST_raw_base_idx(original_st)),
01343 original_tabs);
01344 Set_ST_raw_base_idx(new_st, base_idx);
01345
01346 #if defined(TARG_X8664) || defined(TARG_SL)
01347 if ( ST_sclass(new_st) != SCLASS_COMMON &&
01348
01349 !ST_is_equivalenced(new_st) &&
01350 ST_sym_class(new_st) == CLASS_VAR ) {
01351 TY_IDX ty = ST_type(new_st);
01352 if (TY_kind(ST_type(new_st)) == KIND_POINTER) {
01353 ty = TY_pointed(ST_type(new_st));
01354 }
01355 if (TY_kind(ty) != KIND_FUNCTION) {
01356 TY_IDX st_ty_idx = ST_type(new_st);
01357 Set_TY_align_exp(st_ty_idx, 4);
01358 Set_ST_type(new_st, st_ty_idx);
01359 }
01360 }
01361 #endif
01362
01363 return new_st_idx;
01364 }
01365
01366
01367 static ST_IDX
01368 Merge_St_With_Pext(const IPC_GLOBAL_TABS& original_tabs,
01369 const ST& original_st,
01370 void* pext)
01371 {
01372
01373
01374
01375
01376
01377
01378
01379 const ST_IDX new_st_idx = Enter_Original_St (original_tabs, original_st);
01380 ST& new_st = St_Table[new_st_idx];
01381
01382 switch (ST_storage_class (new_st)) {
01383 case SCLASS_TEXT:
01384 case SCLASS_UGLOBAL:
01385 case SCLASS_DGLOBAL:
01386 if (!ld_resolved_to_obj (pext, original_tabs.p_obj)) {
01387
01388 if (ST_storage_class (new_st) == SCLASS_DGLOBAL)
01389 Invalidate_inito (new_st, original_tabs.inito_tab);
01390 else if (ST_storage_class (new_st) == SCLASS_TEXT)
01391 Set_AUX_PU_file_hdr (Aux_Pu_Table[ST_pu (new_st)], NULL);
01392 Set_ST_storage_class (new_st, SCLASS_EXTERN);
01393 }
01394 break;
01395 }
01396
01397 ld_set_st_idx (pext, new_st_idx);
01398
01399 return new_st_idx;
01400
01401 }
01402
01403
01404
01405
01406 static void
01407 Handle_Incompatible_Func_Types (const ST& merged_st, const ST& original_st,
01408 PU& merged_pu, TY_IDX original_ty_idx)
01409 {
01410 if (ST_storage_class (merged_st) == SCLASS_TEXT)
01411 return;
01412
01413 if (ST_storage_class (original_st) == SCLASS_TEXT) {
01414 TY_IDX ty_idx = PU_prototype (merged_pu);
01415 Set_PU_prototype (merged_pu,
01416 Replace_TY_IDX_index (ty_idx, original_ty_idx));
01417 return;
01418 }
01419
01420
01421 TYLIST_IDX i = TY_tylist (Ty_Table[PU_prototype (merged_pu)]);
01422 TYLIST_IDX j = TY_tylist (Ty_Table[original_ty_idx]);
01423
01424 while (TYLIST_type (Tylist_Table[i]) != 0 &&
01425 TYLIST_type (Tylist_Table[j]) != 0) {
01426 ++i;
01427 ++j;
01428 }
01429
01430 if (TYLIST_type (Tylist_Table[j]) != 0) {
01431 TY_IDX ty_idx = PU_prototype (merged_pu);
01432 Set_PU_prototype (merged_pu,
01433 Replace_TY_IDX_index (ty_idx, original_ty_idx));
01434 }
01435 return;
01436
01437 }
01438
01439
01440 static void
01441 Handle_Incompatible_Data_Types (ST& merged_st, const ST& original_st)
01442 {
01443 if (ST_storage_class (merged_st) == SCLASS_UGLOBAL ||
01444 ST_storage_class (merged_st) == SCLASS_DGLOBAL)
01445 return;
01446
01447 TY_IDX original_ty_idx = (*New_Ty_Idx)[ST_type (original_st)];
01448
01449 if (ST_storage_class (original_st) == SCLASS_UGLOBAL ||
01450 ST_storage_class (original_st) == SCLASS_DGLOBAL) {
01451 TY_IDX ty_idx = ST_type (merged_st);
01452 Set_ST_type (merged_st,
01453 Replace_TY_IDX_index (ty_idx, original_ty_idx));
01454 return;
01455 }
01456
01457 const TY& merged_ty = Ty_Table[ST_type (merged_st)];
01458 const TY& original_ty = Ty_Table[original_ty_idx];
01459
01460 if (TY_size (original_ty) > TY_size (merged_ty)) {
01461 TY_IDX ty_idx = ST_type (merged_st);
01462 Set_ST_type (merged_st,
01463 Replace_TY_IDX_index (ty_idx, original_ty_idx));
01464 }
01465
01466 return;
01467 }
01468
01469
01470 static ST_IDX
01471 Merge_St_With_St(const IPC_GLOBAL_TABS &original_tabs,
01472 ST &merged_st,
01473 const ST &original_st,
01474 void *pext)
01475 {
01476
01477
01478
01479
01480
01481
01482
01483
01484
01485
01486
01487 #if (!defined(_STANDALONE_INLINER) && !defined(_LIGHTWEIGHT_INLINER))
01488
01489 switch (ST_storage_class (original_st)) {
01490 case SCLASS_TEXT:
01491 case SCLASS_UGLOBAL:
01492 case SCLASS_DGLOBAL:
01493 if (!ld_resolved_to_obj (pext, original_tabs.p_obj)) {
01494
01495 if (ST_storage_class (original_st) == SCLASS_DGLOBAL)
01496 Invalidate_inito (original_st, original_tabs.inito_tab);
01497 (*New_St_Idx).set_map (ST_st_idx(original_st),
01498 ST_st_idx(merged_st));
01499 if (ST_addr_passed (original_st))
01500 Set_ST_addr_passed (merged_st);
01501 if (ST_addr_saved (original_st))
01502 Set_ST_addr_saved (merged_st);
01503 return ST_st_idx (merged_st);
01504 }
01505 break;
01506 }
01507 #endif // _STANDALONE_INLINER
01508
01509 if (ST_sym_class (original_st) != ST_sym_class (merged_st)) {
01510 #ifdef KEY
01511
01512 ErrMsg (EC_Inc_Types, ST_name (merged_st));
01513 #else
01514 Fail_FmtAssertion ("symbol %s declared both as function and variable",
01515 ST_name (merged_st));
01516 #endif
01517 }
01518
01519 if (ST_sym_class (original_st) == CLASS_FUNC) {
01520 const PU& original_pu = original_tabs.pu_tab[ST_pu (original_st)];
01521 PU& merged_pu = Pu_Table[ST_pu (merged_st)];
01522 TY_IDX original_ty_idx = (*New_Ty_Idx)[PU_prototype (original_pu)];
01523 if (TY_IDX_index (PU_prototype (merged_pu)) !=
01524 TY_IDX_index (original_ty_idx))
01525 Handle_Incompatible_Func_Types (merged_st, original_st,
01526 merged_pu, original_ty_idx);
01527 } else if (TY_IDX_index (ST_type (merged_st)) !=
01528 TY_IDX_index ((*New_Ty_Idx)[ST_type (original_st)])) {
01529
01530 Handle_Incompatible_Data_Types (merged_st, original_st);
01531 }
01532
01533 Synch_St_With_St (original_tabs, merged_st, original_st);
01534
01535 (*New_St_Idx).set_map (ST_st_idx(original_st), ST_st_idx(merged_st));
01536 #if defined(TARG_X8664) || defined(TARG_SL)
01537 if ( ST_sclass(merged_st) != SCLASS_COMMON &&
01538
01539 !ST_is_equivalenced(merged_st) &&
01540 ST_sym_class(merged_st) == CLASS_VAR ) {
01541 TY_IDX ty = ST_type(merged_st);
01542 if (TY_kind(ST_type(merged_st)) == KIND_POINTER) {
01543 ty = TY_pointed(ST_type(merged_st));
01544 }
01545 if (TY_kind(ty) != KIND_FUNCTION) {
01546 TY_IDX st_ty_idx = ST_type(merged_st);
01547 Set_TY_align_exp(st_ty_idx, 4);
01548 Set_ST_type(merged_st, st_ty_idx);
01549 }
01550 }
01551 #endif
01552 return ST_st_idx (merged_st);
01553 }
01554
01555
01556 static void
01557 Verify_Predefined_Symbols (const ST& st)
01558 {
01559 ST mapped_st = st;
01560 Set_ST_name_idx (mapped_st, (*New_Symstr_Idx)[ST_name_idx (st)]);
01561
01562 FmtAssert (bcmp (&mapped_st, &St_Table[ST_st_idx (st)], sizeof(ST)) == 0,
01563 ("Incompatible predefined pregs in global symbol table"));
01564 (*New_St_Idx).set_map (ST_st_idx (st), ST_st_idx (st));
01565 }
01566
01567
01568
01569
01570
01571 static ST_IDX
01572 Process_Common_Element (const IPC_GLOBAL_TABS& original_tabs,
01573 const ST& original_st)
01574 {
01575 ST_IDX base_idx = (*New_St_Idx)[ST_base_idx (original_st)];
01576
01577 Is_True (base_idx != 0, ("Missing base idx for common block element"));
01578
01579 const TY& ty = Ty_Table[(*New_Ty_Idx)[ST_type (original_st)]];
01580
01581 Is_True (!ST_is_split_common (original_st),
01582 ("Front end should not generate split common under -IPA"));
01583
01584
01585 COMMON_BLOCK_ELEMENTS_MAP::const_iterator block_iter =
01586 Common_Block_Elements_Map->find (base_idx);
01587
01588 BLOCK_ELEMENTS* block;
01589 if (block_iter == Common_Block_Elements_Map->end ()) {
01590 block = CXX_NEW (BLOCK_ELEMENTS (block_element_compare (),
01591 &Common_map_pool),
01592 &Common_map_pool);
01593 (*Common_Block_Elements_Map)[base_idx] = block;
01594 } else
01595 block = (*block_iter).second;
01596
01597 BLOCK_ELEMENT_DESC desc (&ty, ST_ofst (original_st));
01598 BLOCK_ELEMENTS::iterator element = block->find (desc);
01599
01600 ST_IDX new_st_idx;
01601 if (element != block->end ()) {
01602
01603 new_st_idx = (*element).second;
01604 (*New_St_Idx).set_map (ST_st_idx (original_st), new_st_idx);
01605 Synch_ST_flags (St_Table[new_st_idx], original_st);
01606 return new_st_idx;
01607 }
01608
01609 new_st_idx = Enter_Original_St (original_tabs, original_st);
01610 block->insert (element, make_pair (desc, new_st_idx));
01611 return new_st_idx;
01612 }
01613
01614
01615 #if (defined(_STANDALONE_INLINER) || defined(_LIGHTWEIGHT_INLINER))
01616
01617 static ST_IDX
01618 Merge_Global_St(UINT idx,
01619 const IPC_GLOBAL_TABS& original_tabs)
01620 {
01621
01622
01623
01624
01625
01626
01627
01628
01629
01630
01631
01632
01633
01634
01635
01636
01637 Is_True (idx != 0, ("Invalid ST_IDX for Merge_Global_St()"));
01638
01639 ST_IDX new_st_idx = New_St_Idx->map_[idx];
01640
01641 if (new_st_idx != UNINITIALIZED_INDEX)
01642 return new_st_idx;
01643
01644 ST& original_st = original_tabs.st_tab[idx];
01645
01646
01647 if (ST_export(original_st) == EXPORT_LOCAL ||
01648 ST_export(original_st) == EXPORT_LOCAL_INTERNAL) {
01649
01650 if (ST_raw_base_idx (original_st) == ST_st_idx (original_st))
01651 return Enter_Original_St (original_tabs, original_st);
01652 else
01653
01654 return Process_Common_Element (original_tabs, original_st);
01655 }
01656
01657
01658
01659 char *st_name = &original_tabs.symstr_tab[ST_name_idx (original_st)];
01660
01661 ST* global_st = get_global_st(st_name);
01662
01663 if (global_st == NULL) {
01664
01665
01666 return(Enter_Original_St (original_tabs, original_st));
01667 } else {
01668 return Merge_St_With_St (original_tabs, *global_st,
01669 original_st, NULL);
01670 }
01671 }
01672 #else // _STANDALONE_INLINER
01673
01674 static ST_IDX
01675 Merge_Global_St(UINT idx,
01676 const IPC_GLOBAL_TABS& original_tabs)
01677 {
01678
01679
01680
01681
01682
01683
01684
01685
01686
01687
01688
01689
01690
01691
01692
01693
01694 Is_True (idx != 0, ("Invalid ST_IDX for Merge_Global_St()"));
01695
01696 ST_IDX new_st_idx = New_St_Idx->map_[idx];
01697
01698 if (new_st_idx != UNINITIALIZED_INDEX)
01699 return new_st_idx;
01700
01701 ST& original_st = original_tabs.st_tab[idx];
01702
01703
01704 if (ST_export(original_st) == EXPORT_LOCAL ||
01705 ST_export(original_st) == EXPORT_LOCAL_INTERNAL) {
01706
01707 #ifdef KEY
01708
01709 if (ST_raw_base_idx (original_st) == ST_st_idx (original_st) ||
01710 ST_sym_class (original_st) == CLASS_FUNC)
01711 #else
01712 if (ST_raw_base_idx (original_st) == ST_st_idx (original_st))
01713 #endif
01714 return Enter_Original_St (original_tabs, original_st);
01715 else
01716
01717 return Process_Common_Element (original_tabs, original_st);
01718 }
01719
01720
01721
01722
01723
01724
01725
01726
01727
01728
01729 char *st_name = &original_tabs.symstr_tab[ST_name_idx (original_st)];
01730
01731 #if defined(TARG_IA64) || defined(TARG_X8664) || defined(TARG_MIPS) || defined(TARG_SL)
01732 void *pext = ld_slookup_mext(st_name,
01733 (ST_storage_class (original_st) == SCLASS_EXTERN));
01734 #else
01735 void *pext = slookup_mext(st_name);
01736 #endif
01737
01738 if (pext == NULL)
01739 Fail_FmtAssertion("Cannot find pext in Merge_Global_St");
01740
01741 ST_IDX pext_st_idx = ld_get_st_idx (pext);
01742
01743 if (pext_st_idx == WHIRL_ST_IDX_UNINITIALIZED) {
01744
01745
01746 pext_st_idx = Enter_Original_St (original_tabs, original_st);
01747 ld_set_st_idx (pext, pext_st_idx);
01748 return pext_st_idx;
01749 } else if (pext_st_idx == WHIRL_ST_IDX_NOT_AVAILABLE) {
01750
01751
01752
01753
01754
01755
01756 return Merge_St_With_Pext (original_tabs, original_st, pext);
01757 } else {
01758
01759
01760 return Merge_St_With_St (original_tabs, St_Table[pext_st_idx],
01761 original_st, pext);
01762 }
01763 }
01764
01765 #endif // _STANDALONE_INLINER
01766
01767
01768
01769
01770
01771
01772 static INITV_IDX
01773 Merge_Global_Initv(UINT initv_idx,
01774 const IPC_GLOBAL_TABS &original_tabs,
01775 INITV_IDX_MAP &initv_map)
01776 {
01777
01778
01779
01780
01781
01782
01783
01784
01785
01786
01787
01788
01789
01790
01791 if (initv_map[initv_idx] != 0)
01792 return initv_map[initv_idx];
01793
01794 INITV &original_initv = original_tabs.initv_tab[initv_idx];
01795 INITV_IDX new_idx = Initv_Table.Insert(original_initv);
01796 INITV &new_initv = Initv_Table[new_idx];
01797 ST_IDX st_idx, new_st_idx;
01798 INITV_IDX nested_initv_idx;
01799
01800 initv_map.set_map (initv_idx, new_idx);
01801
01802
01803
01804 if (INITV_next(original_initv) != 0) {
01805 nested_initv_idx =
01806 Merge_Global_Initv(INITV_next(original_initv), original_tabs,
01807 initv_map);
01808 Set_INITV_next(new_initv, nested_initv_idx);
01809 }
01810
01811
01812
01813 switch (INITV_kind(original_initv)) {
01814 case INITVKIND_SYMOFF:
01815 #ifdef TARG_IA64
01816 case INITVKIND_SYMIPLT:
01817 #endif
01818 st_idx = INITV_symoff_st(original_initv);
01819 if (ST_IDX_level (st_idx) == GLOBAL_SYMTAB) {
01820 new_st_idx = (*New_St_Idx)[st_idx];
01821 Set_INITV_symoff_st(new_initv, new_st_idx);
01822 }
01823 break;
01824
01825 case INITVKIND_VAL:
01826 Set_INITV_tcon (new_initv,
01827 (*New_Tcon_Idx)[INITV_tcon(original_initv)]);
01828 break;
01829
01830 case INITVKIND_BLOCK:
01831 #ifdef KEY // fixes bug 1010
01832 if (INITV_block_first(original_initv) == INITV_IDX_ZERO)
01833 nested_initv_idx = INITV_IDX_ZERO;
01834 else
01835 #endif
01836 nested_initv_idx =
01837 Merge_Global_Initv(INITV_block_first(original_initv),
01838 original_tabs, initv_map);
01839 Set_INITV_block_first(new_initv, nested_initv_idx);
01840 break;
01841
01842 case INITVKIND_SYMDIFF:
01843 case INITVKIND_SYMDIFF16:
01844 st_idx = INITV_symdiff_st(original_initv);
01845 if (ST_IDX_level (st_idx) == GLOBAL_SYMTAB) {
01846 new_st_idx = (*New_St_Idx)[st_idx];
01847 Set_INITV_symdiff_st(new_initv, new_st_idx);
01848 }
01849 break;
01850
01851 case INITVKIND_ZERO:
01852 case INITVKIND_ONE:
01853 case INITVKIND_PAD:
01854 case INITVKIND_LABEL:
01855 break;
01856
01857 default:
01858 Fail_FmtAssertion ("invalid INITVKIND in Merge_Global_Initv");
01859 break;
01860 }
01861 return new_idx;
01862 }
01863
01864
01865 static void
01866 Merge_Global_Inito(const INITO* inito_tab, UINT32 inito_tab_size,
01867 const INITV_IDX_MAP& initv_map)
01868 {
01869
01870
01871
01872
01873
01874
01875
01876
01877
01878
01879
01880
01881
01882 for (UINT32 idx = 1; idx < inito_tab_size; ++idx) {
01883
01884 const INITO& original_inito = inito_tab[idx];
01885
01886 if (INITO_st_idx (original_inito) == UNINITIALIZED_INDEX)
01887 continue;
01888
01889 INITO_TAB &tab = *(Scope_tab[GLOBAL_SYMTAB].inito_tab);
01890 UINT32 new_idx = tab.Insert(original_inito);
01891 INITO& new_inito = tab[new_idx];
01892
01893
01894
01895 ST_IDX st_idx = (*New_St_Idx)[INITO_st_idx(original_inito)];
01896 Set_INITO_st_idx(new_inito, st_idx);
01897
01898
01899
01900 INITV_IDX initv_idx = initv_map[INITO_val(original_inito)];
01901 Set_INITO_val(new_inito, initv_idx);
01902
01903
01904 ST_To_INITO_Map[st_idx] = make_INITO_IDX (new_idx, GLOBAL_SYMTAB);
01905 }
01906 }
01907
01908
01909 static void
01910 Merge_Global_St_Attr(const ST_ATTR* st_attr_tab, UINT32 size)
01911 {
01912
01913
01914
01915
01916 UINT32 idx;
01917
01918 for (idx = 1; idx < size; ++idx) {
01919
01920
01921
01922
01923
01924
01925
01926 const ST_ATTR old_st_attr = st_attr_tab[idx];
01927 ST_IDX st_idx = (*New_St_Idx) [ST_ATTR_st_idx (old_st_attr)];
01928 Update_reference_count (&St_Table [st_idx], 1,
01929 0, FALSE);
01930 ST_ATTR_KIND akind = old_st_attr.kind;
01931 ST_ATTR_IDX new_st_attr_idx;
01932 ST_ATTR& new_st_attr = New_ST_ATTR (GLOBAL_SYMTAB, new_st_attr_idx);
01933
01934 switch (old_st_attr.kind) {
01935
01936 case ST_ATTR_DEDICATED_REGISTER:
01937 ST_ATTR_Init (new_st_attr, st_idx, ST_ATTR_DEDICATED_REGISTER,
01938 ST_ATTR_reg_id (old_st_attr));
01939 break;
01940
01941 case ST_ATTR_SECTION_NAME:
01942 ST_ATTR_Init (new_st_attr, st_idx, ST_ATTR_SECTION_NAME,
01943 (*New_Symstr_Idx) [ST_ATTR_section_name (old_st_attr)]);
01944 break;
01945
01946 default:
01947 Fail_FmtAssertion ("invalid ATTR_KIND in Merge_Global_St_Attr");
01948 break;
01949 }
01950 }
01951 }
01952
01953
01954 static inline void
01955 Merge_File_Info (const FILE_INFO& info)
01956 {
01957 File_info.flags |= info.flags;
01958 }
01959
01960
01961
01962
01963
01964
01965
01966
01967
01968 IPC_GLOBAL_IDX_MAP *
01969 IPC_merge_global_tab (const IPC_GLOBAL_TABS &original_tabs,
01970 IP_FILE_HDR& hdr, MEM_POOL *mempool)
01971 {
01972
01973
01974
01975
01976
01977
01978
01979
01980
01981
01982
01983
01984
01985
01986
01987
01988
01989
01990
01991
01992
01993
01994
01995
01996
01997
01998
01999
02000
02001
02002
02003
02004
02005
02006
02007
02008
02009
02010 Merge_File_Info (IP_FILE_HDR_file_info (hdr));
02011
02012
02013
02014
02015
02016 IPC_GLOBAL_IDX_MAP *idx_map =
02017 CXX_NEW (IPC_GLOBAL_IDX_MAP (original_tabs.st_tab_size,
02018 original_tabs.ty_tab_size,
02019 original_tabs.tcon_tab_size,
02020 original_tabs.initv_tab_size,
02021 mempool),
02022 mempool);
02023
02024
02025
02026 Merge_Strtab (original_tabs.symstr_tab,
02027 original_tabs.symstr_tab_size,
02028 idx_map->sym_str);
02029
02030 TCONSTR_IDX_MAP tcon_str;
02031 Merge_TCON_Strtab (original_tabs.tconstr_tab,
02032 original_tabs.tconstr_tab_size,
02033 tcon_str);
02034
02035
02036
02037
02038
02039 New_Ty_Idx = &idx_map->ty;
02040 New_St_Idx = &idx_map->st;
02041 New_Symstr_Idx = &idx_map->sym_str;
02042
02043 #ifdef Is_True_On
02044 if (getenv ("no_fast_merge")) {
02045 UINT idx;
02046 for (idx = 1; idx < original_tabs.ty_tab_size; idx++)
02047 if (New_Ty_Idx->map_[idx] == 0) {
02048 BOOL is_new;
02049 TY_INDEX is_recursive;
02050 Merge_Global_Ty(make_TY_IDX (idx), original_tabs, is_new,
02051 is_recursive);
02052 }
02053 } else
02054 #endif
02055 Merge_All_Types (original_tabs, *idx_map);
02056
02057 UINT idx;
02058 #ifdef Is_True_On
02059
02060
02061 for (idx = 1; idx < original_tabs.ty_tab_size; ++idx)
02062 Is_True ((New_Ty_Idx->map_[idx] & 0xff) == 0, ("errors in TY_IDX maps"));
02063
02064 #endif
02065
02066
02067
02068
02069
02070 Merge_Global_Tcon (original_tabs.tcon_tab, original_tabs.tcon_tab_size,
02071 idx_map->tcon, tcon_str);
02072
02073
02074
02075
02076
02077
02078
02079
02080
02081
02082
02083 ST_TO_INITO_MAP st_to_inito_map;
02084
02085 for (idx = 1; idx < original_tabs.inito_tab_size; idx++) {
02086 ST_IDX st_idx = INITO_st_idx(original_tabs.inito_tab[idx]);
02087 st_to_inito_map[ST_IDX_index (st_idx)] = idx;
02088 }
02089
02090 St_To_Inito_Map = &st_to_inito_map;
02091 New_Tcon_Idx = &idx_map->tcon;
02092 current_file_hdr = &hdr;
02093
02094 for (idx = 1; idx < num_predefined_st; ++idx)
02095 Verify_Predefined_Symbols (original_tabs.st_tab[idx]);
02096
02097 for (idx = num_predefined_st; idx < original_tabs.st_tab_size; idx++)
02098 Merge_Global_St (idx, original_tabs);
02099
02100 current_file_hdr = NULL;
02101 New_Ty_Idx = NULL;
02102
02103
02104
02105
02106 idx_map->initv.set_map (0, 0);
02107 for (idx = 1; idx < original_tabs.initv_tab_size; idx++)
02108 if (idx_map->initv[idx] == UNINITIALIZED_INDEX)
02109 Merge_Global_Initv (idx, original_tabs, idx_map->initv);
02110
02111 Merge_Global_Inito (original_tabs.inito_tab,
02112 original_tabs.inito_tab_size, idx_map->initv);
02113
02114
02115
02116
02117
02118 Merge_Global_St_Attr (original_tabs.st_attr_tab,
02119 original_tabs.st_attr_tab_size);
02120
02121 return idx_map;
02122 }
02123
02124
02125
02126
02127
02128
02129
02130
02131 static inline ST*
02132 Get_base_st (ST* st)
02133 {
02134 while (ST_base_idx (st) != ST_st_idx (st))
02135 st = &St_Table[ST_base_idx (st)];
02136 return st;
02137 }
02138
02139
02140
02141 void
02142 Update_reference_count (ST* st, INT32 refcount, INT32 modcount,
02143 BOOL is_cmod)
02144 {
02145 st = Get_base_st (st);
02146 AUX_ST& aux_st = Aux_St_Table[ST_st_idx (st)];
02147
02148 if (is_cmod) {
02149 static BOOL reported = FALSE;
02150 if (!reported) {
02151 DevWarn ("TODO: handle cmod");
02152 reported = TRUE;
02153 }
02154
02155 }
02156
02157 Inc_AUX_ST_refcount (aux_st, refcount);
02158 Inc_AUX_ST_modcount (aux_st, modcount);
02159
02160 if (ST_addr_saved (st) || ST_addr_passed (st))
02161 return;
02162
02163 if (AUX_ST_flags (aux_st, IGNORE_REFCOUNTS))
02164 return;
02165
02166 if (IPA_Enable_DVE && refcount < 0 && AUX_ST_refcount (aux_st) == 0) {
02167 Set_ST_is_not_used (st);
02168 if (Trace_IPA || Trace_Perf)
02169 fprintf(TFile, "%s is marked NOT USED\n", ST_name (st));
02170
02171 if ((ST_sclass(st) == SCLASS_COMMON) || (ST_sclass(st) == SCLASS_DGLOBAL)) {
02172
02173 COMMON_BLOCK_ELEMENTS_MAP::const_iterator block_iter =
02174 Common_Block_Elements_Map->find(ST_st_idx(st));
02175 if (block_iter != Common_Block_Elements_Map->end()) {
02176 const BLOCK_ELEMENTS* block = (*block_iter).second;
02177 BLOCK_ELEMENTS::const_iterator element = block->begin();
02178 BLOCK_ELEMENTS::const_iterator element_end = block->end();
02179 for (; element != element_end; ++element) {
02180 ST_IDX elem_st_idx = (*element).second;
02181 Set_ST_is_not_used (St_Table[elem_st_idx]);
02182 if (Trace_IPA || Trace_Perf)
02183 fprintf(TFile, "%s is marked NOT USED\n", ST_name (elem_st_idx));
02184 }
02185 }
02186 }
02187 } else if (IPA_Enable_CGI && modcount < 0 &&
02188 AUX_ST_modcount (aux_st) == 0) {
02189 Set_ST_is_const_var (st);
02190 if (Trace_IPA || Trace_Perf)
02191 fprintf(TFile, "%s is marked CONSTANT\n", ST_name (st));
02192
02193
02194 if ((ST_sclass(st) == SCLASS_COMMON) || (ST_sclass(st) == SCLASS_DGLOBAL)) {
02195 COMMON_BLOCK_ELEMENTS_MAP::const_iterator block_iter =
02196 Common_Block_Elements_Map->find(ST_st_idx(st));
02197 if (block_iter != Common_Block_Elements_Map->end()) {
02198 const BLOCK_ELEMENTS* block = (*block_iter).second;
02199 BLOCK_ELEMENTS::const_iterator element = block->begin();
02200 BLOCK_ELEMENTS::const_iterator element_end = block->end();
02201 for (; element != element_end; ++element) {
02202 ST_IDX elem_st_idx = (*element).second;
02203 Set_ST_is_const_var (St_Table[elem_st_idx]);
02204 if (Trace_IPA || Trace_Perf)
02205 fprintf(TFile, "%s is marked CONSTANT\n", ST_name (elem_st_idx));
02206 }
02207 }
02208 }
02209 }
02210
02211 }
02212
02213
02214
02215 void
02216 Sync_symbol_attributes (ST_IDX st_idx, UINT32 sym_attr, BOOL is_weak,
02217 UINT32 export_type)
02218 {
02219
02220 Is_True ((sym_attr & ~OBJ_ATTR_MASK) == 0, ("invalid aux_st flags"));
02221 AUX_ST& aux_st = Aux_St_Table[st_idx];
02222 aux_st.flags |= sym_attr;
02223
02224 ST& st = St_Table[st_idx];
02225
02226 if (aux_st.flags & (USED_IN_OBJ|USED_IN_DSO|OBJ_COMMON))
02227 Clear_ST_is_not_used (st);
02228 if (aux_st.flags & ADDR_TAKEN_IN_OBJ) {
02229 Set_ST_addr_saved (st);
02230 Set_ST_addr_passed (st);
02231 }
02232
02233 if (is_weak)
02234 Set_ST_is_weak_symbol (st);
02235 else if (ST_is_weak_symbol (st)) {
02236
02237 Clear_ST_is_weak_symbol (st);
02238 Set_ST_base_idx (st, ST_st_idx(st));
02239 }
02240
02241 switch (export_type) {
02242 case STO_DEFAULT:
02243 case STO_OPTIONAL:
02244 Set_ST_export (st, EXPORT_PREEMPTIBLE);
02245 break;
02246
02247 case STO_PROTECTED:
02248 Set_ST_export (st, EXPORT_PROTECTED);
02249 break;
02250
02251 case STO_HIDDEN:
02252 Set_ST_export (st, EXPORT_HIDDEN);
02253 break;
02254
02255 case STO_INTERNAL:
02256 Set_ST_export (st, EXPORT_INTERNAL);
02257 break;
02258 }
02259
02260 }
02261
02262
02263
02264 void
02265 Linker_mark_not_gp_rel (ST_IDX st_idx)
02266 {
02267 Is_True (st_idx != WHIRL_ST_IDX_UNINITIALIZED &&
02268 st_idx != WHIRL_ST_IDX_NOT_AVAILABLE, ("Invalid ST_IDX"));
02269
02270 ST& st = St_Table[st_idx];
02271 Set_ST_not_gprel (st);
02272 }
02273
02274
02275
02276
02277
02278 static void
02279 Fix_Common_Block (const ST& block_st, const BLOCK_ELEMENTS *block)
02280 {
02281 BLOCK_ELEMENTS::const_iterator element_iter = block->begin ();
02282 BLOCK_ELEMENTS::const_iterator element_end = block->end ();
02283
02284 ST* last_st = NULL;
02285 UINT64 offset = 0;
02286 UINT64 size = 0;
02287
02288 while (element_iter != element_end) {
02289 const TY& ty = *(*element_iter).first.first;
02290 UINT64 ofst = (*element_iter).first.second;
02291 ST_IDX st_idx = (*element_iter).second;
02292 ST& st = St_Table[st_idx];
02293
02294 Is_True (ST_sym_class (st) == CLASS_VAR &&
02295 (ST_export (st) == EXPORT_LOCAL ||
02296 ST_export (st) == EXPORT_LOCAL_INTERNAL),
02297 ("Expecting a common block elements"));
02298
02299
02300 Set_ST_storage_class (st, ST_storage_class (block_st));
02301 if (ST_is_initialized (block_st)) {
02302 Set_ST_is_initialized (st);
02303 if (ST_init_value_zero (block_st))
02304 Set_ST_init_value_zero (st);
02305 }
02306
02307 if (ofst >= offset + size) {
02308 offset = ofst;
02309 size = TY_size (ty);
02310 last_st = &st;
02311 } else {
02312
02313 Set_ST_is_equivalenced (st);
02314 Set_ST_is_equivalenced (last_st);
02315 if (ST_is_f90_target (st) || ST_is_f90_target (last_st)) {
02316
02317 Set_ST_is_f90_target (st);
02318 Set_ST_is_f90_target (last_st);
02319 }
02320
02321 if (ofst + TY_size (ty) >= offset + size) {
02322 offset = ofst;
02323 size = TY_size (ty);
02324 last_st = &st;
02325 }
02326 }
02327
02328 ++element_iter;
02329 }
02330 }
02331
02332
02333
02334 static UINT32
02335 Num_Of_Elements (const ST& st)
02336 {
02337 const TY& ty = Ty_Table[ST_type (st)];
02338
02339 if (TY_kind (ty) != KIND_STRUCT)
02340 return UINT32_MAX;
02341
02342
02343
02344 FLD_ITER iter = Make_fld_iter (TY_fld (ty));
02345
02346 UINT count = 0;
02347
02348 do {
02349 ++count;
02350 } while (!FLD_last_field (iter++));
02351
02352 return count;
02353 }
02354
02355
02356 static void
02357 Fix_Common_Block_Type (ST& block_st, const BLOCK_ELEMENTS *block)
02358 {
02359 CHECKPOINT chkpt;
02360
02361 TY_IDX ty_idx = Copy_TY (ST_type (block_st));
02362
02363 FLD_IDX first_field = FLD_Table_Size ();
02364
02365 BLOCK_ELEMENTS::const_iterator element_iter = block->begin ();
02366 BLOCK_ELEMENTS::const_iterator element_end = block->end ();
02367 FLD_HANDLE fld;
02368
02369 while (element_iter != element_end) {
02370 const ST& st = St_Table[(*element_iter).second];
02371 UINT64 ofst = (*element_iter).first.second;
02372
02373 fld = New_FLD ();
02374 FLD_Init (fld, ST_name_idx (st), ST_type (st), ofst);
02375 if (ST_is_equivalenced (st))
02376 Set_FLD_equivalence (fld);
02377 ++element_iter;
02378 }
02379
02380 Set_FLD_last_field (fld);
02381
02382 TY& ty = Ty_Table[ty_idx];
02383 Set_TY_fld (ty, FLD_HANDLE (first_field));
02384
02385 if (ST_sclass (block_st) == SCLASS_DGLOBAL) {
02386
02387
02388 if (FLD_ofst (fld) + TY_size (FLD_type (fld)) > TY_size (ty))
02389 Set_TY_size (ty, FLD_ofst (fld) + TY_size (FLD_type (fld)));
02390 }
02391
02392 TY_IDX unique_idx = TY_is_unique (ty_idx);
02393
02394 if (unique_idx != ty_idx) {
02395
02396
02397 chkpt.restore ();
02398 Set_ST_type (block_st, unique_idx);
02399 } else
02400 Set_ST_type (block_st, ty_idx);
02401
02402 }
02403
02404
02405 void
02406 Verify_Common_Block_Layout ()
02407 {
02408 COMMON_BLOCK_ELEMENTS_MAP::const_iterator block_iter =
02409 Common_Block_Elements_Map->begin ();
02410 COMMON_BLOCK_ELEMENTS_MAP::const_iterator block_end =
02411 Common_Block_Elements_Map->end ();
02412
02413 while (block_iter != block_end) {
02414 ST& block_st = St_Table[(*block_iter).first];
02415 const BLOCK_ELEMENTS *block = (*block_iter).second;
02416
02417 Fix_Common_Block (block_st, block);
02418
02419
02420 if (block->size () > Num_Of_Elements (block_st))
02421 Fix_Common_Block_Type (block_st, block);
02422
02423 ++block_iter;
02424 }
02425 }