00001
00002
00003
00004
00005
00006
00007
00008
00009
00010
00011
00012
00013
00014
00015
00016
00017
00018
00019
00020
00021
00022
00023
00024
00025
00026
00027
00028
00029
00030
00031
00032
00033
00034
00035
00036
00037
00038
00039
00040
00041
00042 #include <stack>
00043
00044 #include <vector>
00045 extern "C"
00046 {
00047 #include "unistd.h"
00048 #include "sys/types.h"
00049 #include "sys/stat.h"
00050 #include "fcntl.h"
00051 #include "sys/mman.h"
00052 #include "stdio.h"
00053 };
00054
00055 #include <string>
00056 #include <ext/hash_map>
00057 #include <map>
00058 #include<_G_config.h>
00059 using namespace std;
00060 extern "C"
00061 {
00062 #include "stdlib.h"
00063 #include "time.h"
00064 };
00065 #include "cg_instru_lib.h"
00066
00067
00068
00069 typedef PU_PROFILE_INFO * PU_PROFILE;
00070
00071 namespace{
00072 using __gnu_cxx::hash_map;
00073 struct ptrhash{
00074 size_t operator()(void *p)const{return reinterpret_cast<size_t>(p);}
00075 };
00076 }
00077
00078 typedef hash_map<char*,PU_PROFILE,ptrhash> HASH_MAP;
00079 typedef stack<PU_PROFILE> STACK_PROFILE;
00080 typedef stack<char *> STACK_NAME;
00081
00082
00083 static HASH_MAP PU_PROFILE_INFO_TABLE;
00084
00085 static STACK_PROFILE PU_PROFILE_STACK;
00086 static STACK_NAME PU_NAME;
00087
00088 static const INT32 Pu_Hdr_size = sizeof( Pu_Hdr );
00089 static const INT32 Fb_Hdr_size = sizeof( Fb_Hdr );
00090 static const INT32 FB_FREQ_size = sizeof( FB_FREQ );
00091 static const INT32 _FREQ_size = sizeof( _FREQ );
00092 static const INT32 PU_PROFILE_INFO_size = sizeof( PU_PROFILE_INFO );
00093 static const INT32 TNV_item_size = sizeof( FB_TNV );
00094
00095 static INT32 fd = -1;
00096 static INT32 pu_num = 0;
00097 static INT32 pu_counter = 0;
00098 static INT32 profile_offset = 0;
00099 static INT32 file_header_offset = 0;
00100
00101 static PU_PROFILE_INFO* edge_counter = NULL;
00102 static PROFILE_PHASE prof_phase;
00103
00104 static INT32 PU_header_offset = 0;
00105 static INT32 str_table_offset = 0;
00106 static INT32 Pu_file_offset = 0;
00107 static INT32 str_table_size = 0;
00108 static INT32 current_PU_header_offset = 0;
00109 static INT32 current_str_table_offset = 0;
00110 static INT32 current_Pu_file_offset = 0;
00111 static INT32 current_offset = 0 ;
00112 static INT32 output_file_size = 0;
00113 static char* output_file_name = NULL;
00114 static char* map_addr = NULL;
00115 static char* src_fname = NULL;
00116 static char* current_pu_name = NULL;
00117 static BOOL have_open_output_file = FALSE;
00118 static BOOL have_finish = FALSE;
00119
00120 static char* current_srcfile_pu_name = NULL;
00121 static char* prev_srcfile_pu_name = NULL;
00122 static PU_PROFILE_INFO * current_pu_profile_info = NULL ;
00123 static PU_PROFILE_INFO * prev_pu_profile_info = NULL;
00124 static PU_PROFILE cur_pu_profile;
00125
00126 #ifdef VALUE_PROFILE_VERIFY
00127 static FILE * fout;
00128 #endif
00129
00130
00131
00132
00133
00134 static void _write_File_Header(void);
00135 static void _write_Pu_Header(void);
00136 static void _write_Str_Header(void);
00137 static void _write_pu_data(void);
00138 static void _write_edge_profile(PU_PROFILE_INFO* pu_info);
00139
00140 static void _write_TNV_items_profile( PU_PROFILE_INFO* pu_info );
00141 static void _write_srd_TNV_items_profile( PU_PROFILE_INFO* pu_info );
00142
00143
00144
00145 static void __profile_finalize(void);
00146
00147
00148 static void Free_Space(void);
00149
00150
00151
00152
00153 static void instru_lib_error(const char *fmt, const char* msg="");
00154
00155
00156
00157
00158 void __profile_init( char* output_file,
00159 PROFILE_PHASE phasenum)
00160 {
00161 if( !have_open_output_file && !have_finish )
00162 {
00163 char time_str[30];
00164 time_t lt;
00165 lt=time(NULL);
00166 sprintf(time_str,".%d",(INT)lt);
00167
00168 INT32 str_len = strlen(time_str);
00169 INT32 slen = strlen(output_file);
00170 output_file_name = (char *) malloc( sizeof( char ) *
00171 ( slen+str_len+1));
00172 if (output_file_name == NULL)
00173 instru_lib_error( "Unable to malloc space");
00174 strcpy(output_file_name,output_file);
00175 strcpy(&(output_file_name[slen]),time_str);
00176 unlink(output_file_name);
00177 if ( (fd = open64( output_file_name, O_RDWR | O_CREAT | O_TRUNC, 00777 ))<0 )
00178 instru_lib_error( "Unable to open file: %s", output_file_name );
00179 have_open_output_file = TRUE;
00180 prof_phase = phasenum;
00181 void __profile_finalize();
00182 atexit( __profile_finalize );
00183 }
00184 }
00185
00186 char* __profile_pu_init(char* srcfile_pu_name,INT check_sum )
00187 {
00188 if(!have_finish)
00189 {
00190 PU_PROFILE & current_pu_profile = PU_PROFILE_INFO_TABLE[srcfile_pu_name];
00191 current_srcfile_pu_name = srcfile_pu_name;
00192
00193 if (current_pu_profile == NULL)
00194 {
00195 current_pu_profile = new PU_PROFILE_INFO(check_sum,
00196 (_FREQ*) calloc(check_sum,_FREQ_size));
00197 }else
00198 {
00199 if (!( (current_pu_profile->_has_alloc) & EDGE_PROFILE_ALLOC) )
00200 {
00201 current_pu_profile->_counter = (_FREQ *)calloc(check_sum,_FREQ_size);
00202 current_pu_profile->_has_alloc |= EDGE_PROFILE_ALLOC;
00203 current_pu_profile->_edge_sum = check_sum;
00204 }
00205 }
00206 cur_pu_profile = current_pu_profile;
00207 }
00208 return srcfile_pu_name;
00209 }
00210
00211
00212 void __profile_edge(char* srcfile_pu_name,UINT32 id)
00213 {
00214 if(!have_finish)
00215 {
00216 if(current_srcfile_pu_name != srcfile_pu_name)
00217 {
00218 cur_pu_profile = PU_PROFILE_INFO_TABLE[srcfile_pu_name];
00219 current_srcfile_pu_name = srcfile_pu_name;
00220 }
00221
00222 if ( id < cur_pu_profile -> _edge_sum)
00223 cur_pu_profile->_counter[id]._value++;
00224 }
00225 }
00226
00227
00228
00229
00230
00231
00232
00233
00234
00235
00236
00237
00238
00239
00240
00241 static void __profile_finalize( )
00242 {
00243 #ifdef VALUE_PROFILE_VERIFY
00244 fclose( fout );
00245 have_finish=TRUE;
00246 return;
00247 #endif
00248 hash_map<char* ,PU_PROFILE_INFO*,ptrhash >::iterator i;
00249 PU_PROFILE_INFO* current_PU_profile_info;
00250 profile_offset = 0;
00251 pu_counter = PU_PROFILE_INFO_TABLE.size();
00252 file_header_offset = 0;
00253 PU_header_offset = Fb_Hdr_size+file_header_offset;
00254 str_table_offset = pu_counter*Pu_Hdr_size+Fb_Hdr_size;
00255 Pu_file_offset = str_table_offset;
00256 current_PU_header_offset = PU_header_offset;
00257 current_str_table_offset = str_table_offset;
00258
00259
00260 output_file_size = Fb_Hdr_size + Pu_Hdr_size * pu_counter;
00261 str_table_size = 0;
00262 for(i = PU_PROFILE_INFO_TABLE.begin();
00263 i != PU_PROFILE_INFO_TABLE.end(); i++) {
00264 PU_PROFILE_INFO * pu_info = (*i).second;
00265
00266 output_file_size += pu_info->_edge_sum * FB_FREQ_size;
00267 output_file_size += pu_info->_instr_count * TNV_item_size;
00268 output_file_size += pu_info->_ld_count * TNV_item_size;
00269 INT size = strlen((*i).first)+ strlen(" ");
00270 output_file_size += size;
00271 str_table_size += size;
00272 Pu_file_offset += size;
00273 }
00274 current_Pu_file_offset = Pu_file_offset;
00275 if ( lseek( fd, output_file_size, SEEK_SET ) < 0 )
00276 instru_lib_error( "Unable to seek file:%s",output_file_name );
00277
00278 if ( write( fd, "", 1 ) != 1 )
00279 instru_lib_error( "Unable to write file:%s",output_file_name );
00280
00281 map_addr = ( char * ) mmap ( 0, output_file_size, PROT_READ | PROT_WRITE,
00282 MAP_FILE | MAP_SHARED, fd, 0 );
00283
00284 if ( map_addr == MAP_FAILED )
00285 {
00286 close( fd );
00287 instru_lib_error( "Unable to mmap" );
00288 }
00289
00290 _write_File_Header( );
00291 _write_Pu_Header( );
00292 _write_Str_Header( );
00293 _write_pu_data( );
00294
00295 munmap ( map_addr, output_file_size );
00296 close( fd );
00297 Free_Space( );
00298 have_finish=TRUE;
00299 }
00300
00301 static void _write_File_Header( )
00302 {
00303 Fb_Hdr file_header;
00304 char fb_ident[16] = "0123456789abcde";
00305 current_offset = 0;
00306 int i;
00307 for(i=0;i<16;i++)
00308 file_header.fb_ident[i] = fb_ident[i];
00309 file_header.fb_version = INSTR_CURRENT;
00310 file_header.fb_profile_offset = 0;
00311 file_header.fb_pu_hdr_offset = current_PU_header_offset;
00312 file_header.fb_pu_hdr_ent_size = Pu_Hdr_size;
00313 file_header.fb_pu_hdr_num = pu_counter;
00314 file_header.fb_str_table_offset = current_str_table_offset;
00315 file_header.fb_str_table_size = str_table_size;
00316 file_header.phase_num = prof_phase;
00317 memcpy( map_addr+current_offset,&file_header,Fb_Hdr_size );
00318 current_offset += Fb_Hdr_size;
00319 }
00320
00321 static void _write_Str_Header()
00322 {
00323 hash_map<char* ,PU_PROFILE_INFO*,ptrhash >::iterator i;
00324 for(i = PU_PROFILE_INFO_TABLE.begin();
00325 i != PU_PROFILE_INFO_TABLE.end(); i++) {
00326 memcpy( map_addr+current_offset,(*i).first,
00327 strlen( (*i).first ) + 1 );
00328 current_offset += strlen( (*i).first ) + 1;
00329 }
00330 }
00331
00332 static void _write_Pu_Header( )
00333 {
00334
00335 Pu_Hdr pu_header;
00336 INT current_pu_name_index =0;
00337 hash_map<char* ,PU_PROFILE_INFO*,ptrhash >::iterator i;
00338 for(i = PU_PROFILE_INFO_TABLE.begin();
00339 i != PU_PROFILE_INFO_TABLE.end(); i++)
00340 {
00341 PU_PROFILE_INFO* info = (*i).second;
00342 {
00343 pu_header.pu_num_edge_entries =info->_edge_sum;
00344 pu_header.pu_edge_offset = current_Pu_file_offset;
00345 pu_header.pu_value_offset = current_Pu_file_offset +
00346 info->_edge_sum * FB_FREQ_size;
00347 pu_header.pu_stride_offset = pu_header.pu_value_offset +info->_instr_count * TNV_item_size;
00348 pu_header.pu_checksum = info->_edge_sum;
00349 pu_header.pu_name_index = current_pu_name_index;
00350
00351 pu_header.pu_instr_count = info->_instr_count;
00352 pu_header.pu_instr_exec_count = info->_sum_count;
00353 pu_header.pu_ld_count = info->_ld_count;
00354
00355 current_pu_name_index +=strlen((*i).first)+ strlen(" ");
00356 pu_header.pu_file_offset = 0;
00357 pu_header.pu_inv_offset = current_Pu_file_offset;
00358 pu_header.pu_num_inv_entries = 0;
00359 pu_header.pu_br_offset = current_Pu_file_offset;
00360 pu_header.pu_num_br_entries = 0;
00361 pu_header.pu_switch_offset = current_Pu_file_offset;
00362 pu_header.pu_switch_target_offset = current_Pu_file_offset;
00363 pu_header.pu_num_switch_entries = 0;
00364 pu_header.pu_cgoto_offset = current_Pu_file_offset;
00365 pu_header.pu_cgoto_target_offset = current_Pu_file_offset;
00366 pu_header.pu_num_cgoto_entries = 0;
00367 pu_header.pu_loop_offset = current_Pu_file_offset;
00368 pu_header.pu_num_loop_entries = 0;
00369 pu_header.pu_scircuit_offset = current_Pu_file_offset;
00370 pu_header.pu_num_scircuit_entries = 0;
00371 pu_header.pu_call_offset = current_Pu_file_offset;
00372 pu_header.pu_num_call_entries = 0;
00373 memcpy( map_addr+current_offset,&pu_header,Pu_Hdr_size );
00374 current_offset += Pu_Hdr_size;
00375 current_Pu_file_offset += info->_edge_sum * FB_FREQ_size;
00376 current_Pu_file_offset += info->_instr_count * TNV_item_size;
00377 current_Pu_file_offset += info->_ld_count * TNV_item_size;
00378 }
00379 }
00380 }
00381
00382 static void _write_pu_data( )
00383 {
00384
00385 hash_map<char* ,PU_PROFILE_INFO*,ptrhash >::iterator i;
00386 for(i = PU_PROFILE_INFO_TABLE.begin();
00387 i != PU_PROFILE_INFO_TABLE.end(); i++)
00388 {
00389 PU_PROFILE_INFO* info = (*i).second;
00390 _write_edge_profile( info );
00391 _write_TNV_items_profile( info );
00392 _write_srd_TNV_items_profile( info );
00393 }
00394 }
00395
00396 static void _write_edge_profile( PU_PROFILE_INFO* pu_info )
00397 {
00398 INT pu_num_edge_entries = pu_info->_edge_sum;
00399 FB_FREQ fb_freq;
00400 for( INT j = 0;j<pu_num_edge_entries;j++ )
00401 {
00402 fb_freq._value = (float) pu_info->_counter[j]._value;
00403 fb_freq._type = FB_FREQ_TYPE_EXACT;
00404 memcpy( map_addr+current_offset,&fb_freq, FB_FREQ_size );
00405 current_offset += FB_FREQ_size;
00406 }
00407 }
00408
00409 void Free_Space( )
00410 {
00411 hash_map<char* ,PU_PROFILE_INFO*,ptrhash >::iterator i;
00412 for(i = PU_PROFILE_INFO_TABLE.begin();
00413 i != PU_PROFILE_INFO_TABLE.end(); i++)
00414 free((*i).second);
00415 }
00416
00417 void instru_lib_error( const char *fmt, const char* msg )
00418 {
00419 printf( fmt,msg );
00420 exit( -1 );
00421 }
00422
00426 PU_PROFILE_INFO * __value_profile_pu_init(char * outputfile,
00427 char* srcfile_pu_name, PROFILE_PHASE phase, UINT32 instr_count)
00428 {
00429 #ifdef VALUE_PROFILE_VERIFY
00430
00431 if (!have_open_output_file)
00432 {
00433 if ( (fout = fopen( outputfile, "wb"))==NULL )
00434 instru_lib_error( "Unable to open file: %s", outputfile );
00435 have_open_output_file = TRUE;
00436 void __profile_finalize();
00437 atexit( __profile_finalize );
00438 }
00439 return;
00440 #endif
00441 __profile_init(outputfile, phase);
00442
00443 PU_PROFILE_INFO * pPU_PROFILE_INFO;
00444 pPU_PROFILE_INFO = PU_PROFILE_INFO_TABLE[srcfile_pu_name];
00445 if (pPU_PROFILE_INFO != NULL)
00446 {
00447 if ( !( (pPU_PROFILE_INFO->_has_alloc) & VALUE_PROFILE_ALLOC ) )
00448 {
00449 pPU_PROFILE_INFO->_val_prof_tnv_table = (FB_TNV *)calloc(instr_count, TNV_item_size);
00450 if ( !(pPU_PROFILE_INFO->_val_prof_tnv_table) )
00451 {
00452 instru_lib_error("__value_profile_pu_init : Not enough memory.\n");
00453 }
00454 pPU_PROFILE_INFO->_instr_count = instr_count;
00455 pPU_PROFILE_INFO->_has_alloc |= VALUE_PROFILE_ALLOC;
00456 }
00457 }
00458 else
00459 {
00460 FB_TNV * tnv_table = (FB_TNV*) calloc(instr_count, TNV_item_size);
00461 if (!tnv_table)
00462 {
00463 instru_lib_error("__value_profile_pu_init : Not enough memory.\n");
00464 }
00465 pPU_PROFILE_INFO = new PU_PROFILE_INFO(instr_count, 0, 0, tnv_table, NULL);
00466 pPU_PROFILE_INFO->_has_alloc |= VALUE_PROFILE_ALLOC;
00467 PU_PROFILE_INFO_TABLE[srcfile_pu_name] = pPU_PROFILE_INFO;
00468 }
00469 return pPU_PROFILE_INFO;
00470 }
00471
00472 void __value_profile_invoke( PU_PROFILE_INFO * pu_hdr, UINT32 instr_id, UINT64 value)
00473 {
00474 #ifdef VALUE_PROFILE_VERIFY
00475 fprintf( fout, "[%s%c :%u,%llu]",srcfile_pu_name,'\0',instr_id,value );
00476 return;
00477 #endif
00478 PU_PROFILE_INFO * pPU_PROFILE_INFO;
00479 pPU_PROFILE_INFO = pu_hdr;
00480 pPU_PROFILE_INFO->_sum_count++;
00481 pPU_PROFILE_INFO->_val_prof_tnv_table[instr_id]._id = instr_id;
00482 pPU_PROFILE_INFO->_val_prof_tnv_table[instr_id]._exec_counter++;
00483 pPU_PROFILE_INFO->_val_prof_tnv_table[instr_id]._flag = 0;
00484 pPU_PROFILE_INFO->_val_prof_tnv_table[instr_id]._clear_counter++;
00485
00486
00487
00488 FB_TNV * ptnv = &(pPU_PROFILE_INFO->_val_prof_tnv_table[instr_id]);
00489 INT i, j;
00490 UINT64 clear_interval = ptnv->_counters[3] + ptnv->_counters[4];
00491 if (ptnv->_clear_counter >= clear_interval)
00492 {
00493 ptnv->_clear_counter = 0;
00494
00495 UINT64 tmpvalues[10], tmpcounters[10];
00496 for (i=0; i<10; i++)
00497 {
00498 tmpvalues[i] = ptnv->_values[i];
00499 tmpcounters[i] = ptnv->_counters[i];
00500 }
00501 INT a, b;
00502 a = 0;
00503 b = 6;
00504 i = 0;
00505 while ( a < 6 && b < 10 )
00506 {
00507 while ( a < 6 && tmpcounters[a] >= tmpcounters[b] )
00508 {
00509 ptnv->_values[i] = tmpvalues[a];
00510 ptnv->_counters[i] = tmpcounters[a];
00511 i++;
00512 a++;
00513 }
00514 while ( b < 10 && tmpcounters[b] >= tmpcounters[a] )
00515 {
00516 ptnv->_values[i] = tmpvalues[b];
00517 ptnv->_counters[i] = tmpcounters[b];
00518 i++;
00519 b++;
00520 }
00521 }
00522 while ( a < 6 )
00523 {
00524 ptnv->_values[i] = tmpvalues[a];
00525 ptnv->_counters[i] = tmpcounters[a];
00526 i++;
00527 a++;
00528 }
00529 while ( b < 10 )
00530 {
00531 ptnv->_values[i] = tmpvalues[b];
00532 ptnv->_counters[i] = tmpcounters[b];
00533 i++;
00534 b++;
00535 }
00536
00537 for (i=6; i< 10; i++)
00538 {
00539 ptnv->_values[i] = 0;
00540 ptnv->_counters[i] = 0;
00541 }
00542 }
00543
00544
00545 for (i=0;i<6;i++)
00546 {
00547 if (value == ptnv->_values[i] && ptnv->_counters[i]>0)
00548 {
00549 ptnv->_counters[i]++;
00550 j = i;
00551 while (j>0 && ptnv->_counters[j-1]<ptnv->_counters[j])
00552 {
00553 UINT64 tmp;
00554 tmp = ptnv->_values[j-1];
00555 ptnv->_values[j-1] = ptnv->_values[j];
00556 ptnv->_values[j] = tmp;
00557
00558 tmp = ptnv->_counters[j-1];
00559 ptnv->_counters[j-1] = ptnv->_counters[j];
00560 ptnv->_counters[j] = tmp;
00561 }
00562 break;
00563 }
00564 else if (ptnv->_counters[i]==0)
00565 {
00566 ptnv->_values[i] = value;
00567 ptnv->_counters[i] = 1;
00568 break;
00569 }
00570 }
00571
00572
00573
00574 if (i < 6)
00575 return;
00576
00577 for (i=6;i<10;i++)
00578 {
00579 if (value == ptnv->_values[i] && ptnv->_counters[i]>0)
00580 {
00581 ptnv->_counters[i]++;
00582 j = i;
00583 while (j>6 && ptnv->_counters[j-1]<ptnv->_counters[j])
00584 {
00585 UINT64 tmp;
00586 tmp = ptnv->_values[j-1];
00587 ptnv->_values[j-1] = ptnv->_values[j];
00588 ptnv->_values[j] = tmp;
00589
00590 tmp = ptnv->_counters[j-1];
00591 ptnv->_counters[j-1] = ptnv->_counters[j];
00592 ptnv->_counters[j] = tmp;
00593 }
00594 break;
00595 }
00596 else if (ptnv->_counters[i]==0)
00597 {
00598 ptnv->_values[i] = value;
00599 ptnv->_counters[i] = 1;
00600 break;
00601 }
00602 }
00603 }
00604
00605 static void _write_TNV_items_profile( PU_PROFILE_INFO* pu_info )
00606 {
00607 INT pu_num_TNV_items = pu_info->_instr_count;
00608 FB_TNV tnv_item;
00609 for( INT j = 0;j<pu_num_TNV_items;j++ )
00610 {
00611 tnv_item = pu_info->_val_prof_tnv_table[j];
00612 memcpy( map_addr+current_offset,&tnv_item,TNV_item_size );
00613 current_offset += TNV_item_size;
00614 }
00615 }
00616
00620
00624
00625 PU_PROFILE_INFO * __stride_profile_pu_init(char * outputfile,
00626 char* srcfile_pu_name, PROFILE_PHASE phase, UINT32 instr_count)
00627 {
00628 #ifdef VALUE_PROFILE_VERIFY
00629
00630 if (!have_open_output_file)
00631 {
00632 if ( (fout = fopen( outputfile, "wb"))==NULL )
00633 instru_lib_error( "Unable to open file: %s", outputfile );
00634 have_open_output_file = TRUE;
00635 void __profile_finalize();
00636 atexit( __profile_finalize );
00637 }
00638 return;
00639 #endif
00640 __profile_init(outputfile, phase);
00641
00642 PU_PROFILE_INFO * pPU_PROFILE_INFO;
00643 pPU_PROFILE_INFO = PU_PROFILE_INFO_TABLE[srcfile_pu_name];
00644 current_srcfile_pu_name = srcfile_pu_name;
00645 if (pPU_PROFILE_INFO != NULL)
00646 {
00647 if ( !( (pPU_PROFILE_INFO->_has_alloc) & STRIDE_PROFILE_ALLOC ) )
00648 {
00649 pPU_PROFILE_INFO->_srd_prof_tnv_table = (FB_TNV *)calloc(instr_count, TNV_item_size);
00650 if ( !(pPU_PROFILE_INFO->_srd_prof_tnv_table) )
00651 {
00652 instru_lib_error("__stride_profile_pu_init : Not enough memory.\n");
00653 }
00654 pPU_PROFILE_INFO->_ld_count = instr_count;
00655 pPU_PROFILE_INFO->_has_alloc |= STRIDE_PROFILE_ALLOC;
00656 }
00657 }
00658 else
00659 {
00660 FB_TNV * tnv_table = (FB_TNV*) calloc(instr_count, TNV_item_size);
00661 if (!tnv_table)
00662 {
00663 instru_lib_error("__value_profile_pu_init : Not enough memory.\n");
00664 }
00665 pPU_PROFILE_INFO = new PU_PROFILE_INFO(0,instr_count, 0, NULL, tnv_table);
00666 pPU_PROFILE_INFO->_has_alloc |= STRIDE_PROFILE_ALLOC;
00667 PU_PROFILE_INFO_TABLE[srcfile_pu_name] = pPU_PROFILE_INFO;
00668 }
00669 return pPU_PROFILE_INFO;
00670 }
00671
00672 void __stride_profile_invoke( PU_PROFILE_INFO * pu_hdr, UINT32 instr_id, UINT64 value)
00673 {
00674 #ifdef VALUE_PROFILE_VERIFY
00675 fprintf( fout, "[%s%c :%u,%llu]",srcfile_pu_name,'\0',instr_id,value );
00676 return;
00677 #endif
00678
00679 PU_PROFILE_INFO * pPU_PROFILE_INFO;
00680 pPU_PROFILE_INFO = pu_hdr;
00681 instr_id--;
00682 pPU_PROFILE_INFO->_srd_prof_tnv_table[instr_id]._id = instr_id;
00683 pPU_PROFILE_INFO->_srd_prof_tnv_table[instr_id]._flag = 0;
00684 pPU_PROFILE_INFO->_srd_prof_tnv_table[instr_id]._exec_counter++;
00685 pPU_PROFILE_INFO->_srd_prof_tnv_table[instr_id]._clear_counter++;
00686
00687
00688
00689
00690 FB_TNV * ptnv = &(pPU_PROFILE_INFO->_srd_prof_tnv_table[instr_id]);
00691 INT i, j;
00692 UINT64 clear_interval = ptnv->_counters[3] + ptnv->_counters[4];
00693 if (ptnv->_clear_counter >= clear_interval)
00694 {
00695 ptnv->_clear_counter = 0;
00696
00697 UINT64 tmpvalues[10], tmpcounters[10];
00698 for (i=0; i<10; i++)
00699 {
00700 tmpvalues[i] = ptnv->_values[i];
00701 tmpcounters[i] = ptnv->_counters[i];
00702 }
00703 INT a, b;
00704 a = 0;
00705 b = 6;
00706 i = 0;
00707 while ( a < 6 && b < 10 )
00708 {
00709 while ( a < 6 && tmpcounters[a] >= tmpcounters[b] )
00710 {
00711 ptnv->_values[i] = tmpvalues[a];
00712 ptnv->_counters[i] = tmpcounters[a];
00713 i++;
00714 a++;
00715 }
00716 while ( b < 10 && tmpcounters[b] >= tmpcounters[a] )
00717 {
00718 ptnv->_values[i] = tmpvalues[b];
00719 ptnv->_counters[i] = tmpcounters[b];
00720 i++;
00721 b++;
00722 }
00723 }
00724 while ( a < 6 )
00725 {
00726 ptnv->_values[i] = tmpvalues[a];
00727 ptnv->_counters[i] = tmpcounters[a];
00728 i++;
00729 a++;
00730 }
00731 while ( b < 10 )
00732 {
00733 ptnv->_values[i] = tmpvalues[b];
00734 ptnv->_counters[i] = tmpcounters[b];
00735 i++;
00736 b++;
00737 }
00738
00739 for (i=6; i< 10; i++)
00740 {
00741 ptnv->_values[i] = 0;
00742 ptnv->_counters[i] = 0;
00743 }
00744 }
00745 UINT64 temp_address = value;
00746 value = value - ptnv->_address;
00747 if(value == ptnv->_stride_steps)
00748 {
00749 ptnv->_zero_std_counter++;
00750 }
00751 ptnv->_stride_steps =value;
00752 ptnv->_address = temp_address;
00753
00754 for (i=0;i<6;i++)
00755 {
00756 if (value == ptnv->_values[i] && ptnv->_counters[i]>0)
00757 {
00758 ptnv->_counters[i]++;
00759 j = i;
00760 while (j>0 && ptnv->_counters[j-1]<ptnv->_counters[j])
00761 {
00762 UINT64 tmp;
00763 tmp = ptnv->_values[j-1];
00764 ptnv->_values[j-1] = ptnv->_values[j];
00765 ptnv->_values[j] = tmp;
00766
00767 tmp = ptnv->_counters[j-1];
00768 ptnv->_counters[j-1] = ptnv->_counters[j];
00769 ptnv->_counters[j] = tmp;
00770 }
00771 break;
00772 }
00773 else if (ptnv->_counters[i]==0)
00774 {
00775 ptnv->_values[i] = value;
00776 ptnv->_counters[i] = 1;
00777 break;
00778 }
00779 }
00780
00781
00782
00783
00784 if (i < 6)
00785 return;
00786
00787
00788 for (i=6;i<10;i++)
00789 {
00790 if (value == ptnv->_values[i] && ptnv->_counters[i]>0)
00791 {
00792 ptnv->_counters[i]++;
00793 j = i;
00794 while (j>6 && ptnv->_counters[j-1]<ptnv->_counters[j])
00795 {
00796 UINT64 tmp;
00797 tmp = ptnv->_values[j-1];
00798 ptnv->_values[j-1] = ptnv->_values[j];
00799 ptnv->_values[j] = tmp;
00800
00801 tmp = ptnv->_counters[j-1];
00802 ptnv->_counters[j-1] = ptnv->_counters[j];
00803 ptnv->_counters[j] = tmp;
00804 }
00805 break;
00806 }
00807 else if (ptnv->_counters[i]==0)
00808 {
00809 ptnv->_values[i] = value;
00810 ptnv->_counters[i] = 1;
00811 break;
00812 }
00813 }
00814
00815 }
00816
00817 static void _write_srd_TNV_items_profile( PU_PROFILE_INFO* pu_info )
00818 {
00819 INT pu_num_TNV_items = pu_info->_ld_count;
00820 FB_TNV tnv_item;
00821 for( INT j = 0;j<pu_num_TNV_items;j++ )
00822 {
00823 tnv_item = pu_info->_srd_prof_tnv_table[j];
00824 memcpy( map_addr+current_offset,&tnv_item,TNV_item_size );
00825 current_offset += TNV_item_size;
00826 }
00827 }
00828