bearch: Disallow passing Projs to get_irn_ops().
[libfirm] / ir / stat / counter.h
index f6074ca..2b60638 100644 (file)
 /*
- * 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.
+ * This file is part of libFirm.
+ * Copyright (C) 2012 University of Karlsruhe.
  */
-#ifndef _COUNTER_H_
-#define _COUNTER_H_
+
+/**
+ * @file
+ * @brief   Statistics for Firm. Counter implementation.
+ * @author  Michael Beck
+ */
+#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];
+typedef struct counter_t {
+       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;
+
+       i = (1 << (sizeof(a->cnt[0]) * 4));
+       tmp = ((double)i) * ((double)i);
+
+       for (i = 0; i < STAT_CNT_NUM; ++i) {
+               res += scale * (double)a->cnt[i];
+
+               scale *= tmp;
+       }
+       return res;
+}
+
+/**
+ * convert a counter into an unsigned
+ */
+static inline unsigned cnt_to_uint(const counter_t *a)
 {
-  int i;
-  double res = 0.0, scale = 1.0, tmp;
+       int i;
 
-  i = (1 << (sizeof(a->cnt[i]) * 4));
-  tmp = ((double)i) * ((double)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)
+{
+       int i;
+
+       for (i = 1; i < STAT_CNT_NUM; ++i)
+               if (a->cnt[i])
+                       return 0;
+
+       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)
+{
+       int i;
 
-  for (i = 0; i < STAT_CNT_NUM; ++i) {
-    res += scale * (double)a->cnt[i];
+       for (i = 1; i < STAT_CNT_NUM; ++i)
+               if (a->cnt[i])
+                       return 1;
 
-    scale *= tmp;
-  }
-  return res;
+       return a->cnt[0] > value;
 }
 
-#endif /* _COUNTER_H_ */
+#endif /* FIRM_STAT_COUNTER_H */