| 649 | } |
| 650 | |
| 651 | bool is_interdependent(const std::vector<instruction_ref>& instructions, |
| 652 | const_module_ref m, |
| 653 | instruction_ref root) |
| 654 | { |
| 655 | if(instructions.size() < 2) |
| 656 | return true; |
| 657 | const std::size_t small_size = 8; |
| 658 | if(instructions.size() <= small_size) |
| 659 | { |
| 660 | std::array<std::size_t, small_size> loc; |
| 661 | std::transform(instructions.begin(), |
| 662 | instructions.end(), |
| 663 | loc.begin(), |
| 664 | [&](instruction_ref ins) { return std::distance(root, ins); }); |
| 665 | auto start = instructions[std::distance( |
| 666 | loc.begin(), std::min_element(loc.begin(), loc.begin() + instructions.size()))]; |
| 667 | return all_of(instructions, [&](instruction_ref ins) { |
| 668 | if(ins == start) |
| 669 | return true; |
| 670 | return reaches(start, ins, m, [&](instruction_ref i) { |
| 671 | return i != ins and contains(instructions, i); |
| 672 | }); |
| 673 | }); |
| 674 | } |
| 675 | std::unordered_map<instruction_ref, std::size_t> loc; |
| 676 | loc.reserve(instructions.size()); |
| 677 | std::transform( |
| 678 | instructions.begin(), |
| 679 | instructions.end(), |
| 680 | std::inserter(loc, loc.end()), |
| 681 | [&](instruction_ref ins) { return std::make_pair(ins, std::distance(root, ins)); }); |
| 682 | auto min_it = std::min_element( |
| 683 | loc.begin(), loc.end(), [](const auto& x, const auto& y) { return x.second < y.second; }); |
| 684 | auto start = min_it->first; |
| 685 | |
| 686 | return all_of(instructions, [&](instruction_ref ins) { |
| 687 | if(ins == start) |
| 688 | return true; |
| 689 | return reaches( |
| 690 | start, ins, m, [&](instruction_ref i) { return i != ins and contains(loc, i); }); |
| 691 | }); |
| 692 | } |
| 693 | |
| 694 | // Return set of all instructions that are connected to both start and end nodes (inclusive) |
| 695 | std::unordered_set<instruction_ref> |