/* Functions to support fixed-length bitmaps.
Copyright (C) 2024 Free Software Foundation, Inc.
This file is part of GCC.
GCC is free software; you can redistribute it and/or modify it under
the terms of the GNU General Public License as published by the Free
Software Foundation; either version 3, or (at your option) any later
version.
GCC 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. See the GNU General Public License
for more details.
You should have received a copy of the GNU General Public License
along with GCC; see the file COPYING3. If not see
. */
#ifndef GCC_BBITMAP_H
#define GCC_BBITMAP_H
/* Implementation of bounded (fixed length) bitmaps.
This provides a drop-in replacement for bitmaps that have outgrown the
storage capacity of a single integer.
Sets are stored as a fixed length array of uint64_t elements. The length of
this array is given as a template parameter. */
/* Use recusive templated functions to define constexpr operations. */
template
struct bbitmap_operators
{
/* Return a result that maps binary operator OP to elements [0, M) of
X and Y, and takes the remaining elements from REST. */
template
static constexpr Result binary(Operator op, const Arg &x, const Arg &y,
Rest ...rest)
{
return bbitmap_operators::template binary
(op, x, y, op (x.val[M - 1], y.val[M - 1]), rest...);
}
/* Return a result that contains the bitwise inverse of elements [0, M) of X,
and takes the remaining elements from REST. */
template
static constexpr Result bit_not(const Arg &x, Rest ...rest)
{
return bbitmap_operators::template bit_not
(x, ~(x.val[M - 1]), rest...);
}
/* Return true if any element [0, M) of X is nonzero. */
template
static constexpr bool non_zero(const Arg &x)
{
return (bool) x.val[M - 1]
|| bbitmap_operators::template non_zero (x);
}
/* Return true if elements [0, M) of X are all equal to the corresponding
elements of Y. */
template
static constexpr bool equal(const Arg &x, const Arg &y)
{
return x.val[M - 1] == y.val[M - 1]
&& bbitmap_operators::template equal (x, y);
}
/* If bit index INDEX selects a bit in the first M elements, return a
Result with that bit set and the other bits of the leading M elements
clear. Clear the leading M elements otherwise. Take the remaining
elements of the Result from REST. */
template
static constexpr Result from_index(int index, Rest ...rest)
{
return bbitmap_operators::template from_index
(index,
uint64_t ((index - (M - 1) * 64) == (index & 63)) << (index & 63),
rest...);
}
};
/* These functions form the base for the recursive functions above. They
return either bitmap containing the elements passed in REST, or a default
bool result. */
template<>
struct bbitmap_operators<0>
{
template
static constexpr Result binary(Operator, const Arg, const Arg,
Rest ...rest)
{
return Result { rest... };
}
template
static constexpr Result bit_not(const Arg, Rest ...rest)
{
return Result { rest... };
}
template
static constexpr bool non_zero(const Arg)
{
return false;
}
template
static constexpr bool equal(const Arg, const Arg)
{
return true;
}
template
static constexpr Result from_index(int, Rest ...rest)
{
return Result { rest... };
}
};
template
constexpr T bbitmap_element_or(T x, T y) { return x | y;}
template
constexpr T bbitmap_element_and(T x, T y) { return x & y;}
template
constexpr T bbitmap_element_xor(T x, T y) { return x ^ y;}
template
class GTY((user)) bbitmap
{
public:
uint64_t val[N];
template
constexpr bbitmap(Rest ...rest) : val{(uint64_t) rest...} {}
constexpr bbitmap operator|(const bbitmap other) const
{
return bbitmap_operators::template binary>
(bbitmap_element_or, *this, other);
}
bbitmap operator|=(const bbitmap other)
{
for (int i = 0; i < N; i++)
val[i] |= other.val[i];
return this;
}
constexpr bbitmap operator&(const bbitmap other) const
{
return bbitmap_operators::template binary>
(bbitmap_element_and, *this, other);
}
bbitmap operator&=(const bbitmap other)
{
for (int i = 0; i < N; i++)
val[i] &= other.val[i];
return this;
}
constexpr bbitmap operator^(const bbitmap other) const
{
return bbitmap_operators::template binary>
(bbitmap_element_xor, *this, other);
}
bbitmap operator^=(const bbitmap other)
{
for (int i = 0; i < N; i++)
val[i] ^= other.val[i];
return this;
}
constexpr bbitmap operator~() const
{
return bbitmap_operators::template bit_not>(*this);
}
constexpr bool operator!() const
{
return !(bbitmap_operators::template non_zero>(*this));
}
constexpr explicit operator bool() const
{
return bbitmap_operators::template non_zero>(*this);
}
constexpr bool operator==(const bbitmap other) const
{
return bbitmap_operators::template equal>(*this, other);
}
constexpr bool operator!=(const bbitmap other) const
{
return !(bbitmap_operators::template equal>(*this, other));
}
/* Return a bitmap with bit INDEX set and all other bits clear. */
static constexpr bbitmap from_index (int index)
{
return bbitmap_operators::template from_index> (index);
}
};
template
void
gt_ggc_mx (bbitmap *)
{
}
template
void
gt_pch_nx (bbitmap *)
{
}
template
void
gt_pch_nx (bbitmap *, gt_pointer_operator, void *)
{
}
#endif