[K/N] Remove isSuspend hacks from codeGenerator and global optimizations
This commit is contained in:
committed by
Space Team
parent
817dba8564
commit
7e89d59b59
+2
-1
@@ -180,7 +180,8 @@ class KonanConfig(val project: Project, val configuration: CompilerConfiguration
|
|||||||
configuration.get(BinaryOptions.appStateTracking) ?: AppStateTracking.DISABLED
|
configuration.get(BinaryOptions.appStateTracking) ?: AppStateTracking.DISABLED
|
||||||
}
|
}
|
||||||
|
|
||||||
val mimallocUseDefaultOptions by lazy {
|
|
||||||
|
val mimallocUseDefaultOptions: Boolean by lazy {
|
||||||
configuration.get(BinaryOptions.mimallocUseDefaultOptions) ?: false
|
configuration.get(BinaryOptions.mimallocUseDefaultOptions) ?: false
|
||||||
}
|
}
|
||||||
|
|
||||||
|
|||||||
+5
-2
@@ -6,6 +6,7 @@
|
|||||||
package org.jetbrains.kotlin.backend.konan.descriptors
|
package org.jetbrains.kotlin.backend.konan.descriptors
|
||||||
|
|
||||||
import llvm.LLVMStoreSizeOfType
|
import llvm.LLVMStoreSizeOfType
|
||||||
|
import org.jetbrains.kotlin.backend.common.lower.coroutines.getOrCreateFunctionWithContinuationStub
|
||||||
import org.jetbrains.kotlin.backend.konan.*
|
import org.jetbrains.kotlin.backend.konan.*
|
||||||
import org.jetbrains.kotlin.backend.konan.ir.*
|
import org.jetbrains.kotlin.backend.konan.ir.*
|
||||||
import org.jetbrains.kotlin.backend.konan.llvm.computeFunctionName
|
import org.jetbrains.kotlin.backend.konan.llvm.computeFunctionName
|
||||||
@@ -507,8 +508,10 @@ internal class ClassLayoutBuilder(val irClass: IrClass, val context: Context) {
|
|||||||
/**
|
/**
|
||||||
* Normally, function should be already replaced. But if the function come from LazyIr, it can be not replaced.
|
* Normally, function should be already replaced. But if the function come from LazyIr, it can be not replaced.
|
||||||
*/
|
*/
|
||||||
fun IrSimpleFunction.getLoweredVersion() = context.mapping.suspendFunctionsToFunctionWithContinuations[this] ?: this
|
fun IrSimpleFunction.getLoweredVersion() = when {
|
||||||
|
isSuspend -> this.getOrCreateFunctionWithContinuationStub(context)
|
||||||
|
else -> this
|
||||||
|
}
|
||||||
private val overridableOrOverridingMethods: List<IrSimpleFunction>
|
private val overridableOrOverridingMethods: List<IrSimpleFunction>
|
||||||
get() = irClass.simpleFunctions()
|
get() = irClass.simpleFunctions()
|
||||||
.map {it.getLoweredVersion() }
|
.map {it.getLoweredVersion() }
|
||||||
|
|||||||
+3
-7
@@ -105,8 +105,6 @@ internal interface IntrinsicGeneratorEnvironment {
|
|||||||
|
|
||||||
val functionGenerationContext: FunctionGenerationContext
|
val functionGenerationContext: FunctionGenerationContext
|
||||||
|
|
||||||
val continuation: LLVMValueRef
|
|
||||||
|
|
||||||
val exceptionHandler: ExceptionHandler
|
val exceptionHandler: ExceptionHandler
|
||||||
|
|
||||||
val stackLocalsManager: StackLocalsManager
|
val stackLocalsManager: StackLocalsManager
|
||||||
@@ -156,10 +154,10 @@ internal class IntrinsicGenerator(private val environment: IntrinsicGeneratorEnv
|
|||||||
/**
|
/**
|
||||||
* Some intrinsics have to be processed before evaluation of their arguments.
|
* Some intrinsics have to be processed before evaluation of their arguments.
|
||||||
* So this method looks at [callSite] and if it is call to "special" intrinsic
|
* So this method looks at [callSite] and if it is call to "special" intrinsic
|
||||||
* processes it. Otherwise it returns null.
|
* processes it. Otherwise, it returns null.
|
||||||
*/
|
*/
|
||||||
|
@Suppress("UNUSED_PARAMETER")
|
||||||
fun tryEvaluateSpecialCall(callSite: IrFunctionAccessExpression, resultSlot: LLVMValueRef?): LLVMValueRef? {
|
fun tryEvaluateSpecialCall(callSite: IrFunctionAccessExpression, resultSlot: LLVMValueRef?): LLVMValueRef? {
|
||||||
resultSlot.let{}
|
|
||||||
val function = callSite.symbol.owner
|
val function = callSite.symbol.owner
|
||||||
if (!function.isTypedIntrinsic) {
|
if (!function.isTypedIntrinsic) {
|
||||||
return null
|
return null
|
||||||
@@ -241,9 +239,9 @@ internal class IntrinsicGenerator(private val environment: IntrinsicGeneratorEnv
|
|||||||
IntrinsicType.INTEROP_NATIVE_PTR_PLUS_LONG -> emitNativePtrPlusLong(args)
|
IntrinsicType.INTEROP_NATIVE_PTR_PLUS_LONG -> emitNativePtrPlusLong(args)
|
||||||
IntrinsicType.INTEROP_GET_NATIVE_NULL_PTR -> emitGetNativeNullPtr()
|
IntrinsicType.INTEROP_GET_NATIVE_NULL_PTR -> emitGetNativeNullPtr()
|
||||||
IntrinsicType.IDENTITY -> emitIdentity(args)
|
IntrinsicType.IDENTITY -> emitIdentity(args)
|
||||||
IntrinsicType.GET_CONTINUATION -> emitGetContinuation()
|
|
||||||
IntrinsicType.INTEROP_MEMORY_COPY -> emitMemoryCopy(callSite, args)
|
IntrinsicType.INTEROP_MEMORY_COPY -> emitMemoryCopy(callSite, args)
|
||||||
IntrinsicType.IS_EXPERIMENTAL_MM -> emitIsExperimentalMM()
|
IntrinsicType.IS_EXPERIMENTAL_MM -> emitIsExperimentalMM()
|
||||||
|
IntrinsicType.GET_CONTINUATION,
|
||||||
IntrinsicType.RETURN_IF_SUSPENDED,
|
IntrinsicType.RETURN_IF_SUSPENDED,
|
||||||
IntrinsicType.INTEROP_BITS_TO_FLOAT,
|
IntrinsicType.INTEROP_BITS_TO_FLOAT,
|
||||||
IntrinsicType.INTEROP_BITS_TO_DOUBLE,
|
IntrinsicType.INTEROP_BITS_TO_DOUBLE,
|
||||||
@@ -286,8 +284,6 @@ internal class IntrinsicGenerator(private val environment: IntrinsicGeneratorEnv
|
|||||||
private fun reportNonLoweredIntrinsic(intrinsicType: ConstantConstructorIntrinsicType): Nothing =
|
private fun reportNonLoweredIntrinsic(intrinsicType: ConstantConstructorIntrinsicType): Nothing =
|
||||||
context.reportCompilationError("Constant constructor intrinsic of type $intrinsicType should be handled by previous lowering phase")
|
context.reportCompilationError("Constant constructor intrinsic of type $intrinsicType should be handled by previous lowering phase")
|
||||||
|
|
||||||
private fun FunctionGenerationContext.emitGetContinuation(): LLVMValueRef =
|
|
||||||
environment.continuation
|
|
||||||
|
|
||||||
private fun FunctionGenerationContext.emitIdentity(args: List<LLVMValueRef>): LLVMValueRef =
|
private fun FunctionGenerationContext.emitIdentity(args: List<LLVMValueRef>): LLVMValueRef =
|
||||||
args.single()
|
args.single()
|
||||||
|
|||||||
+21
-35
@@ -7,6 +7,7 @@ package org.jetbrains.kotlin.backend.konan.llvm
|
|||||||
|
|
||||||
import kotlinx.cinterop.*
|
import kotlinx.cinterop.*
|
||||||
import llvm.*
|
import llvm.*
|
||||||
|
import org.jetbrains.kotlin.backend.common.lower.coroutines.getOrCreateFunctionWithContinuationStub
|
||||||
import org.jetbrains.kotlin.backend.common.lower.inline.InlinerExpressionLocationHint
|
import org.jetbrains.kotlin.backend.common.lower.inline.InlinerExpressionLocationHint
|
||||||
import org.jetbrains.kotlin.backend.konan.*
|
import org.jetbrains.kotlin.backend.konan.*
|
||||||
import org.jetbrains.kotlin.backend.konan.cgen.CBridgeOrigin
|
import org.jetbrains.kotlin.backend.konan.cgen.CBridgeOrigin
|
||||||
@@ -224,9 +225,6 @@ internal class CodeGeneratorVisitor(val context: Context, val lifetimes: Map<IrE
|
|||||||
override fun calculateLifetime(element: IrElement): Lifetime =
|
override fun calculateLifetime(element: IrElement): Lifetime =
|
||||||
resultLifetime(element)
|
resultLifetime(element)
|
||||||
|
|
||||||
override val continuation: LLVMValueRef
|
|
||||||
get() = getContinuation()
|
|
||||||
|
|
||||||
override val exceptionHandler: ExceptionHandler
|
override val exceptionHandler: ExceptionHandler
|
||||||
get() = currentCodeContext.exceptionHandler
|
get() = currentCodeContext.exceptionHandler
|
||||||
|
|
||||||
@@ -2238,20 +2236,21 @@ internal class CodeGeneratorVisitor(val context: Context, val lifetimes: Map<IrE
|
|||||||
private fun IrFunction.scope(startLine:Int): DIScopeOpaqueRef? {
|
private fun IrFunction.scope(startLine:Int): DIScopeOpaqueRef? {
|
||||||
if (!context.shouldContainLocationDebugInfo())
|
if (!context.shouldContainLocationDebugInfo())
|
||||||
return null
|
return null
|
||||||
val functionLlvmValue =
|
|
||||||
// TODO: May be tie up inline lambdas to their outer function?
|
val functionLlvmValue = when {
|
||||||
if (codegen.isExternal(this) && !KonanBinaryInterface.isExported(this))
|
isReifiedInline -> null
|
||||||
null
|
// TODO: May be tie up inline lambdas to their outer function?
|
||||||
else
|
codegen.isExternal(this) && !KonanBinaryInterface.isExported(this) -> null
|
||||||
codegen.llvmFunctionOrNull(this)?.llvmValue
|
this is IrSimpleFunction && isSuspend -> this.getOrCreateFunctionWithContinuationStub(context).let { codegen.llvmFunctionOrNull(it)?.llvmValue }
|
||||||
return if (!isReifiedInline && functionLlvmValue != null) {
|
else -> codegen.llvmFunctionOrNull(this)?.llvmValue
|
||||||
|
}
|
||||||
|
return if (functionLlvmValue != null) {
|
||||||
debugInfo.subprograms.getOrPut(functionLlvmValue) {
|
debugInfo.subprograms.getOrPut(functionLlvmValue) {
|
||||||
memScoped {
|
memScoped {
|
||||||
val subroutineType = subroutineType(context, codegen.llvmTargetData)
|
val subroutineType = subroutineType(context, codegen.llvmTargetData)
|
||||||
val llvmFunction = codegen.llvmFunction(this@scope).llvmValue
|
diFunctionScope(name.asString(), functionLlvmValue.name!!, startLine, subroutineType).also {
|
||||||
diFunctionScope(name.asString(), llvmFunction.name!!, startLine, subroutineType).also {
|
|
||||||
if (!this@scope.isInline)
|
if (!this@scope.isInline)
|
||||||
DIFunctionAddSubprogram(llvmFunction, it)
|
DIFunctionAddSubprogram(functionLlvmValue, it)
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
} as DIScopeOpaqueRef
|
} as DIScopeOpaqueRef
|
||||||
@@ -2291,19 +2290,10 @@ internal class CodeGeneratorVisitor(val context: Context, val lifetimes: Map<IrE
|
|||||||
|
|
||||||
//-------------------------------------------------------------------------//
|
//-------------------------------------------------------------------------//
|
||||||
|
|
||||||
private fun getContinuation(): LLVMValueRef {
|
|
||||||
val caller = functionGenerationContext.irFunction!!
|
|
||||||
return if (caller.isSuspend)
|
|
||||||
codegen.param(caller, caller.allParametersCount) // The last argument.
|
|
||||||
else {
|
|
||||||
// Suspend call from non-suspend function - must be [invokeSuspend].
|
|
||||||
assert ((caller as IrSimpleFunction).overrides(context.ir.symbols.invokeSuspendFunction.owner),
|
|
||||||
{ "Expected 'BaseContinuationImpl.invokeSuspend' but was '$caller'" })
|
|
||||||
currentCodeContext.genGetValue(caller.dispatchReceiverParameter!!, null)
|
|
||||||
}
|
|
||||||
}
|
|
||||||
|
|
||||||
private fun IrFunction.returnsUnit() = returnType.isUnit() && !isSuspend
|
private fun IrFunction.returnsUnit() = returnType.isUnit().also {
|
||||||
|
require(!isSuspend) { "Suspend functions should be lowered out at this point"}
|
||||||
|
}
|
||||||
|
|
||||||
/**
|
/**
|
||||||
* Evaluates all arguments of [expression] that are explicitly represented in the IR.
|
* Evaluates all arguments of [expression] that are explicitly represented in the IR.
|
||||||
@@ -2421,17 +2411,15 @@ internal class CodeGeneratorVisitor(val context: Context, val lifetimes: Map<IrE
|
|||||||
private fun evaluateFunctionCall(callee: IrCall, args: List<LLVMValueRef>,
|
private fun evaluateFunctionCall(callee: IrCall, args: List<LLVMValueRef>,
|
||||||
resultLifetime: Lifetime, resultSlot: LLVMValueRef?): LLVMValueRef {
|
resultLifetime: Lifetime, resultSlot: LLVMValueRef?): LLVMValueRef {
|
||||||
val function = callee.symbol.owner
|
val function = callee.symbol.owner
|
||||||
|
require(!function.isSuspend) { "Suspend functions should be lowered out at this point"}
|
||||||
|
|
||||||
val argsWithContinuationIfNeeded = if (function.isSuspend)
|
|
||||||
args + getContinuation()
|
|
||||||
else args
|
|
||||||
return when {
|
return when {
|
||||||
function.isTypedIntrinsic -> intrinsicGenerator.evaluateCall(callee, args, resultSlot)
|
function.isTypedIntrinsic -> intrinsicGenerator.evaluateCall(callee, args, resultSlot)
|
||||||
function.isBuiltInOperator -> evaluateOperatorCall(callee, argsWithContinuationIfNeeded)
|
function.isBuiltInOperator -> evaluateOperatorCall(callee, args)
|
||||||
function.origin == DECLARATION_ORIGIN_FILE_GLOBAL_INITIALIZER -> evaluateFileGlobalInitializerCall(function)
|
function.origin == DECLARATION_ORIGIN_FILE_GLOBAL_INITIALIZER -> evaluateFileGlobalInitializerCall(function)
|
||||||
function.origin == DECLARATION_ORIGIN_FILE_THREAD_LOCAL_INITIALIZER -> evaluateFileThreadLocalInitializerCall(function)
|
function.origin == DECLARATION_ORIGIN_FILE_THREAD_LOCAL_INITIALIZER -> evaluateFileThreadLocalInitializerCall(function)
|
||||||
function.origin == DECLARATION_ORIGIN_FILE_STANDALONE_THREAD_LOCAL_INITIALIZER -> evaluateFileStandaloneThreadLocalInitializerCall(function)
|
function.origin == DECLARATION_ORIGIN_FILE_STANDALONE_THREAD_LOCAL_INITIALIZER -> evaluateFileStandaloneThreadLocalInitializerCall(function)
|
||||||
else -> evaluateSimpleFunctionCall(function, argsWithContinuationIfNeeded, resultLifetime, callee.superQualifierSymbol?.owner, resultSlot)
|
else -> evaluateSimpleFunctionCall(function, args, resultLifetime, callee.superQualifierSymbol?.owner, resultSlot)
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
|
|
||||||
@@ -2681,11 +2669,9 @@ internal class CodeGeneratorVisitor(val context: Context, val lifetimes: Map<IrE
|
|||||||
|
|
||||||
val result = call(llvmCallable, args, resultLifetime, exceptionHandler, resultSlot)
|
val result = call(llvmCallable, args, resultLifetime, exceptionHandler, resultSlot)
|
||||||
|
|
||||||
when {
|
when {
|
||||||
!function.isSuspend && function.returnType.isNothing() ->
|
function.returnType.isNothing() -> functionGenerationContext.unreachable()
|
||||||
functionGenerationContext.unreachable()
|
needsNativeThreadState -> functionGenerationContext.switchThreadState(ThreadState.Runnable)
|
||||||
needsNativeThreadState ->
|
|
||||||
functionGenerationContext.switchThreadState(ThreadState.Runnable)
|
|
||||||
}
|
}
|
||||||
|
|
||||||
if (llvmCallable.returnType == voidType) {
|
if (llvmCallable.returnType == voidType) {
|
||||||
|
|||||||
-5
@@ -7,11 +7,6 @@ package org.jetbrains.kotlin.backend.konan.llvm
|
|||||||
|
|
||||||
import llvm.*
|
import llvm.*
|
||||||
import org.jetbrains.kotlin.backend.konan.Context
|
import org.jetbrains.kotlin.backend.konan.Context
|
||||||
import org.jetbrains.kotlin.ir.declarations.IrConstructor
|
|
||||||
import org.jetbrains.kotlin.ir.declarations.IrFunction
|
|
||||||
import org.jetbrains.kotlin.ir.types.isNothing
|
|
||||||
import org.jetbrains.kotlin.ir.util.isSuspend
|
|
||||||
import org.jetbrains.kotlin.ir.util.isThrowable
|
|
||||||
import org.jetbrains.kotlin.konan.target.Architecture
|
import org.jetbrains.kotlin.konan.target.Architecture
|
||||||
import org.jetbrains.kotlin.konan.target.Family
|
import org.jetbrains.kotlin.konan.target.Family
|
||||||
import org.jetbrains.kotlin.konan.target.KonanTarget
|
import org.jetbrains.kotlin.konan.target.KonanTarget
|
||||||
|
|||||||
+2
-2
@@ -193,8 +193,8 @@ private fun mustNotInline(context: Context, irFunction: IrFunction): Boolean {
|
|||||||
|
|
||||||
private fun inferFunctionAttributes(contextUtils: ContextUtils, irFunction: IrFunction): List<LlvmFunctionAttribute> =
|
private fun inferFunctionAttributes(contextUtils: ContextUtils, irFunction: IrFunction): List<LlvmFunctionAttribute> =
|
||||||
mutableListOf<LlvmFunctionAttribute>().apply {
|
mutableListOf<LlvmFunctionAttribute>().apply {
|
||||||
// suspend function can return value in case of COROUTINE_SUSPENDED.
|
if (irFunction.returnType.isNothing()) {
|
||||||
if (irFunction.returnType.isNothing() && !irFunction.isSuspend) {
|
require(!irFunction.isSuspend) { "Suspend functions should be lowered out at this point"}
|
||||||
add(LlvmFunctionAttribute.NoReturn)
|
add(LlvmFunctionAttribute.NoReturn)
|
||||||
}
|
}
|
||||||
if (mustNotInline(contextUtils.context, irFunction)) {
|
if (mustNotInline(contextUtils.context, irFunction)) {
|
||||||
|
|||||||
+3
-3
@@ -10,6 +10,7 @@ import org.jetbrains.kotlin.ir.declarations.IrConstructor
|
|||||||
import org.jetbrains.kotlin.ir.declarations.IrFunction
|
import org.jetbrains.kotlin.ir.declarations.IrFunction
|
||||||
import org.jetbrains.kotlin.ir.util.allParameters
|
import org.jetbrains.kotlin.ir.util.allParameters
|
||||||
import org.jetbrains.kotlin.ir.util.isSuspend
|
import org.jetbrains.kotlin.ir.util.isSuspend
|
||||||
|
import org.jetbrains.kotlin.ir.util.render
|
||||||
|
|
||||||
/**
|
/**
|
||||||
* LLVM function's parameter type with its attributes.
|
* LLVM function's parameter type with its attributes.
|
||||||
@@ -26,8 +27,7 @@ internal fun ContextUtils.getLlvmFunctionParameterTypes(function: IrFunction): L
|
|||||||
val paramTypes = ArrayList(function.allParameters.map {
|
val paramTypes = ArrayList(function.allParameters.map {
|
||||||
LlvmParamType(getLLVMType(it.type), argumentAbiInfo.defaultParameterAttributesForIrType(it.type))
|
LlvmParamType(getLLVMType(it.type), argumentAbiInfo.defaultParameterAttributesForIrType(it.type))
|
||||||
})
|
})
|
||||||
if (function.isSuspend)
|
require(!function.isSuspend) { "Suspend functions should be lowered out at this point"}
|
||||||
paramTypes.add(LlvmParamType(kObjHeaderPtr)) // Suspend functions have implicit parameter of type Continuation<>.
|
|
||||||
if (isObjectType(returnType))
|
if (isObjectType(returnType))
|
||||||
paramTypes.add(LlvmParamType(kObjHeaderPtrPtr))
|
paramTypes.add(LlvmParamType(kObjHeaderPtrPtr))
|
||||||
|
|
||||||
@@ -37,7 +37,7 @@ internal fun ContextUtils.getLlvmFunctionParameterTypes(function: IrFunction): L
|
|||||||
internal fun ContextUtils.getLlvmFunctionReturnType(function: IrFunction): LlvmRetType {
|
internal fun ContextUtils.getLlvmFunctionReturnType(function: IrFunction): LlvmRetType {
|
||||||
val returnType = when {
|
val returnType = when {
|
||||||
function is IrConstructor -> LlvmParamType(voidType)
|
function is IrConstructor -> LlvmParamType(voidType)
|
||||||
function.isSuspend -> LlvmParamType(kObjHeaderPtr) // Suspend functions return Any?.
|
function.isSuspend -> error("Suspend functions should be lowered out at this point, but ${function.render()} is still here")
|
||||||
else -> LlvmParamType(
|
else -> LlvmParamType(
|
||||||
getLLVMReturnType(function.returnType),
|
getLLVMReturnType(function.returnType),
|
||||||
argumentAbiInfo.defaultParameterAttributesForIrType(function.returnType)
|
argumentAbiInfo.defaultParameterAttributesForIrType(function.returnType)
|
||||||
|
|||||||
+2
-7
@@ -76,11 +76,7 @@ private class AutoboxingTransformer(val context: Context) : AbstractValueUsageTr
|
|||||||
}
|
}
|
||||||
|
|
||||||
override fun IrExpression.useAsReturnValue(returnTarget: IrReturnTargetSymbol): IrExpression = when (returnTarget) {
|
override fun IrExpression.useAsReturnValue(returnTarget: IrReturnTargetSymbol): IrExpression = when (returnTarget) {
|
||||||
is IrSimpleFunctionSymbol -> if (returnTarget.owner.isSuspend && returnTarget == currentFunction?.symbol) {
|
is IrSimpleFunctionSymbol -> this.useAs(returnTarget.owner.returnType)
|
||||||
this.useAs(irBuiltIns.anyNType)
|
|
||||||
} else {
|
|
||||||
this.useAs(returnTarget.owner.returnType)
|
|
||||||
}
|
|
||||||
is IrConstructorSymbol -> this.useAs(irBuiltIns.unitType)
|
is IrConstructorSymbol -> this.useAs(irBuiltIns.unitType)
|
||||||
is IrReturnableBlockSymbol -> this.useAs(returnTarget.owner.type)
|
is IrReturnableBlockSymbol -> this.useAs(returnTarget.owner.type)
|
||||||
else -> error(returnTarget)
|
else -> error(returnTarget)
|
||||||
@@ -89,8 +85,7 @@ private class AutoboxingTransformer(val context: Context) : AbstractValueUsageTr
|
|||||||
override fun IrExpression.useAs(type: IrType): IrExpression {
|
override fun IrExpression.useAs(type: IrType): IrExpression {
|
||||||
val actualType = when (this) {
|
val actualType = when (this) {
|
||||||
is IrCall -> {
|
is IrCall -> {
|
||||||
if (this.symbol.owner.isSuspend) irBuiltIns.anyNType
|
if (this.symbol == symbols.reinterpret) this.getTypeArgument(1)!!
|
||||||
else if (this.symbol == symbols.reinterpret) this.getTypeArgument(1)!!
|
|
||||||
else this.callTarget.returnType
|
else this.callTarget.returnType
|
||||||
}
|
}
|
||||||
is IrGetField -> this.symbol.owner.type
|
is IrGetField -> this.symbol.owner.type
|
||||||
|
|||||||
-3
@@ -481,9 +481,6 @@ internal class FunctionReferenceLowering(val context: Context) : FileLoweringPas
|
|||||||
if (parameter == referencedFunction.extensionReceiverParameter
|
if (parameter == referencedFunction.extensionReceiverParameter
|
||||||
&& extensionReceiverParameter != null)
|
&& extensionReceiverParameter != null)
|
||||||
irGet(extensionReceiverParameter!!)
|
irGet(extensionReceiverParameter!!)
|
||||||
else if (function.isSuspend && unboundIndex == valueParameters.size)
|
|
||||||
// For suspend functions the last argument is continuation and it is implicit.
|
|
||||||
irCall(getContinuationSymbol.owner, listOf(returnType))
|
|
||||||
else
|
else
|
||||||
irGet(valueParameters[unboundIndex++])
|
irGet(valueParameters[unboundIndex++])
|
||||||
}
|
}
|
||||||
|
|||||||
+1
-28
@@ -445,8 +445,6 @@ internal class ModuleDFGBuilder(val context: Context, val irModule: IrModuleFrag
|
|||||||
symbols.baseContinuationImpl.owner.declarations
|
symbols.baseContinuationImpl.owner.declarations
|
||||||
.filterIsInstance<IrSimpleFunction>().single { it.name.asString() == "invokeSuspend" }.symbol
|
.filterIsInstance<IrSimpleFunction>().single { it.name.asString() == "invokeSuspend" }.symbol
|
||||||
|
|
||||||
private val getContinuationSymbol = symbols.getContinuation
|
|
||||||
|
|
||||||
private val arrayGetSymbols = symbols.arrayGet.values
|
private val arrayGetSymbols = symbols.arrayGet.values
|
||||||
private val arraySetSymbols = symbols.arraySet.values
|
private val arraySetSymbols = symbols.arraySet.values
|
||||||
private val createUninitializedInstanceSymbol = symbols.createUninitializedInstance
|
private val createUninitializedInstanceSymbol = symbols.createUninitializedInstance
|
||||||
@@ -485,27 +483,12 @@ internal class ModuleDFGBuilder(val context: Context, val irModule: IrModuleFrag
|
|||||||
{ Scoped(DataFlowIR.Node.Parameter(it.index), rootScope) }
|
{ Scoped(DataFlowIR.Node.Parameter(it.index), rootScope) }
|
||||||
)
|
)
|
||||||
|
|
||||||
private val continuationParameter = when {
|
|
||||||
declaration !is IrSimpleFunction -> null
|
|
||||||
|
|
||||||
declaration.isSuspend -> Scoped(DataFlowIR.Node.Parameter(allParameters.size), rootScope)
|
|
||||||
|
|
||||||
declaration.overrides(invokeSuspendFunctionSymbol.owner) -> // <this> is a ContinuationImpl inheritor.
|
|
||||||
templateParameters[declaration.dispatchReceiverParameter!!] // It is its own continuation.
|
|
||||||
|
|
||||||
else -> null
|
|
||||||
}
|
|
||||||
|
|
||||||
private fun getContinuation() = continuationParameter
|
|
||||||
?: error("Function ${declaration.descriptor} has no continuation parameter")
|
|
||||||
|
|
||||||
private val nodes = mutableMapOf<IrExpression, Scoped<DataFlowIR.Node>>()
|
private val nodes = mutableMapOf<IrExpression, Scoped<DataFlowIR.Node>>()
|
||||||
private val variables = mutableMapOf<IrValueDeclaration, Scoped<DataFlowIR.Node.Variable>>()
|
private val variables = mutableMapOf<IrValueDeclaration, Scoped<DataFlowIR.Node.Variable>>()
|
||||||
private val expressionsScopes = mutableMapOf<IrExpression, DataFlowIR.Node.Scope>()
|
private val expressionsScopes = mutableMapOf<IrExpression, DataFlowIR.Node.Scope>()
|
||||||
|
|
||||||
fun build(): DataFlowIR.Function {
|
fun build(): DataFlowIR.Function {
|
||||||
val isSuspend = declaration is IrSimpleFunction && declaration.isSuspend
|
|
||||||
|
|
||||||
val scopes = mutableMapOf<IrLoop, DataFlowIR.Node.Scope>()
|
val scopes = mutableMapOf<IrLoop, DataFlowIR.Node.Scope>()
|
||||||
fun transformLoop(loop: IrLoop, parentLoop: IrLoop?): DataFlowIR.Node.Scope {
|
fun transformLoop(loop: IrLoop, parentLoop: IrLoop?): DataFlowIR.Node.Scope {
|
||||||
scopes[loop]?.let { return it }
|
scopes[loop]?.let { return it }
|
||||||
@@ -566,8 +549,6 @@ internal class ModuleDFGBuilder(val context: Context, val irModule: IrModuleFrag
|
|||||||
rootScope.nodes += templateParameters.values.map { it.value }
|
rootScope.nodes += templateParameters.values.map { it.value }
|
||||||
rootScope.nodes += returnsNode
|
rootScope.nodes += returnsNode
|
||||||
rootScope.nodes += throwsNode
|
rootScope.nodes += throwsNode
|
||||||
if (isSuspend)
|
|
||||||
rootScope.nodes += continuationParameter!!.value
|
|
||||||
|
|
||||||
return DataFlowIR.Function(
|
return DataFlowIR.Function(
|
||||||
symbol = symbolTable.mapFunction(declaration),
|
symbol = symbolTable.mapFunction(declaration),
|
||||||
@@ -610,7 +591,7 @@ internal class ModuleDFGBuilder(val context: Context, val irModule: IrModuleFrag
|
|||||||
private fun mapReturnType(actualType: IrType, returnType: IrType) = mapWrappedType(actualType, returnType)
|
private fun mapReturnType(actualType: IrType, returnType: IrType) = mapWrappedType(actualType, returnType)
|
||||||
|
|
||||||
|
|
||||||
private fun getNode(expression: IrExpression, continuationOverride: DataFlowIR.Node? = null): Scoped<DataFlowIR.Node> {
|
private fun getNode(expression: IrExpression): Scoped<DataFlowIR.Node> {
|
||||||
if (expression is IrGetValue) {
|
if (expression is IrGetValue) {
|
||||||
val valueDeclaration = expression.symbol.owner
|
val valueDeclaration = expression.symbol.owner
|
||||||
if (valueDeclaration is IrValueParameter)
|
if (valueDeclaration is IrValueParameter)
|
||||||
@@ -712,8 +693,6 @@ internal class ModuleDFGBuilder(val context: Context, val irModule: IrModuleFrag
|
|||||||
}
|
}
|
||||||
|
|
||||||
is IrCall -> when (value.symbol) {
|
is IrCall -> when (value.symbol) {
|
||||||
getContinuationSymbol -> continuationOverride ?: getContinuation().value
|
|
||||||
|
|
||||||
in arrayGetSymbols -> {
|
in arrayGetSymbols -> {
|
||||||
val actualCallee = value.actualCallee
|
val actualCallee = value.actualCallee
|
||||||
|
|
||||||
@@ -760,12 +739,6 @@ internal class ModuleDFGBuilder(val context: Context, val irModule: IrModuleFrag
|
|||||||
val callee = value.symbol.owner
|
val callee = value.symbol.owner
|
||||||
val arguments = value.getArguments()
|
val arguments = value.getArguments()
|
||||||
.map { expressionToEdge(it.second) }
|
.map { expressionToEdge(it.second) }
|
||||||
.let {
|
|
||||||
if (callee.isSuspend)
|
|
||||||
it + DataFlowIR.Edge(continuationOverride ?: getContinuation().value, null)
|
|
||||||
else
|
|
||||||
it
|
|
||||||
}
|
|
||||||
|
|
||||||
if (value.isVirtualCall) {
|
if (value.isVirtualCall) {
|
||||||
val owner = callee.parentAsClass
|
val owner = callee.parentAsClass
|
||||||
|
|||||||
+4
-8
@@ -595,8 +595,8 @@ internal object DataFlowIR {
|
|||||||
}
|
}
|
||||||
val name = "kfun:$containingDeclarationPart${it.computeFunctionName()}"
|
val name = "kfun:$containingDeclarationPart${it.computeFunctionName()}"
|
||||||
|
|
||||||
val returnsUnit = it is IrConstructor || (!it.isSuspend && it.returnType.isUnit())
|
val returnsUnit = it is IrConstructor || it.returnType.isUnit()
|
||||||
val returnsNothing = !it.isSuspend && it.returnType.isNothing()
|
val returnsNothing = it.returnType.isNothing()
|
||||||
var attributes = 0
|
var attributes = 0
|
||||||
if (returnsUnit)
|
if (returnsUnit)
|
||||||
attributes = attributes or FunctionAttributes.RETURNS_UNIT
|
attributes = attributes or FunctionAttributes.RETURNS_UNIT
|
||||||
@@ -648,14 +648,10 @@ internal object DataFlowIR {
|
|||||||
}
|
}
|
||||||
functionMap[it] = symbol
|
functionMap[it] = symbol
|
||||||
|
|
||||||
symbol.parameters =
|
symbol.parameters = function.allParameters.map { it.type }
|
||||||
(function.allParameters.map { it.type } + (if (function.isSuspend) listOf(continuationType) else emptyList()))
|
|
||||||
.map { mapTypeToFunctionParameter(it) }
|
.map { mapTypeToFunctionParameter(it) }
|
||||||
.toTypedArray()
|
.toTypedArray()
|
||||||
symbol.returnParameter = mapTypeToFunctionParameter(if (function.isSuspend)
|
symbol.returnParameter = mapTypeToFunctionParameter(function.returnType)
|
||||||
context.irBuiltIns.anyType
|
|
||||||
else
|
|
||||||
function.returnType)
|
|
||||||
|
|
||||||
return symbol
|
return symbol
|
||||||
}
|
}
|
||||||
|
|||||||
+1
-3
@@ -1446,9 +1446,7 @@ internal object DevirtualizationAnalysis {
|
|||||||
val startOffset = expression.startOffset
|
val startOffset = expression.startOffset
|
||||||
val endOffset = expression.endOffset
|
val endOffset = expression.endOffset
|
||||||
val function = expression.symbol.owner
|
val function = expression.symbol.owner
|
||||||
val type = if (callee.isSuspend)
|
val type = function.returnType
|
||||||
context.irBuiltIns.anyNType
|
|
||||||
else function.returnType
|
|
||||||
val irBuilder = context.createIrBuilder(currentScope!!.scope.scopeOwnerSymbol, startOffset, endOffset)
|
val irBuilder = context.createIrBuilder(currentScope!!.scope.scopeOwnerSymbol, startOffset, endOffset)
|
||||||
irBuilder.run {
|
irBuilder.run {
|
||||||
val dispatchReceiver = expression.dispatchReceiver!!
|
val dispatchReceiver = expression.dispatchReceiver!!
|
||||||
|
|||||||
Reference in New Issue
Block a user