[MachineOutliner][NFC] Simplify logic in pruneCandidates
authorJessica Paquette <jpaquette@apple.com>
Thu, 28 Sep 2017 23:39:36 +0000 (23:39 +0000)
committerJessica Paquette <jpaquette@apple.com>
Thu, 28 Sep 2017 23:39:36 +0000 (23:39 +0000)
This commit yanks out the repeated sections of code in pruneCandidates into
two lambdas: ShouldSkipCandidate and Prune. This simplifies the logic in
pruneCandidates significantly, and reduces the chance of introducing bugs by
folding all of the shared logic into one place.

llvm-svn: 314475

llvm/lib/CodeGen/MachineOutliner.cpp

index 38aea4f..8a884a1 100644 (file)
@@ -977,6 +977,59 @@ void MachineOutliner::pruneOverlaps(std::vector<Candidate> &CandidateList,
                                     InstructionMapper &Mapper,
                                     unsigned MaxCandidateLen,
                                     const TargetInstrInfo &TII) {
+
+  // Return true if this candidate became unbeneficial for outlining in a
+  // previous step.
+  auto ShouldSkipCandidate = [&FunctionList](Candidate &C) {
+
+    // Check if the candidate was removed in a previous step.
+    if (!C.InCandidateList)
+      return true;
+
+    // Check if C's associated function is still beneficial after previous
+    // pruning steps.
+    OutlinedFunction &F = FunctionList[C.FunctionIdx];
+
+    if (F.OccurrenceCount < 2 || F.Benefit < 1) {
+      assert(F.OccurrenceCount > 0 &&
+             "Can't remove OutlinedFunction with no occurrences!");
+      F.OccurrenceCount--;
+      C.InCandidateList = false;
+      return true;
+    }
+
+    // C is in the list, and F is still beneficial.
+    return false;
+  };
+
+  // Remove C from the candidate space, and update its OutlinedFunction.
+  auto Prune = [&FunctionList](Candidate &C) {
+
+    // Get the OutlinedFunction associated with this Candidate.
+    OutlinedFunction &F = FunctionList[C.FunctionIdx];
+
+    // Update C's associated function's occurrence count.
+    assert(F.OccurrenceCount > 0 &&
+           "Can't remove OutlinedFunction with no occurrences!");
+    F.OccurrenceCount--;
+
+    // Remove the call overhead from the removed sequence.
+    F.Benefit += C.MInfo.CallOverhead;
+
+    // Add back one instance of the sequence.
+    F.Benefit =
+        (F.Sequence.size() > F.Benefit) ? 0 : F.Benefit - F.Sequence.size();
+
+    // Remove C from the CandidateList.
+    C.InCandidateList = false;
+
+    DEBUG(dbgs() << "- Removed a Candidate \n";
+          dbgs() << "--- Num fns left for candidate: " << F.OccurrenceCount
+                 << "\n";
+          dbgs() << "--- Candidate's functions's benefit: " << F.Benefit
+                 << "\n";);
+  };
+
   // TODO: Experiment with interval trees or other interval-checking structures
   // to lower the time complexity of this function.
   // TODO: Can we do better than the simple greedy choice?
@@ -985,21 +1038,12 @@ void MachineOutliner::pruneOverlaps(std::vector<Candidate> &CandidateList,
   for (auto It = CandidateList.begin(), Et = CandidateList.end(); It != Et;
        It++) {
     Candidate &C1 = *It;
-    OutlinedFunction &F1 = FunctionList[C1.FunctionIdx];
 
-    // If we removed this candidate, skip it.
-    if (!C1.InCandidateList)
+    // If C1 was already pruned, or its function is no longer beneficial for
+    // outlining, move to the next candidate.
+    if (ShouldSkipCandidate(C1))
       continue;
 
-    // Is it still worth it to outline C1?
-    if (F1.Benefit < 1 || F1.OccurrenceCount < 2) {
-      assert(F1.OccurrenceCount > 0 &&
-             "Can't remove OutlinedFunction with no occurrences!");
-      F1.OccurrenceCount--;
-      C1.InCandidateList = false;
-      continue;
-    }
-
     // The minimum start index of any candidate that could overlap with this
     // one.
     unsigned FarthestPossibleIdx = 0;
@@ -1013,26 +1057,16 @@ void MachineOutliner::pruneOverlaps(std::vector<Candidate> &CandidateList,
     // MaxCandidateLen of these.
     for (auto Sit = It + 1; Sit != Et; Sit++) {
       Candidate &C2 = *Sit;
-      OutlinedFunction &F2 = FunctionList[C2.FunctionIdx];
 
       // Is this candidate too far away to overlap?
       if (C2.StartIdx < FarthestPossibleIdx)
         break;
 
-      // Did we already remove this candidate in a previous step?
-      if (!C2.InCandidateList)
+      // If C2 was already pruned, or its function is no longer beneficial for
+      // outlining, move to the next candidate.
+      if (ShouldSkipCandidate(C2))
         continue;
 
-      // Is the function beneficial to outline?
-      if (F2.OccurrenceCount < 2 || F2.Benefit < 1) {
-        // If not, remove this candidate and move to the next one.
-        assert(F2.OccurrenceCount > 0 &&
-               "Can't remove OutlinedFunction with no occurrences!");
-        F2.OccurrenceCount--;
-        C2.InCandidateList = false;
-        continue;
-      }
-
       unsigned C2End = C2.StartIdx + C2.Len - 1;
 
       // Do C1 and C2 overlap?
@@ -1052,52 +1086,9 @@ void MachineOutliner::pruneOverlaps(std::vector<Candidate> &CandidateList,
       // Approximate this by picking the one which would have saved us the
       // most instructions before any pruning.
       if (C1.Benefit >= C2.Benefit) {
-
-        // C1 is better, so remove C2 and update C2's OutlinedFunction to
-        // reflect the removal.
-        assert(F2.OccurrenceCount > 0 &&
-               "Can't remove OutlinedFunction with no occurrences!");
-        F2.OccurrenceCount--;
-
-        // Remove the call overhead from the removed sequence.
-        F2.Benefit += C2.MInfo.CallOverhead;
-
-        // Add back one instance of the sequence.
-        if (F2.Sequence.size() > F2.Benefit)
-          F2.Benefit = 0;
-        else
-          F2.Benefit -= F2.Sequence.size();
-
-        C2.InCandidateList = false;
-
-        DEBUG(dbgs() << "- Removed C2. \n";
-              dbgs() << "--- Num fns left for C2: " << F2.OccurrenceCount
-                     << "\n";
-              dbgs() << "--- C2's benefit: " << F2.Benefit << "\n";);
-
+        Prune(C2);
       } else {
-        // C2 is better, so remove C1 and update C1's OutlinedFunction to
-        // reflect the removal.
-        assert(F1.OccurrenceCount > 0 &&
-               "Can't remove OutlinedFunction with no occurrences!");
-        F1.OccurrenceCount--;
-
-        // Remove the call overhead from the removed sequence.
-        F1.Benefit += C1.MInfo.CallOverhead;
-
-        // Add back one instance of the sequence.
-        if (F1.Sequence.size() > F1.Benefit)
-          F1.Benefit = 0;
-        else
-          F1.Benefit -= F1.Sequence.size();
-
-        C1.InCandidateList = false;
-
-        DEBUG(dbgs() << "- Removed C1. \n";
-              dbgs() << "--- Num fns left for C1: " << F1.OccurrenceCount
-                     << "\n";
-              dbgs() << "--- C1's benefit: " << F1.Benefit << "\n";);
-
+        Prune(C1);
         // C1 is out, so we don't have to compare it against anyone else.
         break;
       }