perf(es/minifier): Make dead branch remover parallel (#5734)

This commit is contained in:
Donny/강동윤 2022-09-04 16:33:26 +09:00 committed by GitHub
parent 8c7f968b53
commit 6ba6da62d7
No known key found for this signature in database
GPG Key ID: 4AEE18F83AFDEB23
3 changed files with 63 additions and 24 deletions

View File

@ -165,12 +165,14 @@ var ts;
function addExportEqualsIfNeeded(statements, emitAsReturn) {
if (currentModuleInfo.exportEquals) {
var expressionResult = ts.visitNode(currentModuleInfo.exportEquals.expression, visitor);
if (expressionResult) if (emitAsReturn) {
var statement = factory.createReturnStatement(expressionResult);
ts.setTextRange(statement, currentModuleInfo.exportEquals), ts.setEmitFlags(statement, 1920), statements.push(statement);
} else {
var statement = factory.createExpressionStatement(factory.createAssignment(factory.createPropertyAccessExpression(factory.createIdentifier("module"), "exports"), expressionResult));
ts.setTextRange(statement, currentModuleInfo.exportEquals), ts.setEmitFlags(statement, 1536), statements.push(statement);
if (expressionResult) {
if (emitAsReturn) {
var statement = factory.createReturnStatement(expressionResult);
ts.setTextRange(statement, currentModuleInfo.exportEquals), ts.setEmitFlags(statement, 1920), statements.push(statement);
} else {
var statement = factory.createExpressionStatement(factory.createAssignment(factory.createPropertyAccessExpression(factory.createIdentifier("module"), "exports"), expressionResult));
ts.setTextRange(statement, currentModuleInfo.exportEquals), ts.setEmitFlags(statement, 1536), statements.push(statement);
}
}
}
}
@ -243,10 +245,12 @@ var ts;
for(var statements, variables, expressions, modifiers = void 0, removeCommentsOnExpressions = !1, _i = 0, _a = node.declarationList.declarations; _i < _a.length; _i++){
var variable = _a[_i];
if (ts.isIdentifier(variable.name) && ts.isLocalName(variable.name)) modifiers || (modifiers = ts.visitNodes(node.modifiers, modifierVisitor, ts.isModifier)), variables = ts.append(variables, variable);
else if (variable.initializer) if (!ts.isBindingPattern(variable.name) && (ts.isArrowFunction(variable.initializer) || ts.isFunctionExpression(variable.initializer) || ts.isClassExpression(variable.initializer))) {
var expression = factory.createAssignment(ts.setTextRange(factory.createPropertyAccessExpression(factory.createIdentifier("exports"), variable.name), variable.name), factory.createIdentifier(ts.getTextOfIdentifierOrLiteral(variable.name))), updatedVariable = factory.createVariableDeclaration(variable.name, variable.exclamationToken, variable.type, ts.visitNode(variable.initializer, visitor));
variables = ts.append(variables, updatedVariable), expressions = ts.append(expressions, expression), removeCommentsOnExpressions = !0;
} else expressions = ts.append(expressions, transformInitializedVariable(variable));
else if (variable.initializer) {
if (!ts.isBindingPattern(variable.name) && (ts.isArrowFunction(variable.initializer) || ts.isFunctionExpression(variable.initializer) || ts.isClassExpression(variable.initializer))) {
var expression = factory.createAssignment(ts.setTextRange(factory.createPropertyAccessExpression(factory.createIdentifier("exports"), variable.name), variable.name), factory.createIdentifier(ts.getTextOfIdentifierOrLiteral(variable.name))), updatedVariable = factory.createVariableDeclaration(variable.name, variable.exclamationToken, variable.type, ts.visitNode(variable.initializer, visitor));
variables = ts.append(variables, updatedVariable), expressions = ts.append(expressions, expression), removeCommentsOnExpressions = !0;
} else expressions = ts.append(expressions, transformInitializedVariable(variable));
}
}
if (variables && (statements = ts.append(statements, factory.updateVariableStatement(node, modifiers, factory.updateVariableDeclarationList(node.declarationList, variables)))), expressions) {
var statement = ts.setOriginalNode(ts.setTextRange(factory.createExpressionStatement(factory.inlineExpressions(expressions)), node), node);

View File

@ -1189,14 +1189,16 @@
if (attrStart && ($compileNode = groupScan(compileNode, attrStart, attrEnd)), $template = undefined, terminalPriority > directive.priority) break;
if ((directiveValue = directive.scope) && (newScopeDirective = newScopeDirective || directive, !directive.templateUrl && (assertNoDuplicate("new/isolated scope", newIsolateScopeDirective, directive, $compileNode), isObject(directiveValue) && (newIsolateScopeDirective = directive))), directiveName = directive.name, !directive.templateUrl && directive.controller && (directiveValue = directive.controller, assertNoDuplicate("'" + directiveName + "' controller", (controllerDirectives = controllerDirectives || {})[directiveName], directive, $compileNode), controllerDirectives[directiveName] = directive), (directiveValue = directive.transclude) && (hasTranscludeDirective = !0, directive.$$tlb || (assertNoDuplicate("transclusion", nonTlbTranscludeDirective, directive, $compileNode), nonTlbTranscludeDirective = directive), "element" == directiveValue ? (hasElementTranscludeDirective = !0, terminalPriority = directive.priority, $template = groupScan(compileNode, attrStart, attrEnd), compileNode = ($compileNode = templateAttrs.$$element = jqLite(document1.createComment(" " + directiveName + ": " + templateAttrs[directiveName] + " ")))[0], replaceWith(jqCollection, jqLite(sliceArgs($template)), compileNode), childTranscludeFn = compile($template, transcludeFn, terminalPriority, replaceDirective && replaceDirective.name, {
nonTlbTranscludeDirective: nonTlbTranscludeDirective
})) : ($template = jqLite(jqLiteClone(compileNode)).contents(), $compileNode.empty(), childTranscludeFn = compile($template, transcludeFn))), directive.template) if (assertNoDuplicate("template", templateDirective, directive, $compileNode), templateDirective = directive, directiveValue = isFunction(directive.template) ? directive.template($compileNode, templateAttrs) : directive.template, directiveValue = denormalizeTemplate(directiveValue), directive.replace) {
if (replaceDirective = directive, compileNode = ($template = jqLite("<div>" + trim(directiveValue) + "</div>").contents())[0], 1 != $template.length || 1 !== compileNode.nodeType) throw $compileMinErr("tplrt", "Template for directive '{0}' must have exactly one root element. {1}", directiveName, "");
replaceWith(jqCollection, $compileNode, compileNode);
var newTemplateAttrs = {
$attr: {}
}, templateDirectives = collectDirectives(compileNode, [], newTemplateAttrs), unprocessedDirectives = directives.splice(i + 1, directives.length - (i + 1));
newIsolateScopeDirective && markDirectivesAsIsolate(templateDirectives), directives = directives.concat(templateDirectives).concat(unprocessedDirectives), mergeTemplateAttributes(templateAttrs, newTemplateAttrs), ii = directives.length;
} else $compileNode.html(directiveValue);
})) : ($template = jqLite(jqLiteClone(compileNode)).contents(), $compileNode.empty(), childTranscludeFn = compile($template, transcludeFn))), directive.template) {
if (assertNoDuplicate("template", templateDirective, directive, $compileNode), templateDirective = directive, directiveValue = isFunction(directive.template) ? directive.template($compileNode, templateAttrs) : directive.template, directiveValue = denormalizeTemplate(directiveValue), directive.replace) {
if (replaceDirective = directive, compileNode = ($template = jqLite("<div>" + trim(directiveValue) + "</div>").contents())[0], 1 != $template.length || 1 !== compileNode.nodeType) throw $compileMinErr("tplrt", "Template for directive '{0}' must have exactly one root element. {1}", directiveName, "");
replaceWith(jqCollection, $compileNode, compileNode);
var newTemplateAttrs = {
$attr: {}
}, templateDirectives = collectDirectives(compileNode, [], newTemplateAttrs), unprocessedDirectives = directives.splice(i + 1, directives.length - (i + 1));
newIsolateScopeDirective && markDirectivesAsIsolate(templateDirectives), directives = directives.concat(templateDirectives).concat(unprocessedDirectives), mergeTemplateAttributes(templateAttrs, newTemplateAttrs), ii = directives.length;
} else $compileNode.html(directiveValue);
}
if (directive.templateUrl) assertNoDuplicate("template", templateDirective, directive, $compileNode), templateDirective = directive, directive.replace && (replaceDirective = directive), nodeLinkFn = compileTemplateUrl(directives.splice(i, directives.length - i), $compileNode, templateAttrs, jqCollection, childTranscludeFn, preLinkFns, postLinkFns, {
controllerDirectives: controllerDirectives,
newIsolateScopeDirective: newIsolateScopeDirective,

View File

@ -7,7 +7,10 @@ use swc_common::{
Mark, Spanned, SyntaxContext, DUMMY_SP,
};
use swc_ecma_ast::*;
use swc_ecma_transforms_base::pass::RepeatedJsPass;
use swc_ecma_transforms_base::{
pass::RepeatedJsPass,
perf::{cpu_count, Parallel, ParallelExt},
};
use swc_ecma_utils::{
extract_var_ids, is_literal, prepend_stmt, undefined, ExprCtx, ExprExt, ExprFactory, Hoister,
IsEmpty, StmtExt, StmtLike, Value::Known,
@ -58,6 +61,17 @@ struct Remover {
expr_ctx: ExprCtx,
}
impl Parallel for Remover {
fn create(&self) -> Self {
Self {
expr_ctx: self.expr_ctx.clone(),
..*self
}
}
fn merge(&mut self, _: Self) {}
}
impl VisitMut for Remover {
noop_visit_mut_type!();
@ -1217,6 +1231,24 @@ impl VisitMut for Remover {
s.cases.clear();
}
}
fn visit_mut_prop_or_spreads(&mut self, n: &mut Vec<PropOrSpread>) {
self.maybe_par(cpu_count() * 8, n, |v, n| {
n.visit_mut_with(v);
})
}
fn visit_mut_expr_or_spreads(&mut self, n: &mut Vec<ExprOrSpread>) {
self.maybe_par(cpu_count() * 8, n, |v, n| {
n.visit_mut_with(v);
})
}
fn visit_mut_opt_vec_expr_or_spreads(&mut self, n: &mut Vec<Option<ExprOrSpread>>) {
self.maybe_par(cpu_count() * 8, n, |v, n| {
n.visit_mut_with(v);
})
}
}
impl Remover {
@ -1231,12 +1263,13 @@ impl Remover {
let mut new_stmts = Vec::with_capacity(stmts.len());
let mut iter = stmts.take().into_iter();
while let Some(mut stmt_like) = iter.next() {
self.normal_block = true;
stmt_like.visit_mut_with(self);
self.normal_block = false;
self.maybe_par(cpu_count() * 8, &mut *stmts, |visitor, stmt| {
visitor.normal_block = true;
stmt.visit_mut_with(visitor);
});
let mut iter = stmts.take().into_iter();
while let Some(stmt_like) = iter.next() {
let stmt_like = match stmt_like.try_into_stmt() {
Ok(stmt) => {
let stmt = match stmt {