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