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
00043
00044
00045
00046
00047
00048
00049 #include <stdio.h>
00050 #include <stdlib.h>
00051 #include "hash_map.h"
00052 #include "vector.h"
00053 #include "utils.h"
00054
00055
00056 #include "profile.h"
00057
00058 namespace Instr {
00059
00060
00061
00062
00063 HASH_MAP PU_Profile_Handle_Table;
00064
00065 static PROFILE_PHASE instrumentation_phase_num = PROFILE_PHASE_NONE;
00066
00067
00068
00069
00070
00071
00072
00073 PU_PROFILE_HANDLE
00074 Get_PU_Handle(char *file_name, char* pu_name, long current_pc, INT32 pu_size, INT32 checksum)
00075 {
00076 PU_PROFILE_HANDLE & pu_handle = PU_Profile_Handle_Table[current_pc];
00077
00078 if (pu_handle == NULL) {
00079
00080 pu_handle = new PU_Profile_Handle(file_name, pu_name, current_pc, pu_size, checksum);
00081
00082 }
00083
00084 return pu_handle;
00085 }
00086
00087
00088
00089 void
00090 PU_Profile_Handle::Set_file_name(char *s)
00091 {
00092 this->file_name = (char *) malloc (sizeof(char) * (strlen(s) + 1));
00093 strcpy(this->file_name, s);
00094 }
00095
00096
00097
00098 void
00099 PU_Profile_Handle::Set_pu_name( char *s)
00100 {
00101 this->pu_name = (char *) malloc (sizeof(char) * (strlen(s) + 1));
00102 strcpy(this->pu_name, s);
00103 }
00104
00105
00106
00107
00108
00109
00110
00111
00112
00113
00114 void
00115 Profile_Invoke_Init(PU_PROFILE_HANDLE pu_handle, INT32 num_invokes)
00116 {
00117 Invoke_Profile_Vector& Inv_Table = pu_handle->Get_Invoke_Table();
00118
00119 if (Inv_Table.empty()) {
00120 Inv_Table.resize(num_invokes);
00121 }
00122 }
00123
00124
00125
00126 void
00127 Profile_Invoke(PU_PROFILE_HANDLE pu_handle, INT32 invoke_id)
00128 {
00129 Invoke_Profile_Vector& Inv_Table = pu_handle->Get_Invoke_Table();
00130
00131 Inv_Table[invoke_id].invoke_count++;
00132 }
00133
00134
00135
00136
00137
00138
00139
00140
00141
00142
00143
00144 void
00145 Profile_Branch_Init(PU_PROFILE_HANDLE pu_handle, INT32 num_branches)
00146 {
00147 Branch_Profile_Vector& Br_Table = pu_handle->Get_Branch_Table();
00148
00149 if (Br_Table.empty()) {
00150 Br_Table.resize(num_branches);
00151 }
00152 }
00153
00154
00155
00156 void
00157 Profile_Branch(PU_PROFILE_HANDLE pu_handle, INT32 branch_id, bool taken)
00158 {
00159 if (taken)
00160 Incr_Branch_Taken(pu_handle, branch_id);
00161 else
00162 Incr_Branch_Not_Taken(pu_handle, branch_id);
00163 }
00164
00165
00166
00167
00168 void Incr_Branch_Taken(PU_PROFILE_HANDLE pu_handle, INT32 id)
00169 {
00170 Branch_Profile_Vector& Br_Table = pu_handle->Get_Branch_Table();
00171 Br_Table[id].taken++;
00172 }
00173
00174
00175
00176
00177 void Incr_Branch_Not_Taken(PU_PROFILE_HANDLE pu_handle, INT32 id)
00178 {
00179 Branch_Profile_Vector& Br_Table = pu_handle->Get_Branch_Table();
00180 Br_Table[id].not_taken++;
00181 }
00182
00183
00184
00185
00186
00187
00188
00189
00190
00191
00192
00193
00194
00195
00196 void
00197 Profile_Switch_Init(PU_PROFILE_HANDLE pu_handle,
00198 INT32 num_switches, INT32 *switch_num_targets,
00199 INT32 num_case_values, FB_NUM_TYPE *case_values)
00200 {
00201 Switch_Profile_Vector& Switch_Table = pu_handle->Get_Switch_Table();
00202
00203 if (Switch_Table.empty()) {
00204
00205 Switch_Table.resize(num_switches);
00206
00207 for (Switch_Profile_Vector::iterator first (Switch_Table.begin ());
00208 first != Switch_Table.end (); ++first) {
00209
00210 Switch_Profile& sp = *first;
00211
00212 INT32 num_targets = *switch_num_targets;
00213
00214 sp.targets_profile.resize (num_targets + 1);
00215
00216 sp.targets_case_value.reserve (num_targets);
00217 sp.targets_case_value.insert (sp.targets_case_value.begin (),
00218 case_values,
00219 case_values + num_targets);
00220 case_values += num_targets;
00221
00222 ++switch_num_targets;
00223 }
00224
00225 }
00226 }
00227
00228
00229
00230
00231
00232
00233
00234
00235
00236 void
00237 Profile_Switch(PU_PROFILE_HANDLE pu_handle, INT32 switch_id, INT32 case_value,
00238 INT32 num_targets)
00239 {
00240 Switch_Profile_Vector& switch_table = pu_handle->Get_Switch_Table();
00241 Switch_Profile& switch_entry = switch_table[switch_id];
00242 Switch_Profile::value_type& targets_profile =
00243 switch_entry.Get_Targets_Profile();
00244 Switch_Profile::value_type& targets_case_value =
00245 switch_entry.Get_Targets_Case_Value();
00246
00247
00248 INT32 t, target = -1;
00249 for (t = 0; t < num_targets; t++) {
00250 if (targets_case_value[t] == case_value) {
00251 target = t;
00252 }
00253 }
00254
00255 targets_profile[target + 1]++;
00256 }
00257
00258
00259
00260
00261
00262
00263
00264
00265
00266
00267
00268
00269
00270
00271 void
00272 Profile_Compgoto_Init(PU_PROFILE_HANDLE pu_handle, INT32 num_compgotos,
00273 INT32 *compgoto_num_targets)
00274 {
00275 Compgoto_Profile_Vector& Compgoto_Table = pu_handle->Get_Compgoto_Table();
00276
00277 if (Compgoto_Table.empty()) {
00278
00279 Compgoto_Table.resize(num_compgotos);
00280
00281 for (INT32 i = 0; i < num_compgotos; i++) {
00282
00283 INT32 num_targets = *compgoto_num_targets + 1;
00284
00285 Compgoto_Table[i].Get_Targets_Profile ().resize(num_targets);
00286
00287 ++compgoto_num_targets;
00288 }
00289 }
00290 }
00291
00292
00293
00294
00295
00296
00297
00298
00299
00300 void
00301 Profile_Compgoto(PU_PROFILE_HANDLE pu_handle, INT32 compgoto_id, INT32 target,
00302 INT32 num_targets)
00303 {
00304 if (target < 0 || target >= num_targets)
00305 target = -1;
00306
00307 Compgoto_Profile_Vector& compgoto_table = pu_handle->Get_Compgoto_Table();
00308
00309 Compgoto_Profile& cgoto = compgoto_table[compgoto_id];
00310
00311 ++(cgoto.Get_Targets_Profile ()[target + 1]);
00312 }
00313
00314
00315
00316
00317
00318
00319
00320
00321
00322
00323 void
00324 Profile_Loop_Init(PU_PROFILE_HANDLE pu_handle, INT32 num_loops)
00325 {
00326
00327 Loop_Profile_Vector& Loop_Table = pu_handle->Get_Loop_Table();
00328
00329 if (Loop_Table.empty()) {
00330 Loop_Table.resize(num_loops);
00331 }
00332 }
00333
00334
00335
00336 void
00337 Profile_Loop(PU_PROFILE_HANDLE pu_handle, INT32 loop_id)
00338 {
00339 Loop_Profile_Vector& Loop_Table = pu_handle->Get_Loop_Table();
00340 Loop_Profile& loop_info = Loop_Table[loop_id];
00341
00342 if (loop_info.invocation_count == 1) {
00343 loop_info.min_trip_count = loop_info.last_trip_count;
00344 loop_info.max_trip_count = loop_info.last_trip_count;
00345 } else if (loop_info.invocation_count != 0) {
00346 loop_info.min_trip_count = min(loop_info.min_trip_count,
00347 loop_info.last_trip_count);
00348 loop_info.max_trip_count = max(loop_info.max_trip_count,
00349 loop_info.last_trip_count);
00350 }
00351
00352
00353
00354
00355
00356 if (loop_info.invocation_count > 0 && loop_info.last_trip_count == 0) {
00357 loop_info.num_zero_trips++;
00358 }
00359
00360 loop_info.invocation_count++;
00361 loop_info.last_trip_count = 0;
00362 }
00363
00364
00365
00366 void
00367 Profile_Loop_Iter(PU_PROFILE_HANDLE pu_handle, INT32 loop_id)
00368 {
00369 Loop_Profile_Vector& Loop_Table = pu_handle->Get_Loop_Table();
00370 Loop_Profile& loop_info = Loop_Table[loop_id];
00371
00372 loop_info.last_trip_count++;
00373 loop_info.total_trip_count++;
00374 }
00375
00376
00377
00378
00379
00380
00381
00382
00383
00384
00385 void
00386 Profile_Short_Circuit_Init(PU_PROFILE_HANDLE pu_handle,
00387 INT32 num_short_circuit_ops)
00388 {
00389 Short_Circuit_Profile_Vector& Short_Circuit_Table
00390 = pu_handle->Get_Short_Circuit_Table();
00391
00392 if (Short_Circuit_Table.empty()) {
00393 Short_Circuit_Table.resize(num_short_circuit_ops);
00394 }
00395 }
00396
00397
00398
00399 void
00400 Profile_Short_Circuit(PU_PROFILE_HANDLE pu_handle, INT32 short_circuit_id,
00401 bool taken)
00402 {
00403 if (taken)
00404 Incr_Right_Taken(pu_handle, short_circuit_id);
00405 else
00406 Incr_Neither_Taken(pu_handle, short_circuit_id);
00407 }
00408
00409
00410
00411
00412 void Incr_Right_Taken(PU_PROFILE_HANDLE pu_handle, INT32 id)
00413 {
00414 Short_Circuit_Profile_Vector& Short_Circuit_Table
00415 = pu_handle->Get_Short_Circuit_Table();
00416 Short_Circuit_Table[id].right_taken_count++;
00417 }
00418
00419
00420
00421
00422 void Incr_Neither_Taken(PU_PROFILE_HANDLE pu_handle, INT32 id)
00423 {
00424 Short_Circuit_Profile_Vector& Short_Circuit_Table
00425 = pu_handle->Get_Short_Circuit_Table();
00426 Short_Circuit_Table[id].neither_taken_count++;
00427 }
00428
00429
00430
00431
00432
00433
00434
00435
00436
00437
00438 void
00439 Profile_Call_Init(PU_PROFILE_HANDLE pu_handle, INT32 num_calls)
00440 {
00441 Call_Profile_Vector& Call_Table = pu_handle->Get_Call_Table();
00442
00443 if (Call_Table.empty()) {
00444 Call_Table.resize(num_calls);
00445 }
00446 }
00447
00448 void
00449 Profile_Icall_Init(PU_PROFILE_HANDLE pu_handle, INT32 num_icalls)
00450 {
00451 Icall_Profile_Vector& Icall_Table = pu_handle->Get_Icall_Table();
00452
00453 if (Icall_Table.empty()) {
00454 Icall_Table.resize(num_icalls);
00455 for (int i=0;i<num_icalls;i++)
00456 {
00457 memset(&(Icall_Table[i].fb_tnv),0,sizeof(FB_TNV));
00458 }
00459 }
00460 }
00461
00462
00463
00464 void
00465 Profile_Call_Entry(PU_PROFILE_HANDLE pu_handle, INT32 call_id)
00466 {
00467 Call_Profile_Vector& Call_Table = pu_handle->Get_Call_Table();
00468
00469 Call_Table[call_id].entry_count++;
00470 }
00471
00472
00473
00474 void
00475 Profile_Call_Exit(PU_PROFILE_HANDLE pu_handle, INT32 call_id)
00476 {
00477 Call_Profile_Vector& Call_Table = pu_handle->Get_Call_Table();
00478
00479 Call_Table[call_id].exit_count++;
00480 }
00481
00482 void
00483 Profile_Icall(PU_PROFILE_HANDLE pu_handle, INT32 icall_id, void * called_fun_address)
00484 {
00485 Icall_Profile_Vector& Icall_Table = pu_handle->Get_Icall_Table();
00486
00487 FB_TNV * ptnv = &(Icall_Table[icall_id].fb_tnv);
00488 ptnv->_id = icall_id;
00489 ptnv->_exec_counter++;
00490 ptnv->_flag = 0;
00491 ptnv->_clear_counter++;
00492
00493 FB_VALUE_TYPE value = (UINTPS)called_fun_address;
00494
00495
00496
00497
00498 INT i, j;
00499 FB_VALUE_TYPE clear_interval = ptnv->_counters[3] + ptnv->_counters[4];
00500 if (ptnv->_clear_counter >= clear_interval)
00501 {
00502 ptnv->_clear_counter = 0;
00503
00504 FB_VALUE_TYPE tmpvalues[10], tmpcounters[10];
00505 for (i=0; i<10; i++)
00506 {
00507 tmpvalues[i] = ptnv->_values[i];
00508 tmpcounters[i] = ptnv->_counters[i];
00509 }
00510 INT a, b;
00511 a = 0;
00512 b = 6;
00513 i = 0;
00514 while ( a < 6 && b < 10 )
00515 {
00516 while ( a < 6 && tmpcounters[a] >= tmpcounters[b] )
00517 {
00518 ptnv->_values[i] = tmpvalues[a];
00519 ptnv->_counters[i] = tmpcounters[a];
00520 i++;
00521 a++;
00522 }
00523 while ( b < 10 && tmpcounters[b] >= tmpcounters[a] )
00524 {
00525 ptnv->_values[i] = tmpvalues[b];
00526 ptnv->_counters[i] = tmpcounters[b];
00527 i++;
00528 b++;
00529 }
00530 }
00531 while ( a < 6 )
00532 {
00533 ptnv->_values[i] = tmpvalues[a];
00534 ptnv->_counters[i] = tmpcounters[a];
00535 i++;
00536 a++;
00537 }
00538 while ( b < 10 )
00539 {
00540 ptnv->_values[i] = tmpvalues[b];
00541 ptnv->_counters[i] = tmpcounters[b];
00542 i++;
00543 b++;
00544 }
00545
00546 for (i=6; i< 10; i++)
00547 {
00548 ptnv->_values[i] = 0;
00549 ptnv->_counters[i] = 0;
00550 }
00551 }
00552
00553
00554 for (i=0;i<6;i++)
00555 {
00556 if (value == ptnv->_values[i] && ptnv->_counters[i]>0)
00557 {
00558 ptnv->_counters[i]++;
00559 j = i;
00560 while (j>0 && ptnv->_counters[j-1]<ptnv->_counters[j])
00561 {
00562 FB_VALUE_TYPE tmp;
00563 tmp = ptnv->_values[j-1];
00564 ptnv->_values[j-1] = ptnv->_values[j];
00565 ptnv->_values[j] = tmp;
00566
00567 tmp = ptnv->_counters[j-1];
00568 ptnv->_counters[j-1] = ptnv->_counters[j];
00569 ptnv->_counters[j] = tmp;
00570 }
00571 break;
00572 }
00573 else if (ptnv->_counters[i]==0)
00574 {
00575 ptnv->_values[i] = value;
00576 ptnv->_counters[i] = 1;
00577 break;
00578 }
00579 }
00580
00581
00582
00583 if (i < 6)
00584 {
00585 return;
00586 }
00587
00588
00589 for (i=6;i<10;i++)
00590 {
00591 if (value == ptnv->_values[i] && ptnv->_counters[i]>0)
00592 {
00593 ptnv->_counters[i]++;
00594 j = i;
00595 while (j>6 && ptnv->_counters[j-1]<ptnv->_counters[j])
00596 {
00597 FB_VALUE_TYPE tmp;
00598 tmp = ptnv->_values[j-1];
00599 ptnv->_values[j-1] = ptnv->_values[j];
00600 ptnv->_values[j] = tmp;
00601
00602 tmp = ptnv->_counters[j-1];
00603 ptnv->_counters[j-1] = ptnv->_counters[j];
00604 ptnv->_counters[j] = tmp;
00605 }
00606 break;
00607 }
00608 else if (ptnv->_counters[i]==0)
00609 {
00610 ptnv->_values[i] = value;
00611 ptnv->_counters[i] = 1;
00612 break;
00613 }
00614 }
00615 }
00616
00617 void
00618 Set_Instrumentation_Phase_Num(PROFILE_PHASE phase_num)
00619 {
00620 instrumentation_phase_num = phase_num;
00621 }
00622
00623
00624
00625 PROFILE_PHASE
00626 Instrumentation_Phase_Num()
00627 {
00628 return instrumentation_phase_num;
00629 }
00630
00631
00632
00633
00634 #ifdef KEY
00635 void Profile_Value_Init( PU_PROFILE_HANDLE pu_handle, INT32 num_values )
00636 {
00637 Value_Profile_Vector& Value_Table = pu_handle->Get_Value_Table();
00638
00639 if( Value_Table.empty() ){
00640 Value_Table.resize(num_values);
00641 }
00642 }
00643
00644
00645
00646 void Profile_Value( PU_PROFILE_HANDLE pu_handle, INT32 inst_id, FB_NUM_TYPE value )
00647 {
00648 Value_Profile_Vector& Value_Table = pu_handle->Get_Value_Table();
00649 Value_Profile* entry = &Value_Table[inst_id];
00650
00651 entry->exe_counter++;
00652
00653 for( int i = 0; i < entry->num_values; i++ ){
00654 if( entry->value[i] == value ){
00655 entry->freq[i]++;
00656 for( int j = i - 1; j >= 0; j-- ){
00657 if( entry->freq[j] >= entry->freq[i] )
00658 break;
00659
00660 const FB_NUM_TYPE tmp_value = entry->value[j];
00661 const FB_NUM_TYPE tmp_freq = entry->freq[j];
00662
00663 entry->freq[j] = entry->freq[i];
00664 entry->value[j] = entry->value[i];
00665 entry->freq[i] = tmp_freq;
00666 entry->value[i] = tmp_value;
00667
00668 i = j;
00669 }
00670
00671 return;
00672 }
00673 }
00674
00675 if( entry->num_values < TNV ){
00676 entry->value[entry->num_values] = value;
00677 entry->freq[entry->num_values] = 1;
00678 entry->num_values++;
00679
00680 } else {
00681
00682 if( entry->exe_counter > ( 2 * entry->freq[0] ) ){
00683 entry->num_values = TNV / 2;
00684 }
00685 }
00686 }
00687
00688 #if !(defined(TARG_SL) && defined(__SL__))
00689 void Profile_Value_FP_Bin_Init( PU_PROFILE_HANDLE pu_handle, INT32 num_values )
00690 {
00691 Value_FP_Bin_Profile_Vector& Value_FP_Bin_Table =
00692 pu_handle->Get_Value_FP_Bin_Table();
00693
00694 if( Value_FP_Bin_Table.empty() ){
00695 Value_FP_Bin_Table.resize(num_values);
00696 }
00697 }
00698
00699
00700
00701 void Profile_Value_FP_Bin( PU_PROFILE_HANDLE pu_handle, INT32 inst_id,
00702 double value_fp_0, double value_fp_1 )
00703 {
00704 Value_FP_Bin_Profile_Vector& Value_FP_Bin_Table =
00705 pu_handle->Get_Value_FP_Bin_Table();
00706 Value_FP_Bin_Profile* entry = &Value_FP_Bin_Table[inst_id];
00707
00708 entry->exe_counter++;
00709 if (value_fp_0 == 0.0) entry->zopnd0 ++;
00710 if (value_fp_1 == 0.0) entry->zopnd1 ++;
00711 if (value_fp_0 == 1.0) entry->uopnd0 ++;
00712 if (value_fp_1 == 1.0) entry->uopnd1 ++;
00713 }
00714 #endif // !TARG_sl
00715 #endif
00716
00717 }