misc: add clz wrapper for builtin
* spot/bricks/brick-bitlevel, spot/misc/Makefile.am, spot/misc/bitset.hh, spot/misc/clz.cc, spot/misc/clz.hh, spot/misc/fixpool.hh: here.
This commit is contained in:
parent
01cceef29a
commit
69457e957b
6 changed files with 158 additions and 8 deletions
|
|
@ -37,6 +37,7 @@
|
||||||
|
|
||||||
#include <atomic>
|
#include <atomic>
|
||||||
#include <cstring>
|
#include <cstring>
|
||||||
|
#include <spot/misc/clz.hh>
|
||||||
|
|
||||||
#ifndef BRICK_BITLEVEL_H
|
#ifndef BRICK_BITLEVEL_H
|
||||||
#define BRICK_BITLEVEL_H
|
#define BRICK_BITLEVEL_H
|
||||||
|
|
@ -182,19 +183,19 @@ static inline unsigned MSB( T x ) {
|
||||||
template<>
|
template<>
|
||||||
inline unsigned MSB< unsigned int >( unsigned int x ) {
|
inline unsigned MSB< unsigned int >( unsigned int x ) {
|
||||||
static const unsigned long bits = sizeof( unsigned int ) * 8 - 1;
|
static const unsigned long bits = sizeof( unsigned int ) * 8 - 1;
|
||||||
return bits - __builtin_clz( x );
|
return bits - spot::clz( x );
|
||||||
}
|
}
|
||||||
|
|
||||||
template<>
|
template<>
|
||||||
inline unsigned MSB< unsigned long >( unsigned long x ) {
|
inline unsigned MSB< unsigned long >( unsigned long x ) {
|
||||||
static const unsigned bits = sizeof( unsigned long ) * 8 - 1;
|
static const unsigned bits = sizeof( unsigned long ) * 8 - 1;
|
||||||
return bits - __builtin_clzl( x );
|
return bits - spot::clz( x );
|
||||||
}
|
}
|
||||||
|
|
||||||
template<>
|
template<>
|
||||||
inline unsigned MSB< unsigned long long >( unsigned long long x ) {
|
inline unsigned MSB< unsigned long long >( unsigned long long x ) {
|
||||||
static const unsigned bits = sizeof( unsigned long long ) * 8 - 1;
|
static const unsigned bits = sizeof( unsigned long long ) * 8 - 1;
|
||||||
return bits - __builtin_clzll( x );
|
return bits - spot::clz( x );
|
||||||
}
|
}
|
||||||
|
|
||||||
// gets only Most Significant Bit
|
// gets only Most Significant Bit
|
||||||
|
|
|
||||||
|
|
@ -36,6 +36,7 @@ misc_HEADERS = \
|
||||||
bitvect.hh \
|
bitvect.hh \
|
||||||
casts.hh \
|
casts.hh \
|
||||||
common.hh \
|
common.hh \
|
||||||
|
clz.hh \
|
||||||
escape.hh \
|
escape.hh \
|
||||||
fixpool.hh \
|
fixpool.hh \
|
||||||
formater.hh \
|
formater.hh \
|
||||||
|
|
@ -63,6 +64,7 @@ libmisc_la_SOURCES = \
|
||||||
bareword.cc \
|
bareword.cc \
|
||||||
bitset.cc \
|
bitset.cc \
|
||||||
bitvect.cc \
|
bitvect.cc \
|
||||||
|
clz.cc \
|
||||||
escape.cc \
|
escape.cc \
|
||||||
formater.cc \
|
formater.cc \
|
||||||
game.cc \
|
game.cc \
|
||||||
|
|
|
||||||
|
|
@ -22,6 +22,7 @@
|
||||||
#include <array>
|
#include <array>
|
||||||
#include <spot/misc/hashfunc.hh>
|
#include <spot/misc/hashfunc.hh>
|
||||||
#include <spot/misc/common.hh>
|
#include <spot/misc/common.hh>
|
||||||
|
#include <spot/misc/clz.hh>
|
||||||
|
|
||||||
namespace spot
|
namespace spot
|
||||||
{
|
{
|
||||||
|
|
@ -362,7 +363,7 @@ namespace spot
|
||||||
continue;
|
continue;
|
||||||
}
|
}
|
||||||
#ifdef __GNUC__
|
#ifdef __GNUC__
|
||||||
res += 8*sizeof(word_t) - __builtin_clz(v);
|
res += 8*sizeof(word_t) - clz(v);
|
||||||
#else
|
#else
|
||||||
while (v)
|
while (v)
|
||||||
{
|
{
|
||||||
|
|
|
||||||
115
spot/misc/clz.cc
Normal file
115
spot/misc/clz.cc
Normal file
|
|
@ -0,0 +1,115 @@
|
||||||
|
// -*- coding: utf-8 -*-
|
||||||
|
// Copyright (C) 2018 Laboratoire de Recherche et Développement
|
||||||
|
// de l'Epita (LRDE).
|
||||||
|
//
|
||||||
|
// This file is part of Spot, a model checking library.
|
||||||
|
//
|
||||||
|
// Spot 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 of the License, or
|
||||||
|
// (at your option) any later version.
|
||||||
|
//
|
||||||
|
// Spot 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 this program. If not, see <http://www.gnu.org/licenses/>.
|
||||||
|
|
||||||
|
#include "config.h"
|
||||||
|
#include <spot/misc/clz.hh>
|
||||||
|
|
||||||
|
namespace spot
|
||||||
|
{
|
||||||
|
// use gcc and clang built-in functions
|
||||||
|
// both compilers use the same function names, and define __GNUC__
|
||||||
|
#if __GNUC__
|
||||||
|
template<class T>
|
||||||
|
struct _clz;
|
||||||
|
|
||||||
|
template<>
|
||||||
|
struct _clz<unsigned>
|
||||||
|
{
|
||||||
|
unsigned
|
||||||
|
operator()(unsigned n) const noexcept
|
||||||
|
{
|
||||||
|
return __builtin_clz(n);
|
||||||
|
}
|
||||||
|
};
|
||||||
|
|
||||||
|
template<>
|
||||||
|
struct _clz<unsigned long>
|
||||||
|
{
|
||||||
|
unsigned long
|
||||||
|
operator()(unsigned long n) const noexcept
|
||||||
|
{
|
||||||
|
return __builtin_clzl(n);
|
||||||
|
}
|
||||||
|
};
|
||||||
|
|
||||||
|
template<>
|
||||||
|
struct _clz<unsigned long long>
|
||||||
|
{
|
||||||
|
unsigned long long
|
||||||
|
operator()(unsigned long long n) const noexcept
|
||||||
|
{
|
||||||
|
return __builtin_clzll(n);
|
||||||
|
}
|
||||||
|
};
|
||||||
|
|
||||||
|
size_t
|
||||||
|
clz(unsigned n)
|
||||||
|
{
|
||||||
|
return _clz<unsigned>()(n);
|
||||||
|
}
|
||||||
|
|
||||||
|
size_t
|
||||||
|
clz(unsigned long n)
|
||||||
|
{
|
||||||
|
return _clz<unsigned long>()(n);
|
||||||
|
}
|
||||||
|
|
||||||
|
size_t
|
||||||
|
clz(unsigned long long n)
|
||||||
|
{
|
||||||
|
return _clz<unsigned long long>()(n);
|
||||||
|
}
|
||||||
|
#else
|
||||||
|
size_t
|
||||||
|
clz(unsigned n)
|
||||||
|
{
|
||||||
|
size_t res = CHAR_BIT*sizeof(size_t);
|
||||||
|
while (n)
|
||||||
|
{
|
||||||
|
--res;
|
||||||
|
n >>= 1;
|
||||||
|
}
|
||||||
|
return res;
|
||||||
|
}
|
||||||
|
|
||||||
|
size_t
|
||||||
|
clz(unsigned long n)
|
||||||
|
{
|
||||||
|
size_t res = CHAR_BIT*sizeof(unsigned long);
|
||||||
|
while (n)
|
||||||
|
{
|
||||||
|
--res;
|
||||||
|
n >>= 1;
|
||||||
|
}
|
||||||
|
return res;
|
||||||
|
}
|
||||||
|
|
||||||
|
size_t
|
||||||
|
clz(unsigned long long n)
|
||||||
|
{
|
||||||
|
size_t res = CHAR_BIT*sizeof(unsigned long long);
|
||||||
|
while (n)
|
||||||
|
{
|
||||||
|
--res;
|
||||||
|
n >>= 1;
|
||||||
|
}
|
||||||
|
return res;
|
||||||
|
}
|
||||||
|
#endif
|
||||||
|
}
|
||||||
33
spot/misc/clz.hh
Normal file
33
spot/misc/clz.hh
Normal file
|
|
@ -0,0 +1,33 @@
|
||||||
|
// -*- coding: utf-8 -*-
|
||||||
|
// Copyright (C) 2018 Laboratoire de Recherche et Développement
|
||||||
|
// de l'Epita (LRDE).
|
||||||
|
//
|
||||||
|
// This file is part of Spot, a model checking library.
|
||||||
|
//
|
||||||
|
// Spot 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 of the License, or
|
||||||
|
// (at your option) any later version.
|
||||||
|
//
|
||||||
|
// Spot 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 this program. If not, see <http://www.gnu.org/licenses/>.
|
||||||
|
|
||||||
|
#pragma once
|
||||||
|
|
||||||
|
#include <spot/misc/common.hh>
|
||||||
|
#include <cstddef>
|
||||||
|
#include <climits>
|
||||||
|
|
||||||
|
namespace spot
|
||||||
|
{
|
||||||
|
SPOT_API size_t clz(unsigned n);
|
||||||
|
|
||||||
|
SPOT_API size_t clz(unsigned long n);
|
||||||
|
|
||||||
|
SPOT_API size_t clz(unsigned long long n);
|
||||||
|
}
|
||||||
|
|
@ -20,8 +20,7 @@
|
||||||
#pragma once
|
#pragma once
|
||||||
|
|
||||||
#include <spot/misc/common.hh>
|
#include <spot/misc/common.hh>
|
||||||
#include <climits>
|
#include <spot/misc/clz.hh>
|
||||||
#include <cstddef>
|
|
||||||
|
|
||||||
#if SPOT_DEBUG && defined(HAVE_VALGRIND_MEMCHECK_H)
|
#if SPOT_DEBUG && defined(HAVE_VALGRIND_MEMCHECK_H)
|
||||||
#include <valgrind/memcheck.h>
|
#include <valgrind/memcheck.h>
|
||||||
|
|
@ -59,8 +58,7 @@ namespace spot
|
||||||
return size;
|
return size;
|
||||||
// small numbers are best aligned to the next power of 2
|
// small numbers are best aligned to the next power of 2
|
||||||
else if (size < alignof(std::max_align_t))
|
else if (size < alignof(std::max_align_t))
|
||||||
return size_t{1} << (CHAR_BIT*sizeof(size_t) -
|
return size_t{1} << (CHAR_BIT*sizeof(size_t) - clz(size));
|
||||||
__builtin_clz(size));
|
|
||||||
else
|
else
|
||||||
{
|
{
|
||||||
size_t mask = alignof(std::max_align_t)-1;
|
size_t mask = alignof(std::max_align_t)-1;
|
||||||
|
|
|
||||||
Loading…
Add table
Add a link
Reference in a new issue