5cf7d685627c4769eca72fe3d37f8d523cfceb23
[libfirm] / ir / stat / counter.h
1 /*
2  * Project:     libFIRM
3  * File name:   ir/ir/counter.h
4  * Purpose:     Statistics for Firm. Counter implementation.
5  * Author:      Michael Beck
6  * Created:
7  * CVS-ID:      $Id$
8  * Copyright:   (c) 2004 Universität Karlsruhe
9  * Licence:     This file protected by GPL -  GNU GENERAL PUBLIC LICENSE.
10  */
11 #ifndef _COUNTER_H_
12 #define _COUNTER_H_
13
14 #include <string.h>
15
16 /*
17  * 32 bit should be enough for most cases
18  */
19 #ifndef STAT_CNT_NUM
20 #define STAT_CNT_NUM 1
21 #endif
22
23 typedef struct _counter_t {
24   unsigned cnt[STAT_CNT_NUM];
25 } counter_t;
26
27 static const counter_t _cnt_0 = { { 0 } };
28 static const counter_t _cnt_1 = { { 1 } };
29
30 /**
31  * returns a counter representing value 0
32  */
33 static INLINE const counter_t *cnt_get_0()
34 {
35   return &_cnt_0;
36 }
37
38 /**
39  * returns a counter representing value 1
40  */
41 static INLINE const counter_t *cnt_get_1()
42 {
43   return &_cnt_1;
44 }
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] != -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, vb;
125
126   for (i = STAT_CNT_NUM - 1 ; i >= 0; --i) {
127     va = a->cnt[i];
128     vb = b->cnt[i];
129
130     if (va != vb)
131       break;
132   }
133
134   if (va != vb)
135     return va < vb ? -1 : 1;
136   return 0;
137 }
138
139 /**
140  * convert a counter into a double
141  */
142 static INLINE double cnt_to_dbl(const counter_t *a)
143 {
144   int i;
145   double res = 0.0, scale = 1.0, tmp;
146
147   i = (1 << (sizeof(a->cnt[i]) * 4));
148   tmp = ((double)i) * ((double)i);
149
150   for (i = 0; i < STAT_CNT_NUM; ++i) {
151     res += scale * (double)a->cnt[i];
152
153     scale *= tmp;
154   }
155   return res;
156 }
157
158 /**
159  * check, if a counter is equal to an unsigned
160  */
161 static INLINE int cnt_eq(const counter_t *a, unsigned value)
162 {
163   int i;
164
165   for (i = 1; i < STAT_CNT_NUM; ++i)
166     if (a->cnt[i])
167       return 0;
168
169   return a->cnt[0] == value;
170 }
171
172 /**
173  * check, if a counter as greater than an unsigned
174  */
175 static INLINE int cnt_gt(const counter_t *a, unsigned value)
176 {
177   int i;
178
179   for (i = 1; i < STAT_CNT_NUM; ++i)
180     if (a->cnt[i])
181       return 1;
182
183   return a->cnt[0] > value;
184 }
185
186
187 #endif /* _COUNTER_H_ */