// First, find all of the repeated substrings in the tree of minimum length
// 2.
std::vector<Candidate> CandidatesForRepeatedSeq;
+ LLVM_DEBUG(dbgs() << "*** Discarding overlapping candidates *** \n");
+ LLVM_DEBUG(
+ dbgs() << "Searching for overlaps in all repeated sequences...\n");
for (const SuffixTree::RepeatedSubstring &RS : ST) {
CandidatesForRepeatedSeq.clear();
unsigned StringLen = RS.Length;
+ LLVM_DEBUG(dbgs() << " Sequence length: " << StringLen << "\n");
+ // Debug code to keep track of how many candidates we removed.
+#ifndef NDEBUG
+ unsigned NumDiscarded = 0;
+ unsigned NumKept = 0;
+#endif
for (const unsigned &StartIdx : RS.StartIndices) {
- unsigned EndIdx = StartIdx + StringLen - 1;
// Trick: Discard some candidates that would be incompatible with the
// ones we've already found for this sequence. This will save us some
// work in candidate selection.
// That is, one must either
// * End before the other starts
// * Start after the other ends
- if (all_of(CandidatesForRepeatedSeq, [&StartIdx,
- &EndIdx](const Candidate &C) {
- return (EndIdx < C.getStartIdx() || StartIdx > C.getEndIdx());
- })) {
- // It doesn't overlap with anything, so we can outline it.
- // Each sequence is over [StartIt, EndIt].
- // Save the candidate and its location.
-
- MachineBasicBlock::iterator StartIt = Mapper.InstrList[StartIdx];
- MachineBasicBlock::iterator EndIt = Mapper.InstrList[EndIdx];
- MachineBasicBlock *MBB = StartIt->getParent();
-
- CandidatesForRepeatedSeq.emplace_back(StartIdx, StringLen, StartIt,
- EndIt, MBB, FunctionList.size(),
- Mapper.MBBFlagsMap[MBB]);
+ unsigned EndIdx = StartIdx + StringLen - 1;
+ auto FirstOverlap = find_if(
+ CandidatesForRepeatedSeq, [StartIdx, EndIdx](const Candidate &C) {
+ return EndIdx >= C.getStartIdx() && StartIdx <= C.getEndIdx();
+ });
+ if (FirstOverlap != CandidatesForRepeatedSeq.end()) {
+#ifndef NDEBUG
+ ++NumDiscarded;
+ LLVM_DEBUG(dbgs() << " .. DISCARD candidate @ [" << StartIdx
+ << ", " << EndIdx << "]; overlaps with candidate @ ["
+ << FirstOverlap->getStartIdx() << ", "
+ << FirstOverlap->getEndIdx() << "]\n");
+#endif
+ continue;
}
+ // It doesn't overlap with anything, so we can outline it.
+ // Each sequence is over [StartIt, EndIt].
+ // Save the candidate and its location.
+#ifndef NDEBUG
+ ++NumKept;
+#endif
+ MachineBasicBlock::iterator StartIt = Mapper.InstrList[StartIdx];
+ MachineBasicBlock::iterator EndIt = Mapper.InstrList[EndIdx];
+ MachineBasicBlock *MBB = StartIt->getParent();
+ CandidatesForRepeatedSeq.emplace_back(StartIdx, StringLen, StartIt, EndIt,
+ MBB, FunctionList.size(),
+ Mapper.MBBFlagsMap[MBB]);
}
+#ifndef NDEBUG
+ LLVM_DEBUG(dbgs() << " Candidates discarded: " << NumDiscarded
+ << "\n");
+ LLVM_DEBUG(dbgs() << " Candidates kept: " << NumKept << "\n\n");
+#endif
// We've found something we might want to outline.
// Create an OutlinedFunction to store it and check if it'd be beneficial
--- /dev/null
+# NOTE: Assertions have been autogenerated by utils/update_mir_test_checks.py UTC_ARGS: --include-generated-funcs
+# RUN: llc %s -mtriple aarch64 -debug-only=machine-outliner -run-pass=machine-outliner -o - 2>&1 | FileCheck %s
+# REQUIRES: asserts
+
+# CHECK: *** Discarding overlapping candidates ***
+# CHECK-NEXT:Searching for overlaps in all repeated sequences...
+# CHECK-DAG: Sequence length: 7
+# CHECK-NEXT: Candidates discarded: 0
+# CHECK-NEXT: Candidates kept: 2
+# CHECK-DAG: Sequence length: 8
+# CHECK-NEXT: .. DISCARD candidate @ [5, 12]; overlaps with candidate @ [12, 19]
+# CHECK-NEXT: Candidates discarded: 1
+# CHECK-NEXT: Candidates kept: 1
+# CHECK-DAG: Sequence length: 9
+# CHECK-NEXT: .. DISCARD candidate @ [4, 12]; overlaps with candidate @ [11, 19]
+# CHECK-NEXT: Candidates discarded: 1
+# CHECK-NEXT: Candidates kept: 1
+# CHECK-DAG: Sequence length: 10
+# CHECK-NEXT: .. DISCARD candidate @ [3, 12]; overlaps with candidate @ [10, 19]
+# CHECK-NEXT: Candidates discarded: 1
+# CHECK-NEXT: Candidates kept: 1
+# CHECK-DAG: Sequence length: 11
+# CHECK-NEXT: .. DISCARD candidate @ [2, 12]; overlaps with candidate @ [9, 19]
+# CHECK-NEXT: Candidates discarded: 1
+# CHECK-NEXT: Candidates kept: 1
+# CHECK-DAG: Sequence length: 12
+# CHECK-NEXT: .. DISCARD candidate @ [1, 12]; overlaps with candidate @ [8, 19]
+# CHECK-NEXT: Candidates discarded: 1
+# CHECK-NEXT: Candidates kept: 1
+# CHECK-DAG: Sequence length: 13
+# CHECK-NEXT: .. DISCARD candidate @ [0, 12]; overlaps with candidate @ [7, 19]
+# CHECK-NEXT: Candidates discarded: 1
+# CHECK-NEXT: Candidates kept: 1
+
+...
+---
+name: overlap
+tracksRegLiveness: true
+machineFunctionInfo:
+ hasRedZone: false
+body: |
+ bb.0:
+ liveins: $x0, $x9
+ ; CHECK-LABEL: name: overlap
+ ; CHECK: liveins: $x0, $x9
+ ; CHECK-NEXT: {{ $}}
+ ; CHECK-NEXT: $x9 = ADDXri $x9, 16, 0
+ ; CHECK-NEXT: $x9 = ADDXri $x9, 16, 0
+ ; CHECK-NEXT: $x9 = ADDXri $x9, 16, 0
+ ; CHECK-NEXT: $x9 = ADDXri $x9, 16, 0
+ ; CHECK-NEXT: $x9 = ADDXri $x9, 16, 0
+ ; CHECK-NEXT: $x9 = ADDXri $x9, 16, 0
+ ; CHECK-NEXT: BL @OUTLINED_FUNCTION_0, implicit-def $lr, implicit $sp, implicit-def $lr, implicit-def $x8, implicit-def $x9, implicit $sp, implicit $x0, implicit $x9
+ ; CHECK-NEXT: BL @OUTLINED_FUNCTION_0, implicit-def $lr, implicit $sp, implicit-def $lr, implicit-def $x8, implicit-def $x9, implicit $sp, implicit $x0, implicit $x9
+ ; CHECK-NEXT: RET undef $x9
+
+ ; fixme: outline!
+ $x9 = ADDXri $x9, 16, 0
+ $x9 = ADDXri $x9, 16, 0
+ $x9 = ADDXri $x9, 16, 0
+ $x9 = ADDXri $x9, 16, 0
+ $x9 = ADDXri $x9, 16, 0
+ $x9 = ADDXri $x9, 16, 0
+
+ $x8 = ADDXri $x0, 3, 0
+
+ ; outline
+ $x9 = ADDXri $x9, 16, 0
+ $x9 = ADDXri $x9, 16, 0
+ $x9 = ADDXri $x9, 16, 0
+ $x9 = ADDXri $x9, 16, 0
+ $x9 = ADDXri $x9, 16, 0
+ $x9 = ADDXri $x9, 16, 0
+
+ $x8 = ADDXri $x0, 3, 0
+
+ ; outline
+ $x9 = ADDXri $x9, 16, 0
+ $x9 = ADDXri $x9, 16, 0
+ $x9 = ADDXri $x9, 16, 0
+ $x9 = ADDXri $x9, 16, 0
+ $x9 = ADDXri $x9, 16, 0
+ $x9 = ADDXri $x9, 16, 0
+ RET undef $x9