Skip to content

Commit

Permalink
feat(es/minifier): Mark ref to fn as non-call in alias analyzer (#6088)
Browse files Browse the repository at this point in the history
  • Loading branch information
kdy1 committed Oct 9, 2022
1 parent 5163200 commit b0c5745
Show file tree
Hide file tree
Showing 19 changed files with 116 additions and 114 deletions.
4 changes: 2 additions & 2 deletions crates/swc/tests/vercel/full/d3-time-format/1/output/index.js
Original file line number Diff line number Diff line change
Expand Up @@ -378,7 +378,7 @@ function nu(n, t) {
return D(n.getFullYear() % 100, t, 2);
}
function nc(n, t) {
return n = nn(n), D(n.getFullYear() % 100, t, 2);
return D((n = nn(n)).getFullYear() % 100, t, 2);
}
function ni(n, t) {
return D(n.getFullYear() % 10000, t, 4);
Expand Down Expand Up @@ -442,7 +442,7 @@ function nM(n, t) {
return D(n.getUTCFullYear() % 100, t, 2);
}
function np(n, t) {
return n = nx(n), D(n.getUTCFullYear() % 100, t, 2);
return D((n = nx(n)).getUTCFullYear() % 100, t, 2);
}
function nH(n, t) {
return D(n.getUTCFullYear() % 10000, t, 4);
Expand Down
Original file line number Diff line number Diff line change
Expand Up @@ -119,9 +119,9 @@ var ItemsList = function(_Component) {
if (!_instanceof(instance, Constructor)) throw TypeError("Cannot call a class as a function");
}(this, ItemsList);
for(var _len = arguments.length, args = Array(_len), _key = 0; _key < _len; _key++)args[_key] = arguments[_key];
return _this = _super.call.apply(_super, [
return _defineProperty(_assertThisInitialized(_this = _super.call.apply(_super, [
this
].concat(args)), _defineProperty(_assertThisInitialized(_this), "storeHighlightedItemReference", function(highlightedItem) {
].concat(args))), "storeHighlightedItemReference", function(highlightedItem) {
_this.props.onHighlightedItemChange(null === highlightedItem ? null : highlightedItem.item);
}), _this;
}
Expand Down
40 changes: 25 additions & 15 deletions crates/swc_ecma_minifier/src/analyzer/mod.rs
Original file line number Diff line number Diff line change
Expand Up @@ -85,6 +85,7 @@ pub(crate) struct VarUsageInfo {
/// `true` if the enclosing function defines this variable as a parameter.
pub declared_as_fn_param: bool,

pub declared_as_fn_decl: bool,
pub declared_as_fn_expr: bool,

pub assign_count: u32,
Expand Down Expand Up @@ -224,19 +225,22 @@ impl ProgramData {
let infects = &info.infects;
if !infects.is_empty() {
let old_len = ids.len();
match iid.1 {
AccessKind::Reference => {
// This is not a call, so effects from call can be skipped
ids.extend(
infects
.iter()
.filter(|(_, kind)| *kind != AccessKind::Call)
.cloned(),
);
}
AccessKind::Call => {
ids.extend_from_slice(infects.as_slice());
}

// This is not a call, so effects from call can be skipped
let can_skip_non_call = matches!(iid.1, AccessKind::Reference)
|| (info.declared_count == 1
&& info.declared_as_fn_decl
&& !info.reassigned());

if can_skip_non_call {
ids.extend(
infects
.iter()
.filter(|(_, kind)| *kind != AccessKind::Call)
.cloned(),
);
} else {
ids.extend_from_slice(infects.as_slice());
}
let new_len = ids.len();
ranges.push(old_len..new_len);
Expand Down Expand Up @@ -390,11 +394,17 @@ where
i: &Ident,
has_init: bool,
kind: Option<VarDeclKind>,
_is_fn_decl: bool,
is_fn_decl: bool,
) -> &mut S::VarData {
self.scope.add_declared_symbol(i);

self.data.declare_decl(self.ctx, i, has_init, kind)
let v = self.data.declare_decl(self.ctx, i, has_init, kind);

if is_fn_decl {
v.mark_declared_as_fn_decl();
}

v
}

fn visit_in_cond<T: VisitWith<Self>>(&mut self, t: &T) {
Expand Down
2 changes: 2 additions & 0 deletions crates/swc_ecma_minifier/src/analyzer/storage/mod.rs
Original file line number Diff line number Diff line change
Expand Up @@ -49,6 +49,8 @@ pub(crate) trait VarDataLike: Sized {
/// See `declared_as_fn_param` of [crate::analyzer::VarUsageInfo].
fn mark_declared_as_fn_param(&mut self);

fn mark_declared_as_fn_decl(&mut self);

fn mark_declared_as_fn_expr(&mut self);

fn mark_has_property_access(&mut self);
Expand Down
5 changes: 5 additions & 0 deletions crates/swc_ecma_minifier/src/analyzer/storage/normal.rs
Original file line number Diff line number Diff line change
Expand Up @@ -62,6 +62,7 @@ impl Storage for ProgramData {
e.get_mut().declared |= var_info.declared;
e.get_mut().declared_count += var_info.declared_count;
e.get_mut().declared_as_fn_param |= var_info.declared_as_fn_param;
e.get_mut().declared_as_fn_decl |= var_info.declared_as_fn_decl;
e.get_mut().declared_as_fn_expr |= var_info.declared_as_fn_expr;

// If a var is registered at a parent scope, it means that it's delcared before
Expand Down Expand Up @@ -295,6 +296,10 @@ impl VarDataLike for VarUsageInfo {
self.declared_as_fn_param = true;
}

fn mark_declared_as_fn_decl(&mut self) {
self.declared_as_fn_decl = true;
}

fn mark_declared_as_fn_expr(&mut self) {
self.declared_as_fn_expr = true;
}
Expand Down
6 changes: 3 additions & 3 deletions crates/swc_ecma_minifier/tests/benches-full/echarts.js
Original file line number Diff line number Diff line change
Expand Up @@ -13138,12 +13138,12 @@
}, ECharts.prototype.convertFromPixel = function(finder, value) {
return doConvertPixel(this, 'convertFromPixel', finder, value);
}, ECharts.prototype.containPixel = function(finder, value) {
var result;
if (this._disposed) {
disposedWarning(this.id);
return;
}
var result, findResult = parseFinder(this._model, finder);
return each(findResult, function(models, key) {
return each(parseFinder(this._model, finder), function(models, key) {
key.indexOf('Models') >= 0 && each(models, function(model) {
var coordSys = model.coordinateSystem;
if (coordSys && coordSys.containPoint) result = result || !!coordSys.containPoint(value);
Expand Down Expand Up @@ -31185,7 +31185,7 @@
if (!1 === clipPathOpt) el && el.getClipPath() && el.removeClipPath();
else if (clipPathOpt) {
var clipPath = el.getClipPath();
clipPath && doesElNeedRecreate(clipPath, clipPathOpt) && (clipPath = null), !clipPath && (clipPath = createEl(clipPathOpt), assert(clipPath instanceof Path, 'Only any type of `path` can be used in `clipPath`, rather than ' + clipPath.type + '.'), el.setClipPath(clipPath)), updateElNormal(null, clipPath, null, dataIndex, clipPathOpt, null, null, seriesModel, isInit, !1);
clipPath && doesElNeedRecreate(clipPath, clipPathOpt) && (clipPath = null), !clipPath && (assert((clipPath = createEl(clipPathOpt)) instanceof Path, 'Only any type of `path` can be used in `clipPath`, rather than ' + clipPath.type + '.'), el.setClipPath(clipPath)), updateElNormal(null, clipPath, null, dataIndex, clipPathOpt, null, null, seriesModel, isInit, !1);
}
}(el, dataIndex, elOption, seriesModel, isInit);
var pendingAllPropsFinal = updateElNormal(api, el, thisElIsMorphTo, dataIndex, elOption, elOption.style, attachedTxInfoTmp, seriesModel, isInit, !1);
Expand Down
2 changes: 1 addition & 1 deletion crates/swc_ecma_minifier/tests/benches-full/lodash.js
Original file line number Diff line number Diff line change
Expand Up @@ -2421,7 +2421,7 @@
});
}, lodash.conforms = function(source) {
var source1, props;
return source1 = baseClone(source, 1), props = keys(source1), function(object) {
return props = keys(source1 = baseClone(source, 1)), function(object) {
return baseConformsTo(object, source1, props);
};
}, lodash.constant = constant, lodash.countBy = countBy, lodash.create = function(prototype, properties) {
Expand Down
6 changes: 3 additions & 3 deletions crates/swc_ecma_minifier/tests/benches-full/moment.js
Original file line number Diff line number Diff line change
Expand Up @@ -951,8 +951,8 @@
}
function createAdder(direction, name) {
return function(val, period) {
var dur, tmp;
return null === period || isNaN(+period) || (deprecateSimple(name, 'moment().' + name + '(period, number) is deprecated. Please use moment().' + name + "(number, period). See http://momentjs.com/guides/#/warnings/add-inverted-param/ for more info."), tmp = val, val = period, period = tmp), dur = createDuration(val, period), addSubtract(this, dur, direction), this;
var tmp;
return null === period || isNaN(+period) || (deprecateSimple(name, 'moment().' + name + '(period, number) is deprecated. Please use moment().' + name + "(number, period). See http://momentjs.com/guides/#/warnings/add-inverted-param/ for more info."), tmp = val, val = period, period = tmp), addSubtract(this, createDuration(val, period), direction), this;
};
}
function addSubtract(mom, duration, isAdding, updateOffset) {
Expand Down Expand Up @@ -1771,7 +1771,7 @@
}, proto$2.months = months, proto$2.years = years, proto$2.humanize = function(argWithSuffix, argThresholds) {
if (!this.isValid()) return this.localeData().invalidDate();
var posNegDuration, withoutSuffix, thresholds1, locale, duration, seconds, minutes, hours, days, months, weeks, years, a, locale1, output, withSuffix = !1, th = thresholds;
return 'object' == typeof argWithSuffix && (argThresholds = argWithSuffix, argWithSuffix = !1), 'boolean' == typeof argWithSuffix && (withSuffix = argWithSuffix), 'object' == typeof argThresholds && (th = Object.assign({}, thresholds, argThresholds), null != argThresholds.s && null == argThresholds.ss && (th.ss = argThresholds.s - 1)), locale1 = this.localeData(), withoutSuffix = !withSuffix, thresholds1 = th, duration = createDuration(this).abs(), seconds = round(duration.as('s')), minutes = round(duration.as('m')), hours = round(duration.as('h')), days = round(duration.as('d')), months = round(duration.as('M')), weeks = round(duration.as('w')), years = round(duration.as('y')), a = seconds <= thresholds1.ss && [
return 'object' == typeof argWithSuffix && (argThresholds = argWithSuffix, argWithSuffix = !1), 'boolean' == typeof argWithSuffix && (withSuffix = argWithSuffix), 'object' == typeof argThresholds && (th = Object.assign({}, thresholds, argThresholds), null != argThresholds.s && null == argThresholds.ss && (th.ss = argThresholds.s - 1)), locale1 = this.localeData(), withoutSuffix = !withSuffix, thresholds1 = th, seconds = round((duration = createDuration(this).abs()).as('s')), minutes = round(duration.as('m')), hours = round(duration.as('h')), days = round(duration.as('d')), months = round(duration.as('M')), weeks = round(duration.as('w')), years = round(duration.as('y')), a = seconds <= thresholds1.ss && [
's',
seconds
] || seconds < thresholds1.s && [
Expand Down
6 changes: 1 addition & 5 deletions crates/swc_ecma_minifier/tests/benches-full/react.js
Original file line number Diff line number Diff line change
Expand Up @@ -566,11 +566,7 @@
!error$1 || error$1 instanceof Error || (setCurrentlyValidatingElement(element), error("%s: type specification of %s `%s` is invalid; the type checker function must return `null` or an `Error` but returned a %s. You may have forgotten to pass an argument to the type checker creator (arrayOf, instanceOf, objectOf, oneOf, oneOfType, and shape all require an argument).", componentName || 'React class', location, typeSpecName, typeof error$1), setCurrentlyValidatingElement(null)), error$1 instanceof Error && !(error$1.message in loggedTypeFailures) && (loggedTypeFailures[error$1.message] = !0, setCurrentlyValidatingElement(element), error('Failed %s type: %s', location, error$1.message), setCurrentlyValidatingElement(null));
}
}(propTypes, element.props, 'prop', name, element);
} else if (void 0 !== type.PropTypes && !propTypesMisspellWarningShown) {
propTypesMisspellWarningShown = !0;
var _name = getComponentName(type);
error('Component %s declared `PropTypes` instead of `propTypes`. Did you misspell the property assignment?', _name || 'Unknown');
}
} else void 0 === type.PropTypes || propTypesMisspellWarningShown || (propTypesMisspellWarningShown = !0, error('Component %s declared `PropTypes` instead of `propTypes`. Did you misspell the property assignment?', getComponentName(type) || 'Unknown'));
'function' != typeof type.getDefaultProps || type.getDefaultProps.isReactClassApproved || error("getDefaultProps is only used on classic React.createClass definitions. Use a static property named `defaultProps` instead.");
}
}
Expand Down

1 comment on commit b0c5745

@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: b0c5745 Previous: 3190f79 Ratio
es/full/minify/libraries/antd 1789600891 ns/iter (± 65847963) 1651851112 ns/iter (± 30504588) 1.08
es/full/minify/libraries/d3 374023126 ns/iter (± 14496031) 354135834 ns/iter (± 9965010) 1.06
es/full/minify/libraries/echarts 1391071015 ns/iter (± 62345247) 1311180694 ns/iter (± 36205603) 1.06
es/full/minify/libraries/jquery 92752187 ns/iter (± 6908908) 85040213 ns/iter (± 7262188) 1.09
es/full/minify/libraries/lodash 108500472 ns/iter (± 5612563) 95621123 ns/iter (± 1472993) 1.13
es/full/minify/libraries/moment 55399095 ns/iter (± 6301563) 49642098 ns/iter (± 805530) 1.12
es/full/minify/libraries/react 19454578 ns/iter (± 803845) 17198981 ns/iter (± 462840) 1.13
es/full/minify/libraries/terser 307164506 ns/iter (± 13111522) 265726997 ns/iter (± 2803171) 1.16
es/full/minify/libraries/three 487830148 ns/iter (± 10428995) 484305998 ns/iter (± 17782164) 1.01
es/full/minify/libraries/typescript 2979459275 ns/iter (± 25898371) 3014986613 ns/iter (± 85504324) 0.99
es/full/minify/libraries/victory 719574542 ns/iter (± 20703052) 703842134 ns/iter (± 16764179) 1.02
es/full/minify/libraries/vue 137646501 ns/iter (± 8983582) 123122307 ns/iter (± 9382443) 1.12
es/full/codegen/es3 34804 ns/iter (± 1671) 35018 ns/iter (± 968) 0.99
es/full/codegen/es5 34883 ns/iter (± 1588) 35307 ns/iter (± 12363) 0.99
es/full/codegen/es2015 35483 ns/iter (± 5273) 35330 ns/iter (± 1046) 1.00
es/full/codegen/es2016 34605 ns/iter (± 1477) 35229 ns/iter (± 1000) 0.98
es/full/codegen/es2017 34896 ns/iter (± 2097) 35276 ns/iter (± 2100) 0.99
es/full/codegen/es2018 35559 ns/iter (± 2080) 35181 ns/iter (± 2008) 1.01
es/full/codegen/es2019 34435 ns/iter (± 1469) 35864 ns/iter (± 2721) 0.96
es/full/codegen/es2020 35308 ns/iter (± 2012) 35301 ns/iter (± 1414) 1.00
es/full/all/es3 205343744 ns/iter (± 11849126) 208350282 ns/iter (± 19634159) 0.99
es/full/all/es5 189463039 ns/iter (± 10807562) 197530236 ns/iter (± 21247992) 0.96
es/full/all/es2015 155389866 ns/iter (± 8880414) 155822722 ns/iter (± 14029788) 1.00
es/full/all/es2016 152325089 ns/iter (± 9292643) 153163937 ns/iter (± 16254923) 0.99
es/full/all/es2017 146548597 ns/iter (± 6006630) 155061144 ns/iter (± 17365634) 0.95
es/full/all/es2018 146435385 ns/iter (± 10375668) 154722898 ns/iter (± 14166409) 0.95
es/full/all/es2019 152777986 ns/iter (± 10552742) 167306987 ns/iter (± 24813855) 0.91
es/full/all/es2020 143407097 ns/iter (± 8244019) 153991246 ns/iter (± 13508900) 0.93
es/full/parser 750076 ns/iter (± 35775) 750831 ns/iter (± 62534) 1.00
es/full/base/fixer 27088 ns/iter (± 2035) 26995 ns/iter (± 1723) 1.00
es/full/base/resolver_and_hygiene 97227 ns/iter (± 6791) 97230 ns/iter (± 3847) 1.00
serialization of ast node 218 ns/iter (± 17) 212 ns/iter (± 4) 1.03
serialization of serde 223 ns/iter (± 23) 214 ns/iter (± 3) 1.04

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

Please sign in to comment.