Skip to content

Commit

Permalink
feat(es/minifier): Support more statements in seqential inliner (#6248)
Browse files Browse the repository at this point in the history
**Description:**

We now inline into the discriminant of a switch statement and into the initializer of for/for-in/for-of statements.
  • Loading branch information
kdy1 committed Oct 26, 2022
1 parent 8da12aa commit 86e265a
Show file tree
Hide file tree
Showing 25 changed files with 675 additions and 750 deletions.
3 changes: 1 addition & 2 deletions crates/swc/tests/tsc-references/for-of24.2.minified.js
@@ -1,3 +1,2 @@
//// [for-of24.ts]
var x;
for (var v of x);
for (var v of void 0);
3 changes: 1 addition & 2 deletions crates/swc/tests/tsc-references/for-of29.2.minified.js
@@ -1,3 +1,2 @@
//// [for-of29.ts]
var iterableWithOptionalIterator;
for (var v of iterableWithOptionalIterator);
for (var v of void 0);
5 changes: 2 additions & 3 deletions crates/swc/tests/tsc-references/for-of37.2.minified.js
@@ -1,8 +1,7 @@
//// [for-of37.ts]
var map = new Map([
for (var v of new Map([
[
"",
!0
]
]);
for (var v of map);
]));
5 changes: 2 additions & 3 deletions crates/swc/tests/tsc-references/for-of38.2.minified.js
@@ -1,8 +1,7 @@
//// [for-of38.ts]
var map = new Map([
for (var [k, v] of new Map([
[
"",
!0
]
]);
for (var [k, v] of map);
]));
5 changes: 2 additions & 3 deletions crates/swc/tests/tsc-references/for-of39.2.minified.js
@@ -1,5 +1,5 @@
//// [for-of39.ts]
var map = new Map([
for (var [k, v] of new Map([
[
"",
!0
Expand All @@ -8,5 +8,4 @@ var map = new Map([
"",
0
]
]);
for (var [k, v] of map);
]));
5 changes: 2 additions & 3 deletions crates/swc/tests/tsc-references/for-of40.2.minified.js
@@ -1,8 +1,7 @@
//// [for-of40.ts]
var map = new Map([
for (var [k = "", v = !1] of new Map([
[
"",
!0
]
]);
for (var [k = "", v = !1] of map);
]));
5 changes: 2 additions & 3 deletions crates/swc/tests/tsc-references/for-of44.2.minified.js
@@ -1,5 +1,5 @@
//// [for-of44.ts]
var array = [
for (var [num, strBoolSym] of [
[
0,
""
Expand All @@ -12,5 +12,4 @@ var array = [
1,
Symbol()
]
];
for (var [num, strBoolSym] of array);
]);
6 changes: 3 additions & 3 deletions crates/swc/tests/tsc-references/for-of45.2.minified.js
@@ -1,8 +1,8 @@
//// [for-of45.ts]
var k, v, map = new Map([
var k, v;
for ([k = "", v = !1] of new Map([
[
"",
!0
]
]);
for ([k = "", v = !1] of map);
]));
6 changes: 3 additions & 3 deletions crates/swc/tests/tsc-references/for-of46.2.minified.js
@@ -1,8 +1,8 @@
//// [for-of46.ts]
var k, v, map = new Map([
var k, v;
for ([k = !1, v = ""] of new Map([
[
"",
!0
]
]);
for ([k = !1, v = ""] of map);
]));
6 changes: 3 additions & 3 deletions crates/swc/tests/tsc-references/for-of49.2.minified.js
@@ -1,8 +1,8 @@
//// [for-of49.ts]
var k, v, map = new Map([
var k, v;
for ([k, ...[v]] of new Map([
[
"",
!0
]
]);
for ([k, ...[v]] of map);
]));
5 changes: 2 additions & 3 deletions crates/swc/tests/tsc-references/for-of50.2.minified.js
@@ -1,8 +1,7 @@
//// [for-of50.ts]
var map = new Map([
for (const [k, v] of new Map([
[
"",
!0
]
]);
for (const [k, v] of map);
]));
3 changes: 1 addition & 2 deletions crates/swc/tests/tsc-references/for-of57.2.minified.js
@@ -1,3 +1,2 @@
//// [for-of57.ts]
var iter;
for (let num of iter);
for (let num of void 0);
Expand Up @@ -7,8 +7,7 @@ import _class_call_check from "@swc/helpers/src/_class_call_check.mjs";
return logger.log(funcDescription + " completed in " + (end - start) + " msec"), result;
}, stringToLiteral = function(value, length) {
var result = "", addChar = function(index) {
var ch = value.charCodeAt(index);
switch(ch){
switch(value.charCodeAt(index)){
case 0x09:
result += "\\t";
break;
Expand Down
@@ -1,12 +1,6 @@
//// [stringLiteralsWithSwitchStatements03.ts]
var x, z;
switch(x){
var z;
switch(void 0){
case randBool() ? "foo" : "baz":
case randBool(), "bar":
case "bar":
case "baz":
case "foo":
case "bar":
case z || "baz":
case "baz":
}
32 changes: 31 additions & 1 deletion crates/swc_ecma_minifier/src/compress/optimize/sequences.rs
Expand Up @@ -581,9 +581,31 @@ where
Stmt::Return(ReturnStmt { arg: Some(arg), .. }) => {
vec![Mergable::Expr(arg)]
}

Stmt::If(s) if options.sequences() => {
vec![Mergable::Expr(&mut s.test)]
}

Stmt::Switch(s) if options.sequences() => {
vec![Mergable::Expr(&mut s.discriminant)]
}

Stmt::For(s) if options.sequences() => {
if let Some(VarDeclOrExpr::Expr(e)) = &mut s.init {
vec![Mergable::Expr(e)]
} else {
return None;
}
}

Stmt::ForOf(s) if options.sequences() => {
vec![Mergable::Expr(&mut s.right)]
}

Stmt::ForIn(s) if options.sequences() => {
vec![Mergable::Expr(&mut s.right)]
}

Stmt::Throw(s) if options.sequences() => {
vec![Mergable::Expr(&mut s.arg)]
}
Expand Down Expand Up @@ -624,7 +646,15 @@ where
for stmt in stmts.iter_mut() {
let is_end = matches!(
stmt.as_stmt(),
Some(Stmt::If(..) | Stmt::Throw(..) | Stmt::Return(..))
Some(
Stmt::If(..)
| Stmt::Throw(..)
| Stmt::Return(..)
| Stmt::Switch(..)
| Stmt::For(..)
| Stmt::ForIn(..)
| Stmt::ForOf(..)
) | None
);
let can_skip = match stmt.as_stmt() {
Some(Stmt::Decl(Decl::Fn(..))) => true,
Expand Down
6 changes: 2 additions & 4 deletions crates/swc_ecma_minifier/tests/benches-full/echarts.js
Expand Up @@ -2428,8 +2428,7 @@
var frameIdx, isAdditive = null != this._additiveTrack, valueKey = isAdditive ? 'additiveValue' : 'value', keyframes = this.keyframes, kfsNum = this.keyframes.length, propName = this.propName, arrDim = this.arrDim, isValueColor = this.isValueColor;
if (percent < 0) frameIdx = 0;
else if (percent < this._lastFramePercent) {
var start = Math.min(this._lastFrame + 1, kfsNum - 1);
for(frameIdx = start; frameIdx >= 0 && !(keyframes[frameIdx].percent <= percent); frameIdx--);
for(frameIdx = Math.min(this._lastFrame + 1, kfsNum - 1); frameIdx >= 0 && !(keyframes[frameIdx].percent <= percent); frameIdx--);
frameIdx = Math.min(frameIdx, kfsNum - 2);
} else {
for(frameIdx = this._lastFrame; frameIdx < kfsNum && !(keyframes[frameIdx].percent > percent); frameIdx++);
Expand Down Expand Up @@ -28477,8 +28476,7 @@
if (offsets) {
var lastFrame = this._lastFrame;
if (t < this._lastFramePercent) {
var start = Math.min(lastFrame + 1, len - 1);
for(frame = start; frame >= 0 && !(offsets[frame] <= t); frame--);
for(frame = Math.min(lastFrame + 1, len - 1); frame >= 0 && !(offsets[frame] <= t); frame--);
frame = Math.min(frame, len - 2);
} else {
for(frame = lastFrame; frame < len && !(offsets[frame] > t); frame++);
Expand Down
3 changes: 1 addition & 2 deletions crates/swc_ecma_minifier/tests/benches-full/terser.js
Expand Up @@ -417,8 +417,7 @@
return ret;
}(function(ch, i) {
if (is_big_int) return !1;
var code = ch.charCodeAt(0);
switch(code){
switch(ch.charCodeAt(0)){
case 95:
return numeric_separator = !0;
case 98:
Expand Down
27 changes: 12 additions & 15 deletions crates/swc_ecma_minifier/tests/benches-full/three.js
Expand Up @@ -12078,21 +12078,18 @@
return;
}
var path = new ShapePath();
if (glyph.o) for(var outline = glyph._cachedOutline || (glyph._cachedOutline = glyph.o.split(' ')), i = 0, l = outline.length; i < l;){
var action = outline[i++];
switch(action){
case 'm':
x = outline[i++] * scale + offsetX, y = outline[i++] * scale + offsetY, path.moveTo(x, y);
break;
case 'l':
x = outline[i++] * scale + offsetX, y = outline[i++] * scale + offsetY, path.lineTo(x, y);
break;
case 'q':
cpx = outline[i++] * scale + offsetX, cpy = outline[i++] * scale + offsetY, cpx1 = outline[i++] * scale + offsetX, cpy1 = outline[i++] * scale + offsetY, path.quadraticCurveTo(cpx1, cpy1, cpx, cpy);
break;
case 'b':
cpx = outline[i++] * scale + offsetX, cpy = outline[i++] * scale + offsetY, cpx1 = outline[i++] * scale + offsetX, cpy1 = outline[i++] * scale + offsetY, cpx2 = outline[i++] * scale + offsetX, cpy2 = outline[i++] * scale + offsetY, path.bezierCurveTo(cpx1, cpy1, cpx2, cpy2, cpx, cpy);
}
if (glyph.o) for(var outline = glyph._cachedOutline || (glyph._cachedOutline = glyph.o.split(' ')), i = 0, l = outline.length; i < l;)switch(outline[i++]){
case 'm':
x = outline[i++] * scale + offsetX, y = outline[i++] * scale + offsetY, path.moveTo(x, y);
break;
case 'l':
x = outline[i++] * scale + offsetX, y = outline[i++] * scale + offsetY, path.lineTo(x, y);
break;
case 'q':
cpx = outline[i++] * scale + offsetX, cpy = outline[i++] * scale + offsetY, cpx1 = outline[i++] * scale + offsetX, cpy1 = outline[i++] * scale + offsetY, path.quadraticCurveTo(cpx1, cpy1, cpx, cpy);
break;
case 'b':
cpx = outline[i++] * scale + offsetX, cpy = outline[i++] * scale + offsetY, cpx1 = outline[i++] * scale + offsetX, cpy1 = outline[i++] * scale + offsetY, cpx2 = outline[i++] * scale + offsetX, cpy2 = outline[i++] * scale + offsetY, path.bezierCurveTo(cpx1, cpy1, cpx2, cpy2, cpx, cpy);
}
return {
offsetX: glyph.ha * scale,
Expand Down
Expand Up @@ -10558,8 +10558,7 @@
return programMapTable;
}
}, parsePesType = function(packet, programMapTable) {
var type = programMapTable[parsePid(packet)];
switch(type){
switch(programMapTable[parsePid(packet)]){
case streamTypes.H264_STREAM_TYPE:
return "video";
case streamTypes.ADTS_STREAM_TYPE:
Expand Down Expand Up @@ -10715,8 +10714,7 @@
}
}, inspectAac_ = function(bytes) {
for(var packet, endLoop = !1, audioCount = 0, sampleRate = null, timestamp = null, frameSize = 0, byteIndex = 0; bytes.length - byteIndex >= 3;){
var type = probe.aac.parseType(bytes, byteIndex);
switch(type){
switch(probe.aac.parseType(bytes, byteIndex)){
case "timed-metadata":
if (bytes.length - byteIndex < 10 || (frameSize = probe.aac.parseId3TagSize(bytes, byteIndex)) > bytes.length) {
endLoop = !0;
Expand Down Expand Up @@ -10757,15 +10755,12 @@
pid: null,
table: null
}, result = {};
for(var pid in parsePsi_(bytes, pmt), pmt.table)if (pmt.table.hasOwnProperty(pid)) {
var type = pmt.table[pid];
switch(type){
case streamTypes.H264_STREAM_TYPE:
result.video = [], parseVideoPes_(bytes, pmt, result), 0 === result.video.length && delete result.video;
break;
case streamTypes.ADTS_STREAM_TYPE:
result.audio = [], parseAudioPes_(bytes, pmt, result), 0 === result.audio.length && delete result.audio;
}
for(var pid in parsePsi_(bytes, pmt), pmt.table)if (pmt.table.hasOwnProperty(pid)) switch(pmt.table[pid]){
case streamTypes.H264_STREAM_TYPE:
result.video = [], parseVideoPes_(bytes, pmt, result), 0 === result.video.length && delete result.video;
break;
case streamTypes.ADTS_STREAM_TYPE:
result.audio = [], parseAudioPes_(bytes, pmt, result), 0 === result.audio.length && delete result.audio;
}
return result;
}, tsInspector = {
Expand Down
Expand Up @@ -8241,8 +8241,8 @@
return t.length < 2 ? "0" + t : t;
}
l.get = function(e) {
var t, r, n = e.substring(0, 3).toLowerCase();
switch(n){
var t, r;
switch(e.substring(0, 3).toLowerCase()){
case "hsl":
t = l.get.hsl(e), r = "hsl";
break;
Expand Down Expand Up @@ -9406,10 +9406,10 @@
stickToLeft: 3,
stickToRight: 4
}; t = e.charAt(r++);){
var o = "." === t, a = !o && /\d/.test(t), u = o ? r - 1 == 0 ? i.stickToLeft : i.stickToRight : a ? i.level : i.alphabet;
switch(u){
var o = "." === t, a = !o && /\d/.test(t);
switch(o ? r - 1 == 0 ? i.stickToLeft : i.stickToRight : a ? i.level : i.alphabet){
case i.alphabet:
l || n.levels.push(0), n.text += t;
u || n.levels.push(0), n.text += t;
break;
case i.level:
n.levels.push(parseInt(t));
Expand All @@ -9420,7 +9420,7 @@
case i.stickToRight:
n.stickToRight = !0;
}
var l = a;
var u = a;
}
return n;
}
Expand Down

1 comment on commit 86e265a

@github-actions
Copy link

Choose a reason for hiding this comment

The reason will be displayed to describe this comment to others. Learn more.

Benchmark

Benchmark suite Current: 86e265a Previous: 01edb4f Ratio
es/full/bugs-1 387271 ns/iter (± 44005) 413795 ns/iter (± 20077) 0.94
es/full/minify/libraries/antd 1919425798 ns/iter (± 69578682) 2013578744 ns/iter (± 45413342) 0.95
es/full/minify/libraries/d3 439895874 ns/iter (± 9446188) 390547845 ns/iter (± 31387493) 1.13
es/full/minify/libraries/echarts 1623574929 ns/iter (± 86070476) 1704129352 ns/iter (± 31177238) 0.95
es/full/minify/libraries/jquery 116698378 ns/iter (± 2073008) 114639845 ns/iter (± 2082991) 1.02
es/full/minify/libraries/lodash 130046915 ns/iter (± 7912521) 141321460 ns/iter (± 3149692) 0.92
es/full/minify/libraries/moment 67110690 ns/iter (± 3357764) 124155576 ns/iter (± 29574186) 0.54
es/full/minify/libraries/react 22592359 ns/iter (± 1594457) 25326873 ns/iter (± 2992753) 0.89
es/full/minify/libraries/terser 342963771 ns/iter (± 18168980) 312746776 ns/iter (± 9812501) 1.10
es/full/minify/libraries/three 544570838 ns/iter (± 18009687) 532482669 ns/iter (± 26915749) 1.02
es/full/minify/libraries/typescript 3392895098 ns/iter (± 61855995) 3790116593 ns/iter (± 81660888) 0.90
es/full/minify/libraries/victory 836893368 ns/iter (± 32989528) 782618271 ns/iter (± 59720608) 1.07
es/full/minify/libraries/vue 159378942 ns/iter (± 6815178) 172810089 ns/iter (± 3431816) 0.92
es/full/codegen/es3 34252 ns/iter (± 1631) 39429 ns/iter (± 2789) 0.87
es/full/codegen/es5 34251 ns/iter (± 2242) 40071 ns/iter (± 2865) 0.85
es/full/codegen/es2015 33984 ns/iter (± 855) 38257 ns/iter (± 2807) 0.89
es/full/codegen/es2016 33691 ns/iter (± 1486) 39066 ns/iter (± 1348) 0.86
es/full/codegen/es2017 33807 ns/iter (± 2128) 38540 ns/iter (± 1958) 0.88
es/full/codegen/es2018 33949 ns/iter (± 1012) 38611 ns/iter (± 1797) 0.88
es/full/codegen/es2019 34066 ns/iter (± 701) 39887 ns/iter (± 2290) 0.85
es/full/codegen/es2020 34042 ns/iter (± 502) 38580 ns/iter (± 1494) 0.88
es/full/all/es3 201231846 ns/iter (± 10537410) 222064422 ns/iter (± 5598935) 0.91
es/full/all/es5 181233095 ns/iter (± 19041028) 211399283 ns/iter (± 7327180) 0.86
es/full/all/es2015 146046126 ns/iter (± 5716949) 170894992 ns/iter (± 8554800) 0.85
es/full/all/es2016 154544399 ns/iter (± 15929619) 169573948 ns/iter (± 6334468) 0.91
es/full/all/es2017 153665769 ns/iter (± 12731676) 168610335 ns/iter (± 13425787) 0.91
es/full/all/es2018 146092101 ns/iter (± 10370831) 165343930 ns/iter (± 6897689) 0.88
es/full/all/es2019 138399647 ns/iter (± 5247802) 164164489 ns/iter (± 5571963) 0.84
es/full/all/es2020 134339039 ns/iter (± 5818882) 158988979 ns/iter (± 6146350) 0.84
es/full/parser 705046 ns/iter (± 30302) 805844 ns/iter (± 38088) 0.87
es/full/base/fixer 25879 ns/iter (± 976) 29050 ns/iter (± 1785) 0.89
es/full/base/resolver_and_hygiene 90517 ns/iter (± 8647) 104876 ns/iter (± 7312) 0.86
serialization of ast node 212 ns/iter (± 7) 255 ns/iter (± 18) 0.83
serialization of serde 218 ns/iter (± 3) 245 ns/iter (± 14) 0.89

This comment was automatically generated by workflow using github-action-benchmark.

Please sign in to comment.