| 960 | } |
| 961 | |
| 962 | static std::array<module::with_inputs, 2> |
| 963 | generic_split(const module& m, |
| 964 | const std::vector<instruction_ref>& args, |
| 965 | const std::vector<instruction_ref>& splits, |
| 966 | std::unordered_map<instruction_ref, instruction_ref>* map_ins = nullptr) |
| 967 | { |
| 968 | std::unordered_map<instruction_ref, instruction_ref> param_map = |
| 969 | m.get_ins_param_map(args, true); |
| 970 | |
| 971 | std::unordered_set<instruction_ref> selected_instructions; |
| 972 | fix([&](auto self, const std::vector<instruction_ref>& inputs) { |
| 973 | for(auto input : inputs) |
| 974 | { |
| 975 | if(contains(selected_instructions, input)) |
| 976 | continue; |
| 977 | selected_instructions.insert(input); |
| 978 | self(input->inputs()); |
| 979 | } |
| 980 | })(splits); |
| 981 | |
| 982 | std::vector<instruction_ref> instructions1; |
| 983 | // TODO: copy_if |
| 984 | for(auto ins : iterator_for(m)) |
| 985 | { |
| 986 | if(not contains(selected_instructions, ins)) |
| 987 | continue; |
| 988 | instructions1.push_back(ins); |
| 989 | } |
| 990 | |
| 991 | std::vector<instruction_ref> inputs1 = select_params(instructions1, param_map); |
| 992 | module m1; |
| 993 | std::unordered_map<instruction_ref, instruction_ref> map_ins1; |
| 994 | m1.add_instructions(instructions1, &map_ins1); |
| 995 | std::vector<instruction_ref> outputs; |
| 996 | std::transform(splits.begin(), |
| 997 | splits.end(), |
| 998 | std::back_inserter(outputs), |
| 999 | [&](instruction_ref ins) { return map_ins1.at(ins); }); |
| 1000 | m1.add_return(outputs); |
| 1001 | |
| 1002 | std::vector<instruction_ref> instructions2; |
| 1003 | for(auto ins : iterator_for(m)) |
| 1004 | { |
| 1005 | if(contains(selected_instructions, ins)) |
| 1006 | continue; |
| 1007 | // Input params can be used in both modules |
| 1008 | std::vector<instruction_ref> input_params; |
| 1009 | std::copy_if(ins->inputs().begin(), |
| 1010 | ins->inputs().end(), |
| 1011 | std::back_inserter(input_params), |
| 1012 | [&](instruction_ref input) { |
| 1013 | if(input->name() != "@param") |
| 1014 | return false; |
| 1015 | return not contains(instructions2, input); |
| 1016 | }); |
| 1017 | instructions2.insert(instructions2.end(), input_params.begin(), input_params.end()); |
| 1018 | instructions2.push_back(ins); |
| 1019 | } |
no test coverage detected