diff --git a/tests/test_other.py b/tests/test_other.py index 9b4313b8fd090..a13de53a475f8 100644 --- a/tests/test_other.py +++ b/tests/test_other.py @@ -1951,16 +1951,19 @@ def fix(src): return map(fix, src) src = '\n'.join(filter(lambda line: 'var ' not in line, src.split('\n'))) # ignore vars def reorder(func): - # emit EYE_ONE always before EYE_TWO, replaceing i1,i2 or i2,i1 - i1 = 'i1' - i2 = 'i2' - if i1 not in func or i2 not in func: return func - ok = func.index(i1) < func.index(i2) - if not ok: - i1 = 'i2' - i2 = 'i1' - func = func.replace(i1, 'EYE_ONE').replace(i2, 'EYE_TWO') - assert func.index('EYE_ONE') < func.index('EYE_TWO') + def swap(func, i1, i2): + # emit EYE_ONE always before EYE_TWO, replacing i1,i2 or i2,i1 etc + if i1 not in func or i2 not in func: return func + ok = func.index(i1) < func.index(i2) + if not ok: + temp = i1 + i1 = i2 + i2 = temp + func = func.replace(i1, 'EYE_ONE').replace(i2, 'EYE_TWO') + assert func.index('EYE_ONE') < func.index('EYE_TWO') + return func + func = swap(func, 'i1', 'i2') + func = swap(func, 'i4', 'i5') return func src = 'function '.join(map(reorder, src.split('function '))) return src diff --git a/tools/optimizer/optimizer.cpp b/tools/optimizer/optimizer.cpp index 4e3475e37a234..3f83408c5f921 100644 --- a/tools/optimizer/optimizer.cpp +++ b/tools/optimizer/optimizer.cpp @@ -516,7 +516,8 @@ Ref makeAsmCoercion(Ref node, AsmType type) { // Checks bool isEmpty(Ref node) { - return node->size() == 2 && node[0] == TOPLEVEL && node[1]->size() == 0; + return (node->size() == 2 && node[0] == TOPLEVEL && node[1]->size() == 0) || + (node->size() > 0 && node[0] == BLOCK && (!node[1] || node[1]->size() == 0)); } bool commable(Ref node) { // TODO: hashing @@ -664,7 +665,6 @@ void clearUselessNodes(Ref arr) { void removeAllEmptySubNodes(Ref ast) { traversePre(ast, [](Ref node) { - int index = -1; if (node[0] == DEFUN) { clearEmptyNodes(node[3]); } else if (node[0] == BLOCK && node->size() > 1 && !!node[1]) { @@ -675,15 +675,31 @@ void removeAllEmptySubNodes(Ref ast) { }); } void removeAllUselessSubNodes(Ref ast) { - traversePre(ast, [](Ref node) { - int index = -1; - if (node[0] == DEFUN) { + traversePrePost(ast, [](Ref node) { + Ref type = node[0]; + if (type == DEFUN) { clearUselessNodes(node[3]); - } else if (node[0] == BLOCK && node->size() > 1 && !!node[1]) { + } else if (type == BLOCK && node->size() > 1 && !!node[1]) { clearUselessNodes(node[1]); - } else if (node[0] == SEQ && isEmpty(node[1])) { + } else if (type == SEQ && isEmpty(node[1])) { safeCopy(node, node[2]); } + }, [](Ref node) { + Ref type = node[0]; + if (type == IF) { + bool empty2 = isEmpty(node[2]), has3 = node->size() == 4 && !!node[3], empty3 = !has3 || isEmpty(node[3]); + if (!empty2 && empty3 && has3) { // empty else clauses + node->setSize(3); + } else if (empty2 && !empty3) { // empty if blocks + safeCopy(node, make2(IF, make2(UNARY_PREFIX, L_NOT, node[1]), node[3])); + } else if (empty2 && empty3) { + if (hasSideEffects(node[1])) { + safeCopy(node, make1(STAT, node[1])); + } else { + safeCopy(node, makeEmpty()); + } + } + } }); } diff --git a/tools/test-js-optimizer-asm-regs-output.js b/tools/test-js-optimizer-asm-regs-output.js index c75bbcf74dab3..ca2f6069f8bd7 100644 --- a/tools/test-js-optimizer-asm-regs-output.js +++ b/tools/test-js-optimizer-asm-regs-output.js @@ -106,5 +106,20 @@ function iffey() { function nops() { var i1 = 0; f(i1); + if (cheez) { + doIt(); + } else { + doIt(); + } + if (cheez) { + doIt(); + } + if (!cheez) { + doIt(); + } + if (!cheez) { + doIt(); + } + doIt(); } diff --git a/tools/test-js-optimizer-asm-regs.js b/tools/test-js-optimizer-asm-regs.js index 9c5b49fd13056..a4d1fb96b2a0f 100644 --- a/tools/test-js-optimizer-asm-regs.js +++ b/tools/test-js-optimizer-asm-regs.js @@ -111,6 +111,23 @@ function nops() { x | 0; ~x; f(x); + // vaccuming + if (cheez) { + doIt(); + } else { + doIt(); + } + if (cheez) { + doIt(); + } else {} + if (cheez) {} else { + doIt(); + } + if (cheez) {} else { + doIt(); + } + if (cheez) {} else {} + if (doIt()) {} else {} } // EMSCRIPTEN_GENERATED_FUNCTIONS: ["asm", "_doit", "stackRestore", "switchey", "switchey2", "iffey", "nops"]