Extracted a separate phase for synthetic fields creation

This commit is contained in:
Igor Chevdar
2018-08-02 14:27:13 +03:00
parent b8428903ed
commit 6b66f632dc
8 changed files with 37 additions and 33 deletions
@@ -27,7 +27,7 @@ val CompilerOutputKind.isNativeBinary: Boolean get() = when (this) {
CompilerOutputKind.LIBRARY, CompilerOutputKind.BITCODE -> false CompilerOutputKind.LIBRARY, CompilerOutputKind.BITCODE -> false
} }
internal fun produceOutput(context: Context) { internal fun produceOutput(context: Context, phaser: PhaseManager) {
val llvmModule = context.llvmModule!! val llvmModule = context.llvmModule!!
val config = context.config.configuration val config = context.config.configuration
@@ -56,7 +56,7 @@ internal fun produceOutput(context: Context) {
context.config.defaultNativeLibraries + context.config.defaultNativeLibraries +
generatedBitcodeFiles generatedBitcodeFiles
PhaseManager(context).phase(KonanPhase.BITCODE_LINKER) { phaser.phase(KonanPhase.BITCODE_LINKER) {
for (library in nativeLibraries) { for (library in nativeLibraries) {
val libraryModule = parseBitcodeFile(library) val libraryModule = parseBitcodeFile(library)
val failed = LLVMLinkModules2(llvmModule, libraryModule) val failed = LLVMLinkModules2(llvmModule, libraryModule)
@@ -52,7 +52,7 @@ fun runTopLevelPhases(konanConfig: KonanConfig, environment: KotlinCoreEnvironme
val analyzerWithCompilerReport = AnalyzerWithCompilerReport(context.messageCollector, val analyzerWithCompilerReport = AnalyzerWithCompilerReport(context.messageCollector,
environment.configuration.languageVersionSettings) environment.configuration.languageVersionSettings)
val phaser = PhaseManager(context) val phaser = PhaseManager(context, null)
phaser.phase(KonanPhase.FRONTEND) { phaser.phase(KonanPhase.FRONTEND) {
// Build AST and binding info. // Build AST and binding info.
@@ -84,21 +84,23 @@ fun runTopLevelPhases(konanConfig: KonanConfig, environment: KotlinCoreEnvironme
// validateIrModule(context, module) // validateIrModule(context, module)
} }
phaser.phase(KonanPhase.SERIALIZER) { phaser.phase(KonanPhase.GEN_SYNTHETIC_FIELDS) {
markBackingFields(context) markBackingFields(context)
}
phaser.phase(KonanPhase.SERIALIZER) {
val serializer = KonanSerializationUtil(context, context.config.configuration.get(CommonConfigurationKeys.METADATA_VERSION)!!) val serializer = KonanSerializationUtil(context, context.config.configuration.get(CommonConfigurationKeys.METADATA_VERSION)!!)
context.serializedLinkData = context.serializedLinkData =
serializer.serializeModule(context.moduleDescriptor) serializer.serializeModule(context.moduleDescriptor)
} }
phaser.phase(KonanPhase.BACKEND) { phaser.phase(KonanPhase.BACKEND) {
phaser.phase(KonanPhase.LOWER) { phaser.phase(KonanPhase.LOWER) {
KonanLower(context).lower() KonanLower(context, phaser).lower()
// validateIrModule(context, context.ir.irModule) // Temporarily disabled until moving to new IR finished. // validateIrModule(context, context.ir.irModule) // Temporarily disabled until moving to new IR finished.
context.ir.moduleIndexForCodegen = ModuleIndex(context.ir.irModule) context.ir.moduleIndexForCodegen = ModuleIndex(context.ir.irModule)
} }
phaser.phase(KonanPhase.BITCODE) { phaser.phase(KonanPhase.BITCODE) {
emitLLVM(context) emitLLVM(context, phaser)
produceOutput(context) produceOutput(context, phaser)
} }
// We always verify bitcode to prevent hard to debug bugs. // We always verify bitcode to prevent hard to debug bugs.
context.verifyBitCode() context.verifyBitCode()
@@ -109,7 +111,7 @@ fun runTopLevelPhases(konanConfig: KonanConfig, environment: KotlinCoreEnvironme
} }
phaser.phase(KonanPhase.LINK_STAGE) { phaser.phase(KonanPhase.LINK_STAGE) {
LinkStage(context).linkStage() LinkStage(context, phaser).linkStage()
} }
} }
@@ -28,25 +28,23 @@ import org.jetbrains.kotlin.ir.util.checkDeclarationParents
import org.jetbrains.kotlin.ir.util.patchDeclarationParents import org.jetbrains.kotlin.ir.util.patchDeclarationParents
import org.jetbrains.kotlin.ir.util.replaceUnboundSymbols import org.jetbrains.kotlin.ir.util.replaceUnboundSymbols
internal class KonanLower(val context: Context) { internal class KonanLower(val context: Context, val parentPhaser: PhaseManager) {
fun lower() { fun lower() {
val irModule = context.irModule!! val irModule = context.irModule!!
// Phases to run against whole module. // Phases to run against whole module.
lowerModule(irModule) lowerModule(irModule, parentPhaser)
// Phases to run against a file. // Phases to run against a file.
irModule.files.forEach { irModule.files.forEach {
lowerFile(it) lowerFile(it, PhaseManager(context, parentPhaser))
} }
irModule.checkDeclarationParents() irModule.checkDeclarationParents()
} }
private fun lowerModule(irModule: IrModuleFragment) { private fun lowerModule(irModule: IrModuleFragment, phaser: PhaseManager) {
val phaser = PhaseManager(context)
phaser.phase(KonanPhase.REMOVE_EXPECT_DECLARATIONS) { phaser.phase(KonanPhase.REMOVE_EXPECT_DECLARATIONS) {
irModule.files.forEach(ExpectDeclarationsRemoving(context)::lower) irModule.files.forEach(ExpectDeclarationsRemoving(context)::lower)
} }
@@ -90,9 +88,7 @@ internal class KonanLower(val context: Context) {
// validateIrModule(context, irModule) // Temporarily disabled until moving to new IR finished. // validateIrModule(context, irModule) // Temporarily disabled until moving to new IR finished.
} }
private fun lowerFile(irFile: IrFile) { private fun lowerFile(irFile: IrFile, phaser: PhaseManager) {
val phaser = PhaseManager(context)
phaser.phase(KonanPhase.LOWER_STRING_CONCAT) { phaser.phase(KonanPhase.LOWER_STRING_CONCAT) {
StringConcatenationLowering(context).lower(irFile) StringConcatenationLowering(context).lower(irFile)
} }
@@ -25,7 +25,8 @@ enum class KonanPhase(val description: String,
var verbose: Boolean = false) { var verbose: Boolean = false) {
/* */ FRONTEND("Frontend builds AST"), /* */ FRONTEND("Frontend builds AST"),
/* */ PSI_TO_IR("Psi to IR conversion"), /* */ PSI_TO_IR("Psi to IR conversion"),
/* */ SERIALIZER("Serialize descriptor tree and inline IR bodies"), /* */ GEN_SYNTHETIC_FIELDS("Generate synthetic fields"),
/* */ SERIALIZER("Serialize descriptor tree and inline IR bodies", GEN_SYNTHETIC_FIELDS),
/* */ BACKEND("All backend"), /* */ BACKEND("All backend"),
/* ... */ LOWER("IR Lowering"), /* ... */ LOWER("IR Lowering"),
/* ... ... */ REMOVE_EXPECT_DECLARATIONS("Expect declarations removing"), /* ... ... */ REMOVE_EXPECT_DECLARATIONS("Expect declarations removing"),
@@ -49,7 +50,7 @@ enum class KonanPhase(val description: String,
/* ... ... */ LOWER_DEFAULT_PARAMETER_EXTENT("Default Parameter Extent Lowering", LOWER_TAILREC, LOWER_ENUMS), /* ... ... */ LOWER_DEFAULT_PARAMETER_EXTENT("Default Parameter Extent Lowering", LOWER_TAILREC, LOWER_ENUMS),
/* ... ... */ LOWER_VARARG("Vararg lowering", LOWER_CALLABLES, LOWER_DEFAULT_PARAMETER_EXTENT), /* ... ... */ LOWER_VARARG("Vararg lowering", LOWER_CALLABLES, LOWER_DEFAULT_PARAMETER_EXTENT),
/* ... ... */ LOWER_COMPILE_TIME_EVAL("Compile time evaluation lowering", LOWER_VARARG), /* ... ... */ LOWER_COMPILE_TIME_EVAL("Compile time evaluation lowering", LOWER_VARARG),
/* ... ... */ LOWER_INNER_CLASSES("Inner classes lowering", LOWER_DEFAULT_PARAMETER_EXTENT), /* ... ... */ LOWER_INNER_CLASSES("Inner classes lowering", LOWER_DEFAULT_PARAMETER_EXTENT, GEN_SYNTHETIC_FIELDS),
/* ... ... */ LOWER_BUILTIN_OPERATORS("BuiltIn Operators Lowering", LOWER_DEFAULT_PARAMETER_EXTENT), /* ... ... */ LOWER_BUILTIN_OPERATORS("BuiltIn Operators Lowering", LOWER_DEFAULT_PARAMETER_EXTENT),
/* ... ... */ LOWER_COROUTINES("Coroutines lowering", LOWER_LOCAL_FUNCTIONS), /* ... ... */ LOWER_COROUTINES("Coroutines lowering", LOWER_LOCAL_FUNCTIONS),
/* ... ... */ LOWER_TYPE_OPERATORS("Type operators lowering", LOWER_COROUTINES), /* ... ... */ LOWER_TYPE_OPERATORS("Type operators lowering", LOWER_COROUTINES),
@@ -115,16 +116,21 @@ object KonanPhases {
} }
} }
internal class PhaseManager(val context: Context) { internal class PhaseManager(val context: Context, val parent: PhaseManager? = null) {
val previousPhases = mutableSetOf<KonanPhase>() val previousPhases = mutableSetOf<KonanPhase>()
internal fun phase(phase: KonanPhase, body: () -> Unit) { fun createChild() = PhaseManager(context, this)
private fun checkPrerequisite(phase: KonanPhase): Boolean =
previousPhases.contains(phase) || parent?.checkPrerequisite(phase) == true
fun phase(phase: KonanPhase, body: () -> Unit) {
if (!phase.enabled) return if (!phase.enabled) return
phase.prerequisite.forEach { phase.prerequisite.forEach {
if (!previousPhases.contains(it)) if (!checkPrerequisite(it))
throw Error("$phase requires $it") throw Error("$phase requires $it")
} }
@@ -26,7 +26,7 @@ typealias BitcodeFile = String
typealias ObjectFile = String typealias ObjectFile = String
typealias ExecutableFile = String typealias ExecutableFile = String
internal class LinkStage(val context: Context) { internal class LinkStage(val context: Context, val phaser: PhaseManager) {
private val config = context.config.configuration private val config = context.config.configuration
private val target = context.config.target private val target = context.config.target
@@ -228,7 +228,6 @@ internal class LinkStage(val context: Context) {
val objectFiles: MutableList<String> = mutableListOf() val objectFiles: MutableList<String> = mutableListOf()
val phaser = PhaseManager(context)
phaser.phase(KonanPhase.OBJECT_FILES) { phaser.phase(KonanPhase.OBJECT_FILES) {
objectFiles.add( objectFiles.add(
when (platform.configurables) { when (platform.configurables) {
@@ -51,7 +51,7 @@ private val threadLocalAnnotationFqName = FqName("konan.ThreadLocal")
val IrClassSymbol.objectIsShared get() = val IrClassSymbol.objectIsShared get() =
!descriptor.annotations.hasAnnotation(threadLocalAnnotationFqName) !descriptor.annotations.hasAnnotation(threadLocalAnnotationFqName)
internal fun emitLLVM(context: Context) { internal fun emitLLVM(context: Context, phaser: PhaseManager) {
val irModule = context.irModule!! val irModule = context.irModule!!
// Note that we don't set module target explicitly. // Note that we don't set module target explicitly.
@@ -64,8 +64,6 @@ internal fun emitLLVM(context: Context) {
context.debugInfo.builder = DICreateBuilder(llvmModule) context.debugInfo.builder = DICreateBuilder(llvmModule)
context.llvmDeclarations = createLlvmDeclarations(context) context.llvmDeclarations = createLlvmDeclarations(context)
val phaser = PhaseManager(context)
phaser.phase(KonanPhase.RTTI) { phaser.phase(KonanPhase.RTTI) {
irModule.acceptVoid(RTTIGeneratorVisitor(context)) irModule.acceptVoid(RTTIGeneratorVisitor(context))
} }
@@ -32,7 +32,6 @@ import org.jetbrains.kotlin.ir.expressions.impl.IrGetValueImpl
import org.jetbrains.kotlin.ir.expressions.impl.IrSetFieldImpl import org.jetbrains.kotlin.ir.expressions.impl.IrSetFieldImpl
import org.jetbrains.kotlin.ir.symbols.IrConstructorSymbol import org.jetbrains.kotlin.ir.symbols.IrConstructorSymbol
import org.jetbrains.kotlin.ir.symbols.IrFieldSymbol import org.jetbrains.kotlin.ir.symbols.IrFieldSymbol
import org.jetbrains.kotlin.ir.util.addChild
import org.jetbrains.kotlin.ir.util.transformFlat import org.jetbrains.kotlin.ir.util.transformFlat
import org.jetbrains.kotlin.ir.visitors.transformChildrenVoid import org.jetbrains.kotlin.ir.visitors.transformChildrenVoid
import org.jetbrains.kotlin.resolve.scopes.receivers.ImplicitClassReceiver import org.jetbrains.kotlin.resolve.scopes.receivers.ImplicitClassReceiver
@@ -56,9 +55,7 @@ internal class InnerClassLowering(val context: Context) : ClassLoweringPass {
} }
private fun createOuterThisField() { private fun createOuterThisField() {
val field = context.specialDeclarationsFactory.getOuterThisField(irClass) outerThisFieldSymbol = context.specialDeclarationsFactory.getOuterThisField(irClass).symbol
outerThisFieldSymbol = field.symbol
irClass.addChild(field)
} }
private fun lowerConstructors() { private fun lowerConstructors() {
@@ -17,13 +17,12 @@
package org.jetbrains.kotlin.backend.konan.serialization package org.jetbrains.kotlin.backend.konan.serialization
import org.jetbrains.kotlin.backend.konan.Context import org.jetbrains.kotlin.backend.konan.Context
import org.jetbrains.kotlin.descriptors.PropertyDescriptor
import org.jetbrains.kotlin.ir.IrElement import org.jetbrains.kotlin.ir.IrElement
import org.jetbrains.kotlin.ir.declarations.IrClass import org.jetbrains.kotlin.ir.declarations.IrClass
import org.jetbrains.kotlin.ir.declarations.IrField import org.jetbrains.kotlin.ir.declarations.IrField
import org.jetbrains.kotlin.ir.declarations.IrFile import org.jetbrains.kotlin.ir.declarations.IrFile
import org.jetbrains.kotlin.ir.declarations.IrProperty import org.jetbrains.kotlin.ir.declarations.IrProperty
import org.jetbrains.kotlin.ir.util.parentAsClass import org.jetbrains.kotlin.ir.util.addChild
import org.jetbrains.kotlin.ir.visitors.IrElementVisitorVoid import org.jetbrains.kotlin.ir.visitors.IrElementVisitorVoid
import org.jetbrains.kotlin.ir.visitors.acceptChildrenVoid import org.jetbrains.kotlin.ir.visitors.acceptChildrenVoid
@@ -34,6 +33,8 @@ internal class BackingFieldVisitor(val context: Context) : IrElementVisitorVoid
} }
override fun visitProperty(declaration: IrProperty) { override fun visitProperty(declaration: IrProperty) {
super.visitProperty(declaration)
if (declaration.isDelegated) { if (declaration.isDelegated) {
val irClass = declaration.parent as? IrClass val irClass = declaration.parent as? IrClass
val list = irClass?.let { context.ir.classesDelegatedBackingFields.getOrPut(irClass.descriptor) { mutableListOf() } } val list = irClass?.let { context.ir.classesDelegatedBackingFields.getOrPut(irClass.descriptor) { mutableListOf() } }
@@ -46,10 +47,15 @@ internal class BackingFieldVisitor(val context: Context) : IrElementVisitorVoid
} }
override fun visitClass(declaration: IrClass) { override fun visitClass(declaration: IrClass) {
if (declaration.isInner)
declaration.addChild(context.specialDeclarationsFactory.getOuterThisField(declaration))
// Mark all dangling fields (they are created when class is inherited via delegation).
declaration.declarations.filterIsInstance<IrField>().forEach { declaration.declarations.filterIsInstance<IrField>().forEach {
val list = context.ir.classesDelegatedBackingFields.getOrPut(declaration.descriptor) { mutableListOf() } val list = context.ir.classesDelegatedBackingFields.getOrPut(declaration.descriptor) { mutableListOf() }
list.add(it.descriptor) list.add(it.descriptor)
} }
super.visitClass(declaration) super.visitClass(declaration)
} }
} }