2 * Helper code to output instrumentation results.
3 * This file is a supplement to libFirm. It is public domain.
4 * @author Matthias Braun, Steven Schaefer
10 /* Prevent the compiler from mangling the name of this function. */
11 void __init_firmprof(const char*, unsigned int*, size_t)
12 asm("__init_firmprof");
14 typedef struct _profile_counter_t {
18 struct _profile_counter_t *next;
21 static profile_counter_t *counters = NULL;
24 * Write counter values to profiling output file.
25 * We define our output format to be a sequence of 32-bit unsigned integer
26 * values stored in little endian format.
28 void write_little_endian(unsigned *counter, unsigned len, FILE *f)
32 for (i = 0; i < len; ++i) {
33 unsigned v = counter[i];
34 unsigned char bytes[4];
36 bytes[0] = ((v >> 0) & 0xff);
37 bytes[1] = ((v >> 8) & 0xff);
38 bytes[2] = ((v >> 16) & 0xff);
39 bytes[3] = ((v >> 24) & 0xff);
41 fwrite(bytes, 1, 4, f);
45 static void write_profiles(void)
47 profile_counter_t *counter = counters;
48 while (counter != NULL) {
49 profile_counter_t *next = counter->next;
50 FILE *f = fopen(counter->filename, "wb");
52 perror("Warning: couldn't open file for writing profiling data");
55 write_little_endian(counter->counters, counter->len, f);
64 * Register a new profile counter. This is called by separate constructors
65 * for each translation unit. Incidentally, referring to this function as
66 * "__init_firmprof" is perfectly linker friendly.
68 void __init_firmprof(const char *filename,
69 unsigned int *counts, size_t len)
71 static int initialized = 0;
72 profile_counter_t *counter;
76 atexit(write_profiles);
79 counter = (profile_counter_t*) malloc(sizeof(*counter));
83 counter->filename = filename;
84 counter->counters = counts;
85 counter->next = counters;