Skip to content

Commit 16c925a

Browse files
authored
[MachineOutliner] Efficient Implementation of MachineOutliner::findCandidates() (#90260)
This reduce the time complexity of the main loop of `findCandidates()` method from $O(n^2)$ to $O(n \log n)$. For small $n$, the modification does not regress the build time, but it helps significantly when $n$ is large. For one application, this reduces the runtime of the main loop from 120 seconds to 28 seconds. This is the first commit for an enhanced version of machine outliner -- see [RFC](https://discourse.llvm.org/t/rfc-enhanced-machine-outliner-part-1-fulllto-part-2-thinlto-nolto-to-come/78732).
1 parent 1388562 commit 16c925a

File tree

2 files changed

+17
-16
lines changed

2 files changed

+17
-16
lines changed

llvm/lib/CodeGen/MachineOutliner.cpp

Lines changed: 11 additions & 10 deletions
Original file line numberDiff line numberDiff line change
@@ -584,7 +584,7 @@ void MachineOutliner::findCandidates(
584584
LLVM_DEBUG(dbgs() << "*** Discarding overlapping candidates *** \n");
585585
LLVM_DEBUG(
586586
dbgs() << "Searching for overlaps in all repeated sequences...\n");
587-
for (const SuffixTree::RepeatedSubstring &RS : ST) {
587+
for (SuffixTree::RepeatedSubstring &RS : ST) {
588588
CandidatesForRepeatedSeq.clear();
589589
unsigned StringLen = RS.Length;
590590
LLVM_DEBUG(dbgs() << " Sequence length: " << StringLen << "\n");
@@ -593,6 +593,9 @@ void MachineOutliner::findCandidates(
593593
unsigned NumDiscarded = 0;
594594
unsigned NumKept = 0;
595595
#endif
596+
// Sort the start indices so that we can efficiently check if candidates
597+
// overlap with the ones we've already found for this sequence.
598+
llvm::sort(RS.StartIndices);
596599
for (const unsigned &StartIdx : RS.StartIndices) {
597600
// Trick: Discard some candidates that would be incompatible with the
598601
// ones we've already found for this sequence. This will save us some
@@ -616,17 +619,15 @@ void MachineOutliner::findCandidates(
616619
// * End before the other starts
617620
// * Start after the other ends
618621
unsigned EndIdx = StartIdx + StringLen - 1;
619-
auto FirstOverlap = find_if(
620-
CandidatesForRepeatedSeq, [StartIdx, EndIdx](const Candidate &C) {
621-
return EndIdx >= C.getStartIdx() && StartIdx <= C.getEndIdx();
622-
});
623-
if (FirstOverlap != CandidatesForRepeatedSeq.end()) {
622+
if (!CandidatesForRepeatedSeq.empty() &&
623+
StartIdx <= CandidatesForRepeatedSeq.back().getEndIdx()) {
624624
#ifndef NDEBUG
625625
++NumDiscarded;
626-
LLVM_DEBUG(dbgs() << " .. DISCARD candidate @ [" << StartIdx
627-
<< ", " << EndIdx << "]; overlaps with candidate @ ["
628-
<< FirstOverlap->getStartIdx() << ", "
629-
<< FirstOverlap->getEndIdx() << "]\n");
626+
LLVM_DEBUG(dbgs() << " .. DISCARD candidate @ [" << StartIdx << ", "
627+
<< EndIdx << "]; overlaps with candidate @ ["
628+
<< CandidatesForRepeatedSeq.back().getStartIdx()
629+
<< ", " << CandidatesForRepeatedSeq.back().getEndIdx()
630+
<< "]\n");
630631
#endif
631632
continue;
632633
}

llvm/test/CodeGen/AArch64/machine-outliner-overlap.mir

Lines changed: 6 additions & 6 deletions
Original file line numberDiff line numberDiff line change
@@ -8,27 +8,27 @@
88
# CHECK-NEXT: Candidates discarded: 0
99
# CHECK-NEXT: Candidates kept: 2
1010
# CHECK-DAG: Sequence length: 8
11-
# CHECK-NEXT: .. DISCARD candidate @ [5, 12]; overlaps with candidate @ [12, 19]
11+
# CHECK-NEXT: .. DISCARD candidate @ [12, 19]; overlaps with candidate @ [5, 12]
1212
# CHECK-NEXT: Candidates discarded: 1
1313
# CHECK-NEXT: Candidates kept: 1
1414
# CHECK-DAG: Sequence length: 9
15-
# CHECK-NEXT: .. DISCARD candidate @ [4, 12]; overlaps with candidate @ [11, 19]
15+
# CHECK-NEXT: .. DISCARD candidate @ [11, 19]; overlaps with candidate @ [4, 12]
1616
# CHECK-NEXT: Candidates discarded: 1
1717
# CHECK-NEXT: Candidates kept: 1
1818
# CHECK-DAG: Sequence length: 10
19-
# CHECK-NEXT: .. DISCARD candidate @ [3, 12]; overlaps with candidate @ [10, 19]
19+
# CHECK-NEXT: .. DISCARD candidate @ [10, 19]; overlaps with candidate @ [3, 12]
2020
# CHECK-NEXT: Candidates discarded: 1
2121
# CHECK-NEXT: Candidates kept: 1
2222
# CHECK-DAG: Sequence length: 11
23-
# CHECK-NEXT: .. DISCARD candidate @ [2, 12]; overlaps with candidate @ [9, 19]
23+
# CHECK-NEXT: .. DISCARD candidate @ [9, 19]; overlaps with candidate @ [2, 12]
2424
# CHECK-NEXT: Candidates discarded: 1
2525
# CHECK-NEXT: Candidates kept: 1
2626
# CHECK-DAG: Sequence length: 12
27-
# CHECK-NEXT: .. DISCARD candidate @ [1, 12]; overlaps with candidate @ [8, 19]
27+
# CHECK-NEXT: .. DISCARD candidate @ [8, 19]; overlaps with candidate @ [1, 12]
2828
# CHECK-NEXT: Candidates discarded: 1
2929
# CHECK-NEXT: Candidates kept: 1
3030
# CHECK-DAG: Sequence length: 13
31-
# CHECK-NEXT: .. DISCARD candidate @ [0, 12]; overlaps with candidate @ [7, 19]
31+
# CHECK-NEXT: .. DISCARD candidate @ [7, 19]; overlaps with candidate @ [0, 12]
3232
# CHECK-NEXT: Candidates discarded: 1
3333
# CHECK-NEXT: Candidates kept: 1
3434

0 commit comments

Comments
 (0)