--- /dev/null
+/*
+ * Copyright (C) 1995-2007 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.
+ */
+
+/**
+ * @file
+ * @brief macros for alignment.
+ * @author Markus Armbruster
+ * @version $Id$
+ */
+#ifndef FIRM_ADT_ALIGN_H
+#define FIRM_ADT_ALIGN_H
+
+#include <stddef.h>
+
+/** A size handled efficiently by malloc(), at least 1K. */
+#define PREF_MALLOC_SIZE 2048
+
+
+/** A wrapper around GNU C's __attribute__ */
+
+/* According to the documentation, the attributes we are interested in
+ work with 2.5, but we encountered trouble before 2.7. */
+#if defined (__GNUC__) && __GNUC__ >= 2 && __GNUC_MINOR__ >= 7
+# define HAVE_ATTRIBUTE 1
+# define ATTRIBUTE(attrs) __attribute__ (attrs)
+#else
+# define ATTRIBUTE(attrs)
+#endif
+
+
+/* Alignment */
+
+/** A type that has most constrained alignment. */
+typedef union {
+ long double d;
+ void *p;
+ long l;
+} aligned_type ATTRIBUTE ((aligned));
+
+/** Inquiring about the alignment of a type. */
+#ifdef __GNUC__
+# define ALIGNOF(type) __alignof__ (type)
+#else
+# define ALIGNOF(type) offsetof (struct { char c; type d; }, d)
+#endif
+
+/** Maximal alignment required for any type. */
+#define MAX_ALIGN ALIGNOF (aligned_type)
+
+#endif
--- /dev/null
+/*
+ * Copyright (C) 1995-2007 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.
+ */
+
+/**
+ * @file
+ * @brief Dynamic and flexible arrays for C.
+ * @author Markus Armbruster
+ * @version $Id$
+ */
+#ifndef FIRM_ADT_ARRAY_H
+#define FIRM_ADT_ARRAY_H
+
+#include <assert.h>
+#include <stddef.h>
+
+#include "obst.h"
+#include "fourcc.h"
+#include "align.h"
+#include "xmalloc.h"
+
+#define ARR_D_MAGIC FOURCC('A','R','R','D')
+#define ARR_A_MAGIC FOURCC('A','R','R','A')
+#define ARR_F_MAGIC FOURCC('A','R','R','F')
+
+/**
+ * Creates a flexible array.
+ *
+ * @param type The element type of the new array.
+ * @param nelts a size_t expression evaluating to the number of elements
+ *
+ * This macro creates a flexible array of a given type at runtime.
+ * The size of the array can be changed later.
+ *
+ * @return A pointer to the flexible array (can be used as a pointer to the
+ * first element of this array).
+ */
+#define NEW_ARR_F(type, nelts) \
+ ((type *)_new_arr_f ((nelts), sizeof(type) * (nelts)))
+
+/**
+ * Creates a new flexible array with the same number of elements as a
+ * given one.
+ *
+ * @param type The element type of the new array.
+ * @param arr An array from which the number of elements will be taken
+ *
+ * This macro creates a flexible array of a given type at runtime.
+ * The size of the array can be changed later.
+ *
+ * @return A pointer to the flexible array (can be used as a pointer to the
+ * first element of this array).
+ */
+#define CLONE_ARR_F(type, arr) \
+ NEW_ARR_F (type, ARR_LEN ((arr)))
+
+/**
+ * Duplicates an array and returns the new flexible one.
+ *
+ * @param type The element type of the new array.
+ * @param arr An array from which the elements will be duplicated
+ *
+ * This macro creates a flexible array of a given type at runtime.
+ * The size of the array can be changed later.
+ *
+ * @return A pointer to the flexible array (can be used as a pointer to the
+ * first element of this array).
+ */
+#define DUP_ARR_F(type, arr) \
+ memcpy (CLONE_ARR_F (type, (arr)), (arr), sizeof(type) * ARR_LEN((arr)))
+
+/**
+ * Delete a flexible array.
+ *
+ * @param arr The flexible array.
+ */
+#define DEL_ARR_F(arr) (_del_arr_f ((arr)))
+
+/**
+ * Creates a dynamic array on an obstack.
+ *
+ * @param type The element type of the new array.
+ * @param obstack A struct obstack * were the data will be allocated
+ * @param nelts A size_t expression evaluating to the number of elements
+ *
+ * This macro creates a dynamic array of a given type at runtime.
+ * The size of the array cannot be changed later.
+ *
+ * @return A pointer to the dynamic array (can be used as a pointer to the
+ * first element of this array).
+ */
+#define NEW_ARR_D(type, obstack, nelts) \
+ ( nelts \
+ ? (type *)_new_arr_d ((obstack), (nelts), sizeof(type) * (nelts)) \
+ : (type *)arr_mt_descr.v.elts)
+
+/**
+ * Creates a new dynamic array with the same number of elements as a
+ * given one.
+ *
+ * @param type The element type of the new array.
+ * @param obstack An struct obstack * were the data will be allocated
+ * @param arr An array from which the number of elements will be taken
+ *
+ * This macro creates a dynamic array of a given type at runtime.
+ * The size of the array cannot be changed later.
+ *
+ * @return A pointer to the dynamic array (can be used as a pointer to the
+ * first element of this array).
+ */
+#define CLONE_ARR_D(type, obstack, arr) \
+ NEW_ARR_D (type, (obstack), ARR_LEN ((arr)))
+
+/**
+ * Duplicates an array and returns the new dynamic one.
+ *
+ * @param type The element type of the new array.
+ * @param obstack An struct obstack * were the data will be allocated
+ * @param arr An array from which the elements will be duplicated
+ *
+ * This macro creates a dynamic array of a given type at runtime.
+ * The size of the array cannot be changed later.
+ *
+ * @return A pointer to the dynamic array (can be used as a pointer to the
+ * first element of this array).
+ */
+#define DUP_ARR_D(type, obstack, arr) \
+ memcpy (CLONE_ARR_D (type, (obstack), (arr)), (arr), sizeof(type) * ARR_LEN ((arr)))
+
+/**
+ * Create an automatic array which will be deleted at return from function.
+ * Beware, the data will be allocated on the function stack!
+ *
+ * @param type The element type of the new array.
+ * @param var A lvalue of type (type *) which will hold the new array.
+ * @param n number of elements in this array.
+ *
+ * This macro creates a dynamic array on the functions stack of a given type at runtime.
+ * The size of the array cannot be changed later.
+ */
+#define NEW_ARR_A(type, var, n) \
+ do { \
+ int _nelts = (n); \
+ assert (_nelts >= 0); \
+ (var) = (void *)((_arr_descr *)alloca (_ARR_ELTS_OFFS + sizeof(type) * _nelts))->v.elts; \
+ _ARR_SET_DBGINF (_ARR_DESCR ((var)), ARR_A_MAGIC, sizeof (type)); \
+ (void)(_ARR_DESCR ((var))->nelts = _nelts); \
+ } while (0)
+
+/**
+ * Creates a new automatic array with the same number of elements as a
+ * given one.
+ *
+ * @param type The element type of the new array.
+ * @param var A lvalue of type (type *) which will hold the new array.
+ * @param arr An array from which the elements will be duplicated
+ *
+ * This macro creates a dynamic array of a given type at runtime.
+ * The size of the array cannot be changed later.
+ *
+ * @return A pointer to the dynamic array (can be used as a pointer to the
+ * first element of this array).
+ */
+#define CLONE_ARR_A(type, var, arr) \
+ NEW_ARR_A (type, (var), ARR_LEN ((arr)))
+
+/**
+ * Duplicates an array and returns a new automatic one.
+ *
+ * @param type The element type of the new array.
+ * @param var A lvalue of type (type *) which will hold the new array.
+ * @param arr An array from with the number of elements will be taken
+ *
+ * This macro creates a dynamic array of a given type at runtime.
+ * The size of the array cannot be changed later.
+ *
+ * @return A pointer to the dynamic array (can be used as a pointer to the
+ * first element of this array).
+ */
+#define DUP_ARR_A(type, var, arr) \
+ do { CLONE_ARR_A(type, (var), (arr)); \
+ memcpy ((var), (arr), sizeof (type) * ARR_LEN ((arr))); } \
+ while (0)
+
+/**
+ * Declare an initialized (zero'ed) array of fixed size.
+ * This macro should be used at file scope only.
+ *
+ * @param type The element type of the new array.
+ * @param var A lvalue of type (type *) which will hold the new array.
+ * @param _nelts Number of elements in this new array.
+ */
+#define DECL_ARR_S(type, var, _nelts) \
+ ARR_STRUCT(type, (_nelts) ? (_nelts) : 1) _##var; \
+ type *var = (_ARR_SET_DBGINF (&_##var, ARR_A_MAGIC, sizeof (type)), \
+ _##var.nelts = _nelts, \
+ _##var.v.elts)
+
+/**
+ * Returns the length of an array
+ *
+ * @param arr a flexible, dynamic, automatic or static array.
+ */
+#define ARR_LEN(arr) (ARR_VRFY ((arr)), _ARR_DESCR((arr))->nelts)
+
+/**
+ * Resize a flexible array, allocate more data if needed but do NOT
+ * reduce.
+ *
+ * @param type The element type of the array.
+ * @param arr The array, which must be an lvalue.
+ * @param n The new size of the array.
+ *
+ * @remark This macro may change arr, so update all references!
+ */
+#define ARR_RESIZE(type, arr, n) \
+ ((arr) = _arr_resize ((arr), (n), sizeof(type)))
+
+/**
+ * Resize a flexible array, always reallocate data.
+ *
+ * @param type The element type of the array.
+ * @param arr The array, which must be an lvalue.
+ * @param n The new size of the array.
+ *
+ * @remark This macro may change arr, so update all references!
+ */
+#define ARR_SETLEN(type, arr, n) \
+ ((arr) = _arr_setlen ((arr), (n), sizeof(type) * (n)))
+
+/** Set a length smaller than the current length of the array. Do not
+ * resize. len must be <= ARR_LEN(arr). */
+#define ARR_SHRINKLEN(arr,len) \
+ (ARR_VRFY ((arr)), assert(_ARR_DESCR((arr))->nelts >= len), \
+ _ARR_DESCR((arr))->nelts = len)
+
+/**
+ * Resize a flexible array by growing it by delta elements.
+ *
+ * @param type The element type of the array.
+ * @param arr The array, which must be an lvalue.
+ * @param delta The delta number of elements.
+ *
+ * @remark This macro may change arr, so update all references!
+ */
+#define ARR_EXTEND(type, arr, delta) \
+ ARR_RESIZE (type, (arr), ARR_LEN ((arr)) + (delta))
+
+/**
+ * Resize a flexible array to hold n elements only if it is currently shorter
+ * than n.
+ *
+ * @param type The element type of the array.
+ * @param arr The array, which must be an lvalue.
+ * @param n The new size of the array.
+ *
+ * @remark This macro may change arr, so update all references!
+ */
+#define ARR_EXTO(type, arr, n) \
+ ((n) >= ARR_LEN ((arr)) ? ARR_RESIZE (type, (arr), (n)+1) : (arr))
+
+/**
+ * Append one element to a flexible array.
+ *
+ * @param type The element type of the array.
+ * @param arr The array, which must be an lvalue.
+ * @param elt The new element, must be of type (type).
+ */
+#define ARR_APP1(type, arr, elt) \
+ (ARR_EXTEND (type, (arr), 1), (arr)[ARR_LEN ((arr))-1] = (elt))
+
+
+#ifdef NDEBUG
+# define ARR_VRFY(arr) ((void)0)
+# define ARR_IDX_VRFY(arr, idx) ((void)0)
+#else
+# define ARR_VRFY(arr) \
+ assert ( ( (_ARR_DESCR((arr))->magic == ARR_D_MAGIC) \
+ || (_ARR_DESCR((arr))->magic == ARR_A_MAGIC) \
+ || (_ARR_DESCR((arr))->magic == ARR_F_MAGIC)) \
+ && ( (_ARR_DESCR((arr))->magic != ARR_F_MAGIC) \
+ || (_ARR_DESCR((arr))->u.allocated >= _ARR_DESCR((arr))->nelts)) \
+ && (_ARR_DESCR((arr))->nelts >= 0))
+# define ARR_IDX_VRFY(arr, idx) \
+ assert ((0 <= (idx)) && ((idx) < ARR_LEN ((arr))))
+#endif
+
+
+/* Private !!!
+ Don't try this at home, kids, we're trained professionals ;->
+ ... or at the IPD, either. */
+#ifdef NDEBUG
+# define _ARR_DBGINF_DECL
+# define _ARR_SET_DBGINF(descr, co, es)
+#else
+# define _ARR_DBGINF_DECL int magic; size_t eltsize;
+# define _ARR_SET_DBGINF(descr, co, es) \
+ ( (descr)->magic = (co), (descr)->eltsize = (es) )
+#endif
+
+/**
+ * Construct an array header.
+ */
+#define ARR_STRUCT(type, _nelts) \
+ struct { \
+ _ARR_DBGINF_DECL \
+ union { \
+ struct obstack *obstack; /* dynamic: allocated on this obstack */ \
+ int allocated; /* flexible: #slots allocated */ \
+ } u; \
+ int nelts; \
+ union { \
+ type elts[(_nelts)]; \
+ aligned_type align[1]; \
+ } v; \
+ }
+
+/**
+ * The array descriptor header type.
+ */
+typedef ARR_STRUCT (aligned_type, 1) _arr_descr;
+
+extern _arr_descr arr_mt_descr;
+
+void *_new_arr_f (int, size_t);
+void _del_arr_f (void *);
+void *_new_arr_d (struct obstack *obstack, int nelts, size_t elts_size);
+void *_arr_resize (void *, int, size_t);
+void *_arr_setlen (void *, int, size_t);
+
+#define _ARR_ELTS_OFFS offsetof (_arr_descr, v.elts)
+#define _ARR_DESCR(elts) ((_arr_descr *)(void *)((char *)(elts) - _ARR_ELTS_OFFS))
+
+#endif /* FIRM_ADT_ARRAY_H */
--- /dev/null
+/*
+ * Copyright (C) 1995-2007 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.
+ */
+
+/**
+ * @file
+ * @date 26.01.2006
+ * @author Sebastian Hack
+ * @brief Implements bipartite matchings.
+ */
+#ifndef FIRM_ADT_BIPARTITE_H
+#define FIRM_ADT_BIPARTITE_H
+
+typedef struct _bipartite_t bipartite_t;
+
+bipartite_t *bipartite_new(int n_left, int n_right);
+void bipartite_free(bipartite_t *gr);
+void bipartite_add(bipartite_t *gr, int i, int j);
+void bipartite_remv(bipartite_t *gr, int i, int j);
+int bipartite_adj(const bipartite_t *gr, int i, int j);
+void bipartite_matching(const bipartite_t *gr, int *matching);
+
+/**
+ * Dumps a bipartite graph to a file stream.
+ */
+void bipartite_dump_f(FILE *f, const bipartite_t *gr);
+
+/**
+ * Dumps a bipartite graph to file name.
+ */
+void bipartite_dump(const char *name, const bipartite_t *gr);
+
+#endif /* _BIPARTITE_H */
--- /dev/null
+/*
+ * Copyright (C) 1995-2007 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.
+ */
+
+/**
+ * @file
+ * @date 28.9.2004
+ * @brief Functions from hackers delight.
+ * @author Sebastian Hack, Matthias Braun
+ * @version $Id$
+ */
+#ifndef FIRM_ADT_BITFIDDLE_H
+#define FIRM_ADT_BITFIDDLE_H
+
+#include <limits.h>
+#include <assert.h>
+#include "util.h"
+
+/* some functions here assume ints are 32 bit wide */
+#define HACKDEL_WORDSIZE 32
+COMPILETIME_ASSERT(sizeof(unsigned) == 4, unsignedsize)
+COMPILETIME_ASSERT(UINT_MAX == 4294967295U, uintmax)
+
+/**
+ * Add saturated.
+ * @param x Summand 1.
+ * @param y Summand 2.
+ * @return x + y or INT_MAX/INT_MIN if an overflow occurred and x,y was positive/negative.
+ *
+ * @note See hacker's delight, page 27.
+ */
+static INLINE __attribute__((const))
+int add_saturated(int x, int y)
+{
+ int sum = x + y;
+ /*
+ An overflow occurs, if the sign of the both summands is equal
+ and the one of the sum is different from the summand's one.
+ The sign bit is 1, if an overflow occurred, 0 otherwise.
+ int overflow = ~(x ^ y) & (sum ^ x);
+ */
+ int overflow = (x ^ sum) & (y ^ sum);
+
+ /*
+ The infinity to use.
+ Make a mask of the sign bit of x and y (they are the same if an
+ overflow occurred).
+ INT_MIN == ~INT_MAX, so if the sign was negative, INT_MAX becomes
+ INT_MIN.
+ */
+ int inf = (x >> (sizeof(x) * 8 - 1)) ^ INT_MAX;
+
+ return overflow < 0 ? inf : sum;
+}
+
+/**
+ * Compute the count of set bits in a 32-bit word.
+ * @param x A 32-bit word.
+ * @return The number of bits set in x.
+ */
+static INLINE __attribute__((const))
+unsigned popcnt(unsigned x) {
+ x -= ((x >> 1) & 0x55555555);
+ x = (x & 0x33333333) + ((x >> 2) & 0x33333333);
+ x = (x + (x >> 4)) & 0x0f0f0f0f;
+ x += x >> 8;
+ x += x >> 16;
+ return x & 0x3f;
+}
+
+/**
+ * Compute the number of leading zeros in a word.
+ * @param x The word.
+ * @return The number of leading (from the most significant bit) zeros.
+ */
+static INLINE __attribute__((const))
+unsigned nlz(unsigned x) {
+#ifdef USE_X86_ASSEMBLY
+ unsigned res;
+ if(x == 0)
+ return 32;
+
+ __asm__("bsrl %1,%0"
+ : "=r" (res)
+ : "r" (x));
+ return 31 - res;
+#else
+ x |= x >> 1;
+ x |= x >> 2;
+ x |= x >> 4;
+ x |= x >> 8;
+ x |= x >> 16;
+ return popcnt(~x);
+#endif
+}
+
+/**
+ * Compute the number of trailing zeros in a word.
+ * @param x The word.
+ * @return The number of trailing zeros.
+ */
+static INLINE __attribute__((const))
+unsigned ntz(unsigned x) {
+#ifdef USE_X86_ASSEMBLY
+ unsigned res;
+ if(x == 0)
+ return 32;
+
+ __asm__("bsfl %1,%0"
+ : "=r" (res)
+ : "r" (x));
+ return res;
+#else
+ return HACKDEL_WORDSIZE - nlz(~x & (x - 1));
+#endif
+}
+
+/**
+ * Compute the greatest power of 2 smaller or equal to a value.
+ * This is also known as the binary logarithm.
+ * @param x The value.
+ * @return The power of two.
+ */
+#define log2_floor(x) (HACKDEL_WORDSIZE - 1 - nlz(x))
+
+/**
+ * Compute the smallest power of 2 greater or equal to a value.
+ * This is also known as the binary logarithm.
+ * @param x The value.
+ * @return The power of two.
+ */
+#define log2_ceil(x) (HACKDEL_WORDSIZE - nlz((x) - 1))
+
+/**
+ * Round up to the next multiple of a power of two.
+ * @param x A value.
+ * @param pot A power of two.
+ * @return x rounded up to the next multiple of pot.
+ */
+#define round_up2(x,pot) (((x) + ((pot) - 1)) & (~((pot) - 1)))
+
+/**
+ * Returns the biggest power of 2 that is equal or smaller than @p x
+ * (see hackers delight power-of-2 boundaries, page 48)
+ */
+static INLINE __attribute__((const))
+unsigned floor_po2(unsigned x)
+{
+#ifdef USE_X86_ASSEMBLY // in this case nlz is fast
+ if(x == 0)
+ return 0;
+ // note that x != 0 here, so nlz(x) < 32!
+ return 0x80000000U >> nlz(x);
+#else
+ x |= x >> 1;
+ x |= x >> 2;
+ x |= x >> 4;
+ x |= x >> 8;
+ x |= x >> 16;
+ return x - (x >> 1);
+#endif
+}
+
+/**
+ * Returns the smallest power of 2 that is equal or greater than x
+ * @remark x has to be <= 0x8000000 of course
+ * @note see hackers delight power-of-2 boundaries, page 48
+ */
+static INLINE __attribute__((const))
+unsigned ceil_po2(unsigned x)
+{
+ if(x == 0)
+ return 0;
+ assert(x < (1U << 31));
+
+#ifdef USE_X86_ASSEMBLY // in this case nlz is fast
+ // note that x != 0 here!
+ return 0x80000000U >> (nlz(x-1) - 1);
+#else
+ x = x - 1;
+ x |= x >> 1;
+ x |= x >> 2;
+ x |= x >> 4;
+ x |= x >> 8;
+ x |= x >> 16;
+ return x + 1;
+#endif
+}
+
+/**
+ * Tests whether @p x is a power of 2
+ */
+static INLINE __attribute__((const))
+int is_po2(unsigned x)
+{
+ return (x & (x-1)) == 0;
+}
+
+#endif
--- /dev/null
+/*
+ * Copyright (C) 1995-2007 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.
+ */
+
+/**
+ * @file
+ * @brief A bitset implementation.
+ * @author Sebastian Hack
+ * @date 15.10.2004
+ * @version $Id$
+ */
+#ifndef FIRM_ADT_BITSET_H
+#define FIRM_ADT_BITSET_H
+
+#include "firm_config.h"
+
+#include <stdlib.h>
+#include <stdio.h>
+#include <assert.h>
+#include <string.h>
+
+#include "xmalloc.h"
+#include "bitfiddle.h"
+
+typedef unsigned int bitset_pos_t;
+
+#include "bitset_std.h"
+
+/*
+#if defined(__GNUC__) && defined(__i386__)
+#include "bitset_ia32.h"
+#endif
+*/
+
+typedef struct _bitset_t {
+ bitset_pos_t units;
+ bitset_pos_t size;
+ bitset_unit_t *data;
+} bitset_t;
+
+#define BS_UNIT_SIZE sizeof(bitset_unit_t)
+#define BS_UNIT_SIZE_BITS (BS_UNIT_SIZE * 8)
+#define BS_UNIT_MASK (BS_UNIT_SIZE_BITS - 1)
+
+/**
+ * Initialize a bitset.
+ * This functions should not be called.
+ *
+ * Note that this function needs three macros which must be provided by the
+ * bitfield implementor:
+ * - _bitset_overall_size(size) The overall size that must be
+ * allocated for the bitfield in bytes.
+ * - _bitset_units(size) The number of units that will be
+ * present in the bitfield for a given highest bit.
+ * - _bitset_data_ptr(data, size) This produces as pointer to the
+ * first unit in the allocated memory area. The main reason for this
+ * macro is, that some bitset implementors want control over memory
+ * alignment.
+ *
+ * @param area A pointer to memory reserved for the bitset.
+ * @param size The size of the bitset in bits.
+ * @return A pointer to the initialized bitset.
+ */
+static INLINE bitset_t *_bitset_prepare(void *area, bitset_pos_t size)
+{
+ bitset_t *ptr = area;
+ memset(area, 0, _bitset_overall_size(sizeof(bitset_t), size));
+ ptr->units = _bitset_units(size);
+ ptr->size = size;
+ ptr->data = _bitset_data_ptr(area, sizeof(bitset_t), size);
+ return ptr;
+}
+
+/**
+ * Mask out all bits, which are only there, because the number
+ * of bits in the set didn't match a unit size boundary.
+ * @param bs The bitset.
+ * @return The masked bitset.
+ */
+static INLINE bitset_t *_bitset_mask_highest(bitset_t *bs)
+{
+ bitset_pos_t rest = bs->size & BS_UNIT_MASK;
+ if (rest)
+ bs->data[bs->units - 1] &= (1 << rest) - 1;
+ return bs;
+}
+
+/**
+ * Get the capacity of the bitset in bits.
+ * @param bs The bitset.
+ * @return The capacity in bits of the bitset.
+ */
+#define bitset_capacity(bs) ((bs)->units * BS_UNIT_SIZE_BITS)
+
+/**
+ * Get the size of the bitset in bits.
+ * @note Note the difference between capacity and size.
+ * @param bs The bitset.
+ * @return The highest bit which can be set or cleared plus 1.
+ */
+#define bitset_size(bs) ((bs)->size)
+
+/**
+ * Allocate a bitset on an obstack.
+ * @param obst The obstack.
+ * @param size The greatest bit that shall be stored in the set.
+ * @return A pointer to an empty initialized bitset.
+ */
+#define bitset_obstack_alloc(obst,size) \
+ _bitset_prepare(obstack_alloc(obst, _bitset_overall_size(sizeof(bitset_t), size)), size)
+
+/**
+ * Allocate a bitset via malloc.
+ * @param size The greatest bit that shall be stored in the set.
+ * @return A pointer to an empty initialized bitset.
+ */
+#define bitset_malloc(size) \
+ _bitset_prepare(xmalloc(_bitset_overall_size(sizeof(bitset_t), size)), size)
+
+/**
+ * Free a bitset allocated with bitset_malloc().
+ * @param bs The bitset.
+ */
+#define bitset_free(bs) free(bs)
+
+/**
+ * Allocate a bitset on the stack via alloca.
+ * @param size The greatest bit that shall be stored in the set.
+ * @return A pointer to an empty initialized bitset.
+ */
+#define bitset_alloca(size) \
+ _bitset_prepare(alloca(_bitset_overall_size(sizeof(bitset_t), size)), size)
+
+
+/**
+ * Get the unit which contains a specific bit.
+ * This function is internal.
+ * @param bs The bitset.
+ * @param bit The bit.
+ * @return A pointer to the unit containing the bit.
+ */
+static INLINE bitset_unit_t *_bitset_get_unit(const bitset_t *bs, bitset_pos_t bit)
+{
+ /* assert(bit < bs->units * BS_UNIT_SIZE_BITS && "Bit too large"); */
+ assert(bit <= bs->size && "Bit to large");
+ return bs->data + bit / BS_UNIT_SIZE_BITS;
+}
+
+/**
+ * Set a bit in the bitset.
+ * @param bs The bitset.
+ * @param bit The bit to set.
+ */
+static INLINE void bitset_set(bitset_t *bs, bitset_pos_t bit)
+{
+ bitset_unit_t *unit = _bitset_get_unit(bs, bit);
+ _bitset_inside_set(unit, bit & BS_UNIT_MASK);
+}
+
+/**
+ * Clear a bit in the bitset.
+ * @param bs The bitset.
+ * @param bit The bit to clear.
+ */
+static INLINE void bitset_clear(bitset_t *bs, bitset_pos_t bit)
+{
+ bitset_unit_t *unit = _bitset_get_unit(bs, bit);
+ _bitset_inside_clear(unit, bit & BS_UNIT_MASK);
+}
+
+/**
+ * Check, if a bit is set.
+ * @param bs The bitset.
+ * @param bit The bit to check for.
+ * @return 1, if the bit was set, 0 if not.
+ */
+static INLINE int bitset_is_set(const bitset_t *bs, bitset_pos_t bit)
+{
+ bitset_unit_t *unit = _bitset_get_unit(bs, bit);
+ return _bitset_inside_is_set(unit, bit & BS_UNIT_MASK);
+}
+
+/**
+ * Flip a bit in a bitset.
+ * @param bs The bitset.
+ * @param bit The bit to flip.
+ */
+static INLINE void bitset_flip(bitset_t *bs, bitset_pos_t bit)
+{
+ bitset_unit_t *unit = _bitset_get_unit(bs, bit);
+ _bitset_inside_flip(unit, bit & BS_UNIT_MASK);
+}
+
+/**
+ * Flip the whole bitset.
+ * @param bs The bitset.
+ */
+static INLINE void bitset_flip_all(bitset_t *bs)
+{
+ bitset_pos_t i;
+ for(i = 0; i < bs->units; i++)
+ _bitset_inside_flip_unit(&bs->data[i]);
+ _bitset_mask_highest(bs);
+}
+
+/**
+ * Copy a bitset to another.
+ * @param tgt The target bitset.
+ * @param src The source bitset.
+ * @return The target bitset.
+ */
+static INLINE bitset_t *bitset_copy(bitset_t *tgt, const bitset_t *src)
+{
+ bitset_pos_t tu = tgt->units;
+ bitset_pos_t su = src->units;
+ bitset_pos_t min_units = tu < su ? tu : su;
+ memcpy(tgt->data, src->data, min_units * BS_UNIT_SIZE);
+ if(tu > min_units)
+ memset(tgt->data + min_units, 0, BS_UNIT_SIZE * (tu - min_units));
+ return _bitset_mask_highest(tgt);
+}
+
+/**
+ * Find the smallest bit set in the bitset.
+ * @param bs The bitset.
+ * @return The smallest bit set in the bitset.
+ */
+static INLINE bitset_pos_t bitset_min(const bitset_t *bs)
+{
+ bitset_pos_t i, ofs = 0;
+
+ for(i = 0; i < bs->units; ++i) {
+ bitset_unit_t *unit = &bs->data[i];
+ bitset_pos_t pos = _bitset_inside_ntz(unit);
+ if(pos > 0)
+ return ofs + pos;
+ ofs += BS_UNIT_SIZE_BITS;
+ }
+
+ return 0;
+}
+
+/**
+ * Find the greatest bit set in the bitset.
+ * @param bs The bitset.
+ * @return The greatest bit set in the bitset.
+ */
+static INLINE bitset_pos_t bitset_max(const bitset_t *bs)
+{
+ bitset_pos_t i, max = 0, ofs = 0;
+
+ for(i = 0; i < bs->units; ++i) {
+ bitset_unit_t *unit = &bs->data[i];
+ bitset_pos_t pos = _bitset_inside_nlz(unit);
+ if(pos > 0)
+ max = ofs + pos;
+ ofs += BS_UNIT_SIZE_BITS;
+ }
+
+ return max;
+}
+
+/**
+ * Find the next set bit from a given bit.
+ * @note Note that if pos is set, pos is returned.
+ * @param bs The bitset.
+ * @param pos The bit from which to search for the next set bit.
+ * @return The next set bit from pos on, or -1, if no set bit was found
+ * after pos.
+ */
+static INLINE bitset_pos_t _bitset_next(const bitset_t *bs,
+ bitset_pos_t pos, int set)
+{
+ bitset_pos_t unit_number = pos / BS_UNIT_SIZE_BITS;
+ bitset_pos_t res;
+
+ if(pos >= bs->size)
+ return -1;
+
+ {
+ bitset_pos_t bit_in_unit = pos & BS_UNIT_MASK;
+ bitset_pos_t in_unit_mask = (1 << bit_in_unit) - 1;
+
+ /*
+ * Mask out the bits smaller than pos in the current unit.
+ * We are only interested in bits set higher than pos.
+ */
+ bitset_unit_t curr_unit = bs->data[unit_number];
+
+ /*
+ * Find the next bit set in the unit.
+ * Mind that this function returns 0, if the unit is -1 and
+ * counts the bits from 1 on.
+ */
+ bitset_pos_t next_in_this_unit =
+ _bitset_inside_ntz_value((set ? curr_unit : ~curr_unit) & ~in_unit_mask);
+
+ /* If there is a bit set in the current unit, exit. */
+ if (next_in_this_unit < BS_UNIT_SIZE_BITS) {
+ res = next_in_this_unit + unit_number * BS_UNIT_SIZE_BITS;
+ return res < bs->size ? res : -1;
+ }
+
+ /* Else search for set bits in the next units. */
+ else {
+ bitset_pos_t i;
+ for(i = unit_number + 1; i < bs->units; ++i) {
+ bitset_unit_t data = bs->data[i];
+ bitset_pos_t first_set =
+ _bitset_inside_ntz_value(set ? data : ~data);
+
+ if (first_set < BS_UNIT_SIZE_BITS) {
+ res = first_set + i * BS_UNIT_SIZE_BITS;
+ return res < bs->size ? res : -1;
+ }
+ }
+ }
+ }
+
+ return -1;
+}
+
+#define bitset_next_clear(bs,pos) _bitset_next((bs), (pos), 0)
+#define bitset_next_set(bs,pos) _bitset_next((bs), (pos), 1)
+
+/**
+ * Convenience macro for bitset iteration.
+ * @param bitset The bitset.
+ * @param elm A unsigned long variable.
+ */
+#define bitset_foreach(bitset,elm) \
+ for(elm = bitset_next_set(bitset,0); elm != -1; elm = bitset_next_set(bitset,elm+1))
+
+
+#define bitset_foreach_clear(bitset,elm) \
+ for(elm = bitset_next_clear(bitset,0); elm != -1; elm = bitset_next_clear(bitset,elm+1))
+
+/**
+ * Count the bits set.
+ * This can also be seen as the cardinality of the set.
+ * @param bs The bitset.
+ * @return The number of bits set in the bitset.
+ */
+static INLINE unsigned bitset_popcnt(const bitset_t *bs)
+{
+ bitset_pos_t i;
+ bitset_unit_t *unit;
+ unsigned pop = 0;
+
+ for (i = 0, unit = bs->data; i < bs->units; ++i, ++unit)
+ pop += _bitset_inside_pop(unit);
+
+ return pop;
+}
+
+/**
+ * Clear the bitset.
+ * This sets all bits to zero.
+ * @param bs The bitset.
+ */
+static INLINE bitset_t *bitset_clear_all(bitset_t *bs)
+{
+ memset(bs->data, 0, BS_UNIT_SIZE * bs->units);
+ return bs;
+}
+
+/**
+ * Set the bitset.
+ * This sets all bits to one.
+ * @param bs The bitset.
+ */
+static INLINE bitset_t *bitset_set_all(bitset_t *bs)
+{
+ memset(bs->data, -1, bs->units * BS_UNIT_SIZE);
+ return _bitset_mask_highest(bs);
+}
+
+/**
+ * Check, if one bitset is contained by another.
+ * That is, each bit set in lhs is also set in rhs.
+ * @param lhs A bitset.
+ * @param rhs Another bitset.
+ * @return 1, if all bits in lhs are also set in rhs, 0 otherwise.
+ */
+static INLINE int bitset_contains(const bitset_t *lhs, const bitset_t *rhs)
+{
+ bitset_pos_t n = lhs->units < rhs->units ? lhs->units : rhs->units;
+ bitset_pos_t i;
+
+ for(i = 0; i < n; ++i) {
+ bitset_unit_t lu = lhs->data[i];
+ bitset_unit_t ru = rhs->data[i];
+
+ if((lu | ru) & ~ru)
+ return 0;
+ }
+
+ /*
+ * If the left hand sinde is a larger bitset than rhs,
+ * we have to check, that all extra bits in lhs are 0
+ */
+ if(lhs->units > n) {
+ for(i = n; i < lhs->units; ++i) {
+ if(lhs->data[i] != 0)
+ return 0;
+ }
+ }
+
+ return 1;
+}
+
+/**
+ * Treat the bitset as a number and subtract 1.
+ * @param bs The bitset.
+ * @return The same bitset.
+ */
+static INLINE void bitset_minus1(bitset_t *bs)
+{
+#define _SH (sizeof(bitset_unit_t) * 8 - 1)
+
+ bitset_pos_t i;
+
+ for(i = 0; i < bs->units; ++i) {
+ bitset_unit_t unit = bs->data[i];
+ bitset_unit_t um1 = unit - 1;
+
+ bs->data[i] = um1;
+
+ if(((unit >> _SH) ^ (um1 >> _SH)) == 0)
+ break;
+ }
+#undef _SH
+}
+
+/**
+ * Check if two bitsets intersect.
+ * @param a The first bitset.
+ * @param b The second bitset.
+ * @return 1 if they have a bit in common, 0 if not.
+ */
+static INLINE int bitset_intersect(const bitset_t *a, const bitset_t *b)
+{
+ bitset_pos_t n = a->units < b->units ? a->units : b->units;
+ bitset_pos_t i;
+
+ for (i = 0; i < n; ++i)
+ if (a->data[i] & b->data[i])
+ return 1;
+
+ return 0;
+}
+
+/**
+ * Check, if a bitset is empty.
+ * @param a The bitset.
+ * @return 1, if the bitset is empty, 0 if not.
+ */
+static INLINE int bitset_is_empty(const bitset_t *a)
+{
+ bitset_pos_t i;
+ for (i = 0; i < a->units; ++i)
+ if (a->data[i] != 0)
+ return 0;
+ return 1;
+}
+
+/**
+ * Print a bitset to a stream.
+ * The bitset is printed as a comma separated list of bits set.
+ * @param file The stream.
+ * @param bs The bitset.
+ */
+static INLINE void bitset_fprint(FILE *file, const bitset_t *bs)
+{
+ const char *prefix = "";
+ int i;
+
+ putc('{', file);
+ for(i = bitset_next_set(bs, 0); i != -1; i = bitset_next_set(bs, i + 1)) {
+ fprintf(file, "%s%u", prefix, i);
+ prefix = ",";
+ }
+ putc('}', file);
+}
+
+static INLINE void bitset_debug_fprint(FILE *file, const bitset_t *bs)
+{
+ bitset_pos_t i;
+
+ fprintf(file, "%u:", bs->units);
+ for(i = 0; i < bs->units; ++i)
+ fprintf(file, " " BITSET_UNIT_FMT, bs->data[i]);
+}
+
+/**
+ * Perform tgt = tgt \ src operation.
+ * @param tgt The target bitset.
+ * @param src The source bitset.
+ * @return the tgt set.
+ */
+static INLINE bitset_t *bitset_andnot(bitset_t *tgt, const bitset_t *src);
+
+/**
+ * Perform Union, tgt = tgt u src operation.
+ * @param tgt The target bitset.
+ * @param src The source bitset.
+ * @return the tgt set.
+ */
+static INLINE bitset_t *bitset_or(bitset_t *tgt, const bitset_t *src);
+
+/**
+ * Perform tgt = tgt ^ ~src operation.
+ * @param tgt The target bitset.
+ * @param src The source bitset.
+ * @return the tgt set.
+ */
+static INLINE bitset_t *bitset_xor(bitset_t *tgt, const bitset_t *src);
+
+/*
+ * Here, the binary operations follow.
+ * And, Or, And Not, Xor are available.
+ */
+#define BINARY_OP(op) \
+static INLINE bitset_t *bitset_ ## op(bitset_t *tgt, const bitset_t *src) \
+{ \
+ bitset_pos_t i; \
+ bitset_pos_t n = tgt->units > src->units ? src->units : tgt->units; \
+ for(i = 0; i < n; i += _BITSET_BINOP_UNITS_INC) \
+ _bitset_inside_binop_ ## op(&tgt->data[i], &src->data[i]); \
+ if(n < tgt->units) \
+ _bitset_clear_rest(&tgt->data[i], tgt->units - i); \
+ return _bitset_mask_highest(tgt); \
+}
+
+/*
+ * Define the clear rest macro for the and, since it is the only case,
+ * were non existed (treated as 0) units in the src must be handled.
+ * For all other operations holds: x Op 0 = x for Op in { Andnot, Or, Xor }
+ *
+ * For and, each bitset implementer has to provide the macro
+ * _bitset_clear_units(data, n), which clears n units from the pointer
+ * data on.
+ */
+#define _bitset_clear_rest(data,n) _bitset_inside_clear_units(data, n)
+BINARY_OP(and)
+#undef _bitset_clear_rest
+#define _bitset_clear_rest(data,n)
+
+BINARY_OP(andnot)
+BINARY_OP(or)
+BINARY_OP(xor)
+
+#endif
--- /dev/null
+/*
+ * Copyright (C) 1995-2007 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.
+ */
+
+/**
+ * @file
+ * @brief intel 80x86 implementation of bitsets
+ * @version $Id$
+ */
+#ifndef _BITSET_IA32_H
+#define _BITSET_IA32_H
+
+typedef unsigned int bitset_unit_t;
+#define BITSET_UNIT_FMT "%0x"
+
+#undef _bitset_inside_clear
+#undef _bitset_inside_set
+#undef _bitset_inside_flip
+#undef _bitset_inside_is_set
+
+#undef _bitset_inside_nlz
+#undef _bitset_inside_ntz
+#undef _bitset_inside_ntz_value
+
+#define _bitset_inside_set(unit,bit) \
+ __asm__( "btsl %1,%0" :"=m" (unit) :"Ir" (bit))
+
+#define _bitset_inside_clear(unit,bit) \
+ __asm__( "btrl %1,%0" :"=m" (unit) :"Ir" (bit))
+
+#define _bitset_inside_flip(unit,bit) \
+ __asm__( "btcl %1,%0" :"=m" (unit) :"Ir" (bit))
+
+#define _bitset_inside_is_set(unit,bit) _bitset_ia32_inside_is_set(unit, bit)
+#define _bitset_inside_nlz(unit) _bitset_ia32_inside_nlz(unit)
+#define _bitset_inside_ntz(unit) _bitset_ia32_inside_ntz(unit)
+#define _bitset_inside_ntz_value(unit) _bitset_ia32_inside_ntz_value(unit)
+
+static INLINE int _bitset_ia32_inside_is_set(bitset_unit_t *unit, unsigned bit)
+{
+ int res = 0;
+ __asm__("mov $0,%0\n\tbtl %1,%2\n\tadc $0,%0"
+ : "=r" (res)
+ : "Ir" (bit), "m" (unit)
+ : "cc");
+ return res;
+}
+
+static INLINE unsigned _bitset_ia32_inside_nlz(bitset_unit_t *unit)
+{
+ unsigned res = 0;
+ __asm__("bsrl %1,%0" :"=r" (res) :"m" (unit));
+ return *unit == 0 ? 32 : res;
+}
+
+static INLINE unsigned _bitset_ia32_inside_ntz(bitset_unit_t *unit) {
+ unsigned res = 0;
+ __asm__("bsfl %1,%0" :"=r" (res) :"m" (unit));
+ return *unit == 0 ? 32 : res;
+}
+
+static INLINE unsigned _bitset_ia32_inside_ntz_value(bitset_unit_t unit) {
+ unsigned res = 0;
+ __asm__("bsfl %1,%0" :"=r" (res) :"rm" (unit));
+ return unit == 0 ? 32 : res;
+}
+
+#if defined(__GNUC__) && defined(__SSE2__)
+
+#include <stddef.h>
+#include <xmmintrin.h>
+
+#undef _bitset_units
+#undef _bitset_overall_size
+#undef _bitset_data_ptr
+
+#undef _BITSET_BINOP_UNITS_INC
+
+#undef _bitset_inside_binop_and
+#undef _bitset_inside_binop_andnot
+#undef _bitset_inside_binop_or
+#undef _bitset_inside_binop_xor
+
+#undef _bitset_inside_binop_with_zero_and
+#undef _bitset_inside_binop_with_zero_andnot
+#undef _bitset_inside_binop_with_zero_or
+#undef _bitset_inside_binop_with_zero_xor
+
+#define _bitset_units(highest_bit) (round_up2(highest_bit, 128) / BS_UNIT_SIZE_BITS)
+
+#define _bitset_overall_size(bitset_base_size,highest_bit) \
+ ((bitset_base_size) + 16 + _bitset_units(highest_bit) * BS_UNIT_SIZE)
+
+#define _bitset_data_ptr(data,bitset_base_size,highest_bit) \
+ _bitset_sse_data_ptr(data, bitset_base_size, highest_bit)
+
+static INLINE bitset_unit_t *_bitset_sse_data_ptr(void *data, size_t bitset_base_size,
+ bitset_pos_t highest_bit)
+{
+ ptrdiff_t diff;
+ char *units = data;
+
+ diff = (units - (char *) 0) + bitset_base_size;
+ diff = round_up2(diff, 16);
+ units = (char *) 0 + diff;
+ return (bitset_unit_t *) units;
+}
+
+#define _BITSET_BINOP_UNITS_INC 4
+#define _bitset_inside_binop_and(tgt,src) _bitset_sse_inside_binop_and(tgt,src)
+#define _bitset_inside_binop_andnot(tgt,src) _bitset_sse_inside_binop_andnot(tgt,src)
+#define _bitset_inside_binop_or(tgt,src) _bitset_sse_inside_binop_or(tgt,src)
+#define _bitset_inside_binop_xor(tgt,src) _bitset_sse_inside_binop_xor(tgt,src)
+
+#define _BITSET_SSE_BINOP(name) \
+static INLINE void _bitset_sse_inside_binop_ ## name(bitset_unit_t *tgt, bitset_unit_t *src) \
+{ \
+ __m128i src_op = _mm_load_si128((__m128i *) src); \
+ __m128i tgt_op = _mm_load_si128((__m128i *) tgt); \
+ __m128i res = _mm_ ## name ## _si128(tgt_op, src_op); \
+ _mm_store_si128((void *) tgt, res); \
+}
+
+
+static INLINE void _bitset_sse_inside_binop_with_zero_and(bitset_unit_t *tgt)
+{
+ tgt[0] = 0;
+ tgt[1] = 0;
+ tgt[2] = 0;
+ tgt[3] = 0;
+}
+
+static INLINE void _bitset_sse_inside_binop_andnot(bitset_unit_t *tgt, bitset_unit_t *src)
+{
+ __m128i src_op = _mm_load_si128((void *) src);
+ __m128i tgt_op = _mm_load_si128((void *) tgt);
+ __m128i res = _mm_andnot_si128(src_op, tgt_op);
+ _mm_store_si128((__m128i *) tgt, res);
+}
+
+_BITSET_SSE_BINOP(and)
+_BITSET_SSE_BINOP(or)
+_BITSET_SSE_BINOP(xor)
+
+
+#endif
+#endif
--- /dev/null
+/*
+ * Copyright (C) 1995-2007 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.
+ */
+
+/**
+ * @file
+ * @brief ANSI-C compliant implementation of bitsets
+ * @version $Id$
+ */
+#ifndef FIRM_ADT_BITSET_STD_H
+#define FIRM_ADT_BITSET_STD_H
+
+#include "bitfiddle.h"
+
+/** Use ordinary ints as unit types. */
+typedef unsigned int bitset_unit_t;
+
+#define BITSET_UNIT_FMT "%0x"
+#define BITSET_UNIT_ALL_ONE ((unsigned int) -1)
+
+/**
+ * Units needed for a given highest bit.
+ * This implementation always allocates units in a multiple of 16 bytes.
+ * @param size The size of the bitset in bits.
+ * @return The number of units needed.
+ */
+#define _bitset_units(size) (round_up2(size, BS_UNIT_SIZE_BITS) / BS_UNIT_SIZE_BITS)
+
+/**
+ * Compute the size in bytes needed for a bitseti, overall.
+ * This also include the size for the bitset data structure.
+ * This implementation computes the size in wat, that the bitset units
+ * can be aligned to 16 bytes.
+ * @param size The size of the bitset in bits.
+ * @return The overall amount of bytes needed for that bitset.
+ */
+#define _bitset_overall_size(bitset_base_size,size) \
+ (bitset_base_size + _bitset_units(size) * BS_UNIT_SIZE)
+
+/**
+ * calculate the pointer to the data space of the bitset.
+ * @param data The base address of the allocated memory
+ * @param bitset_base_size The size of the basical bitset data structure
+ * which has to be taken into account.
+ * @param size The size of the bitset in bits.
+ */
+#define _bitset_data_ptr(data,bitset_base_size,size) \
+ ((bitset_unit_t *) ((char *) data + bitset_base_size))
+
+
+/**
+ * Clear some units from a certain address on.
+ * @param addr The address from where to clear.
+ * @param n The number of units to set to 0.
+ */
+#define _bitset_inside_clear_units(addr,n) \
+ memset(addr, 0, n * BS_UNIT_SIZE)
+
+/**
+ * Set a bit in a unit.
+ * @param unit A pointer to the unit.
+ * @param bit which bit to set.
+ */
+#define _bitset_inside_set(unit_ptr,bit) (*unit_ptr) |= (1 << (bit))
+
+/**
+ * Clear a bit in a unit.
+ * @param unit A pointer to the unit.
+ * @param bit which bit to set.
+ */
+#define _bitset_inside_clear(unit_ptr,bit) (*unit_ptr) &= ~(1 << (bit))
+
+/**
+ * Flip a bit in a unit.
+ * @param unit A pointer to the unit.
+ * @param bit which bit to set.
+ */
+#define _bitset_inside_flip(unit_ptr,bit) (*unit_ptr) ^= (1 << (bit))
+
+/**
+ * Flip a whole unit.
+ * @param unit_ptr The pointer to the unit.
+ */
+#define _bitset_inside_flip_unit(unit_ptr) (*unit_ptr) = ~(*unit_ptr)
+
+/**
+ * Count the number of leading zeroes in a unit.
+ * @param unit A pointer to the unit.
+ * @return The Number of leading zeroes.
+ */
+#define _bitset_inside_nlz(unit_ptr) (nlz(*unit_ptr))
+
+
+/**
+ * Count the number of trailing zeroes in a unit.
+ * @param unit A pointer to the unit.
+ * @return The Number of leading zeroes.
+ */
+#define _bitset_inside_ntz(unit_ptr) _bitset_std_inside_ntz(unit_ptr)
+static INLINE unsigned _bitset_std_inside_ntz(bitset_unit_t *unit_ptr)
+{
+ unsigned long data = *unit_ptr;
+ return 32 - (unsigned) nlz(~data & (data - 1));
+}
+
+/**
+ * Count the number of trailing zeroes in a unit (whereas the unit is no
+ * pointer but a value).
+ * @param unit A unit.
+ * @return The Number of leading zeroes.
+ */
+#define _bitset_inside_ntz_value(unit) (32 - nlz(~(unit) & ((unit) - 1)))
+
+/**
+ * test if a bit is set in a unit.
+ * @param unit_ptr The pointer to the unit.
+ * @param bit The bit to check.
+ * @return 1, if the bit is set, 0 otherise.
+ */
+#define _bitset_inside_is_set(unit_ptr,bit) \
+ (((*unit_ptr) & (1 << (bit))) != 0)
+
+/**
+ * count the number of bits set in a unit.
+ * @param unit_ptr The pointer to a unit.
+ * @return The number of bits set in the unit.
+ */
+#define _bitset_inside_pop(unit_ptr) (popcnt(*unit_ptr))
+
+#define _BITSET_BINOP_UNITS_INC 1
+
+#define _bitset_inside_binop_and(tgt,src) ((*tgt) &= (*src))
+#define _bitset_inside_binop_andnot(tgt,src) ((*tgt) &= ~(*src))
+#define _bitset_inside_binop_or(tgt,src) ((*tgt) |= (*src))
+#define _bitset_inside_binop_xor(tgt,src) ((*tgt) ^= (*src))
+
+#endif
--- /dev/null
+/*
+ * Copyright (C) 1995-2007 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.
+ */
+
+/**
+ * @file
+ * @date 16.03.2007
+ * @brief a set of pointers with a custom compare function
+ * @author Matthias Braun
+ * @version $Id$
+ */
+#ifndef FIRM_ADT_CPSET_H
+#define FIRM_ADT_CPSET_H
+
+/**
+ * The type of a cpset compare function.
+ *
+ * @param p1 pointer to an element
+ * @param p2 pointer to another element
+ *
+ * @return 1 if the elements are identically, zero else
+ */
+typedef int (*cpset_cmp_function) (const void *p1, const void *p2);
+
+/**
+ * The type of a cpset hash function.
+ *
+ * @param p1 pointer to an element
+ * @param p2 pointer to another element
+ *
+ * @return 1 if the elements are identically, zero else
+ */
+typedef unsigned (*cpset_hash_function) (const void *obj);
+
+#define HashSet cpset_t
+#define HashSetIterator cpset_iterator_t
+#define HashSetEntry cpset_hashset_entry_t
+#define ValueType void*
+#define ADDITIONAL_DATA cpset_cmp_function cmp_function; cpset_hash_function hash_function;
+#include "hashset.h"
+#undef ADDITIONAL_DATA
+#undef ValueType
+#undef HashSetEntry
+#undef HashSetIterator
+#undef HashSet
+
+/**
+ * Initializes a cpset
+ *
+ * @param cpset Pointer to allocated space for the cpset
+ * @param cmp_function The compare function to use
+ */
+void cpset_init(cpset_t *cpset, cpset_hash_function hash_function,
+ cpset_cmp_function cmp_function);
+
+/**
+ * Initializes a cpset
+ *
+ * @param cpset Pointer to allocated space for the cpset
+ * @param cmp_function The compare function to use
+ * @param expected_elements Number of elements expected in the cpset (roughly)
+ */
+void cpset_init_size(cpset_t *cpset, cpset_hash_function hash_function,
+ cpset_cmp_function cmp_function,
+ size_t expected_elements);
+
+/**
+ * Destroys a cpset and frees the memory allocated for hashtable. The memory of
+ * the cpset itself is not freed.
+ *
+ * @param cpset Pointer to the cpset
+ */
+void cpset_destroy(cpset_t *cpset);
+
+/**
+ * Inserts an element into a cpset.
+ *
+ * @param cpset Pointer to the cpset
+ * @param obj Element to insert into the cpset
+ * @returns The element itself or a pointer to an existing element
+ */
+void* cpset_insert(cpset_t *cpset, void *obj);
+
+/**
+ * Removes an element from a cpset. Does nothing if the cpset doesn't contain the
+ * element.
+ *
+ * @param cpset Pointer to the cpset
+ * @param obj Pointer to remove from the cpset
+ */
+void cpset_remove(cpset_t *cpset, const void *obj);
+
+/**
+ * Tests whether a cpset contains a pointer
+ *
+ * @param cpset Pointer to the cpset
+ * @param obj The pointer to find
+ * @returns An equivalent object to @p obj or NULL
+ */
+void *cpset_find(const cpset_t *cpset, const void *obj);
+
+/**
+ * Returns the number of pointers contained in the cpset
+ *
+ * @param cpset Pointer to the cpset
+ * @returns Number of pointers contained in the cpset
+ */
+size_t cpset_size(const cpset_t *cpset);
+
+/**
+ * Initializes a cpset iterator. Sets the iterator before the first element in
+ * the cpset.
+ *
+ * @param iterator Pointer to already allocated iterator memory
+ * @param cpset Pointer to the cpset
+ */
+void cpset_iterator_init(cpset_iterator_t *iterator, const cpset_t *cpset);
+
+/**
+ * Advances the iterator and returns the current element or NULL if all elements
+ * in the cpset have been processed.
+ * @attention It is not allowed to use cpset_insert or cpset_remove while
+ * iterating over a cpset.
+ *
+ * @param iterator Pointer to the cpset iterator.
+ * @returns Next element in the cpset or NULL
+ */
+void *cpset_iterator_next(cpset_iterator_t *iterator);
+
+/**
+ * Removed the element the iterator currently points to
+ *
+ * @param cpset Pointer to the cpset
+ * @param iterator Pointer to the cpset iterator.
+ */
+void cpset_remove_iterator(cpset_t *cpset, const cpset_iterator_t *iterator);
+
+#endif /* FIRM_ADT_CPSET_H */
--- /dev/null
+/*
+ * Copyright (C) 1995-2007 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.
+ */
+
+/**
+ * @file
+ * @brief a pointer hashset (WARNING: deprecated, use hashset_new.*
+ * instead)
+ * @author Hubert Schmid
+ * @date 09.06.2002
+ * @version $Id$
+ */
+#ifndef FIRM_ADT_ESET_H
+#define FIRM_ADT_ESET_H
+
+/**
+ * "eset" is a set of addresses. The addresses are used for element
+ * compare and hash calculation.
+ * The value "NULL" can not be stored, as it is used as internal sentinel.
+ */
+typedef struct eset eset;
+
+/** Creates a new empty set. */
+eset *eset_create(void);
+
+/**
+ * Creates a copy of the given set. Does NOT work if NULL is contained in source. */
+eset *eset_copy(eset *source);
+
+/** Deletes a set. */
+void eset_destroy(eset *s);
+
+/** Returns the number of elements in the set. */
+int eset_count(eset *s);
+
+/** Inserts an address into the set. */
+void eset_insert(eset *s, void *p);
+
+/** Checks, whether an address is element of a set. */
+int eset_contains(eset *s, void *p);
+
+/**
+ * Starts the iteration over a set and returns the first element or NULL
+ * if the set is empty.
+ *
+ * @note: It is NOT possible to add new elements while iterating through a set.
+ */
+void *eset_first(eset *s);
+
+/**
+ * Continues iteration through a set and returns the next element or NULL if the
+ * iteration is finished.
+ *
+ * @note: It is NOT possible to add new elements while iterating through a set.
+ */
+void *eset_next(eset *s);
+
+/** Inserts all elements of source into target (union). Does NOT work if NULL is contained in source. */
+void eset_insert_all(eset *target, eset *source);
+
+#endif
--- /dev/null
+/*
+ * Copyright (C) 1995-2007 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.
+ */
+
+/**
+ * @file
+ * @brief Define the famous infame FOURCC macro.
+ * @date 02.01.2004
+ * @version $Id$
+ */
+#ifndef FIRM_ADT_FOURCC_H
+#define FIRM_ADT_FOURCC_H
+
+/** define a readable fourcc code */
+#define FOURCC(a,b,c,d) ((a) | ((b) << 8) | ((c) << 16) | ((d) << 24))
+
+#endif
--- /dev/null
+/**
+ * @file
+ * @brief solves a system of linear equations
+ */
+#ifndef FIRM_ADT_GAUSSJORDAN_H
+#define FIRM_ADT_GAUSSJORDAN_H
+
+/**
+ * solves a system of linear equations and returns 0 if successful
+ *
+ * @param A the linear equations as matrix
+ * @param b the result vector, will contain the result if successful
+ */
+int firm_gaussjordansolve(double *A, double *b, int nsize);
+
+#endif
--- /dev/null
+/*
+ * Copyright (C) 1995-2007 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.
+ */
+
+/**
+ * @file
+ * @brief Hash function for pointers
+ * @author Michael Beck, Sebastian Hack
+ * @version $Id$
+ */
+#ifndef FIRM_ADT_HASHPTR_H
+#define FIRM_ADT_HASHPTR_H
+
+#include "firm_config.h"
+
+#define _FIRM_FNV_OFFSET_BASIS 2166136261U
+#define _FIRM_FNV_FNV_PRIME 16777619U
+
+/* Computing x * _FIRM_FNV_FNV_PRIME */
+#define _FIRM_FNV_TIMES_PRIME(x) \
+ (((x) << 24) + ((x) << 8) + ((x) << 7) + ((x) << 4) + ((x) << 1) + 1)
+
+static INLINE unsigned firm_fnv_hash(const unsigned char *data, unsigned bytes)
+{
+ unsigned i;
+ unsigned hash = _FIRM_FNV_OFFSET_BASIS;
+
+ for(i = 0; i < bytes; ++i) {
+ hash = _FIRM_FNV_TIMES_PRIME(hash);
+ hash ^= data[i];
+ }
+
+ return hash;
+}
+
+/**
+ * hash a pointer value: Pointer addresses are mostly aligned to 4
+ * or 8 bytes. So we remove the lowest 3 bits
+ */
+#define HASH_PTR(ptr) (((char *) (ptr) - (char *)0) >> 3)
+
+/**
+ * Hash a string.
+ * @param str The string (can be const).
+ * @param len The length of the string.
+ * @return A hash value for the string.
+ */
+#define HASH_STR(str,len) firm_fnv_hash((const unsigned char *) (str), (len))
+
+#ifdef _MSC_VER
+#pragma warning(disable:4307)
+#endif /* _MSC_VER */
+
+static INLINE unsigned _hash_combine(unsigned x, unsigned y)
+{
+ unsigned hash = _FIRM_FNV_TIMES_PRIME(_FIRM_FNV_OFFSET_BASIS);
+ hash ^= x;
+ hash = _FIRM_FNV_TIMES_PRIME(hash);
+ hash ^= y;
+ return hash;
+}
+
+#ifdef _MSC_VER
+#pragma warning(default:4307)
+#endif /* _MSC_VER */
+
+/**
+ * Make one hash value out of two others.
+ * @param a One hash value.
+ * @param b Another hash value.
+ * @return A hash value computed from the both.
+ */
+#define HASH_COMBINE(a,b) _hash_combine(a, b)
+
+#endif
--- /dev/null
+/*
+ * Copyright (C) 1995-2007 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.
+ */
+
+/**
+ * @file
+ * @date 16.03.2007
+ * @brief Generic hashset functions
+ * @author Matthias Braun
+ * @version $Id$
+ *
+ * You have to specialize this header by defining HashSet, HashSetIterator and
+ * ValueType
+ */
+#ifdef HashSet
+
+#include <stdlib.h>
+
+#ifdef DO_REHASH
+#define HashSetEntry ValueType
+#else
+typedef struct HashSetEntry {
+ ValueType data;
+ unsigned hash;
+} HashSetEntry;
+#endif
+
+typedef struct HashSet {
+ HashSetEntry *entries;
+ size_t num_buckets;
+ size_t enlarge_threshold;
+ size_t shrink_threshold;
+ size_t num_elements;
+ size_t num_deleted;
+ int consider_shrink;
+#ifndef NDEBUG
+ unsigned entries_version;
+#endif
+#ifdef ADDITIONAL_DATA
+ ADDITIONAL_DATA
+#endif
+} HashSet;
+
+typedef struct HashSetIterator {
+ HashSetEntry *current_bucket;
+ HashSetEntry *end;
+#ifndef NDEBUG
+ const HashSet *set;
+ unsigned entries_version;
+#endif
+} HashSetIterator;
+
+#ifdef DO_REHASH
+#undef HashSetEntry
+#endif
+
+#endif
--- /dev/null
+/********************************************************************
+ ********************************************************************
+ **
+ ** libhungarian by Cyrill Stachniss, 2004
+ **
+ ** Added to libFirm by Christian Wuerdig, 2006
+ ** Added several options for not-perfect matchings.
+ **
+ ** Solving the Minimum Assignment Problem using the
+ ** Hungarian Method.
+ **
+ ** ** This file may be freely copied and distributed! **
+ **
+ ** Parts of the used code was originally provided by the
+ ** "Stanford GraphGase", but I made changes to this code.
+ ** As asked by the copyright node of the "Stanford GraphGase",
+ ** I hereby proclaim that this file are *NOT* part of the
+ ** "Stanford GraphGase" distrubition!
+ **
+ ** This file is distributed in the hope that it will be useful,
+ ** but WITHOUT ANY WARRANTY; without even the implied
+ ** warranty of MERCHANTABILITY or FITNESS FOR A PARTICULAR
+ ** PURPOSE.
+ **
+ ********************************************************************
+ ********************************************************************/
+
+/**
+ * @file
+ * @brief Solving the Minimum Assignment Problem using the Hungarian Method.
+ * @version $Id$
+ */
+#ifndef FIRM_ADT_HUNGARIAN_H
+#define FIRM_ADT_HUNGARIAN_H
+
+#define HUNGARIAN_MODE_MINIMIZE_COST 0
+#define HUNGARIAN_MODE_MAXIMIZE_UTIL 1
+
+#define HUNGARIAN_MATCH_NORMAL 0
+#define HUNGARIAN_MATCH_PERFECT 1
+
+typedef struct _hungarian_problem_t hungarian_problem_t;
+
+/**
+ * This method initialize the hungarian_problem structure and init
+ * the cost matrix (missing lines or columns are filled with 0).
+ *
+ * @param rows Number of rows in the given matrix
+ * @param cols Number of cols in the given matrix
+ * @param width Element width for matrix dumping
+ * @param match_type The type of matching:
+ * HUNGARIAN_MATCH_PERFECT - every nodes matches another node
+ * HUNGARIAN_MATCH_NORMAL - matchings of nodes having no edge getting removed
+ * @return The problem object.
+ */
+hungarian_problem_t *hungarian_new(int rows, int cols, int width, int match_type);
+
+/**
+ * Adds an edge from left to right with some costs.
+ */
+void hungarian_add(hungarian_problem_t *p, int left, int right, int cost);
+
+/**
+* Removes the edge from left to right.
+*/
+void hungarian_remv(hungarian_problem_t *p, int left, int right);
+
+/**
+ * Prepares the cost matrix, dependend on the given mode.
+ *
+ * @param p The hungarian object
+ * @param mode HUNGARIAN_MODE_MAXIMIZE_UTIL or HUNGARIAN_MODE_MINIMIZE_COST (default)
+ */
+void hungarian_prepare_cost_matrix(hungarian_problem_t *p, int mode);
+
+/**
+ * Destroys the hungarian object.
+ */
+void hungarian_free(hungarian_problem_t *p);
+
+/**
+ * This method computes the optimal assignment.
+ * @param p The hungarian object
+ * @param assignment The final assignment
+ * @param final_cost The final costs
+ * @param cost_threshold Matchings with costs >= this limit will be removed (if limit > 0)
+ * @return 0 on success, negative number otherwise
+ */
+int hungarian_solve(hungarian_problem_t *p, int *assignment, int *final_cost, int cost_threshold);
+
+/**
+ * Print the cost matrix.
+ * @param p The hungarian object
+ */
+void hungarian_print_costmatrix(hungarian_problem_t *p);
+
+#endif /* _HUNGARIAN_H_ */
--- /dev/null
+/*
+ * Copyright (C) 1995-2007 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.
+ */
+
+/**
+ * @file
+ * @brief Some macros for wrapper function implementation. (WARNING deprecated)
+ * @author Sebastian Hack
+ * @date 9.12.2004
+ *
+ * Please don't use these macros, they make the code unnecessarily unreadable!
+ */
+#ifndef FIRM_ADT_IMPL_H
+#define FIRM_ADT_IMPL_H
+
+#define _MANGLE(prefix,name) prefix ## name
+
+#define INTERNAL(name) _MANGLE(_, name)
+
+
+#define _HEAD1(name,res,t1) \
+ res (name)(t1 p1)
+
+#define _HEAD2(name,res,t1,t2) \
+ res (name)(t1 p1, t2 p2)
+
+#define _HEAD3(name,res,t1,t2,t3) \
+ res (name)(t1 p1, t2 p2, t3 p3)
+
+#define _HEAD4(name,res,t1,t2,t3,t4) \
+ res (name)(t1 p1, t2 p2, t3 p3, t4 p4)
+
+
+#define _IMPL1(name,prefix,ret,res,t1) \
+_HEAD1(name, res, t1) { \
+ ret prefix ## name (p1); \
+}
+
+#define _IMPL2(name,prefix,ret,res,t1,t2) \
+_HEAD2(name, res, t1, t2) { \
+ ret prefix ## name (p1, p2); \
+}
+
+#define _IMPL3(name,prefix,ret,res,t1,t2,t3) \
+_HEAD3(name, res, t1, t2, t3) { \
+ ret prefix ## name (p1, p2, p3); \
+}
+
+#define _IMPL4(name,prefix,ret,res,t1,t2,t3,t4) \
+_HEAD4(name, res, t1, t2, t3, t4) { \
+ ret prefix ## name (p1, p2, p3, p4); \
+}
+
+#define IMPL1_VOID(name,prefix,t1) \
+ _IMPL1(name, prefix, (void), void, t1)
+
+#define IMPL2_VOID(name,prefix,t1,t2) \
+ _IMPL2(name, prefix, (void), void, t1, t2)
+
+#define IMPL3_VOID(name,prefix,t1,t2,t3) \
+ _IMPL3(name, prefix, (void), void, t1, t2, t3)
+
+#define IMPL4_VOID(name,prefix,t1,t2,t3,t4) \
+ _IMPL4(name, prefix, (void), void, t1, t2, t3, t4)
+
+
+#define IMPL1(name,type,prefix,t1) \
+ _IMPL1(name, prefix, return, type, t1)
+
+#define IMPL2(name,type,prefix,t1,t2) \
+ _IMPL2(name, prefix, return, type, t1, t2)
+
+#define IMPL3(name,type,prefix,t1,t2,t3) \
+ _IMPL3(name, prefix, return, type, t1, t2, t3)
+
+#define IMPL4(name,type,prefix,t1,t2,t3,t4) \
+ _IMPL4(name, prefix, return, type, t1, t2, t3, t4)
+
+
+#define FIRM_IMPL1(name,type,t1) \
+ _IMPL1(name, _, return, type, t1)
+
+#define FIRM_IMPL2(name,type,t1,t2) \
+ _IMPL2(name, _, return, type, t1, t2)
+
+#define FIRM_IMPL3(name,type,t1,t2,t3) \
+ _IMPL3(name, _, return, type, t1, t2, t3)
+
+#define FIRM_IMPL4(name,type,t1,t2,t3,t4) \
+ _IMPL4(name, _, return, type, t1, t2, t3, t4)
+
+
+#define FIRM_IMPL1_VOID(name,t1) \
+ _IMPL1(name, _, (void), void, t1)
+
+#define FIRM_IMPL2_VOID(name,t1,t2) \
+ _IMPL2(name, _, (void), void, t1, t2)
+
+#define FIRM_IMPL3_VOID(name,t1,t2,t3) \
+ _IMPL3(name, _, (void), void, t1, t2, t3)
+
+#define FIRM_IMPL4_VOID(name,t1,t2,t3,t4) \
+ _IMPL4(name, _, (void), void, t1, t2, t3, t4)
+
+#define FIRM_PROTO1(name,type,t1) _HEAD1(name, type, t1)
+#define FIRM_PROTO2(name,type,t1,t2) _HEAD2(name, type, t1, t2)
+#define FIRM_PROTO3(name,type,t1,t2,t3) _HEAD3(name, type, t1, t2, t3)
+#define FIRM_PROTO4(name,type,t1,t2,t3,t4) _HEAD4(name, type, t1, t2, t3, t4)
+
+#endif
--- /dev/null
+/*
+ * Copyright (C) 1995-2007 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.
+ */
+
+/**
+ * @file
+ * @brief Iterators for the several collection types used in firm.
+ * Useful for formatted and unified dumping of collections of objects.
+ * @author Sebastian Hack
+ * @date 29.11.2004
+ * @version $Id$
+ */
+#ifndef FIRM_ADT_ITERATOR_H
+#define FIRM_ADT_ITERATOR_H
+
+#include "fourcc.h"
+
+/**
+ * The iterator magic word.
+ */
+#define ITERATOR_MAGIC FOURCC('I', 'T', 'E', 'R')
+
+/**
+ * Check, if some memory object appears to be an iterator.
+ * @param ptr Some memory.
+ * @return 1, if that memory area appears to be an iterator, 0 if not.
+ */
+#define is_iterator(ptr) (((const iterator_t *) (ptr))->magic == ITERATOR_MAGIC)
+
+typedef struct _iterator_t {
+ unsigned magic;
+ void *(*start)(void *collection);
+ void *(*next)(void *collection, void *curr);
+ void (*finish)(void *collection, void *curr);
+} iterator_t;
+
+/**
+ * An iterator implementation for linked lists.
+ */
+extern const iterator_t *list_iterator;
+
+/**
+ * An iterator implementation for psets.
+ */
+extern const iterator_t *pset_iterator;
+
+#endif
--- /dev/null
+
+/**
+ * @file
+ * @brief Doubly linked lists.
+ * @version $Id$
+ *
+ * Simple doubly linked list implementation.
+ *
+ * Some of the internal functions ("__xxx") are useful when
+ * manipulating whole lists rather than single entries, as
+ * sometimes we already know the next/prev entries and we can
+ * generate better code by using them directly rather than
+ * using the generic single-entry routines.
+ */
+#ifndef FIRM_ADT_LIST_H
+#define FIRM_ADT_LIST_H
+
+#include "firm_config.h"
+
+struct list_head {
+ struct list_head *next, *prev;
+};
+
+#define LIST_HEAD_INIT(name) { &(name), &(name) }
+
+#define LIST_HEAD(name) \
+ struct list_head name = LIST_HEAD_INIT(name)
+
+#define INIT_LIST_HEAD(ptr) do { \
+ (ptr)->next = (ptr); (ptr)->prev = (ptr); \
+} while (0)
+
+#define _list_offsetof(type,member) \
+ ((char *) &(((type *) 0)->member) - (char *) 0)
+
+#define _list_container_of(ptr, type, member) \
+ ((type *) ((char *) (ptr) - _list_offsetof(type, member)))
+
+/*
+ * Insert a new entry between two known consecutive entries.
+ *
+ * This is only for internal list manipulation where we know
+ * the prev/next entries already!
+ */
+static INLINE void __list_add(struct list_head *new_node,
+ struct list_head *prev,
+ struct list_head *next)
+{
+ next->prev = new_node;
+ new_node->next = next;
+ new_node->prev = prev;
+ prev->next = new_node;
+}
+
+/**
+ * list_add - add a new entry
+ * @param new_node new entry to be added
+ * @param head list head to add it after
+ *
+ * Insert a new entry after the specified head.
+ * This is good for implementing stacks.
+ */
+static INLINE void list_add(struct list_head *new_node, struct list_head *head)
+{
+ __list_add(new_node, head, head->next);
+}
+
+/**
+ * list_add_tail - add a new entry
+ * @param new_node new entry to be added
+ * @param head list head to add it before
+ *
+ * Insert a new entry before the specified head.
+ * This is useful for implementing queues.
+ */
+static INLINE void list_add_tail(struct list_head *new_node, struct list_head *head)
+{
+ __list_add(new_node, head->prev, head);
+}
+
+/*
+ * Delete a list entry by making the prev/next entries
+ * point to each other.
+ *
+ * This is only for internal list manipulation where we know
+ * the prev/next entries already!
+ */
+static INLINE void __list_del(struct list_head * prev, struct list_head * next)
+{
+ next->prev = prev;
+ prev->next = next;
+}
+
+/**
+ * list_del - deletes entry from list.
+ * @param entry the element to delete from the list.
+ *
+ * @Note
+ * list_empty on entry does not return true after this, the entry is
+ * in an undefined state.
+ */
+static INLINE void list_del(struct list_head *entry)
+{
+ __list_del(entry->prev, entry->next);
+ entry->next = NULL;
+ entry->prev = NULL;
+}
+
+
+/**
+ * list_del_init - deletes entry from list and reinitialize it.
+ * @param entry the element to delete from the list.
+ */
+static INLINE void list_del_init(struct list_head *entry)
+{
+ __list_del(entry->prev, entry->next);
+ INIT_LIST_HEAD(entry);
+}
+
+/**
+ * list_move - delete from one list and add as another's head
+ * @param list the entry to move
+ * @param head the head that will precede our entry
+ */
+static INLINE void list_move(struct list_head *list, struct list_head *head)
+{
+ __list_del(list->prev, list->next);
+ list_add(list, head);
+}
+
+/**
+ * list_move_tail - delete from one list and add as another's tail
+ * @param list the entry to move
+ * @param head the head that will follow our entry
+ */
+static INLINE void list_move_tail(struct list_head *list,
+ struct list_head *head)
+{
+ __list_del(list->prev, list->next);
+ list_add_tail(list, head);
+}
+
+/**
+ * list_empty - tests whether a list is empty
+ * @param head the list to test.
+ */
+static INLINE int list_empty(const struct list_head *head)
+{
+ return head->next == head;
+}
+
+static INLINE void __list_splice(struct list_head *list,
+ struct list_head *head)
+{
+ struct list_head *first = list->next;
+ struct list_head *last = list->prev;
+ struct list_head *at = head->next;
+
+ first->prev = head;
+ head->next = first;
+
+ last->next = at;
+ at->prev = last;
+}
+
+/**
+ * list_splice - join two lists
+ * @param list the new list to add.
+ * @param head the place to add it in the first list.
+ */
+static INLINE void list_splice(struct list_head *list, struct list_head *head)
+{
+ if (!list_empty(list))
+ __list_splice(list, head);
+}
+
+/**
+ * list_splice_init - join two lists and reinitialize the emptied list.
+ * @param list the new list to add.
+ * @param head the place to add it in the first list.
+ *
+ * The list at list is reinitialized
+ */
+static INLINE void list_splice_init(struct list_head *list,
+ struct list_head *head)
+{
+ if (!list_empty(list)) {
+ __list_splice(list, head);
+ INIT_LIST_HEAD(list);
+ }
+}
+
+/**
+ * list_entry - get the struct for this entry
+ * @param ptr the &struct list_head pointer.
+ * @param type the type of the struct this is embedded in.
+ * @param member the name of the list_struct within the struct.
+ */
+#define list_entry(ptr, type, member) \
+ _list_container_of(ptr, type, member)
+
+/**
+ * list_for_each - iterate over a list
+ * @param pos the &struct list_head to use as a loop counter.
+ * @param head the head for your list.
+ */
+#define list_for_each(pos, head) \
+ for (pos = (head)->next; pos != (head); pos = pos->next)
+
+/**
+ * __list_for_each - iterate over a list
+ * @param pos the &struct list_head to use as a loop counter.
+ * @param head the head for your list.
+ *
+ * This variant differs from list_for_each() in that it's the
+ * simplest possible list iteration code, no ing is done.
+ * Use this for code that knows the list to be very short (empty
+ * or 1 entry) most of the time.
+ */
+#define __list_for_each(pos, head) \
+ for (pos = (head)->next; pos != (head); pos = pos->next)
+
+/**
+ * list_for_each_prev - iterate over a list backwards
+ * @param pos the &struct list_head to use as a loop counter.
+ * @param head the head for your list.
+ */
+#define list_for_each_prev(pos, head) \
+ for (pos = (head)->prev; pos != (head); pos = pos->prev)
+
+/**
+ * list_for_each_safe - iterate over a list safe against removal of list entry
+ * @param pos the &struct list_head to use as a loop counter.
+ * @param n another &struct list_head to use as temporary storage
+ * @param head the head for your list.
+ */
+#define list_for_each_safe(pos, n, head) \
+ for (pos = (head)->next, n = pos->next; pos != (head); \
+ pos = n, n = pos->next)
+
+/**
+ * list_for_each_entry - iterate over list of given type
+ * @param type the type of the struct where the listhead is embedded in
+ * @param pos the type * to use as a loop counter.
+ * @param head the head for your list.
+ * @param member the name of the list_struct within the struct.
+ */
+#define list_for_each_entry(type, pos, head, member) \
+ for (pos = list_entry((head)->next, type, member); \
+ &pos->member != (head); \
+ pos = list_entry(pos->member.next, type, member))
+
+/**
+ * list_for_each_entry_reverse - iterate backwards over list of given type.
+ * @param type the type of the struct where the listhead is embedded in
+ * @param pos the type * to use as a loop counter.
+ * @param head the head for your list.
+ * @param member the name of the list_struct within the struct.
+ */
+#define list_for_each_entry_reverse(type, pos, head, member) \
+ for (pos = list_entry((head)->prev, type, member); \
+ &pos->member != (head); \
+ pos = list_entry(pos->member.prev, type, member))
+
+
+/**
+ * list_for_each_entry_safe - iterate over list of given type safe against removal of list entry
+ * @param type the type of the struct where the listhead is embedded in
+ * @param pos the type * to use as a loop counter.
+ * @param n another type * to use as temporary storage
+ * @param head the head for your list.
+ * @param member the name of the list_struct within the struct.
+ */
+#define list_for_each_entry_safe(type, pos, n, head, member) \
+ for (pos = list_entry((head)->next, type, member), \
+ n = list_entry(pos->member.next, type, member); \
+ &pos->member != (head); \
+ pos = n, n = list_entry(n->member.next, type, member))
+
+
+#endif
--- /dev/null
+/*
+ * Copyright (C) 1995-2007 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.
+ */
+
+/**
+ * @file
+ * @brief Provied obstack_chunk_alloc and obstack_chunk_free for obstack.h
+ * @author Martin Trapp, Christian Schaefer
+ * @version $Id$
+ */
+#ifndef FIRM_ADT_OBST_H
+#define FIRM_ADT_OBST_H
+
+#include <obstack.h>
+#include "xmalloc.h"
+
+#define obstack_chunk_alloc xmalloc
+#define obstack_chunk_free free
+
+#endif
--- /dev/null
+/*
+ * Copyright (C) 1995-2007 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.
+ */
+
+/**
+ * @file
+ * @brief Implementation of offset_of and container_of
+ * @date 31.05.2005
+ * @author Sebastian Hack
+ */
+#ifndef FIRM_ADT_OFFSET_H
+#define FIRM_ADT_OFFSET_H
+
+/**
+ * Get the offset of a member of a struct.
+ * @param type The type of the struct member is in.
+ * @param member The name of the member.
+ * @return The offset of member in type in bytes.
+ */
+#define firm_offset_of(type, member) ((char *) &((type *) 0)->member - (char *) 0)
+
+/**
+ * Make pointer to the struct from a pointer to a member of that struct.
+ * @param ptr The pointer to the member.
+ * @param type The type of the struct.
+ * @param member The name of the member.
+ * @return A pointer to the struct member is in.
+ */
+#define firm_container_of(ptr, type, member) ((type *) ((char *) (ptr) - firm_offset_of(type, member)))
+
+#endif
--- /dev/null
+/*
+ * Copyright (C) 1995-2007 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.
+ */
+
+/**
+ * @file
+ * @brief double ended queue of generic pointers.
+ * @author Christian von Roques
+ * @version $Id$
+ */
+#ifndef FIRM_ADT_PDEQ_H
+#define FIRM_ADT_PDEQ_H
+
+/**
+ * The type of the pointer compare function.
+ *
+ * @param elem The list element.
+ * @param key The user supplied key.
+ *
+ * @return 0 if the element matches the key, non-zero else.
+ */
+typedef int (*cmp_fun)(const void *elem, const void *key);
+
+/**
+ * The pointer double ended queue (list).
+ */
+typedef struct pdeq pdeq;
+
+/**
+ * Creates a new double ended pointer list.
+ *
+ * @return A new list.
+ */
+pdeq *new_pdeq(void);
+
+/**
+ * Creates a new double ended pointer list and puts an initial pointer element in.
+ *
+ * @param x The pointer element to put in.
+ *
+ * @return The new list.
+ */
+pdeq *new_pdeq1(const void *x);
+
+/**
+ * Delete a double ended pointer list.
+ *
+ * @param dq The list to be deleted.
+ */
+void del_pdeq(pdeq *dq);
+
+/**
+ * Returns the lenght of a double ended pointer list.
+ *
+ * @param dq The list.
+ */
+int pdeq_len(pdeq *dq);
+
+/**
+ * Checks if a list is empty.
+ *
+ * @param dq The list.
+ *
+ * @return non-zero if the list is empty.
+ */
+int pdeq_empty(pdeq *dq);
+
+/**
+ * Returns non-zero if a double ended pointer list
+ * contains a pointer x.
+ *
+ * @param dq The list.
+ * @param x The pointer to be searched for.
+ */
+int pdeq_contains(pdeq *dq, const void *x);
+
+/**
+ * Search a key in a double ended pointer list, the search
+ * is controlled by a compare function.
+ * An element is found, if the compare function returns 0.
+ * The search is started from the left site of the list.
+ *
+ * @param qp The list.
+ * @param cmp The compare function.
+ * @param key The search key.
+ *
+ * @return The address of the element entry if the key was found,
+ * NULL else.
+ */
+void *pdeq_search(pdeq *qp, cmp_fun cmp, const void *key);
+
+/**
+ * Convert the double ended pointer list into a linear array beginning from
+ * left, the first element in the linear array will be the left one.
+ *
+ * @param qp The list.
+ * @param dst A pointer to a pointer array with must be at least
+ * pdeq_len(dq) * sizeof(void *)
+ *
+ * @return dst
+ */
+void **pdeq_copyl(pdeq *qp, const void **dst);
+
+/**
+ * Convert the double ended pointer list into a linear array beginning from
+ * right, the first element in the linear array will be the right one.
+ *
+ * @param qp The list.
+ * @param dst A pointer to a pointer array with must be at least
+ * pdeq_len(dq) * sizeof(void *)
+ *
+ * @return dst
+ */
+void **pdeq_copyr(pdeq *qp, const void **dst);
+
+/**
+ * Add a pointer to the left side of a double ended pointer list.
+ *
+ * @param dq The list to add a pointer to.
+ * @param x The pointer element to be added
+ *
+ * @return The list.
+ */
+pdeq *pdeq_putl(pdeq *dq, const void *x);
+
+/**
+ * Add a pointer to the right side of a double ended pointer list.
+ *
+ * @param dq The list to add a pointer to.
+ * @param x The pointer element to be added
+ *
+ * @return The list.
+ */
+pdeq *pdeq_putr(pdeq *dq, const void *x);
+
+/**
+ * Retrieve a pointer from the left site of a double ended pointer list.
+ *
+ * @param dq The list
+ *
+ * @return The pointer element.
+ *
+ * @remark This function will fail if the list is empty.
+ */
+void *pdeq_getl(pdeq *dq);
+
+/**
+ * Retrieve a pointer from the right site of a double ended pointer list.
+ *
+ * @param dq The list
+ *
+ * @return The pointer element.
+ *
+ * @remark This function will fail if the list is empty.
+ */
+void *pdeq_getr(pdeq *dq);
+
+#ifdef NDEBUG
+#define PDEQ_VRFY(deq) ((void)0)
+#else
+#define PDEQ_VRFY(deq) _pdeq_vrfy ((deq))
+void _pdeq_vrfy(pdeq *dq);
+#endif
+
+/**
+ * The pdeq is often used as a wait queue. A helper
+ * type to support this.
+ */
+typedef pdeq waitq;
+
+/**
+ * Creates a new pointer wait queue (fifo).
+ *
+ * @return A new queue.
+ */
+#define new_waitq() new_pdeq()
+
+/**
+ * Delete a wait queue (fifo)
+ *
+ * @param wq The wait queue.
+ */
+#define del_waitq(wq) del_pdeq(wq)
+
+/**
+ * Retrieve a pointer from the wait queue (fifo).
+ *
+ * @param wq The wait queue.
+ *
+ * @return The pointer element.
+ *
+ * @remark This function will fail if the queue is empty.
+ */
+#define waitq_get(wq) pdeq_getl(wq)
+
+/**
+ * Add a pointer to the wait queue (fifo).
+ *
+ * @param wq The wait queue
+ * @param x The pointer element to be added
+ *
+ * @return The wait queue.
+ */
+#define waitq_put(wq, x) pdeq_putr((wq), (x))
+
+/**
+ * Checks if a wait queue is empty.
+ *
+ * @param wq The wait queue.
+ *
+ * @return non-zero if the queue is empty.
+ */
+#define waitq_empty(wq) pdeq_empty(wq)
+
+/**
+ * The pdeq can be used as a stack. A helper
+ * type to support this.
+ */
+typedef pdeq stack;
+
+/**
+ * Creates a new pointer stack (lifo).
+ *
+ * @return A new stack.
+ */
+#define new_stack() new_pdeq()
+
+/**
+ * Pop a pointer from the stack (lifo).
+ *
+ * @param st The stack.
+ *
+ * @return The pointer element.
+ *
+ * @remark This function will fail if the stack is empty.
+ */
+#define stack_pop(st) pdeq_getr(st)
+
+/**
+ * Push a pointer to the stack (lifo).
+ *
+ * @param st The stack.
+ * @param x The pointer element to be added
+ *
+ * @return The stack.
+ */
+#define stack_push(st, x) pdeq_putr((st), (x))
+
+/**
+ * Checks if a stack is empty.
+ *
+ * @param st The stack.
+ *
+ * @return non-zero if the stack is empty.
+ */
+#define stack_empty(st) pdeq_empty(wq)
+
+#endif
--- /dev/null
+/*
+ * Copyright (C) 1995-2007 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.
+ */
+
+/**
+ * @file
+ * @author Kimon Hoffmann
+ * @date 14.07.2005
+ * @cvs-id $Id$
+ * @summary Simple, non circular, double linked pointer list.
+ * Created because the properties of the standard circular list were
+ * not very well suited for the interference graph implementation.
+ * This list uses an obstack and a free-list to efficiently manage its
+ * elements.
+ * @note Until now the code is entirely untested so it probably contains
+ * plenty of errors. (Matze: Is this still true, the code seems to be
+ * used at some places....)
+ */
+#ifndef FIRM_ADT_PLIST_H
+#define FIRM_ADT_PLIST_H
+
+#include <stddef.h>
+#include "obst.h"
+
+typedef struct _plist_element plist_element_t;
+typedef struct _plist plist_t;
+
+/**
+ * The plist data type.
+ */
+struct _plist {
+ /**
+ * The obstack used for all allocations.
+ */
+ struct obstack *obst;
+
+ /* Set to 1 if plist uses a foreign obstack */
+ unsigned foreign_obstack : 1;
+
+ /**
+ * First element in the list.
+ */
+ plist_element_t *first_element;
+
+ /**
+ * Last element in the list.
+ */
+ plist_element_t *last_element;
+
+ /**
+ * Current number of elements in the list.
+ */
+ int element_count;
+
+ /**
+ * First element in the free list.
+ * Please note that the free list is a single linked list and all back
+ * references are invalid.
+ */
+ plist_element_t* first_free_element;
+};
+
+/**
+ * An element in the pointer list.
+ */
+struct _plist_element {
+ plist_element_t *next;
+ plist_element_t *prev;
+ void *data;
+};
+
+/**
+ * Creates a new pointer list and initializes it.
+ * @return The newly created pointer list.
+ */
+plist_t *plist_new(void);
+
+/**
+ * Creates a new pointer list and initializes it.
+ * Uses the given obstack instead of creating one.
+ * @param obst The obstack to use
+ * @return The newly created pointer list.
+ */
+plist_t *plist_obstack_new(struct obstack *obst);
+
+/**
+ * Frees the passed pointer list.
+ * After a call to this function all references to the list and any of
+ * its elements are invalid.
+ */
+void plist_free(plist_t *list);
+
+/**
+ * Returns the number of elements in a pointer list.
+ * @param list the pointer list
+ * @return The number of elements in a pointer list.
+ */
+#define plist_count(list) \
+ ((list)->element_count)
+
+/**
+ * Inserts an element at the back of a pointer list.
+ * @param list the pointer list to append the new element to.
+ * @param value the element value to append.
+ */
+void plist_insert_back(plist_t *list, void *value);
+
+/**
+ * Inserts an element at the front of a pointer list.
+ * @param list the pointer list to prepend the new element to.
+ * @param value the element value to prepend.
+ */
+void plist_insert_front(plist_t *list, void *value);
+
+/**
+ * Inserts an element into a pointer list before the specified element,
+ * which must be non null.
+ * @param list the pointer list to insert the new element into.
+ * @param element the list element before which the new element should
+ * be inserted. This element must be a part of @p list.
+ * @param value the element value to insert.
+ */
+void plist_insert_before(plist_t *list, plist_element_t *element, void *value);
+
+/**
+ * Inserts an element into a pointer list after the specified element,
+ * which must be non null.
+ * @param list the pointer list to insert the new element into.
+ * @param element the list element after which the new element should
+ * be inserted. This element must be a part of @p list.
+ * @param value the element value to insert.
+ */
+void plist_insert_after(plist_t *list, plist_element_t *element, void *value);
+
+/**
+ * Checks if list has an element with the given data pointer.
+ * @param list the list to check
+ * @param value the data pointer to look for
+ * @return 1 if element with data pointer found, 0 otherwise
+ */
+int plist_has_value(plist_t *list, void *value);
+
+/**
+ * Tries to find list element associated to the given data pointer.
+ * @param list the list to check
+ * @param value the data pointer to look for
+ * @return The first list element associated to data pointer if found, NULL otherwise
+ */
+plist_element_t *plist_find_value(plist_t *list, void *value);
+
+/**
+ * Erases the specified element from the pointer list.
+ * @param list the pointer list from which the element should be erased.
+ * @param element the list element to erase. This element must be a part
+ * of @p list.
+ */
+void plist_erase(plist_t *list, plist_element_t *element);
+
+/**
+ * Erases all elements from the specified pointer list.
+ * @param list the pointer list that should be cleared.
+ */
+void plist_clear(plist_t *list);
+
+/**
+ * Returns the first element of a pointer list.
+ * @param list the pointer list to iterate
+ * @return a pointer to the element or NULL if the list is empty
+ */
+ #define plist_first(list) \
+ ((list)->first_element)
+
+/**
+ * Returns the last element of a pointer list.
+ * @param list the pointer list to iterate
+ * @return a pointer to the element or NULL if the list is empty
+ */
+ #define plist_last(list) \
+ ((list)->last_element)
+
+/**
+ * Checks whether a pointer list element has a successor or not.
+ * @param element the list element that should be queried for existence
+ * of a successor.
+ * @return TRUE if @p element has a successor, otherwise FALSE.
+ */
+#define plist_element_has_next(element) \
+ ((element)->next != NULL)
+
+/**
+ * Checks whether a pointer list element has a predecessor or not.
+ * @param element the list element that should be queried for existence
+ * of a predecessor.
+ * @return TRUE if @p element has a successor, otherwise FALSE.
+ */
+#define plist_element_has_prev(element) \
+ ((element)->prev != NULL)
+
+/**
+ * Gets the successor of the passed list element.
+ * @param element the list element to return the successor of.
+ * @return The successor of @p element or NULL if @p element is the last
+ * element in the sequence.
+ */
+#define plist_element_get_next(element) \
+ ((element)->next)
+
+/**
+ * Gets the predecessor of the passed list element.
+ * @param element the list element to return the predecessor of.
+ * @return The predecessor of @p element or NULL if @p element is the last
+ * element in the sequence.
+ */
+#define plist_element_get_prev(element) \
+ ((element)->prev)
+
+/**
+ * Gets the value stored in the passed list element.
+ * @param element the list element to return the value of.
+ * @return The value stored in @p element.
+ */
+#define plist_element_get_value(element) \
+ ((element)->data)
+
+/**
+ * Convenience macro to iterate over a plist.
+ */
+#define foreach_plist(list, el) \
+ for (el = plist_first(list); el; el = plist_element_get_next(el))
+
+#endif /*_PLIST_H_*/
--- /dev/null
+/*
+ * Copyright (C) 1995-2007 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.
+ */
+
+/**
+ * @file
+ * @brief Simplified hashnap for pointer->pointer relations
+ * @author Hubert Schmid
+ * @date 09.06.2002
+ * @version $Id$
+ */
+#ifndef FIRM_ADT_PMAP_H
+#define FIRM_ADT_PMAP_H
+
+/** A map which maps addresses to addresses. */
+typedef struct pmap pmap;
+
+/**
+ * A key, value pair.
+ */
+typedef struct pmap_entry {
+ const void *key; /**< The key. */
+ void *value; /**< The value. */
+} pmap_entry;
+
+
+/** Creates a new empty map. */
+pmap *pmap_create(void);
+
+/** Creates a new empty map with an initial number of slots. */
+pmap *pmap_create_ex(int slots);
+
+/** Deletes a map. */
+void pmap_destroy(pmap *);
+
+/**
+ * Inserts a pair (key,value) into the map. If an entry with key
+ * "key" already exists, its "value" is overwritten.
+ */
+void pmap_insert(pmap *map, const void * key, void * value);
+
+/** Checks if an entry with key "key" exists. */
+int pmap_contains(pmap *map, const void * key);
+
+/** Returns the key, value pair of "key". */
+pmap_entry * pmap_find(pmap *map, const void * key);
+
+/** Returns the value of "key". */
+void * pmap_get(pmap *map, const void * key);
+
+int pmap_count(pmap *map);
+
+/**
+ * Returns the first entry of a map if the map is not empty.
+ */
+pmap_entry *pmap_first(pmap *map);
+
+/**
+ * Returns the next entry of a map or NULL if all entries were visited.
+ */
+pmap_entry *pmap_next(pmap *);
+
+#define pmap_foreach(pmap, curr) \
+ for (curr = pmap_first(pmap); curr; curr = pmap_next(pmap))
+
+/** Breaks an iteration.
+ * Must be called, if a iteration ends before p_map_next() returns NULL.
+ */
+void pmap_break(pmap *map);
+
+#endif
--- /dev/null
+/*
+ * Copyright (C) 1995-2007 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.
+ */
+
+/**
+ * @file
+ * @date 18.04.2007
+ * @author Christian Wuerdig
+ * @brief Implementation of a priority queue. This is the ported version of the
+ * original Java implementation by Matthias Braun.
+ * @version $Id$
+ */
+#ifndef FIRM_ADT_PQUEUE_H
+#define FIRM_ADT_PQUEUE_H
+
+typedef struct _pqueue_t pqueue;
+
+/**
+ * Creates a new priority queue.
+ * @return A priority queue of initial length 0.
+ */
+pqueue *new_pqueue(void);
+
+/**
+ * Frees all memory allocated by the priority queue.
+ * @param q The priority queue to destroy.
+ */
+void del_pqueue(pqueue *q);
+
+/**
+ * Inserts a new element into a priority queue.
+ * @param q The priority queue the element should be inserted to.
+ * @param data The actual data which should be stored in the queue.
+ * @param key The priority for the data.
+ */
+void pqueue_put(pqueue *q, void *data, int key);
+
+/**
+ * Returns and removes the first element, ie. that one with the highest priority, from the queue.
+ * @param q The priority queue.
+ * @return The first element of the queue. Asserts if queue is empty.
+ */
+void *pqueue_get(pqueue *q);
+
+/**
+ * Get the length of the priority queue.
+ * @param q The priority queue.
+ * @return The length of the queue.
+ */
+int pqueue_length(pqueue *q);
+
+/**
+ * Returns true if queue is empty.
+ * @param q The priority queue.
+ * @return 1 if the queue is empty, 0 otherwise.
+ */
+int pqueue_empty(pqueue *q);
+
+#endif
--- /dev/null
+/*
+ * Copyright (C) 1995-2007 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.
+ */
+
+/**
+ * @file
+ * @brief optimized version of set for sets containing only pointers
+ * (deprecated)
+ * @author Markus Armbruster
+ * @version $Id$
+ * @note This code has been deprecated. Use pset_new or cpset for new
+ * code.
+ */
+#ifndef FIRM_ADT_PSET_H
+#define FIRM_ADT_PSET_H
+
+#include <stddef.h>
+
+#include "hashptr.h"
+#include "iterator.h"
+
+/**
+ * The default comparison function for pointers.
+ * @param x A pointer.
+ * @param y A pointer.
+ * @return 0 if @p x and @p y are equal. Some value != 0 otherwise.
+ */
+int pset_default_ptr_cmp(const void *x, const void *y);
+
+/**
+ * The abstract type of a pset (Set of pointers).
+ *
+ * This kind of sets stores only pointer to elements, the elements itself
+ * must be stored somewhere else.
+ *
+ * @see set
+ */
+typedef struct pset pset;
+
+/*
+ * Define some convenience macros using the predefined hash function.
+ */
+#define pset_insert_ptr(set,key) pset_insert(set, key, HASH_PTR(key))
+#define pset_hinsert_ptr(set,key) pset_hinsert(set, key, HASH_PTR(key))
+#define pset_remove_ptr(set,key) pset_remove(set, key, HASH_PTR(key))
+#define pset_find_ptr(set,key) pset_find(set, key, HASH_PTR(key))
+#define pset_new_ptr(slots) new_pset(pset_default_ptr_cmp, slots)
+#define pset_new_ptr_default() pset_new_ptr(64)
+
+/** The entry of a pset, representing an element pointer in the set and it's meta-information */
+typedef struct {
+ unsigned hash;
+ void *dptr;
+} pset_entry;
+
+/**
+ * The type of a set compare function.
+ *
+ * @param elt pointer to an element
+ * @param key pointer to another element
+ *
+ * @return
+ * 0 if the elements are identically, non-zero else
+ */
+typedef int (*pset_cmp_fun) (const void *elt, const void *key);
+
+/**
+ * Creates a new pset.
+ *
+ * @param func The compare function of this pset.
+ * @param slots Initial number of collision chains. I.e., #slots
+ * different keys can be hashed without collisions.
+ *
+ * @returns
+ * created pset
+ */
+pset *new_pset (pset_cmp_fun func, int slots);
+
+/**
+ * Deletes a pset.
+ *
+ * @param pset the pset
+ *
+ * @note
+ * This does NOT delete the elements of this pset, just it's pointers!
+ */
+void del_pset (pset *pset);
+
+/**
+ * Returns the number of elements in a pset.
+ *
+ * @param pset the pset
+ */
+int pset_count (pset *pset);
+
+/**
+ * Searches an element pointer in a pset.
+ *
+ * @param pset the pset to search in
+ * @param key the element to search
+ * @param hash the hash value of key
+ *
+ * @return
+ * the pointer of the found element in the pset or NULL if it was not found
+ */
+void *pset_find (pset *pset, const void *key, unsigned hash);
+
+/**
+ * Inserts an element pointer into a pset.
+ *
+ * @param pset the pset to insert in
+ * @param key a pointer to the element to be inserted
+ * @param hash the hash-value of the element
+ *
+ * @return a pointer to the inserted element
+ *
+ * @note
+ * It is not possible to insert an element more than once. If an element
+ * that should be inserted is already in the set, this functions does
+ * nothing but returning its already existing set_entry.
+
+ */
+void *pset_insert (pset *pset, const void *key, unsigned hash);
+
+/**
+ * Inserts an element pointer into a pset and returns its pset_entry.
+ *
+ * @param pset the pset to insert in
+ * @param key a pointer to the element to be inserted
+ * @param hash the hash-value of the element
+ *
+ * @return a pointer to the pset_entry of the inserted element
+ *
+ * @note
+ * It is not possible to insert an element more than once. If an element
+ * that should be inserted is already in the pset, this functions does
+ * nothing but returning its pset_entry.
+ */
+pset_entry *pset_hinsert (pset *pset, const void *key, unsigned hash);
+
+/**
+ * Removes an element from a pset.
+ *
+ * @param pset the pset to delete in
+ * @param key a pointer to the element to be deleted
+ * @param hash the hash-value of the element
+ *
+ * @return
+ * the pointer to the removed element
+ *
+ * @remark
+ * The current implementation did not allow to remove non-existing elements.
+ * @@@ so, does it do now?
+ * Further, it is allowed to remove elements during an iteration
+ * including the current one.
+ */
+void *pset_remove (pset *pset, const void *key, unsigned hash);
+
+/**
+ * Returns the first element of a pset.
+ *
+ * @param pset the pset to iterate
+ *
+ * @return a pointer to the element or NULL if the set is empty
+ */
+void *pset_first (pset *pset);
+
+/**
+ * Returns the next element of a pset.
+ *
+ * @param pset the pset to iterate
+ *
+ * @return a pointer to the next element or NULL if the
+ * iteration is finished
+ */
+void *pset_next (pset *pset);
+
+/**
+ * Breaks the iteration of a set. Must be called before
+ * the next pset_first() call if the iteration was NOT
+ * finished.
+ *
+ * @param pset the pset
+ */
+void pset_break (pset *pset);
+
+/**
+ * Iterates oven an pset.
+ *
+ * @param pset the pset
+ * @param entry the iterator
+ */
+#define foreach_pset(pset, entry) for (entry = pset_first(pset); entry; entry = pset_next(pset))
+
+/**
+ * Inserts all elements of the pointer set src into
+ * the set target (union).
+ *
+ * @param target the target set, will contain the union
+ * @param src a set, will not be changed
+ */
+void pset_insert_pset_ptr(pset *target, pset *src);
+
+#define new_pset(cmp, slots) (PSET_TRACE (new_pset) ((cmp), (slots)))
+#define pset_find(pset, key, hash) \
+ _pset_search ((pset), (key), (hash), _pset_find)
+#define pset_insert(pset, key, hash) \
+ _pset_search ((pset), (key), (hash), _pset_insert)
+#define pset_hinsert(pset, key, hash) \
+ ((pset_entry *)_pset_search ((pset), (key), (hash), _pset_hinsert))
+
+#ifdef STATS
+/**
+ * Prints statistics on a set to stdout.
+ *
+ * @param pset the pset
+ */
+void pset_stats (pset *pset);
+#else
+# define pset_stats(s) ((void)0)
+#endif
+
+#ifdef DEBUG
+/**
+ * Describe a pset.
+ *
+ * Writes a description of a set to stdout. The description includes:
+ * - a header telling how many elements (nkey) and segments (nseg) are in use
+ * - for every collision chain the number of element with its hash values
+ *
+ * @param pset the pset
+ */
+void pset_describe (pset *pset);
+#endif
+
+/* @@@ NYI */
+#define PSET_VRFY(pset) (void)0
+
+
+/* Private */
+
+typedef enum { _pset_find, _pset_insert, _pset_hinsert } _pset_action;
+
+void *_pset_search (pset *, const void *, unsigned, _pset_action);
+
+#if defined(DEBUG) && defined(HAVE_GNU_MALLOC)
+extern const char *pset_tag;
+# ifdef PSET_ID
+# define PSET_TRACE pset_tag = SET_ID,
+# else
+# define PSET_TRACE pset_tag = __FILE__,
+# endif
+#else /* !(DEBUG && HAVE_GNU_MALLOC) */
+# define PSET_TRACE
+#endif /* !(DEBUG && HAVE_GNU_MALLOC) */
+
+#endif
--- /dev/null
+/*
+ * Copyright (C) 1995-2007 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.
+ */
+
+/**
+ * @file
+ * @date 17.03.2007
+ * @brief hashset containing pointers
+ * @author Matthias Braun
+ * @version $Id$
+ *
+ * @note This has been named pset_new_new for now until all code has been
+ * changed to use this instead of the old deprecated pset_new functions!
+ * This version performs better than pset in terms of speed and memory
+ * usage and allows multiple iterators over the set
+ */
+#ifndef FIRM_ADT_PSET_NEW_H
+#define FIRM_ADT_PSET_NEW_H
+
+#define HashSet pset_new_t
+#define HashSetIterator pset_new_iterator_t
+#define ValueType void*
+#define DO_REHASH
+#include "hashset.h"
+#undef DO_REHASH
+#undef HashSet
+#undef HashSetIterator
+#undef ValueType
+
+/**
+ * Initializes a pset_new
+ *
+ * @param pset_new Pointer to allocated space for the pset_new
+ */
+void pset_new_init(pset_new_t *pset_new);
+
+/**
+ * Initializes a pset_new
+ *
+ * @param pset_new Pointer to allocated space for the pset_new
+ * @param expected_elements Number of elements expected in the pset_new (roughly)
+ */
+void pset_new_init_size(pset_new_t *pset_new, size_t expected_elements);
+
+/**
+ * Destroys a pset_new and frees the memory allocated for hashtable. The memory of
+ * the pset_new itself is not freed.
+ *
+ * @param pset_new Pointer to the pset_new
+ */
+void pset_new_destroy(pset_new_t *pset_new);
+
+/**
+ * Inserts an element into a pset_new.
+ *
+ * @param pset_new Pointer to the pset_new
+ * @param ptr Pointer to insert into the pset_new
+ * @returns 1 if the pointer was inserted, 0 if it was already there
+ */
+int pset_new_insert(pset_new_t *pset_new, void *ptr);
+
+/**
+ * Removes an element from a pset_new. Does nothing if the pset_new doesn't contain the
+ * element.
+ *
+ * @param pset_new Pointer to the pset_new
+ * @param ptr Pointer to remove from the pset_new
+ */
+void pset_new_remove(pset_new_t *pset_new, const void *ptr);
+
+/**
+ * Tests whether a pset_new contains a pointer
+ *
+ * @param pset_new Pointer to the pset_new
+ * @param ptr The pointer to test
+ * @returns 1 @p pset_new contains the @p ptr, 0 otherwise
+ */
+int pset_new_contains(const pset_new_t *pset_new, const void *ptr);
+
+/**
+ * Returns the number of pointers contained in the pset_new
+ *
+ * @param pset_new Pointer to the pset_new
+ * @returns Number of pointers contained in the pset_new
+ */
+size_t pset_new_size(const pset_new_t *pset_new);
+
+/**
+ * Initializes a pset_new iterator. Sets the iterator before the first element in
+ * the pset_new.
+ *
+ * @param iterator Pointer to already allocated iterator memory
+ * @param pset_new Pointer to the pset_new
+ */
+void pset_new_iterator_init(pset_new_iterator_t *iterator, const pset_new_t *pset_new);
+
+/**
+ * Advances the iterator and returns the current element or NULL if all elements
+ * in the pset_new have been processed.
+ * @attention It is not allowed to use pset_new_insert or pset_new_remove while
+ * iterating over a pset_new; pset_new_remove_iter is allowed.
+ *
+ * @param iterator Pointer to the pset_new iterator.
+ * @returns Next element in the pset_new or NULL
+ */
+void* pset_new_iterator_next(pset_new_iterator_t *iterator);
+
+/**
+ * Removes the element that the iterator currently points to from the hashset.
+ *
+ * @param pset_new Pointer to the pset_new
+ * @param iterator Pointer to the iterator
+ */
+void pset_new_remove_iterator(pset_new_t *pset_new, const pset_new_iterator_t *iterator);
+
+/**
+ * Convenience macro for iterating over a pset_new.
+ */
+#define foreach_pset_new(pset_new, ptr, iter) \
+ for(pset_new_iterator_init(&iter, pset_new), \
+ ptr = pset_new_iterator_next(&iter); \
+ ptr != NULL; ptr = pset_new_iterator_next(&iter))
+
+#endif
--- /dev/null
+/*
+ * Copyright (C) 1995-2007 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.
+ */
+
+/**
+ * @file
+ * @brief helper functions for working with raw bitsets
+ * @date 15.10.2004
+ * @author Matthias Braun
+ * @version $Id$
+ * @summary
+ * Raw bitsets are constructed from int arrays. Additional information
+ * like the size of the bitset or the used memory aren't saved for
+ * efficiency reasons.
+ *
+ * These bitsets need less space than bitset_t and their representation
+ * as int arrays allows having constant bitsets in the ro data segment.
+ * They should for smaller bitset, whose length is known through other means
+ * (a typical usage case is a set of cpu registers)
+ *
+ * The bitset is built as an array of unsigned integers. It is assumed that
+ * exactly 32 bits may be put into each element of the array. If there are
+ * remaining bits, then they should be 0
+ */
+#ifndef FIRM_ADT_RAW_BITSET_H
+#define FIRM_ADT_RAW_BITSET_H
+
+#include <assert.h>
+#include "bitset.h"
+#include "bitset_std.h"
+#include "obst.h"
+
+#define BITS_PER_ELEM 32
+#define BITSET_SIZE_ELEMS(size_bits) ((size_bits)/32 + 1)
+#define BITSET_SIZE_BYTES(size_bits) (BITSET_SIZE_ELEMS(size_bits)*4)
+#define BITSET_ELEM(bitset,pos) bitset[pos / 32]
+
+/**
+ * Allocate an empty raw bitset on the stack.
+ *
+ * @param res will contain the newly allocated bitset
+ * @param size element size of the bitset
+ */
+#define rbitset_alloca(res, size) \
+do { \
+ unsigned size_bytes = BITSET_SIZE_BYTES(size); \
+ res = alloca(size_bytes); \
+ memset(res, 0, size_bytes); \
+} while(0)
+
+/**
+ * Allocate an empty raw bitset on an obstack.
+ *
+ * @param obst the obstack where the bitset is allocated on
+ * @param size element size of the bitset
+ *
+ * @return the new bitset
+ */
+static INLINE unsigned *rbitset_obstack_alloc(struct obstack *obst, unsigned size) {
+ unsigned size_bytes = BITSET_SIZE_BYTES(size);
+ unsigned *res = obstack_alloc(obst, size_bytes);
+ memset(res, 0, size_bytes);
+
+ return res;
+}
+
+/**
+ * Duplicate a raw bitset on an obstack.
+ *
+ * @param obst the obstack where the bitset is allocated on
+ * @param old_bitset the bitset to be duplicated
+ * @param size element size of the bitset
+ *
+ * @return the new bitset
+ */
+static INLINE
+unsigned *rbitset_duplicate_obstack_alloc(struct obstack *obst,
+ const unsigned *old_bitset,
+ unsigned size)
+{
+ unsigned size_bytes = BITSET_SIZE_BYTES(size);
+ unsigned *res = obstack_alloc(obst, size_bytes);
+ memcpy(res, old_bitset, size_bytes);
+
+ return res;
+}
+
+/**
+ * Set a bit at position pos.
+ *
+ * @param bitset the bitset
+ * @param pos the position of the bit to be set
+ */
+static INLINE void rbitset_set(unsigned *bitset, unsigned pos) {
+ BITSET_ELEM(bitset,pos) |= 1 << (pos % BITS_PER_ELEM);
+}
+
+/**
+ * Clear a bit at position pos.
+ *
+ * @param bitset the bitset
+ * @param pos the position of the bit to be clear
+ */
+static INLINE void rbitset_clear(unsigned *bitset, unsigned pos) {
+ BITSET_ELEM(bitset, pos) &= ~(1 << (pos % BITS_PER_ELEM));
+}
+
+/**
+ * Check if a bit is set at position pos.
+ *
+ * @param bitset the bitset
+ * @param pos the position of the bit to check
+ */
+static INLINE int rbitset_is_set(const unsigned *bitset, unsigned pos) {
+ return BITSET_ELEM(bitset, pos) & (1 << (pos % BITS_PER_ELEM));
+}
+
+/**
+ * Calculate the number of set bits (number of elements).
+ *
+ * @param bitset the bitset
+ */
+static INLINE unsigned rbitset_popcnt(const unsigned *bitset, unsigned size) {
+ unsigned pos;
+ unsigned n = BITSET_SIZE_ELEMS(size);
+ unsigned res = 0;
+ const unsigned *elem = bitset;
+
+ for(pos = 0; pos < n; ++pos) {
+ res += _bitset_inside_pop(elem);
+ elem++;
+ }
+
+ return res;
+}
+
+static INLINE unsigned rbitset_next(const unsigned *bitset, unsigned pos, int set) {
+ unsigned p;
+ unsigned elem_pos = pos / BITS_PER_ELEM;
+ unsigned bit_pos = pos % BITS_PER_ELEM;
+
+ unsigned elem = bitset[elem_pos];
+
+ /*
+ * Mask out the bits smaller than pos in the current unit.
+ * We are only interested in bits set higher than pos.
+ */
+ unsigned in_elem_mask = (1 << bit_pos) - 1;
+
+ if(!set)
+ elem = ~elem;
+ p = _bitset_inside_ntz_value(elem & ~in_elem_mask);
+
+ /* If there is a bit set in the current elem, exit. */
+ if(p < BITS_PER_ELEM) {
+ return elem_pos * BITS_PER_ELEM + p;
+ }
+
+ /* Else search for set bits in the next units. */
+ while(1) {
+ elem_pos++;
+ elem = bitset[elem_pos];
+ if(!set)
+ elem = ~elem;
+
+ p = _bitset_inside_ntz_value(elem);
+ if(p < BITS_PER_ELEM) {
+ return elem_pos * BITS_PER_ELEM + p;
+ }
+ }
+
+ assert(0);
+ return 0xdeadbeef;
+}
+
+/**
+ * Inplace Intersection of two sets.
+ */
+static INLINE void rbitset_and(unsigned *bitset1, const unsigned *bitset2,
+ unsigned size)
+{
+ unsigned i, n = BITSET_SIZE_ELEMS(size);
+
+ for(i = 0; i < n; ++i) {
+ bitset1[i] &= bitset2[i];
+ }
+}
+
+/**
+ * Inplace Union of two sets.
+ */
+static INLINE void rbitset_or(unsigned *bitset1, const unsigned *bitset2,
+ unsigned size)
+{
+ unsigned i, n = BITSET_SIZE_ELEMS(size);
+
+ for(i = 0; i < n; ++i) {
+ bitset1[i] |= bitset2[i];
+ }
+}
+
+/**
+ * Remove all bits in bitset2 from bitset 1.
+ */
+static INLINE void rbitset_andnot(unsigned *bitset1, const unsigned *bitset2,
+ unsigned size)
+{
+ unsigned i, n = BITSET_SIZE_ELEMS(size);
+
+ for(i = 0; i < n; ++i) {
+ bitset1[i] &= ~bitset2[i];
+ }
+}
+
+/**
+ * Xor of two bitsets.
+ */
+static INLINE void rbitset_xor(unsigned *bitset1, const unsigned *bitset2,
+ unsigned size)
+{
+ unsigned i, n = BITSET_SIZE_ELEMS(size);
+
+ for(i = 0; i < n; ++i) {
+ bitset1[i] ^= bitset2[i];
+ }
+}
+
+/**
+ * Copy a raw bitset into an bitset.
+ *
+ * @deprecated
+ */
+static INLINE void rbitset_copy_to_bitset(const unsigned *rbitset, bitset_t *bitset) {
+ // TODO optimize me (or remove me)
+ unsigned i, n = bitset_size(bitset);
+ for(i = 0; i < n; ++i) {
+ if(rbitset_is_set(rbitset, i))
+ bitset_set(bitset, i);
+ }
+}
+
+#endif /* FIRM_ADT_RAW_BITSET_H */
--- /dev/null
+/*
+ * Copyright (C) 1995-2007 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.
+ */
+
+/**
+ * @file
+ * @brief hashset: datastructure containing objects accessible by their key
+ * @author Markus Armbruster
+ * @verison $Id$
+ */
+#ifndef FIRM_ADT_SET_H
+#define FIRM_ADT_SET_H
+
+#include <stddef.h>
+
+/**
+ * The abstract type of a set.
+ *
+ * This sets stores copies of its elements, so there is no need
+ * to store the elements after they were added to a set.
+ *
+ * @see pset
+ */
+typedef struct set set;
+
+/** The entry of a set, representing an element in the set and it's meta-information */
+typedef struct set_entry {
+ unsigned hash; /**< the hash value of the element */
+ size_t size; /**< the size of the element */
+ int dptr[1]; /**< the element itself, data copied in must not need more
+ alignment than this */
+} set_entry;
+
+/**
+ * The type of a set compare function.
+ *
+ * @param elt pointer to an element
+ * @param key pointer to another element
+ * @param size size of the elements
+ *
+ * @return
+ * 0 if the elements are identically, non-zero else
+ *
+ * @note
+ * Although it is possible to define different meanings of equality
+ * of two elements of a set, they can be only equal if their sizes are
+ * are equal. This is checked before the compare function is called.
+ */
+typedef int (*set_cmp_fun) (const void *elt, const void *key, size_t size);
+
+/**
+ * Creates a new set.
+ *
+ * @param func The compare function of this set.
+ * @param slots Initial number of collision chains. I.e., #slots
+ * different keys can be hashed without collisions.
+ *
+ * @returns
+ * created set
+ */
+set *new_set (set_cmp_fun func, int slots);
+
+/**
+ * Deletes a set and all elements of it.
+ */
+void del_set (set *set);
+
+/**
+ * Returns the number of elements in a set.
+ *
+ * @param set the set
+ */
+int set_count (set *set);
+
+/**
+ * Searches an element in a set.
+ *
+ * @param set the set to search in
+ * @param key the element to is searched
+ * @param size the size of key
+ * @param hash the hash value of key
+ *
+ * @return
+ * The address of the found element in the set or NULL if it was not found.
+ */
+void *set_find (set *set, const void *key, size_t size, unsigned hash);
+
+/**
+ * Inserts an element into a set.
+ *
+ * @param set the set to insert in
+ * @param key a pointer to the element to be inserted. Element is copied!
+ * @param size the size of the element that should be inserted
+ * @param hash the hash-value of the element
+ *
+ * @return a pointer to the inserted element
+ *
+ * @note
+ * It is not possible to insert one element more than once. If an element
+ * that should be inserted is already in the set, this functions does
+ * nothing but returning its pointer.
+ */
+void *set_insert (set *set, const void *key, size_t size, unsigned hash);
+
+/**
+ * Inserts an element into a set and returns its set_entry.
+ *
+ * @param set the set to insert in
+ * @param key a pointer to the element to be inserted. Element is copied!
+ * @param size the size of the element that should be inserted
+ * @param hash the hash-value of the element
+ *
+ * @return a pointer to the set_entry of the inserted element
+ *
+ * @note
+ * It is not possible to insert an element more than once. If an element
+ * that should be inserted is already in the set, this functions does
+ * nothing but returning its set_entry.
+ */
+set_entry *set_hinsert (set *set, const void *key, size_t size, unsigned hash);
+
+/**
+ * Inserts an element into a set, zero-terminate it and returns its set_entry.
+ *
+ * @param set the set to insert in
+ * @param key a pointer to the element to be inserted. Element is copied!
+ * @param size the size of the element that should be inserted
+ * @param hash the hash-value of the element
+ *
+ * @return a pointer to the set_entry of the inserted element
+ *
+ * @note
+ * It is not possible to insert on element more than once. If an element
+ * that should be inserted is already in the set, this functions does
+ * nothing but returning its set_entry.
+ */
+set_entry *set_hinsert0 (set *set, const void *key, size_t size, unsigned hash);
+
+/**
+ * Returns the first element of a set.
+ *
+ * @param set the set to iterate
+ *
+ * @return a pointer to the element or NULL if the set is empty
+ */
+void *set_first (set *set);
+
+/**
+ * Returns the next element of a set.
+ *
+ * @param set the set to iterate
+ *
+ * @return a pointer to the next element or NULL if the
+ * iteration is finished
+ */
+void *set_next (set *set);
+
+/**
+ * Breaks the iteration of a set. Must be called before
+ * the next set_first() call if the iteration was NOT
+ * finished.
+ *
+ * @param set the set
+ */
+void set_break (set *set);
+
+/**
+ * Iterates over an set.
+ *
+ * @param set the set
+ * @param entry the iterator
+ */
+#define foreach_set(set, entry) for (entry = set_first(set); entry; entry = set_next(set))
+
+/* implementation specific */
+#define new_set(cmp, slots) (SET_TRACE (new_set) ((cmp), (slots)))
+#define set_find(set, key, size, hash) \
+ _set_search ((set), (key), (size), (hash), _set_find)
+#define set_insert(set, key, size, hash) \
+ _set_search ((set), (key), (size), (hash), _set_insert)
+#define set_hinsert(set, key, size, hash) \
+ ((set_entry *)_set_search ((set), (key), (size), (hash), _set_hinsert))
+#define set_hinsert0(set, key, size, hash) \
+ ((set_entry *)_set_search ((set), (key), (size), (hash), _set_hinsert0))
+
+#define SET_VRFY(set) (void)0
+
+#ifdef STATS
+/**
+ * Prints statistics on a set to stdout.
+ *
+ * @param set the set
+ */
+void set_stats (set *set);
+#else
+# define set_stats(s) ((void)0)
+#endif
+
+#ifdef DEBUG
+/**
+ * Describe a set.
+ *
+ * Writes a description of a set to stdout. The description includes:
+ * - a header telling how many elements (nkey) and segments (nseg) are in use
+ * - for every collision chain the number of element with its hash values
+ *
+ * @param set the set
+ */
+void set_describe (set *set);
+#endif
+
+
+/* Private */
+
+typedef enum { _set_find, _set_insert, _set_hinsert, _set_hinsert0 } _set_action;
+
+void *_set_search (set *, const void *, size_t, unsigned, _set_action);
+
+#if defined(DEBUG) && defined(HAVE_GNU_MALLOC)
+extern const char *set_tag;
+# ifdef SET_ID
+# define SET_TRACE set_tag = SET_ID,
+# else
+# define SET_TRACE set_tag = __FILE__,
+# endif
+#else /* !(DEBUG && HAVE_GNU_MALLOC) */
+# define SET_TRACE
+#endif /* !(DEBUG && HAVE_GNU_MALLOC) */
+
+#endif
--- /dev/null
+/*
+ * Copyright (C) 1995-2007 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.
+ */
+
+/**
+ * @file
+ * @brief Union-Find datastructure
+ * @author Matthias Braun
+ * @version $Id$
+ * @summary
+ * Union-Find datastructure
+ *
+ * This implementation uses weighted sets and path compression which results
+ * in (nearly) O(n) complexity for n find and union operations
+ */
+#ifndef FIRM_ADT_UNIONFIND_H
+#define FIRM_ADT_UNIONFIND_H
+
+#include <assert.h>
+
+/**
+ * Call this to initialize an array of @p count elements to be used by the
+ * union find functions.
+ *
+ * @param data The array (you have to allocate it yourself)
+ * @param from The first element that should be initialized
+ * @param to the index of the first element which is not initialized anymore
+ */
+static INLINE void uf_init(int* data, int from, int to) {
+ int i;
+ for(i = from; i < to; ++i) {
+ data[i] = -1;
+ }
+}
+
+/**
+ * Merge 2 sets (union operation). Note that you have to pass the
+ * representatives of the sets and not just random elements
+ *
+ * @param data The union find data
+ * @param set1 Representative of set1
+ * @param set2 Representative of set2
+ * @return 0 if the new union set is represented by set1, 1 if it is
+ * represented by set2
+ */
+static INLINE int uf_union(int* data, int set1, int set2) {
+ int d1 = data[set1];
+ int d2 = data[set2];
+ int newcount;
+
+ if(set1 == set2)
+ return 0;
+
+ /* need 2 set representatives */
+ assert(d1 < 0 && d2 < 0);
+
+ newcount = d1 + d2;
+ if(d1 > d2) {
+ data[set1] = set2;
+ data[set2] = newcount;
+ return 1;
+ } else {
+ data[set2] = set1;
+ data[set1] = newcount;
+ return 0;
+ }
+}
+
+/**
+ * Finds the representative for the set with member @p e.
+ * The representative of a set is unique, so if the find operations finds
+ * the same/different representatives, then the elements are in the
+ * the same/different sets.
+ *
+ * @param data The union find data
+ * @param e The element
+ * @return The representative of the set that contains @p e
+ */
+static INLINE int uf_find(int* data, int e) {
+ /* go through list to find representative */
+ int repr = e;
+ while(data[repr] >= 0) {
+ repr = data[repr];
+ }
+
+ /* update list to point to new representative (path compression) */
+ while(e != repr) {
+ int next = data[e];
+ data[e] = repr;
+ e = next;
+ }
+
+ return repr;
+}
+
+#endif /* FIRM_ADT_UNIONFIND_H */
--- /dev/null
+/*
+ * Copyright (C) 1995-2007 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.
+ */
+
+/**
+ * @file
+ * @date 31.05.2005
+ * @author Sebastian Hack
+ * @brief Some utility macros.
+ */
+#ifndef FIRM_ADT_UTIL_H
+#define FIRM_ADT_UTIL_H
+
+#include "firm_config.h"
+
+/**
+ * Get the offset of a member of a struct.
+ * @param type The type of the struct member is in.
+ * @param member The name of the member.
+ * @return The offset of member in type in bytes.
+ */
+#define offset_of(type, member) \
+ ((char *) &(((type *) 0)->member) - (char *) 0)
+
+/**
+ * Make pointer to the struct from a pointer to a member of that struct.
+ * @param ptr The pointer to the member.
+ * @param type The type of the struct.
+ * @param member The name of the member.
+ * @return A pointer to the struct member is in.
+ */
+#define container_of(ptr, type, member) \
+ ((type *) ((char *) (ptr) - offset_of(type, member)))
+
+/**
+ * Get the number of elements of a static array.
+ * @param arr The static array.
+ * @return The number of elements in that array.
+ */
+#define array_size(arr) \
+ (sizeof(arr) / sizeof((arr)[0]))
+
+/**
+ * Asserts that the constant expression x is not zero at compiletime. name has
+ * to be a unique identifier.
+ *
+ * @note This uses the fact, that double case labels are not allowed.
+ */
+#define COMPILETIME_ASSERT(x, name) \
+ static __attribute__((unused)) void compiletime_assert_##name (int h) { \
+ switch(h) { case 0: case (x): ; } \
+ }
+
+#ifdef __GNUC__
+/**
+ * Indicates to the compiler that the value of x is very likely 1
+ * @note Only use this in speed critical code and when you are sure x is often 1
+ */
+#define LIKELY(x) __builtin_expect((x), 1)
+
+/**
+ * Indicates to the compiler that it's very likely that x is 0
+ * @note Only use this in speed critical code and when you are sure x is often 0
+ */
+#define UNLIKELY(x) __builtin_expect((x), 0)
+#else
+#define LIKELY(x) x
+#define UNLIKELY(x) x
+#endif
+
+#endif
--- /dev/null
+/*
+ * Copyright (C) 1995-2007 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.
+ */
+
+/**
+ * @file
+ * @brief never failing wrappers for malloc() & friends.
+ * @author Markus Armbruster
+ * @version $Id$
+ * @note The functions here never fail because they simply abort your
+ * program in case of an error.
+ */
+#ifndef FIRM_ADT_XMALLOC_H
+#define FIRM_ADT_XMALLOC_H
+
+#include <stddef.h>
+
+/* xmalloc() & friends. */
+
+void *xmalloc(size_t size);
+void *xcalloc(size_t num, size_t size);
+void *xrealloc(void *ptr, size_t size);
+char *xstrdup(const char *str);
+void free(void *ptr);
+
+#define xfree(ptr) free(ptr)
+
+
+/* Includes for alloca() */
+#if defined(__FreeBSD__)
+#include <stdlib.h>
+#elif defined(_WIN32)
+#include <malloc.h>
+#else
+#include <alloca.h>
+#endif
+
+#endif
+++ /dev/null
-/*
- * Copyright (C) 1995-2007 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.
- */
-
-/**
- * @file
- * @brief macros for alignment.
- * @author Markus Armbruster
- * @version $Id$
- */
-#ifndef FIRM_ADT_ALIGN_H
-#define FIRM_ADT_ALIGN_H
-
-#include <stddef.h>
-
-/** A size handled efficiently by malloc(), at least 1K. */
-#define PREF_MALLOC_SIZE 2048
-
-
-/** A wrapper around GNU C's __attribute__ */
-
-/* According to the documentation, the attributes we are interested in
- work with 2.5, but we encountered trouble before 2.7. */
-#if defined (__GNUC__) && __GNUC__ >= 2 && __GNUC_MINOR__ >= 7
-# define HAVE_ATTRIBUTE 1
-# define ATTRIBUTE(attrs) __attribute__ (attrs)
-#else
-# define ATTRIBUTE(attrs)
-#endif
-
-
-/* Alignment */
-
-/** A type that has most constrained alignment. */
-typedef union {
- long double d;
- void *p;
- long l;
-} aligned_type ATTRIBUTE ((aligned));
-
-/** Inquiring about the alignment of a type. */
-#ifdef __GNUC__
-# define ALIGNOF(type) __alignof__ (type)
-#else
-# define ALIGNOF(type) offsetof (struct { char c; type d; }, d)
-#endif
-
-/** Maximal alignment required for any type. */
-#define MAX_ALIGN ALIGNOF (aligned_type)
-
-#endif
+++ /dev/null
-/*
- * Copyright (C) 1995-2007 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.
- */
-
-/**
- * @file
- * @brief Dynamic and flexible arrays for C.
- * @author Markus Armbruster
- * @version $Id$
- */
-#ifndef FIRM_ADT_ARRAY_H
-#define FIRM_ADT_ARRAY_H
-
-#include <assert.h>
-#include <stddef.h>
-
-#include "obst.h"
-#include "fourcc.h"
-#include "align.h"
-#include "xmalloc.h"
-
-#define ARR_D_MAGIC FOURCC('A','R','R','D')
-#define ARR_A_MAGIC FOURCC('A','R','R','A')
-#define ARR_F_MAGIC FOURCC('A','R','R','F')
-
-/**
- * Creates a flexible array.
- *
- * @param type The element type of the new array.
- * @param nelts a size_t expression evaluating to the number of elements
- *
- * This macro creates a flexible array of a given type at runtime.
- * The size of the array can be changed later.
- *
- * @return A pointer to the flexible array (can be used as a pointer to the
- * first element of this array).
- */
-#define NEW_ARR_F(type, nelts) \
- ((type *)_new_arr_f ((nelts), sizeof(type) * (nelts)))
-
-/**
- * Creates a new flexible array with the same number of elements as a
- * given one.
- *
- * @param type The element type of the new array.
- * @param arr An array from which the number of elements will be taken
- *
- * This macro creates a flexible array of a given type at runtime.
- * The size of the array can be changed later.
- *
- * @return A pointer to the flexible array (can be used as a pointer to the
- * first element of this array).
- */
-#define CLONE_ARR_F(type, arr) \
- NEW_ARR_F (type, ARR_LEN ((arr)))
-
-/**
- * Duplicates an array and returns the new flexible one.
- *
- * @param type The element type of the new array.
- * @param arr An array from which the elements will be duplicated
- *
- * This macro creates a flexible array of a given type at runtime.
- * The size of the array can be changed later.
- *
- * @return A pointer to the flexible array (can be used as a pointer to the
- * first element of this array).
- */
-#define DUP_ARR_F(type, arr) \
- memcpy (CLONE_ARR_F (type, (arr)), (arr), sizeof(type) * ARR_LEN((arr)))
-
-/**
- * Delete a flexible array.
- *
- * @param arr The flexible array.
- */
-#define DEL_ARR_F(arr) (_del_arr_f ((arr)))
-
-/**
- * Creates a dynamic array on an obstack.
- *
- * @param type The element type of the new array.
- * @param obstack A struct obstack * were the data will be allocated
- * @param nelts A size_t expression evaluating to the number of elements
- *
- * This macro creates a dynamic array of a given type at runtime.
- * The size of the array cannot be changed later.
- *
- * @return A pointer to the dynamic array (can be used as a pointer to the
- * first element of this array).
- */
-#define NEW_ARR_D(type, obstack, nelts) \
- ( nelts \
- ? (type *)_new_arr_d ((obstack), (nelts), sizeof(type) * (nelts)) \
- : (type *)arr_mt_descr.v.elts)
-
-/**
- * Creates a new dynamic array with the same number of elements as a
- * given one.
- *
- * @param type The element type of the new array.
- * @param obstack An struct obstack * were the data will be allocated
- * @param arr An array from which the number of elements will be taken
- *
- * This macro creates a dynamic array of a given type at runtime.
- * The size of the array cannot be changed later.
- *
- * @return A pointer to the dynamic array (can be used as a pointer to the
- * first element of this array).
- */
-#define CLONE_ARR_D(type, obstack, arr) \
- NEW_ARR_D (type, (obstack), ARR_LEN ((arr)))
-
-/**
- * Duplicates an array and returns the new dynamic one.
- *
- * @param type The element type of the new array.
- * @param obstack An struct obstack * were the data will be allocated
- * @param arr An array from which the elements will be duplicated
- *
- * This macro creates a dynamic array of a given type at runtime.
- * The size of the array cannot be changed later.
- *
- * @return A pointer to the dynamic array (can be used as a pointer to the
- * first element of this array).
- */
-#define DUP_ARR_D(type, obstack, arr) \
- memcpy (CLONE_ARR_D (type, (obstack), (arr)), (arr), sizeof(type) * ARR_LEN ((arr)))
-
-/**
- * Create an automatic array which will be deleted at return from function.
- * Beware, the data will be allocated on the function stack!
- *
- * @param type The element type of the new array.
- * @param var A lvalue of type (type *) which will hold the new array.
- * @param n number of elements in this array.
- *
- * This macro creates a dynamic array on the functions stack of a given type at runtime.
- * The size of the array cannot be changed later.
- */
-#define NEW_ARR_A(type, var, n) \
- do { \
- int _nelts = (n); \
- assert (_nelts >= 0); \
- (var) = (void *)((_arr_descr *)alloca (_ARR_ELTS_OFFS + sizeof(type) * _nelts))->v.elts; \
- _ARR_SET_DBGINF (_ARR_DESCR ((var)), ARR_A_MAGIC, sizeof (type)); \
- (void)(_ARR_DESCR ((var))->nelts = _nelts); \
- } while (0)
-
-/**
- * Creates a new automatic array with the same number of elements as a
- * given one.
- *
- * @param type The element type of the new array.
- * @param var A lvalue of type (type *) which will hold the new array.
- * @param arr An array from which the elements will be duplicated
- *
- * This macro creates a dynamic array of a given type at runtime.
- * The size of the array cannot be changed later.
- *
- * @return A pointer to the dynamic array (can be used as a pointer to the
- * first element of this array).
- */
-#define CLONE_ARR_A(type, var, arr) \
- NEW_ARR_A (type, (var), ARR_LEN ((arr)))
-
-/**
- * Duplicates an array and returns a new automatic one.
- *
- * @param type The element type of the new array.
- * @param var A lvalue of type (type *) which will hold the new array.
- * @param arr An array from with the number of elements will be taken
- *
- * This macro creates a dynamic array of a given type at runtime.
- * The size of the array cannot be changed later.
- *
- * @return A pointer to the dynamic array (can be used as a pointer to the
- * first element of this array).
- */
-#define DUP_ARR_A(type, var, arr) \
- do { CLONE_ARR_A(type, (var), (arr)); \
- memcpy ((var), (arr), sizeof (type) * ARR_LEN ((arr))); } \
- while (0)
-
-/**
- * Declare an initialized (zero'ed) array of fixed size.
- * This macro should be used at file scope only.
- *
- * @param type The element type of the new array.
- * @param var A lvalue of type (type *) which will hold the new array.
- * @param _nelts Number of elements in this new array.
- */
-#define DECL_ARR_S(type, var, _nelts) \
- ARR_STRUCT(type, (_nelts) ? (_nelts) : 1) _##var; \
- type *var = (_ARR_SET_DBGINF (&_##var, ARR_A_MAGIC, sizeof (type)), \
- _##var.nelts = _nelts, \
- _##var.v.elts)
-
-/**
- * Returns the length of an array
- *
- * @param arr a flexible, dynamic, automatic or static array.
- */
-#define ARR_LEN(arr) (ARR_VRFY ((arr)), _ARR_DESCR((arr))->nelts)
-
-/**
- * Resize a flexible array, allocate more data if needed but do NOT
- * reduce.
- *
- * @param type The element type of the array.
- * @param arr The array, which must be an lvalue.
- * @param n The new size of the array.
- *
- * @remark This macro may change arr, so update all references!
- */
-#define ARR_RESIZE(type, arr, n) \
- ((arr) = _arr_resize ((arr), (n), sizeof(type)))
-
-/**
- * Resize a flexible array, always reallocate data.
- *
- * @param type The element type of the array.
- * @param arr The array, which must be an lvalue.
- * @param n The new size of the array.
- *
- * @remark This macro may change arr, so update all references!
- */
-#define ARR_SETLEN(type, arr, n) \
- ((arr) = _arr_setlen ((arr), (n), sizeof(type) * (n)))
-
-/** Set a length smaller than the current length of the array. Do not
- * resize. len must be <= ARR_LEN(arr). */
-#define ARR_SHRINKLEN(arr,len) \
- (ARR_VRFY ((arr)), assert(_ARR_DESCR((arr))->nelts >= len), \
- _ARR_DESCR((arr))->nelts = len)
-
-/**
- * Resize a flexible array by growing it by delta elements.
- *
- * @param type The element type of the array.
- * @param arr The array, which must be an lvalue.
- * @param delta The delta number of elements.
- *
- * @remark This macro may change arr, so update all references!
- */
-#define ARR_EXTEND(type, arr, delta) \
- ARR_RESIZE (type, (arr), ARR_LEN ((arr)) + (delta))
-
-/**
- * Resize a flexible array to hold n elements only if it is currently shorter
- * than n.
- *
- * @param type The element type of the array.
- * @param arr The array, which must be an lvalue.
- * @param n The new size of the array.
- *
- * @remark This macro may change arr, so update all references!
- */
-#define ARR_EXTO(type, arr, n) \
- ((n) >= ARR_LEN ((arr)) ? ARR_RESIZE (type, (arr), (n)+1) : (arr))
-
-/**
- * Append one element to a flexible array.
- *
- * @param type The element type of the array.
- * @param arr The array, which must be an lvalue.
- * @param elt The new element, must be of type (type).
- */
-#define ARR_APP1(type, arr, elt) \
- (ARR_EXTEND (type, (arr), 1), (arr)[ARR_LEN ((arr))-1] = (elt))
-
-
-#ifdef NDEBUG
-# define ARR_VRFY(arr) ((void)0)
-# define ARR_IDX_VRFY(arr, idx) ((void)0)
-#else
-# define ARR_VRFY(arr) \
- assert ( ( (_ARR_DESCR((arr))->magic == ARR_D_MAGIC) \
- || (_ARR_DESCR((arr))->magic == ARR_A_MAGIC) \
- || (_ARR_DESCR((arr))->magic == ARR_F_MAGIC)) \
- && ( (_ARR_DESCR((arr))->magic != ARR_F_MAGIC) \
- || (_ARR_DESCR((arr))->u.allocated >= _ARR_DESCR((arr))->nelts)) \
- && (_ARR_DESCR((arr))->nelts >= 0))
-# define ARR_IDX_VRFY(arr, idx) \
- assert ((0 <= (idx)) && ((idx) < ARR_LEN ((arr))))
-#endif
-
-
-/* Private !!!
- Don't try this at home, kids, we're trained professionals ;->
- ... or at the IPD, either. */
-#ifdef NDEBUG
-# define _ARR_DBGINF_DECL
-# define _ARR_SET_DBGINF(descr, co, es)
-#else
-# define _ARR_DBGINF_DECL int magic; size_t eltsize;
-# define _ARR_SET_DBGINF(descr, co, es) \
- ( (descr)->magic = (co), (descr)->eltsize = (es) )
-#endif
-
-/**
- * Construct an array header.
- */
-#define ARR_STRUCT(type, _nelts) \
- struct { \
- _ARR_DBGINF_DECL \
- union { \
- struct obstack *obstack; /* dynamic: allocated on this obstack */ \
- int allocated; /* flexible: #slots allocated */ \
- } u; \
- int nelts; \
- union { \
- type elts[(_nelts)]; \
- aligned_type align[1]; \
- } v; \
- }
-
-/**
- * The array descriptor header type.
- */
-typedef ARR_STRUCT (aligned_type, 1) _arr_descr;
-
-extern _arr_descr arr_mt_descr;
-
-void *_new_arr_f (int, size_t);
-void _del_arr_f (void *);
-void *_new_arr_d (struct obstack *obstack, int nelts, size_t elts_size);
-void *_arr_resize (void *, int, size_t);
-void *_arr_setlen (void *, int, size_t);
-
-#define _ARR_ELTS_OFFS offsetof (_arr_descr, v.elts)
-#define _ARR_DESCR(elts) ((_arr_descr *)(void *)((char *)(elts) - _ARR_ELTS_OFFS))
-
-#endif /* FIRM_ADT_ARRAY_H */
+++ /dev/null
-/*
- * Copyright (C) 1995-2007 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.
- */
-
-/**
- * @file
- * @date 26.01.2006
- * @author Sebastian Hack
- * @brief Implements bipartite matchings.
- */
-#ifndef FIRM_ADT_BIPARTITE_H
-#define FIRM_ADT_BIPARTITE_H
-
-typedef struct _bipartite_t bipartite_t;
-
-bipartite_t *bipartite_new(int n_left, int n_right);
-void bipartite_free(bipartite_t *gr);
-void bipartite_add(bipartite_t *gr, int i, int j);
-void bipartite_remv(bipartite_t *gr, int i, int j);
-int bipartite_adj(const bipartite_t *gr, int i, int j);
-void bipartite_matching(const bipartite_t *gr, int *matching);
-
-/**
- * Dumps a bipartite graph to a file stream.
- */
-void bipartite_dump_f(FILE *f, const bipartite_t *gr);
-
-/**
- * Dumps a bipartite graph to file name.
- */
-void bipartite_dump(const char *name, const bipartite_t *gr);
-
-#endif /* _BIPARTITE_H */
+++ /dev/null
-/*
- * Copyright (C) 1995-2007 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.
- */
-
-/**
- * @file
- * @date 28.9.2004
- * @brief Functions from hackers delight.
- * @author Sebastian Hack, Matthias Braun
- * @version $Id$
- */
-#ifndef FIRM_ADT_BITFIDDLE_H
-#define FIRM_ADT_BITFIDDLE_H
-
-#include <limits.h>
-#include <assert.h>
-#include "util.h"
-
-/* some functions here assume ints are 32 bit wide */
-#define HACKDEL_WORDSIZE 32
-COMPILETIME_ASSERT(sizeof(unsigned) == 4, unsignedsize)
-COMPILETIME_ASSERT(UINT_MAX == 4294967295U, uintmax)
-
-/**
- * Add saturated.
- * @param x Summand 1.
- * @param y Summand 2.
- * @return x + y or INT_MAX/INT_MIN if an overflow occurred and x,y was positive/negative.
- *
- * @note See hacker's delight, page 27.
- */
-static INLINE __attribute__((const))
-int add_saturated(int x, int y)
-{
- int sum = x + y;
- /*
- An overflow occurs, if the sign of the both summands is equal
- and the one of the sum is different from the summand's one.
- The sign bit is 1, if an overflow occurred, 0 otherwise.
- int overflow = ~(x ^ y) & (sum ^ x);
- */
- int overflow = (x ^ sum) & (y ^ sum);
-
- /*
- The infinity to use.
- Make a mask of the sign bit of x and y (they are the same if an
- overflow occurred).
- INT_MIN == ~INT_MAX, so if the sign was negative, INT_MAX becomes
- INT_MIN.
- */
- int inf = (x >> (sizeof(x) * 8 - 1)) ^ INT_MAX;
-
- return overflow < 0 ? inf : sum;
-}
-
-/**
- * Compute the count of set bits in a 32-bit word.
- * @param x A 32-bit word.
- * @return The number of bits set in x.
- */
-static INLINE __attribute__((const))
-unsigned popcnt(unsigned x) {
- x -= ((x >> 1) & 0x55555555);
- x = (x & 0x33333333) + ((x >> 2) & 0x33333333);
- x = (x + (x >> 4)) & 0x0f0f0f0f;
- x += x >> 8;
- x += x >> 16;
- return x & 0x3f;
-}
-
-/**
- * Compute the number of leading zeros in a word.
- * @param x The word.
- * @return The number of leading (from the most significant bit) zeros.
- */
-static INLINE __attribute__((const))
-unsigned nlz(unsigned x) {
-#ifdef USE_X86_ASSEMBLY
- unsigned res;
- if(x == 0)
- return 32;
-
- __asm__("bsrl %1,%0"
- : "=r" (res)
- : "r" (x));
- return 31 - res;
-#else
- x |= x >> 1;
- x |= x >> 2;
- x |= x >> 4;
- x |= x >> 8;
- x |= x >> 16;
- return popcnt(~x);
-#endif
-}
-
-/**
- * Compute the number of trailing zeros in a word.
- * @param x The word.
- * @return The number of trailing zeros.
- */
-static INLINE __attribute__((const))
-unsigned ntz(unsigned x) {
-#ifdef USE_X86_ASSEMBLY
- unsigned res;
- if(x == 0)
- return 32;
-
- __asm__("bsfl %1,%0"
- : "=r" (res)
- : "r" (x));
- return res;
-#else
- return HACKDEL_WORDSIZE - nlz(~x & (x - 1));
-#endif
-}
-
-/**
- * Compute the greatest power of 2 smaller or equal to a value.
- * This is also known as the binary logarithm.
- * @param x The value.
- * @return The power of two.
- */
-#define log2_floor(x) (HACKDEL_WORDSIZE - 1 - nlz(x))
-
-/**
- * Compute the smallest power of 2 greater or equal to a value.
- * This is also known as the binary logarithm.
- * @param x The value.
- * @return The power of two.
- */
-#define log2_ceil(x) (HACKDEL_WORDSIZE - nlz((x) - 1))
-
-/**
- * Round up to the next multiple of a power of two.
- * @param x A value.
- * @param pot A power of two.
- * @return x rounded up to the next multiple of pot.
- */
-#define round_up2(x,pot) (((x) + ((pot) - 1)) & (~((pot) - 1)))
-
-/**
- * Returns the biggest power of 2 that is equal or smaller than @p x
- * (see hackers delight power-of-2 boundaries, page 48)
- */
-static INLINE __attribute__((const))
-unsigned floor_po2(unsigned x)
-{
-#ifdef USE_X86_ASSEMBLY // in this case nlz is fast
- if(x == 0)
- return 0;
- // note that x != 0 here, so nlz(x) < 32!
- return 0x80000000U >> nlz(x);
-#else
- x |= x >> 1;
- x |= x >> 2;
- x |= x >> 4;
- x |= x >> 8;
- x |= x >> 16;
- return x - (x >> 1);
-#endif
-}
-
-/**
- * Returns the smallest power of 2 that is equal or greater than x
- * @remark x has to be <= 0x8000000 of course
- * @note see hackers delight power-of-2 boundaries, page 48
- */
-static INLINE __attribute__((const))
-unsigned ceil_po2(unsigned x)
-{
- if(x == 0)
- return 0;
- assert(x < (1U << 31));
-
-#ifdef USE_X86_ASSEMBLY // in this case nlz is fast
- // note that x != 0 here!
- return 0x80000000U >> (nlz(x-1) - 1);
-#else
- x = x - 1;
- x |= x >> 1;
- x |= x >> 2;
- x |= x >> 4;
- x |= x >> 8;
- x |= x >> 16;
- return x + 1;
-#endif
-}
-
-/**
- * Tests whether @p x is a power of 2
- */
-static INLINE __attribute__((const))
-int is_po2(unsigned x)
-{
- return (x & (x-1)) == 0;
-}
-
-#endif
+++ /dev/null
-/*
- * Copyright (C) 1995-2007 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.
- */
-
-/**
- * @file
- * @brief A bitset implementation.
- * @author Sebastian Hack
- * @date 15.10.2004
- * @version $Id$
- */
-#ifndef FIRM_ADT_BITSET_H
-#define FIRM_ADT_BITSET_H
-
-#include "firm_config.h"
-
-#include <stdlib.h>
-#include <stdio.h>
-#include <assert.h>
-#include <string.h>
-
-#include "xmalloc.h"
-#include "bitfiddle.h"
-
-typedef unsigned int bitset_pos_t;
-
-#include "bitset_std.h"
-
-/*
-#if defined(__GNUC__) && defined(__i386__)
-#include "bitset_ia32.h"
-#endif
-*/
-
-typedef struct _bitset_t {
- bitset_pos_t units;
- bitset_pos_t size;
- bitset_unit_t *data;
-} bitset_t;
-
-#define BS_UNIT_SIZE sizeof(bitset_unit_t)
-#define BS_UNIT_SIZE_BITS (BS_UNIT_SIZE * 8)
-#define BS_UNIT_MASK (BS_UNIT_SIZE_BITS - 1)
-
-/**
- * Initialize a bitset.
- * This functions should not be called.
- *
- * Note that this function needs three macros which must be provided by the
- * bitfield implementor:
- * - _bitset_overall_size(size) The overall size that must be
- * allocated for the bitfield in bytes.
- * - _bitset_units(size) The number of units that will be
- * present in the bitfield for a given highest bit.
- * - _bitset_data_ptr(data, size) This produces as pointer to the
- * first unit in the allocated memory area. The main reason for this
- * macro is, that some bitset implementors want control over memory
- * alignment.
- *
- * @param area A pointer to memory reserved for the bitset.
- * @param size The size of the bitset in bits.
- * @return A pointer to the initialized bitset.
- */
-static INLINE bitset_t *_bitset_prepare(void *area, bitset_pos_t size)
-{
- bitset_t *ptr = area;
- memset(area, 0, _bitset_overall_size(sizeof(bitset_t), size));
- ptr->units = _bitset_units(size);
- ptr->size = size;
- ptr->data = _bitset_data_ptr(area, sizeof(bitset_t), size);
- return ptr;
-}
-
-/**
- * Mask out all bits, which are only there, because the number
- * of bits in the set didn't match a unit size boundary.
- * @param bs The bitset.
- * @return The masked bitset.
- */
-static INLINE bitset_t *_bitset_mask_highest(bitset_t *bs)
-{
- bitset_pos_t rest = bs->size & BS_UNIT_MASK;
- if (rest)
- bs->data[bs->units - 1] &= (1 << rest) - 1;
- return bs;
-}
-
-/**
- * Get the capacity of the bitset in bits.
- * @param bs The bitset.
- * @return The capacity in bits of the bitset.
- */
-#define bitset_capacity(bs) ((bs)->units * BS_UNIT_SIZE_BITS)
-
-/**
- * Get the size of the bitset in bits.
- * @note Note the difference between capacity and size.
- * @param bs The bitset.
- * @return The highest bit which can be set or cleared plus 1.
- */
-#define bitset_size(bs) ((bs)->size)
-
-/**
- * Allocate a bitset on an obstack.
- * @param obst The obstack.
- * @param size The greatest bit that shall be stored in the set.
- * @return A pointer to an empty initialized bitset.
- */
-#define bitset_obstack_alloc(obst,size) \
- _bitset_prepare(obstack_alloc(obst, _bitset_overall_size(sizeof(bitset_t), size)), size)
-
-/**
- * Allocate a bitset via malloc.
- * @param size The greatest bit that shall be stored in the set.
- * @return A pointer to an empty initialized bitset.
- */
-#define bitset_malloc(size) \
- _bitset_prepare(xmalloc(_bitset_overall_size(sizeof(bitset_t), size)), size)
-
-/**
- * Free a bitset allocated with bitset_malloc().
- * @param bs The bitset.
- */
-#define bitset_free(bs) free(bs)
-
-/**
- * Allocate a bitset on the stack via alloca.
- * @param size The greatest bit that shall be stored in the set.
- * @return A pointer to an empty initialized bitset.
- */
-#define bitset_alloca(size) \
- _bitset_prepare(alloca(_bitset_overall_size(sizeof(bitset_t), size)), size)
-
-
-/**
- * Get the unit which contains a specific bit.
- * This function is internal.
- * @param bs The bitset.
- * @param bit The bit.
- * @return A pointer to the unit containing the bit.
- */
-static INLINE bitset_unit_t *_bitset_get_unit(const bitset_t *bs, bitset_pos_t bit)
-{
- /* assert(bit < bs->units * BS_UNIT_SIZE_BITS && "Bit too large"); */
- assert(bit <= bs->size && "Bit to large");
- return bs->data + bit / BS_UNIT_SIZE_BITS;
-}
-
-/**
- * Set a bit in the bitset.
- * @param bs The bitset.
- * @param bit The bit to set.
- */
-static INLINE void bitset_set(bitset_t *bs, bitset_pos_t bit)
-{
- bitset_unit_t *unit = _bitset_get_unit(bs, bit);
- _bitset_inside_set(unit, bit & BS_UNIT_MASK);
-}
-
-/**
- * Clear a bit in the bitset.
- * @param bs The bitset.
- * @param bit The bit to clear.
- */
-static INLINE void bitset_clear(bitset_t *bs, bitset_pos_t bit)
-{
- bitset_unit_t *unit = _bitset_get_unit(bs, bit);
- _bitset_inside_clear(unit, bit & BS_UNIT_MASK);
-}
-
-/**
- * Check, if a bit is set.
- * @param bs The bitset.
- * @param bit The bit to check for.
- * @return 1, if the bit was set, 0 if not.
- */
-static INLINE int bitset_is_set(const bitset_t *bs, bitset_pos_t bit)
-{
- bitset_unit_t *unit = _bitset_get_unit(bs, bit);
- return _bitset_inside_is_set(unit, bit & BS_UNIT_MASK);
-}
-
-/**
- * Flip a bit in a bitset.
- * @param bs The bitset.
- * @param bit The bit to flip.
- */
-static INLINE void bitset_flip(bitset_t *bs, bitset_pos_t bit)
-{
- bitset_unit_t *unit = _bitset_get_unit(bs, bit);
- _bitset_inside_flip(unit, bit & BS_UNIT_MASK);
-}
-
-/**
- * Flip the whole bitset.
- * @param bs The bitset.
- */
-static INLINE void bitset_flip_all(bitset_t *bs)
-{
- bitset_pos_t i;
- for(i = 0; i < bs->units; i++)
- _bitset_inside_flip_unit(&bs->data[i]);
- _bitset_mask_highest(bs);
-}
-
-/**
- * Copy a bitset to another.
- * @param tgt The target bitset.
- * @param src The source bitset.
- * @return The target bitset.
- */
-static INLINE bitset_t *bitset_copy(bitset_t *tgt, const bitset_t *src)
-{
- bitset_pos_t tu = tgt->units;
- bitset_pos_t su = src->units;
- bitset_pos_t min_units = tu < su ? tu : su;
- memcpy(tgt->data, src->data, min_units * BS_UNIT_SIZE);
- if(tu > min_units)
- memset(tgt->data + min_units, 0, BS_UNIT_SIZE * (tu - min_units));
- return _bitset_mask_highest(tgt);
-}
-
-/**
- * Find the smallest bit set in the bitset.
- * @param bs The bitset.
- * @return The smallest bit set in the bitset.
- */
-static INLINE bitset_pos_t bitset_min(const bitset_t *bs)
-{
- bitset_pos_t i, ofs = 0;
-
- for(i = 0; i < bs->units; ++i) {
- bitset_unit_t *unit = &bs->data[i];
- bitset_pos_t pos = _bitset_inside_ntz(unit);
- if(pos > 0)
- return ofs + pos;
- ofs += BS_UNIT_SIZE_BITS;
- }
-
- return 0;
-}
-
-/**
- * Find the greatest bit set in the bitset.
- * @param bs The bitset.
- * @return The greatest bit set in the bitset.
- */
-static INLINE bitset_pos_t bitset_max(const bitset_t *bs)
-{
- bitset_pos_t i, max = 0, ofs = 0;
-
- for(i = 0; i < bs->units; ++i) {
- bitset_unit_t *unit = &bs->data[i];
- bitset_pos_t pos = _bitset_inside_nlz(unit);
- if(pos > 0)
- max = ofs + pos;
- ofs += BS_UNIT_SIZE_BITS;
- }
-
- return max;
-}
-
-/**
- * Find the next set bit from a given bit.
- * @note Note that if pos is set, pos is returned.
- * @param bs The bitset.
- * @param pos The bit from which to search for the next set bit.
- * @return The next set bit from pos on, or -1, if no set bit was found
- * after pos.
- */
-static INLINE bitset_pos_t _bitset_next(const bitset_t *bs,
- bitset_pos_t pos, int set)
-{
- bitset_pos_t unit_number = pos / BS_UNIT_SIZE_BITS;
- bitset_pos_t res;
-
- if(pos >= bs->size)
- return -1;
-
- {
- bitset_pos_t bit_in_unit = pos & BS_UNIT_MASK;
- bitset_pos_t in_unit_mask = (1 << bit_in_unit) - 1;
-
- /*
- * Mask out the bits smaller than pos in the current unit.
- * We are only interested in bits set higher than pos.
- */
- bitset_unit_t curr_unit = bs->data[unit_number];
-
- /*
- * Find the next bit set in the unit.
- * Mind that this function returns 0, if the unit is -1 and
- * counts the bits from 1 on.
- */
- bitset_pos_t next_in_this_unit =
- _bitset_inside_ntz_value((set ? curr_unit : ~curr_unit) & ~in_unit_mask);
-
- /* If there is a bit set in the current unit, exit. */
- if (next_in_this_unit < BS_UNIT_SIZE_BITS) {
- res = next_in_this_unit + unit_number * BS_UNIT_SIZE_BITS;
- return res < bs->size ? res : -1;
- }
-
- /* Else search for set bits in the next units. */
- else {
- bitset_pos_t i;
- for(i = unit_number + 1; i < bs->units; ++i) {
- bitset_unit_t data = bs->data[i];
- bitset_pos_t first_set =
- _bitset_inside_ntz_value(set ? data : ~data);
-
- if (first_set < BS_UNIT_SIZE_BITS) {
- res = first_set + i * BS_UNIT_SIZE_BITS;
- return res < bs->size ? res : -1;
- }
- }
- }
- }
-
- return -1;
-}
-
-#define bitset_next_clear(bs,pos) _bitset_next((bs), (pos), 0)
-#define bitset_next_set(bs,pos) _bitset_next((bs), (pos), 1)
-
-/**
- * Convenience macro for bitset iteration.
- * @param bitset The bitset.
- * @param elm A unsigned long variable.
- */
-#define bitset_foreach(bitset,elm) \
- for(elm = bitset_next_set(bitset,0); elm != -1; elm = bitset_next_set(bitset,elm+1))
-
-
-#define bitset_foreach_clear(bitset,elm) \
- for(elm = bitset_next_clear(bitset,0); elm != -1; elm = bitset_next_clear(bitset,elm+1))
-
-/**
- * Count the bits set.
- * This can also be seen as the cardinality of the set.
- * @param bs The bitset.
- * @return The number of bits set in the bitset.
- */
-static INLINE unsigned bitset_popcnt(const bitset_t *bs)
-{
- bitset_pos_t i;
- bitset_unit_t *unit;
- unsigned pop = 0;
-
- for (i = 0, unit = bs->data; i < bs->units; ++i, ++unit)
- pop += _bitset_inside_pop(unit);
-
- return pop;
-}
-
-/**
- * Clear the bitset.
- * This sets all bits to zero.
- * @param bs The bitset.
- */
-static INLINE bitset_t *bitset_clear_all(bitset_t *bs)
-{
- memset(bs->data, 0, BS_UNIT_SIZE * bs->units);
- return bs;
-}
-
-/**
- * Set the bitset.
- * This sets all bits to one.
- * @param bs The bitset.
- */
-static INLINE bitset_t *bitset_set_all(bitset_t *bs)
-{
- memset(bs->data, -1, bs->units * BS_UNIT_SIZE);
- return _bitset_mask_highest(bs);
-}
-
-/**
- * Check, if one bitset is contained by another.
- * That is, each bit set in lhs is also set in rhs.
- * @param lhs A bitset.
- * @param rhs Another bitset.
- * @return 1, if all bits in lhs are also set in rhs, 0 otherwise.
- */
-static INLINE int bitset_contains(const bitset_t *lhs, const bitset_t *rhs)
-{
- bitset_pos_t n = lhs->units < rhs->units ? lhs->units : rhs->units;
- bitset_pos_t i;
-
- for(i = 0; i < n; ++i) {
- bitset_unit_t lu = lhs->data[i];
- bitset_unit_t ru = rhs->data[i];
-
- if((lu | ru) & ~ru)
- return 0;
- }
-
- /*
- * If the left hand sinde is a larger bitset than rhs,
- * we have to check, that all extra bits in lhs are 0
- */
- if(lhs->units > n) {
- for(i = n; i < lhs->units; ++i) {
- if(lhs->data[i] != 0)
- return 0;
- }
- }
-
- return 1;
-}
-
-/**
- * Treat the bitset as a number and subtract 1.
- * @param bs The bitset.
- * @return The same bitset.
- */
-static INLINE void bitset_minus1(bitset_t *bs)
-{
-#define _SH (sizeof(bitset_unit_t) * 8 - 1)
-
- bitset_pos_t i;
-
- for(i = 0; i < bs->units; ++i) {
- bitset_unit_t unit = bs->data[i];
- bitset_unit_t um1 = unit - 1;
-
- bs->data[i] = um1;
-
- if(((unit >> _SH) ^ (um1 >> _SH)) == 0)
- break;
- }
-#undef _SH
-}
-
-/**
- * Check if two bitsets intersect.
- * @param a The first bitset.
- * @param b The second bitset.
- * @return 1 if they have a bit in common, 0 if not.
- */
-static INLINE int bitset_intersect(const bitset_t *a, const bitset_t *b)
-{
- bitset_pos_t n = a->units < b->units ? a->units : b->units;
- bitset_pos_t i;
-
- for (i = 0; i < n; ++i)
- if (a->data[i] & b->data[i])
- return 1;
-
- return 0;
-}
-
-/**
- * Check, if a bitset is empty.
- * @param a The bitset.
- * @return 1, if the bitset is empty, 0 if not.
- */
-static INLINE int bitset_is_empty(const bitset_t *a)
-{
- bitset_pos_t i;
- for (i = 0; i < a->units; ++i)
- if (a->data[i] != 0)
- return 0;
- return 1;
-}
-
-/**
- * Print a bitset to a stream.
- * The bitset is printed as a comma separated list of bits set.
- * @param file The stream.
- * @param bs The bitset.
- */
-static INLINE void bitset_fprint(FILE *file, const bitset_t *bs)
-{
- const char *prefix = "";
- int i;
-
- putc('{', file);
- for(i = bitset_next_set(bs, 0); i != -1; i = bitset_next_set(bs, i + 1)) {
- fprintf(file, "%s%u", prefix, i);
- prefix = ",";
- }
- putc('}', file);
-}
-
-static INLINE void bitset_debug_fprint(FILE *file, const bitset_t *bs)
-{
- bitset_pos_t i;
-
- fprintf(file, "%u:", bs->units);
- for(i = 0; i < bs->units; ++i)
- fprintf(file, " " BITSET_UNIT_FMT, bs->data[i]);
-}
-
-/**
- * Perform tgt = tgt \ src operation.
- * @param tgt The target bitset.
- * @param src The source bitset.
- * @return the tgt set.
- */
-static INLINE bitset_t *bitset_andnot(bitset_t *tgt, const bitset_t *src);
-
-/**
- * Perform Union, tgt = tgt u src operation.
- * @param tgt The target bitset.
- * @param src The source bitset.
- * @return the tgt set.
- */
-static INLINE bitset_t *bitset_or(bitset_t *tgt, const bitset_t *src);
-
-/**
- * Perform tgt = tgt ^ ~src operation.
- * @param tgt The target bitset.
- * @param src The source bitset.
- * @return the tgt set.
- */
-static INLINE bitset_t *bitset_xor(bitset_t *tgt, const bitset_t *src);
-
-/*
- * Here, the binary operations follow.
- * And, Or, And Not, Xor are available.
- */
-#define BINARY_OP(op) \
-static INLINE bitset_t *bitset_ ## op(bitset_t *tgt, const bitset_t *src) \
-{ \
- bitset_pos_t i; \
- bitset_pos_t n = tgt->units > src->units ? src->units : tgt->units; \
- for(i = 0; i < n; i += _BITSET_BINOP_UNITS_INC) \
- _bitset_inside_binop_ ## op(&tgt->data[i], &src->data[i]); \
- if(n < tgt->units) \
- _bitset_clear_rest(&tgt->data[i], tgt->units - i); \
- return _bitset_mask_highest(tgt); \
-}
-
-/*
- * Define the clear rest macro for the and, since it is the only case,
- * were non existed (treated as 0) units in the src must be handled.
- * For all other operations holds: x Op 0 = x for Op in { Andnot, Or, Xor }
- *
- * For and, each bitset implementer has to provide the macro
- * _bitset_clear_units(data, n), which clears n units from the pointer
- * data on.
- */
-#define _bitset_clear_rest(data,n) _bitset_inside_clear_units(data, n)
-BINARY_OP(and)
-#undef _bitset_clear_rest
-#define _bitset_clear_rest(data,n)
-
-BINARY_OP(andnot)
-BINARY_OP(or)
-BINARY_OP(xor)
-
-#endif
+++ /dev/null
-/*
- * Copyright (C) 1995-2007 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.
- */
-
-/**
- * @file
- * @brief intel 80x86 implementation of bitsets
- * @version $Id$
- */
-#ifndef _BITSET_IA32_H
-#define _BITSET_IA32_H
-
-typedef unsigned int bitset_unit_t;
-#define BITSET_UNIT_FMT "%0x"
-
-#undef _bitset_inside_clear
-#undef _bitset_inside_set
-#undef _bitset_inside_flip
-#undef _bitset_inside_is_set
-
-#undef _bitset_inside_nlz
-#undef _bitset_inside_ntz
-#undef _bitset_inside_ntz_value
-
-#define _bitset_inside_set(unit,bit) \
- __asm__( "btsl %1,%0" :"=m" (unit) :"Ir" (bit))
-
-#define _bitset_inside_clear(unit,bit) \
- __asm__( "btrl %1,%0" :"=m" (unit) :"Ir" (bit))
-
-#define _bitset_inside_flip(unit,bit) \
- __asm__( "btcl %1,%0" :"=m" (unit) :"Ir" (bit))
-
-#define _bitset_inside_is_set(unit,bit) _bitset_ia32_inside_is_set(unit, bit)
-#define _bitset_inside_nlz(unit) _bitset_ia32_inside_nlz(unit)
-#define _bitset_inside_ntz(unit) _bitset_ia32_inside_ntz(unit)
-#define _bitset_inside_ntz_value(unit) _bitset_ia32_inside_ntz_value(unit)
-
-static INLINE int _bitset_ia32_inside_is_set(bitset_unit_t *unit, unsigned bit)
-{
- int res = 0;
- __asm__("mov $0,%0\n\tbtl %1,%2\n\tadc $0,%0"
- : "=r" (res)
- : "Ir" (bit), "m" (unit)
- : "cc");
- return res;
-}
-
-static INLINE unsigned _bitset_ia32_inside_nlz(bitset_unit_t *unit)
-{
- unsigned res = 0;
- __asm__("bsrl %1,%0" :"=r" (res) :"m" (unit));
- return *unit == 0 ? 32 : res;
-}
-
-static INLINE unsigned _bitset_ia32_inside_ntz(bitset_unit_t *unit) {
- unsigned res = 0;
- __asm__("bsfl %1,%0" :"=r" (res) :"m" (unit));
- return *unit == 0 ? 32 : res;
-}
-
-static INLINE unsigned _bitset_ia32_inside_ntz_value(bitset_unit_t unit) {
- unsigned res = 0;
- __asm__("bsfl %1,%0" :"=r" (res) :"rm" (unit));
- return unit == 0 ? 32 : res;
-}
-
-#if defined(__GNUC__) && defined(__SSE2__)
-
-#include <stddef.h>
-#include <xmmintrin.h>
-
-#undef _bitset_units
-#undef _bitset_overall_size
-#undef _bitset_data_ptr
-
-#undef _BITSET_BINOP_UNITS_INC
-
-#undef _bitset_inside_binop_and
-#undef _bitset_inside_binop_andnot
-#undef _bitset_inside_binop_or
-#undef _bitset_inside_binop_xor
-
-#undef _bitset_inside_binop_with_zero_and
-#undef _bitset_inside_binop_with_zero_andnot
-#undef _bitset_inside_binop_with_zero_or
-#undef _bitset_inside_binop_with_zero_xor
-
-#define _bitset_units(highest_bit) (round_up2(highest_bit, 128) / BS_UNIT_SIZE_BITS)
-
-#define _bitset_overall_size(bitset_base_size,highest_bit) \
- ((bitset_base_size) + 16 + _bitset_units(highest_bit) * BS_UNIT_SIZE)
-
-#define _bitset_data_ptr(data,bitset_base_size,highest_bit) \
- _bitset_sse_data_ptr(data, bitset_base_size, highest_bit)
-
-static INLINE bitset_unit_t *_bitset_sse_data_ptr(void *data, size_t bitset_base_size,
- bitset_pos_t highest_bit)
-{
- ptrdiff_t diff;
- char *units = data;
-
- diff = (units - (char *) 0) + bitset_base_size;
- diff = round_up2(diff, 16);
- units = (char *) 0 + diff;
- return (bitset_unit_t *) units;
-}
-
-#define _BITSET_BINOP_UNITS_INC 4
-#define _bitset_inside_binop_and(tgt,src) _bitset_sse_inside_binop_and(tgt,src)
-#define _bitset_inside_binop_andnot(tgt,src) _bitset_sse_inside_binop_andnot(tgt,src)
-#define _bitset_inside_binop_or(tgt,src) _bitset_sse_inside_binop_or(tgt,src)
-#define _bitset_inside_binop_xor(tgt,src) _bitset_sse_inside_binop_xor(tgt,src)
-
-#define _BITSET_SSE_BINOP(name) \
-static INLINE void _bitset_sse_inside_binop_ ## name(bitset_unit_t *tgt, bitset_unit_t *src) \
-{ \
- __m128i src_op = _mm_load_si128((__m128i *) src); \
- __m128i tgt_op = _mm_load_si128((__m128i *) tgt); \
- __m128i res = _mm_ ## name ## _si128(tgt_op, src_op); \
- _mm_store_si128((void *) tgt, res); \
-}
-
-
-static INLINE void _bitset_sse_inside_binop_with_zero_and(bitset_unit_t *tgt)
-{
- tgt[0] = 0;
- tgt[1] = 0;
- tgt[2] = 0;
- tgt[3] = 0;
-}
-
-static INLINE void _bitset_sse_inside_binop_andnot(bitset_unit_t *tgt, bitset_unit_t *src)
-{
- __m128i src_op = _mm_load_si128((void *) src);
- __m128i tgt_op = _mm_load_si128((void *) tgt);
- __m128i res = _mm_andnot_si128(src_op, tgt_op);
- _mm_store_si128((__m128i *) tgt, res);
-}
-
-_BITSET_SSE_BINOP(and)
-_BITSET_SSE_BINOP(or)
-_BITSET_SSE_BINOP(xor)
-
-
-#endif
-#endif
+++ /dev/null
-/*
- * Copyright (C) 1995-2007 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.
- */
-
-/**
- * @file
- * @brief ANSI-C compliant implementation of bitsets
- * @version $Id$
- */
-#ifndef FIRM_ADT_BITSET_STD_H
-#define FIRM_ADT_BITSET_STD_H
-
-#include "bitfiddle.h"
-
-/** Use ordinary ints as unit types. */
-typedef unsigned int bitset_unit_t;
-
-#define BITSET_UNIT_FMT "%0x"
-#define BITSET_UNIT_ALL_ONE ((unsigned int) -1)
-
-/**
- * Units needed for a given highest bit.
- * This implementation always allocates units in a multiple of 16 bytes.
- * @param size The size of the bitset in bits.
- * @return The number of units needed.
- */
-#define _bitset_units(size) (round_up2(size, BS_UNIT_SIZE_BITS) / BS_UNIT_SIZE_BITS)
-
-/**
- * Compute the size in bytes needed for a bitseti, overall.
- * This also include the size for the bitset data structure.
- * This implementation computes the size in wat, that the bitset units
- * can be aligned to 16 bytes.
- * @param size The size of the bitset in bits.
- * @return The overall amount of bytes needed for that bitset.
- */
-#define _bitset_overall_size(bitset_base_size,size) \
- (bitset_base_size + _bitset_units(size) * BS_UNIT_SIZE)
-
-/**
- * calculate the pointer to the data space of the bitset.
- * @param data The base address of the allocated memory
- * @param bitset_base_size The size of the basical bitset data structure
- * which has to be taken into account.
- * @param size The size of the bitset in bits.
- */
-#define _bitset_data_ptr(data,bitset_base_size,size) \
- ((bitset_unit_t *) ((char *) data + bitset_base_size))
-
-
-/**
- * Clear some units from a certain address on.
- * @param addr The address from where to clear.
- * @param n The number of units to set to 0.
- */
-#define _bitset_inside_clear_units(addr,n) \
- memset(addr, 0, n * BS_UNIT_SIZE)
-
-/**
- * Set a bit in a unit.
- * @param unit A pointer to the unit.
- * @param bit which bit to set.
- */
-#define _bitset_inside_set(unit_ptr,bit) (*unit_ptr) |= (1 << (bit))
-
-/**
- * Clear a bit in a unit.
- * @param unit A pointer to the unit.
- * @param bit which bit to set.
- */
-#define _bitset_inside_clear(unit_ptr,bit) (*unit_ptr) &= ~(1 << (bit))
-
-/**
- * Flip a bit in a unit.
- * @param unit A pointer to the unit.
- * @param bit which bit to set.
- */
-#define _bitset_inside_flip(unit_ptr,bit) (*unit_ptr) ^= (1 << (bit))
-
-/**
- * Flip a whole unit.
- * @param unit_ptr The pointer to the unit.
- */
-#define _bitset_inside_flip_unit(unit_ptr) (*unit_ptr) = ~(*unit_ptr)
-
-/**
- * Count the number of leading zeroes in a unit.
- * @param unit A pointer to the unit.
- * @return The Number of leading zeroes.
- */
-#define _bitset_inside_nlz(unit_ptr) (nlz(*unit_ptr))
-
-
-/**
- * Count the number of trailing zeroes in a unit.
- * @param unit A pointer to the unit.
- * @return The Number of leading zeroes.
- */
-#define _bitset_inside_ntz(unit_ptr) _bitset_std_inside_ntz(unit_ptr)
-static INLINE unsigned _bitset_std_inside_ntz(bitset_unit_t *unit_ptr)
-{
- unsigned long data = *unit_ptr;
- return 32 - (unsigned) nlz(~data & (data - 1));
-}
-
-/**
- * Count the number of trailing zeroes in a unit (whereas the unit is no
- * pointer but a value).
- * @param unit A unit.
- * @return The Number of leading zeroes.
- */
-#define _bitset_inside_ntz_value(unit) (32 - nlz(~(unit) & ((unit) - 1)))
-
-/**
- * test if a bit is set in a unit.
- * @param unit_ptr The pointer to the unit.
- * @param bit The bit to check.
- * @return 1, if the bit is set, 0 otherise.
- */
-#define _bitset_inside_is_set(unit_ptr,bit) \
- (((*unit_ptr) & (1 << (bit))) != 0)
-
-/**
- * count the number of bits set in a unit.
- * @param unit_ptr The pointer to a unit.
- * @return The number of bits set in the unit.
- */
-#define _bitset_inside_pop(unit_ptr) (popcnt(*unit_ptr))
-
-#define _BITSET_BINOP_UNITS_INC 1
-
-#define _bitset_inside_binop_and(tgt,src) ((*tgt) &= (*src))
-#define _bitset_inside_binop_andnot(tgt,src) ((*tgt) &= ~(*src))
-#define _bitset_inside_binop_or(tgt,src) ((*tgt) |= (*src))
-#define _bitset_inside_binop_xor(tgt,src) ((*tgt) ^= (*src))
-
-#endif
+++ /dev/null
-/*
- * Copyright (C) 1995-2007 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.
- */
-
-/**
- * @file
- * @date 16.03.2007
- * @brief a set of pointers with a custom compare function
- * @author Matthias Braun
- * @version $Id$
- */
-#ifndef FIRM_ADT_CPSET_H
-#define FIRM_ADT_CPSET_H
-
-/**
- * The type of a cpset compare function.
- *
- * @param p1 pointer to an element
- * @param p2 pointer to another element
- *
- * @return 1 if the elements are identically, zero else
- */
-typedef int (*cpset_cmp_function) (const void *p1, const void *p2);
-
-/**
- * The type of a cpset hash function.
- *
- * @param p1 pointer to an element
- * @param p2 pointer to another element
- *
- * @return 1 if the elements are identically, zero else
- */
-typedef unsigned (*cpset_hash_function) (const void *obj);
-
-#define HashSet cpset_t
-#define HashSetIterator cpset_iterator_t
-#define HashSetEntry cpset_hashset_entry_t
-#define ValueType void*
-#define ADDITIONAL_DATA cpset_cmp_function cmp_function; cpset_hash_function hash_function;
-#include "hashset.h"
-#undef ADDITIONAL_DATA
-#undef ValueType
-#undef HashSetEntry
-#undef HashSetIterator
-#undef HashSet
-
-/**
- * Initializes a cpset
- *
- * @param cpset Pointer to allocated space for the cpset
- * @param cmp_function The compare function to use
- */
-void cpset_init(cpset_t *cpset, cpset_hash_function hash_function,
- cpset_cmp_function cmp_function);
-
-/**
- * Initializes a cpset
- *
- * @param cpset Pointer to allocated space for the cpset
- * @param cmp_function The compare function to use
- * @param expected_elements Number of elements expected in the cpset (roughly)
- */
-void cpset_init_size(cpset_t *cpset, cpset_hash_function hash_function,
- cpset_cmp_function cmp_function,
- size_t expected_elements);
-
-/**
- * Destroys a cpset and frees the memory allocated for hashtable. The memory of
- * the cpset itself is not freed.
- *
- * @param cpset Pointer to the cpset
- */
-void cpset_destroy(cpset_t *cpset);
-
-/**
- * Inserts an element into a cpset.
- *
- * @param cpset Pointer to the cpset
- * @param obj Element to insert into the cpset
- * @returns The element itself or a pointer to an existing element
- */
-void* cpset_insert(cpset_t *cpset, void *obj);
-
-/**
- * Removes an element from a cpset. Does nothing if the cpset doesn't contain the
- * element.
- *
- * @param cpset Pointer to the cpset
- * @param obj Pointer to remove from the cpset
- */
-void cpset_remove(cpset_t *cpset, const void *obj);
-
-/**
- * Tests whether a cpset contains a pointer
- *
- * @param cpset Pointer to the cpset
- * @param obj The pointer to find
- * @returns An equivalent object to @p obj or NULL
- */
-void *cpset_find(const cpset_t *cpset, const void *obj);
-
-/**
- * Returns the number of pointers contained in the cpset
- *
- * @param cpset Pointer to the cpset
- * @returns Number of pointers contained in the cpset
- */
-size_t cpset_size(const cpset_t *cpset);
-
-/**
- * Initializes a cpset iterator. Sets the iterator before the first element in
- * the cpset.
- *
- * @param iterator Pointer to already allocated iterator memory
- * @param cpset Pointer to the cpset
- */
-void cpset_iterator_init(cpset_iterator_t *iterator, const cpset_t *cpset);
-
-/**
- * Advances the iterator and returns the current element or NULL if all elements
- * in the cpset have been processed.
- * @attention It is not allowed to use cpset_insert or cpset_remove while
- * iterating over a cpset.
- *
- * @param iterator Pointer to the cpset iterator.
- * @returns Next element in the cpset or NULL
- */
-void *cpset_iterator_next(cpset_iterator_t *iterator);
-
-/**
- * Removed the element the iterator currently points to
- *
- * @param cpset Pointer to the cpset
- * @param iterator Pointer to the cpset iterator.
- */
-void cpset_remove_iterator(cpset_t *cpset, const cpset_iterator_t *iterator);
-
-#endif /* FIRM_ADT_CPSET_H */
+++ /dev/null
-/*
- * Copyright (C) 1995-2007 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.
- */
-
-/**
- * @file
- * @brief a pointer hashset (WARNING: deprecated, use hashset_new.*
- * instead)
- * @author Hubert Schmid
- * @date 09.06.2002
- * @version $Id$
- */
-#ifndef FIRM_ADT_ESET_H
-#define FIRM_ADT_ESET_H
-
-/**
- * "eset" is a set of addresses. The addresses are used for element
- * compare and hash calculation.
- * The value "NULL" can not be stored, as it is used as internal sentinel.
- */
-typedef struct eset eset;
-
-/** Creates a new empty set. */
-eset *eset_create(void);
-
-/**
- * Creates a copy of the given set. Does NOT work if NULL is contained in source. */
-eset *eset_copy(eset *source);
-
-/** Deletes a set. */
-void eset_destroy(eset *s);
-
-/** Returns the number of elements in the set. */
-int eset_count(eset *s);
-
-/** Inserts an address into the set. */
-void eset_insert(eset *s, void *p);
-
-/** Checks, whether an address is element of a set. */
-int eset_contains(eset *s, void *p);
-
-/**
- * Starts the iteration over a set and returns the first element or NULL
- * if the set is empty.
- *
- * @note: It is NOT possible to add new elements while iterating through a set.
- */
-void *eset_first(eset *s);
-
-/**
- * Continues iteration through a set and returns the next element or NULL if the
- * iteration is finished.
- *
- * @note: It is NOT possible to add new elements while iterating through a set.
- */
-void *eset_next(eset *s);
-
-/** Inserts all elements of source into target (union). Does NOT work if NULL is contained in source. */
-void eset_insert_all(eset *target, eset *source);
-
-#endif
+++ /dev/null
-/*
- * Copyright (C) 1995-2007 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.
- */
-
-/**
- * @file
- * @brief Define the famous infame FOURCC macro.
- * @date 02.01.2004
- * @version $Id$
- */
-#ifndef FIRM_ADT_FOURCC_H
-#define FIRM_ADT_FOURCC_H
-
-/** define a readable fourcc code */
-#define FOURCC(a,b,c,d) ((a) | ((b) << 8) | ((c) << 16) | ((d) << 24))
-
-#endif
+++ /dev/null
-/**
- * @file
- * @brief solves a system of linear equations
- */
-#ifndef FIRM_ADT_GAUSSJORDAN_H
-#define FIRM_ADT_GAUSSJORDAN_H
-
-/**
- * solves a system of linear equations and returns 0 if successful
- *
- * @param A the linear equations as matrix
- * @param b the result vector, will contain the result if successful
- */
-int firm_gaussjordansolve(double *A, double *b, int nsize);
-
-#endif
+++ /dev/null
-/*
- * Copyright (C) 1995-2007 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.
- */
-
-/**
- * @file
- * @brief Hash function for pointers
- * @author Michael Beck, Sebastian Hack
- * @version $Id$
- */
-#ifndef FIRM_ADT_HASHPTR_H
-#define FIRM_ADT_HASHPTR_H
-
-#include "firm_config.h"
-
-#define _FIRM_FNV_OFFSET_BASIS 2166136261U
-#define _FIRM_FNV_FNV_PRIME 16777619U
-
-/* Computing x * _FIRM_FNV_FNV_PRIME */
-#define _FIRM_FNV_TIMES_PRIME(x) \
- (((x) << 24) + ((x) << 8) + ((x) << 7) + ((x) << 4) + ((x) << 1) + 1)
-
-static INLINE unsigned firm_fnv_hash(const unsigned char *data, unsigned bytes)
-{
- unsigned i;
- unsigned hash = _FIRM_FNV_OFFSET_BASIS;
-
- for(i = 0; i < bytes; ++i) {
- hash = _FIRM_FNV_TIMES_PRIME(hash);
- hash ^= data[i];
- }
-
- return hash;
-}
-
-/**
- * hash a pointer value: Pointer addresses are mostly aligned to 4
- * or 8 bytes. So we remove the lowest 3 bits
- */
-#define HASH_PTR(ptr) (((char *) (ptr) - (char *)0) >> 3)
-
-/**
- * Hash a string.
- * @param str The string (can be const).
- * @param len The length of the string.
- * @return A hash value for the string.
- */
-#define HASH_STR(str,len) firm_fnv_hash((const unsigned char *) (str), (len))
-
-#ifdef _MSC_VER
-#pragma warning(disable:4307)
-#endif /* _MSC_VER */
-
-static INLINE unsigned _hash_combine(unsigned x, unsigned y)
-{
- unsigned hash = _FIRM_FNV_TIMES_PRIME(_FIRM_FNV_OFFSET_BASIS);
- hash ^= x;
- hash = _FIRM_FNV_TIMES_PRIME(hash);
- hash ^= y;
- return hash;
-}
-
-#ifdef _MSC_VER
-#pragma warning(default:4307)
-#endif /* _MSC_VER */
-
-/**
- * Make one hash value out of two others.
- * @param a One hash value.
- * @param b Another hash value.
- * @return A hash value computed from the both.
- */
-#define HASH_COMBINE(a,b) _hash_combine(a, b)
-
-#endif
+++ /dev/null
-/*
- * Copyright (C) 1995-2007 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.
- */
-
-/**
- * @file
- * @date 16.03.2007
- * @brief Generic hashset functions
- * @author Matthias Braun
- * @version $Id$
- *
- * You have to specialize this header by defining HashSet, HashSetIterator and
- * ValueType
- */
-#ifdef HashSet
-
-#include <stdlib.h>
-
-#ifdef DO_REHASH
-#define HashSetEntry ValueType
-#else
-typedef struct HashSetEntry {
- ValueType data;
- unsigned hash;
-} HashSetEntry;
-#endif
-
-typedef struct HashSet {
- HashSetEntry *entries;
- size_t num_buckets;
- size_t enlarge_threshold;
- size_t shrink_threshold;
- size_t num_elements;
- size_t num_deleted;
- int consider_shrink;
-#ifndef NDEBUG
- unsigned entries_version;
-#endif
-#ifdef ADDITIONAL_DATA
- ADDITIONAL_DATA
-#endif
-} HashSet;
-
-typedef struct HashSetIterator {
- HashSetEntry *current_bucket;
- HashSetEntry *end;
-#ifndef NDEBUG
- const HashSet *set;
- unsigned entries_version;
-#endif
-} HashSetIterator;
-
-#ifdef DO_REHASH
-#undef HashSetEntry
-#endif
-
-#endif
+++ /dev/null
-/********************************************************************
- ********************************************************************
- **
- ** libhungarian by Cyrill Stachniss, 2004
- **
- ** Added to libFirm by Christian Wuerdig, 2006
- ** Added several options for not-perfect matchings.
- **
- ** Solving the Minimum Assignment Problem using the
- ** Hungarian Method.
- **
- ** ** This file may be freely copied and distributed! **
- **
- ** Parts of the used code was originally provided by the
- ** "Stanford GraphGase", but I made changes to this code.
- ** As asked by the copyright node of the "Stanford GraphGase",
- ** I hereby proclaim that this file are *NOT* part of the
- ** "Stanford GraphGase" distrubition!
- **
- ** This file is distributed in the hope that it will be useful,
- ** but WITHOUT ANY WARRANTY; without even the implied
- ** warranty of MERCHANTABILITY or FITNESS FOR A PARTICULAR
- ** PURPOSE.
- **
- ********************************************************************
- ********************************************************************/
-
-/**
- * @file
- * @brief Solving the Minimum Assignment Problem using the Hungarian Method.
- * @version $Id$
- */
-#ifndef FIRM_ADT_HUNGARIAN_H
-#define FIRM_ADT_HUNGARIAN_H
-
-#define HUNGARIAN_MODE_MINIMIZE_COST 0
-#define HUNGARIAN_MODE_MAXIMIZE_UTIL 1
-
-#define HUNGARIAN_MATCH_NORMAL 0
-#define HUNGARIAN_MATCH_PERFECT 1
-
-typedef struct _hungarian_problem_t hungarian_problem_t;
-
-/**
- * This method initialize the hungarian_problem structure and init
- * the cost matrix (missing lines or columns are filled with 0).
- *
- * @param rows Number of rows in the given matrix
- * @param cols Number of cols in the given matrix
- * @param width Element width for matrix dumping
- * @param match_type The type of matching:
- * HUNGARIAN_MATCH_PERFECT - every nodes matches another node
- * HUNGARIAN_MATCH_NORMAL - matchings of nodes having no edge getting removed
- * @return The problem object.
- */
-hungarian_problem_t *hungarian_new(int rows, int cols, int width, int match_type);
-
-/**
- * Adds an edge from left to right with some costs.
- */
-void hungarian_add(hungarian_problem_t *p, int left, int right, int cost);
-
-/**
-* Removes the edge from left to right.
-*/
-void hungarian_remv(hungarian_problem_t *p, int left, int right);
-
-/**
- * Prepares the cost matrix, dependend on the given mode.
- *
- * @param p The hungarian object
- * @param mode HUNGARIAN_MODE_MAXIMIZE_UTIL or HUNGARIAN_MODE_MINIMIZE_COST (default)
- */
-void hungarian_prepare_cost_matrix(hungarian_problem_t *p, int mode);
-
-/**
- * Destroys the hungarian object.
- */
-void hungarian_free(hungarian_problem_t *p);
-
-/**
- * This method computes the optimal assignment.
- * @param p The hungarian object
- * @param assignment The final assignment
- * @param final_cost The final costs
- * @param cost_threshold Matchings with costs >= this limit will be removed (if limit > 0)
- * @return 0 on success, negative number otherwise
- */
-int hungarian_solve(hungarian_problem_t *p, int *assignment, int *final_cost, int cost_threshold);
-
-/**
- * Print the cost matrix.
- * @param p The hungarian object
- */
-void hungarian_print_costmatrix(hungarian_problem_t *p);
-
-#endif /* _HUNGARIAN_H_ */
+++ /dev/null
-/*
- * Copyright (C) 1995-2007 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.
- */
-
-/**
- * @file
- * @brief Some macros for wrapper function implementation. (WARNING deprecated)
- * @author Sebastian Hack
- * @date 9.12.2004
- *
- * Please don't use these macros, they make the code unnecessarily unreadable!
- */
-#ifndef FIRM_ADT_IMPL_H
-#define FIRM_ADT_IMPL_H
-
-#define _MANGLE(prefix,name) prefix ## name
-
-#define INTERNAL(name) _MANGLE(_, name)
-
-
-#define _HEAD1(name,res,t1) \
- res (name)(t1 p1)
-
-#define _HEAD2(name,res,t1,t2) \
- res (name)(t1 p1, t2 p2)
-
-#define _HEAD3(name,res,t1,t2,t3) \
- res (name)(t1 p1, t2 p2, t3 p3)
-
-#define _HEAD4(name,res,t1,t2,t3,t4) \
- res (name)(t1 p1, t2 p2, t3 p3, t4 p4)
-
-
-#define _IMPL1(name,prefix,ret,res,t1) \
-_HEAD1(name, res, t1) { \
- ret prefix ## name (p1); \
-}
-
-#define _IMPL2(name,prefix,ret,res,t1,t2) \
-_HEAD2(name, res, t1, t2) { \
- ret prefix ## name (p1, p2); \
-}
-
-#define _IMPL3(name,prefix,ret,res,t1,t2,t3) \
-_HEAD3(name, res, t1, t2, t3) { \
- ret prefix ## name (p1, p2, p3); \
-}
-
-#define _IMPL4(name,prefix,ret,res,t1,t2,t3,t4) \
-_HEAD4(name, res, t1, t2, t3, t4) { \
- ret prefix ## name (p1, p2, p3, p4); \
-}
-
-#define IMPL1_VOID(name,prefix,t1) \
- _IMPL1(name, prefix, (void), void, t1)
-
-#define IMPL2_VOID(name,prefix,t1,t2) \
- _IMPL2(name, prefix, (void), void, t1, t2)
-
-#define IMPL3_VOID(name,prefix,t1,t2,t3) \
- _IMPL3(name, prefix, (void), void, t1, t2, t3)
-
-#define IMPL4_VOID(name,prefix,t1,t2,t3,t4) \
- _IMPL4(name, prefix, (void), void, t1, t2, t3, t4)
-
-
-#define IMPL1(name,type,prefix,t1) \
- _IMPL1(name, prefix, return, type, t1)
-
-#define IMPL2(name,type,prefix,t1,t2) \
- _IMPL2(name, prefix, return, type, t1, t2)
-
-#define IMPL3(name,type,prefix,t1,t2,t3) \
- _IMPL3(name, prefix, return, type, t1, t2, t3)
-
-#define IMPL4(name,type,prefix,t1,t2,t3,t4) \
- _IMPL4(name, prefix, return, type, t1, t2, t3, t4)
-
-
-#define FIRM_IMPL1(name,type,t1) \
- _IMPL1(name, _, return, type, t1)
-
-#define FIRM_IMPL2(name,type,t1,t2) \
- _IMPL2(name, _, return, type, t1, t2)
-
-#define FIRM_IMPL3(name,type,t1,t2,t3) \
- _IMPL3(name, _, return, type, t1, t2, t3)
-
-#define FIRM_IMPL4(name,type,t1,t2,t3,t4) \
- _IMPL4(name, _, return, type, t1, t2, t3, t4)
-
-
-#define FIRM_IMPL1_VOID(name,t1) \
- _IMPL1(name, _, (void), void, t1)
-
-#define FIRM_IMPL2_VOID(name,t1,t2) \
- _IMPL2(name, _, (void), void, t1, t2)
-
-#define FIRM_IMPL3_VOID(name,t1,t2,t3) \
- _IMPL3(name, _, (void), void, t1, t2, t3)
-
-#define FIRM_IMPL4_VOID(name,t1,t2,t3,t4) \
- _IMPL4(name, _, (void), void, t1, t2, t3, t4)
-
-#define FIRM_PROTO1(name,type,t1) _HEAD1(name, type, t1)
-#define FIRM_PROTO2(name,type,t1,t2) _HEAD2(name, type, t1, t2)
-#define FIRM_PROTO3(name,type,t1,t2,t3) _HEAD3(name, type, t1, t2, t3)
-#define FIRM_PROTO4(name,type,t1,t2,t3,t4) _HEAD4(name, type, t1, t2, t3, t4)
-
-#endif
+++ /dev/null
-/*
- * Copyright (C) 1995-2007 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.
- */
-
-/**
- * @file
- * @brief Iterators for the several collection types used in firm.
- * Useful for formatted and unified dumping of collections of objects.
- * @author Sebastian Hack
- * @date 29.11.2004
- * @version $Id$
- */
-#ifndef FIRM_ADT_ITERATOR_H
-#define FIRM_ADT_ITERATOR_H
-
-#include "fourcc.h"
-
-/**
- * The iterator magic word.
- */
-#define ITERATOR_MAGIC FOURCC('I', 'T', 'E', 'R')
-
-/**
- * Check, if some memory object appears to be an iterator.
- * @param ptr Some memory.
- * @return 1, if that memory area appears to be an iterator, 0 if not.
- */
-#define is_iterator(ptr) (((const iterator_t *) (ptr))->magic == ITERATOR_MAGIC)
-
-typedef struct _iterator_t {
- unsigned magic;
- void *(*start)(void *collection);
- void *(*next)(void *collection, void *curr);
- void (*finish)(void *collection, void *curr);
-} iterator_t;
-
-/**
- * An iterator implementation for linked lists.
- */
-extern const iterator_t *list_iterator;
-
-/**
- * An iterator implementation for psets.
- */
-extern const iterator_t *pset_iterator;
-
-#endif
+++ /dev/null
-
-/**
- * @file
- * @brief Doubly linked lists.
- * @version $Id$
- *
- * Simple doubly linked list implementation.
- *
- * Some of the internal functions ("__xxx") are useful when
- * manipulating whole lists rather than single entries, as
- * sometimes we already know the next/prev entries and we can
- * generate better code by using them directly rather than
- * using the generic single-entry routines.
- */
-#ifndef FIRM_ADT_LIST_H
-#define FIRM_ADT_LIST_H
-
-#include "firm_config.h"
-
-struct list_head {
- struct list_head *next, *prev;
-};
-
-#define LIST_HEAD_INIT(name) { &(name), &(name) }
-
-#define LIST_HEAD(name) \
- struct list_head name = LIST_HEAD_INIT(name)
-
-#define INIT_LIST_HEAD(ptr) do { \
- (ptr)->next = (ptr); (ptr)->prev = (ptr); \
-} while (0)
-
-#define _list_offsetof(type,member) \
- ((char *) &(((type *) 0)->member) - (char *) 0)
-
-#define _list_container_of(ptr, type, member) \
- ((type *) ((char *) (ptr) - _list_offsetof(type, member)))
-
-/*
- * Insert a new entry between two known consecutive entries.
- *
- * This is only for internal list manipulation where we know
- * the prev/next entries already!
- */
-static INLINE void __list_add(struct list_head *new_node,
- struct list_head *prev,
- struct list_head *next)
-{
- next->prev = new_node;
- new_node->next = next;
- new_node->prev = prev;
- prev->next = new_node;
-}
-
-/**
- * list_add - add a new entry
- * @param new_node new entry to be added
- * @param head list head to add it after
- *
- * Insert a new entry after the specified head.
- * This is good for implementing stacks.
- */
-static INLINE void list_add(struct list_head *new_node, struct list_head *head)
-{
- __list_add(new_node, head, head->next);
-}
-
-/**
- * list_add_tail - add a new entry
- * @param new_node new entry to be added
- * @param head list head to add it before
- *
- * Insert a new entry before the specified head.
- * This is useful for implementing queues.
- */
-static INLINE void list_add_tail(struct list_head *new_node, struct list_head *head)
-{
- __list_add(new_node, head->prev, head);
-}
-
-/*
- * Delete a list entry by making the prev/next entries
- * point to each other.
- *
- * This is only for internal list manipulation where we know
- * the prev/next entries already!
- */
-static INLINE void __list_del(struct list_head * prev, struct list_head * next)
-{
- next->prev = prev;
- prev->next = next;
-}
-
-/**
- * list_del - deletes entry from list.
- * @param entry the element to delete from the list.
- *
- * @Note
- * list_empty on entry does not return true after this, the entry is
- * in an undefined state.
- */
-static INLINE void list_del(struct list_head *entry)
-{
- __list_del(entry->prev, entry->next);
- entry->next = NULL;
- entry->prev = NULL;
-}
-
-
-/**
- * list_del_init - deletes entry from list and reinitialize it.
- * @param entry the element to delete from the list.
- */
-static INLINE void list_del_init(struct list_head *entry)
-{
- __list_del(entry->prev, entry->next);
- INIT_LIST_HEAD(entry);
-}
-
-/**
- * list_move - delete from one list and add as another's head
- * @param list the entry to move
- * @param head the head that will precede our entry
- */
-static INLINE void list_move(struct list_head *list, struct list_head *head)
-{
- __list_del(list->prev, list->next);
- list_add(list, head);
-}
-
-/**
- * list_move_tail - delete from one list and add as another's tail
- * @param list the entry to move
- * @param head the head that will follow our entry
- */
-static INLINE void list_move_tail(struct list_head *list,
- struct list_head *head)
-{
- __list_del(list->prev, list->next);
- list_add_tail(list, head);
-}
-
-/**
- * list_empty - tests whether a list is empty
- * @param head the list to test.
- */
-static INLINE int list_empty(const struct list_head *head)
-{
- return head->next == head;
-}
-
-static INLINE void __list_splice(struct list_head *list,
- struct list_head *head)
-{
- struct list_head *first = list->next;
- struct list_head *last = list->prev;
- struct list_head *at = head->next;
-
- first->prev = head;
- head->next = first;
-
- last->next = at;
- at->prev = last;
-}
-
-/**
- * list_splice - join two lists
- * @param list the new list to add.
- * @param head the place to add it in the first list.
- */
-static INLINE void list_splice(struct list_head *list, struct list_head *head)
-{
- if (!list_empty(list))
- __list_splice(list, head);
-}
-
-/**
- * list_splice_init - join two lists and reinitialize the emptied list.
- * @param list the new list to add.
- * @param head the place to add it in the first list.
- *
- * The list at list is reinitialized
- */
-static INLINE void list_splice_init(struct list_head *list,
- struct list_head *head)
-{
- if (!list_empty(list)) {
- __list_splice(list, head);
- INIT_LIST_HEAD(list);
- }
-}
-
-/**
- * list_entry - get the struct for this entry
- * @param ptr the &struct list_head pointer.
- * @param type the type of the struct this is embedded in.
- * @param member the name of the list_struct within the struct.
- */
-#define list_entry(ptr, type, member) \
- _list_container_of(ptr, type, member)
-
-/**
- * list_for_each - iterate over a list
- * @param pos the &struct list_head to use as a loop counter.
- * @param head the head for your list.
- */
-#define list_for_each(pos, head) \
- for (pos = (head)->next; pos != (head); pos = pos->next)
-
-/**
- * __list_for_each - iterate over a list
- * @param pos the &struct list_head to use as a loop counter.
- * @param head the head for your list.
- *
- * This variant differs from list_for_each() in that it's the
- * simplest possible list iteration code, no ing is done.
- * Use this for code that knows the list to be very short (empty
- * or 1 entry) most of the time.
- */
-#define __list_for_each(pos, head) \
- for (pos = (head)->next; pos != (head); pos = pos->next)
-
-/**
- * list_for_each_prev - iterate over a list backwards
- * @param pos the &struct list_head to use as a loop counter.
- * @param head the head for your list.
- */
-#define list_for_each_prev(pos, head) \
- for (pos = (head)->prev; pos != (head); pos = pos->prev)
-
-/**
- * list_for_each_safe - iterate over a list safe against removal of list entry
- * @param pos the &struct list_head to use as a loop counter.
- * @param n another &struct list_head to use as temporary storage
- * @param head the head for your list.
- */
-#define list_for_each_safe(pos, n, head) \
- for (pos = (head)->next, n = pos->next; pos != (head); \
- pos = n, n = pos->next)
-
-/**
- * list_for_each_entry - iterate over list of given type
- * @param type the type of the struct where the listhead is embedded in
- * @param pos the type * to use as a loop counter.
- * @param head the head for your list.
- * @param member the name of the list_struct within the struct.
- */
-#define list_for_each_entry(type, pos, head, member) \
- for (pos = list_entry((head)->next, type, member); \
- &pos->member != (head); \
- pos = list_entry(pos->member.next, type, member))
-
-/**
- * list_for_each_entry_reverse - iterate backwards over list of given type.
- * @param type the type of the struct where the listhead is embedded in
- * @param pos the type * to use as a loop counter.
- * @param head the head for your list.
- * @param member the name of the list_struct within the struct.
- */
-#define list_for_each_entry_reverse(type, pos, head, member) \
- for (pos = list_entry((head)->prev, type, member); \
- &pos->member != (head); \
- pos = list_entry(pos->member.prev, type, member))
-
-
-/**
- * list_for_each_entry_safe - iterate over list of given type safe against removal of list entry
- * @param type the type of the struct where the listhead is embedded in
- * @param pos the type * to use as a loop counter.
- * @param n another type * to use as temporary storage
- * @param head the head for your list.
- * @param member the name of the list_struct within the struct.
- */
-#define list_for_each_entry_safe(type, pos, n, head, member) \
- for (pos = list_entry((head)->next, type, member), \
- n = list_entry(pos->member.next, type, member); \
- &pos->member != (head); \
- pos = n, n = list_entry(n->member.next, type, member))
-
-
-#endif
+++ /dev/null
-/*
- * Copyright (C) 1995-2007 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.
- */
-
-/**
- * @file
- * @brief Provied obstack_chunk_alloc and obstack_chunk_free for obstack.h
- * @author Martin Trapp, Christian Schaefer
- * @version $Id$
- */
-#ifndef FIRM_ADT_OBST_H
-#define FIRM_ADT_OBST_H
-
-#include <obstack.h>
-#include "xmalloc.h"
-
-#define obstack_chunk_alloc xmalloc
-#define obstack_chunk_free free
-
-#endif
+++ /dev/null
-/*
- * Copyright (C) 1995-2007 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.
- */
-
-/**
- * @file
- * @brief Implementation of offset_of and container_of
- * @date 31.05.2005
- * @author Sebastian Hack
- */
-#ifndef FIRM_ADT_OFFSET_H
-#define FIRM_ADT_OFFSET_H
-
-/**
- * Get the offset of a member of a struct.
- * @param type The type of the struct member is in.
- * @param member The name of the member.
- * @return The offset of member in type in bytes.
- */
-#define firm_offset_of(type, member) ((char *) &((type *) 0)->member - (char *) 0)
-
-/**
- * Make pointer to the struct from a pointer to a member of that struct.
- * @param ptr The pointer to the member.
- * @param type The type of the struct.
- * @param member The name of the member.
- * @return A pointer to the struct member is in.
- */
-#define firm_container_of(ptr, type, member) ((type *) ((char *) (ptr) - firm_offset_of(type, member)))
-
-#endif
+++ /dev/null
-/*
- * Copyright (C) 1995-2007 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.
- */
-
-/**
- * @file
- * @brief double ended queue of generic pointers.
- * @author Christian von Roques
- * @version $Id$
- */
-#ifndef FIRM_ADT_PDEQ_H
-#define FIRM_ADT_PDEQ_H
-
-/**
- * The type of the pointer compare function.
- *
- * @param elem The list element.
- * @param key The user supplied key.
- *
- * @return 0 if the element matches the key, non-zero else.
- */
-typedef int (*cmp_fun)(const void *elem, const void *key);
-
-/**
- * The pointer double ended queue (list).
- */
-typedef struct pdeq pdeq;
-
-/**
- * Creates a new double ended pointer list.
- *
- * @return A new list.
- */
-pdeq *new_pdeq(void);
-
-/**
- * Creates a new double ended pointer list and puts an initial pointer element in.
- *
- * @param x The pointer element to put in.
- *
- * @return The new list.
- */
-pdeq *new_pdeq1(const void *x);
-
-/**
- * Delete a double ended pointer list.
- *
- * @param dq The list to be deleted.
- */
-void del_pdeq(pdeq *dq);
-
-/**
- * Returns the lenght of a double ended pointer list.
- *
- * @param dq The list.
- */
-int pdeq_len(pdeq *dq);
-
-/**
- * Checks if a list is empty.
- *
- * @param dq The list.
- *
- * @return non-zero if the list is empty.
- */
-int pdeq_empty(pdeq *dq);
-
-/**
- * Returns non-zero if a double ended pointer list
- * contains a pointer x.
- *
- * @param dq The list.
- * @param x The pointer to be searched for.
- */
-int pdeq_contains(pdeq *dq, const void *x);
-
-/**
- * Search a key in a double ended pointer list, the search
- * is controlled by a compare function.
- * An element is found, if the compare function returns 0.
- * The search is started from the left site of the list.
- *
- * @param qp The list.
- * @param cmp The compare function.
- * @param key The search key.
- *
- * @return The address of the element entry if the key was found,
- * NULL else.
- */
-void *pdeq_search(pdeq *qp, cmp_fun cmp, const void *key);
-
-/**
- * Convert the double ended pointer list into a linear array beginning from
- * left, the first element in the linear array will be the left one.
- *
- * @param qp The list.
- * @param dst A pointer to a pointer array with must be at least
- * pdeq_len(dq) * sizeof(void *)
- *
- * @return dst
- */
-void **pdeq_copyl(pdeq *qp, const void **dst);
-
-/**
- * Convert the double ended pointer list into a linear array beginning from
- * right, the first element in the linear array will be the right one.
- *
- * @param qp The list.
- * @param dst A pointer to a pointer array with must be at least
- * pdeq_len(dq) * sizeof(void *)
- *
- * @return dst
- */
-void **pdeq_copyr(pdeq *qp, const void **dst);
-
-/**
- * Add a pointer to the left side of a double ended pointer list.
- *
- * @param dq The list to add a pointer to.
- * @param x The pointer element to be added
- *
- * @return The list.
- */
-pdeq *pdeq_putl(pdeq *dq, const void *x);
-
-/**
- * Add a pointer to the right side of a double ended pointer list.
- *
- * @param dq The list to add a pointer to.
- * @param x The pointer element to be added
- *
- * @return The list.
- */
-pdeq *pdeq_putr(pdeq *dq, const void *x);
-
-/**
- * Retrieve a pointer from the left site of a double ended pointer list.
- *
- * @param dq The list
- *
- * @return The pointer element.
- *
- * @remark This function will fail if the list is empty.
- */
-void *pdeq_getl(pdeq *dq);
-
-/**
- * Retrieve a pointer from the right site of a double ended pointer list.
- *
- * @param dq The list
- *
- * @return The pointer element.
- *
- * @remark This function will fail if the list is empty.
- */
-void *pdeq_getr(pdeq *dq);
-
-#ifdef NDEBUG
-#define PDEQ_VRFY(deq) ((void)0)
-#else
-#define PDEQ_VRFY(deq) _pdeq_vrfy ((deq))
-void _pdeq_vrfy(pdeq *dq);
-#endif
-
-/**
- * The pdeq is often used as a wait queue. A helper
- * type to support this.
- */
-typedef pdeq waitq;
-
-/**
- * Creates a new pointer wait queue (fifo).
- *
- * @return A new queue.
- */
-#define new_waitq() new_pdeq()
-
-/**
- * Delete a wait queue (fifo)
- *
- * @param wq The wait queue.
- */
-#define del_waitq(wq) del_pdeq(wq)
-
-/**
- * Retrieve a pointer from the wait queue (fifo).
- *
- * @param wq The wait queue.
- *
- * @return The pointer element.
- *
- * @remark This function will fail if the queue is empty.
- */
-#define waitq_get(wq) pdeq_getl(wq)
-
-/**
- * Add a pointer to the wait queue (fifo).
- *
- * @param wq The wait queue
- * @param x The pointer element to be added
- *
- * @return The wait queue.
- */
-#define waitq_put(wq, x) pdeq_putr((wq), (x))
-
-/**
- * Checks if a wait queue is empty.
- *
- * @param wq The wait queue.
- *
- * @return non-zero if the queue is empty.
- */
-#define waitq_empty(wq) pdeq_empty(wq)
-
-/**
- * The pdeq can be used as a stack. A helper
- * type to support this.
- */
-typedef pdeq stack;
-
-/**
- * Creates a new pointer stack (lifo).
- *
- * @return A new stack.
- */
-#define new_stack() new_pdeq()
-
-/**
- * Pop a pointer from the stack (lifo).
- *
- * @param st The stack.
- *
- * @return The pointer element.
- *
- * @remark This function will fail if the stack is empty.
- */
-#define stack_pop(st) pdeq_getr(st)
-
-/**
- * Push a pointer to the stack (lifo).
- *
- * @param st The stack.
- * @param x The pointer element to be added
- *
- * @return The stack.
- */
-#define stack_push(st, x) pdeq_putr((st), (x))
-
-/**
- * Checks if a stack is empty.
- *
- * @param st The stack.
- *
- * @return non-zero if the stack is empty.
- */
-#define stack_empty(st) pdeq_empty(wq)
-
-#endif
+++ /dev/null
-/*
- * Copyright (C) 1995-2007 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.
- */
-
-/**
- * @file
- * @author Kimon Hoffmann
- * @date 14.07.2005
- * @cvs-id $Id$
- * @summary Simple, non circular, double linked pointer list.
- * Created because the properties of the standard circular list were
- * not very well suited for the interference graph implementation.
- * This list uses an obstack and a free-list to efficiently manage its
- * elements.
- * @note Until now the code is entirely untested so it probably contains
- * plenty of errors. (Matze: Is this still true, the code seems to be
- * used at some places....)
- */
-#ifndef FIRM_ADT_PLIST_H
-#define FIRM_ADT_PLIST_H
-
-#include <stddef.h>
-#include "obst.h"
-
-typedef struct _plist_element plist_element_t;
-typedef struct _plist plist_t;
-
-/**
- * The plist data type.
- */
-struct _plist {
- /**
- * The obstack used for all allocations.
- */
- struct obstack *obst;
-
- /* Set to 1 if plist uses a foreign obstack */
- unsigned foreign_obstack : 1;
-
- /**
- * First element in the list.
- */
- plist_element_t *first_element;
-
- /**
- * Last element in the list.
- */
- plist_element_t *last_element;
-
- /**
- * Current number of elements in the list.
- */
- int element_count;
-
- /**
- * First element in the free list.
- * Please note that the free list is a single linked list and all back
- * references are invalid.
- */
- plist_element_t* first_free_element;
-};
-
-/**
- * An element in the pointer list.
- */
-struct _plist_element {
- plist_element_t *next;
- plist_element_t *prev;
- void *data;
-};
-
-/**
- * Creates a new pointer list and initializes it.
- * @return The newly created pointer list.
- */
-plist_t *plist_new(void);
-
-/**
- * Creates a new pointer list and initializes it.
- * Uses the given obstack instead of creating one.
- * @param obst The obstack to use
- * @return The newly created pointer list.
- */
-plist_t *plist_obstack_new(struct obstack *obst);
-
-/**
- * Frees the passed pointer list.
- * After a call to this function all references to the list and any of
- * its elements are invalid.
- */
-void plist_free(plist_t *list);
-
-/**
- * Returns the number of elements in a pointer list.
- * @param list the pointer list
- * @return The number of elements in a pointer list.
- */
-#define plist_count(list) \
- ((list)->element_count)
-
-/**
- * Inserts an element at the back of a pointer list.
- * @param list the pointer list to append the new element to.
- * @param value the element value to append.
- */
-void plist_insert_back(plist_t *list, void *value);
-
-/**
- * Inserts an element at the front of a pointer list.
- * @param list the pointer list to prepend the new element to.
- * @param value the element value to prepend.
- */
-void plist_insert_front(plist_t *list, void *value);
-
-/**
- * Inserts an element into a pointer list before the specified element,
- * which must be non null.
- * @param list the pointer list to insert the new element into.
- * @param element the list element before which the new element should
- * be inserted. This element must be a part of @p list.
- * @param value the element value to insert.
- */
-void plist_insert_before(plist_t *list, plist_element_t *element, void *value);
-
-/**
- * Inserts an element into a pointer list after the specified element,
- * which must be non null.
- * @param list the pointer list to insert the new element into.
- * @param element the list element after which the new element should
- * be inserted. This element must be a part of @p list.
- * @param value the element value to insert.
- */
-void plist_insert_after(plist_t *list, plist_element_t *element, void *value);
-
-/**
- * Checks if list has an element with the given data pointer.
- * @param list the list to check
- * @param value the data pointer to look for
- * @return 1 if element with data pointer found, 0 otherwise
- */
-int plist_has_value(plist_t *list, void *value);
-
-/**
- * Tries to find list element associated to the given data pointer.
- * @param list the list to check
- * @param value the data pointer to look for
- * @return The first list element associated to data pointer if found, NULL otherwise
- */
-plist_element_t *plist_find_value(plist_t *list, void *value);
-
-/**
- * Erases the specified element from the pointer list.
- * @param list the pointer list from which the element should be erased.
- * @param element the list element to erase. This element must be a part
- * of @p list.
- */
-void plist_erase(plist_t *list, plist_element_t *element);
-
-/**
- * Erases all elements from the specified pointer list.
- * @param list the pointer list that should be cleared.
- */
-void plist_clear(plist_t *list);
-
-/**
- * Returns the first element of a pointer list.
- * @param list the pointer list to iterate
- * @return a pointer to the element or NULL if the list is empty
- */
- #define plist_first(list) \
- ((list)->first_element)
-
-/**
- * Returns the last element of a pointer list.
- * @param list the pointer list to iterate
- * @return a pointer to the element or NULL if the list is empty
- */
- #define plist_last(list) \
- ((list)->last_element)
-
-/**
- * Checks whether a pointer list element has a successor or not.
- * @param element the list element that should be queried for existence
- * of a successor.
- * @return TRUE if @p element has a successor, otherwise FALSE.
- */
-#define plist_element_has_next(element) \
- ((element)->next != NULL)
-
-/**
- * Checks whether a pointer list element has a predecessor or not.
- * @param element the list element that should be queried for existence
- * of a predecessor.
- * @return TRUE if @p element has a successor, otherwise FALSE.
- */
-#define plist_element_has_prev(element) \
- ((element)->prev != NULL)
-
-/**
- * Gets the successor of the passed list element.
- * @param element the list element to return the successor of.
- * @return The successor of @p element or NULL if @p element is the last
- * element in the sequence.
- */
-#define plist_element_get_next(element) \
- ((element)->next)
-
-/**
- * Gets the predecessor of the passed list element.
- * @param element the list element to return the predecessor of.
- * @return The predecessor of @p element or NULL if @p element is the last
- * element in the sequence.
- */
-#define plist_element_get_prev(element) \
- ((element)->prev)
-
-/**
- * Gets the value stored in the passed list element.
- * @param element the list element to return the value of.
- * @return The value stored in @p element.
- */
-#define plist_element_get_value(element) \
- ((element)->data)
-
-/**
- * Convenience macro to iterate over a plist.
- */
-#define foreach_plist(list, el) \
- for (el = plist_first(list); el; el = plist_element_get_next(el))
-
-#endif /*_PLIST_H_*/
+++ /dev/null
-/*
- * Copyright (C) 1995-2007 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.
- */
-
-/**
- * @file
- * @brief Simplified hashnap for pointer->pointer relations
- * @author Hubert Schmid
- * @date 09.06.2002
- * @version $Id$
- */
-#ifndef FIRM_ADT_PMAP_H
-#define FIRM_ADT_PMAP_H
-
-/** A map which maps addresses to addresses. */
-typedef struct pmap pmap;
-
-/**
- * A key, value pair.
- */
-typedef struct pmap_entry {
- const void *key; /**< The key. */
- void *value; /**< The value. */
-} pmap_entry;
-
-
-/** Creates a new empty map. */
-pmap *pmap_create(void);
-
-/** Creates a new empty map with an initial number of slots. */
-pmap *pmap_create_ex(int slots);
-
-/** Deletes a map. */
-void pmap_destroy(pmap *);
-
-/**
- * Inserts a pair (key,value) into the map. If an entry with key
- * "key" already exists, its "value" is overwritten.
- */
-void pmap_insert(pmap *map, const void * key, void * value);
-
-/** Checks if an entry with key "key" exists. */
-int pmap_contains(pmap *map, const void * key);
-
-/** Returns the key, value pair of "key". */
-pmap_entry * pmap_find(pmap *map, const void * key);
-
-/** Returns the value of "key". */
-void * pmap_get(pmap *map, const void * key);
-
-int pmap_count(pmap *map);
-
-/**
- * Returns the first entry of a map if the map is not empty.
- */
-pmap_entry *pmap_first(pmap *map);
-
-/**
- * Returns the next entry of a map or NULL if all entries were visited.
- */
-pmap_entry *pmap_next(pmap *);
-
-#define pmap_foreach(pmap, curr) \
- for (curr = pmap_first(pmap); curr; curr = pmap_next(pmap))
-
-/** Breaks an iteration.
- * Must be called, if a iteration ends before p_map_next() returns NULL.
- */
-void pmap_break(pmap *map);
-
-#endif
+++ /dev/null
-/*
- * Copyright (C) 1995-2007 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.
- */
-
-/**
- * @file
- * @date 18.04.2007
- * @author Christian Wuerdig
- * @brief Implementation of a priority queue. This is the ported version of the
- * original Java implementation by Matthias Braun.
- * @version $Id$
- */
-#ifndef FIRM_ADT_PQUEUE_H
-#define FIRM_ADT_PQUEUE_H
-
-typedef struct _pqueue_t pqueue;
-
-/**
- * Creates a new priority queue.
- * @return A priority queue of initial length 0.
- */
-pqueue *new_pqueue(void);
-
-/**
- * Frees all memory allocated by the priority queue.
- * @param q The priority queue to destroy.
- */
-void del_pqueue(pqueue *q);
-
-/**
- * Inserts a new element into a priority queue.
- * @param q The priority queue the element should be inserted to.
- * @param data The actual data which should be stored in the queue.
- * @param key The priority for the data.
- */
-void pqueue_put(pqueue *q, void *data, int key);
-
-/**
- * Returns and removes the first element, ie. that one with the highest priority, from the queue.
- * @param q The priority queue.
- * @return The first element of the queue. Asserts if queue is empty.
- */
-void *pqueue_get(pqueue *q);
-
-/**
- * Get the length of the priority queue.
- * @param q The priority queue.
- * @return The length of the queue.
- */
-int pqueue_length(pqueue *q);
-
-/**
- * Returns true if queue is empty.
- * @param q The priority queue.
- * @return 1 if the queue is empty, 0 otherwise.
- */
-int pqueue_empty(pqueue *q);
-
-#endif
+++ /dev/null
-/*
- * Copyright (C) 1995-2007 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.
- */
-
-/**
- * @file
- * @brief optimized version of set for sets containing only pointers
- * (deprecated)
- * @author Markus Armbruster
- * @version $Id$
- * @note This code has been deprecated. Use pset_new or cpset for new
- * code.
- */
-#ifndef FIRM_ADT_PSET_H
-#define FIRM_ADT_PSET_H
-
-#include <stddef.h>
-
-#include "hashptr.h"
-#include "iterator.h"
-
-/**
- * The default comparison function for pointers.
- * @param x A pointer.
- * @param y A pointer.
- * @return 0 if @p x and @p y are equal. Some value != 0 otherwise.
- */
-int pset_default_ptr_cmp(const void *x, const void *y);
-
-/**
- * The abstract type of a pset (Set of pointers).
- *
- * This kind of sets stores only pointer to elements, the elements itself
- * must be stored somewhere else.
- *
- * @see set
- */
-typedef struct pset pset;
-
-/*
- * Define some convenience macros using the predefined hash function.
- */
-#define pset_insert_ptr(set,key) pset_insert(set, key, HASH_PTR(key))
-#define pset_hinsert_ptr(set,key) pset_hinsert(set, key, HASH_PTR(key))
-#define pset_remove_ptr(set,key) pset_remove(set, key, HASH_PTR(key))
-#define pset_find_ptr(set,key) pset_find(set, key, HASH_PTR(key))
-#define pset_new_ptr(slots) new_pset(pset_default_ptr_cmp, slots)
-#define pset_new_ptr_default() pset_new_ptr(64)
-
-/** The entry of a pset, representing an element pointer in the set and it's meta-information */
-typedef struct {
- unsigned hash;
- void *dptr;
-} pset_entry;
-
-/**
- * The type of a set compare function.
- *
- * @param elt pointer to an element
- * @param key pointer to another element
- *
- * @return
- * 0 if the elements are identically, non-zero else
- */
-typedef int (*pset_cmp_fun) (const void *elt, const void *key);
-
-/**
- * Creates a new pset.
- *
- * @param func The compare function of this pset.
- * @param slots Initial number of collision chains. I.e., #slots
- * different keys can be hashed without collisions.
- *
- * @returns
- * created pset
- */
-pset *new_pset (pset_cmp_fun func, int slots);
-
-/**
- * Deletes a pset.
- *
- * @param pset the pset
- *
- * @note
- * This does NOT delete the elements of this pset, just it's pointers!
- */
-void del_pset (pset *pset);
-
-/**
- * Returns the number of elements in a pset.
- *
- * @param pset the pset
- */
-int pset_count (pset *pset);
-
-/**
- * Searches an element pointer in a pset.
- *
- * @param pset the pset to search in
- * @param key the element to search
- * @param hash the hash value of key
- *
- * @return
- * the pointer of the found element in the pset or NULL if it was not found
- */
-void *pset_find (pset *pset, const void *key, unsigned hash);
-
-/**
- * Inserts an element pointer into a pset.
- *
- * @param pset the pset to insert in
- * @param key a pointer to the element to be inserted
- * @param hash the hash-value of the element
- *
- * @return a pointer to the inserted element
- *
- * @note
- * It is not possible to insert an element more than once. If an element
- * that should be inserted is already in the set, this functions does
- * nothing but returning its already existing set_entry.
-
- */
-void *pset_insert (pset *pset, const void *key, unsigned hash);
-
-/**
- * Inserts an element pointer into a pset and returns its pset_entry.
- *
- * @param pset the pset to insert in
- * @param key a pointer to the element to be inserted
- * @param hash the hash-value of the element
- *
- * @return a pointer to the pset_entry of the inserted element
- *
- * @note
- * It is not possible to insert an element more than once. If an element
- * that should be inserted is already in the pset, this functions does
- * nothing but returning its pset_entry.
- */
-pset_entry *pset_hinsert (pset *pset, const void *key, unsigned hash);
-
-/**
- * Removes an element from a pset.
- *
- * @param pset the pset to delete in
- * @param key a pointer to the element to be deleted
- * @param hash the hash-value of the element
- *
- * @return
- * the pointer to the removed element
- *
- * @remark
- * The current implementation did not allow to remove non-existing elements.
- * @@@ so, does it do now?
- * Further, it is allowed to remove elements during an iteration
- * including the current one.
- */
-void *pset_remove (pset *pset, const void *key, unsigned hash);
-
-/**
- * Returns the first element of a pset.
- *
- * @param pset the pset to iterate
- *
- * @return a pointer to the element or NULL if the set is empty
- */
-void *pset_first (pset *pset);
-
-/**
- * Returns the next element of a pset.
- *
- * @param pset the pset to iterate
- *
- * @return a pointer to the next element or NULL if the
- * iteration is finished
- */
-void *pset_next (pset *pset);
-
-/**
- * Breaks the iteration of a set. Must be called before
- * the next pset_first() call if the iteration was NOT
- * finished.
- *
- * @param pset the pset
- */
-void pset_break (pset *pset);
-
-/**
- * Iterates oven an pset.
- *
- * @param pset the pset
- * @param entry the iterator
- */
-#define foreach_pset(pset, entry) for (entry = pset_first(pset); entry; entry = pset_next(pset))
-
-/**
- * Inserts all elements of the pointer set src into
- * the set target (union).
- *
- * @param target the target set, will contain the union
- * @param src a set, will not be changed
- */
-void pset_insert_pset_ptr(pset *target, pset *src);
-
-#define new_pset(cmp, slots) (PSET_TRACE (new_pset) ((cmp), (slots)))
-#define pset_find(pset, key, hash) \
- _pset_search ((pset), (key), (hash), _pset_find)
-#define pset_insert(pset, key, hash) \
- _pset_search ((pset), (key), (hash), _pset_insert)
-#define pset_hinsert(pset, key, hash) \
- ((pset_entry *)_pset_search ((pset), (key), (hash), _pset_hinsert))
-
-#ifdef STATS
-/**
- * Prints statistics on a set to stdout.
- *
- * @param pset the pset
- */
-void pset_stats (pset *pset);
-#else
-# define pset_stats(s) ((void)0)
-#endif
-
-#ifdef DEBUG
-/**
- * Describe a pset.
- *
- * Writes a description of a set to stdout. The description includes:
- * - a header telling how many elements (nkey) and segments (nseg) are in use
- * - for every collision chain the number of element with its hash values
- *
- * @param pset the pset
- */
-void pset_describe (pset *pset);
-#endif
-
-/* @@@ NYI */
-#define PSET_VRFY(pset) (void)0
-
-
-/* Private */
-
-typedef enum { _pset_find, _pset_insert, _pset_hinsert } _pset_action;
-
-void *_pset_search (pset *, const void *, unsigned, _pset_action);
-
-#if defined(DEBUG) && defined(HAVE_GNU_MALLOC)
-extern const char *pset_tag;
-# ifdef PSET_ID
-# define PSET_TRACE pset_tag = SET_ID,
-# else
-# define PSET_TRACE pset_tag = __FILE__,
-# endif
-#else /* !(DEBUG && HAVE_GNU_MALLOC) */
-# define PSET_TRACE
-#endif /* !(DEBUG && HAVE_GNU_MALLOC) */
-
-#endif
+++ /dev/null
-/*
- * Copyright (C) 1995-2007 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.
- */
-
-/**
- * @file
- * @date 17.03.2007
- * @brief hashset containing pointers
- * @author Matthias Braun
- * @version $Id$
- *
- * @note This has been named pset_new_new for now until all code has been
- * changed to use this instead of the old deprecated pset_new functions!
- * This version performs better than pset in terms of speed and memory
- * usage and allows multiple iterators over the set
- */
-#ifndef FIRM_ADT_PSET_NEW_H
-#define FIRM_ADT_PSET_NEW_H
-
-#define HashSet pset_new_t
-#define HashSetIterator pset_new_iterator_t
-#define ValueType void*
-#define DO_REHASH
-#include "hashset.h"
-#undef DO_REHASH
-#undef HashSet
-#undef HashSetIterator
-#undef ValueType
-
-/**
- * Initializes a pset_new
- *
- * @param pset_new Pointer to allocated space for the pset_new
- */
-void pset_new_init(pset_new_t *pset_new);
-
-/**
- * Initializes a pset_new
- *
- * @param pset_new Pointer to allocated space for the pset_new
- * @param expected_elements Number of elements expected in the pset_new (roughly)
- */
-void pset_new_init_size(pset_new_t *pset_new, size_t expected_elements);
-
-/**
- * Destroys a pset_new and frees the memory allocated for hashtable. The memory of
- * the pset_new itself is not freed.
- *
- * @param pset_new Pointer to the pset_new
- */
-void pset_new_destroy(pset_new_t *pset_new);
-
-/**
- * Inserts an element into a pset_new.
- *
- * @param pset_new Pointer to the pset_new
- * @param ptr Pointer to insert into the pset_new
- * @returns 1 if the pointer was inserted, 0 if it was already there
- */
-int pset_new_insert(pset_new_t *pset_new, void *ptr);
-
-/**
- * Removes an element from a pset_new. Does nothing if the pset_new doesn't contain the
- * element.
- *
- * @param pset_new Pointer to the pset_new
- * @param ptr Pointer to remove from the pset_new
- */
-void pset_new_remove(pset_new_t *pset_new, const void *ptr);
-
-/**
- * Tests whether a pset_new contains a pointer
- *
- * @param pset_new Pointer to the pset_new
- * @param ptr The pointer to test
- * @returns 1 @p pset_new contains the @p ptr, 0 otherwise
- */
-int pset_new_contains(const pset_new_t *pset_new, const void *ptr);
-
-/**
- * Returns the number of pointers contained in the pset_new
- *
- * @param pset_new Pointer to the pset_new
- * @returns Number of pointers contained in the pset_new
- */
-size_t pset_new_size(const pset_new_t *pset_new);
-
-/**
- * Initializes a pset_new iterator. Sets the iterator before the first element in
- * the pset_new.
- *
- * @param iterator Pointer to already allocated iterator memory
- * @param pset_new Pointer to the pset_new
- */
-void pset_new_iterator_init(pset_new_iterator_t *iterator, const pset_new_t *pset_new);
-
-/**
- * Advances the iterator and returns the current element or NULL if all elements
- * in the pset_new have been processed.
- * @attention It is not allowed to use pset_new_insert or pset_new_remove while
- * iterating over a pset_new; pset_new_remove_iter is allowed.
- *
- * @param iterator Pointer to the pset_new iterator.
- * @returns Next element in the pset_new or NULL
- */
-void* pset_new_iterator_next(pset_new_iterator_t *iterator);
-
-/**
- * Removes the element that the iterator currently points to from the hashset.
- *
- * @param pset_new Pointer to the pset_new
- * @param iterator Pointer to the iterator
- */
-void pset_new_remove_iterator(pset_new_t *pset_new, const pset_new_iterator_t *iterator);
-
-/**
- * Convenience macro for iterating over a pset_new.
- */
-#define foreach_pset_new(pset_new, ptr, iter) \
- for(pset_new_iterator_init(&iter, pset_new), \
- ptr = pset_new_iterator_next(&iter); \
- ptr != NULL; ptr = pset_new_iterator_next(&iter))
-
-#endif
+++ /dev/null
-/*
- * Copyright (C) 1995-2007 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.
- */
-
-/**
- * @file
- * @brief helper functions for working with raw bitsets
- * @date 15.10.2004
- * @author Matthias Braun
- * @version $Id$
- * @summary
- * Raw bitsets are constructed from int arrays. Additional information
- * like the size of the bitset or the used memory aren't saved for
- * efficiency reasons.
- *
- * These bitsets need less space than bitset_t and their representation
- * as int arrays allows having constant bitsets in the ro data segment.
- * They should for smaller bitset, whose length is known through other means
- * (a typical usage case is a set of cpu registers)
- *
- * The bitset is built as an array of unsigned integers. It is assumed that
- * exactly 32 bits may be put into each element of the array. If there are
- * remaining bits, then they should be 0
- */
-#ifndef FIRM_ADT_RAW_BITSET_H
-#define FIRM_ADT_RAW_BITSET_H
-
-#include <assert.h>
-#include "bitset.h"
-#include "bitset_std.h"
-#include "obst.h"
-
-#define BITS_PER_ELEM 32
-#define BITSET_SIZE_ELEMS(size_bits) ((size_bits)/32 + 1)
-#define BITSET_SIZE_BYTES(size_bits) (BITSET_SIZE_ELEMS(size_bits)*4)
-#define BITSET_ELEM(bitset,pos) bitset[pos / 32]
-
-/**
- * Allocate an empty raw bitset on the stack.
- *
- * @param res will contain the newly allocated bitset
- * @param size element size of the bitset
- */
-#define rbitset_alloca(res, size) \
-do { \
- unsigned size_bytes = BITSET_SIZE_BYTES(size); \
- res = alloca(size_bytes); \
- memset(res, 0, size_bytes); \
-} while(0)
-
-/**
- * Allocate an empty raw bitset on an obstack.
- *
- * @param obst the obstack where the bitset is allocated on
- * @param size element size of the bitset
- *
- * @return the new bitset
- */
-static INLINE unsigned *rbitset_obstack_alloc(struct obstack *obst, unsigned size) {
- unsigned size_bytes = BITSET_SIZE_BYTES(size);
- unsigned *res = obstack_alloc(obst, size_bytes);
- memset(res, 0, size_bytes);
-
- return res;
-}
-
-/**
- * Duplicate a raw bitset on an obstack.
- *
- * @param obst the obstack where the bitset is allocated on
- * @param old_bitset the bitset to be duplicated
- * @param size element size of the bitset
- *
- * @return the new bitset
- */
-static INLINE
-unsigned *rbitset_duplicate_obstack_alloc(struct obstack *obst,
- const unsigned *old_bitset,
- unsigned size)
-{
- unsigned size_bytes = BITSET_SIZE_BYTES(size);
- unsigned *res = obstack_alloc(obst, size_bytes);
- memcpy(res, old_bitset, size_bytes);
-
- return res;
-}
-
-/**
- * Set a bit at position pos.
- *
- * @param bitset the bitset
- * @param pos the position of the bit to be set
- */
-static INLINE void rbitset_set(unsigned *bitset, unsigned pos) {
- BITSET_ELEM(bitset,pos) |= 1 << (pos % BITS_PER_ELEM);
-}
-
-/**
- * Clear a bit at position pos.
- *
- * @param bitset the bitset
- * @param pos the position of the bit to be clear
- */
-static INLINE void rbitset_clear(unsigned *bitset, unsigned pos) {
- BITSET_ELEM(bitset, pos) &= ~(1 << (pos % BITS_PER_ELEM));
-}
-
-/**
- * Check if a bit is set at position pos.
- *
- * @param bitset the bitset
- * @param pos the position of the bit to check
- */
-static INLINE int rbitset_is_set(const unsigned *bitset, unsigned pos) {
- return BITSET_ELEM(bitset, pos) & (1 << (pos % BITS_PER_ELEM));
-}
-
-/**
- * Calculate the number of set bits (number of elements).
- *
- * @param bitset the bitset
- */
-static INLINE unsigned rbitset_popcnt(const unsigned *bitset, unsigned size) {
- unsigned pos;
- unsigned n = BITSET_SIZE_ELEMS(size);
- unsigned res = 0;
- const unsigned *elem = bitset;
-
- for(pos = 0; pos < n; ++pos) {
- res += _bitset_inside_pop(elem);
- elem++;
- }
-
- return res;
-}
-
-static INLINE unsigned rbitset_next(const unsigned *bitset, unsigned pos, int set) {
- unsigned p;
- unsigned elem_pos = pos / BITS_PER_ELEM;
- unsigned bit_pos = pos % BITS_PER_ELEM;
-
- unsigned elem = bitset[elem_pos];
-
- /*
- * Mask out the bits smaller than pos in the current unit.
- * We are only interested in bits set higher than pos.
- */
- unsigned in_elem_mask = (1 << bit_pos) - 1;
-
- if(!set)
- elem = ~elem;
- p = _bitset_inside_ntz_value(elem & ~in_elem_mask);
-
- /* If there is a bit set in the current elem, exit. */
- if(p < BITS_PER_ELEM) {
- return elem_pos * BITS_PER_ELEM + p;
- }
-
- /* Else search for set bits in the next units. */
- while(1) {
- elem_pos++;
- elem = bitset[elem_pos];
- if(!set)
- elem = ~elem;
-
- p = _bitset_inside_ntz_value(elem);
- if(p < BITS_PER_ELEM) {
- return elem_pos * BITS_PER_ELEM + p;
- }
- }
-
- assert(0);
- return 0xdeadbeef;
-}
-
-/**
- * Inplace Intersection of two sets.
- */
-static INLINE void rbitset_and(unsigned *bitset1, const unsigned *bitset2,
- unsigned size)
-{
- unsigned i, n = BITSET_SIZE_ELEMS(size);
-
- for(i = 0; i < n; ++i) {
- bitset1[i] &= bitset2[i];
- }
-}
-
-/**
- * Inplace Union of two sets.
- */
-static INLINE void rbitset_or(unsigned *bitset1, const unsigned *bitset2,
- unsigned size)
-{
- unsigned i, n = BITSET_SIZE_ELEMS(size);
-
- for(i = 0; i < n; ++i) {
- bitset1[i] |= bitset2[i];
- }
-}
-
-/**
- * Remove all bits in bitset2 from bitset 1.
- */
-static INLINE void rbitset_andnot(unsigned *bitset1, const unsigned *bitset2,
- unsigned size)
-{
- unsigned i, n = BITSET_SIZE_ELEMS(size);
-
- for(i = 0; i < n; ++i) {
- bitset1[i] &= ~bitset2[i];
- }
-}
-
-/**
- * Xor of two bitsets.
- */
-static INLINE void rbitset_xor(unsigned *bitset1, const unsigned *bitset2,
- unsigned size)
-{
- unsigned i, n = BITSET_SIZE_ELEMS(size);
-
- for(i = 0; i < n; ++i) {
- bitset1[i] ^= bitset2[i];
- }
-}
-
-/**
- * Copy a raw bitset into an bitset.
- *
- * @deprecated
- */
-static INLINE void rbitset_copy_to_bitset(const unsigned *rbitset, bitset_t *bitset) {
- // TODO optimize me (or remove me)
- unsigned i, n = bitset_size(bitset);
- for(i = 0; i < n; ++i) {
- if(rbitset_is_set(rbitset, i))
- bitset_set(bitset, i);
- }
-}
-
-#endif /* FIRM_ADT_RAW_BITSET_H */
+++ /dev/null
-/*
- * Copyright (C) 1995-2007 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.
- */
-
-/**
- * @file
- * @brief hashset: datastructure containing objects accessible by their key
- * @author Markus Armbruster
- * @verison $Id$
- */
-#ifndef FIRM_ADT_SET_H
-#define FIRM_ADT_SET_H
-
-#include <stddef.h>
-
-/**
- * The abstract type of a set.
- *
- * This sets stores copies of its elements, so there is no need
- * to store the elements after they were added to a set.
- *
- * @see pset
- */
-typedef struct set set;
-
-/** The entry of a set, representing an element in the set and it's meta-information */
-typedef struct set_entry {
- unsigned hash; /**< the hash value of the element */
- size_t size; /**< the size of the element */
- int dptr[1]; /**< the element itself, data copied in must not need more
- alignment than this */
-} set_entry;
-
-/**
- * The type of a set compare function.
- *
- * @param elt pointer to an element
- * @param key pointer to another element
- * @param size size of the elements
- *
- * @return
- * 0 if the elements are identically, non-zero else
- *
- * @note
- * Although it is possible to define different meanings of equality
- * of two elements of a set, they can be only equal if their sizes are
- * are equal. This is checked before the compare function is called.
- */
-typedef int (*set_cmp_fun) (const void *elt, const void *key, size_t size);
-
-/**
- * Creates a new set.
- *
- * @param func The compare function of this set.
- * @param slots Initial number of collision chains. I.e., #slots
- * different keys can be hashed without collisions.
- *
- * @returns
- * created set
- */
-set *new_set (set_cmp_fun func, int slots);
-
-/**
- * Deletes a set and all elements of it.
- */
-void del_set (set *set);
-
-/**
- * Returns the number of elements in a set.
- *
- * @param set the set
- */
-int set_count (set *set);
-
-/**
- * Searches an element in a set.
- *
- * @param set the set to search in
- * @param key the element to is searched
- * @param size the size of key
- * @param hash the hash value of key
- *
- * @return
- * The address of the found element in the set or NULL if it was not found.
- */
-void *set_find (set *set, const void *key, size_t size, unsigned hash);
-
-/**
- * Inserts an element into a set.
- *
- * @param set the set to insert in
- * @param key a pointer to the element to be inserted. Element is copied!
- * @param size the size of the element that should be inserted
- * @param hash the hash-value of the element
- *
- * @return a pointer to the inserted element
- *
- * @note
- * It is not possible to insert one element more than once. If an element
- * that should be inserted is already in the set, this functions does
- * nothing but returning its pointer.
- */
-void *set_insert (set *set, const void *key, size_t size, unsigned hash);
-
-/**
- * Inserts an element into a set and returns its set_entry.
- *
- * @param set the set to insert in
- * @param key a pointer to the element to be inserted. Element is copied!
- * @param size the size of the element that should be inserted
- * @param hash the hash-value of the element
- *
- * @return a pointer to the set_entry of the inserted element
- *
- * @note
- * It is not possible to insert an element more than once. If an element
- * that should be inserted is already in the set, this functions does
- * nothing but returning its set_entry.
- */
-set_entry *set_hinsert (set *set, const void *key, size_t size, unsigned hash);
-
-/**
- * Inserts an element into a set, zero-terminate it and returns its set_entry.
- *
- * @param set the set to insert in
- * @param key a pointer to the element to be inserted. Element is copied!
- * @param size the size of the element that should be inserted
- * @param hash the hash-value of the element
- *
- * @return a pointer to the set_entry of the inserted element
- *
- * @note
- * It is not possible to insert on element more than once. If an element
- * that should be inserted is already in the set, this functions does
- * nothing but returning its set_entry.
- */
-set_entry *set_hinsert0 (set *set, const void *key, size_t size, unsigned hash);
-
-/**
- * Returns the first element of a set.
- *
- * @param set the set to iterate
- *
- * @return a pointer to the element or NULL if the set is empty
- */
-void *set_first (set *set);
-
-/**
- * Returns the next element of a set.
- *
- * @param set the set to iterate
- *
- * @return a pointer to the next element or NULL if the
- * iteration is finished
- */
-void *set_next (set *set);
-
-/**
- * Breaks the iteration of a set. Must be called before
- * the next set_first() call if the iteration was NOT
- * finished.
- *
- * @param set the set
- */
-void set_break (set *set);
-
-/**
- * Iterates over an set.
- *
- * @param set the set
- * @param entry the iterator
- */
-#define foreach_set(set, entry) for (entry = set_first(set); entry; entry = set_next(set))
-
-/* implementation specific */
-#define new_set(cmp, slots) (SET_TRACE (new_set) ((cmp), (slots)))
-#define set_find(set, key, size, hash) \
- _set_search ((set), (key), (size), (hash), _set_find)
-#define set_insert(set, key, size, hash) \
- _set_search ((set), (key), (size), (hash), _set_insert)
-#define set_hinsert(set, key, size, hash) \
- ((set_entry *)_set_search ((set), (key), (size), (hash), _set_hinsert))
-#define set_hinsert0(set, key, size, hash) \
- ((set_entry *)_set_search ((set), (key), (size), (hash), _set_hinsert0))
-
-#define SET_VRFY(set) (void)0
-
-#ifdef STATS
-/**
- * Prints statistics on a set to stdout.
- *
- * @param set the set
- */
-void set_stats (set *set);
-#else
-# define set_stats(s) ((void)0)
-#endif
-
-#ifdef DEBUG
-/**
- * Describe a set.
- *
- * Writes a description of a set to stdout. The description includes:
- * - a header telling how many elements (nkey) and segments (nseg) are in use
- * - for every collision chain the number of element with its hash values
- *
- * @param set the set
- */
-void set_describe (set *set);
-#endif
-
-
-/* Private */
-
-typedef enum { _set_find, _set_insert, _set_hinsert, _set_hinsert0 } _set_action;
-
-void *_set_search (set *, const void *, size_t, unsigned, _set_action);
-
-#if defined(DEBUG) && defined(HAVE_GNU_MALLOC)
-extern const char *set_tag;
-# ifdef SET_ID
-# define SET_TRACE set_tag = SET_ID,
-# else
-# define SET_TRACE set_tag = __FILE__,
-# endif
-#else /* !(DEBUG && HAVE_GNU_MALLOC) */
-# define SET_TRACE
-#endif /* !(DEBUG && HAVE_GNU_MALLOC) */
-
-#endif
+++ /dev/null
-/*
- * Copyright (C) 1995-2007 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.
- */
-
-/**
- * @file
- * @brief Union-Find datastructure
- * @author Matthias Braun
- * @version $Id$
- * @summary
- * Union-Find datastructure
- *
- * This implementation uses weighted sets and path compression which results
- * in (nearly) O(n) complexity for n find and union operations
- */
-#ifndef FIRM_ADT_UNIONFIND_H
-#define FIRM_ADT_UNIONFIND_H
-
-#include <assert.h>
-
-/**
- * Call this to initialize an array of @p count elements to be used by the
- * union find functions.
- *
- * @param data The array (you have to allocate it yourself)
- * @param from The first element that should be initialized
- * @param to the index of the first element which is not initialized anymore
- */
-static INLINE void uf_init(int* data, int from, int to) {
- int i;
- for(i = from; i < to; ++i) {
- data[i] = -1;
- }
-}
-
-/**
- * Merge 2 sets (union operation). Note that you have to pass the
- * representatives of the sets and not just random elements
- *
- * @param data The union find data
- * @param set1 Representative of set1
- * @param set2 Representative of set2
- * @return 0 if the new union set is represented by set1, 1 if it is
- * represented by set2
- */
-static INLINE int uf_union(int* data, int set1, int set2) {
- int d1 = data[set1];
- int d2 = data[set2];
- int newcount;
-
- if(set1 == set2)
- return 0;
-
- /* need 2 set representatives */
- assert(d1 < 0 && d2 < 0);
-
- newcount = d1 + d2;
- if(d1 > d2) {
- data[set1] = set2;
- data[set2] = newcount;
- return 1;
- } else {
- data[set2] = set1;
- data[set1] = newcount;
- return 0;
- }
-}
-
-/**
- * Finds the representative for the set with member @p e.
- * The representative of a set is unique, so if the find operations finds
- * the same/different representatives, then the elements are in the
- * the same/different sets.
- *
- * @param data The union find data
- * @param e The element
- * @return The representative of the set that contains @p e
- */
-static INLINE int uf_find(int* data, int e) {
- /* go through list to find representative */
- int repr = e;
- while(data[repr] >= 0) {
- repr = data[repr];
- }
-
- /* update list to point to new representative (path compression) */
- while(e != repr) {
- int next = data[e];
- data[e] = repr;
- e = next;
- }
-
- return repr;
-}
-
-#endif /* FIRM_ADT_UNIONFIND_H */
+++ /dev/null
-/*
- * Copyright (C) 1995-2007 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.
- */
-
-/**
- * @file
- * @date 31.05.2005
- * @author Sebastian Hack
- * @brief Some utility macros.
- */
-#ifndef FIRM_ADT_UTIL_H
-#define FIRM_ADT_UTIL_H
-
-#include "firm_config.h"
-
-/**
- * Get the offset of a member of a struct.
- * @param type The type of the struct member is in.
- * @param member The name of the member.
- * @return The offset of member in type in bytes.
- */
-#define offset_of(type, member) \
- ((char *) &(((type *) 0)->member) - (char *) 0)
-
-/**
- * Make pointer to the struct from a pointer to a member of that struct.
- * @param ptr The pointer to the member.
- * @param type The type of the struct.
- * @param member The name of the member.
- * @return A pointer to the struct member is in.
- */
-#define container_of(ptr, type, member) \
- ((type *) ((char *) (ptr) - offset_of(type, member)))
-
-/**
- * Get the number of elements of a static array.
- * @param arr The static array.
- * @return The number of elements in that array.
- */
-#define array_size(arr) \
- (sizeof(arr) / sizeof((arr)[0]))
-
-/**
- * Asserts that the constant expression x is not zero at compiletime. name has
- * to be a unique identifier.
- *
- * @note This uses the fact, that double case labels are not allowed.
- */
-#define COMPILETIME_ASSERT(x, name) \
- static __attribute__((unused)) void compiletime_assert_##name (int h) { \
- switch(h) { case 0: case (x): ; } \
- }
-
-#ifdef __GNUC__
-/**
- * Indicates to the compiler that the value of x is very likely 1
- * @note Only use this in speed critical code and when you are sure x is often 1
- */
-#define LIKELY(x) __builtin_expect((x), 1)
-
-/**
- * Indicates to the compiler that it's very likely that x is 0
- * @note Only use this in speed critical code and when you are sure x is often 0
- */
-#define UNLIKELY(x) __builtin_expect((x), 0)
-#else
-#define LIKELY(x) x
-#define UNLIKELY(x) x
-#endif
-
-#endif
+++ /dev/null
-/*
- * Copyright (C) 1995-2007 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.
- */
-
-/**
- * @file
- * @brief never failing wrappers for malloc() & friends.
- * @author Markus Armbruster
- * @version $Id$
- * @note The functions here never fail because they simply abort your
- * program in case of an error.
- */
-#ifndef FIRM_ADT_XMALLOC_H
-#define FIRM_ADT_XMALLOC_H
-
-#include <stddef.h>
-
-/* xmalloc() & friends. */
-
-void *xmalloc(size_t size);
-void *xcalloc(size_t num, size_t size);
-void *xrealloc(void *ptr, size_t size);
-char *xstrdup(const char *str);
-void free(void *ptr);
-
-#define xfree(ptr) free(ptr)
-
-
-/* Includes for alloca() */
-#if defined(__FreeBSD__)
-#include <stdlib.h>
-#elif defined(_WIN32)
-#include <malloc.h>
-#else
-#include <alloca.h>
-#endif
-
-#endif