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 /* ==================================================================== 00037 * ==================================================================== 00038 * 00039 * 00040 * Revision history: 00041 * 25-Apr-93 - Original Version 00042 * 00043 * Description: 00044 * 00045 * The DST info is internally represented as an array of block headers, 00046 * where each block header contains the kind, size, and offset of a block 00047 * of DST data. In particular, there should be one block each for the 00048 * file-scope, include, file-names, and macro info, then one block for 00049 * each local-scope PU info. 00050 * 00051 * When a block grows beyond its size, we allocate a new block. 00052 * We can't realloc space because there are places where we use a pointer 00053 * to the info in order to get the attributes. 00054 * In the intermediate file, only the exact size of the blocks 00055 * is written and read. 00056 * ==================================================================== 00057 * ==================================================================== 00058 */ 00059 00060 #ifdef USE_PCH 00061 #include "common_com_pch.h" 00062 #endif /* USE_PCH */ 00063 #pragma hdrstop 00064 #include "defs.h" 00065 #include "mempool.h" 00066 #define USE_DST_INTERNALS 00067 #include "dwarf_DST_mem.h" 00068 #include "errors.h" 00069 #include "stab.h" 00070 00071 static inline void * 00072 Symtab_Alloc (size_t bytes, BOOL is_global) 00073 { 00074 if ( is_global ) { 00075 return (void *) Src_Alloc ( bytes ); 00076 } else { 00077 return (void *) Pu_Alloc ( bytes ); 00078 } 00079 } 00080 00081 00082 #define NUM_BLOCK_HEADERS 1024 /* initial # of block headers */ 00083 #define BLOCK_SIZE 256 /* size of individual block */ 00084 00085 DST_TYPE Current_DST = NULL; 00086 DST_Type *current_DST = NULL; 00087 00088 00089 /* Represents a NULL DST_IDX value. Always initialize a declared 00090 * DST_IDX with this value!! 00091 */ 00092 const DST_IDX DST_INVALID_IDX = {DST_INVALID_BLOCK_IDX, DST_INVALID_BYTE_IDX}; 00093 00094 00095 /*----------------* 00096 * Error Checking * 00097 *----------------*/ 00098 00099 #ifdef Is_True_On 00100 /* then do Error Checking */ 00101 00102 static DST_BLOCK_IDX 00103 DST_CHECK_BLOCK_IDX(DST_BLOCK_IDX b) 00104 { 00105 Is_True((b != DST_INVALID_BLOCK_IDX && b >= 0 && 00106 b <= current_DST->last_block_header), 00107 ("Illegal DST block idx")); 00108 return b; 00109 } 00110 00111 static DST_IDX 00112 DST_CHECK_IDX(DST_IDX i) 00113 { 00114 Is_True( ((i.byte_idx >= 0 && 00115 i.byte_idx < current_DST->dst_blocks[DST_CHECK_BLOCK_IDX(i.block_idx)].size)) || DST_IS_FOREIGN_OBJ(i), 00116 ("Illegal DST idx")); 00117 return i; 00118 } 00119 00120 #else /* do not do Error Checking */ 00121 00122 #define DST_CHECK_BLOCK_IDX(b) (b) 00123 #define DST_CHECK_IDX(i) (i) 00124 00125 /* Error Checking */ 00126 #endif 00127 00128 00129 extern DST_TYPE 00130 New_DST (void) 00131 { 00132 INT32 i; 00133 DST_Type *dst = TYPE_MEM_POOL_ALLOC(DST_Type, MEM_src_pool_ptr); 00134 00135 dst->last_block_header = -1; 00136 dst->max_block_header = NUM_BLOCK_HEADERS; 00137 dst->current_block_header = -1; 00138 00139 /* the block_list should point to the first block 00140 for each of the block kinds */ 00141 for (i = 0; i < DST_noblock; i++) { 00142 dst->block_list[i] = DST_INVALID_BLOCK_IDX; 00143 } 00144 00145 return (DST_TYPE)dst; 00146 } 00147 00148 00149 extern void 00150 DST_Init (char *start, INT32 num_blocks) 00151 { 00152 INT i; 00153 block_header *blocks; 00154 DST_BLOCK_IDX *blklist; 00155 00156 00157 if (Current_DST == NULL) 00158 Current_DST = New_DST(); 00159 00160 current_DST = (DST_Type *)Current_DST; 00161 00162 if (start == NULL) { 00163 /* create new list of blocks */ 00164 blocks = (block_header*) Symtab_Alloc (NUM_BLOCK_HEADERS*sizeof(block_header), TRUE); 00165 } else { 00166 /* use existing space as list of blocks */ 00167 blocks = (block_header *) start; 00168 current_DST->max_block_header = num_blocks; 00169 current_DST->last_block_header = num_blocks - 1; 00170 00171 blklist = ¤t_DST->block_list[0]; 00172 FOREACH_DST_BLOCK(i) { 00173 /* Would be nice if global blocks came first, 00174 * but that doesn't seem to be true, so search 00175 * thru all blocks. */ 00176 /* Assume that when multiple blocks are used for a 00177 * kind, first block will be earliest in the array. */ 00178 if (blklist[blocks[i].kind] == DST_INVALID_BLOCK_IDX) 00179 blklist[blocks[i].kind] = i; 00180 } 00181 #if defined(_SUPPORT_IPA) || defined(_STANDALONE_INLINER) || defined(MONGOOSE_BE) 00182 blocks[current_DST->last_block_header].allocsize = 00183 blocks[current_DST->last_block_header].size; 00184 #endif 00185 } 00186 current_DST->dst_blocks = blocks; 00187 current_DST->current_dst = blocks; 00188 } 00189 00190 static void 00191 set_current_dst_to_current ( void ) 00192 { 00193 current_DST->current_block_header = current_DST->last_block_header; 00194 current_DST->current_dst = 00195 ¤t_DST->dst_blocks[current_DST->current_block_header]; 00196 } 00197 00198 /* 00199 #if !(defined(MONGOOSE_BE)) || defined(_STANDALONE_INLINER) || defined(_SUPPORT_IPA) 00200 */ 00201 00202 static block_header * 00203 new_block (DST_BLOCK_KIND kind, INT32 size) 00204 { 00205 INT32 allocsize = (size < BLOCK_SIZE ? BLOCK_SIZE : size); 00206 DST_BLOCK_IDX last_block = current_DST->last_block_header; 00207 DST_BLOCK_IDX max_block = current_DST->max_block_header; 00208 block_header *blocks = current_DST->dst_blocks; 00209 block_header *current; 00210 00211 if (++last_block >= max_block) { 00212 blocks = TYPE_MEM_POOL_REALLOC_N(block_header, 00213 MEM_src_pool_ptr , 00214 blocks, max_block, 00215 2 * max_block); 00216 max_block *= 2; 00217 00218 current_DST->dst_blocks = blocks; 00219 current_DST->max_block_header = max_block; 00220 } 00221 current_DST->last_block_header = last_block; 00222 current_DST->current_block_header = last_block; 00223 00224 #if defined(_SUPPORT_IPA) || defined(_STANDALONE_INLINER) || defined(MONGOOSE_BE) 00225 /* force Symtab_Alloc to allocate from the Src_block, not the PU_block 00226 */ 00227 blocks[last_block].offset = (char*) Symtab_Alloc(allocsize, 00228 TRUE); 00229 #else 00230 blocks[last_block].offset = (char*) Symtab_Alloc(allocsize, 00231 (kind == DST_local_scope_block) ? FALSE : TRUE); 00232 #endif 00233 current = &blocks[last_block]; 00234 current->kind = kind; 00235 current->size = 0; 00236 current->allocsize = allocsize; 00237 current_DST->current_dst = current; 00238 00239 return current; 00240 } 00241 00242 00243 extern void 00244 DST_begin_block (DST_BLOCK_KIND block_kind) 00245 { 00246 DST_BLOCK_IDX *blklist; 00247 current_DST = (DST_Type *)Current_DST; 00248 blklist = ¤t_DST->block_list[0]; 00249 current_DST->current_dst = new_block (block_kind, 0); 00250 if (blklist[block_kind] == DST_INVALID_BLOCK_IDX) 00251 blklist[block_kind] = current_DST->last_block_header; 00252 } 00253 00254 extern DST_IDX 00255 DST_allocate (INT32 size, INT32 align) 00256 { 00257 DST_IDX new_idx; 00258 INT32 total_size; 00259 INT32 align_mod, align_padding; 00260 block_header *current; 00261 current_DST = (DST_Type *)Current_DST; 00262 00263 #if defined(_SUPPORT_IPA) || defined(_STANDALONE_INLINER) || defined(MONGOOSE_BE) 00264 #if 0 00265 if ((current_DST->dst_blocks == current_DST->current_dst) && 00266 (current_DST->current_dst->kind != DST_local_scope_block)) { 00267 /* we should set current_dst to a new block */ 00268 current = new_block (DST_local_scope_block, size); 00269 /* recalculate the alignment padding in the current_block */ 00270 align_padding = 0; 00271 total_size = size; 00272 set_current_dst_to_current(); 00273 } 00274 else { 00275 #endif 00276 set_current_dst_to_current(); 00277 current = current_DST->current_dst; 00278 #if 0 00279 } 00280 #endif 00281 #else 00282 current = current_DST->current_dst; 00283 #endif 00284 00285 00286 /* Calculate the alignment padding in the current_block */ 00287 align_mod = current->size % align; 00288 align_padding = (align_mod ? (align - align_mod) : 0); 00289 total_size = current->size + size + align_padding; 00290 00291 if (total_size > current->allocsize) { 00292 /* Turn off the following if inliner/ipa is the one calling this 00293 * the first time 00294 * because by this time current->allocsize is NOT the amount 00295 * of space you can use anymore. FE only reserved current->size 00296 * + align_padding for this current block 00297 */ 00298 /* allocate new block */ 00299 #if defined(_SUPPORT_IPA) || defined(_STANDALONE_INLINER) || defined(MONGOOSE_BE) 00300 current = new_block (DST_local_scope_block, size); 00301 #else 00302 current = new_block (current->kind, size); 00303 #endif 00304 /* recalculate the alignment padding in the current_block */ 00305 align_padding = 0; 00306 total_size = size; 00307 } 00308 00309 new_idx.block_idx = current_DST->current_block_header; 00310 new_idx.byte_idx = current->size + align_padding; 00311 current->size = total_size; 00312 return new_idx; 00313 } 00314 00315 00316 /* Resets "current_block" to become the last block in the block-list 00317 * into which idx points. 00318 */ 00319 extern void 00320 DST_return_to_block(DST_IDX idx) 00321 { 00322 DST_BLOCK_IDX current_block; 00323 current_DST = (DST_Type *)Current_DST; 00324 current_block = DST_CHECK_IDX(idx).block_idx; 00325 current_DST->current_block_header = current_block; 00326 current_DST->current_dst = ¤t_DST->dst_blocks[current_block]; 00327 } 00328 /* 00329 #endif * !MONGOOSE_BE || _STANDALONE_INLINER || _SUPPORT_IPA */ 00330 00331 00332 /* Returns a pointer to the beginning of an allocated data area. It 00333 * is up to the caller to ensure that access does not occur beyond the 00334 * end of the allocated area. The accessed block must not yet be 00335 * written to file. 00336 */ 00337 extern char * 00338 DST_idx_to_string(DST_IDX idx) 00339 { 00340 block_header *block; 00341 current_DST = (DST_Type *)Current_DST; 00342 block = ¤t_DST->dst_blocks[DST_CHECK_IDX(idx).block_idx]; 00343 if (idx.byte_idx == DST_INVALID_BYTE_IDX) 00344 return NULL; 00345 else 00346 return &(block->offset[idx.byte_idx]); 00347 } 00348 00349 00350 static DST_IDX 00351 DST_get_block_list(DST_BLOCK_KIND block_kind) 00352 { 00353 DST_IDX idx; 00354 DST_BLOCK_IDX bidx = current_DST->block_list[block_kind]; 00355 00356 if ((bidx == DST_INVALID_BLOCK_IDX) || 00357 (current_DST->dst_blocks[DST_CHECK_BLOCK_IDX(bidx)].size <= 0)) { 00358 idx = DST_INVALID_IDX; 00359 } else { 00360 idx.byte_idx = 0; /* First byte in block */ 00361 idx.block_idx = bidx; 00362 current_DST->current_dst = ¤t_DST->dst_blocks[bidx]; 00363 } 00364 return idx; 00365 } 00366 00367 00368 /* Returns an index to the first DST_INCLUDE_DIR entry, which may be 00369 * DST_INVALID_IDX in the abscence of any DST_INCLUDE_DIR entries. 00370 */ 00371 extern DST_IDX 00372 DST_get_include_dirs(void) 00373 { 00374 current_DST = (DST_Type *)Current_DST; 00375 return DST_get_block_list(DST_include_dirs_block); 00376 } 00377 00378 00379 /* Returns an index to the first DST_FILE_NAME entry, which may be 00380 * DST_INVALID_IDX in the abscence of any DST_FILE_NAME entries. 00381 */ 00382 extern DST_IDX 00383 DST_get_file_names(void) 00384 { 00385 current_DST = (DST_Type *)Current_DST; 00386 return DST_get_block_list(DST_file_names_block); 00387 } 00388 00389 00390 /* Returns an index to the first DST_MACRO_INFO entry, which may be 00391 * DST_INVALID_IDX in the abscence of any DST_MACRO_INFO entries. 00392 */ 00393 extern DST_IDX 00394 DST_get_macro_info(void) 00395 { 00396 current_DST = (DST_Type *)Current_DST; 00397 return DST_get_block_list(DST_macro_info_block); 00398 } 00399 00400 00401 /* Returns an index to the DST_COMPILE_UNIT entry, which may be 00402 * DST_INVALID_IDX in the abscence of any DST_COMPILE_UNIT entry. 00403 */ 00404 extern DST_IDX 00405 DST_get_compile_unit(void) 00406 { 00407 current_DST = (DST_Type *)Current_DST; 00408 return DST_get_block_list(DST_file_scope_block); 00409 } 00410