Reapply [PostOrderIterator] Store end iterator (NFC)

Replace structured bindings with std::get, as they apparently
break the modules build.

-----

Store the end iterator on the VisitStack, instead of recomputing
it every time, as doing so is not free.
This commit is contained in:
Nikita Popov 2023-05-22 15:04:18 +02:00
parent 211055c744
commit 18a920978f

View File

@ -106,13 +106,14 @@ private:
using NodeRef = typename GT::NodeRef;
using ChildItTy = typename GT::ChildIteratorType;
// VisitStack - Used to maintain the ordering. Top = current block
// First element is basic block pointer, second is the 'next child' to visit
SmallVector<std::pair<NodeRef, ChildItTy>, 8> VisitStack;
/// Used to maintain the ordering.
/// First element is basic block pointer, second is iterator for the next
/// child to visit, third is the end iterator.
SmallVector<std::tuple<NodeRef, ChildItTy, ChildItTy>, 8> VisitStack;
po_iterator(NodeRef BB) {
this->insertEdge(std::optional<NodeRef>(), BB);
VisitStack.push_back(std::make_pair(BB, GT::child_begin(BB)));
VisitStack.emplace_back(BB, GT::child_begin(BB), GT::child_end(BB));
traverseChild();
}
@ -121,7 +122,7 @@ private:
po_iterator(NodeRef BB, SetType &S)
: po_iterator_storage<SetType, ExtStorage>(S) {
if (this->insertEdge(std::optional<NodeRef>(), BB)) {
VisitStack.push_back(std::make_pair(BB, GT::child_begin(BB)));
VisitStack.emplace_back(BB, GT::child_begin(BB), GT::child_end(BB));
traverseChild();
}
}
@ -131,12 +132,14 @@ private:
} // End is when stack is empty.
void traverseChild() {
while (VisitStack.back().second != GT::child_end(VisitStack.back().first)) {
NodeRef BB = *VisitStack.back().second++;
if (this->insertEdge(std::optional<NodeRef>(VisitStack.back().first),
BB)) {
while (true) {
auto &Entry = VisitStack.back();
if (std::get<1>(Entry) == std::get<2>(Entry))
break;
NodeRef BB = *std::get<1>(Entry)++;
if (this->insertEdge(std::optional<NodeRef>(std::get<0>(Entry)), BB)) {
// If the block is not visited...
VisitStack.push_back(std::make_pair(BB, GT::child_begin(BB)));
VisitStack.emplace_back(BB, GT::child_begin(BB), GT::child_end(BB));
}
}
}
@ -158,7 +161,7 @@ public:
}
bool operator!=(const po_iterator &x) const { return !(*this == x); }
const NodeRef &operator*() const { return VisitStack.back().first; }
const NodeRef &operator*() const { return std::get<0>(VisitStack.back()); }
// This is a nonstandard operator-> that dereferences the pointer an extra
// time... so that you can actually call methods ON the BasicBlock, because
@ -167,7 +170,7 @@ public:
NodeRef operator->() const { return **this; }
po_iterator &operator++() { // Preincrement
this->finishPostorder(VisitStack.back().first);
this->finishPostorder(std::get<0>(VisitStack.back()));
VisitStack.pop_back();
if (!VisitStack.empty())
traverseChild();