[JS IC] Don't persist temporary copies of inline functions

- drop special `IrValueParameterPublicSymbol`
 - drop special `IrAnonymousInitializerPublicSymbolImpl`
 - drop hacky `useGlobalSignatures`
This commit is contained in:
Roman Artemev
2021-07-28 20:25:56 +03:00
committed by teamcityserver
parent b1251c1716
commit b1eeb1fb27
10 changed files with 77 additions and 52 deletions
@@ -93,6 +93,8 @@ class FunctionInlining(
private var containerScope: ScopeWithIr? = null
private var deepInline: Boolean = false
override fun lower(irBody: IrBody, container: IrDeclaration) {
// TODO container: IrSymbolDeclaration
containerScope = createScope(container as IrSymbolOwner)
@@ -155,16 +157,6 @@ class FunctionInlining(
fun inline() = inlineFunction(callSite, callee, true)
/**
* TODO: JVM inliner crashed on attempt inline this function from transform.kt with:
* j.l.IllegalStateException: Couldn't obtain compiled function body for
* public inline fun <reified T : org.jetbrains.kotlin.ir.IrElement> kotlin.collections.MutableList<T>.transform...
*/
private inline fun <reified T : IrElement> MutableList<T>.transform(transformation: (T) -> IrElement) {
forEachIndexed { i, item ->
set(i, transformation(item) as T)
}
}
private fun inlineFunction(
callSite: IrFunctionAccessExpression,
@@ -172,9 +164,22 @@ class FunctionInlining(
performRecursiveInline: Boolean
): IrReturnableBlock {
val copiedCallee = (copyIrElement.copy(callee) as IrFunction).apply {
// It's a hack to overtake another hack in PIR. Due to PersistentIrFactory registers every created declaration
// there also get temporary declaration like this which leads to some unclear behaviour. Since I am not aware
// enough about PIR internals the simplest way seemed to me is to unregister temporary function. Hope it is going
// to be removed ASAP along with registering every PIR declaration.
factory.unlistFunction(this)
parent = callee.parent
if (performRecursiveInline) {
body?.transformChildrenVoid()
val old = deepInline
try {
deepInline = true
body?.transformChildrenVoid()
} finally {
deepInline = old
}
valueParameters.forEachIndexed { index, param ->
if (callSite.getValueArgument(index) == null) {
// Default values can recursively reference [callee] - transform only needed.
@@ -537,6 +542,13 @@ class FunctionInlining(
if (argument.isInlinableLambdaArgument) {
substituteMap[argument.parameter] = argument.argumentExpression
(argument.argumentExpression as? IrFunctionReference)?.let { evaluationStatements += evaluateArguments(it) }
(argument.argumentExpression as? IrFunctionExpression)?.let {
if (deepInline) {
it.function.factory.unlistFunction(it.function)
}
}
return@forEach
}
@@ -15,7 +15,6 @@ import org.jetbrains.kotlin.ir.expressions.IrExpressionBody
import org.jetbrains.kotlin.ir.expressions.persistent.PersistentIrBlockBody
import org.jetbrains.kotlin.ir.expressions.persistent.PersistentIrExpressionBody
import org.jetbrains.kotlin.ir.symbols.*
import org.jetbrains.kotlin.ir.symbols.impl.IrPublicSymbolBase
import org.jetbrains.kotlin.ir.types.IrType
import org.jetbrains.kotlin.ir.util.IdSignature
import org.jetbrains.kotlin.name.Name
@@ -26,9 +25,9 @@ class PersistentIrFactory : IrFactory {
override var stageController = StageController()
val allDeclarations = mutableListOf<IrDeclaration>()
val allDeclarations = hashSetOf<IrDeclaration>()
val allBodies = mutableListOf<IrBody>()
val allBodies = hashSetOf<IrBody>()
private fun IrDeclaration.register() {
allDeclarations += this
@@ -38,6 +37,15 @@ class PersistentIrFactory : IrFactory {
return (declaration as? PersistentIrDeclarationBase<*>)?.signature ?: declaration.symbol.signature
}
override fun unlistFunction(f: IrFunction) {
allDeclarations.remove(f)
f.dispatchReceiverParameter?.let { allDeclarations.remove(it) }
f.extensionReceiverParameter?.let { allDeclarations.remove(it) }
allDeclarations.removeAll(f.valueParameters)
allDeclarations.removeAll(f.typeParameters)
allBodies.remove(f.body)
}
@Suppress("UNUSED_PARAMETER")
internal fun currentSignature(declaration: IrDeclaration): IdSignature? {
val parentSig = stageController.currentDeclaration?.let { declarationSignature(it) } ?: return null
@@ -125,7 +133,19 @@ class PersistentIrFactory : IrFactory {
isExternal: Boolean,
isStatic: Boolean,
): IrField =
PersistentIrField(startOffset, endOffset, origin, symbol, name, type, visibility, isFinal, isExternal, isStatic, this).also { it.register() }
PersistentIrField(
startOffset,
endOffset,
origin,
symbol,
name,
type,
visibility,
isFinal,
isExternal,
isStatic,
this
).also { it.register() }
override fun createFunction(
startOffset: Int,
@@ -268,7 +288,19 @@ class PersistentIrFactory : IrFactory {
isAssignable: Boolean
): IrValueParameter =
PersistentIrValueParameter(
startOffset, endOffset, origin, symbol, name, index, type, varargElementType, isCrossinline, isNoinline, isHidden, isAssignable, this
startOffset,
endOffset,
origin,
symbol,
name,
index,
type,
varargElementType,
isCrossinline,
isNoinline,
isHidden,
isAssignable,
this
).also { it.register() }
override fun createExpressionBody(
@@ -239,4 +239,6 @@ interface IrFactory {
endOffset: Int,
initializer: IrBlockBody.() -> Unit,
): IrBlockBody
fun unlistFunction(f: IrFunction) {}
}
@@ -27,8 +27,7 @@ abstract class BasicIrModuleDeserializer(
override val klib: IrLibrary,
override val strategy: DeserializationStrategy,
libraryAbiVersion: KotlinAbiVersion,
private val containsErrorCode: Boolean = false,
private val useGlobalSignatures: Boolean = false,
private val containsErrorCode: Boolean = false
) :
IrModuleDeserializer(moduleDescriptor, libraryAbiVersion) {
@@ -119,7 +118,6 @@ abstract class BasicIrModuleDeserializer(
allowErrorNodes,
strategy.inlineBodies,
moduleDeserializer,
useGlobalSignatures,
linker::handleNoModuleDeserializerFound,
)
@@ -66,7 +66,6 @@ class FileDeserializationState(
allowErrorNodes: Boolean,
deserializeInlineFunctions: Boolean,
moduleDeserializer: IrModuleDeserializer,
useGlobalSignatures: Boolean,
handleNoModuleDeserializerFound: (IdSignature, ModuleDescriptor, Collection<IrModuleDeserializer>) -> IrModuleDeserializer,
) {
@@ -76,7 +75,6 @@ class FileDeserializationState(
fileProto.actualList,
::addIdSignature,
linker::handleExpectActualMapping,
useGlobalSignatures = useGlobalSignatures,
) { idSig, symbolKind ->
val topLevelSig = idSig.topLevelSignature()
@@ -8,12 +8,14 @@ package org.jetbrains.kotlin.backend.common.serialization
import org.jetbrains.kotlin.backend.common.serialization.encodings.BinarySymbolData
import org.jetbrains.kotlin.backend.common.serialization.proto.Actual
import org.jetbrains.kotlin.backend.common.serialization.proto.IdSignature.IdSigCase.*
import org.jetbrains.kotlin.descriptors.ClassDescriptor
import org.jetbrains.kotlin.descriptors.ParameterDescriptor
import org.jetbrains.kotlin.ir.declarations.IrAnonymousInitializer
import org.jetbrains.kotlin.ir.declarations.IrValueParameter
import org.jetbrains.kotlin.ir.symbols.*
import org.jetbrains.kotlin.ir.symbols.impl.*
import org.jetbrains.kotlin.ir.symbols.IrFileSymbol
import org.jetbrains.kotlin.ir.symbols.IrPropertySymbol
import org.jetbrains.kotlin.ir.symbols.IrSimpleFunctionSymbol
import org.jetbrains.kotlin.ir.symbols.IrSymbol
import org.jetbrains.kotlin.ir.symbols.impl.IrAnonymousInitializerSymbolImpl
import org.jetbrains.kotlin.ir.symbols.impl.IrLocalDelegatedPropertySymbolImpl
import org.jetbrains.kotlin.ir.symbols.impl.IrValueParameterSymbolImpl
import org.jetbrains.kotlin.ir.symbols.impl.IrVariableSymbolImpl
import org.jetbrains.kotlin.ir.util.*
import org.jetbrains.kotlin.protobuf.CodedInputStream
import org.jetbrains.kotlin.protobuf.ExtensionRegistryLite
@@ -34,7 +36,6 @@ class IrSymbolDeserializer(
val enqueueLocalTopLevelDeclaration: (IdSignature) -> Unit,
val handleExpectActualMapping: (IdSignature, IrSymbol) -> IrSymbol,
private val enqueueAllDeclarations: Boolean = false,
private val useGlobalSignatures: Boolean = false,
val deserializedSymbols: MutableMap<IdSignature, IrSymbol> = mutableMapOf(), // Per-file signature cache. TODO: do we really need it?
val deserializePublicSymbol: (IdSignature, BinarySymbolData.SymbolKind) -> IrSymbol,
) {
@@ -51,7 +52,7 @@ class IrSymbolDeserializer(
private fun referenceDeserializedSymbol(symbolKind: BinarySymbolData.SymbolKind, idSig: IdSignature): IrSymbol = symbolTable.run {
when (symbolKind) {
BinarySymbolData.SymbolKind.ANONYMOUS_INIT_SYMBOL -> if (useGlobalSignatures) IrAnonymousInitializerPublicSymbolImpl(idSig) else IrAnonymousInitializerSymbolImpl()
BinarySymbolData.SymbolKind.ANONYMOUS_INIT_SYMBOL -> IrAnonymousInitializerSymbolImpl()
BinarySymbolData.SymbolKind.CLASS_SYMBOL -> referenceClassFromLinker(idSig)
BinarySymbolData.SymbolKind.CONSTRUCTOR_SYMBOL -> referenceConstructorFromLinker(idSig)
BinarySymbolData.SymbolKind.TYPE_PARAMETER_SYMBOL -> referenceGlobalTypeParameterFromLinker(idSig)
@@ -62,8 +63,8 @@ class IrSymbolDeserializer(
BinarySymbolData.SymbolKind.TYPEALIAS_SYMBOL -> referenceTypeAliasFromLinker(idSig)
BinarySymbolData.SymbolKind.PROPERTY_SYMBOL -> referencePropertyFromLinker(idSig)
BinarySymbolData.SymbolKind.VARIABLE_SYMBOL -> IrVariableSymbolImpl()
BinarySymbolData.SymbolKind.VALUE_PARAMETER_SYMBOL -> if (useGlobalSignatures) IrValueParameterPublicSymbolImpl(idSig) else IrValueParameterSymbolImpl()
BinarySymbolData.SymbolKind.RECEIVER_PARAMETER_SYMBOL -> if (useGlobalSignatures) IrValueParameterPublicSymbolImpl(idSig) else IrValueParameterSymbolImpl()
BinarySymbolData.SymbolKind.VALUE_PARAMETER_SYMBOL -> IrValueParameterSymbolImpl()
BinarySymbolData.SymbolKind.RECEIVER_PARAMETER_SYMBOL -> IrValueParameterSymbolImpl()
BinarySymbolData.SymbolKind.LOCAL_DELEGATED_PROPERTY_SYMBOL ->
IrLocalDelegatedPropertySymbolImpl()
BinarySymbolData.SymbolKind.FILE_SYMBOL -> (idSig as IdSignature.FileSignature).fileSymbol
@@ -200,12 +201,3 @@ class IrSymbolDeserializer(
}
}
}
// TODO: make internal and move to deserializer
private class IrAnonymousInitializerPublicSymbolImpl(sig: IdSignature, descriptor: ClassDescriptor? = null) :
IrBindablePublicSymbolBase<ClassDescriptor, IrAnonymousInitializer>(sig, descriptor),
IrAnonymousInitializerSymbol
private class IrValueParameterPublicSymbolImpl(sig: IdSignature, descriptor: ParameterDescriptor? = null) :
IrBindablePublicSymbolBase<ParameterDescriptor, IrValueParameter>(sig, descriptor),
IrValueParameterSymbol
@@ -35,7 +35,6 @@ class IcFileDeserializer(
allowErrorNodes: Boolean,
deserializeInlineFunctions: Boolean,
val moduleDeserializer: IrModuleDeserializer,
useGlobalSignatures: Boolean,
val handleNoModuleDeserializerFound: (IdSignature, ModuleDescriptor, Collection<IrModuleDeserializer>) -> IrModuleDeserializer,
val originalEnqueue: IdSignature.(IcFileDeserializer) -> Unit,
val icFileData: SerializedIcDataForFile,
@@ -56,7 +55,6 @@ class IcFileDeserializer(
}
},
linker::handleExpectActualMapping,
useGlobalSignatures = useGlobalSignatures,
enqueueAllDeclarations = true,
deserializePublicSymbol = ::deserializeOriginalPublicSymbol,
)
@@ -151,7 +149,6 @@ class IcFileDeserializer(
{ idSig -> idSig.enqueue(this) },
{ _, s -> s },
enqueueAllDeclarations = true,
useGlobalSignatures = true,
deserializedSymbols = originalFileDeserializer.symbolDeserializer.deserializedSymbols,
::deserializePublicSymbol
)
@@ -33,7 +33,6 @@ class IcModuleDeserializer(
override val klib: IrLibrary,
override val strategy: DeserializationStrategy,
private val containsErrorCode: Boolean = false,
private val useGlobalSignatures: Boolean = false,
) : IrModuleDeserializer(moduleDescriptor, KotlinAbiVersion.CURRENT) {
private val fileToDeserializerMap = mutableMapOf<IrFile, IrFileDeserializer>()
@@ -145,7 +144,6 @@ class IcModuleDeserializer(
allowErrorNodes,
strategy.inlineBodies,
moduleDeserializer,
useGlobalSignatures,
linker::handleNoModuleDeserializerFound,
{ fileDeserializer -> originalEnqueue(fileDeserializer) },
icFileData,
@@ -290,8 +290,7 @@ fun loadIr(
symbolTable,
feContext,
null,
depsDescriptors.loweredIcData,
loweringsCacheProvider != null
depsDescriptors.loweredIcData
)
val deserializedModuleFragments = sortDependencies(allDependencies, depsDescriptors.descriptors).map { klib ->
irLinker.deserializeIrModuleHeader(
@@ -359,8 +358,7 @@ fun loadIr(
symbolTable,
null,
null,
loweredIcData,
loweringsCacheProvider != null
loweredIcData
)
val moduleFragmentToUniqueName = mutableMapOf<IrModuleFragment, String>()
@@ -30,7 +30,6 @@ class JsIrLinker(
override val translationPluginContext: TranslationPluginContext?,
private val icData: ICData? = null,
private val loweredIcData: Map<ModuleDescriptor, SerializedIcData> = emptyMap(),
private val useGlobalSignatures: Boolean = false,
) : KotlinIrLinker(currentModule, messageLogger, builtIns, symbolTable, emptyList()) {
override val fakeOverrideBuilder = FakeOverrideBuilder(this, symbolTable, JsManglerIr, IrTypeSystemContextImpl(builtIns))
@@ -53,7 +52,6 @@ class JsIrLinker(
klib,
strategy,
containsErrorCode = klib.libContainsErrorCode,
useGlobalSignatures = useGlobalSignatures
)
}
return JsModuleDeserializer(moduleDescriptor, klib, strategy, klib.versions.abiVersion ?: KotlinAbiVersion.CURRENT, klib.libContainsErrorCode)
@@ -62,7 +60,7 @@ class JsIrLinker(
val mapping: JsMapping by lazy { JsMapping(symbolTable.irFactory) }
private inner class JsModuleDeserializer(moduleDescriptor: ModuleDescriptor, klib: IrLibrary, strategy: DeserializationStrategy, libraryAbiVersion: KotlinAbiVersion, allowErrorCode: Boolean) :
BasicIrModuleDeserializer(this, moduleDescriptor, klib, strategy, libraryAbiVersion, allowErrorCode, useGlobalSignatures)
BasicIrModuleDeserializer(this, moduleDescriptor, klib, strategy, libraryAbiVersion, allowErrorCode)
override fun maybeWrapWithBuiltInAndInit(
moduleDescriptor: ModuleDescriptor,