summaryrefslogtreecommitdiff
diff options
context:
space:
mode:
-rw-r--r--src/analysis/lattices/int.h63
-rw-r--r--test/gtest/lattices.cpp36
2 files changed, 99 insertions, 0 deletions
diff --git a/src/analysis/lattices/int.h b/src/analysis/lattices/int.h
new file mode 100644
index 000000000..a2cd37c1e
--- /dev/null
+++ b/src/analysis/lattices/int.h
@@ -0,0 +1,63 @@
+/*
+ * Copyright 2023 WebAssembly Community Group participants
+ *
+ * Licensed under the Apache License, Version 2.0 (the "License");
+ * you may not use this file except in compliance with the License.
+ * You may obtain a copy of the License at
+ *
+ * http://www.apache.org/licenses/LICENSE-2.0
+ *
+ * Unless required by applicable law or agreed to in writing, software
+ * distributed under the License is distributed on an "AS IS" BASIS,
+ * WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied.
+ * See the License for the specific language governing permissions and
+ * limitations under the License.
+ */
+
+#ifndef wasm_analysis_lattices_int_h
+#define wasm_analysis_lattices_int_h
+
+#include <cstdint>
+#include <limits>
+
+#include "../lattice.h"
+
+namespace wasm::analysis {
+
+// The lattice of integers of the given type `T`, ordered by <. The min integer
+// is the bottom element and the max integer is the top element.
+#if __cplusplus >= 202002L
+template<std::integral T>
+#else
+template<typename T>
+#endif
+struct Integer {
+ using Element = T;
+ Element getBottom() const noexcept { return std::numeric_limits<T>::min(); }
+ LatticeComparison compare(Element a, Element b) const noexcept {
+ return a > b ? GREATER : a == b ? EQUAL : LESS;
+ }
+ bool join(Element& self, Element other) const noexcept {
+ if (self < other) {
+ self = other;
+ return true;
+ }
+ return false;
+ }
+};
+
+using Int32 = Integer<int32_t>;
+using UInt32 = Integer<uint32_t>;
+using Int64 = Integer<int64_t>;
+using UInt64 = Integer<uint64_t>;
+
+#if __cplusplus >= 202002L
+static_assert(Lattice<Int32>);
+static_assert(Lattice<Int64>);
+static_assert(Lattice<UInt32>);
+static_assert(Lattice<UInt64>);
+#endif // __cplusplus >= 202002L
+
+} // namespace wasm::analysis
+
+#endif // wasm_analysis_lattices_int_h
diff --git a/test/gtest/lattices.cpp b/test/gtest/lattices.cpp
index f06ba612b..d72e088fc 100644
--- a/test/gtest/lattices.cpp
+++ b/test/gtest/lattices.cpp
@@ -15,6 +15,7 @@
*/
#include "analysis/lattices/bool.h"
+#include "analysis/lattices/int.h"
#include "gtest/gtest.h"
using namespace wasm;
@@ -48,3 +49,38 @@ TEST(BoolLattice, Join) {
EXPECT_FALSE(lattice.join(elem, true));
ASSERT_TRUE(elem);
}
+
+TEST(IntLattice, GetBottom) {
+ analysis::Int32 int32;
+ EXPECT_EQ(int32.getBottom(), (int32_t)(1ll << 31));
+
+ analysis::Int64 int64;
+ EXPECT_EQ(int64.getBottom(), (int64_t)(1ll << 63));
+
+ analysis::UInt32 uint32;
+ EXPECT_EQ(uint32.getBottom(), (uint32_t)0);
+
+ analysis::UInt64 uint64;
+ EXPECT_EQ(uint64.getBottom(), (uint32_t)0);
+}
+
+TEST(IntLattice, Compare) {
+ analysis::Int32 int32;
+ EXPECT_EQ(int32.compare(-5, 42), analysis::LESS);
+ EXPECT_EQ(int32.compare(42, -5), analysis::GREATER);
+ EXPECT_EQ(int32.compare(42, 42), analysis::EQUAL);
+}
+
+TEST(IntLattice, Join) {
+ analysis::Int32 int32;
+ int elem = 0;
+
+ EXPECT_FALSE(int32.join(elem, -10));
+ ASSERT_EQ(elem, 0);
+
+ EXPECT_FALSE(int32.join(elem, 0));
+ ASSERT_EQ(elem, 0);
+
+ EXPECT_TRUE(int32.join(elem, 100));
+ ASSERT_EQ(elem, 100);
+}