Skip to content

Commit 7284a60

Browse files
committed
Optimize branch selector to not need a sparse set.
1 parent fc78586 commit 7284a60

File tree

1 file changed

+51
-50
lines changed

1 file changed

+51
-50
lines changed

llvm/lib/Target/Z80/Z80BranchSelector.cpp

Lines changed: 51 additions & 50 deletions
Original file line numberDiff line numberDiff line change
@@ -20,9 +20,7 @@
2020
#include "Z80Subtarget.h"
2121
#include "llvm/ADT/Optional.h"
2222
#include "llvm/ADT/SmallVector.h"
23-
#include "llvm/ADT/SparseSet.h"
2423
#include "llvm/CodeGen/MachineFunctionPass.h"
25-
#include "llvm/Support/MathExtras.h"
2624
using namespace llvm;
2725

2826
#define DEBUG_TYPE "z80-branch-select"
@@ -205,7 +203,7 @@ template <typename T> class OffsetTree {
205203
return Idx;
206204
}
207205

208-
SmallVector<T, 0> Tree{{T()}};
206+
SmallVector<T> Tree{{T()}};
209207
#ifndef NDEBUG
210208
bool IsFrozen = false;
211209
#endif
@@ -223,11 +221,14 @@ class BranchTracker {
223221
assert(Phase == Phase::Invalid && "Forgot to call done()");
224222
}
225223

