1e6674010SJames Molloy //===- unittest/TableGen/AutomataTest.cpp - DFA tests ---------------------===//
2e6674010SJames Molloy //
3e6674010SJames Molloy // Part of the LLVM Project, under the Apache License v2.0 with LLVM Exceptions.
4e6674010SJames Molloy // See https://llvm.org/LICENSE.txt for license information.
5e6674010SJames Molloy // SPDX-License-Identifier: Apache-2.0 WITH LLVM-exception
6e6674010SJames Molloy //
7e6674010SJames Molloy //===----------------------------------------------------------------------===//
8e6674010SJames Molloy
9e6674010SJames Molloy #include "llvm/ADT/STLExtras.h"
10e6674010SJames Molloy #include "llvm/Support/Debug.h"
11e6674010SJames Molloy #include "llvm/Support/Automaton.h"
12e6674010SJames Molloy #include "gmock/gmock.h"
13e6674010SJames Molloy #include "gtest/gtest.h"
14e6674010SJames Molloy
15e6674010SJames Molloy using namespace llvm;
16e6674010SJames Molloy using testing::ContainerEq;
17e6674010SJames Molloy using testing::UnorderedElementsAre;
18e6674010SJames Molloy
19e6674010SJames Molloy // Bring in the enums created by SearchableTables.td.
20e6674010SJames Molloy #define GET_SymKind_DECL
21e6674010SJames Molloy #define GET_BinRequirementKindEnum_DECL
22e6674010SJames Molloy #include "AutomataTables.inc"
23e6674010SJames Molloy
24e6674010SJames Molloy // And bring in the automata from Automata.td.
25e6674010SJames Molloy #define GET_SimpleAutomaton_DECL
26e6674010SJames Molloy #define GET_TupleAutomaton_DECL
27e6674010SJames Molloy #define GET_NfaAutomaton_DECL
28e6674010SJames Molloy #define GET_BinPackerAutomaton_DECL
29e6674010SJames Molloy #include "AutomataAutomata.inc"
30e6674010SJames Molloy
TEST(Automata,SimpleAutomatonAcceptsFromInitialState)31e6674010SJames Molloy TEST(Automata, SimpleAutomatonAcceptsFromInitialState) {
32*38818b60Sserge-sans-paille Automaton<SymKind> A{ArrayRef(SimpleAutomatonTransitions)};
33e6674010SJames Molloy EXPECT_TRUE(A.add(SK_a));
34e6674010SJames Molloy A.reset();
35e6674010SJames Molloy EXPECT_TRUE(A.add(SK_b));
36e6674010SJames Molloy A.reset();
37e6674010SJames Molloy EXPECT_TRUE(A.add(SK_c));
38e6674010SJames Molloy A.reset();
39e6674010SJames Molloy EXPECT_FALSE(A.add(SK_d));
40e6674010SJames Molloy }
41e6674010SJames Molloy
TEST(Automata,SimpleAutomatonAcceptsSequences)42e6674010SJames Molloy TEST(Automata, SimpleAutomatonAcceptsSequences) {
43*38818b60Sserge-sans-paille Automaton<SymKind> A{ArrayRef(SimpleAutomatonTransitions)};
44e6674010SJames Molloy // Test sequence <a b>
45e6674010SJames Molloy A.reset();
46e6674010SJames Molloy EXPECT_TRUE(A.add(SK_a));
47e6674010SJames Molloy EXPECT_TRUE(A.add(SK_b));
48e6674010SJames Molloy
49e6674010SJames Molloy // Test sequence <a c> is rejected (c cannot get bit 0b10);
50e6674010SJames Molloy A.reset();
51e6674010SJames Molloy EXPECT_TRUE(A.add(SK_a));
52e6674010SJames Molloy EXPECT_FALSE(A.add(SK_c));
53e6674010SJames Molloy
54e6674010SJames Molloy // Symmetric test: sequence <c a> is rejected.
55e6674010SJames Molloy A.reset();
56e6674010SJames Molloy EXPECT_TRUE(A.add(SK_c));
57e6674010SJames Molloy EXPECT_FALSE(A.add(SK_a));
58e6674010SJames Molloy }
59e6674010SJames Molloy
TEST(Automata,TupleAutomatonAccepts)60e6674010SJames Molloy TEST(Automata, TupleAutomatonAccepts) {
61*38818b60Sserge-sans-paille Automaton<TupleAutomatonAction> A{ArrayRef(TupleAutomatonTransitions)};
62e6674010SJames Molloy A.reset();
63e6674010SJames Molloy EXPECT_TRUE(
64b1f0183eSJames Molloy A.add(TupleAutomatonAction{SK_a, SK_b, "yeet"}));
65e6674010SJames Molloy A.reset();
66e6674010SJames Molloy EXPECT_FALSE(
67b1f0183eSJames Molloy A.add(TupleAutomatonAction{SK_a, SK_a, "yeet"}));
68e6674010SJames Molloy A.reset();
69e6674010SJames Molloy EXPECT_FALSE(
70b1f0183eSJames Molloy A.add(TupleAutomatonAction{SK_a, SK_b, "feet"}));
71e6674010SJames Molloy A.reset();
72e6674010SJames Molloy EXPECT_TRUE(
73b1f0183eSJames Molloy A.add(TupleAutomatonAction{SK_b, SK_b, "foo"}));
74e6674010SJames Molloy }
75e6674010SJames Molloy
TEST(Automata,NfaAutomatonAccepts)76e6674010SJames Molloy TEST(Automata, NfaAutomatonAccepts) {
77*38818b60Sserge-sans-paille Automaton<SymKind> A{ArrayRef(NfaAutomatonTransitions)};
78e6674010SJames Molloy
79e6674010SJames Molloy // Test sequences <a a>, <a b>, <b a>, <b b>. All should be accepted.
80e6674010SJames Molloy A.reset();
81e6674010SJames Molloy EXPECT_TRUE(A.add(SK_a));
82e6674010SJames Molloy EXPECT_TRUE(A.add(SK_a));
83e6674010SJames Molloy A.reset();
84e6674010SJames Molloy EXPECT_TRUE(A.add(SK_a));
85e6674010SJames Molloy EXPECT_TRUE(A.add(SK_b));
86e6674010SJames Molloy A.reset();
87e6674010SJames Molloy EXPECT_TRUE(A.add(SK_b));
88e6674010SJames Molloy EXPECT_TRUE(A.add(SK_a));
89e6674010SJames Molloy A.reset();
90e6674010SJames Molloy EXPECT_TRUE(A.add(SK_b));
91e6674010SJames Molloy EXPECT_TRUE(A.add(SK_b));
92e6674010SJames Molloy
93e6674010SJames Molloy // Expect that <b b b> is not accepted.
94e6674010SJames Molloy A.reset();
95e6674010SJames Molloy EXPECT_TRUE(A.add(SK_b));
96e6674010SJames Molloy EXPECT_TRUE(A.add(SK_b));
97e6674010SJames Molloy EXPECT_FALSE(A.add(SK_b));
98e6674010SJames Molloy }
99e6674010SJames Molloy
TEST(Automata,BinPackerAutomatonAccepts)100e6674010SJames Molloy TEST(Automata, BinPackerAutomatonAccepts) {
101*38818b60Sserge-sans-paille Automaton<BinPackerAutomatonAction> A{
102*38818b60Sserge-sans-paille ArrayRef(BinPackerAutomatonTransitions)};
103e6674010SJames Molloy
104e6674010SJames Molloy // Expect that we can pack two double-bins in 0-4, then no more in 0-4.
105e6674010SJames Molloy A.reset();
106e6674010SJames Molloy EXPECT_TRUE(A.add(BRK_0_to_4_dbl));
107e6674010SJames Molloy EXPECT_TRUE(A.add(BRK_0_to_4_dbl));
108e6674010SJames Molloy EXPECT_FALSE(A.add(BRK_0_to_4));
109e6674010SJames Molloy
110e6674010SJames Molloy // Expect that we can pack two double-bins in 0-4, two more in 0-6 then no
111e6674010SJames Molloy // more.
112e6674010SJames Molloy A.reset();
113e6674010SJames Molloy EXPECT_TRUE(A.add(BRK_0_to_4_dbl));
114e6674010SJames Molloy EXPECT_TRUE(A.add(BRK_0_to_4_dbl));
115e6674010SJames Molloy EXPECT_TRUE(A.add(BRK_0_to_6));
116e6674010SJames Molloy EXPECT_TRUE(A.add(BRK_0_to_6));
117e6674010SJames Molloy EXPECT_FALSE(A.add(BRK_0_to_6));
118e6674010SJames Molloy
119e6674010SJames Molloy // Expect that we can pack BRK_0_to_6 five times to occupy five bins, then
120e6674010SJames Molloy // cannot allocate any double-bins.
121e6674010SJames Molloy A.reset();
122e6674010SJames Molloy for (unsigned I = 0; I < 5; ++I)
123e6674010SJames Molloy EXPECT_TRUE(A.add(BRK_0_to_6));
124e6674010SJames Molloy EXPECT_FALSE(A.add(BRK_0_to_6_dbl));
125e6674010SJames Molloy }
126e6674010SJames Molloy
127e6674010SJames Molloy // The state we defined in TableGen uses the least significant 6 bits to represent a bin state.
128e6674010SJames Molloy #define BINS(a, b, c, d, e, f) \
129e6674010SJames Molloy ((a << 5) | (b << 4) | (c << 3) | (d << 2) | (e << 1) | (f << 0))
130e6674010SJames Molloy
TEST(Automata,BinPackerAutomatonExplains)131e6674010SJames Molloy TEST(Automata, BinPackerAutomatonExplains) {
132*38818b60Sserge-sans-paille Automaton<BinPackerAutomatonAction> A{
133*38818b60Sserge-sans-paille ArrayRef(BinPackerAutomatonTransitions),
134*38818b60Sserge-sans-paille ArrayRef(BinPackerAutomatonTransitionInfo)};
135e6674010SJames Molloy // Pack two double-bins in 0-4, then a single bin in 0-6.
136e6674010SJames Molloy EXPECT_TRUE(A.add(BRK_0_to_4_dbl));
137e6674010SJames Molloy EXPECT_TRUE(A.add(BRK_0_to_4_dbl));
138e6674010SJames Molloy EXPECT_TRUE(A.add(BRK_0_to_6));
139e6674010SJames Molloy EXPECT_THAT(
140e6674010SJames Molloy A.getNfaPaths(),
141e6674010SJames Molloy UnorderedElementsAre(
142e6674010SJames Molloy // Allocate {0,1} first, then 6.
143e6674010SJames Molloy ContainerEq(NfaPath{BINS(0, 0, 0, 0, 1, 1), BINS(0, 0, 1, 1, 1, 1),
144e6674010SJames Molloy BINS(1, 0, 1, 1, 1, 1)}),
145e6674010SJames Molloy // Allocate {0,1} first, then 5.
146e6674010SJames Molloy ContainerEq(NfaPath{BINS(0, 0, 0, 0, 1, 1), BINS(0, 0, 1, 1, 1, 1),
147e6674010SJames Molloy BINS(0, 1, 1, 1, 1, 1)}),
148e6674010SJames Molloy // Allocate {2,3} first, then 6.
149e6674010SJames Molloy ContainerEq(NfaPath{BINS(0, 0, 1, 1, 0, 0), BINS(0, 0, 1, 1, 1, 1),
150e6674010SJames Molloy BINS(1, 0, 1, 1, 1, 1)}),
151e6674010SJames Molloy // Allocate {2,3} first, then 5.
152e6674010SJames Molloy ContainerEq(NfaPath{BINS(0, 0, 1, 1, 0, 0), BINS(0, 0, 1, 1, 1, 1),
153e6674010SJames Molloy BINS(0, 1, 1, 1, 1, 1)})));
154e6674010SJames Molloy }
155