1 //===- unittest/TableGen/AutomataTest.cpp - DFA 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 //===----------------------------------------------------------------------===//
9 #include "llvm/ADT/ArrayRef.h"
10 #include "llvm/ADT/STLExtras.h"
11 #include "llvm/Support/Debug.h"
12 #include "llvm/Support/Automaton.h"
13 #include "gmock/gmock.h"
14 #include "gtest/gtest.h"
17 using testing::ContainerEq
;
18 using testing::UnorderedElementsAre
;
20 // Bring in the enums created by SearchableTables.td.
21 #define GET_SymKind_DECL
22 #define GET_BinRequirementKindEnum_DECL
23 #include "AutomataTables.inc"
25 // And bring in the automata from Automata.td.
26 #define GET_SimpleAutomaton_DECL
27 #define GET_TupleAutomaton_DECL
28 #define GET_NfaAutomaton_DECL
29 #define GET_BinPackerAutomaton_DECL
30 #include "AutomataAutomata.inc"
32 TEST(Automata
, SimpleAutomatonAcceptsFromInitialState
) {
33 Automaton
<SymKind
> A(makeArrayRef(SimpleAutomatonTransitions
));
34 EXPECT_TRUE(A
.add(SK_a
));
36 EXPECT_TRUE(A
.add(SK_b
));
38 EXPECT_TRUE(A
.add(SK_c
));
40 EXPECT_FALSE(A
.add(SK_d
));
43 TEST(Automata
, SimpleAutomatonAcceptsSequences
) {
44 Automaton
<SymKind
> A(makeArrayRef(SimpleAutomatonTransitions
));
45 // Test sequence <a b>
47 EXPECT_TRUE(A
.add(SK_a
));
48 EXPECT_TRUE(A
.add(SK_b
));
50 // Test sequence <a c> is rejected (c cannot get bit 0b10);
52 EXPECT_TRUE(A
.add(SK_a
));
53 EXPECT_FALSE(A
.add(SK_c
));
55 // Symmetric test: sequence <c a> is rejected.
57 EXPECT_TRUE(A
.add(SK_c
));
58 EXPECT_FALSE(A
.add(SK_a
));
61 TEST(Automata
, TupleAutomatonAccepts
) {
62 Automaton
<TupleAutomatonAction
> A(makeArrayRef(TupleAutomatonTransitions
));
65 A
.add(TupleAutomatonAction
{SK_a
, SK_b
, "yeet"}));
68 A
.add(TupleAutomatonAction
{SK_a
, SK_a
, "yeet"}));
71 A
.add(TupleAutomatonAction
{SK_a
, SK_b
, "feet"}));
74 A
.add(TupleAutomatonAction
{SK_b
, SK_b
, "foo"}));
77 TEST(Automata
, NfaAutomatonAccepts
) {
78 Automaton
<SymKind
> A(makeArrayRef(NfaAutomatonTransitions
));
80 // Test sequences <a a>, <a b>, <b a>, <b b>. All should be accepted.
82 EXPECT_TRUE(A
.add(SK_a
));
83 EXPECT_TRUE(A
.add(SK_a
));
85 EXPECT_TRUE(A
.add(SK_a
));
86 EXPECT_TRUE(A
.add(SK_b
));
88 EXPECT_TRUE(A
.add(SK_b
));
89 EXPECT_TRUE(A
.add(SK_a
));
91 EXPECT_TRUE(A
.add(SK_b
));
92 EXPECT_TRUE(A
.add(SK_b
));
94 // Expect that <b b b> is not accepted.
96 EXPECT_TRUE(A
.add(SK_b
));
97 EXPECT_TRUE(A
.add(SK_b
));
98 EXPECT_FALSE(A
.add(SK_b
));
101 TEST(Automata
, BinPackerAutomatonAccepts
) {
102 Automaton
<BinPackerAutomatonAction
> A(makeArrayRef(BinPackerAutomatonTransitions
));
104 // Expect that we can pack two double-bins in 0-4, then no more in 0-4.
106 EXPECT_TRUE(A
.add(BRK_0_to_4_dbl
));
107 EXPECT_TRUE(A
.add(BRK_0_to_4_dbl
));
108 EXPECT_FALSE(A
.add(BRK_0_to_4
));
110 // Expect that we can pack two double-bins in 0-4, two more in 0-6 then no
113 EXPECT_TRUE(A
.add(BRK_0_to_4_dbl
));
114 EXPECT_TRUE(A
.add(BRK_0_to_4_dbl
));
115 EXPECT_TRUE(A
.add(BRK_0_to_6
));
116 EXPECT_TRUE(A
.add(BRK_0_to_6
));
117 EXPECT_FALSE(A
.add(BRK_0_to_6
));
119 // Expect that we can pack BRK_0_to_6 five times to occupy five bins, then
120 // cannot allocate any double-bins.
122 for (unsigned I
= 0; I
< 5; ++I
)
123 EXPECT_TRUE(A
.add(BRK_0_to_6
));
124 EXPECT_FALSE(A
.add(BRK_0_to_6_dbl
));
127 // The state we defined in TableGen uses the least significant 6 bits to represent a bin state.
128 #define BINS(a, b, c, d, e, f) \
129 ((a << 5) | (b << 4) | (c << 3) | (d << 2) | (e << 1) | (f << 0))
131 TEST(Automata
, BinPackerAutomatonExplains
) {
132 Automaton
<BinPackerAutomatonAction
> A(makeArrayRef(BinPackerAutomatonTransitions
),
133 makeArrayRef(BinPackerAutomatonTransitionInfo
));
134 // Pack two double-bins in 0-4, then a single bin in 0-6.
135 EXPECT_TRUE(A
.add(BRK_0_to_4_dbl
));
136 EXPECT_TRUE(A
.add(BRK_0_to_4_dbl
));
137 EXPECT_TRUE(A
.add(BRK_0_to_6
));
140 UnorderedElementsAre(
141 // Allocate {0,1} first, then 6.
142 ContainerEq(NfaPath
{BINS(0, 0, 0, 0, 1, 1), BINS(0, 0, 1, 1, 1, 1),
143 BINS(1, 0, 1, 1, 1, 1)}),
144 // Allocate {0,1} first, then 5.
145 ContainerEq(NfaPath
{BINS(0, 0, 0, 0, 1, 1), BINS(0, 0, 1, 1, 1, 1),
146 BINS(0, 1, 1, 1, 1, 1)}),
147 // Allocate {2,3} first, then 6.
148 ContainerEq(NfaPath
{BINS(0, 0, 1, 1, 0, 0), BINS(0, 0, 1, 1, 1, 1),
149 BINS(1, 0, 1, 1, 1, 1)}),
150 // Allocate {2,3} first, then 5.
151 ContainerEq(NfaPath
{BINS(0, 0, 1, 1, 0, 0), BINS(0, 0, 1, 1, 1, 1),
152 BINS(0, 1, 1, 1, 1, 1)})));