From dc762d09141ee7b71d813f019607186385cbe82e Mon Sep 17 00:00:00 2001 From: Jacques Lucke Date: Tue, 19 Mar 2024 13:45:04 +0100 Subject: [PATCH] BLI: avoid compiling same function multiple times for trivial types For example, copying and moving a trivial type ends is the same. However, currently we generate the code for both cases independently instead of reusing the same underlying function. This reduces the size of the Blender binary from `218.548.896` to `218.355.552` bytes for me. So it's a reduction of about 200kb. It's probably possible to reduce this even more, but that's for another day. The main tricky thing here is telling the compiler that a `const` from a function parameter can be cast away for trivial types (see code comment). Maybe there is a better way to do this while making sure the compiler doesn't generate unnecessary code. Pull Request: https://projects.blender.org/blender/blender/pulls/119601 --- source/blender/blenlib/BLI_cpp_type_make.hh | 64 ++++++++++++++++----- 1 file changed, 50 insertions(+), 14 deletions(-) diff --git a/source/blender/blenlib/BLI_cpp_type_make.hh b/source/blender/blenlib/BLI_cpp_type_make.hh index 944780bd52d..b6b83e3cf7b 100644 --- a/source/blender/blenlib/BLI_cpp_type_make.hh +++ b/source/blender/blenlib/BLI_cpp_type_make.hh @@ -244,33 +244,69 @@ CPPType::CPPType(TypeTag /*type*/, copy_assign_compressed_ = copy_assign_compressed_cb; } if constexpr (std::is_copy_constructible_v) { - copy_construct_ = copy_construct_cb; - copy_construct_indices_ = copy_construct_indices_cb; - copy_construct_compressed_ = copy_construct_compressed_cb; + if constexpr (std::is_trivially_copy_constructible_v) { + copy_construct_ = copy_assign_; + copy_construct_indices_ = copy_assign_indices_; + copy_construct_compressed_ = copy_assign_compressed_; + } + else { + copy_construct_ = copy_construct_cb; + copy_construct_indices_ = copy_construct_indices_cb; + copy_construct_compressed_ = copy_construct_compressed_cb; + } } if constexpr (std::is_move_assignable_v) { - move_assign_ = move_assign_cb; - move_assign_indices_ = move_assign_indices_cb; + if constexpr (std::is_trivially_move_assignable_v) { + /* This casts away the const from the src pointer. This is fine for trivial types as moving + * them does not change the original value. */ + move_assign_ = reinterpret_cast(copy_assign_); + move_assign_indices_ = reinterpret_cast( + copy_assign_indices_); + } + else { + move_assign_ = move_assign_cb; + move_assign_indices_ = move_assign_indices_cb; + } } if constexpr (std::is_move_constructible_v) { - move_construct_ = move_construct_cb; - move_construct_indices_ = move_construct_indices_cb; + if constexpr (std::is_trivially_move_constructible_v) { + move_construct_ = move_assign_; + move_construct_indices_ = move_assign_indices_; + } + else { + move_construct_ = move_construct_cb; + move_construct_indices_ = move_construct_indices_cb; + } } if constexpr (std::is_destructible_v) { - if constexpr (std::is_move_assignable_v) { - relocate_assign_ = relocate_assign_cb; - relocate_assign_indices_ = relocate_assign_indices_cb; + if constexpr (std::is_trivially_move_assignable_v && std::is_trivially_destructible_v) { + relocate_assign_ = move_assign_; + relocate_assign_indices_ = move_assign_indices_; + + relocate_construct_ = move_assign_; + relocate_construct_indices_ = move_assign_indices_; } - if constexpr (std::is_move_constructible_v) { - relocate_construct_ = relocate_construct_cb; - relocate_construct_indices_ = relocate_construct_indices_cb; + else { + if constexpr (std::is_move_assignable_v) { + relocate_assign_ = relocate_assign_cb; + relocate_assign_indices_ = relocate_assign_indices_cb; + } + if constexpr (std::is_move_constructible_v) { + relocate_construct_ = relocate_construct_cb; + relocate_construct_indices_ = relocate_construct_indices_cb; + } } } if constexpr (std::is_copy_assignable_v) { fill_assign_indices_ = fill_assign_indices_cb; } if constexpr (std::is_copy_constructible_v) { - fill_construct_indices_ = fill_construct_indices_cb; + if constexpr (std::is_trivially_constructible_v) { + fill_construct_indices_ = fill_assign_indices_; + } + else { + fill_construct_indices_ = fill_construct_indices_cb; + } } if constexpr ((bool)(Flags & CPPTypeFlags::Hashable)) { hash_ = hash_cb;