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