| 706 | } |
| 707 | |
| 708 | void Prog::MarkDominator(int root, SparseArray<int>* rootmap, |
| 709 | SparseArray<int>* predmap, |
| 710 | std::vector<std::vector<int>>* predvec, |
| 711 | SparseSet* reachable, std::vector<int>* stk) { |
| 712 | reachable->clear(); |
| 713 | stk->clear(); |
| 714 | stk->push_back(root); |
| 715 | while (!stk->empty()) { |
| 716 | int id = stk->back(); |
| 717 | stk->pop_back(); |
| 718 | Loop: |
| 719 | if (reachable->contains(id)) |
| 720 | continue; |
| 721 | reachable->insert_new(id); |
| 722 | |
| 723 | if (id != root && rootmap->has_index(id)) { |
| 724 | // We reached another "tree" via epsilon transition. |
| 725 | continue; |
| 726 | } |
| 727 | |
| 728 | Inst* ip = inst(id); |
| 729 | switch (ip->opcode()) { |
| 730 | default: |
| 731 | LOG(DFATAL) << "unhandled opcode: " << ip->opcode(); |
| 732 | break; |
| 733 | |
| 734 | case kInstAltMatch: |
| 735 | case kInstAlt: |
| 736 | stk->push_back(ip->out1()); |
| 737 | id = ip->out(); |
| 738 | goto Loop; |
| 739 | |
| 740 | case kInstByteRange: |
| 741 | case kInstCapture: |
| 742 | case kInstEmptyWidth: |
| 743 | break; |
| 744 | |
| 745 | case kInstNop: |
| 746 | id = ip->out(); |
| 747 | goto Loop; |
| 748 | |
| 749 | case kInstMatch: |
| 750 | case kInstFail: |
| 751 | break; |
| 752 | } |
| 753 | } |
| 754 | |
| 755 | for (SparseSet::const_iterator i = reachable->begin(); |
| 756 | i != reachable->end(); |
| 757 | ++i) { |
| 758 | int id = *i; |
| 759 | if (predmap->has_index(id)) { |
| 760 | for (int pred : (*predvec)[predmap->get_existing(id)]) { |
| 761 | if (!reachable->contains(pred)) { |
| 762 | // id has a predecessor that cannot be reached from root! |
| 763 | // Therefore, id must be a "root" too - mark it as such. |
| 764 | if (!rootmap->has_index(id)) |
| 765 | rootmap->set_new(id, rootmap->size()); |
nothing calls this directly
no test coverage detected