/*
- * Project: libFIRM
- * File name: ir/ir/counter.h
- * Purpose: Statistics for Firm. Counter implementation.
- * Author: Michael Beck
- * Created:
- * CVS-ID: $Id$
- * Copyright: (c) 2004 Universität Karlsruhe
- * Licence: This file protected by GPL - GNU GENERAL PUBLIC LICENSE.
+ * Copyright (C) 1995-2008 University of Karlsruhe. All right reserved.
+ *
+ * This file is part of libFirm.
+ *
+ * This file may be distributed and/or modified under the terms of the
+ * GNU General Public License version 2 as published by the Free Software
+ * Foundation and appearing in the file LICENSE.GPL included in the
+ * packaging of this file.
+ *
+ * Licensees holding valid libFirm Professional Edition licenses may use
+ * this file in accordance with the libFirm Commercial License.
+ * Agreement provided with the Software.
+ *
+ * This file is provided AS IS with NO WARRANTY OF ANY KIND, INCLUDING THE
+ * WARRANTY OF DESIGN, MERCHANTABILITY AND FITNESS FOR A PARTICULAR
+ * PURPOSE.
*/
-#ifndef _COUNTER_H_
-#define _COUNTER_H_
+
+/**
+ * @file
+ * @brief Statistics for Firm. Counter implementation.
+ * @author Michael Beck
+ * @version $Id$
+ */
+#ifndef FIRM_STAT_COUNTER_H
+#define FIRM_STAT_COUNTER_H
#include <string.h>
+#include <limits.h>
/*
- * 32 bit should be enough for now
+ * 32 bit should be enough for most cases
*/
+#ifndef STAT_CNT_NUM
#define STAT_CNT_NUM 1
+#endif
typedef struct _counter_t {
- unsigned cnt[STAT_CNT_NUM];
+ unsigned cnt[STAT_CNT_NUM];
} counter_t;
+/** initializes a counter with zero */
+#define ZERO_CNT { { 0 } }
+
/**
* increase a counter
*/
-static INLINE void cnt_inc(counter_t *cnt)
+static inline void cnt_inc(counter_t *cnt)
{
- int i;
+ int i;
- for (i = 0; i < STAT_CNT_NUM; ++i) {
- if (++cnt->cnt[i])
- break;
- }
+ for (i = 0; i < STAT_CNT_NUM; ++i) {
+ if (++cnt->cnt[i])
+ break;
+ }
}
/**
- * decreace a counter
+ * decrease a counter
*/
-static INLINE void cnt_dec(counter_t *cnt)
+static inline void cnt_dec(counter_t *cnt)
{
- int i;
+ int i;
- for (i = 0; i < STAT_CNT_NUM; ++i) {
- if (--cnt->cnt[i] != -1)
- break;
- }
+ for (i = 0; i < STAT_CNT_NUM; ++i) {
+ if (--cnt->cnt[i] != (unsigned) -1)
+ break;
+ }
}
/**
* set a counter to zero
*/
-static INLINE void cnt_clr(counter_t *cnt)
+static inline void cnt_clr(counter_t *cnt)
{
- memset(cnt->cnt, 0, sizeof(cnt->cnt));
+ memset(cnt->cnt, 0, sizeof(cnt->cnt));
}
/**
* add a counter to another
*/
-static INLINE void cnt_add(counter_t *dst, const counter_t *src)
+static inline void cnt_add(counter_t *dst, const counter_t *src)
{
- int i, carry = 0;
+ int i, carry = 0;
- for (i = 0; i < STAT_CNT_NUM; ++i) {
- unsigned a = dst->cnt[i] + src->cnt[i] + carry;
+ for (i = 0; i < STAT_CNT_NUM; ++i) {
+ unsigned x = dst->cnt[i];
+ unsigned y = src->cnt[i];
+ unsigned a = x + y + carry;
- if (carry)
- carry = a <= dst->cnt[i];
- else
- carry = a < dst->cnt[i];
+ carry = (int)((x & y) | ((x | y) & ~a)) < 0 ? 1 : 0;
- dst->cnt[i] = a;
-
- if (! carry)
- break;
- }
+ dst->cnt[i] = a;
+ }
}
/**
- * add an integer to an counter
+ * add an (positive) integer to an counter
*/
-static INLINE void cnt_add_i(counter_t *dst, int src)
+static inline void cnt_add_i(counter_t *dst, int src)
{
- int i;
- unsigned a = dst->cnt[0] + src;
- unsigned carry = a < dst->cnt[0];
-
- dst->cnt[0] = a;
- if (! carry)
- return;
+ int i;
+ unsigned carry = src;
- for (i = 1; i < STAT_CNT_NUM; ++i) {
- unsigned a = dst->cnt[i] + carry;
+ for (i = 0; i < STAT_CNT_NUM; ++i) {
+ unsigned a = dst->cnt[i] + carry;
- carry = a < dst->cnt[i];
+ carry = a < dst->cnt[i];
- dst->cnt[i] = a;
+ dst->cnt[i] = a;
- if (! carry)
- break;
- }
+ if (! carry)
+ break;
+ }
}
/**
* compare two counter
*/
-static INLINE int cnt_cmp(const counter_t *a, const counter_t *b)
+static inline int cnt_cmp(const counter_t *a, const counter_t *b)
{
- int i;
- unsigned va, vb;
+ int i;
+ unsigned va = 0;
+ unsigned vb = 0;
- for (i = STAT_CNT_NUM - 1 ; i >= 0; --i) {
- va = a->cnt[i];
- vb = b->cnt[i];
+ for (i = STAT_CNT_NUM - 1 ; i >= 0; --i) {
+ va = a->cnt[i];
+ vb = b->cnt[i];
- if (va != vb)
- break;
- }
+ if (va != vb)
+ break;
+ }
- if (va != vb)
- return va < vb ? -1 : 1;
- return 0;
+ if (va != vb)
+ return va < vb ? -1 : 1;
+ return 0;
}
/**
* convert a counter into a double
*/
-static INLINE double cnt_to_dbl(const counter_t *a)
+static inline double cnt_to_dbl(const counter_t *a)
{
- int i;
- double res = 0.0, scale = 1.0, tmp;
+ int i;
+ double res = 0.0, scale = 1.0, tmp;
+
+ i = (1 << (sizeof(a->cnt[0]) * 4));
+ tmp = ((double)i) * ((double)i);
- i = (1 << (sizeof(a->cnt[i]) * 4));
- tmp = ((double)i) * ((double)i);
+ for (i = 0; i < STAT_CNT_NUM; ++i) {
+ res += scale * (double)a->cnt[i];
- for (i = 0; i < STAT_CNT_NUM; ++i) {
- res += scale * (double)a->cnt[i];
+ scale *= tmp;
+ }
+ return res;
+}
- scale *= tmp;
- }
- return res;
+/**
+ * convert a counter into an unsigned
+ */
+static inline unsigned cnt_to_uint(const counter_t *a)
+{
+ int i;
+
+ for (i = 1; i < STAT_CNT_NUM; ++i)
+ if (a->cnt[i])
+ return UINT_MAX;
+
+ return a->cnt[0];
}
/**
* check, if a counter is equal to an unsigned
*/
-static INLINE int cnt_eq(const counter_t *a, unsigned value)
+static inline int cnt_eq(const counter_t *a, unsigned value)
{
- int i;
+ int i;
- for (i = 1; i < STAT_CNT_NUM; ++i)
- if (a->cnt[i])
- return 0;
+ for (i = 1; i < STAT_CNT_NUM; ++i)
+ if (a->cnt[i])
+ return 0;
- return a->cnt[0] == value;
+ return a->cnt[0] == value;
}
/**
* check, if a counter as greater than an unsigned
*/
-static INLINE int cnt_gt(const counter_t *a, unsigned value)
+static inline int cnt_gt(const counter_t *a, unsigned value)
{
- int i;
+ int i;
- for (i = 1; i < STAT_CNT_NUM; ++i)
- if (a->cnt[i])
- return 1;
+ for (i = 1; i < STAT_CNT_NUM; ++i)
+ if (a->cnt[i])
+ return 1;
- return a->cnt[0] > value;
+ return a->cnt[0] > value;
}
-
-#endif /* _COUNTER_H_ */
+#endif /* FIRM_STAT_COUNTER_H */