From 8b5bb763a8bcdef028d672bfc866a3a06434bd79 Mon Sep 17 00:00:00 2001 From: SadiinsoSnowfall Date: Mon, 25 Nov 2024 15:12:28 +0100 Subject: [PATCH] mark some branches as constexpr --- include/eve/arch/cpu/top_bits.hpp | 22 ++-- include/eve/arch/riscv/rvv_utils.hpp | 8 +- .../eve/module/core/named_shuffles/blend.hpp | 68 ++++++------ .../core/named_shuffles/broadcast_lane.hpp | 60 +++++------ .../module/core/named_shuffles/reverse.hpp | 101 +++++++++--------- .../named_shuffles/reverse_in_subgroups.hpp | 47 ++++---- .../eve/module/core/named_shuffles/slide.hpp | 46 ++++---- .../core/named_shuffles/swap_adjacent.hpp | 44 ++++---- 8 files changed, 204 insertions(+), 192 deletions(-) diff --git a/include/eve/arch/cpu/top_bits.hpp b/include/eve/arch/cpu/top_bits.hpp index 6fe3743dcc..e7acd805f9 100644 --- a/include/eve/arch/cpu/top_bits.hpp +++ b/include/eve/arch/cpu/top_bits.hpp @@ -114,24 +114,24 @@ namespace detail static constexpr bool is_cheap_impl() { - if ( has_emulated_abi_v ) return true; - if constexpr ( is_aggregated ) return top_bits::is_cheap; + if constexpr ( has_emulated_abi_v ) return true; + else if constexpr ( is_aggregated ) return top_bits::is_cheap; - if ( x86_abi ) return true; - if ( ppc_abi ) return true; + else if constexpr ( x86_abi ) return true; + else if constexpr ( ppc_abi ) return true; - if ( arm_abi ) + else if constexpr ( arm_abi ) { - if ( static_size == 1 ) return true; - if ( static_size * sizeof(scalar_type) <= 4 ) return true; - if ( current_api >= eve::asimd ) + if constexpr ( static_size == 1 ) return true; + else if constexpr ( static_size * sizeof(scalar_type) <= 4 ) return true; + else if constexpr ( current_api >= eve::asimd ) { - if ( sizeof(scalar_type) >= 2 ) return true; + if constexpr ( sizeof(scalar_type) >= 2 ) return true; return static_size <= 8; // 16 chars is expensive } - return false; + else return false; } - return false; + else return false; } public: diff --git a/include/eve/arch/riscv/rvv_utils.hpp b/include/eve/arch/riscv/rvv_utils.hpp index e783ca92b8..24e191abe6 100644 --- a/include/eve/arch/riscv/rvv_utils.hpp +++ b/include/eve/arch/riscv/rvv_utils.hpp @@ -20,16 +20,16 @@ constexpr auto rvv_lmul_v = [] { constexpr std::ptrdiff_t m1_len = __riscv_v_fixed_vlen; constexpr std::ptrdiff_t min_len = m1_len * sizeof(scalar_type) / 8; - std::ptrdiff_t expected_len = sizeof(scalar_type) * 8 * cardinal::value; - std::ptrdiff_t reg_len = std::max(min_len, expected_len); - if( reg_len >= m1_len ) return static_cast(reg_len / m1_len); + constexpr std::ptrdiff_t expected_len = sizeof(scalar_type) * 8 * cardinal::value; + constexpr std::ptrdiff_t reg_len = std::max(min_len, expected_len); + if constexpr ( reg_len >= m1_len ) return static_cast(reg_len / m1_len); else return -static_cast(m1_len / reg_len); }(); template constexpr auto rvv_logical_ratio_v = [] { - auto lmul = rvv_lmul_v; + constexpr auto lmul = rvv_lmul_v; constexpr auto element_size = sizeof(scalar_type) * 8; return lmul > 0 ? element_size / lmul : element_size * (-lmul); }(); diff --git a/include/eve/module/core/named_shuffles/blend.hpp b/include/eve/module/core/named_shuffles/blend.hpp index 42ed4339c6..a7b81cd250 100644 --- a/include/eve/module/core/named_shuffles/blend.hpp +++ b/include/eve/module/core/named_shuffles/blend.hpp @@ -95,42 +95,50 @@ struct blend_t level(as {}, as {}, g, p1)); } - if( ((I == 0) && ...) ) return 0; - if( ((I == 1) && ...) ) return 0; + else if constexpr ( ((I == 0) && ...) ) return 0; + else if constexpr ( ((I == 1) && ...) ) return 0; - if( current_api >= sve ) return logical_simd_value ? 6 : 2; - if( current_api >= avx512 ) return logical_simd_value ? 6 : 2; - if( current_api >= vmx ) return 3; - - const std::ptrdiff_t g_size = sizeof(element_type_t) * G; - const std::size_t reg_size = sizeof(element_type_t) * T::size(); - const std::size_t count_from_x = ((I == 0) + ...); - const std::size_t count_from_y = ((I == 1) + ...); - - if( current_api >= neon ) + else if constexpr ( current_api >= sve ) return logical_simd_value ? 6 : 2; + else if constexpr ( current_api >= avx512 ) return logical_simd_value ? 6 : 2; + else if constexpr ( current_api >= vmx ) return 3; + else { - if( current_api >= asimd && (count_from_x == 1 || count_from_y == 1) ) return 2; - return 3; - } + constexpr std::ptrdiff_t g_size = sizeof(element_type_t) * G; + constexpr std::size_t reg_size = sizeof(element_type_t) * T::size(); + constexpr std::size_t count_from_x = ((I == 0) + ...); + constexpr std::size_t count_from_y = ((I == 1) + ...); - if( current_api >= sse2 ) - { - if constexpr( current_api == avx && reg_size >= 32 && g_size <= 2 ) + if constexpr ( current_api >= neon ) { - using half_t = decltype(T {}.slice(lower_)); - auto [p0, p1] = detail::idxm::slice_pattern::size() / 2>(p); - auto l0 = level(as {}, as {}, g, p0); - auto l1 = level(as {}, as {}, g, p1); - return detail::idxm::add_shuffle_levels(std::array {l0, l1, 4}); + if constexpr ( current_api >= asimd && (count_from_x == 1 || count_from_y == 1) ) return 2; + else return 3; + } + else if constexpr ( current_api >= sse2 ) + { + if constexpr( current_api == avx && reg_size >= 32 && g_size <= 2 ) + { + using half_t = decltype(T {}.slice(lower_)); + auto [p0, p1] = detail::idxm::slice_pattern::size() / 2>(p); + auto l0 = level(as {}, as {}, g, p0); + auto l1 = level(as {}, as {}, g, p1); + return detail::idxm::add_shuffle_levels(std::array {l0, l1, 4}); + } + else if constexpr ( current_api >= sse4_1 ) + { + return g_size >= 4 ? 2 : 3; + } + else + { + if constexpr ( g_size >= 8 ) return 2; + else if constexpr ( g_size == 2 && reg_size == 4 ) return 6; + else return 7; + } + } + else + { + return 2; } - if( current_api >= sse4_1 ) return g_size >= 4 ? 2 : 3; - - if( g_size >= 8 ) return 2; - if( g_size == 2 && reg_size == 4 ) return 6; - return 7; } - - return 2; } template diff --git a/include/eve/module/core/named_shuffles/broadcast_lane.hpp b/include/eve/module/core/named_shuffles/broadcast_lane.hpp index fbbf0b1ea2..bcdc341c7c 100644 --- a/include/eve/module/core/named_shuffles/broadcast_lane.hpp +++ b/include/eve/module/core/named_shuffles/broadcast_lane.hpp @@ -68,8 +68,8 @@ struct broadcast_lane_t template static constexpr std::ptrdiff_t level(eve::as tgt, eve::fixed g, eve::index_t i) { - const std::size_t reg_size = sizeof(element_type_t) * T::size(); - const std::ptrdiff_t g_size = sizeof(element_type_t) * G; + constexpr std::size_t reg_size = sizeof(element_type_t) * T::size(); + constexpr std::ptrdiff_t g_size = sizeof(element_type_t) * G; if constexpr( eve::has_aggregated_abi_v ) { @@ -80,47 +80,47 @@ struct broadcast_lane_t else if constexpr( current_api >= vmx ) return 2; else if constexpr( current_api >= sve ) { - if( !logical_value ) return g_size > 8 ? 3 : 2; - if( G == 1 ) return 4; - if( g_size <= 8 ) return 6; - return 7; + if constexpr ( !logical_value ) return g_size > 8 ? 3 : 2; + else if constexpr ( G == 1 ) return 4; + else if constexpr ( g_size <= 8 ) return 6; + else return 7; } else if constexpr( current_api >= neon ) { - if( current_api >= asimd ) return 2; - if( reg_size <= 8 ) return 2; - return 4; + if constexpr ( current_api >= asimd ) return 2; + else if constexpr ( reg_size <= 8 ) return 2; + else return 4; } // x86 - if (current_api == avx512 && logical_value) + if constexpr (current_api == avx512 && logical_value) { - if (G == 1) return 4; - return level(detail::mask_type(tgt), g, i) + 4; + if constexpr (G == 1) return 4; + else return level(detail::mask_type(tgt), g, i) + 4; } - - if (reg_size == 64) + else if constexpr (reg_size == 64) { - if (g_size >= 16) return 2; - if (g_size >= 2) return 3; - return 4; + if constexpr (g_size >= 16) return 2; + else if constexpr (g_size >= 2) return 3; + else return 4; } - - if (reg_size == 32) + else if constexpr (reg_size == 32) { - if (g_size >= 16) return 2; - if (current_api == avx) return 4; - if (g_size >= 8) return 2; - if (g_size >= 4) return 3; - if (g_size >= 2 && current_api == avx512) return 3; - return 4; + if constexpr (g_size >= 16) return 2; + if constexpr (current_api == avx) return 4; + if constexpr (g_size >= 8) return 2; + if constexpr (g_size >= 4) return 3; + if constexpr (g_size >= 2 && current_api == avx512) return 3; + else return 4; + } + else + { + if constexpr ( g_size >= 4 ) return 2; + else if constexpr ( g_size == 2 && reg_size <= 8 ) return 2; + else if constexpr ( current_api >= ssse3 ) return 3; + else return 4; } - - if ( g_size >= 4 ) return 2; - if ( g_size == 2 && reg_size <= 8 ) return 2; - if ( current_api >= ssse3 ) return 3; - return 4; } }; diff --git a/include/eve/module/core/named_shuffles/reverse.hpp b/include/eve/module/core/named_shuffles/reverse.hpp index 44612b86ec..ec89ef2264 100644 --- a/include/eve/module/core/named_shuffles/reverse.hpp +++ b/include/eve/module/core/named_shuffles/reverse.hpp @@ -66,68 +66,73 @@ struct reverse_t if constexpr( eve::has_aggregated_abi_v ) { if constexpr( G == T::size() / 2 ) return 0; - using half_t = decltype(T {}.slice(lower_)); - return level(as {}, g); + else + { + using half_t = decltype(T {}.slice(lower_)); + return level(as {}, g); + } } - - const std::ptrdiff_t g_size = sizeof(element_type_t) * G; - const std::size_t reg_size = sizeof(element_type_t) * T::size(); - const bool is_expected_cardinal = T::size() == eve::expected_cardinal_v>; - - if( current_api >= sve ) + else { - if( !logical_value ) + constexpr std::ptrdiff_t g_size = sizeof(element_type_t) * G; + constexpr std::size_t reg_size = sizeof(element_type_t) * T::size(); + constexpr bool is_expected_cardinal = T::size() == eve::expected_cardinal_v>; + + if constexpr ( current_api >= sve ) { - if( reg_size <= 8 ) return 2; - if( is_expected_cardinal && g_size <= 8 ) return 2; - if( is_expected_cardinal && g_size == reg_size / 2 ) return 2; - return 3; + if constexpr ( !logical_value ) + { + if constexpr ( reg_size <= 8 ) return 2; + else if constexpr ( is_expected_cardinal && g_size <= 8 ) return 2; + else if constexpr ( is_expected_cardinal && g_size == reg_size / 2 ) return 2; + else return 3; + } + else if constexpr ( is_expected_cardinal && g_size <= 8 ) return 2; + else return level(detail::mask_type(tgt), g) + 4; } - if( is_expected_cardinal && g_size <= 8 ) return 2; - return level(detail::mask_type(tgt), g) + 4; - } - if (current_api >= neon) { - if ( reg_size <= 8 ) return 2; - if ( g_size == 8 ) return 2; - if ( current_api >= asimd ) return 3; - return 4; - } + else if constexpr (current_api >= neon) { + if constexpr ( reg_size <= 8 ) return 2; + if constexpr ( g_size == 8 ) return 2; + if constexpr ( current_api >= asimd ) return 3; + else return 4; + } - if( current_api >= vmx ) return 3; + else if constexpr ( current_api >= vmx ) return 3; - if( current_api == avx512 && logical_value ) { return level(detail::mask_type(tgt), g) + 4; } + else if constexpr ( current_api == avx512 && logical_value ) { return level(detail::mask_type(tgt), g) + 4; } - if( current_api >= avx2 && reg_size >= 32 ) - { - if( g_size >= 16 ) return 2; - if( g_size >= 8 ) return reg_size == 64 ? 3 : 2; - if( g_size >= 4 ) return 3; - if( g_size == 2 && current_api >= avx512 ) return 3; - return 5; - } + else if constexpr ( current_api >= avx2 && reg_size >= 32 ) + { + if constexpr ( g_size >= 16 ) return 2; + else if constexpr ( g_size >= 8 ) return reg_size == 64 ? 3 : 2; + else if constexpr ( g_size >= 4 ) return 3; + else if constexpr ( g_size == 2 && current_api >= avx512 ) return 3; + else return 5; + } - if( current_api == avx && reg_size >= 32 ) - { - if( g_size >= 16 ) return 2; - if( g_size >= 4 ) return 4; - if( g_size == 2 && current_api >= avx512 ) return 3; - return 9; - } + else if constexpr ( current_api == avx && reg_size >= 32 ) + { + if constexpr ( g_size >= 16 ) return 2; + else if constexpr ( g_size >= 4 ) return 4; + else if constexpr ( g_size == 2 && current_api >= avx512 ) return 3; + else return 9; + } - if( g_size >= 4 ) return 2; - if( g_size == 2 && reg_size <= 8 ) return 2; + else if constexpr ( g_size >= 4 ) return 2; + else if constexpr ( g_size == 2 && reg_size <= 8 ) return 2; - if( current_api >= ssse3 ) return 3; + else if constexpr ( current_api >= ssse3 ) return 3; - if( g_size == 2 ) return 6; + else if constexpr ( g_size == 2 ) return 6; - // chars on sse2 - if( reg_size == 2 ) return 6; + // chars on sse2 + else if constexpr ( reg_size == 2 ) return 6; - // swap chars + reverse shorts - if( reg_size <= 8 ) return 8; - return 12; + // swap chars + reverse shorts + else if constexpr ( reg_size <= 8 ) return 8; + else return 12; + } } }; diff --git a/include/eve/module/core/named_shuffles/reverse_in_subgroups.hpp b/include/eve/module/core/named_shuffles/reverse_in_subgroups.hpp index e1cfcc91f8..856d664892 100644 --- a/include/eve/module/core/named_shuffles/reverse_in_subgroups.hpp +++ b/include/eve/module/core/named_shuffles/reverse_in_subgroups.hpp @@ -79,9 +79,9 @@ struct reverse_in_subgroups_t template static constexpr std::ptrdiff_t level(eve::as tgt, eve::fixed g, eve::fixed sub_g) { - const std::ptrdiff_t g_size = sizeof(element_type_t) * G; - const std::size_t sub_size = g_size * SubG; - const std::size_t reg_size = sizeof(element_type_t) * T::size(); + constexpr std::ptrdiff_t g_size = sizeof(element_type_t) * G; + constexpr std::size_t sub_size = g_size * SubG; + constexpr std::size_t reg_size = sizeof(element_type_t) * T::size(); if constexpr( SubG == 1 ) return 0; else if constexpr( SubG == 2 ) return swap_adjacent.level(tgt, g); @@ -93,40 +93,37 @@ struct reverse_in_subgroups_t return level(as {}, g, sub_g); } - if( current_api >= sve ) + else if constexpr ( current_api >= sve ) { - if( !logical_value ) + if constexpr ( !logical_value ) { - if( sub_size <= 8 ) return 2; - return 3; + if constexpr ( sub_size <= 8 ) return 2; + else return 3; } - return level(detail::mask_type(tgt), g, sub_g) + 4; + else return level(detail::mask_type(tgt), g, sub_g) + 4; } - if( current_api >= vmx ) return 3; - if( current_api >= neon ) return 2; + else if constexpr ( current_api >= vmx ) return 3; + else if constexpr ( current_api >= neon ) return 2; - if( current_api == avx512 && logical_value ) + else if constexpr ( current_api == avx512 && logical_value ) { return level(detail::mask_type(tgt), g, sub_g) + 4; } - if (sub_size == 32) { - if (g_size == 8) return 2; - if (g_size == 4) return 3; - if (g_size == 2 && current_api >= avx512) return 3; - return 5; + else if constexpr (sub_size == 32) { + if constexpr (g_size == 8) return 2; + else if constexpr (g_size == 4) return 3; + else if constexpr (g_size == 2 && current_api >= avx512) return 3; + else return 5; } - if( g_size >= 4 ) return 2; - - if (current_api == avx && reg_size == 32) return 9; - - if( current_api >= ssse3 ) return 3; - - if( g_size == 2 ) return 4; - if (reg_size <= 8) return 8; - return 10; + else if constexpr ( g_size >= 4 ) return 2; + else if constexpr (current_api == avx && reg_size == 32) return 9; + else if constexpr ( current_api >= ssse3 ) return 3; + else if constexpr ( g_size == 2 ) return 4; + else if constexpr (reg_size <= 8) return 8; + else return 10; } }; diff --git a/include/eve/module/core/named_shuffles/slide.hpp b/include/eve/module/core/named_shuffles/slide.hpp index 8ff91303ee..44e6f9550e 100644 --- a/include/eve/module/core/named_shuffles/slide.hpp +++ b/include/eve/module/core/named_shuffles/slide.hpp @@ -78,7 +78,7 @@ struct slide_left_impl_t static constexpr std::ptrdiff_t level(eve::as tgt, eve::fixed g, eve::index_t s) { using abi_t = typename T::abi_type; - const std::size_t reg_size = sizeof(element_type_t) * T::size(); + constexpr std::size_t reg_size = sizeof(element_type_t) * T::size(); constexpr std::ptrdiff_t S = G * S_; constexpr bool is_shift_by_16 = (S * sizeof(element_type_t) % 16) == 0; constexpr bool is_shift_by_4 = (S * sizeof(element_type_t) % 4) == 0; @@ -110,22 +110,23 @@ struct slide_left_impl_t } else if constexpr( current_api >= neon || current_api >= sve ) { - if( reg_size <= 8 ) return 2; - return 3; + if constexpr ( reg_size <= 8 ) return 2; + else return 3; } else { - if( reg_size <= 8 ) return 2; - if( current_api >= avx512 ) + if constexpr ( reg_size <= 8 ) return 2; + else if constexpr ( current_api >= avx512 ) { - if( is_shift_by_4 ) return 2; - if( reg_size <= 16 ) return 2; - if( is_shift_by_2 ) return 3; - if (reg_size == 64) return 5; // this is not yet done + if constexpr ( is_shift_by_4 ) return 2; + else if constexpr ( reg_size <= 16 ) return 2; + else if constexpr ( is_shift_by_2 ) return 3; + else if constexpr (reg_size == 64) return 5; // this is not yet done } - if( reg_size == 32 && is_shift_by_16 ) return 2; - if( current_api >= avx2 && reg_size == 32 ) { return 4; } - return 2; + + if constexpr ( reg_size == 32 && is_shift_by_16 ) return 2; + else if constexpr ( current_api >= avx2 && reg_size == 32 ) return 4; + else return 2; } } @@ -137,7 +138,7 @@ struct slide_left_impl_t { using abi_t = typename T::abi_type; constexpr std::ptrdiff_t S = S_ * G; - const std::size_t reg_size = sizeof(element_type_t) * T::size(); + constexpr std::size_t reg_size = sizeof(element_type_t) * T::size(); constexpr bool is_shift_by_16 = (S * sizeof(element_type_t) % 16) == 0; constexpr bool is_shift_by_8 = (S * sizeof(element_type_t) % 8) == 0; @@ -145,23 +146,24 @@ struct slide_left_impl_t constexpr bool is_shift_by_2 = (S * sizeof(element_type_t) % 2) == 0; if constexpr( S == 0 || S == T::size() ) return 0; - if constexpr( logical_simd_value && !abi_t::is_wide_logical ) + else if constexpr( logical_simd_value && !abi_t::is_wide_logical ) { auto mask = detail::mask_type(tgt); return level(mask, mask, g, s) + 6; } - if constexpr( current_api >= neon || current_api >= sve ) return 2; - if( current_api >= avx512 ) + else if constexpr( current_api >= neon || current_api >= sve ) return 2; + else if constexpr ( current_api >= avx512 ) { - if( is_shift_by_4 ) return 2; - if( is_shift_by_2 ) return 3; + if constexpr ( is_shift_by_4 ) return 2; + else if constexpr ( is_shift_by_2 ) return 3; } - if( is_shift_by_16 && reg_size == 32 ) return 2; - if( current_api >= avx2 && reg_size == 32 ) return 4; - if( current_api >= sse4_2 ) return 2; + if constexpr ( is_shift_by_16 && reg_size == 32 ) return 2; + else if constexpr ( current_api >= avx2 && reg_size == 32 ) return 4; + + else if constexpr ( current_api >= sse4_2 ) return 2; // sse2 - return is_shift_by_8 ? 2 : 6; + else return is_shift_by_8 ? 2 : 6; } }; diff --git a/include/eve/module/core/named_shuffles/swap_adjacent.hpp b/include/eve/module/core/named_shuffles/swap_adjacent.hpp index 16ef7ae98c..0f3ae72b46 100644 --- a/include/eve/module/core/named_shuffles/swap_adjacent.hpp +++ b/include/eve/module/core/named_shuffles/swap_adjacent.hpp @@ -67,50 +67,50 @@ struct swap_adjacent_t template static constexpr std::ptrdiff_t level(eve::as tgt, eve::fixed g) { - const std::ptrdiff_t g_size = sizeof(element_type_t) * G; - const std::size_t reg_size = sizeof(element_type_t) * T::size(); - const std::size_t fund_size = eve::fundamental_cardinal_v; + constexpr std::ptrdiff_t g_size = sizeof(element_type_t) * G; + constexpr std::size_t reg_size = sizeof(element_type_t) * T::size(); + constexpr std::size_t fund_size = eve::fundamental_cardinal_v; - if( current_api >= sve ) + if constexpr ( current_api >= sve ) { - if( arithmetic_simd_value ) + if constexpr( arithmetic_simd_value ) { - if (g_size <= 4 || g_size == fund_size / 2) return 2; - return 3; + if constexpr (g_size <= 4 || g_size == fund_size / 2) return 2; + else return 3; } else { - if( g_size == 8 && fund_size == 16 ) return 2; - return level(detail::mask_type(tgt), g) + 4; + if constexpr ( g_size == 8 && fund_size == 16 ) return 2; + else return level(detail::mask_type(tgt), g) + 4; } } - if( current_api >= vmx ) return 3; - if( current_api >= neon ) return 2; + else if constexpr ( current_api >= vmx ) return 3; + else if constexpr ( current_api >= neon ) return 2; - if( eve::current_api == avx512 && logical_simd_value ) + else if constexpr ( current_api == avx512 && logical_simd_value ) { return level(detail::mask_type(tgt), g) + 4; } - if constexpr( current_api == avx && reg_size >= 32 && g_size <= 2 ) + else if constexpr( current_api == avx && reg_size >= 32 && g_size <= 2 ) { using half_t = decltype(T {}.slice(lower_)); std::ptrdiff_t half_l = level(eve::as {}, g); // since we are adding, we need to deal with aggregation - if( reg_size > 32 ) return half_l; - return detail::idxm::add_shuffle_levels({half_l, half_l, 4}); + if constexpr ( reg_size > 32 ) return half_l; + else return detail::idxm::add_shuffle_levels({half_l, half_l, 4}); } - if( current_api >= sse2 ) + if constexpr ( current_api >= sse2 ) { - if( g_size >= 4 ) return 2; - if( g_size == 2 && reg_size <= 8 ) return 2; - if( current_api >= ssse3 ) return 3; - if( g_size == 2 ) return 4; - return 6; + if constexpr ( g_size >= 4 ) return 2; + else if constexpr ( g_size == 2 && reg_size <= 8 ) return 2; + else if constexpr ( current_api >= ssse3 ) return 3; + else if constexpr ( g_size == 2 ) return 4; + else return 6; } - return 2; + else return 2; } };