Skip to content

Commit b52e036

Browse files
author
Francis Visoiu Mistrih
committed
BitVector: add iterators for set bits
Differential revision: https://reviews.llvm.org/D32060 llvm-svn: 303227
1 parent de83fec commit b52e036

18 files changed

+135
-50
lines changed

llvm/include/llvm/ADT/BitVector.h

+57
Original file line numberDiff line numberDiff line change
@@ -15,6 +15,7 @@
1515
#define LLVM_ADT_BITVECTOR_H
1616

1717
#include "llvm/ADT/ArrayRef.h"
18+
#include "llvm/ADT/iterator_range.h"
1819
#include "llvm/Support/MathExtras.h"
1920
#include <algorithm>
2021
#include <cassert>
@@ -26,6 +27,50 @@
2627

2728
namespace llvm {
2829

30+
/// ForwardIterator for the bits that are set.
31+
/// Iterators get invalidated when resize / reserve is called.
32+
template <typename BitVectorT> class const_set_bits_iterator_impl {
33+
const BitVectorT &Parent;
34+
int Current = 0;
35+
36+
void advance() {
37+
assert(Current != -1 && "Trying to advance past end.");
38+
Current = Parent.find_next(Current);
39+
}
40+
41+
public:
42+
const_set_bits_iterator_impl(const BitVectorT &Parent, int Current)
43+
: Parent(Parent), Current(Current) {}
44+
explicit const_set_bits_iterator_impl(const BitVectorT &Parent)
45+
: const_set_bits_iterator_impl(Parent, Parent.find_first()) {}
46+
const_set_bits_iterator_impl(const const_set_bits_iterator_impl &) = default;
47+
48+
const_set_bits_iterator_impl operator++(int) {
49+
auto Prev = *this;
50+
advance();
51+
return Prev;
52+
}
53+
54+
const_set_bits_iterator_impl &operator++() {
55+
advance();
56+
return *this;
57+
}
58+
59+
unsigned operator*() const { return Current; }
60+
61+
bool operator==(const const_set_bits_iterator_impl &Other) const {
62+
assert(&Parent == &Other.Parent &&
63+
"Comparing iterators from different BitVectors");
64+
return Current == Other.Current;
65+
}
66+
67+
bool operator!=(const const_set_bits_iterator_impl &Other) const {
68+
assert(&Parent == &Other.Parent &&
69+
"Comparing iterators from different BitVectors");
70+
return Current != Other.Current;
71+
}
72+
};
73+
2974
class BitVector {
3075
typedef unsigned long BitWord;
3176

@@ -73,6 +118,18 @@ class BitVector {
73118
}
74119
};
75120

121+
typedef const_set_bits_iterator_impl<BitVector> const_set_bits_iterator;
122+
typedef const_set_bits_iterator set_iterator;
123+
124+
const_set_bits_iterator set_bits_begin() const {
125+
return const_set_bits_iterator(*this);
126+
}
127+
const_set_bits_iterator set_bits_end() const {
128+
return const_set_bits_iterator(*this, -1);
129+
}
130+
iterator_range<const_set_bits_iterator> set_bits() const {
131+
return make_range(set_bits_begin(), set_bits_end());
132+
}
76133

77134
/// BitVector default ctor - Creates an empty bitvector.
78135
BitVector() : Size(0) {}

llvm/include/llvm/ADT/SmallBitVector.h

+13
Original file line numberDiff line numberDiff line change
@@ -134,6 +134,19 @@ class SmallBitVector {
134134
}
135135

136136
public:
137+
typedef const_set_bits_iterator_impl<SmallBitVector> const_set_bits_iterator;
138+
typedef const_set_bits_iterator set_iterator;
139+
140+
const_set_bits_iterator set_bits_begin() const {
141+
return const_set_bits_iterator(*this);
142+
}
143+
const_set_bits_iterator set_bits_end() const {
144+
return const_set_bits_iterator(*this, -1);
145+
}
146+
iterator_range<const_set_bits_iterator> set_bits() const {
147+
return make_range(set_bits_begin(), set_bits_end());
148+
}
149+
137150
/// Creates an empty bitvector.
138151
SmallBitVector() : X(1) {}
139152

llvm/lib/Analysis/DependenceAnalysis.cpp

+16-17
Original file line numberDiff line numberDiff line change
@@ -2984,7 +2984,7 @@ bool DependenceInfo::propagate(const SCEV *&Src, const SCEV *&Dst,
29842984
SmallVectorImpl<Constraint> &Constraints,
29852985
bool &Consistent) {
29862986
bool Result = false;
2987-
for (int LI = Loops.find_first(); LI >= 0; LI = Loops.find_next(LI)) {
2987+
for (unsigned LI : Loops.set_bits()) {
29882988
DEBUG(dbgs() << "\t Constraint[" << LI << "] is");
29892989
DEBUG(Constraints[LI].dump(dbgs()));
29902990
if (Constraints[LI].isDistance())
@@ -3266,7 +3266,7 @@ bool DependenceInfo::tryDelinearize(Instruction *Src, Instruction *Dst,
32663266
// For debugging purposes, dump a small bit vector to dbgs().
32673267
static void dumpSmallBitVector(SmallBitVector &BV) {
32683268
dbgs() << "{";
3269-
for (int VI = BV.find_first(); VI >= 0; VI = BV.find_next(VI)) {
3269+
for (unsigned VI : BV.set_bits()) {
32703270
dbgs() << VI;
32713271
if (BV.find_next(VI) >= 0)
32723272
dbgs() << ' ';
@@ -3506,7 +3506,7 @@ DependenceInfo::depends(Instruction *Src, Instruction *Dst,
35063506
NewConstraint.setAny(SE);
35073507

35083508
// test separable subscripts
3509-
for (int SI = Separable.find_first(); SI >= 0; SI = Separable.find_next(SI)) {
3509+
for (unsigned SI : Separable.set_bits()) {
35103510
DEBUG(dbgs() << "testing subscript " << SI);
35113511
switch (Pair[SI].Classification) {
35123512
case Subscript::ZIV:
@@ -3545,14 +3545,14 @@ DependenceInfo::depends(Instruction *Src, Instruction *Dst,
35453545
SmallVector<Constraint, 4> Constraints(MaxLevels + 1);
35463546
for (unsigned II = 0; II <= MaxLevels; ++II)
35473547
Constraints[II].setAny(SE);
3548-
for (int SI = Coupled.find_first(); SI >= 0; SI = Coupled.find_next(SI)) {
3548+
for (unsigned SI : Coupled.set_bits()) {
35493549
DEBUG(dbgs() << "testing subscript group " << SI << " { ");
35503550
SmallBitVector Group(Pair[SI].Group);
35513551
SmallBitVector Sivs(Pairs);
35523552
SmallBitVector Mivs(Pairs);
35533553
SmallBitVector ConstrainedLevels(MaxLevels + 1);
35543554
SmallVector<Subscript *, 4> PairsInGroup;
3555-
for (int SJ = Group.find_first(); SJ >= 0; SJ = Group.find_next(SJ)) {
3555+
for (unsigned SJ : Group.set_bits()) {
35563556
DEBUG(dbgs() << SJ << " ");
35573557
if (Pair[SJ].Classification == Subscript::SIV)
35583558
Sivs.set(SJ);
@@ -3564,7 +3564,7 @@ DependenceInfo::depends(Instruction *Src, Instruction *Dst,
35643564
DEBUG(dbgs() << "}\n");
35653565
while (Sivs.any()) {
35663566
bool Changed = false;
3567-
for (int SJ = Sivs.find_first(); SJ >= 0; SJ = Sivs.find_next(SJ)) {
3567+
for (unsigned SJ : Sivs.set_bits()) {
35683568
DEBUG(dbgs() << "testing subscript " << SJ << ", SIV\n");
35693569
// SJ is an SIV subscript that's part of the current coupled group
35703570
unsigned Level;
@@ -3588,7 +3588,7 @@ DependenceInfo::depends(Instruction *Src, Instruction *Dst,
35883588
DEBUG(dbgs() << " propagating\n");
35893589
DEBUG(dbgs() << "\tMivs = ");
35903590
DEBUG(dumpSmallBitVector(Mivs));
3591-
for (int SJ = Mivs.find_first(); SJ >= 0; SJ = Mivs.find_next(SJ)) {
3591+
for (unsigned SJ : Mivs.set_bits()) {
35923592
// SJ is an MIV subscript that's part of the current coupled group
35933593
DEBUG(dbgs() << "\tSJ = " << SJ << "\n");
35943594
if (propagate(Pair[SJ].Src, Pair[SJ].Dst, Pair[SJ].Loops,
@@ -3622,7 +3622,7 @@ DependenceInfo::depends(Instruction *Src, Instruction *Dst,
36223622
}
36233623

36243624
// test & propagate remaining RDIVs
3625-
for (int SJ = Mivs.find_first(); SJ >= 0; SJ = Mivs.find_next(SJ)) {
3625+
for (unsigned SJ : Mivs.set_bits()) {
36263626
if (Pair[SJ].Classification == Subscript::RDIV) {
36273627
DEBUG(dbgs() << "RDIV test\n");
36283628
if (testRDIV(Pair[SJ].Src, Pair[SJ].Dst, Result))
@@ -3635,7 +3635,7 @@ DependenceInfo::depends(Instruction *Src, Instruction *Dst,
36353635
// test remaining MIVs
36363636
// This code is temporary.
36373637
// Better to somehow test all remaining subscripts simultaneously.
3638-
for (int SJ = Mivs.find_first(); SJ >= 0; SJ = Mivs.find_next(SJ)) {
3638+
for (unsigned SJ : Mivs.set_bits()) {
36393639
if (Pair[SJ].Classification == Subscript::MIV) {
36403640
DEBUG(dbgs() << "MIV test\n");
36413641
if (testMIV(Pair[SJ].Src, Pair[SJ].Dst, Pair[SJ].Loops, Result))
@@ -3647,9 +3647,8 @@ DependenceInfo::depends(Instruction *Src, Instruction *Dst,
36473647

36483648
// update Result.DV from constraint vector
36493649
DEBUG(dbgs() << " updating\n");
3650-
for (int SJ = ConstrainedLevels.find_first(); SJ >= 0;
3651-
SJ = ConstrainedLevels.find_next(SJ)) {
3652-
if (SJ > (int)CommonLevels)
3650+
for (unsigned SJ : ConstrainedLevels.set_bits()) {
3651+
if (SJ > CommonLevels)
36533652
break;
36543653
updateDirection(Result.DV[SJ - 1], Constraints[SJ]);
36553654
if (Result.DV[SJ - 1].Direction == Dependence::DVEntry::NONE)
@@ -3859,7 +3858,7 @@ const SCEV *DependenceInfo::getSplitIteration(const Dependence &Dep,
38593858
NewConstraint.setAny(SE);
38603859

38613860
// test separable subscripts
3862-
for (int SI = Separable.find_first(); SI >= 0; SI = Separable.find_next(SI)) {
3861+
for (unsigned SI : Separable.set_bits()) {
38633862
switch (Pair[SI].Classification) {
38643863
case Subscript::SIV: {
38653864
unsigned Level;
@@ -3886,20 +3885,20 @@ const SCEV *DependenceInfo::getSplitIteration(const Dependence &Dep,
38863885
SmallVector<Constraint, 4> Constraints(MaxLevels + 1);
38873886
for (unsigned II = 0; II <= MaxLevels; ++II)
38883887
Constraints[II].setAny(SE);
3889-
for (int SI = Coupled.find_first(); SI >= 0; SI = Coupled.find_next(SI)) {
3888+
for (unsigned SI : Coupled.set_bits()) {
38903889
SmallBitVector Group(Pair[SI].Group);
38913890
SmallBitVector Sivs(Pairs);
38923891
SmallBitVector Mivs(Pairs);
38933892
SmallBitVector ConstrainedLevels(MaxLevels + 1);
3894-
for (int SJ = Group.find_first(); SJ >= 0; SJ = Group.find_next(SJ)) {
3893+
for (unsigned SJ : Group.set_bits()) {
38953894
if (Pair[SJ].Classification == Subscript::SIV)
38963895
Sivs.set(SJ);
38973896
else
38983897
Mivs.set(SJ);
38993898
}
39003899
while (Sivs.any()) {
39013900
bool Changed = false;
3902-
for (int SJ = Sivs.find_first(); SJ >= 0; SJ = Sivs.find_next(SJ)) {
3901+
for (unsigned SJ : Sivs.set_bits()) {
39033902
// SJ is an SIV subscript that's part of the current coupled group
39043903
unsigned Level;
39053904
const SCEV *SplitIter = nullptr;
@@ -3914,7 +3913,7 @@ const SCEV *DependenceInfo::getSplitIteration(const Dependence &Dep,
39143913
}
39153914
if (Changed) {
39163915
// propagate, possibly creating new SIVs and ZIVs
3917-
for (int SJ = Mivs.find_first(); SJ >= 0; SJ = Mivs.find_next(SJ)) {
3916+
for (unsigned SJ : Mivs.set_bits()) {
39183917
// SJ is an MIV subscript that's part of the current coupled group
39193918
if (propagate(Pair[SJ].Src, Pair[SJ].Dst,
39203919
Pair[SJ].Loops, Constraints, Result.Consistent)) {

llvm/lib/CodeGen/AggressiveAntiDepBreaker.cpp

+2-3
Original file line numberDiff line numberDiff line change
@@ -128,8 +128,7 @@ AggressiveAntiDepBreaker::AggressiveAntiDepBreaker(
128128
}
129129

130130
DEBUG(dbgs() << "AntiDep Critical-Path Registers:");
131-
DEBUG(for (int r = CriticalPathSet.find_first(); r != -1;
132-
r = CriticalPathSet.find_next(r))
131+
DEBUG(for (unsigned r : CriticalPathSet.set_bits())
133132
dbgs() << " " << TRI->getName(r));
134133
DEBUG(dbgs() << '\n');
135134
}
@@ -571,7 +570,7 @@ bool AggressiveAntiDepBreaker::FindSuitableFreeRegisters(
571570

572571
DEBUG({
573572
dbgs() << " ::";
574-
for (int r = BV.find_first(); r != -1; r = BV.find_next(r))
573+
for (unsigned r : BV.set_bits())
575574
dbgs() << " " << TRI->getName(r);
576575
dbgs() << "\n";
577576
});

llvm/lib/CodeGen/AsmPrinter/DbgValueHistoryCalculator.cpp

+1-2
Original file line numberDiff line numberDiff line change
@@ -209,8 +209,7 @@ void llvm::calculateDbgValueHistory(const MachineFunction *MF,
209209
} else if (MO.isRegMask()) {
210210
// If this is a register mask operand, clobber all debug values in
211211
// non-CSRs.
212-
for (int I = ChangingRegs.find_first(); I != -1;
213-
I = ChangingRegs.find_next(I)) {
212+
for (unsigned I : ChangingRegs.set_bits()) {
214213
// Don't consider SP to be clobbered by register masks.
215214
if (unsigned(I) != SP && TRI->isPhysicalRegister(I) &&
216215
MO.clobbersPhysReg(I)) {

llvm/lib/CodeGen/MachineVerifier.cpp

+1-1
Original file line numberDiff line numberDiff line change
@@ -760,7 +760,7 @@ MachineVerifier::visitMachineBasicBlockBefore(const MachineBasicBlock *MBB) {
760760

761761
const MachineFrameInfo &MFI = MF->getFrameInfo();
762762
BitVector PR = MFI.getPristineRegs(*MF);
763-
for (int I = PR.find_first(); I>0; I = PR.find_next(I)) {
763+
for (unsigned I : PR.set_bits()) {
764764
for (MCSubRegIterator SubRegs(I, TRI, /*IncludeSelf=*/true);
765765
SubRegs.isValid(); ++SubRegs)
766766
regsLive.insert(*SubRegs);

llvm/lib/CodeGen/RegAllocGreedy.cpp

+4-7
Original file line numberDiff line numberDiff line change
@@ -285,8 +285,7 @@ class RAGreedy : public MachineFunctionPass,
285285
// Set B[i] = C for every live bundle where B[i] was NoCand.
286286
unsigned getBundles(SmallVectorImpl<unsigned> &B, unsigned C) {
287287
unsigned Count = 0;
288-
for (int i = LiveBundles.find_first(); i >= 0;
289-
i = LiveBundles.find_next(i))
288+
for (unsigned i : LiveBundles.set_bits())
290289
if (B[i] == NoCand) {
291290
B[i] = C;
292291
Count++;
@@ -1162,9 +1161,8 @@ bool RAGreedy::calcCompactRegion(GlobalSplitCandidate &Cand) {
11621161
}
11631162

11641163
DEBUG({
1165-
for (int i = Cand.LiveBundles.find_first(); i>=0;
1166-
i = Cand.LiveBundles.find_next(i))
1167-
dbgs() << " EB#" << i;
1164+
for (int i : Cand.LiveBundles.set_bits())
1165+
dbgs() << " EB#" << i;
11681166
dbgs() << ".\n";
11691167
});
11701168
return true;
@@ -1482,8 +1480,7 @@ unsigned RAGreedy::calculateRegionSplitCost(LiveInterval &VirtReg,
14821480
DEBUG({
14831481
dbgs() << ", total = "; MBFI->printBlockFreq(dbgs(), Cost)
14841482
<< " with bundles";
1485-
for (int i = Cand.LiveBundles.find_first(); i>=0;
1486-
i = Cand.LiveBundles.find_next(i))
1483+
for (int i : Cand.LiveBundles.set_bits())
14871484
dbgs() << " EB#" << i;
14881485
dbgs() << ".\n";
14891486
});

llvm/lib/CodeGen/SpillPlacement.cpp

+2-2
Original file line numberDiff line numberDiff line change
@@ -310,7 +310,7 @@ void SpillPlacement::addLinks(ArrayRef<unsigned> Links) {
310310

311311
bool SpillPlacement::scanActiveBundles() {
312312
RecentPositive.clear();
313-
for (int n = ActiveNodes->find_first(); n>=0; n = ActiveNodes->find_next(n)) {
313+
for (unsigned n : ActiveNodes->set_bits()) {
314314
update(n);
315315
// A node that must spill, or a node without any links is not going to
316316
// change its value ever again, so exclude it from iterations.
@@ -365,7 +365,7 @@ SpillPlacement::finish() {
365365

366366
// Write preferences back to ActiveNodes.
367367
bool Perfect = true;
368-
for (int n = ActiveNodes->find_first(); n>=0; n = ActiveNodes->find_next(n))
368+
for (unsigned n : ActiveNodes->set_bits())
369369
if (!nodes[n].preferReg()) {
370370
ActiveNodes->reset(n);
371371
Perfect = false;

llvm/lib/CodeGen/StackColoring.cpp

+2-4
Original file line numberDiff line numberDiff line change
@@ -703,12 +703,10 @@ void StackColoring::calculateLiveIntervals(unsigned NumSlots) {
703703

704704
// Create the interval of the blocks that we previously found to be 'alive'.
705705
BlockLifetimeInfo &MBBLiveness = BlockLiveness[&MBB];
706-
for (int pos = MBBLiveness.LiveIn.find_first(); pos != -1;
707-
pos = MBBLiveness.LiveIn.find_next(pos)) {
706+
for (unsigned pos : MBBLiveness.LiveIn.set_bits()) {
708707
Starts[pos] = Indexes->getMBBStartIdx(&MBB);
709708
}
710-
for (int pos = MBBLiveness.LiveOut.find_first(); pos != -1;
711-
pos = MBBLiveness.LiveOut.find_next(pos)) {
709+
for (unsigned pos : MBBLiveness.LiveOut.set_bits()) {
712710
Finishes[pos] = Indexes->getMBBEndIdx(&MBB);
713711
}
714712

llvm/lib/CodeGen/TargetLoweringBase.cpp

+1-1
Original file line numberDiff line numberDiff line change
@@ -1312,7 +1312,7 @@ TargetLoweringBase::findRepresentativeClass(const TargetRegisterInfo *TRI,
13121312

13131313
// Find the first legal register class with the largest spill size.
13141314
const TargetRegisterClass *BestRC = RC;
1315-
for (int i = SuperRegRC.find_first(); i >= 0; i = SuperRegRC.find_next(i)) {
1315+
for (unsigned i : SuperRegRC.set_bits()) {
13161316
const TargetRegisterClass *SuperRC = TRI->getRegClass(i);
13171317
// We want the largest possible spill size.
13181318
if (TRI->getSpillSize(*SuperRC) <= TRI->getSpillSize(*BestRC))

llvm/lib/CodeGen/TargetRegisterInfo.cpp

+1-2
Original file line numberDiff line numberDiff line change
@@ -50,8 +50,7 @@ bool TargetRegisterInfo::checkAllSuperRegsMarked(const BitVector &RegisterSet,
5050
ArrayRef<MCPhysReg> Exceptions) const {
5151
// Check that all super registers of reserved regs are reserved as well.
5252
BitVector Checked(getNumRegs());
53-
for (int Reg = RegisterSet.find_first(); Reg>=0;
54-
Reg = RegisterSet.find_next(Reg)) {
53+
for (unsigned Reg : RegisterSet.set_bits()) {
5554
if (Checked[Reg])
5655
continue;
5756
for (MCSuperRegIterator SR(Reg, this); SR.isValid(); ++SR) {

llvm/lib/Target/AArch64/AArch64FrameLowering.cpp

+1-2
Original file line numberDiff line numberDiff line change
@@ -1158,8 +1158,7 @@ void AArch64FrameLowering::determineCalleeSaves(MachineFunction &MF,
11581158
}
11591159

11601160
DEBUG(dbgs() << "*** determineCalleeSaves\nUsed CSRs:";
1161-
for (int Reg = SavedRegs.find_first(); Reg != -1;
1162-
Reg = SavedRegs.find_next(Reg))
1161+
for (unsigned Reg : SavedRegs.set_bits())
11631162
dbgs() << ' ' << PrintReg(Reg, RegInfo);
11641163
dbgs() << "\n";);
11651164

llvm/lib/Target/ARM/Thumb1FrameLowering.cpp

+1-2
Original file line numberDiff line numberDiff line change
@@ -571,8 +571,7 @@ bool Thumb1FrameLowering::emitPopSpecialFixUp(MachineBasicBlock &MBB,
571571
GPRsNoLRSP.reset(ARM::LR);
572572
GPRsNoLRSP.reset(ARM::SP);
573573
GPRsNoLRSP.reset(ARM::PC);
574-
for (int Register = GPRsNoLRSP.find_first(); Register != -1;
575-
Register = GPRsNoLRSP.find_next(Register)) {
574+
for (unsigned Register : GPRsNoLRSP.set_bits()) {
576575
if (!UsedRegs.contains(Register)) {
577576
// Remember the first pop-friendly register and exit.
578577
if (PopFriendly.test(Register)) {

llvm/lib/Target/Mips/MipsDelaySlotFiller.cpp

+1-1
Original file line numberDiff line numberDiff line change
@@ -386,7 +386,7 @@ void RegDefsUses::setCallerSaved(const MachineInstr &MI) {
386386
void RegDefsUses::setUnallocatableRegs(const MachineFunction &MF) {
387387
BitVector AllocSet = TRI.getAllocatableSet(MF);
388388

389-
for (int R = AllocSet.find_first(); R != -1; R = AllocSet.find_next(R))
389+
for (unsigned R : AllocSet.set_bits())
390390
for (MCRegAliasIterator AI(R, &TRI, false); AI.isValid(); ++AI)
391391
AllocSet.set(*AI);
392392

llvm/lib/Target/WebAssembly/WebAssemblyRegColoring.cpp

+1-2
Original file line numberDiff line numberDiff line change
@@ -140,8 +140,7 @@ bool WebAssemblyRegColoring::runOnMachineFunction(MachineFunction &MF) {
140140

141141
// Check if it's possible to reuse any of the used colors.
142142
if (!MRI->isLiveIn(Old))
143-
for (int C(UsedColors.find_first()); C != -1;
144-
C = UsedColors.find_next(C)) {
143+
for (unsigned C : UsedColors.set_bits()) {
145144
if (MRI->getRegClass(SortedIntervals[C]->reg) != RC)
146145
continue;
147146
for (LiveInterval *OtherLI : Assignments[C])

0 commit comments

Comments
 (0)