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 #ifndef clone_INCLUDED
00038 #define clone_INCLUDED
00039
00040
00041
00042
00043
00044
00045
00046
00047
00048
00049
00050
00051
00052
00053
00054
00055
00056
00057
00058
00059
00060
00061 #ifndef __SGI_STL_ALGO_H
00062
00063 # include <algorithm>
00064
00065 #endif // __SGI_STL_ALGO_H
00066
00067 #ifndef __SGI_STL_HASH_MAP_H
00068
00069 # ifndef _USE_STL_EXT
00070 # include <map>
00071 # else
00072 # include <hash_map>
00073 # endif
00074
00075 #endif
00076
00077 using namespace std;
00078
00079
00080 #ifndef CXX_MEMORY_INCLUDED
00081 #include "cxx_memory.h"
00082 #endif
00083
00084 #include "defs.h"
00085
00086 #include "symtab.h"
00087 #include "wn.h"
00088
00089
00090
00091
00092
00093
00094
00095
00096
00097
00098
00099
00100
00101
00102
00103
00104
00105
00106
00107
00108
00109
00110
00111
00112
00113
00114
00115
00116
00117
00118
00119
00120
00121 class IPO_ADDR_HASH {
00122
00123 private:
00124
00125 static const INT hash_size = 256;
00126
00127 struct hash_node {
00128 void *orig;
00129 void *copy;
00130 struct hash_node *next;
00131 } *table[hash_size];
00132
00133 MEM_POOL *mem;
00134
00135 BOOL table_empty;
00136
00137 INT hash (INT key) {
00138 return (key & 0xff) ^ ((key >> 8) & 0xff);
00139 };
00140
00141 public:
00142
00143 IPO_ADDR_HASH (MEM_POOL *m) {
00144 mem = m;
00145 table_empty = TRUE;
00146 memset (table, '\0', sizeof(table));
00147 };
00148
00149 void Insert (void *orig, void *copy);
00150
00151 void *Lookup (void *);
00152
00153 void Clear (void) {
00154 if (!table_empty) {
00155 memset (table, '\0', sizeof(table));
00156 table_empty = TRUE;
00157 }
00158 };
00159
00160 void Reset_Lookup (void *key);
00161 };
00162
00163
00164 class IPO_SYMTAB {
00165
00166 private:
00167
00168 SCOPE *_orig_scope_tab;
00169 SCOPE *_cloned_scope_tab;
00170 SYMTAB_IDX _orig_level;
00171 SYMTAB_IDX _cloned_level;
00172
00173 MEM_POOL *_mem;
00174 IPO_ADDR_HASH *_hash_maps;
00175
00176
00177 BOOL _same_file;
00178 UINT _cloned_st_last_idx;
00179
00180
00181
00182
00183
00184 UINT _cloned_inito_last_idx;
00185
00186
00187
00188
00189
00190 UINT _cloned_label_last_idx;
00191
00192
00193
00194
00195
00196 UINT _cloned_preg_last_idx;
00197
00198
00199
00200
00201 UINT _cloned_st_attr_last_idx;
00202
00203
00204
00205
00206 BOOL _is_new_clone;
00207
00208
00209
00210 void Copy_Local_Tables(BOOL);
00211
00212 template <class T>
00213 struct fix_table_entry
00214 {
00215 IPO_SYMTAB *_sym;
00216
00217 fix_table_entry(IPO_SYMTAB *sym): _sym(sym) {}
00218
00219 void operator () (UINT idx, T *entry) const;
00220 };
00221
00222 template <class T>
00223 struct promote_entry
00224 {
00225 IPO_SYMTAB *_sym;
00226
00227 promote_entry(IPO_SYMTAB *sym): _sym(sym) {}
00228
00229 void operator () (UINT idx, T* entry) const;
00230 };
00231
00232 template <class T>
00233 struct fix_base
00234 {
00235 IPO_SYMTAB *_sym;
00236
00237 fix_base(IPO_SYMTAB *sym): _sym(sym) {}
00238
00239 void operator () (UINT idx, T* entry) const;
00240 };
00241
00242 public:
00243
00244
00245
00246
00247 IPO_SYMTAB (SCOPE *orig_scope_tab,
00248 SYMTAB_IDX symtab_idx, MEM_POOL *m) :
00249 _orig_scope_tab(orig_scope_tab), _cloned_scope_tab(NULL), _mem(m),
00250 _same_file(TRUE), _orig_level(symtab_idx), _cloned_level(symtab_idx) {
00251 _cloned_st_last_idx = 0;
00252 _cloned_inito_last_idx = 0;
00253 _cloned_label_last_idx = 0;
00254 _cloned_preg_last_idx = 0;
00255 _cloned_st_attr_last_idx = 0;
00256 _is_new_clone = TRUE;
00257 _hash_maps = CXX_NEW (IPO_ADDR_HASH (m), m);
00258 };
00259
00260
00261 IPO_SYMTAB (SCOPE *orig_scope_tab, SCOPE *cloned_scope_tab,
00262 SYMTAB_IDX orig_symtab_idx,
00263 SYMTAB_IDX cloned_symtab_idx, MEM_POOL *m,
00264 BOOL Same_file = TRUE) :
00265 _orig_scope_tab(orig_scope_tab), _cloned_scope_tab(cloned_scope_tab),
00266 _mem(m), _same_file(Same_file), _orig_level(orig_symtab_idx), _cloned_level(cloned_symtab_idx) {
00267 _cloned_st_last_idx = cloned_scope_tab[cloned_symtab_idx].st_tab->Size()-1;
00268 _cloned_inito_last_idx = cloned_scope_tab[cloned_symtab_idx].inito_tab->Size()-1;
00269 _cloned_label_last_idx = cloned_scope_tab[cloned_symtab_idx].label_tab->Size()-1;
00270 _cloned_preg_last_idx = cloned_scope_tab[cloned_symtab_idx].preg_tab->Size()-1;
00271 _cloned_st_attr_last_idx = cloned_scope_tab[cloned_symtab_idx].st_attr_tab->Size()-1;
00272 _is_new_clone = FALSE;
00273 _hash_maps = CXX_NEW (IPO_ADDR_HASH (m), m);
00274 };
00275
00276
00277 void New_Symtab ();
00278
00279
00280 void Update_Symtab (BOOL);
00281
00282
00283 void Promote_Statics ();
00284
00285 INITO_IDX Copy_INITO(INITO_IDX orig_init=0);
00286
00287
00288
00289 INITV_IDX Clone_INITVs_For_EH (INITV_IDX , INITO_IDX );
00290
00291
00292
00293 SCOPE* Get_orig_scope_tab () const { return _orig_scope_tab; }
00294 SCOPE* Get_cloned_scope_tab () const { return _cloned_scope_tab; }
00295 SYMTAB_IDX Get_orig_level () const { return _orig_level;}
00296 SYMTAB_IDX Get_cloned_level () const { return _cloned_level;}
00297 UINT Get_cloned_st_last_idx () const { return _cloned_st_last_idx;}
00298 UINT Get_cloned_inito_last_idx() const { return _cloned_inito_last_idx;}
00299 void Set_cloned_inito_last_idx (UINT idx) { _cloned_inito_last_idx = idx;}
00300 UINT Get_cloned_label_last_idx () const { return _cloned_label_last_idx;}
00301 void Set_cloned_label_last_idx (UINT idx) { _cloned_label_last_idx = idx;}
00302 UINT Get_cloned_preg_last_idx() const { return _cloned_preg_last_idx;}
00303 UINT Get_cloned_st_attr_last_idx() const { return _cloned_st_attr_last_idx;}
00304 BOOL Is_new_clone () const { return _is_new_clone; }
00305 BOOL Same_file () const { return _same_file; }
00306
00307 void Set_Cloned_Symtab (SCOPE *scope_tab) {
00308 _cloned_scope_tab = scope_tab;
00309 }
00310
00311 void Set_Cloned_ST(ST* old_st, ST* new_st);
00312
00313 ST* Get_Cloned_ST(ST* old_st) {return (ST *) _hash_maps->Lookup (old_st); };
00314
00315 void Hide_Cloned_ST (ST *st) { _hash_maps->Reset_Lookup (st); };
00316
00317 void Set_Cloned_INITO(INITO* old_inito, INITO_IDX new_inito);
00318
00319 INITO_IDX Get_Cloned_INITO_IDX(INITO* old_inito) {
00320 return (INITO_IDX)(INTPTR)_hash_maps->Lookup (old_inito);
00321 }
00322
00323 ST* Get_ST(ST* old_st) {
00324 return ((ST_level(old_st) != _orig_level)? old_st : &_cloned_scope_tab[_cloned_level].st_tab->Entry(ST_index(old_st)+_cloned_st_last_idx));
00325 }
00326
00327 INITO_IDX Get_INITO_IDX(INITO_IDX old_inito) {
00328 return make_INITO_IDX(INITO_IDX_index(old_inito)+_cloned_inito_last_idx, _cloned_level);
00329 }
00330
00331 INITO* Get_INITO(INITO_IDX idx) {
00332 SYMTAB_IDX level = INITO_IDX_level (idx);
00333 UINT32 index = INITO_IDX_index (idx);
00334 return (&_orig_scope_tab[_orig_level].inito_tab->Entry(index));
00335 }
00336
00337 ST* Get_Orig_ST(ST_IDX idx) {
00338 return (&_orig_scope_tab[ST_IDX_level(idx)].st_tab->Entry(ST_IDX_index(idx)));
00339 }
00340
00341 ST* IPO_Copy_ST (ST* st, SYMTAB_IDX scope);
00342
00343 BOOL Is_Cloned_ST(ST* st) { return ((ST_level(st) != _cloned_level) ||
00344 (ST_index(st) > _cloned_st_last_idx)); }
00345
00346 };
00347
00348
00349
00350
00351
00352
00353
00354
00355
00356
00357
00358
00359 class IPO_CLONE {
00360
00361 private:
00362
00363 WN *_orig_pu;
00364 WN *_cloned_pu;
00365
00366 IPO_SYMTAB *_sym;
00367
00368 static INT _label;
00369 static const INT _default_buf_size = 2048;
00370
00371 WN_MAP_TAB *_orig_map_tab;
00372 WN_MAP_TAB *_cloned_map_tab;
00373
00374 WN_MAP _parent_map;
00375
00376 MEM_POOL *_mem;
00377
00378 BOOL _same_file;
00379
00380 mUINT16 _cloned_node_file_id;
00381
00382
00383 WN *_raw_buffer;
00384 UINT _raw_buf_size;
00385
00386
00387
00388
00389
00390 void Fix_ST (WN *, WN *);
00391 void Fix_TY (WN *, WN *);
00392 void Fix_INITO(WN* cloned_wn, WN* wn);
00393
00394 WN *Copy_Node (const WN *src_wn);
00395
00396 public:
00397
00398
00399
00400
00401
00402 IPO_CLONE (WN *pu,
00403 SCOPE *scope_tab,
00404 SYMTAB_IDX symtab_idx,
00405 WN_MAP_TAB* map_tab,
00406 MEM_POOL *map_pool,
00407 MEM_POOL *m) :
00408 _orig_map_tab(map_tab), _cloned_map_tab(NULL), _parent_map(0),
00409 _sym(CXX_NEW (IPO_SYMTAB (scope_tab, symtab_idx, m), m)),
00410 _orig_pu(pu), _cloned_pu(NULL),
00411 _mem(map_pool),
00412 _cloned_node_file_id(0),
00413 _same_file(TRUE), _raw_buf_size(0)
00414 {
00415 };
00416
00417
00418
00419
00420
00421
00422 IPO_CLONE (WN_MAP_TAB *caller,
00423 WN_MAP_TAB *callee,
00424 WN_MAP parent,
00425 SCOPE *callee_scope_tab=NULL,
00426 SCOPE *caller_scope_tab=NULL,
00427 SYMTAB_IDX callee_symtab_idx=0,
00428 SYMTAB_IDX caller_symtab_idx=0,
00429 IPO_SYMTAB *cloned_symtab=NULL,
00430 MEM_POOL *map_pool=NULL,
00431 BOOL same_file=TRUE,
00432 mUINT16 filenum=0) :
00433 _orig_pu(NULL), _cloned_pu(NULL),
00434 #if (!(defined(linux) && defined(_LP64)))
00435 _sym(cloned_symtab? cloned_symtab :
00436 (callee_scope_tab == NULL? NULL :
00437 CXX_NEW(IPO_SYMTAB(callee_scope_tab,
00438 caller_scope_tab,
00439 callee_symtab_idx,
00440 caller_symtab_idx,
00441 Malloc_Mem_Pool, same_file),
00442 Malloc_Mem_Pool))),
00443 #endif
00444 _orig_map_tab (callee), _cloned_map_tab(caller), _parent_map(parent),
00445 _mem(map_pool),
00446 _cloned_node_file_id(filenum),
00447 _same_file(same_file), _raw_buf_size (0)
00448 {
00449 #if defined(linux) && defined(_LP64)
00450 if ((cloned_symtab == NULL) && (callee_scope_tab != NULL))
00451 _sym = CXX_NEW (IPO_SYMTAB (callee_scope_tab,
00452 caller_scope_tab,
00453 callee_symtab_idx,
00454 caller_symtab_idx,
00455 Malloc_Mem_Pool, same_file),
00456 Malloc_Mem_Pool);
00457 else
00458 _sym = cloned_symtab;
00459 #endif
00460 };
00461
00462
00463 IPO_CLONE (IPO_SYMTAB *ipo_symtab) :
00464 _orig_map_tab(NULL), _cloned_map_tab(NULL), _parent_map(0),
00465 _sym(ipo_symtab),
00466 _orig_pu(NULL), _cloned_pu(NULL),
00467 _mem(NULL),
00468 _cloned_node_file_id(0),
00469 _same_file(ipo_symtab->Same_file()), _raw_buf_size(0)
00470 {
00471 };
00472
00473
00474 void Set_Entry_Point (WN *, WN *, ST *);
00475 #if 0
00476 void Set_Entry_Point (WN *, WN *);
00477 #endif
00478
00479
00480 WN *Clone_Tree (WN *, ST *clone_st = NULL);
00481
00482
00483 void New_Clone (ST *clone_st = NULL);
00484
00485
00486 void Promote_Statics() { _sym ->Promote_Statics();}
00487
00488
00489 WN *Get_Cloned_PU () const { return _cloned_pu; };
00490
00491 SCOPE* Get_Cloned_Symtab () const { return _sym->Get_cloned_scope_tab (); };
00492
00493 char *Get_Func_Name () { return ST_name(WN_st(_cloned_pu)); };
00494
00495 WN_MAP_TAB *Get_Cloned_maptab () { return _cloned_map_tab; };
00496
00497 WN_MAP Get_parent_map () { return _parent_map; };
00498
00499 ST *Get_Func_ST () { return WN_st(_cloned_pu); };
00500
00501 IPO_SYMTAB *Get_sym() { return _sym; };
00502
00503
00504 };
00505
00506
00507 #endif // clone_INCLUDED
00508