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 #if defined(BUILD_OS_DARWIN)
00058 #include <darwin_elf.h>
00059 #else
00060 #include <elf.h>
00061 #endif
00062
00063
00064 #include "defs.h"
00065 #include "strtab.h"
00066 #include "irbdata.h"
00067 #include "cxx_memory.h"
00068 #include "wn.h"
00069 #ifndef _LEGO_CLONER
00070 #include "config_ipa.h"
00071 #include "ipo_parent.h"
00072 #endif
00073
00074 #include "clone.h"
00075 #include "targ_sim.h"
00076
00077
00078
00079
00080 class SCOPE_CONTEXT
00081 {
00082 private:
00083 SCOPE* _scope_tab;
00084
00085 public:
00086 SCOPE_CONTEXT (SCOPE *scope) {
00087 _scope_tab = Scope_tab;
00088 Scope_tab = scope;
00089 }
00090
00091 ~SCOPE_CONTEXT () {
00092 Scope_tab = _scope_tab;
00093 }
00094 };
00095
00096
00097
00098
00099
00100
00101
00102
00103
00104
00105 INT IPO_CLONE::_label = 0;
00106
00107
00108
00109
00110
00111
00112
00113
00114
00115 void
00116 IPO_CLONE::Set_Entry_Point(WN *wn, WN *cloned_wn, ST *cloned_st)
00117 {
00118 Is_True(wn && cloned_wn && cloned_st && _sym,
00119 ("IPO_CLONE::Set_Entry_Point parameter is null"));
00120 Is_True(WN_opcode(wn) == OPC_FUNC_ENTRY ||
00121 WN_opcode(wn) == OPC_ALTENTRY,
00122 ("Set_Entry_Point can only be invoked on FUNCTIONs\n"));
00123
00124 WN_st_idx(cloned_wn) = ST_st_idx(cloned_st);
00125
00126 #ifndef _LEGO_CLONER
00127
00128
00129 Set_ST_addr_not_saved(cloned_st);
00130
00131 Set_ST_export (cloned_st, EXPORT_INTERNAL);
00132 #endif
00133
00134 #if _THIS_SEEMS_TO_BE_DOING_NOTHING_
00135 ST *st = WN_st(wn);
00136 _sym->Set_Cloned_ST(st, cloned_st);
00137 _sym->Hide_Cloned_ST(st);
00138 #endif
00139 }
00140
00141
00142 #if 0 // obsolete function
00143
00144
00145
00146
00147 void
00148 IPO_CLONE::Set_Entry_Point (WN* wn, WN* cloned_wn)
00149 {
00150 Is_True(wn && cloned_wn && _sym,
00151 ("IPO_CLONE::Set_Entry_Point parameter is null"));
00152 Is_True(WN_opcode(wn) == OPC_FUNC_ENTRY ||
00153 WN_opcode(wn) == OPC_ALTENTRY,
00154 ("Set_Entry_Point can only be invoked on FUNCTIONs\n"));
00155
00156 ST* st = WN_st(wn);
00157 ST* cloned_st = _sym->IPO_Copy_ST(st, GLOBAL_SYMTAB);
00158
00159 if (WN_opcode(wn) == OPC_FUNC_ENTRY) {
00160
00161 PU_IDX pu_idx;
00162 PU& pu = New_PU (pu_idx);
00163 PU_Init (pu, ST_pu_type(st), PU_lexical_level(st));
00164 Set_ST_pu (cloned_st, pu_idx);
00165 }
00166
00167
00168
00169 Set_ST_addr_not_saved(cloned_st);
00170
00171 Set_ST_export (cloned_st, EXPORT_INTERNAL);
00172
00173 WN_st_idx(cloned_wn) = ST_st_idx(cloned_st);
00174
00175 _sym->Hide_Cloned_ST (st);
00176
00177 }
00178 #endif // obsolete function
00179
00180
00181
00182
00183
00184
00185 void
00186 IPO_CLONE::Fix_ST (WN* cloned_wn, WN* wn)
00187 {
00188 ST *st = NULL;
00189 ST *cloned_st;
00190
00191 FmtAssert(wn && cloned_wn && _sym,("IPO_CLONE::Fix_ST parameter is null"));
00192
00193 OPCODE op = WN_opcode(wn);
00194 if (OPCODE_has_sym(op))
00195 st = WN_st(wn);
00196
00197 if (st == NULL) {
00198
00199 INT lab_level, lab_index;
00200 if (OPCODE_has_label(op)) {
00201 lab_level = _sym->Get_cloned_level();
00202 lab_index = LABEL_IDX_index(WN_label_number(cloned_wn));
00203 lab_index += _sym->Get_cloned_label_last_idx();
00204 WN_label_number(cloned_wn) = make_LABEL_IDX(lab_index, lab_level);
00205 }
00206 if (OPCODE_has_last_label(op)) {
00207 lab_level = _sym->Get_cloned_level();
00208 lab_index = LABEL_IDX_index(WN_last_label(cloned_wn));
00209 lab_index += _sym->Get_cloned_label_last_idx();
00210 WN_last_label(cloned_wn) = make_LABEL_IDX(lab_index, lab_level);
00211 }
00212 return;
00213 }
00214
00215 if (WN_operator(wn) == OPR_PRAGMA &&
00216 WN_pragma(wn) == WN_PRAGMA_ASM_CONSTRAINT) {
00217 cloned_st = _sym->Get_Cloned_ST (&St_Table[(ST_IDX) WN_pragma_arg1(wn)]);
00218 if ((cloned_st != NULL) && (ST_level(cloned_st) == GLOBAL_SYMTAB)) {
00219 WN_pragma_arg1(wn) = (INT32) ST_st_idx(cloned_st);
00220 }
00221 else {
00222 cloned_st = _sym->Get_ST(&St_Table[(ST_IDX) WN_pragma_arg1(wn)]);
00223 }
00224 WN_pragma_arg1(cloned_wn) = (INT32) ST_st_idx(cloned_st);
00225 }
00226
00227 if (ST_class(st) == CLASS_PREG) {
00228
00229 WN_OFFSET offst;
00230
00231 if (WN_operator(wn) == OPR_PRAGMA) {
00232 if (WN_pragma(wn) != WN_PRAGMA_ASM_CONSTRAINT) {
00233 offst = WN_pragma_arg1(cloned_wn);
00234 if (!Preg_Is_Dedicated(offst))
00235 WN_pragma_arg1(cloned_wn) += _sym->Get_cloned_preg_last_idx();
00236 }
00237 }
00238 else {
00239 offst = WN_offset(cloned_wn);
00240 if (!Preg_Is_Dedicated(offst))
00241 WN_offset(cloned_wn) += _sym->Get_cloned_preg_last_idx();
00242 }
00243
00244 return;
00245 }
00246
00247 cloned_st = _sym->Get_Cloned_ST (st);
00248
00249 if ((cloned_st != NULL) && (ST_level(cloned_st) == GLOBAL_SYMTAB))
00250
00251 WN_st_idx(wn) = ST_st_idx(cloned_st);
00252 else
00253 cloned_st = _sym->Get_ST(st);
00254
00255 WN_st_idx(cloned_wn) = ST_st_idx(cloned_st);
00256
00257 }
00258
00259
00260
00261
00262
00263
00264 void
00265 IPO_CLONE::Fix_INITO(WN* cloned_wn, WN* wn)
00266 {
00267 FmtAssert(wn && cloned_wn && _sym,("IPO_CLONE::Fix_INITO parameter is null"));
00268
00269 INITO_IDX init_idx, init_cp_idx;
00270 if (init_idx = WN_ereg_supp(wn)) {
00271 if (_sym) {
00272
00273 if (init_cp_idx = _sym->Get_Cloned_INITO_IDX(_sym->Get_INITO(init_idx))) {
00274 WN_ereg_supp(cloned_wn) = init_cp_idx;
00275 WN_ereg_supp(wn) = init_cp_idx;
00276 }
00277 else
00278 WN_ereg_supp(cloned_wn) = _sym->Get_INITO_IDX(WN_ereg_supp(wn));
00279 }
00280 else {
00281 WN_ereg_supp(cloned_wn) = WN_ereg_supp(wn);
00282 }
00283 }
00284 }
00285
00286
00287
00288
00289
00290 static void
00291 Copy_PU_Flags(PU_IDX old_pu, PU_IDX new_pu)
00292 {
00293 #if _DONT_COPY_ALL_THE_FLAGS_
00294 Pu_Table[new_pu].flags |=
00295 (Pu_Table[old_pu].flags & (PU_HAS_EXC_SCOPES |
00296 PU_NEEDS_FILL_ALIGN_LOWERING |
00297 PU_HAS_VERY_HIGH_WHIRL |
00298 PU_MP_NEEDS_LNO |
00299 PU_HAS_ALLOCA |
00300 PU_HAS_MP |
00301 PU_HAS_NAMELIST |
00302 PU_UPLEVEL |
00303 PU_HAS_REGION ));
00304 #else
00305 Pu_Table[new_pu].src_lang = Pu_Table[old_pu].src_lang;
00306 Pu_Table[new_pu].flags = Pu_Table[old_pu].flags;
00307 #endif
00308 }
00309
00310
00311
00312
00313
00314
00315 WN *
00316 IPO_CLONE::Copy_Node (const WN *src_wn)
00317 {
00318 INT16 next_prev_ptrs
00319 = (OPERATOR_has_next_prev(WN_operator(src_wn)) ? 1 : 0);
00320 INT16 size = (sizeof(WN) +
00321 (sizeof(WN *) * (MAX(0,WN_kid_count(src_wn)-2))) +
00322 next_prev_ptrs * (sizeof(mUINT64) + (2 * sizeof(WN *))));
00323
00324 size = (size + 7) & (~7);
00325
00326
00327 if (_raw_buf_size < size) {
00328 UINT new_size = _default_buf_size;
00329 while (new_size < size)
00330 new_size *= 2;
00331 _raw_buffer = (WN *)MEM_POOL_Alloc(WN_mem_pool_ptr, new_size);
00332 BZERO (_raw_buffer, new_size);
00333 _raw_buf_size = new_size;
00334 }
00335
00336 WN *wn = _raw_buffer;
00337 _raw_buffer = (WN *) ((char *) _raw_buffer + size);
00338 _raw_buf_size -= size;
00339
00340 if (next_prev_ptrs) {
00341 STMT_WN *stmt_wn = (STMT_WN *) wn;
00342 wn = (WN *)&(WN_real_fields(stmt_wn));
00343
00344 WN_linenum(wn) = WN_linenum(src_wn);
00345 if (_cloned_node_file_id)
00346 USRCPOS_filenum(*(USRCPOS *)&(WN_linenum(wn))) = _cloned_node_file_id;
00347 }
00348
00349 wn->common = src_wn->common;
00350 WN_set_map_id(wn, (WN_MAP_ID) (-1));
00351
00352 WN_Copy_u1u2 (wn, src_wn);
00353 WN_Copy_u3 (wn, src_wn);
00354
00355 #if defined(TARG_SL) || defined(TARG_SL2)
00356
00357 WN_Copy_sl_ext(wn, src_wn);
00358 #endif
00359
00360 return(wn);
00361 }
00362
00363
00364
00365
00366
00367
00368
00369
00370
00371 WN *
00372 IPO_CLONE::Clone_Tree (WN *wn, ST *clone_st)
00373 {
00374 WN *ret_wn = NULL;
00375 WN* kid;
00376 WN* ret_kid;
00377 WN* prev_wn;
00378 OPCODE op;
00379
00380 if (wn == NULL)
00381 return NULL;
00382
00383 ret_wn = Copy_Node (wn);
00384
00385 op = WN_opcode(wn);
00386
00387 if (_sym) {
00388
00389
00390
00391
00392
00393 if ((WN_operator(wn) == OPR_REGION) && (WN_region_is_EH(wn))) {
00394 #if 0
00395
00396 if (_sym && (!_sym->Get_Cloned_Scope_Tab())) {
00397 INITO_IDX init_idx = WN_ereg_supp(wn);
00398 if (init_idx) {
00399
00400
00401
00402 INITO_IDX init_cp_idx;
00403 if (init_cp_idx = _sym->Get_Cloned_INITO_IDX(Get_INITO(init_idx))) {
00404 WN_ereg_supp(wn) = init_cp_idx;
00405 WN_ereg_supp(ret_wn) = init_cp_idx;
00406 }
00407 }
00408 }
00409 else
00410 #endif
00411
00412 Fix_INITO(ret_wn, wn);
00413 }
00414
00415
00416
00417
00418 if (op == OPC_ALTENTRY || op == OPC_FUNC_ENTRY) {
00419 if (_sym->Is_new_clone())
00420 Set_Entry_Point (wn, ret_wn, clone_st);
00421 }
00422 else if (OPCODE_has_sym(op) || OPCODE_has_label(op))
00423 Fix_ST (ret_wn, wn);
00424
00425 #if 0
00426
00427
00428
00429 if (OPCODE_has_sym(op) && WN_st(wn)) {
00430 ST * st = _sym->Get_Cloned_ST(ST_base(WN_st(wn)));
00431 if (st) {
00432 Set_ST_sclass(ST_base(WN_st(wn)),SCLASS_AUTO);
00433 Set_ST_base_idx(WN_st(ret_wn), ST_st_idx(st));
00434 Set_ST_base_idx(WN_st(wn), ST_st_idx(st));
00435 }
00436 }
00437 #endif
00438 }
00439
00440
00441 if (op == OPC_BLOCK) {
00442 ret_kid = NULL;
00443 kid = WN_first (wn);
00444 if (kid) {
00445 ret_kid = Clone_Tree (kid);
00446 WN_prev (ret_kid) = NULL;
00447 WN_first(ret_wn) = ret_kid;
00448
00449 if (_parent_map)
00450 IPA_WN_MAP_Set (_cloned_map_tab, _parent_map, ret_kid, ret_wn);
00451
00452 kid = WN_next (kid);
00453 prev_wn = ret_kid;
00454
00455 while (kid) {
00456 ret_kid = Clone_Tree (kid);
00457 WN_next (prev_wn) = ret_kid;
00458 WN_prev (ret_kid) = prev_wn;
00459
00460 if (_parent_map)
00461 IPA_WN_MAP_Set (_cloned_map_tab, _parent_map, ret_kid, ret_wn);
00462
00463 prev_wn = ret_kid;
00464 kid = WN_next(kid);
00465 }
00466
00467 WN_next(ret_kid) = NULL;
00468
00469 } else
00470 WN_first(ret_wn) = NULL;
00471
00472 WN_last(ret_wn) = ret_kid;
00473
00474 } else {
00475 INT kidno;
00476 for (kidno = 0; kidno < WN_kid_count(wn); kidno++) {
00477 if (WN_kid (wn, kidno)) {
00478 ret_kid = Clone_Tree (WN_kid (wn, kidno));
00479
00480 if (_parent_map)
00481 IPA_WN_MAP_Set (_cloned_map_tab, _parent_map,
00482 ret_kid, ret_wn);
00483
00484 WN_kid (ret_wn, kidno) = ret_kid;
00485 } else
00486 WN_kid (ret_wn, kidno) = NULL;
00487 }
00488 }
00489
00490 return ret_wn;
00491
00492 }
00493
00494
00495
00496
00497
00498
00499
00500
00501
00502
00503
00504 void
00505 IPO_CLONE::New_Clone (ST *clone_st)
00506 {
00507 _sym->New_Symtab();
00508
00509 _sym->Promote_Statics ();
00510
00511 FmtAssert(_orig_pu,("IPO_CLONE::orig_pu is null"));
00512 ST * s = WN_st(_orig_pu);
00513 #if 0
00514 SYMTAB_IDX o_symtab = _sym->Get_Orig_Level();
00515
00516 if (o_symtab && PU_has_exc_scopes(Get_Current_PU()))
00517 {
00518 _sym->Copy_INITO();
00519 }
00520 #endif
00521
00522 _cloned_map_tab = WN_MAP_TAB_Create (_mem);
00523
00524 _cloned_pu = Clone_Tree (_orig_pu, clone_st);
00525
00526 Copy_PU_Flags(ST_pu(s), ST_pu(WN_st(_cloned_pu)));
00527
00528 #ifndef _LEGO_CLONER
00529 _parent_map = IPA_WN_MAP_Create (_cloned_map_tab, _mem);
00530 WN_Parentize (_cloned_pu, _parent_map, _cloned_map_tab);
00531 #endif
00532
00533 }
00534
00535
00536
00537
00538
00539
00540
00541
00542
00543
00544
00545
00546 template <>
00547 inline void
00548 IPO_SYMTAB::fix_table_entry<ST>::operator () (UINT idx, ST* st) const
00549 {
00550 Set_ST_st_idx(st, make_ST_IDX(idx, _sym->Get_cloned_level()));
00551 if (ST_IDX_level (ST_base_idx (st)) == _sym->Get_orig_level ())
00552 Set_ST_base_idx(st, make_ST_IDX (ST_IDX_index (ST_base_idx (st)) +
00553 _sym->Get_cloned_st_last_idx (),
00554 _sym->Get_cloned_level ()));
00555 if (ST_base_idx(st) == ST_st_idx(st))
00556 Set_ST_ofst(st, 0);
00557 #ifdef KEY
00558
00559 if (ST_one_per_pu(st)) {
00560 Set_ST_is_not_used(st);
00561 return;
00562 }
00563 #endif
00564 switch (ST_sclass(st)) {
00565 case SCLASS_FORMAL:
00566 case SCLASS_FORMAL_REF:
00567
00568
00569 Set_ST_is_not_used(st);
00570 break;
00571 default:
00572 break;
00573 }
00574 }
00575
00576
00577
00578
00579 template <>
00580 inline void
00581 IPO_SYMTAB::fix_table_entry<INITO>::operator () (UINT idx, INITO* inito) const
00582 {
00583 Set_INITO_st_idx(*inito, make_ST_IDX(ST_IDX_index(INITO_st_idx(*inito))+_sym->Get_cloned_st_last_idx(), _sym->Get_cloned_level()));
00584 }
00585
00586
00587
00588
00589 template <>
00590 inline void
00591 IPO_SYMTAB::fix_table_entry<ST_ATTR>::operator () (UINT idx, ST_ATTR* st_attr) const
00592 {
00593
00594 Is_True (ST_ATTR_kind (*st_attr) == ST_ATTR_DEDICATED_REGISTER ||
00595 ST_ATTR_kind (*st_attr) == ST_ATTR_SECTION_NAME,
00596 ("expecting ST_ATTR_DEDICATED_REGISTER or ST_ATTR_SECTION_NAME"));
00597 ST_IDX st_idx = ST_ATTR_st_idx (*st_attr);
00598 Set_ST_ATTR_st_idx (*st_attr, make_ST_IDX (ST_IDX_index (st_idx) +
00599 _sym->Get_cloned_st_last_idx(),
00600 ST_IDX_level (st_idx)));
00601 }
00602
00603
00604
00605
00606
00607
00608
00609
00610
00611
00612
00613 void
00614 IPO_SYMTAB::Copy_Local_Tables(BOOL label_only)
00615 {
00616
00617 UINT32 start_idx = 0;
00618
00619 if (_is_new_clone == FALSE)
00620 start_idx = 1;
00621
00622 if (label_only == FALSE) {
00623 (void)Copy_array_range(*_orig_scope_tab[_orig_level].st_tab,
00624 *_cloned_scope_tab[_cloned_level].st_tab,
00625 start_idx,
00626 (_orig_scope_tab[_orig_level].st_tab)->Size());
00627
00628 (void)Copy_array_range(*_orig_scope_tab[_orig_level].preg_tab,
00629 *_cloned_scope_tab[_cloned_level].preg_tab,
00630 start_idx,
00631 (_orig_scope_tab[_orig_level].preg_tab)->Size());
00632
00633 (void)Copy_array_range(*_orig_scope_tab[_orig_level].st_attr_tab,
00634 *_cloned_scope_tab[_cloned_level].st_attr_tab,
00635 start_idx,
00636 (_orig_scope_tab[_orig_level].st_attr_tab)->Size());
00637
00638 (void)Copy_array_range(*_orig_scope_tab[_orig_level].inito_tab,
00639 *_cloned_scope_tab[_cloned_level].inito_tab,
00640 start_idx,
00641 (_orig_scope_tab[_orig_level].inito_tab)->Size());
00642
00643 }
00644 else {
00645
00646 Set_cloned_label_last_idx((_cloned_scope_tab[_cloned_level].label_tab)->Size()-1);
00647 Set_cloned_inito_last_idx((_cloned_scope_tab[_cloned_level].inito_tab)->Size()-1);
00648 #ifdef KEY
00649 if (PU_src_lang (Get_Current_PU()) & PU_CXX_LANG)
00650 {
00651 #if 0
00652
00653
00654
00655 for (int i=start_idx;
00656 i<(_orig_scope_tab[_orig_level].inito_tab)->Size(); ++i)
00657 {
00658 INITO copy = (*_orig_scope_tab[_orig_level].inito_tab)[i];
00659 if (ST_sclass(INITO_st(copy)) == SCLASS_EH_REGION_SUPP)
00660 (*_cloned_scope_tab[_cloned_level].inito_tab).Insert (copy);
00661 }
00662 #else
00663
00664
00665
00666 (void)Copy_array_range(*_orig_scope_tab[_orig_level].inito_tab,
00667 *_cloned_scope_tab[_cloned_level].inito_tab,
00668 start_idx,
00669 (_orig_scope_tab[_orig_level].inito_tab)->Size());
00670 #endif
00671 }
00672 #endif
00673 }
00674
00675 (void)Copy_array_range(*_orig_scope_tab[_orig_level].label_tab,
00676 *_cloned_scope_tab[_cloned_level].label_tab,
00677 start_idx,
00678 (_orig_scope_tab[_orig_level].label_tab)->Size());
00679
00680 (void)Delete_array_item(*_orig_scope_tab[_orig_level].label_tab,
00681 *_cloned_scope_tab[_cloned_level].label_tab,
00682 start_idx,
00683 (_orig_scope_tab[_orig_level].label_tab)->Size());
00684
00685 if ((_is_new_clone == FALSE) && (label_only == FALSE)) {
00686
00687
00688
00689 For_all_entries(*_cloned_scope_tab[_cloned_level].st_tab,
00690 fix_table_entry<ST> (this), _cloned_st_last_idx+1);
00691
00692 For_all_entries(*_cloned_scope_tab[_cloned_level].st_attr_tab,
00693 fix_table_entry<ST_ATTR> (this), _cloned_st_attr_last_idx+1);
00694 }
00695
00696 For_all_entries(*_cloned_scope_tab[_cloned_level].inito_tab,
00697 fix_table_entry<INITO> (this), _cloned_inito_last_idx+1);
00698
00699 }
00700
00701
00702
00703
00704
00705
00706
00707
00708 void
00709 IPO_SYMTAB::New_Symtab (void)
00710 {
00711
00712 FmtAssert(!PU_has_altentry(Pu_Table[ST_pu(_orig_scope_tab[_orig_level].st)]),
00713 ("Can't clone procedures with multiple entry point"));
00714
00715 SCOPE *_cloned_scope_tab = (SCOPE *) MEM_POOL_Alloc (_mem,
00716 (_orig_level+1) * sizeof(SCOPE));
00717
00718
00719
00720
00721 SYMTAB_IDX i;
00722 for (i = 1; i < _orig_level; ++i) {
00723 _cloned_scope_tab[i] = _orig_scope_tab[i];
00724 }
00725
00726 Set_Cloned_Symtab(_cloned_scope_tab);
00727
00728
00729
00730 SCOPE_CONTEXT switch_scope(_cloned_scope_tab);
00731
00732
00733
00734 New_Scope(_orig_level, _mem, FALSE);
00735
00736 Copy_Local_Tables(FALSE);
00737
00738 }
00739
00740
00741
00742
00743
00744
00745
00746
00747
00748 void
00749 IPO_SYMTAB::Update_Symtab (BOOL label_only)
00750 {
00751
00752 FmtAssert(!PU_has_altentry(Pu_Table[ST_pu(_orig_scope_tab[_orig_level].st)]),
00753 ("Can't inline procedures with multiple entry point"));
00754
00755 FmtAssert(_cloned_scope_tab, ("Cloned scope tab is not set up in Update_Symtab"));
00756
00757 Copy_Local_Tables(label_only);
00758 }
00759
00760 #ifdef KEY
00761
00762
00763
00764 static inline void
00765 traverse_initvs (INITV_IDX start, ST_IDX old, ST_IDX copy)
00766 {
00767 if (! start) return;
00768
00769 switch (INITV_kind (start))
00770 {
00771 case INITVKIND_BLOCK:
00772 traverse_initvs (INITV_blk (start), old, copy);
00773 traverse_initvs (INITV_next (start), old, copy);
00774 break;
00775 case INITVKIND_SYMOFF:
00776 {
00777 ST_IDX st = INITV_st (start);
00778 if (st == old)
00779 Set_INITV_st (start, copy);
00780
00781 }
00782 default:
00783 traverse_initvs (INITV_next (start), old, copy);
00784 break;
00785 }
00786 }
00787 #endif // KEY
00788
00789
00790
00791
00792
00793 template<>
00794 inline void
00795 IPO_SYMTAB::promote_entry<ST>::operator () (UINT idx, ST* old_st) const
00796 {
00797 ST *copy_st;
00798 ST_IDX old_st_idx = ST_st_idx(old_st);
00799 INITO_TAB *it_tab = Scope_tab[ST_IDX_level(old_st_idx)].inito_tab;
00800 int it_tab_size = it_tab->Size();
00801
00802 switch (ST_sclass(old_st)) {
00803 case SCLASS_PSTATIC:
00804 case SCLASS_FSTATIC:
00805 copy_st = _sym->IPO_Copy_ST(old_st, GLOBAL_SYMTAB);
00806 Set_ST_sclass(copy_st, SCLASS_FSTATIC);
00807 Set_ST_is_not_used(old_st);
00808 #ifdef TARG_X8664
00809
00810
00811
00812
00813
00814
00815
00816 if ( ST_sym_class(copy_st) == CLASS_VAR &&
00817 !ST_is_equivalenced(copy_st) ) {
00818 TY_IDX ty = ST_type(copy_st);
00819 if (TY_kind(ST_type(copy_st)) == KIND_POINTER) {
00820 ty = TY_pointed(ST_type(copy_st));
00821 }
00822 if (TY_kind(ty) != KIND_FUNCTION) {
00823 TY_IDX st_ty_idx = ST_type(copy_st);
00824 Set_TY_align_exp(st_ty_idx, 4);
00825 Set_ST_type(copy_st, st_ty_idx);
00826 }
00827 }
00828 #endif
00829
00830
00831
00832 for(INITO_IDX it_idx = 1; it_idx<(INITO_IDX)it_tab_size; it_idx++) {
00833 INITV_IDX iv_idx = (*it_tab)[it_idx].val;
00834 #ifdef KEY
00835 traverse_initvs (iv_idx, ST_st_idx (old_st), ST_st_idx (copy_st));
00836 #else
00837 INITV &iv = Initv_Table[iv_idx];
00838 switch (INITV_kind(iv)) {
00839 case INITVKIND_SYMOFF:
00840 {
00841 ST* initv_st = &St_Table[INITV_st(iv)];
00842 if(initv_st == old_st)
00843 Set_INITV_st(iv_idx, ST_st_idx(copy_st));
00844 }
00845 break;
00846 case INITVKIND_SYMDIFF:
00847 case INITVKIND_SYMDIFF16:
00848 case INITVKIND_LABEL:
00849 case INITVKIND_BLOCK:
00850 default:
00851 break;
00852 }
00853 #endif // KEY
00854 }
00855 break;
00856 default:
00857 break;
00858 }
00859 }
00860
00861
00862 template <>
00863 inline void
00864 IPO_SYMTAB::promote_entry<ST_ATTR>::operator () (UINT idx, ST_ATTR* old_attr) const
00865 {
00866
00867
00868 ST *orig_ST = &St_Table[ST_ATTR_st_idx (*old_attr)];
00869 ST *cloned_ST = _sym->Get_Cloned_ST(orig_ST);
00870 if ( cloned_ST ) {
00871 ST_ATTR_IDX new_attr_idx;
00872 ST_ATTR& new_attr = New_ST_ATTR(GLOBAL_SYMTAB, new_attr_idx);
00873 ST_ATTR_Init(new_attr, ST_st_idx(cloned_ST),
00874 ST_ATTR_kind(*old_attr), ST_ATTR_section_name(*old_attr) );
00875 }
00876 }
00877
00878
00879
00880
00881
00882
00883
00884 template <>
00885 inline void
00886 IPO_SYMTAB::fix_base<ST>::operator () (UINT idx, ST* old_st) const
00887 {
00888 ST *copy_st = NULL;
00889
00890 switch (ST_sclass(old_st)) {
00891 case SCLASS_PSTATIC:
00892 case SCLASS_FSTATIC:
00893 copy_st = _sym->Get_Cloned_ST(old_st);
00894 Is_True(copy_st, ("PSTATIC symbol must have been promoted at this point"));
00895 if (ST_base_idx (old_st) != ST_st_idx (old_st)) {
00896
00897 ST *st = _sym->Get_Cloned_ST(ST_base(old_st));
00898 Is_True(st, ("Base of PSTATIC symbol must have been promoted at this point"));
00899 Set_ST_base_idx(copy_st, ST_st_idx(st));
00900 }
00901 break;
00902 default:
00903 break;
00904 }
00905 }
00906
00907 template <>
00908 inline void
00909 IPO_SYMTAB::promote_entry<INITO>::operator () (UINT idx, INITO* old_inito) const
00910 {
00911
00912
00913 ST *cloned_ST = _sym->Get_Cloned_ST(INITO_st(old_inito));
00914 if (cloned_ST) {
00915 INITO_IDX new_inito_idx = New_INITO(ST_st_idx(cloned_ST), old_inito->val);
00916 _sym->Set_Cloned_INITO(old_inito, new_inito_idx);
00917 }
00918 }
00919
00920 void
00921 IPO_SYMTAB::Promote_Statics (void)
00922 {
00923
00924 For_all (St_Table, _orig_level, promote_entry<ST>(this));
00925 For_all (St_Table, _orig_level, fix_base<ST>(this));
00926 For_all (Inito_Table, _orig_level, promote_entry<INITO>(this));
00927
00928 For_all (St_Attr_Table, _orig_level, promote_entry<ST_ATTR>(this));
00929
00930 }
00931
00932
00933
00934
00935 ST*
00936 IPO_SYMTAB::IPO_Copy_ST (ST* st, SYMTAB_IDX scope)
00937 {
00938 ST* new_st;
00939
00940 new_st = Get_Cloned_ST(st);
00941
00942
00943
00944
00945 if (new_st && (scope == GLOBAL_SYMTAB))
00946 return new_st;
00947
00948
00949
00950 SCOPE_CONTEXT switch_scope(_cloned_scope_tab);
00951
00952 new_st = Copy_ST_No_Base(st, scope);
00953
00954 Set_Cloned_ST(st, new_st);
00955
00956 return new_st;
00957 }
00958
00959
00960 INITO_IDX
00961 IPO_SYMTAB::Copy_INITO(INITO_IDX orig_init_idx)
00962 {
00963 FmtAssert(FALSE,("IPO_SYMTAB::Copy_INITO NOT IMPLEMENTED FOR NEW SYMTAB\n"));
00964 return orig_init_idx;
00965 }
00966
00967 void
00968 IPO_SYMTAB::Set_Cloned_ST (ST *old_st, ST* new_st)
00969 {
00970
00971 _hash_maps->Insert(old_st, new_st);
00972 }
00973
00974 void
00975 IPO_SYMTAB::Set_Cloned_INITO (INITO *old_inito, INITO_IDX new_inito)
00976 {
00977
00978 _hash_maps->Insert(old_inito, (void *)(INTPTR)new_inito);
00979 }
00980
00981 INITV_IDX
00982 IPO_SYMTAB::Clone_INITVs_For_EH (INITV_IDX inov, INITO_IDX ino)
00983 {
00984 INITV_IDX head=0, tail=0;
00985
00986 while (inov) {
00987 INITV_IDX cloned_iv = Copy_INITV(tail, ino, inov);
00988 INITV &iv = Initv_Table[inov];
00989 INITV &c_iv = Initv_Table[cloned_iv];
00990
00991 if (head == 0)
00992 head = tail = cloned_iv;
00993
00994 tail = cloned_iv;
00995
00996 switch (INITV_kind(iv)) {
00997 case INITVKIND_SYMOFF:
00998 {
00999 ST* initv_st = Get_Orig_ST(INITV_st(iv));
01000 ST* cloned_st;
01001
01002 if (ST_level(initv_st) == GLOBAL_SYMTAB)
01003 cloned_st = initv_st;
01004 else
01005 cloned_st = Get_Cloned_ST(initv_st);
01006
01007 if (cloned_st == NULL) {
01008 cloned_st = Get_ST(initv_st);
01009
01010 switch (ST_sclass(cloned_st)) {
01011 case SCLASS_FORMAL:
01012 case SCLASS_FORMAL_REF:
01013 if (ST_is_not_used(cloned_st)) {
01014
01015
01016 cloned_st = Get_Cloned_ST(cloned_st);
01017 Is_True(cloned_st, ("FORMAL ST should have been cloned"));
01018 }
01019 break;
01020 default:
01021 break;
01022 }
01023 }
01024
01025 Set_INITV_st (cloned_iv, ST_st_idx(cloned_st));
01026 }
01027 break;
01028 case INITVKIND_SYMDIFF:
01029 case INITVKIND_SYMDIFF16:
01030 {
01031 ST* initv_st = Get_Orig_ST(INITV_st2(iv));
01032 ST* cloned_st;
01033
01034 if (ST_level(initv_st) == GLOBAL_SYMTAB)
01035 cloned_st = initv_st;
01036 else
01037 cloned_st = Get_Cloned_ST(initv_st);
01038
01039 if (cloned_st == NULL) {
01040 cloned_st = Get_ST(initv_st);
01041
01042 switch (ST_sclass(cloned_st)) {
01043 case SCLASS_FORMAL:
01044 case SCLASS_FORMAL_REF:
01045 if (ST_is_not_used(cloned_st)) {
01046
01047
01048 cloned_st = Get_Cloned_ST(cloned_st);
01049 Is_True(cloned_st, ("FORMAL ST should have been cloned"));
01050 }
01051 break;
01052 default:
01053 break;
01054 }
01055 }
01056 INT lab_level = LABEL_IDX_level(INITV_lab1(iv));
01057 INT lab_index = LABEL_IDX_index(INITV_lab1(iv)) +
01058 Get_cloned_label_last_idx();
01059 Set_INITV_lab1 (cloned_iv, make_LABEL_IDX(lab_index, lab_level));
01060
01061 Set_INITV_st2 (cloned_iv, ST_st_idx(cloned_st));
01062 }
01063 break;
01064
01065 case INITVKIND_LABEL:
01066 {
01067 INT lab_level = LABEL_IDX_level(INITV_lab(iv));
01068 INT lab_index = LABEL_IDX_index(INITV_lab(iv)) +
01069 Get_cloned_label_last_idx();
01070 Set_INITV_lab (cloned_iv, make_LABEL_IDX(lab_index, lab_level));
01071 break;
01072 }
01073
01074 case INITVKIND_BLOCK:
01075 Set_INITV_blk(cloned_iv, Clone_INITVs_For_EH (INITV_blk(iv), ino));
01076 break;
01077
01078 default:
01079 break;
01080 }
01081
01082
01083 inov = INITV_next(iv);
01084 }
01085
01086 return head;
01087
01088 }
01089
01090
01091
01092
01093
01094
01095
01096 const INT IPO_ADDR_HASH::hash_size;
01097
01098 void
01099 IPO_ADDR_HASH::Insert (void *orig, void *copy)
01100 {
01101 struct hash_node *p = CXX_NEW (struct hash_node, mem);
01102 INT hash_value = hash ((INT)(INTPS) orig);
01103
01104 p->orig = orig;
01105 p->copy = copy;
01106 p->next = table[hash_value];
01107 table[hash_value] = p;
01108 table_empty = FALSE;
01109
01110 }
01111
01112 void *
01113 IPO_ADDR_HASH::Lookup (void *key)
01114 {
01115 if (key == 0 || table_empty)
01116 return 0;
01117
01118 INT hash_value = hash ((INT)(INTPS) key);
01119 struct hash_node *p = table[hash_value];
01120
01121 while (p) {
01122 if (p->orig == key)
01123 return p->copy;
01124 p = p->next;
01125 }
01126
01127 return 0;
01128 }
01129
01130
01131
01132
01133
01134
01135 void
01136 IPO_ADDR_HASH::Reset_Lookup (void *key)
01137 {
01138 if (key == 0 || table_empty)
01139 return;
01140
01141 INT hash_value = hash ((INT)(INTPS) key);
01142 struct hash_node *p = table[hash_value];
01143 struct hash_node *prev = table[hash_value];
01144
01145 while (p) {
01146 if (p->orig == key)
01147 {
01148 if (table[hash_value] == p)
01149 table[hash_value] = p->next;
01150 else
01151 prev->next = p->next;
01152 CXX_DELETE(p, mem);
01153 return;
01154 }
01155 prev = p;
01156 p = p->next;
01157 }
01158 }
01159