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