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