示例#1
0
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;
}