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
}
internal fun produceOutput(context: Context) {
internal fun produceOutput(context: Context, phaser: PhaseManager) {
val llvmModule = context.llvmModule!!
val config = context.config.configuration
@@ -56,7 +56,7 @@ internal fun produceOutput(context: Context) {
context.config.defaultNativeLibraries +
generatedBitcodeFiles
PhaseManager(context).phase(KonanPhase.BITCODE_LINKER) {
phaser.phase(KonanPhase.BITCODE_LINKER) {
for (library in nativeLibraries) {
val libraryModule = parseBitcodeFile(library)
val failed = LLVMLinkModules2(llvmModule, libraryModule)
@@ -52,7 +52,7 @@ fun runTopLevelPhases(konanConfig: KonanConfig, environment: KotlinCoreEnvironme
val analyzerWithCompilerReport = AnalyzerWithCompilerReport(context.messageCollector,
environment.configuration.languageVersionSettings)
val phaser = PhaseManager(context)
val phaser = PhaseManager(context, null)
phaser.phase(KonanPhase.FRONTEND) {
// Build AST and binding info.
@@ -84,21 +84,23 @@ fun runTopLevelPhases(konanConfig: KonanConfig, environment: KotlinCoreEnvironme
// validateIrModule(context, module)
}
phaser.phase(KonanPhase.SERIALIZER) {
phaser.phase(KonanPhase.GEN_SYNTHETIC_FIELDS) {
markBackingFields(context)
}
phaser.phase(KonanPhase.SERIALIZER) {
val serializer = KonanSerializationUtil(context, context.config.configuration.get(CommonConfigurationKeys.METADATA_VERSION)!!)
context.serializedLinkData =
serializer.serializeModule(context.moduleDescriptor)
}
phaser.phase(KonanPhase.BACKEND) {
phaser.phase(KonanPhase.LOWER) {
KonanLower(context).lower()
KonanLower(context, phaser).lower()
// validateIrModule(context, context.ir.irModule) // Temporarily disabled until moving to new IR finished.
context.ir.moduleIndexForCodegen = ModuleIndex(context.ir.irModule)
}
phaser.phase(KonanPhase.BITCODE) {
emitLLVM(context)
produceOutput(context)
emitLLVM(context, phaser)
produceOutput(context, phaser)
}
// We always verify bitcode to prevent hard to debug bugs.
context.verifyBitCode()
@@ -109,7 +111,7 @@ fun runTopLevelPhases(konanConfig: KonanConfig, environment: KotlinCoreEnvironme
}
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.replaceUnboundSymbols
internal class KonanLower(val context: Context) {
internal class KonanLower(val context: Context, val parentPhaser: PhaseManager) {
fun lower() {
val irModule = context.irModule!!
// Phases to run against whole module.
lowerModule(irModule)
lowerModule(irModule, parentPhaser)
// Phases to run against a file.
irModule.files.forEach {
lowerFile(it)
lowerFile(it, PhaseManager(context, parentPhaser))
}
irModule.checkDeclarationParents()
}
private fun lowerModule(irModule: IrModuleFragment) {
val phaser = PhaseManager(context)
private fun lowerModule(irModule: IrModuleFragment, phaser: PhaseManager) {
phaser.phase(KonanPhase.REMOVE_EXPECT_DECLARATIONS) {
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.
}
private fun lowerFile(irFile: IrFile) {
val phaser = PhaseManager(context)
private fun lowerFile(irFile: IrFile, phaser: PhaseManager) {
phaser.phase(KonanPhase.LOWER_STRING_CONCAT) {
StringConcatenationLowering(context).lower(irFile)
}
@@ -25,7 +25,8 @@ enum class KonanPhase(val description: String,
var verbose: Boolean = false) {
/* */ FRONTEND("Frontend builds AST"),
/* */ 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"),
/* ... */ LOWER("IR Lowering"),
/* ... ... */ 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_VARARG("Vararg lowering", LOWER_CALLABLES, LOWER_DEFAULT_PARAMETER_EXTENT),
/* ... ... */ 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_COROUTINES("Coroutines lowering", LOWER_LOCAL_FUNCTIONS),
/* ... ... */ 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>()
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
phase.prerequisite.forEach {
if (!previousPhases.contains(it))
if (!checkPrerequisite(it))
throw Error("$phase requires $it")
}
@@ -26,7 +26,7 @@ typealias BitcodeFile = String
typealias ObjectFile = 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 target = context.config.target
@@ -228,7 +228,6 @@ internal class LinkStage(val context: Context) {
val objectFiles: MutableList<String> = mutableListOf()
val phaser = PhaseManager(context)
phaser.phase(KonanPhase.OBJECT_FILES) {
objectFiles.add(
when (platform.configurables) {
@@ -51,7 +51,7 @@ private val threadLocalAnnotationFqName = FqName("konan.ThreadLocal")
val IrClassSymbol.objectIsShared get() =
!descriptor.annotations.hasAnnotation(threadLocalAnnotationFqName)
internal fun emitLLVM(context: Context) {
internal fun emitLLVM(context: Context, phaser: PhaseManager) {
val irModule = context.irModule!!
// Note that we don't set module target explicitly.
@@ -64,8 +64,6 @@ internal fun emitLLVM(context: Context) {
context.debugInfo.builder = DICreateBuilder(llvmModule)
context.llvmDeclarations = createLlvmDeclarations(context)
val phaser = PhaseManager(context)
phaser.phase(KonanPhase.RTTI) {
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.symbols.IrConstructorSymbol
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.visitors.transformChildrenVoid
import org.jetbrains.kotlin.resolve.scopes.receivers.ImplicitClassReceiver
@@ -56,9 +55,7 @@ internal class InnerClassLowering(val context: Context) : ClassLoweringPass {
}
private fun createOuterThisField() {
val field = context.specialDeclarationsFactory.getOuterThisField(irClass)
outerThisFieldSymbol = field.symbol
irClass.addChild(field)
outerThisFieldSymbol = context.specialDeclarationsFactory.getOuterThisField(irClass).symbol
}
private fun lowerConstructors() {
@@ -17,13 +17,12 @@
package org.jetbrains.kotlin.backend.konan.serialization
import org.jetbrains.kotlin.backend.konan.Context
import org.jetbrains.kotlin.descriptors.PropertyDescriptor
import org.jetbrains.kotlin.ir.IrElement
import org.jetbrains.kotlin.ir.declarations.IrClass
import org.jetbrains.kotlin.ir.declarations.IrField
import org.jetbrains.kotlin.ir.declarations.IrFile
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.acceptChildrenVoid
@@ -34,6 +33,8 @@ internal class BackingFieldVisitor(val context: Context) : IrElementVisitorVoid
}
override fun visitProperty(declaration: IrProperty) {
super.visitProperty(declaration)
if (declaration.isDelegated) {
val irClass = declaration.parent as? IrClass
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) {
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 {
val list = context.ir.classesDelegatedBackingFields.getOrPut(declaration.descriptor) { mutableListOf() }
list.add(it.descriptor)
}
super.visitClass(declaration)
}
}