From 2dc597d50d0f44a20e98f5c5ceb3742d72f187d5 Mon Sep 17 00:00:00 2001 From: Adrien Destugues Date: Fri, 8 May 2020 11:46:15 +0200 Subject: [PATCH] Optimize ffs() implementation - Use gcc builtin - Define as a static inline function in the .h so no function call overhead is needed - Keep the function in libroot for backwards compatibility - Remove a duplicate implementation in the freebsd compatibility layer gcc2 does not document the builtin, but it is in fact already available there as well. Fixes #3281. Change-Id: I94f8a2548637aa70e85febbfab06f07c1a427005 Reviewed-on: https://review.haiku-os.org/c/haiku/+/2605 Reviewed-by: waddlesplash --- headers/posix/strings.h | 2 +- src/libs/compat/freebsd_network/device.c | 17 ----------------- src/system/libroot/posix/string/ffs.cpp | 18 +++--------------- 3 files changed, 4 insertions(+), 33 deletions(-) diff --git a/headers/posix/strings.h b/headers/posix/strings.h index a267758356..adc06074b4 100644 --- a/headers/posix/strings.h +++ b/headers/posix/strings.h @@ -13,7 +13,7 @@ extern "C" { #endif -extern int ffs(int i); +static inline int ffs(int i) { return __builtin_ffs(i); } extern int strcasecmp(const char *string1, const char *string2); extern int strncasecmp(const char *string1, const char *string2, diff --git a/src/libs/compat/freebsd_network/device.c b/src/libs/compat/freebsd_network/device.c index 72816cc13b..872a8a082e 100644 --- a/src/libs/compat/freebsd_network/device.c +++ b/src/libs/compat/freebsd_network/device.c @@ -624,23 +624,6 @@ printf(const char *format, ...) } -#ifndef __clang__ -int -ffs(int value) -{ - int i = 1; - - if (value == 0) - return 0; - - for (; !(value & 1); i++) - value >>= 1; - - return i; -} -#endif - - int resource_int_value(const char *name, int unit, const char *resname, int *result) diff --git a/src/system/libroot/posix/string/ffs.cpp b/src/system/libroot/posix/string/ffs.cpp index 7f5ff3f6b3..f7d03a1dfc 100644 --- a/src/system/libroot/posix/string/ffs.cpp +++ b/src/system/libroot/posix/string/ffs.cpp @@ -1,24 +1,12 @@ /* - * Copyright 2005, Ingo Weinhold, bonefish@users.sf.net. + * Copyright 2020, Adrien Destugues . * Distributed under the terms of the MIT License. */ -#include // find first (least significant) set bit -int +extern "C" int ffs(int value) { - if (!value) - return 0; - - // ToDo: This can certainly be optimized (e.g. by binary search). Or not - // unlikely there's a single assembler instruction... - for (int i = 1; i <= (int)sizeof(value) * 8; i++, value >>= 1) { - if (value & 1) - return i; - } - - // never gets here - return 0; + return __builtin_ffs(value); }