From 2da1b20451a744daa613e818f71e8f52de3a818e Mon Sep 17 00:00:00 2001 From: Alon Zakai Date: Wed, 28 Sep 2016 13:10:59 -0700 Subject: Type check block/loop/if sigs (#717) * type check using block/loop/if types provided in text and binary formats. * print if and loop sigs which were missing. * remove dsl from OptimizeInstructions as after those changes it needs rethinking. --- src/passes/OptimizeInstructions.cpp | 60 +++++++++++ src/passes/OptimizeInstructions.wast | 132 +------------------------ src/passes/OptimizeInstructions.wast.processed | 132 +------------------------ src/passes/Print.cpp | 3 + src/passes/RemoveUnusedBrs.cpp | 2 +- src/wasm-binary.h | 52 +++------- src/wasm-s-parser.h | 28 +++--- src/wasm-validator.h | 23 +++++ src/wasm.cpp | 43 ++++++++ src/wasm.h | 42 ++++---- 10 files changed, 179 insertions(+), 338 deletions(-) (limited to 'src') diff --git a/src/passes/OptimizeInstructions.cpp b/src/passes/OptimizeInstructions.cpp index 48639a341..f467b395e 100644 --- a/src/passes/OptimizeInstructions.cpp +++ b/src/passes/OptimizeInstructions.cpp @@ -175,6 +175,7 @@ struct OptimizeInstructions : public WalkerPasspatternMap.find(curr->_id); if (iter == database->patternMap.end()) return; @@ -209,6 +210,56 @@ struct OptimizeInstructions : public WalkerPassop == EqInt32) { + if (auto* c = binary->right->dynCast()) { + if (c->value.geti32() == 0) { + // equal 0 => eqz + return Builder(*getModule()).makeUnary(EqZInt32, binary->left); + } + } + if (auto* c = binary->left->dynCast()) { + if (c->value.geti32() == 0) { + // equal 0 => eqz + return Builder(*getModule()).makeUnary(EqZInt32, binary->right); + } + } + } + } else if (auto* unary = curr->dynCast()) { + // de-morgan's laws + if (unary->op == EqZInt32) { + if (auto* inner = unary->value->dynCast()) { + switch (inner->op) { + case EqInt32: inner->op = NeInt32; return inner; + case NeInt32: inner->op = EqInt32; return inner; + case LtSInt32: inner->op = GeSInt32; return inner; + case LtUInt32: inner->op = GeUInt32; return inner; + case LeSInt32: inner->op = GtSInt32; return inner; + case LeUInt32: inner->op = GtUInt32; return inner; + case GtSInt32: inner->op = LeSInt32; return inner; + case GtUInt32: inner->op = LeUInt32; return inner; + case GeSInt32: inner->op = LtSInt32; return inner; + case GeUInt32: inner->op = LtUInt32; return inner; + + case EqInt64: inner->op = NeInt64; return inner; + case NeInt64: inner->op = EqInt64; return inner; + case LtSInt64: inner->op = GeSInt64; return inner; + case LtUInt64: inner->op = GeUInt64; return inner; + case LeSInt64: inner->op = GtSInt64; return inner; + case LeUInt64: inner->op = GtUInt64; return inner; + case GtSInt64: inner->op = LeSInt64; return inner; + case GtUInt64: inner->op = LeUInt64; return inner; + case GeSInt64: inner->op = LtSInt64; return inner; + case GeUInt64: inner->op = LtUInt64; return inner; + + case EqFloat32: inner->op = NeFloat32; return inner; + case NeFloat32: inner->op = EqFloat32; return inner; + + case EqFloat64: inner->op = NeFloat64; return inner; + case NeFloat64: inner->op = EqFloat64; return inner; + + default: {} + } + } } } else if (auto* set = curr->dynCast()) { // optimize out a set of a get @@ -218,6 +269,15 @@ struct OptimizeInstructions : public WalkerPassdynCast()) { iff->condition = optimizeBoolean(iff->condition); + if (iff->ifFalse) { + if (auto* unary = iff->condition->dynCast()) { + if (unary->op == EqZInt32) { + // flip if-else arms to get rid of an eqz + iff->condition = unary->value; + std::swap(iff->ifTrue, iff->ifFalse); + } + } + } } else if (auto* select = curr->dynCast