226-
MachineInstr *operator[](size_type BranchIdx) { return Branches[BranchIdx]; }
227-
size_type size() {
224+
size_type size() const {
228225
assert(Branches.size() == BranchTree.size());
229226
return Branches.size();
230227
}
228+
MachineInstr *operator[](size_type BranchIdx) const {
229+
return Branches[BranchIdx];
230+
}
231+
MachineInstr *&operator[](size_type BranchIdx) { return Branches[BranchIdx]; }
231232

232233
void init(MachineFunction &MF) {
233234
assert(std::exchange(Phase, Phase::Build) == Phase::Invalid);
@@ -298,10 +299,7 @@ class BranchTracker {
298299
void adjustBranchSize(size_type BranchIdx, Range<Offset> Amt) {
299300
assert(Phase == Phase::Query);
300301
BranchTree.adjust(BranchIdx + 1, -Amt);
301-
TargetTree.adjust(
302-
getTargetIndex(
303-
*std::exchange(Branches[BranchIdx], nullptr)->getParent()),
304-
-Amt);
302+
TargetTree.adjust(getTargetIndex(*Branches[BranchIdx]->getParent()), -Amt);
305303
}
306304

307305
void done() { assert(std::exchange(Phase, Phase::Invalid) == Phase::Query); }
@@ -324,17 +322,19 @@ class BranchTracker {
324322
}
325323

326324
void dump() const {
327-
for (size_type Idx = TargetTree.size(), Num = 0; Idx--; ++Num)
328-
dbgs() << TargetTree.get<Tree::Debug>(Idx) -
325+
for (size_type TargetIdx = TargetTree.size(); TargetIdx--;)
326+
dbgs() << TargetTree.get<Tree::Debug>(TargetIdx) -
329327
TargetTree.current<Tree::Debug>()
330-
<< '\t' << printMBBReference(*DebugMF->getBlockNumbered(Num))
328+
<< '\t'
329+
<< printMBBReference(*DebugMF->getBlockNumbered(
330+
DebugMF->getNumBlockIDs() - 1 - TargetIdx))
331331
<< ":\n";
332-
for (size_type Idx = BranchTree.size(); Idx--;) {
333-
dbgs() << BranchTree.get<Tree::Debug>(Idx) -
332+
for (size_type BranchIdx = BranchTree.size(); BranchIdx--;) {
333+
dbgs() << BranchTree.get<Tree::Debug>(BranchIdx) -
334334
BranchTree.current<Tree::Debug>()
335335
<< "\t\t";
336-
if (Branches[Idx])
337-
Branches[Idx]->dump();
336+
if (MachineInstr *Branch = Branches[BranchIdx])
337+
Branch->dump();
338338
else
339339
dbgs() << "\t(selected)\n";
340340
}
@@ -351,7 +351,7 @@ class BranchTracker {
351351
MachineFunction *DebugMF;
352352
#endif
353353

354-
SmallVector<MachineInstr *, 0> Branches;
354+
SmallVector<MachineInstr *> Branches;
355355
Tree BranchTree, TargetTree;
356356
};
357357

@@ -482,47 +482,48 @@ bool Z80BranchSelector::runOnMachineFunction(MachineFunction &MF) {
482482
LLVM_DEBUG(dbgs() << '\n'; Tracker.dump());
483483

484484
// Phase 2: Select definite relative and required absolute branches.
485-
SparseSet<BranchTracker::size_type, identity<unsigned>, uint16_t>
486-
PendingRelaxBranch;
487-
PendingRelaxBranch.setUniverse(Tracker.size());
488-
const auto relaxBranch = [&](BranchTracker::size_type BranchIdx,
489-
BranchTracker::size_type MaxBranchIdx) {
490-
makeBranchAbsolute(*Tracker[BranchIdx]);
491-
Tracker.adjustBranchSize(BranchIdx, {BranchSize.delta(), 0});
492-
LLVM_DEBUG(dbgs() << ".. Making absolute\n"; Tracker.dump());
493-
for (auto Idx = BranchIdx;
494-
++Idx != MaxBranchIdx &&
495-
isInt<8>(Tracker.getBranchToBranchOffset(Idx, BranchIdx).Min -
496-
BranchSize.delta());)
497-
if (Tracker[Idx] && !isInt<8>(Tracker.getBranchDisplacement(Idx).Min))
498-
PendingRelaxBranch.insert(Idx);
499-
for (auto Idx = BranchIdx;
500-
Idx && isInt<8>(Tracker.getBranchToBranchOffset(--Idx, BranchIdx).Min -
501-
BranchSize.delta());)
502-
if (Tracker[Idx] && !isInt<8>(Tracker.getBranchDisplacement(Idx).Min))
503-
PendingRelaxBranch.insert(Idx);
504-
};
505-
for (BranchTracker::size_type BranchIdx = 0; BranchIdx != Tracker.size();
506-
++BranchIdx) {
507-
if (!Tracker[BranchIdx])
508-
continue;
485+
SmallVector<BranchTracker::size_type> Queue;
486+
const auto selectBranch = [&,
487+
BranchSize](BranchTracker::size_type BranchIdx) {
488+
MachineInstr *&Branch = Tracker[BranchIdx];
509489
auto Displacement = Tracker.getBranchDisplacement(BranchIdx);
510-
LLVM_DEBUG(dbgs() << Displacement; Tracker[BranchIdx]->dump());
490+
LLVM_DEBUG(dbgs() << Displacement; Branch->dump());
511491
if (isInt<8>(Displacement.Max)) {
512-
makeBranchRelative(*Tracker[BranchIdx]);
492+
makeBranchRelative(*Branch);
513493
Tracker.adjustBranchSize(BranchIdx, {0, -BranchSize.delta()});
494+
Branch = nullptr;
514495
LLVM_DEBUG(dbgs() << ".. Making relative\n"; Tracker.dump());
515496
} else if (!isInt<8>(Displacement.Min)) {
516-
relaxBranch(BranchIdx, BranchIdx + 1);
517-
while (!PendingRelaxBranch.empty())
518-
relaxBranch(PendingRelaxBranch.pop_back_val(), BranchIdx);
497+
makeBranchAbsolute(*Branch);
498+
Tracker.adjustBranchSize(BranchIdx, {BranchSize.delta(), 0});
499+
Branch = nullptr;
500+
LLVM_DEBUG(dbgs() << ".. Making absolute\n"; Tracker.dump());
501+
Queue.push_back(BranchIdx);
502+
}
503+
};
504+
for (BranchTracker::size_type MaxBranchIdx = 0, BranchCount = Tracker.size();
505+
MaxBranchIdx != BranchCount; ++MaxBranchIdx) {
506+
selectBranch(MaxBranchIdx);
507+
while (!Queue.empty()) {
508+
auto BranchIdx = Queue.pop_back_val();
509+
for (auto Idx = BranchIdx;
510+
Idx != MaxBranchIdx &&
511+
isInt<8>(Tracker.getBranchToBranchOffset(++Idx, BranchIdx).Min -
512+
BranchSize.delta());)
513+
if (Tracker[Idx])
514+
selectBranch(Idx);
515+
for (auto Idx = BranchIdx;
516+
Idx &&
517+
isInt<8>(Tracker.getBranchToBranchOffset(--Idx, BranchIdx).Min -
518+
BranchSize.delta());)
519+
if (Tracker[Idx])
520+
selectBranch(Idx);
519521
}
520522
}
521-
assert(PendingRelaxBranch.empty());
522523

523-
// Phase 3: All of the remaining branches can now be made relative.
524-
for (BranchTracker::size_type BranchIdx = 0; BranchIdx != Tracker.size();
525-
++BranchIdx)
524+
// Phase 3: All of the remaining ambiguous branches can now be made relative.
525+
for (BranchTracker::size_type BranchIdx = 0, BranchCount = Tracker.size();
526+
BranchIdx != BranchCount; ++BranchIdx)
526527
if (MachineInstr *Branch = Tracker[BranchIdx])
527528
makeBranchRelative(*Branch);
528529

0 commit comments

Comments
 (0)