| 1439 | } |
| 1440 | |
| 1441 | Status ConstantFolding::FoldNode(NodeDef* node, GraphDef* output_graph, |
| 1442 | bool* result_too_large) { |
| 1443 | *result_too_large = false; |
| 1444 | if (IsMerge(*node)) { |
| 1445 | return FoldMergeNode(node, output_graph); |
| 1446 | } |
| 1447 | |
| 1448 | std::vector<NodeDef> const_nodes; |
| 1449 | TF_RETURN_IF_ERROR( |
| 1450 | EvaluateOneFoldable(*node, &const_nodes, result_too_large)); |
| 1451 | VLOG(2) << "Folded node: " << SummarizeNodeDef(*node); |
| 1452 | |
| 1453 | NodeDef* constant_output = nullptr; |
| 1454 | for (int i = 0; i < const_nodes.size(); i++) { |
| 1455 | NodeDef* const_node = &const_nodes[i]; |
| 1456 | VLOG(3) << "Generated constant node: " << SummarizeNodeDef(*const_node); |
| 1457 | if (const_node->name().empty()) { |
| 1458 | // Dead output: we can't create a constant to encode its value, so we'll |
| 1459 | // just skip it. We'll preserve the edges that originate from that |
| 1460 | // output below to preserve the overall behavior of the graph wrt dead |
| 1461 | // edges. |
| 1462 | continue; |
| 1463 | } |
| 1464 | |
| 1465 | // Returns `true` iff `const_node` already has control input named `input`. |
| 1466 | const auto is_duplicate_control_input = [&](const string& input) -> bool { |
| 1467 | auto it = absl::c_find(const_node->input(), input); |
| 1468 | return it != const_node->input().end(); |
| 1469 | }; |
| 1470 | |
| 1471 | // Forward control dependencies. |
| 1472 | for (const string& input : node->input()) { |
| 1473 | // Forward control dependencies from folded node. |
| 1474 | if (IsControlInput(input)) { |
| 1475 | if (!is_duplicate_control_input(input)) { |
| 1476 | *const_node->add_input() = input; |
| 1477 | } |
| 1478 | } |
| 1479 | |
| 1480 | // Forward control dependencies from constant inputs to folded node. |
| 1481 | if (!IsControlInput(input)) { |
| 1482 | NodeDef* input_node = node_map_->GetNode(input); |
| 1483 | for (const string& fanin_of_input : input_node->input()) { |
| 1484 | if (!is_duplicate_control_input(fanin_of_input)) { |
| 1485 | *const_node->add_input() = fanin_of_input; |
| 1486 | } |
| 1487 | } |
| 1488 | } |
| 1489 | } |
| 1490 | |
| 1491 | // We rewrite the existing node if it only has a single output, and |
| 1492 | // create new nodes otherwise. |
| 1493 | if (const_nodes.size() == 1) { |
| 1494 | node->set_op("Const"); |
| 1495 | // Note we need to clear the inputs in NodeMap before we clear the inputs |
| 1496 | // in the node, otherwise NodeMap would see empty inputs and effectively |
| 1497 | // does nothing. |
| 1498 | node_map_->RemoveInputs(node->name()); |
nothing calls this directly
no test coverage detected