From: Matthias Braun Date: Fri, 1 Jun 2007 15:55:50 +0000 (+0000) Subject: move adt headers X-Git-Url: http://nsz.repo.hu/git/?a=commitdiff_plain;h=435253f3a8766fec2ac2adf559bb10cfcb5d36f4;p=libfirm move adt headers [r14243] --- diff --git a/include/libfirm/adt/align.h b/include/libfirm/adt/align.h new file mode 100644 index 000000000..51d605868 --- /dev/null +++ b/include/libfirm/adt/align.h @@ -0,0 +1,66 @@ +/* + * 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 + +/** 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 diff --git a/include/libfirm/adt/array.h b/include/libfirm/adt/array.h new file mode 100644 index 000000000..7a72b9e57 --- /dev/null +++ b/include/libfirm/adt/array.h @@ -0,0 +1,349 @@ +/* + * 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 +#include + +#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 */ diff --git a/include/libfirm/adt/bipartite.h b/include/libfirm/adt/bipartite.h new file mode 100644 index 000000000..dc250fea3 --- /dev/null +++ b/include/libfirm/adt/bipartite.h @@ -0,0 +1,48 @@ +/* + * 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 */ diff --git a/include/libfirm/adt/bitfiddle.h b/include/libfirm/adt/bitfiddle.h new file mode 100644 index 000000000..ee851fa70 --- /dev/null +++ b/include/libfirm/adt/bitfiddle.h @@ -0,0 +1,214 @@ +/* + * 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 +#include +#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 diff --git a/include/libfirm/adt/bitset.h b/include/libfirm/adt/bitset.h new file mode 100644 index 000000000..0b647d5f8 --- /dev/null +++ b/include/libfirm/adt/bitset.h @@ -0,0 +1,568 @@ +/* + * 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 +#include +#include +#include + +#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 diff --git a/include/libfirm/adt/bitset_ia32.h b/include/libfirm/adt/bitset_ia32.h new file mode 100644 index 000000000..1136f0308 --- /dev/null +++ b/include/libfirm/adt/bitset_ia32.h @@ -0,0 +1,162 @@ +/* + * 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 +#include + +#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 diff --git a/include/libfirm/adt/bitset_std.h b/include/libfirm/adt/bitset_std.h new file mode 100644 index 000000000..18cd42242 --- /dev/null +++ b/include/libfirm/adt/bitset_std.h @@ -0,0 +1,152 @@ +/* + * 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 diff --git a/include/libfirm/adt/cpset.h b/include/libfirm/adt/cpset.h new file mode 100644 index 000000000..60e06d8ba --- /dev/null +++ b/include/libfirm/adt/cpset.h @@ -0,0 +1,153 @@ +/* + * 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 */ diff --git a/include/libfirm/adt/eset.h b/include/libfirm/adt/eset.h new file mode 100644 index 000000000..60284fdb8 --- /dev/null +++ b/include/libfirm/adt/eset.h @@ -0,0 +1,76 @@ +/* + * 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 diff --git a/include/libfirm/adt/fourcc.h b/include/libfirm/adt/fourcc.h new file mode 100644 index 000000000..86129780b --- /dev/null +++ b/include/libfirm/adt/fourcc.h @@ -0,0 +1,32 @@ +/* + * 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 diff --git a/include/libfirm/adt/gaussjordan.h b/include/libfirm/adt/gaussjordan.h new file mode 100644 index 000000000..c89977bf6 --- /dev/null +++ b/include/libfirm/adt/gaussjordan.h @@ -0,0 +1,16 @@ +/** + * @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 diff --git a/include/libfirm/adt/hashptr.h b/include/libfirm/adt/hashptr.h new file mode 100644 index 000000000..043ba5b63 --- /dev/null +++ b/include/libfirm/adt/hashptr.h @@ -0,0 +1,90 @@ +/* + * 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 diff --git a/include/libfirm/adt/hashset.h b/include/libfirm/adt/hashset.h new file mode 100644 index 000000000..9495ef0f7 --- /dev/null +++ b/include/libfirm/adt/hashset.h @@ -0,0 +1,72 @@ +/* + * 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 + +#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 diff --git a/include/libfirm/adt/hungarian.h b/include/libfirm/adt/hungarian.h new file mode 100644 index 000000000..1c5851ad9 --- /dev/null +++ b/include/libfirm/adt/hungarian.h @@ -0,0 +1,97 @@ +/******************************************************************** + ******************************************************************** + ** + ** 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_ */ diff --git a/include/libfirm/adt/impl.h b/include/libfirm/adt/impl.h new file mode 100644 index 000000000..8cba167ea --- /dev/null +++ b/include/libfirm/adt/impl.h @@ -0,0 +1,125 @@ +/* + * 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 diff --git a/include/libfirm/adt/iterator.h b/include/libfirm/adt/iterator.h new file mode 100644 index 000000000..ac834a418 --- /dev/null +++ b/include/libfirm/adt/iterator.h @@ -0,0 +1,62 @@ +/* + * 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 diff --git a/include/libfirm/adt/list.h b/include/libfirm/adt/list.h new file mode 100644 index 000000000..8b8f205ed --- /dev/null +++ b/include/libfirm/adt/list.h @@ -0,0 +1,281 @@ + +/** + * @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 diff --git a/include/libfirm/adt/obst.h b/include/libfirm/adt/obst.h new file mode 100644 index 000000000..73042707a --- /dev/null +++ b/include/libfirm/adt/obst.h @@ -0,0 +1,35 @@ +/* + * 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 +#include "xmalloc.h" + +#define obstack_chunk_alloc xmalloc +#define obstack_chunk_free free + +#endif diff --git a/include/libfirm/adt/offset.h b/include/libfirm/adt/offset.h new file mode 100644 index 000000000..70e74d17c --- /dev/null +++ b/include/libfirm/adt/offset.h @@ -0,0 +1,46 @@ +/* + * 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 diff --git a/include/libfirm/adt/pdeq.h b/include/libfirm/adt/pdeq.h new file mode 100644 index 000000000..ebbb4e68a --- /dev/null +++ b/include/libfirm/adt/pdeq.h @@ -0,0 +1,273 @@ +/* + * 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 diff --git a/include/libfirm/adt/plist.h b/include/libfirm/adt/plist.h new file mode 100644 index 000000000..af9efe72c --- /dev/null +++ b/include/libfirm/adt/plist.h @@ -0,0 +1,246 @@ +/* + * 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 +#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_*/ diff --git a/include/libfirm/adt/pmap.h b/include/libfirm/adt/pmap.h new file mode 100644 index 000000000..e204bbae3 --- /dev/null +++ b/include/libfirm/adt/pmap.h @@ -0,0 +1,86 @@ +/* + * 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 diff --git a/include/libfirm/adt/pqueue.h b/include/libfirm/adt/pqueue.h new file mode 100644 index 000000000..dff60a357 --- /dev/null +++ b/include/libfirm/adt/pqueue.h @@ -0,0 +1,74 @@ +/* + * 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 diff --git a/include/libfirm/adt/pset.h b/include/libfirm/adt/pset.h new file mode 100644 index 000000000..6c6e4c009 --- /dev/null +++ b/include/libfirm/adt/pset.h @@ -0,0 +1,272 @@ +/* + * 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 + +#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 diff --git a/include/libfirm/adt/pset_new.h b/include/libfirm/adt/pset_new.h new file mode 100644 index 000000000..357f17c73 --- /dev/null +++ b/include/libfirm/adt/pset_new.h @@ -0,0 +1,139 @@ +/* + * 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 diff --git a/include/libfirm/adt/raw_bitset.h b/include/libfirm/adt/raw_bitset.h new file mode 100644 index 000000000..3a5bfd683 --- /dev/null +++ b/include/libfirm/adt/raw_bitset.h @@ -0,0 +1,257 @@ +/* + * 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 +#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 */ diff --git a/include/libfirm/adt/set.h b/include/libfirm/adt/set.h new file mode 100644 index 000000000..8236152fc --- /dev/null +++ b/include/libfirm/adt/set.h @@ -0,0 +1,245 @@ +/* + * 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 + +/** + * 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 diff --git a/include/libfirm/adt/unionfind.h b/include/libfirm/adt/unionfind.h new file mode 100644 index 000000000..a4fb551fc --- /dev/null +++ b/include/libfirm/adt/unionfind.h @@ -0,0 +1,111 @@ +/* + * 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 + +/** + * 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 */ diff --git a/include/libfirm/adt/util.h b/include/libfirm/adt/util.h new file mode 100644 index 000000000..6730c443f --- /dev/null +++ b/include/libfirm/adt/util.h @@ -0,0 +1,86 @@ +/* + * 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 diff --git a/include/libfirm/adt/xmalloc.h b/include/libfirm/adt/xmalloc.h new file mode 100644 index 000000000..30925b989 --- /dev/null +++ b/include/libfirm/adt/xmalloc.h @@ -0,0 +1,53 @@ +/* + * 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 + +/* 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 +#elif defined(_WIN32) +#include +#else +#include +#endif + +#endif diff --git a/ir/adt/align.h b/ir/adt/align.h deleted file mode 100644 index 51d605868..000000000 --- a/ir/adt/align.h +++ /dev/null @@ -1,66 +0,0 @@ -/* - * 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 - -/** 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 diff --git a/ir/adt/array.h b/ir/adt/array.h deleted file mode 100644 index 7a72b9e57..000000000 --- a/ir/adt/array.h +++ /dev/null @@ -1,349 +0,0 @@ -/* - * 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 -#include - -#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 */ diff --git a/ir/adt/bipartite.h b/ir/adt/bipartite.h deleted file mode 100644 index dc250fea3..000000000 --- a/ir/adt/bipartite.h +++ /dev/null @@ -1,48 +0,0 @@ -/* - * 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 */ diff --git a/ir/adt/bitfiddle.h b/ir/adt/bitfiddle.h deleted file mode 100644 index ee851fa70..000000000 --- a/ir/adt/bitfiddle.h +++ /dev/null @@ -1,214 +0,0 @@ -/* - * 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 -#include -#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 diff --git a/ir/adt/bitset.h b/ir/adt/bitset.h deleted file mode 100644 index 0b647d5f8..000000000 --- a/ir/adt/bitset.h +++ /dev/null @@ -1,568 +0,0 @@ -/* - * 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 -#include -#include -#include - -#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 diff --git a/ir/adt/bitset_ia32.h b/ir/adt/bitset_ia32.h deleted file mode 100644 index 1136f0308..000000000 --- a/ir/adt/bitset_ia32.h +++ /dev/null @@ -1,162 +0,0 @@ -/* - * 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 -#include - -#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 diff --git a/ir/adt/bitset_std.h b/ir/adt/bitset_std.h deleted file mode 100644 index 18cd42242..000000000 --- a/ir/adt/bitset_std.h +++ /dev/null @@ -1,152 +0,0 @@ -/* - * 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 diff --git a/ir/adt/cpset.h b/ir/adt/cpset.h deleted file mode 100644 index 60e06d8ba..000000000 --- a/ir/adt/cpset.h +++ /dev/null @@ -1,153 +0,0 @@ -/* - * 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 */ diff --git a/ir/adt/eset.h b/ir/adt/eset.h deleted file mode 100644 index 60284fdb8..000000000 --- a/ir/adt/eset.h +++ /dev/null @@ -1,76 +0,0 @@ -/* - * 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 diff --git a/ir/adt/fourcc.h b/ir/adt/fourcc.h deleted file mode 100644 index 86129780b..000000000 --- a/ir/adt/fourcc.h +++ /dev/null @@ -1,32 +0,0 @@ -/* - * 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 diff --git a/ir/adt/gaussjordan.h b/ir/adt/gaussjordan.h deleted file mode 100644 index c89977bf6..000000000 --- a/ir/adt/gaussjordan.h +++ /dev/null @@ -1,16 +0,0 @@ -/** - * @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 diff --git a/ir/adt/hashptr.h b/ir/adt/hashptr.h deleted file mode 100644 index 043ba5b63..000000000 --- a/ir/adt/hashptr.h +++ /dev/null @@ -1,90 +0,0 @@ -/* - * 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 diff --git a/ir/adt/hashset.h b/ir/adt/hashset.h deleted file mode 100644 index 9495ef0f7..000000000 --- a/ir/adt/hashset.h +++ /dev/null @@ -1,72 +0,0 @@ -/* - * 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 - -#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 diff --git a/ir/adt/hungarian.h b/ir/adt/hungarian.h deleted file mode 100644 index 1c5851ad9..000000000 --- a/ir/adt/hungarian.h +++ /dev/null @@ -1,97 +0,0 @@ -/******************************************************************** - ******************************************************************** - ** - ** 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_ */ diff --git a/ir/adt/impl.h b/ir/adt/impl.h deleted file mode 100644 index 8cba167ea..000000000 --- a/ir/adt/impl.h +++ /dev/null @@ -1,125 +0,0 @@ -/* - * 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 diff --git a/ir/adt/iterator.h b/ir/adt/iterator.h deleted file mode 100644 index ac834a418..000000000 --- a/ir/adt/iterator.h +++ /dev/null @@ -1,62 +0,0 @@ -/* - * 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 diff --git a/ir/adt/list.h b/ir/adt/list.h deleted file mode 100644 index 8b8f205ed..000000000 --- a/ir/adt/list.h +++ /dev/null @@ -1,281 +0,0 @@ - -/** - * @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 diff --git a/ir/adt/obst.h b/ir/adt/obst.h deleted file mode 100644 index 73042707a..000000000 --- a/ir/adt/obst.h +++ /dev/null @@ -1,35 +0,0 @@ -/* - * 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 -#include "xmalloc.h" - -#define obstack_chunk_alloc xmalloc -#define obstack_chunk_free free - -#endif diff --git a/ir/adt/offset.h b/ir/adt/offset.h deleted file mode 100644 index 70e74d17c..000000000 --- a/ir/adt/offset.h +++ /dev/null @@ -1,46 +0,0 @@ -/* - * 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 diff --git a/ir/adt/pdeq.h b/ir/adt/pdeq.h deleted file mode 100644 index ebbb4e68a..000000000 --- a/ir/adt/pdeq.h +++ /dev/null @@ -1,273 +0,0 @@ -/* - * 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 diff --git a/ir/adt/plist.h b/ir/adt/plist.h deleted file mode 100644 index af9efe72c..000000000 --- a/ir/adt/plist.h +++ /dev/null @@ -1,246 +0,0 @@ -/* - * 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 -#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_*/ diff --git a/ir/adt/pmap.h b/ir/adt/pmap.h deleted file mode 100644 index e204bbae3..000000000 --- a/ir/adt/pmap.h +++ /dev/null @@ -1,86 +0,0 @@ -/* - * 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 diff --git a/ir/adt/pqueue.h b/ir/adt/pqueue.h deleted file mode 100644 index dff60a357..000000000 --- a/ir/adt/pqueue.h +++ /dev/null @@ -1,74 +0,0 @@ -/* - * 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 diff --git a/ir/adt/pset.h b/ir/adt/pset.h deleted file mode 100644 index 6c6e4c009..000000000 --- a/ir/adt/pset.h +++ /dev/null @@ -1,272 +0,0 @@ -/* - * 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 - -#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 diff --git a/ir/adt/pset_new.h b/ir/adt/pset_new.h deleted file mode 100644 index 357f17c73..000000000 --- a/ir/adt/pset_new.h +++ /dev/null @@ -1,139 +0,0 @@ -/* - * 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 diff --git a/ir/adt/raw_bitset.h b/ir/adt/raw_bitset.h deleted file mode 100644 index 3a5bfd683..000000000 --- a/ir/adt/raw_bitset.h +++ /dev/null @@ -1,257 +0,0 @@ -/* - * 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 -#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 */ diff --git a/ir/adt/set.h b/ir/adt/set.h deleted file mode 100644 index 8236152fc..000000000 --- a/ir/adt/set.h +++ /dev/null @@ -1,245 +0,0 @@ -/* - * 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 - -/** - * 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 diff --git a/ir/adt/unionfind.h b/ir/adt/unionfind.h deleted file mode 100644 index a4fb551fc..000000000 --- a/ir/adt/unionfind.h +++ /dev/null @@ -1,111 +0,0 @@ -/* - * 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 - -/** - * 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 */ diff --git a/ir/adt/util.h b/ir/adt/util.h deleted file mode 100644 index 6730c443f..000000000 --- a/ir/adt/util.h +++ /dev/null @@ -1,86 +0,0 @@ -/* - * 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 diff --git a/ir/adt/xmalloc.h b/ir/adt/xmalloc.h deleted file mode 100644 index 30925b989..000000000 --- a/ir/adt/xmalloc.h +++ /dev/null @@ -1,53 +0,0 @@ -/* - * 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 - -/* 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 -#elif defined(_WIN32) -#include -#else -#include -#endif - -#endif