JVM_IR minor cleanup in inliner
This commit is contained in:
committed by
TeamCityServer
parent
d88a665fa8
commit
ec90649854
+29
-19
@@ -461,9 +461,9 @@ class ExpressionCodegen(
|
|||||||
require(callee.parent is IrClass) { "Unhandled intrinsic in ExpressionCodegen: ${callee.render()}" }
|
require(callee.parent is IrClass) { "Unhandled intrinsic in ExpressionCodegen: ${callee.render()}" }
|
||||||
val callable = methodSignatureMapper.mapToCallableMethod(expression, irFunction)
|
val callable = methodSignatureMapper.mapToCallableMethod(expression, irFunction)
|
||||||
val callGenerator = getOrCreateCallGenerator(expression, data, callable.signature)
|
val callGenerator = getOrCreateCallGenerator(expression, data, callable.signature)
|
||||||
val isSuspensionPoint = expression.isSuspensionPoint()
|
|
||||||
|
|
||||||
if (isSuspensionPoint != SuspensionPointKind.NEVER) {
|
val suspensionPointKind = expression.getSuspensionPointKind()
|
||||||
|
if (suspensionPointKind != SuspensionPointKind.NEVER) {
|
||||||
addInlineMarker(mv, isStartNotEnd = true)
|
addInlineMarker(mv, isStartNotEnd = true)
|
||||||
}
|
}
|
||||||
|
|
||||||
@@ -490,16 +490,16 @@ class ExpressionCodegen(
|
|||||||
|
|
||||||
expression.markLineNumber(true)
|
expression.markLineNumber(true)
|
||||||
|
|
||||||
if (isSuspensionPoint != SuspensionPointKind.NEVER) {
|
if (suspensionPointKind != SuspensionPointKind.NEVER) {
|
||||||
addSuspendMarker(mv, isStartNotEnd = true, isSuspensionPoint == SuspensionPointKind.NOT_INLINE)
|
addSuspendMarker(mv, isStartNotEnd = true, suspensionPointKind == SuspensionPointKind.NOT_INLINE)
|
||||||
}
|
}
|
||||||
|
|
||||||
callGenerator.genCall(callable, this, expression, isInsideCondition)
|
callGenerator.genCall(callable, this, expression, isInsideCondition)
|
||||||
|
|
||||||
val unboxedInlineClassIrType = callee.originalReturnTypeOfSuspendFunctionReturningUnboxedInlineClass()
|
val unboxedInlineClassIrType = callee.originalReturnTypeOfSuspendFunctionReturningUnboxedInlineClass()
|
||||||
|
|
||||||
if (isSuspensionPoint != SuspensionPointKind.NEVER) {
|
if (suspensionPointKind != SuspensionPointKind.NEVER) {
|
||||||
addSuspendMarker(mv, isStartNotEnd = false, isSuspensionPoint == SuspensionPointKind.NOT_INLINE)
|
addSuspendMarker(mv, isStartNotEnd = false, suspensionPointKind == SuspensionPointKind.NOT_INLINE)
|
||||||
if (unboxedInlineClassIrType != null) {
|
if (unboxedInlineClassIrType != null) {
|
||||||
generateResumePathUnboxing(mv, unboxedInlineClassIrType, typeMapper)
|
generateResumePathUnboxing(mv, unboxedInlineClassIrType, typeMapper)
|
||||||
}
|
}
|
||||||
@@ -541,17 +541,24 @@ class ExpressionCodegen(
|
|||||||
}
|
}
|
||||||
}
|
}
|
||||||
|
|
||||||
private fun IrFunctionAccessExpression.isSuspensionPoint(): SuspensionPointKind = when {
|
private fun IrFunctionAccessExpression.getSuspensionPointKind(): SuspensionPointKind =
|
||||||
!symbol.owner.isSuspend || !irFunction.shouldContainSuspendMarkers() -> SuspensionPointKind.NEVER
|
when {
|
||||||
// Copy-pasted bytecode blocks are not suspension points.
|
!symbol.owner.isSuspend || !irFunction.shouldContainSuspendMarkers() ->
|
||||||
symbol.owner.isInline ->
|
SuspensionPointKind.NEVER
|
||||||
if (symbol.owner.name.asString() == "suspendCoroutineUninterceptedOrReturn" &&
|
// Copy-pasted bytecode blocks are not suspension points.
|
||||||
symbol.owner.getPackageFragment()?.fqName == FqName("kotlin.coroutines.intrinsics")
|
symbol.owner.isInline ->
|
||||||
) SuspensionPointKind.ALWAYS else SuspensionPointKind.NEVER
|
if (symbol.owner.name.asString() == "suspendCoroutineUninterceptedOrReturn" &&
|
||||||
// This includes inline lambdas, but only in functions intended for the inliner; in others, they stay as `f.invoke()`.
|
symbol.owner.getPackageFragment()?.fqName == FqName("kotlin.coroutines.intrinsics")
|
||||||
dispatchReceiver.isReadOfInlineLambda() -> SuspensionPointKind.NOT_INLINE
|
)
|
||||||
else -> SuspensionPointKind.ALWAYS
|
SuspensionPointKind.ALWAYS
|
||||||
}
|
else
|
||||||
|
SuspensionPointKind.NEVER
|
||||||
|
// This includes inline lambdas, but only in functions intended for the inliner; in others, they stay as `f.invoke()`.
|
||||||
|
dispatchReceiver.isReadOfInlineLambda() ->
|
||||||
|
SuspensionPointKind.NOT_INLINE
|
||||||
|
else ->
|
||||||
|
SuspensionPointKind.ALWAYS
|
||||||
|
}
|
||||||
|
|
||||||
override fun visitDelegatingConstructorCall(expression: IrDelegatingConstructorCall, data: BlockInfo): PromisedValue {
|
override fun visitDelegatingConstructorCall(expression: IrDelegatingConstructorCall, data: BlockInfo): PromisedValue {
|
||||||
val callee = expression.symbol.owner
|
val callee = expression.symbol.owner
|
||||||
@@ -645,7 +652,8 @@ class ExpressionCodegen(
|
|||||||
internal fun genOrGetLocal(expression: IrExpression, type: Type, parameterType: IrType, data: BlockInfo): StackValue =
|
internal fun genOrGetLocal(expression: IrExpression, type: Type, parameterType: IrType, data: BlockInfo): StackValue =
|
||||||
if (expression is IrGetValue)
|
if (expression is IrGetValue)
|
||||||
StackValue.local(
|
StackValue.local(
|
||||||
findLocalIndex(expression.symbol), frameMap.typeOf(expression.symbol),
|
findLocalIndex(expression.symbol),
|
||||||
|
frameMap.typeOf(expression.symbol),
|
||||||
expression.symbol.owner.realType.toIrBasedKotlinType()
|
expression.symbol.owner.realType.toIrBasedKotlinType()
|
||||||
)
|
)
|
||||||
else
|
else
|
||||||
@@ -1403,7 +1411,9 @@ class ExpressionCodegen(
|
|||||||
}
|
}
|
||||||
|
|
||||||
private fun getOrCreateCallGenerator(
|
private fun getOrCreateCallGenerator(
|
||||||
element: IrFunctionAccessExpression, data: BlockInfo, signature: JvmMethodSignature
|
element: IrFunctionAccessExpression,
|
||||||
|
data: BlockInfo,
|
||||||
|
signature: JvmMethodSignature
|
||||||
): IrCallGenerator {
|
): IrCallGenerator {
|
||||||
if (!element.symbol.owner.isInlineFunctionCall(context) ||
|
if (!element.symbol.owner.isInlineFunctionCall(context) ||
|
||||||
classCodegen.irClass.fileParent.fileEntry is MultifileFacadeFileEntry ||
|
classCodegen.irClass.fileParent.fileEntry is MultifileFacadeFileEntry ||
|
||||||
|
|||||||
+33
-24
@@ -55,7 +55,7 @@ class IrInlineCodegen(
|
|||||||
) {
|
) {
|
||||||
val isInlineParameter = irValueParameter.isInlineParameter()
|
val isInlineParameter = irValueParameter.isInlineParameter()
|
||||||
if (isInlineParameter && argumentExpression.isInlineIrExpression()) {
|
if (isInlineParameter && argumentExpression.isInlineIrExpression()) {
|
||||||
val irReference = (argumentExpression as IrBlock).statements.filterIsInstance<IrFunctionReference>().single()
|
val irReference = (argumentExpression as IrBlock).statements.last() as IrFunctionReference
|
||||||
val lambdaInfo = IrExpressionLambdaImpl(codegen, irReference)
|
val lambdaInfo = IrExpressionLambdaImpl(codegen, irReference)
|
||||||
rememberClosure(parameterType, irValueParameter.index, lambdaInfo)
|
rememberClosure(parameterType, irValueParameter.index, lambdaInfo)
|
||||||
lambdaInfo.generateLambdaBody(sourceCompiler)
|
lambdaInfo.generateLambdaBody(sourceCompiler)
|
||||||
@@ -65,30 +65,39 @@ class IrInlineCodegen(
|
|||||||
putCapturedToLocalVal(onStack, param, ir.type.toIrBasedKotlinType())
|
putCapturedToLocalVal(onStack, param, ir.type.toIrBasedKotlinType())
|
||||||
}
|
}
|
||||||
} else {
|
} else {
|
||||||
val kind = when (irValueParameter.origin) {
|
val kind = when {
|
||||||
IrDeclarationOrigin.MASK_FOR_DEFAULT_FUNCTION -> ValueKind.DEFAULT_MASK
|
irValueParameter.origin == IrDeclarationOrigin.MASK_FOR_DEFAULT_FUNCTION ->
|
||||||
IrDeclarationOrigin.METHOD_HANDLER_IN_DEFAULT_FUNCTION -> ValueKind.METHOD_HANDLE_IN_DEFAULT
|
ValueKind.DEFAULT_MASK
|
||||||
else -> when {
|
irValueParameter.origin == IrDeclarationOrigin.METHOD_HANDLER_IN_DEFAULT_FUNCTION ->
|
||||||
argumentExpression is IrContainerExpression && argumentExpression.origin == IrStatementOrigin.DEFAULT_VALUE ->
|
ValueKind.METHOD_HANDLE_IN_DEFAULT
|
||||||
if (isInlineParameter) ValueKind.DEFAULT_INLINE_PARAMETER else ValueKind.DEFAULT_PARAMETER
|
argumentExpression is IrContainerExpression && argumentExpression.origin == IrStatementOrigin.DEFAULT_VALUE ->
|
||||||
// TODO ValueKind.NON_INLINEABLE_ARGUMENT_FOR_INLINE_PARAMETER_CALLED_IN_SUSPEND?
|
if (isInlineParameter)
|
||||||
isInlineParameter && irValueParameter.type.isSuspendFunctionTypeOrSubtype() ->
|
ValueKind.DEFAULT_INLINE_PARAMETER
|
||||||
ValueKind.NON_INLINEABLE_ARGUMENT_FOR_INLINE_SUSPEND_PARAMETER
|
else
|
||||||
else -> ValueKind.GENERAL
|
ValueKind.DEFAULT_PARAMETER
|
||||||
}
|
// TODO ValueKind.NON_INLINEABLE_ARGUMENT_FOR_INLINE_PARAMETER_CALLED_IN_SUSPEND?
|
||||||
|
isInlineParameter && irValueParameter.type.isSuspendFunctionTypeOrSubtype() ->
|
||||||
|
ValueKind.NON_INLINEABLE_ARGUMENT_FOR_INLINE_SUSPEND_PARAMETER
|
||||||
|
else ->
|
||||||
|
ValueKind.GENERAL
|
||||||
}
|
}
|
||||||
|
|
||||||
val onStack = when (kind) {
|
val onStack = when (kind) {
|
||||||
ValueKind.METHOD_HANDLE_IN_DEFAULT -> StackValue.constant(null, AsmTypes.OBJECT_TYPE)
|
ValueKind.METHOD_HANDLE_IN_DEFAULT ->
|
||||||
ValueKind.DEFAULT_MASK -> StackValue.constant((argumentExpression as IrConst<*>).value, Type.INT_TYPE)
|
StackValue.constant(null, AsmTypes.OBJECT_TYPE)
|
||||||
ValueKind.DEFAULT_PARAMETER, ValueKind.DEFAULT_INLINE_PARAMETER -> StackValue.createDefaultValue(parameterType)
|
ValueKind.DEFAULT_MASK ->
|
||||||
// Here we replicate the old backend: reusing the locals for everything except extension receivers.
|
StackValue.constant((argumentExpression as IrConst<*>).value, Type.INT_TYPE)
|
||||||
// TODO when stopping at a breakpoint placed in an inline function, arguments which reuse an existing
|
ValueKind.DEFAULT_PARAMETER, ValueKind.DEFAULT_INLINE_PARAMETER ->
|
||||||
// local will not be visible in the debugger, so this needs to be reconsidered.
|
StackValue.createDefaultValue(parameterType)
|
||||||
else -> if (irValueParameter.index >= 0)
|
else -> {
|
||||||
codegen.genOrGetLocal(argumentExpression, parameterType, irValueParameter.type, blockInfo)
|
// Here we replicate the old backend: reusing the locals for everything except extension receivers.
|
||||||
else
|
// TODO when stopping at a breakpoint placed in an inline function, arguments which reuse an existing
|
||||||
codegen.gen(argumentExpression, parameterType, irValueParameter.type, blockInfo)
|
// local will not be visible in the debugger, so this needs to be reconsidered.
|
||||||
|
if (irValueParameter.index >= 0)
|
||||||
|
codegen.genOrGetLocal(argumentExpression, parameterType, irValueParameter.type, blockInfo)
|
||||||
|
else
|
||||||
|
codegen.gen(argumentExpression, parameterType, irValueParameter.type, blockInfo)
|
||||||
|
}
|
||||||
}
|
}
|
||||||
|
|
||||||
val expectedType = JvmKotlinType(parameterType, irValueParameter.type.toIrBasedKotlinType())
|
val expectedType = JvmKotlinType(parameterType, irValueParameter.type.toIrBasedKotlinType())
|
||||||
@@ -166,8 +175,8 @@ fun IrExpression.isInlineIrExpression() =
|
|||||||
when (this) {
|
when (this) {
|
||||||
is IrBlock -> origin.isInlineIrExpression()
|
is IrBlock -> origin.isInlineIrExpression()
|
||||||
is IrCallableReference<*> -> true.also {
|
is IrCallableReference<*> -> true.also {
|
||||||
assert((0 until valueArgumentsCount).count { getValueArgument(it) != null } == 0) {
|
assert((0 until valueArgumentsCount).none { getValueArgument(it) != null }) {
|
||||||
"Expecting 0 value arguments for bounded callable reference: ${dump()}"
|
"Expecting 0 value arguments for bound callable reference: ${dump()}"
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
else -> false
|
else -> false
|
||||||
|
|||||||
Reference in New Issue
Block a user