cfaf266a7665cb0b5664fd7dac288df529d24930
[libfirm] / ir / stat / counter.h
1 /*
2  * Copyright (C) 1995-2007 University of Karlsruhe.  All right reserved.
3  *
4  * This file is part of libFirm.
5  *
6  * This file may be distributed and/or modified under the terms of the
7  * GNU General Public License version 2 as published by the Free Software
8  * Foundation and appearing in the file LICENSE.GPL included in the
9  * packaging of this file.
10  *
11  * Licensees holding valid libFirm Professional Edition licenses may use
12  * this file in accordance with the libFirm Commercial License.
13  * Agreement provided with the Software.
14  *
15  * This file is provided AS IS with NO WARRANTY OF ANY KIND, INCLUDING THE
16  * WARRANTY OF DESIGN, MERCHANTABILITY AND FITNESS FOR A PARTICULAR
17  * PURPOSE.
18  */
19
20 /*
21  * Project:     libFIRM
22  * File name:   ir/ir/counter.h
23  * Purpose:     Statistics for Firm. Counter implementation.
24  * Author:      Michael Beck
25  * Created:
26  * CVS-ID:      $Id$
27  * Copyright:   (c) 2004 Universität Karlsruhe
28  */
29 #ifndef _COUNTER_H_
30 #define _COUNTER_H_
31
32 #include <string.h>
33 #include <limits.h>
34
35 /*
36  * 32 bit should be enough for most cases
37  */
38 #ifndef STAT_CNT_NUM
39 #define STAT_CNT_NUM 1
40 #endif
41
42 typedef struct _counter_t {
43         unsigned cnt[STAT_CNT_NUM];
44 } counter_t;
45
46 /** initializes a counter with zero */
47 #define ZERO_CNT { { 0 } }
48
49 /**
50  * increase a counter
51  */
52 static INLINE void cnt_inc(counter_t *cnt)
53 {
54         int i;
55
56         for (i = 0; i < STAT_CNT_NUM; ++i) {
57                 if (++cnt->cnt[i])
58                         break;
59         }
60 }
61
62 /**
63  * decrease a counter
64  */
65 static INLINE void cnt_dec(counter_t *cnt)
66 {
67         int i;
68
69         for (i = 0; i < STAT_CNT_NUM; ++i) {
70                 if (--cnt->cnt[i] != -1)
71                         break;
72         }
73 }
74
75 /**
76  * set a counter to zero
77  */
78 static INLINE void cnt_clr(counter_t *cnt)
79 {
80         memset(cnt->cnt, 0, sizeof(cnt->cnt));
81 }
82
83 /**
84  * add a counter to another
85  */
86 static INLINE void cnt_add(counter_t *dst, const counter_t *src)
87 {
88         int i, carry = 0;
89
90         for (i = 0; i < STAT_CNT_NUM; ++i) {
91                 unsigned x = dst->cnt[i];
92                 unsigned y = src->cnt[i];
93                 unsigned a = x + y + carry;
94
95                 carry = (int)((x & y) | ((x | y) & ~a)) < 0 ? 1 : 0;
96
97                 dst->cnt[i] = a;
98         }
99 }
100
101 /**
102  * add an (positive) integer to an counter
103  */
104 static INLINE void cnt_add_i(counter_t *dst, int src)
105 {
106         int i;
107         unsigned carry = src;
108
109         for (i = 0; i < STAT_CNT_NUM; ++i) {
110                 unsigned a = dst->cnt[i] + carry;
111
112                 carry = a < dst->cnt[i];
113
114                 dst->cnt[i] = a;
115
116                 if (! carry)
117                         break;
118         }
119 }
120
121 /**
122  * compare two counter
123  */
124 static INLINE int cnt_cmp(const counter_t *a, const counter_t *b)
125 {
126         int i;
127         unsigned va, vb;
128
129         for (i = STAT_CNT_NUM - 1 ; i >= 0; --i) {
130                 va = a->cnt[i];
131                 vb = b->cnt[i];
132
133                 if (va != vb)
134                         break;
135         }
136
137         if (va != vb)
138                 return va < vb ? -1 : 1;
139         return 0;
140 }
141
142 /**
143  * convert a counter into a double
144  */
145 static INLINE double cnt_to_dbl(const counter_t *a)
146 {
147         int i;
148         double res = 0.0, scale = 1.0, tmp;
149
150         i = (1 << (sizeof(a->cnt[0]) * 4));
151         tmp = ((double)i) * ((double)i);
152
153         for (i = 0; i < STAT_CNT_NUM; ++i) {
154                 res += scale * (double)a->cnt[i];
155
156                 scale *= tmp;
157         }
158         return res;
159 }
160
161 /**
162  * convert a counter into an unsigned
163  */
164 static INLINE unsigned cnt_to_uint(const counter_t *a)
165 {
166         int i;
167
168         for (i = 1; i < STAT_CNT_NUM; ++i)
169                 if (a->cnt[i])
170                         return UINT_MAX;
171
172         return a->cnt[0];
173 }
174
175 /**
176  * check, if a counter is equal to an unsigned
177  */
178 static INLINE int cnt_eq(const counter_t *a, unsigned value)
179 {
180         int i;
181
182         for (i = 1; i < STAT_CNT_NUM; ++i)
183                 if (a->cnt[i])
184                         return 0;
185
186         return a->cnt[0] == value;
187 }
188
189 /**
190  * check, if a counter as greater than an unsigned
191  */
192 static INLINE int cnt_gt(const counter_t *a, unsigned value)
193 {
194         int i;
195
196         for (i = 1; i < STAT_CNT_NUM; ++i)
197                 if (a->cnt[i])
198                         return 1;
199
200         return a->cnt[0] > value;
201 }
202
203 #endif /* _COUNTER_H_ */