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 * 09-Dec-94 - Original Version (derived from old wn_map.cxx file) 00042 * 00043 * Description: WHIRL mapping mechanism 00044 * 00045 * ==================================================================== 00046 * ==================================================================== 00047 */ 00048 00049 #ifdef USE_PCH 00050 #include "common_com_pch.h" 00051 #endif /* USE_PCH */ 00052 #pragma hdrstop 00053 00054 #include <string.h> /* for memset() */ 00055 #include "wn.h" 00056 00098 /* global variable to keep track of the current map table */ 00099 WN_MAP_TAB *Current_Map_Tab = NULL; 00100 00101 #define INIT_MAP_SIZE 20 00102 00103 static WN_MAP_ID WN_MAP_get_map_id( 00104 WN_MAP_TAB *maptab, 00105 OPERATOR_MAPCAT category, 00106 WN *wn); 00107 00108 static void WN_MAP_realloc_array( 00109 WN_MAP_TAB *maptab, 00110 OPERATOR_MAPCAT category, 00111 WN_MAP wn_map, 00112 WN_MAP_ID id, 00113 INT32 elemsz); 00114 00115 00116 #define WN_MAP_check_kind(maptab, wn_map, kind) \ 00117 ((maptab)->_kind[(wn_map)] == (kind)) 00118 00119 00120 /* 00121 * Create a new map table and initialize it. The slots for the 00122 * predefined maps must be marked as "in use" and all the other 00123 * slots must be cleared out. 00124 */ 00125 00126 WN_MAP_TAB * 00127 WN_MAP_TAB_Create(MEM_POOL *pool) 00128 { 00129 INT32 i, category; 00130 WN_MAP_TAB *maptab = TYPE_MEM_POOL_ALLOC(WN_MAP_TAB, pool); 00131 00132 maptab->_free_list_pool = pool; 00133 00134 /* initialize the predefined mappings */ 00135 for (i = 0; i < WN_MAP_RESERVED; i++) { 00136 maptab->_is_used[i] = TRUE; 00137 /* zero the _map_size counter */ 00138 for (category = 0; category < WN_MAP_CATEGORIES; category++) { 00139 maptab->_map_size[category][i] = 0; 00140 maptab->_mapping[category][i] = NULL; 00141 } 00142 maptab->_pool[i] = pool; 00143 } 00144 00145 /* set the kinds for the predefined mappings */ 00146 maptab->_kind[WN_MAP_DEPGRAPH] = WN_MAP_KIND_VOIDP; 00147 maptab->_kind[WN_MAP_PREFETCH] = WN_MAP_KIND_VOIDP; 00148 maptab->_kind[WN_MAP_FEEDBACK] = WN_MAP_KIND_INT32; 00149 maptab->_kind[WN_MAP_AC_INTERNAL] = WN_MAP_KIND_VOIDP; 00150 maptab->_kind[WN_MAP_ALIAS_CLASS] = WN_MAP_KIND_INT32; 00151 00152 /* clear the slots that are not reserved */ 00153 for (i = WN_MAP_RESERVED; i < WN_MAP_MAX; i++) { 00154 maptab->_is_used[i] = FALSE; 00155 } 00156 /* clear all category info, even for reserved ones */ 00157 /* Because we don't init mem to 0, have to set values here. */ 00158 for (i = 0; i < WN_MAP_CATEGORIES; i++) { 00159 maptab->_last_map_id[i] = -1; 00160 maptab->_free_list_count[i] = 0; 00161 maptab->_free_list_size[i] = 0; 00162 } 00163 00164 /* record the current map table */ 00165 Current_Map_Tab = maptab; 00166 return maptab; 00167 } 00168 00169 00170 /* 00171 * Deallocate a map table. 00172 */ 00173 00174 void 00175 WN_MAP_TAB_Delete(WN_MAP_TAB *maptab) 00176 { 00177 INT32 i, category; 00178 00179 /* delete the maps that are in use */ 00180 for (i = 0; i < WN_MAP_MAX; i++) { 00181 if (maptab->_is_used[i]) { 00182 IPA_WN_MAP_Delete(maptab, i); 00183 } 00184 } 00185 00186 /* deallocate the free list storage */ 00187 for (category = 0; category < WN_MAP_CATEGORIES; category++) { 00188 if (maptab->_free_list_size[category] > 0) { 00189 MEM_POOL_FREE(maptab->_free_list_pool, maptab->_free_list[category]); 00190 } 00191 } 00192 00193 /* finally deallocate the table itself */ 00194 MEM_POOL_FREE(maptab->_free_list_pool, maptab); 00195 } 00196 00197 00198 /* 00199 * Search a map table for an open slot and initialize that slots to 00200 * contain a new mapping. If no slots are available, return -1. 00201 */ 00202 00203 WN_MAP 00204 WN_MAP_Do_Create(WN_MAP_TAB *maptab, MEM_POOL *pool, WN_MAP_KIND kind) 00205 { 00206 WN_MAP_ID wn_map; 00207 INT32 category; 00208 00209 /* find an unused map, return -1 on error */ 00210 for (wn_map = WN_MAP_RESERVED; wn_map < WN_MAP_MAX; wn_map++) { 00211 if (!maptab->_is_used[wn_map]) break; 00212 } 00213 FmtAssert(wn_map != WN_MAP_MAX,("WN_MAP_Do_Create, ran out of maps")); 00214 00215 maptab->_is_used[wn_map] = TRUE; 00216 00217 /* zero the _map_size counter */ 00218 for (category = 0; category < WN_MAP_CATEGORIES; category++) { 00219 maptab->_map_size[category][wn_map] = 0; 00220 maptab->_mapping[category][wn_map] = NULL; 00221 } 00222 00223 maptab->_pool[wn_map] = pool; 00224 maptab->_kind[wn_map] = kind; 00225 return wn_map; 00226 } 00227 00228 00229 /* 00230 * Delete a map from a map table so that its slot can be reused. The 00231 * space used by the map value array is only deallocated if the MEM_POOL 00232 * is the Malloc_Mem_Pool. 00233 */ 00234 00235 void 00236 IPA_WN_MAP_Delete(WN_MAP_TAB *maptab, WN_MAP wn_map) 00237 { 00238 INT32 category; 00239 00240 if (maptab == 0) 00241 return; 00242 00243 Is_True(0 <= wn_map && wn_map < WN_MAP_MAX, 00244 ("IPA_WN_MAP_Delete: invalid map index %d", wn_map)); 00245 00246 for (category = 0; category < WN_MAP_CATEGORIES; category++) { 00247 if (maptab->_map_size[category][wn_map] != 0) { 00248 if (maptab->_pool[wn_map] == Malloc_Mem_Pool) { 00249 MEM_POOL_FREE(Malloc_Mem_Pool, maptab->_mapping[category][wn_map]); 00250 } 00251 maptab->_map_size[category][wn_map] = 0; 00252 maptab->_mapping[category][wn_map] = NULL; 00253 } 00254 } 00255 maptab->_is_used[wn_map] = FALSE; 00256 } 00257 00258 WN_MAP_ID 00259 IPA_WN_MAP_Status(WN_MAP_TAB *maptab) 00260 { 00261 WN_MAP_ID wn_map; 00262 00263 /* find an first unused map, return -1 on error */ 00264 for (wn_map = WN_MAP_RESERVED; wn_map < WN_MAP_MAX; wn_map++) 00265 if (!maptab->_is_used[wn_map]) 00266 return wn_map; 00267 Is_True(0,("WN_MAP_Status, all maps used")); 00268 return (WN_MAP_ID)(-1); 00269 } 00270 00271 /* 00272 * The following functions are used to set the value for a WN in a 00273 * particular mapping. The WN_MAP_get_map_id function checks if 00274 * the WN has been assigned a map_id. If not it gets a new map_id, 00275 * checking the free list to see if it can reuse an old map_id value. 00276 * WN_MAP_realloc_array reallocates the map value array if it is not 00277 * big enough. 00278 */ 00279 00280 WN_MAP_ID 00281 WN_MAP_get_map_id (WN_MAP_TAB *maptab, OPERATOR_MAPCAT category, WN *wn) 00282 { 00283 /* Check if this node has been given an id */ 00284 if (WN_map_id(wn) != -1) { 00285 return WN_map_id(wn); 00286 } 00287 00288 /* is there anything on the free list */ 00289 if (maptab->_free_list_count[category] > 0) { 00290 INT32 i; 00291 WN_MAP_ID id = 00292 maptab->_free_list[category][--maptab->_free_list_count[category]]; 00293 WN_map_id(wn) = id; 00294 /* grabbed it from the free list, now must zero old mappings */ 00295 for (i = 0; i < WN_MAP_MAX; i++) { 00296 if (maptab->_is_used[i] && (id < maptab->_map_size[category][i])) { 00297 switch (maptab->_kind[i]) { 00298 case WN_MAP_KIND_VOIDP: 00299 maptab->_mapping[category][i][id] = NULL; 00300 break; 00301 case WN_MAP_KIND_INT32: 00302 ((INT32*)maptab->_mapping[category][i])[id] = 0; 00303 break; 00304 case WN_MAP_KIND_INT64: 00305 ((INT64*)maptab->_mapping[category][i])[id] = 0; 00306 break; 00307 default: 00308 Is_True(FALSE, ("WN_MAP_do_set: unknown map kind")); 00309 } 00310 } 00311 } 00312 return id; 00313 } 00314 00315 /* nothing on the free list, give it a new id */ 00316 WN_map_id(wn) = ++maptab->_last_map_id[category]; 00317 return WN_map_id(wn); 00318 } 00319 00320 00321 void 00322 WN_MAP_realloc_array (WN_MAP_TAB *maptab, OPERATOR_MAPCAT category, 00323 WN_MAP wn_map, WN_MAP_ID id, INT32 elemsz) 00324 { 00325 INT32 old_size = maptab->_map_size[category][wn_map]; 00326 INT32 new_size; 00327 if (old_size == 0) { 00328 new_size = INIT_MAP_SIZE; 00329 } else { 00330 new_size = old_size * 2; 00331 } 00332 while (id >= new_size) { 00333 new_size *= 2; 00334 } 00335 00336 maptab->_map_size[category][wn_map] = new_size; 00337 maptab->_mapping[category][wn_map] = (void **) 00338 MEM_POOL_Realloc(maptab->_pool[wn_map], 00339 maptab->_mapping[category][wn_map], 00340 old_size * elemsz, 00341 new_size * elemsz); 00342 00343 /* make sure the new storage is zeroed */ 00344 if (!(maptab->_pool[wn_map]->bz)) { 00345 INTPS address = ((INTPS) maptab->_mapping[category][wn_map]) + (old_size * elemsz); 00346 memset((void *) address, '\0', (new_size - old_size) * elemsz); 00347 } 00348 } 00349 00350 00351 void 00352 IPA_WN_MAP_Set(WN_MAP_TAB *maptab, WN_MAP wn_map, WN *wn, void *thing) 00353 { 00354 OPERATOR_MAPCAT category; 00355 WN_MAP_ID id; 00356 00357 Is_True(wn != NULL,("WN_MAP_Set: wn is NULL")); 00358 category = OPCODE_mapcat(WN_opcode(wn)); 00359 Is_True(maptab->_is_used[wn_map], ("WN_MAP_Set: wn_map is not valid")); 00360 Is_True(WN_MAP_check_kind(maptab, wn_map, WN_MAP_KIND_VOIDP), 00361 ("WN_MAP_Set: not a VOID* map")); 00362 00363 id = WN_MAP_get_map_id(maptab, category, wn); 00364 if (id >= maptab->_map_size[category][wn_map]) { 00365 WN_MAP_realloc_array(maptab, category, wn_map, id, sizeof(void*)); 00366 } 00367 maptab->_mapping[category][wn_map][id] = thing; 00368 } 00369 00370 00371 void 00372 IPA_WN_MAP32_Set(WN_MAP_TAB *maptab, WN_MAP wn_map, WN *wn, INT32 thing) 00373 { 00374 OPERATOR_MAPCAT category = OPCODE_mapcat(WN_opcode(wn)); 00375 WN_MAP_ID id; 00376 00377 Is_True(maptab->_is_used[wn_map], ("WN_MAP32_Set: wn_map is not valid")); 00378 Is_True(WN_MAP_check_kind(maptab, wn_map, WN_MAP_KIND_INT32), 00379 ("WN_MAP32_Set: not an INT32 map")); 00380 00381 id = WN_MAP_get_map_id(maptab, category, wn); 00382 if (id >= maptab->_map_size[category][wn_map]) { 00383 WN_MAP_realloc_array(maptab, category, wn_map, id, sizeof(INT32)); 00384 } 00385 ((INT32*)maptab->_mapping[category][wn_map])[id] = thing; 00386 } 00387 00388 00389 void 00390 IPA_WN_MAP64_Set(WN_MAP_TAB *maptab, WN_MAP wn_map, WN *wn, INT64 thing) 00391 { 00392 OPERATOR_MAPCAT category = OPCODE_mapcat(WN_opcode(wn)); 00393 WN_MAP_ID id; 00394 00395 Is_True(maptab->_is_used[wn_map], ("WN_MAP64_Set: wn_map is not valid")); 00396 Is_True(WN_MAP_check_kind(maptab, wn_map, WN_MAP_KIND_INT64), 00397 ("WN_MAP64_Set: not an INT64 map")); 00398 00399 id = WN_MAP_get_map_id(maptab, category, wn); 00400 if (id >= maptab->_map_size[category][wn_map]) { 00401 WN_MAP_realloc_array(maptab, category, wn_map, id, sizeof(INT64)); 00402 } 00403 ((INT64*)maptab->_mapping[category][wn_map])[id] = thing; 00404 } 00405 00406 00407 /* 00408 * The following functions retrieve the value for a WN in a particular 00409 * map. If no value has been assigned for that WN, they return 0. 00410 */ 00411 00412 void * 00413 IPA_WN_MAP_Get(WN_MAP_TAB *maptab, WN_MAP wn_map, const WN *wn) 00414 { 00415 WN_MAP_ID id = WN_map_id(wn); 00416 OPERATOR_MAPCAT category; 00417 00418 if (id == -1) return NULL; 00419 Is_True(maptab->_is_used[wn_map], ("WN_MAP_Get: wn_map is not valid")); 00420 Is_True(WN_MAP_check_kind(maptab, wn_map, WN_MAP_KIND_VOIDP), 00421 ("WN_MAP_Get: not a VOID* map")); 00422 00423 category = OPCODE_mapcat(WN_opcode(wn)); 00424 if (id >= maptab->_map_size[category][wn_map]) return NULL; 00425 return maptab->_mapping[category][wn_map][id]; 00426 } 00427 00428 00429 INT32 00430 IPA_WN_MAP32_Get(WN_MAP_TAB *maptab, WN_MAP wn_map, const WN *wn) 00431 { 00432 WN_MAP_ID id = WN_map_id(wn); 00433 OPERATOR_MAPCAT category; 00434 00435 Is_True(maptab->_is_used[wn_map], ("WN_MAP32_Get: wn_map is not valid")); 00436 Is_True(WN_MAP_check_kind(maptab, wn_map, WN_MAP_KIND_INT32), 00437 ("WN_MAP32_Get: not an INT32 map")); 00438 00439 if (id == -1) return 0; 00440 category = OPCODE_mapcat(WN_opcode(wn)); 00441 if (id >= maptab->_map_size[category][wn_map]) return 0; 00442 return ((INT32*)maptab->_mapping[category][wn_map])[id]; 00443 } 00444 00445 00446 INT64 00447 IPA_WN_MAP64_Get(WN_MAP_TAB *maptab, WN_MAP wn_map, const WN *wn) 00448 { 00449 WN_MAP_ID id = WN_map_id(wn); 00450 OPERATOR_MAPCAT category; 00451 00452 Is_True(maptab->_is_used[wn_map], ("WN_MAP64_Get: wn_map is not valid")); 00453 Is_True(WN_MAP_check_kind(maptab, wn_map, WN_MAP_KIND_INT64), 00454 ("WN_MAP64_Get: not an INT64 map")); 00455 00456 if (id == -1) return 0; 00457 category = OPCODE_mapcat(WN_opcode(wn)); 00458 if (id >= maptab->_map_size[category][wn_map]) return 0; 00459 return ((INT64*)maptab->_mapping[category][wn_map])[id]; 00460 } 00461 00462 00463 /* 00464 * Add the map_id for a WN to the free list in a map table. This is 00465 * called automatically by WN_Delete. The free list is just an array; 00466 * if it runs out of space, we just realloc it. 00467 */ 00468 00469 void 00470 WN_MAP_Add_Free_List(WN_MAP_TAB *maptab, WN *wn) 00471 { 00472 OPERATOR_MAPCAT category = OPCODE_mapcat(WN_opcode(wn)); 00473 INT32 count, size; 00474 00475 if (WN_map_id(wn) == -1) return; /* no map_id to free */ 00476 00477 count = maptab->_free_list_count[category]; 00478 size = maptab->_free_list_size[category]; 00479 00480 /* is there space, if not, make some */ 00481 if (count >= size) { 00482 if (size == 0) { 00483 INT32 elements = 50; 00484 maptab->_free_list[category] = 00485 TYPE_MEM_POOL_ALLOC_N(WN_MAP_ID, maptab->_free_list_pool, elements); 00486 maptab->_free_list_size[category] = elements; 00487 } else { 00488 INT32 elements = max(2 * size, size + 50); 00489 maptab->_free_list[category] = 00490 TYPE_MEM_POOL_REALLOC_N(WN_MAP_ID, maptab->_free_list_pool, 00491 maptab->_free_list[category], size, elements); 00492 maptab->_free_list_size[category] = elements; 00493 } 00494 } 00495 00496 maptab->_free_list[category][count] = WN_map_id(wn); 00497 maptab->_free_list_count[category] = count + 1; 00498 } 00499 00500 00501 /* 00502 * Set the WN map_id field if it doesn't already have an ID. 00503 */ 00504 00505 void 00506 WN_MAP_Set_ID (WN_MAP_TAB *maptab, WN *wn) 00507 { 00508 OPERATOR_MAPCAT category = OPCODE_mapcat(WN_opcode(wn)); 00509 (void)WN_MAP_get_map_id (maptab, category, wn); 00510 } 00511 00512