in src/compiler/ast/fold_code.cc [24:79]
bool fold_code(ASTNode* node, CodeFoldingContext* context,
ASTBuilder* builder) {
if (node->node_id == 0) {
if (node->data_count) {
context->log_root_data_count = std::log(node->data_count.value());
} else {
context->log_root_data_count = std::numeric_limits<double>::quiet_NaN();
}
if (node->sum_hess) {
context->log_root_sum_hess = std::log(node->sum_hess.value());
} else {
context->log_root_sum_hess = std::numeric_limits<double>::quiet_NaN();
}
}
if ( (node->data_count && !std::isnan(context->log_root_data_count)
&& context->log_root_data_count - std::log(node->data_count.value())
>= context->magnitude_req)
|| (node->sum_hess && !std::isnan(context->log_root_sum_hess)
&& context->log_root_sum_hess - std::log(node->sum_hess.value())
>= context->magnitude_req) ) {
// fold the subtree whose root is [node]
ASTNode* parent_node = node->parent;
ASTNode* folder_node = nullptr;
ASTNode* tu_node = nullptr;
if (context->create_new_translation_unit) {
tu_node
= builder->AddNode<TranslationUnitNode>(parent_node, context->num_tu++);
ASTNode* ac = builder->AddNode<AccumulatorContextNode>(tu_node);
folder_node = builder->AddNode<CodeFolderNode>(ac);
tu_node->children.push_back(ac);
ac->children.push_back(folder_node);
} else {
folder_node = builder->AddNode<CodeFolderNode>(parent_node);
}
size_t node_loc = -1; // is current node 1st child or 2nd child or so forth
for (size_t i = 0; i < parent_node->children.size(); ++i) {
if (parent_node->children[i] == node) {
node_loc = i;
break;
}
}
CHECK_NE(node_loc, -1); // parent should have a link to current node
parent_node->children[node_loc]
= context->create_new_translation_unit ? tu_node : folder_node;
folder_node->children.push_back(node);
node->parent = folder_node;
return true;
} else {
bool folded_at_least_once = false;
for (ASTNode* child : node->children) {
folded_at_least_once |= fold_code(child, context, builder);
}
return folded_at_least_once;
}
}