From 888e35f0fed393e8496414e5c285cf4ca4788f67 Mon Sep 17 00:00:00 2001 From: Andreas Kling Date: Thu, 30 Apr 2020 11:43:25 +0200 Subject: [PATCH] AK: Add ALWAYS_INLINE, NEVER_INLINE and FLATTEN macros It's tedious to write (and look at) [[gnu::always_inline]] etc. :^) --- AK/FlyString.h | 2 +- AK/Memory.h | 4 ++-- AK/Optional.h | 14 +++++++------- AK/Platform.h | 19 +++++++++++++++++-- AK/PrintfImplementation.h | 18 +++++++++--------- AK/StringView.h | 8 ++++---- Kernel/Heap/kmalloc.h | 2 +- Kernel/KSyms.cpp | 2 +- Kernel/Lock.h | 8 ++++---- Libraries/LibBareMetal/IO.h | 4 ++-- Libraries/LibC/stdio.cpp | 6 +++--- Libraries/LibGfx/PNGLoader.cpp | 6 +++--- Libraries/LibGfx/Painter.cpp | 16 ++++------------ Libraries/LibThread/Lock.h | 10 +++++----- 14 files changed, 63 insertions(+), 56 deletions(-) diff --git a/AK/FlyString.h b/AK/FlyString.h index 7985cf2dfd..cbab71a26d 100644 --- a/AK/FlyString.h +++ b/AK/FlyString.h @@ -56,7 +56,7 @@ public: const char* characters() const { return m_impl ? m_impl->characters() : nullptr; } size_t length() const { return m_impl ? m_impl->length() : 0; } - [[gnu::always_inline]] inline u32 hash() const { return m_impl ? m_impl->existing_hash() : 0; } + ALWAYS_INLINE u32 hash() const { return m_impl ? m_impl->existing_hash() : 0; } StringView view() const; diff --git a/AK/Memory.h b/AK/Memory.h index 27b5d2c54b..4d2efb012c 100644 --- a/AK/Memory.h +++ b/AK/Memory.h @@ -13,7 +13,7 @@ extern "C" void* mmx_memcpy(void* to, const void* from, size_t); #endif -[[gnu::always_inline]] inline void fast_u32_copy(u32* dest, const u32* src, size_t count) +ALWAYS_INLINE void fast_u32_copy(u32* dest, const u32* src, size_t count) { #if defined(__serenity__) && !defined(KERNEL) && !defined(BOOTSTRAPPER) if (count >= 256) { @@ -28,7 +28,7 @@ extern "C" void* mmx_memcpy(void* to, const void* from, size_t); : "memory"); } -[[gnu::always_inline]] inline void fast_u32_fill(u32* dest, u32 value, size_t count) +ALWAYS_INLINE void fast_u32_fill(u32* dest, u32 value, size_t count) { asm volatile( "rep stosl\n" diff --git a/AK/Optional.h b/AK/Optional.h index 6c713db346..37b4647e6b 100644 --- a/AK/Optional.h +++ b/AK/Optional.h @@ -105,12 +105,12 @@ public: return *this; } - [[gnu::always_inline]] inline ~Optional() + ALWAYS_INLINE ~Optional() { clear(); } - [[gnu::always_inline]] inline void clear() + ALWAYS_INLINE void clear() { if (m_has_value) { value().~T(); @@ -119,17 +119,17 @@ public: } SET_TYPESTATE(consumed) - [[gnu::always_inline]] inline bool has_value() const { return m_has_value; } + ALWAYS_INLINE bool has_value() const { return m_has_value; } CALLABLE_WHEN(consumed) - [[gnu::always_inline]] inline T& value() + ALWAYS_INLINE T& value() { ASSERT(m_has_value); return *reinterpret_cast(&m_storage); } CALLABLE_WHEN(consumed) - [[gnu::always_inline]] inline const T& value() const + ALWAYS_INLINE const T& value() const { return value_without_consume_state(); } @@ -144,7 +144,7 @@ public: return released_value; } - [[gnu::always_inline]] inline T value_or(const T& fallback) const + ALWAYS_INLINE T value_or(const T& fallback) const { if (m_has_value) return value(); @@ -153,7 +153,7 @@ public: private: // Call when we don't want to alter the consume state - [[gnu::always_inline]] inline const T& value_without_consume_state() const + ALWAYS_INLINE const T& value_without_consume_state() const { ASSERT(m_has_value); return *reinterpret_cast(&m_storage); diff --git a/AK/Platform.h b/AK/Platform.h index 6763f641c2..df72a1cd09 100644 --- a/AK/Platform.h +++ b/AK/Platform.h @@ -36,6 +36,21 @@ #define ARCH(arch) (defined(AK_ARCH_##arch) && AK_ARCH_##arch) +#ifdef ALWAYS_INLINE +#undef ALWAYS_INLINE +#endif +#define ALWAYS_INLINE [[gnu::always_inline]] inline + +#ifdef NEVER_INLINE +#undef NEVER_INLINE +#endif +#define NEVER_INLINE [[gnu::noinline]] + +#ifdef FLATTEN +#undef FLATTEN +#endif +#define FLATTEN [[gnu::flatten]] + // FIXME: Re-enable this when we can figure out why Clang gets confused about "unknown" #if 0 # define CONSUMABLE(initial_state) __attribute__((consumable(initial_state))) @@ -70,7 +85,7 @@ inline int open_with_path_length(const char* path, size_t path_length, int optio #endif template -[[gnu::always_inline]] inline T convert_between_host_and_network(T value) +ALWAYS_INLINE T convert_between_host_and_network(T value) { #if __BYTE_ORDER__ == __ORDER_LITTLE_ENDIAN__ if constexpr (sizeof(T) == 8) @@ -86,7 +101,7 @@ template #endif } -[[gnu::always_inline]] inline int count_trailing_zeroes_32(unsigned int val) +ALWAYS_INLINE int count_trailing_zeroes_32(unsigned int val) { #if defined(__GNUC__) || defined(__clang__) return __builtin_ctz(val); diff --git a/AK/PrintfImplementation.h b/AK/PrintfImplementation.h index b46fff6c1a..9471ffd8ab 100644 --- a/AK/PrintfImplementation.h +++ b/AK/PrintfImplementation.h @@ -42,7 +42,7 @@ extern "C" size_t strlen(const char*); #endif template -[[gnu::always_inline]] inline int print_hex(PutChFunc putch, char*& bufptr, T number, bool upper_case, bool alternate_form, bool left_pad, bool zeroPad, u8 width) +ALWAYS_INLINE int print_hex(PutChFunc putch, char*& bufptr, T number, bool upper_case, bool alternate_form, bool left_pad, bool zeroPad, u8 width) { int ret = 0; @@ -96,7 +96,7 @@ template } template -[[gnu::always_inline]] inline int print_number(PutChFunc putch, char*& bufptr, u32 number, bool leftPad, bool zeroPad, u32 fieldWidth) +ALWAYS_INLINE int print_number(PutChFunc putch, char*& bufptr, u32 number, bool leftPad, bool zeroPad, u32 fieldWidth) { u32 divisor = 1000000000; char ch; @@ -137,7 +137,7 @@ template } template -[[gnu::always_inline]] inline int print_u64(PutChFunc putch, char*& bufptr, u64 number, bool leftPad, bool zeroPad, u32 fieldWidth) +ALWAYS_INLINE int print_u64(PutChFunc putch, char*& bufptr, u64 number, bool leftPad, bool zeroPad, u32 fieldWidth) { u64 divisor = 10000000000000000000LLU; char ch; @@ -178,7 +178,7 @@ template } template -[[gnu::always_inline]] inline int print_double(PutChFunc putch, char*& bufptr, double number, bool leftPad, bool zeroPad, u32 fieldWidth, u32 fraction_length = 6) +ALWAYS_INLINE int print_double(PutChFunc putch, char*& bufptr, double number, bool leftPad, bool zeroPad, u32 fieldWidth, u32 fraction_length = 6) { int length = 0; @@ -200,7 +200,7 @@ template } template -[[gnu::always_inline]] inline int print_i64(PutChFunc putch, char*& bufptr, i64 number, bool leftPad, bool zeroPad, u32 fieldWidth) +ALWAYS_INLINE int print_i64(PutChFunc putch, char*& bufptr, i64 number, bool leftPad, bool zeroPad, u32 fieldWidth) { if (number < 0) { putch(bufptr, '-'); @@ -210,7 +210,7 @@ template } template -[[gnu::always_inline]] inline int print_octal_number(PutChFunc putch, char*& bufptr, u32 number, bool leftPad, bool zeroPad, u32 fieldWidth) +ALWAYS_INLINE int print_octal_number(PutChFunc putch, char*& bufptr, u32 number, bool leftPad, bool zeroPad, u32 fieldWidth) { u32 divisor = 134217728; char ch; @@ -251,7 +251,7 @@ template } template -[[gnu::always_inline]] inline int print_string(PutChFunc putch, char*& bufptr, const char* str, bool left_pad, size_t field_width, bool dot) +ALWAYS_INLINE int print_string(PutChFunc putch, char*& bufptr, const char* str, bool left_pad, size_t field_width, bool dot) { size_t len = strlen(str); if (!dot && (!field_width || field_width < len)) @@ -273,7 +273,7 @@ template } template -[[gnu::always_inline]] inline int print_signed_number(PutChFunc putch, char*& bufptr, int number, bool leftPad, bool zeroPad, u32 fieldWidth, bool always_sign) +ALWAYS_INLINE int print_signed_number(PutChFunc putch, char*& bufptr, int number, bool leftPad, bool zeroPad, u32 fieldWidth, bool always_sign) { if (number < 0) { putch(bufptr, '-'); @@ -285,7 +285,7 @@ template } template -[[gnu::always_inline]] inline int printf_internal(PutChFunc putch, char* buffer, const char*& fmt, va_list ap) +ALWAYS_INLINE int printf_internal(PutChFunc putch, char* buffer, const char*& fmt, va_list ap) { const char* p; diff --git a/AK/StringView.h b/AK/StringView.h index 909125e23b..491e1cf2c3 100644 --- a/AK/StringView.h +++ b/AK/StringView.h @@ -38,20 +38,20 @@ class StringView { public: using ConstIterator = const char*; - [[gnu::always_inline]] inline StringView() { } - [[gnu::always_inline]] inline StringView(const char* characters, size_t length) + ALWAYS_INLINE StringView() { } + ALWAYS_INLINE StringView(const char* characters, size_t length) : m_characters(characters) , m_length(length) { ASSERT(!Checked::addition_would_overflow((uintptr_t)characters, length)); } - [[gnu::always_inline]] inline StringView(const unsigned char* characters, size_t length) + ALWAYS_INLINE StringView(const unsigned char* characters, size_t length) : m_characters((const char*)characters) , m_length(length) { ASSERT(!Checked::addition_would_overflow((uintptr_t)characters, length)); } - [[gnu::always_inline]] inline StringView(const char* cstring) + ALWAYS_INLINE StringView(const char* cstring) : m_characters(cstring) , m_length(cstring ? __builtin_strlen(cstring) : 0) { diff --git a/Kernel/Heap/kmalloc.h b/Kernel/Heap/kmalloc.h index a60422ea1e..c895f6578e 100644 --- a/Kernel/Heap/kmalloc.h +++ b/Kernel/Heap/kmalloc.h @@ -53,7 +53,7 @@ extern bool g_dump_kmalloc_stacks; inline void* operator new(size_t, void* p) { return p; } inline void* operator new[](size_t, void* p) { return p; } -[[gnu::always_inline]] inline void* kmalloc(size_t size) +ALWAYS_INLINE void* kmalloc(size_t size) { #ifdef KMALLOC_DEBUG_LARGE_ALLOCATIONS // Any kernel allocation >= 1M is 99.9% a bug. diff --git a/Kernel/KSyms.cpp b/Kernel/KSyms.cpp index f9af289d89..4f1c0d5119 100644 --- a/Kernel/KSyms.cpp +++ b/Kernel/KSyms.cpp @@ -115,7 +115,7 @@ static void load_kernel_sybols_from_data(const ByteBuffer& buffer) g_kernel_symbols_available = true; } -[[gnu::noinline]] void dump_backtrace_impl(u32 ebp, bool use_ksyms) +NEVER_INLINE void dump_backtrace_impl(u32 ebp, bool use_ksyms) { SmapDisabler disabler; #if 0 diff --git a/Kernel/Lock.h b/Kernel/Lock.h index d3337e1304..b3d589e139 100644 --- a/Kernel/Lock.h +++ b/Kernel/Lock.h @@ -77,14 +77,14 @@ private: class Locker { public: - [[gnu::always_inline]] inline explicit Locker(Lock& l, Lock::Mode mode = Lock::Mode::Exclusive) + ALWAYS_INLINE explicit Locker(Lock& l, Lock::Mode mode = Lock::Mode::Exclusive) : m_lock(l) { m_lock.lock(mode); } - [[gnu::always_inline]] inline ~Locker() { unlock(); } - [[gnu::always_inline]] inline void unlock() { m_lock.unlock(); } - [[gnu::always_inline]] inline void lock(Lock::Mode mode = Lock::Mode::Exclusive) { m_lock.lock(mode); } + ALWAYS_INLINE ~Locker() { unlock(); } + ALWAYS_INLINE void unlock() { m_lock.unlock(); } + ALWAYS_INLINE void lock(Lock::Mode mode = Lock::Mode::Exclusive) { m_lock.lock(mode); } private: Lock& m_lock; diff --git a/Libraries/LibBareMetal/IO.h b/Libraries/LibBareMetal/IO.h index 6d3eec41bd..6e30562b42 100644 --- a/Libraries/LibBareMetal/IO.h +++ b/Libraries/LibBareMetal/IO.h @@ -118,7 +118,7 @@ public: void mask(u16 m) { m_address &= m; } template - [[gnu::always_inline]] inline T in() + ALWAYS_INLINE T in() { if constexpr (sizeof(T) == 4) return IO::in32(get()); @@ -130,7 +130,7 @@ public: } template - [[gnu::always_inline]] inline void out(T value) + ALWAYS_INLINE void out(T value) { if constexpr (sizeof(T) == 4) { IO::out32(get(), value); diff --git a/Libraries/LibC/stdio.cpp b/Libraries/LibC/stdio.cpp index 8bcf059ff2..35b2c38b88 100644 --- a/Libraries/LibC/stdio.cpp +++ b/Libraries/LibC/stdio.cpp @@ -393,13 +393,13 @@ int dbgprintf(const char* fmt, ...) return ret; } -[[gnu::always_inline]] inline void stdout_putch(char*&, char ch) +ALWAYS_INLINE void stdout_putch(char*&, char ch) { putchar(ch); } static FILE* __current_stream = nullptr; -[[gnu::always_inline]] inline static void stream_putch(char*&, char ch) +ALWAYS_INLINE static void stream_putch(char*&, char ch) { fputc(ch, __current_stream); } @@ -455,7 +455,7 @@ int sprintf(char* buffer, const char* fmt, ...) } static size_t __vsnprintf_space_remaining; -[[gnu::always_inline]] inline void sized_buffer_putch(char*& bufptr, char ch) +ALWAYS_INLINE void sized_buffer_putch(char*& bufptr, char ch) { if (__vsnprintf_space_remaining) { *bufptr++ = ch; diff --git a/Libraries/LibGfx/PNGLoader.cpp b/Libraries/LibGfx/PNGLoader.cpp index a7e64b8a9b..dd22604600 100644 --- a/Libraries/LibGfx/PNGLoader.cpp +++ b/Libraries/LibGfx/PNGLoader.cpp @@ -204,7 +204,7 @@ RefPtr load_png_from_memory(const u8* data, size_t length) return bitmap; } -[[gnu::always_inline]] static inline u8 paeth_predictor(int a, int b, int c) +ALWAYS_INLINE static u8 paeth_predictor(int a, int b, int c) { int p = a + b - c; int pa = abs(p - a); @@ -231,7 +231,7 @@ union [[gnu::packed]] Pixel static_assert(sizeof(Pixel) == 4); template -[[gnu::always_inline]] static inline void unfilter_impl(Gfx::Bitmap& bitmap, int y, const void* dummy_scanline_data) +ALWAYS_INLINE static void unfilter_impl(Gfx::Bitmap& bitmap, int y, const void* dummy_scanline_data) { auto* dummy_scanline = (const Pixel*)dummy_scanline_data; if constexpr (filter_type == 0) { @@ -312,7 +312,7 @@ template } } -[[gnu::noinline]] static void unfilter(PNGLoadingContext& context) +NEVER_INLINE FLATTEN static void unfilter(PNGLoadingContext& context) { // First unpack the scanlines to RGBA: switch (context.color_type) { diff --git a/Libraries/LibGfx/Painter.cpp b/Libraries/LibGfx/Painter.cpp index b1d80ea7db..6435512404 100644 --- a/Libraries/LibGfx/Painter.cpp +++ b/Libraries/LibGfx/Painter.cpp @@ -44,18 +44,10 @@ # pragma GCC optimize("O3") #endif -#ifndef ALWAYS_INLINE -# if __has_attribute(always_inline) -# define ALWAYS_INLINE __attribute__((always_inline)) -# else -# define ALWAYS_INLINE inline -# endif -#endif - namespace Gfx { template -static ALWAYS_INLINE Color get_pixel(const Gfx::Bitmap& bitmap, int x, int y) +ALWAYS_INLINE Color get_pixel(const Gfx::Bitmap& bitmap, int x, int y) { if constexpr (format == BitmapFormat::Indexed8) return bitmap.palette_color(bitmap.bits(y)[x]); @@ -752,12 +744,12 @@ void Painter::draw_scaled_bitmap(const Rect& a_dst_rect, const Gfx::Bitmap& sour } } -[[gnu::flatten]] void Painter::draw_glyph(const Point& point, char ch, Color color) +FLATTEN void Painter::draw_glyph(const Point& point, char ch, Color color) { draw_glyph(point, ch, font(), color); } -[[gnu::flatten]] void Painter::draw_glyph(const Point& point, char ch, const Font& font, Color color) +FLATTEN void Painter::draw_glyph(const Point& point, char ch, const Font& font, Color color) { draw_bitmap(point, font.glyph_bitmap(ch), color); } @@ -936,7 +928,7 @@ void Painter::set_pixel(const Point& p, Color color) m_target->scanline(point.y())[point.x()] = color.value(); } -[[gnu::always_inline]] inline void Painter::set_pixel_with_draw_op(u32& pixel, const Color& color) +ALWAYS_INLINE void Painter::set_pixel_with_draw_op(u32& pixel, const Color& color) { if (draw_op() == DrawOp::Copy) pixel = color.value(); diff --git a/Libraries/LibThread/Lock.h b/Libraries/LibThread/Lock.h index dd3b6e55f1..def18517ab 100644 --- a/Libraries/LibThread/Lock.h +++ b/Libraries/LibThread/Lock.h @@ -50,20 +50,20 @@ private: class Locker { public: - [[gnu::always_inline]] inline explicit Locker(Lock& l) + ALWAYS_INLINE explicit Locker(Lock& l) : m_lock(l) { lock(); } - [[gnu::always_inline]] inline ~Locker() { unlock(); } - [[gnu::always_inline]] inline void unlock() { m_lock.unlock(); } - [[gnu::always_inline]] inline void lock() { m_lock.lock(); } + ALWAYS_INLINE ~Locker() { unlock(); } + ALWAYS_INLINE void unlock() { m_lock.unlock(); } + ALWAYS_INLINE void lock() { m_lock.lock(); } private: Lock& m_lock; }; -[[gnu::always_inline]] inline void Lock::lock() +ALWAYS_INLINE void Lock::lock() { int tid = gettid(); if (m_holder == tid) {