Skip to content

Commit

Permalink
Moar optimizations for side-effecty if statements
Browse files Browse the repository at this point in the history
  • Loading branch information
boopathi committed Jan 25, 2017
1 parent 64db587 commit 688c0c5
Show file tree
Hide file tree
Showing 2 changed files with 64 additions and 12 deletions.
Original file line number Diff line number Diff line change
Expand Up @@ -2422,12 +2422,42 @@ describe("dce-plugin", () => {
expect(transform(source)).toBe(expected);
});

it("should deopt impure expressions in if statements", () => {
it("should impure expressions in confidently evaluated if statements", () => {
const source = unpad(`
if (a.b(), true) {
foo();
}
`);
expect(transform(source)).toBe(source);
const expected = unpad(`
a.b();
foo();
`);
expect(transform(source)).toBe(expected);
});

it("should extract all necessary things from if statements", () => {
const source = unpad(`
if (a.b(), false) {
var foo = foo1;
foo();
} else if (b.c(), true) {
var bar = bar1;
bar();
} else {
var baz = baz1;
baz();
}
`);
const expected = unpad(`
a.b();
b.c();
var bar = bar1;
bar();
var baz;
var foo;
`);
expect(transform(source)).toBe(expected);
});
});
42 changes: 32 additions & 10 deletions packages/babel-plugin-minify-dead-code-elimination/src/index.js
Original file line number Diff line number Diff line change
Expand Up @@ -640,20 +640,27 @@ module.exports = ({ types: t, traverse }) => {
const alternate = path.get("alternate");
const test = path.get("test");

const evalResult = test.evaluate();
const isPure = test.isPure();

const evaluateTest = test.evaluateTruthy();
const replacements = [];

if (evalResult.confident && !isPure && test.isSequenceExpression()) {
replacements.push(
t.expressionStatement(extractSequenceImpure(test))
);
}

// we can check if a test will be truthy 100% and if so then we can inline
// the consequent and completely ignore the alternate
//
// if (true) { foo; } -> { foo; }
// if ("foo") { foo; } -> { foo; }
//
if (isPure && evaluateTest === true) {
path.replaceWithMultiple(
[...toStatements(consequent), ...extractVars(alternate)]
);
if (evalResult.confident && evalResult.value) {
path.replaceWithMultiple([
...replacements, ...toStatements(consequent), ...extractVars(alternate)
]);
return;
}

Expand All @@ -663,14 +670,16 @@ module.exports = ({ types: t, traverse }) => {
// if ("") { bar; } else { foo; } -> { foo; }
// if ("") { bar; } ->
//
if (isPure && evaluateTest === false) {
if (evalResult.confident && !evalResult.value) {
if (alternate.node) {
path.replaceWithMultiple(
[...toStatements(alternate), ...extractVars(consequent)]
);
path.replaceWithMultiple([
...replacements, ...toStatements(alternate), ...extractVars(consequent)
]);
return;
} else {
path.replaceWithMultiple(extractVars(consequent));
path.replaceWithMultiple([
...replacements, ...extractVars(consequent)
]);
}
}

Expand Down Expand Up @@ -700,11 +709,13 @@ module.exports = ({ types: t, traverse }) => {
}
},
},

EmptyStatement(path) {
if (path.parentPath.isBlockStatement() || path.parentPath.isProgram()) {
path.remove();
}
},

Program: {
exit(path, {
opts: {
Expand Down Expand Up @@ -1026,4 +1037,15 @@ module.exports = ({ types: t, traverse }) => {
} while (parent = parent.parentPath);
return false;
}

function extractSequenceImpure(seq) {
const expressions = seq.get("expressions");
const result = [];
for (let i = 0; i < expressions.length; i++) {
if (!expressions[i].isPure()) {
result.push(expressions[i].node);
}
}
return t.sequenceExpression(result);
}
};

0 comments on commit 688c0c5

Please sign in to comment.