Support smap creation for functions inlined with IR inliner

This commit is contained in:
Ivan Kylchik
2022-12-16 14:53:11 +01:00
committed by Space Team
parent d451bc94a2
commit 32a7633c06
14 changed files with 409 additions and 68 deletions
@@ -49,12 +49,9 @@ abstract class DefaultArgumentFunctionFactory(open val context: CommonBackendCon
type = if (makeNullable) newType.makeNullable() else newType,
defaultValue = if (it.defaultValue != null) {
original.factory.createExpressionBody(
IrErrorExpressionImpl(
UNDEFINED_OFFSET,
UNDEFINED_OFFSET,
it.type,
"Default Stub"
)
IrErrorExpressionImpl(UNDEFINED_OFFSET, UNDEFINED_OFFSET, it.type, "Default Stub").apply {
attributeOwnerId = it.defaultValue!!.expression
}
)
} else null,
isAssignable = it.defaultValue != null
@@ -462,7 +462,9 @@ class DefaultParameterCleaner(
if (replaceDefaultValuesWithStubs) {
if (context.mapping.defaultArgumentsOriginalFunction[declaration.parent as IrFunction] == null) {
declaration.defaultValue = context.irFactory.createExpressionBody(
IrErrorExpressionImpl(UNDEFINED_OFFSET, UNDEFINED_OFFSET, declaration.type, "Default Stub")
IrErrorExpressionImpl(UNDEFINED_OFFSET, UNDEFINED_OFFSET, declaration.type, "Default Stub").apply {
attributeOwnerId = declaration.defaultValue!!.expression
}
)
}
} else {
@@ -6,24 +6,19 @@
package org.jetbrains.kotlin.backend.common.lower
import org.jetbrains.kotlin.backend.common.BodyLoweringPass
import org.jetbrains.kotlin.backend.common.FileLoweringPass
import org.jetbrains.kotlin.ir.IrElement
import org.jetbrains.kotlin.ir.IrStatement
import org.jetbrains.kotlin.ir.declarations.IrDeclaration
import org.jetbrains.kotlin.ir.declarations.IrFile
import org.jetbrains.kotlin.ir.declarations.IrVariable
import org.jetbrains.kotlin.ir.declarations.copyAttributes
import org.jetbrains.kotlin.ir.expressions.*
import org.jetbrains.kotlin.ir.expressions.impl.IrBlockImpl
import org.jetbrains.kotlin.ir.expressions.impl.IrFunctionReferenceImpl
import org.jetbrains.kotlin.ir.util.remapTypes
import org.jetbrains.kotlin.ir.visitors.IrElementTransformer
import org.jetbrains.kotlin.ir.visitors.IrElementTransformerVoid
import org.jetbrains.kotlin.ir.visitors.transformChildrenVoid
class ProvisionalFunctionExpressionLoweringContext(
val outer: ProvisionalFunctionExpressionLoweringContext? = null,
val startOffset: Int? = null,
val endOffset: Int? = null)
val endOffset: Int? = null
)
class ProvisionalFunctionExpressionLowering :
IrElementTransformer<ProvisionalFunctionExpressionLoweringContext>,
BodyLoweringPass {
@@ -35,7 +30,6 @@ class ProvisionalFunctionExpressionLowering :
override fun visitCall(expression: IrCall, data: ProvisionalFunctionExpressionLoweringContext) = super.visitCall(
expression,
ProvisionalFunctionExpressionLoweringContext(
data,
expression.startOffset,
expression.endOffset
)
@@ -44,14 +38,18 @@ class ProvisionalFunctionExpressionLowering :
override fun visitVariable(declaration: IrVariable, data: ProvisionalFunctionExpressionLoweringContext) = super.visitVariable(
declaration,
ProvisionalFunctionExpressionLoweringContext(
data,
declaration.startOffset,
declaration.endOffset
)
)
override fun visitContainerExpression(expression: IrContainerExpression, data: ProvisionalFunctionExpressionLoweringContext): IrExpression {
if (expression !is IrReturnableBlock) return super.visitContainerExpression(expression, data)
return super.visitContainerExpression(expression, ProvisionalFunctionExpressionLoweringContext())
}
override fun visitFunctionExpression(expression: IrFunctionExpression, data: ProvisionalFunctionExpressionLoweringContext): IrElement {
expression.transformChildren(this, ProvisionalFunctionExpressionLoweringContext(data))
expression.transformChildren(this, ProvisionalFunctionExpressionLoweringContext())
val startOffset = data.startOffset ?: expression.startOffset
val endOffset = data.endOffset ?: expression.endOffset
@@ -70,7 +68,7 @@ class ProvisionalFunctionExpressionLowering :
valueArgumentsCount = function.valueParameters.size,
reflectionTarget = null,
origin = origin
)
).copyAttributes(expression) // TODO better to copy just name
)
)
}
@@ -9,6 +9,7 @@ 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.ir.IrStatement
import org.jetbrains.kotlin.ir.UNDEFINED_OFFSET
import org.jetbrains.kotlin.ir.builders.*
import org.jetbrains.kotlin.ir.declarations.IrDeclaration
import org.jetbrains.kotlin.ir.declarations.IrSymbolOwner
@@ -162,7 +163,8 @@ class ReturnableBlockTransformer(val context: CommonBackendContext, val containe
if (!expression.type.isUnit()) {
// In case of Unit return type we don't need to return an explicit value. This will not be optimized by JVM backend and
// may result in exceptions in `MethodVerifier` before optimizations.
+irGet(variable)
// Also note that `UNDEFINED_OFFSET` is needed to make proper line number for JVM.
+at(UNDEFINED_OFFSET, UNDEFINED_OFFSET).irGet(variable)
}
}
}
@@ -689,6 +689,8 @@ class FunctionInlining(
} else {
val newVariable =
currentScope.scope.createTemporaryVariable(
startOffset = if (it.isDefaultArg) irExpression.startOffset else UNDEFINED_OFFSET,
endOffset = if (it.isDefaultArg) irExpression.startOffset else UNDEFINED_OFFSET,
irExpression = irExpression,
irType = if (inlineArgumentsWithTheirOriginalTypeAndOffset) it.parameter.getOriginalType() else irExpression.type,
nameHint = callee.symbol.owner.name.asStringStripSpecialMarkers() + "_" + it.parameter.name.asStringStripSpecialMarkers(),
@@ -793,14 +795,18 @@ class FunctionInlining(
(alwaysCreateTemporaryVariablesForArguments && !parameter.isInlineParameter()) ||
argument.shouldBeSubstitutedViaTemporaryVariable()
if (!shouldCreateTemporaryVariable) {
substituteMap[parameter] = variableInitializer
if (shouldCreateTemporaryVariable) {
val newVariable = createTemporaryVariable(parameter, variableInitializer, argument.isDefaultArg, callee)
if (argument.isDefaultArg) evaluationStatementsFromDefault.add(newVariable) else evaluationStatements.add(newVariable)
substituteMap[parameter] = IrGetValueWithoutLocation(newVariable.symbol)
return@forEach
}
val newVariable = createTemporaryVariable(parameter, variableInitializer, callee)
if (argument.isDefaultArg) evaluationStatementsFromDefault.add(newVariable) else evaluationStatements.add(newVariable)
substituteMap[parameter] = IrGetValueWithoutLocation(newVariable.symbol)
substituteMap[parameter] = if (variableInitializer is IrGetValue) {
IrGetValueWithoutLocation(variableInitializer.symbol)
} else {
variableInitializer
}
}
@@ -824,13 +830,19 @@ class FunctionInlining(
}
private fun ParameterToArgument.shouldBeSubstitutedViaTemporaryVariable(): Boolean =
!isImmutableVariableLoad && !(argumentExpression.isPure(false, context = context) && inlinePureArguments)
!(isImmutableVariableLoad && parameter.index >= 0) &&
!(argumentExpression.isPure(false, context = context) && inlinePureArguments)
private fun createTemporaryVariable(parameter: IrValueParameter, variableInitializer: IrExpression, callee: IrFunction): IrVariable {
private fun createTemporaryVariable(
parameter: IrValueParameter,
variableInitializer: IrExpression,
isDefaultArg: Boolean,
callee: IrFunction
): IrVariable {
val variable = currentScope.scope.createTemporaryVariable(
irExpression = IrBlockImpl(
variableInitializer.startOffset,
variableInitializer.endOffset,
if (isDefaultArg) variableInitializer.startOffset else UNDEFINED_OFFSET,
if (isDefaultArg) variableInitializer.endOffset else UNDEFINED_OFFSET,
if (inlineArgumentsWithTheirOriginalTypeAndOffset) parameter.getOriginalType() else variableInitializer.type,
InlinerExpressionLocationHint((currentScope.irElement as IrSymbolOwner).symbol)
).apply {