summaryrefslogtreecommitdiffstats
path: root/llvm/unittests/TableGen/AutomataTest.cpp
diff options
context:
space:
mode:
Diffstat (limited to 'llvm/unittests/TableGen/AutomataTest.cpp')
-rw-r--r--llvm/unittests/TableGen/AutomataTest.cpp153
1 files changed, 153 insertions, 0 deletions
diff --git a/llvm/unittests/TableGen/AutomataTest.cpp b/llvm/unittests/TableGen/AutomataTest.cpp
new file mode 100644
index 00000000000..11c03426fd8
--- /dev/null
+++ b/llvm/unittests/TableGen/AutomataTest.cpp
@@ -0,0 +1,153 @@
+//===- unittest/TableGen/AutomataTest.cpp - DFA tests ---------------------===//
+//
+// Part of the LLVM Project, under the Apache License v2.0 with LLVM Exceptions.
+// See https://llvm.org/LICENSE.txt for license information.
+// SPDX-License-Identifier: Apache-2.0 WITH LLVM-exception
+//
+//===----------------------------------------------------------------------===//
+
+#include "llvm/ADT/ArrayRef.h"
+#include "llvm/ADT/STLExtras.h"
+#include "llvm/Support/Debug.h"
+#include "llvm/Support/Automaton.h"
+#include "gmock/gmock.h"
+#include "gtest/gtest.h"
+
+using namespace llvm;
+using testing::ContainerEq;
+using testing::UnorderedElementsAre;
+
+// Bring in the enums created by SearchableTables.td.
+#define GET_SymKind_DECL
+#define GET_BinRequirementKindEnum_DECL
+#include "AutomataTables.inc"
+
+// And bring in the automata from Automata.td.
+#define GET_SimpleAutomaton_DECL
+#define GET_TupleAutomaton_DECL
+#define GET_NfaAutomaton_DECL
+#define GET_BinPackerAutomaton_DECL
+#include "AutomataAutomata.inc"
+
+TEST(Automata, SimpleAutomatonAcceptsFromInitialState) {
+ Automaton<SymKind> A(makeArrayRef(SimpleAutomatonTransitions));
+ EXPECT_TRUE(A.add(SK_a));
+ A.reset();
+ EXPECT_TRUE(A.add(SK_b));
+ A.reset();
+ EXPECT_TRUE(A.add(SK_c));
+ A.reset();
+ EXPECT_FALSE(A.add(SK_d));
+}
+
+TEST(Automata, SimpleAutomatonAcceptsSequences) {
+ Automaton<SymKind> A(makeArrayRef(SimpleAutomatonTransitions));
+ // Test sequence <a b>
+ A.reset();
+ EXPECT_TRUE(A.add(SK_a));
+ EXPECT_TRUE(A.add(SK_b));
+
+ // Test sequence <a c> is rejected (c cannot get bit 0b10);
+ A.reset();
+ EXPECT_TRUE(A.add(SK_a));
+ EXPECT_FALSE(A.add(SK_c));
+
+ // Symmetric test: sequence <c a> is rejected.
+ A.reset();
+ EXPECT_TRUE(A.add(SK_c));
+ EXPECT_FALSE(A.add(SK_a));
+}
+
+TEST(Automata, TupleAutomatonAccepts) {
+ Automaton<TupleAutomatonAction> A(makeArrayRef(TupleAutomatonTransitions));
+ A.reset();
+ EXPECT_TRUE(
+ A.add({SK_a, SK_b, "yeet"}));
+ A.reset();
+ EXPECT_FALSE(
+ A.add({SK_a, SK_a, "yeet"}));
+ A.reset();
+ EXPECT_FALSE(
+ A.add({SK_a, SK_b, "feet"}));
+ A.reset();
+ EXPECT_TRUE(
+ A.add({SK_b, SK_b, "foo"}));
+}
+
+TEST(Automata, NfaAutomatonAccepts) {
+ Automaton<SymKind> A(makeArrayRef(NfaAutomatonTransitions));
+
+ // Test sequences <a a>, <a b>, <b a>, <b b>. All should be accepted.
+ A.reset();
+ EXPECT_TRUE(A.add(SK_a));
+ EXPECT_TRUE(A.add(SK_a));
+ A.reset();
+ EXPECT_TRUE(A.add(SK_a));
+ EXPECT_TRUE(A.add(SK_b));
+ A.reset();
+ EXPECT_TRUE(A.add(SK_b));
+ EXPECT_TRUE(A.add(SK_a));
+ A.reset();
+ EXPECT_TRUE(A.add(SK_b));
+ EXPECT_TRUE(A.add(SK_b));
+
+ // Expect that <b b b> is not accepted.
+ A.reset();
+ EXPECT_TRUE(A.add(SK_b));
+ EXPECT_TRUE(A.add(SK_b));
+ EXPECT_FALSE(A.add(SK_b));
+}
+
+TEST(Automata, BinPackerAutomatonAccepts) {
+ Automaton<BinPackerAutomatonAction> A(makeArrayRef(BinPackerAutomatonTransitions));
+
+ // Expect that we can pack two double-bins in 0-4, then no more in 0-4.
+ A.reset();
+ EXPECT_TRUE(A.add(BRK_0_to_4_dbl));
+ EXPECT_TRUE(A.add(BRK_0_to_4_dbl));
+ EXPECT_FALSE(A.add(BRK_0_to_4));
+
+ // Expect that we can pack two double-bins in 0-4, two more in 0-6 then no
+ // more.
+ A.reset();
+ EXPECT_TRUE(A.add(BRK_0_to_4_dbl));
+ EXPECT_TRUE(A.add(BRK_0_to_4_dbl));
+ EXPECT_TRUE(A.add(BRK_0_to_6));
+ EXPECT_TRUE(A.add(BRK_0_to_6));
+ EXPECT_FALSE(A.add(BRK_0_to_6));
+
+ // Expect that we can pack BRK_0_to_6 five times to occupy five bins, then
+ // cannot allocate any double-bins.
+ A.reset();
+ for (unsigned I = 0; I < 5; ++I)
+ EXPECT_TRUE(A.add(BRK_0_to_6));
+ EXPECT_FALSE(A.add(BRK_0_to_6_dbl));
+}
+
+// The state we defined in TableGen uses the least significant 6 bits to represent a bin state.
+#define BINS(a, b, c, d, e, f) \
+ ((a << 5) | (b << 4) | (c << 3) | (d << 2) | (e << 1) | (f << 0))
+
+TEST(Automata, BinPackerAutomatonExplains) {
+ Automaton<BinPackerAutomatonAction> A(makeArrayRef(BinPackerAutomatonTransitions),
+ makeArrayRef(BinPackerAutomatonTransitionInfo));
+ // Pack two double-bins in 0-4, then a single bin in 0-6.
+ EXPECT_TRUE(A.add(BRK_0_to_4_dbl));
+ EXPECT_TRUE(A.add(BRK_0_to_4_dbl));
+ EXPECT_TRUE(A.add(BRK_0_to_6));
+ EXPECT_THAT(
+ A.getNfaPaths(),
+ UnorderedElementsAre(
+ // Allocate {0,1} first, then 6.
+ ContainerEq(NfaPath{BINS(0, 0, 0, 0, 1, 1), BINS(0, 0, 1, 1, 1, 1),
+ BINS(1, 0, 1, 1, 1, 1)}),
+ // Allocate {0,1} first, then 5.
+ ContainerEq(NfaPath{BINS(0, 0, 0, 0, 1, 1), BINS(0, 0, 1, 1, 1, 1),
+ BINS(0, 1, 1, 1, 1, 1)}),
+ // Allocate {2,3} first, then 6.
+ ContainerEq(NfaPath{BINS(0, 0, 1, 1, 0, 0), BINS(0, 0, 1, 1, 1, 1),
+ BINS(1, 0, 1, 1, 1, 1)}),
+ // Allocate {2,3} first, then 5.
+ ContainerEq(NfaPath{BINS(0, 0, 1, 1, 0, 0), BINS(0, 0, 1, 1, 1, 1),
+ BINS(0, 1, 1, 1, 1, 1)})));
+}
OpenPOWER on IntegriCloud