[JS IR] Not create temporary variable for pure expressions on inline
This commit is contained in:
@@ -664,6 +664,7 @@ fun IrExpression?.isPure(
|
|||||||
}
|
}
|
||||||
is IrCall -> context?.isSideEffectFree(this) ?: false
|
is IrCall -> context?.isSideEffectFree(this) ?: false
|
||||||
is IrGetObjectValue -> type.isUnit()
|
is IrGetObjectValue -> type.isUnit()
|
||||||
|
is IrVararg -> elements.all { (it as? IrExpression).isPure(anyVariable, checkFields, context) }
|
||||||
else -> false
|
else -> false
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
|
|||||||
+36
-18
@@ -6,8 +6,12 @@
|
|||||||
package org.jetbrains.kotlin.backend.common.lower.inline
|
package org.jetbrains.kotlin.backend.common.lower.inline
|
||||||
|
|
||||||
|
|
||||||
import org.jetbrains.kotlin.backend.common.*
|
import org.jetbrains.kotlin.backend.common.BodyLoweringPass
|
||||||
|
import org.jetbrains.kotlin.backend.common.CommonBackendContext
|
||||||
|
import org.jetbrains.kotlin.backend.common.IrElementTransformerVoidWithContext
|
||||||
|
import org.jetbrains.kotlin.backend.common.ScopeWithIr
|
||||||
import org.jetbrains.kotlin.backend.common.ir.Symbols
|
import org.jetbrains.kotlin.backend.common.ir.Symbols
|
||||||
|
import org.jetbrains.kotlin.backend.common.ir.isPure
|
||||||
import org.jetbrains.kotlin.backend.common.lower.createIrBuilder
|
import org.jetbrains.kotlin.backend.common.lower.createIrBuilder
|
||||||
import org.jetbrains.kotlin.config.LanguageFeature
|
import org.jetbrains.kotlin.config.LanguageFeature
|
||||||
import org.jetbrains.kotlin.config.LanguageVersionSettings
|
import org.jetbrains.kotlin.config.LanguageVersionSettings
|
||||||
@@ -20,9 +24,14 @@ import org.jetbrains.kotlin.ir.builders.irReturn
|
|||||||
import org.jetbrains.kotlin.ir.declarations.*
|
import org.jetbrains.kotlin.ir.declarations.*
|
||||||
import org.jetbrains.kotlin.ir.expressions.*
|
import org.jetbrains.kotlin.ir.expressions.*
|
||||||
import org.jetbrains.kotlin.ir.expressions.impl.*
|
import org.jetbrains.kotlin.ir.expressions.impl.*
|
||||||
import org.jetbrains.kotlin.ir.symbols.*
|
import org.jetbrains.kotlin.ir.symbols.IrFunctionSymbol
|
||||||
|
import org.jetbrains.kotlin.ir.symbols.IrSymbol
|
||||||
|
import org.jetbrains.kotlin.ir.symbols.IrValueSymbol
|
||||||
import org.jetbrains.kotlin.ir.symbols.impl.IrReturnableBlockSymbolImpl
|
import org.jetbrains.kotlin.ir.symbols.impl.IrReturnableBlockSymbolImpl
|
||||||
import org.jetbrains.kotlin.ir.types.*
|
import org.jetbrains.kotlin.ir.types.IrSimpleType
|
||||||
|
import org.jetbrains.kotlin.ir.types.IrType
|
||||||
|
import org.jetbrains.kotlin.ir.types.isNullable
|
||||||
|
import org.jetbrains.kotlin.ir.types.typeOrNull
|
||||||
import org.jetbrains.kotlin.ir.util.*
|
import org.jetbrains.kotlin.ir.util.*
|
||||||
import org.jetbrains.kotlin.ir.visitors.IrElementTransformerVoid
|
import org.jetbrains.kotlin.ir.visitors.IrElementTransformerVoid
|
||||||
import org.jetbrains.kotlin.ir.visitors.IrElementVisitor
|
import org.jetbrains.kotlin.ir.visitors.IrElementVisitor
|
||||||
@@ -516,6 +525,7 @@ class FunctionInlining(
|
|||||||
val arguments = buildParameterToArgument(callSite, callee)
|
val arguments = buildParameterToArgument(callSite, callee)
|
||||||
val evaluationStatements = mutableListOf<IrStatement>()
|
val evaluationStatements = mutableListOf<IrStatement>()
|
||||||
val substitutor = ParameterSubstitutor()
|
val substitutor = ParameterSubstitutor()
|
||||||
|
var argumentExtracted = false
|
||||||
arguments.forEach { argument ->
|
arguments.forEach { argument ->
|
||||||
/*
|
/*
|
||||||
* We need to create temporary variable for each argument except inlinable lambda arguments.
|
* We need to create temporary variable for each argument except inlinable lambda arguments.
|
||||||
@@ -523,12 +533,14 @@ class FunctionInlining(
|
|||||||
* not only for those referring to inlinable lambdas.
|
* not only for those referring to inlinable lambdas.
|
||||||
*/
|
*/
|
||||||
if (argument.isInlinableLambdaArgument) {
|
if (argument.isInlinableLambdaArgument) {
|
||||||
|
argumentExtracted = true
|
||||||
substituteMap[argument.parameter] = argument.argumentExpression
|
substituteMap[argument.parameter] = argument.argumentExpression
|
||||||
(argument.argumentExpression as? IrFunctionReference)?.let { evaluationStatements += evaluateArguments(it) }
|
(argument.argumentExpression as? IrFunctionReference)?.let { evaluationStatements += evaluateArguments(it) }
|
||||||
return@forEach
|
return@forEach
|
||||||
}
|
}
|
||||||
|
|
||||||
if (argument.isImmutableVariableLoad) {
|
if (argument.isImmutableVariableLoad) {
|
||||||
|
argumentExtracted = true
|
||||||
substituteMap[argument.parameter] =
|
substituteMap[argument.parameter] =
|
||||||
argument.argumentExpression.transform( // Arguments may reference the previous ones - substitute them.
|
argument.argumentExpression.transform( // Arguments may reference the previous ones - substitute them.
|
||||||
substitutor,
|
substitutor,
|
||||||
@@ -537,25 +549,31 @@ class FunctionInlining(
|
|||||||
return@forEach
|
return@forEach
|
||||||
}
|
}
|
||||||
|
|
||||||
|
argumentExtracted = argumentExtracted || !argument.argumentExpression.isPure(false)
|
||||||
|
|
||||||
// Arguments may reference the previous ones - substitute them.
|
// Arguments may reference the previous ones - substitute them.
|
||||||
val variableInitializer = argument.argumentExpression.transform(substitutor, data = null)
|
val variableInitializer = argument.argumentExpression.transform(substitutor, data = null)
|
||||||
|
|
||||||
val newVariable =
|
if (!argumentExtracted) {
|
||||||
currentScope.scope.createTemporaryVariable(
|
substituteMap[argument.parameter] = variableInitializer
|
||||||
irExpression = IrBlockImpl(
|
} else {
|
||||||
variableInitializer.startOffset,
|
val newVariable =
|
||||||
variableInitializer.endOffset,
|
currentScope.scope.createTemporaryVariable(
|
||||||
variableInitializer.type,
|
irExpression = IrBlockImpl(
|
||||||
InlinerExpressionLocationHint((currentScope.irElement as IrSymbolOwner).symbol)
|
variableInitializer.startOffset,
|
||||||
).apply {
|
variableInitializer.endOffset,
|
||||||
statements.add(variableInitializer)
|
variableInitializer.type,
|
||||||
},
|
InlinerExpressionLocationHint((currentScope.irElement as IrSymbolOwner).symbol)
|
||||||
nameHint = callee.symbol.owner.name.toString(),
|
).apply {
|
||||||
isMutable = false
|
statements.add(variableInitializer)
|
||||||
)
|
},
|
||||||
|
nameHint = callee.symbol.owner.name.toString(),
|
||||||
|
isMutable = false
|
||||||
|
)
|
||||||
|
|
||||||
evaluationStatements.add(newVariable)
|
evaluationStatements.add(newVariable)
|
||||||
substituteMap[argument.parameter] = IrGetValueWithoutLocation(newVariable.symbol)
|
substituteMap[argument.parameter] = IrGetValueWithoutLocation(newVariable.symbol)
|
||||||
|
}
|
||||||
}
|
}
|
||||||
return evaluationStatements
|
return evaluationStatements
|
||||||
}
|
}
|
||||||
|
|||||||
Reference in New Issue
Block a user