1 //===----- llvm/unittest/ADT/SCCIteratorTest.cpp - SCCIterator tests ------===//
3 // The LLVM Compiler Infrastructure
5 // This file is distributed under the University of Illinois Open Source
6 // License. See LICENSE.TXT for details.
8 //===----------------------------------------------------------------------===//
10 #include "llvm/ADT/SCCIterator.h"
11 #include "gtest/gtest.h"
12 #include "TestGraph.h"
19 TEST(SCCIteratorTest
, AllSmallGraphs
) {
20 // Test SCC computation against every graph with NUM_NODES nodes or less.
21 // Since SCC considers every node to have an implicit self-edge, we only
22 // create graphs for which every node has a self-edge.
24 #define NUM_GRAPHS (NUM_NODES * (NUM_NODES - 1))
25 typedef Graph
<NUM_NODES
> GT
;
27 /// Enumerate all graphs using NUM_GRAPHS bits.
28 static_assert(NUM_GRAPHS
< sizeof(unsigned) * CHAR_BIT
, "Too many graphs!");
29 for (unsigned GraphDescriptor
= 0; GraphDescriptor
< (1U << NUM_GRAPHS
);
33 // Add edges as specified by the descriptor.
34 unsigned DescriptorCopy
= GraphDescriptor
;
35 for (unsigned i
= 0; i
!= NUM_NODES
; ++i
)
36 for (unsigned j
= 0; j
!= NUM_NODES
; ++j
) {
37 // Always add a self-edge.
42 if (DescriptorCopy
& 1)
47 // Test the SCC logic on this graph.
49 /// NodesInSomeSCC - Those nodes which are in some SCC.
50 GT::NodeSubset NodesInSomeSCC
;
52 for (scc_iterator
<GT
> I
= scc_begin(G
), E
= scc_end(G
); I
!= E
; ++I
) {
53 const std::vector
<GT::NodeType
*> &SCC
= *I
;
55 // Get the nodes in this SCC as a NodeSubset rather than a vector.
56 GT::NodeSubset NodesInThisSCC
;
57 for (unsigned i
= 0, e
= SCC
.size(); i
!= e
; ++i
)
58 NodesInThisSCC
.AddNode(SCC
[i
]->first
);
60 // There should be at least one node in every SCC.
61 EXPECT_FALSE(NodesInThisSCC
.isEmpty());
63 // Check that every node in the SCC is reachable from every other node in
65 for (unsigned i
= 0; i
!= NUM_NODES
; ++i
)
66 if (NodesInThisSCC
.count(i
))
67 EXPECT_TRUE(NodesInThisSCC
.isSubsetOf(G
.NodesReachableFrom(i
)));
69 // OK, now that we now that every node in the SCC is reachable from every
70 // other, this means that the set of nodes reachable from any node in the
71 // SCC is the same as the set of nodes reachable from every node in the
72 // SCC. Check that for every node N not in the SCC but reachable from the
73 // SCC, no element of the SCC is reachable from N.
74 for (unsigned i
= 0; i
!= NUM_NODES
; ++i
)
75 if (NodesInThisSCC
.count(i
)) {
76 GT::NodeSubset NodesReachableFromSCC
= G
.NodesReachableFrom(i
);
77 GT::NodeSubset ReachableButNotInSCC
=
78 NodesReachableFromSCC
.Meet(NodesInThisSCC
.Complement());
80 for (unsigned j
= 0; j
!= NUM_NODES
; ++j
)
81 if (ReachableButNotInSCC
.count(j
))
82 EXPECT_TRUE(G
.NodesReachableFrom(j
).Meet(NodesInThisSCC
).isEmpty());
84 // The result must be the same for all other nodes in this SCC, so
85 // there is no point in checking them.
89 // This is indeed a SCC: a maximal set of nodes for which each node is
90 // reachable from every other.
92 // Check that we didn't already see this SCC.
93 EXPECT_TRUE(NodesInSomeSCC
.Meet(NodesInThisSCC
).isEmpty());
95 NodesInSomeSCC
= NodesInSomeSCC
.Join(NodesInThisSCC
);
97 // Check a property that is specific to the LLVM SCC iterator and
98 // guaranteed by it: if a node in SCC S1 has an edge to a node in
99 // SCC S2, then S1 is visited *after* S2. This means that the set
100 // of nodes reachable from this SCC must be contained either in the
101 // union of this SCC and all previously visited SCC's.
103 for (unsigned i
= 0; i
!= NUM_NODES
; ++i
)
104 if (NodesInThisSCC
.count(i
)) {
105 GT::NodeSubset NodesReachableFromSCC
= G
.NodesReachableFrom(i
);
106 EXPECT_TRUE(NodesReachableFromSCC
.isSubsetOf(NodesInSomeSCC
));
107 // The result must be the same for all other nodes in this SCC, so
108 // there is no point in checking them.
113 // Finally, check that the nodes in some SCC are exactly those that are
114 // reachable from the initial node.
115 EXPECT_EQ(NodesInSomeSCC
, G
.NodesReachableFrom(0));