diff options
-rw-r--r-- | src/ir/match.h | 43 | ||||
-rw-r--r-- | src/passes/OptimizeInstructions.cpp | 7 | ||||
-rw-r--r-- | test/example/match.cpp | 14 | ||||
-rw-r--r-- | test/example/match.txt | 2 |
4 files changed, 52 insertions, 14 deletions
diff --git a/src/ir/match.h b/src/ir/match.h index 2ab3afe65..0d8d3c20a 100644 --- a/src/ir/match.h +++ b/src/ir/match.h @@ -39,12 +39,12 @@ namespace Match { // argument can be a specific value to match or it can be a pointer to a // value, Literal, or Const* at which to store the matched entity. // -// ival, fval +// bval, ival, fval // -// Match any integer constant or any floating point constant. Takes neither, -// either, or both of two possible arguments: first, a pointer to a value, -// Literal, or Const* at which to store the matched entity and second, a -// specific value to match. +// Match any boolean, any integer or any floating point constant. Takes +// neither, either, or both of two possible arguments: first, a pointer to a +// value, Literal, or Const* at which to store the matched entity and second, +// a specific value to match. // // constant // @@ -395,7 +395,14 @@ template<class T> inline decltype(auto) Exact(T* binder, T data) { return Matcher<ExactKind<T>>(binder, data); } -// {I32,I64,Int,F32,F64,Float,Number}Lit: match `Literal` of the expected `Type` +// {Bool,I32,I64,Int,F32,F64,Float,Number}Lit: +// match `Literal` of the expected `Type` +struct BoolLK { + static bool matchType(Literal lit) { + return lit.type == Type::i32 && (uint32_t)lit.geti32() <= 1U; + } + static int32_t getVal(Literal lit) { return lit.geti32(); } +}; struct I32LK { static bool matchType(Literal lit) { return lit.type == Type::i32; } static int32_t getVal(Literal lit) { return lit.geti32(); } @@ -434,6 +441,9 @@ template<class T> struct NumComponents<LitKind<T>> { template<class T> struct GetComponent<LitKind<T>, 0> { decltype(auto) operator()(Literal lit) { return T::getVal(lit); } }; +template<class S> inline decltype(auto) BoolLit(Literal* binder, S&& s) { + return Matcher<LitKind<BoolLK>, S>(binder, {}, s); +} template<class S> inline decltype(auto) I32Lit(Literal* binder, S&& s) { return Matcher<LitKind<I32LK>, S>(binder, {}, s); } @@ -601,6 +611,27 @@ SelectMatcher(Select** binder, S1&& s1, S2&& s2, S3&& s3) { // Public matching API +inline decltype(auto) bval() { + return Internal::ConstMatcher( + nullptr, Internal::BoolLit(nullptr, Internal::Any<bool>(nullptr))); +} +inline decltype(auto) bval(bool x) { + return Internal::ConstMatcher( + nullptr, Internal::BoolLit(nullptr, Internal::Exact<bool>(nullptr, x))); +} +inline decltype(auto) bval(bool* binder) { + return Internal::ConstMatcher( + nullptr, Internal::BoolLit(nullptr, Internal::Any(binder))); +} +inline decltype(auto) bval(Literal* binder) { + return Internal::ConstMatcher( + nullptr, Internal::BoolLit(binder, Internal::Any<bool>(nullptr))); +} +inline decltype(auto) bval(Const** binder) { + return Internal::ConstMatcher( + binder, Internal::BoolLit(nullptr, Internal::Any<bool>(nullptr))); +} + inline decltype(auto) i32() { return Internal::ConstMatcher( nullptr, Internal::I32Lit(nullptr, Internal::Any<int32_t>(nullptr))); diff --git a/src/passes/OptimizeInstructions.cpp b/src/passes/OptimizeInstructions.cpp index cc263d228..d18990e8e 100644 --- a/src/passes/OptimizeInstructions.cpp +++ b/src/passes/OptimizeInstructions.cpp @@ -3350,14 +3350,9 @@ private: curr->ifTrue->type != Type::unreachable && curr->ifFalse->type != Type::unreachable) { Unary* un; - Expression* x; Const* c; auto check = [&](Expression* a, Expression* b) { - if (matches(a, unary(&un, EqZ, any(&x))) && matches(b, ival(&c))) { - auto value = c->value.getInteger(); - return value == 0 || value == 1; - } - return false; + return matches(b, bval(&c)) && matches(a, unary(&un, EqZ, any())); }; if (check(curr->ifTrue, curr->ifFalse) || check(curr->ifFalse, curr->ifTrue)) { diff --git a/test/example/match.cpp b/test/example/match.cpp index 21bbbab98..125ce8e92 100644 --- a/test/example/match.cpp +++ b/test/example/match.cpp @@ -123,10 +123,11 @@ void test_internal_exact() { } void test_internal_literal() { - std::cout << "Testing Internal::{I32,I64,Int,F32,F64,Float}Lit\n"; + std::cout << "Testing Internal::{Bool,I32,I64,Int,F32,F64,Float}Lit\n"; Literal i32Zero(int32_t(0)); Literal i32One(int32_t(1)); + Literal i32Two(int32_t(2)); Literal f32Zero(float(0)); Literal f32One(float(1)); Literal i64Zero(int64_t(0)); @@ -134,6 +135,17 @@ void test_internal_literal() { Literal f64Zero(double(0)); Literal f64One(double(1)); + auto anyBool = Internal::BoolLit(nullptr, Internal::Any<bool>(nullptr)); + assert(anyBool.matches(i32Zero)); + assert(anyBool.matches(i32One)); + assert(!anyBool.matches(i32Two)); + assert(!anyBool.matches(f32Zero)); + assert(!anyBool.matches(f32One)); + assert(!anyBool.matches(i64Zero)); + assert(!anyBool.matches(i64One)); + assert(!anyBool.matches(f64Zero)); + assert(!anyBool.matches(f64One)); + auto anyi32 = Internal::I32Lit(nullptr, Internal::Any<int32_t>(nullptr)); assert(anyi32.matches(i32Zero)); assert(anyi32.matches(i32One)); diff --git a/test/example/match.txt b/test/example/match.txt index c4ad57d73..2a66f054e 100644 --- a/test/example/match.txt +++ b/test/example/match.txt @@ -1,6 +1,6 @@ Testing Internal::Any Testing Internal::Exact -Testing Internal::{I32,I64,Int,F32,F64,Float}Lit +Testing Internal::{Bool,I32,I64,Int,F32,F64,Float}Lit Testing Internal::ConstantMatcher Testing Internal::UnaryMatcher Testing Internal::UnaryOpMatcher |