diff options
author | Alon Zakai <azakai@google.com> | 2019-05-07 10:02:01 -0700 |
---|---|---|
committer | GitHub <noreply@github.com> | 2019-05-07 10:02:01 -0700 |
commit | da716eb233f9fe7cefc61d9d1ce54f8b8c9d9126 (patch) | |
tree | f2ee2f838b6a71a90cedce2cf54da1348f3b9348 /src | |
parent | 9384c1d52a8176666e0412b23d9a32ccbc4a8f44 (diff) | |
download | binaryen-da716eb233f9fe7cefc61d9d1ce54f8b8c9d9126.tar.gz binaryen-da716eb233f9fe7cefc61d9d1ce54f8b8c9d9126.tar.bz2 binaryen-da716eb233f9fe7cefc61d9d1ce54f8b8c9d9126.zip |
wasm2js: optimize booleans (#2090)
Diffstat (limited to 'src')
-rw-r--r-- | src/tools/wasm2js.cpp | 78 |
1 files changed, 52 insertions, 26 deletions
diff --git a/src/tools/wasm2js.cpp b/src/tools/wasm2js.cpp index 611b00803..00ea23e7d 100644 --- a/src/tools/wasm2js.cpp +++ b/src/tools/wasm2js.cpp @@ -155,9 +155,26 @@ static void optimizeJS(Ref ast) { return false; }; - auto isConstantAnd = [](Ref node, int num) { + auto isUnary = [](Ref node, IString op) { + return node->isArray() && !node->empty() && node[0] == UNARY_PREFIX && + node[1] == op; + }; + + auto isConstantBitwise = [](Ref node, IString op, int num) { return node->isArray() && !node->empty() && node[0] == BINARY && - node[1] == AND && node[3]->isNumber() && node[3]->getNumber() == num; + node[1] == op && node[3]->isNumber() && node[3]->getNumber() == num; + }; + + auto isWhile = [](Ref node) { + return node->isArray() && !node->empty() && node[0] == WHILE; + }; + + auto isDo = [](Ref node) { + return node->isArray() && !node->empty() && node[0] == DO; + }; + + auto isIf = [](Ref node) { + return node->isArray() && !node->empty() && node[0] == IF; }; auto removeOrZero = [&](Ref node) { @@ -211,35 +228,40 @@ static void optimizeJS(Ref ast) { return false; }; + auto optimizeBoolean = [&](Ref node) { + // x ^ 1 => !x + if (isConstantBitwise(node, XOR, 1)) { + node[0]->setString(UNARY_PREFIX); + node[1]->setString(L_NOT); + node[3]->setNull(); + } + return node; + }; + // Optimizations - // x >> 0 => x | 0 - traversePost(ast, [](Ref node) { - if (node->isArray() && !node->empty() && node[0] == BINARY && - node[1] == RSHIFT && node[3]->isNumber()) { - if (node[3]->getNumber() == 0) { - node[1]->setString(OR); - } + // Pre-simplification + traversePost(ast, [&](Ref node) { + // x >> 0 => x | 0 + if (isConstantBitwise(node, RSHIFT, 0)) { + node[1]->setString(OR); } }); traversePost(ast, [&](Ref node) { - // x | 0 | 0 => x | 0 - if (isOrZero(node)) { - while (isOrZero(node[2])) { - node[2] = node[2][2]; - } - if (isBitwise(node[2])) { - auto child = node[2]; - node[1] = child[1]; - node[2] = child[2]; - node[3] = child[3]; - } - } - // x | 0 going into a bitwise op => skip the | 0 - else if (isBitwise(node)) { + if (isBitwise(node)) { + // x | 0 going into a bitwise op => skip the | 0 node[2] = removeOrZero(node[2]); node[3] = removeOrZero(node[3]); + // x | 0 | 0 => x | 0 + if (isOrZero(node)) { + if (isBitwise(node[2])) { + auto child = node[2]; + node[1] = child[1]; + node[2] = child[2]; + node[3] = child[3]; + } + } // A load into an & may allow using a simpler heap, e.g. HEAPU8[..] & 1 // (a load of a boolean) may be HEAP8[..] & 1. The signed heaps are more // commonly used, so it compresses better, and also they seem to have @@ -247,7 +269,7 @@ static void optimizeJS(Ref ast) { // smallint). if (node[1] == AND && isHeapAccess(node[2])) { auto heap = getHeapFromAccess(node[2]); - if (isConstantAnd(node, 1)) { + if (isConstantBitwise(node, AND, 1)) { if (heap == HEAPU8) { setHeapOnAccess(node[2], HEAP8); } else if (heap == HEAPU16) { @@ -263,6 +285,8 @@ static void optimizeJS(Ref ast) { // +(+x) => +x else if (isFround(node)) { node[2] = removePlusAndFround(node[2]); + } else if (isUnary(node, L_NOT)) { + node[2] = optimizeBoolean(node[2]); } // Assignment into a heap coerces. else if (node->isAssign()) { @@ -273,12 +297,12 @@ static void optimizeJS(Ref ast) { if (isIntegerHeap(heap)) { if (heap == HEAP8 || heap == HEAPU8) { while (isOrZero(assign->value()) || - isConstantAnd(assign->value(), 255)) { + isConstantBitwise(assign->value(), AND, 255)) { assign->value() = assign->value()[2]; } } else if (heap == HEAP16 || heap == HEAPU16) { while (isOrZero(assign->value()) || - isConstantAnd(assign->value(), 65535)) { + isConstantBitwise(assign->value(), AND, 65535)) { assign->value() = assign->value()[2]; } } else { @@ -294,6 +318,8 @@ static void optimizeJS(Ref ast) { } } } + } else if (isWhile(node) || isDo(node) || isIf(node)) { + node[1] = optimizeBoolean(node[1]); } }); |