Open64 (mfef90, whirl2f, and IR tools)
TAG: version-openad; SVN changeset: 916
|
00001 /* 00002 00003 Copyright (C) 2000, 2001 Silicon Graphics, Inc. All Rights Reserved. 00004 00005 This program is free software; you can redistribute it and/or modify it 00006 under the terms of version 2 of the GNU General Public License as 00007 published by the Free Software Foundation. 00008 00009 This program is distributed in the hope that it would be useful, but 00010 WITHOUT ANY WARRANTY; without even the implied warranty of 00011 MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. 00012 00013 Further, this software is distributed without any warranty that it is 00014 free of the rightful claim of any third person regarding infringement 00015 or the like. Any license provided herein, whether implied or 00016 otherwise, applies only to this software file. Patent licenses, if 00017 any, provided herein do not apply to combinations of this program with 00018 other software, or any other product whatsoever. 00019 00020 You should have received a copy of the GNU General Public License along 00021 with this program; if not, write the Free Software Foundation, Inc., 59 00022 Temple Place - Suite 330, Boston MA 02111-1307, USA. 00023 00024 Contact information: Silicon Graphics, Inc., 1600 Amphitheatre Pky, 00025 Mountain View, CA 94043, or: 00026 00027 http://www.sgi.com 00028 00029 For further information regarding this notice, see: 00030 00031 http://oss.sgi.com/projects/GenInfo/NoticeExplan 00032 00033 */ 00034 00035 00036 /* -*-Mode: c++;-*- (Tell emacs to use c++ mode) */ 00037 #ifndef clone_INCLUDED 00038 #define clone_INCLUDED 00039 // ==================================================================== 00040 // ==================================================================== 00041 // 00042 // 00043 // Revision history: 00044 // 22-Sep-97 - Original Version 00045 // 00046 // Description: 00047 // 00048 // ======================= PU and Symtab clone routines ======================= 00049 00050 // CLONE LEGALITY: 00051 // (a) Cannot clone recursive PUs (TODO: investigate how to do this) 00052 // (b) Cannot clone alternate entry pts PUS 00053 00054 // CLONE USAGE: 00055 // * During inlining (clone callee) 00056 // * During constant propogation (function cloning): 00057 // - need to generate unique names, need to create new "scope" struct 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 /* __SGI_STL_HASHTABLE_H */ 00076 00077 using namespace std; 00078 00079 00080 #ifndef CXX_MEMORY_INCLUDED 00081 #include "cxx_memory.h" // For CXX_NEW 00082 #endif /* CXX_MEMORY_INCLUDED */ 00083 00084 #include "defs.h" 00085 00086 #include "symtab.h" // for Scope_tab 00087 #include "wn.h" // includes wn_map.h 00088 00089 00090 // ====================================================================== 00091 // IPO_SYMTAB class: encapsulates LOCAL symbol table info 00092 // Under the new symtab design, the local symbol table contains info on 00093 // a. LABEL_TAB, PREG_TAB (local ONLY) 00094 // b. ST_TAB, INITO_TAB, INITV_TAB, and ST_ATTR_TAB (local/global) 00095 // Maps SYMTAB_IDX (original symtab) ---> SYMTAB_IDX (cloned symtab) 00096 // ====================================================================== 00097 // (1) Function Inlining 00098 // - create copy of callee whirl tree 00099 // - Promote PU Statics to File Statics (These go into IPA Global symtab) 00100 // - Append callee local tables to caller local tables 00101 // (label, preg, st, inito): compute offsets for each of these tables 00102 // - Assume: Global Tables already fixed when PUs are read in 00103 // ie IPA Global symtab is all set and has necessary maps 00104 // - Fix/Patch ST and TY in callee using offsets and Global Maps 00105 // - Clone INITVs, INITOs 00106 // (2) Function Cloning 00107 // - create copy of callee whirl tree 00108 // - Note: pu, cloned_pu are in same_file 00109 // - Create copy of scope[orig_symtab_idx] : the "new" symtab for cloned pu 00110 // (copy all 4 local tables: label, preg, st, inito 00111 // - Note: during function cloning "global" tables don't change EXCEPT 00112 // - Create new ST in global st table for "cloned" pu 00113 // - Fix/Patch local table info in cloned pu (using the copy of scope[..] 00114 // - Promote PU Statics to File Statics (These go into IPA Global symtab) 00115 // Needed because both pu and cloned_pu need to access same static 00116 // 00117 00118 // Generic hash table for mapping a pair of addresses. Used for 00119 // mapping the address of a TY/ST to that of its copy. 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 }; // IPO_ADDR_HASH 00162 00163 00164 class IPO_SYMTAB { 00165 00166 private: 00167 00168 SCOPE *_orig_scope_tab; // Original (input) scope table 00169 SCOPE *_cloned_scope_tab; // Cloned (output) scope table 00170 SYMTAB_IDX _orig_level; // The level of current PU in orig scope_table 00171 SYMTAB_IDX _cloned_level; // The level of cloned PU in cloned scope_table 00172 // Same as _orig_level for PU cloning 00173 MEM_POOL *_mem; // for temp. data structures 00174 IPO_ADDR_HASH *_hash_maps; // maps for lookup 00175 // used for initos and STs 00176 00177 BOOL _same_file; // both symtabs come from the same file 00178 UINT _cloned_st_last_idx; // If the table is newly cloned, 00179 // then this has value = 0 00180 // otherwise it contains the 00181 // last st_idx of the ST_TAB 00182 // of the passed-in _cloned_level 00183 // usually for inlining purpose 00184 UINT _cloned_inito_last_idx; // If the table is newly cloned, 00185 // then this has value = 0 00186 // otherwise it contains the 00187 // last inito_idx of the INITO_TAB 00188 // of the passed-in _cloned_level 00189 // usually for inlining purpose 00190 UINT _cloned_label_last_idx; // If the table is newly cloned, 00191 // then this has value = 0 00192 // otherwise it contains the 00193 // last st_idx of the LABEL_TAB 00194 // of the passed-in _cloned_level 00195 // usually for inlining purpose 00196 UINT _cloned_preg_last_idx; // If the table is newly cloned, 00197 // then this has value = 0 00198 // otherwise it contains the 00199 // last preg_idx of the PREG_TAB 00200 // of the passed-in _cloned_level 00201 UINT _cloned_st_attr_last_idx; // If the table is newly cloned, 00202 // then this has value = 0 00203 // otherwise it contains the 00204 // last st_attr_idx of the ST_ATTR_TAB 00205 // of the passed-in _cloned_level 00206 BOOL _is_new_clone; // True if really creates a brand new 00207 // PU, false as in the case of inlining 00208 00209 00210 void Copy_Local_Tables(BOOL); // LABEL, PREG, ST, INITO, ST_ATTR 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 // Constructor 00246 // Calls to do cloning for constant propagation 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 // Calls to do cloning for inlining 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 // Member functions: initializer 00277 void New_Symtab (); // Creates "new" cloned_scope_tab 00278 // Used for cloning 00279 00280 void Update_Symtab (BOOL); // Appends to cloned_scope_tab 00281 // Used for inlining 00282 00283 void Promote_Statics (); // move local statics to IPA global symtab 00284 00285 INITO_IDX Copy_INITO(INITO_IDX orig_init=0); 00286 // Initialized data objects 00287 // special case for C++ EH 00288 00289 INITV_IDX Clone_INITVs_For_EH (INITV_IDX , INITO_IDX ); 00290 00291 // member access functions 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) { // Get the copy of the orig 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 }; // IPO_SYMTAB 00347 00348 // ====================================================================== 00349 // class IPO_CLONE 00350 // ====================================================================== 00351 // used during fn INLINING and fn CLONING 00352 00353 // maps a PU into a cloned PU 00354 // Main functions: used by others (such as IPO, IPA) 00355 // a. Constructor 00356 // b. Clone_Tree 00357 // c. New_Clone 00358 00359 class IPO_CLONE { 00360 00361 private: 00362 00363 WN *_orig_pu; // original tree 00364 WN *_cloned_pu; // cloned tree 00365 00366 IPO_SYMTAB *_sym; // handle cloning of symtab 00367 00368 static INT _label; // unique labels for cloned function name 00369 static const INT _default_buf_size = 2048; 00370 00371 WN_MAP_TAB *_orig_map_tab; // map tables 00372 WN_MAP_TAB *_cloned_map_tab; 00373 00374 WN_MAP _parent_map; // parent pointers 00375 00376 MEM_POOL *_mem; // mem pool for cloned map tables 00377 00378 BOOL _same_file; // if src and dest are from the same file 00379 00380 mUINT16 _cloned_node_file_id; // file id of a cloned node in the 00381 // current file, for cross-file inlining (DST) 00382 00383 WN *_raw_buffer; // pre-allocated buffer for copied nodes 00384 UINT _raw_buf_size; 00385 00386 // For each of the next three functions use the offsets determined by 00387 // (1) copying callee tables into caller tables (inlining) OR by 00388 // (2) maps from orig_symtab to cloned_symtab 00389 00390 void Fix_ST (WN *, WN *); // fix the ST pointer in a tree node: 00391 void Fix_TY (WN *, WN *); // fix the TY pointer in a tree node 00392 void Fix_INITO(WN* cloned_wn, WN* wn);// fix the INITO in a tree node 00393 00394 WN *Copy_Node (const WN *src_wn); // copy one tree node 00395 00396 public: 00397 00398 // Constructor(s) used by MAIN IPA to clone a WN *pu 00399 // 1. Used only in function cloning (_same_file is true: also for IPO_SYMTAB) 00400 // Caller needs to specify scope_tab and symtab_idx of this PU 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), // mem pool for map tables 00412 _cloned_node_file_id(0), 00413 _same_file(TRUE), _raw_buf_size(0) 00414 { 00415 }; 00416 00417 00418 // 2. used only by inlining 00419 // a. to make copy of callee, and patch symtabs 00420 // b. to make copy of whirl tree 00421 // Called from IPO_Copy_Tree defined in ipo_clone.cxx, used in ipo_inline.cxx 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 /* (!(defined(linux) && defined(_LP64))) */ 00444 _orig_map_tab (callee), _cloned_map_tab(caller), _parent_map(parent), 00445 _mem(map_pool), // mem pool for map tables 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 /* defined(linux) && defined(_LP64) */ 00460 }; 00461 00462 // 3. used only for cloning dynamic array bound expressions 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 // Extern interface 00474 void Set_Entry_Point (WN *, WN *, ST *); // Set node as entry point 00475 #if 0 00476 void Set_Entry_Point (WN *, WN *); // Set node as entry point 00477 #endif 00478 00479 // Actual copying of the tree 00480 WN *Clone_Tree (WN *, ST *clone_st = NULL); 00481 00482 // Create a new copy of _sym 00483 void New_Clone (ST *clone_st = NULL); 00484 00485 // Promote Statics 00486 void Promote_Statics() { _sym ->Promote_Statics();} 00487 00488 //data Access functions 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 }; // IPO_CLONE 00505 00506 00507 #endif // clone_INCLUDED 00508