Open64 (mfef90, whirl2f, and IR tools)  TAG: version-openad; SVN changeset: 916
cwh_data.i
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 // -*-C++-*-
00036 // Template stuff for sorting
00037 
00038 #include <vector>
00039 #include <algorithm>
00040 
00041 using namespace std;
00042 
00043 static ST *orig_st; /* The symbol being initialized (for error reporting only) */
00044 static ST *current_st; /* The symbol being initialized */
00045 static TY_IDX current_ty;
00046 static INT64 current_bytesize;
00047 static INT32 current_pos; /* position in the array to initialize (0 based, byte indexed) */
00048 static INT32 array_pos; /* position in the current array */
00049 static BOOL is_struct_or_array; /* TRUE if initilaizing an array */
00050 static INITO_IDX current_inito = 0;
00051 
00052 /* for pulling apart bases and offsets */
00053 typedef struct {
00054   INT64 offset;
00055   ST *  base;
00056 } b_and_o;
00057 
00058 struct data_element_s {
00059   INT64 offset; 
00060   INT64 initv_size;
00061   union {
00062     b_and_o  bo;
00063     struct {
00064       TCON_IDX tc;
00065       INT32    repeat_count;
00066     } tc_val;
00067   } val;
00068   UINT32 sequence_num:30;
00069   UINT32 is_b_and_o:1;
00070   UINT32 is_valid:1;
00071   
00072 #ifdef DATA_DEBUG
00073   void print() {
00074     printf("Off: %12lld   TC: %d (x %d) %s\n",offset,val.tc_val.tc,val.tc_val.repeat_count,
00075            is_valid ? "valid" : "invalid");
00076   }
00077 #endif
00078 
00079   inline data_element_s(INT64 o, TCON_IDX tc, b_and_o *bo, INT64 isize, UINT32 seqnum) {
00080     offset=o; initv_size=isize; sequence_num = seqnum; is_valid = TRUE;
00081     if (bo) {
00082       is_b_and_o = TRUE;
00083       val.bo = *bo;
00084     } else {
00085       is_b_and_o = FALSE;
00086       val.tc_val.tc = tc;
00087       val.tc_val.repeat_count = 1;
00088     }
00089   }
00090   
00091   INITV_IDX create_initv()
00092   {
00093     if (is_b_and_o) {
00094       return (Irb_Init_Symoff(0, 0, 1, val.bo.base, val.bo.offset));
00095     } else {
00096       return (Irb_Init_Val(0, 0, val.tc_val.repeat_count, val.tc_val.tc));
00097     }
00098   }
00099 
00100 
00101   // Compare on offset first. If the offsets are the same, the larger
00102   // comes first (so that we get a more complete cover). If the sizes are the
00103   // same (the usual case, we'd expect) take the last one entered
00104   static bool comp(data_element_s a, data_element_s b) {
00105     if (a.offset != b.offset) return (a.offset < b.offset);
00106     if (a.initv_size != b.initv_size) return (b.initv_size < a.initv_size);
00107     return (b.sequence_num < a.sequence_num);
00108   }
00109 };
00110 
00111 
00112 typedef vector<data_element_s> DATA_ELEMENTS;
00113 
00114 //
00115 //  miscellaneous stuff needed for data intialization
00116 //
00117 //  st_inito - the INITO for a symbol
00118 //  data_elements - the data elements of 
00119 //
00120 struct data_info_s {
00121   INITO_IDX st_inito;
00122   DATA_ELEMENTS data_elements;
00123   UINT32 sequence_num;
00124   
00125   data_info_s(ST *st) {st_inito = New_INITO(st); sequence_num=0;}
00126   ~data_info_s(void) {}
00127   
00128   void sort_data(ST *st) {
00129     BOOL message_issued = FALSE;
00130     sort(data_elements.begin(),data_elements.end(),data_element_s::comp);
00131 
00132     // Now pack together the data for multiple initv's, and flag errors
00133     INT32 vsize,i,last_index;
00134     INT64 pos=0;
00135 
00136     vsize = data_elements.size();
00137 #ifdef DATA_DEBUG
00138     printf("======== before duplicate processing %s\n",ST_name(st));
00139     for (i=0; i < vsize; i++) {
00140       data_elements[i].print();
00141     }
00142 #endif
00143     for (i=0,last_index=0; i < vsize; i++) {
00144       if (data_elements[i].offset < pos) {
00145         if (!message_issued) {
00146           ErrMsg(EC_Multiple_Initialization,ST_name(st));
00147           message_issued = TRUE;
00148         }
00149         data_elements[i].is_valid = FALSE;
00150         continue;
00151       }
00152       
00153       // Valid init, increment pos, check for packing
00154       if ((last_index != i) &&
00155           (pos == data_elements[i].offset) &&
00156           (!data_elements[last_index].is_b_and_o) &&
00157           (!data_elements[i].is_b_and_o) &&
00158           (data_elements[i].val.tc_val.tc == data_elements[last_index].val.tc_val.tc)) {
00159         // update repeat count of last_index, mark current as invalid
00160         data_elements[last_index].val.tc_val.repeat_count += 1;
00161         data_elements[last_index].initv_size += data_elements[i].initv_size;
00162         data_elements[i].is_valid = FALSE;
00163         pos += data_elements[i].initv_size;
00164       } else {
00165         // update the current position
00166         pos = data_elements[i].offset + data_elements[i].initv_size;
00167         last_index = i;
00168       }
00169     }
00170 #ifdef DATA_DEBUG
00171     printf("======== after duplicate processing\n");
00172     for (i=0; i < vsize; i++) {
00173       data_elements[i].print();
00174     }
00175 #endif
00176   }
00177   
00178   inline INITO_IDX Get_Inito(void) {return st_inito;}
00179   inline DATA_ELEMENTS *Get_Data_Elements(void) {return &data_elements;}
00180 
00181   inline void Reserve(INT64 num_to_add) {
00182      // To avoid a bad case in which we spend lots of time reserving tiny little
00183      // chunks, we reserve at least at 5% increase each time. 
00184      INT64 excess_capacity = data_elements.capacity() - data_elements.size();
00185      if (excess_capacity > num_to_add) return;
00186 
00187      INT64 new_size = num_to_add + data_elements.size();
00188      INT64 min_new_size = INT64(1.05 * data_elements.capacity());
00189      if (new_size < min_new_size) new_size = min_new_size;
00190      data_elements.reserve(new_size);
00191   }
00192   
00193   inline void Add_Data_Element(INT64 offset, TCON_IDX val, b_and_o *bo, INT64 isize) {
00194 #ifdef DATA_DEBUG
00195     printf("Add at offset %lld: TCON = %d\n",offset,val);
00196 #endif
00197     data_elements.push_back(data_element_s(offset,val,bo,isize,sequence_num++));
00198   }
00199 };
00200 
00201 typedef data_info_s *DATA_INFO;
00202         
00203 static DATA_INFO current_data_info;
00204 
00205 static void cwh_data_set_init_flag(ST * st, enum list_name list);
00206 
00207 
 All Classes Namespaces Files Functions Variables Typedefs Enumerations Enumerator Friends Defines