[K2/N] KT-55598: Run special backend checks in K2/Native pipeline

Merge-request: KT-MR-8204
Merged-by: Vladimir Sukharev <Vladimir.Sukharev@jetbrains.com>
This commit is contained in:
Vladimir Sukharev
2023-01-13 09:57:11 +00:00
committed by Space Team
parent 6b01886334
commit c0961e91b8
7 changed files with 109 additions and 42 deletions
@@ -6,6 +6,8 @@ import org.jetbrains.kotlin.backend.common.serialization.signature.IdSignatureDe
import org.jetbrains.kotlin.backend.konan.driver.PhaseContext
import org.jetbrains.kotlin.backend.konan.driver.phases.Fir2IrOutput
import org.jetbrains.kotlin.backend.konan.driver.phases.FirOutput
import org.jetbrains.kotlin.backend.konan.ir.KonanSymbolsOverFir
import org.jetbrains.kotlin.backend.konan.serialization.KonanIdSignaturer
import org.jetbrains.kotlin.backend.konan.serialization.KonanManglerDesc
import org.jetbrains.kotlin.backend.konan.serialization.KonanManglerIr
import org.jetbrains.kotlin.builtins.DefaultBuiltIns
@@ -15,9 +17,7 @@ import org.jetbrains.kotlin.config.languageVersionSettings
import org.jetbrains.kotlin.descriptors.deserialization.PlatformDependentTypeTransformer
import org.jetbrains.kotlin.descriptors.impl.ModuleDescriptorImpl
import org.jetbrains.kotlin.fir.FirSession
import org.jetbrains.kotlin.fir.backend.Fir2IrConverter
import org.jetbrains.kotlin.fir.backend.Fir2IrExtensions
import org.jetbrains.kotlin.fir.backend.Fir2IrVisibilityConverter
import org.jetbrains.kotlin.fir.backend.*
import org.jetbrains.kotlin.fir.backend.jvm.Fir2IrJvmSpecialAnnotationSymbolProvider
import org.jetbrains.kotlin.fir.backend.jvm.FirJvmKotlinMangler
import org.jetbrains.kotlin.fir.descriptors.FirModuleDescriptor
@@ -26,6 +26,7 @@ import org.jetbrains.kotlin.fir.resolve.providers.firProvider
import org.jetbrains.kotlin.fir.resolve.providers.impl.FirProviderImpl
import org.jetbrains.kotlin.incremental.components.LookupTracker
import org.jetbrains.kotlin.ir.declarations.impl.IrFactoryImpl
import org.jetbrains.kotlin.ir.util.SymbolTable
import org.jetbrains.kotlin.library.metadata.KlibMetadataFactories
import org.jetbrains.kotlin.library.unresolvedDependencies
import org.jetbrains.kotlin.storage.LockBasedStorageManager
@@ -82,6 +83,17 @@ internal fun PhaseContext.fir2Ir(
(it.irModuleFragment.descriptor as? FirModuleDescriptor)?.let { it.allDependencyModules = librariesDescriptors }
}
val symbols = createKonanSymbols(fir2irResult)
// TODO KT-55580 Invoke CopyDefaultValuesToActualPhase, same as PsiToir phase does.
return Fir2IrOutput(input.session, input.scopeSession, input.firFiles, fir2irResult)
return Fir2IrOutput(input.session, input.scopeSession, input.firFiles, fir2irResult, symbols)
}
private fun PhaseContext.createKonanSymbols(
fir2irResult: Fir2IrResult,
): KonanSymbolsOverFir {
val moduleDescriptor = fir2irResult.irModuleFragment.descriptor
val symbolTable = SymbolTable(KonanIdSignaturer(KonanManglerDesc), fir2irResult.pluginContext.irFactory)
val descriptorsLookup = DescriptorsLookup(moduleDescriptor.builtIns as KonanBuiltIns)
return KonanSymbolsOverFir(this, descriptorsLookup, fir2irResult.components.irBuiltIns, symbolTable, symbolTable.lazyWrapper)
}
@@ -12,7 +12,7 @@ import org.jetbrains.kotlin.backend.konan.descriptors.isFromInteropLibrary
import org.jetbrains.kotlin.backend.konan.driver.phases.PsiToIrContext
import org.jetbrains.kotlin.backend.konan.driver.phases.PsiToIrInput
import org.jetbrains.kotlin.backend.konan.driver.phases.PsiToIrOutput
import org.jetbrains.kotlin.backend.konan.ir.KonanSymbols
import org.jetbrains.kotlin.backend.konan.ir.KonanSymbolsOverDescriptors
import org.jetbrains.kotlin.backend.konan.ir.interop.IrProviderForCEnumAndCStructStubs
import org.jetbrains.kotlin.backend.konan.ir.konanLibrary
import org.jetbrains.kotlin.backend.konan.serialization.*
@@ -90,7 +90,7 @@ internal fun PsiToIrContext.psiToIr(
BuiltInFictitiousFunctionIrClassFactory(symbolTable, irBuiltInsOverDescriptors, reflectionTypes)
irBuiltInsOverDescriptors.functionFactory = functionIrClassFactory
val descriptorsLookup = DescriptorsLookup(this.builtIns)
val symbols = KonanSymbols(this, descriptorsLookup, generatorContext.irBuiltIns, symbolTable, symbolTable.lazyWrapper)
val symbols = KonanSymbolsOverDescriptors(this, descriptorsLookup, generatorContext.irBuiltIns, symbolTable, symbolTable.lazyWrapper)
val irDeserializer = if (isProducingLibrary && !useLinkerWhenProducingLibrary) {
// Enable lazy IR generation for newly-created symbols inside BE
@@ -68,15 +68,13 @@ internal fun IrType.isObjCReferenceType(target: KonanTarget, irBuiltIns: IrBuilt
if (isObjCObjectType()) return true
val descriptor = classifierOrNull?.descriptor ?: return false
val builtIns = (irBuiltIns as IrBuiltInsOverDescriptors).builtIns
return when (descriptor) {
builtIns.any,
builtIns.string,
builtIns.list, builtIns.mutableList,
builtIns.set,
builtIns.map -> true
return when (classifierOrNull) {
irBuiltIns.anyClass,
irBuiltIns.stringClass,
irBuiltIns.listClass,
irBuiltIns.mutableListClass,
irBuiltIns.setClass,
irBuiltIns.mapClass -> true
else -> false
}
}
@@ -90,6 +90,7 @@ internal class DynamicCompilerDriver : CompilerDriver() {
require(frontendOutput is FirOutput.Full)
val fir2IrOutput = engine.runFir2Ir(frontendOutput)
engine.runK2SpecialBackendChecks(fir2IrOutput)
return engine.runFirSerializer(fir2IrOutput)
}
@@ -6,10 +6,12 @@
package org.jetbrains.kotlin.backend.konan.driver.phases
import org.jetbrains.kotlin.backend.common.lower
import org.jetbrains.kotlin.backend.konan.InteropBuiltIns
import org.jetbrains.kotlin.backend.konan.driver.PhaseContext
import org.jetbrains.kotlin.backend.konan.driver.PhaseEngine
import org.jetbrains.kotlin.backend.konan.lower.ExpectToActualDefaultValueCopier
import org.jetbrains.kotlin.backend.konan.lower.SpecialBackendChecksTraversal
import org.jetbrains.kotlin.builtins.konan.KonanBuiltIns
import org.jetbrains.kotlin.ir.declarations.IrModuleFragment
internal val SpecialBackendChecksPhase = createSimpleNamedCompilerPhase<PsiToIrContext, PsiToIrOutput>(
@@ -19,6 +21,18 @@ internal val SpecialBackendChecksPhase = createSimpleNamedCompilerPhase<PsiToIrC
SpecialBackendChecksTraversal(context, context.interopBuiltIns, input.symbols, input.irModule.irBuiltins).lower(input.irModule)
}
internal val K2SpecialBackendChecksPhase = createSimpleNamedCompilerPhase<PhaseContext, Fir2IrOutput>(
"SpecialBackendChecks",
"Special backend checks",
) { context, input ->
val moduleFragment = input.fir2irResult.irModuleFragment
SpecialBackendChecksTraversal(
context,
InteropBuiltIns(input.fir2irResult.pluginContext.moduleDescriptor.builtIns as KonanBuiltIns),
input.symbols,
moduleFragment.irBuiltins
).lower(moduleFragment)
}
internal val CopyDefaultValuesToActualPhase = createSimpleNamedCompilerPhase<PhaseContext, IrModuleFragment>(
name = "CopyDefaultValuesToActual",
@@ -29,4 +43,8 @@ internal val CopyDefaultValuesToActualPhase = createSimpleNamedCompilerPhase<Pha
internal fun <T : PsiToIrContext> PhaseEngine<T>.runSpecialBackendChecks(psiToIrOutput: PsiToIrOutput) {
runPhase(SpecialBackendChecksPhase, psiToIrOutput)
}
internal fun <T : PhaseContext> PhaseEngine<T>.runK2SpecialBackendChecks(fir2IrOutput: Fir2IrOutput) {
runPhase(K2SpecialBackendChecksPhase, fir2IrOutput)
}
@@ -8,16 +8,18 @@ package org.jetbrains.kotlin.backend.konan.driver.phases
import org.jetbrains.kotlin.backend.konan.driver.PhaseContext
import org.jetbrains.kotlin.backend.konan.driver.PhaseEngine
import org.jetbrains.kotlin.backend.konan.fir2Ir
import org.jetbrains.kotlin.backend.konan.ir.KonanSymbols
import org.jetbrains.kotlin.fir.FirSession
import org.jetbrains.kotlin.fir.backend.Fir2IrResult
import org.jetbrains.kotlin.fir.declarations.FirFile
import org.jetbrains.kotlin.fir.resolve.ScopeSession
data class Fir2IrOutput(
internal data class Fir2IrOutput(
val session: FirSession,
val scopeSession: ScopeSession,
val firFiles: List<FirFile>,
val fir2irResult: Fir2IrResult,
val symbols: KonanSymbols
)
internal val Fir2IrPhase = createSimpleNamedCompilerPhase(
@@ -13,18 +13,23 @@ import org.jetbrains.kotlin.backend.konan.driver.PhaseContext
import org.jetbrains.kotlin.backend.konan.llvm.findMainEntryPoint
import org.jetbrains.kotlin.backend.konan.lower.TestProcessor
import org.jetbrains.kotlin.builtins.StandardNames
import org.jetbrains.kotlin.descriptors.ClassDescriptor
import org.jetbrains.kotlin.descriptors.FunctionDescriptor
import org.jetbrains.kotlin.fir.backend.IrBuiltInsOverFir
import org.jetbrains.kotlin.incremental.components.NoLookupLocation
import org.jetbrains.kotlin.ir.IrBuiltIns
import org.jetbrains.kotlin.ir.declarations.IrEnumEntry
import org.jetbrains.kotlin.ir.declarations.IrModuleFragment
import org.jetbrains.kotlin.ir.declarations.IrProperty
import org.jetbrains.kotlin.ir.declarations.IrSimpleFunction
import org.jetbrains.kotlin.ir.symbols.IrClassSymbol
import org.jetbrains.kotlin.ir.symbols.IrSimpleFunctionSymbol
import org.jetbrains.kotlin.ir.types.IrType
import org.jetbrains.kotlin.ir.types.defaultType
import org.jetbrains.kotlin.ir.types.typeWith
import org.jetbrains.kotlin.ir.util.ReferenceSymbolTable
import org.jetbrains.kotlin.ir.util.SymbolTable
import org.jetbrains.kotlin.ir.util.constructors
import org.jetbrains.kotlin.ir.util.findDeclaration
import org.jetbrains.kotlin.name.FqName
import org.jetbrains.kotlin.name.Name
import org.jetbrains.kotlin.psi2ir.descriptors.IrBuiltInsOverDescriptors
@@ -40,13 +45,15 @@ internal class KonanIr(context: Context, irModule: IrModuleFragment): Ir<Context
override var symbols: KonanSymbols by Delegates.notNull()
}
internal class KonanSymbols(
internal abstract class KonanSymbols(
context: PhaseContext,
descriptorsLookup: DescriptorsLookup,
irBuiltIns: IrBuiltIns,
private val symbolTable: SymbolTable,
internal val symbolTable: SymbolTable,
lazySymbolTable: ReferenceSymbolTable
): Symbols(irBuiltIns, symbolTable) {
internal abstract fun IrClassSymbol.findMemberSimpleFunction(name: Name): IrSimpleFunctionSymbol?
internal abstract fun IrClassSymbol.findMemberPropertyGetter(name: Name): IrSimpleFunctionSymbol?
val entryPoint = findMainEntryPoint(context, descriptorsLookup.builtIns)?.let { symbolTable.referenceSimpleFunction(it) }
@@ -82,7 +89,7 @@ internal class KonanSymbols(
val symbol = if (fromClass in signedIntegerClasses && toClass in unsignedIntegerClasses) {
irBuiltIns.getNonBuiltInFunctionsByExtensionReceiver(name, "kotlin")[fromClass]!!
} else {
irBuiltIns.findBuiltInClassMemberFunctions(fromClass, name).single()
fromClass.findMemberSimpleFunction(name)!!
}
(fromClass to toClass) to symbol
@@ -237,7 +244,7 @@ internal class KonanSymbols(
val ieee754Equals = internalFunctions("ieee754Equals")
val equals = irBuiltIns.findBuiltInClassMemberFunctions(any, Name.identifier("equals")).single()
val equals = any.findMemberSimpleFunction(Name.identifier("equals"))!!
val throwArithmeticException = internalFunction("ThrowArithmeticException")
@@ -294,14 +301,11 @@ internal class KonanSymbols(
val copyInto = arrayToExtensionSymbolMap("copyInto")
val copyOf = arrayToExtensionSymbolMap("copyOf") { it.valueParameters.isEmpty() }
val arrayGet = arrays.associateWith { irBuiltIns.findBuiltInClassMemberFunctions(it, Name.identifier("get")).single() }
val arrayGet = arrays.associateWith { it.findMemberSimpleFunction(Name.identifier("get"))!! }
val arraySet = arrays.associateWith { irBuiltIns.findBuiltInClassMemberFunctions(it, Name.identifier("set")).single() }
val arraySize = arrays.associateWith { it.descriptor.unsubstitutedMemberScope
.getContributedVariables(Name.identifier("size"), NoLookupLocation.FROM_BACKEND)
.single().let { symbolTable.referenceSimpleFunction(it.getter!!) } }
val arraySet = arrays.associateWith { it.findMemberSimpleFunction(Name.identifier("set"))!! }
val arraySize = arrays.associateWith { it.findMemberPropertyGetter(Name.identifier("size"))!! }
val valuesForEnum = internalFunction("valuesForEnum")
@@ -317,7 +321,7 @@ internal class KonanSymbols(
val initInstance = internalFunction("initInstance")
val println = irBuiltIns.findFunctions(Name.identifier("println"), "kotlin", "io")
.single { it.descriptor.valueParameters.singleOrNull()?.type == (irBuiltIns as IrBuiltInsOverDescriptors).builtIns.stringType }
.single { it.descriptor.valueParameters.singleOrNull()?.type?.constructor?.declarationDescriptor == string.descriptor }
override val getContinuation = internalFunction("getContinuation")
@@ -350,13 +354,9 @@ internal class KonanSymbols(
val continuationImpl = internalCoroutinesClass("ContinuationImpl")
val invokeSuspendFunction =
irBuiltIns.findBuiltInClassMemberFunctions(baseContinuationImpl, Name.identifier("invokeSuspend")).single()
baseContinuationImpl.findMemberSimpleFunction(Name.identifier("invokeSuspend"))!!
val completionGetter = symbolTable.referenceSimpleFunction(
baseContinuationImpl.descriptor.unsubstitutedMemberScope
.getContributedVariables(Name.identifier("completion"), NoLookupLocation.FROM_BACKEND).single()
.getter!!
)
val completionGetter = baseContinuationImpl.findMemberPropertyGetter(Name.identifier("completion"))!!
override val coroutineSuspendedGetter = symbolTable.referenceSimpleFunction(
coroutinesIntrinsicsPackage
@@ -455,15 +455,51 @@ internal class KonanSymbols(
override val setWithoutBoundCheckName: Name? = KonanNameConventions.setWithoutBoundCheck
private val testFunctionKindCache = TestProcessor.FunctionKind.values().associate {
val symbol = if (it.runtimeKindString.isEmpty())
null
else
symbolTable.referenceEnumEntry(testFunctionKind.descriptor.unsubstitutedMemberScope.getContributedClassifier(
Name.identifier(it.runtimeKindString), NoLookupLocation.FROM_BACKEND
) as ClassDescriptor)
it to symbol
private val testFunctionKindCache by lazy {
TestProcessor.FunctionKind.values().associateWith { kind ->
if (kind.runtimeKindString.isEmpty())
null
else
testFunctionKind.owner.declarations
.filterIsInstance<IrEnumEntry>()
.single { it.name == Name.identifier(kind.runtimeKindString) }
.symbol
}
}
fun getTestFunctionKind(kind: TestProcessor.FunctionKind) = testFunctionKindCache[kind]!!
}
internal class KonanSymbolsOverDescriptors(
context: PhaseContext,
descriptorsLookup: DescriptorsLookup,
irBuiltIns: IrBuiltIns,
symbolTable: SymbolTable,
lazySymbolTable: ReferenceSymbolTable
) : KonanSymbols(context, descriptorsLookup, irBuiltIns, symbolTable, lazySymbolTable) {
override fun IrClassSymbol.findMemberSimpleFunction(name: Name): IrSimpleFunctionSymbol? =
// inspired by: irBuiltIns.findBuiltInClassMemberFunctions(this, name).singleOrNull()
descriptor.unsubstitutedMemberScope.getContributedFunctions(name, NoLookupLocation.FROM_BACKEND)
.singleOrNull()
?.let { symbolTable.referenceSimpleFunction(it) }
override fun IrClassSymbol.findMemberPropertyGetter(name: Name): IrSimpleFunctionSymbol? =
descriptor.unsubstitutedMemberScope.getContributedVariables(name, NoLookupLocation.FROM_BACKEND)
.singleOrNull()
?.getter
?.let { symbolTable.referenceSimpleFunction(it) }
}
internal class KonanSymbolsOverFir(
context: PhaseContext,
descriptorsLookup: DescriptorsLookup,
irBuiltIns: IrBuiltIns,
symbolTable: SymbolTable,
lazySymbolTable: ReferenceSymbolTable
) : KonanSymbols(context, descriptorsLookup, irBuiltIns, symbolTable, lazySymbolTable) {
override fun IrClassSymbol.findMemberSimpleFunction(name: Name): IrSimpleFunctionSymbol? =
owner.findDeclaration<IrSimpleFunction> { it.name == name }?.symbol
override fun IrClassSymbol.findMemberPropertyGetter(name: Name): IrSimpleFunctionSymbol? =
owner.findDeclaration<IrProperty> { it.name == name }?.getter?.symbol
}