Welcome to mirror list, hosted at ThFree Co, Russian Federation.

git.blender.org/blender.git - Unnamed repository; edit this file 'description' to name the repository.
summaryrefslogtreecommitdiff
diff options
context:
space:
mode:
authorJacques Lucke <jacques@blender.org>2022-04-26 18:40:53 +0300
committerJacques Lucke <jacques@blender.org>2022-04-26 18:41:16 +0300
commitd8ef52ca47e0cf65f7dbcf4dd111ee840d0fcb06 (patch)
tree1b66a93c563ddeaeab27e88fca8442e8d6c10375
parent3e7ee3f3bcd61a1fb1395683ba7ecc430c9932db (diff)
Fix: some multi-functions are executed more than once
The good thing is that this fix also makes function evaluation a bit faster.
-rw-r--r--source/blender/blenlib/BLI_devirtualize_parameters.hh47
1 files changed, 32 insertions, 15 deletions
diff --git a/source/blender/blenlib/BLI_devirtualize_parameters.hh b/source/blender/blenlib/BLI_devirtualize_parameters.hh
index bf4f6c47cfe..ca11ec2e579 100644
--- a/source/blender/blenlib/BLI_devirtualize_parameters.hh
+++ b/source/blender/blenlib/BLI_devirtualize_parameters.hh
@@ -107,8 +107,8 @@ template<typename Fn, typename... SourceTypes> class Devirtualizer {
{
BLI_assert(!executed_);
static_assert(sizeof...(AllowedModes) == SourceTypesNum);
- return this->try_execute_devirtualized_impl(DeviModeSequence<>(),
- DeviModeSequence<AllowedModes...>());
+ this->try_execute_devirtualized_impl(DeviModeSequence<>(),
+ DeviModeSequence<AllowedModes...>());
}
/**
@@ -131,9 +131,11 @@ template<typename Fn, typename... SourceTypes> class Devirtualizer {
* At every recursive step, the #DeviMode of one parameter is determined. This is achieved by
* extending #DeviModeSequence<Mode...> by one element in each step. The recursion ends once all
* parameters are handled.
+ *
+ * \return True when the function has been executed.
*/
template<DeviMode... Mode, DeviMode... AllowedModes>
- void try_execute_devirtualized_impl(
+ bool try_execute_devirtualized_impl(
/* Initially empty, but then extended by one element in each recursive step. */
DeviModeSequence<Mode...> /* modes */,
/* Bit flag for every parameter. */
@@ -144,6 +146,7 @@ template<typename Fn, typename... SourceTypes> class Devirtualizer {
/* End of recursion, now call the function with the determined #DeviModes. */
this->try_execute_devirtualized_impl_call(DeviModeSequence<Mode...>(),
std::make_index_sequence<SourceTypesNum>());
+ return true;
}
else {
/* Index of the parameter that is checked in the current recursive step. */
@@ -160,21 +163,27 @@ template<typename Fn, typename... SourceTypes> class Devirtualizer {
/* Check if the virtual array is a single value. */
if constexpr ((allowed_modes & DeviMode::Single) != DeviMode::None) {
if (varray.is_single()) {
- this->try_execute_devirtualized_impl(DeviModeSequence<Mode..., DeviMode::Single>(),
- DeviModeSequence<AllowedModes...>());
+ if (this->try_execute_devirtualized_impl(DeviModeSequence<Mode..., DeviMode::Single>(),
+ DeviModeSequence<AllowedModes...>())) {
+ return true;
+ }
}
}
/* Check if the virtual array is a span. */
if constexpr ((allowed_modes & DeviMode::Span) != DeviMode::None) {
if (varray.is_span()) {
- this->try_execute_devirtualized_impl(DeviModeSequence<Mode..., DeviMode::Span>(),
- DeviModeSequence<AllowedModes...>());
+ if (this->try_execute_devirtualized_impl(DeviModeSequence<Mode..., DeviMode::Span>(),
+ DeviModeSequence<AllowedModes...>())) {
+ return true;
+ }
}
}
/* Check if it is ok if the virtual array is not devirtualized. */
if constexpr ((allowed_modes & DeviMode::Keep) != DeviMode::None) {
- this->try_execute_devirtualized_impl(DeviModeSequence<Mode..., DeviMode::Keep>(),
- DeviModeSequence<AllowedModes...>());
+ if (this->try_execute_devirtualized_impl(DeviModeSequence<Mode..., DeviMode::Keep>(),
+ DeviModeSequence<AllowedModes...>())) {
+ return true;
+ }
}
}
@@ -185,23 +194,30 @@ template<typename Fn, typename... SourceTypes> class Devirtualizer {
/* The actual mask used for dynamic dispatch at run-time. */
const IndexMask &mask = *std::get<I>(sources_);
if (mask.is_range()) {
- this->try_execute_devirtualized_impl(DeviModeSequence<Mode..., DeviMode::Range>(),
- DeviModeSequence<AllowedModes...>());
+ if (this->try_execute_devirtualized_impl(DeviModeSequence<Mode..., DeviMode::Range>(),
+ DeviModeSequence<AllowedModes...>())) {
+ return true;
+ }
}
}
/* Check if mask is also allowed to stay a span. */
if constexpr ((allowed_modes & DeviMode::Span) != DeviMode::None) {
- this->try_execute_devirtualized_impl(DeviModeSequence<Mode..., DeviMode::Span>(),
- DeviModeSequence<AllowedModes...>());
+ if (this->try_execute_devirtualized_impl(DeviModeSequence<Mode..., DeviMode::Span>(),
+ DeviModeSequence<AllowedModes...>())) {
+ return true;
+ }
}
}
/* Handle unknown types. */
else {
- this->try_execute_devirtualized_impl(DeviModeSequence<Mode..., DeviMode::Keep>(),
- DeviModeSequence<AllowedModes...>());
+ if (this->try_execute_devirtualized_impl(DeviModeSequence<Mode..., DeviMode::Keep>(),
+ DeviModeSequence<AllowedModes...>())) {
+ return true;
+ }
}
}
+ return false;
}
/**
@@ -212,6 +228,7 @@ template<typename Fn, typename... SourceTypes> class Devirtualizer {
std::index_sequence<I...> /* indices */)
{
+ BLI_assert(!executed_);
fn_(this->get_devirtualized_parameter<I, Mode>()...);
executed_ = true;
}