Removes all stateless nodes that do not contribute to a return value from the function body. Unlike `RemoveDeadNodes()`, which is triggered by `OptimizerOptions.do_function_inlining`, this pass ignores the SINK node, from which (by definition) all nodes are reverse reachable, and preserves all nodes that are reachable from control output nodes. TODO(ezhulenev, skyewm): Function body should not ha
| 893 | // stateful ops, graph should encode nodes that must execute with `control_ret` |
| 894 | // and `control_output`. |
| 895 | void PruneFunctionBody(const FunctionDef& fdef, Graph* g) { |
| 896 | VLOG(2) << "Pruning function body: function_name=" << fdef.signature().name(); |
| 897 | |
| 898 | // `control_ret` nodes must be always executed. |
| 899 | std::unordered_set<StringPiece, StringPieceHasher> control_ret_nodes; |
| 900 | for (const auto& control_ret : fdef.control_ret()) { |
| 901 | control_ret_nodes.insert(control_ret.second); |
| 902 | } |
| 903 | |
| 904 | std::unordered_set<const Node*> nodes; |
| 905 | for (auto n : g->nodes()) { |
| 906 | // NOTE(mrry): "_Retval" nodes are stateful, and so will be added |
| 907 | // to the seed set of `nodes`. "_Arg" nodes are also stateful, but we |
| 908 | // specifically exclude them as seeds, to avoid unconditionally executing |
| 909 | // unused argument nodes (e.g. in a function like `lambda x, y: y`). |
| 910 | // TODO(mrry): Investigate whether the `n->IsControlFlow()` test is |
| 911 | // still needed. It would be preferable to prune entire loops and/or |
| 912 | // conditionals if they are not used in the graph. |
| 913 | if (n->IsControlFlow() || |
| 914 | (n->op_def().is_stateful() && n->type_string() != kArgOp) || |
| 915 | (control_ret_nodes.find(n->name()) != control_ret_nodes.end())) { |
| 916 | nodes.insert(n); |
| 917 | } |
| 918 | } |
| 919 | bool changed = PruneForReverseReachability(g, std::move(nodes)); |
| 920 | if (changed) { |
| 921 | FixupSourceAndSinkEdges(g); |
| 922 | } |
| 923 | } |
| 924 | } // namespace |
| 925 | |
| 926 | Status FunctionLibraryRuntimeImpl::CreateItem(Item** item) { |
no test coverage detected