Skip to content

Commit 25249e6

Browse files
authored
Merge pull request #16869 from davezarzycki/cache_bb_during_SILSuccessor_iteration
[SIL] Perf: Cache basic block during SILSuccessor iteration
2 parents 71e381e + 52fd7cb commit 25249e6

File tree

3 files changed

+28
-19
lines changed

3 files changed

+28
-19
lines changed

include/swift/SIL/SILInstruction.h

Lines changed: 9 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -8094,6 +8094,15 @@ inline EnumElementDecl **SelectEnumInstBase::getEnumElementDeclStorage() {
80948094
llvm_unreachable("Unhandled SelectEnumInstBase subclass");
80958095
}
80968096

8097+
inline void SILSuccessor::pred_iterator::cacheBasicBlock() {
8098+
if (Cur != nullptr) {
8099+
Block = Cur->ContainingInst->getParent();
8100+
assert(Block != nullptr);
8101+
} else {
8102+
Block = nullptr;
8103+
}
8104+
}
8105+
80978106
} // end swift namespace
80988107

80998108
//===----------------------------------------------------------------------===//

include/swift/SIL/SILSuccessor.h

Lines changed: 19 additions & 7 deletions
Original file line numberDiff line numberDiff line change
@@ -87,33 +87,45 @@ class SILSuccessor {
8787
class pred_iterator {
8888
SILSuccessor *Cur;
8989

90+
// Cache the basic block to avoid repeated pointer chasing.
91+
SILBasicBlock *Block;
92+
93+
void cacheBasicBlock();
94+
9095
public:
9196
using difference_type = std::ptrdiff_t;
9297
using value_type = SILBasicBlock *;
9398
using pointer = SILBasicBlock **;
9499
using reference = SILBasicBlock *&;
95100
using iterator_category = std::forward_iterator_tag;
96101

97-
pred_iterator(SILSuccessor *Cur = 0) : Cur(Cur) {}
102+
pred_iterator(SILSuccessor *Cur = nullptr) : Cur(Cur), Block(nullptr) {
103+
cacheBasicBlock();
104+
}
98105

99106
bool operator==(pred_iterator I2) const { return Cur == I2.Cur; }
100107
bool operator!=(pred_iterator I2) const { return Cur != I2.Cur; }
101108

102109
pred_iterator &operator++() {
103-
assert(Cur && "Trying to advance past end");
110+
assert(Cur != nullptr);
104111
Cur = Cur->Next;
112+
cacheBasicBlock();
105113
return *this;
106114
}
107115

108-
pred_iterator operator++(int) {
109-
pred_iterator copy = *this;
110-
++*this;
116+
pred_iterator operator+(unsigned distance) const {
117+
auto copy = *this;
118+
if (distance == 0)
119+
return copy;
120+
do {
121+
copy.Cur = Cur->Next;
122+
} while (--distance > 0);
123+
copy.cacheBasicBlock();
111124
return copy;
112125
}
113126

114127
SILSuccessor *getSuccessorRef() const { return Cur; }
115-
SILBasicBlock *operator*();
116-
const SILBasicBlock *operator*() const;
128+
SILBasicBlock *operator*() const { return Block; }
117129
};
118130
};
119131

lib/SIL/SILSuccessor.cpp

Lines changed: 0 additions & 12 deletions
Original file line numberDiff line numberDiff line change
@@ -37,15 +37,3 @@ void SILSuccessor::operator=(SILBasicBlock *BB) {
3737

3838
SuccessorBlock = BB;
3939
}
40-
41-
// Dereferencing the pred_iterator returns the predecessor's SILBasicBlock.
42-
SILBasicBlock *SILSuccessor::pred_iterator::operator*() {
43-
assert(Cur && "Can't deference end (or default constructed) iterator");
44-
return Cur->ContainingInst->getParent();
45-
}
46-
47-
// Dereferencing the pred_iterator returns the predecessor's SILBasicBlock.
48-
const SILBasicBlock *SILSuccessor::pred_iterator::operator*() const {
49-
assert(Cur && "Can't deference end (or default constructed) iterator");
50-
return Cur->ContainingInst->getParent();
51-
}

0 commit comments

Comments
 (0)