Functions: simplify multi-function signature type

* `depends_on_context` was not used for a long time already.
* `param_data_indices` is not used since rB42b88c008861b6.
* The remaining data is moved to a single `Vector` to avoid
  having to do two allocations when the size signature becomes
  larger than fits into the inline buffer.
This commit is contained in:
Jacques Lucke 2023-01-07 16:51:26 +01:00
parent 577442a26f
commit a5b27f9858
5 changed files with 27 additions and 46 deletions

View File

@ -67,22 +67,22 @@ class MultiFunction {
int param_amount() const
{
return signature_ref_->param_types.size();
return signature_ref_->params.size();
}
IndexRange param_indices() const
{
return signature_ref_->param_types.index_range();
return signature_ref_->params.index_range();
}
MFParamType param_type(int param_index) const
{
return signature_ref_->param_types[param_index];
return signature_ref_->params[param_index].type;
}
StringRefNull param_name(int param_index) const
{
return signature_ref_->param_names[param_index];
return signature_ref_->params[param_index].name;
}
StringRefNull name() const
@ -92,11 +92,6 @@ class MultiFunction {
virtual std::string debug_name() const;
bool depends_on_context() const
{
return signature_ref_->depends_on_context;
}
const MFSignature &signature() const
{
BLI_assert(signature_ref_ != nullptr);

View File

@ -40,7 +40,7 @@ class MFParamsBuilder {
MFParamsBuilder(const MFSignature &signature, const IndexMask mask)
: signature_(&signature), mask_(mask), min_array_size_(mask.min_array_size())
{
actual_params_.reserve(signature.param_types.size());
actual_params_.reserve(signature.params.size());
}
public:
@ -124,7 +124,7 @@ class MFParamsBuilder {
{
this->assert_current_param_name(expected_name);
const int param_index = this->current_param_index();
const MFParamType &param_type = signature_->param_types[param_index];
const MFParamType &param_type = signature_->params[param_index].type;
BLI_assert(param_type.category() == MFParamCategory::SingleOutput);
const CPPType &type = param_type.data_type().single_type();
/* An empty span indicates that this is ignored. */
@ -157,7 +157,7 @@ class MFParamsBuilder {
GMutableSpan computed_array(int param_index)
{
BLI_assert(ELEM(signature_->param_types[param_index].category(),
BLI_assert(ELEM(signature_->params[param_index].type.category(),
MFParamCategory::SingleOutput,
MFParamCategory::SingleMutable));
return *std::get_if<GMutableSpan>(&actual_params_[param_index]);
@ -165,7 +165,7 @@ class MFParamsBuilder {
GVectorArray &computed_vector_array(int param_index)
{
BLI_assert(ELEM(signature_->param_types[param_index].category(),
BLI_assert(ELEM(signature_->params[param_index].type.category(),
MFParamCategory::VectorOutput,
MFParamCategory::VectorMutable));
return **std::get_if<GVectorArray *>(&actual_params_[param_index]);
@ -184,11 +184,11 @@ class MFParamsBuilder {
int param_index = this->current_param_index();
if (expected_name != "") {
StringRef actual_name = signature_->param_names[param_index];
StringRef actual_name = signature_->params[param_index].name;
BLI_assert(actual_name == expected_name);
}
MFParamType expected_type = signature_->param_types[param_index];
MFParamType expected_type = signature_->params[param_index].type;
BLI_assert(expected_type == param_type);
#endif
}
@ -201,7 +201,7 @@ class MFParamsBuilder {
return;
}
const int param_index = this->current_param_index();
StringRef actual_name = signature_->param_names[param_index];
StringRef actual_name = signature_->params[param_index].name;
BLI_assert(actual_name == expected_name);
#endif
}
@ -325,9 +325,9 @@ class MFParams {
{
UNUSED_VARS_NDEBUG(param_index, name, param_type);
#ifdef DEBUG
BLI_assert(builder_->signature_->param_types[param_index] == param_type);
BLI_assert(builder_->signature_->params[param_index].type == param_type);
if (name.size() > 0) {
BLI_assert(builder_->signature_->param_names[param_index] == name);
BLI_assert(builder_->signature_->params[param_index].name == name);
}
#endif
}
@ -336,9 +336,9 @@ class MFParams {
{
UNUSED_VARS_NDEBUG(param_index, name, category);
#ifdef DEBUG
BLI_assert(builder_->signature_->param_types[param_index].category() == category);
BLI_assert(builder_->signature_->params[param_index].type.category() == category);
if (name.size() > 0) {
BLI_assert(builder_->signature_->param_names[param_index] == name);
BLI_assert(builder_->signature_->params[param_index].name == name);
}
#endif
}

View File

@ -16,6 +16,11 @@
namespace blender::fn {
struct MFSignature {
struct ParamInfo {
MFParamType type;
const char *name;
};
/**
* The name should be statically allocated so that it lives longer than this signature. This is
* used instead of an #std::string because of the overhead when many functions are created.
@ -24,10 +29,7 @@ struct MFSignature {
* actually needed.
*/
const char *function_name;
Vector<const char *> param_names;
Vector<MFParamType> param_types;
Vector<int> param_data_indices;
bool depends_on_context = false;
Vector<ParamInfo> params;
};
class MFSignatureBuilder {
@ -61,8 +63,7 @@ class MFSignatureBuilder {
}
void input(const char *name, MFDataType data_type)
{
signature_.param_names.append(name);
signature_.param_types.append(MFParamType(MFParamType::Input, data_type));
signature_.params.append({MFParamType(MFParamType::Input, data_type), name});
}
/* Output Parameter Types */
@ -85,8 +86,7 @@ class MFSignatureBuilder {
}
void output(const char *name, MFDataType data_type)
{
signature_.param_names.append(name);
signature_.param_types.append(MFParamType(MFParamType::Output, data_type));
signature_.params.append({MFParamType(MFParamType::Output, data_type), name});
}
/* Mutable Parameter Types */
@ -109,8 +109,7 @@ class MFSignatureBuilder {
}
void mutable_(const char *name, MFDataType data_type)
{
signature_.param_names.append(name);
signature_.param_types.append(MFParamType(MFParamType::Mutable, data_type));
signature_.params.append({MFParamType(MFParamType::Mutable, data_type), name});
}
void add(const char *name, const MFParamType &param_type)
@ -153,15 +152,6 @@ class MFSignatureBuilder {
}
BLI_assert_unreachable();
}
/* Context */
/** This indicates that the function accesses the context. This disables optimizations that
* depend on the fact that the function always performers the same operation. */
void depends_on_context()
{
signature_.depends_on_context = true;
}
};
} // namespace blender::fn

View File

@ -26,7 +26,7 @@ CustomMF_GenericConstant::CustomMF_GenericConstant(const CPPType &type,
CustomMF_GenericConstant::~CustomMF_GenericConstant()
{
if (owns_value_) {
signature_.param_types[0].data_type().single_type().destruct(const_cast<void *>(value_));
signature_.params[0].type.data_type().single_type().destruct(const_cast<void *>(value_));
MEM_freeN(const_cast<void *>(value_));
}
}

View File

@ -974,14 +974,10 @@ class VariableStates {
}
};
static bool evaluate_as_one(const MultiFunction &fn,
Span<VariableState *> param_variable_states,
static bool evaluate_as_one(Span<VariableState *> param_variable_states,
const IndexMask &mask,
const IndexMask &full_mask)
{
if (fn.depends_on_context()) {
return false;
}
if (mask.size() < full_mask.size()) {
return false;
}
@ -1059,7 +1055,7 @@ static void execute_call_instruction(const MFCallInstruction &instruction,
/* If all inputs to the function are constant, it's enough to call the function only once instead
* of for every index. */
if (evaluate_as_one(fn, param_variable_states, mask, variable_states.full_mask())) {
if (evaluate_as_one(param_variable_states, mask, variable_states.full_mask())) {
MFParamsBuilder params(fn, 1);
fill_params__one(fn, mask, params, variable_states, param_variable_states);