2 * Copyright (C) 1995-2007 University of Karlsruhe. All right reserved.
4 * This file is part of libFirm.
6 * This file may be distributed and/or modified under the terms of the
7 * GNU General Public License version 2 as published by the Free Software
8 * Foundation and appearing in the file LICENSE.GPL included in the
9 * packaging of this file.
11 * Licensees holding valid libFirm Professional Edition licenses may use
12 * this file in accordance with the libFirm Commercial License.
13 * Agreement provided with the Software.
15 * This file is provided AS IS with NO WARRANTY OF ANY KIND, INCLUDING THE
16 * WARRANTY OF DESIGN, MERCHANTABILITY AND FITNESS FOR A PARTICULAR
22 * @brief Statistic events.
23 * @author Sebastian Hack
36 #include <libcore/lc_timing.h>
50 static ctx_t ctx_stack[MAX_CTX];
52 static unsigned long time_in_ev = 0;
53 static int ctx_sp = -1;
54 static FILE *file_ev = NULL;
56 static lc_timer_t *timer = NULL;
58 int stat_ev_enabled = 0;
60 typedef struct print_ev_t {
62 struct print_ev_t *next;
65 static print_ev_t *print_events = NULL;
66 static int ctx_switch_since_last_print = 0;
68 #define get_time() lc_timer_elapsed_usec(timer)
70 void stat_ev_ctx_push(const char *key, const char *value)
73 unsigned long start = get_time();
74 ctx_t *ctx = &ctx_stack[ctx_sp + 1];
75 unsigned hash = firm_fnv_hash_str(key);
77 hash = HASH_COMBINE(hash, firm_fnv_hash_str(value));
79 hash = HASH_COMBINE(hash, ctx_stack[ctx_sp].hash);
81 snprintf(ctx->key, array_size(ctx->key), "%s", key);
82 snprintf(ctx->value, array_size(ctx->value), "%s", value);
86 fprintf(file_ev, "P %10x %30s %30s\n", ctx->hash, ctx->key, ctx->value);
88 ctx_switch_since_last_print = 1;
90 time_in_ev += get_time() - start;
94 void stat_ev_ctx_push_fobj(const char *key, const void *firm_object)
98 ir_snprintf(buf, sizeof(buf), "%+F", firm_object);
99 stat_ev_ctx_push(key, buf);
103 void stat_ev_ctx_pop(void)
107 fprintf(file_ev, "O %10x\n", ctx_stack[ctx_sp].hash);
108 ctx_switch_since_last_print = 1;
114 static void maybe_print_context(void)
118 if(!ctx_switch_since_last_print)
121 for(i = 0; i <= ctx_sp; ++i) {
124 fputs(ctx_stack[i].value, stderr);
127 ctx_switch_since_last_print = 0;
130 void stat_ev_emit(const char *name, double value)
133 unsigned long start = get_time();
134 unsigned id = ctx_sp >= 0 ? ctx_stack[ctx_sp].hash : 0;
136 fprintf(file_ev, "E %10x %30s %30f %10ld %10ld\n", id, name, value, start, time_in_ev);
138 if(print_events != NULL) {
139 print_ev_t *print_ev = print_events;
140 while(print_ev != NULL) {
141 /* maybe wanna use regexes instead of strcmp? */
142 if(strstr(name, print_ev->filter) != NULL) {
143 maybe_print_context();
144 fprintf(stderr, "\t%20s %30f\n", name, value);
147 print_ev = print_ev->next;
151 time_in_ev += get_time() - start;
155 void stat_ev_begin(const char *prefix)
159 snprintf(buf, sizeof(buf), "%s.ev", prefix);
165 file_ev = fopen(buf, "wt");
166 timer = lc_timer_register("stat_ev", "firm stat event timer");
168 lc_timer_start(timer);
171 void stat_ev_end(void)
174 lc_timer_stop(timer);
178 print_ev_t *print_ev = print_events;
179 while(print_ev != NULL) {
180 print_ev_t *next = print_ev->next;
186 void stat_ev_flush(void)
188 unsigned long start = get_time();
191 time_in_ev += get_time() - start;
194 void stat_ev_print(const char *filter)
196 print_ev_t *print_ev = malloc(sizeof(print_ev[0]));
197 memset(print_ev, 0, sizeof(print_ev[0]));
199 size_t len = strlen(filter) + 1;
200 if(len >= sizeof(print_ev->filter)) {
201 fprintf(stderr, "Warning: capping event filter (too long)");
202 len = sizeof(print_ev->filter);
204 memcpy(print_ev->filter, filter, len);
205 print_ev->filter[len-1] = 0;
207 print_ev->next = print_events;
208 print_events = print_ev;