Merge Fix: Spills have ProjMs now
[libfirm] / ir / stat / statev.h
1 /*
2  * Copyright (C) 1995-2008 University of Karlsruhe.  All right reserved.
3  *
4  * This file is part of libFirm.
5  *
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.
10  *
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.
14  *
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
17  * PURPOSE.
18  */
19
20 /**
21  * @file
22  * @brief       Statistic events.
23  * @author      Sebastian Hack
24  * @date        17.06.2007
25  * @version     $Id$
26  */
27
28 #ifndef FIRM_STATEVENT_H
29 #define FIRM_STATEVENT_H
30
31 #ifdef DISABLE_STATEV
32
33 #define stat_ev_enabled                          0
34 #define stat_ev_dbl(name, val)                   ((void)0)
35 #define stat_ev_int(name, val)                   ((void)0)
36 #define stat_ev(name)                            ((void)0)
37 #define stat_ev_emit(name, value)                ((void)0)
38
39 #define stat_ev_cnt_decl(var)                    ((void)0)
40 #define stat_ev_cnt_inc(var)                     ((void)0)
41 #define stat_ev_cnt_done(name, var)              ((void)0)
42 #define stat_ev_tim_push()                       ((void)0)
43 #define stat_ev_tim_pop(name)                    ((void)0)
44
45 #define stat_ev_ctx_push(key)                    ((void)0)
46 #define stat_ev_ctx_push_str(key, str)           ((void)0)
47 #define stat_ev_ctx_push_fmt(key, fmt, value)    ((void)0)
48 #define stat_ev_ctx_push_fobj(key, firm_object)  ((void)0)
49 #define stat_ev_ctx_pop(key)                     ((void)0)
50 #define stat_ev_flush()                          ((void)0)
51
52 #else
53
54 #include <stdio.h>
55 #include "stat_timing.h"
56
57 extern void           stat_ev_printf(char ev_type, const char *key, const char *fmt, ...);
58
59 extern int            stat_ev_enabled;
60 extern int            stat_ev_timer_sp;
61 extern timing_ticks_t stat_ev_timer_elapsed[];
62 extern timing_ticks_t stat_ev_timer_start[];
63
64 static inline void stat_ev_tim_push(void) {
65         timing_ticks_t temp;
66         int sp = stat_ev_timer_sp++;
67         timing_ticks(temp);
68         if (sp == 0) {
69                 timing_enter_max_prio();
70         } else {
71                 timing_ticks_sub(temp, stat_ev_timer_start[sp - 1]);
72                 timing_ticks_add(stat_ev_timer_elapsed[sp - 1], temp);
73         }
74         timing_ticks_init(stat_ev_timer_elapsed[sp]);
75         timing_ticks(stat_ev_timer_start[sp]);
76 }
77
78 static inline void stat_ev_tim_pop(const char *name) {
79         int sp;
80         timing_ticks_t temp;
81         timing_ticks(temp);
82         sp = --stat_ev_timer_sp;
83         timing_ticks_sub(temp, stat_ev_timer_start[sp]);
84         timing_ticks_add(stat_ev_timer_elapsed[sp], temp);
85         if (name != NULL && stat_ev_enabled)
86                 stat_ev_printf('E', name, "%g", timing_ticks_dbl(stat_ev_timer_elapsed[sp]));
87         if (sp == 0) {
88                 timing_leave_max_prio();
89         } else {
90                 timing_ticks(stat_ev_timer_start[sp - 1]);
91         }
92 }
93
94 #define stat_ev_ctx_push_fmt(key, fmt, value) \
95         do { \
96                 if (stat_ev_enabled) { \
97                         stat_ev_tim_push(); \
98                         stat_ev_printf('P', key, fmt, (value)); \
99                         stat_ev_tim_pop(NULL); \
100                 } \
101         } while(0)
102
103 #define stat_ev_ctx_pop(key) \
104         do { \
105                 if (stat_ev_enabled) { \
106                         stat_ev_tim_push(); \
107                         stat_ev_printf('O', key, NULL); \
108                         stat_ev_tim_pop(NULL); \
109                 } \
110         } while(0)
111
112 #define stat_ev_emit(name, value) \
113         do { \
114                 if (stat_ev_enabled) { \
115                         stat_ev_tim_push(); \
116                         stat_ev_printf('E', name, "%g", (double) (value)); \
117                         stat_ev_tim_pop(NULL); \
118                 } \
119         } while(0)
120
121 #define stat_ev_ctx_push_fobj(key, firm_object) stat_ev_ctx_push_fmt((key), "%+F", (firm_object))
122 #define stat_ev_ctx_push_str(key, str)          stat_ev_ctx_push_fmt((key), "%s", (str))
123 #define stat_ev_ctx_push(key)                   stat_ev_ctx_push_fmt((key), "X", NULL)
124
125 #define stat_ev_dbl(name, val)      stat_ev_emit((name), (val))
126 #define stat_ev_int(name, val)      stat_ev_dbl((name), (double) (val))
127 #define stat_ev(name)               stat_ev_emit((name), 0.0)
128
129 #define stat_ev_cnt_decl(var)       int stat_ev_cnt_var_ ## var = 0
130 #define stat_ev_cnt_inc(var)        do { ++stat_ev_cnt_var_ ## var; } while(0)
131 #define stat_ev_cnt_done(var, name) stat_ev_emit((name), stat_ev_cnt_var_ ## var)
132
133 /**
134  * Initialize the stat ev machinery.
135  * @param filename_prefix  The prefix of the filename (.ev or .ev.gz will be appended).
136  * @param filter           All pushes, pops and events will be filtered by this.
137  *                         If we have regex support, you can give an extended regex here.
138  *                         If not, each key will be matched against this.
139  *                         Matched means, we look if the key starts with @p filter.
140  *                         If NULL is given, each key passes, ie thefilter is always TRUE.
141  */
142 void stat_ev_begin(const char *filename_prefix, const char *filter);
143 void stat_ev_end(void);
144
145 #define stat_ev_flush()             do { if (stat_ev_enabled) fflush(stat_ev_enabled); } while(0)
146
147 #endif
148
149 #endif