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