114 for (
const bNode *node :
tree.all_nodes()) {
115 const aal::RelationsInNode *node_relations =
nullptr;
116 switch (node->type_legacy) {
122 aal::RelationsInNode &relations = scope.
construct<aal::RelationsInNode>();
125 int prev_geometry_index = -1;
126 for (
const int i : node->input_sockets().index_range()) {
129 prev_geometry_index =
i;
132 if (prev_geometry_index == -1) {
136 relations.eval_relations.append({
i, prev_geometry_index});
142 int prev_geometry_index = -1;
143 for (
const int i : node->output_sockets().index_range()) {
146 prev_geometry_index =
i;
148 if (prev_geometry_index == -1) {
152 relations.available_relations.append({
i, prev_geometry_index});
156 node_relations = &relations;
161 aal::RelationsInNode &relations = scope.
construct<aal::RelationsInNode>();
162 for (
const bNodeSocket *socket : node->output_sockets()) {
164 for (
const bNodeSocket *other_output : node->output_sockets()) {
166 relations.available_relations.append({other_output->index(), socket->index()});
171 for (
const bNodeSocket *socket : node->input_sockets()) {
173 for (
const bNodeSocket *other_input : node->input_sockets()) {
175 relations.eval_relations.append({other_input->index(), socket->index()});
184 const int input_items_start = 1;
185 const int output_items_start = 1;
186 const int items_num = node->output_sockets().size() - 1 - output_items_start;
188 const int input_index = input_items_start +
i;
189 const int output_index = output_items_start +
i;
190 const bNodeSocket &input_socket = node->input_socket(input_index);
192 relations.propagate_relations.append({input_index, output_index});
195 relations.reference_relations.append({input_index, output_index});
199 node_relations = &relations;
203 static const aal::RelationsInNode reroute_relations = []() {
204 aal::RelationsInNode relations;
205 relations.propagate_relations.append({0, 0});
206 relations.reference_relations.append({0, 0});
209 node_relations = &reroute_relations;
215 if (group->runtime->reference_lifetimes_info) {
216 node_relations = &group->runtime->reference_lifetimes_info->tree_relations;
223 node_relations = node_decl->anonymous_attribute_relations();
228 relations_by_node[node->index()] = node_relations;
230 return relations_by_node;
244 for (
const int input_i : interface_inputs.
index_range()) {
253 for (
const int output_i : interface_outputs.
index_range()) {
258 r_group_output_reference_sets.
append(
263 for (
const int input_i : interface_inputs.
index_range()) {
268 for (
const bNode *node :
tree.group_input_nodes()) {
269 const bNodeSocket &socket = node->output_socket(input_i);
271 source.potential_data_origins.append(&socket);
277 for (
const bNode *node :
tree.all_nodes()) {
278 if (node->is_muted()) {
281 if (
const aal::RelationsInNode *relations = relations_by_node[node->index()]) {
282 for (
const aal::AvailableRelation &relation : relations->available_relations) {
283 const bNodeSocket &data_socket = node->output_socket(relation.geometry_output);
284 const bNodeSocket &reference_socket = node->output_socket(relation.field_output);
285 if (!reference_socket.is_available() || !reference_socket.is_available()) {
288 if (!reference_socket.is_directly_linked() || !data_socket.is_directly_linked()) {
292 reference_sets.
last().potential_data_origins.append(&data_socket);
298 for (
const bNode *node :
tree.nodes_by_type(
"NodeEvaluateClosure")) {
301 for (
const int i :
IndexRange(storage.output_items.items_num)) {
304 reference_outputs.
append(&node->output_socket(
i));
307 if (!reference_outputs.
is_empty()) {
308 for (
const int i :
IndexRange(storage.output_items.items_num)) {
312 reference_sets.
last().potential_data_origins.extend(reference_outputs);
320 return reference_sets;
329 const int old_reference_sets_count = reference_sets.
size();
331 for (
const int input_i :
IndexRange(storage.input_items.items_num)) {
332 const bNodeSocket &socket = input_node.output_socket(input_i);
338 for (
const int output_i :
IndexRange(storage.output_items.items_num)) {
339 const bNodeSocket &socket = output_node.input_socket(output_i);
341 r_output_set_sources_by_closure_zone.
add(
348 old_reference_sets_count);
349 for (
const int input_i :
IndexRange(storage.input_items.items_num)) {
350 const bNodeSocket &socket = input_node.output_socket(input_i);
353 source.potential_data_origins.append(&socket);
358 return reference_sets;
423 bool needs_extra_pass =
false;
425 for (
const bNode *node :
tree.toposort_left_to_right()) {
426 for (
const bNodeSocket *socket : node->input_sockets()) {
427 if (!socket->is_available()) {
430 const int dst_index = socket->index_in_tree();
431 for (
const bNodeLink *link : socket->directly_linked_links()) {
432 if (!link->is_used()) {
435 const int src_index = link->fromsock->index_in_tree();
436 r_potential_data_by_socket[dst_index] |= r_potential_data_by_socket[src_index];
437 r_potential_reference_by_socket[dst_index] |= r_potential_reference_by_socket[src_index];
440 if (node->is_muted()) {
441 for (
const bNodeLink &link : node->internal_links()) {
444 if (!input_socket.is_available() || !output_socket.is_available()) {
447 const int src_index = input_socket.index_in_tree();
448 const int dst_index = output_socket.index_in_tree();
449 r_potential_data_by_socket[dst_index] |= r_potential_data_by_socket[src_index];
450 r_potential_reference_by_socket[dst_index] |= r_potential_reference_by_socket[src_index];
454 if (
const aal::RelationsInNode *relations = relations_by_node[node->index()]) {
456 for (
const aal::ReferenceRelation &relation : relations->reference_relations) {
457 const bNodeSocket &from_socket = node->input_socket(relation.from_field_input);
458 const bNodeSocket &to_socket = node->output_socket(relation.to_field_output);
459 if (!from_socket.is_available() || !to_socket.is_available()) {
462 const int src_index = from_socket.index_in_tree();
463 const int dst_index = to_socket.index_in_tree();
464 r_potential_reference_by_socket[dst_index] |= r_potential_reference_by_socket[src_index];
467 for (
const aal::PropagateRelation &relation : relations->propagate_relations) {
468 const bNodeSocket &from_socket = node->input_socket(relation.from_geometry_input);
469 const bNodeSocket &to_socket = node->output_socket(relation.to_geometry_output);
470 if (!from_socket.is_available() || !to_socket.is_available()) {
473 const int src_index = from_socket.index_in_tree();
474 const int dst_index = to_socket.index_in_tree();
475 r_potential_data_by_socket[dst_index] |= r_potential_data_by_socket[src_index];
478 switch (node->type_legacy) {
487 const bNode *output_node = node;
490 const int src_index = input_node->input_socket(0).index_in_tree();
491 for (
const bNodeSocket *output_socket : output_node->output_sockets()) {
493 const int dst_index = output_socket->index_in_tree();
494 r_potential_data_by_socket[dst_index] |= r_potential_data_by_socket[src_index];
502 *zone, {&r_potential_data_by_socket, &r_potential_reference_by_socket});
503 for (
const int item_i :
IndexRange(storage->generation_items.items_num)) {
504 const int src_index =
505 node->input_socket(storage->main_items.items_num + item_i).index_in_tree();
506 const int dst_index =
507 node->output_socket(1 + storage->main_items.items_num + item_i).index_in_tree();
510 r_potential_data_by_socket[src_index]);
513 r_potential_reference_by_socket[src_index]);
525 *zone, {&r_potential_data_by_socket, &r_potential_reference_by_socket});
526 for (
const int i : node->output_sockets().index_range()) {
527 const int dst_index = input_node.output_socket(
i).index_in_tree();
528 r_potential_data_by_socket[dst_index] |= outside_references;
529 r_potential_reference_by_socket[dst_index] |= outside_references;
541 *zone, {&r_potential_reference_by_socket});
543 *zone, {&r_potential_data_by_socket});
544 const int dst_index = output_node.output_socket(0).index_in_tree();
545 for ([[maybe_unused]]
const int i : node->input_sockets().index_range()) {
546 r_potential_data_by_socket[dst_index] |= passed_in_data;
547 r_potential_reference_by_socket[dst_index] |= passed_in_references;
556 for (
const bNodeSocket *socket : node->input_sockets()) {
557 const int src_index = socket->index_in_tree();
558 potential_input_references |= r_potential_reference_by_socket[src_index];
559 potential_input_data |= r_potential_data_by_socket[src_index];
561 for (
const bNodeSocket *out_socket : node->output_sockets()) {
562 const int dst_index = out_socket->index_in_tree();
563 r_potential_reference_by_socket[dst_index] |= potential_input_references;
564 r_potential_data_by_socket[dst_index] |= potential_input_data;
575 const int items_num = output_node.output_sockets().size() - 1;
579 const int src_index = input_node.input_socket(
i + 1).index_in_tree();
580 const int dst_index = output_node.output_socket(
i).index_in_tree();
581 r_potential_data_by_socket[dst_index] |= r_potential_data_by_socket[src_index];
582 r_potential_reference_by_socket[dst_index] |= r_potential_reference_by_socket[src_index];
586 *zone, {&r_potential_data_by_socket, &r_potential_reference_by_socket});
590 const int src_index = output_node.input_socket(
i).index_in_tree();
591 const int dst_index = output_node.output_socket(
i).index_in_tree();
594 r_potential_data_by_socket[src_index]);
597 r_potential_reference_by_socket[src_index]);
603 const bNodeSocket &body_input_socket = input_node.output_socket(
i + 1);
604 const bNodeSocket &body_output_socket = output_node.input_socket(
i);
605 const int in_index = body_output_socket.index_in_tree();
606 const int out_index = body_input_socket.index_in_tree();
608 r_potential_data_by_socket[out_index],
611 r_potential_reference_by_socket[out_index],
618 return needs_extra_pass;
726 bool needs_extra_pass =
false;
728 for (
const bNode *node :
tree.toposort_right_to_left()) {
729 for (
const bNodeSocket *socket : node->output_sockets()) {
730 if (!socket->is_available()) {
733 const int dst_index = socket->index_in_tree();
734 for (
const bNodeLink *link : socket->directly_linked_links()) {
735 if (!link->is_used()) {
738 const int src_index = link->tosock->index_in_tree();
739 r_required_data_by_socket[dst_index] |= r_required_data_by_socket[src_index];
742 if (node->is_muted()) {
743 for (
const bNodeLink &link : node->internal_links()) {
746 if (!input_socket.is_available() || !output_socket.is_available()) {
749 const int dst_index = input_socket.index_in_tree();
750 const int src_index = output_socket.index_in_tree();
751 r_required_data_by_socket[dst_index] |= r_required_data_by_socket[src_index];
755 if (
const aal::RelationsInNode *relations = relations_by_node[node->index()]) {
756 for (
const aal::PropagateRelation &relation : relations->propagate_relations) {
757 const bNodeSocket &output_socket = node->output_socket(relation.to_geometry_output);
758 const bNodeSocket &input_socket = node->input_socket(relation.from_geometry_input);
759 if (!input_socket.is_available() || !output_socket.is_available()) {
762 const int dst_index = input_socket.index_in_tree();
763 const int src_index = output_socket.index_in_tree();
764 r_required_data_by_socket[dst_index] |= r_required_data_by_socket[src_index];
766 for (
const aal::EvalRelation &relation : relations->eval_relations) {
767 const bNodeSocket &data_socket = node->input_socket(relation.geometry_input);
768 const bNodeSocket &reference_socket = node->input_socket(relation.field_input);
769 if (!data_socket.is_available() || !reference_socket.is_available()) {
772 r_required_data_by_socket[data_socket.index_in_tree()] |=
773 potential_reference_by_socket[reference_socket.index_in_tree()];
777 switch (node->type_legacy) {
784 const bNode *input_node = node;
786 const int dst_index = input_node->input_socket(0).index_in_tree();
787 for (
const bNodeSocket *output_socket : output_node->output_sockets()) {
789 const int src_index = output_socket->index_in_tree();
790 r_required_data_by_socket[dst_index] |= r_required_data_by_socket[src_index];
796 const bNode *output_node = node;
800 for (
const int item_i :
IndexRange(storage->generation_items.items_num)) {
801 const int src_index =
802 node->output_socket(1 + storage->main_items.items_num + item_i).index_in_tree();
803 const int dst_index =
804 node->input_socket(storage->main_items.items_num + item_i).index_in_tree();
805 r_required_data_by_socket[dst_index] |= r_required_data_by_socket[src_index];
815 const int items_num = node->output_sockets().size() - 1;
817 const int src_index = node->output_socket(
i).index_in_tree();
818 const int dst_index = node->input_socket(
i).index_in_tree();
819 r_required_data_by_socket[dst_index] |= r_required_data_by_socket[src_index];
828 const bNode *input_node = node;
830 const int items_num = output_node->output_sockets().size() - 1;
832 const bNodeSocket &body_input_socket = input_node->output_socket(
i + 1);
833 const bNodeSocket &body_output_socket = output_node->input_socket(
i);
834 const int in_index = body_input_socket.index_in_tree();
835 const int out_index = body_output_socket.index_in_tree();
837 r_required_data_by_socket[out_index]);
843 const bNodeSocket &closure_socket = node->input_socket(0);
845 potential_reference_by_socket[closure_socket.index_in_tree()];
847 for (
const bNodeSocket *socket : node->output_sockets()) {
848 required_data_on_inputs |= r_required_data_by_socket[socket->index_in_tree()];
852 for (
const bNodeSocket *socket : node->input_sockets()) {
854 required_data_on_inputs |= potential_reference_by_socket[socket->index_in_tree()];
857 for (
const bNodeSocket *socket : node->input_sockets()) {
858 const int dst_index = socket->index_in_tree();
859 r_required_data_by_socket[dst_index] |= required_data_on_inputs;
869 const bNodeSocket &output_socket = node->output_socket(0);
871 r_required_data_by_socket[output_socket.index_in_tree()];
872 for (
const bNodeSocket *input_socket : node->input_sockets()) {
873 r_required_data_by_socket[input_socket->index_in_tree()] |= required_data;
879 return needs_extra_pass;
912 aal::RelationsInNode tree_relations;
913 const bNode *group_output_node =
tree.group_output_node();
915 for (
const int input_i :
tree.interface_inputs().index_range()) {
920 for (
const bNode *input_node :
tree.group_input_nodes()) {
922 required_data_by_socket[input_node->output_socket(input_i).index_in_tree()];
926 switch (reference_set.
type) {
928 tree_relations.propagate_relations.append_non_duplicates(
929 {input_i, reference_set.
index});
933 tree_relations.eval_relations.append_non_duplicates({reference_set.
index, input_i});
942 if (group_output_node) {
943 for (
const int output_i :
tree.interface_outputs().index_range()) {
944 const bNodeSocket &socket = group_output_node->input_socket(output_i);
948 potential_reference_by_socket[socket.index_in_tree()];
951 switch (reference_set.
type) {
953 tree_relations.reference_relations.append_non_duplicates(
954 {reference_set.
index, output_i});
964 const BoundedBitSpan potential_data = potential_data_by_socket[socket.index_in_tree()];
967 switch (reference_set.
type) {
970 group_output_node->input_sockets().drop_back(1))
976 potential_reference_by_socket[other_socket->index_in_tree()];
977 if (potential_references[reference_set_i].test()) {
978 tree_relations.available_relations.append_non_duplicates(
979 {other_socket->index(), output_i});
993 return tree_relations;
998 tree.ensure_topology_cache();
999 tree.ensure_interface_cache();
1000 if (
tree.has_available_link_cycle()) {
1004 if (zones ==
nullptr) {
1008 std::unique_ptr<ReferenceLifetimesInfo> reference_lifetimes_info =
1009 std::make_unique<ReferenceLifetimesInfo>();
1017 tree, relations_by_node, group_output_set_sources, output_set_sources_by_closure_zone);
1020 const int sockets_num =
tree.all_sockets().size();
1021 const int reference_sets_num = reference_sets.
size();
1023 BitGroupVector<> potential_data_by_socket(sockets_num, reference_sets_num,
false);
1024 BitGroupVector<> potential_reference_by_socket(sockets_num, reference_sets_num,
false);
1026 tree, reference_sets, potential_data_by_socket, potential_reference_by_socket);
1031 tree, relations_by_node, potential_data_by_socket, potential_reference_by_socket))
1035 BitGroupVector<> required_data_by_socket(sockets_num, reference_sets_num,
false);
1038 group_output_set_sources,
1039 output_set_sources_by_closure_zone,
1040 potential_data_by_socket,
1041 potential_reference_by_socket,
1042 required_data_by_socket);
1045 tree, relations_by_node, potential_reference_by_socket, required_data_by_socket))
1057 potential_reference_by_socket,
1058 required_data_by_socket}))
1065 potential_data_by_socket,
1066 potential_reference_by_socket,
1067 required_data_by_socket);
1068 reference_lifetimes_info->required_data_by_socket = std::move(required_data_by_socket);
1069 return reference_lifetimes_info;