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"
2624using 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