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