clz: inline the implementation

__builtin_clz() can be implemented with two x86 instructions, so we
don't want to hide it behind a function call.

* spot/misc/clz.cc: Delete the implementation.
* spot/misc/Makefile.am: Delete clz.cc.
* spot/misc/clz.hh: Make the implementation public.
This commit is contained in:
Alexandre Duret-Lutz 2021-01-17 16:00:16 +01:00
parent a8ee291abe
commit d1cc45f223
3 changed files with 33 additions and 122 deletions

View file

@ -1,6 +1,6 @@
## -*- coding: utf-8 -*-
## Copyright (C) 2011-2014, 2016-2018, 2020 Laboratoire de Recherche
## et Développement de l'Epita (LRDE).
## Copyright (C) 2011-2014, 2016-2018, 2020-2021 Laboratoire de
## Recherche et Développement de l'Epita (LRDE).
## Copyright (C) 2003, 2004, 2005, 2006 Laboratoire d'Informatique de
## Paris 6 (LIP6), département Systèmes Répartis Coopératifs (SRC),
## Université Pierre et Marie Curie.
@ -63,7 +63,6 @@ libmisc_la_SOURCES = \
bareword.cc \
bitset.cc \
bitvect.cc \
clz.cc \
escape.cc \
formater.cc \
intvcomp.cc \

View file

@ -1,115 +0,0 @@
// -*- 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
}

View file

@ -1,5 +1,5 @@
// -*- coding: utf-8 -*-
// Copyright (C) 2018 Laboratoire de Recherche et Développement
// Copyright (C) 2018, 2021 Laboratoire de Recherche et Développement
// de l'Epita (LRDE).
//
// This file is part of Spot, a model checking library.
@ -25,9 +25,36 @@
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);
template<typename Type,
typename = std::enable_if_t<std::is_unsigned<Type>::value>>
inline constexpr unsigned clz(Type n) noexcept
{
unsigned res = CHAR_BIT * sizeof(Type);
while (n)
{
--res;
n >>= 1;
}
return res;
}
#if __GNUC__
template<>
inline constexpr unsigned clz(unsigned n) noexcept
{
return __builtin_clz(n);
}
template<>
inline constexpr unsigned clz(unsigned long n) noexcept
{
return __builtin_clzl(n);
}
template<>
inline constexpr unsigned clz(unsigned long long n) noexcept
{
return __builtin_clzll(n);
}
#endif
}