From c0961e91b8b20a8474aa5fcf1b67aa90425a205a Mon Sep 17 00:00:00 2001 From: Vladimir Sukharev Date: Fri, 13 Jan 2023 09:57:11 +0000 Subject: [PATCH] [K2/N] KT-55598: Run special backend checks in K2/Native pipeline Merge-request: KT-MR-8204 Merged-by: Vladimir Sukharev --- .../jetbrains/kotlin/backend/konan/Fir2Ir.kt | 20 ++++- .../jetbrains/kotlin/backend/konan/PsiToIr.kt | 4 +- .../backend/konan/cgen/InteropIrUtils.kt | 16 ++-- .../konan/driver/DynamicCompilerDriver.kt | 1 + .../konan/driver/phases/BackendPhases.kt | 18 ++++ .../backend/konan/driver/phases/Fir2Ir.kt | 4 +- .../jetbrains/kotlin/backend/konan/ir/Ir.kt | 88 +++++++++++++------ 7 files changed, 109 insertions(+), 42 deletions(-) diff --git a/kotlin-native/backend.native/compiler/ir/backend.native/src/org/jetbrains/kotlin/backend/konan/Fir2Ir.kt b/kotlin-native/backend.native/compiler/ir/backend.native/src/org/jetbrains/kotlin/backend/konan/Fir2Ir.kt index 18d7711685e..c42f80f5253 100644 --- a/kotlin-native/backend.native/compiler/ir/backend.native/src/org/jetbrains/kotlin/backend/konan/Fir2Ir.kt +++ b/kotlin-native/backend.native/compiler/ir/backend.native/src/org/jetbrains/kotlin/backend/konan/Fir2Ir.kt @@ -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) } diff --git a/kotlin-native/backend.native/compiler/ir/backend.native/src/org/jetbrains/kotlin/backend/konan/PsiToIr.kt b/kotlin-native/backend.native/compiler/ir/backend.native/src/org/jetbrains/kotlin/backend/konan/PsiToIr.kt index 000d71149f3..27980fa22ea 100644 --- a/kotlin-native/backend.native/compiler/ir/backend.native/src/org/jetbrains/kotlin/backend/konan/PsiToIr.kt +++ b/kotlin-native/backend.native/compiler/ir/backend.native/src/org/jetbrains/kotlin/backend/konan/PsiToIr.kt @@ -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 diff --git a/kotlin-native/backend.native/compiler/ir/backend.native/src/org/jetbrains/kotlin/backend/konan/cgen/InteropIrUtils.kt b/kotlin-native/backend.native/compiler/ir/backend.native/src/org/jetbrains/kotlin/backend/konan/cgen/InteropIrUtils.kt index 3ab41c35c95..47c2a0d8eb8 100644 --- a/kotlin-native/backend.native/compiler/ir/backend.native/src/org/jetbrains/kotlin/backend/konan/cgen/InteropIrUtils.kt +++ b/kotlin-native/backend.native/compiler/ir/backend.native/src/org/jetbrains/kotlin/backend/konan/cgen/InteropIrUtils.kt @@ -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 } } diff --git a/kotlin-native/backend.native/compiler/ir/backend.native/src/org/jetbrains/kotlin/backend/konan/driver/DynamicCompilerDriver.kt b/kotlin-native/backend.native/compiler/ir/backend.native/src/org/jetbrains/kotlin/backend/konan/driver/DynamicCompilerDriver.kt index 8971595a57f..131162e4b16 100644 --- a/kotlin-native/backend.native/compiler/ir/backend.native/src/org/jetbrains/kotlin/backend/konan/driver/DynamicCompilerDriver.kt +++ b/kotlin-native/backend.native/compiler/ir/backend.native/src/org/jetbrains/kotlin/backend/konan/driver/DynamicCompilerDriver.kt @@ -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) } diff --git a/kotlin-native/backend.native/compiler/ir/backend.native/src/org/jetbrains/kotlin/backend/konan/driver/phases/BackendPhases.kt b/kotlin-native/backend.native/compiler/ir/backend.native/src/org/jetbrains/kotlin/backend/konan/driver/phases/BackendPhases.kt index 6bbf29dacee..fa1304c0aaa 100644 --- a/kotlin-native/backend.native/compiler/ir/backend.native/src/org/jetbrains/kotlin/backend/konan/driver/phases/BackendPhases.kt +++ b/kotlin-native/backend.native/compiler/ir/backend.native/src/org/jetbrains/kotlin/backend/konan/driver/phases/BackendPhases.kt @@ -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( @@ -19,6 +21,18 @@ internal val SpecialBackendChecksPhase = createSimpleNamedCompilerPhase( + "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( name = "CopyDefaultValuesToActual", @@ -29,4 +43,8 @@ internal val CopyDefaultValuesToActualPhase = createSimpleNamedCompilerPhase PhaseEngine.runSpecialBackendChecks(psiToIrOutput: PsiToIrOutput) { runPhase(SpecialBackendChecksPhase, psiToIrOutput) +} + +internal fun PhaseEngine.runK2SpecialBackendChecks(fir2IrOutput: Fir2IrOutput) { + runPhase(K2SpecialBackendChecksPhase, fir2IrOutput) } \ No newline at end of file diff --git a/kotlin-native/backend.native/compiler/ir/backend.native/src/org/jetbrains/kotlin/backend/konan/driver/phases/Fir2Ir.kt b/kotlin-native/backend.native/compiler/ir/backend.native/src/org/jetbrains/kotlin/backend/konan/driver/phases/Fir2Ir.kt index 066c6850177..ae0d3adbda6 100644 --- a/kotlin-native/backend.native/compiler/ir/backend.native/src/org/jetbrains/kotlin/backend/konan/driver/phases/Fir2Ir.kt +++ b/kotlin-native/backend.native/compiler/ir/backend.native/src/org/jetbrains/kotlin/backend/konan/driver/phases/Fir2Ir.kt @@ -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, val fir2irResult: Fir2IrResult, + val symbols: KonanSymbols ) internal val Fir2IrPhase = createSimpleNamedCompilerPhase( diff --git a/kotlin-native/backend.native/compiler/ir/backend.native/src/org/jetbrains/kotlin/backend/konan/ir/Ir.kt b/kotlin-native/backend.native/compiler/ir/backend.native/src/org/jetbrains/kotlin/backend/konan/ir/Ir.kt index 524db61940d..d719cb3dbb3 100644 --- a/kotlin-native/backend.native/compiler/ir/backend.native/src/org/jetbrains/kotlin/backend/konan/ir/Ir.kt +++ b/kotlin-native/backend.native/compiler/ir/backend.native/src/org/jetbrains/kotlin/backend/konan/ir/Ir.kt @@ -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 + if (kind.runtimeKindString.isEmpty()) + null + else + testFunctionKind.owner.declarations + .filterIsInstance() + .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 { it.name == name }?.symbol + + override fun IrClassSymbol.findMemberPropertyGetter(name: Name): IrSimpleFunctionSymbol? = + owner.findDeclaration { it.name == name }?.getter?.symbol +}