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:
Diffstat (limited to 'source/blender/functions/intern/multi_function_procedure_optimization.cc')
-rw-r--r--source/blender/functions/intern/multi_function_procedure_optimization.cc63
1 files changed, 29 insertions, 34 deletions
diff --git a/source/blender/functions/intern/multi_function_procedure_optimization.cc b/source/blender/functions/intern/multi_function_procedure_optimization.cc
index 8321dc7d405..728a1aead39 100644
--- a/source/blender/functions/intern/multi_function_procedure_optimization.cc
+++ b/source/blender/functions/intern/multi_function_procedure_optimization.cc
@@ -18,6 +18,20 @@
namespace blender::fn::procedure_optimization {
+static bool uses_variable(const MFInstruction &instr, const MFVariable &variable)
+{
+ switch (instr.type()) {
+ case MFInstructionType::Branch:
+ return static_cast<const MFBranchInstruction &>(instr).condition() == &variable;
+ case MFInstructionType::Call:
+ return static_cast<const MFCallInstruction &>(instr).params().contains(&variable);
+ case MFInstructionType::Destruct:
+ return static_cast<const MFDestructInstruction &>(instr).variable() == &variable;
+ default:
+ return false;
+ }
+}
+
void move_destructs_up(MFProcedure &procedure)
{
for (MFDestructInstruction *destruct_instr : procedure.destruct_instructions()) {
@@ -25,46 +39,27 @@ void move_destructs_up(MFProcedure &procedure)
if (variable == nullptr) {
continue;
}
- if (variable->users().size() != 3) {
- /* Only support the simple case with two uses of the variable for now. */
- continue;
- }
- /* TODO: This is not working yet. */
- MFCallInstruction *last_call_instr = nullptr;
- for (MFInstruction *instr : variable->users()) {
- if (instr->type() == MFInstructionType::Call) {
- MFCallInstruction *call_instr = static_cast<MFCallInstruction *>(instr);
- const int first_param_index = call_instr->params().first_index_try(variable);
- if (call_instr->fn().param_type(first_param_index).interface_type() ==
- MFParamType::Output) {
- last_call_instr = call_instr;
- }
+ MFInstruction *last_use_in_block_instr = nullptr;
+ MFInstruction *current_instr = destruct_instr;
+ while (current_instr->prev().size() == 1) {
+ current_instr = current_instr->prev()[0].instruction();
+ if (current_instr == nullptr) {
+ break;
+ }
+ if (uses_variable(*current_instr, *variable)) {
+ last_use_in_block_instr = current_instr;
break;
}
}
- if (last_call_instr == nullptr) {
- continue;
- }
- MFInstruction *after_last_call_instr = last_call_instr->next();
- if (after_last_call_instr == destruct_instr) {
- continue;
- }
- if (destruct_instr->prev().size() != 1) {
+ if (last_use_in_block_instr == nullptr) {
continue;
}
- MFInstruction *before_destruct_instr = destruct_instr->prev()[0];
- MFInstruction *after_destruct_instr = destruct_instr->next();
- if (before_destruct_instr->type() == MFInstructionType::Call) {
- static_cast<MFCallInstruction *>(before_destruct_instr)->set_next(after_destruct_instr);
- }
- else if (before_destruct_instr->type() == MFInstructionType::Destruct) {
- static_cast<MFDestructInstruction *>(before_destruct_instr)->set_next(after_destruct_instr);
- }
- else {
- continue;
+ if (last_use_in_block_instr->type() == MFInstructionType::Call) {
+ MFCallInstruction &call_instr = static_cast<MFCallInstruction &>(*last_use_in_block_instr);
+ destruct_instr->prev()[0].set_next(procedure, destruct_instr->next());
+ destruct_instr->set_next(call_instr.next());
+ call_instr.set_next(destruct_instr);
}
- last_call_instr->set_next(destruct_instr);
- destruct_instr->set_next(after_last_call_instr);
}
}