From: Matthias Braun Date: Sat, 11 Oct 2008 18:52:18 +0000 (+0000) Subject: - remove some now unnecessary firm_config.h X-Git-Url: http://nsz.repo.hu/git/?a=commitdiff_plain;h=972eca70744a2c9a0e0d472db4f62250cdeee01c;p=libfirm - remove some now unnecessary firm_config.h - move some nonportable bitfiddle stuff to sources [r22707] --- diff --git a/include/libfirm/adt/array.h b/include/libfirm/adt/array.h index 1a56f7380..76347ac70 100644 --- a/include/libfirm/adt/array.h +++ b/include/libfirm/adt/array.h @@ -29,7 +29,6 @@ #include #include -#include "firm_config.h" #include "obst.h" #include "fourcc.h" #include "align.h" @@ -283,7 +282,7 @@ typedef int (ir_arr_cmp_func_t)(const void *a, const void *b); * @note The differences to bsearch(3) which does not give proper insert locations * in the case that the element is not conatined in the array. */ -static INLINE __attribute__((const, unused)) int +static inline __attribute__((const, unused)) int ir_arr_bsearch(const void *arr, size_t elm_size, ir_arr_cmp_func_t *cmp, const void *elm) { int hi = ARR_LEN(arr); diff --git a/include/libfirm/adt/bitfiddle.h b/include/libfirm/adt/bitfiddle.h deleted file mode 100644 index a5ef6523a..000000000 --- a/include/libfirm/adt/bitfiddle.h +++ /dev/null @@ -1,219 +0,0 @@ -/* - * Copyright (C) 1995-2008 University of Karlsruhe. All right reserved. - * - * This file is part of libFirm. - * - * This file may be distributed and/or modified under the terms of the - * GNU General Public License version 2 as published by the Free Software - * Foundation and appearing in the file LICENSE.GPL included in the - * packaging of this file. - * - * Licensees holding valid libFirm Professional Edition licenses may use - * this file in accordance with the libFirm Commercial License. - * Agreement provided with the Software. - * - * This file is provided AS IS with NO WARRANTY OF ANY KIND, INCLUDING THE - * WARRANTY OF DESIGN, MERCHANTABILITY AND FITNESS FOR A PARTICULAR - * PURPOSE. - */ - -/** - * @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 "firm_config.h" - -#include -#include -#include "compiler.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 PURE -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 PURE -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 PURE -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 - unsigned y; - int n = 32; - - y = x >>16; if (y != 0) { n -= 16; x = y; } - y = x >> 8; if (y != 0) { n -= 8; x = y; } - y = x >> 4; if (y != 0) { n -= 4; x = y; } - y = x >> 2; if (y != 0) { n -= 2; x = y; } - y = x >> 1; if (y != 0) return n - 2; - return n - x; -#endif -} - -/** - * Compute the number of trailing zeros in a word. - * @param x The word. - * @return The number of trailing zeros. - */ -static INLINE PURE -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 PURE -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 PURE -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 PURE -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 deleted file mode 100644 index f793083c8..000000000 --- a/include/libfirm/adt/bitset.h +++ /dev/null @@ -1,603 +0,0 @@ -/* - * Copyright (C) 1995-2008 University of Karlsruhe. All right reserved. - * - * This file is part of libFirm. - * - * This file may be distributed and/or modified under the terms of the - * GNU General Public License version 2 as published by the Free Software - * Foundation and appearing in the file LICENSE.GPL included in the - * packaging of this file. - * - * Licensees holding valid libFirm Professional Edition licenses may use - * this file in accordance with the libFirm Commercial License. - * Agreement provided with the Software. - * - * This file is provided AS IS with NO WARRANTY OF ANY KIND, INCLUDING THE - * WARRANTY OF DESIGN, MERCHANTABILITY AND FITNESS FOR A PARTICULAR - * PURPOSE. - */ - -/** - * @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_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) - -#define BS_DATA(bs) ((bitset_unit_t *) ((char *) (bs) + sizeof(bitset_t))) -#define BS_UNITS(bits) (round_up2(bits, BS_UNIT_SIZE_BITS) / BS_UNIT_SIZE_BITS) -#define BS_TOTAL_SIZE(bits) (sizeof(bitset_t) + BS_UNITS(bits) * BS_UNIT_SIZE) - -/** - * 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(ptr, 0, BS_TOTAL_SIZE(size)); - ptr->units = BS_UNITS(size); - ptr->size = 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)[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, BS_TOTAL_SIZE(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(BS_TOTAL_SIZE(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(BS_TOTAL_SIZE(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->size && "Bit to large"); - return BS_DATA(bs) + 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(bs)[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(BS_DATA(tgt), BS_DATA(src), min_units * BS_UNIT_SIZE); - if(tu > min_units) - memset(BS_DATA(tgt) + min_units, 0, BS_UNIT_SIZE * (tu - min_units)); - return _bitset_mask_highest(tgt); -} - -/** - * 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(bs)[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 : (bitset_pos_t) -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(bs)[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 : (bitset_pos_t) -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 != (bitset_pos_t) -1; elm = bitset_next_set(bitset,elm+1)) - - -#define bitset_foreach_clear(bitset,elm) \ - for(elm = bitset_next_clear(bitset,0); elm != (bitset_pos_t) -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(bs); 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(bs), 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(bs), -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 = BS_DATA(lhs)[i]; - bitset_unit_t ru = BS_DATA(rhs)[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(BS_DATA(lhs)[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(bs)[i]; - bitset_unit_t um1 = unit - 1; - - BS_DATA(bs)[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 (BS_DATA(a)[i] & BS_DATA(b)[i]) - return 1; - - return 0; -} - -/** - * set or clear all bits in the range [from;to[. - * @param a The bitset. - * @param from The first index to set to one. - * @param to The last index plus one to set to one. - * @param do_set If 1 the bits are set, if 0, they are cleared. - */ -static INLINE void bitset_mod_range(bitset_t *a, bitset_pos_t from, bitset_pos_t to, int do_set) -{ - bitset_pos_t from_unit, to_unit, i; - bitset_unit_t from_unit_mask, to_unit_mask; - - if (from == to) - return; - - if (to < from) { - bitset_pos_t tmp = from; - from = to; - to = tmp; - } - - if (to > a->size) - to = a->size; - - /* - * A small example (for cleaning bits in the same unit). - * from = 7 - * to = 19 - * do_set = 0 - * result: xxxxxxx000000000000xxxxxxxxxxxxx - * from_unit_mask: 00000001111111111111111111111111 - * to_unit_mask: 11111111111111111110000000000000 - * scale: 01234567890123456789012345678901 - * 1 2 3 - */ - - from_unit = from / BS_UNIT_SIZE_BITS; - from_unit_mask = ~((1 << from) - 1); - from = from & BS_UNIT_MASK; - - to_unit = to / BS_UNIT_SIZE_BITS; - to_unit_mask = (1 << to) - 1; - to = to & BS_UNIT_MASK; - - /* do we want to set the bits in the range? */ - if (do_set) { - /* If from and to are in the same unit: */ - if (from_unit == to_unit) - BS_DATA(a)[from_unit] |= from_unit_mask & to_unit_mask; - - /* Else, we have to treat the from and to units seperately */ - else { - BS_DATA(a)[from_unit] |= from_unit_mask; - BS_DATA(a)[to_unit] |= to_unit_mask; - for (i = from_unit + 1; i < to_unit; i++) - BS_DATA(a)[i] = BITSET_UNIT_ALL_ONE; - } - } - - /* ... or clear them? */ - else { - if (from_unit == to_unit) - BS_DATA(a)[from_unit] &= ~(from_unit_mask & to_unit_mask); - - else { - BS_DATA(a)[from_unit] &= ~from_unit_mask; - BS_DATA(a)[to_unit] &= ~to_unit_mask; - for (i = from_unit + 1; i < to_unit; i++) - BS_DATA(a)[i] = 0; - } - } -} - -#define bitset_set_range(bs, from, to) bitset_mod_range((bs), (from), (to), 1) -#define bitset_clear_range(bs, from, to) bitset_mod_range((bs), (from), (to), 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 (BS_DATA(a)[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(bs)[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(&BS_DATA(tgt)[i], &BS_DATA(src)[i]); \ - if(n < tgt->units) \ - _bitset_clear_rest(&BS_DATA(tgt)[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) do { } while(0) - -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 deleted file mode 100644 index 529057de8..000000000 --- a/include/libfirm/adt/bitset_ia32.h +++ /dev/null @@ -1,96 +0,0 @@ -/* - * Copyright (C) 1995-2008 University of Karlsruhe. All right reserved. - * - * This file is part of libFirm. - * - * This file may be distributed and/or modified under the terms of the - * GNU General Public License version 2 as published by the Free Software - * Foundation and appearing in the file LICENSE.GPL included in the - * packaging of this file. - * - * Licensees holding valid libFirm Professional Edition licenses may use - * this file in accordance with the libFirm Commercial License. - * Agreement provided with the Software. - * - * This file is provided AS IS with NO WARRANTY OF ANY KIND, INCLUDING THE - * WARRANTY OF DESIGN, MERCHANTABILITY AND FITNESS FOR A PARTICULAR - * PURPOSE. - */ - -/** - * @file - * @brief intel 80x86 implementation of bitsets - * @version $Id$ - */ -#ifndef _BITSET_IA32_H -#define _BITSET_IA32_H - -#undef _bitset_inside_clear -#undef _bitset_inside_set -#undef _bitset_inside_flip - -#define _bitset_inside_set(unit, bit) \ - __asm__ __volatile__( "btsl %1,%0" :"=m" (*unit) : "Ir" (bit) : "cc") - -#define _bitset_inside_clear(unit, bit) \ - __asm__ __volatile__( "btrl %1,%0" :"=m" (*unit) : "Ir" (bit) : "cc") - -#define _bitset_inside_flip(unit, bit) \ - __asm__ __volatile__( "btcl %1,%0" :"=m" (*unit) : "Ir" (bit) : "cc") - -#undef _bitset_inside_is_set -#undef _bitset_inside_nlz -#undef _bitset_inside_ntz -#undef _bitset_inside_ntz_value - -#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; - __asm__("bt %2, %1\n\t" - "rcl $1, %0\n\t" - "and $1, %0" - : "=r" (res) - : "m" (*unit), "Ir" (bit) - : "cc"); - return res; -} - -static INLINE unsigned _bitset_ia32_inside_nlz(bitset_unit_t *unit) -{ - unsigned res; - __asm__("bsr %1, %0\n\t" - "cmovz %2, %0\n\t" - "neg %0\n\t" - "add $31, %0" - : "=&r" (res) - : "m" (*unit), "r" (-1) - : "cc"); - return res; -} - -static INLINE unsigned _bitset_ia32_inside_ntz(bitset_unit_t *unit) { - unsigned res; - __asm__("bsfl %1, %0\n\t" - "cmovz %2, %0\n\t" - : "=&r" (res) - : "m" (*unit), "r" (32) - : "cc"); - return res; -} - -static INLINE unsigned _bitset_ia32_inside_ntz_value(bitset_unit_t unit) { - unsigned res; - __asm__("bsfl %1, %0\n\t" - "cmovz %2, %0\n\t" - : "=&r" (res) - : "r" (unit), "r" (32) - : "cc"); - return res; -} - -#endif diff --git a/include/libfirm/adt/bitset_std.h b/include/libfirm/adt/bitset_std.h deleted file mode 100644 index e0d00abf5..000000000 --- a/include/libfirm/adt/bitset_std.h +++ /dev/null @@ -1,122 +0,0 @@ -/* - * Copyright (C) 1995-2008 University of Karlsruhe. All right reserved. - * - * This file is part of libFirm. - * - * This file may be distributed and/or modified under the terms of the - * GNU General Public License version 2 as published by the Free Software - * Foundation and appearing in the file LICENSE.GPL included in the - * packaging of this file. - * - * Licensees holding valid libFirm Professional Edition licenses may use - * this file in accordance with the libFirm Commercial License. - * Agreement provided with the Software. - * - * This file is provided AS IS with NO WARRANTY OF ANY KIND, INCLUDING THE - * WARRANTY OF DESIGN, MERCHANTABILITY AND FITNESS FOR A PARTICULAR - * PURPOSE. - */ - -/** - * @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) - -/** - * 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/compiler.h b/include/libfirm/adt/compiler.h deleted file mode 100644 index f9e67c7b0..000000000 --- a/include/libfirm/adt/compiler.h +++ /dev/null @@ -1,67 +0,0 @@ -/* - * Copyright (C) 1995-2008 University of Karlsruhe. All right reserved. - * - * This file is part of libFirm. - * - * This file may be distributed and/or modified under the terms of the - * GNU General Public License version 2 as published by the Free Software - * Foundation and appearing in the file LICENSE.GPL included in the - * packaging of this file. - * - * Licensees holding valid libFirm Professional Edition licenses may use - * this file in accordance with the libFirm Commercial License. - * Agreement provided with the Software. - * - * This file is provided AS IS with NO WARRANTY OF ANY KIND, INCLUDING THE - * WARRANTY OF DESIGN, MERCHANTABILITY AND FITNESS FOR A PARTICULAR - * PURPOSE. - */ - -/** - * @file - * @date 04.06.2007 - * @author Matthias Braun, Sebastian Hack - * @brief Macros to instruct the compiler compiling libFirm. - */ - -#ifndef FIRM_COMPILER_H -#define FIRM_COMPILER_H - -/** - * 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) - -/** - * Tell the compiler, that a function is pure, i.e. it only - * uses its parameters and never modifies the "state". - * Add this macro after the return type. - */ -#define PURE __attribute__((const)) - -#else -#define LIKELY(x) x -#define UNLIKELY(x) x -#define PURE -#endif - -#endif diff --git a/include/libfirm/adt/hashptr.h b/include/libfirm/adt/hashptr.h index 918843e85..7a369c5fe 100644 --- a/include/libfirm/adt/hashptr.h +++ b/include/libfirm/adt/hashptr.h @@ -26,16 +26,13 @@ #ifndef FIRM_ADT_HASHPTR_H #define FIRM_ADT_HASHPTR_H -#include "firm_config.h" -#include "compiler.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) * _FIRM_FNV_FNV_PRIME) -static INLINE unsigned firm_fnv_hash(const unsigned char *data, unsigned bytes) +static inline unsigned firm_fnv_hash(const unsigned char *data, unsigned bytes) { unsigned i; unsigned hash = _FIRM_FNV_OFFSET_BASIS; @@ -48,7 +45,7 @@ static INLINE unsigned firm_fnv_hash(const unsigned char *data, unsigned bytes) return hash; } -static INLINE unsigned firm_fnv_hash_str(const char *data) +static inline unsigned firm_fnv_hash_str(const char *data) { unsigned i; unsigned hash = _FIRM_FNV_OFFSET_BASIS; @@ -79,7 +76,7 @@ static INLINE unsigned firm_fnv_hash_str(const char *data) #pragma warning(disable:4307) #endif /* _MSC_VER */ -static INLINE unsigned _hash_combine(unsigned x, unsigned y) +static inline unsigned _hash_combine(unsigned x, unsigned y) { unsigned hash = _FIRM_FNV_TIMES_PRIME(_FIRM_FNV_OFFSET_BASIS); hash ^= x; diff --git a/include/libfirm/adt/list.h b/include/libfirm/adt/list.h index d77eb2941..35b487327 100644 --- a/include/libfirm/adt/list.h +++ b/include/libfirm/adt/list.h @@ -15,7 +15,6 @@ #ifndef FIRM_ADT_LIST_H #define FIRM_ADT_LIST_H -#include "firm_config.h" #include typedef struct list_head list_head; @@ -44,7 +43,7 @@ struct list_head { * 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, +static inline void __list_add(struct list_head *new_node, struct list_head *prev, struct list_head *next) { @@ -62,7 +61,7 @@ static INLINE void __list_add(struct list_head *new_node, * 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) +static inline void list_add(struct list_head *new_node, struct list_head *head) { __list_add(new_node, head, head->next); } @@ -75,7 +74,7 @@ static INLINE void list_add(struct list_head *new_node, struct list_head *head) * 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) +static inline void list_add_tail(struct list_head *new_node, struct list_head *head) { __list_add(new_node, head->prev, head); } @@ -87,7 +86,7 @@ static INLINE void list_add_tail(struct list_head *new_node, struct list_head *h * 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) +static inline void __list_del(struct list_head * prev, struct list_head * next) { next->prev = prev; prev->next = next; @@ -101,7 +100,7 @@ static INLINE void __list_del(struct list_head * prev, struct list_head * next) * 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) +static inline void list_del(struct list_head *entry) { __list_del(entry->prev, entry->next); entry->next = NULL; @@ -113,7 +112,7 @@ static INLINE void list_del(struct list_head *entry) * 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) +static inline void list_del_init(struct list_head *entry) { __list_del(entry->prev, entry->next); INIT_LIST_HEAD(entry); @@ -124,7 +123,7 @@ static INLINE void list_del_init(struct list_head *entry) * @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) +static inline void list_move(struct list_head *list, struct list_head *head) { __list_del(list->prev, list->next); list_add(list, head); @@ -135,7 +134,7 @@ static INLINE void list_move(struct list_head *list, struct list_head *head) * @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, +static inline void list_move_tail(struct list_head *list, struct list_head *head) { __list_del(list->prev, list->next); @@ -146,12 +145,12 @@ static INLINE void list_move_tail(struct list_head *list, * list_empty - tests whether a list is empty * @param head the list to test. */ -static INLINE int list_empty(const struct list_head *head) +static inline int list_empty(const struct list_head *head) { return head->next == head; } -static INLINE void __list_splice(struct list_head *list, +static inline void __list_splice(struct list_head *list, struct list_head *head) { struct list_head *first = list->next; @@ -170,7 +169,7 @@ static INLINE void __list_splice(struct list_head *list, * @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) +static inline void list_splice(struct list_head *list, struct list_head *head) { if (!list_empty(list)) __list_splice(list, head); @@ -183,7 +182,7 @@ static INLINE void list_splice(struct list_head *list, struct list_head *head) * * The list at list is reinitialized */ -static INLINE void list_splice_init(struct list_head *list, +static inline void list_splice_init(struct list_head *list, struct list_head *head) { if (!list_empty(list)) { diff --git a/include/libfirm/adt/raw_bitset.h b/include/libfirm/adt/raw_bitset.h index 1426b137a..6093cbee7 100644 --- a/include/libfirm/adt/raw_bitset.h +++ b/include/libfirm/adt/raw_bitset.h @@ -59,7 +59,7 @@ typedef unsigned int rawbs_base_t; * * @return the new bitset */ -static INLINE unsigned *rbitset_malloc(unsigned size) { +static inline unsigned *rbitset_malloc(unsigned size) { unsigned size_bytes = BITSET_SIZE_BYTES(size); unsigned *res = xmalloc(size_bytes); memset(res, 0, size_bytes); @@ -88,7 +88,7 @@ do { \ * * @return the new bitset */ -static INLINE unsigned *rbitset_obstack_alloc(struct obstack *obst, unsigned size) { +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); @@ -105,7 +105,7 @@ static INLINE unsigned *rbitset_obstack_alloc(struct obstack *obst, unsigned siz * * @return the new bitset */ -static INLINE unsigned *rbitset_w_size_obstack_alloc(struct obstack *obst, unsigned size) { +static inline unsigned *rbitset_w_size_obstack_alloc(struct obstack *obst, unsigned size) { unsigned size_bytes = BITSET_SIZE_BYTES(size); unsigned *res = obstack_alloc(obst, size_bytes + sizeof(unsigned)); *res = size; @@ -127,7 +127,7 @@ static INLINE unsigned *rbitset_w_size_obstack_alloc(struct obstack *obst, unsig * * @return the new bitset */ -static INLINE +static inline unsigned *rbitset_duplicate_obstack_alloc(struct obstack *obst, const unsigned *old_bitset, unsigned size) @@ -142,7 +142,7 @@ unsigned *rbitset_duplicate_obstack_alloc(struct obstack *obst, /** * Check if a bitset is empty, ie all bits cleared. */ -static INLINE int rbitset_is_empty(unsigned *bitset, unsigned size) { +static inline int rbitset_is_empty(unsigned *bitset, unsigned size) { unsigned i, size_bytes = BITSET_SIZE_BYTES(size); for (i = 0; i < size_bytes; ++i) if (bitset[i]) return 0; @@ -155,7 +155,7 @@ static INLINE int rbitset_is_empty(unsigned *bitset, unsigned size) { * @param bitset the bitset * @param pos the position of the bit to be set */ -static INLINE void rbitset_set(unsigned *bitset, unsigned pos) { +static inline void rbitset_set(unsigned *bitset, unsigned pos) { BITSET_ELEM(bitset,pos) |= 1 << (pos % BITS_PER_ELEM); } @@ -165,7 +165,7 @@ static INLINE void rbitset_set(unsigned *bitset, unsigned pos) { * @param bitset the bitset * @param pos the position of the bit to be clear */ -static INLINE void rbitset_clear(unsigned *bitset, unsigned pos) { +static inline void rbitset_clear(unsigned *bitset, unsigned pos) { BITSET_ELEM(bitset, pos) &= ~(1 << (pos % BITS_PER_ELEM)); } @@ -175,7 +175,7 @@ static INLINE void rbitset_clear(unsigned *bitset, unsigned pos) { * @param bitset the bitset * @param size number of bits in the bitset */ -static INLINE void rbitset_clear_all(unsigned *bitset, unsigned size) { +static inline void rbitset_clear_all(unsigned *bitset, unsigned size) { unsigned size_bytes = BITSET_SIZE_BYTES(size); memset(bitset, 0, size_bytes); } @@ -186,7 +186,7 @@ static INLINE void rbitset_clear_all(unsigned *bitset, unsigned size) { * @param bitset the bitset * @param pos the position of the bit to check */ -static INLINE int rbitset_is_set(const unsigned *bitset, unsigned pos) { +static inline int rbitset_is_set(const unsigned *bitset, unsigned pos) { return BITSET_ELEM(bitset, pos) & (1 << (pos % BITS_PER_ELEM)); } @@ -195,7 +195,7 @@ static INLINE int rbitset_is_set(const unsigned *bitset, unsigned pos) { * * @param bitset the bitset */ -static INLINE unsigned rbitset_popcnt(const unsigned *bitset, unsigned size) { +static inline unsigned rbitset_popcnt(const unsigned *bitset, unsigned size) { unsigned pos; unsigned n = BITSET_SIZE_ELEMS(size); unsigned res = 0; @@ -209,7 +209,7 @@ static INLINE unsigned rbitset_popcnt(const unsigned *bitset, unsigned size) { return res; } -static INLINE unsigned rbitset_next(const unsigned *bitset, unsigned pos, int set) { +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; @@ -251,7 +251,7 @@ static INLINE unsigned rbitset_next(const unsigned *bitset, unsigned pos, int se /** * Inplace Intersection of two sets. */ -static INLINE void rbitset_and(unsigned *bitset1, const unsigned *bitset2, +static inline void rbitset_and(unsigned *bitset1, const unsigned *bitset2, unsigned size) { unsigned i, n = BITSET_SIZE_ELEMS(size); @@ -264,7 +264,7 @@ static INLINE void rbitset_and(unsigned *bitset1, const unsigned *bitset2, /** * Inplace Union of two sets. */ -static INLINE void rbitset_or(unsigned *bitset1, const unsigned *bitset2, +static inline void rbitset_or(unsigned *bitset1, const unsigned *bitset2, unsigned size) { unsigned i, n = BITSET_SIZE_ELEMS(size); @@ -277,7 +277,7 @@ static INLINE void rbitset_or(unsigned *bitset1, const unsigned *bitset2, /** * Remove all bits in bitset2 from bitset 1. */ -static INLINE void rbitset_andnot(unsigned *bitset1, const unsigned *bitset2, +static inline void rbitset_andnot(unsigned *bitset1, const unsigned *bitset2, unsigned size) { unsigned i, n = BITSET_SIZE_ELEMS(size); @@ -290,7 +290,7 @@ static INLINE void rbitset_andnot(unsigned *bitset1, const unsigned *bitset2, /** * Xor of two bitsets. */ -static INLINE void rbitset_xor(unsigned *bitset1, const unsigned *bitset2, +static inline void rbitset_xor(unsigned *bitset1, const unsigned *bitset2, unsigned size) { unsigned i, n = BITSET_SIZE_ELEMS(size); @@ -300,7 +300,7 @@ static INLINE void rbitset_xor(unsigned *bitset1, const unsigned *bitset2, } } -static INLINE int rbitset_equal(const unsigned *bitset1, +static inline int rbitset_equal(const unsigned *bitset1, const unsigned *bitset2, size_t size) { unsigned i, n = BITSET_SIZE_ELEMS(size); @@ -317,7 +317,7 @@ static INLINE int rbitset_equal(const unsigned *bitset1, * * @deprecated */ -static INLINE void rbitset_copy_to_bitset(const unsigned *rbitset, bitset_t *bitset) { +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) { diff --git a/include/libfirm/adt/unionfind.h b/include/libfirm/adt/unionfind.h index 5d5efb144..5e1cb47d5 100644 --- a/include/libfirm/adt/unionfind.h +++ b/include/libfirm/adt/unionfind.h @@ -41,7 +41,7 @@ * @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) { +static inline void uf_init(int* data, int from, int to) { int i; for(i = from; i < to; ++i) { data[i] = -1; @@ -58,7 +58,7 @@ static INLINE void uf_init(int* data, int from, int to) { * @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) { +static inline int uf_union(int* data, int set1, int set2) { int d1 = data[set1]; int d2 = data[set2]; int newcount; @@ -91,7 +91,7 @@ static INLINE int uf_union(int* data, int set1, int set2) { * @param e The element * @return The representative of the set that contains @p e */ -static INLINE int uf_find(int* data, int e) { +static inline int uf_find(int* data, int e) { /* go through list to find representative */ int repr = e; while(data[repr] >= 0) { diff --git a/include/libfirm/adt/util.h b/include/libfirm/adt/util.h index bffaa5d56..678c0ddb3 100644 --- a/include/libfirm/adt/util.h +++ b/include/libfirm/adt/util.h @@ -26,8 +26,6 @@ #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. diff --git a/include/libfirm/ircgcons.h b/include/libfirm/ircgcons.h index f5ec0926c..829fd2baf 100644 --- a/include/libfirm/ircgcons.h +++ b/include/libfirm/ircgcons.h @@ -28,8 +28,6 @@ #ifndef FIRM_IR_IRCGCONS_H #define FIRM_IR_IRCGCONS_H -#include "firm_config.h" - #ifdef INTERPROCEDURAL_VIEW #include "firm_types.h" diff --git a/include/libfirm/irgraph.h b/include/libfirm/irgraph.h index 64558a28f..84cdb1e63 100644 --- a/include/libfirm/irgraph.h +++ b/include/libfirm/irgraph.h @@ -28,7 +28,6 @@ #include -#include "firm_config.h" #include "firm_types.h" #include "irop.h" #include "iropt.h" diff --git a/include/libfirm/irhooks.h b/include/libfirm/irhooks.h index e597fe5be..0f9c840fb 100644 --- a/include/libfirm/irhooks.h +++ b/include/libfirm/irhooks.h @@ -26,7 +26,6 @@ #ifndef FIRM_IR_IRHOOKS_H #define FIRM_IR_IRHOOKS_H -#include "firm_config.h" #include "irop.h" #include "irnode.h" #include "irgraph.h" diff --git a/include/libfirm/irprintf.h b/include/libfirm/irprintf.h index cfb868fd1..7103587ee 100644 --- a/include/libfirm/irprintf.h +++ b/include/libfirm/irprintf.h @@ -27,8 +27,6 @@ #ifndef FIRM_IR_IRPRINTF_H #define FIRM_IR_IRPRINTF_H -#include "firm_config.h" - #include #include #include diff --git a/ir/adt/bitfiddle.h b/ir/adt/bitfiddle.h new file mode 100644 index 000000000..29ff4387e --- /dev/null +++ b/ir/adt/bitfiddle.h @@ -0,0 +1,218 @@ +/* + * Copyright (C) 1995-2008 University of Karlsruhe. All right reserved. + * + * This file is part of libFirm. + * + * This file may be distributed and/or modified under the terms of the + * GNU General Public License version 2 as published by the Free Software + * Foundation and appearing in the file LICENSE.GPL included in the + * packaging of this file. + * + * Licensees holding valid libFirm Professional Edition licenses may use + * this file in accordance with the libFirm Commercial License. + * Agreement provided with the Software. + * + * This file is provided AS IS with NO WARRANTY OF ANY KIND, INCLUDING THE + * WARRANTY OF DESIGN, MERCHANTABILITY AND FITNESS FOR A PARTICULAR + * PURPOSE. + */ + +/** + * @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 "compiler.h" + +#include +#include + +/* 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 +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 +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 +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 + unsigned y; + int n = 32; + + y = x >>16; if (y != 0) { n -= 16; x = y; } + y = x >> 8; if (y != 0) { n -= 8; x = y; } + y = x >> 4; if (y != 0) { n -= 4; x = y; } + y = x >> 2; if (y != 0) { n -= 2; x = y; } + y = x >> 1; if (y != 0) return n - 2; + return n - x; +#endif +} + +/** + * Compute the number of trailing zeros in a word. + * @param x The word. + * @return The number of trailing zeros. + */ +static inline +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 +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 +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 +int is_po2(unsigned x) +{ + return (x & (x-1)) == 0; +} + +#endif diff --git a/ir/adt/bitset.h b/ir/adt/bitset.h new file mode 100644 index 000000000..a8e44f913 --- /dev/null +++ b/ir/adt/bitset.h @@ -0,0 +1,603 @@ +/* + * Copyright (C) 1995-2008 University of Karlsruhe. All right reserved. + * + * This file is part of libFirm. + * + * This file may be distributed and/or modified under the terms of the + * GNU General Public License version 2 as published by the Free Software + * Foundation and appearing in the file LICENSE.GPL included in the + * packaging of this file. + * + * Licensees holding valid libFirm Professional Edition licenses may use + * this file in accordance with the libFirm Commercial License. + * Agreement provided with the Software. + * + * This file is provided AS IS with NO WARRANTY OF ANY KIND, INCLUDING THE + * WARRANTY OF DESIGN, MERCHANTABILITY AND FITNESS FOR A PARTICULAR + * PURPOSE. + */ + +/** + * @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_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) + +#define BS_DATA(bs) ((bitset_unit_t *) ((char *) (bs) + sizeof(bitset_t))) +#define BS_UNITS(bits) (round_up2(bits, BS_UNIT_SIZE_BITS) / BS_UNIT_SIZE_BITS) +#define BS_TOTAL_SIZE(bits) (sizeof(bitset_t) + BS_UNITS(bits) * BS_UNIT_SIZE) + +/** + * 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(ptr, 0, BS_TOTAL_SIZE(size)); + ptr->units = BS_UNITS(size); + ptr->size = 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)[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, BS_TOTAL_SIZE(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(BS_TOTAL_SIZE(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(BS_TOTAL_SIZE(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->size && "Bit to large"); + return BS_DATA(bs) + 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(bs)[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(BS_DATA(tgt), BS_DATA(src), min_units * BS_UNIT_SIZE); + if(tu > min_units) + memset(BS_DATA(tgt) + min_units, 0, BS_UNIT_SIZE * (tu - min_units)); + return _bitset_mask_highest(tgt); +} + +/** + * 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(bs)[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 : (bitset_pos_t) -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(bs)[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 : (bitset_pos_t) -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 != (bitset_pos_t) -1; elm = bitset_next_set(bitset,elm+1)) + + +#define bitset_foreach_clear(bitset,elm) \ + for(elm = bitset_next_clear(bitset,0); elm != (bitset_pos_t) -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(bs); 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(bs), 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(bs), -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 = BS_DATA(lhs)[i]; + bitset_unit_t ru = BS_DATA(rhs)[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(BS_DATA(lhs)[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(bs)[i]; + bitset_unit_t um1 = unit - 1; + + BS_DATA(bs)[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 (BS_DATA(a)[i] & BS_DATA(b)[i]) + return 1; + + return 0; +} + +/** + * set or clear all bits in the range [from;to[. + * @param a The bitset. + * @param from The first index to set to one. + * @param to The last index plus one to set to one. + * @param do_set If 1 the bits are set, if 0, they are cleared. + */ +static inline void bitset_mod_range(bitset_t *a, bitset_pos_t from, bitset_pos_t to, int do_set) +{ + bitset_pos_t from_unit, to_unit, i; + bitset_unit_t from_unit_mask, to_unit_mask; + + if (from == to) + return; + + if (to < from) { + bitset_pos_t tmp = from; + from = to; + to = tmp; + } + + if (to > a->size) + to = a->size; + + /* + * A small example (for cleaning bits in the same unit). + * from = 7 + * to = 19 + * do_set = 0 + * result: xxxxxxx000000000000xxxxxxxxxxxxx + * from_unit_mask: 00000001111111111111111111111111 + * to_unit_mask: 11111111111111111110000000000000 + * scale: 01234567890123456789012345678901 + * 1 2 3 + */ + + from_unit = from / BS_UNIT_SIZE_BITS; + from_unit_mask = ~((1 << from) - 1); + from = from & BS_UNIT_MASK; + + to_unit = to / BS_UNIT_SIZE_BITS; + to_unit_mask = (1 << to) - 1; + to = to & BS_UNIT_MASK; + + /* do we want to set the bits in the range? */ + if (do_set) { + /* If from and to are in the same unit: */ + if (from_unit == to_unit) + BS_DATA(a)[from_unit] |= from_unit_mask & to_unit_mask; + + /* Else, we have to treat the from and to units seperately */ + else { + BS_DATA(a)[from_unit] |= from_unit_mask; + BS_DATA(a)[to_unit] |= to_unit_mask; + for (i = from_unit + 1; i < to_unit; i++) + BS_DATA(a)[i] = BITSET_UNIT_ALL_ONE; + } + } + + /* ... or clear them? */ + else { + if (from_unit == to_unit) + BS_DATA(a)[from_unit] &= ~(from_unit_mask & to_unit_mask); + + else { + BS_DATA(a)[from_unit] &= ~from_unit_mask; + BS_DATA(a)[to_unit] &= ~to_unit_mask; + for (i = from_unit + 1; i < to_unit; i++) + BS_DATA(a)[i] = 0; + } + } +} + +#define bitset_set_range(bs, from, to) bitset_mod_range((bs), (from), (to), 1) +#define bitset_clear_range(bs, from, to) bitset_mod_range((bs), (from), (to), 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 (BS_DATA(a)[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(bs)[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(&BS_DATA(tgt)[i], &BS_DATA(src)[i]); \ + if(n < tgt->units) \ + _bitset_clear_rest(&BS_DATA(tgt)[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) do { } while(0) + +BINARY_OP(andnot) +BINARY_OP(or) +BINARY_OP(xor) + +#endif diff --git a/ir/adt/bitset_ia32.h b/ir/adt/bitset_ia32.h new file mode 100644 index 000000000..20ad6317a --- /dev/null +++ b/ir/adt/bitset_ia32.h @@ -0,0 +1,96 @@ +/* + * Copyright (C) 1995-2008 University of Karlsruhe. All right reserved. + * + * This file is part of libFirm. + * + * This file may be distributed and/or modified under the terms of the + * GNU General Public License version 2 as published by the Free Software + * Foundation and appearing in the file LICENSE.GPL included in the + * packaging of this file. + * + * Licensees holding valid libFirm Professional Edition licenses may use + * this file in accordance with the libFirm Commercial License. + * Agreement provided with the Software. + * + * This file is provided AS IS with NO WARRANTY OF ANY KIND, INCLUDING THE + * WARRANTY OF DESIGN, MERCHANTABILITY AND FITNESS FOR A PARTICULAR + * PURPOSE. + */ + +/** + * @file + * @brief intel 80x86 implementation of bitsets + * @version $Id$ + */ +#ifndef _BITSET_IA32_H +#define _BITSET_IA32_H + +#undef _bitset_inside_clear +#undef _bitset_inside_set +#undef _bitset_inside_flip + +#define _bitset_inside_set(unit, bit) \ + __asm__ __volatile__( "btsl %1,%0" :"=m" (*unit) : "Ir" (bit) : "cc") + +#define _bitset_inside_clear(unit, bit) \ + __asm__ __volatile__( "btrl %1,%0" :"=m" (*unit) : "Ir" (bit) : "cc") + +#define _bitset_inside_flip(unit, bit) \ + __asm__ __volatile__( "btcl %1,%0" :"=m" (*unit) : "Ir" (bit) : "cc") + +#undef _bitset_inside_is_set +#undef _bitset_inside_nlz +#undef _bitset_inside_ntz +#undef _bitset_inside_ntz_value + +#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; + __asm__("bt %2, %1\n\t" + "rcl $1, %0\n\t" + "and $1, %0" + : "=r" (res) + : "m" (*unit), "Ir" (bit) + : "cc"); + return res; +} + +static inline unsigned _bitset_ia32_inside_nlz(bitset_unit_t *unit) +{ + unsigned res; + __asm__("bsr %1, %0\n\t" + "cmovz %2, %0\n\t" + "neg %0\n\t" + "add $31, %0" + : "=&r" (res) + : "m" (*unit), "r" (-1) + : "cc"); + return res; +} + +static inline unsigned _bitset_ia32_inside_ntz(bitset_unit_t *unit) { + unsigned res; + __asm__("bsfl %1, %0\n\t" + "cmovz %2, %0\n\t" + : "=&r" (res) + : "m" (*unit), "r" (32) + : "cc"); + return res; +} + +static inline unsigned _bitset_ia32_inside_ntz_value(bitset_unit_t unit) { + unsigned res; + __asm__("bsfl %1, %0\n\t" + "cmovz %2, %0\n\t" + : "=&r" (res) + : "r" (unit), "r" (32) + : "cc"); + return res; +} + +#endif diff --git a/ir/adt/bitset_std.h b/ir/adt/bitset_std.h new file mode 100644 index 000000000..101c9dc23 --- /dev/null +++ b/ir/adt/bitset_std.h @@ -0,0 +1,122 @@ +/* + * Copyright (C) 1995-2008 University of Karlsruhe. All right reserved. + * + * This file is part of libFirm. + * + * This file may be distributed and/or modified under the terms of the + * GNU General Public License version 2 as published by the Free Software + * Foundation and appearing in the file LICENSE.GPL included in the + * packaging of this file. + * + * Licensees holding valid libFirm Professional Edition licenses may use + * this file in accordance with the libFirm Commercial License. + * Agreement provided with the Software. + * + * This file is provided AS IS with NO WARRANTY OF ANY KIND, INCLUDING THE + * WARRANTY OF DESIGN, MERCHANTABILITY AND FITNESS FOR A PARTICULAR + * PURPOSE. + */ + +/** + * @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) + +/** + * 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/compiler.h b/ir/adt/compiler.h new file mode 100644 index 000000000..f9e67c7b0 --- /dev/null +++ b/ir/adt/compiler.h @@ -0,0 +1,67 @@ +/* + * Copyright (C) 1995-2008 University of Karlsruhe. All right reserved. + * + * This file is part of libFirm. + * + * This file may be distributed and/or modified under the terms of the + * GNU General Public License version 2 as published by the Free Software + * Foundation and appearing in the file LICENSE.GPL included in the + * packaging of this file. + * + * Licensees holding valid libFirm Professional Edition licenses may use + * this file in accordance with the libFirm Commercial License. + * Agreement provided with the Software. + * + * This file is provided AS IS with NO WARRANTY OF ANY KIND, INCLUDING THE + * WARRANTY OF DESIGN, MERCHANTABILITY AND FITNESS FOR A PARTICULAR + * PURPOSE. + */ + +/** + * @file + * @date 04.06.2007 + * @author Matthias Braun, Sebastian Hack + * @brief Macros to instruct the compiler compiling libFirm. + */ + +#ifndef FIRM_COMPILER_H +#define FIRM_COMPILER_H + +/** + * 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) + +/** + * Tell the compiler, that a function is pure, i.e. it only + * uses its parameters and never modifies the "state". + * Add this macro after the return type. + */ +#define PURE __attribute__((const)) + +#else +#define LIKELY(x) x +#define UNLIKELY(x) x +#define PURE +#endif + +#endif