merge kaps
[libfirm] / ir / stat / counter.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   Statistics for Firm. Counter implementation.
23  * @author  Michael Beck
24  * @version $Id$
25  */
26 #ifndef FIRM_STAT_COUNTER_H
27 #define FIRM_STAT_COUNTER_H
28
29 #include <string.h>
30 #include <limits.h>
31
32 /*
33  * 32 bit should be enough for most cases
34  */
35 #ifndef STAT_CNT_NUM
36 #define STAT_CNT_NUM 1
37 #endif
38
39 typedef struct counter_t {
40         unsigned cnt[STAT_CNT_NUM];
41 } counter_t;
42
43 /** initializes a counter with zero */
44 #define ZERO_CNT { { 0 } }
45
46 /**
47  * increase a counter
48  */
49 static inline void cnt_inc(counter_t *cnt)
50 {
51         int i;
52
53         for (i = 0; i < STAT_CNT_NUM; ++i) {
54                 if (++cnt->cnt[i])
55                         break;
56         }
57 }
58
59 /**
60  * decrease a counter
61  */
62 static inline void cnt_dec(counter_t *cnt)
63 {
64         int i;
65
66         for (i = 0; i < STAT_CNT_NUM; ++i) {
67                 if (--cnt->cnt[i] != (unsigned) -1)
68                         break;
69         }
70 }
71
72 /**
73  * set a counter to zero
74  */
75 static inline void cnt_clr(counter_t *cnt)
76 {
77         memset(cnt->cnt, 0, sizeof(cnt->cnt));
78 }
79
80 /**
81  * add a counter to another
82  */
83 static inline void cnt_add(counter_t *dst, const counter_t *src)
84 {
85         int i, carry = 0;
86
87         for (i = 0; i < STAT_CNT_NUM; ++i) {
88                 unsigned x = dst->cnt[i];
89                 unsigned y = src->cnt[i];
90                 unsigned a = x + y + carry;
91
92                 carry = (int)((x & y) | ((x | y) & ~a)) < 0 ? 1 : 0;
93
94                 dst->cnt[i] = a;
95         }
96 }
97
98 /**
99  * add an (positive) integer to an counter
100  */
101 static inline void cnt_add_i(counter_t *dst, int src)
102 {
103         int i;
104         unsigned carry = src;
105
106         for (i = 0; i < STAT_CNT_NUM; ++i) {
107                 unsigned a = dst->cnt[i] + carry;
108
109                 carry = a < dst->cnt[i];
110
111                 dst->cnt[i] = a;
112
113                 if (! carry)
114                         break;
115         }
116 }
117
118 /**
119  * compare two counter
120  */
121 static inline int cnt_cmp(const counter_t *a, const counter_t *b)
122 {
123         int i;
124         unsigned va = 0;
125         unsigned vb = 0;
126
127         for (i = STAT_CNT_NUM - 1 ; i >= 0; --i) {
128                 va = a->cnt[i];
129                 vb = b->cnt[i];
130
131                 if (va != vb)
132                         break;
133         }
134
135         if (va != vb)
136                 return va < vb ? -1 : 1;
137         return 0;
138 }
139
140 /**
141  * convert a counter into a double
142  */
143 static inline double cnt_to_dbl(const counter_t *a)
144 {
145         int i;
146         double res = 0.0, scale = 1.0, tmp;
147
148         i = (1 << (sizeof(a->cnt[0]) * 4));
149         tmp = ((double)i) * ((double)i);
150
151         for (i = 0; i < STAT_CNT_NUM; ++i) {
152                 res += scale * (double)a->cnt[i];
153
154                 scale *= tmp;
155         }
156         return res;
157 }
158
159 /**
160  * convert a counter into an unsigned
161  */
162 static inline unsigned cnt_to_uint(const counter_t *a)
163 {
164         int i;
165
166         for (i = 1; i < STAT_CNT_NUM; ++i)
167                 if (a->cnt[i])
168                         return UINT_MAX;
169
170         return a->cnt[0];
171 }
172
173 /**
174  * check, if a counter is equal to an unsigned
175  */
176 static inline int cnt_eq(const counter_t *a, unsigned value)
177 {
178         int i;
179
180         for (i = 1; i < STAT_CNT_NUM; ++i)
181                 if (a->cnt[i])
182                         return 0;
183
184         return a->cnt[0] == value;
185 }
186
187 /**
188  * check, if a counter as greater than an unsigned
189  */
190 static inline int cnt_gt(const counter_t *a, unsigned value)
191 {
192         int i;
193
194         for (i = 1; i < STAT_CNT_NUM; ++i)
195                 if (a->cnt[i])
196                         return 1;
197
198         return a->cnt[0] > value;
199 }
200
201 #endif /* FIRM_STAT_COUNTER_H */