Open64 (mfef90, whirl2f, and IR tools)  TAG: version-openad; SVN changeset: 916
wn_map.cxx
Go to the documentation of this file.
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 
 All Classes Namespaces Files Functions Variables Typedefs Enumerations Enumerator Friends Defines