/* * Registra todas as ocorrências do padrão no texto */ void SuffixTree::getMatchings(const char* pat, size_t m, SuffixTreeNode& node, int nodeHeight, Printer& printer) { if(node.isLeaf()) //É folha printer.addMatching(n-nodeHeight); else { for(int nt = node.firstChild; nt != -1; nt = nodes.at(nt).sibling){ SuffixTreeNode& next = nodes.at(nt); int edgeSize = next.end - next.start + 1; getMatchings(pat, m, next, nodeHeight + edgeSize, printer); } } }
unsigned MachineOutliner::findCandidates(SuffixTree &ST, const TargetInstrInfo &TII, InstructionMapper &Mapper, std::vector<Candidate> &CandidateList, std::vector<OutlinedFunction> &FunctionList) { CandidateList.clear(); FunctionList.clear(); unsigned MaxLen = 0; // FIXME: Visit internal nodes instead of leaves. for (SuffixTreeNode *Leaf : ST.LeafVector) { assert(Leaf && "Leaves in LeafVector cannot be null!"); if (!Leaf->IsInTree) continue; assert(Leaf->Parent && "All leaves must have parents!"); SuffixTreeNode &Parent = *(Leaf->Parent); // If it doesn't appear enough, or we already outlined from it, skip it. if (Parent.OccurrenceCount < 2 || Parent.isRoot() || !Parent.IsInTree) continue; // Figure out if this candidate is beneficial. unsigned StringLen = Leaf->ConcatLen - (unsigned)Leaf->size(); // Too short to be beneficial; skip it. // FIXME: This isn't necessarily true for, say, X86. If we factor in // instruction lengths we need more information than this. if (StringLen < 2) continue; // If this is a beneficial class of candidate, then every one is stored in // this vector. std::vector<Candidate> CandidatesForRepeatedSeq; // Describes the start and end point of each candidate. This allows the // target to infer some information about each occurrence of each repeated // sequence. // FIXME: CandidatesForRepeatedSeq and this should be combined. std::vector< std::pair<MachineBasicBlock::iterator, MachineBasicBlock::iterator>> RepeatedSequenceLocs; // Figure out the call overhead for each instance of the sequence. for (auto &ChildPair : Parent.Children) { SuffixTreeNode *M = ChildPair.second; if (M && M->IsInTree && M->isLeaf()) { // Each sequence is over [StartIt, EndIt]. MachineBasicBlock::iterator StartIt = Mapper.InstrList[M->SuffixIdx]; MachineBasicBlock::iterator EndIt = Mapper.InstrList[M->SuffixIdx + StringLen - 1]; CandidatesForRepeatedSeq.emplace_back(M->SuffixIdx, StringLen, FunctionList.size()); RepeatedSequenceLocs.emplace_back(std::make_pair(StartIt, EndIt)); // Never visit this leaf again. M->IsInTree = false; } } // We've found something we might want to outline. // Create an OutlinedFunction to store it and check if it'd be beneficial // to outline. TargetInstrInfo::MachineOutlinerInfo MInfo = TII.getOutlininingCandidateInfo(RepeatedSequenceLocs); std::vector<unsigned> Seq; for (unsigned i = Leaf->SuffixIdx; i < Leaf->SuffixIdx + StringLen; i++) Seq.push_back(ST.Str[i]); OutlinedFunction OF(FunctionList.size(), Parent.OccurrenceCount, Seq, MInfo); unsigned Benefit = OF.getBenefit(); // Is it better to outline this candidate than not? if (Benefit < 1) { // Outlining this candidate would take more instructions than not // outlining. // Emit a remark explaining why we didn't outline this candidate. std::pair<MachineBasicBlock::iterator, MachineBasicBlock::iterator> C = RepeatedSequenceLocs[0]; MachineOptimizationRemarkEmitter MORE( *(C.first->getParent()->getParent()), nullptr); MachineOptimizationRemarkMissed R(DEBUG_TYPE, "NotOutliningCheaper", C.first->getDebugLoc(), C.first->getParent()); R << "Did not outline " << NV("Length", StringLen) << " instructions" << " from " << NV("NumOccurrences", RepeatedSequenceLocs.size()) << " locations." << " Instructions from outlining all occurrences (" << NV("OutliningCost", OF.getOutliningCost()) << ")" << " >= Unoutlined instruction count (" << NV("NotOutliningCost", StringLen * OF.OccurrenceCount) << ")" << " (Also found at: "; // Tell the user the other places the candidate was found. for (unsigned i = 1, e = RepeatedSequenceLocs.size(); i < e; i++) { R << NV((Twine("OtherStartLoc") + Twine(i)).str(), RepeatedSequenceLocs[i].first->getDebugLoc()); if (i != e - 1) R << ", "; } R << ")"; MORE.emit(R); // Move to the next candidate. continue; } if (StringLen > MaxLen) MaxLen = StringLen; // At this point, the candidate class is seen as beneficial. Set their // benefit values and save them in the candidate list. for (Candidate &C : CandidatesForRepeatedSeq) { C.Benefit = Benefit; C.MInfo = MInfo; CandidateList.push_back(C); } FunctionList.push_back(OF); // Move to the next function. Parent.IsInTree = false; } return MaxLen; }