1 //===- PostOrderIteratorTest.cpp - PostOrderIterator unit tests -----------===//
3 // Part of the LLVM Project, under the Apache License v2.0 with LLVM Exceptions.
4 // See https://llvm.org/LICENSE.txt for license information.
5 // SPDX-License-Identifier: Apache-2.0 WITH LLVM-exception
7 //===----------------------------------------------------------------------===//
8 #include "llvm/ADT/PostOrderIterator.h"
9 #include "llvm/IR/BasicBlock.h"
10 #include "llvm/IR/CFG.h"
11 #include "gtest/gtest.h"
12 #include "TestGraph.h"
16 #include <type_traits>
24 // Whether we're able to compile
25 TEST(PostOrderIteratorTest
, Compiles
) {
26 typedef SmallPtrSet
<void *, 4> ExtSetTy
;
28 // Tests that template specializations are kept up to date
30 po_iterator_storage
<std::set
<void *>, false> PIS
;
31 PIS
.insertEdge(std::optional
<void *>(), Null
);
33 po_iterator_storage
<ExtSetTy
, true> PISExt(Ext
);
34 PIS
.insertEdge(std::optional
<void *>(), Null
);
36 // Test above, but going through po_iterator (which inherits from template
38 BasicBlock
*NullBB
= nullptr;
39 auto PI
= po_end(NullBB
);
40 PI
.insertEdge(std::optional
<BasicBlock
*>(), NullBB
);
41 auto PIExt
= po_ext_end(NullBB
, Ext
);
42 PIExt
.insertEdge(std::optional
<BasicBlock
*>(), NullBB
);
46 std::is_convertible_v
<decltype(*std::declval
<po_iterator
<Graph
<3>>>()),
47 typename po_iterator
<Graph
<3>>::reference
>);
49 // Test post-order and reverse post-order traversals for simple graph type.
50 TEST(PostOrderIteratorTest
, PostOrderAndReversePostOrderTraverrsal
) {
61 SmallVector
<int> FromIterator
;
62 for (auto N
: post_order(G
))
63 FromIterator
.push_back(N
->first
);
64 EXPECT_EQ(6u, FromIterator
.size());
65 EXPECT_EQ(4, FromIterator
[0]);
66 EXPECT_EQ(1, FromIterator
[1]);
67 EXPECT_EQ(5, FromIterator
[2]);
68 EXPECT_EQ(2, FromIterator
[3]);
69 EXPECT_EQ(3, FromIterator
[4]);
70 EXPECT_EQ(0, FromIterator
[5]);
73 ReversePostOrderTraversal
<Graph
<6>> RPOT(G
);
75 FromIterator
.push_back(N
->first
);
76 EXPECT_EQ(6u, FromIterator
.size());
77 EXPECT_EQ(0, FromIterator
[0]);
78 EXPECT_EQ(3, FromIterator
[1]);
79 EXPECT_EQ(2, FromIterator
[2]);
80 EXPECT_EQ(5, FromIterator
[3]);
81 EXPECT_EQ(1, FromIterator
[4]);
82 EXPECT_EQ(4, FromIterator
[5]);
85 // po_iterator should be (at-least) a forward-iterator
86 static_assert(std::is_base_of_v
<std::forward_iterator_tag
,
87 po_iterator
<Graph
<4>>::iterator_category
>);
89 // po_ext_iterator cannot provide multi-pass guarantee, therefore its only
91 static_assert(std::is_same_v
<po_ext_iterator
<Graph
<4>>::iterator_category
,
92 std::input_iterator_tag
>);
94 TEST(PostOrderIteratorTest
, MultiPassSafeWithInternalSet
) {
100 std::array
<decltype(G
)::NodeType
*, 4> NodesFirstPass
, NodesSecondPass
;
102 auto B
= po_begin(G
), E
= po_end(G
);
105 for (auto It
= B
; It
!= E
; ++It
)
106 NodesFirstPass
[I
++] = *It
;
109 for (auto It
= B
; It
!= E
; ++It
)
110 NodesSecondPass
[I
++] = *It
;
112 EXPECT_EQ(NodesFirstPass
, NodesSecondPass
);