From 5dc7f870f05e718a07bc935b891884eba0749395 Mon Sep 17 00:00:00 2001 From: Anton Korobeynikov Date: Fri, 13 Dec 2024 08:09:09 -0800 Subject: [PATCH] Mark RTTI methods as const / pure, so compiler could optimize subsequent calls, if necessary. (#5049) * Mark RTTI methods as const / pure, so compiler could optimize subsequent calls, if necessary. Signed-off-by: Anton Korobeynikov * Add some explanation to RTTI boilerplate Signed-off-by: Anton Korobeynikov --------- Signed-off-by: Anton Korobeynikov --- lib/rtti.h | 32 ++++++++++++++++++++------------ 1 file changed, 20 insertions(+), 12 deletions(-) diff --git a/lib/rtti.h b/lib/rtti.h index 223118da9d9..bccd8a142e5 100644 --- a/lib/rtti.h +++ b/lib/rtti.h @@ -296,18 +296,26 @@ struct Base { }; \ DECLARE_TYPEINFO_COMMON(T, ##__VA_ARGS__) -#define DECLARE_TYPEINFO_COMMON(T, ...) \ - public: \ - static constexpr T *rttiEnabledMarker(T *); \ - using TypeInfo = P4::RTTI::TypeInfo; \ - [[nodiscard]] P4::RTTI::TypeId typeId() const noexcept override { return TypeInfo::id(); } \ - [[nodiscard]] bool isA(P4::RTTI::TypeId typeId) const noexcept override { \ - return TypeInfo::isA(typeId); \ - } \ - \ - protected: \ - [[nodiscard]] const void *toImpl(P4::RTTI::TypeId typeId) const noexcept override { \ - return TypeInfo::isA(typeId) ? TypeInfo::dyn_cast(typeId, this) : nullptr; \ +// Common typeinfo boilerplate methods. Note that they are marked pure / const, so consecutive +// calls to is<> / to<> on the same pointer could be eliminated by a compiler. +// - typeId() / isA are const as they do not access any global state, they +// always return the same value (for same input arguments) +// - toImpl() is pure. It only access global state via its arguments (this pointer). So for +// the same `this` the result is also the same. +#define DECLARE_TYPEINFO_COMMON(T, ...) \ + public: \ + static constexpr T *rttiEnabledMarker(T *); \ + using TypeInfo = P4::RTTI::TypeInfo; \ + [[nodiscard, gnu::const]] P4::RTTI::TypeId typeId() const noexcept override { \ + return TypeInfo::id(); \ + } \ + [[nodiscard, gnu::const]] bool isA(P4::RTTI::TypeId typeId) const noexcept override { \ + return TypeInfo::isA(typeId); \ + } \ + \ + protected: \ + [[nodiscard, gnu::pure]] const void *toImpl(P4::RTTI::TypeId typeId) const noexcept override { \ + return TypeInfo::isA(typeId) ? TypeInfo::dyn_cast(typeId, this) : nullptr; \ } #endif /* LIB_RTTI_H_ */