rename type entity into ir_entity
[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 unsigned
142  */
143 static INLINE unsigned cnt_to_uint(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 #endif /* _COUNTER_H_ */