Commit c684d586 authored by Etienne Renault's avatar Etienne Renault

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.
parent 9c01cc6c
......@@ -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)
{
......
// -*- 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
}
// -*- 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;
......
Markdown is supported
0%
or
You are about to add 0 people to the discussion. Proceed with caution.
Finish editing this message first!
Please register or to comment