JVM IR: run FileClass & ExpectDeclarationsRemoving phases on whole module

Since we now generate file classes even for IR loaded from dependencies
(see 3a9b94235f) 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)
This commit is contained in:
Alexander Udalov
2019-07-17 16:55:32 +02:00
parent e867830eab
commit 5341de253f
3 changed files with 88 additions and 84 deletions
@@ -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
}
}
}
@@ -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<JvmBackendContext>(
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)
}
}
@@ -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 {