[PATCH] D100169: [ADT] Update RPOT to work with specializations of different types.
Florian Hahn via Phabricator via llvm-commits
llvm-commits at lists.llvm.org
Fri Apr 9 03:08:48 PDT 2021
fhahn created this revision.
fhahn added reviewers: dexonsmith, dblaikie, bkramer, nhaehnle.
fhahn requested review of this revision.
Herald added a project: LLVM.
At the moment, ReversePostOrderTraversal performs a post-order walk on
the entry node of the passed in graph, rather than the graph type
itself.
If GT::NodeRef is the same as GraphT, everything works as expected and
this is the case for the current uses in-tree. But it does not work as
expected if GraphT != GT::NodeRef. In that case, we either fail to build
(if there is no GraphTrait specialization for GT:NodeRef) or we pick the
GraphTrait specialization for GT::NodeRef, instead of the specialization
of GraphT.
Both the depth-first and post-order iterators pick the expected
specalization and this patch updates ReversePostOrderTraversal to
delegate to po_begin & po_end to pick the right specialization, rather
than forcing using GraphTraits<GT::NodeRef>, by first getting the entry
node.
This makes `ReversePostOrderTraversal<Graph<6>> RPOT(G);` build and
work as expected in the test.
The patch also updates a couple of functions that unnecessarily took the
input graph by value, when it was not needed. They can take the graph by
const-reference instead, which does not require GraphT to provide a copy
constructor. This technically is a separate change, but is required to
be able to use Graph<> from TestGraph in the test, because it does not
provide a copy constructor. If desired, I can split this out as a
separate change.
Repository:
rG LLVM Github Monorepo
https://reviews.llvm.org/D100169
Files:
llvm/include/llvm/ADT/PostOrderIterator.h
llvm/unittests/ADT/PostOrderIteratorTest.cpp
Index: llvm/unittests/ADT/PostOrderIteratorTest.cpp
===================================================================
--- llvm/unittests/ADT/PostOrderIteratorTest.cpp
+++ llvm/unittests/ADT/PostOrderIteratorTest.cpp
@@ -6,6 +6,7 @@
//
//===----------------------------------------------------------------------===//
#include "llvm/ADT/PostOrderIterator.h"
+#include "TestGraph.h"
#include "llvm/IR/BasicBlock.h"
#include "llvm/IR/CFG.h"
#include "gtest/gtest.h"
@@ -33,4 +34,40 @@
auto PIExt = po_ext_end(NullBB, Ext);
PIExt.insertEdge(Optional<BasicBlock *>(), NullBB);
}
+
+// Test post-order and reverse post-order traversals for simple graph type.
+TEST(PostOrderIteratorTest, PostOrderAndReversePostOrderTraverrsal) {
+ Graph<6> G;
+ G.AddEdge(0, 1);
+ G.AddEdge(0, 2);
+ G.AddEdge(0, 3);
+ G.AddEdge(1, 4);
+ G.AddEdge(2, 5);
+ G.AddEdge(5, 2);
+ G.AddEdge(2, 4);
+ G.AddEdge(1, 4);
+
+ SmallVector<int> FromIterator;
+ for (auto N : post_order(G))
+ FromIterator.push_back(N->first);
+ EXPECT_EQ(6u, FromIterator.size());
+ EXPECT_EQ(4, FromIterator[0]);
+ EXPECT_EQ(1, FromIterator[1]);
+ EXPECT_EQ(5, FromIterator[2]);
+ EXPECT_EQ(2, FromIterator[3]);
+ EXPECT_EQ(3, FromIterator[4]);
+ EXPECT_EQ(0, FromIterator[5]);
+ FromIterator.clear();
+
+ ReversePostOrderTraversal<Graph<6>> RPOT(G);
+ for (auto N : RPOT)
+ FromIterator.push_back(N->first);
+ EXPECT_EQ(6u, FromIterator.size());
+ EXPECT_EQ(0, FromIterator[0]);
+ EXPECT_EQ(3, FromIterator[1]);
+ EXPECT_EQ(2, FromIterator[2]);
+ EXPECT_EQ(5, FromIterator[3]);
+ EXPECT_EQ(1, FromIterator[4]);
+ EXPECT_EQ(4, FromIterator[5]);
+}
}
Index: llvm/include/llvm/ADT/PostOrderIterator.h
===================================================================
--- llvm/include/llvm/ADT/PostOrderIterator.h
+++ llvm/include/llvm/ADT/PostOrderIterator.h
@@ -138,15 +138,15 @@
using pointer = typename super::pointer;
// Provide static "constructors"...
- static po_iterator begin(GraphT G) {
+ static po_iterator begin(const GraphT &G) {
return po_iterator(GT::getEntryNode(G));
}
- static po_iterator end(GraphT G) { return po_iterator(); }
+ static po_iterator end(const GraphT &G) { return po_iterator(); }
- static po_iterator begin(GraphT G, SetType &S) {
+ static po_iterator begin(const GraphT &G, SetType &S) {
return po_iterator(GT::getEntryNode(G), S);
}
- static po_iterator end(GraphT G, SetType &S) { return po_iterator(S); }
+ static po_iterator end(const GraphT &G, SetType &S) { return po_iterator(S); }
bool operator==(const po_iterator &x) const {
return VisitStack == x.VisitStack;
@@ -290,15 +290,15 @@
std::vector<NodeRef> Blocks; // Block list in normal PO order
- void Initialize(NodeRef BB) {
- std::copy(po_begin(BB), po_end(BB), std::back_inserter(Blocks));
+ void Initialize(const GraphT &G) {
+ std::copy(po_begin(G), po_end(G), std::back_inserter(Blocks));
}
public:
using rpo_iterator = typename std::vector<NodeRef>::reverse_iterator;
using const_rpo_iterator = typename std::vector<NodeRef>::const_reverse_iterator;
- ReversePostOrderTraversal(GraphT G) { Initialize(GT::getEntryNode(G)); }
+ ReversePostOrderTraversal(const GraphT &G) { Initialize(G); }
// Because we want a reverse post order, use reverse iterators from the vector
rpo_iterator begin() { return Blocks.rbegin(); }
-------------- next part --------------
A non-text attachment was scrubbed...
Name: D100169.336370.patch
Type: text/x-patch
Size: 3402 bytes
Desc: not available
URL: <http://lists.llvm.org/pipermail/llvm-commits/attachments/20210409/8bc8dcfe/attachment.bin>
More information about the llvm-commits
mailing list