提交 8ef284da 编写于 作者: A Alexey Andreev

JS: improve temporary variable elimination in some cases. Apply redundant...

JS: improve temporary variable elimination in some cases. Apply redundant statement elimination when statement in not synthetic, but its expression is
上级 35ab41e9
...@@ -33,7 +33,9 @@ import org.jetbrains.kotlin.js.inline.clean.RemoveUnusedLocalFunctionDeclaration ...@@ -33,7 +33,9 @@ import org.jetbrains.kotlin.js.inline.clean.RemoveUnusedLocalFunctionDeclaration
import org.jetbrains.kotlin.js.inline.context.FunctionContext; import org.jetbrains.kotlin.js.inline.context.FunctionContext;
import org.jetbrains.kotlin.js.inline.context.InliningContext; import org.jetbrains.kotlin.js.inline.context.InliningContext;
import org.jetbrains.kotlin.js.inline.context.NamingContext; import org.jetbrains.kotlin.js.inline.context.NamingContext;
import org.jetbrains.kotlin.js.inline.util.*; import org.jetbrains.kotlin.js.inline.util.CollectUtilsKt;
import org.jetbrains.kotlin.js.inline.util.CollectionUtilsKt;
import org.jetbrains.kotlin.js.inline.util.NamingUtilsKt;
import org.jetbrains.kotlin.js.translate.context.TranslationContext; import org.jetbrains.kotlin.js.translate.context.TranslationContext;
import org.jetbrains.kotlin.resolve.inline.InlineStrategy; import org.jetbrains.kotlin.resolve.inline.InlineStrategy;
...@@ -268,7 +270,9 @@ public class JsInliner extends JsVisitorWithContextImpl { ...@@ -268,7 +270,9 @@ public class JsInliner extends JsVisitorWithContextImpl {
return; return;
} }
context.replaceMe(accept(resultExpression)); resultExpression = accept(resultExpression);
MetadataProperties.setSynthetic(resultExpression, true);
context.replaceMe(resultExpression);
} }
@NotNull @NotNull
......
...@@ -35,7 +35,7 @@ class RedundantStatementElimination(private val root: JsFunction) { ...@@ -35,7 +35,7 @@ class RedundantStatementElimination(private val root: JsFunction) {
private fun process() { private fun process() {
object : JsVisitorWithContextImpl() { object : JsVisitorWithContextImpl() {
override fun visit(x: JsExpressionStatement, ctx: JsContext<JsNode>): Boolean { override fun visit(x: JsExpressionStatement, ctx: JsContext<JsNode>): Boolean {
if (x.synthetic) { if (x.synthetic || x.expression.synthetic) {
val replacement = replace(x.expression) val replacement = replace(x.expression)
if (replacement.size != 1 || replacement[0] != x.expression) { if (replacement.size != 1 || replacement[0] != x.expression) {
hasChanges = true hasChanges = true
......
...@@ -18,6 +18,7 @@ package org.jetbrains.kotlin.js.inline.clean ...@@ -18,6 +18,7 @@ package org.jetbrains.kotlin.js.inline.clean
import com.google.dart.compiler.backend.js.ast.* import com.google.dart.compiler.backend.js.ast.*
import com.google.dart.compiler.backend.js.ast.metadata.SideEffectKind import com.google.dart.compiler.backend.js.ast.metadata.SideEffectKind
import com.google.dart.compiler.backend.js.ast.metadata.imported
import com.google.dart.compiler.backend.js.ast.metadata.sideEffects import com.google.dart.compiler.backend.js.ast.metadata.sideEffects
import com.google.dart.compiler.backend.js.ast.metadata.synthetic import com.google.dart.compiler.backend.js.ast.metadata.synthetic
import org.jetbrains.kotlin.js.inline.util.collectFreeVariables import org.jetbrains.kotlin.js.inline.util.collectFreeVariables
...@@ -116,35 +117,43 @@ internal class TemporaryVariableElimination(private val function: JsFunction) { ...@@ -116,35 +117,43 @@ internal class TemporaryVariableElimination(private val function: JsFunction) {
var localVars = mutableSetOf<JsName>() var localVars = mutableSetOf<JsName>()
override fun visitExpressionStatement(x: JsExpressionStatement) { override fun visitExpressionStatement(x: JsExpressionStatement) {
val assignment = JsAstUtils.decomposeAssignmentToVariable(x.expression) (x.expression as? JsBinaryOperation)?.let { expression ->
return processBinaryExpression(expression, x.synthetic) { super.visitExpressionStatement(x) }
}
super.visitExpressionStatement(x)
}
override fun visitBinaryExpression(x: JsBinaryOperation) = processBinaryExpression(x, false) { super.visitBinaryExpression(x) }
private fun processBinaryExpression(expression: JsBinaryOperation, synthetic: Boolean, orElse: () -> Unit) {
val assignment = JsAstUtils.decomposeAssignmentToVariable(expression)
if (assignment != null) { if (assignment != null) {
val (name, value) = assignment val (name, value) = assignment
if (name in localVariables) { if (name in localVariables) {
assignVariable(name, value) assignVariable(name, value)
addVar(name) addVar(name)
accept(value) accept(value)
if (x.synthetic) { if (synthetic) {
temporary += name temporary += name
} }
}
else {
super.visitExpressionStatement(x)
}
return return
} }
super.visitExpressionStatement(x) }
orElse()
} }
override fun visitVars(x: JsVars) { override fun visitVars(x: JsVars) {
for (v in x.vars) { for (v in x.vars) {
val name = v.name val name = v.name
val value = v.initExpression val value = v.initExpression
if (value != null && name in localVariables) { if (name in localVariables) {
if (x.synthetic) {
temporary += name
}
if (value != null) {
assignVariable(name, value) assignVariable(name, value)
addVar(name) addVar(name)
accept(value) accept(value)
if (x.synthetic) {
temporary += name
} }
} }
} }
...@@ -507,11 +516,11 @@ internal class TemporaryVariableElimination(private val function: JsFunction) { ...@@ -507,11 +516,11 @@ internal class TemporaryVariableElimination(private val function: JsFunction) {
initializers.forEach { accept(it) } initializers.forEach { accept(it) }
if (isRemoved) { if (isRemoved) {
for (initializer in initializers) { for (initializer in initializers) {
ctx.addPrevious(JsExpressionStatement(accept(initializer)).apply { synthetic = x.synthetic }) ctx.addPrevious(JsExpressionStatement(accept(initializer)).apply { synthetic = true })
} }
} }
else { else {
ctx.addPrevious(JsVars(*subList.toTypedArray()).apply { synthetic = x.synthetic }) ctx.addPrevious(JsVars(*subList.toTypedArray()).apply { synthetic = true })
} }
} }
ctx.removeMe() ctx.removeMe()
...@@ -525,7 +534,12 @@ internal class TemporaryVariableElimination(private val function: JsFunction) { ...@@ -525,7 +534,12 @@ internal class TemporaryVariableElimination(private val function: JsFunction) {
return false return false
} }
val assignment = JsAstUtils.decomposeAssignmentToVariable(x.expression) val expression = x.expression
if (expression is JsNameRef && expression.qualifier == null && expression.name in localVariables) {
x.synthetic = true
}
val assignment = JsAstUtils.decomposeAssignmentToVariable(expression)
if (assignment != null) { if (assignment != null) {
val (name, value) = assignment val (name, value) = assignment
if (shouldConsiderUnused(name)) { if (shouldConsiderUnused(name)) {
...@@ -583,7 +597,8 @@ internal class TemporaryVariableElimination(private val function: JsFunction) { ...@@ -583,7 +597,8 @@ internal class TemporaryVariableElimination(private val function: JsFunction) {
usages[name] = (usages[name] ?: 0) + 1 usages[name] = (usages[name] ?: 0) + 1
} }
private fun shouldConsiderUnused(name: JsName) = definitions[name] == 1 && (usages[name] ?: 0) == 0 && name in temporary private fun shouldConsiderUnused(name: JsName) =
(definitions[name] ?: 0) > 0 && (usages[name] ?: 0) == 0 && name in temporary && !name.imported
private fun shouldConsiderTemporary(name: JsName): Boolean { private fun shouldConsiderTemporary(name: JsName): Boolean {
if (definitions[name] != 1 || name !in temporary) return false if (definitions[name] != 1 || name !in temporary) return false
......
var log = ""; var log = "";
function test(a) { function test(a) {
var $tmp1; log += 1;
log += $tmp1 = 1;
return a; return a;
} }
......
Markdown is supported
0% .
You are about to add 0 people to the discussion. Proceed with caution.
先完成此消息的编辑!
想要评论请 注册