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 <cstring>
|
||||
#include <spot/misc/clz.hh>
|
||||
|
||||
#ifndef BRICK_BITLEVEL_H
|
||||
#define BRICK_BITLEVEL_H
|
||||
|
|
@ -182,19 +183,19 @@ static inline unsigned MSB( T x ) {
|
|||
template<>
|
||||
inline unsigned MSB< unsigned int >( unsigned int x ) {
|
||||
static const unsigned long bits = sizeof( unsigned int ) * 8 - 1;
|
||||
return bits - __builtin_clz( x );
|
||||
return bits - spot::clz( x );
|
||||
}
|
||||
|
||||
template<>
|
||||
inline unsigned MSB< unsigned long >( unsigned long x ) {
|
||||
static const unsigned bits = sizeof( unsigned long ) * 8 - 1;
|
||||
return bits - __builtin_clzl( x );
|
||||
return bits - spot::clz( x );
|
||||
}
|
||||
|
||||
template<>
|
||||
inline unsigned MSB< unsigned long long >( unsigned long long x ) {
|
||||
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
|
||||
|
|
|
|||
|
|
@ -36,6 +36,7 @@ misc_HEADERS = \
|
|||
bitvect.hh \
|
||||
casts.hh \
|
||||
common.hh \
|
||||
clz.hh \
|
||||
escape.hh \
|
||||
fixpool.hh \
|
||||
formater.hh \
|
||||
|
|
@ -63,6 +64,7 @@ libmisc_la_SOURCES = \
|
|||
bareword.cc \
|
||||
bitset.cc \
|
||||
bitvect.cc \
|
||||
clz.cc \
|
||||
escape.cc \
|
||||
formater.cc \
|
||||
game.cc \
|
||||
|
|
|
|||
|
|
@ -22,6 +22,7 @@
|
|||
#include <array>
|
||||
#include <spot/misc/hashfunc.hh>
|
||||
#include <spot/misc/common.hh>
|
||||
#include <spot/misc/clz.hh>
|
||||
|
||||
namespace spot
|
||||
{
|
||||
|
|
@ -362,7 +363,7 @@ namespace spot
|
|||
continue;
|
||||
}
|
||||
#ifdef __GNUC__
|
||||
res += 8*sizeof(word_t) - __builtin_clz(v);
|
||||
res += 8*sizeof(word_t) - clz(v);
|
||||
#else
|
||||
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
|
||||
|
||||
#include <spot/misc/common.hh>
|
||||
#include <climits>
|
||||
#include <cstddef>
|
||||
#include <spot/misc/clz.hh>
|
||||
|
||||
#if SPOT_DEBUG && defined(HAVE_VALGRIND_MEMCHECK_H)
|
||||
#include <valgrind/memcheck.h>
|
||||
|
|
@ -59,8 +58,7 @@ namespace spot
|
|||
return size;
|
||||
// small numbers are best aligned to the next power of 2
|
||||
else if (size < alignof(std::max_align_t))
|
||||
return size_t{1} << (CHAR_BIT*sizeof(size_t) -
|
||||
__builtin_clz(size));
|
||||
return size_t{1} << (CHAR_BIT*sizeof(size_t) - clz(size));
|
||||
else
|
||||
{
|
||||
size_t mask = alignof(std::max_align_t)-1;
|
||||
|
|
|
|||
Loading…
Add table
Add a link
Reference in a new issue