| 1748 | } |
| 1749 | |
| 1750 | Status ValidateInlining(const Node* node, const FunctionBody* fbody, |
| 1751 | const InlineFunctionBodyOptions& options) { |
| 1752 | // TODO(ezhulenev): Currently common_runtime function inlining can't guarantee |
| 1753 | // that all side-effectful ops will be executed after inlining. See Grappler |
| 1754 | // function_optimizer for details. Unify all function inlining mechanism. |
| 1755 | // Do not inline if `!fbody->control_ret_nodes.empty()`. |
| 1756 | |
| 1757 | const auto num_node_inputs = static_cast<size_t>(node->num_inputs()); |
| 1758 | const auto num_node_outputs = static_cast<size_t>(node->num_outputs()); |
| 1759 | |
| 1760 | if (num_node_inputs != fbody->arg_types.size() || |
| 1761 | num_node_inputs != fbody->arg_nodes.size()) { |
| 1762 | return errors::InvalidArgument( |
| 1763 | "Node inputs do not match function arguments: inputs=", num_node_inputs, |
| 1764 | " arg_types=", fbody->arg_types.size(), |
| 1765 | " arg_nodes=", fbody->arg_nodes.size()); |
| 1766 | } |
| 1767 | |
| 1768 | if (num_node_outputs != fbody->ret_types.size() || |
| 1769 | num_node_outputs != fbody->ret_nodes.size()) { |
| 1770 | return errors::InvalidArgument( |
| 1771 | "Node outputs do not match function returns: outputs=", |
| 1772 | num_node_outputs, " ret_types=", fbody->ret_types.size(), |
| 1773 | " ret_nodes=", fbody->ret_nodes.size()); |
| 1774 | } |
| 1775 | |
| 1776 | for (int i = 0; i < node->num_inputs(); ++i) { |
| 1777 | if (node->input_type(i) != fbody->arg_types[i]) { |
| 1778 | return errors::InvalidArgument( |
| 1779 | "Node input type doesn't match function argument type: ", |
| 1780 | node->input_type(i), " != ", fbody->arg_types[i], " @ index=", i); |
| 1781 | } |
| 1782 | } |
| 1783 | for (int i = 0; i < node->num_outputs(); ++i) { |
| 1784 | if (node->output_type(i) != fbody->ret_types[i]) { |
| 1785 | return errors::InvalidArgument( |
| 1786 | "Node output type doesn't match function return type: ", |
| 1787 | node->output_type(i), " != ", fbody->ret_types[i], " @ index=", i); |
| 1788 | } |
| 1789 | } |
| 1790 | |
| 1791 | if (options.disable_inlining) { |
| 1792 | return errors::InvalidArgument( |
| 1793 | "Function inlining explicitly disabled by 'options.disable_inlining'"); |
| 1794 | } |
| 1795 | |
| 1796 | if (!options.inline_impl_selection_group_functions) { |
| 1797 | bool is_impl_selection_group_function = |
| 1798 | fbody->fdef.attr().find("api_implements") != fbody->fdef.attr().end(); |
| 1799 | if (is_impl_selection_group_function) { |
| 1800 | return errors::InvalidArgument( |
| 1801 | "Inlining of implementation selection group function ", |
| 1802 | fbody->fdef.signature().name(), |
| 1803 | " is disabled by options.inline_impl_selection_group_functions"); |
| 1804 | } |
| 1805 | } |
| 1806 | |
| 1807 | if (!options.ignore_noinline) { |
no test coverage detected