From 5341de253f9b6a7ef8f789ef2c4c2203bcfaa7e2 Mon Sep 17 00:00:00 2001 From: Alexander Udalov Date: Wed, 17 Jul 2019 16:55:32 +0200 Subject: [PATCH] JVM IR: run FileClass & ExpectDeclarationsRemoving phases on whole module Since we now generate file classes even for IR loaded from dependencies (see 3a9b94235fd) to simplify code in certain lowerings, it makes sense to do that for all source files together before any meaningful lowerings. The easiest way to do so is to make FileClassLowering a module-wide phase. ExpectDeclarationsRemoveLowering is now also a module-wide phase because it needs to be run before FileClassLowering (to avoid producing empty facades for files that only contain `expect` declarations) --- .../kotlin/backend/jvm/JvmBackendFacade.kt | 20 ++- .../jetbrains/kotlin/backend/jvm/JvmLower.kt | 142 +++++++++--------- .../backend/jvm/lower/FileClassLowering.kt | 10 +- 3 files changed, 88 insertions(+), 84 deletions(-) diff --git a/compiler/ir/backend.jvm/src/org/jetbrains/kotlin/backend/jvm/JvmBackendFacade.kt b/compiler/ir/backend.jvm/src/org/jetbrains/kotlin/backend/jvm/JvmBackendFacade.kt index 0de3de1d890..d947c57704b 100644 --- a/compiler/ir/backend.jvm/src/org/jetbrains/kotlin/backend/jvm/JvmBackendFacade.kt +++ b/compiler/ir/backend.jvm/src/org/jetbrains/kotlin/backend/jvm/JvmBackendFacade.kt @@ -73,20 +73,18 @@ object JvmBackendFacade { facadeClassGenerator = ::facadeClassGenerator ).generateUnboundSymbolsAsDependencies() - val lower = JvmLower(context) - for (irFile in irModuleFragment.files) { - try { - for (extension in IrGenerationExtension.getInstances(context.state.project)) { - extension.generate(irFile, context, context.state.bindingContext) - } - - lower.lower(irFile) - } catch (e: Throwable) { - errorHandler.reportException(e, null) // TODO ktFile.virtualFile.url + for (extension in IrGenerationExtension.getInstances(context.state.project)) { + extension.generate(irFile, context, context.state.bindingContext) } } + try { + JvmLower(context).lower(irModuleFragment) + } catch (e: Throwable) { + errorHandler.reportException(e, null) + } + for (irFile in irModuleFragment.files) { try { for (loweredClass in irFile.declarations) { @@ -98,7 +96,7 @@ object JvmBackendFacade { } state.afterIndependentPart() } catch (e: Throwable) { - errorHandler.reportException(e, null) + errorHandler.reportException(e, null) // TODO ktFile.virtualFile.url } } } diff --git a/compiler/ir/backend.jvm/src/org/jetbrains/kotlin/backend/jvm/JvmLower.kt b/compiler/ir/backend.jvm/src/org/jetbrains/kotlin/backend/jvm/JvmLower.kt index 47061880fb8..1bbd9cda73d 100644 --- a/compiler/ir/backend.jvm/src/org/jetbrains/kotlin/backend/jvm/JvmLower.kt +++ b/compiler/ir/backend.jvm/src/org/jetbrains/kotlin/backend/jvm/JvmLower.kt @@ -13,6 +13,7 @@ import org.jetbrains.kotlin.backend.jvm.lower.* import org.jetbrains.kotlin.descriptors.Visibilities import org.jetbrains.kotlin.ir.declarations.IrDeclarationWithName import org.jetbrains.kotlin.ir.declarations.IrFile +import org.jetbrains.kotlin.ir.declarations.IrModuleFragment import org.jetbrains.kotlin.ir.util.PatchDeclarationParentsVisitor import org.jetbrains.kotlin.ir.visitors.acceptVoid import org.jetbrains.kotlin.load.java.JvmAbi @@ -41,7 +42,7 @@ private val arrayConstructorPhase = makeIrFilePhase( description = "Transform `Array(size) { index -> value }` into a loop" ) -private val expectDeclarationsRemovingPhase = makeIrFilePhase( +private val expectDeclarationsRemovingPhase = makeIrModulePhase( ::ExpectDeclarationsRemoveLowering, name = "ExpectDeclarationsRemoving", description = "Remove expect declaration from module fragment" @@ -90,81 +91,84 @@ private val innerClassesPhase = makeIrFilePhase( prerequisite = setOf(localDeclarationsPhase) ) -val jvmPhases = namedIrFilePhase( +private val jvmFilePhases = inventNamesForLocalClassesPhase then + + kCallableNamePropertyPhase then + arrayConstructorPhase then + + lateinitPhase then + + moveOrCopyCompanionObjectFieldsPhase then + inlineCallableReferenceToLambdaPhase then + propertyReferencePhase then + constPhase then + propertiesToFieldsPhase then + propertiesPhase then + renameFieldsPhase then + annotationPhase then + tailrecPhase then + + jvmInlineClassPhase then + + sharedVariablesPhase then + + makePatchParentsPhase(1) then + + enumWhenPhase then + singletonReferencesPhase then + localDeclarationsPhase then + defaultArgumentStubPhase then + + interfacePhase then + interfaceDelegationPhase then + interfaceSuperCallsPhase then + + singleAbstractMethodPhase then + addContinuationPhase then + callableReferencePhase then + functionNVarargInvokePhase then + + innerClassesPhase then + innerClassConstructorCallsPhase then + forLoopsPhase then + + makePatchParentsPhase(2) then + + enumClassPhase then + objectClassPhase then + makeInitializersPhase(JvmLoweredDeclarationOrigin.CLASS_STATIC_INITIALIZER, true) then + syntheticAccessorPhase then + collectionStubMethodLowering then + bridgePhase then + jvmOverloadsAnnotationPhase then + jvmDefaultConstructorPhase then + jvmStaticAnnotationPhase then + staticDefaultFunctionPhase then + + toArrayPhase then + flattenStringConcatenationPhase then + foldConstantLoweringPhase then + computeStringTrimPhase then + jvmBuiltinOptimizationLoweringPhase then + additionalClassAnnotationPhase then + + recordNamesForKotlinTypeMapperPhase then + + // should be last transformation + removeDeclarationsThatWouldBeInlined then + makePatchParentsPhase(3) + +val jvmPhases = namedIrModulePhase( name = "IrLowering", description = "IR lowering", lower = expectDeclarationsRemovingPhase then fileClassPhase then - inventNamesForLocalClassesPhase then - kCallableNamePropertyPhase then - arrayConstructorPhase then - - lateinitPhase then - - moveOrCopyCompanionObjectFieldsPhase then - inlineCallableReferenceToLambdaPhase then - propertyReferencePhase then - constPhase then - propertiesToFieldsPhase then - propertiesPhase then - renameFieldsPhase then - annotationPhase then - tailrecPhase then - - jvmInlineClassPhase then - - sharedVariablesPhase then - - makePatchParentsPhase(1) then - - enumWhenPhase then - singletonReferencesPhase then - localDeclarationsPhase then - defaultArgumentStubPhase then - - interfacePhase then - interfaceDelegationPhase then - interfaceSuperCallsPhase then - - singleAbstractMethodPhase then - addContinuationPhase then - callableReferencePhase then - functionNVarargInvokePhase then - - innerClassesPhase then - innerClassConstructorCallsPhase then - forLoopsPhase then - - makePatchParentsPhase(2) then - - enumClassPhase then - objectClassPhase then - makeInitializersPhase(JvmLoweredDeclarationOrigin.CLASS_STATIC_INITIALIZER, true) then - syntheticAccessorPhase then - collectionStubMethodLowering then - bridgePhase then - jvmOverloadsAnnotationPhase then - jvmDefaultConstructorPhase then - jvmStaticAnnotationPhase then - staticDefaultFunctionPhase then - - toArrayPhase then - flattenStringConcatenationPhase then - foldConstantLoweringPhase then - computeStringTrimPhase then - jvmBuiltinOptimizationLoweringPhase then - additionalClassAnnotationPhase then - - recordNamesForKotlinTypeMapperPhase then - - // should be last transformation - removeDeclarationsThatWouldBeInlined then - makePatchParentsPhase(3) + performByIrFile(lower = jvmFilePhases) ) class JvmLower(val context: JvmBackendContext) { - fun lower(irFile: IrFile) { + fun lower(irModuleFragment: IrModuleFragment) { // TODO run lowering passes as callbacks in bottom-up visitor - jvmPhases.invokeToplevel(context.phaseConfig, context, irFile) + jvmPhases.invokeToplevel(context.phaseConfig, context, irModuleFragment) } } diff --git a/compiler/ir/backend.jvm/src/org/jetbrains/kotlin/backend/jvm/lower/FileClassLowering.kt b/compiler/ir/backend.jvm/src/org/jetbrains/kotlin/backend/jvm/lower/FileClassLowering.kt index cf9065d1586..74170c1e37f 100644 --- a/compiler/ir/backend.jvm/src/org/jetbrains/kotlin/backend/jvm/lower/FileClassLowering.kt +++ b/compiler/ir/backend.jvm/src/org/jetbrains/kotlin/backend/jvm/lower/FileClassLowering.kt @@ -19,7 +19,7 @@ package org.jetbrains.kotlin.backend.jvm.lower import org.jetbrains.kotlin.backend.common.FileLoweringPass import org.jetbrains.kotlin.backend.common.descriptors.WrappedClassDescriptor import org.jetbrains.kotlin.backend.common.ir.createImplicitParameterDeclarationWithWrappedDescriptor -import org.jetbrains.kotlin.backend.common.phaser.makeIrFilePhase +import org.jetbrains.kotlin.backend.common.phaser.makeIrModulePhase import org.jetbrains.kotlin.backend.jvm.JvmBackendContext import org.jetbrains.kotlin.codegen.AsmUtil import org.jetbrains.kotlin.descriptors.ClassKind @@ -33,15 +33,17 @@ import org.jetbrains.kotlin.psi2ir.PsiSourceManager import org.jetbrains.kotlin.resolve.source.KotlinSourceElement import java.util.* -internal val fileClassPhase = makeIrFilePhase( +internal val fileClassPhase = makeIrModulePhase( ::FileClassLowering, name = "FileClass", description = "Put file level function and property declaration into a class", stickyPostconditions = setOf(::checkAllFileLevelDeclarationsAreClasses) ) -private fun checkAllFileLevelDeclarationsAreClasses(irFile: IrFile) { - assert(irFile.declarations.all { it is IrClass }) +private fun checkAllFileLevelDeclarationsAreClasses(irModuleFragment: IrModuleFragment) { + assert(irModuleFragment.files.all { irFile -> + irFile.declarations.all { it is IrClass } + }) } private class FileClassLowering(val context: JvmBackendContext) : FileLoweringPass {