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 <vector>
00062
00063 using std::vector;
00064
00065 #include "profile.h"
00066 #include "profile_interface.h"
00067 #include "profile_errors.h"
00068 #include "dump.h"
00069
00070
00071
00072
00073
00074 static char *output_filename = NULL;
00075 static BOOL unique_output_filename = FALSE;
00076
00077
00078
00079
00080
00081
00082
00083 void __profile_init(char *fname, int phase_num, BOOL unique_name)
00084 {
00085
00086 PROFILE_PHASE curr_phase_num;
00087
00088 void (*pf)() = __profile_finish;
00089 static bool first_call_to_profile_init = true;
00090 if (first_call_to_profile_init) {
00091
00092 atexit(pf);
00093
00094 output_filename = new char[strlen(fname) + 7 + 1];
00095 strcpy(output_filename, fname);
00096 if (unique_name)
00097 strcat (output_filename, ".XXXXXX");
00098 unique_output_filename = unique_name;
00099 first_call_to_profile_init = false;
00100 }
00101
00102 curr_phase_num = Instrumentation_Phase_Num();
00103
00104 if (curr_phase_num == PROFILE_PHASE_NONE) {
00105 Set_Instrumentation_Phase_Num((PROFILE_PHASE) phase_num);
00106 } else if(curr_phase_num != (PROFILE_PHASE) phase_num) {
00107 profile_warn("Phase Number already set to a different value in: %s",
00108 output_filename);
00109 }
00110 }
00111
00112
00113
00114
00115
00116
00117
00118
00119
00120
00121
00122 void *
00123 __profile_pu_init(char *file_name, char* pu_name, long current_pc,
00124 INT32 pusize, INT32 checksum)
00125 {
00126 PU_PROFILE_HANDLE pu_handle
00127 = Get_PU_Handle(file_name, pu_name, current_pc, pusize, checksum);
00128 pu_handle->pu_size = pusize;
00129 pu_handle->runtime_fun_address = current_pc;
00130 return (void *) pu_handle;
00131 }
00132
00133
00134
00135
00136
00137 void
00138 __profile_invoke_init(void *pu_handle, INT32 num_invokes)
00139 {
00140 Profile_Invoke_Init((PU_PROFILE_HANDLE) pu_handle, num_invokes);
00141 }
00142
00143
00144
00145
00146 void
00147 __profile_invoke(void *pu_handle, INT32 invoke_id)
00148 {
00149 Profile_Invoke((PU_PROFILE_HANDLE) pu_handle, invoke_id);
00150 }
00151
00152
00153
00154
00155
00156 void
00157 __profile_branch_init(void *pu_handle, INT32 num_branches)
00158 {
00159 Profile_Branch_Init((PU_PROFILE_HANDLE) pu_handle, num_branches);
00160 }
00161
00162
00163
00164
00165 void
00166 __profile_branch(void *pu_handle, INT32 branch_id, bool taken)
00167 {
00168 Profile_Branch((PU_PROFILE_HANDLE) pu_handle, branch_id, taken);
00169 }
00170
00171
00172
00173
00174
00175 void
00176 __profile_switch_init(void *pu_handle,
00177 INT32 num_switches, INT32 *switch_num_targets,
00178 INT32 num_case_values, INT64 *case_values)
00179 {
00180 Profile_Switch_Init((PU_PROFILE_HANDLE) pu_handle,
00181 num_switches, switch_num_targets,
00182 num_case_values, case_values);
00183 }
00184
00185
00186
00187
00188 void
00189 __profile_switch(void *pu_handle, INT32 switch_id, INT32 target,
00190 INT32 num_targets)
00191 {
00192 Profile_Switch((PU_PROFILE_HANDLE) pu_handle, switch_id, target,
00193 num_targets);
00194 }
00195
00196
00197
00198
00199
00200 void
00201 __profile_compgoto_init(void *pu_handle, INT32 num_compgotos,
00202 INT32 *compgoto_num_targets)
00203 {
00204 Profile_Compgoto_Init((PU_PROFILE_HANDLE) pu_handle, num_compgotos,
00205 compgoto_num_targets);
00206 }
00207
00208
00209
00210
00211 void
00212 __profile_compgoto(void *pu_handle, INT32 compgoto_id, INT32 target,
00213 INT32 num_targets)
00214 {
00215 Profile_Compgoto((PU_PROFILE_HANDLE) pu_handle, compgoto_id, target,
00216 num_targets);
00217 }
00218
00219 #ifdef KEY
00220
00221
00222
00223 void __profile_value_init( void *pu_handle, INT32 num_values )
00224 {
00225 Profile_Value_Init( (PU_PROFILE_HANDLE) pu_handle, num_values );
00226 }
00227
00228
00229
00230
00231 void
00232 __profile_value( void *pu_handle, INT32 inst_id, INT64 value )
00233 {
00234 Profile_Value( (PU_PROFILE_HANDLE) pu_handle, inst_id, value );
00235 }
00236
00237
00238
00239
00240 void __profile_value_fp_bin_init( void *pu_handle, INT32 num_values )
00241 {
00242 Profile_Value_FP_Bin_Init( (PU_PROFILE_HANDLE) pu_handle, num_values );
00243 }
00244
00245
00246
00247
00248 void
00249 __profile_value_fp_bin( void *pu_handle, INT32 inst_id,
00250 double value_fp_0, double value_fp_1 )
00251 {
00252 Profile_Value_FP_Bin( (PU_PROFILE_HANDLE) pu_handle, inst_id,
00253 value_fp_0, value_fp_1 );
00254 }
00255 #endif
00256
00257
00258
00259
00260
00261 void
00262 __profile_loop_init(void *pu_handle, INT32 num_loops)
00263 {
00264 Profile_Loop_Init((PU_PROFILE_HANDLE) pu_handle, num_loops);
00265 }
00266
00267
00268
00269
00270 void
00271 __profile_loop(void *pu_handle, INT32 loop_id)
00272 {
00273 Profile_Loop((PU_PROFILE_HANDLE) pu_handle, loop_id);
00274 }
00275
00276
00277
00278
00279 void
00280 __profile_loop_iter(void *pu_handle, INT32 loop_id)
00281 {
00282 Profile_Loop_Iter((PU_PROFILE_HANDLE) pu_handle, loop_id);
00283 }
00284
00285
00286
00287
00288
00289 void
00290 __profile_short_circuit_init(void *pu_handle, INT32 num_short_circuit_ops)
00291 {
00292 Profile_Short_Circuit_Init((PU_PROFILE_HANDLE) pu_handle,
00293 num_short_circuit_ops);
00294 }
00295
00296
00297
00298
00299 void
00300 __profile_short_circuit(void *pu_handle, INT32 short_circuit_id, bool taken)
00301 {
00302 Profile_Short_Circuit((PU_PROFILE_HANDLE) pu_handle,
00303 short_circuit_id, taken);
00304 }
00305
00306
00307
00308
00309
00310 void
00311 __profile_call_init(void *pu_handle, int num_calls)
00312 {
00313 Profile_Call_Init((PU_PROFILE_HANDLE) pu_handle, num_calls);
00314 }
00315
00316
00317
00318
00319 void
00320 __profile_icall_init(void *pu_handle, int num_icalls)
00321 {
00322 Profile_Icall_Init((PU_PROFILE_HANDLE) pu_handle, num_icalls);
00323 }
00324
00325
00326
00327 void
00328 __profile_call_entry(void *pu_handle, int call_id)
00329 {
00330 Profile_Call_Entry((PU_PROFILE_HANDLE) pu_handle, call_id);
00331 }
00332
00333
00334
00335
00336 void
00337 __profile_call_exit(void *pu_handle, int call_id)
00338 {
00339 Profile_Call_Exit((PU_PROFILE_HANDLE) pu_handle, call_id);
00340 }
00341
00342 void
00343 __profile_icall(void * pu_handle, int icall_id, void * called_fun_address)
00344 {
00345 Profile_Icall((PU_PROFILE_HANDLE) pu_handle, icall_id, called_fun_address);
00346 }
00347
00348
00349
00350
00351 void __profile_finish(void)
00352 {
00353 FILE *fp;
00354 HASH_MAP::iterator i;
00355
00356 if (unique_output_filename) {
00357 int file_id = mkstemp (output_filename);
00358 fp = fdopen (file_id, "w+");
00359 } else
00360 fp = fopen (output_filename, "w+");
00361
00362 if (fp == NULL) {
00363 profile_error("Unable to open file: %s", output_filename);
00364 }
00365
00366 Dump_all(fp, output_filename);
00367
00368 #if 0 // so the fini routine won't core dump if it access instrumented code
00369
00370
00371
00372
00373 for(i = PU_Profile_Handle_Table.begin();
00374 i != PU_Profile_Handle_Table.end(); i++) {
00375 PU_PROFILE_HANDLE pu_handle = (*i).second;
00376 delete pu_handle;
00377 }
00378 #endif
00379
00380 fclose(fp);
00381
00382 delete [] output_filename;
00383 }